feat(ui): UI-008 echte Status-Badges statt badge-neutral, Epic 20 komplett
FehlbestandListePage, MangelListePage (Status + Prioritäts-Badge statt Inline-Farbe) und admin/GeraeteInstanzenListe zeigten Status immer als neutrales Badge statt farblich zu unterscheiden. Letzte hartkodierte Hex-Fallbacks (NachfuellDialog, BeladungsplanerBoard) auf reine Tokens umgestellt. Damit ist Epic 20 (UI-Redesign, UI-001..008) vollständig durchlaufen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
@@ -272,7 +272,7 @@ eigenes Modul (MAINT-\*, MABEA hat nur Prüfung, keine Wartung)**.
|
|||||||
| `17_zustaendigkeit.md` | ZUST-001 … ZUST-002 (vollständig, nachträglich ergänzt) |
|
| `17_zustaendigkeit.md` | ZUST-001 … ZUST-002 (vollständig, nachträglich ergänzt) |
|
||||||
| `18_notifications.md` | NOTIF-001 … NOTIF-002 (vollständig, nachträglich ergänzt) |
|
| `18_notifications.md` | NOTIF-001 … NOTIF-002 (vollständig, nachträglich ergänzt) |
|
||||||
| `19_satelliten_server.md` | SAT-001 (Platzhalter, nachträglich ergänzt, bewusst zurückgestellt) |
|
| `19_satelliten_server.md` | SAT-001 (Platzhalter, nachträglich ergänzt, bewusst zurückgestellt) |
|
||||||
| `20_ui_redesign.md` | UI-001 … UI-008 (vollständig, nachträglich ergänzt, in Umsetzung) |
|
| `20_ui_redesign.md` | UI-001 … UI-008 (vollständig umgesetzt, 2026-09-06) |
|
||||||
|
|
||||||
**Alle 20 Epics durchgegangen** (16 ursprüngliche + 17 Zuständigkeit/18 Notifications/19
|
**Alle 20 Epics durchgegangen** (16 ursprüngliche + 17 Zuständigkeit/18 Notifications/19
|
||||||
Satelliten-Server/20 UI-Redesign, nachträglich ergänzt). Detaillierungsphase
|
Satelliten-Server/20 UI-Redesign, nachträglich ergänzt). Detaillierungsphase
|
||||||
|
|||||||
@@ -207,7 +207,14 @@ Aktueller Stand vor Redesign: 39 Seiten-/Komponenten-Dateien, ~7.000 Zeilen, ein
|
|||||||
- **Rechte:** keine Änderung
|
- **Rechte:** keine Änderung
|
||||||
- **Akzeptanzkriterien:** keine Seite mehr im alten Stil.
|
- **Akzeptanzkriterien:** keine Seite mehr im alten Stil.
|
||||||
- **Tests:** bestehende Tests bleiben grün.
|
- **Tests:** bestehende Tests bleiben grün.
|
||||||
- **DoD:** offen.
|
- **DoD:** umgesetzt (2026-09-06). Rest-Audit über alle Seiten/Komponenten
|
||||||
|
(`grep` nach Hex-Farben, `badge-neutral` auf echten Status-Feldern): letzte
|
||||||
|
hartkodierte Hex-Fallbacks (`NachfuellDialog.tsx`, `BeladungsplanerBoard.tsx`)
|
||||||
|
auf reine Tokens umgestellt. `FehlbestandListePage`, `MangelListePage`
|
||||||
|
(Status UND Prioritäts-Badge statt Inline-Farbe) und
|
||||||
|
`GeraeteInstanzenListe.tsx` (Admin) bekamen echte Status-Farben statt immer
|
||||||
|
`badge-neutral`. Damit ist Epic 20 (UI-Redesign, UI-001..008) vollständig
|
||||||
|
durchlaufen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,16 @@ import { apiRequest } from "../api/client";
|
|||||||
import { useAuth } from "../auth/AuthContext";
|
import { useAuth } from "../auth/AuthContext";
|
||||||
import type { Fehlbestand, Material, Objekt } from "../api/types";
|
import type { Fehlbestand, Material, Objekt } from "../api/types";
|
||||||
|
|
||||||
|
// UI-008 (Epic 20): Status war bisher immer badge-neutral, unabhängig vom
|
||||||
|
// tatsächlichen Zustand - andere Listen (Mängel, Ausgabe) unterscheiden längst
|
||||||
|
// visuell zwischen offen/erledigt.
|
||||||
|
const STATUS_BADGE: Record<string, string> = {
|
||||||
|
offen: "badge-warning",
|
||||||
|
in_bearbeitung: "badge-warning",
|
||||||
|
nachgefuellt_teilweise: "badge-warning",
|
||||||
|
erledigt: "badge-success",
|
||||||
|
};
|
||||||
|
|
||||||
// Eigenständige Abarbeitung offener Fehlbestände (Nutzer-Vorgabe): Nachfüllen/
|
// Eigenständige Abarbeitung offener Fehlbestände (Nutzer-Vorgabe): Nachfüllen/
|
||||||
// Mindermenge-Genehmigung sollen ohne komplette Kontrolle möglich sein - Backend
|
// Mindermenge-Genehmigung sollen ohne komplette Kontrolle möglich sein - Backend
|
||||||
// (GET /fehlbestaende, POST .../nachfuellungen, POST .../mindermenge) existierte
|
// (GET /fehlbestaende, POST .../nachfuellungen, POST .../mindermenge) existierte
|
||||||
@@ -112,7 +122,7 @@ export function FehlbestandListePage() {
|
|||||||
<span>
|
<span>
|
||||||
<strong>{objektName(fb.objekt_id)}</strong> – {materialName(fb.material_id)}
|
<strong>{objektName(fb.objekt_id)}</strong> – {materialName(fb.material_id)}
|
||||||
</span>
|
</span>
|
||||||
<span className="badge badge-neutral">{fb.status}</span>
|
<span className={`badge ${STATUS_BADGE[fb.status] ?? "badge-neutral"}`}>{fb.status}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-muted" style={{ margin: "0.4rem 0" }}>
|
<div className="text-muted" style={{ margin: "0.4rem 0" }}>
|
||||||
Soll {fb.sollmenge} / Ist {fb.istmenge} – Fehlmenge {fb.fehlmenge}
|
Soll {fb.sollmenge} / Ist {fb.istmenge} – Fehlmenge {fb.fehlmenge}
|
||||||
|
|||||||
@@ -14,6 +14,15 @@ const STATUS_LABEL: Record<MangelStatus, string> = {
|
|||||||
erledigt: "Erledigt",
|
erledigt: "Erledigt",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// UI-008 (Epic 20): Status-Badge war immer neutral, unabhängig vom Zustand.
|
||||||
|
const STATUS_BADGE: Record<MangelStatus, string> = {
|
||||||
|
neu: "badge-warning",
|
||||||
|
in_bearbeitung: "badge-warning",
|
||||||
|
ersatzteil_bestellt: "badge-warning",
|
||||||
|
reparatur_geplant: "badge-warning",
|
||||||
|
erledigt: "badge-success",
|
||||||
|
};
|
||||||
|
|
||||||
const STATUS_OPTIONEN: MangelStatus[] = [
|
const STATUS_OPTIONEN: MangelStatus[] = [
|
||||||
"neu",
|
"neu",
|
||||||
"in_bearbeitung",
|
"in_bearbeitung",
|
||||||
@@ -150,9 +159,9 @@ export function MangelListePage() {
|
|||||||
<div className="row-between">
|
<div className="row-between">
|
||||||
<span>
|
<span>
|
||||||
<strong>{objektName(m.objekt_id)}</strong>
|
<strong>{objektName(m.objekt_id)}</strong>
|
||||||
{m.prioritaet === "hoch" && <span style={{ color: "var(--color-danger)" }}> ⚠ hoch</span>}
|
{m.prioritaet === "hoch" && <span className="badge badge-danger" style={{ marginLeft: "0.4rem" }}>⚠ hoch</span>}
|
||||||
</span>
|
</span>
|
||||||
<span className="badge badge-neutral">{STATUS_LABEL[m.status]}</span>
|
<span className={`badge ${STATUS_BADGE[m.status]}`}>{STATUS_LABEL[m.status]}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ margin: "0.4rem 0" }}>{m.beschreibung}</div>
|
<div style={{ margin: "0.4rem 0" }}>{m.beschreibung}</div>
|
||||||
{darfStatusAendern && m.status !== "erledigt" && (
|
{darfStatusAendern && m.status !== "erledigt" && (
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export function BeladungsplanerBoard({ zeilen, onZeilenChange, materialien, faec
|
|||||||
marginBottom: "0.4rem",
|
marginBottom: "0.4rem",
|
||||||
padding: "0.35rem 0.5rem",
|
padding: "0.35rem 0.5rem",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
outline: ausgewaehlt === m.id ? "2px solid var(--color-primary, #2563eb)" : "none",
|
outline: ausgewaehlt === m.id ? "2px solid var(--color-primary)" : "none",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{m.name}
|
{m.name}
|
||||||
@@ -99,7 +99,7 @@ export function BeladungsplanerBoard({ zeilen, onZeilenChange, materialien, faec
|
|||||||
flex: "0 0 14rem",
|
flex: "0 0 14rem",
|
||||||
minHeight: "8rem",
|
minHeight: "8rem",
|
||||||
cursor: ausgewaehlt !== null ? "pointer" : "default",
|
cursor: ausgewaehlt !== null ? "pointer" : "default",
|
||||||
borderColor: ausgewaehlt !== null ? "var(--color-primary, #2563eb)" : undefined,
|
borderColor: ausgewaehlt !== null ? "var(--color-primary)" : undefined,
|
||||||
}}
|
}}
|
||||||
onClick={() => zuordnen(spalte)}
|
onClick={() => zuordnen(spalte)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ const STATUS_LABEL: Record<GeraetInstanz["status"], string> = {
|
|||||||
in_reparatur: "In Reparatur",
|
in_reparatur: "In Reparatur",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// UI-008 (Epic 20): Status-Badge war immer neutral, unabhängig vom Zustand.
|
||||||
|
const STATUS_BADGE: Record<GeraetInstanz["status"], string> = {
|
||||||
|
einsatzbereit: "badge-success",
|
||||||
|
defekt: "badge-danger",
|
||||||
|
in_reparatur: "badge-warning",
|
||||||
|
};
|
||||||
|
|
||||||
/** Karte 14: löst das Einzelfeld objektposition.seriennummer ab - beliebig
|
/** Karte 14: löst das Einzelfeld objektposition.seriennummer ab - beliebig
|
||||||
* viele Geräte-Exemplare pro Position (z.B. 2 Pulsoxymeter im selben
|
* viele Geräte-Exemplare pro Position (z.B. 2 Pulsoxymeter im selben
|
||||||
* Rucksack), je mit eigenem Prüfdatum/Status. */
|
* Rucksack), je mit eigenem Prüfdatum/Status. */
|
||||||
@@ -103,7 +110,7 @@ export function GeraeteInstanzenListe({ objektpositionId, pruefintervallMonate,
|
|||||||
<div className="row-between">
|
<div className="row-between">
|
||||||
<span>
|
<span>
|
||||||
{instanz.status === "einsatzbereit" ? "✓" : "✗"} {instanz.seriennummer}{" "}
|
{instanz.status === "einsatzbereit" ? "✓" : "✗"} {instanz.seriennummer}{" "}
|
||||||
<span className="badge badge-neutral">{STATUS_LABEL[instanz.status]}</span>{" "}
|
<span className={`badge ${STATUS_BADGE[instanz.status]}`}>{STATUS_LABEL[instanz.status]}</span>{" "}
|
||||||
{instanz.naechste_pruefung && (
|
{instanz.naechste_pruefung && (
|
||||||
<span className="text-muted">nächste Prüfung: {instanz.naechste_pruefung}</span>
|
<span className="text-muted">nächste Prüfung: {instanz.naechste_pruefung}</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export function NachfuellDialog({
|
|||||||
const [begruendung, setBegruendung] = useState("");
|
const [begruendung, setBegruendung] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card" style={{ borderColor: "var(--color-warning, #b45309)", marginTop: "0.6rem" }}>
|
<div className="card" style={{ borderColor: "var(--color-warning)", marginTop: "0.6rem" }}>
|
||||||
<div className="card-subtitle">
|
<div className="card-subtitle">
|
||||||
Fehlmenge bei {materialName} – jetzt aus Lager nachfüllen?
|
Fehlmenge bei {materialName} – jetzt aus Lager nachfüllen?
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user