Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
| Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [x] Pas de régression - [ ] TU/TI/TF rédigée - [x] TU/TI/TF OK - [ ] CHANGELOG modifié Reviewed-on: #15 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
133 lines
5.5 KiB
Vue
133 lines
5.5 KiB
Vue
<template>
|
|
<div class="bg-white overflow-hidden flex min-h-0 flex-col">
|
|
<div v-if="isWeekLoading" class="p-6 text-md text-neutral-600">Chargement de la semaine...</div>
|
|
<div v-else class="overflow-y-auto min-h-0">
|
|
<div
|
|
class="grid w-full min-w-0 gap-1 border border-black bg-tertiary-500 px-4 py-3 text-sm font-semibold text-black rounded-t-md sticky top-0 z-10"
|
|
:style="{ gridTemplateColumns: weekGridCols }"
|
|
>
|
|
<span>Nom</span>
|
|
<span v-for="day in weekDayHeaders" :key="day.date" class="text-left">{{ day.weekday }}<br>{{ day.dayDate }}</span>
|
|
<span>Jour/Nuit <br>sem.</span>
|
|
<span>Atelier <br>sem.</span>
|
|
<span>Total <br>sem.</span>
|
|
<span>Total <br>h. supp.</span>
|
|
<span>+25%</span>
|
|
<span>+50%</span>
|
|
<span>Total <br>récup.</span>
|
|
<span>Petit <br>déj.</span>
|
|
<span>Déj.</span>
|
|
<span>Dîner</span>
|
|
<span>Nuit.</span>
|
|
</div>
|
|
|
|
<div class="border-x border-b border-primary-500 rounded-b-md">
|
|
<div
|
|
v-for="row in weeklySummary?.rows ?? []"
|
|
:key="row.employeeId"
|
|
class="grid w-full min-w-0 items-center gap-1 border-b border-primary-500 px-4 py-2 text-sm font-bold text-primary-500 last:border-b-0 hover:bg-tertiary-500"
|
|
:style="{ gridTemplateColumns: weekGridCols }"
|
|
>
|
|
<div class="text-neutral-900 min-w-0">
|
|
<p class="font-semibold truncate">
|
|
{{ row.firstName }} {{ row.lastName }}
|
|
<span class="font-normal text-neutral-600">({{ row.contractName ?? '-' }})</span>
|
|
</p>
|
|
<p class="text-[11px] text-neutral-500 truncate inline-flex items-center gap-2">
|
|
<span>{{ row.siteName ?? 'Sans site' }}<span v-if="row.contractNature"> — {{ contractNatureLabel(row.contractNature) }}</span></span>
|
|
<button v-if="isAdmin" type="button" class="inline-flex items-center justify-center rounded-md p-1 text-white transition-colors" :class="row.comment ? 'bg-red-500 hover:bg-red-600' : 'bg-primary-500 hover:bg-secondary-500'" :title="row.comment ?? 'Ajouter un commentaire'" @click="$emit('open-comment', row)">
|
|
<Icon name="mdi:comment-text-outline" size="12"/>
|
|
</button>
|
|
</p>
|
|
</div>
|
|
|
|
<div
|
|
v-for="daily in row.daily"
|
|
:key="daily.date"
|
|
class="text-left leading-4 rounded-md px-2 py-1"
|
|
:class="daily.hasAbsence ? 'text-white' : ''"
|
|
:style="getDailyCellStyle(daily)"
|
|
:title="cellTitle(daily)"
|
|
>
|
|
<div>J {{ formatMinutes(daily.dayMinutes) }}</div>
|
|
<div>N {{ formatMinutes(daily.nightMinutes) }}</div>
|
|
<div v-if="daily.workshopMinutes">A {{ formatMinutes(daily.workshopMinutes) }}</div>
|
|
<div v-if="daily.hasBreakfast || daily.hasLunch || daily.hasDinner || daily.hasOvernight" class="text-[10px] flex gap-1 mt-0.5">
|
|
<span v-if="daily.hasBreakfast" title="Petit déjeuner">PD</span>
|
|
<span v-if="daily.hasLunch" title="Déjeuner">DJ</span>
|
|
<span v-if="daily.hasDinner" title="Dîner">DI</span>
|
|
<span v-if="daily.hasOvernight" title="Nuitée">NU</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="font-semibold leading-4">
|
|
<div>J {{ formatMinutes(row.weeklyDayMinutes) }}</div>
|
|
<div>N {{ formatMinutes(row.weeklyNightMinutes) }}</div>
|
|
</div>
|
|
<div class="font-semibold">
|
|
{{ formatMinutes(row.weeklyWorkshopMinutes ?? 0) }}
|
|
</div>
|
|
<div class="font-semibold">
|
|
{{ formatMinutes(row.weeklyTotalMinutes) }}
|
|
</div>
|
|
<div class="font-semibold">
|
|
{{ formatMinutes(row.weeklyOvertimeTotalMinutes ?? 0) }}
|
|
</div>
|
|
<div class="font-semibold">
|
|
{{ formatMinutes(row.weeklyOvertime25Minutes ?? 0) }}
|
|
</div>
|
|
<div class="font-semibold">
|
|
{{ formatMinutes(row.weeklyOvertime50Minutes ?? 0) }}
|
|
</div>
|
|
<div class="font-semibold">
|
|
{{ formatMinutes(row.weeklyRecoveryMinutes ?? 0) }}
|
|
</div>
|
|
<div class="font-semibold">{{ row.weeklyBreakfastCount ?? 0 }}</div>
|
|
<div class="font-semibold">{{ row.weeklyLunchCount ?? 0 }}</div>
|
|
<div class="font-semibold">{{ row.weeklyDinnerCount ?? 0 }}</div>
|
|
<div class="font-semibold">{{ row.weeklyOvernightCount ?? 0 }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { WeeklyWorkHourSummary } from '~/services/dto/work-hour'
|
|
import { contractNatureLabel } from '~/utils/contract'
|
|
|
|
const HOLIDAY_BG_COLOR = '#b3e5fc'
|
|
|
|
const getDailyCellStyle = (daily: {
|
|
hasAbsence?: boolean
|
|
absenceColor?: string | null
|
|
holidayLabel?: string | null
|
|
}) => {
|
|
if (daily.hasAbsence) return { backgroundColor: daily.absenceColor || '#dc2626' }
|
|
if (daily.holidayLabel) return { backgroundColor: HOLIDAY_BG_COLOR }
|
|
return undefined
|
|
}
|
|
|
|
const cellTitle = (daily: {
|
|
hasAbsence?: boolean
|
|
absenceLabel?: string | null
|
|
holidayLabel?: string | null
|
|
}) => {
|
|
const parts: string[] = []
|
|
if (daily.absenceLabel) parts.push(daily.absenceLabel)
|
|
if (daily.holidayLabel) parts.push(`Férié : ${daily.holidayLabel}`)
|
|
return parts.join(' — ')
|
|
}
|
|
|
|
defineProps<{
|
|
isWeekLoading: boolean
|
|
isAdmin: boolean
|
|
weekGridCols: string
|
|
weeklySummary: WeeklyWorkHourSummary | null
|
|
weekDayHeaders: Array<{ date: string; weekday: string; dayDate: string }>
|
|
formatMinutes: (minutes: number) => string
|
|
}>()
|
|
|
|
defineEmits<{ (e: 'open-comment', row: WeeklyWorkHourSummary['rows'][number]): void }>()
|
|
</script>
|