salix-front/src/pages/Order/Card/OrderCatalog.vue

174 lines
4.9 KiB
Vue

<script setup>
import { useStateStore } from 'stores/useStateStore';
import { useRoute, useRouter } from 'vue-router';
import { onMounted, ref, 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 { useArrayData } from 'src/composables/useArrayData';
import RightMenu from 'src/components/common/RightMenu.vue';
import { onUnmounted } from 'vue';
const route = useRoute();
const router = useRouter();
const stateStore = useStateStore();
const { t } = useI18n();
const dataKey = 'OrderCatalogList';
const catalogParams = {
orderFk: route.params.id,
orderBy: JSON.stringify({ field: 'relevancy DESC, name', way: 'ASC', isTag: false }),
};
const arrayData = useArrayData(dataKey, {
url: 'Orders/CatalogFilter',
userParams: catalogParams,
exprBuilder,
searchUrl: 'table',
});
const store = arrayData.store;
const tags = ref([]);
const itemRefs = ref({});
onMounted(async () => {
stateStore.rightDrawer = true;
checkOrderConfirmation();
if (
arrayData.store.userParams &&
Object.keys(arrayData.store.userParams).some((key) => !key.startsWith('order'))
) {
await arrayData.fetch({});
}
});
onUnmounted(() => {
arrayData.destroy();
});
function exprBuilder(param, value) {
switch (param) {
case 'categoryFk':
case 'typeFk':
return { [param]: value };
case 'search':
if (/^\d+$/.test(value)) return { 'i.id': value };
else return { 'i.name': { like: `%${value}%` } };
}
}
async function checkOrderConfirmation() {
const response = await axios.get(`Orders/${route.params.id}`);
if (response.data.isConfirmed === 1) {
router.push(`/order/${route.params.id}/line`);
}
}
function extractTags(items) {
if (!items || !items.length) return;
const resultTags = [];
(items || []).forEach((item) => {
(item.tags || []).forEach((tag) => {
const index = resultTags.findIndex((item) => item.tagFk === tag.tagFk);
if (index === -1) {
resultTags.push({ ...tag, priority: 1 });
} else {
resultTags[index].priority += 1;
}
});
});
tags.value = resultTags;
extractValueTags(items);
}
const tagValue = ref([]);
function extractValueTags(items) {
const resultValueTags = items.flatMap((x) =>
Object.keys(x)
.filter((k) => /^value\d+$/.test(k))
.map((v) => x[v])
.filter((v) => v)
.sort(),
);
tagValue.value = resultValueTags;
}
watch(
() => store.data,
(val) => {
extractTags(val);
},
{ immediate: true },
);
</script>
<template>
<Teleport to="#section-searchbar" v-if="stateStore.isHeaderMounted()">
<VnSearchbar
:data-key="dataKey"
:redirect="false"
:label="t('Search items')"
:info="t('You can search items by name or id')"
:search-remove-params="false"
/>
</Teleport>
<RightMenu>
<template #right-panel>
<OrderCatalogFilter
:data-key="dataKey"
:tag-value="tagValue"
:tags="tags"
:initial-catalog-params="catalogParams"
:arrayData
/>
</template>
</RightMenu>
<QPage class="column items-center q-pa-md" data-cy="orderCatalogPage">
<div class="full-width">
<VnPaginate :data-key="dataKey">
<template #body="{ rows }">
<div class="catalog-list">
<div v-if="rows && !rows?.length" class="no-result">
{{ t('globals.noResults') }}
</div>
<CatalogItem
v-for="row in rows"
:key="row.id"
:ref="(el) => (itemRefs[row.id] = el)"
:item="row"
is-catalog
class="fill-icon"
data-cy="orderCatalogItem"
/>
</div>
</template>
</VnPaginate>
</div>
</QPage>
</template>
<style lang="scss" scoped>
.catalog-list {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
justify-content: center;
gap: 16px;
}
.no-result {
font-size: 24px;
font-weight: bold;
color: var(--vn-label-color);
text-align: center;
}
</style>
<i18n>
es:
You can search items by name or id: Puedes buscar items por nombre o id
Search items: Buscar artículos
</i18n>