forked from verdnatura/salix-front
Last changes
This commit is contained in:
parent
dae08c322d
commit
4b6038d1d2
|
@ -23,7 +23,8 @@ const businessFk = ref(null);
|
|||
const year = ref(Date.vnNew().getFullYear());
|
||||
const contractHolidays = ref(null);
|
||||
const yearHolidays = ref(null);
|
||||
const events = ref({});
|
||||
const eventsMap = ref({});
|
||||
const festiveEventsMap = ref({});
|
||||
|
||||
const onFetchActiveContract = (data) => {
|
||||
if (!data) return;
|
||||
|
@ -31,21 +32,27 @@ const onFetchActiveContract = (data) => {
|
|||
hasWorkCenter.value = Boolean(data?.workCenterFk);
|
||||
};
|
||||
|
||||
const addEvent = (day, newEvent) => {
|
||||
const addEvent = (day, newEvent, isFestive = false) => {
|
||||
const timestamp = new Date(day).getTime();
|
||||
let event = events.value[timestamp];
|
||||
let event = eventsMap.value[timestamp];
|
||||
|
||||
if (event) {
|
||||
if (!event) {
|
||||
eventsMap.value[timestamp] = newEvent;
|
||||
if (isFestive)
|
||||
festiveEventsMap.value[timestamp] = JSON.parse(JSON.stringify(newEvent));
|
||||
} else {
|
||||
const oldName = event.name;
|
||||
const oldEventWasFestive = event.isFestive;
|
||||
Object.assign(event, newEvent);
|
||||
event.isFestive = oldEventWasFestive;
|
||||
event.name = `${oldName}, ${event.name}`;
|
||||
} else events.value[timestamp] = newEvent;
|
||||
}
|
||||
};
|
||||
|
||||
const onFetchAbsences = (data) => {
|
||||
if (!data) return;
|
||||
|
||||
events.value = {};
|
||||
eventsMap.value = {};
|
||||
|
||||
if (data.holidays) {
|
||||
data.holidays.forEach((holiday) => {
|
||||
|
@ -53,10 +60,14 @@ const onFetchAbsences = (data) => {
|
|||
const holidayType = holiday.type && holiday.type.name;
|
||||
const holidayName = holidayDetail || holidayType;
|
||||
|
||||
addEvent(holiday.dated, {
|
||||
name: holidayName,
|
||||
className: 'festive',
|
||||
});
|
||||
addEvent(
|
||||
holiday.dated,
|
||||
{
|
||||
name: holidayName,
|
||||
isFestive: true,
|
||||
},
|
||||
true
|
||||
);
|
||||
});
|
||||
}
|
||||
if (data.absences) {
|
||||
|
@ -67,10 +78,10 @@ const onFetchAbsences = (data) => {
|
|||
color: type.rgb,
|
||||
type: type.code,
|
||||
absenceId: absence.id,
|
||||
isFestive: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
console.log('events:: ', events.value);
|
||||
};
|
||||
|
||||
const getAbsences = async () => {
|
||||
|
@ -120,7 +131,10 @@ const refreshData = () => {
|
|||
};
|
||||
|
||||
const onDeletedEvent = (timestamp) => {
|
||||
delete events.value[timestamp];
|
||||
delete eventsMap.value[timestamp];
|
||||
// Si el evento que eliminamos se encontraba dentro de un dia festivo, volvemos a agregar el evento festivo
|
||||
if (festiveEventsMap.value[timestamp])
|
||||
eventsMap.value[timestamp] = festiveEventsMap.value[timestamp];
|
||||
};
|
||||
|
||||
watch([year, businessFk], () => refreshData());
|
||||
|
@ -161,6 +175,8 @@ watch([year, businessFk], () => refreshData());
|
|||
v-model:business-fk="businessFk"
|
||||
v-model:year="year"
|
||||
v-model:absence-type="absenceType"
|
||||
:contract-holidays="contractHolidays"
|
||||
:year-holidays="yearHolidays"
|
||||
/>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
|
@ -195,7 +211,7 @@ watch([year, businessFk], () => refreshData());
|
|||
:month="month"
|
||||
:absence-type="absenceType"
|
||||
:business-fk="businessFk"
|
||||
:events="events"
|
||||
:events="eventsMap"
|
||||
@refresh="refreshData"
|
||||
@on-deleted-event="onDeletedEvent"
|
||||
/>
|
||||
|
|
|
@ -20,7 +20,15 @@ const props = defineProps({
|
|||
default: null,
|
||||
},
|
||||
absenceType: {
|
||||
type: Number,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
contractHolidays: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
yearHolidays: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
@ -29,10 +37,7 @@ const emit = defineEmits(['update:businessFk', 'update:year', 'update:absenceTyp
|
|||
|
||||
const selectedBusinessFk = computed({
|
||||
get: () => props.businessFk,
|
||||
set: (value) => {
|
||||
console.log('businessFk', value);
|
||||
emit('update:businessFk', value);
|
||||
},
|
||||
set: (value) => emit('update:businessFk', value),
|
||||
});
|
||||
|
||||
const selectedYear = computed({
|
||||
|
@ -76,42 +81,61 @@ const yearList = ref(generateYears());
|
|||
@on-fetch="(data) => (contractList = data)"
|
||||
auto-load
|
||||
/>
|
||||
<QItem v-if="contractHolidays" class="q-py-md">
|
||||
<QItemSection class="text-center">
|
||||
<p class="holiday-title q-mb-sm">
|
||||
|
||||
<div
|
||||
v-if="contractHolidays"
|
||||
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
||||
style="border: 2px solid black"
|
||||
>
|
||||
<QCardSection horizontal>
|
||||
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
||||
{{ t('Contract') }} #{{ selectedBusinessFk }}
|
||||
</p>
|
||||
<div>
|
||||
</span>
|
||||
</QCardSection>
|
||||
<QCardSection class="column items-center" horizontal>
|
||||
<span>
|
||||
{{ t('Used') }} {{ contractHolidays.holidaysEnjoyed || 0 }} {{ t('of') }}
|
||||
{{ contractHolidays.totalHolidays || 0 }}
|
||||
{{ t('days') }}
|
||||
</div>
|
||||
<div>
|
||||
</span>
|
||||
</QCardSection>
|
||||
<QCardSection class="column items-center" horizontal>
|
||||
<span>
|
||||
{{ t('Spent') }} {{ contractHolidays.hoursEnjoyed || 0 }} {{ t('of') }}
|
||||
{{ contractHolidays.totalHours || 0 }} {{ t('hours') }}
|
||||
</div>
|
||||
<div>
|
||||
</span>
|
||||
</QCardSection>
|
||||
<QCardSection class="column items-center" horizontal>
|
||||
<span>
|
||||
{{ t('Paid holidays') }}
|
||||
{{ contractHolidays.payedHolidays || 0 }}
|
||||
{{ t('days') }}
|
||||
</div>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
<QItem v-if="yearHolidays" class="q-py-md">
|
||||
<QItemSection class="text-center">
|
||||
<p class="holiday-title q-mb-sm">{{ t('Year') }} {{ selectedYear }}</p>
|
||||
<div>
|
||||
</span>
|
||||
</QCardSection>
|
||||
</div>
|
||||
<div
|
||||
v-if="contractHolidays"
|
||||
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
||||
style="border: 2px solid black"
|
||||
>
|
||||
<QCardSection horizontal>
|
||||
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
||||
{{ t('Year') }} {{ selectedYear }}
|
||||
</span>
|
||||
</QCardSection>
|
||||
<QCardSection class="column items-center" horizontal>
|
||||
<span>
|
||||
{{ t('Used') }} {{ yearHolidays.holidaysEnjoyed || 0 }} {{ t('of') }}
|
||||
{{ yearHolidays.totalHolidays || 0 }} {{ t('days') }}
|
||||
</div>
|
||||
<div>
|
||||
</span>
|
||||
</QCardSection>
|
||||
<QCardSection class="column items-center" horizontal>
|
||||
<span>
|
||||
{{ t('Spent') }} {{ yearHolidays.hoursEnjoyed || 0 }} {{ t('of') }}
|
||||
{{ yearHolidays.totalHours || 0 }} {{ t('hours') }}
|
||||
</div>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
</span>
|
||||
</QCardSection>
|
||||
</div>
|
||||
<QList dense class="list q-gutter-y-sm q-my-lg">
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
|
@ -172,17 +196,18 @@ const yearList = ref(generateYears());
|
|||
</QItem>
|
||||
</QList>
|
||||
<QSeparator />
|
||||
<QList dense class="list q-my-lg">
|
||||
<QList dense class="list q-my-lg no-pointer-events">
|
||||
<QItem>
|
||||
<WorkerDateLabel avatar-class="worker-calendar-festive">
|
||||
Festive
|
||||
{{ t('Festive') }}
|
||||
</WorkerDateLabel>
|
||||
<WorkerDateLabel avatar-class="worker-calendar-today">
|
||||
Current day
|
||||
{{ t('Current day') }}
|
||||
</WorkerDateLabel>
|
||||
</QItem>
|
||||
</QList>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.worker-calendar-festive {
|
||||
border: 2px solid $negative;
|
||||
|
@ -192,12 +217,6 @@ const yearList = ref(generateYears());
|
|||
border: 2px solid $info;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.holiday-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { onBeforeMount, ref, watch } from 'vue';
|
||||
import { onBeforeMount, ref, watch, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { date } from 'quasar';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
@ -48,6 +48,12 @@ const weekdayStore = useWeekdayStore();
|
|||
const selectedDate = ref();
|
||||
const calendarEventDates = [];
|
||||
const today = ref(date.formatDate(Date.vnNew(), 'YYYY-MM-DD'));
|
||||
const todayTimestamp = computed(() => {
|
||||
const date = Date.vnNew();
|
||||
date.setHours(0, 0, 0, 0);
|
||||
return date.getTime();
|
||||
});
|
||||
const _year = computed(() => props.year);
|
||||
|
||||
const updateSelectedDate = (year) => {
|
||||
const _date = new Date(year, props.month - 1, 1);
|
||||
|
@ -67,10 +73,9 @@ const createEvent = async (date) => {
|
|||
params
|
||||
);
|
||||
|
||||
console.log('CREATE data:: ', data);
|
||||
if (data) emit('refresh');
|
||||
} catch (error) {
|
||||
console.log('error creating event:: ', error);
|
||||
console.error('error creating event:: ', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -88,12 +93,11 @@ const editEvent = async (event) => {
|
|||
|
||||
if (data) emit('refresh');
|
||||
} catch (error) {
|
||||
console.log('error editing event:: ', error);
|
||||
console.error('error editing event:: ', error);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteEvent = async (event, date) => {
|
||||
console.log('deleteEvent:: ', event);
|
||||
const params = { absenceId: event.absenceId };
|
||||
const { data } = await axios.delete(`Workers/${route.params.id}/deleteAbsence`, {
|
||||
params,
|
||||
|
@ -117,8 +121,14 @@ const handleDateSelected = (date) => {
|
|||
};
|
||||
|
||||
const handleEventSelected = (event, { year, month, day }) => {
|
||||
if (!props.absenceType) {
|
||||
notify(t('Choose an absence type from the right menu'), 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const date = new Date(year, month - 1, day);
|
||||
if (event.type == props.absenceType.code) deleteEvent(event, date);
|
||||
if (!event.absenceId) createEvent(date);
|
||||
else if (event.type == props.absenceType.code) deleteEvent(event, date);
|
||||
else editEvent(event);
|
||||
};
|
||||
|
||||
|
@ -131,20 +141,34 @@ const getEventAttrs = (timestamp) => {
|
|||
const event = getEventByTimestamp(timestamp);
|
||||
if (!event) return {};
|
||||
|
||||
const { name, color } = event;
|
||||
const { name, color, isFestive } = event;
|
||||
|
||||
// Atributos a asignar a cada slot que representa un evento en el calendario
|
||||
return {
|
||||
|
||||
const attrs = {
|
||||
title: name,
|
||||
style: `background-color: ${color};`,
|
||||
style: color ? `background-color: ${color};` : '',
|
||||
label: timestamp.day,
|
||||
};
|
||||
|
||||
if (isFestive) {
|
||||
attrs.class = '--festive';
|
||||
attrs.label = event.absenceId ? timestamp.day : '';
|
||||
}
|
||||
|
||||
return attrs;
|
||||
};
|
||||
|
||||
const isToday = (timestamp) => {
|
||||
const { year, month, day } = timestamp;
|
||||
return todayTimestamp.value === new Date(year, month - 1, day).getTime();
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
updateSelectedDate(props.year);
|
||||
updateSelectedDate(_year.value);
|
||||
});
|
||||
|
||||
watch(props.year, (newValue) => {
|
||||
watch(_year, (newValue) => {
|
||||
updateSelectedDate(newValue);
|
||||
});
|
||||
</script>
|
||||
|
@ -173,16 +197,20 @@ watch(props.year, (newValue) => {
|
|||
>
|
||||
<template #day="{ scope: { timestamp } }">
|
||||
<!-- Este slot representa cada día del calendario y muestra un botón representando el correspondiente evento -->
|
||||
<QButton
|
||||
<QBtn
|
||||
v-if="getEventByTimestamp(timestamp)"
|
||||
v-bind="{ ...getEventAttrs(timestamp) }"
|
||||
@click="
|
||||
handleEventSelected(getEventByTimestamp(timestamp), timestamp)
|
||||
"
|
||||
rounded
|
||||
dense
|
||||
flat
|
||||
class="calendar-event"
|
||||
>
|
||||
{{ timestamp.day }}
|
||||
</QButton>
|
||||
:class="{
|
||||
'--today': isToday(timestamp),
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</QCalendarMonth>
|
||||
</template>
|
||||
|
@ -190,6 +218,11 @@ watch(props.year, (newValue) => {
|
|||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
:root {
|
||||
--calendar-border-current-dark: #84d0e2 2px solid;
|
||||
--calendar-border-current: #84d0e2 2px solid;
|
||||
}
|
||||
|
||||
.q-calendar__button {
|
||||
&:hover {
|
||||
background-color: var(--vn-accent-color);
|
||||
|
@ -197,6 +230,10 @@ watch(props.year, (newValue) => {
|
|||
}
|
||||
}
|
||||
|
||||
.q-calendar__button--bordered {
|
||||
color: $info !important;
|
||||
}
|
||||
|
||||
.q-calendar-month__day--content {
|
||||
position: absolute;
|
||||
top: 1;
|
||||
|
@ -213,13 +250,20 @@ watch(props.year, (newValue) => {
|
|||
.calendar-event {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
font-size: 0.75em;
|
||||
line-height: 1.715em;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
|
||||
&.--today {
|
||||
border: 2px solid $info;
|
||||
}
|
||||
|
||||
&.--festive {
|
||||
border: 2px solid $negative;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
|
|
|
@ -18,7 +18,7 @@ defineEmits(['update:selected']);
|
|||
|
||||
<template>
|
||||
<QChip
|
||||
class="chip glossy"
|
||||
class="chip"
|
||||
:selected="selected"
|
||||
:style="selected ? { backgroundColor: color } : null"
|
||||
@update:selected="$emit('update:selected', $event)"
|
||||
|
@ -26,7 +26,6 @@ defineEmits(['update:selected']);
|
|||
<QAvatar
|
||||
:color="color"
|
||||
:class="avatarClass"
|
||||
class="glossy"
|
||||
:style="{ backgroundColor: color }"
|
||||
/>
|
||||
<slot />
|
||||
|
|
Loading…
Reference in New Issue