feat: Contact exporting

This commit is contained in:
iamsivin
2024-11-09 14:06:33 +05:30
parent 1b013544a8
commit 271b322761
6 changed files with 103 additions and 7 deletions
@@ -0,0 +1,76 @@
<script setup>
import { ref, computed } from 'vue';
import { useStore, useMapGetter } from 'dashboard/composables/store';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useAlert } from 'dashboard/composables';
import filterQueryGenerator from 'dashboard/helper/filterQueryGenerator';
import Dialog from 'dashboard/components-next/dialog/Dialog.vue';
const { t } = useI18n();
const store = useStore();
const route = useRoute();
const dialogRef = ref(null);
const segments = useMapGetter('customViews/getContactCustomViews');
const appliedFilters = useMapGetter('contacts/getAppliedContactFilters');
const uiFlags = useMapGetter('contacts/getUIFlags');
const isExportingContact = computed(() => uiFlags.value.isExporting);
const activeSegmentId = computed(() => route.params.segmentId);
const activeSegment = computed(() =>
activeSegmentId.value
? segments.value.find(view => view.id === Number(activeSegmentId.value))
: undefined
);
const exportContacts = async () => {
let query = { payload: [] };
if (activeSegmentId.value && activeSegment.value) {
query = activeSegment.value.query;
} else if (Object.keys(appliedFilters.value).length > 0) {
query = filterQueryGenerator(appliedFilters.value);
}
try {
store.dispatch('contacts/export', {
...query,
label: route.params.label || '',
});
useAlert(
t('CONTACTS_LAYOUT.HEADER.ACTIONS.EXPORT_CONTACT.SUCCESS_MESSAGE')
);
} catch (error) {
useAlert(
error.message ||
t('CONTACTS_LAYOUT.HEADER.ACTIONS.EXPORT_CONTACT.ERROR_MESSAGE')
);
}
};
const handleDialogConfirm = async () => {
await exportContacts();
dialogRef.value?.close();
};
defineExpose({ dialogRef });
</script>
<template>
<Dialog
ref="dialogRef"
:title="t('CONTACTS_LAYOUT.HEADER.ACTIONS.EXPORT_CONTACT.TITLE')"
:description="
t('CONTACTS_LAYOUT.HEADER.ACTIONS.EXPORT_CONTACT.DESCRIPTION')
"
:confirm-button-label="
t('CONTACTS_LAYOUT.HEADER.ACTIONS.EXPORT_CONTACT.CONFIRM')
"
:is-loading="isExportingContact"
:disable-confirm-button="isExportingContact"
@confirm="handleDialogConfirm"
/>
</template>
@@ -1,6 +1,6 @@
<script setup>
import { ref } from 'vue';
import { useStore } from 'dashboard/composables/store';
import { ref, computed } from 'vue';
import { useStore, useMapGetter } from 'dashboard/composables/store';
import { useI18n } from 'vue-i18n';
import { useAlert, useTrack } from 'dashboard/composables';
import { CONTACTS_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
@@ -11,6 +11,9 @@ import Button from 'dashboard/components-next/button/Button.vue';
const { t } = useI18n();
const store = useStore();
const uiFlags = useMapGetter('contacts/getUIFlags');
const isImportingContact = computed(() => uiFlags.value.isImporting);
const dialogRef = ref(null);
const fileInput = ref(null);
@@ -69,6 +72,8 @@ defineExpose({ dialogRef });
:confirm-button-label="
t('CONTACTS_LAYOUT.HEADER.ACTIONS.IMPORT_CONTACT.IMPORT')
"
:is-loading="isImportingContact"
:disable-confirm-button="isImportingContact"
@confirm="uploadFile"
>
<template #description>
@@ -6,6 +6,7 @@ import Button from 'dashboard/components-next/button/Button.vue';
import DropdownMenu from 'dashboard/components-next/dropdown-menu/DropdownMenu.vue';
import CreateNewContactDialog from 'dashboard/components-next/Contacts/ContactsForm/CreateNewContactDialog.vue';
import ContactImportDialog from 'dashboard/components-next/Contacts/ContactHeader/ContactImportDialog.vue';
import ContactExportDialog from 'dashboard/components-next/Contacts/ContactHeader/ContactExportDialog.vue';
const { t } = useI18n();
@@ -33,12 +34,15 @@ const contactMenuItems = [
const showActionsDropdown = ref(false);
const createNewContactDialogRef = ref(null);
const contactImportDialogRef = ref(null);
const contactExportDialogRef = ref(null);
const handleContactAction = ({ action }) => {
if (action === 'add') {
createNewContactDialogRef.value?.dialogRef.open();
} else if (action === 'import') {
contactImportDialogRef.value?.dialogRef.open();
} else if (action === 'export') {
contactExportDialogRef.value?.dialogRef.open();
}
};
</script>
@@ -62,4 +66,5 @@ const handleContactAction = ({ action }) => {
</div>
<CreateNewContactDialog ref="createNewContactDialogRef" />
<ContactImportDialog ref="contactImportDialogRef" />
<ContactExportDialog ref="contactExportDialogRef" />
</template>
@@ -414,6 +414,13 @@
"SUCCESS_MESSAGE": "You will be notified via email when the import is complete.",
"ERROR_MESSAGE": "There was an error, please try again"
},
"EXPORT_CONTACT": {
"TITLE": "Export contacts",
"DESCRIPTION": "Quickly export a csv file with comprehensive details of your contacts",
"CONFIRM": "Export",
"SUCCESS_MESSAGE": "Export is in progress. You will be notified on email when the export file is ready to download.",
"ERROR_MESSAGE": "There was an error, please try again"
},
"SORT_BY": {
"LABEL": "Sort by",
"OPTIONS": {
@@ -126,12 +126,12 @@ export const actions = {
},
import: async ({ commit }, file) => {
commit(types.SET_CONTACT_UI_FLAG, { isCreating: true });
commit(types.SET_CONTACT_UI_FLAG, { isImporting: true });
try {
await ContactAPI.importContacts(file);
commit(types.SET_CONTACT_UI_FLAG, { isCreating: false });
commit(types.SET_CONTACT_UI_FLAG, { isImporting: false });
} catch (error) {
commit(types.SET_CONTACT_UI_FLAG, { isCreating: false });
commit(types.SET_CONTACT_UI_FLAG, { isImporting: false });
if (error.response?.data?.message) {
throw new ExceptionWithMessage(error.response.data.message);
}
@@ -139,12 +139,13 @@ export const actions = {
},
export: async ({ commit }, { payload, label }) => {
commit(types.SET_CONTACT_UI_FLAG, { isExporting: true });
try {
await ContactAPI.exportContacts({ payload, label });
commit(types.SET_CONTACT_UI_FLAG, { isCreating: false });
commit(types.SET_CONTACT_UI_FLAG, { isExporting: false });
} catch (error) {
commit(types.SET_CONTACT_UI_FLAG, { isCreating: false });
commit(types.SET_CONTACT_UI_FLAG, { isExporting: false });
if (error.response?.data?.message) {
throw new Error(error.response.data.message);
} else {
@@ -15,6 +15,8 @@ const state = {
isUpdating: false,
isMerging: false,
isDeleting: false,
isExporting: false,
isImporting: false,
},
sortOrder: [],
appliedFilters: [],