feat: Improve Contact list (#10522)
This commit is contained in:
@@ -214,6 +214,10 @@ const resetValidation = () => {
|
||||
v$.value.$reset();
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
Object.assign(state, defaultState);
|
||||
};
|
||||
|
||||
watch(() => props.contactData, prepareStateBasedOnProps, {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
@@ -224,6 +228,7 @@ defineExpose({
|
||||
state,
|
||||
resetValidation,
|
||||
isFormInvalid,
|
||||
resetForm,
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -261,7 +266,7 @@ defineExpose({
|
||||
:placeholder="item.placeholder"
|
||||
:message-type="getMessageType(item.key)"
|
||||
:custom-input-class="`h-8 !pt-1 !pb-1 ${
|
||||
!isDetailsView ? '[&:not(.error)]:!border-transparent' : ''
|
||||
!isDetailsView ? '[&:not(.error,.focus)]:!border-transparent' : ''
|
||||
}`"
|
||||
class="w-full"
|
||||
@input="
|
||||
|
||||
@@ -27,11 +27,16 @@ const handleDialogConfirm = async () => {
|
||||
emit('create', contact.value);
|
||||
};
|
||||
|
||||
const onSuccess = () => {
|
||||
contactsFormRef.value?.resetForm();
|
||||
dialogRef.value.close();
|
||||
};
|
||||
|
||||
const closeDialog = () => {
|
||||
dialogRef.value.close();
|
||||
};
|
||||
|
||||
defineExpose({ dialogRef, contactsFormRef });
|
||||
defineExpose({ dialogRef, contactsFormRef, onSuccess });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -7,6 +7,10 @@ import { useAlert, useTrack } from 'dashboard/composables';
|
||||
import { CONTACTS_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
|
||||
import filterQueryGenerator from 'dashboard/helper/filterQueryGenerator';
|
||||
import contactFilterItems from 'dashboard/routes/dashboard/contacts/contactFilterItems';
|
||||
import {
|
||||
DuplicateContactException,
|
||||
ExceptionWithMessage,
|
||||
} from 'shared/helpers/CustomErrors';
|
||||
import { generateValuesForEditCustomViews } from 'dashboard/helper/customViewsHelper';
|
||||
import countries from 'shared/constants/countries';
|
||||
import {
|
||||
@@ -23,38 +27,14 @@ import DeleteSegmentDialog from 'dashboard/components-next/Contacts/ContactsForm
|
||||
import ContactsFilter from 'dashboard/components-next/filter/ContactsFilter.vue';
|
||||
|
||||
const props = defineProps({
|
||||
showSearch: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
searchValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
activeSort: {
|
||||
type: String,
|
||||
default: 'last_activity_at',
|
||||
},
|
||||
activeOrdering: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
headerTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
segmentsId: {
|
||||
type: [String, Number],
|
||||
default: 0,
|
||||
},
|
||||
activeSegment: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
hasAppliedFilters: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showSearch: { type: Boolean, default: true },
|
||||
searchValue: { type: String, default: '' },
|
||||
activeSort: { type: String, default: 'last_activity_at' },
|
||||
activeOrdering: { type: String, default: '' },
|
||||
headerTitle: { type: String, default: '' },
|
||||
segmentsId: { type: [String, Number], default: 0 },
|
||||
activeSegment: { type: Object, default: null },
|
||||
hasAppliedFilters: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
@@ -99,8 +79,26 @@ const openDeleteSegmentDialog = () =>
|
||||
deleteSegmentDialogRef.value?.dialogRef.open();
|
||||
|
||||
const onCreate = async contact => {
|
||||
await store.dispatch('contacts/create', contact);
|
||||
createNewContactDialogRef.value?.dialogRef.close();
|
||||
try {
|
||||
await store.dispatch('contacts/create', contact);
|
||||
createNewContactDialogRef.value?.onSuccess();
|
||||
useAlert(
|
||||
t('CONTACTS_LAYOUT.HEADER.ACTIONS.CONTACT_CREATION.SUCCESS_MESSAGE')
|
||||
);
|
||||
} catch (error) {
|
||||
const i18nPrefix = 'CONTACTS_LAYOUT.HEADER.ACTIONS.CONTACT_CREATION';
|
||||
if (error instanceof DuplicateContactException) {
|
||||
if (error.data.includes('email')) {
|
||||
useAlert(t(`${i18nPrefix}.EMAIL_ADDRESS_DUPLICATE`));
|
||||
} else if (error.data.includes('phone_number')) {
|
||||
useAlert(t(`${i18nPrefix}.PHONE_NUMBER_DUPLICATE`));
|
||||
}
|
||||
} else if (error instanceof ExceptionWithMessage) {
|
||||
useAlert(error.data);
|
||||
} else {
|
||||
useAlert(t(`${i18nPrefix}.ERROR_MESSAGE`));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onImport = async file => {
|
||||
@@ -135,11 +133,19 @@ const onCreateSegment = async payload => {
|
||||
...payload,
|
||||
query: segmentsQuery.value,
|
||||
};
|
||||
await store.dispatch('customViews/create', payloadData);
|
||||
const response = await store.dispatch('customViews/create', payloadData);
|
||||
createSegmentDialogRef.value?.dialogRef.close();
|
||||
useAlert(
|
||||
t('CONTACTS_LAYOUT.HEADER.ACTIONS.FILTERS.CREATE_SEGMENT.SUCCESS_MESSAGE')
|
||||
);
|
||||
const segmentId = response?.data?.id;
|
||||
if (!segmentId) return;
|
||||
// Navigate to the created segment
|
||||
router.push({
|
||||
name: 'contacts_dashboard_segments_index',
|
||||
params: { segmentId },
|
||||
query: { page: 1 },
|
||||
});
|
||||
} catch {
|
||||
useAlert(
|
||||
t('CONTACTS_LAYOUT.HEADER.ACTIONS.FILTERS.CREATE_SEGMENT.ERROR_MESSAGE')
|
||||
|
||||
@@ -91,13 +91,18 @@ const activeCountry = computed(() =>
|
||||
const inputBorderClass = computed(() => {
|
||||
const errorClass =
|
||||
'border-n-ruby-8 dark:border-n-ruby-8 hover:border-n-ruby-9 dark:hover:border-n-ruby-9 disabled:border-n-ruby-8 dark:disabled:border-n-ruby-8';
|
||||
const focusClass =
|
||||
'has-[:focus]:border-n-brand dark:has-[:focus]:border-n-brand';
|
||||
|
||||
if (!props.showBorder) {
|
||||
return hasError.value ? errorClass : 'border-transparent';
|
||||
if (hasError.value) return errorClass;
|
||||
return `border-transparent ${focusClass}`;
|
||||
}
|
||||
|
||||
if (hasError.value) {
|
||||
return errorClass;
|
||||
}
|
||||
return 'has-[:focus]:border-n-brand dark:has-[:focus]:border-n-brand border-n-weak dark:border-n-weak hover:border-n-slate-6 dark:hover:border-n-slate-6 disabled:border-n-weak dark:disabled:border-n-weak';
|
||||
return `${focusClass} border-n-weak dark:border-n-weak hover:border-n-slate-6 dark:hover:border-n-slate-6 disabled:border-n-weak dark:disabled:border-n-weak`;
|
||||
});
|
||||
|
||||
const phoneNumberError = computed(() => {
|
||||
|
||||
@@ -401,7 +401,11 @@
|
||||
"ADD_CONTACT": "Add contact",
|
||||
"EXPORT_CONTACT": "Export contacts",
|
||||
"IMPORT_CONTACT": "Import contacts",
|
||||
"SAVE_CONTACT": "Save contact"
|
||||
"SAVE_CONTACT": "Save contact",
|
||||
"EMAIL_ADDRESS_DUPLICATE": "This email address is in use for another contact.",
|
||||
"PHONE_NUMBER_DUPLICATE": "This phone number is in use for another contact.",
|
||||
"SUCCESS_MESSAGE": "Contact saved successfully",
|
||||
"ERROR_MESSAGE": "Unable to save contact. Please try again later."
|
||||
},
|
||||
"IMPORT_CONTACT": {
|
||||
"TITLE": "Import contacts",
|
||||
|
||||
@@ -70,6 +70,7 @@ export const actions = {
|
||||
data: response.data,
|
||||
filterType: FILTER_KEYS[obj.filter_type],
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
const errorMessage = error?.response?.data?.message;
|
||||
throw new Error(errorMessage);
|
||||
|
||||
Reference in New Issue
Block a user