feat: Create modal to merge two contacts (#2457)

This commit is contained in:
Nithin David Thomas
2021-10-13 18:35:13 +05:30
committed by GitHub
parent 6c3e2a0bd3
commit b33701a666
16 changed files with 437 additions and 110 deletions

View File

@@ -0,0 +1,89 @@
<template>
<woot-modal :show.sync="show" :on-close="onClose">
<woot-modal-header
:header-title="$t('MERGE_CONTACTS.TITLE')"
:header-content="$t('MERGE_CONTACTS.DESCRIPTION')"
/>
<merge-contact
:primary-contact="primaryContact"
:is-searching="isSearching"
:is-merging="uiFlags.isMerging"
:search-results="searchResults"
@search="onContactSearch"
@cancel="onClose"
@submit="onMergeContacts"
/>
</woot-modal>
</template>
<script>
import alertMixin from 'shared/mixins/alertMixin';
import MergeContact from 'dashboard/modules/contact/components/MergeContact';
import ContactAPI from 'dashboard/api/contacts';
import { mapGetters } from 'vuex';
export default {
components: { MergeContact },
mixins: [alertMixin],
props: {
primaryContact: {
type: Object,
required: true,
},
show: {
type: Boolean,
default: false,
},
},
data() {
return {
isSearching: false,
searchResults: [],
};
},
computed: {
...mapGetters({
uiFlags: 'contacts/getUIFlags',
}),
},
methods: {
onClose() {
this.$emit('close');
},
async onContactSearch(query) {
this.isSearching = true;
this.searchResults = [];
try {
const {
data: { payload },
} = await ContactAPI.search(query);
this.searchResults = payload.filter(
contact => contact.id !== this.primaryContact.id
);
} catch (error) {
this.showAlert(this.$t('MERGE_CONTACTS.SEARCH.ERROR_MESSAGE'));
} finally {
this.isSearching = false;
}
},
async onMergeContacts(childContactId) {
try {
await this.$store.dispatch('contacts/merge', {
childId: childContactId,
parentId: this.primaryContact.id,
});
this.showAlert(this.$t('MERGE_CONTACTS.FORM.SUCCESS_MESSAGE'));
this.onClose();
} catch (error) {
this.showAlert(this.$t('MERGE_CONTACTS.FORM.ERROR_MESSAGE'));
}
},
},
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,9 +1,24 @@
<template>
<div class="option-item--user">
<thumbnail :src="thumbnail" size="24px" :username="name" />
<span class="option__title">
{{ name }}
</span>
<thumbnail :src="thumbnail" size="28px" :username="name" />
<div class="option__user-data">
<h5 class="option__title">
{{ name }}
<span v-if="identifier" class="user-identifier">
( id: {{ identifier }} )
</span>
</h5>
<p class="option__body">
<span v-if="email" class="email-icon-wrap">
<i class="icon ion-email" />{{ email }}
</span>
<span v-if="phoneNumber" class="phone-icon-wrap">
<i class="icon ion-ios-telephone" />
{{ phoneNumber }}
</span>
<span v-if="!phoneNumber && !email">{{ '---' }}</span>
</p>
</div>
</div>
</template>
@@ -23,6 +38,18 @@ export default {
type: String,
default: '',
},
email: {
type: String,
default: '',
},
phoneNumber: {
type: String,
default: '',
},
identifier: {
type: String,
default: '',
},
},
};
</script>
@@ -30,5 +57,49 @@ export default {
<style lang="scss" scoped>
.option-item--user {
display: flex;
align-items: center;
}
.user-identifier {
font-size: var(--font-size-mini);
margin-left: var(--space-micro);
color: var(--s-700);
}
.option__user-data {
display: flex;
flex-direction: column;
flex-grow: 1;
margin-left: var(--space-small);
}
.option__body,
.option__title {
display: flex;
align-items: center;
justify-content: flex-start;
line-height: 1.2;
font-size: var(--font-size-small);
}
.option__body .icon {
position: relative;
top: 1px;
margin-right: var(--space-micro);
}
.option__title {
font-weight: var(--font-weight-medium);
margin-bottom: var(--space-micro);
}
.option__body {
font-size: var(--font-size-mini);
color: var(--s-700);
}
.email-icon-wrap {
margin-right: var(--space-normal);
}
.option__user-data .option__body {
> .phone-icon-wrap,
> .email-icon-wrap {
width: auto;
}
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="contact-fields">
<h3 class="block-title title">Contact fields</h3>
<h3 class="block-title title">{{ $t('CONTACTS_PAGE.FIELDS') }}</h3>
<attribute
:label="$t('CONTACT_PANEL.EMAIL_ADDRESS')"
icon="ion-email"

View File

@@ -1,9 +1,15 @@
<template>
<form @submit.prevent="onSubmit">
<div class="merge-contacts">
<div class="multiselect-wrap--small">
<div class="multiselect-wrap--medium">
<label class="multiselect__label">
{{ $t('MERGE_CONTACTS.PRIMARY.TITLE') }}
<woot-label
:title="$t('MERGE_CONTACTS.PRIMARY.HELP_LABEL')"
color-scheme="success"
small
class="label--merge-warning"
></woot-label>
</label>
<multiselect
:value="primaryContact"
@@ -17,6 +23,9 @@
<contact-dropdown-item
:thumbnail="props.option.thumbnail"
:name="props.option.name"
:identifier="props.option.id"
:email="props.option.email"
:phone-number="props.option.phoneNumber"
/>
</template>
</multiselect>
@@ -27,11 +36,17 @@
<i class="ion-ios-arrow-up up" />
</div>
<div
class="child-contact multiselect-wrap--small"
class="child-contact multiselect-wrap--medium"
:class="{ error: $v.childContact.$error }"
>
<label class="multiselect__label">
{{ $t('MERGE_CONTACTS.CHILD.TITLE') }}
{{ $t('MERGE_CONTACTS.CHILD.TITLE')
}}<woot-label
:title="$t('MERGE_CONTACTS.CHILD.HELP_LABEL')"
color-scheme="alert"
small
class="label--merge-warning"
></woot-label>
</label>
<multiselect
v-model="childContact"
@@ -51,7 +66,19 @@
<template slot="singleLabel" slot-scope="props">
<contact-dropdown-item
:thumbnail="props.option.thumbnail"
:identifier="props.option.id"
:name="props.option.name"
:email="props.option.email"
:phone-number="props.option.phone_number"
/>
</template>
<template slot="option" slot-scope="props">
<contact-dropdown-item
:thumbnail="props.option.thumbnail"
:identifier="props.option.id"
:name="props.option.name"
:email="props.option.email"
:phone-number="props.option.phone_number"
/>
</template>
<span slot="noResult">
@@ -190,12 +217,6 @@ export default {
left: var(--space-normal);
}
::v-deep .multiselect__tags .option__title {
display: inline-flex;
align-items: center;
margin-left: var(--space-small);
}
.footer {
margin-top: var(--space-medium);
display: flex;
@@ -206,4 +227,8 @@ export default {
.error .message {
margin-top: 0;
}
.label--merge-warning {
margin-left: var(--space-small);
}
</style>

View File

@@ -5,7 +5,7 @@
</h5>
<ul class="summary-items">
<li>
<span></span>
<span class="bullet"></span>
<span
v-html="
$t('MERGE_CONTACTS.SUMMARY.DELETE_WARNING', {
@@ -15,7 +15,7 @@
/>
</li>
<li>
<span>✅</span>
<span class="bullet">✅</span>
<span
v-html="
$t('MERGE_CONTACTS.SUMMARY.ATTRIBUTE_WARNING', {
@@ -59,4 +59,9 @@ export default {
margin-bottom: var(--space-smaller);
}
}
.bullet {
display: inline-block;
margin-right: var(--space-smaller);
}
</style>