Checkpoint: Remplacement de bg-inherit par des couleurs de fond explicites (hsl CSS vars) sur toutes les cellules sticky (Code, Établissement, Total) dans le tableau OPEX vue Établissements. Ajout de border-separate + border-spacing-0 sur le tableau et d'ombres portées pour matérialiser la séparation visuelle lors du scroll horizontal.

This commit is contained in:
Manus
2026-06-10 09:01:42 +00:00
parent 3145e9c84f
commit 8de20ba62e

View File

@@ -1249,11 +1249,11 @@ export default function DsiOpex() {
{/* Tableau scrollable horizontalement avec tous les postes */} {/* Tableau scrollable horizontalement avec tous les postes */}
<div className="bg-card border border-border rounded-xl overflow-hidden"> <div className="bg-card border border-border rounded-xl overflow-hidden">
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="text-xs" style={{ minWidth: 'max-content', width: '100%' }}> <table className="text-xs border-separate border-spacing-0" style={{ minWidth: 'max-content', width: '100%' }}>
<thead> <thead>
<tr className="border-b border-border bg-muted/40"> <tr className="border-b border-border bg-muted/40">
<th className="text-left px-3 py-3 font-medium text-muted-foreground sticky left-0 bg-muted/40 z-10 min-w-[80px]">Code</th> <th className="text-left px-3 py-3 font-medium text-muted-foreground sticky left-0 z-20 min-w-[80px]" style={{ background: 'hsl(var(--muted) / 0.4)', boxShadow: '2px 0 0 0 hsl(var(--border))' }}>Code</th>
<th className="text-left px-3 py-3 font-medium text-muted-foreground sticky left-[80px] bg-muted/40 z-10 min-w-[200px]"> <th className="text-left px-3 py-3 font-medium text-muted-foreground sticky left-[80px] z-20 min-w-[200px]" style={{ background: 'hsl(var(--muted) / 0.4)', boxShadow: '2px 0 4px -2px rgba(0,0,0,0.15)' }}>
<SortBtn col="nom" label="Établissement" /> <SortBtn col="nom" label="Établissement" />
</th> </th>
{/* Colonnes postes — vert = prorata auto, bleu = manuel */} {/* Colonnes postes — vert = prorata auto, bleu = manuel */}
@@ -1285,10 +1285,10 @@ export default function DsiOpex() {
<tbody> <tbody>
{sortedEtabs.map((etab, idx) => ( {sortedEtabs.map((etab, idx) => (
<tr key={etab.code} className={`border-b border-border/50 hover:bg-muted/20 transition-colors ${idx % 2 === 0 ? '' : 'bg-muted/5'}`}> <tr key={etab.code} className={`border-b border-border/50 hover:bg-muted/20 transition-colors ${idx % 2 === 0 ? '' : 'bg-muted/5'}`}>
<td className="px-3 py-2 sticky left-0 bg-inherit z-10"> <td className="px-3 py-2 sticky left-0 z-10 whitespace-nowrap" style={{ background: idx % 2 === 0 ? 'hsl(var(--card))' : 'hsl(var(--muted) / 0.05)', boxShadow: '2px 0 0 0 hsl(var(--border))' }}>
<span className="font-mono bg-muted px-1.5 py-0.5 rounded text-muted-foreground">{etab.code}</span> <span className="font-mono bg-muted px-1.5 py-0.5 rounded text-muted-foreground">{etab.code}</span>
</td> </td>
<td className="px-3 py-2 font-medium text-foreground sticky left-[80px] bg-inherit z-10 whitespace-nowrap">{etab.nom}</td> <td className="px-3 py-2 font-medium text-foreground sticky left-[80px] z-10 whitespace-nowrap" style={{ background: idx % 2 === 0 ? 'hsl(var(--card))' : 'hsl(var(--muted) / 0.05)', boxShadow: '2px 0 4px -2px rgba(0,0,0,0.15)' }}>{etab.nom}</td>
{opexState.lignes.map(ligne => { {opexState.lignes.map(ligne => {
const srcPoste = getOpexDataForAnnee(annee).postes.find(p => p.libelle === ligne.libelle); const srcPoste = getOpexDataForAnnee(annee).postes.find(p => p.libelle === ligne.libelle);
const isManuel = srcPoste?.mode_ventilation === 'Manuel' || ligne.isCustom; const isManuel = srcPoste?.mode_ventilation === 'Manuel' || ligne.isCustom;
@@ -1341,7 +1341,7 @@ export default function DsiOpex() {
</td> </td>
); );
})} })}
<td className="px-3 py-2 text-right font-semibold tabular-nums sticky right-0 bg-card z-10 border-l border-border"> <td className="px-3 py-2 text-right font-semibold tabular-nums sticky right-0 z-10 border-l border-border" style={{ background: idx % 2 === 0 ? 'hsl(var(--card))' : 'hsl(var(--muted) / 0.05)', boxShadow: '-2px 0 4px -2px rgba(0,0,0,0.15)' }}>
<span className={etab.total > 0 ? 'text-orange-600' : 'text-muted-foreground'}> <span className={etab.total > 0 ? 'text-orange-600' : 'text-muted-foreground'}>
{etab.total > 0 ? formatEuros(etab.total) : ''} {etab.total > 0 ? formatEuros(etab.total) : ''}
</span> </span>
@@ -1351,7 +1351,7 @@ export default function DsiOpex() {
</tbody> </tbody>
<tfoot> <tfoot>
<tr className="bg-muted/40 border-t-2 border-border"> <tr className="bg-muted/40 border-t-2 border-border">
<td colSpan={2} className="px-3 py-3 font-bold text-foreground sticky left-0 bg-muted/40 z-10"> <td colSpan={2} className="px-3 py-3 font-bold text-foreground sticky left-0 z-10" style={{ background: 'hsl(var(--muted) / 0.4)', boxShadow: '2px 0 4px -2px rgba(0,0,0,0.15)' }}>
TOTAL — {sortedEtabs.length} établissements TOTAL — {sortedEtabs.length} établissements
</td> </td>
{opexState.lignes.map(ligne => { {opexState.lignes.map(ligne => {
@@ -1371,7 +1371,7 @@ export default function DsiOpex() {
</td> </td>
); );
})} })}
<td className="px-3 py-3 text-right font-bold text-orange-600 text-sm tabular-nums sticky right-0 bg-muted/40 z-10 border-l border-border"> <td className="px-3 py-3 text-right font-bold text-orange-600 text-sm tabular-nums sticky right-0 z-10 border-l border-border" style={{ background: 'hsl(var(--muted) / 0.4)', boxShadow: '-2px 0 4px -2px rgba(0,0,0,0.15)' }}>
{formatEuros(sortedEtabs.reduce((s, e) => s + e.total, 0))} {formatEuros(sortedEtabs.reduce((s, e) => s + e.total, 0))}
</td> </td>
</tr> </tr>