fix/OrderCatalog #893

Merged
jsegarra merged 11 commits from wbuezas/salix-front-mindshore-fork2:fix/OrderCatalog into dev 2024-11-12 12:01:43 +00:00
4 changed files with 231 additions and 156 deletions
Showing only changes of commit d627c1f698 - Show all commits

View File

@ -120,7 +120,7 @@ watch(options, (newValue) => {
});
watch(modelValue, async (newValue) => {
if (!myOptions.value.some((option) => option[optionValue.value] == newValue))
if (!myOptions?.value?.some((option) => option[optionValue.value] == newValue))
await fetchFilter(newValue);
if ($props.noOne) myOptions.value.unshift(noOneOpt.value);

View File

@ -189,7 +189,6 @@ const tags = computed(() => {
const filteredTags = tagsList.value.filter(
(tag) => !($props.customTags || []).includes(tag.label)
);
console.log('formatTags: ', formatTags(filteredTags));
return formatTags(filteredTags);
});

View File

@ -0,0 +1,150 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import VnSelect from 'components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue';
const props = defineProps({
tags: {
type: Array,
default: () => [],
},
});
const emit = defineEmits(['applyTags']);
const { t } = useI18n();
const tagValues = ref([{}]);
const tagOptions = ref([]);
const selectedTag = ref(null);
const applyTags = () => {
if (tagValues.value.some((tag) => !tag.value)) return;
const tagInfo = {
values: [...tagValues.value],
tagFk: selectedTag?.value?.id,
tagSelection: {
name: selectedTag?.value?.name,
},
};
emit('applyTags', tagInfo);
};
const removeTagGroupParam = (valIndex = null) => {
if (!valIndex) {
tagValues.value = [{}];
} else {
(tagValues.value || []).splice(valIndex, 1);
}
};
const getSelectedTagValues = async (tag) => {
try {
if (!tag?.id) return;
const filter = {
fields: ['value'],
order: 'value ASC',
limit: 30,
};
const url = `Tags/${tag?.id}/filterValue`;
const params = { filter: JSON.stringify(filter) };
const { data } = await axios.get(url, {
params,
});
tagOptions.value = data;
} catch (err) {
console.error('Error getting selected tag values');
}
};
</script>
<template>
<QForm @submit="applyTags(tagValues)" class="all-pointer-events">
<QCard class="q-pa-sm column q-pa-lg">
<VnSelect
:label="t('params.tag')"
v-model="selectedTag"
:options="props.tags || []"
jsegarra marked this conversation as resolved Outdated

porque pones un valor por defecto si ya tiene el default?

porque pones un valor por defecto si ya tiene el default?

Buena observación, había quedado de antes que componentice esta parte.

Commit: 498a52a3e5

Buena observación, había quedado de antes que componentice esta parte. Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/498a52a3e5a78c4e8c8f7c58a3cc4b655ca33cac
option-value="id"
option-label="name"
dense
outlined
class="q-mb-md"
rounded
:emit-value="false"
use-input
@update:model-value="($event) => getSelectedTagValues($event)"
/>
<div
v-for="(value, index) in tagValues"
:key="value"
class="filter-value column align-left"
>
<div class="col row q-mb-md">
<VnSelect
v-if="!selectedTag?.isFree && tagOptions"
:label="t('components.itemsFilterPanel.value')"
v-model="value.value"
:options="tagOptions || []"
option-value="value"
option-label="value"
dense
outlined
rounded
emit-value
use-input
:disable="!value"
:is-clearable="false"
class="col"
/>
<VnInput
v-else
v-model="value.value"
:label="t('components.itemsFilterPanel.value')"
:disable="!value"
is-outlined
:is-clearable="false"
class="col"
/>
<QIcon
name="delete"
class="filter-icon col-2"
@click="removeTagGroupParam(index)"
/>
</div>
</div>
<QBtn
icon="add_circle"
shortcut="+"
flat
class="filter-icon q-mb-md"
size="md"
dense
@click="tagValues.push({})"
/>
<QBtn color="primary" type="submit">
{{ t('search') }}
</QBtn>
</QCard>
</QForm>
</template>
<style scoped lang="scss">
.filter-icon {
font-size: 24px;
color: $primary;
padding: 0 4px;
cursor: pointer;
}
</style>
<i18n>
en:
params:
tag: Tag
es:
params:
tag: Etiqueta
</i18n>

View File

@ -9,6 +9,7 @@ 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';
const { t } = useI18n();
@ -28,13 +29,13 @@ const props = defineProps({
},
});
const showValueFilterDialog = ref(false);
const categoryList = ref(null);
const selectedCategoryFk = ref(null);
const typeList = ref([]);
const selectedTypeFk = ref(null);
const selectedTag = ref(null);
const tagValues = ref([{}]);
const tagOptions = ref([]);
const generalSearchParam = ref(null);
const vnFilterPanelRef = ref();
const orderByList = ref([
{ id: 'relevancy DESC, name', name: t('params.relevancy'), priority: 999 },
@ -49,20 +50,17 @@ const orderWayList = ref([
const orderBySelected = ref('relevancy DESC, name');
const orderWaySelected = ref('ASC');
const resetCategory = () => {
const resetCategory = (params, search) => {
selectedCategoryFk.value = null;
typeList.value = null;
};
const clearFilter = (key) => {
if (key === 'categoryFk') {
resetCategory();
}
params.categoryFk = null;
params.typeFk = null;
search();
};
const selectCategory = (params, category, search) => {
if (params.categoryFk === category?.id) {
resetCategory();
resetCategory(params, search);
params.categoryFk = null;
} else {
selectedCategoryFk.value = category?.id;
@ -102,37 +100,28 @@ function exprBuilder(param, value) {
}
}
const applyTags = (params, search) => {
if (!tagValues.value?.length) {
const applyTags = (tagInfo, params, search) => {
if (!tagInfo || !tagInfo.values.length) {
params.tagGroups = null;
search();
toggleValueFilterDialog();
return;
}
const tagGroups = {
values: [...tagValues.value],
tagFk: selectedTag?.value?.id,
tagSelection: {
name: selectedTag?.value?.name,
},
};
params.tagGroups = tagGroups;
if (!params.tagGroups) params.tagGroups = [];
params.tagGroups.push(tagInfo);
search();
toggleValueFilterDialog();
};
const removeTagGroupParam = (params, search, valIndex = null) => {
if (!params.tagGroups) return;
if (!valIndex) {
params.tagGroups = null;
tagValues.value = [{}];
search();
} else {
(tagValues.value || []).splice(valIndex, 1);
params.tagGroups.values.splice(valIndex, 1);
params.tagGroups.splice(valIndex, 1);
search();
}
search();
};
const setCategoryList = (data) => {
@ -160,37 +149,13 @@ function addOrder(value, field, params) {
vnFilterPanelRef.value.search();
}
const getSelectedTagValues = async (tag) => {
try {
if (!tag?.id) return;
const filter = {
fields: ['value'],
order: 'value ASC',
limit: 30,
};
const url = `Tags/${tag?.id}/filterValue`;
console.log('url', url);
const params = { filter: JSON.stringify(filter) };
const { data } = await axios.get(url, {
params,
});
tagOptions.value = data;
} catch (err) {
console.error('Error getting selected tag values');
}
const toggleValueFilterDialog = () => {
showValueFilterDialog.value = !showValueFilterDialog.value;
};
onMounted(() => {
selectedCategoryFk.value = getParamWhere(route, 'categoryFk');
selectedTypeFk.value = getParamWhere(route, 'typeFk');
if (route.query.params && JSON.parse(route.query.params).tagGroups) {
const tagGroups = JSON.parse(route.query.params).tagGroups;
tagValues.value = [...tagGroups.values];
selectedTag.value = (props.tags || []).find(
(tag) => tag.name === tagGroups.tagSelection.name
);
}
});
</script>
@ -202,15 +167,11 @@ onMounted(() => {
:hidden-tags="['orderFk', 'orderBy']"
:un-removable-params="['orderFk', 'orderBy']"
:expr-builder="exprBuilder"
:custom-tags="['tagGroups']"
@remove="clearFilter"
:custom-tags="['tagGroups', 'categoryFk']"
:redirect="false"
>
<template #tags="{ tag, formatFn }">
<strong v-if="tag.label === 'categoryFk'">
{{ t(selectedCategory?.name || '') }}
</strong>
<strong v-else-if="tag.label === 'typeFk'">
<strong v-if="tag.label === 'typeFk'">
{{ t(selectedType?.name || '') }}
</strong>
<div v-else class="q-gutter-x-xs">
@ -219,24 +180,33 @@ onMounted(() => {
</div>
</template>
<template #customTags="{ tags: customTags, params, searchFn }">
<template v-for="tag in customTags" :key="tag.label">
<template v-if="tag.label === 'tagGroups'">
<VnFilterPanelChip
removable
@remove="removeTagGroupParam(params, searchFn)"
>
<strong class="q-mr-xs">
{{ tag.value?.tagSelection?.name }}:
</strong>
<span>
{{
(tag.value?.values || [])
.map((item) => `"${item.value}"`)
.join(', ')
}}
</span>
</VnFilterPanelChip>
</template>
<template v-for="customTag in customTags" :key="customTag.label">
<VnFilterPanelChip
v-for="(tag, valIndex) in Array.isArray(customTag.value)
? customTag.value
: 1"
:key="valIndex"
removable
@remove="
customTag.label === 'categoryFk'
? resetCategory(params, searchFn)
: removeTagGroupParam(params, searchFn, valIndex)
"
>
<strong v-if="customTag.label === 'categoryFk'">
jsegarra marked this conversation as resolved
Review

ufff 2 veces la misma comprobacion...

ufff 2 veces la misma comprobacion...
{{ t(selectedCategory?.name || '') }}
</strong>
<strong v-if="tag?.tagSelection?.name" class="q-mr-xs">
{{ tag.tagSelection.name }}:
</strong>
<span>
{{
(tag?.values || [])
.map((item) => `"${item.value}"`)
.join(', ')
}}
</span>
</VnFilterPanelChip>
</template>
</template>
<template #body="{ params, searchFn }">
@ -320,70 +290,43 @@ onMounted(() => {
</QItemSection>
</QItem>
<QSeparator />
<QItem class="q-mt-md">
<QItemSection>
<VnSelect
:label="t('params.tag')"
v-model="selectedTag"
:options="props.tags || []"
option-value="id"
option-label="name"
dense
outlined
rounded
:emit-value="false"
use-input
@update:model-value="($event) => getSelectedTagValues($event)"
/>
</QItemSection>
</QItem>
<QItem
v-for="(value, index) in tagValues"
:key="value"
class="q-mt-md filter-value"
>
<VnSelect
v-if="!selectedTag?.isFree && tagOptions"
:label="t('components.itemsFilterPanel.value')"
v-model="value.value"
:options="tagOptions || []"
option-value="value"
option-label="value"
dense
outlined
rounded
emit-value
use-input
:disable="!value"
:is-clearable="false"
@update:model-value="applyTags(params, searchFn)"
/>
<QItem class="q-mt-lg">
<VnInput
v-else
v-model="value.value"
:label="t('components.itemsFilterPanel.value')"
:disable="!value"
is-outlined
:is-clearable="false"
@keyup.enter="applyTags(params, searchFn)"
/>
<QIcon
name="delete"
class="filter-icon"
@click="removeTagGroupParam(params, searchFn, index)"
/>
</QItem>
<QItem class="q-mt-lg">
<QBtn
icon="add_circle"
shortcut="+"
flat
class="filter-icon"
size="md"
@click="tagValues.push({})"
/>
v-model="generalSearchParam"
@keyup.enter="
applyTags(
{ values: [{ value: generalSearchParam }] },
params,
searchFn
)
"
>
<template #prepend>
<QIcon name="search" />
</template>
<template #append>
<QBtn
icon="add_circle"
shortcut="+"
flat
color="primary"
size="md"
@click="toggleValueFilterDialog()"
/>
</template>
</VnInput>
</QItem>
<QSeparator />
<QDialog v-model="showValueFilterDialog">
jsegarra marked this conversation as resolved Outdated

Prueba con QPopupProxy mejor que dialogo porque así se abre en la misma región y no hay que mover tanto el ratón y vista.
También nos facilita copiar y pegar valores

Prueba con QPopupProxy mejor que dialogo porque así se abre en la misma región y no hay que mover tanto el ratón y vista. También nos facilita copiar y pegar valores

Coincido, QPopupProxy aplicado.

Commit: 52a2250acc

Coincido, `QPopupProxy` aplicado. Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/52a2250acc721f80a9a5e5d85dd4b9bad99ea1df
<CatalogFilterValueDialog
:tags="tags"
@apply-tags="($event) => applyTags($event, params, searchFn)"
/>
</QDialog>
</template>
</VnFilterPanel>
</template>
@ -416,23 +359,6 @@ onMounted(() => {
cursor: pointer;
}
}
.filter-icon {
font-size: 24px;
color: $primary;
padding: 0 4px;
cursor: pointer;
}
.filter-input {
flex-shrink: 1;
min-width: 0;
}
.filter-value {
display: flex;
align-items: center;
}
</style>
<i18n>