feat(heures) : affichage des jours travaillés (CUSTOM) sur la vue Jour
Auto Tag Develop / tag (push) Successful in 12s
Auto Tag Develop / tag (push) Successful in 12s
Le libellé sous le nom de l'employé affiche en suffixe les jours du planning workDaysHours au format court (ex. BUREAU — CDI — LU,JE) pour les contrats CUSTOM. Résolu à la date filtrée et exposé via WorkHourDayContext.workDaysHours ; formaté front par formatWorkedDaysShort. Limité aux CUSTOM (35h/39h/forfait/intérim sans planning → rien affiché) et à l'écran Heures (pas Heures Conducteurs). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
<span class="font-normal text-neutral-600 text-sm">({{ contractLabel(employee) }})</span>
|
||||
</p>
|
||||
<p class="text-sm text-neutral-500 truncate">
|
||||
{{ employee.site?.name ?? 'Sans site' }}<span v-if="getRowContractNature(employee.id)"> — {{ contractNatureLabel(getRowContractNature(employee.id) ?? undefined) }}</span>
|
||||
{{ employee.site?.name ?? 'Sans site' }}<span v-if="getRowContractNature(employee.id)"> — {{ contractNatureLabel(getRowContractNature(employee.id) ?? undefined) }}</span><span v-if="getRowWorkedDaysLabel(employee.id)"> — {{ getRowWorkedDaysLabel(employee.id) }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
</p>
|
||||
<p class="text-neutral-500 truncate inline-flex items-center gap-2">
|
||||
<span>
|
||||
{{ employee.site?.name ?? 'Sans site' }}<span v-if="getRowContractNature(employee.id)"> — {{ contractNatureLabel(getRowContractNature(employee.id) ?? undefined) }}</span>
|
||||
{{ employee.site?.name ?? 'Sans site' }}<span v-if="getRowContractNature(employee.id)"> — {{ contractNatureLabel(getRowContractNature(employee.id) ?? undefined) }}</span><span v-if="getRowWorkedDaysLabel(employee.id)"> — {{ getRowWorkedDaysLabel(employee.id) }}</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="isAdmin && (rows[employee.id]?.isSiteValid ?? false)"
|
||||
@@ -406,6 +406,7 @@ const props = defineProps<{
|
||||
hasRowFormation: (employeeId: number) => boolean
|
||||
getRowFormationLabel: (employeeId: number) => string
|
||||
getRowContractNature: (employeeId: number) => 'CDI' | 'CDD' | 'INTERIM' | null
|
||||
getRowWorkedDaysLabel: (employeeId: number) => string | null
|
||||
getRowUpdatedAt: (employeeId: number) => string
|
||||
getPresenceDayValue: (employeeId: number) => string
|
||||
onAbsenceClick: (employeeId: number) => void
|
||||
|
||||
@@ -517,6 +517,11 @@ export const useHoursPage = () => {
|
||||
return dayContextByEmployeeId.value.get(employeeId)?.contractNature ?? null
|
||||
}
|
||||
|
||||
// Jours travaillés du planning (contrats CUSTOM uniquement), ex. "LU,VE". null sinon.
|
||||
const getRowWorkedDaysLabel = (employeeId: number): string | null => {
|
||||
return formatWorkedDaysShort(dayContextByEmployeeId.value.get(employeeId)?.workDaysHours)
|
||||
}
|
||||
|
||||
const getRowUpdatedAt = (employeeId: number): string => {
|
||||
const raw = rows.value[employeeId]?.updatedAt
|
||||
if (!raw) return ''
|
||||
@@ -1207,6 +1212,7 @@ export const useHoursPage = () => {
|
||||
hasRowFormation,
|
||||
getRowFormationLabel,
|
||||
getRowContractNature,
|
||||
getRowWorkedDaysLabel,
|
||||
getRowUpdatedAt,
|
||||
getPresenceDayValue,
|
||||
openAbsenceDrawer,
|
||||
|
||||
@@ -29,6 +29,7 @@ export const documentationSections: DocSection[] = [
|
||||
{ type: 'list', content: 'Boutons "Hier" / "Aujourd\'hui" / "Demain" pour naviguer rapidement\nSélecteur de date pour choisir une date spécifique\nFiltrage par site si vous avez accès à plusieurs sites' },
|
||||
{ type: 'paragraph', content: 'Seuls les employés ayant un contrat actif à la date sélectionnée sont affichés.' },
|
||||
{ type: 'note', content: 'Sous le nom de l\'employé, la nature du contrat (CDI / CDD / Intérim) affichée correspond à la période couvrant la date filtrée, et non à aujourd\'hui.' },
|
||||
{ type: 'paragraph', content: 'Pour un contrat à temps partiel avec un planning de jours travaillés (contrat « personnalisé »), les jours travaillés sont rappelés à la suite du libellé site et nature, en abrégé : par exemple « BUREAU — CDI — LU,JE » pour un salarié travaillant le lundi et le jeudi. Les contrats 35h, 39h, forfait et intérim n\'affichent pas ce rappel.' },
|
||||
{ type: 'paragraph', content: 'Sur la vue Jour, l\'affichage (saisie d\'heures ou cases de présence) et le libellé de contrat correspondent au contrat de l\'employé à la date consultée. Si un salarié a changé de type de contrat (par exemple un passage en forfait), les jours antérieurs à ce changement restent affichés selon l\'ancien contrat.' },
|
||||
],
|
||||
},
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
:has-row-formation="hasRowFormation"
|
||||
:get-row-formation-label="getRowFormationLabel"
|
||||
:get-row-contract-nature="getRowContractNature"
|
||||
:get-row-worked-days-label="getRowWorkedDaysLabel"
|
||||
:get-row-updated-at="getRowUpdatedAt"
|
||||
:get-presence-day-value="getPresenceDayValue"
|
||||
:on-absence-click="openAbsenceDrawer"
|
||||
@@ -215,6 +216,7 @@ const {
|
||||
hasRowFormation,
|
||||
getRowFormationLabel,
|
||||
getRowContractNature,
|
||||
getRowWorkedDaysLabel,
|
||||
getRowUpdatedAt,
|
||||
getPresenceDayValue,
|
||||
openAbsenceDrawer,
|
||||
|
||||
@@ -119,6 +119,7 @@ export type WorkHourDayContextRow = {
|
||||
weeklyHours?: number | null
|
||||
contractType?: ContractType | null
|
||||
contractName?: string | null
|
||||
workDaysHours?: Record<number, number> | null
|
||||
}
|
||||
|
||||
export type WorkHourDayContext = {
|
||||
|
||||
@@ -37,6 +37,26 @@ export const requiresWorkDaysHours = (
|
||||
|
||||
const DAY_SHORT_LABELS: Record<number, string> = { 1: 'Lun', 2: 'Mar', 3: 'Mer', 4: 'Jeu', 5: 'Ven' }
|
||||
|
||||
const DAY_TINY_LABELS: Record<number, string> = { 1: 'LU', 2: 'MA', 3: 'ME', 4: 'JE', 5: 'VE' }
|
||||
|
||||
/**
|
||||
* Very compact worked-days summary for the day view header, e.g. "LU,VE".
|
||||
* Lists the iso days actually worked (minutes > 0), uppercase 2-letter, comma-separated.
|
||||
* Returns null when the schedule is empty/unset (non-CUSTOM contracts have no schedule).
|
||||
*/
|
||||
export const formatWorkedDaysShort = (
|
||||
workDaysHours: Record<number, number> | null | undefined
|
||||
): string | null => {
|
||||
if (!workDaysHours) return null
|
||||
const days = Object.entries(workDaysHours)
|
||||
.map(([iso, minutes]) => [Number(iso), Number(minutes)] as const)
|
||||
.filter(([iso, minutes]) => iso >= 1 && iso <= 5 && minutes > 0)
|
||||
.sort(([a], [b]) => a - b)
|
||||
.map(([iso]) => DAY_TINY_LABELS[iso])
|
||||
if (days.length === 0) return null
|
||||
return days.join(',')
|
||||
}
|
||||
|
||||
/**
|
||||
* Compact human-readable summary of a per-day schedule, e.g. "Lun 2h, Jeu 2h".
|
||||
* Returns null when the schedule is empty/unset.
|
||||
|
||||
Reference in New Issue
Block a user