enhancement: Custom views (#3838)
* enhancement: Custom views * Review fixes
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<div class="left-wrap" :class="wrapClas">
|
||||
<contacts-header
|
||||
:search-query="searchQuery"
|
||||
:custom-views-id="customViewsId"
|
||||
:segments-id="segmentsId"
|
||||
:on-search-submit="onSearchSubmit"
|
||||
this-selected-contact-id=""
|
||||
:on-input-search="onInputSearch"
|
||||
@@ -31,18 +31,20 @@
|
||||
</div>
|
||||
|
||||
<add-custom-views
|
||||
v-if="showAddCustomViewsModal"
|
||||
:custom-views-query="customViewsQuery"
|
||||
v-if="showAddSegmentsModal"
|
||||
:custom-views-query="segmentsQuery"
|
||||
:filter-type="filterType"
|
||||
@close="onCloseAddCustomViewsModal"
|
||||
:open-last-saved-item="openSavedItemInSegment"
|
||||
@close="onCloseAddSegmentsModal"
|
||||
/>
|
||||
<delete-custom-views
|
||||
v-if="showDeleteCustomViewsModal"
|
||||
:show-delete-popup.sync="showDeleteCustomViewsModal"
|
||||
:active-custom-view="activeCustomView"
|
||||
:custom-views-id="customViewsId"
|
||||
v-if="showDeleteSegmentsModal"
|
||||
:show-delete-popup.sync="showDeleteSegmentsModal"
|
||||
:active-custom-view="activeSegment"
|
||||
:custom-views-id="segmentsId"
|
||||
:active-filter-type="filterType"
|
||||
@close="onCloseDeleteCustomViewsModal"
|
||||
:open-last-item-after-delete="openLastItemAfterDeleteInSegment"
|
||||
@close="onCloseDeleteSegmentsModal"
|
||||
/>
|
||||
|
||||
<contact-info-panel
|
||||
@@ -102,7 +104,7 @@ export default {
|
||||
},
|
||||
props: {
|
||||
label: { type: String, default: '' },
|
||||
customViewsId: {
|
||||
segmentsId: {
|
||||
type: [String, Number],
|
||||
default: 0,
|
||||
},
|
||||
@@ -121,10 +123,10 @@ export default {
|
||||
`CONTACTS_FILTER.ATTRIBUTES.${filter.attributeI18nKey}`
|
||||
),
|
||||
})),
|
||||
customViewsQuery: {},
|
||||
segmentsQuery: {},
|
||||
filterType: FILTER_TYPE_CONTACT,
|
||||
showAddCustomViewsModal: false,
|
||||
showDeleteCustomViewsModal: false,
|
||||
showAddSegmentsModal: false,
|
||||
showDeleteSegmentsModal: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -132,7 +134,7 @@ export default {
|
||||
records: 'contacts/getContacts',
|
||||
uiFlags: 'contacts/getUIFlags',
|
||||
meta: 'contacts/getMeta',
|
||||
customViews: 'customViews/getCustomViews',
|
||||
segments: 'customViews/getCustomViews',
|
||||
getAppliedContactFilters: 'contacts/getAppliedContactFilters',
|
||||
}),
|
||||
showEmptySearchResult() {
|
||||
@@ -142,12 +144,18 @@ export default {
|
||||
hasAppliedFilters() {
|
||||
return this.getAppliedContactFilters.length;
|
||||
},
|
||||
hasActiveCustomViews() {
|
||||
return this.activeCustomView && this.customViewsId !== 0;
|
||||
hasActiveSegments() {
|
||||
return this.activeSegment && this.segmentsId !== 0;
|
||||
},
|
||||
isContactAndLabelDashboard() {
|
||||
return (
|
||||
this.$route.name === 'contacts_dashboard' ||
|
||||
this.$route.name === 'contacts_labels_dashboard'
|
||||
);
|
||||
},
|
||||
pageTitle() {
|
||||
if (this.hasActiveCustomViews) {
|
||||
return this.activeCustomView.name;
|
||||
if (this.hasActiveSegments) {
|
||||
return this.activeSegment.name;
|
||||
}
|
||||
if (this.label) {
|
||||
return `#${this.label}`;
|
||||
@@ -176,10 +184,10 @@ export default {
|
||||
? selectedPageNumber
|
||||
: DEFAULT_PAGE;
|
||||
},
|
||||
activeCustomView() {
|
||||
if (this.customViewsId) {
|
||||
const [firstValue] = this.customViews.filter(
|
||||
view => view.id === Number(this.customViewsId)
|
||||
activeSegment() {
|
||||
if (this.segmentsId) {
|
||||
const [firstValue] = this.segments.filter(
|
||||
view => view.id === Number(this.segmentsId)
|
||||
);
|
||||
return firstValue;
|
||||
}
|
||||
@@ -189,11 +197,17 @@ export default {
|
||||
watch: {
|
||||
label() {
|
||||
this.fetchContacts(DEFAULT_PAGE);
|
||||
if (this.hasAppliedFilters) {
|
||||
this.clearFilters();
|
||||
}
|
||||
},
|
||||
activeCustomView() {
|
||||
if (this.hasActiveCustomViews) {
|
||||
const payload = this.activeCustomView.query;
|
||||
this.fetchSavedFilteredContact(payload);
|
||||
activeSegment() {
|
||||
if (this.hasActiveSegments) {
|
||||
const payload = this.activeSegment.query;
|
||||
this.fetchSavedFilteredContact(payload, DEFAULT_PAGE);
|
||||
}
|
||||
if (this.hasAppliedFilters && this.$route.name === 'contacts_dashboard') {
|
||||
this.fetchFilteredContacts(DEFAULT_PAGE);
|
||||
} else {
|
||||
this.fetchContacts(DEFAULT_PAGE);
|
||||
}
|
||||
@@ -222,35 +236,49 @@ export default {
|
||||
return sortAttr;
|
||||
},
|
||||
fetchContacts(page) {
|
||||
this.updatePageParam(page);
|
||||
let value = '';
|
||||
if (this.searchQuery.charAt(0) === '+') {
|
||||
value = this.searchQuery.substring(1);
|
||||
} else {
|
||||
value = this.searchQuery;
|
||||
if (this.isContactAndLabelDashboard) {
|
||||
this.updatePageParam(page);
|
||||
let value = '';
|
||||
if (this.searchQuery.charAt(0) === '+') {
|
||||
value = this.searchQuery.substring(1);
|
||||
} else {
|
||||
value = this.searchQuery;
|
||||
}
|
||||
const requestParams = {
|
||||
page,
|
||||
sortAttr: this.getSortAttribute(),
|
||||
label: this.label,
|
||||
};
|
||||
if (!value) {
|
||||
this.$store.dispatch('contacts/get', requestParams);
|
||||
} else {
|
||||
this.$store.dispatch('contacts/search', {
|
||||
search: value,
|
||||
...requestParams,
|
||||
});
|
||||
}
|
||||
}
|
||||
const requestParams = {
|
||||
page,
|
||||
sortAttr: this.getSortAttribute(),
|
||||
label: this.label,
|
||||
};
|
||||
if (!value) {
|
||||
this.$store.dispatch('contacts/get', requestParams);
|
||||
} else {
|
||||
this.$store.dispatch('contacts/search', {
|
||||
search: value,
|
||||
...requestParams,
|
||||
},
|
||||
fetchSavedFilteredContact(payload, page) {
|
||||
if (this.hasActiveSegments) {
|
||||
this.updatePageParam(page);
|
||||
this.$store.dispatch('contacts/filter', {
|
||||
queryPayload: payload,
|
||||
page,
|
||||
});
|
||||
}
|
||||
},
|
||||
fetchSavedFilteredContact(payload) {
|
||||
fetchFilteredContacts(page) {
|
||||
if (this.hasAppliedFilters) {
|
||||
this.clearFilters();
|
||||
const payload = this.segmentsQuery;
|
||||
this.updatePageParam(page);
|
||||
this.$store.dispatch('contacts/filter', {
|
||||
queryPayload: payload,
|
||||
page,
|
||||
});
|
||||
}
|
||||
this.$store.dispatch('contacts/filter', {
|
||||
queryPayload: payload,
|
||||
});
|
||||
},
|
||||
|
||||
onInputSearch(event) {
|
||||
const newQuery = event.target.value;
|
||||
const refetchAllContacts = !!this.searchQuery && newQuery === '';
|
||||
@@ -267,7 +295,15 @@ export default {
|
||||
},
|
||||
onPageChange(page) {
|
||||
this.selectedContactId = '';
|
||||
this.fetchContacts(page);
|
||||
if (this.segmentsId !== 0) {
|
||||
const payload = this.activeSegment.query;
|
||||
this.fetchSavedFilteredContact(payload, page);
|
||||
}
|
||||
if (this.hasAppliedFilters) {
|
||||
this.fetchFilteredContacts(page);
|
||||
} else {
|
||||
this.fetchContacts(page);
|
||||
}
|
||||
},
|
||||
openContactInfoPanel(contactId) {
|
||||
this.selectedContactId = contactId;
|
||||
@@ -281,16 +317,16 @@ export default {
|
||||
this.showCreateModal = !this.showCreateModal;
|
||||
},
|
||||
onToggleSaveFilters() {
|
||||
this.showAddCustomViewsModal = true;
|
||||
this.showAddSegmentsModal = true;
|
||||
},
|
||||
onCloseAddCustomViewsModal() {
|
||||
this.showAddCustomViewsModal = false;
|
||||
onCloseAddSegmentsModal() {
|
||||
this.showAddSegmentsModal = false;
|
||||
},
|
||||
onToggleDeleteFilters() {
|
||||
this.showDeleteCustomViewsModal = true;
|
||||
this.showDeleteSegmentsModal = true;
|
||||
},
|
||||
onCloseDeleteCustomViewsModal() {
|
||||
this.showDeleteCustomViewsModal = false;
|
||||
onCloseDeleteSegmentsModal() {
|
||||
this.showDeleteSegmentsModal = false;
|
||||
},
|
||||
onToggleImport() {
|
||||
this.showImportModal = !this.showImportModal;
|
||||
@@ -304,7 +340,7 @@ export default {
|
||||
},
|
||||
onApplyFilter(payload) {
|
||||
this.closeContactInfoPanel();
|
||||
this.customViewsQuery = { payload };
|
||||
this.segmentsQuery = { payload };
|
||||
this.$store.dispatch('contacts/filter', {
|
||||
queryPayload: filterQueryGenerator(payload),
|
||||
});
|
||||
@@ -314,6 +350,22 @@ export default {
|
||||
this.$store.dispatch('contacts/clearContactFilters');
|
||||
this.fetchContacts(this.pageParameter);
|
||||
},
|
||||
openSavedItemInSegment() {
|
||||
const lastItemInSegments = this.segments[this.segments.length - 1];
|
||||
const lastItemId = lastItemInSegments.id;
|
||||
this.$router.push({
|
||||
name: 'contacts_segments_dashboard',
|
||||
params: { id: lastItemId },
|
||||
});
|
||||
},
|
||||
openLastItemAfterDeleteInSegment() {
|
||||
if (this.segments.length > 0) {
|
||||
this.openSavedItemInSegment();
|
||||
} else {
|
||||
this.$router.push({ name: 'contacts_dashboard' });
|
||||
this.fetchContacts(DEFAULT_PAGE);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -26,18 +26,16 @@
|
||||
{{ $t('CONTACTS_PAGE.SEARCH_BUTTON') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
|
||||
<woot-button
|
||||
v-if="hasActiveCustomViews && !hasAppliedFilters"
|
||||
v-if="hasActiveSegments"
|
||||
class="margin-right-small clear"
|
||||
color-scheme="alert"
|
||||
icon="delete"
|
||||
@click="onToggleDeleteCustomViewsModal"
|
||||
@click="onToggleDeleteSegmentsModal"
|
||||
>
|
||||
{{ $t('CONTACTS_PAGE.FILTER_CONTACTS_DELETE') }}
|
||||
</woot-button>
|
||||
|
||||
<div v-if="!hasActiveCustomViews" class="filters__button-wrap">
|
||||
<div v-if="!hasActiveSegments" class="filters__button-wrap">
|
||||
<div v-if="hasAppliedFilters" class="filters__applied-indicator" />
|
||||
<woot-button
|
||||
class="margin-right-small clear"
|
||||
@@ -51,12 +49,12 @@
|
||||
</div>
|
||||
|
||||
<woot-button
|
||||
v-if="hasAppliedFilters && !hasActiveCustomViews"
|
||||
v-if="hasAppliedFilters && !hasActiveSegments"
|
||||
class="margin-right-small clear"
|
||||
color-scheme="alert"
|
||||
variant="clear"
|
||||
icon="save"
|
||||
@click="onToggleCustomViewsModal"
|
||||
@click="onToggleSegmentsModal"
|
||||
>
|
||||
{{ $t('CONTACTS_PAGE.FILTER_CONTACTS_SAVE') }}
|
||||
</woot-button>
|
||||
@@ -96,7 +94,7 @@ export default {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
customViewsId: {
|
||||
segmentsId: {
|
||||
type: [String, Number],
|
||||
default: 0,
|
||||
},
|
||||
@@ -137,15 +135,15 @@ export default {
|
||||
hasAppliedFilters() {
|
||||
return this.getAppliedContactFilters.length;
|
||||
},
|
||||
hasActiveCustomViews() {
|
||||
return this.customViewsId !== 0;
|
||||
hasActiveSegments() {
|
||||
return this.segmentsId !== 0;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onToggleCustomViewsModal() {
|
||||
onToggleSegmentsModal() {
|
||||
this.$emit('on-toggle-save-filter');
|
||||
},
|
||||
onToggleDeleteCustomViewsModal() {
|
||||
onToggleDeleteSegmentsModal() {
|
||||
this.$emit('on-toggle-delete-filter');
|
||||
},
|
||||
},
|
||||
|
||||
@@ -12,11 +12,11 @@ export const routes = [
|
||||
},
|
||||
{
|
||||
path: frontendURL('accounts/:accountId/contacts/custom_view/:id'),
|
||||
name: 'contacts_through_custom_view',
|
||||
name: 'contacts_segments_dashboard',
|
||||
roles: ['administrator', 'agent'],
|
||||
component: ContactsView,
|
||||
props: route => {
|
||||
return { customViewsId: route.params.id };
|
||||
return { segmentsId: route.params.id };
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:label="label"
|
||||
:team-id="teamId"
|
||||
:conversation-type="conversationType"
|
||||
:custom-views-id="customViewsId"
|
||||
:folders-id="foldersId"
|
||||
@conversation-load="onConversationLoad"
|
||||
>
|
||||
<pop-over-search />
|
||||
@@ -55,7 +55,7 @@ export default {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
customViewsId: {
|
||||
foldersId: {
|
||||
type: [String, Number],
|
||||
default: 0,
|
||||
},
|
||||
|
||||
@@ -85,21 +85,21 @@ export default {
|
||||
},
|
||||
{
|
||||
path: frontendURL('accounts/:accountId/custom_view/:id'),
|
||||
name: 'custom_view_conversations',
|
||||
name: 'folder_conversations',
|
||||
roles: ['administrator', 'agent'],
|
||||
component: ConversationView,
|
||||
props: route => ({ customViewsId: route.params.id }),
|
||||
props: route => ({ foldersId: route.params.id }),
|
||||
},
|
||||
{
|
||||
path: frontendURL(
|
||||
'accounts/:accountId/custom_view/:id/conversations/:conversation_id'
|
||||
),
|
||||
name: 'conversations_through_custom_view',
|
||||
name: 'conversations_through_folders',
|
||||
roles: ['administrator', 'agent'],
|
||||
component: ConversationView,
|
||||
props: route => ({
|
||||
conversationId: route.params.conversation_id,
|
||||
customViewsId: route.params.id,
|
||||
foldersId: route.params.id,
|
||||
}),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -43,6 +43,10 @@ export default {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
openLastSavedItem: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
@@ -80,17 +84,21 @@ export default {
|
||||
filter_type: this.filterType,
|
||||
query: this.customViewsQuery,
|
||||
});
|
||||
this.alertMessage = this.$t(
|
||||
'FILTER.CUSTOM_VIEWS.ADD.API.SUCCESS_MESSAGE'
|
||||
);
|
||||
this.alertMessage =
|
||||
this.filterType === 0
|
||||
? this.$t('FILTER.CUSTOM_VIEWS.ADD.API_FOLDERS.SUCCESS_MESSAGE')
|
||||
: this.$t('FILTER.CUSTOM_VIEWS.ADD.API_SEGMENTS.SUCCESS_MESSAGE');
|
||||
this.onClose();
|
||||
} catch (error) {
|
||||
const errorMessage = error?.message;
|
||||
this.alertMessage =
|
||||
errorMessage || this.$t('FILTER.CUSTOM_VIEWS.ADD.API.ERROR_MESSAGE');
|
||||
errorMessage || this.filterType === 0
|
||||
? this.$t('FILTER.CUSTOM_VIEWS.ADD.API_FOLDERS.ERROR_MESSAGE')
|
||||
: this.$t('FILTER.CUSTOM_VIEWS.ADD.API_SEGMENTS.ERROR_MESSAGE');
|
||||
} finally {
|
||||
this.showAlert(this.alertMessage);
|
||||
}
|
||||
this.openLastSavedItem();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -34,6 +34,10 @@ export default {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
openLastItemAfterDelete: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
@@ -75,20 +79,20 @@ export default {
|
||||
await this.$store.dispatch('customViews/delete', { id, filterType });
|
||||
this.closeDeletePopup();
|
||||
this.showAlert(
|
||||
this.$t('FILTER.CUSTOM_VIEWS.DELETE.API.SUCCESS_MESSAGE')
|
||||
this.activeFilterType === 0
|
||||
? this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_FOLDERS.SUCCESS_MESSAGE')
|
||||
: this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_SEGMENTS.SUCCESS_MESSAGE')
|
||||
);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error?.response?.message ||
|
||||
this.$t('FILTER.CUSTOM_VIEWS.DELETE.API.ERROR_MESSAGE');
|
||||
error?.response?.message || this.activeFilterType === 0
|
||||
? this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_FOLDERS.SUCCESS_MESSAGE')
|
||||
: this.$t(
|
||||
'FILTER.CUSTOM_VIEWS.DELETE.API_SEGMENTS.SUCCESS_MESSAGE'
|
||||
);
|
||||
this.showAlert(errorMessage);
|
||||
}
|
||||
if (this.isFolderSection) {
|
||||
this.$router.push({ name: 'home' });
|
||||
}
|
||||
if (this.isSegmentSection) {
|
||||
this.$router.push({ name: 'contacts_dashboard' });
|
||||
}
|
||||
this.openLastItemAfterDelete();
|
||||
},
|
||||
closeDeletePopup() {
|
||||
this.$emit('close');
|
||||
|
||||
Reference in New Issue
Block a user