feat: refs #8664 add CmrFilter component and integrate it into CmrList for enhanced filtering options

This commit is contained in:
Jose Antonio Tubau 2025-02-25 13:21:47 +01:00
parent 566e4f0e13
commit ccda0a53c0
2 changed files with 209 additions and 63 deletions

View File

@ -0,0 +1,128 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnInput from 'components/common/VnInput.vue';
import FetchData from 'src/components/FetchData.vue';
const { t } = useI18n();
const props = defineProps({
dataKey: {
type: String,
required: true,
},
});
const countriesOptions = ref([]);
</script>
<template>
<FetchData
url="Countries"
auto-load
@on-fetch="(data) => (countriesOptions = data)"
/>
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
<template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs">
<strong>{{ t(`route.cmr.params.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span>
</div>
</template>
<template #body="{ params, searchFn }">
<QItem class="q-my-sm">
<QItemSection>
<VnInput
v-model="params.cmrFk"
type="number"
:label="t('route.cmr.params.cmrFk')"
is-outlined
clearable
/>
</QItemSection>
</QItem>
<QCheckbox
:label="t('route.cmr.params.hasCmrDms')"
v-model="params.hasCmrDms"
@update:model-value="searchFn()"
toggle-indeterminate
/>
<QItem class="q-my-sm">
<QItemSection>
<VnInput
v-model="params.ticketFk"
type="number"
:label="t('route.cmr.params.ticketFk')"
is-outlined
clearable
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInput
v-model="params.routeFk"
type="number"
:label="t('route.cmr.params.routeFk')"
is-outlined
clearable
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInput
v-model="params.clientFk"
type="number"
:label="t('route.cmr.params.clientFk')"
is-outlined
clearable
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnSelect
:label="t('route.cmr.params.countryFk')"
v-model="params.countryFk"
@update:model-value="searchFn()"
:options="countriesOptions"
option-value="id"
option-label="name"
dense
outlined
rounded
:input-debounce="0"
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInputDate
v-model="params.shipped"
:label="t('route.cmr.params.shipped')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnSelect
:label="t('route.cmr.params.warehouseFk')"
v-model="params.warehouseFk"
@update:model-value="searchFn()"
url="warehouses"
option-value="id"
option-label="name"
dense
outlined
rounded
:input-debounce="0"
/>
</QItemSection>
</QItem>
</template>
</VnFilterPanel>
</template>

View File

@ -1,29 +1,30 @@
<script setup>
import { onBeforeMount, onMounted, computed, ref } from 'vue';
import { onMounted, computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar';
import { useSession } from 'src/composables/useSession';
import { toDateHourMin } from 'filters/index';
import { useStateStore } from 'src/stores/useStateStore';
import axios from 'axios';
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import CmrFilter from './CmrFilter.vue';
import VnSection from 'src/components/common/VnSection.vue';
const { t } = useI18n();
const { getTokenMultimedia } = useSession();
const token = getTokenMultimedia();
const state = useStateStore();
const warehouses = ref([]);
const selectedRows = ref([]);
const dataKey = 'CmrList';
const columns = computed(() => [
{
align: 'left',
name: 'cmrFk',
label: t('route.cmr.list.cmrFk'),
label: t('route.cmr.params.cmrFk'),
chip: {
condition: () => true,
},
@ -32,62 +33,69 @@ const columns = computed(() => [
{
align: 'center',
name: 'hasCmrDms',
label: t('route.cmr.list.hasCmrDms'),
label: t('route.cmr.params.hasCmrDms'),
component: 'checkbox',
cardVisible: true,
},
{
align: 'left',
label: t('route.cmr.list.ticketFk'),
label: t('route.cmr.params.ticketFk'),
name: 'ticketFk',
},
{
align: 'left',
label: t('route.cmr.list.routeFk'),
label: t('route.cmr.params.routeFk'),
name: 'routeFk',
},
{
align: 'left',
label: t('route.cmr.list.clientFk'),
label: t('route.cmr.params.clientFk'),
name: 'clientFk',
},
{
align: 'right',
label: t('route.cmr.list.country'),
label: t('route.cmr.params.countryFk'),
name: 'countryFk',
cardVisible: true,
component: 'select',
attrs: {
url: 'countries',
fields: ['id', 'name'],
optionLabel: 'name',
optionValue: 'id',
},
columnFilter: {
inWhere: true,
component: 'select',
name: 'countryFk',
attrs: {
url: 'countries',
fields: ['id', 'name'],
},
},
format: ({ countryName }) => countryName,
},
{
align: 'right',
label: t('route.cmr.list.shipped'),
label: t('route.cmr.params.shipped'),
name: 'shipped',
cardVisible: true,
component: 'date',
columnFilter: {
component: 'date',
inWhere: true,
},
format: ({ shipped }) => toDateHourMin(shipped),
},
{
align: 'right',
label: t('route.cmr.params.warehouseFk'),
name: 'warehouseFk',
label: t('globals.warehouse'),
columnFilter: {
component: 'select',
},
component: 'select',
attrs: {
options: warehouses.value,
url: 'warehouses',
fields: ['id', 'name'],
},
columnFilter: {
name: 'warehouseFk',
attrs: {
url: 'warehouses',
fields: ['id', 'name'],
},
},
format: ({ warehouseName }) => warehouseName,
},
@ -96,7 +104,7 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
title: t('Ver cmr'),
title: t('route.cmr.params.viewCmr'),
icon: 'visibility',
isPrimary: true,
action: (row) => window.open(getCmrUrl(row?.cmrFk), '_blank'),
@ -105,11 +113,6 @@ const columns = computed(() => [
},
]);
onBeforeMount(async () => {
const { data } = await axios.get('Warehouses');
warehouses.value = data;
});
onMounted(() => (state.rightDrawer = true));
function getApiUrl() {
@ -133,45 +136,60 @@ function downloadPdfs() {
}
</script>
<template>
<VnSubToolbar>
<template #st-actions>
<QBtn
icon="cloud_download"
color="primary"
class="q-mr-sm"
:disable="!selectedRows?.length"
@click="downloadPdfs"
>
<QTooltip>{{ t('route.cmr.list.downloadCmrs') }}</QTooltip>
</QBtn>
</template>
</VnSubToolbar>
<VnTable
ref="tableRef"
data-key="CmrList"
url="Cmrs/filter"
<VnSection
:data-key
:columns="columns"
:right-search="true"
default-mode="table"
v-model:selected="selectedRows"
table-height="85vh"
:table="{
'row-key': 'cmrFk',
selection: 'multiple',
prefix="route.cmr"
:right-filter="true"
:array-data-props="{
url: 'Cmrs/filter',
}"
:disable-option="{ card: true }"
>
<template #column-ticketFk="{ row }">
<span class="link" @click.stop>
{{ row.ticketFk }}
<TicketDescriptorProxy :id="row.ticketFk" />
</span>
<template #advanced-menu>
<CmrFilter :data-key />
</template>
<template #column-clientFk="{ row }">
<span class="link" @click.stop>
{{ row.clientFk }}
<CustomerDescriptorProxy :id="row.clientFk" />
</span>
<template #body>
<VnSubToolbar>
<template #st-actions>
<QBtn
icon="cloud_download"
color="primary"
class="q-mr-sm"
:disable="!selectedRows?.length"
@click="downloadPdfs"
>
<QTooltip>{{ t('route.cmr.params.downloadCmrs') }}</QTooltip>
</QBtn>
</template>
</VnSubToolbar>
<VnTable
ref="tableRef"
:data-key
url="Cmrs/filter"
:columns="columns"
:right-search="false"
default-mode="table"
v-model:selected="selectedRows"
table-height="85vh"
:table="{
'row-key': 'cmrFk',
selection: 'multiple',
}"
:disable-option="{ card: true }"
>
<template #column-ticketFk="{ row }">
<span class="link" @click.stop>
{{ row.ticketFk }}
<TicketDescriptorProxy :id="row.ticketFk" />
</span>
</template>
<template #column-clientFk="{ row }">
<span class="link" @click.stop>
{{ row.clientFk }}
<CustomerDescriptorProxy :id="row.clientFk" />
</span>
</template>
</VnTable>
</template>
</VnTable>
</VnSection>
</template>