This commit is contained in:
William Buezas 2024-05-24 08:18:38 -03:00
parent 790e69f659
commit 9b3135fd97
10 changed files with 437 additions and 26 deletions

View File

@ -0,0 +1,37 @@
<script setup>
import { ref } from 'vue';
import { useWeekdayStore } from 'src/stores/useWeekdayStore';
const props = defineProps({
wdays: {
type: Array,
default: () => [],
},
});
const emit = defineEmits(['update:wdays']);
const weekdayStore = useWeekdayStore();
const selectedWDays = ref(props.wdays);
const toggleDay = (index) => {
selectedWDays.value[index] = !selectedWDays.value[index];
emit('update:wdays', selectedWDays.value);
};
</script>
<template>
<div class="q-gutter-x-sm" style="width: max-content">
<QBtn
v-for="(weekday, index) in weekdayStore.getLocalesMap"
:key="index"
:label="weekday.localeChar"
rounded
style="max-width: 36px"
:color="selectedWDays[weekday.index] ? 'primary' : ''"
@click="toggleDay(weekday.index)"
/>
</div>
</template>

View File

@ -0,0 +1 @@
<template>Zone event exclusion form</template>

View File

@ -0,0 +1,214 @@
<script setup>
import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import VnInput from 'src/components/common/VnInput.vue';
import { useRoute } from 'vue-router';
import VnRow from 'components/ui/VnRow.vue';
import FormPopup from 'components/FormPopup.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnWeekdayPicker from 'src/components/common/VnWeekdayPicker.vue';
import VnInputTime from 'components/common/VnInputTime.vue';
import { useArrayData } from 'src/composables/useArrayData';
import { useWeekdayStore } from 'src/stores/useWeekdayStore';
import axios from 'axios';
import { onMounted } from 'vue';
const props = defineProps({
date: {
type: Date,
required: true,
default: null,
},
event: {
type: Object,
default: null,
},
isNewMode: {
type: Boolean,
default: true,
},
});
const emit = defineEmits(['onSubmit']);
const route = useRoute();
const { t } = useI18n();
const weekdayStore = useWeekdayStore();
const isNew = computed(() => props.isNewMode);
const eventInclusionFormData = ref({});
const _eventType = ref('day');
const eventType = computed({
get: () => _eventType.value,
set: (val) => {
_eventType.value = val;
eventInclusionFormData.value.type = val;
},
});
const arrayData = useArrayData('ZoneEvents');
const createEvent = async () => {
try {
eventInclusionFormData.value.weekDays = weekdayStore.toSet(
eventInclusionFormData.value.wdays
);
if (eventType.value == 'day') eventInclusionFormData.value.weekDays = '';
else eventInclusionFormData.value.dated = null;
if (eventType.value != 'range') {
eventInclusionFormData.value.started = null;
eventInclusionFormData.value.ended = null;
}
if (isNew.value)
await axios.post(
`Zones/${route.params.id}/events`,
eventInclusionFormData.value
);
else
await axios.put(
`Zones/${route.params.id}/events/${props.event?.id}`,
eventInclusionFormData.value
);
await refetchEvents();
emit('onSubmit');
// case 'delete':
// return this.onDelete(this.selected.id).then(
// (response) => response == 'accept'
// );
} catch (err) {
console.error('Error creating event', err);
}
};
const refetchEvents = async () => {
await arrayData.refresh({ append: false });
};
onMounted(() => {
console.log('props.event', props.event);
if (props.event) {
eventInclusionFormData.value = { ...props.event };
eventType.value = props.event.type;
} else if (props.date) eventInclusionFormData.value.dated = props.date;
console.log('eventInclusionFormData', eventInclusionFormData.value);
});
</script>
<template>
<FormPopup
:title="
isNew ? t('eventsInclusionForm.addEvent') : t('eventsInclusionForm.editEvent')
"
:custom-submit-button-label="isNew ? t('globals.save') : t('globals.add')"
@on-submit="createEvent()"
>
<template #form-inputs>
<div class="column q-gutter-y-sm q-mb-md">
<pre>{{ isNew }}</pre>
<QRadio
v-model="eventType"
dense
val="day"
:label="t('eventsInclusionForm.oneDay')"
/>
<QRadio
v-model="eventType"
dense
val="indefinitely"
:label="t('eventsInclusionForm.indefinitely')"
/>
<QRadio
v-model="eventType"
dense
val="range"
:label="t('eventsInclusionForm.rangeOfDates')"
class="q-mb-sm"
/>
</div>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col flex justify-center">
<VnInputDate
v-if="eventType === 'day'"
:label="t('eventsInclusionForm.day')"
v-model="eventInclusionFormData.dated"
class="full-width"
/>
<VnWeekdayPicker
v-else
v-model:wdays="eventInclusionFormData.wdays"
/>
</div>
</VnRow>
<VnRow v-if="eventType === 'range'" class="row q-gutter-md q-mb-md">
<VnInputDate
:label="t('eventsInclusionForm.from')"
v-model="eventInclusionFormData.started"
/>
<VnInputDate
:label="t('eventsInclusionForm.to')"
v-model="eventInclusionFormData.ended"
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<VnInputTime
v-model="eventInclusionFormData.hour"
:label="t('eventsInclusionForm.closing')"
/>
<VnInput
v-model="eventInclusionFormData.travelingDays"
:label="t('eventsInclusionForm.travelingDays')"
type="number"
min="0"
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<VnInput
v-model="eventInclusionFormData.price"
:label="t('eventsInclusionForm.price')"
type="number"
min="0"
/>
<VnInput
v-model="eventInclusionFormData.bonus"
:label="t('eventsInclusionForm.bonus')"
type="number"
min="0"
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<VnInput
v-model="eventInclusionFormData.m3Max"
:label="t('eventsInclusionForm.m3Max')"
type="number"
min="0"
/>
</VnRow>
</template>
</FormPopup>
</template>
<i18n>
en:
title: New bank entity
subtitle: Please, ensure you put the correct data!
name: Name
swift: Swift
country: Country
id: Entity code
es:
title: Nueva entidad bancaria
subtitle: ¡Por favor, asegúrate de poner los datos correctos!
name: Nombre
swift: Swift
country: País
id: Código de la entidad
</i18n>

View File

@ -4,11 +4,14 @@ import { useI18n } from 'vue-i18n';
import ZoneEventsPanel from './ZoneEventsPanel.vue'; import ZoneEventsPanel from './ZoneEventsPanel.vue';
import ZoneDeliveryCalendar from '../ZoneDeliveryCalendar.vue'; import ZoneDeliveryCalendar from '../ZoneDeliveryCalendar.vue';
import ZoneEventInclusionForm from './ZoneEventInclusionForm.vue';
import ZoneEventExclusionForm from './ZoneEventExclusionForm.vue';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { useWeekdayStore } from 'src/stores/useWeekdayStore'; import { useWeekdayStore } from 'src/stores/useWeekdayStore';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import { reactive } from 'vue';
const { t } = useI18n(); const { t } = useI18n();
const stateStore = useStateStore(); const stateStore = useStateStore();
@ -24,11 +27,16 @@ const days = ref({});
const exclusions = ref({}); const exclusions = ref({});
const geoExclusions = ref({}); const geoExclusions = ref({});
const events = ref([]); const events = ref([]);
const formModeName = ref('include');
const showZoneEventForm = ref(false);
const zoneEventsFormProps = reactive({
isNewMode: true,
date: null,
});
const arrayData = useArrayData('ZoneEvents'); const arrayData = useArrayData('ZoneEvents');
const { store } = arrayData; const { store } = arrayData;
// const urlPath = computed(() => `Zones/${route.params.id}/events`);
const refreshEvents = () => { const refreshEvents = () => {
days.value = {}; days.value = {};
if (!data.value) return; if (!data.value) return;
@ -171,8 +179,29 @@ const step = (direction) => {
date.value = _date; date.value = _date;
}; };
const openEditMode = (mode) => { const openEventIncludeForm = ({ date, isNewMode, event }) => {
console.log('openEditMode', mode); zoneEventsFormProps.date = date;
zoneEventsFormProps.isNewMode = isNewMode;
zoneEventsFormProps.event = event;
showZoneEventForm.value = true;
console.log('zoneEventsFormProps: ', zoneEventsFormProps);
};
const handleEventModeOpen = ({ date, isNewMode, event }) => {
if (formModeName.value === 'include')
openEventIncludeForm({ date, isNewMode, event });
else openEventExcludeForm({ date, isNewMode });
};
const openEventExcludeForm = ({ date, isNewMode }) => {
// zoneEventsFormProps.date = date;
// zoneEventsFormProps.isNewMode = isNewMode;
showZoneEventForm.value = true;
// console.log('zoneEventsFormProps: ', zoneEventsFormProps);
};
const onZoneEventFormClose = () => {
zoneEventsFormProps.date = null;
}; };
onMounted(async () => { onMounted(async () => {
@ -212,7 +241,8 @@ onUnmounted(() => arrayData.destroy());
:first-day="firstDay" :first-day="firstDay"
:last-day="lastDay" :last-day="lastDay"
:events="events" :events="events"
@open-edit-mode="openEditMode" v-model:formModeName="formModeName"
@open-zone-form="openEventIncludeForm"
/> />
</QScrollArea> </QScrollArea>
</QDrawer> </QDrawer>
@ -245,9 +275,19 @@ onUnmounted(() => arrayData.destroy());
:geo-exclusions="geoExclusions" :geo-exclusions="geoExclusions"
:exclusions="exclusions" :exclusions="exclusions"
:days-map="days" :days-map="days"
:form-mode-name="formModeName"
@open-zone-form="handleEventModeOpen"
/> />
</div> </div>
</QCard> </QCard>
<QDialog v-model="showZoneEventForm" @hide="onZoneEventFormClose()">
<ZoneEventInclusionForm
v-if="formModeName === 'include'"
@on-data-saved="refetch()"
v-bind="zoneEventsFormProps"
/>
<ZoneEventExclusionForm v-else />
</QDialog>
</QPage> </QPage>
</template> </template>

View File

@ -1,12 +1,12 @@
<script setup> <script setup>
import { onMounted, ref, computed, nextTick } from 'vue'; import { onMounted, watch, computed, nextTick } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import axios from 'axios'; import axios from 'axios';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import { toDateFormat } from 'src/filters/date.js'; import { toDateFormat, toTimeFormat } from 'src/filters/date.js';
import { toCurrency } from 'filters/index'; import { toCurrency } from 'filters/index';
import { dashIfEmpty } from 'src/filters'; import { dashIfEmpty } from 'src/filters';
import { useWeekdayStore } from 'src/stores/useWeekdayStore'; import { useWeekdayStore } from 'src/stores/useWeekdayStore';
@ -28,9 +28,14 @@ const props = defineProps({
required: true, required: true,
default: () => [], default: () => [],
}, },
formModeName: {
type: String,
required: true,
default: 'include',
},
}); });
const emit = defineEmits(['openEditMode']); const emit = defineEmits(['openZoneForm', 'update:formModeName']);
const { t } = useI18n(); const { t } = useI18n();
const { notify } = useNotify(); const { notify } = useNotify();
@ -38,7 +43,10 @@ const route = useRoute();
const weekdayStore = useWeekdayStore(); const weekdayStore = useWeekdayStore();
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
const editMode = ref('include'); const formName = computed({
get: () => props.formModeName,
set: (value) => emit('update:formModeName', value),
});
const params = computed(() => ({ const params = computed(() => ({
zoneFk: route.params.id, zoneFk: route.params.id,
@ -49,7 +57,16 @@ const arrayData = useArrayData('ZoneEvents', {
params: params, params: params,
url: `Zones/getEventsFiltered`, url: `Zones/getEventsFiltered`,
}); });
const { store } = arrayData;
const startParamsWatcher = () => {
watch(
params,
async () => {
await fetchData();
},
{ deep: true }
);
};
const fetchData = async () => { const fetchData = async () => {
try { try {
@ -81,9 +98,14 @@ const deleteEvent = async (id) => {
} }
}; };
const openEditMode = () => { const openIncludeForm = (event) => {
console.log('editMode.value', editMode.value); console.log('zone event panel EVENT: ', event);
// emit('openEditMode', editMode.value); formName.value = 'include';
emit('openZoneForm', {
date: event.dated,
event,
isNewMode: false,
});
}; };
onMounted(async () => { onMounted(async () => {
@ -91,36 +113,40 @@ onMounted(async () => {
console.log('weekdayStore', weekdayStore.getLocalesMap); console.log('weekdayStore', weekdayStore.getLocalesMap);
await nextTick(); await nextTick();
await fetchData(); await fetchData();
startParamsWatcher();
}); });
</script> </script>
<template> <template>
<pre> {{ params }}</pre>
<QForm @submit="onSubmit()"> <QForm @submit="onSubmit()">
<div class="column q-pa-md q-gutter-y-sm"> <div class="column q-pa-md q-gutter-y-sm">
<span class="color-vn-label">{{ t('eventsPanel.editMode') }}</span> <span class="color-vn-label text-subtitle1">{{
t('eventsPanel.editMode')
}}</span>
<QRadio <QRadio
v-model="editMode" v-model="formName"
dense dense
val="include" val="include"
:label="t('eventsPanel.include')" :label="t('eventsPanel.include')"
/> />
<QRadio <QRadio
v-model="editMode" v-model="formName"
dense dense
val="exclude" val="exclude"
:label="t('eventsPanel.exclude')" :label="t('eventsPanel.exclude')"
class="q-mb-sm" class="q-mb-sm"
/> />
</div> </div>
<span class="color-vn-label q-px-md">{{ t('eventsPanel.events') }}</span> <span class="color-vn-label text-subtitle1 q-px-md">{{
t('eventsPanel.events')
}}</span>
<QList> <QList>
<QItem v-for="(event, index) in events" :key="index" class="event-card"> <QItem v-for="(event, index) in events" :key="index" class="event-card">
<QItemSection left @click="openEditMode()"> <QItemSection left @click="openIncludeForm(event)">
<div v-if="event.type == 'day'" class="vn-mb-sm"> <div v-if="event.type == 'day'" class="q-mb-xs">
{{ toDateFormat(event.dated) }} {{ toDateFormat(event.dated) }}
</div> </div>
<div v-if="event.type != 'day'" class="q-mb-sm"> <div v-if="event.type != 'day'" class="q-mb-xs">
<span v-if="event.weekDays"> <span v-if="event.weekDays">
{{ formatWdays(event) }} {{ formatWdays(event) }}
</span> </span>
@ -132,7 +158,7 @@ onMounted(async () => {
<span class="color-vn-label"> <span class="color-vn-label">
{{ t('eventsPanel.closing') }}: {{ t('eventsPanel.closing') }}:
<span class="color-vn-text q-ml-xs"> <span class="color-vn-text q-ml-xs">
{{ dashIfEmpty(event.hour) }} {{ dashIfEmpty(toTimeFormat(event.hour)) }}
</span> </span>
</span> </span>
<span class="color-vn-label"> <span class="color-vn-label">
@ -143,7 +169,7 @@ onMounted(async () => {
</span> </span>
<span class="color-vn-label"> <span class="color-vn-label">
{{ t('eventsPanel.price') }}: {{ t('eventsPanel.price') }}:
<span class="color-vn-text"> {{ dashIfEmpty(event.price) }}</span> <span class="color-vn-text"> {{ toCurrency(event.price) }}</span>
</span> </span>
<span class="color-vn-label"> <span class="color-vn-label">
{{ t('eventsPanel.bonus') }}: {{ t('eventsPanel.bonus') }}:
@ -154,7 +180,7 @@ onMounted(async () => {
<span class="color-vn-text"> {{ dashIfEmpty(event.m3Max) }}</span> <span class="color-vn-text"> {{ dashIfEmpty(event.m3Max) }}</span>
</span> </span>
</QItemSection> </QItemSection>
<QItemSection side @click="openEditMode()"> <QItemSection side @click="openIncludeForm(event)">
<QBtn <QBtn
icon="delete" icon="delete"
flat flat

View File

@ -36,8 +36,18 @@ const props = defineProps({
type: Object, type: Object,
default: null, default: null,
}, },
isZoneDeliveryView: {
type: Boolean,
default: false,
},
formModeName: {
type: String,
default: 'include',
},
}); });
const emit = defineEmits(['openZoneForm']);
const { locale } = useI18n(); const { locale } = useI18n();
const calendarRef = ref(null); const calendarRef = ref(null);
@ -53,6 +63,8 @@ const todayTimestamp = computed(() => {
const _monthDate = computed(() => date.formatDate(props.monthDate, 'YYYY-MM-DD')); const _monthDate = computed(() => date.formatDate(props.monthDate, 'YYYY-MM-DD'));
const onEventSelection = async ({ year, month, day }) => { const onEventSelection = async ({ year, month, day }) => {
if (!props.isZoneDeliveryView) return;
const date = new Date(year, month - 1, day); const date = new Date(year, month - 1, day);
const stamp = date.getTime(); const stamp = date.getTime();
const events = props.daysMap[stamp]; const events = props.daysMap[stamp];
@ -104,6 +116,20 @@ const isToday = (timestamp) => {
const calendarHeaderTitle = computed(() => { const calendarHeaderTitle = computed(() => {
return `${weekdayStore.getLocaleMonths[props.month - 1].locale} ${props.year}`; return `${weekdayStore.getLocaleMonths[props.month - 1].locale} ${props.year}`;
}); });
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);
emit('openZoneForm', {
date,
isNewMode: !event,
event: event && event.length > 0 ? event[0] : null,
});
};
</script> </script>
<template> <template>
@ -128,6 +154,7 @@ const calendarHeaderTitle = computed(() => {
short-weekday-label short-weekday-label
:locale="locale" :locale="locale"
:now="today" :now="today"
@click-date="handleDateClick($event.scope.timestamp)"
mini-mode mini-mode
> >
<template #day="{ scope: { timestamp } }"> <template #day="{ scope: { timestamp } }">
@ -135,7 +162,11 @@ const calendarHeaderTitle = computed(() => {
<QBtn <QBtn
v-if="getEventByTimestamp(timestamp)" v-if="getEventByTimestamp(timestamp)"
v-bind="{ ...getEventAttrs(timestamp) }" v-bind="{ ...getEventAttrs(timestamp) }"
@click="onEventSelection(timestamp)" @click="
isZoneDeliveryView
? onEventSelection(timestamp)
: handleDateClick(timestamp)
"
rounded rounded
dense dense
flat flat
@ -144,7 +175,7 @@ const calendarHeaderTitle = computed(() => {
'--today': isToday(timestamp), '--today': isToday(timestamp),
}" }"
> >
<QPopupProxy> <QPopupProxy v-if="isZoneDeliveryView">
<ZoneClosingTable <ZoneClosingTable
v-if="zoneClosingData && zoneClosingData.length" v-if="zoneClosingData && zoneClosingData.length"
:rows="zoneClosingData" :rows="zoneClosingData"

View File

@ -231,6 +231,7 @@ onUnmounted(() => arrayData.destroy());
:geo-exclusions="geoExclusions" :geo-exclusions="geoExclusions"
:exclusions="exclusions" :exclusions="exclusions"
:days-map="days" :days-map="days"
is-zone-delivery-view
/> />
</div> </div>
</QCard> </QCard>

View File

@ -79,3 +79,22 @@ eventsPanel:
delete: Delete delete: Delete
deleteTitle: This item will be deleted deleteTitle: This item will be deleted
deleteSubtitle: Are you sure you want to continue? deleteSubtitle: Are you sure you want to continue?
eventsExclusionForm:
addExclusion: Add exclusion
day: Day
all: All
specificLocations: Specific locations
eventsInclusionForm:
addEvent: Add event
editEvent: Edit event
oneDay: One day
indefinitely: Indefinitely
rangeOfDates: Range of dates
day: Day
closing: Closing
travelingDays: Traveling days
price: Price
bonus: Bonus
m3Max: Max m³
from: From
to: To

View File

@ -81,3 +81,22 @@ eventsPanel:
delete: Eliminar delete: Eliminar
deleteTitle: Este elemento será eliminado deleteTitle: Este elemento será eliminado
deleteSubtitle: ¿Seguro que quieres continuar? deleteSubtitle: ¿Seguro que quieres continuar?
eventsExclusionForm:
addExclusion: Añadir exclusión
day: Día
all: Todo
specificLocations: Localizaciones concretas
eventsInclusionForm:
addEvent: Añadir evento
editEvent: Editar evento
oneDay: Un día
indefinitely: Indefinido
rangeOfDates: Rango de fechas
day: Día
closing: Cierre
travelingDays: Días de viaje
price: Precio
bonus: Bonificación
m3Max: Medida máxima
from: Desde
to: Hasta

View File

@ -122,6 +122,28 @@ export const useWeekdayStore = defineStore('weekdayStore', () => {
return wdays; return wdays;
}; };
/**
* Perform the inverse operation of fromSet() method. Transforms an
* array whose indexes are weekday index with selected days set to %true to
* weekday codes separated by commas.
*
* @param {Array<Boolean>} _weekDays Array with selected days set to %true
* @return {String} weekDays Weekday codes separated by commas
*/
const toSet = (_weekDays) => {
let wdays = [];
if (_weekDays) {
for (let i = 0; i < _weekDays.length; i++) {
if (!_weekDays[i]) continue;
let data = weekdays[i];
if (data) wdays.push(data.code);
}
}
return wdays.join(',');
};
return { return {
initStore, initStore,
weekdaysMap, weekdaysMap,
@ -131,6 +153,7 @@ export const useWeekdayStore = defineStore('weekdayStore', () => {
monthCodes, monthCodes,
getLocaleMonths, getLocaleMonths,
fromSet, fromSet,
toSet,
getLocalesMap, getLocalesMap,
}; };
}); });