fix : wip
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="h-full min-h-0 overflow-auto rounded-lg border border-neutral-200 bg-white">
|
||||
<div class="min-w-[900px]">
|
||||
<div class="grid" :style="gridStyle">
|
||||
<div class="grid" :style="gridStyle" @mouseleave="clearHoveredCell">
|
||||
<div
|
||||
class="sticky left-0 top-0 z-30 border-b border-neutral-200 bg-tertiary-500 px-4 py-3 text-md font-semibold text-neutral-700"
|
||||
>
|
||||
@@ -10,16 +10,23 @@
|
||||
<div
|
||||
v-for="day in daysInMonth"
|
||||
:key="day.date"
|
||||
class="sticky top-0 z-20 border-b border-neutral-200 bg-tertiary-500 px-2 py-3 text-center text-xs font-semibold text-neutral-700"
|
||||
class="sticky top-0 z-20 border-b border-neutral-200 px-2 py-3 text-center text-xs font-semibold transition-colors"
|
||||
:class="isHoveredColumn(day.date) ? 'bg-primary-500 text-white' : 'bg-tertiary-500 text-neutral-700'"
|
||||
>
|
||||
<div>{{ day.label }}</div>
|
||||
<div class="text-[10px] text-neutral-500">{{ day.weekday }}</div>
|
||||
<div
|
||||
class="text-[10px]"
|
||||
:class="isHoveredColumn(day.date) ? 'text-white/90' : 'text-neutral-500'"
|
||||
>
|
||||
{{ day.weekday }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-for="employee in visibleEmployees" :key="employee.id">
|
||||
<div
|
||||
class="sticky left-0 z-10 border-b border-neutral-100 px-4 py-3 text-md font-semibold text-black cursor-pointer"
|
||||
:style="{ backgroundColor: employee.site?.color ?? '#304998' }"
|
||||
class="sticky left-0 z-10 border-b border-neutral-100 px-4 py-3 text-md font-semibold text-black cursor-pointer transition-shadow"
|
||||
:class="isHoveredRow(employee.id) ? 'bg-primary-500 text-white ring-2 ring-inset ring-primary-500/40' : ''"
|
||||
:style="rowHeaderStyle(employee)"
|
||||
draggable="true"
|
||||
@dragstart="handleDragStart($event, employee)"
|
||||
@dragover="handleDragOver"
|
||||
@@ -30,12 +37,14 @@
|
||||
<div
|
||||
v-for="day in daysInMonth"
|
||||
:key="employee.id + '-' + day.date"
|
||||
class="border-b border-neutral-300 px-2 py-2 text-center text-xs text-neutral-800 hover:bg-neutral-500"
|
||||
class="border-b border-neutral-300 px-2 py-2 text-center text-xs text-neutral-800 transition-colors"
|
||||
:class="cellContainerClass(employee.id, day.date)"
|
||||
@mouseenter="setHoveredCell(employee.id, day.date)"
|
||||
>
|
||||
<template v-if="getCellInfo(employee.id, day.date)">
|
||||
<button
|
||||
type="button"
|
||||
class="relative flex h-8 w-full items-center justify-center overflow-hidden rounded-md border border-neutral-200 text-[11px] font-semibold text-neutral-800 hover:border-white"
|
||||
class="relative flex h-8 w-full items-center justify-center overflow-hidden rounded-md border border-neutral-200 text-[11px] font-semibold text-neutral-800"
|
||||
:class="isHolidayDate(day.date) ? 'cursor-not-allowed opacity-80' : ''"
|
||||
:style="getCellStyle(employee.id, day.date)"
|
||||
:disabled="isHolidayDate(day.date)"
|
||||
@@ -63,7 +72,7 @@
|
||||
<template v-else>
|
||||
<button
|
||||
type="button"
|
||||
class="relative flex h-8 w-full items-center justify-center rounded-md border border-neutral-200 text-[11px] font-semibold text-neutral-800 bg-white hover:border-white"
|
||||
class="relative flex h-8 w-full items-center justify-center rounded-md border border-neutral-200 text-[11px] font-semibold text-neutral-800 bg-white"
|
||||
:class="isHolidayDate(day.date) ? 'cursor-not-allowed opacity-80' : ''"
|
||||
:style="getCellStyle(employee.id, day.date)"
|
||||
:disabled="isHolidayDate(day.date)"
|
||||
@@ -89,7 +98,7 @@ type DayInfo = {
|
||||
weekday: string
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
daysInMonth: DayInfo[]
|
||||
visibleEmployees: Employee[]
|
||||
gridStyle: Record<string, string>
|
||||
@@ -124,4 +133,56 @@ const handleDrop = (event: DragEvent, employee: Employee) => {
|
||||
if (!dragId || dragId === employee.id) return
|
||||
emit('reorder', { dragId, dropId: employee.id })
|
||||
}
|
||||
|
||||
// Etat de la cellule actuellement survolee.
|
||||
const hoveredEmployeeId = ref<number | null>(null)
|
||||
const hoveredDate = ref<string | null>(null)
|
||||
|
||||
const setHoveredCell = (employeeId: number, date: string) => {
|
||||
hoveredEmployeeId.value = employeeId
|
||||
hoveredDate.value = date
|
||||
}
|
||||
|
||||
const clearHoveredCell = () => {
|
||||
hoveredEmployeeId.value = null
|
||||
hoveredDate.value = null
|
||||
}
|
||||
|
||||
const isHoveredRow = (employeeId: number) => hoveredEmployeeId.value === employeeId
|
||||
|
||||
const isHoveredColumn = (date: string) => hoveredDate.value === date
|
||||
|
||||
// On garde la couleur du site tant que la ligne n'est pas survolee.
|
||||
const rowHeaderStyle = (employee: Employee) => {
|
||||
if (isHoveredRow(employee.id)) return undefined
|
||||
return { backgroundColor: employee.site?.color ?? '#304998' }
|
||||
}
|
||||
|
||||
// Index de ligne par employe pour savoir si une case est "au-dessus" de la case survolee.
|
||||
const employeeIndexById = computed(() => {
|
||||
const indexMap = new Map<number, number>()
|
||||
props.visibleEmployees.forEach((employee, index) => {
|
||||
indexMap.set(employee.id, index)
|
||||
})
|
||||
return indexMap
|
||||
})
|
||||
|
||||
const cellContainerClass = (employeeId: number, date: string) => {
|
||||
if (!hoveredEmployeeId.value || !hoveredDate.value) return 'hover:bg-primary-500'
|
||||
|
||||
const hoveredRowIndex = employeeIndexById.value.get(hoveredEmployeeId.value)
|
||||
const currentRowIndex = employeeIndexById.value.get(employeeId)
|
||||
|
||||
// Forme en L:
|
||||
// - ligne: toutes les cases a gauche (et la case cible)
|
||||
// - colonne: toutes les cases au-dessus (et la case cible)
|
||||
const isOnLeftSegment = isHoveredRow(employeeId) && date <= hoveredDate.value
|
||||
const isOnTopSegment = isHoveredColumn(date)
|
||||
&& typeof hoveredRowIndex === 'number'
|
||||
&& typeof currentRowIndex === 'number'
|
||||
&& currentRowIndex <= hoveredRowIndex
|
||||
|
||||
if (isOnLeftSegment || isOnTopSegment) return 'bg-primary-500'
|
||||
return 'hover:bg-primary-500'
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user