forked from verdnatura/salix-front
Zone exclude form and tree implementation
This commit is contained in:
parent
a1fde3f645
commit
097197b8dc
|
@ -9,7 +9,6 @@ import ZoneLocationsTree from './ZoneLocationsTree.vue';
|
|||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import { useWeekdayStore } from 'src/stores/useWeekdayStore';
|
||||
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||
import axios from 'axios';
|
||||
|
||||
|
@ -27,9 +26,13 @@ const props = defineProps({
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
isExclusion: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
eventType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
geoIds: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -37,11 +40,11 @@ const emit = defineEmits(['onSubmit', 'closeForm']);
|
|||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const weekdayStore = useWeekdayStore();
|
||||
const { openConfirmationModal } = useVnConfirm();
|
||||
|
||||
const isNew = computed(() => props.isNewMode);
|
||||
const dated = ref(null);
|
||||
const tickedNodes = ref();
|
||||
|
||||
const _excludeType = ref('all');
|
||||
const excludeType = computed({
|
||||
|
@ -55,7 +58,21 @@ const arrayData = useArrayData('ZoneEvents');
|
|||
|
||||
const exclusionGeoCreate = async () => {
|
||||
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) {
|
||||
console.error('Error creating exclusion geo: ', err);
|
||||
}
|
||||
|
@ -86,7 +103,9 @@ const onSubmit = async () => {
|
|||
const deleteEvent = async () => {
|
||||
try {
|
||||
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();
|
||||
} catch (err) {
|
||||
console.error('Error deleting event: ', err);
|
||||
|
@ -104,7 +123,8 @@ onMounted(() => {
|
|||
console.log('props.event', props.event);
|
||||
if (props.event) {
|
||||
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;
|
||||
});
|
||||
</script>
|
||||
|
@ -138,6 +158,13 @@ onMounted(() => {
|
|||
:label="t('eventsExclusionForm.specificLocations')"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="excludeType === 'specificLocations'">
|
||||
<ZoneLocationsTree
|
||||
:toggle-indeterminate="false"
|
||||
:root-label="t('eventsExclusionForm.rootTreeLabel')"
|
||||
v-model:tickedNodes="tickedNodes"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #custom-buttons>
|
||||
<QBtn
|
||||
|
@ -148,7 +175,9 @@ onMounted(() => {
|
|||
v-close-popup
|
||||
/>
|
||||
<QBtn
|
||||
v-if="!isNew && isExclusion"
|
||||
v-if="
|
||||
!isNew && (eventType === 'exclusion' || eventType === 'geoExclusion')
|
||||
"
|
||||
:label="t('globals.delete')"
|
||||
color="primary"
|
||||
flat
|
||||
|
|
|
@ -29,7 +29,7 @@ const props = defineProps({
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
isExclusion: {
|
||||
eventType: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
|
@ -45,11 +45,11 @@ const { openConfirmationModal } = useVnConfirm();
|
|||
const isNew = computed(() => props.isNewMode);
|
||||
const eventInclusionFormData = ref({});
|
||||
|
||||
const _eventType = ref('day');
|
||||
const eventType = computed({
|
||||
get: () => _eventType.value,
|
||||
const _inclusionType = ref('day');
|
||||
const inclusionType = computed({
|
||||
get: () => _inclusionType.value,
|
||||
set: (val) => {
|
||||
_eventType.value = val;
|
||||
_inclusionType.value = val;
|
||||
eventInclusionFormData.value.type = val;
|
||||
},
|
||||
});
|
||||
|
@ -62,10 +62,10 @@ const createEvent = async () => {
|
|||
eventInclusionFormData.value.wdays
|
||||
);
|
||||
|
||||
if (eventType.value == 'day') eventInclusionFormData.value.weekDays = '';
|
||||
if (inclusionType.value == 'day') eventInclusionFormData.value.weekDays = '';
|
||||
else eventInclusionFormData.value.dated = null;
|
||||
|
||||
if (eventType.value != 'range') {
|
||||
if (inclusionType.value != 'range') {
|
||||
eventInclusionFormData.value.started = null;
|
||||
eventInclusionFormData.value.ended = null;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ const refetchEvents = async () => {
|
|||
onMounted(() => {
|
||||
if (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;
|
||||
});
|
||||
</script>
|
||||
|
@ -127,19 +127,19 @@ onMounted(() => {
|
|||
<template #form-inputs>
|
||||
<div class="column q-gutter-y-sm q-mb-md">
|
||||
<QRadio
|
||||
v-model="eventType"
|
||||
v-model="inclusionType"
|
||||
dense
|
||||
val="day"
|
||||
:label="t('eventsInclusionForm.oneDay')"
|
||||
/>
|
||||
<QRadio
|
||||
v-model="eventType"
|
||||
v-model="inclusionType"
|
||||
dense
|
||||
val="indefinitely"
|
||||
:label="t('eventsInclusionForm.indefinitely')"
|
||||
/>
|
||||
<QRadio
|
||||
v-model="eventType"
|
||||
v-model="inclusionType"
|
||||
dense
|
||||
val="range"
|
||||
:label="t('eventsInclusionForm.rangeOfDates')"
|
||||
|
@ -149,7 +149,7 @@ onMounted(() => {
|
|||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col flex justify-center">
|
||||
<VnInputDate
|
||||
v-if="eventType === 'day'"
|
||||
v-if="inclusionType === 'day'"
|
||||
:label="t('eventsInclusionForm.day')"
|
||||
v-model="eventInclusionFormData.dated"
|
||||
class="full-width"
|
||||
|
@ -160,7 +160,7 @@ onMounted(() => {
|
|||
/>
|
||||
</div>
|
||||
</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
|
||||
:label="t('eventsInclusionForm.from')"
|
||||
v-model="eventInclusionFormData.started"
|
||||
|
@ -214,7 +214,7 @@ onMounted(() => {
|
|||
v-close-popup
|
||||
/>
|
||||
<QBtn
|
||||
v-if="!isNew && !isExclusion"
|
||||
v-if="!isNew && isExclusion === 'event'"
|
||||
:label="t('globals.delete')"
|
||||
color="primary"
|
||||
flat
|
||||
|
|
|
@ -127,11 +127,10 @@ const data = computed({
|
|||
|
||||
geoExclusions.value = {};
|
||||
let _geoExclusions = value.geoExclusions;
|
||||
|
||||
if (_geoExclusions) {
|
||||
for (let geoExclusion of _geoExclusions) {
|
||||
let stamp = toStamp(geoExclusion.dated);
|
||||
if (!geoExclusions[stamp]) geoExclusions.value[stamp] = [];
|
||||
if (!geoExclusions.value[stamp]) geoExclusions.value[stamp] = [];
|
||||
geoExclusions.value[stamp].push(geoExclusion);
|
||||
}
|
||||
}
|
||||
|
@ -179,11 +178,13 @@ const step = (direction) => {
|
|||
date.value = _date;
|
||||
};
|
||||
|
||||
const openForm = ({ date, isNewMode, event, isExclusion }) => {
|
||||
const openForm = ({ date, isNewMode, event, eventType, geoIds = [] }) => {
|
||||
zoneEventsFormProps.date = date;
|
||||
zoneEventsFormProps.isNewMode = isNewMode;
|
||||
zoneEventsFormProps.event = event;
|
||||
zoneEventsFormProps.isExclusion = isExclusion;
|
||||
zoneEventsFormProps.eventType = eventType;
|
||||
if (geoIds.length) zoneEventsFormProps.geoIds = geoIds;
|
||||
|
||||
showZoneEventForm.value = true;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { onMounted, ref, computed, watch } from 'vue';
|
||||
import { onMounted, ref, computed, watch, onUnmounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
|
@ -7,6 +7,27 @@ import { useState } from 'src/composables/useState';
|
|||
import axios from 'axios';
|
||||
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 route = useRoute();
|
||||
const state = useState();
|
||||
|
@ -21,9 +42,20 @@ const { store } = arrayData;
|
|||
const storeData = computed(() => store.data);
|
||||
|
||||
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 onNodeExpanded = async (nodeKeysArray) => {
|
||||
|
@ -46,6 +78,10 @@ const onNodeExpanded = async (nodeKeysArray) => {
|
|||
};
|
||||
|
||||
const formatNodeSelected = (node) => {
|
||||
if (!props.isZoneLocationsView) {
|
||||
node.selected = false;
|
||||
return;
|
||||
}
|
||||
if (node.selected === 1) node.selected = true;
|
||||
else if (node.selected === 0) node.selected = false;
|
||||
};
|
||||
|
@ -83,6 +119,7 @@ const fetchNodeLeaves = async (nodeKey) => {
|
|||
|
||||
const onSelected = async (val, node) => {
|
||||
try {
|
||||
if (!props.isZoneLocationsView) return;
|
||||
if (val === null) val = undefined;
|
||||
const params = { geoId: node.id, isIncluded: val };
|
||||
await axios.post(`Zones/${route.params.id}/toggleIsIncluded`, params);
|
||||
|
@ -141,45 +178,49 @@ onMounted(async () => {
|
|||
}
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
state.set('Tree', undefined);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QCard class="full-width" style="max-width: 800px">
|
||||
<QTree
|
||||
ref="treeRef"
|
||||
:nodes="nodes"
|
||||
node-key="id"
|
||||
label-key="name"
|
||||
v-model:expanded="expanded"
|
||||
@update:expanded="onNodeExpanded($event)"
|
||||
:default-expand-all="true"
|
||||
>
|
||||
<template #default-header="{ node }">
|
||||
<div
|
||||
:id="node.id"
|
||||
class="qtr row justify-between full-width q-pr-md cursor-pointer"
|
||||
>
|
||||
<span v-if="!node.id">{{ node.name }}</span>
|
||||
<QCheckbox
|
||||
v-else
|
||||
v-model="node.selected"
|
||||
:label="node.name"
|
||||
@update:model-value="($event) => onSelected($event, node)"
|
||||
toggle-indeterminate
|
||||
color="transparent"
|
||||
:class="[
|
||||
'checkbox',
|
||||
node.selected
|
||||
? '--checked'
|
||||
: node.selected == false
|
||||
? '--unchecked'
|
||||
: '--indeterminate',
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</QTree>
|
||||
</QCard>
|
||||
<QTree
|
||||
ref="treeRef"
|
||||
:nodes="nodes"
|
||||
node-key="id"
|
||||
label-key="name"
|
||||
v-model:expanded="expanded"
|
||||
tick-strategy="strict"
|
||||
v-model:ticked="_tickedNodes"
|
||||
@update:expanded="onNodeExpanded($event)"
|
||||
:default-expand-all="true"
|
||||
>
|
||||
<template #default-header="{ node }">
|
||||
<div
|
||||
:id="node.id"
|
||||
class="qtr row justify-between full-width q-pr-md cursor-pointer"
|
||||
>
|
||||
<span v-if="!isZoneLocationsView">{{ node.name }}</span>
|
||||
<QCheckbox
|
||||
v-else
|
||||
v-model="node.selected"
|
||||
:label="node.name"
|
||||
@update:model-value="($event) => onSelected($event, node)"
|
||||
toggle-indeterminate
|
||||
color="transparent"
|
||||
:class="[
|
||||
'checkbox',
|
||||
node.selected
|
||||
? '--checked'
|
||||
: node.selected == false
|
||||
? '--unchecked'
|
||||
: '--indeterminate',
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</QTree>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -93,10 +93,11 @@ const getEventByTimestamp = ({ year, month, day }) => {
|
|||
);
|
||||
};
|
||||
|
||||
const eventIsAnyExclusion = ({ year, month, day }) => {
|
||||
if (!event) return false;
|
||||
const getEventType = ({ year, month, day }) => {
|
||||
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 }) => {
|
||||
|
@ -127,14 +128,21 @@ const handleDateClick = (timestamp) => {
|
|||
if (props.isZoneDeliveryView) return;
|
||||
|
||||
const event = getEventByTimestamp(timestamp);
|
||||
console.log('eventTTTTTTTT: ', event);
|
||||
const { year, month, day } = timestamp;
|
||||
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', {
|
||||
date,
|
||||
isNewMode: !event,
|
||||
event: event && event.length > 0 ? event[0] : null,
|
||||
isExclusion: eventIsAnyExclusion(timestamp),
|
||||
eventType,
|
||||
geoIds,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -85,6 +85,7 @@ eventsExclusionForm:
|
|||
day: Day
|
||||
all: All
|
||||
specificLocations: Specific locations
|
||||
rootTreeLabel: Locations where it is not distributed
|
||||
eventsInclusionForm:
|
||||
addEvent: Add event
|
||||
editEvent: Edit event
|
||||
|
|
|
@ -87,6 +87,7 @@ eventsExclusionForm:
|
|||
day: Día
|
||||
all: Todo
|
||||
specificLocations: Localizaciones concretas
|
||||
rootTreeLabel: Localizaciones en las que no se reparte
|
||||
eventsInclusionForm:
|
||||
addEvent: Añadir evento
|
||||
editEvent: Editar evento
|
||||
|
|
Loading…
Reference in New Issue