feature: Filtering conversations and contacts with custom attributes (#3851)
This commit is contained in:
@@ -9,7 +9,8 @@
|
||||
v-for="(filter, i) in appliedFilters"
|
||||
:key="i"
|
||||
v-model="appliedFilters[i]"
|
||||
:filter-attributes="filterAttributes"
|
||||
:filter-groups="filterGroups"
|
||||
:grouped-filters="true"
|
||||
:input-type="getInputType(appliedFilters[i].attribute_key)"
|
||||
:operators="getOperators(appliedFilters[i].attribute_key)"
|
||||
:dropdown-values="getDropdownValues(appliedFilters[i].attribute_key)"
|
||||
@@ -58,21 +59,23 @@
|
||||
<script>
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import { required } from 'vuelidate/lib/validators';
|
||||
import FilterInputBox from '../../../../components/widgets/FilterInput.vue';
|
||||
import countries from '/app/javascript/shared/constants/countries.js';
|
||||
import FilterInputBox from '../../../../components/widgets/FilterInput/Index.vue';
|
||||
import countries from 'shared/constants/countries.js';
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
import { filterAttributeGroups } from '../contactFilterItems';
|
||||
import filterMixin from 'shared/mixins/filterMixin';
|
||||
import * as OPERATORS from 'dashboard/components/widgets/FilterInput/FilterOperatorTypes.js';
|
||||
export default {
|
||||
components: {
|
||||
FilterInputBox,
|
||||
},
|
||||
mixins: [alertMixin],
|
||||
mixins: [alertMixin, filterMixin],
|
||||
props: {
|
||||
onClose: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
filterTypes: {
|
||||
initialFilterTypes: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
@@ -91,17 +94,15 @@ export default {
|
||||
return {
|
||||
show: true,
|
||||
appliedFilters: [],
|
||||
filterTypes: this.initialFilterTypes,
|
||||
filterGroups: [],
|
||||
allCustomAttributes: [],
|
||||
filterAttributeGroups,
|
||||
attributeModel: 'contact_attribute',
|
||||
filtersFori18n: 'CONTACTS_FILTER',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
filterAttributes() {
|
||||
return this.filterTypes.map(type => {
|
||||
return {
|
||||
key: type.attributeKey,
|
||||
name: this.$t(`CONTACTS_FILTER.ATTRIBUTES.${type.attributeI18nKey}`),
|
||||
};
|
||||
});
|
||||
},
|
||||
...mapGetters({
|
||||
getAppliedContactFilters: 'contacts/getAppliedContactFilters',
|
||||
}),
|
||||
@@ -110,6 +111,7 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setFilterAttributes();
|
||||
if (this.getAppliedContactFilters.length) {
|
||||
this.appliedFilters = [...this.getAppliedContactFilters];
|
||||
} else {
|
||||
@@ -118,10 +120,41 @@ export default {
|
||||
filter_operator: 'equal_to',
|
||||
values: '',
|
||||
query_operator: 'and',
|
||||
attribute_model: 'standard',
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getOperatorTypes(key) {
|
||||
switch (key) {
|
||||
case 'list':
|
||||
return OPERATORS.OPERATOR_TYPES_1;
|
||||
case 'text':
|
||||
return OPERATORS.OPERATOR_TYPES_3;
|
||||
case 'number':
|
||||
return OPERATORS.OPERATOR_TYPES_1;
|
||||
case 'link':
|
||||
return OPERATORS.OPERATOR_TYPES_1;
|
||||
case 'date':
|
||||
return OPERATORS.OPERATOR_TYPES_4;
|
||||
case 'checkbox':
|
||||
return OPERATORS.OPERATOR_TYPES_1;
|
||||
default:
|
||||
return OPERATORS.OPERATOR_TYPES_1;
|
||||
}
|
||||
},
|
||||
customAttributeInputType(key) {
|
||||
switch (key) {
|
||||
case 'date':
|
||||
return 'date';
|
||||
default:
|
||||
return 'plain_text';
|
||||
}
|
||||
},
|
||||
getAttributeModel(key) {
|
||||
const type = this.filterTypes.find(filter => filter.attributeKey === key);
|
||||
return type.attributeModel;
|
||||
},
|
||||
getInputType(key) {
|
||||
const type = this.filterTypes.find(filter => filter.attributeKey === key);
|
||||
return type.inputType;
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<contacts-advanced-filters
|
||||
v-if="showFiltersModal"
|
||||
:on-close="onToggleFilters"
|
||||
:filter-types="contactFilterItems"
|
||||
:initial-filter-types="contactFilterItems"
|
||||
@applyFilter="onApplyFilter"
|
||||
@clearFilters="clearFilters"
|
||||
/>
|
||||
|
||||
@@ -1,27 +1,14 @@
|
||||
import {
|
||||
OPERATOR_TYPES_1,
|
||||
OPERATOR_TYPES_3,
|
||||
} from 'dashboard/components/widgets/FilterInput/FilterOperatorTypes.js';
|
||||
const filterTypes = [
|
||||
{
|
||||
attributeKey: 'name',
|
||||
attributeI18nKey: 'NAME',
|
||||
inputType: 'plain_text',
|
||||
dataType: 'text',
|
||||
filterOperators: [
|
||||
{
|
||||
value: 'equal_to',
|
||||
label: 'Equal to',
|
||||
},
|
||||
{
|
||||
value: 'not_equal_to',
|
||||
label: 'Not equal to',
|
||||
},
|
||||
{
|
||||
value: 'contains',
|
||||
label: 'Contains',
|
||||
},
|
||||
{
|
||||
value: 'does_not_contain',
|
||||
label: 'Does not contain',
|
||||
},
|
||||
],
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
attribute_type: 'standard',
|
||||
},
|
||||
{
|
||||
@@ -29,24 +16,7 @@ const filterTypes = [
|
||||
attributeI18nKey: 'EMAIL',
|
||||
inputType: 'plain_text',
|
||||
dataType: 'text',
|
||||
filterOperators: [
|
||||
{
|
||||
value: 'equal_to',
|
||||
label: 'Equal to',
|
||||
},
|
||||
{
|
||||
value: 'not_equal_to',
|
||||
label: 'Not equal to',
|
||||
},
|
||||
{
|
||||
value: 'contains',
|
||||
label: 'Contains',
|
||||
},
|
||||
{
|
||||
value: 'does_not_contain',
|
||||
label: 'Does not contain',
|
||||
},
|
||||
],
|
||||
filterOperators: OPERATOR_TYPES_3,
|
||||
attribute_type: 'standard',
|
||||
},
|
||||
{
|
||||
@@ -54,24 +24,7 @@ const filterTypes = [
|
||||
attributeI18nKey: 'PHONE_NUMBER',
|
||||
inputType: 'plain_text',
|
||||
dataType: 'text',
|
||||
filterOperators: [
|
||||
{
|
||||
value: 'equal_to',
|
||||
label: 'Equal to',
|
||||
},
|
||||
{
|
||||
value: 'not_equal_to',
|
||||
label: 'Not equal to',
|
||||
},
|
||||
{
|
||||
value: 'contains',
|
||||
label: 'Contains',
|
||||
},
|
||||
{
|
||||
value: 'does_not_contain',
|
||||
label: 'Does not contain',
|
||||
},
|
||||
],
|
||||
filterOperators: OPERATOR_TYPES_3,
|
||||
attribute_type: 'standard',
|
||||
},
|
||||
{
|
||||
@@ -79,16 +32,7 @@ const filterTypes = [
|
||||
attributeI18nKey: 'IDENTIFIER',
|
||||
inputType: 'plain_text',
|
||||
dataType: 'number',
|
||||
filterOperators: [
|
||||
{
|
||||
value: 'equal_to',
|
||||
label: 'Equal to',
|
||||
},
|
||||
{
|
||||
value: 'not_equal_to',
|
||||
label: 'Not equal to',
|
||||
},
|
||||
],
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
attribute_type: 'standard',
|
||||
},
|
||||
{
|
||||
@@ -96,16 +40,7 @@ const filterTypes = [
|
||||
attributeI18nKey: 'COUNTRY',
|
||||
inputType: 'search_select',
|
||||
dataType: 'number',
|
||||
filterOperators: [
|
||||
{
|
||||
value: 'equal_to',
|
||||
label: 'Equal to',
|
||||
},
|
||||
{
|
||||
value: 'not_equal_to',
|
||||
label: 'Not equal to',
|
||||
},
|
||||
],
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
attribute_type: 'standard',
|
||||
},
|
||||
{
|
||||
@@ -113,26 +48,42 @@ const filterTypes = [
|
||||
attributeI18nKey: 'CITY',
|
||||
inputType: 'plain_text',
|
||||
dataType: 'Number',
|
||||
filterOperators: [
|
||||
{
|
||||
value: 'equal_to',
|
||||
label: 'Equal to',
|
||||
},
|
||||
{
|
||||
value: 'not_equal_to',
|
||||
label: 'Not equal to',
|
||||
},
|
||||
{
|
||||
value: 'contains',
|
||||
label: 'Contains',
|
||||
},
|
||||
{
|
||||
value: 'does_not_contain',
|
||||
label: 'Does not contain',
|
||||
},
|
||||
],
|
||||
filterOperators: OPERATOR_TYPES_3,
|
||||
attribute_type: 'standard',
|
||||
},
|
||||
];
|
||||
|
||||
export const filterAttributeGroups = [
|
||||
{
|
||||
name: 'Standard Filters',
|
||||
i18nGroup: 'STANDARD_FILTERS',
|
||||
attributes: [
|
||||
{
|
||||
key: 'name',
|
||||
i18nKey: 'NAME',
|
||||
},
|
||||
{
|
||||
key: 'email',
|
||||
i18nKey: 'EMAIL',
|
||||
},
|
||||
{
|
||||
key: 'phone_number',
|
||||
i18nKey: 'PHONE_NUMBER',
|
||||
},
|
||||
{
|
||||
key: 'identifier',
|
||||
i18nKey: 'IDENTIFIER',
|
||||
},
|
||||
{
|
||||
key: 'country_code',
|
||||
i18nKey: 'COUNTRY',
|
||||
},
|
||||
{
|
||||
key: 'city',
|
||||
i18nKey: 'CITY',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default filterTypes;
|
||||
|
||||
Reference in New Issue
Block a user