Compare commits

...

27 Commits

Author SHA1 Message Date
Jon Elias 6273aea7ff Merge pull request '#8028: Modified arrayData to fix inject warning' (!1747) from 8028-WarningInject into dev
gitea/salix-front/pipeline/head This commit looks good Details
Reviewed-on: #1747
Reviewed-by: Jorge Penadés <jorgep@verdnatura.es>
2025-04-25 11:33:46 +00:00
Jon Elias 397e378856 Merge branch 'dev' into 8028-WarningInject
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-04-25 07:48:13 +00:00
Alex Moreno f145351cf1 Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix-front into dev
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-25 09:39:26 +02:00
Alex Moreno 8bceb21493 Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix-front into test
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-25 09:39:15 +02:00
Alex Moreno e30232741f fix(VnCard): conditionally update card descriptor based on visual prop
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-25 09:39:10 +02:00
Jon Elias d71b928802 Merge branch 'dev' into 8028-WarningInject
gitea/salix-front/pipeline/pr-dev This commit is unstable Details
2025-04-25 06:47:09 +00:00
Alex Moreno 0748a2728c fix(ItemDescriptorProxy): add proxy-render prop to ItemDescriptor component
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-25 08:33:51 +02:00
Alex Moreno bac21ac062 Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix-front into dev
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-25 08:28:28 +02:00
Alex Moreno ce81185089 Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix-front into test
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-25 08:28:14 +02:00
Alex Moreno 4eff607ecb fix(WorkerTimeControl): replace axiosNoError with axios for API calls
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-25 08:28:06 +02:00
Alex Moreno 92b3ea126f refactor(WorkerBasicData): update addAdvancedData to use formData and remove state dependency
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-25 08:07:22 +02:00
Alex Moreno 312677964e refactor(workerBasicData): fix useAdvancedSummary
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-25 07:35:30 +02:00
Jon Elias d568fc3100 refactor: refs #8028 modified arrayData to fix inject warning
gitea/salix-front/pipeline/pr-dev This commit is unstable Details
2025-04-24 16:18:38 +02:00
Alex Moreno 16eecb324f Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix-front into dev
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-24 15:08:30 +02:00
Alex Moreno 3ed24ae23d Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix-front into test
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-24 15:08:23 +02:00
Alex Moreno ba2ab0f300 refactor: workerDescriptor use CardDescriptor
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-24 15:08:08 +02:00
Javier Segarra 97f82ffa3a fix: update getDate function to handle hour data and add VnInputTime component for shipped hour
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-24 12:41:17 +02:00
Jon Elias 8df3ed8779 Merge pull request 'Hotfix[VnDmsList]: Open file in new window to equal Salix's behavior' (!1744) from Hotfix-VnDmsList into master
gitea/salix-front/pipeline/head This commit looks good Details
Reviewed-on: #1744
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2025-04-24 11:25:22 +00:00
Jon Elias 295d514457 Merge branch 'master' into Hotfix-VnDmsList
gitea/salix-front/pipeline/pr-master This commit looks good Details
2025-04-24 10:53:43 +00:00
Alex Moreno 8ee1d96bda Merge pull request 'fix: remove unused props and simplify component structure in multiple descriptor proxies' (!1742) from hotFix_descriptor_getData into master
gitea/salix-front/pipeline/head This commit looks good Details
Reviewed-on: #1742
Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
2025-04-24 10:47:11 +00:00
Jon Elias 7c699e9022 fix: open dms file in new window instead of downloading it automatically to equal salix behavior
gitea/salix-front/pipeline/pr-master This commit is unstable Details
2025-04-24 12:27:58 +02:00
Javier Segarra c540865694 fix: update getDate function to handle hour data and add VnInputTime component for shipped hour
gitea/salix-front/pipeline/head This commit looks good Details
2025-04-24 12:01:43 +02:00
Jorge Penadés 5b4ff55a1d Merge pull request 'fix: refs #8936 change default value of preventSubmit to false' (!1743) from 8936-preventSubmit into dev
gitea/salix-front/pipeline/head This commit looks good Details
Reviewed-on: #1743
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2025-04-24 09:27:08 +00:00
Jorge Penadés 43b23f62a5 fix: refs #8936 change default value of preventSubmit to false
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-04-24 10:20:06 +02:00
Alex Moreno 3b6c41208f fix: remove unused props and simplify component structure in multiple descriptor proxies
gitea/salix-front/pipeline/pr-master This commit looks good Details
2025-04-24 09:04:42 +02:00
Alex Moreno f72543f533 Merge pull request 'fix: refactor createTicket function to use formData directly and remove unused reactive state' (!1737) from hotFix_ticketExpedition into master
gitea/salix-front/pipeline/head This commit looks good Details
Reviewed-on: #1737
Reviewed-by: Jon Elias <jon@verdnatura.es>
2025-04-23 10:20:50 +00:00
Alex Moreno bcdb89d1a7 fix: refactor createTicket function to use formData directly and remove unused reactive state
gitea/salix-front/pipeline/pr-master This commit looks good Details
2025-04-23 11:21:14 +02:00
17 changed files with 88 additions and 95 deletions

View File

@ -100,7 +100,7 @@ const $props = defineProps({
},
preventSubmit: {
type: Boolean,
default: true,
default: false,
},
});
const emit = defineEmits(['onFetch', 'onDataSaved', 'submit']);
@ -287,7 +287,7 @@ function updateAndEmit(evt, { val, res, old } = { val: null, res: null, old: nul
state.set(modelValue, val);
if (!$props.url) arrayData.store.data = val;
emit(evt, state.get(modelValue), res, old);
emit(evt, state.get(modelValue), res, old, formData);
}
function trimData(data) {

View File

@ -33,7 +33,7 @@ onBeforeRouteLeave(() => {
});
onBeforeMount(async () => {
stateStore.cardDescriptorChangeValue(markRaw(props.descriptor));
if (props.visual) stateStore.cardDescriptorChangeValue(markRaw(props.descriptor));
const route = router.currentRoute.value;
try {

View File

@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import { useQuasar, QCheckbox, QBtn, QInput } from 'quasar';
import axios from 'axios';
import { usePrintService } from 'composables/usePrintService';
import VnUserLink from '../ui/VnUserLink.vue';
import { downloadFile } from 'src/composables/downloadFile';
@ -23,6 +24,7 @@ const rows = ref([]);
const dmsRef = ref();
const formDialog = ref({});
const token = useSession().getTokenMultimedia();
const { openReport } = usePrintService();
const $props = defineProps({
model: {
@ -199,12 +201,7 @@ const columns = computed(() => [
color: 'primary',
}),
click: (prop) =>
downloadFile(
prop.row.id,
$props.downloadModel,
undefined,
prop.row.download,
),
openReport(`dms/${prop.row.id}/downloadFile`, {}, '_blank'),
},
{
component: QBtn,

View File

@ -1,5 +1,5 @@
<script setup>
import { ref, onMounted, onUnmounted, watch, computed } from 'vue';
import { ref, onMounted, onUnmounted, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';

View File

@ -1,8 +1,6 @@
<script setup>
import { onBeforeMount, watch, computed, ref } from 'vue';
import { watch, ref, onMounted } from 'vue';
import { useArrayData } from 'composables/useArrayData';
import { useState } from 'src/composables/useState';
import { useRoute } from 'vue-router';
import VnDescriptor from './VnDescriptor.vue';
const $props = defineProps({
@ -20,39 +18,50 @@ const $props = defineProps({
},
});
const state = useState();
const route = useRoute();
let arrayData;
let store;
let entity;
const entity = ref();
const isLoading = ref(false);
const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName);
defineExpose({ getData });
const containerRef = ref(null);
onBeforeMount(async () => {
arrayData = useArrayData($props.dataKey, {
onMounted(async () => {
let isPopup;
let el = containerRef.value.$el;
while (el) {
if (el.classList?.contains('q-menu')) {
isPopup = true;
break;
}
el = el.parentElement;
}
arrayData = useArrayData($props.dataKey + (isPopup ? 'Proxy' : ''), {
url: $props.url,
userFilter: $props.filter,
skip: 0,
oneRecord: true,
});
store = arrayData.store;
entity = computed(() => {
const data = store.data ?? {};
if (data) emit('onFetch', data);
return data;
});
// It enables to load data only once if the module is the same as the dataKey
if (!isSameDataKey.value || !route.params.id) await getData();
watch(
() => [$props.url, $props.filter],
async () => {
if (!isSameDataKey.value) await getData();
await getData();
},
{ immediate: true },
);
watch(
() => arrayData.store.data,
(newValue) => {
entity.value = newValue;
},
);
});
defineExpose({ getData });
const emit = defineEmits(['onFetch']);
async function getData() {
store.url = $props.url;
store.filter = $props.filter ?? {};
@ -60,18 +69,15 @@ async function getData() {
try {
await arrayData.fetch({ append: false, updateRouter: false });
const { data } = store;
state.set($props.dataKey, data);
emit('onFetch', data);
} finally {
isLoading.value = false;
}
}
const emit = defineEmits(['onFetch']);
</script>
<template>
<VnDescriptor v-model="entity" v-bind="$attrs" :module="dataKey">
<VnDescriptor v-model="entity" v-bind="$attrs" :module="dataKey" ref="containerRef">
<template v-for="(_, slotName) in $slots" #[slotName]="slotData" :key="slotName">
<slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
</template>

View File

@ -146,14 +146,14 @@ const addFilter = async (filter, params) => {
};
async function fetch(params) {
useArrayData(props.dataKey, params);
arrayData.setOptions(params);
arrayData.resetPagination();
await arrayData.fetch({ append: false });
return emitStoreData();
}
async function update(params) {
useArrayData(props.dataKey, params);
arrayData.setOptions(params);
const { limit, skip } = store;
store.limit = limit + skip;
store.skip = 0;

View File

@ -41,7 +41,7 @@ export function useArrayData(key, userOptions) {
if (key && userOptions) setOptions();
function setOptions() {
function setOptions(params = userOptions) {
const allowedOptions = [
'url',
'filter',
@ -57,14 +57,14 @@ export function useArrayData(key, userOptions) {
'mapKey',
'oneRecord',
];
if (typeof userOptions === 'object') {
for (const option in userOptions) {
const isEmpty = userOptions[option] == null || userOptions[option] === '';
if (typeof params === 'object') {
for (const option in params) {
const isEmpty = params[option] == null || params[option] === '';
if (isEmpty || !allowedOptions.includes(option)) continue;
if (Object.hasOwn(store, option)) {
const defaultOpts = userOptions[option];
store[option] = userOptions.keepOpts?.includes(option)
const defaultOpts = params[option];
store[option] = params.keepOpts?.includes(option)
? Object.assign(defaultOpts, store[option])
: defaultOpts;
if (option === 'userParams') store.defaultParams = store[option];
@ -367,5 +367,6 @@ export function useArrayData(key, userOptions) {
deleteOption,
reset,
resetPagination,
setOptions,
};
}

View File

@ -4,11 +4,6 @@ import AccountSummary from './AccountSummary.vue';
</script>
<template>
<QPopupProxy style="max-width: 10px">
<AccountDescriptor
v-if="$attrs.id"
v-bind="$attrs"
:summary="AccountSummary"
:proxy-render="true"
/>
<AccountDescriptor v-if="$attrs.id" v-bind="$attrs" :summary="AccountSummary" />
</QPopupProxy>
</template>

View File

@ -1,5 +1,5 @@
<script setup>
import { ref, computed, onMounted } from 'vue';
import { computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { toDateHourMinSec, toPercentage } from 'src/filters';
@ -9,7 +9,6 @@ import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/Departme
import EntityDescriptor from 'components/ui/EntityDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import { getUrl } from 'src/composables/getUrl';
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import filter from './ClaimFilter.js';
@ -23,7 +22,6 @@ const $props = defineProps({
const route = useRoute();
const { t } = useI18n();
const salixUrl = ref();
const entityId = computed(() => {
return $props.id || route.params.id;
});
@ -31,10 +29,6 @@ const entityId = computed(() => {
function stateColor(entity) {
return entity?.claimState?.classColor;
}
onMounted(async () => {
salixUrl.value = await getUrl('');
});
</script>
<template>
@ -126,7 +120,7 @@ onMounted(async () => {
size="md"
icon="assignment"
color="primary"
:href="salixUrl + 'ticket/' + entity.ticketFk + '/sale-tracking'"
:to="{ name: 'TicketSaleTracking', params: { id: entity.ticketFk } }"
>
<QTooltip>{{ t('claim.saleTracking') }}</QTooltip>
</QBtn>
@ -134,7 +128,7 @@ onMounted(async () => {
size="md"
icon="visibility"
color="primary"
:href="salixUrl + 'ticket/' + entity.ticketFk + '/tracking/index'"
:to="{ name: 'TicketTracking', params: { id: entity.ticketFk } }"
>
<QTooltip>{{ t('claim.ticketTracking') }}</QTooltip>
</QBtn>

View File

@ -4,11 +4,6 @@ import ClaimSummary from './ClaimSummary.vue';
</script>
<template>
<QPopupProxy style="max-width: 10px">
<ClaimDescriptor
v-if="$attrs.id"
v-bind="$attrs.id"
:summary="ClaimSummary"
:proxy-render="true"
/>
<ClaimDescriptor v-if="$attrs.id" v-bind="$attrs" :summary="ClaimSummary" />
</QPopupProxy>
</template>

View File

@ -4,11 +4,6 @@ import ParkingSummary from './ParkingSummary.vue';
</script>
<template>
<QPopupProxy style="max-width: 10px">
<ParkingDescriptor
v-if="$attrs.id"
v-bind="$attrs.id"
:summary="ParkingSummary"
:proxy-render="true"
/>
<ParkingDescriptor v-if="$attrs.id" v-bind="$attrs" :summary="ParkingSummary" />
</QPopupProxy>
</template>

View File

@ -70,8 +70,6 @@ async function getDate(query, params) {
for (const param in params) {
if (!params[param]) return;
}
formData.value.zoneFk = null;
zonesOptions.value = [];
const { data } = await axios.get(query, { params });
if (!data) return notify(t('basicData.noDeliveryZoneAvailable'), 'negative');
@ -79,7 +77,7 @@ async function getDate(query, params) {
formData.value.zoneFk = data.zoneFk;
formData.value.landed = data.landed;
const shippedDate = new Date(params.shipped);
const landedDate = new Date(data.landed);
const landedDate = new Date(data.hour);
shippedDate.setHours(
landedDate.getHours(),
landedDate.getMinutes(),
@ -427,6 +425,14 @@ async function getZone(options) {
:rules="validate('ticketList.shipped')"
@update:model-value="setShipped"
/>
<VnInputTime
:label="t('basicData.shippedHour')"
v-model="formData.shipped"
:required="true"
:rules="validate('basicData.shippedHour')"
disabled
@update:model-value="setShipped"
/>
<VnInputDate
:label="t('basicData.landed')"
v-model="formData.landed"

View File

@ -1,5 +1,4 @@
<script setup>
import { reactive } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
@ -30,31 +29,29 @@ const { t } = useI18n();
const router = useRouter();
const { notify } = useNotify();
const newTicketFormData = reactive({});
const date = new Date();
const createTicket = async () => {
async function createTicket(formData) {
const expeditionIds = $props.selectedExpeditions.map((expedition) => expedition.id);
const params = {
clientId: $props.ticket.clientFk,
landed: newTicketFormData.landed,
landed: formData.landed,
warehouseId: $props.ticket.warehouseFk,
addressId: $props.ticket.addressFk,
agencyModeId: $props.ticket.agencyModeFk,
routeId: newTicketFormData.routeFk,
routeId: formData.routeFk,
expeditionIds: expeditionIds,
};
const { data } = await axios.post('Expeditions/moveExpeditions', params);
notify(t('globals.dataSaved'), 'positive');
router.push({ name: 'TicketSummary', params: { id: data.id } });
};
}
</script>
<template>
<FormModelPopup
model="expeditionNewTicket"
:form-initial-data="newTicketFormData"
:form-initial-data="{}"
:save-fn="createTicket"
>
<template #form-inputs="{ data }">

View File

@ -1,6 +1,5 @@
<script setup>
import { ref, nextTick, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import FetchData from 'components/FetchData.vue';
@ -9,21 +8,23 @@ import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import { useAdvancedSummary } from 'src/composables/useAdvancedSummary';
import { useRoute } from 'vue-router';
const { t } = useI18n();
const form = ref();
const educationLevels = ref([]);
const countries = ref([]);
const model = 'Worker';
const maritalStatus = [
{ code: 'M', name: t('Married') },
{ code: 'S', name: t('Single') },
];
onMounted(async () => {
const advanced = await useAdvancedSummary('Workers', useRoute().params.id);
Object.assign(form.value.formData, advanced);
const route = useRoute();
async function addAdvancedData(data) {
const advanced = await useAdvancedSummary('Workers', route.params.id);
data.value = { ...data.value, ...advanced };
nextTick(() => (form.value.hasChanges = false));
});
}
</script>
<template>
<FetchData
@ -42,7 +43,8 @@ onMounted(async () => {
ref="form"
:url-update="`Workers/${$route.params.id}`"
auto-load
model="Worker"
:model
@on-fetch="(data, res, old, formData) => addAdvancedData(formData)"
>
<template #form="{ data }">
<VnRow>

View File

@ -4,9 +4,11 @@ import VnCard from 'src/components/common/VnCard.vue';
</script>
<template>
<VnCard
data-key="Worker"
:data-key="$attrs['data-key'] ?? 'Worker'"
url="Workers/summary"
:id-in-where="true"
:descriptor="WorkerDescriptor"
v-bind="$attrs"
v-on="$attrs"
/>
</template>

View File

@ -2,7 +2,6 @@
import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import EntityDescriptor from 'src/components/ui/EntityDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
import VnChangePassword from 'src/components/common/VnChangePassword.vue';
@ -11,6 +10,8 @@ import VnImg from 'src/components/ui/VnImg.vue';
import EditPictureForm from 'components/EditPictureForm.vue';
import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
import WorkerCard from './WorkerCard.vue';
const $props = defineProps({
id: {
@ -52,14 +53,17 @@ const handlePhotoUpdated = (evt = false) => {
};
</script>
<template>
<EntityDescriptor
<CardDescriptor
v-bind="$attrs"
ref="cardDescriptorRef"
:data-key="dataKey"
:summary="$props.summary"
url="Workers/summary"
:card="WorkerCard"
:id="entityId"
:filter="{ where: { id: entityId } }"
title="user.nickname"
@on-fetch="getIsExcluded"
module="Worker"
>
<template #menu="{ entity }">
<WorkerDescriptorMenu
@ -165,7 +169,7 @@ const handlePhotoUpdated = (evt = false) => {
</QBtn>
</QCardActions>
</template>
</EntityDescriptor>
</CardDescriptor>
<VnChangePassword
ref="changePassRef"
:submit-fn="

View File

@ -2,7 +2,6 @@
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import { onMounted, ref, computed, onBeforeMount, nextTick, reactive } from 'vue';
import { axiosNoError } from 'src/boot/axios';
import FetchData from 'components/FetchData.vue';
import WorkerTimeHourChip from 'pages/Worker/Card/WorkerTimeHourChip.vue';
@ -281,11 +280,11 @@ const fetchWeekData = async () => {
week: selectedWeekNumber.value,
};
try {
const [{ data: mailData }, { data: countData }] = await Promise.all([
axiosNoError.get(`Workers/${route.params.id}/mail`, {
const [{ data: mailData }, { data: countData }] = await Promise.allS([
axios.get(`Workers/${route.params.id}/mail`, {
params: { filter: { where } },
}),
axiosNoError.get('WorkerTimeControlMails/count', { params: { where } }),
axios.get('WorkerTimeControlMails/count', { params: { where } }),
]);
const mail = mailData[0];