Kairo-Jinkendo/frontend/src/components/InitiativeLifecycleBar.jsx
Lars 33831a8c2c
Some checks failed
Deploy Development / deploy (push) Successful in 43s
Test Suite / pytest-backend (push) Failing after 1m48s
Test Suite / k6 /api/health Baseline (push) Has been skipped
Test Suite / playwright-smoke (push) Has been skipped
Test Suite / lint-backend (push) Successful in 3s
Test Suite / compose-smoke (push) Has been skipped
AP1.5e: Projekt-Detail, Bearbeitung und Lifecycle in der Ausführung.
Detail-Route mit vollem Formular, Struktur-Navigator statt Inline-CRUD, Lifecycle sichtbar im Vorhaben-Header und auf Ausführung (0.15.1-ap1.5e).
2026-07-08 11:06:10 +02:00

82 lines
2.3 KiB
JavaScript

import { LIFECYCLE_LABELS } from '../constants/operating.js'
import { Link } from 'react-router-dom'
export function InitiativeLifecycleBar({
snapshot,
loading,
error,
initiativeId,
compact = false,
}) {
if (loading) {
return (
<section className="initiative-lifecycle-bar card card--flat">
<p className="muted">Steuerungszustand wird geladen </p>
</section>
)
}
if (error || !snapshot) {
return (
<section className="initiative-lifecycle-bar card card--flat initiative-lifecycle-bar--muted">
<p className="muted">
Steuerungszustand nicht verfügbar siehe Tab{' '}
<Link to={`/initiatives/${initiativeId}`}>Steuerung</Link>.
</p>
</section>
)
}
const displayLabel =
snapshot.lifecycle_label ||
LIFECYCLE_LABELS[snapshot.lifecycle_state] ||
snapshot.lifecycle_state
const stats = [
{ label: 'Offen', value: snapshot.counts?.actions_open ?? 0, warn: false },
{
label: 'Blockiert',
value: snapshot.counts?.actions_blocked ?? 0,
warn: (snapshot.counts?.actions_blocked ?? 0) > 0,
},
{
label: 'Review',
value: snapshot.counts?.actions_review_required ?? 0,
warn: (snapshot.counts?.actions_review_required ?? 0) > 0,
},
{
label: 'Blocker',
value: snapshot.counts?.blockers_open ?? 0,
warn: (snapshot.counts?.blockers_open ?? 0) > 0,
},
]
return (
<section
className={`initiative-lifecycle-bar card card--flat${compact ? ' initiative-lifecycle-bar--compact' : ''}`}
>
<div className="initiative-lifecycle-bar-main">
<div>
<p className="initiative-lifecycle-kicker">Programm-Fortschritt</p>
<span className="badge status-badge status-active steering-lifecycle-badge">
{displayLabel}
</span>
</div>
<Link className="btn btn-secondary btn-sm" to={`/initiatives/${initiativeId}`}>
Steuerung
</Link>
</div>
<div className="initiative-lifecycle-stats">
{stats.map(({ label, value, warn }) => (
<span
key={label}
className={`initiative-lifecycle-stat${warn ? ' initiative-lifecycle-stat--warn' : ''}`}
>
<strong>{value}</strong> {label}
</span>
))}
</div>
</section>
)
}