Merge branch '7404-add-e2e-to-route' of https://gitea.verdnatura.es/verdnatura/salix-front into 7404-add-e2e-to-route
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Pablo Natek 2024-07-03 10:20:58 +02:00
commit 29c4b1bcb8
29 changed files with 136 additions and 166 deletions

View File

@ -1,6 +1,6 @@
<script setup>
import { onBeforeMount, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
import { useArrayData } from 'src/composables/useArrayData';
import { useStateStore } from 'stores/useStateStore';
import useCardSize from 'src/composables/useCardSize';
@ -41,6 +41,15 @@ onBeforeMount(async () => {
if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
await arrayData.fetch({ append: false });
});
if (props.baseUrl) {
onBeforeRouteUpdate(async (to, from) => {
if (to.params.id !== from.params.id) {
arrayData.store.url = `${props.baseUrl}/${to.params.id}`;
await arrayData.fetch({ append: false, updateRouter: false });
}
});
}
</script>
<template>
<QDrawer

View File

@ -46,7 +46,7 @@ let arrayData;
let store;
let entity;
const isLoading = ref(false);
const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName);
defineExpose({ getData });
onBeforeMount(async () => {
@ -58,10 +58,12 @@ onBeforeMount(async () => {
store = arrayData.store;
entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
// It enables to load data only once if the module is the same as the dataKey
if ($props.dataKey !== route.meta.moduleName || !route.params.id) await getData();
if (!isSameDataKey.value || !route.params.id) await getData();
watch(
() => [$props.url, $props.filter],
async () => await getData()
async () => {
if (!isSameDataKey.value) await getData();
}
);
});
@ -77,14 +79,50 @@ async function getData() {
isLoading.value = false;
}
}
function getValueFromPath(path) {
if (!path) return;
const keys = path.toString().split('.');
let current = entity.value;
for (let i = 0; i < keys.length; i++) {
if (current[keys[i]] === undefined) return undefined;
else current = current[keys[i]];
}
return current;
}
const emit = defineEmits(['onFetch']);
const iconModule = computed(() => route.matched[1].meta.icon);
const toModule = computed(() =>
route.matched[1].path.split('/').length > 2
? route.matched[1].redirect
: route.matched[1].children[0].redirect
);
</script>
<template>
<div class="descriptor">
<template v-if="entity && !isLoading">
<div class="header bg-primary q-pa-sm justify-between">
<slot name="header-extra-action" />
<slot name="header-extra-action"
><QBtn
round
flat
dense
size="md"
:icon="iconModule"
color="white"
class="link"
:to="toModule"
>
<QTooltip>
{{ t('globals.goToModuleIndex') }}
</QTooltip>
</QBtn></slot
>
<QBtn
@click.stop="viewSummary(entity.id, $props.summary)"
round
@ -139,8 +177,8 @@ const emit = defineEmits(['onFetch']);
<QList dense>
<QItemLabel header class="ellipsis text-h5" :lines="1">
<div class="title">
<span v-if="$props.title" :title="$props.title">
{{ entity[title] ?? $props.title }}
<span v-if="$props.title" :title="getValueFromPath(title)">
{{ getValueFromPath(title) ?? $props.title }}
</span>
<slot v-else name="description" :entity="entity">
<span :title="entity.name">
@ -151,7 +189,7 @@ const emit = defineEmits(['onFetch']);
</QItemLabel>
<QItem dense>
<QItemLabel class="subtitle" caption>
#{{ $props.subtitle ?? entity.id }}
#{{ getValueFromPath(subtitle) ?? entity.id }}
</QItemLabel>
</QItem>
</QList>

View File

@ -114,6 +114,7 @@ async function search(evt) {
store.userParamsChanged = true;
store.filter.skip = 0;
store.skip = 0;
store.page = 1;
const { params: newParams } = await arrayData.addFilter({ params: userParams.value });
userParams.value = newParams;
@ -126,7 +127,8 @@ async function search(evt) {
async function reload() {
isLoading.value = true;
const params = Object.values(userParams.value).filter((param) => param);
store.skip = 0;
store.page = 1;
await arrayData.fetch({ append: false });
if (!$props.showAll && !params.length) store.data = [];
isLoading.value = false;
@ -138,6 +140,7 @@ async function clearFilters() {
store.userParamsChanged = true;
store.filter.skip = 0;
store.skip = 0;
store.page = 1;
// Filtrar los params no removibles
const removableFilters = Object.keys(userParams.value).filter((param) =>
$props.unremovableParams.includes(param)

View File

@ -104,6 +104,7 @@ async function search() {
([key, value]) => value && (props.staticParams || []).includes(key)
);
store.skip = 0;
store.page = 1;
if (props.makeFetch)
await arrayData.applyFilter({

View File

@ -1,4 +1,4 @@
import { onMounted, ref, computed } from 'vue';
import { onMounted, computed } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import axios from 'axios';
import { useArrayDataStore } from 'stores/useArrayDataStore';
@ -16,8 +16,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
const router = useRouter();
let canceller = null;
const page = ref(1);
onMounted(() => {
setOptions();
store.skip = 0;
@ -87,13 +85,13 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
}
Object.assign(filter, store.userFilter, exprFilter);
Object.assign(store.filter, { ...filter, skip: store.skip });
const params = {
filter: JSON.stringify(store.filter),
};
Object.assign(store.filter, filter);
const params = { filter: store.filter };
Object.assign(params, userParams);
params.filter.skip = store.skip;
params.filter = JSON.stringify(params.filter);
store.currentFilter = params;
store.isLoading = true;
const response = await axios.get(store.url, {
@ -154,8 +152,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
store.userParams = userParams;
store.skip = 0;
store.filter.skip = 0;
page.value = 1;
store.page = 1;
await fetch({ append: false });
return { filter, params };
}
@ -187,10 +184,11 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
async function loadMore() {
if (!store.hasMoreData) return;
store.skip = store.limit * page.value;
page.value += 1;
store.skip = store.limit * store.page;
store.page += 1;
await fetch({ append: true });
updateStateParams();
}
async function refresh() {

View File

@ -245,6 +245,7 @@ globals:
new: New
comment: Comment
observations: Observations
goToModuleIndex: Go to module index
errors:
statusUnauthorized: Access denied
statusInternalServerError: An internal server error has ocurred

View File

@ -246,6 +246,7 @@ globals:
new: Nuevo
comment: Comentario
observations: Observaciones
goToModuleIndex: Ir al índice del módulo
errors:
statusUnauthorized: Acceso denegado
statusInternalServerError: Ha ocurrido un error interno del servidor

View File

@ -49,20 +49,6 @@ const hasAccount = ref(false);
:title="data.title"
:subtitle="data.subtitle"
>
<template #header-extra-action>
<QBtn
round
flat
size="md"
color="white"
icon="face"
:to="{ name: 'AccountList' }"
>
<QTooltip>
{{ t('Go to module index') }}
</QTooltip>
</QBtn>
</template>
<template #menu>
<AccountDescriptorMenu :has-account="hasAccount" />
</template>

View File

@ -56,8 +56,7 @@ onMounted(async () => {
:url="`Claims/${entityId}`"
:filter="filter"
module="Claim"
:title="data.title"
:subtitle="data.subtitle"
title="client.name"
@on-fetch="setData"
data-key="Claim"
>

View File

@ -45,20 +45,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.name, entity
:summary="$props.summary"
data-key="customerData"
>
<template #header-extra-action>
<QBtn
round
flat
size="sm"
icon="vn:Person"
color="white"
:to="{ name: 'CustomerList' }"
>
<QTooltip>
{{ t('Go to module index') }}
</QTooltip>
</QBtn>
</template>
<template #menu="{ entity }">
<CustomerDescriptorMenu :customer="entity" />
</template>

View File

@ -1,5 +1,5 @@
<script setup>
import { ref, computed, watch } from 'vue';
import { ref, computed, watch, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
@ -10,6 +10,7 @@ import useCardDescription from 'src/composables/useCardDescription';
import { useState } from 'src/composables/useState';
import { toDate } from 'src/filters';
import { usePrintService } from 'composables/usePrintService';
import { getUrl } from 'src/composables/getUrl';
const $props = defineProps({
id: {
@ -17,10 +18,6 @@ const $props = defineProps({
required: false,
default: null,
},
summary: {
type: Object,
default: null,
},
});
const route = useRoute();
@ -28,6 +25,7 @@ const { t } = useI18n();
const { openReport } = usePrintService();
const state = useState();
const entryDescriptorRef = ref(null);
const url = ref();
const entryFilter = {
include: [
@ -69,6 +67,9 @@ const entryFilter = {
const entityId = computed(() => {
return $props.id || route.params.id;
});
onMounted(async () => {
url.value = await getUrl('');
});
const data = ref(useCardDescription());
const setData = (entity) =>
@ -114,6 +115,7 @@ watch;
:subtitle="data.subtitle"
@on-fetch="setData"
data-key="entry"
:summary="$attrs"
>
<template #menu="{ entity }">
<QItem v-ripple clickable @click="showEntryReport(entity)">

View File

@ -1,5 +1,6 @@
<script setup>
import EntryDescriptor from './EntryDescriptor.vue';
import EntrySummary from './EntrySummary.vue';
const $props = defineProps({
id: {
@ -11,6 +12,6 @@ const $props = defineProps({
<template>
<QPopupProxy>
<EntryDescriptor v-if="$props.id" :id="$props.id" />
<EntryDescriptor v-if="$props.id" :id="$props.id" :summary="EntrySummary" />
</QPopupProxy>
</template>

View File

@ -1,5 +1,6 @@
<script setup>
import InvoiceInDescriptor from "pages/InvoiceIn/Card/InvoiceInDescriptor.vue";
import InvoiceInDescriptor from 'pages/InvoiceIn/Card/InvoiceInDescriptor.vue';
import InvoiceInSummary from './InvoiceInSummary.vue';
const $props = defineProps({
id: {
@ -10,6 +11,10 @@ const $props = defineProps({
</script>
<template>
<QPopupProxy>
<InvoiceInDescriptor v-if="$props.id" :id="$props.id" />
<InvoiceInDescriptor
v-if="$props.id"
:id="$props.id"
:summary="InvoiceInSummary"
/>
</QPopupProxy>
</template>

View File

@ -51,20 +51,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity
@on-fetch="setData"
data-key="entry"
>
<template #header-extra-action>
<QBtn
round
flat
size="sm"
icon="vn:item"
color="white"
:to="{ name: 'ItemTypeList' }"
>
<QTooltip>
{{ t('Go to module index') }}
</QTooltip>
</QBtn>
</template>
<template #body="{ entity }">
<VnLv :label="t('shared.code')" :value="entity.code" />
<VnLv :label="t('shared.name')" :value="entity.name" />

View File

@ -2,7 +2,6 @@
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import { useArrayData } from 'src/composables/useArrayData';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'components/ui/VnLv.vue';
@ -17,8 +16,7 @@ const props = defineProps({
const { t } = useI18n();
const route = useRoute();
const entityId = computed(() => props.id || route.params.id);
const { store } = useArrayData('Parking');
const parking = computed(() => store.data);
const filter = {
fields: ['id', 'sectorFk', 'code', 'pickingOrder', 'row', 'column'],
include: [{ relation: 'sector', scope: { fields: ['id', 'description'] } }],
@ -29,15 +27,13 @@ const filter = {
module="Parking"
data-key="Parking"
:url="`Parkings/${entityId}`"
:title="parking?.code"
:subtitle="parking?.id"
title="code"
:filter="filter"
@on-fetch="(data) => (parking = data)"
>
<template #body>
<VnLv :label="t('globals.code')" :value="parking.code" />
<VnLv :label="t('parking.pickingOrder')" :value="parking.pickingOrder" />
<VnLv :label="t('parking.sector')" :value="parking.sector?.description" />
<template #body="{ entity }">
<VnLv :label="t('globals.code')" :value="entity.code" />
<VnLv :label="t('parking.pickingOrder')" :value="entity.pickingOrder" />
<VnLv :label="t('parking.sector')" :value="entity.sector?.description" />
</template>
</CardDescriptor>
</template>

View File

@ -1,10 +1,9 @@
<script setup>
import { ref, computed } from 'vue';
import { computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'components/ui/VnLv.vue';
import { useArrayData } from 'src/composables/useArrayData';
const $props = defineProps({
id: {
@ -15,9 +14,7 @@ const $props = defineProps({
const router = useRoute();
const { t } = useI18n();
const entityId = computed(() => $props.id || router.params.id);
const { store } = useArrayData('Parking');
const parking = ref(store.data);
const filter = {
fields: ['id', 'sectorFk', 'code', 'pickingOrder', 'row', 'column'],
include: [{ relation: 'sector', scope: { fields: ['id', 'description'] } }],
@ -26,14 +23,9 @@ const filter = {
<template>
<div class="q-pa-md">
<CardSummary
:url="`Parkings/${entityId}`"
:filter="filter"
@on-fetch="(data) => (parking = data)"
data-key="Parking"
>
<template #header>{{ parking.code }}</template>
<template #body>
<CardSummary :url="`Parkings/${entityId}`" data-key="Parking" :filter="filter">
<template #header="{ entity }">{{ entity.code }}</template>
<template #body="{ entity }">
<QCard class="vn-one">
<QCardSection class="q-pa-none">
<a
@ -44,17 +36,17 @@ const filter = {
<QIcon name="open_in_new" />
</a>
</QCardSection>
<VnLv :label="t('globals.code')" :value="parking.code" />
<VnLv :label="t('globals.code')" :value="entity.code" />
<VnLv
:label="t('parking.pickingOrder')"
:value="parking.pickingOrder"
:value="entity.pickingOrder"
/>
<VnLv
:label="t('parking.sector')"
:value="parking.sector?.description"
:value="entity.sector?.description"
/>
<VnLv :label="t('parking.row')" :value="parking.row" />
<VnLv :label="t('parking.column')" :value="parking.column" />
<VnLv :label="t('parking.row')" :value="entity.row" />
<VnLv :label="t('parking.column')" :value="entity.column" />
</QCard>
</template>
</CardSummary>

View File

@ -74,8 +74,9 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity
:filter="filter"
:title="data.title"
:subtitle="data.subtitle"
data-key="Routes"
data-key="routeData"
@on-fetch="setData"
:summary="$attrs"
>
<template #body="{ entity }">
<VnLv :label="t('Date')" :value="toDate(entity?.created)" />

View File

@ -1,5 +1,6 @@
<script setup>
import RouteDescriptor from 'pages/Route/Card/RouteDescriptor.vue';
import RouteSummary from './RouteSummary.vue';
const $props = defineProps({
id: {
@ -10,6 +11,6 @@ const $props = defineProps({
</script>
<template>
<QPopupProxy>
<RouteDescriptor v-if="$props.id" :id="$props.id" />
<RouteDescriptor v-if="$props.id" :id="$props.id" :summary="RouteSummary" />
</QPopupProxy>
</template>

View File

@ -51,6 +51,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity
:subtitle="data.subtitle"
data-key="Shelvings"
@on-fetch="setData"
:summary="$attrs"
>
<template #body="{ entity }">
<VnLv :label="t('shelving.summary.code')" :value="entity.code" />

View File

@ -1,5 +1,6 @@
<script setup>
import ShelvingDescriptor from "pages/Shelving/Card/ShelvingDescriptor.vue";
import ShelvingDescriptor from 'pages/Shelving/Card/ShelvingDescriptor.vue';
import ShelvingSummary from './ShelvingSummary.vue';
const $props = defineProps({
id: {
@ -10,6 +11,6 @@ const $props = defineProps({
</script>
<template>
<QPopupProxy>
<ShelvingDescriptor v-if="$props.id" :id="$props.id" />
<ShelvingDescriptor v-if="$props.id" :id="$props.id" :summary="ShelvingSummary" />
</QPopupProxy>
</template>

View File

@ -112,22 +112,6 @@ const getEntryQueryParams = (supplier) => {
data-key="supplier"
:summary="$props.summary"
>
<template #header-extra-action>
<QBtn
round
flat
dense
size="md"
icon="vn:supplier"
color="white"
class="link"
:to="{ name: 'SupplierList' }"
>
<QTooltip>
{{ t('Go to module index') }}
</QTooltip>
</QBtn>
</template>
<template #body="{ entity }">
<VnLv :label="t('supplier.summary.taxNumber')" :value="entity.nif" />
<VnLv label="Alias" :value="entity.nickname" />

View File

@ -70,8 +70,6 @@ const filter = {
};
const data = ref(useCardDescription());
const setData = (entity) =>
(data.value = useCardDescription(entity.client?.name, entity.id));
</script>
<template>
@ -82,7 +80,6 @@ const setData = (entity) =>
:title="data.title"
:subtitle="data.subtitle"
data-key="ticketData"
@on-fetch="setData"
>
<template #menu="{ entity }">
<TicketDescriptorMenu :ticket="entity" />
@ -153,4 +150,5 @@ const setData = (entity) =>
<i18n>
es:
This ticket is deleted: Este ticket está eliminado
Go to module index: Ir al índice del modulo
</i18n>

View File

@ -1,5 +1,6 @@
<script setup>
import TicketDescriptor from './TicketDescriptor.vue';
import TicketSummary from './TicketSummary.vue';
const $props = defineProps({
id: {
@ -10,6 +11,6 @@ const $props = defineProps({
</script>
<template>
<QPopupProxy>
<TicketDescriptor v-if="$props.id" :id="$props.id" />
<TicketDescriptor v-if="$props.id" :id="$props.id" :summary="TicketSummary" />
</QPopupProxy>
</template>

View File

@ -1,10 +1,11 @@
<script setup>
import { computed } from 'vue';
import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import useCardDescription from 'src/composables/useCardDescription';
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
import { toDate } from 'src/filters';
@ -51,32 +52,22 @@ const filter = {
const entityId = computed(() => {
return $props.id || route.params.id;
});
const data = ref(useCardDescription());
const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.id));
</script>
<template>
<CardDescriptor
module="Travel"
:url="`Travels/${entityId}`"
title="ref"
:title="data.title"
:subtitle="data.subtitle"
:filter="filter"
data-key="Travel"
data-key="travelData"
:summary="$attrs"
@on-fetch="setData"
>
<template #header-extra-action>
<QBtn
round
flat
dense
size="md"
icon="local_airport"
color="white"
class="link"
:to="{ name: 'TravelList' }"
>
<QTooltip>
{{ t('Go to module index') }}
</QTooltip>
</QBtn>
</template>
<template #menu="{ entity }">
<TravelDescriptorMenuItems :travel="entity" />
</template>

View File

@ -1,5 +1,6 @@
<script setup>
import TravelDescriptor from './TravelDescriptor.vue';
import TravelSummary from './TravelSummary.vue';
const $props = defineProps({
id: {
@ -11,6 +12,6 @@ const $props = defineProps({
<template>
<QPopupProxy>
<TravelDescriptor v-if="$props.id" :id="$props.id" />
<TravelDescriptor v-if="$props.id" :id="$props.id" :summary="TravelSummary" />
</QPopupProxy>
</template>

View File

@ -17,10 +17,6 @@ const $props = defineProps({
required: false,
default: null,
},
summary: {
type: Object,
default: null,
},
});
const route = useRoute();
@ -115,7 +111,7 @@ const refetch = async () => await cardDescriptorRef.value.getData();
:filter="filter"
:title="data.title"
:subtitle="data.subtitle"
:summary="$props.summary"
:summary="$attrs"
@on-fetch="
(data) => {
worker = data;

View File

@ -38,7 +38,6 @@ const entityId = computed(() => {
});
const data = ref(useCardDescription());
const setData = (entity) => {
data.value = useCardDescription(entity.ref, entity.id);
};
@ -53,23 +52,8 @@ const setData = (entity) => {
:filter="filter"
@on-fetch="setData"
data-key="zoneData"
:summary="$attrs"
>
<template #header-extra-action>
<QBtn
round
flat
dense
size="md"
icon="vn:zone"
color="white"
class="link"
:to="{ name: 'ZoneList' }"
>
<QTooltip>
{{ t('Summary') }}
</QTooltip>
</QBtn>
</template>
<template #menu="{ entity }">
<ZoneDescriptorMenuItems :zone="entity" />
</template>
@ -82,3 +66,8 @@ const setData = (entity) => {
</template>
</CardDescriptor>
</template>
<i18n>
es:
Go to module index: Ir al índice del módulo
</i18n>

View File

@ -1,5 +1,6 @@
<script setup>
import ZoneDescriptor from './ZoneDescriptor.vue';
import ZoneSummary from './ZoneSummary.vue';
const $props = defineProps({
id: {
@ -11,6 +12,6 @@ const $props = defineProps({
<template>
<QPopupProxy>
<ZoneDescriptor v-if="$props.id" :id="$props.id" />
<ZoneDescriptor v-if="$props.id" :id="$props.id" :summary="ZoneSummary" />
</QPopupProxy>
</template>

View File

@ -23,6 +23,7 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
exprBuilder: null,
searchUrl: 'params',
navigate: null,
page: 1,
};
}