All checks were successful
Deploy Development / deploy (push) Successful in 45s
Test Suite / pytest-backend (push) Successful in 1m13s
Test Suite / lint-backend (push) Successful in 2s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 18s
Test Suite / playwright-smoke (push) Successful in 15s
Workspace beantwortet die Leitfrage mit prominenten Next-Action- und Heute-Widgets sowie erweitertem Steuerungszustand pro Vorhaben. Co-authored-by: Cursor <cursoragent@cursor.com>
84 lines
2.5 KiB
JavaScript
84 lines
2.5 KiB
JavaScript
import { useNavigate } from 'react-router-dom'
|
|
import { useState } from 'react'
|
|
import { useCapabilities } from '../hooks/useCapabilities.js'
|
|
import { getWidgetsForArea } from '../registry/widgetRegistry.js'
|
|
import { useSession } from '../context/SessionContext.jsx'
|
|
import { InitiativeForm } from '../components/InitiativeForm.jsx'
|
|
import { createInitiative } from '../api/initiatives.js'
|
|
import { Link } from 'react-router-dom'
|
|
|
|
export function WorkspacePage() {
|
|
const navigate = useNavigate()
|
|
const { context } = useSession()
|
|
const { capabilities, hasCapability } = useCapabilities()
|
|
const widgets = getWidgetsForArea('workspace', capabilities)
|
|
const [showForm, setShowForm] = useState(false)
|
|
const [formBusy, setFormBusy] = useState(false)
|
|
const [formError, setFormError] = useState(null)
|
|
|
|
async function handleCreateInitiative(payload) {
|
|
setFormBusy(true)
|
|
setFormError(null)
|
|
try {
|
|
await createInitiative({
|
|
...payload,
|
|
owner_actor_id: context?.actor?.id,
|
|
})
|
|
setShowForm(false)
|
|
navigate('/initiatives')
|
|
} catch (err) {
|
|
setFormError(err.message)
|
|
} finally {
|
|
setFormBusy(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="app-page">
|
|
<header className="page-header">
|
|
<div>
|
|
<h1>Workspace</h1>
|
|
<p className="page-lead">Was ist dein nächster sinnvoller Schritt?</p>
|
|
</div>
|
|
{hasCapability('kairo.initiative.manage') && (
|
|
<button
|
|
type="button"
|
|
className="btn btn-primary btn-block-mobile"
|
|
onClick={() => setShowForm((v) => !v)}
|
|
>
|
|
{showForm ? 'Abbrechen' : 'Vorhaben anlegen'}
|
|
</button>
|
|
)}
|
|
</header>
|
|
|
|
{showForm && (
|
|
<section className="card inline-form-card">
|
|
<h2 className="card-title card-title--lg">Neues Vorhaben</h2>
|
|
{formError && <p className="error">{formError}</p>}
|
|
<InitiativeForm
|
|
onSubmit={handleCreateInitiative}
|
|
onCancel={() => setShowForm(false)}
|
|
busy={formBusy}
|
|
submitLabel="Vorhaben anlegen"
|
|
/>
|
|
</section>
|
|
)}
|
|
|
|
<div className="widget-grid">
|
|
{widgets.map((widget) => {
|
|
const Component = widget.component
|
|
return <Component key={widget.key} />
|
|
})}
|
|
</div>
|
|
|
|
{hasCapability('kairo.initiative.read') && (
|
|
<p className="page-footer-link">
|
|
<Link to="/initiatives" className="link-inline">
|
|
Zur Vorhabenliste →
|
|
</Link>
|
|
</p>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|