Merge pull request 'Implementacion de shelvings' (#23) from feature/shelving into dev

Reviewed-on: hyervoni/salix-front-mindshore#23
This commit is contained in:
Kevin Martinez 2023-12-01 11:28:51 +00:00
commit f040037f8f
19 changed files with 211 additions and 97 deletions

View File

@ -19,6 +19,18 @@ const props = defineProps({
type: String, type: String,
default: null, default: null,
}, },
url: {
type: String,
default: null,
},
mapper: {
type: Function,
default: null,
},
filter: {
type: Object,
default: null,
}
}); });
const columns = [ const columns = [
@ -65,17 +77,18 @@ function actionColor(action) {
<template> <template>
<div class="column items-center"> <div class="column items-center">
<QTimeline class="q-pa-md"> <QTimeline class="q-pa-md">
<QTimelineEntry heading tag="h4"> {{ t('Audit logs') }} </QTimelineEntry> <QTimelineEntry heading tag="h4"> {{ t('Audit logs') }}</QTimelineEntry>
<VnPaginate <VnPaginate
:data-key="`${props.model}Logs`" :data-key="`${props.model}Logs`"
:url="`${props.model}s/${route.params.id}/logs`" :url="props.url ?? `${props.model}s/${route.params.id}/logs`"
order="id DESC" order="id DESC"
:offset="100" :offset="100"
:limit="5" :limit="5"
:filter="props.filter"
auto-load auto-load
> >
<template #body="{ rows }"> <template #body="{ rows }">
<template v-for="log of rows" :key="log.id"> <template v-for="log of (props.mapper ? (rows || []).map(props.mapper) :rows)" :key="log.id">
<QTimelineEntry <QTimelineEntry
:avatar="`/api/Images/user/160x160/${log.userFk}/download?access_token=${token}`" :avatar="`/api/Images/user/160x160/${log.userFk}/download?access_token=${token}`"
> >
@ -144,65 +157,67 @@ function actionColor(action) {
</style> </style>
<i18n> <i18n>
en: en:
actions: actions:
insert: Creates insert: Creates
update: Updates update: Updates
delete: Deletes delete: Deletes
models: models:
Claim: Claim Claim: Claim
ClaimDms: Document ClaimDms: Document
ClaimBeginning: Claimed Sales ClaimBeginning: Claimed Sales
ClaimObservation: Observation ClaimObservation: Observation
properties: Shelving: Shelving
id: ID properties:
claimFk: Claim ID id: ID
saleFk: Sale ID claimFk: Claim ID
quantity: Quantity saleFk: Sale ID
observation: Observation quantity: Quantity
ticketCreated: Created observation: Observation
created: Created ticketCreated: Created
isChargedToMana: Charged to mana created: Created
hasToPickUp: Has to pick Up isChargedToMana: Charged to mana
dmsFk: Document ID hasToPickUp: Has to pick Up
text: Description dmsFk: Document ID
claimStateFk: Claim State text: Description
workerFk: Worker claimStateFk: Claim State
clientFk: Customer workerFk: Worker
rma: RMA clientFk: Customer
responsibility: Responsibility rma: RMA
packages: Packages responsibility: Responsibility
packages: Packages
es: es:
Audit logs: Registros de auditoría Audit logs: Registros de auditoría
Property: Propiedad Property: Propiedad
Before: Antes Before: Antes
After: Después After: Después
Yes: Si Yes: Si
Nothing: Nada Nothing: Nada
actions: actions:
insert: Crea insert: Crea
update: Actualiza update: Actualiza
delete: Elimina delete: Elimina
models: models:
Claim: Reclamación Claim: Reclamación
ClaimDms: Documento ClaimDms: Documento
ClaimBeginning: Línea reclamada ClaimBeginning: Línea reclamada
ClaimObservation: Observación ClaimObservation: Observación
properties: Shelving: Carro
id: ID properties:
claimFk: ID reclamación id: ID
saleFk: ID linea de venta claimFk: ID reclamación
quantity: Cantidad saleFk: ID linea de venta
observation: Observación quantity: Cantidad
ticketCreated: Creado observation: Observación
created: Creado ticketCreated: Creado
isChargedToMana: Cargado a maná created: Creado
hasToPickUp: Se debe recoger isChargedToMana: Cargado a maná
dmsFk: ID documento hasToPickUp: Se debe recoger
text: Descripción dmsFk: ID documento
claimStateFk: Estado de la reclamación text: Descripción
workerFk: Trabajador claimStateFk: Estado de la reclamación
clientFk: Cliente workerFk: Trabajador
rma: RMA clientFk: Cliente
responsibility: Responsabilidad rma: RMA
packages: Bultos responsibility: Responsabilidad
packages: Bultos
</i18n> </i18n>

View File

@ -26,7 +26,7 @@ const props = defineProps({
}, },
}); });
const emit = defineEmits(['refresh', 'clear']); const emit = defineEmits(['refresh', 'clear', 'search']);
const arrayData = useArrayData(props.dataKey); const arrayData = useArrayData(props.dataKey);
const store = arrayData.store; const store = arrayData.store;
@ -49,6 +49,7 @@ async function search() {
if (!props.showAll && !Object.values(params).length) store.data = []; if (!props.showAll && !Object.values(params).length) store.data = [];
isLoading.value = false; isLoading.value = false;
emit('search');
} }
async function reload() { async function reload() {

View File

@ -149,13 +149,13 @@ export function useArrayData(key, userOptions) {
return { filter, params }; return { filter, params };
} }
function sanitizerParams(params) { function sanitizerParams(params, exprBuilder) {
for (const param in params) { for (const param in params) {
if (params[param] === '' || params[param] === null) { if (params[param] === '' || params[param] === null) {
delete store.userParams[param]; delete store.userParams[param];
delete params[param]; delete params[param];
if (store.filter?.where) { if (store.filter?.where) {
delete store.filter.where[Object.keys(store?.exprBuilder(param))[0]]; delete store.filter.where[Object.keys(exprBuilder ? exprBuilder(param) : param)[0]];
if (Object.keys(store.filter.where).length === 0) { if (Object.keys(store.filter.where).length === 0) {
delete store.filter.where; delete store.filter.where;
} }

View File

@ -439,6 +439,7 @@ export default {
create: 'Create', create: 'Create',
summary: 'Summary', summary: 'Summary',
basicData: 'Basic Data', basicData: 'Basic Data',
log: 'Logs'
}, },
list: { list: {
parking: 'Parking', parking: 'Parking',

View File

@ -441,6 +441,7 @@ export default {
create: 'Crear', create: 'Crear',
summary: 'Resumen', summary: 'Resumen',
basicData: 'Datos básicos', basicData: 'Datos básicos',
log: 'Registros de auditoría'
}, },
list: { list: {
parking: 'Parking', parking: 'Parking',

View File

@ -1,15 +1,11 @@
<script setup> <script setup>
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import LeftMenu from 'components/LeftMenu.vue'; import LeftMenu from 'components/LeftMenu.vue';
import ShelvingSearchbar from "pages/Shelving/components/ShelvingSearchbar.vue"; import ShelvingDescriptor from 'pages/Shelving/Card/ShelvingDescriptor.vue';
import ShelvingDescriptor from "pages/Shelving/components/ShelvingDescriptor.vue";
const stateStore = useStateStore(); const stateStore = useStateStore();
</script> </script>
<template> <template>
<Teleport to="#searchbar" v-if="stateStore.isHeaderMounted()">
<ShelvingSearchbar />
</Teleport>
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
<QScrollArea class="fit"> <QScrollArea class="fit">
<ShelvingDescriptor /> <ShelvingDescriptor />

View File

@ -3,10 +3,10 @@ import { ref, computed } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import CardDescriptor from 'components/ui/CardDescriptor.vue'; import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'components/ui/VnLv.vue';
import useCardDescription from 'src/composables/useCardDescription'; import useCardDescription from 'composables/useCardDescription';
import WorkerDescriptorProxy from "pages/Worker/Card/WorkerDescriptorProxy.vue"; import WorkerDescriptorProxy from "pages/Worker/Card/WorkerDescriptorProxy.vue";
import ShelvingDescriptorMenu from "pages/Shelving/components/ShelvingDescriptorMenu.vue"; import ShelvingDescriptorMenu from "pages/Shelving/Card/ShelvingDescriptorMenu.vue";
const $props = defineProps({ const $props = defineProps({
id: { id: {

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import ShelvingDescriptor from "pages/Shelving/components/ShelvingDescriptor.vue"; import ShelvingDescriptor from "pages/Shelving/Card/ShelvingDescriptor.vue";
const $props = defineProps({ const $props = defineProps({
id: { id: {

View File

@ -12,6 +12,8 @@ const props = defineProps({
}, },
}); });
const emit = defineEmits(['search']);
const workers = ref(); const workers = ref();
const parkings = ref(); const parkings = ref();
@ -39,7 +41,7 @@ function setParkings(data) {
@on-fetch="setWorkers" @on-fetch="setWorkers"
auto-load auto-load
/> />
<VnFilterPanel :data-key="props.dataKey" :search-button="true"> <VnFilterPanel :data-key="props.dataKey" :search-button="true" @search="emit('search')">
<template #tags="{ tag, formatFn }"> <template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs"> <div class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong> <strong>{{ t(`params.${tag.label}`) }}: </strong>

View File

@ -0,0 +1,53 @@
<script setup>
import VnLog from 'src/components/common/VnLog.vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const getChanges = (oldInstance, newInstance) => {
const changes = [];
Object.entries(newInstance).forEach(([key, newValue]) => {
const oldValue = oldInstance?.[key];
if (oldValue !== newValue) {
changes.push({
property: key,
before: oldValue,
after: newValue,
});
}
});
return changes;
};
const shelvingMapper = (shelving) => ({
...shelving,
action: shelving.action,
created: shelving.creationDate,
model: shelving.changedModel,
userFk: shelving.userFk,
userName: shelving.user?.name,
changes: getChanges(shelving.oldInstance, shelving.newInstance),
});
const shelvingFilter = {
include: [
{
relation: 'user',
scope: {
fields: ['nickname', 'name'],
},
},
],
where: {
originFk: route.params.id,
},
};
</script>
<template>
<VnLog
model="Shelving"
url="/ShelvingLogs"
:mapper="shelvingMapper"
:filter="shelvingFilter"
></VnLog>
</template>

View File

@ -1,9 +1,11 @@
<script setup> <script setup>
import { computed } from 'vue'; import {computed, onMounted, onUnmounted} from 'vue';
import { useRoute } from 'vue-router'; import {useRoute, useRouter} from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import CardSummary from 'components/ui/CardSummary.vue'; import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'components/ui/VnLv.vue';
import ShelvingFilter from 'pages/Shelving/Card/ShelvingFilter.vue';
import { useStateStore } from 'stores/useStateStore';
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -12,7 +14,11 @@ const $props = defineProps({
}, },
}); });
const route = useRoute(); const route = useRoute();
const stateStore = useStateStore();
const router = useRouter();
const { t } = useI18n(); const { t } = useI18n();
onMounted(() => (stateStore.rightDrawer = false));
onUnmounted(() => (stateStore.rightDrawer = false));
const entityId = computed(() => $props.id || route.params.id); const entityId = computed(() => $props.id || route.params.id);
const filter = { const filter = {
@ -33,6 +39,23 @@ const filter = {
</script> </script>
<template> <template>
<template v-if="stateStore.isHeaderMounted()">
<Teleport to="#actions-append">
<div class="row q-gutter-x-sm">
<QBtn
flat
@click="stateStore.toggleRightDrawer()"
round
dense
icon="menu"
>
<QTooltip bottom anchor="bottom right">
{{ t('globals.collapseMenu') }}
</QTooltip>
</QBtn>
</div>
</Teleport>
</template>
<CardSummary ref="summary" :url="`Shelvings/${entityId}`" :filter="filter"> <CardSummary ref="summary" :url="`Shelvings/${entityId}`" :filter="filter">
<template #header="{ entity }"> <template #header="{ entity }">
<div>{{ entity.code }}</div> <div>{{ entity.code }}</div>
@ -42,18 +65,12 @@ const filter = {
<div class="header"> <div class="header">
{{ t('shelving.pageTitles.basicData') }} {{ t('shelving.pageTitles.basicData') }}
</div> </div>
<VnLv <VnLv :label="t('shelving.summary.code')" :value="entity.code" />
:label="t('shelving.summary.code')"
:value="entity.code"
/>
<VnLv <VnLv
:label="t('shelving.summary.parking')" :label="t('shelving.summary.parking')"
:value="entity.parking?.code" :value="entity.parking?.code"
/> />
<VnLv <VnLv :label="t('shelving.summary.priority')" :value="entity.priority" />
:label="t('shelving.summary.priority')"
:value="entity.priority"
/>
<VnLv <VnLv
:label="t('shelving.summary.worker')" :label="t('shelving.summary.worker')"
:value="entity.worker?.user?.nickname" :value="entity.worker?.user?.nickname"
@ -65,4 +82,12 @@ const filter = {
</QCard> </QCard>
</template> </template>
</CardSummary> </CardSummary>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8">
<ShelvingFilter
data-key="ShelvingList"
@search="router.push({ name: 'ShelvingList' })"
/>
</QScrollArea>
</QDrawer>
</template> </template>

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import { useDialogPluginComponent } from 'quasar'; import { useDialogPluginComponent } from 'quasar';
import ShelvingSummary from "pages/Shelving/Summary/ShelvingSummary.vue"; import ShelvingSummary from "pages/Shelving/Card/ShelvingSummary.vue";
const $props = defineProps({ const $props = defineProps({
id: { id: {

View File

@ -1,7 +1,7 @@
<script setup> <script setup>
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import FormModel from 'components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
import ShelvingForm from "pages/Shelving/components/ShelvingForm.vue"; import ShelvingForm from "pages/Shelving/Card/ShelvingForm.vue";
const route = useRoute(); const route = useRoute();

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import ShelvingForm from 'pages/Shelving/components/ShelvingForm.vue'; import ShelvingForm from 'pages/Shelving/Card/ShelvingForm.vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useValidator } from 'composables/useValidator'; import { useValidator } from 'composables/useValidator';
import { ref } from 'vue'; import { ref } from 'vue';

View File

@ -7,9 +7,9 @@ import CardList from 'components/ui/CardList.vue';
import VnLv from 'components/ui/VnLv.vue'; import VnLv from 'components/ui/VnLv.vue';
import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import ShelvingFilter from 'pages/Shelving/components/ShelvingFilter.vue'; import ShelvingFilter from 'pages/Shelving/Card/ShelvingFilter.vue';
import ShelvingSummaryDialog from 'pages/Shelving/Summary/ShelvingSummaryDialog.vue'; import ShelvingSummaryDialog from 'pages/Shelving/Card/ShelvingSummaryDialog.vue';
import ShelvingSearchbar from 'pages/Shelving/components/ShelvingSearchbar.vue'; import ShelvingSearchbar from 'pages/Shelving/Card/ShelvingSearchbar.vue';
const stateStore = useStateStore(); const stateStore = useStateStore();
const router = useRouter(); const router = useRouter();
@ -34,6 +34,17 @@ function viewSummary(id) {
}, },
}); });
} }
function exprBuilder(param, value) {
switch (param) {
case 'search':
return {code: {like: `%${value}%`}};
case 'parkingFk':
case 'userFk':
case 'isRecyclable':
return {[param]: value};
}
}
</script> </script>
<template> <template>
@ -68,6 +79,7 @@ function viewSummary(id) {
data-key="ShelvingList" data-key="ShelvingList"
url="Shelvings" url="Shelvings"
:filter="filter" :filter="filter"
:expr-builder="exprBuilder"
auto-load auto-load
> >
<template #body="{ rows }"> <template #body="{ rows }">
@ -79,7 +91,6 @@ function viewSummary(id) {
@click="navigate(row.id)" @click="navigate(row.id)"
> >
<template #list-items> <template #list-items>
<VnLv label="ID" :value="row.id" />
<VnLv <VnLv
:label="t('shelving.list.parking')" :label="t('shelving.list.parking')"
:title-label="t('shelving.list.parking')" :title-label="t('shelving.list.parking')"

View File

@ -11,7 +11,7 @@ export default {
redirect: { name: 'ShelvingMain' }, redirect: { name: 'ShelvingMain' },
menus: { menus: {
main: ['ShelvingList'], main: ['ShelvingList'],
card: ['ShelvingBasicData'] card: ['ShelvingBasicData', 'ShelvingLog']
}, },
children: [ children: [
{ {
@ -42,7 +42,7 @@ export default {
{ {
name: 'ShelvingLayout', name: 'ShelvingLayout',
path: ':id', path: ':id',
component: () => import('pages/Shelving/Summary/ShelvingSummaryPage.vue'), component: () => import('pages/Shelving/Card/ShelvingCard.vue'),
redirect: { name: 'ShelvingSummary' }, redirect: { name: 'ShelvingSummary' },
children: [ children: [
{ {
@ -52,7 +52,7 @@ export default {
title: 'summary', title: 'summary',
}, },
component: () => component: () =>
import('pages/Shelving/Summary/ShelvingSummary.vue'), import('pages/Shelving/Card/ShelvingSummary.vue'),
}, },
{ {
name: 'ShelvingBasicData', name: 'ShelvingBasicData',
@ -64,6 +64,15 @@ export default {
}, },
component: () => import('pages/Shelving/ShelvingBasicData.vue'), component: () => import('pages/Shelving/ShelvingBasicData.vue'),
}, },
{
name: 'ShelvingLog',
path: 'log',
meta: {
title: 'log',
icon: 'history',
},
component: () => import('src/pages/Shelving/Card/ShelvingLog.vue'),
},
], ],
}, },
] ]