0
0
Fork 0

create travel filters and integrate

This commit is contained in:
William Buezas 2023-11-27 12:49:19 -03:00
parent df599f1e8d
commit 7e22a2924e
4 changed files with 415 additions and 5 deletions

View File

@ -7,6 +7,13 @@
* @param {Object} optionsToFilter - Objeto que contiene las opciones originales y filtradas. * @param {Object} optionsToFilter - Objeto que contiene las opciones originales y filtradas.
*/ */
function normalizeString(text) {
return text
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '');
}
export function inputSelectFilter(val, update, abort, optionsToFilter) { export function inputSelectFilter(val, update, abort, optionsToFilter) {
if (val === '') { if (val === '') {
update(() => { update(() => {
@ -20,7 +27,7 @@ export function inputSelectFilter(val, update, abort, optionsToFilter) {
update(() => { update(() => {
const searchQuery = val.toLowerCase(); const searchQuery = val.toLowerCase();
optionsToFilter.filtered = optionsToFilter.original.filter((option) => optionsToFilter.filtered = optionsToFilter.original.filter((option) =>
option.label.toLowerCase().includes(searchQuery) normalizeString(option.label).includes(normalizeString(searchQuery))
); );
}); });
} }

View File

@ -41,8 +41,8 @@ const cloneTravel = () => {
const headerMenuOptions = [ const headerMenuOptions = [
{ name: t('travel.summary.cloneShipping'), action: cloneTravel }, { name: t('travel.summary.cloneShipping'), action: cloneTravel },
{ name: t('travel.summary.CloneTravelAndEntries'), action: cloneTravel }, { name: t('travel.summary.CloneTravelAndEntries'), action: null },
{ name: t('travel.summary.AddEntry'), action: cloneTravel }, { name: t('travel.summary.AddEntry'), action: null },
]; ];
const tableColumnComponents = { const tableColumnComponents = {
@ -56,34 +56,42 @@ const tableColumnComponents = {
id: { id: {
component: () => 'span', component: () => 'span',
props: () => {}, props: () => {},
event: () => openEntryDescriptor(),
}, },
supplierName: { supplierName: {
component: () => 'span', component: () => 'span',
props: () => {}, props: () => {},
event: () => {},
}, },
reference: { reference: {
component: () => 'span', component: () => 'span',
props: () => {}, props: () => {},
event: () => {},
}, },
freightValue: { freightValue: {
component: () => 'span', component: () => 'span',
props: () => {}, props: () => {},
event: () => {},
}, },
packageValue: { packageValue: {
component: () => 'span', component: () => 'span',
props: () => {}, props: () => {},
event: () => {},
}, },
cc: { cc: {
component: () => 'span', component: () => 'span',
props: () => {}, props: () => {},
event: () => {},
}, },
pallet: { pallet: {
component: () => 'span', component: () => 'span',
props: () => {}, props: () => {},
event: () => {},
}, },
m3: { m3: {
component: () => 'span', component: () => 'span',
props: () => {}, props: () => {},
event: () => {},
}, },
observation: { observation: {
component: (props) => (props.value ? QIcon : null), component: (props) => (props.value ? QIcon : null),
@ -164,6 +172,8 @@ async function setTravelData(data) {
const redirectToCreateView = (queryParams) => { const redirectToCreateView = (queryParams) => {
router.push({ name: 'TravelCreate', query: { travelData: queryParams } }); router.push({ name: 'TravelCreate', query: { travelData: queryParams } });
}; };
const openEntryDescriptor = () => {};
</script> </script>
<template> <template>

View File

@ -0,0 +1,380 @@
<script setup>
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import { inputSelectFilter } from 'src/composables/inputSelectFilterFn.js';
import FetchData from 'components/FetchData.vue';
import { toDate } from 'src/filters';
const { t } = useI18n();
const props = defineProps({
dataKey: {
type: String,
required: true,
},
});
const warehousesOptions = reactive({
original: [],
filtered: [],
});
const continentsOptions = reactive({
original: [],
filtered: [],
});
const agenciesOptions = reactive({
original: [],
filtered: [],
});
const onFetchWarehouses = (warehouses) => {
warehousesOptions.original = warehouses.map((warehouse) => {
return { value: warehouse.id, label: warehouse.name };
});
};
const onFetchContinents = (continents) => {
continentsOptions.original = continents.map((continent) => {
return { value: continent.code, label: continent.name };
});
};
const onFetchAgencies = (agencies) => {
agenciesOptions.original = agencies.map((agency) => {
return { value: agency.agencyFk, label: agency.name };
});
};
const add = (paramsObj, key) => {
if (paramsObj[key] === undefined) {
paramsObj[key] = 1;
} else {
paramsObj[key]++;
}
};
const decrement = (paramsObj, key) => {
if (paramsObj[key] === 0) return;
paramsObj[key]--;
};
</script>
<template>
<FetchData url="Warehouses" @on-fetch="(data) => onFetchWarehouses(data)" auto-load />
<FetchData url="Continents" @on-fetch="(data) => onFetchContinents(data)" auto-load />
<FetchData url="AgencyModes" @on-fetch="(data) => onFetchAgencies(data)" auto-load />
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
<template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span>
</div>
</template>
<!-- searchFn -->
<template #body="{ params }">
<QList dense>
<QItem class="q-my-sm">
<QItemSection>
<QInput
:label="t('params.search')"
dense
lazy-rules
outlined
rounded
v-model="params.search"
/>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<QSelect
:label="t('params.agencyModeFk')"
:options="agenciesOptions.filtered"
use-input
option-value="value"
option-label="label"
emit-value
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense
lazy-rules
outlined
rounded
@filter="
(val, update, abort) =>
inputSelectFilter(val, update, abort, agenciesOptions)
"
v-model="params.agencyModeFk"
/>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<QSelect
:label="t('travel.shared.wareHouseOut')"
:options="warehousesOptions.filtered"
use-input
option-value="value"
option-label="label"
emit-value
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense
lazy-rules
outlined
rounded
@filter="
(val, update, abort) =>
inputSelectFilter(
val,
update,
abort,
warehousesOptions
)
"
v-model="params.warehouseOutFk"
/>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<QSelect
:label="t('params.wareHouseIn')"
:options="warehousesOptions.filtered"
use-input
option-value="value"
option-label="label"
emit-value
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense
lazy-rules
outlined
rounded
@filter="
(val, update, abort) =>
inputSelectFilter(
val,
update,
abort,
warehousesOptions
)
"
v-model="params.warehouseInFk"
/>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<QInput
v-model="params.scopeDays"
type="number"
:label="t('params.scopeDays')"
dense
lazy-rules
outlined
rounded
class="input-number"
>
<template #append>
<QBtn
icon="add"
flat
dense
size="12px"
@click="add(params, 'scopeDays')"
/>
<QBtn
icon="remove"
flat
dense
size="12px"
@click="decrement(params, 'scopeDays')"
/>
</template>
</QInput>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<QInput
dense
lazy-rules
outlined
rounded
placeholder="dd-mm-aaa"
:label="t('params.landedFrom')"
:model-value="toDate(params.landedFrom)"
>
<template #append>
<QIcon name="event" class="cursor-pointer">
<QPopupProxy
cover
transition-show="scale"
transition-hide="scale"
>
<QDate v-model="params.landedFrom">
<div class="row items-center justify-end">
<QBtn
v-close-popup
label="Close"
color="primary"
flat
/>
</div>
</QDate>
</QPopupProxy>
</QIcon>
</template>
</QInput>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<QInput
dense
lazy-rules
outlined
rounded
placeholder="dd-mm-aaa"
:model-value="toDate(params.landedTo)"
:label="t('params.landedTo')"
>
<template #append>
<QIcon name="event" class="cursor-pointer">
<QPopupProxy
cover
transition-show="scale"
transition-hide="scale"
>
<QDate v-model="params.landedTo">
<div class="row items-center justify-end">
<QBtn
v-close-popup
label="Close"
color="primary"
flat
/>
</div>
</QDate>
</QPopupProxy>
</QIcon>
</template>
</QInput>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<QSelect
:label="t('params.continent')"
:options="continentsOptions.filtered"
use-input
option-value="value"
option-label="label"
emit-value
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense
lazy-rules
outlined
rounded
@filter="
(val, update, abort) =>
inputSelectFilter(
val,
update,
abort,
continentsOptions
)
"
v-model="params.continent"
/>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<QInput
v-model="params.totalEntries"
type="number"
:label="t('params.totalEntries')"
dense
lazy-rules
outlined
rounded
min="0"
class="input-number"
>
<template #append>
<QBtn
icon="add"
flat
dense
size="12px"
@click="add(params, 'totalEntries')"
/>
<QBtn
icon="remove"
flat
dense
size="12px"
@click="decrement(params, 'totalEntries')"
/>
</template>
</QInput>
</QItemSection>
</QItem>
</QList>
</template>
</VnFilterPanel>
</template>
<style scoped>
.input-number >>> input[type='number'] {
-moz-appearance: textfield;
}
.input-number >>> input::-webkit-outer-spin-button,
.input-number >>> input::-webkit-inner-spin-button {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
}
</style>
<i18n>
{
"en": {
"params": {
"search": "Id/Reference",
"agencyModeFk": "Agency",
"wareHouseIn": "Warehouse In",
"wareHouseOut": "Warehouse Out",
"scopeDays": "Days onward",
"landedFrom": "Landed from",
"landedTo": "Landed to",
"continent": "Continent out",
"totalEntries": "Total entries"
},
},
"es": {
"params":{
"search": "Id/Referencia",
"agencyModeFk": "Agencia",
"wareHouseIn": "Alm. entrada",
"wareHouseOut": "Alm. salida",
"scopeDays": "Días adelante",
"landedFrom": "Llegada desde",
"landedTo": "Llegada hasta",
"continent": "Cont. Salida",
"totalEntries": "Ent. totales"
},
}
}
</i18n>

View File

@ -10,11 +10,14 @@ import VnLv from 'src/components/ui/VnLv.vue';
import TravelSummaryDialog from './Card/TravelSummaryDialog.vue'; import TravelSummaryDialog from './Card/TravelSummaryDialog.vue';
import { useTravelStore } from 'src/stores/travel.js'; import { useTravelStore } from 'src/stores/travel.js';
import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import { useStateStore } from 'stores/useStateStore';
import TravelFilter from './TravelFilter.vue';
const router = useRouter(); const router = useRouter();
const travelStore = useTravelStore(); const travelStore = useTravelStore();
const quasar = useQuasar(); const quasar = useQuasar();
const { t } = useI18n(); const { t } = useI18n();
const stateStore = useStateStore();
const navigateToTravelId = (id) => { const navigateToTravelId = (id) => {
router.push({ path: `/travel/${id}` }); router.push({ path: `/travel/${id}` });
@ -22,7 +25,6 @@ const navigateToTravelId = (id) => {
const cloneTravel = (travelData) => { const cloneTravel = (travelData) => {
const stringifiedTravelData = JSON.stringify(travelData); const stringifiedTravelData = JSON.stringify(travelData);
console.log('clone data:: ', stringifiedTravelData);
redirectToCreateView(stringifiedTravelData); redirectToCreateView(stringifiedTravelData);
}; };
@ -41,13 +43,24 @@ const viewSummary = (id) => {
onMounted(async () => { onMounted(async () => {
await travelStore.init(); await travelStore.init();
stateStore.rightDrawer = true;
}); });
</script> </script>
<template> <template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8">
<TravelFilter data-key="TravelList" />
</QScrollArea>
</QDrawer>
<QPage class="column items-center q-pa-md"> <QPage class="column items-center q-pa-md">
<div class="card-list"> <div class="card-list">
<VnPaginate data-key="SuppliersList" url="Travels/filter" auto-load> <VnPaginate
data-key="TravelList"
url="Travels/filter"
auto-load
order="shipped DESC, landed DESC"
>
<template #body="{ rows }"> <template #body="{ rows }">
<CardList2 <CardList2
v-for="row of rows" v-for="row of rows"