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
Detail-Route mit vollem Formular, Struktur-Navigator statt Inline-CRUD, Lifecycle sichtbar im Vorhaben-Header und auf Ausführung (0.15.1-ap1.5e).
82 lines
2.3 KiB
JavaScript
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>
|
|
)
|
|
}
|