Refactor to make the filter component resuable.
This commit is contained in:
parent
449245c087
commit
3b9deb2434
3 changed files with 231 additions and 36 deletions
|
@ -6,7 +6,7 @@
|
|||
{{ pageTitle }}
|
||||
</h1>
|
||||
<button class="btn-filter" @click="onToggleAdvanceFiltersModal">
|
||||
<i class="icon ion-funnel" />
|
||||
<i class="icon ion-ios-settings-strong" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -61,6 +61,7 @@
|
|||
>
|
||||
<chat-advanced-filter
|
||||
v-if="showAdvancedFilters"
|
||||
:filter-types="advancedFilterTypes"
|
||||
:on-close="onToggleAdvanceFiltersModal"
|
||||
/>
|
||||
</woot-modal>
|
||||
|
@ -77,6 +78,7 @@ import timeMixin from '../mixins/time';
|
|||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||
import conversationMixin from '../mixins/conversations';
|
||||
import wootConstants from '../constants';
|
||||
import advancedFilterTypes from './widgets/conversation/advancedFilterItems';
|
||||
import {
|
||||
hasPressedAltAndJKey,
|
||||
hasPressedAltAndKKey,
|
||||
|
@ -108,6 +110,7 @@ export default {
|
|||
activeAssigneeTab: wootConstants.ASSIGNEE_TYPE.ME,
|
||||
activeStatus: wootConstants.STATUS_TYPE.OPEN,
|
||||
showAdvancedFilters: false,
|
||||
advancedFilterTypes,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -1,39 +1,37 @@
|
|||
<template>
|
||||
<div class="column">
|
||||
<woot-modal-header header-title="Filter Conversations">
|
||||
<p>
|
||||
{{ $t('FILTER.SUBTITLE') }}
|
||||
</p>
|
||||
</woot-modal-header>
|
||||
<div class="row modal-content">
|
||||
<div class="medium-12 columns filter-modal-content">
|
||||
<filter-input-box
|
||||
v-for="(filter, i) in appliedFilters"
|
||||
:key="i"
|
||||
v-model="appliedFilters[i]"
|
||||
:filter-data="filter"
|
||||
:filter-attributes="filterAttributes"
|
||||
:input-type="getInputType(appliedFilters[i].attribute_key)"
|
||||
:operators="getOperators(appliedFilters[i].attribute_key)"
|
||||
:dropdown-values="getDropdownValues(appliedFilters[i].attribute_key)"
|
||||
:show-query-operator="i !== appliedFilters.length - 1"
|
||||
:v="$v.appliedFilters.$each[i]"
|
||||
@clearPreviousValues="clearPreviousValues(i)"
|
||||
@removeFilter="removeFilter(i)"
|
||||
/>
|
||||
<div class="filter-actions">
|
||||
<button class="append-filter-btn" @click="appendNewFilter">
|
||||
<i class="icon ion-plus-circled margin-right-small" />
|
||||
<span>{{ $t('FILTER.ADD_NEW_FILTER') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-footer justify-content-end">
|
||||
<woot-button class="button clear" @click.prevent="onClose">
|
||||
{{ $t('FILTER.CANCEL_BUTTON_LABEL') }}
|
||||
</woot-button>
|
||||
<woot-button @click="submitFilterQuery">
|
||||
{{ $t('FILTER.SUBMIT_BUTTON_LABEL') }}
|
||||
</woot-button>
|
||||
<modal :show.sync="show" :on-close="onClose">
|
||||
<div class="column">
|
||||
<woot-modal-header header-title="Filter Conversations">
|
||||
<p>
|
||||
Add filters below and hit "Submit" to filter conversations.
|
||||
</p>
|
||||
</woot-modal-header>
|
||||
<div class="row modal-content">
|
||||
<div class="medium-12 columns filter-modal-content">
|
||||
<filter-input-box
|
||||
v-for="(filter, i) in appliedFilters"
|
||||
:key="i"
|
||||
v-model="filter"
|
||||
:filter-data="filter"
|
||||
:filter-attributes="filterAttributes"
|
||||
:input-type="getInputType(filter.attribute_key)"
|
||||
:operators="getOperators(filter.attribute_key)"
|
||||
:dropdown-values="getDropdownValues(filter.attribute_key)"
|
||||
/>
|
||||
<div class="filter-actions">
|
||||
<button class="append-filter-btn" @click="appendNewFilter">
|
||||
<i class="icon ion-plus-circled margin-right-small" />
|
||||
<span>Add Filter</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-footer justify-content-end">
|
||||
<button class="button clear" @click.prevent="onClose">
|
||||
Cancel
|
||||
</button>
|
||||
<woot-button @click="submitFilterQuery">
|
||||
Submit
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -85,6 +83,24 @@ export default {
|
|||
query_operator: 'and',
|
||||
},
|
||||
],
|
||||
mockOptions: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Option 1',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Option 2',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Option 3',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'Option 4',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
<template>
|
||||
<div class="filters">
|
||||
<div class="filter--attributes">
|
||||
<select
|
||||
v-model="attribute_key"
|
||||
class="filter--attributes_select"
|
||||
@change="values = ''"
|
||||
>
|
||||
<option
|
||||
v-for="attribute in filterAttributes"
|
||||
:key="attribute.key"
|
||||
:value="attribute.key"
|
||||
>
|
||||
{{ attribute.name }}
|
||||
</option>
|
||||
</select>
|
||||
<button class="filter--attribute_clearbtn" @click="removeFilter(i)">
|
||||
<i class="icon ion-close-circled" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="filter-values">
|
||||
<div class="row">
|
||||
<div class="small-4 columns padding-right-small">
|
||||
<select v-model="filter_operator" class="filter--values_select">
|
||||
<option
|
||||
v-for="(operator, o) in operators"
|
||||
:key="o"
|
||||
:value="operator.key"
|
||||
>
|
||||
{{ operator.value }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="small-8 columns">
|
||||
<input
|
||||
v-if="inputType === 'plain_text'"
|
||||
v-model="values"
|
||||
type="text"
|
||||
class="filter--attributes_input"
|
||||
placeholder="Enter value"
|
||||
/>
|
||||
<div class="multiselect-wrap--small">
|
||||
<multiselect
|
||||
v-if="inputType === 'multi_select'"
|
||||
v-model="values"
|
||||
track-by="id"
|
||||
label="name"
|
||||
:placeholder="'Select'"
|
||||
:multiple="true"
|
||||
selected-label
|
||||
:select-label="$t('FORMS.MULTISELECT.ENTER_TO_SELECT')"
|
||||
deselect-label=""
|
||||
:options="dropdownValues"
|
||||
:allow-empty="false"
|
||||
/>
|
||||
</div>
|
||||
<div class="multiselect-wrap--small">
|
||||
<multiselect
|
||||
v-if="inputType === 'search_select'"
|
||||
v-model="values"
|
||||
track-by="id"
|
||||
label="name"
|
||||
:placeholder="'Select'"
|
||||
selected-label
|
||||
:select-label="$t('FORMS.MULTISELECT.ENTER_TO_SELECT')"
|
||||
deselect-label=""
|
||||
:options="dropdownValues"
|
||||
:allow-empty="false"
|
||||
:option-height="104"
|
||||
/>
|
||||
</div>
|
||||
<!-- <div v-if="!v.filter.values.required" class="error">
|
||||
Value is required.
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div v-if="i !== appliedFilters.length - 1" class="filter--query_operator">
|
||||
<hr class="filter--query_operator_line" />
|
||||
<div class="filter--query_operator_container">
|
||||
<select
|
||||
v-model="filter.query_operator"
|
||||
class="filter--query_operator_select"
|
||||
>
|
||||
<option value="and">
|
||||
AND
|
||||
</option>
|
||||
<option value="or">
|
||||
OR
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
filterData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
filterAttributes: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
inputType: {
|
||||
type: String,
|
||||
default: 'plain_text',
|
||||
},
|
||||
operators: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
dropdownValues: {
|
||||
type: Array,
|
||||
default: () => ['op1', 'op2', 'op3'],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filter: this.filterData,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
attribute_key: {
|
||||
get() {
|
||||
if (!this.value) return null;
|
||||
return this.value.attribute_key;
|
||||
},
|
||||
set(value) {
|
||||
const payload = this.value || {};
|
||||
this.$emit('input', { ...payload, attribute_key: value });
|
||||
},
|
||||
},
|
||||
filter_operator: {
|
||||
get() {
|
||||
if (!this.value) return null;
|
||||
return this.value.filter_operator;
|
||||
},
|
||||
set(value) {
|
||||
const payload = this.value || {};
|
||||
this.$emit('input', { ...payload, filter_operator: value });
|
||||
},
|
||||
},
|
||||
values: {
|
||||
get() {
|
||||
if (!this.value) return null;
|
||||
return this.value.values;
|
||||
},
|
||||
set(value) {
|
||||
const payload = this.value || {};
|
||||
this.$emit('input', { ...payload, values: value });
|
||||
},
|
||||
},
|
||||
query_operator: {
|
||||
get() {
|
||||
if (!this.value) return null;
|
||||
return this.value.query_operator;
|
||||
},
|
||||
set(value) {
|
||||
const payload = this.value || {};
|
||||
this.$emit('input', { ...payload, query_operator: value });
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
removeFilter() {
|
||||
this.$emit('remove-filter');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
Loading…
Reference in a new issue