salix-front/src/components/EntityCalendarGrid.vue

126 lines
3.1 KiB
Vue

<script setup>
import { computed, onMounted, ref, onUnmounted, nextTick } from 'vue';
import { useStateStore } from 'stores/useStateStore';
import { useWeekdayStore } from 'src/stores/useWeekdayStore';
import { useArrayData } from 'src/composables/useArrayData';
const props = defineProps({
dataKey: {
type: String,
required: true,
},
calendarComponent: {
type: Object,
required: true,
},
additionalProps: {
type: Object,
default: () => ({}),
}
});
const stateStore = useStateStore();
const weekdayStore = useWeekdayStore();
const nMonths = ref(4);
const _date = ref(Date.vnNew());
const firstDay = ref(Date.vnNew());
const lastDay = ref(Date.vnNew());
const months = ref([]);
const arrayData = useArrayData(props.dataKey);
onMounted(async () => {
const initialDate = Date.vnNew();
initialDate.setDate(1);
initialDate.setHours(0, 0, 0, 0);
date.value = initialDate;
await nextTick();
stateStore.rightDrawer = true;
});
onUnmounted(() => arrayData.destroy());
const emit = defineEmits([
'update:firstDay',
'update:lastDay',
'update:events',
'onDateSelected',
]);
const date = computed({
get: () => _date.value,
set: (value) => {
if (!(value instanceof Date)) return;
_date.value = value;
const stamp = value.getTime();
firstDay.value = new Date(stamp);
firstDay.value.setDate(1);
lastDay.value = new Date(stamp);
lastDay.value.setMonth(lastDay.value.getMonth() + nMonths.value);
lastDay.value.setDate(0);
months.value = [];
for (let i = 0; i < nMonths.value; i++) {
const monthDate = new Date(stamp);
monthDate.setMonth(value.getMonth() + i);
months.value.push(monthDate);
}
emit('update:firstDay', firstDay.value);
emit('update:lastDay', lastDay.value);
emit('refresh-events');
},
});
const headerTitle = computed(() => {
if (!months.value?.length) return '';
const getMonthName = date =>
`${weekdayStore.getLocaleMonths[date.getMonth()].locale} ${date.getFullYear()}`;
return `${getMonthName(months.value[0])} - ${getMonthName(months.value[months.value.length - 1])}`;
});
const step = (direction) => {
const newDate = new Date(date.value);
newDate.setMonth(newDate.getMonth() + nMonths.value * direction);
date.value = newDate;
};
defineExpose({
firstDay,
lastDay
});
</script>
<template>
<QCard style="height: max-content">
<div class="calendars-header">
<QBtn
icon="arrow_left"
size="sm"
flat
class="full-height"
@click="step(-1)"
/>
<span>{{ headerTitle }}</span>
<QBtn
icon="arrow_right"
size="sm"
flat
class="full-height"
@click="step(1)"
/>
</div>
<div class="calendars-container">
<component
:is="calendarComponent"
v-for="(month, index) in months"
:key="index"
:month="month.getMonth() + 1"
:year="month.getFullYear()"
:month-date="month"
v-bind="additionalProps"
@on-date-selected="data => emit('onDateSelected', data)"
/>
</div>
</QCard>
</template>