feat : ajout d'un onglet formation
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
This commit is contained in:
@@ -49,6 +49,10 @@
|
||||
<div :style="{ backgroundColor: type.color }" class="h-4 w-4 rounded"></div>
|
||||
<p>{{ type.label }}</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="h-4 w-4 rounded bg-indigo-500"></div>
|
||||
<p>FORMATION</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -99,6 +103,8 @@ import {HALF_DAYS} from '~/services/dto/half-day'
|
||||
import {listEmployees, updateEmployeeOrder} from '~/services/employees'
|
||||
import {listAbsenceTypes} from '~/services/absence-types'
|
||||
import {createAbsence, deleteAbsence, listAbsences, updateAbsence} from '~/services/absences'
|
||||
import {listFormationsByDateRange} from '~/services/formations'
|
||||
import type {Formation} from '~/services/dto/formation'
|
||||
import {listPublicHolidays} from '~/services/public-holidays'
|
||||
import {getDaysInMonth, normalizeDate, parseYmd, toYmd} from '~/utils/date'
|
||||
import {compareEmployeesInSite, sortEmployeesBySiteAndOrder} from '~/utils/employee'
|
||||
@@ -163,6 +169,7 @@ const visibleEmployees = computed(() => {
|
||||
// Données de référence et absences du mois affiché.
|
||||
const absenceTypes = ref<AbsenceType[]>([])
|
||||
const absences = ref<Absence[]>([])
|
||||
const formations = ref<Formation[]>([])
|
||||
const publicHolidays = ref<Record<string, string>>({})
|
||||
|
||||
// États UI.
|
||||
@@ -384,12 +391,18 @@ const loadAbsences = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
const loadFormations = async () => {
|
||||
const monthStart = toYmd(selectedYear.value, selectedMonth.value, 1)
|
||||
const monthEnd = toYmd(selectedYear.value, selectedMonth.value + 1, 0)
|
||||
formations.value = await listFormationsByDateRange(monthStart, monthEnd)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([loadEmployees(), loadAbsenceTypes(), loadPublicHolidays(), loadAbsences()])
|
||||
await Promise.all([loadEmployees(), loadAbsenceTypes(), loadPublicHolidays(), loadAbsences(), loadFormations()])
|
||||
})
|
||||
|
||||
watch([selectedMonth, selectedYear, selectedSiteIds], async () => {
|
||||
await loadAbsences()
|
||||
await Promise.all([loadAbsences(), loadFormations()])
|
||||
})
|
||||
|
||||
watch(selectedYear, async () => {
|
||||
@@ -441,6 +454,42 @@ const cellAbsenceMap = computed(() => {
|
||||
return map
|
||||
})
|
||||
|
||||
// Indexation des formations par cellule pour un lookup O(1).
|
||||
const cellFormationMap = computed(() => {
|
||||
const set = new Set<string>()
|
||||
const monthStart = monthStartDate.value
|
||||
const monthEnd = monthEndDate.value
|
||||
|
||||
for (const formation of formations.value) {
|
||||
const employeeId = formation.employee?.id
|
||||
if (!employeeId) continue
|
||||
const startDate = normalizeDate(formation.startDate)
|
||||
const endDate = normalizeDate(formation.endDate)
|
||||
const start = parseYmd(startDate)
|
||||
const end = parseYmd(endDate)
|
||||
if (!start || !end) continue
|
||||
|
||||
const rangeStart = start < monthStart ? monthStart : start
|
||||
const rangeEnd = end > monthEnd ? monthEnd : end
|
||||
if (rangeEnd < rangeStart) continue
|
||||
|
||||
for (
|
||||
let currentDate = new Date(rangeStart.getTime());
|
||||
currentDate <= rangeEnd;
|
||||
currentDate.setDate(currentDate.getDate() + 1)
|
||||
) {
|
||||
const dateKey = toYmd(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate())
|
||||
set.add(`${employeeId}-${dateKey}`)
|
||||
}
|
||||
}
|
||||
|
||||
return set
|
||||
})
|
||||
|
||||
const hasFormationOn = (employeeId: number, date: string): boolean => {
|
||||
return cellFormationMap.value.has(`${employeeId}-${date}`)
|
||||
}
|
||||
|
||||
// Jours fériés (interdit pour la création).
|
||||
const isHolidayDate = (date: string) => {
|
||||
return Boolean(publicHolidays.value[date])
|
||||
@@ -457,7 +506,16 @@ const getCellAbsence = (employeeId: number, date: string) => {
|
||||
}
|
||||
}
|
||||
const absence = cellAbsenceMap.value.get(`${employeeId}-${date}`)
|
||||
if (absence) return absence
|
||||
if (absence) return { ...absence, hasFormation: hasFormationOn(employeeId, date) }
|
||||
if (hasFormationOn(employeeId, date)) {
|
||||
return {
|
||||
id: 0,
|
||||
code: 'F',
|
||||
color: '#6366f1',
|
||||
textColor: '#fff',
|
||||
hasFormation: true
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user