0
0
Fork 0

Zone exclude form and tree implementation

This commit is contained in:
William Buezas 2024-05-26 17:17:58 -03:00
parent a1fde3f645
commit 097197b8dc
7 changed files with 151 additions and 70 deletions

View File

@ -9,7 +9,6 @@ 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 { useWeekdayStore } from 'src/stores/useWeekdayStore';
import { useVnConfirm } from 'composables/useVnConfirm'; import { useVnConfirm } from 'composables/useVnConfirm';
import axios from 'axios'; import axios from 'axios';
@ -27,9 +26,13 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
isExclusion: { eventType: {
type: Boolean, type: String,
default: true, default: '',
},
geoIds: {
type: Array,
default: () => [],
}, },
}); });
@ -37,11 +40,11 @@ const emit = defineEmits(['onSubmit', 'closeForm']);
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const weekdayStore = useWeekdayStore();
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
const isNew = computed(() => props.isNewMode); const isNew = computed(() => props.isNewMode);
const dated = ref(null); const dated = ref(null);
const tickedNodes = ref();
const _excludeType = ref('all'); const _excludeType = ref('all');
const excludeType = computed({ const excludeType = computed({
@ -55,7 +58,21 @@ const arrayData = useArrayData('ZoneEvents');
const exclusionGeoCreate = async () => { const exclusionGeoCreate = async () => {
try { try {
console.log('exclusionGeoCreate'); if (isNew.value) {
const params = {
zoneFk: parseInt(route.params.id),
date: dated.value,
geoIds: tickedNodes.value,
};
await axios.post('Zones/exclusionGeo', params);
} else {
const params = {
zoneExclusionFk: props.event?.id,
geoIds: tickedNodes.value,
};
await axios.post('Zones/updateExclusionGeo', params);
}
await refetchEvents();
} catch (err) { } catch (err) {
console.error('Error creating exclusion geo: ', err); console.error('Error creating exclusion geo: ', err);
} }
@ -86,7 +103,9 @@ const onSubmit = async () => {
const deleteEvent = async () => { const deleteEvent = async () => {
try { try {
if (!props.event) return; if (!props.event) return;
await axios.delete(`Zones/${route.params.id}/exclusions/${props.event?.id}`); await axios.delete(
`Zones/${route.params.id}/exclusions/${props.event?.zoneExclusionFk}`
);
await refetchEvents(); await refetchEvents();
} catch (err) { } catch (err) {
console.error('Error deleting event: ', err); console.error('Error deleting event: ', err);
@ -104,7 +123,8 @@ onMounted(() => {
console.log('props.event', props.event); console.log('props.event', props.event);
if (props.event) { if (props.event) {
dated.value = props.event?.dated; dated.value = props.event?.dated;
excludeType.value = props.event?.type || 'all'; excludeType.value = props.geoIds.length ? 'specificLocations' : 'all';
tickedNodes.value = props.geoIds || [];
} else if (props.date) dated.value = props.date; } else if (props.date) dated.value = props.date;
}); });
</script> </script>
@ -138,6 +158,13 @@ onMounted(() => {
:label="t('eventsExclusionForm.specificLocations')" :label="t('eventsExclusionForm.specificLocations')"
/> />
</div> </div>
<div v-if="excludeType === 'specificLocations'">
<ZoneLocationsTree
:toggle-indeterminate="false"
:root-label="t('eventsExclusionForm.rootTreeLabel')"
v-model:tickedNodes="tickedNodes"
/>
</div>
</template> </template>
<template #custom-buttons> <template #custom-buttons>
<QBtn <QBtn
@ -148,7 +175,9 @@ onMounted(() => {
v-close-popup v-close-popup
/> />
<QBtn <QBtn
v-if="!isNew && isExclusion" v-if="
!isNew && (eventType === 'exclusion' || eventType === 'geoExclusion')
"
:label="t('globals.delete')" :label="t('globals.delete')"
color="primary" color="primary"
flat flat

View File

@ -29,7 +29,7 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
isExclusion: { eventType: {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
@ -45,11 +45,11 @@ const { openConfirmationModal } = useVnConfirm();
const isNew = computed(() => props.isNewMode); const isNew = computed(() => props.isNewMode);
const eventInclusionFormData = ref({}); const eventInclusionFormData = ref({});
const _eventType = ref('day'); const _inclusionType = ref('day');
const eventType = computed({ const inclusionType = computed({
get: () => _eventType.value, get: () => _inclusionType.value,
set: (val) => { set: (val) => {
_eventType.value = val; _inclusionType.value = val;
eventInclusionFormData.value.type = val; eventInclusionFormData.value.type = val;
}, },
}); });
@ -62,10 +62,10 @@ const createEvent = async () => {
eventInclusionFormData.value.wdays eventInclusionFormData.value.wdays
); );
if (eventType.value == 'day') eventInclusionFormData.value.weekDays = ''; if (inclusionType.value == 'day') eventInclusionFormData.value.weekDays = '';
else eventInclusionFormData.value.dated = null; else eventInclusionFormData.value.dated = null;
if (eventType.value != 'range') { if (inclusionType.value != 'range') {
eventInclusionFormData.value.started = null; eventInclusionFormData.value.started = null;
eventInclusionFormData.value.ended = null; eventInclusionFormData.value.ended = null;
} }
@ -110,7 +110,7 @@ const refetchEvents = async () => {
onMounted(() => { onMounted(() => {
if (props.event) { if (props.event) {
eventInclusionFormData.value = { ...props.event }; eventInclusionFormData.value = { ...props.event };
eventType.value = props.event?.type || 'day'; inclusionType.value = props.event?.type || 'day';
} else if (props.date) eventInclusionFormData.value.dated = props.date; } else if (props.date) eventInclusionFormData.value.dated = props.date;
}); });
</script> </script>
@ -127,19 +127,19 @@ onMounted(() => {
<template #form-inputs> <template #form-inputs>
<div class="column q-gutter-y-sm q-mb-md"> <div class="column q-gutter-y-sm q-mb-md">
<QRadio <QRadio
v-model="eventType" v-model="inclusionType"
dense dense
val="day" val="day"
:label="t('eventsInclusionForm.oneDay')" :label="t('eventsInclusionForm.oneDay')"
/> />
<QRadio <QRadio
v-model="eventType" v-model="inclusionType"
dense dense
val="indefinitely" val="indefinitely"
:label="t('eventsInclusionForm.indefinitely')" :label="t('eventsInclusionForm.indefinitely')"
/> />
<QRadio <QRadio
v-model="eventType" v-model="inclusionType"
dense dense
val="range" val="range"
:label="t('eventsInclusionForm.rangeOfDates')" :label="t('eventsInclusionForm.rangeOfDates')"
@ -149,7 +149,7 @@ onMounted(() => {
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col flex justify-center"> <div class="col flex justify-center">
<VnInputDate <VnInputDate
v-if="eventType === 'day'" v-if="inclusionType === 'day'"
:label="t('eventsInclusionForm.day')" :label="t('eventsInclusionForm.day')"
v-model="eventInclusionFormData.dated" v-model="eventInclusionFormData.dated"
class="full-width" class="full-width"
@ -160,7 +160,7 @@ onMounted(() => {
/> />
</div> </div>
</VnRow> </VnRow>
<VnRow v-if="eventType === 'range'" class="row q-gutter-md q-mb-md"> <VnRow v-if="inclusionType === 'range'" class="row q-gutter-md q-mb-md">
<VnInputDate <VnInputDate
:label="t('eventsInclusionForm.from')" :label="t('eventsInclusionForm.from')"
v-model="eventInclusionFormData.started" v-model="eventInclusionFormData.started"
@ -214,7 +214,7 @@ onMounted(() => {
v-close-popup v-close-popup
/> />
<QBtn <QBtn
v-if="!isNew && !isExclusion" v-if="!isNew && isExclusion === 'event'"
:label="t('globals.delete')" :label="t('globals.delete')"
color="primary" color="primary"
flat flat

View File

@ -127,11 +127,10 @@ const data = computed({
geoExclusions.value = {}; geoExclusions.value = {};
let _geoExclusions = value.geoExclusions; let _geoExclusions = value.geoExclusions;
if (_geoExclusions) { if (_geoExclusions) {
for (let geoExclusion of _geoExclusions) { for (let geoExclusion of _geoExclusions) {
let stamp = toStamp(geoExclusion.dated); let stamp = toStamp(geoExclusion.dated);
if (!geoExclusions[stamp]) geoExclusions.value[stamp] = []; if (!geoExclusions.value[stamp]) geoExclusions.value[stamp] = [];
geoExclusions.value[stamp].push(geoExclusion); geoExclusions.value[stamp].push(geoExclusion);
} }
} }
@ -179,11 +178,13 @@ const step = (direction) => {
date.value = _date; date.value = _date;
}; };
const openForm = ({ date, isNewMode, event, isExclusion }) => { const openForm = ({ date, isNewMode, event, eventType, geoIds = [] }) => {
zoneEventsFormProps.date = date; zoneEventsFormProps.date = date;
zoneEventsFormProps.isNewMode = isNewMode; zoneEventsFormProps.isNewMode = isNewMode;
zoneEventsFormProps.event = event; zoneEventsFormProps.event = event;
zoneEventsFormProps.isExclusion = isExclusion; zoneEventsFormProps.eventType = eventType;
if (geoIds.length) zoneEventsFormProps.geoIds = geoIds;
showZoneEventForm.value = true; showZoneEventForm.value = true;
}; };

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { onMounted, ref, computed, watch } from 'vue'; import { onMounted, ref, computed, watch, onUnmounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
@ -7,6 +7,27 @@ import { useState } from 'src/composables/useState';
import axios from 'axios'; import axios from 'axios';
import { useArrayData } from 'composables/useArrayData'; import { useArrayData } from 'composables/useArrayData';
const props = defineProps({
toggleIndeterminate: {
type: Boolean,
default: false,
},
isZoneLocationsView: {
type: Boolean,
default: false,
},
rootLabel: {
type: String,
default: 'Locations',
},
tickedNodes: {
type: Array,
default: () => [],
},
});
const emit = defineEmits(['update:tickedNodes']);
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const state = useState(); const state = useState();
@ -21,9 +42,20 @@ const { store } = arrayData;
const storeData = computed(() => store.data); const storeData = computed(() => store.data);
const nodes = ref([ const nodes = ref([
{ id: null, name: t('zoneLocations.locations'), sons: true, children: [{}] }, {
id: null,
name: props.rootLabel,
sons: true,
tickable: false,
noTick: true,
children: [{}],
},
]); ]);
const _tickedNodes = computed({
get: () => props.tickedNodes,
set: (value) => emit('update:tickedNodes', value),
});
const previousExpandedNodes = ref(new Set()); const previousExpandedNodes = ref(new Set());
const onNodeExpanded = async (nodeKeysArray) => { const onNodeExpanded = async (nodeKeysArray) => {
@ -46,6 +78,10 @@ const onNodeExpanded = async (nodeKeysArray) => {
}; };
const formatNodeSelected = (node) => { const formatNodeSelected = (node) => {
if (!props.isZoneLocationsView) {
node.selected = false;
return;
}
if (node.selected === 1) node.selected = true; if (node.selected === 1) node.selected = true;
else if (node.selected === 0) node.selected = false; else if (node.selected === 0) node.selected = false;
}; };
@ -83,6 +119,7 @@ const fetchNodeLeaves = async (nodeKey) => {
const onSelected = async (val, node) => { const onSelected = async (val, node) => {
try { try {
if (!props.isZoneLocationsView) return;
if (val === null) val = undefined; if (val === null) val = undefined;
const params = { geoId: node.id, isIncluded: val }; const params = { geoId: node.id, isIncluded: val };
await axios.post(`Zones/${route.params.id}/toggleIsIncluded`, params); await axios.post(`Zones/${route.params.id}/toggleIsIncluded`, params);
@ -141,16 +178,21 @@ onMounted(async () => {
} }
}, 1000); }, 1000);
}); });
onUnmounted(() => {
state.set('Tree', undefined);
});
</script> </script>
<template> <template>
<QCard class="full-width" style="max-width: 800px">
<QTree <QTree
ref="treeRef" ref="treeRef"
:nodes="nodes" :nodes="nodes"
node-key="id" node-key="id"
label-key="name" label-key="name"
v-model:expanded="expanded" v-model:expanded="expanded"
tick-strategy="strict"
v-model:ticked="_tickedNodes"
@update:expanded="onNodeExpanded($event)" @update:expanded="onNodeExpanded($event)"
:default-expand-all="true" :default-expand-all="true"
> >
@ -159,7 +201,7 @@ onMounted(async () => {
:id="node.id" :id="node.id"
class="qtr row justify-between full-width q-pr-md cursor-pointer" class="qtr row justify-between full-width q-pr-md cursor-pointer"
> >
<span v-if="!node.id">{{ node.name }}</span> <span v-if="!isZoneLocationsView">{{ node.name }}</span>
<QCheckbox <QCheckbox
v-else v-else
v-model="node.selected" v-model="node.selected"
@ -179,7 +221,6 @@ onMounted(async () => {
</div> </div>
</template> </template>
</QTree> </QTree>
</QCard>
</template> </template>
<style lang="scss"> <style lang="scss">

View File

@ -93,10 +93,11 @@ const getEventByTimestamp = ({ year, month, day }) => {
); );
}; };
const eventIsAnyExclusion = ({ year, month, day }) => { const getEventType = ({ year, month, day }) => {
if (!event) return false;
const stamp = new Date(year, month - 1, day).getTime(); const stamp = new Date(year, month - 1, day).getTime();
return !!props.exclusions[stamp] || !!props.geoExclusions[stamp]; if (props.exclusions[stamp]) return 'exclusion';
if (props.geoExclusions[stamp]) return 'geoExclusion';
return 'event';
}; };
const getEventAttrs = ({ year, month, day }) => { const getEventAttrs = ({ year, month, day }) => {
@ -127,14 +128,21 @@ const handleDateClick = (timestamp) => {
if (props.isZoneDeliveryView) return; if (props.isZoneDeliveryView) return;
const event = getEventByTimestamp(timestamp); const event = getEventByTimestamp(timestamp);
console.log('eventTTTTTTTT: ', event);
const { year, month, day } = timestamp; const { year, month, day } = timestamp;
const date = new Date(year, month - 1, day); const date = new Date(year, month - 1, day);
const stamp = date.getTime();
const eventType = getEventType(timestamp);
let geoIds = [];
if (eventType === 'geoExclusion')
geoIds = props.geoExclusions[stamp].map((geoExclusion) => geoExclusion.geoFk);
emit('openZoneForm', { emit('openZoneForm', {
date, date,
isNewMode: !event, isNewMode: !event,
event: event && event.length > 0 ? event[0] : null, event: event && event.length > 0 ? event[0] : null,
isExclusion: eventIsAnyExclusion(timestamp), eventType,
geoIds,
}); });
}; };
</script> </script>

View File

@ -85,6 +85,7 @@ eventsExclusionForm:
day: Day day: Day
all: All all: All
specificLocations: Specific locations specificLocations: Specific locations
rootTreeLabel: Locations where it is not distributed
eventsInclusionForm: eventsInclusionForm:
addEvent: Add event addEvent: Add event
editEvent: Edit event editEvent: Edit event

View File

@ -87,6 +87,7 @@ eventsExclusionForm:
day: Día day: Día
all: Todo all: Todo
specificLocations: Localizaciones concretas specificLocations: Localizaciones concretas
rootTreeLabel: Localizaciones en las que no se reparte
eventsInclusionForm: eventsInclusionForm:
addEvent: Añadir evento addEvent: Añadir evento
editEvent: Editar evento editEvent: Editar evento