feat: refs #7869 added include and exclude event from list
gitea/salix-front/pipeline/pr-dev There was a failure building this commit Details

This commit is contained in:
Jon Elias 2025-03-07 07:09:07 +01:00
parent d5cd3aee2d
commit 590e764cc2
7 changed files with 144 additions and 28 deletions

View File

@ -1,16 +1,18 @@
<script setup> <script setup>
import { ref, computed, onMounted, reactive } from 'vue'; import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useQuasar } from 'quasar';
import axios from 'axios';
import moment from 'moment';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import FormPopup from 'components/FormPopup.vue'; import FormPopup from 'components/FormPopup.vue';
import ZoneLocationsTree from './ZoneLocationsTree.vue'; import ZoneLocationsTree from './ZoneLocationsTree.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import { useVnConfirm } from 'composables/useVnConfirm'; import { useVnConfirm } from 'composables/useVnConfirm';
import axios from 'axios'; import { toDateFormat } from 'src/filters/date';
const props = defineProps({ const props = defineProps({
date: { date: {
@ -34,18 +36,25 @@ const props = defineProps({
type: Array, type: Array,
default: () => [], default: () => [],
}, },
isMasiveEdit: {
type: Boolean,
default: false,
},
zoneIds: {
type: Array,
default: () => [],
},
}); });
const emit = defineEmits(['onSubmit', 'closeForm']); const emit = defineEmits(['onSubmit', 'closeForm']);
const quasar = useQuasar();
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
const isNew = computed(() => props.isNewMode); const isNew = computed(() => props.isNewMode);
const dated = reactive(props.date); const dated = ref(props.date || Date.vnNew());
const tickedNodes = ref(); const tickedNodes = ref();
const _excludeType = ref('all'); const _excludeType = ref('all');
const excludeType = computed({ const excludeType = computed({
get: () => _excludeType.value, get: () => _excludeType.value,
@ -63,16 +72,43 @@ const exclusionGeoCreate = async () => {
geoIds: tickedNodes.value, geoIds: tickedNodes.value,
}; };
await axios.post('Zones/exclusionGeo', params); await axios.post('Zones/exclusionGeo', params);
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
await refetchEvents(); await refetchEvents();
}; };
const exclusionCreate = async () => { const exclusionCreate = async () => {
const url = `Zones/${route.params.id}/exclusions`;
const body = { const body = {
dated, dated: dated.value,
}; };
if (isNew.value || props.event?.type) await axios.post(`${url}`, [body]); for (const id of props.zoneIds) {
else await axios.put(`${url}/${props.event?.id}`, body); const url = `Zones/${id}/exclusions`;
let today = moment(dated.value);
let lastDay = today.clone().add(4, 'months').endOf('month');
const { data } = await axios.get(`Zones/getEventsFiltered`, {
params: {
zoneFk: id,
started: today,
ended: lastDay,
},
});
const existsEvent = data.events.find(
(event) => toDateFormat(event.dated) === toDateFormat(dated.value),
);
if (existsEvent) {
await axios.delete(`Zones/${existsEvent?.zoneFk}/events/${existsEvent?.id}`);
}
if (isNew.value || props.event?.type) await axios.post(`${url}`, [body]);
else await axios.put(`${url}/${props.event?.id}`, body);
}
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
await refetchEvents(); await refetchEvents();
}; };
@ -129,6 +165,7 @@ onMounted(() => {
:label="t('eventsExclusionForm.all')" :label="t('eventsExclusionForm.all')"
/> />
<QRadio <QRadio
v-if="!props.isMasiveEdit"
v-model="excludeType" v-model="excludeType"
dense dense
val="specificLocations" val="specificLocations"
@ -171,7 +208,7 @@ onMounted(() => {
openConfirmationModal( openConfirmationModal(
t('eventsPanel.deleteTitle'), t('eventsPanel.deleteTitle'),
t('eventsPanel.deleteSubtitle'), t('eventsPanel.deleteSubtitle'),
() => deleteEvent() () => deleteEvent(),
) )
" "
/> />

View File

@ -2,6 +2,7 @@
import { ref, computed, onMounted } from 'vue'; import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useQuasar } from 'quasar';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import FormPopup from 'components/FormPopup.vue'; import FormPopup from 'components/FormPopup.vue';
@ -9,7 +10,6 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnWeekdayPicker from 'src/components/common/VnWeekdayPicker.vue'; import VnWeekdayPicker from 'src/components/common/VnWeekdayPicker.vue';
import VnInputTime from 'components/common/VnInputTime.vue'; import VnInputTime from 'components/common/VnInputTime.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import { useWeekdayStore } from 'src/stores/useWeekdayStore'; import { useWeekdayStore } from 'src/stores/useWeekdayStore';
import { useVnConfirm } from 'composables/useVnConfirm'; import { useVnConfirm } from 'composables/useVnConfirm';
@ -33,6 +33,14 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
isMasiveEdit: {
type: Boolean,
default: false,
},
zoneIds: {
type: Array,
default: () => [],
},
}); });
const emit = defineEmits(['onSubmit', 'closeForm']); const emit = defineEmits(['onSubmit', 'closeForm']);
@ -41,7 +49,7 @@ const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const weekdayStore = useWeekdayStore(); const weekdayStore = useWeekdayStore();
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
const quasar = useQuasar();
const isNew = computed(() => props.isNewMode); const isNew = computed(() => props.isNewMode);
const eventInclusionFormData = ref({ wdays: [] }); const eventInclusionFormData = ref({ wdays: [] });
@ -58,7 +66,7 @@ const arrayData = useArrayData('ZoneEvents');
const createEvent = async () => { const createEvent = async () => {
eventInclusionFormData.value.weekDays = weekdayStore.toSet( eventInclusionFormData.value.weekDays = weekdayStore.toSet(
eventInclusionFormData.value.wdays eventInclusionFormData.value.wdays,
); );
if (inclusionType.value == 'day') eventInclusionFormData.value.weekDays = ''; if (inclusionType.value == 'day') eventInclusionFormData.value.weekDays = '';
@ -69,14 +77,20 @@ const createEvent = async () => {
eventInclusionFormData.value.ended = null; eventInclusionFormData.value.ended = null;
} }
if (isNew.value) const zoneIds = props.zoneIds?.length ? props.zoneIds : [route.params.id];
await axios.post(`Zones/${route.params.id}/events`, eventInclusionFormData.value); for (const id of zoneIds) {
else if (isNew.value)
await axios.put( await axios.post(`Zones/${id}/events`, eventInclusionFormData.value);
`Zones/${route.params.id}/events/${props.event?.id}`, else
eventInclusionFormData.value await axios.put(
); `Zones/${id}/events/${props.event?.id}`,
eventInclusionFormData.value,
);
}
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
await refetchEvents(); await refetchEvents();
emit('onSubmit'); emit('onSubmit');
}; };
@ -125,12 +139,14 @@ onMounted(() => {
:label="t('eventsInclusionForm.oneDay')" :label="t('eventsInclusionForm.oneDay')"
/> />
<QRadio <QRadio
v-if="!props.isMasiveEdit"
v-model="inclusionType" v-model="inclusionType"
dense dense
val="indefinitely" val="indefinitely"
:label="t('eventsInclusionForm.indefinitely')" :label="t('eventsInclusionForm.indefinitely')"
/> />
<QRadio <QRadio
v-if="!props.isMasiveEdit"
v-model="inclusionType" v-model="inclusionType"
dense dense
val="range" val="range"
@ -221,7 +237,7 @@ onMounted(() => {
openConfirmationModal( openConfirmationModal(
t('zone.deleteTitle'), t('zone.deleteTitle'),
t('zone.deleteSubtitle'), t('zone.deleteSubtitle'),
() => deleteEvent() () => deleteEvent(),
) )
" "
/> />

View File

@ -42,7 +42,7 @@ const refreshEvents = () => {
days.value = {}; days.value = {};
if (!data.value) return; if (!data.value) return;
let day = new Date(firstDay.value.getTime()); let day = new Date(firstDay?.value?.getTime());
while (day <= lastDay.value) { while (day <= lastDay.value) {
let stamp = day.getTime(); let stamp = day.getTime();
@ -156,7 +156,7 @@ watch(
(value) => { (value) => {
data.value = value; data.value = value;
}, },
{ immediate: true } { immediate: true },
); );
const getMonthNameAndYear = (date) => { const getMonthNameAndYear = (date) => {

View File

@ -15,8 +15,11 @@ import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnInputTime from 'src/components/common/VnInputTime.vue'; import VnInputTime from 'src/components/common/VnInputTime.vue';
import RightMenu from 'src/components/common/RightMenu.vue'; import RightMenu from 'src/components/common/RightMenu.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import ZoneFilterPanel from './ZoneFilterPanel.vue'; import ZoneFilterPanel from './ZoneFilterPanel.vue';
import ZoneSearchbar from './Card/ZoneSearchbar.vue'; import ZoneSearchbar from './Card/ZoneSearchbar.vue';
import ZoneEventInclusionForm from './Card/ZoneEventInclusionForm.vue';
import ZoneEventExclusionForm from './Card/ZoneEventExclusionForm.vue';
const { t } = useI18n(); const { t } = useI18n();
const router = useRouter(); const router = useRouter();
@ -25,7 +28,11 @@ const { viewSummary } = useSummaryDialog();
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
const tableRef = ref(); const tableRef = ref();
const warehouseOptions = ref([]); const warehouseOptions = ref([]);
const selectedRows = ref([]);
const hasSelectedRows = computed(() => selectedRows.value.length > 0);
const openInclusionForm = ref();
const showZoneEventForm = ref(false);
const zoneIds = ref({});
const tableFilter = { const tableFilter = {
include: [ include: [
{ {
@ -169,6 +176,16 @@ function formatRow(row) {
return dashIfEmpty(`${row?.address?.nickname}, return dashIfEmpty(`${row?.address?.nickname},
${row?.address?.postcode?.town?.name} (${row?.address?.province?.name})`); ${row?.address?.postcode?.town?.name} (${row?.address?.province?.name})`);
} }
function openForm(value, rows) {
zoneIds.value = rows.map((row) => row.id);
openInclusionForm.value = value;
showZoneEventForm.value = true;
}
const closeEventForm = () => {
showZoneEventForm.value = false;
};
</script> </script>
<template> <template>
@ -178,6 +195,28 @@ function formatRow(row) {
<ZoneFilterPanel data-key="ZonesList" /> <ZoneFilterPanel data-key="ZonesList" />
</template> </template>
</RightMenu> </RightMenu>
<VnSubToolbar>
<template #st-actions>
<QBtnGroup style="column-gap: 10px">
<QBtn
color="primary"
icon-right="event_available"
:disable="!hasSelectedRows"
@click="openForm(true, selectedRows)"
>
<QTooltip>{{ t('list.includeEvent') }}</QTooltip>
</QBtn>
<QBtn
color="primary"
icon-right="event_busy"
:disable="!hasSelectedRows"
@click="openForm(false, selectedRows)"
>
<QTooltip>{{ t('list.excludeEvent') }}</QTooltip>
</QBtn>
</QBtnGroup>
</template>
</VnSubToolbar>
<VnTable <VnTable
ref="tableRef" ref="tableRef"
data-key="ZonesList" data-key="ZonesList"
@ -192,6 +231,11 @@ function formatRow(row) {
:columns="columns" :columns="columns"
redirect="zone" redirect="zone"
:right-search="false" :right-search="false"
v-model:selected="selectedRows"
:table="{
'row-key': 'id',
selection: 'multiple',
}"
> >
<template #column-addressFk="{ row }"> <template #column-addressFk="{ row }">
{{ dashIfEmpty(formatRow(row)) }} {{ dashIfEmpty(formatRow(row)) }}
@ -238,6 +282,21 @@ function formatRow(row) {
/> />
</template> </template>
</VnTable> </VnTable>
<QDialog v-model="showZoneEventForm" @hide="closeEventForm()">
<ZoneEventInclusionForm
v-if="openInclusionForm"
:event="'event'"
:is-masive-edit="true"
:zone-ids="zoneIds"
@close-form="closeEventForm"
/>
<ZoneEventExclusionForm
v-else
:zone-ids="zoneIds"
:is-masive-edit="true"
@close-form="closeEventForm"
/>
</QDialog>
</template> </template>
<i18n> <i18n>

View File

@ -33,6 +33,8 @@ list:
createZone: Create zone createZone: Create zone
zoneSummary: Summary zoneSummary: Summary
addressFk: Address addressFk: Address
includeEvent: Include event
excludeEvent: Exclude event
create: create:
name: Name name: Name
closingHour: Closing hour closingHour: Closing hour

View File

@ -35,6 +35,8 @@ list:
createZone: Crear zona createZone: Crear zona
zoneSummary: Resumen zoneSummary: Resumen
addressFk: Consignatario addressFk: Consignatario
includeEvent: Incluir evento
excludeEvent: Excluir evento
create: create:
closingHour: Hora de cierre closingHour: Hora de cierre
itemMaxSize: Medida máxima itemMaxSize: Medida máxima

View File

@ -77,14 +77,14 @@ export const useWeekdayStore = defineStore('weekdayStore', () => {
const locales = {}; const locales = {};
for (let code of localeOrder.es) { for (let code of localeOrder.es) {
const weekDay = weekdaysMap[code]; const weekDay = weekdaysMap[code];
const locale = t(`weekdays.${weekdaysMap[code].code}`); const locale = t(`weekdays.${weekDay?.code}`);
const obj = { const obj = {
...weekDay, ...weekDay,
locale, locale,
localeChar: locale.substr(0, 1), localeChar: locale.substr(0, 1),
localeAbr: locale.substr(0, 3), localeAbr: locale.substr(0, 3),
}; };
locales[weekDay.code] = obj; locales[weekDay?.code] = obj;
} }
return locales; return locales;
}); });