Merge pull request 'fix: orderCatalogFilter and fix useArrayData' (!989) from hotFix_orderCatalogFilter_refactor_fix into master
gitea/salix-front/pipeline/head This commit looks good Details

Reviewed-on: #989
Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
This commit is contained in:
Javier Segarra 2024-11-22 10:24:18 +00:00
commit 651b67e98f
4 changed files with 69 additions and 111 deletions

View File

@ -57,7 +57,6 @@ const $props = defineProps({
},
});
defineExpose({ search, sanitizer });
const emit = defineEmits([
'update:modelValue',
'refresh',
@ -76,6 +75,9 @@ const arrayData = useArrayData($props.dataKey, {
const route = useRoute();
const store = arrayData.store;
const userParams = ref({});
defineExpose({ search, sanitizer, params: userParams });
onMounted(() => {
userParams.value = $props.modelValue ?? {};
emit('init', { params: userParams.value });
@ -179,7 +181,7 @@ const customTags = computed(() =>
async function remove(key) {
userParams.value[key] = undefined;
search();
await search();
emit('remove', key);
emit('update:modelValue', userParams.value);
}

View File

@ -74,18 +74,10 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
limit: store.limit,
};
let exprFilter;
let userParams = { ...store.userParams };
if (store?.exprBuilder) {
const where = buildFilter(userParams, (param, value) => {
const res = store.exprBuilder(param, value);
if (res) delete userParams[param];
return res;
});
exprFilter = where ? { where } : null;
}
Object.assign(filter, store.userFilter, exprFilter);
Object.assign(filter, store.userFilter);
let where;
if (filter?.where || store.filter?.where)
where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
@ -94,12 +86,29 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
const params = { filter };
Object.assign(params, userParams);
params.filter.skip = store.skip;
if (store.order && store.order.length) params.filter.order = store.order;
if (params.filter) params.filter.skip = store.skip;
if (store?.order && typeof store?.order == 'string') store.order = [store.order];
if (store.order?.length) params.filter.order = [...store.order];
else delete params.filter.order;
store.currentFilter = JSON.parse(JSON.stringify(params));
delete store.currentFilter.filter.include;
store.currentFilter.filter = JSON.stringify(store.currentFilter.filter);
let exprFilter;
if (store?.exprBuilder) {
exprFilter = buildFilter(params, (param, value) => {
if (param == 'filter') return;
const res = store.exprBuilder(param, value);
if (res) delete params[param];
return res;
});
}
if (params.filter.where || exprFilter)
params.filter.where = { ...params.filter.where, ...exprFilter };
params.filter = JSON.stringify(params.filter);
store.currentFilter = params;
store.isLoading = true;
const response = await axios.get(store.url, {
signal: canceller.signal,
@ -249,7 +258,8 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
function updateStateParams() {
if (!route?.path) return;
const newUrl = { path: route.path, query: { ...(route.query ?? {}) } };
newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter);
if (store?.searchUrl)
newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter);
if (store.navigate) {
const { customRouteRedirectName, searchText } = store.navigate;

View File

@ -1,14 +1,13 @@
<script setup>
import { useStateStore } from 'stores/useStateStore';
import { useRoute, useRouter } from 'vue-router';
import { onBeforeMount, onMounted, onUnmounted, ref, computed, watch } from 'vue';
import { onMounted, onUnmounted, ref, computed, watch } from 'vue';
import axios from 'axios';
import { useI18n } from 'vue-i18n';
import VnPaginate from 'src/components/ui/VnPaginate.vue';
import CatalogItem from 'src/components/ui/CatalogItem.vue';
import OrderCatalogFilter from 'src/pages/Order/Card/OrderCatalogFilter.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import getParamWhere from 'src/filters/getParamWhere';
import { useArrayData } from 'src/composables/useArrayData';
const route = useRoute();
@ -18,7 +17,6 @@ const { t } = useI18n();
const dataKey = 'OrderCatalogList';
const arrayData = useArrayData(dataKey);
const store = arrayData.store;
const showFilter = ref(null);
const tags = ref([]);
let catalogParams = {
@ -26,27 +24,6 @@ let catalogParams = {
orderBy: JSON.stringify({ field: 'relevancy DESC, name', way: 'ASC', isTag: false }),
};
onBeforeMount(() => {
const whereParams = getParamWhere(route);
if (whereParams) {
const formattedWhereParams = {};
if (whereParams.and) {
whereParams.and.forEach((item) => {
Object.assign(formattedWhereParams, item);
});
} else {
Object.assign(formattedWhereParams, whereParams);
}
catalogParams = {
...catalogParams,
...formattedWhereParams,
};
} else {
showFilter.value = true;
}
});
onMounted(() => {
stateStore.rightDrawer = true;
checkOrderConfirmation();
@ -90,7 +67,7 @@ function extractValueTags(items) {
);
tagValue.value = resultValueTags;
}
const autoLoad = computed(() => !!catalogParams.categoryFk);
const autoLoad = computed(() => !!JSON.parse(route?.query.table ?? '{}')?.categoryFk);
watch(
() => store.data,
@ -112,7 +89,7 @@ watch(
:info="t('You can search items by name or id')"
/>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea v-if="showFilter" class="fit text-grey-8">
<QScrollArea class="fit text-grey-8">
<OrderCatalogFilter
:data-key="dataKey"
:tag-value="tagValue"
@ -128,8 +105,6 @@ watch(
url="Orders/CatalogFilter"
:limit="50"
:user-params="catalogParams"
@on-fetch="showFilter = true"
:update-router="false"
:auto-load="autoLoad"
>
<template #body="{ rows }">

View File

@ -1,5 +1,5 @@
<script setup>
import { computed, ref, onMounted } from 'vue';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import axios from 'axios';
@ -8,7 +8,6 @@ import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
import VnInput from 'src/components/common/VnInput.vue';
import getParamWhere from 'src/filters/getParamWhere';
import CatalogFilterValueDialog from 'src/pages/Order/Card/CatalogFilterValueDialog.vue';
import { useArrayData } from 'composables/useArrayData';
@ -32,11 +31,8 @@ const route = useRoute();
const arrayData = useArrayData(props.dataKey);
const currentParams = ref({});
const categoryList = ref(null);
const selectedCategoryFk = ref(null);
const typeList = ref([]);
const selectedTypeFk = ref(null);
const searchByTag = ref(null);
const vnFilterPanelRef = ref();
@ -53,50 +49,32 @@ const orderWayList = ref([
const orderBySelected = ref('relevancy DESC, name');
const orderWaySelected = ref('ASC');
onMounted(() => {
selectedCategoryFk.value = getParamWhere(route, 'categoryFk');
selectedTypeFk.value = getParamWhere(route, 'typeFk');
});
const resetCategory = (params, search) => {
selectedCategoryFk.value = null;
typeList.value = null;
params.categoryFk = null;
params.typeFk = null;
arrayData.store.userFilter = null;
removeTagGroupParam(search);
};
const selectCategory = (params, category, search) => {
if (params.categoryFk === category?.id) {
resetCategory(params, search);
return;
}
selectedCategoryFk.value = category?.id;
params.categoryFk = category?.id;
params.typeFk = null;
selectedTypeFk.value = null;
loadTypes(category?.id);
search();
};
const loadTypes = async (categoryFk = selectedCategoryFk.value) => {
const selectCategory = async (params, category, search) => {
if (vnFilterPanelRef.value.params.categoryFk === category?.id) {
resetCategory(params, search);
return;
}
params.typeFk = null;
params.categoryFk = category.id;
await loadTypes(category?.id);
await search();
};
const loadTypes = async (id) => {
const { data } = await axios.get(`Orders/${route.params.id}/getItemTypeAvailable`, {
params: { itemCategoryId: categoryFk },
params: { itemCategoryId: id },
});
typeList.value = data;
};
const selectedCategory = computed(() => {
return (categoryList.value || []).find(
(category) => category?.id === selectedCategoryFk.value
);
});
const selectedType = computed(() => {
return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value);
});
function exprBuilder(param, value) {
switch (param) {
case 'categoryFk':
@ -122,21 +100,21 @@ const applyTags = (tagInfo, params, search) => {
async function onSearchByTag(value) {
if (!value.target.value) return;
if (!currentParams.value?.tagGroups) {
currentParams.value.tagGroups = [];
if (!vnFilterPanelRef.value.params?.tagGroups) {
vnFilterPanelRef.value.params.tagGroups = [];
}
currentParams.value.tagGroups.push({
vnFilterPanelRef.value.params.tagGroups.push({
values: [{ value: value.target.value }],
});
searchByTag.value = null;
}
const removeTagGroupParam = (search, valIndex) => {
const removeTagGroupParam = (params, search, valIndex) => {
if (!valIndex && valIndex !== 0) {
currentParams.value.tagGroups = null;
params.tagGroups = null;
} else {
currentParams.value.tagGroups.splice(valIndex, 1);
params.tagGroups.splice(valIndex, 1);
}
search();
};
@ -149,7 +127,8 @@ const setCategoryList = (data) => {
icon: `vn:${(category.icon || '').split('-')[1]}`,
}));
selectedCategoryFk.value && loadTypes();
vnFilterPanelRef.value.params.categoryFk &&
loadTypes(vnFilterPanelRef.value.params.categoryFk);
};
const getCategoryClass = (category, params) => {
@ -158,12 +137,6 @@ const getCategoryClass = (category, params) => {
}
};
const clearFilter = (key) => {
if (key === 'categoryFk') {
resetCategory();
}
};
function addOrder(value, field, params) {
let { orderBy } = params;
orderBy = JSON.parse(orderBy);
@ -178,24 +151,22 @@ function addOrder(value, field, params) {
<VnFilterPanel
ref="vnFilterPanelRef"
:data-key="props.dataKey"
:hidden-tags="['orderFk', 'orderBy']"
:un-removable-params="['orderFk', 'orderBy']"
:hidden-tags="['filter', 'orderFk', 'orderBy']"
:unremovable-params="['orderFk', 'orderBy']"
:expr-builder="exprBuilder"
:custom-tags="['tagGroups', 'categoryFk']"
:redirect="false"
@remove="clearFilter"
v-model="currentParams"
>
<template #tags="{ tag, formatFn }">
<strong v-if="tag.label === 'typeFk'">
{{ t(selectedType?.name || '') }}
<strong v-if="tag.label === 'typeFk' && typeList">
{{ t(typeList.find((t) => t.id == tag.value)?.name || '') }}
</strong>
<div v-else class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span>
</div>
</template>
<template #customTags="{ tags: customTags, params, searchFn }">
<template #customTags="{ params, tags: customTags, searchFn }">
<template v-for="customTag in customTags" :key="customTag.label">
<VnFilterPanelChip
v-for="(tag, valIndex) in Array.isArray(customTag.value)
@ -206,11 +177,16 @@ function addOrder(value, field, params) {
@remove="
customTag.label === 'categoryFk'
? resetCategory(params, searchFn)
: removeTagGroupParam(searchFn, valIndex)
: removeTagGroupParam(params, searchFn, valIndex)
"
>
<strong v-if="customTag.label === 'categoryFk'">
{{ t(selectedCategory?.name || '') }}
<strong v-if="customTag.label === 'categoryFk' && categoryList">
{{
t(
categoryList.find((c) => c.id == customTag.value)?.name ||
''
)
}}
</strong>
<strong v-if="tag?.tagSelection?.name" class="q-mr-xs">
{{ tag.tagSelection.name }}:
@ -257,13 +233,8 @@ function addOrder(value, field, params) {
emit-value
use-input
sort-by="name ASC"
:disable="!selectedCategoryFk"
@update:model-value="
(value) => {
selectedTypeFk = value;
searchFn();
}
"
:disable="!params.categoryFk"
@update:model-value="searchFn()"
>
<template #option="{ itemProps, opt }">
<QItem v-bind="itemProps">
@ -333,7 +304,7 @@ function addOrder(value, field, params) {
style="display: inline-block"
:tags="tags"
@apply-tags="
($event) => applyTags($event, currentParams, searchFn)
($event) => applyTags($event, params, searchFn)
"
/>
</QPopupProxy>