mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
feat(r2.3): écrans web exploitation — OT, demandes, préventif, compteurs, urgence
- liste OT (filtres, strie rouge, « immédiat ») ; fiche OT : transitions pilotées par allowedTransitions, clôture grisée avec la garde expliquée, bilan codé (6 selects sur référentiels), checklist Fait→N-A→à faire, activité + commentaires, assignation, annulation motivée - nouvel OT : interrupteur « personne bloquée » qui force la priorité - demandes : table + panneau d'approbation (priorité, assignation, approuver → fiche OT), rejet en modale à motif obligatoire, signalement interne ; statut « Résolue » dérivé de l'OT lié - préventif : tuiles réelles, générer + résumé (« regénérer ne double rien »), gabarits administrables ; compteurs : saisie + historique - tableau de bord réel : bandeau urgence cliquable, KPIs, OT par statut, interventions récentes ; accueil dédié aux rôles sans exploitation - urgence traversante : chip topbar pulsante (60 s), badges de nav - GET /assets/options (auth seule) : le Demandeur peut désigner l'appareil qu'il signale — trou débusqué par l'e2e (49 opérations au contrat) - génération préventive durcie : collision de référence RETENTÉE (plus de saut silencieux), P2003 toléré ; 3 runs Jest complets consécutifs verts - 9 tests Playwright (recette R2 officielle rejouée intégralement), 50 tests API (94,6 % / 78,9 %) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -750,6 +750,129 @@ table {
|
||||
.avatars .avatar { width: 24px; height: 24px; font-size: 10px; border: 2px solid var(--surface); margin-left: -6px; }
|
||||
.avatars .avatar:first-child { margin-left: 0; }
|
||||
|
||||
/* ═══ R2 — Exploitation (classes extraites des maquettes validées) ═══ */
|
||||
/* Statuts de DEMANDE (validés R2 : extension cohérente des couleurs) */
|
||||
.st.recue { color: var(--st-ouvert); background: var(--st-ouvert-fond); }
|
||||
.st.approuvee { color: var(--st-encours); background: var(--st-encours-fond); }
|
||||
.st.rejetee { color: var(--st-annule); background: var(--st-annule-fond); }
|
||||
.st.resolue { color: var(--st-termine); background: var(--st-termine-fond); }
|
||||
|
||||
/* Urgence « personne bloquée » — seule animation continue de l'app */
|
||||
.chip-urgence {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
background: var(--prio-bloque-fond);
|
||||
color: var(--prio-bloque);
|
||||
border: 1px solid color-mix(in srgb, var(--prio-bloque) 30%, transparent);
|
||||
padding: 6px 12px;
|
||||
border-radius: var(--rayon-pastille);
|
||||
font-weight: 700;
|
||||
font-size: 12.5px;
|
||||
}
|
||||
.bandeau-urgence {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
background: var(--prio-bloque-fond);
|
||||
border: 1px solid color-mix(in srgb, var(--prio-bloque) 35%, transparent);
|
||||
border-left: 4px solid var(--prio-bloque);
|
||||
border-radius: var(--rayon);
|
||||
padding: 12px 16px;
|
||||
}
|
||||
.bandeau-urgence b { color: var(--prio-bloque); }
|
||||
.bandeau-urgence .depuis { color: var(--encre-2); font-size: 12.5px; }
|
||||
|
||||
/* Tuiles KPI (tableau de bord + préventif) */
|
||||
.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
|
||||
@media (max-width: 1100px) { .kpis { grid-template-columns: repeat(2, 1fr); } }
|
||||
.kpi { background: var(--surface); border: 1px solid var(--bordure); border-radius: var(--rayon); padding: 14px 16px; }
|
||||
.kpi .lib { font-size: 11.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--encre-2); font-weight: 600; }
|
||||
.kpi .val { font-size: 27px; font-weight: 700; letter-spacing: -0.02em; margin-top: 4px; }
|
||||
.kpi .delta { font-size: 12px; font-weight: 600; margin-top: 2px; }
|
||||
.delta.bon { color: var(--succes); }
|
||||
.delta.mauvais { color: var(--danger); }
|
||||
.delta.neutre { color: var(--encre-3); }
|
||||
.kpi.alarme { border-color: color-mix(in srgb, var(--danger) 45%, transparent); }
|
||||
.kpi.alarme .val { color: var(--danger); }
|
||||
|
||||
/* Barres horizontales (OT par statut) */
|
||||
.barres-h .ligne-b { display: grid; grid-template-columns: 110px 1fr 40px; align-items: center; gap: 10px; font-size: 13px; }
|
||||
.barres-h .fond-b { background: var(--graf-grille); border-radius: 4px; height: 14px; overflow: hidden; }
|
||||
.barres-h .rempli { height: 100%; border-radius: 4px 0 0 4px; }
|
||||
.barres-h .valeur { text-align: right; font-weight: 600; }
|
||||
|
||||
/* Activité chronologique */
|
||||
.chrono { list-style: none; display: flex; flex-direction: column; gap: 0; font-size: 13px; padding: 0; }
|
||||
.chrono li { position: relative; padding: 0 0 16px 22px; }
|
||||
.chrono li::before { content: ''; position: absolute; left: 5px; top: 5px; width: 8px; height: 8px; border-radius: 50%; background: var(--bordure-forte); }
|
||||
.chrono li.fait::before { background: var(--primaire); }
|
||||
.chrono li::after { content: ''; position: absolute; left: 8.5px; top: 15px; bottom: -2px; width: 1px; background: var(--bordure); }
|
||||
.chrono li:last-child::after { display: none; }
|
||||
.chrono .quand { color: var(--encre-3); font-size: 11.5px; }
|
||||
|
||||
/* Checklist Fait / N-A */
|
||||
.check { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--bordure); font-size: 13.5px; }
|
||||
.check:last-of-type { border-bottom: 0; }
|
||||
.coche {
|
||||
width: 19px; height: 19px; border-radius: 5px; border: 1.5px solid var(--bordure-forte);
|
||||
flex: none; display: flex; align-items: center; justify-content: center;
|
||||
color: #fff; font-size: 11px; background: none; padding: 0; cursor: pointer;
|
||||
}
|
||||
.coche.ok { background: var(--succes); border-color: var(--succes); }
|
||||
.coche.na { background: var(--encre-3); border-color: var(--encre-3); font-size: 8.5px; }
|
||||
.check .qui-fait { margin-left: auto; color: var(--encre-3); font-size: 12px; white-space: nowrap; }
|
||||
|
||||
/* Bilan codé (6 champs) */
|
||||
.bilan { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; }
|
||||
@media (max-width: 900px) { .bilan { grid-template-columns: 1fr; } }
|
||||
.bilan .champ-b { font-size: 12.5px; }
|
||||
.bilan .champ-b label { color: var(--encre-2); font-weight: 600; display: block; margin-bottom: 4px; }
|
||||
.bilan .champ-b label em { color: var(--danger); font-style: normal; }
|
||||
.bilan select {
|
||||
width: 100%; padding: 8px 11px; border: 1px solid var(--bordure-forte);
|
||||
border-radius: var(--rayon-controle); font: inherit; background: var(--surface); color: var(--encre);
|
||||
}
|
||||
.avertissement { margin-top: 12px; font-size: 12.5px; color: var(--alerte); }
|
||||
|
||||
/* Préventif */
|
||||
.periode {
|
||||
display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 700;
|
||||
color: var(--primaire); background: var(--primaire-doux); padding: 2px 9px; border-radius: var(--rayon-pastille);
|
||||
}
|
||||
.periode.reglementaire { color: var(--safran); background: var(--safran-doux); }
|
||||
.gen-info { border-left: 3px solid var(--succes); }
|
||||
|
||||
/* Panneau d'approbation (demandes) */
|
||||
.panneau { border: 1px solid var(--bordure); border-radius: var(--rayon); background: var(--surface); padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; }
|
||||
|
||||
/* Interrupteur (personne bloquée) */
|
||||
.gros-toggle {
|
||||
display: flex; align-items: center; gap: 12px; background: var(--prio-bloque-fond);
|
||||
border: 1px solid color-mix(in srgb, var(--prio-bloque) 30%, transparent);
|
||||
border-radius: 10px; padding: 12px 14px;
|
||||
}
|
||||
.gros-toggle b { color: var(--prio-bloque); }
|
||||
.interrupteur {
|
||||
margin-left: auto; width: 44px; height: 24px; border-radius: var(--rayon-pastille);
|
||||
background: var(--bordure-forte); position: relative; flex: none; border: 0; cursor: pointer;
|
||||
transition: background var(--transition);
|
||||
}
|
||||
.interrupteur::after {
|
||||
content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px;
|
||||
border-radius: 50%; background: #fff; transition: left var(--transition);
|
||||
}
|
||||
.interrupteur[aria-checked='true'] { background: var(--prio-bloque); }
|
||||
.interrupteur[aria-checked='true']::after { left: 22px; }
|
||||
|
||||
/* Relevés de compteurs */
|
||||
.releve-saisie { display: flex; gap: 8px; align-items: center; }
|
||||
.releve-saisie input {
|
||||
width: 140px; padding: 8px 11px; border: 1px solid var(--bordure-forte);
|
||||
border-radius: var(--rayon-controle); font: inherit; background: var(--surface);
|
||||
color: var(--encre); text-align: right;
|
||||
}
|
||||
|
||||
/* ═══ Page /design : nuanciers ═══ */
|
||||
.nuancier {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user