feat: Add the ability to save filters for contact (#3791)

This commit is contained in:
Sivin Varghese
2022-01-22 03:41:59 +05:30
committed by GitHub
parent 693f2531ab
commit 504fc24fb3
12 changed files with 203 additions and 31 deletions

View File

@@ -3,13 +3,15 @@
<div class="left-wrap" :class="wrapClas">
<contacts-header
:search-query="searchQuery"
:custom-views-id="customViewsId"
:on-search-submit="onSearchSubmit"
this-selected-contact-id=""
:on-input-search="onInputSearch"
:on-toggle-create="onToggleCreate"
:on-toggle-import="onToggleImport"
:on-toggle-filter="onToggleFilters"
:header-title="label"
:header-title="pageTitle"
@on-toggle-save-filter="onToggleSaveFilters"
/>
<contacts-table
:contacts="records"
@@ -26,6 +28,12 @@
:total-count="meta.count"
/>
</div>
<add-custom-views
v-if="showAddCustomViewsModal"
:custom-views-query="customViewsQuery"
:filter-type="filterType"
@close="onCloseAddCustomViewsModal"
/>
<contact-info-panel
v-if="showContactViewPane"
:contact="selectedContact"
@@ -63,8 +71,10 @@ import ImportContacts from './ImportContacts.vue';
import ContactsAdvancedFilters from './ContactsAdvancedFilters.vue';
import contactFilterItems from '../contactFilterItems';
import filterQueryGenerator from '../../../../helper/filterQueryGenerator';
import AddCustomViews from 'dashboard/routes/dashboard/customviews/AddCustomViews';
const DEFAULT_PAGE = 1;
const FILTER_TYPE_CONTACT = 1;
export default {
components: {
@@ -75,9 +85,14 @@ export default {
CreateContact,
ImportContacts,
ContactsAdvancedFilters,
AddCustomViews,
},
props: {
label: { type: String, default: '' },
customViewsId: {
type: [String, Number],
default: 0,
},
},
data() {
return {
@@ -93,6 +108,9 @@ export default {
`CONTACTS_FILTER.ATTRIBUTES.${filter.attributeI18nKey}`
),
})),
customViewsQuery: {},
filterType: FILTER_TYPE_CONTACT,
showAddCustomViewsModal: false,
};
},
computed: {
@@ -100,11 +118,28 @@ export default {
records: 'contacts/getContacts',
uiFlags: 'contacts/getUIFlags',
meta: 'contacts/getMeta',
customViews: 'customViews/getCustomViews',
getAppliedContactFilters: 'contacts/getAppliedContactFilters',
}),
showEmptySearchResult() {
const hasEmptyResults = !!this.searchQuery && this.records.length === 0;
return hasEmptyResults;
},
hasAppliedFilters() {
return this.getAppliedContactFilters.length;
},
hasActiveCustomViews() {
return this.activeCustomView && this.customViewsId !== 0;
},
pageTitle() {
if (this.hasActiveCustomViews) {
return this.activeCustomView.name;
}
if (this.label) {
return `#${this.label}`;
}
return this.$t('CONTACTS_PAGE.HEADER');
},
selectedContact() {
if (this.selectedContactId) {
const contact = this.records.find(
@@ -127,11 +162,28 @@ export default {
? selectedPageNumber
: DEFAULT_PAGE;
},
activeCustomView() {
if (this.customViewsId) {
const [firstValue] = this.customViews.filter(
view => view.id === Number(this.customViewsId)
);
return firstValue;
}
return undefined;
},
},
watch: {
label() {
this.fetchContacts(DEFAULT_PAGE);
},
activeCustomView() {
if (this.hasActiveCustomViews) {
const payload = this.activeCustomView.query;
this.fetchSavedFilteredContact(payload);
} else {
this.fetchContacts(DEFAULT_PAGE);
}
},
},
mounted() {
this.fetchContacts(this.pageParameter);
@@ -177,6 +229,14 @@ export default {
});
}
},
fetchSavedFilteredContact(payload) {
if (this.hasAppliedFilters) {
this.clearFilters();
}
this.$store.dispatch('contacts/filter', {
queryPayload: payload,
});
},
onInputSearch(event) {
const newQuery = event.target.value;
const refetchAllContacts = !!this.searchQuery && newQuery === '';
@@ -206,6 +266,12 @@ export default {
onToggleCreate() {
this.showCreateModal = !this.showCreateModal;
},
onToggleSaveFilters() {
this.showAddCustomViewsModal = true;
},
onCloseAddCustomViewsModal() {
this.showAddCustomViewsModal = false;
},
onToggleImport() {
this.showImportModal = !this.showImportModal;
},
@@ -218,6 +284,7 @@ export default {
},
onApplyFilter(payload) {
this.closeContactInfoPanel();
this.customViewsQuery = { payload };
this.$store.dispatch('contacts/filter', {
queryPayload: filterQueryGenerator(payload),
});

View File

@@ -3,7 +3,7 @@
<div class="table-actions-wrap">
<div class="left-aligned-wrap">
<h1 class="page-title">
{{ headerTitle ? `#${headerTitle}` : $t('CONTACTS_PAGE.HEADER') }}
{{ headerTitle }}
</h1>
</div>
<div class="right-aligned-wrap">
@@ -26,7 +26,7 @@
{{ $t('CONTACTS_PAGE.SEARCH_BUTTON') }}
</woot-button>
</div>
<div class="filters__button-wrap">
<div v-if="!hasActiveCustomViews" class="filters__button-wrap">
<div v-if="hasAppliedFilters" class="filters__applied-indicator" />
<woot-button
class="margin-right-small clear"
@@ -38,6 +38,16 @@
{{ $t('CONTACTS_PAGE.FILTER_CONTACTS') }}
</woot-button>
</div>
<woot-button
v-if="hasAppliedFilters && !hasActiveCustomViews"
class="margin-right-small clear"
color-scheme="alert"
variant="clear"
icon="save"
@click="onToggleCustomViewsModal"
>
{{ $t('CONTACTS_PAGE.FILTER_CONTACTS_SAVE') }}
</woot-button>
<woot-button
class="margin-right-small clear"
color-scheme="success"
@@ -74,6 +84,10 @@ export default {
type: String,
default: '',
},
customViewsId: {
type: [String, Number],
default: 0,
},
onInputSearch: {
type: Function,
default: () => {},
@@ -111,6 +125,14 @@ export default {
hasAppliedFilters() {
return this.getAppliedContactFilters.length;
},
hasActiveCustomViews() {
return this.customViewsId !== 0;
},
},
methods: {
onToggleCustomViewsModal() {
this.$emit('on-toggle-save-filter');
},
},
};
</script>

View File

@@ -10,6 +10,15 @@ export const routes = [
roles: ['administrator', 'agent'],
component: ContactsView,
},
{
path: frontendURL('accounts/:accountId/contacts/custom_view/:id'),
name: 'contacts_through_custom_view',
roles: ['administrator', 'agent'],
component: ContactsView,
props: route => {
return { customViewsId: route.params.id };
},
},
{
path: frontendURL('accounts/:accountId/labels/:label/contacts'),
name: 'contacts_labels_dashboard',