QCalendar implementation WIP
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
This commit is contained in:
parent
5964189a83
commit
0a74b2a96e
|
@ -32,6 +32,7 @@
|
|||
"@intlify/unplugin-vue-i18n": "^0.8.1",
|
||||
"@pinia/testing": "^0.1.2",
|
||||
"@quasar/app-vite": "^1.7.3",
|
||||
"@quasar/quasar-app-extension-qcalendar": "4.0.0-beta.15",
|
||||
"@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0",
|
||||
"@vue/test-utils": "^2.4.4",
|
||||
"autoprefixer": "^10.4.14",
|
||||
|
|
|
@ -49,6 +49,9 @@ devDependencies:
|
|||
'@quasar/app-vite':
|
||||
specifier: ^1.7.3
|
||||
version: 1.7.3(eslint@8.56.0)(pinia@2.1.7)(quasar@2.14.5)(vue-router@4.2.5)(vue@3.4.19)
|
||||
'@quasar/quasar-app-extension-qcalendar':
|
||||
specifier: 4.0.0-beta.15
|
||||
version: 4.0.0-beta.15
|
||||
'@quasar/quasar-app-extension-testing-unit-vitest':
|
||||
specifier: ^0.4.0
|
||||
version: 0.4.0(@vue/test-utils@2.4.4)(quasar@2.14.5)(vite@5.1.4)(vitest@0.31.4)(vue@3.4.19)
|
||||
|
@ -912,6 +915,13 @@ packages:
|
|||
resolution: {integrity: sha512-SlOhwzXyPQHWgQIS2ncyDdYdksCJvUYNtgsDQqzAKEG3r3d/ejOxvThle79HTK3Q6HB+gQWFG21Ux00Osr5XSw==}
|
||||
dev: false
|
||||
|
||||
/@quasar/quasar-app-extension-qcalendar@4.0.0-beta.15:
|
||||
resolution: {integrity: sha512-i6hQkcP70LXLfVMPZMKQjSg3681gjZmASV3vq6ULzc0LhtBiPneLdVNNtH2itkWxAmaUj+1heQDI5Pa0F7VKLQ==}
|
||||
engines: {node: '>= 10.0.0', npm: '>= 5.6.0', yarn: '>= 1.6.0'}
|
||||
dependencies:
|
||||
'@quasar/quasar-ui-qcalendar': 4.0.0-beta.16
|
||||
dev: true
|
||||
|
||||
/@quasar/quasar-app-extension-testing-unit-vitest@0.4.0(@vue/test-utils@2.4.4)(quasar@2.14.5)(vite@5.1.4)(vitest@0.31.4)(vue@3.4.19):
|
||||
resolution: {integrity: sha512-eyzdUdmZiCueNS+5nedjMmzdbpCetSrtdGIwW6KplW1dTzRbLiNvYUjpBOxQGmJCgEhWy9zuswJ7MZ/bTql24Q==}
|
||||
engines: {node: '>= 12.22.1', npm: '>= 6.14.12', yarn: '>= 1.17.3'}
|
||||
|
@ -939,6 +949,10 @@ packages:
|
|||
- vite
|
||||
dev: true
|
||||
|
||||
/@quasar/quasar-ui-qcalendar@4.0.0-beta.16:
|
||||
resolution: {integrity: sha512-KVbFJD1HQp91tiklv+6XsG7bq8FKK6mhhnoVzmjgoyhUAEb9csfbDPbpegy1/FzXy3o0wITe6mmRZ8nbaiMEZg==}
|
||||
dev: true
|
||||
|
||||
/@quasar/render-ssr-error@1.0.3:
|
||||
resolution: {integrity: sha512-A8RF99q6/sOSe1Ighnh5syEIbliD3qUYEJd2HyfFyBPSMF+WYGXon5dmzg4nUoK662NgOggInevkDyBDJcZugg==}
|
||||
engines: {node: '>= 16'}
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
"options": [
|
||||
"scripts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"@quasar/qcalendar": {}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { QCalendarMonth } from '@quasar/quasar-ui-qcalendar/src/index.js';
|
||||
import '@quasar/quasar-ui-qcalendar/src/QCalendarMonth.sass';
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
const $props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
selectedDates: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
showNavigation: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
activeDate: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
workerTimeControlMails: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'clickDate']);
|
||||
|
||||
const { locale } = useI18n();
|
||||
|
||||
const calendarRef = ref(null);
|
||||
|
||||
const workerTimeControlMailsMap = computed(() => {
|
||||
if (!$props.workerTimeControlMails || $props.workerTimeControlMails.length === 0)
|
||||
return {};
|
||||
const obj = {};
|
||||
return obj;
|
||||
});
|
||||
|
||||
const value = computed({
|
||||
get: () => $props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val),
|
||||
});
|
||||
|
||||
const formattedNavigationLabel = computed(() => {
|
||||
const [year, month, day] = $props.modelValue.split('-');
|
||||
const date = new Date(year, month - 1, day);
|
||||
const _month = date.toLocaleString(locale, { month: 'long' });
|
||||
return `${_month.charAt(0).toUpperCase() + _month.slice(1)} ${year}`;
|
||||
});
|
||||
|
||||
const onPrev = () => {
|
||||
calendarRef.value.prev();
|
||||
};
|
||||
|
||||
const onNext = () => {
|
||||
calendarRef.value.next();
|
||||
};
|
||||
|
||||
const clickDate = (ev) => {
|
||||
emit('clickDate', ev);
|
||||
};
|
||||
|
||||
const workWeeks = ref(null);
|
||||
|
||||
onMounted(async () => {
|
||||
workWeeks.value = document.getElementsByClassName('q-calendar-month__workweek');
|
||||
setTimeout(() => {
|
||||
const firstElement = workWeeks.value[0];
|
||||
console.log('firstElement:: ', firstElement);
|
||||
console.log('workWeeks:: ', workWeeks.value);
|
||||
firstElement.style.backgroundColor = 'lightBlue';
|
||||
firstElement.style.color = 'red';
|
||||
}, 1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="['main-container-background', $q.dark.isActive ? '--dark' : '--light']">
|
||||
<div class="nav-container row">
|
||||
<QIcon name="arrow_back_ios" class="nav-arrow col" @click="onPrev" />
|
||||
<span class="col-6 text-no-wrap text-center text-subtitle1">{{
|
||||
formattedNavigationLabel
|
||||
}}</span>
|
||||
<QIcon name="arrow_forward_ios" class="nav-arrow col" @click="onNext" />
|
||||
</div>
|
||||
<QCalendarMonth
|
||||
ref="calendarRef"
|
||||
show-work-weeks
|
||||
:weekdays="[1, 2, 3, 4, 5, 6, 0]"
|
||||
v-model="value"
|
||||
:selected-dates="selectedDates"
|
||||
:locale="locale"
|
||||
mini-mode
|
||||
enable-outside-days
|
||||
no-active-date
|
||||
@click-date="clickDate"
|
||||
/>
|
||||
|
||||
<pre> {{ workerTimeControlMailsMap }}</pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.main-container-background {
|
||||
&.--dark {
|
||||
background-color: var(--calendar-background-dark);
|
||||
}
|
||||
|
||||
&.--light {
|
||||
background-color: var(--calendar-background);
|
||||
}
|
||||
}
|
||||
|
||||
.confirmed {
|
||||
color: #97b92f;
|
||||
}
|
||||
|
||||
.revise {
|
||||
color: #f61e1e;
|
||||
}
|
||||
|
||||
.sended {
|
||||
color: #d19b25;
|
||||
}
|
||||
|
||||
.nav-container {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-arrow {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.q-calendar__button {
|
||||
&:hover {
|
||||
background-color: var(--vn-accent-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -26,11 +26,11 @@ export function isValidDate(date) {
|
|||
* // returns "02/12/2022"
|
||||
* toDateFormat(new Date(2022, 11, 2));
|
||||
*/
|
||||
export function toDateFormat(date) {
|
||||
export function toDateFormat(date, locale = 'es-ES') {
|
||||
if (!isValidDate(date)) {
|
||||
return '';
|
||||
}
|
||||
return new Date(date).toLocaleDateString('es-ES', {
|
||||
return new Date(date).toLocaleDateString(locale, {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
|
|
|
@ -957,7 +957,7 @@ export default {
|
|||
roadmap: 'Troncales',
|
||||
summary: 'Resumen',
|
||||
basicData: 'Datos básicos',
|
||||
stops: 'Paradas'
|
||||
stops: 'Paradas',
|
||||
},
|
||||
},
|
||||
roadmap: {
|
||||
|
@ -965,7 +965,7 @@ export default {
|
|||
roadmap: 'Troncales',
|
||||
summary: 'Resumen',
|
||||
basicData: 'Datos básicos',
|
||||
stops: 'Paradas'
|
||||
stops: 'Paradas',
|
||||
},
|
||||
},
|
||||
route: {
|
||||
|
|
|
@ -8,6 +8,7 @@ import WorkerTimeHourChip from 'components/WorkerTimeHourChip.vue';
|
|||
import WorkerTimeForm from 'components/WorkerTimeForm.vue';
|
||||
import WorkerTimeReasonForm from 'components/WorkerTimeReasonForm.vue';
|
||||
import WorkerDateLabel from './WorkerDateLabel.vue';
|
||||
import VnCalendarMonth from 'components/common/VnCalendarMonth.vue';
|
||||
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import axios from 'axios';
|
||||
|
@ -19,6 +20,7 @@ import { dashIfEmpty } from 'src/filters';
|
|||
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import { toTimeFormat, secondsToHoursMinutes } from 'filters/date.js';
|
||||
import toDateString from 'filters/toDateString.js';
|
||||
|
||||
const route = useRoute();
|
||||
const { t, locale } = useI18n();
|
||||
|
@ -34,10 +36,7 @@ const { openConfirmationModal } = useVnConfirm();
|
|||
const workerTimeFormDialogRef = ref(null);
|
||||
const workerTimeReasonFormDialogRef = ref(null);
|
||||
const workerHoursRef = ref(null);
|
||||
const calendarRef = ref(null);
|
||||
const selectedDate = ref(null);
|
||||
// Dates formateadas para bindear al componente QDate
|
||||
const selectedCalendarDates = ref([]);
|
||||
const startOfWeek = ref(null);
|
||||
const endOfWeek = ref(null);
|
||||
const selectedWeekNumber = ref(null);
|
||||
|
@ -45,12 +44,17 @@ const state = ref(null);
|
|||
const reason = ref(null);
|
||||
const canResend = ref(null);
|
||||
const weekTotalHours = ref(null);
|
||||
const workerTimeControlMails = ref(null);
|
||||
const workerTimeControlMails = ref([]);
|
||||
const workerTimeFormProps = reactive({
|
||||
dated: null,
|
||||
formType: null,
|
||||
});
|
||||
|
||||
// Array utilizado por QCalendar para seleccionar un rango de fechas
|
||||
const selectedCalendarDates = ref([]);
|
||||
// Date formateada para bindear al componente QDate
|
||||
const selectedDateFormatted = ref(toDateString(Date.vnNew()));
|
||||
|
||||
const arrayData = useArrayData('workerData');
|
||||
|
||||
const worker = computed(() => arrayData.store?.data);
|
||||
|
@ -84,17 +88,12 @@ const formattedWeekTotalHours = computed(() =>
|
|||
secondsToHoursMinutes(weekTotalHours.value)
|
||||
);
|
||||
|
||||
const defaultDate = computed(() => {
|
||||
const date = Date.vnNew();
|
||||
return `${date.getFullYear()}/${(date.getMonth() + 1).toString().padStart(2, '0')}`;
|
||||
});
|
||||
const onInputChange = async (date) => {
|
||||
if (!date) return;
|
||||
|
||||
const onInputChange = async (dates, _, selectedDateDetails) => {
|
||||
if (!dates.length || !selectedDateDetails) return;
|
||||
|
||||
const { year, month, day } = selectedDateDetails;
|
||||
const date = new Date(year, month - 1, day);
|
||||
setDate(date);
|
||||
const { year, month, day } = date.scope.timestamp;
|
||||
const _date = new Date(year, month - 1, day);
|
||||
setDate(_date);
|
||||
};
|
||||
|
||||
const setDate = async (date) => {
|
||||
|
@ -134,19 +133,19 @@ const getEndOfWeek = (startOfWeek) => {
|
|||
|
||||
// Función para obtener las fechas de la semana seleccionada
|
||||
const getWeekDates = (startOfWeek, endOfWeek) => {
|
||||
selectedCalendarDates.value = []; // Limpiar las fechas seleccionadas previamente usadas por QDate
|
||||
selectedCalendarDates.value = []; // Limpiar las fechas seleccionadas previamente usadas por QCalendar
|
||||
weekDays.value = []; // Limpiar la información de las fechas seleccionadas previamente
|
||||
let currentDate = new Date(startOfWeek);
|
||||
|
||||
while (currentDate <= endOfWeek) {
|
||||
// Iterar sobre los días de la semana
|
||||
selectedCalendarDates.value.push(formatDate(currentDate)); // Agregar fecha formateada para el array de fechas bindeado al componente QDate
|
||||
selectedCalendarDates.value.push(formatDate(currentDate)); // Agregar fecha formateada para el array de fechas bindeado al componente QCalendar
|
||||
weekDays.value.push({ dated: new Date(currentDate.getTime()) }); // Agregar el día de la semana al array información de días de la semana
|
||||
currentDate = new Date(currentDate.setDate(currentDate.getDate() + 1)); // Avanzar al siguiente día
|
||||
}
|
||||
};
|
||||
|
||||
// Función para Convertir la fecha al formato que acepta el componente QDate: '2001-01-01'
|
||||
// Función para Convertir la fecha al formato que acepta el componente QCalendar: '2001-01-01'
|
||||
const formatDate = (date) => {
|
||||
return date.toISOString().slice(0, 10);
|
||||
};
|
||||
|
@ -223,10 +222,6 @@ const getAbsences = async () => {
|
|||
if (data) addEvents(data);
|
||||
};
|
||||
|
||||
const hasEvents = (day) => {
|
||||
return day >= startOfWeek.value && day < endOfWeek.value;
|
||||
};
|
||||
|
||||
const addEvents = (data) => {
|
||||
const events = {};
|
||||
|
||||
|
@ -278,6 +273,7 @@ const fetchWorkerTimeControlMails = async (filter) => {
|
|||
params: { filter: JSON.stringify(filter) },
|
||||
});
|
||||
|
||||
console.log('data:: ', data);
|
||||
return data;
|
||||
} catch (err) {
|
||||
console.error('Error fetching worker time control mails');
|
||||
|
@ -295,9 +291,9 @@ const fetchWeekData = async () => {
|
|||
};
|
||||
|
||||
const data = await fetchWorkerTimeControlMails(filter);
|
||||
|
||||
if (!data.length) {
|
||||
state.value = null;
|
||||
return;
|
||||
} else {
|
||||
const [mail] = data;
|
||||
state.value = mail.state;
|
||||
|
@ -336,6 +332,7 @@ const setHours = (data) => {
|
|||
} else weekDay.hours = null;
|
||||
}
|
||||
};
|
||||
|
||||
const getFinishTime = () => {
|
||||
if (!weekDays.value || weekDays.value.length === 0) return;
|
||||
|
||||
|
@ -486,7 +483,7 @@ onMounted(async () => {
|
|||
@click="showReasonForm()"
|
||||
/>
|
||||
<QBtn
|
||||
v-if="isHr && state !== 'CONFIRMED' && canResend"
|
||||
v-if="isHr && state && state !== 'CONFIRMED' && canResend"
|
||||
:label="state ? t('Resend') : t('globals.send')"
|
||||
color="primary"
|
||||
type="submit"
|
||||
|
@ -526,17 +523,12 @@ onMounted(async () => {
|
|||
<span></span>
|
||||
</QCardSection>
|
||||
</div>
|
||||
<QDate
|
||||
ref="calendarRef"
|
||||
:model-value="selectedCalendarDates"
|
||||
@update:model-value="onInputChange"
|
||||
mask="YYYY-MM-DD"
|
||||
color="primary"
|
||||
minimal
|
||||
multiple
|
||||
bordered
|
||||
dense
|
||||
:default-year-month="defaultDate"
|
||||
<VnCalendarMonth
|
||||
v-model:model-value="selectedDateFormatted"
|
||||
:selected-dates="selectedCalendarDates"
|
||||
:active-date="false"
|
||||
:worker-time-control-mails="workerTimeControlMails"
|
||||
@click-date="onInputChange"
|
||||
/>
|
||||
</QDrawer>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
|
@ -622,7 +614,7 @@ onMounted(async () => {
|
|||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
<style scoped lang="scss">
|
||||
.column-title-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -635,13 +627,6 @@ onMounted(async () => {
|
|||
color: var(--vn-label);
|
||||
}
|
||||
|
||||
.q-date,
|
||||
.q-date__content,
|
||||
.q-date__main {
|
||||
max-width: 228px !important;
|
||||
min-width: 228px !important;
|
||||
}
|
||||
|
||||
.hour-chip {
|
||||
margin-bottom: 16px;
|
||||
|
||||
|
|
Loading…
Reference in New Issue