feat: Improve Contact list (#10522)

This commit is contained in:
Sivin Varghese
2024-12-03 07:53:41 +05:30
committed by GitHub
parent 86bd339a47
commit 062587487a
6 changed files with 66 additions and 40 deletions

View File

@@ -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="

View File

@@ -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>

View File

@@ -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')

View File

@@ -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(() => {

View File

@@ -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",

View File

@@ -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);