0
0
Fork 0

Implement tag filter

This commit is contained in:
Kevin Martinez 2024-01-05 13:04:06 -04:00
parent b622f9cca7
commit c997d19a5e
3 changed files with 91 additions and 35 deletions

View File

@ -4,6 +4,8 @@ import { useI18n } from 'vue-i18n';
import { useArrayData } from 'composables/useArrayData';
import toDate from 'filters/toDate';
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
const { t } = useI18n();
const props = defineProps({
dataKey: {
@ -39,6 +41,10 @@ const props = defineProps({
type: Array,
default: () => [],
},
customTags: {
type: Array,
default: () => [],
},
});
const emit = defineEmits(['refresh', 'clear', 'search', 'init', 'remove']);
@ -104,19 +110,26 @@ async function clearFilters() {
emit('clear');
}
const tags = computed(() => {
return Object.entries(userParams.value)
const tagsList = computed(() =>
Object.entries(userParams.value)
.filter(([key, value]) => value && !(props.hiddenTags || []).includes(key))
.map(([key, value]) => ({
label: key,
value: value,
}));
});
}))
);
const tags = computed(() =>
tagsList.value.filter((tag) => !(props.customTags || []).includes(tag.label))
);
const customTags = computed(() =>
tagsList.value.filter((tag) => (props.customTags || []).includes(tag.label))
);
async function remove(key) {
userParams.value[key] = null;
await search();
emit('remove', key)
emit('remove', key);
}
function formatValue(value) {
@ -172,21 +185,17 @@ function formatValue(value) {
</QItem>
<QItem class="q-mb-sm">
<div
v-if="tags.length === 0"
v-if="tagsList.length === 0"
class="text-grey font-xs text-center full-width"
>
{{ t(`No filters applied`) }}
</div>
<div>
<QChip
:key="chip.label"
@remove="remove(chip.label)"
class="text-dark"
color="primary"
icon="label"
:removable="!unremovableParams.includes(chip.label)"
size="sm"
<VnFilterPanelChip
v-for="chip of tags"
:key="chip.label"
:removable="!unremovableParams.includes(chip.label)"
@remove="remove(chip.label)"
>
<slot name="tags" :tag="chip" :format-fn="formatValue">
<div class="q-gutter-x-xs">
@ -194,7 +203,15 @@ function formatValue(value) {
<span>"{{ chip.value }}"</span>
</div>
</slot>
</QChip>
</VnFilterPanelChip>
<slot
v-if="$slots.customTags"
name="customTags"
:params="userParams"
:tags="customTags"
:format-fn="formatValue"
:search-fn="search"
/>
</div>
</QItem>
<QSeparator />

View File

@ -0,0 +1,7 @@
<script setup></script>
<template>
<QChip class="text-dark" color="primary" icon="label" size="sm" v-bind="$attrs">
<slot />
</QChip>
</template>

View File

@ -1,12 +1,14 @@
<script setup>
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import axios from 'axios';
import VnInput from 'components/common/VnInput.vue';
import FetchData from 'components/FetchData.vue';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
import axios from 'axios';
import { useRoute } from 'vue-router';
import VnInput from 'components/common/VnInput.vue';
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
const { t } = useI18n();
const route = useRoute();
@ -97,6 +99,7 @@ function exprBuilder(param, value) {
const selectedTag = ref(null);
const tagValues = ref([{}]);
const tagOptions = ref(null);
const isButtonDisabled = computed(()=> !selectedTag.value || tagValues.value.some(item => !item.value))
const applyTagFilter = (params, search) => {
if (!tagValues.value?.length) {
@ -104,14 +107,30 @@ const applyTagFilter = (params, search) => {
search();
return;
}
params.tagGroups = JSON.stringify({
values: tagValues.value,
tagSelection: {
...selectedTag.value,
orgShowField: selectedTag.value.name,
},
tagFk: selectedTag.value.tagFk,
});
if (!params.tagGroups) {
params.tagGroups = [];
}
params.tagGroups.push(
JSON.stringify({
values: tagValues.value,
tagSelection: {
...selectedTag.value,
orgShowField: selectedTag.value.name,
},
tagFk: selectedTag.value.tagFk,
})
);
search();
selectedTag.value = null;
tagValues.value = [{}]
};
const removeTagChip = (selection, params, search) => {
if (params.tagGroups) {
params.tagGroups = (params.tagGroups || []).filter(
(value) => value !== selection
);
}
search();
};
@ -144,19 +163,12 @@ const onOrderChange = (value, params, search) => {
:data-key="props.dataKey"
:hidden-tags="['orderFk', 'orderBy']"
:expr-builder="exprBuilder"
:custom-tags="['tagGroups']"
@init="onFilterInit"
@remove="clearFilter"
>
<template #tags="{ tag, formatFn }">
<div v-if="tag.label === 'tagGroups'">
<strong> {{ JSON.parse(tag?.value).tagSelection?.name }}: </strong>
<span>{{
(JSON.parse(tag?.value).values || [])
.map((item) => item.value)
.join(' | ')
}}</span>
</div>
<strong v-else-if="tag.label === 'categoryFk'">
<strong v-if="tag.label === 'categoryFk'">
{{ t(selectedCategory?.name || '') }}
</strong>
<strong v-else-if="tag.label === 'typeFk'">
@ -167,6 +179,25 @@ const onOrderChange = (value, params, search) => {
<span>{{ formatFn(tag.value) }}</span>
</div>
</template>
<template #customTags="{ tags: customTags, params, searchFn }">
<template v-for="tag in customTags" :key="tag.label">
<template v-if="tag.label === 'tagGroups'">
<VnFilterPanelChip
v-for="chip in tag.value"
:key="chip"
removable
@remove="removeTagChip(chip, params, searchFn)"
>
<strong> {{ JSON.parse(chip).tagSelection?.name }}: </strong>
<span>{{
(JSON.parse(chip).values || [])
.map((item) => item.value)
.join(' | ')
}}</span>
</VnFilterPanelChip>
</template>
</template>
</template>
<template #body="{ params, searchFn }">
<QList dense style="max-width: 256px">
<QItem class="category-filter q-mt-md">
@ -320,6 +351,7 @@ const onOrderChange = (value, params, search) => {
rounded
type="button"
unelevated
:disable="isButtonDisabled"
@click.stop="applyTagFilter(params, searchFn)"
/>
</QItemSection>