WorkerCalendar #270
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"@quasar/testing-unit-vitest": {
|
||||
"options": [
|
||||
"scripts"
|
||||
]
|
||||
}
|
||||
}
|
||||
"@quasar/testing-unit-vitest": {
|
||||
"options": ["scripts"]
|
||||
},
|
||||
"@quasar/qcalendar": {}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<div :class="['main-container-background', $q.dark.isActive ? '--dark' : '--light']">
|
||||
<div class="nav-container row"><slot name="header" /></div>
|
||||
<slot name="calendar" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.main-container-background {
|
||||
&.--dark {
|
||||
background-color: var(--calendar-background-dark);
|
||||
}
|
||||
|
||||
&.--light {
|
||||
background-color: var(--calendar-background);
|
||||
}
|
||||
}
|
||||
|
||||
.nav-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
|
@ -1,5 +1,6 @@
|
|||
// app global css in SCSS form
|
||||
@import './icons.scss';
|
||||
@import '@quasar/quasar-ui-qcalendar/src/QCalendarMonth.sass';
|
||||
|
||||
body.body--light {
|
||||
--fount-color: black;
|
||||
|
@ -120,3 +121,14 @@ input::-webkit-inner-spin-button {
|
|||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
// Clases para modificar el color de fecha seleccionada en componente QCalendarMonth
|
||||
.q-dark div .q-calendar-mini .q-calendar-month__day.q-selected .q-calendar__button {
|
||||
background-color: $primary !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.q-calendar-mini .q-calendar-month__day.q-selected .q-calendar__button {
|
||||
background-color: $primary !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
|
|
@ -1225,4 +1225,27 @@ export default {
|
|||
},
|
||||
iban_tooltip: 'IBAN: ES21 1234 5678 90 0123456789',
|
||||
},
|
||||
weekdays: {
|
||||
sun: 'Sunday',
|
||||
mon: 'Monday',
|
||||
tue: 'Tuesday',
|
||||
wed: 'Wednesday',
|
||||
thu: 'Thursday',
|
||||
fri: 'Friday',
|
||||
sat: 'Saturday',
|
||||
},
|
||||
months: {
|
||||
jan: 'January',
|
||||
feb: 'February',
|
||||
mar: 'March',
|
||||
apr: 'April',
|
||||
may: 'May',
|
||||
jun: 'June',
|
||||
jul: 'July',
|
||||
aug: 'August',
|
||||
sep: 'September',
|
||||
oct: 'October',
|
||||
nov: 'November',
|
||||
dec: 'December',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1225,4 +1225,27 @@ export default {
|
|||
},
|
||||
iban_tooltip: 'IBAN: ES21 1234 5678 90 0123456789',
|
||||
},
|
||||
weekdays: {
|
||||
sun: 'Domingo',
|
||||
mon: 'Lunes',
|
||||
tue: 'Martes',
|
||||
wed: 'Miércoles',
|
||||
thu: 'Jueves',
|
||||
fri: 'Viernes',
|
||||
sat: 'Sábado',
|
||||
},
|
||||
months: {
|
||||
jan: 'Enero',
|
||||
feb: 'Febrero',
|
||||
mar: 'Marzo',
|
||||
apr: 'Abril',
|
||||
may: 'Mayo',
|
||||
jun: 'Junio',
|
||||
jul: 'Julio',
|
||||
aug: 'Agosto',
|
||||
sep: 'Septiembre',
|
||||
oct: 'Octubre',
|
||||
nov: 'Noviembre',
|
||||
dec: 'Diciembre',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,26 +1,35 @@
|
|||
<script setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import WorkerCalendarFilter from 'pages/Worker/Card/WorkerCalendarFilter.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { ref } from 'vue';
|
||||
import WorkerCalendarItem from 'pages/Worker/Card/WorkerCalendarItem.vue';
|
||||
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
|
||||
const stateStore = useStateStore();
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
||||
const workerCalendarFilterRef = ref(null);
|
||||
const workerCalendarRef = ref(null);
|
||||
const businessFk = ref(null);
|
||||
const absenceType = ref(null);
|
||||
const hasWorkCenter = ref(false);
|
||||
const isSubordinate = ref(false);
|
||||
const year = ref(Date.vnNew().getFullYear());
|
||||
const events = ref({});
|
||||
|
||||
const onFetchActiveContract = (data) => {
|
||||
businessFk.value = data?.businessFk;
|
||||
hasWorkCenter.value = Boolean(data?.workCenterFk);
|
||||
};
|
||||
|
||||
const onEventsUpdated = (ev) => (events.value = ev);
|
||||
|
||||
const onHandleRefresh = () => workerCalendarFilterRef.value.refreshData();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -35,7 +44,7 @@ const onFetchActiveContract = (data) => {
|
|||
auto-load
|
||||
/>
|
||||
<template v-if="stateStore.isHeaderMounted()">
|
||||
<Teleport to="#actions-append">
|
||||
<!-- <Teleport to="#actions-append">
|
||||
<div class="row q-gutter-x-sm">
|
||||
<QBtn
|
||||
flat
|
||||
|
@ -49,14 +58,16 @@ const onFetchActiveContract = (data) => {
|
|||
</QTooltip>
|
||||
</QBtn>
|
||||
jsegarra marked this conversation as resolved
Outdated
|
||||
</div>
|
||||
</Teleport>
|
||||
</Teleport> -->
|
||||
</template>
|
||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<WorkerCalendarFilter
|
||||
ref="workerCalendarFilterRef"
|
||||
v-model:business-fk="businessFk"
|
||||
v-model:year="year"
|
||||
v-model:absence-type="absenceType"
|
||||
@update-events="onEventsUpdated"
|
||||
/>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
|
@ -66,15 +77,39 @@ const onFetchActiveContract = (data) => {
|
|||
{{ t('Autonomous worker') }}
|
||||
</QCardSection>
|
||||
</QCard>
|
||||
<QCard class="full-width">
|
||||
<QCardSection class="calendar-container">
|
||||
<div v-for="month in 12" :key="month" class="full-width full-height">
|
||||
<WorkerCalendarItem class="full-width" :year="year" :month="month" />
|
||||
</div>
|
||||
</QCardSection>
|
||||
<QCard v-else class="full-width q-pa-xl">
|
||||
<QIcon
|
||||
v-if="isSubordinate"
|
||||
name="info"
|
||||
size="sm"
|
||||
class="absolute"
|
||||
style="top: 16px; right: 16px"
|
||||
>
|
||||
<QTooltip max-width="250px">
|
||||
{{
|
||||
t(
|
||||
'To start adding absences, click an absence type from the right menu and then on the day you want to add an absence'
|
||||
)
|
||||
}}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
<div class="calendar-container">
|
||||
<WorkerCalendarItem
|
||||
ref="workerCalendarRef"
|
||||
v-for="month in 12"
|
||||
:key="month"
|
||||
:year="year"
|
||||
:month="month"
|
||||
:absence-type="absenceType"
|
||||
:business-fk="businessFk"
|
||||
:events="events"
|
||||
@refresh="onHandleRefresh"
|
||||
/>
|
||||
</div>
|
||||
</QCard>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.calendar-container {
|
||||
display: grid;
|
||||
|
@ -88,19 +123,16 @@ const onFetchActiveContract = (data) => {
|
|||
}
|
||||
}
|
||||
|
||||
@media (max-width: $breakpoint-sm) {
|
||||
@media (max-width: $breakpoint-xs) {
|
||||
.calendar-container {
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
.calendar-item {
|
||||
max-width: 324px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Search worker: Buscar trabajador
|
||||
You can search by worker id or name: Puedes buscar por id o nombre del trabajador
|
||||
To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia
|
||||
</i18n>
|
||||
|
|
|
@ -4,7 +4,7 @@ import FetchData from 'components/FetchData.vue';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { computed, ref, watch, reactive } from 'vue';
|
||||
import { toDateFormat } from '../../../filters/date';
|
||||
import axios from 'axios';
|
||||
|
||||
|
@ -26,7 +26,12 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:businessFk', 'update:year', 'update:absenceType']);
|
||||
const emit = defineEmits([
|
||||
'update:businessFk',
|
||||
'update:year',
|
||||
'update:absenceType',
|
||||
'updateEvents',
|
||||
]);
|
||||
|
||||
const selectedBusinessFk = computed({
|
||||
get: () => props.businessFk,
|
||||
|
@ -35,13 +40,18 @@ const selectedBusinessFk = computed({
|
|||
emit('update:businessFk', value);
|
||||
},
|
||||
});
|
||||
|
||||
const selectedYear = computed({
|
||||
get: () => props.year,
|
||||
set: (value) => emit('update:year', value),
|
||||
});
|
||||
|
||||
const selectedAbsenceType = computed({
|
||||
get: () => props.absenceType,
|
||||
set: (value) => emit('update:absenceType', value),
|
||||
set: (value) => {
|
||||
if (value === props.absenceType) value = null;
|
||||
emit('update:absenceType', value);
|
||||
},
|
||||
});
|
||||
|
||||
const generateYears = () => {
|
||||
|
@ -57,11 +67,19 @@ const yearList = ref(generateYears());
|
|||
|
||||
const contractHolidays = ref(null);
|
||||
const yearHolidays = ref(null);
|
||||
const events = reactive({});
|
||||
const calendar = ref(null);
|
||||
|
||||
const getHolidays = async (params) => {
|
||||
return axios
|
||||
.get(`Workers/${route.params.id}/holidays`, { params })
|
||||
.then((res) => res.data);
|
||||
try {
|
||||
const { data } = await axios.get(`Workers/${route.params.id}/holidays`, {
|
||||
alexm
commented
Este if diria q no hace falta Este if diria q no hace falta
wbuezas
commented
Quitado Commit: Quitado
Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/c12fd772184b8d7a26391c817d96a72004c3b392
|
||||
params,
|
||||
});
|
||||
return data;
|
||||
} catch (error) {
|
||||
alexm
commented
Y este where no debe estar. si no en el desplegable solo me muestra mi contrato actual Y este where no debe estar. si no en el desplegable solo me muestra mi contrato actual
wbuezas
commented
Quitado Commit: También me acabo de dar cuenta que estaba repetido el Commit: Quitado
Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/c12fd772184b8d7a26391c817d96a72004c3b392
También me acabo de dar cuenta que estaba repetido el `businessFk` en `fields`
Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/3d9d444bb425099ed13aeb709c85a7b87bbb3d38
|
||||
console.error('Error fetching holidays:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const updateContractHolidays = async () => {
|
||||
|
@ -75,14 +93,80 @@ const updateYearHolidays = async () => {
|
|||
yearHolidays.value = await getHolidays({ year: selectedYear.value });
|
||||
};
|
||||
|
||||
watch(selectedYear, () => {
|
||||
const getAbsences = async () => {
|
||||
try {
|
||||
const params = {
|
||||
workerFk: route.params.id,
|
||||
businessFk: props.businessFk,
|
||||
year: props.year,
|
||||
};
|
||||
const { data } = await axios.get('Calendars/absences', { params });
|
||||
if (data) onAbsencesFetched(data);
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching absences:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const refreshData = () => {
|
||||
updateYearHolidays();
|
||||
updateContractHolidays();
|
||||
getAbsences();
|
||||
};
|
||||
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
la condicion if está bien? la condicion if está bien?
Porque en el bloque de antes se usaba contractHolidays y ahora yearHolidays
wbuezas
commented
Buena observación, cambie la variable Commit: Buena observación, cambie la variable `contractHolidays` por `yearHolidays`
Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/196679b9e987719569eafcf57963510faf0b4121
|
||||
const onAbsencesFetched = (data) => {
|
||||
calendar.value = data.calendar;
|
||||
|
||||
let addEvent = (day, newEvent) => {
|
||||
const timestamp = new Date(day).getTime();
|
||||
let event = events[timestamp];
|
||||
|
||||
if (event) {
|
||||
const oldName = event.name;
|
||||
Object.assign(event, newEvent);
|
||||
event.name = `${oldName}, ${event.name}`;
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Bien, pero si podemos tener traducción con parámetros quizás mejor Bien, pero si podemos tener traducción con parámetros quizás mejor
wbuezas
commented
Traducciones mejoradas. Commit: Traducciones mejoradas.
Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/881c6e2f7fa214ffa04e461681ad1a4f9823b223
|
||||
} else events[timestamp] = newEvent;
|
||||
};
|
||||
|
||||
if (data.holidays) {
|
||||
data.holidays.forEach((holiday) => {
|
||||
const holidayDetail = holiday.detail && holiday.detail.name;
|
||||
const holidayType = holiday.type && holiday.type.name;
|
||||
const holidayName = holidayDetail || holidayType;
|
||||
|
||||
addEvent(holiday.dated, {
|
||||
name: holidayName,
|
||||
className: 'festive',
|
||||
});
|
||||
});
|
||||
}
|
||||
if (data.absences) {
|
||||
data.absences.forEach((absence) => {
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
valor por defecto puede ir en la declaracion? valor por defecto puede ir en la declaracion?
wbuezas
commented
Valores por default movidos. Commit: Valores por default movidos.
Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/0941d74d528fa910df2061f2f5782c83621ff8e9
|
||||
let type = absence.absenceType;
|
||||
addEvent(absence.dated, {
|
||||
name: type.name,
|
||||
color: type.rgb,
|
||||
type: type.code,
|
||||
absenceId: absence.id,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
emit('updateEvents', events);
|
||||
console.log('events:: ', events);
|
||||
};
|
||||
|
||||
watch(selectedYear, () => {
|
||||
refreshData();
|
||||
});
|
||||
|
||||
watch(selectedBusinessFk, () => {
|
||||
updateYearHolidays();
|
||||
updateContractHolidays();
|
||||
refreshData();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
refreshData,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
<script setup>
|
||||
import { onBeforeMount, ref, watch } from 'vue';
|
||||
import { QCalendarMonth, today } from '@quasar/quasar-ui-qcalendar/src/index.js';
|
||||
import '@quasar/quasar-ui-qcalendar/src/QCalendarVariables.sass';
|
||||
import '@quasar/quasar-ui-qcalendar/src/QCalendarTransitions.sass';
|
||||
import '@quasar/quasar-ui-qcalendar/src/QCalendarMonth.sass';
|
||||
import { date } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { date } from 'quasar';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import QCalendarMonthWrapper from 'src/components/ui/QCalendarMonthWrapper.vue';
|
||||
import { QCalendarMonth } from '@quasar/quasar-ui-qcalendar/src/index.js';
|
||||
import '@quasar/quasar-ui-qcalendar/src/QCalendarVariables.sass';
|
||||
import '@quasar/quasar-ui-qcalendar/src/QCalendarMonth.sass';
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Mmm...ya se esta usando en app.scss no? Mmm...ya se esta usando en app.scss no?
wbuezas
commented
Efectivamente, lo removí. Commit: Efectivamente, lo removí.
Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/3e5a5dfe1c4a238a9ad6292b8bc6b54e50d13cfb
|
||||
|
||||
import { useWeekdayStore } from 'src/stores/useWeekdayStore';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import axios from 'axios';
|
||||
|
||||
const props = defineProps({
|
||||
year: {
|
||||
|
@ -16,41 +22,181 @@ const props = defineProps({
|
|||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
absenceType: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
businessFk: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
events: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const { notify } = useNotify();
|
||||
const { locale } = useI18n();
|
||||
|
||||
const calendarRef = ref(null);
|
||||
const selectedDate = ref(today());
|
||||
const weekdayStore = useWeekdayStore();
|
||||
const selectedDate = ref(null);
|
||||
const calendarEventDates = [];
|
||||
|
||||
const updateSelectedDate = (year) => {
|
||||
const dateObject = Date.vnNew();
|
||||
dateObject.setFullYear(year);
|
||||
dateObject.setMonth(props.month - 1);
|
||||
selectedDate.value = date.formatDate(dateObject, 'YYYY-MM-DD');
|
||||
console.log(date.formatDate(dateObject, 'YYYY-MM-DD'));
|
||||
const _date = new Date(year, props.month - 1, 1);
|
||||
selectedDate.value = date.formatDate(_date, 'YYYY-MM-DD');
|
||||
};
|
||||
|
||||
const createEvent = async (date) => {
|
||||
try {
|
||||
const params = {
|
||||
dated: date,
|
||||
absenceTypeId: props.absenceType,
|
||||
businessFk: props.businessFk,
|
||||
};
|
||||
|
||||
const { data } = await axios.post(
|
||||
`Workers/${route.params.id}/createAbsence`,
|
||||
params
|
||||
);
|
||||
console.log('data:: ', data);
|
||||
// TODO: Agregar notify success
|
||||
emit('refresh');
|
||||
} catch (error) {
|
||||
console.log('error creating event:: ', error);
|
||||
}
|
||||
};
|
||||
|
||||
const editEvent = async (event) => {
|
||||
console.log('editEvent');
|
||||
};
|
||||
|
||||
const deleteEvent = async (date, event) => {
|
||||
console.log('deleteEvent');
|
||||
};
|
||||
|
||||
const handleDateSelected = (date) => {
|
||||
if (!props.absenceType) {
|
||||
notify(t('Choose an absence type from the right menu'), 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const { year, month, day } = date.scope.timestamp;
|
||||
const _date = new Date(year, month - 1, day);
|
||||
const stamp = _date.getTime();
|
||||
const event = props.events[stamp];
|
||||
|
||||
if (event && event.absenceId) {
|
||||
if (event.type == props.absenceType.code) deleteEvent(_date, event);
|
||||
else editEvent(event);
|
||||
} else createEvent(_date);
|
||||
};
|
||||
|
||||
const getEventByTimestamp = ({ year, month, day }) => {
|
||||
const stamp = date.formatDate(new Date(year, month - 1, day), 'x');
|
||||
return props.events[stamp] || null;
|
||||
};
|
||||
|
||||
const getEventAttrs = (timestamp) => {
|
||||
const event = getEventByTimestamp(timestamp);
|
||||
if (!event) return '';
|
||||
|
||||
const { name, color } = event;
|
||||
return {
|
||||
title: name,
|
||||
style: `background-color: ${color};`,
|
||||
};
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
updateSelectedDate(props.year);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.year,
|
||||
(newValue) => {
|
||||
updateSelectedDate(newValue);
|
||||
}
|
||||
);
|
||||
watch(props.year, (newValue) => {
|
||||
updateSelectedDate(newValue);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QCalendarMonth
|
||||
ref="calendarRef"
|
||||
v-model="selectedDate"
|
||||
show-work-weeks
|
||||
no-outside-days
|
||||
:selected-dates="[]"
|
||||
:disabled-weekdays="[0, 6]"
|
||||
:locale="locale"
|
||||
animated
|
||||
mini-mode
|
||||
/>
|
||||
<QCalendarMonthWrapper style="height: 200px">
|
||||
<template #header>
|
||||
<span class="full-width text-center text-body1 q-py-sm">{{
|
||||
weekdayStore.getLocaleMonths[$props.month - 1].locale
|
||||
}}</span>
|
||||
</template>
|
||||
<template #calendar>
|
||||
<QCalendarMonth
|
||||
ref="calendarRef"
|
||||
v-model="selectedDate"
|
||||
@click-date="handleDateSelected"
|
||||
show-work-weeks
|
||||
no-outside-days
|
||||
:selected-dates="calendarEventDates"
|
||||
no-active-date
|
||||
:weekdays="[1, 2, 3, 4, 5, 6, 0]"
|
||||
:disabled-weekdays="[0, 6]"
|
||||
:locale="locale"
|
||||
mini-mode
|
||||
>
|
||||
<template #day="{ scope: { timestamp } }">
|
||||
<QButton
|
||||
v-if="getEventByTimestamp(timestamp)"
|
||||
v-bind="{ ...getEventAttrs(timestamp) }"
|
||||
class="calendar-event"
|
||||
>
|
||||
{{ timestamp.day }}
|
||||
</QButton>
|
||||
</template>
|
||||
</QCalendarMonth>
|
||||
</template>
|
||||
</QCalendarMonthWrapper>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.q-calendar__button {
|
||||
&:hover {
|
||||
background-color: var(--vn-accent-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.q-calendar-month__day--content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.q-outside .calendar-event {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.calendar-event {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
font-size: 0.75em;
|
||||
line-height: 1.715em;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha
|
||||
</i18n>
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
import { reactive, ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export const useWeekdayStore = defineStore('weekdayStore', () => {
|
||||
const { t } = useI18n();
|
||||
|
||||
const weekdays = [
|
||||
{ code: 'sun', name: 'Sunday' },
|
||||
{ code: 'mon', name: 'Monday' },
|
||||
{ code: 'tue', name: 'Tuesday' },
|
||||
{ code: 'wed', name: 'Wednesday' },
|
||||
{ code: 'thu', name: 'Thursday' },
|
||||
{ code: 'fri', name: 'Friday' },
|
||||
{ code: 'sat', name: 'Saturday' },
|
||||
];
|
||||
|
||||
const monthCodes = [
|
||||
'jan',
|
||||
'feb',
|
||||
'mar',
|
||||
'apr',
|
||||
'may',
|
||||
'jun',
|
||||
'jul',
|
||||
'aug',
|
||||
'sep',
|
||||
'oct',
|
||||
'nov',
|
||||
'dec',
|
||||
];
|
||||
|
||||
const localeOrder = {
|
||||
es: ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'],
|
||||
en: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],
|
||||
};
|
||||
|
||||
const weekdaysMap = reactive({});
|
||||
const localeWeekdays = ref([]);
|
||||
|
||||
const initStore = () => {
|
||||
getWeekdaysMap();
|
||||
};
|
||||
|
||||
const getWeekdaysMap = () => {
|
||||
if (Object.keys(weekdaysMap).length > 0) return weekdaysMap;
|
||||
|
||||
weekdays.forEach((day, i) => {
|
||||
const obj = {
|
||||
...day,
|
||||
index: i,
|
||||
char: day.name.substr(0, 1),
|
||||
abr: day.name.substr(0, 3),
|
||||
};
|
||||
weekdaysMap[day.code] = obj;
|
||||
});
|
||||
};
|
||||
|
||||
const getLocales = computed(() => {
|
||||
// El día de mañana esto permitirá ordenar los weekdays en base a el locale si se lo desea reemplazando localeOrder.es por localeOrder[locale]
|
||||
const locales = [];
|
||||
for (let code of localeOrder.es) {
|
||||
const obj = {
|
||||
...weekdaysMap[code],
|
||||
locale: t(`weekdays.${weekdaysMap[code].code}`),
|
||||
localeChar: t(`weekdays.${weekdaysMap[code].code}`).substr(0, 1),
|
||||
localeAbr: t(`weekdays.${weekdaysMap[code].code}`).substr(0, 3),
|
||||
};
|
||||
locales.push(obj);
|
||||
}
|
||||
return locales;
|
||||
});
|
||||
|
||||
const getLocaleMonths = computed(() => {
|
||||
const locales = [];
|
||||
for (let code of monthCodes) {
|
||||
const obj = {
|
||||
code: code,
|
||||
locale: t(`months.${code}`),
|
||||
};
|
||||
locales.push(obj);
|
||||
}
|
||||
return locales;
|
||||
});
|
||||
|
||||
return {
|
||||
initStore,
|
||||
weekdaysMap,
|
||||
localeWeekdays,
|
||||
getLocales,
|
||||
weekdays,
|
||||
monthCodes,
|
||||
getLocaleMonths,
|
||||
};
|
||||
});
|
Loading…
Reference in New Issue
Podemos usar chaining/? hoilday?.detail
Esa parte del código la había copiado exactamente igual a
salix
, aunque me parece bien la idea del chaining y lo apliqué.Commit:
b05c28f571