From 6baaebf6bd6008cdb2fb93d020810bb5d9c33ea3 Mon Sep 17 00:00:00 2001 From: wbuezas Date: Thu, 14 Mar 2024 09:48:04 -0300 Subject: [PATCH 01/56] WIP --- src/i18n/en/index.js | 10 ++ src/i18n/es/index.js | 10 ++ src/pages/Worker/Card/WorkerTimeControl.vue | 146 ++++++++++++++++++++ src/router/modules/worker.js | 12 +- src/stores/useWeekdayStore.js | 71 ++++++++++ 5 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 src/pages/Worker/Card/WorkerTimeControl.vue create mode 100644 src/stores/useWeekdayStore.js diff --git a/src/i18n/en/index.js b/src/i18n/en/index.js index 0be04003e..558709513 100644 --- a/src/i18n/en/index.js +++ b/src/i18n/en/index.js @@ -835,6 +835,7 @@ export default { workerCreate: 'New worker', department: 'Department', pda: 'PDA', + timeControl: 'Time control', }, list: { name: 'Name', @@ -1201,4 +1202,13 @@ 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', + }, }; diff --git a/src/i18n/es/index.js b/src/i18n/es/index.js index 610c6017f..0a81b7ec5 100644 --- a/src/i18n/es/index.js +++ b/src/i18n/es/index.js @@ -835,6 +835,7 @@ export default { workerCreate: 'Nuevo trabajador', department: 'Departamentos', pda: 'PDA', + timeControl: 'Control de horario', }, list: { name: 'Nombre', @@ -1201,4 +1202,13 @@ 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', + }, }; diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue new file mode 100644 index 000000000..306e7bc54 --- /dev/null +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -0,0 +1,146 @@ + + + + + + + +es: + Entrada: Entrada + Intermedio: Intermedio + Salida: Salida + diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js index 1c722afe8..8d7891b40 100644 --- a/src/router/modules/worker.js +++ b/src/router/modules/worker.js @@ -12,7 +12,7 @@ export default { redirect: { name: 'WorkerMain' }, menus: { main: ['WorkerList', 'WorkerDepartment'], - card: ['WorkerNotificationsManager', 'WorkerPda'], + card: ['WorkerNotificationsManager', 'WorkerPda', 'WorkerTimeControl'], departmentCard: ['BasicData'], }, children: [ @@ -85,6 +85,16 @@ export default { }, component: () => import('src/pages/Worker/Card/WorkerPda.vue'), }, + { + name: 'WorkerTimeControl', + path: 'time-control', + meta: { + title: 'timeControl', + icon: 'access_time', + }, + component: () => + import('src/pages/Worker/Card/WorkerTimeControl.vue'), + }, ], }, ], diff --git a/src/stores/useWeekdayStore.js b/src/stores/useWeekdayStore.js new file mode 100644 index 000000000..2d0078c1e --- /dev/null +++ b/src/stores/useWeekdayStore.js @@ -0,0 +1,71 @@ +import { computed, ref, reactive } from 'vue'; +import { useI18n } from 'vue-i18n'; +import { defineStore } from 'pinia'; + +export const useWeekdayStore = defineStore('weekdayStore', () => { + 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 localeOrder = { + es: ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'], + en: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], + }; + + const { t, locale } = useI18n(); + const localeWeekdays = ref([]); + const weekdaysMap = reactive({}); + + const initStore = () => { + getWeekdaysMap(); + getLocales(); + console.log('weekdaysMap:: ', weekdaysMap); + }; + + 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), + locale: t(`weekdays.${day.code}`), + localeChar: t(`weekdays.${day.code}`).substr(0, 1), + localeAbr: t(`weekdays.${day.code}`).substr(0, 3), + }; + weekdaysMap[day.code] = obj; + }); + }; + + const getLocales = () => { + if (localeWeekdays.value.length > 0) return localeWeekdays.value; + for (let code of localeOrder.es) { + console.log('code:: ', code); + localeWeekdays.value.push(weekdaysMap[code]); + } + console.log('localeWeekdays:: ', localeWeekdays.value); + return localeWeekdays.value; + }; + + // const orderLocales = (weekDaysArray) => { + // const order = localeOrder[locale.value] || localeOrder.en; + // const orderedLocales = []; + // for (let code of order) orderedLocales.push(weekDaysArray[code]); + // // return order.map((code) => localeWeekdays.value.find((day) => day.code === code)); + // }; + + return { + initStore, + getLocales, + localeWeekdays, + weekdaysMap, + }; +}); From c7b60346e9d35bbc49df859ff9db857966e70b02 Mon Sep 17 00:00:00 2001 From: wbuezas Date: Fri, 15 Mar 2024 08:20:48 -0300 Subject: [PATCH 02/56] WIP --- src/pages/Worker/Card/WorkerTimeControl.vue | 169 +++++++++++--------- 1 file changed, 93 insertions(+), 76 deletions(-) diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index 306e7bc54..f273416cc 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -9,19 +9,26 @@ import axios from 'axios'; import { useRole } from 'src/composables/useRole'; import { useWeekdayStore } from 'src/stores/useWeekdayStore'; import { useStateStore } from 'stores/useStateStore'; +import { useState } from 'src/composables/useState'; const route = useRoute(); const { t } = useI18n(); -const { notify } = useNotify(); +// const { notify } = useNotify(); const { hasAny } = useRole(); +const state = useState(); +const user = state.getUser(); const stateStore = useStateStore(); const weekdayStore = useWeekdayStore(); -const entryDirections = [ - { code: 'in', description: t('Entrada') }, - { code: 'middle', description: t('Intermedio') }, - { code: 'out', description: t('Salida') }, -]; +// const entryDirections = [ +// { code: 'in', description: t('Entrada') }, +// { code: 'middle', description: t('Intermedio') }, +// { code: 'out', description: t('Salida') }, +// ]; + +const isHr = computed(() => hasAny(['hr'])); + +const isHimSelf = computed(() => user.value.id === route.params.id); const columns = computed(() => { return weekdayStore.localeWeekdays?.map((day) => { @@ -34,54 +41,74 @@ const columns = computed(() => { }); }); +const fetchWorkerTimeControlRef = ref(null); const calendarRef = ref(null); -const selectedDate = ref(null); -const selectedDateRange = ref(null); +// const selectedDate = ref(null); +const selectedDates = ref([]); +const endOfWeek = ref(null); +const startOfWeek = ref(null); -const handleDateSelection = (date) => { - if (!date) return; - console.log('date', date); +const defaultDate = computed(() => { + const date = Date.vnNew(); + const year = date.getFullYear(); + const month = date.getMonth() + 1; // Nota: getMonth devuelve el mes indexado desde 0 + return `${year}/${month.toString().padStart(2, '0')}`; +}); - const _date = new Date(date.year, date.month - 1, date.day); - console.log('_date', _date); +const handleDateSelection = async (dates, _, selectedDateDetails) => { + if (!dates.length || !selectedDateDetails) return; - const dateRange = { from: '', to: '' }; + const selectedDate = new Date( + selectedDateDetails.year, + selectedDateDetails.month - 1, + selectedDateDetails.day + ); - // Obtener la fecha de 3 días atrás - const threeDaysAgo = new Date(_date); - threeDaysAgo.setDate(_date.getDate() - 3); - dateRange.from = { - year: threeDaysAgo.getFullYear(), - month: threeDaysAgo.getMonth() + 1, // Los meses van de 0 a 11, por eso sumamos 1 - day: threeDaysAgo.getDate(), - }; + // Obtener el día de la semana de la fecha seleccionada (0 = Domingo, 1 = Lunes, ..., 6 = Sábado) + const dayOfWeek = selectedDate.getDay(); - // Obtener la fecha de 3 días adelante - const threeDaysAhead = new Date(_date); - threeDaysAhead.setDate(_date.getDate() + 3); - dateRange.to = { - year: threeDaysAhead.getFullYear(), - month: threeDaysAhead.getMonth() + 1, // Los meses van de 0 a 11, por eso sumamos 1 - day: threeDaysAhead.getDate(), - }; + // Obtener el primer día de la semana (Lunes) + const newStartOfWeek = new Date(selectedDate); + newStartOfWeek.setDate( + selectedDate.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) + ); + startOfWeek.value = newStartOfWeek; - calendarRef.value.setEditingRange(dateRange.from, dateRange.to); - console.log('date range:', dateRange); + // Obtener el último día de la semana (Domingo) + const newEndOfWeek = new Date(newStartOfWeek); + newEndOfWeek.setDate(newStartOfWeek.getDate() + 6); + endOfWeek.value = newEndOfWeek; + + // Crear un array con las fechas de la semana seleccionada + const selectedDatesArray = []; + for ( + let date = new Date(newStartOfWeek); + date <= newEndOfWeek; + date.setDate(date.getDate() + 1) + ) { + selectedDatesArray.push(new Date(date).toISOString().slice(0, 10)); + } + + console.log('start of week:: ', startOfWeek.value); + console.log('new end of week:: ', endOfWeek.value); + + // Asignar el array de fechas de la semana seleccionada al valor reactivo + selectedDates.value = selectedDatesArray; + + setTimeout(async () => { + await fetchWorkerTimeControlRef.value.fetch(); + }, 1); }; -// const isAllowedToEdit = computed(() => hasAny(['hr', 'productionAssi'])); -// const columns = computed(() => [ -// { -// label: 'asd', -// name: 'picture', -// align: 'left', -// }, -// { -// label: t('entry.latestBuys.tags'), -// name: 'tags', -// align: 'left', -// }, -// ]); +const workerTimeControlsFilter = computed(() => ({ + where: { + and: [{ timed: { gte: startOfWeek.value } }, { timed: { lte: endOfWeek.value } }], + }, +})); + +const setWorkerTimeControls = (data) => { + console.log('worker time controls:: ', data); +}; console.log('columns:: ', columns.value); @@ -96,34 +123,28 @@ onMounted(async () => { - + es: From d12fa85d738cac460968e0bbfdde2ba6bcb4a7fd Mon Sep 17 00:00:00 2001 From: wbuezas Date: Fri, 15 Mar 2024 10:20:07 -0300 Subject: [PATCH 03/56] WIP --- src/pages/Worker/Card/WorkerTimeControl.vue | 87 +++++++++++---------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index f273416cc..1eb6049bc 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -19,7 +19,7 @@ const state = useState(); const user = state.getUser(); const stateStore = useStateStore(); const weekdayStore = useWeekdayStore(); - +const weekDays = ref([]); // const entryDirections = [ // { code: 'in', description: t('Entrada') }, // { code: 'middle', description: t('Intermedio') }, @@ -43,61 +43,58 @@ const columns = computed(() => { const fetchWorkerTimeControlRef = ref(null); const calendarRef = ref(null); -// const selectedDate = ref(null); -const selectedDates = ref([]); -const endOfWeek = ref(null); +// Dates formateadas para bindear al componente QDate +const selectedCalendarDates = ref([]); const startOfWeek = ref(null); +const endOfWeek = ref(null); const defaultDate = computed(() => { const date = Date.vnNew(); - const year = date.getFullYear(); - const month = date.getMonth() + 1; // Nota: getMonth devuelve el mes indexado desde 0 - return `${year}/${month.toString().padStart(2, '0')}`; + return `${date.getFullYear()}/${(date.getMonth() + 1).toString().padStart(2, '0')}`; }); const handleDateSelection = async (dates, _, selectedDateDetails) => { if (!dates.length || !selectedDateDetails) return; - const selectedDate = new Date( - selectedDateDetails.year, - selectedDateDetails.month - 1, - selectedDateDetails.day - ); + const { year, month, day } = selectedDateDetails; + const selectedDate = new Date(year, month - 1, day); - // Obtener el día de la semana de la fecha seleccionada (0 = Domingo, 1 = Lunes, ..., 6 = Sábado) + startOfWeek.value = getStartOfWeek(selectedDate); + endOfWeek.value = getEndOfWeek(startOfWeek.value); + + getWeekDates(startOfWeek.value, endOfWeek.value); + + await fetchWorkerTimeControl(); +}; + +const getStartOfWeek = (selectedDate) => { const dayOfWeek = selectedDate.getDay(); + const startOfWeek = new Date(selectedDate); + startOfWeek.setDate(selectedDate.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1)); + return startOfWeek; +}; - // Obtener el primer día de la semana (Lunes) - const newStartOfWeek = new Date(selectedDate); - newStartOfWeek.setDate( - selectedDate.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) - ); - startOfWeek.value = newStartOfWeek; +const getEndOfWeek = (startOfWeek) => { + const endOfWeek = new Date(startOfWeek); + endOfWeek.setDate(startOfWeek.getDate() + 6); + return endOfWeek; +}; - // Obtener el último día de la semana (Domingo) - const newEndOfWeek = new Date(newStartOfWeek); - newEndOfWeek.setDate(newStartOfWeek.getDate() + 6); - endOfWeek.value = newEndOfWeek; +const getWeekDates = (startOfWeek, endOfWeek) => { + selectedCalendarDates.value = []; + let currentDate = new Date(startOfWeek); - // Crear un array con las fechas de la semana seleccionada - const selectedDatesArray = []; - for ( - let date = new Date(newStartOfWeek); - date <= newEndOfWeek; - date.setDate(date.getDate() + 1) - ) { - selectedDatesArray.push(new Date(date).toISOString().slice(0, 10)); + while (currentDate <= endOfWeek) { + selectedCalendarDates.value.push(formatDate(currentDate)); + weekDays.value.push({ + dated: new Date(currentDate.getTime()), + }); + currentDate = new Date(currentDate.setDate(currentDate.getDate() + 1)); } +}; - console.log('start of week:: ', startOfWeek.value); - console.log('new end of week:: ', endOfWeek.value); - - // Asignar el array de fechas de la semana seleccionada al valor reactivo - selectedDates.value = selectedDatesArray; - - setTimeout(async () => { - await fetchWorkerTimeControlRef.value.fetch(); - }, 1); +const formatDate = (date) => { + return date.toISOString().slice(0, 10); }; const workerTimeControlsFilter = computed(() => ({ @@ -106,6 +103,14 @@ const workerTimeControlsFilter = computed(() => ({ }, })); +const fetchWorkerTimeControl = async () => { + try { + await fetchWorkerTimeControlRef.value.fetch(); + } catch (err) { + console.error('Error fetching worker time control'); + } +}; + const setWorkerTimeControls = (data) => { console.log('worker time controls:: ', data); }; @@ -135,7 +140,7 @@ onMounted(async () => { Date: Tue, 19 Mar 2024 13:39:46 -0300 Subject: [PATCH 04/56] WIP --- src/components/WorkerTimeHourChip.vue | 123 +++++ src/composables/useVnConfirm.js | 23 + src/css/app.scss | 4 + src/pages/Worker/Card/WorkerTimeControl.vue | 484 ++++++++++++++++++-- 4 files changed, 588 insertions(+), 46 deletions(-) create mode 100644 src/components/WorkerTimeHourChip.vue create mode 100644 src/composables/useVnConfirm.js diff --git a/src/components/WorkerTimeHourChip.vue b/src/components/WorkerTimeHourChip.vue new file mode 100644 index 000000000..2dedf1be8 --- /dev/null +++ b/src/components/WorkerTimeHourChip.vue @@ -0,0 +1,123 @@ + + + + + + + +es: + Entrada: Entrada + Salida: Salida + Edit: Editar + This time entry will be deleted: Se eliminará la hora fichada + Are you sure you want to delete this entry?: ¿Seguro que quieres eliminarla? + Entry removed: Fichada borrada + diff --git a/src/composables/useVnConfirm.js b/src/composables/useVnConfirm.js new file mode 100644 index 000000000..76c3f4f28 --- /dev/null +++ b/src/composables/useVnConfirm.js @@ -0,0 +1,23 @@ +import VnConfirm from 'components/ui/VnConfirm.vue'; +import { useQuasar } from 'quasar'; + +export function useVnConfirm() { + const quasar = useQuasar(); + + const openConfirmationModal = (title, message, promise, successFn) => { + quasar + .dialog({ + component: VnConfirm, + componentProps: { + title: title, + message: message, + promise: promise, + }, + }) + .onOk(async () => { + if (successFn) successFn(); + }); + }; + + return { openConfirmationModal }; +} diff --git a/src/css/app.scss b/src/css/app.scss index 38dd642a3..388492432 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -97,6 +97,10 @@ select:-webkit-autofill { background-color: var(--vn-light-gray); } +.fill-icon { + font-variation-settings: 'FILL' 1; +} + /* Estilo para el asterisco en campos requeridos */ .q-field.required .q-field__label:after { content: ' *'; diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index 1eb6049bc..212eb0441 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -1,121 +1,404 @@ + + + + +es: + Add time: Añadir hora + Edit entry: Editar entrada + Hour: Hora + Type: Tipo + Entrada: Entrada + Intermedio: Intermedio + Salida: Salida + diff --git a/src/components/WorkerTimeHourChip.vue b/src/components/WorkerTimeHourChip.vue index 2dedf1be8..1a6c60eaa 100644 --- a/src/components/WorkerTimeHourChip.vue +++ b/src/components/WorkerTimeHourChip.vue @@ -22,7 +22,7 @@ const $props = defineProps({ }, }); -const emit = defineEmits(['onHourEntryDeleted']); +const emit = defineEmits(['onHourEntryDeleted', 'showWorkerTimeForm']); const { t } = useI18n(); const { notify } = useNotify(); @@ -57,6 +57,16 @@ const deleteHourEntry = async () => { console.error('Error deleting hour entry'); } }; + +const getChipFormattedHour = (date) => { + //TODO:: Ver si se puede hacer una funcion reutilizable o complementar a utils de dates + const newDate = new Date(date); + const hour = newDate.getHours(); + const min = newDate.getMinutes(); + return `${hour < 10 ? '0' + hour : hour}:${min < 10 ? '0' + min : min}`; +}; + +const showWorkerTimeForm = () => emit('showWorkerTimeForm'); @@ -550,9 +555,6 @@ onMounted(async () => { es: - Entrada: Entrada - Intermedio: Intermedio - Salida: Salida Hours: Horas Total semana: Total semana Termina a las: Termina a las From fc5d858bf16677f408acceaf498896efdf95d6dc Mon Sep 17 00:00:00 2001 From: wbuezas Date: Thu, 21 Mar 2024 08:37:11 -0300 Subject: [PATCH 06/56] WIP --- src/components/FormPopup.vue | 96 ++++++++++++ src/components/WorkerTimeReasonForm.vue | 47 ++++++ src/i18n/en/index.js | 1 + src/i18n/es/index.js | 1 + src/pages/Worker/Card/WorkerTimeControl.vue | 159 +++++++++++++++++--- 5 files changed, 284 insertions(+), 20 deletions(-) create mode 100644 src/components/FormPopup.vue create mode 100644 src/components/WorkerTimeReasonForm.vue diff --git a/src/components/FormPopup.vue b/src/components/FormPopup.vue new file mode 100644 index 000000000..b6eff5d80 --- /dev/null +++ b/src/components/FormPopup.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/src/components/WorkerTimeReasonForm.vue b/src/components/WorkerTimeReasonForm.vue new file mode 100644 index 000000000..2f151dbc8 --- /dev/null +++ b/src/components/WorkerTimeReasonForm.vue @@ -0,0 +1,47 @@ + + + + + +es: + Reason: Motivo + diff --git a/src/i18n/en/index.js b/src/i18n/en/index.js index 558709513..17b042923 100644 --- a/src/i18n/en/index.js +++ b/src/i18n/en/index.js @@ -84,6 +84,7 @@ export default { selectFile: 'Select a file', copyClipboard: 'Copy on clipboard', salesPerson: 'SalesPerson', + send: 'Send', }, errors: { statusUnauthorized: 'Access denied', diff --git a/src/i18n/es/index.js b/src/i18n/es/index.js index 0a81b7ec5..7f46ed3b2 100644 --- a/src/i18n/es/index.js +++ b/src/i18n/es/index.js @@ -84,6 +84,7 @@ export default { selectFile: 'Seleccione un fichero', copyClipboard: 'Copiar en portapapeles', salesPerson: 'Comercial', + send: 'Enviar', }, errors: { statusUnauthorized: 'Acceso denegado', diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index e5eaba648..894f6ccc6 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -6,6 +6,7 @@ import { onMounted, ref, computed, onBeforeMount, nextTick, reactive } from 'vue import FetchData from 'components/FetchData.vue'; import WorkerTimeHourChip from 'components/WorkerTimeHourChip.vue'; import WorkerTimeForm from 'components/WorkerTimeForm.vue'; +import WorkerTimeReasonForm from 'components/WorkerTimeReasonForm.vue'; import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; @@ -14,6 +15,8 @@ import { useWeekdayStore } from 'src/stores/useWeekdayStore'; import { useStateStore } from 'stores/useStateStore'; import { useState } from 'src/composables/useState'; import { dashIfEmpty } from 'src/filters'; +import { useVnConfirm } from 'composables/useVnConfirm'; +import { useArrayData } from 'composables/useArrayData'; const route = useRoute(); const { t } = useI18n(); @@ -24,26 +27,10 @@ const user = _state.getUser(); const stateStore = useStateStore(); const weekdayStore = useWeekdayStore(); const weekDays = ref([]); - -const isHr = computed(() => hasAny(['hr'])); - -const isHimSelf = computed(() => user.value.id === route.params.id); - -const columns = computed(() => { - return weekdayStore.localeWeekdays?.map((day, index) => { - const obj = { - label: day.locale, - formattedDate: getHeaderFormattedDate(weekDays.value[index]?.dated), - name: day.name, - align: 'left', - colIndex: index, - dayData: weekDays.value[index], - }; - return obj; - }); -}); +const { openConfirmationModal } = useVnConfirm(); const workerTimeFormDialogRef = ref(null); +const workerTimeReasonFormDialogRef = ref(null); const workerHoursRef = ref(null); const calendarRef = ref(null); const selectedDate = ref(null); @@ -62,7 +49,27 @@ const workerTimeFormProps = reactive({ formType: null, }); -onMounted(() => setDate(Date.vnNew())); +const arrayData = useArrayData('workerData'); + +const worker = computed(() => arrayData.store?.data); + +const isHr = computed(() => hasAny(['hr'])); + +const isHimSelf = computed(() => user.value.id === route.params.id); + +const columns = computed(() => { + return weekdayStore.localeWeekdays?.map((day, index) => { + const obj = { + label: day.locale, + formattedDate: getHeaderFormattedDate(weekDays.value[index]?.dated), + name: day.name, + align: 'left', + colIndex: index, + dayData: weekDays.value[index], + }; + return obj; + }); +}); const getHeaderFormattedDate = (date) => { //TODO:: Ver si se puede hacer una funcion reutilizable o complementar a utils de dates @@ -307,7 +314,7 @@ const fetchWeekData = async () => { } else { const [mail] = data; state.value = mail.state; - reason.value.value = mail.reason; + reason.value = mail.reason; } await canBeResend(); @@ -403,13 +410,67 @@ const showWorkerTimeForm = (propValue, formType) => { workerTimeFormDialogRef.value.show(); }; +const showReasonForm = () => { + workerTimeReasonFormDialogRef.value.show(); +}; + +const updateWorkerTimeControlMail = async (state, reason) => { + try { + const params = { + workerId: Number(route.params.id), + year: selectedDate.value.getFullYear(), + week: selectedWeekNumber.value, + state, + }; + + if (reason) params.reason = reason; + + await axios.post('WorkerTimeControls/updateWorkerTimeControlMail', params); + await getMailStates(selectedDate.value); + await fetchWeekData(); + notify(t('globals.dataSaved'), 'positive'); + } catch (err) { + console.error('Error updating worker time control mail'); + } +}; + +const isSatisfied = async () => { + await updateWorkerTimeControlMail('CONFIRMED'); +}; + +const isUnsatisfied = async (reason) => { + console.log('unsatiesfied reason:: ', reason); + if (!reason) return; // TODO: Mostrar notify de 'debe haber una razon' + updateWorkerTimeControlMail('REVISE', reason); +}; + +const resendEmail = async () => { + try { + const params = { + recipient: worker.value?.user?.email, + week: selectedWeekNumber.value, + year: selectedDate.value.getFullYear(), + workerId: Number(route.params.id), + state: 'SENDED', + }; + await axios.post('WorkerTimeControls/weekly-hour-hecord-email', params); + await getMailStates(selectedDate.value); + notify(t('Email sended'), 'positive'); + } catch (err) { + console.error('Error sending email'); + } +}; + onBeforeMount(() => { weekdayStore.initStore(); console.log('asdasdasd:: ', weekdayStore); }); onMounted(async () => { + setDate(Date.vnNew()); stateStore.rightDrawer = true; + const test = useArrayData('workerData').store.data; + console.log('test:: ', test); }); @@ -423,6 +484,53 @@ onMounted(async () => { }" @on-fetch="(data) => setHours(data)" /> + +
+ + + + + + {{ state ? t('Resend') : t('globals.send') }} + {{ t('email of this week to the user') }} + + +
+
@@ -520,6 +628,9 @@ onMounted(async () => { + + +
{{ columns }}
@@ -559,4 +670,12 @@ es: Total semana: Total semana Termina a las: Termina a las Add time: Añadir hora + Reason: Motivo + Not satisfied: No conforme + Satisfied: Conforme + Resend: Reenviar + email of this week to the user: email de esta semana al usuario + Email sended: Email enviado + Send time control email: Enviar email control horario + Are you sure you want to send it?: ¿Seguro que quieres enviarlo? From d20828ac7ca21b539e0b5525b726fa8696413e35 Mon Sep 17 00:00:00 2001 From: wbuezas Date: Thu, 21 Mar 2024 13:15:11 -0300 Subject: [PATCH 07/56] remove console.logs --- src/pages/Worker/Card/WorkerTimeControl.vue | 16 +++-------- src/stores/useWeekdayStore.js | 31 ++------------------- 2 files changed, 6 insertions(+), 41 deletions(-) diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index 894f6ccc6..4b2e432d3 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -116,7 +116,6 @@ const setDate = async (date) => { startOfWeek.value = newStartOfWeek; endOfWeek.value = newEndOfWeek; selectedWeekNumber.value = getWeekNumber(newStartOfWeek); // Asignar el número de la semana - console.log('selectedWeekNumber:: ', selectedWeekNumber.value); getWeekDates(newStartOfWeek, newEndOfWeek); @@ -230,7 +229,6 @@ const getAbsences = async () => { }; const { data } = await axios.get('Calendars/absences', { params }); - console.log('absenses:: ', data); if (data) addEvents(data); }; @@ -239,7 +237,6 @@ const hasEvents = (day) => { }; const addEvents = (data) => { - console.log('ADD EVENTS:: '); const events = {}; const addEvent = (day, event) => { @@ -272,7 +269,6 @@ const addEvents = (data) => { const timestamp = day.dated.getTime(); if (events[timestamp]) day.event = events[timestamp]; }); - console.log('weekdays after events:: ', weekDays.value); }; const fetchHours = async () => { @@ -396,12 +392,9 @@ const getMailStates = async (date) => { { params } ); workerTimeControlMails.value = data; - console.log('workerTimeControlMails: ', workerTimeControlMails.value); - // await repaint(); }; const showWorkerTimeForm = (propValue, formType) => { - console.log('workerTimeFormDialogRef:: ', workerTimeFormDialogRef.value); if (formType === 'edit') { workerTimeFormProps.entryId = propValue; } else { @@ -439,8 +432,10 @@ const isSatisfied = async () => { }; const isUnsatisfied = async (reason) => { - console.log('unsatiesfied reason:: ', reason); - if (!reason) return; // TODO: Mostrar notify de 'debe haber una razon' + if (!reason) { + notify(t('You must indicate a reason', 'negative')); + return; + } updateWorkerTimeControlMail('REVISE', reason); }; @@ -463,14 +458,11 @@ const resendEmail = async () => { onBeforeMount(() => { weekdayStore.initStore(); - console.log('asdasdasd:: ', weekdayStore); }); onMounted(async () => { setDate(Date.vnNew()); stateStore.rightDrawer = true; - const test = useArrayData('workerData').store.data; - console.log('test:: ', test); }); diff --git a/src/stores/useWeekdayStore.js b/src/stores/useWeekdayStore.js index 2d0078c1e..cc339a549 100644 --- a/src/stores/useWeekdayStore.js +++ b/src/stores/useWeekdayStore.js @@ -1,4 +1,4 @@ -import { computed, ref, reactive } from 'vue'; +import { reactive } from 'vue'; import { useI18n } from 'vue-i18n'; import { defineStore } from 'pinia'; @@ -13,19 +13,11 @@ export const useWeekdayStore = defineStore('weekdayStore', () => { { code: 'sat', name: 'Saturday' }, ]; - const localeOrder = { - es: ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'], - en: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], - }; - - const { t, locale } = useI18n(); - const localeWeekdays = ref([]); + const { t } = useI18n(); const weekdaysMap = reactive({}); const initStore = () => { getWeekdaysMap(); - getLocales(); - console.log('weekdaysMap:: ', weekdaysMap); }; const getWeekdaysMap = () => { @@ -45,27 +37,8 @@ export const useWeekdayStore = defineStore('weekdayStore', () => { }); }; - const getLocales = () => { - if (localeWeekdays.value.length > 0) return localeWeekdays.value; - for (let code of localeOrder.es) { - console.log('code:: ', code); - localeWeekdays.value.push(weekdaysMap[code]); - } - console.log('localeWeekdays:: ', localeWeekdays.value); - return localeWeekdays.value; - }; - - // const orderLocales = (weekDaysArray) => { - // const order = localeOrder[locale.value] || localeOrder.en; - // const orderedLocales = []; - // for (let code of order) orderedLocales.push(weekDaysArray[code]); - // // return order.map((code) => localeWeekdays.value.find((day) => day.code === code)); - // }; - return { initStore, - getLocales, - localeWeekdays, weekdaysMap, }; }); From f1faf1852369d4089cc15264bddadee1ebe4c263 Mon Sep 17 00:00:00 2001 From: wbuezas Date: Fri, 22 Mar 2024 14:10:00 -0300 Subject: [PATCH 08/56] General improvements --- src/components/WorkerTimeForm.vue | 1 - src/components/WorkerTimeHourChip.vue | 15 ++------ src/filters/date.js | 2 +- src/pages/Worker/Card/WorkerTimeControl.vue | 41 +++++++++------------ src/stores/useWeekdayStore.js | 28 ++++++++++++-- 5 files changed, 46 insertions(+), 41 deletions(-) diff --git a/src/components/WorkerTimeForm.vue b/src/components/WorkerTimeForm.vue index 54462873b..5a70108f5 100644 --- a/src/components/WorkerTimeForm.vue +++ b/src/components/WorkerTimeForm.vue @@ -89,7 +89,6 @@ onBeforeMount(() => { hide-selected :required="true" /> -
{{ workerHourEntry }}
diff --git a/src/components/WorkerTimeHourChip.vue b/src/components/WorkerTimeHourChip.vue index 1a6c60eaa..a2f516098 100644 --- a/src/components/WorkerTimeHourChip.vue +++ b/src/components/WorkerTimeHourChip.vue @@ -4,6 +4,7 @@ import { computed } from 'vue'; import useNotify from 'src/composables/useNotify.js'; import { useVnConfirm } from 'composables/useVnConfirm'; +import { toTimeFormat } from 'filters/date.js'; import axios from 'axios'; const $props = defineProps({ @@ -58,14 +59,6 @@ const deleteHourEntry = async () => { } }; -const getChipFormattedHour = (date) => { - //TODO:: Ver si se puede hacer una funcion reutilizable o complementar a utils de dates - const newDate = new Date(date); - const hour = newDate.getHours(); - const min = newDate.getMinutes(); - return `${hour < 10 ? '0' + hour : hour}:${min < 10 ? '0' + min : min}`; -}; - const showWorkerTimeForm = () => emit('showWorkerTimeForm'); @@ -79,7 +72,7 @@ const showWorkerTimeForm = () => emit('showWorkerTimeForm'); {{ t('Edit') }} {{ - getChipFormattedHour(hour) + toTimeFormat(hour) }} emit('showWorkerTimeForm'); diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index cd37944e8..b08409ddd 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -7,6 +7,7 @@ import FetchData from 'components/FetchData.vue'; import WorkerTimeHourChip from 'components/WorkerTimeHourChip.vue'; import WorkerTimeForm from 'components/WorkerTimeForm.vue'; import WorkerTimeReasonForm from 'components/WorkerTimeReasonForm.vue'; +import WorkerDateLabel from './WorkerDateLabel.vue'; import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; @@ -552,12 +553,15 @@ onMounted(async () => {
{{ t(col.label) }} {{ col.formattedDate }} - - {{ col.dayData.event.name }} - + + {{ col.dayData.event.name }} + +
From 0a74b2a96e37232d5f1322a2ab0a8871720e8165 Mon Sep 17 00:00:00 2001 From: wbuezas Date: Tue, 26 Mar 2024 15:38:06 -0300 Subject: [PATCH 12/56] QCalendar implementation WIP --- package.json | 1 + pnpm-lock.yaml | 14 ++ quasar.extensions.json | 3 +- src/components/common/VnCalendarMonth.vue | 149 ++++++++++++++++++++ src/filters/date.js | 4 +- src/i18n/es/index.js | 4 +- src/pages/Worker/Card/WorkerTimeControl.vue | 69 ++++----- 7 files changed, 197 insertions(+), 47 deletions(-) create mode 100644 src/components/common/VnCalendarMonth.vue diff --git a/package.json b/package.json index a35020b66..f4e0a0690 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f3fe7df55..9dfe836d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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'} diff --git a/quasar.extensions.json b/quasar.extensions.json index e5c5cbfaa..309687b6c 100644 --- a/quasar.extensions.json +++ b/quasar.extensions.json @@ -3,5 +3,6 @@ "options": [ "scripts" ] - } + }, + "@quasar/qcalendar": {} } \ No newline at end of file diff --git a/src/components/common/VnCalendarMonth.vue b/src/components/common/VnCalendarMonth.vue new file mode 100644 index 000000000..24eb65660 --- /dev/null +++ b/src/components/common/VnCalendarMonth.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/src/filters/date.js b/src/filters/date.js index d739aec57..fc341ae32 100644 --- a/src/filters/date.js +++ b/src/filters/date.js @@ -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', diff --git a/src/i18n/es/index.js b/src/i18n/es/index.js index 7b636c2cf..dc4494399 100644 --- a/src/i18n/es/index.js +++ b/src/i18n/es/index.js @@ -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: { diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index b08409ddd..7bedc13d0 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -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()" /> {
-
@@ -622,7 +614,7 @@ onMounted(async () => { - diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index 6b16f5bff..935cef953 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -531,11 +531,10 @@ onMounted(async () => { >
{{ t(col.label) }} - {{ col.formattedDate }} + {{ col.formattedDate }} {{ col.dayData.event.name }} From c4a8127a5b06e0ff1d9b08f7adbbcf446ac22f1c Mon Sep 17 00:00:00 2001 From: wbuezas Date: Fri, 12 Apr 2024 08:24:56 -0300 Subject: [PATCH 25/56] Add toggle right drawer button --- src/pages/Worker/Card/WorkerTimeControl.vue | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index 935cef953..c7f091dc7 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -489,6 +489,23 @@ onMounted(async () => {
+
From 9283b190b01b241bb1e4a98f721a1548a0f3a24b Mon Sep 17 00:00:00 2001 From: wbuezas Date: Fri, 12 Apr 2024 08:35:39 -0300 Subject: [PATCH 26/56] Differentiate manual chips --- src/pages/Worker/Card/WorkerTimeControl.vue | 1 + src/pages/Worker/Card/WorkerTimeHourChip.vue | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index c7f091dc7..6971d3201 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -573,6 +573,7 @@ onMounted(async () => { v-for="(hour, ind) in day.dayData?.hours" :key="ind" :hour="hour.timed" + :manual="hour.manual" :direction="hour.direction" :id="hour.id" @on-hour-entry-deleted="updateData()" diff --git a/src/pages/Worker/Card/WorkerTimeHourChip.vue b/src/pages/Worker/Card/WorkerTimeHourChip.vue index a2f516098..0bd090a80 100644 --- a/src/pages/Worker/Card/WorkerTimeHourChip.vue +++ b/src/pages/Worker/Card/WorkerTimeHourChip.vue @@ -12,6 +12,10 @@ const $props = defineProps({ type: Number, required: true, }, + manual: { + type: Boolean, + required: true, + }, hour: { type: String, required: true, @@ -67,7 +71,12 @@ const showWorkerTimeForm = () => emit('showWorkerTimeForm'); {{ directionIconTooltip }} - + {{ t('Edit') }} @@ -93,10 +102,15 @@ const showWorkerTimeForm = () => emit('showWorkerTimeForm'); diff --git a/src/pages/Worker/Card/WorkerTimeControlCalendar.vue b/src/pages/Worker/Card/WorkerTimeControlCalendar.vue index 4b4edb90e..210bb2619 100644 --- a/src/pages/Worker/Card/WorkerTimeControlCalendar.vue +++ b/src/pages/Worker/Card/WorkerTimeControlCalendar.vue @@ -3,6 +3,7 @@ import { ref, computed, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import { QCalendarMonth } from '@quasar/quasar-ui-qcalendar/src/index.js'; +import QCalendarMonthWrapper from 'src/components/ui/QCalendarMonthWrapper.vue'; const $props = defineProps({ modelValue: { @@ -121,29 +122,33 @@ const paintWorkWeeks = async () => { diff --git a/src/pages/Worker/Card/WorkerTimeControlCalendar.vue b/src/pages/Worker/Card/WorkerTimeControlCalendar.vue index 2e848b7d5..20d02ca78 100644 --- a/src/pages/Worker/Card/WorkerTimeControlCalendar.vue +++ b/src/pages/Worker/Card/WorkerTimeControlCalendar.vue @@ -152,16 +152,6 @@ const paintWorkWeeks = async () => { From 84dfd6d474a8d92c54f603e8fb964f41ebebbc0d Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 18 Apr 2024 08:12:11 +0200 Subject: [PATCH 34/56] hotFix(workerDms): use undefined --- src/components/common/VnDmsList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index f70146c58..e3cb2874a 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -187,7 +187,7 @@ const columns = computed(() => [ downloadFile( prop.row.id, $props.downloadModel, - null, + undefined, prop.row.download ), }, From 69850d65e70c0c7bfb587b88790f358da4308040 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 18 Apr 2024 10:13:36 +0200 Subject: [PATCH 35/56] fix(VnNotes) refs #7226 use v-bind --- src/components/ui/VnNotes.vue | 164 ++++++++++++++++------------------ 1 file changed, 79 insertions(+), 85 deletions(-) diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue index 44ef798ec..081c58f14 100644 --- a/src/components/ui/VnNotes.vue +++ b/src/components/ui/VnNotes.vue @@ -27,93 +27,87 @@ async function insert() { }