Grille : ordonner les créneaux de nuit après minuit selon la vraie journée

Un créneau type commençant avant la frontière du jour (le plus petit
`order`, ex. « Nuit » 00 h–03 h après « Soirée » 19 h–00 h) était généré
sur la même date calendaire que la soirée elle-même au lieu du lendemain,
et s'affichait donc avant 19 h/22 h/23 h dans la grille des besoins au
lieu d'après 23 h. Corrigé dans la génération des créneaux
(_shiftgen.py, même frontière que validation.engine._day_boundary) et
dans le regroupement/tri de la grille (planning.ts : `dayBoundary`
calculé depuis les créneaux types).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
AdamThomas
2026-09-17 22:59:17 +02:00
co-authored by Claude Sonnet 5
parent f565feb3bc
commit 4bcdafca96
6 changed files with 128 additions and 24 deletions
+12 -4
View File
@@ -1,17 +1,24 @@
import { useMemo, useState } from 'react';
import { useAssignments, useMatrix, useRunSolver, useVolunteers } from '@/api/hooks';
import { useAssignments, useDayParts, useMatrix, useRunSolver, useVolunteers } from '@/api/hooks';
import type { MatrixPosition, MatrixShift, PositionCategory } from '@/api/schema';
import { Chip, HelpTip } from '@/components/ui';
import { EmptyNote, ErrorNote, Loading } from '@/components/state';
import { AssignmentPanel } from '@/pages/grille/AssignmentPanel';
import { categoryLabel, columnWidthPx, latticeFromMatrix, type LatticeColumn } from '@/lib/planning';
import {
categoryLabel,
columnWidthPx,
dayBoundaryFromDayParts,
latticeFromMatrix,
type LatticeColumn,
} from '@/lib/planning';
import { datePart, shortDayLabel, timePart } from '@/lib/time';
import { t } from '@/i18n';
import { cx } from '@/lib/cx';
export function GrillePage() {
const matrix = useMatrix();
const dayParts = useDayParts();
const runSolver = useRunSolver();
const assignments = useAssignments();
const volunteers = useVolunteers();
@@ -19,9 +26,10 @@ export function GrillePage() {
const [categoryFilter, setCategoryFilter] = useState<'all' | PositionCategory>('all');
const [selectedShiftId, setSelectedShiftId] = useState<string | null>(null);
const dayBoundary = useMemo(() => dayBoundaryFromDayParts(dayParts.data ?? []), [dayParts.data]);
const lattice = useMemo(
() => (matrix.data ? latticeFromMatrix(matrix.data) : { days: [], columns: [] }),
[matrix.data],
() => (matrix.data ? latticeFromMatrix(matrix.data, dayBoundary) : { days: [], columns: [] }),
[matrix.data, dayBoundary],
);
// Noms des bénévoles affectés, par créneau — pour l'aperçu au survol d'une