2026-07-08 12:55:37 +02:00
|
|
|
import { Navigate, Outlet } from 'react-router-dom'
|
2026-07-12 16:27:34 +02:00
|
|
|
import { useEffect, useState } from 'react'
|
2026-07-10 14:26:14 +02:00
|
|
|
import { ModeAreaShell } from '../../components/ModeAreaShell.jsx'
|
|
|
|
|
import { ModeAreaNav } from '../../components/ModeAreaNav.jsx'
|
2026-07-08 12:55:37 +02:00
|
|
|
import { ModeShell } from '../../components/ModeShell.jsx'
|
2026-07-10 14:26:14 +02:00
|
|
|
import { WORK_NAV_ITEMS, resolveWorkNavActiveKey } from '../../config/workNav.js'
|
2026-07-12 19:20:06 +02:00
|
|
|
import { resolveWorkNavItems } from '../../config/methodUiDefaults.js'
|
2026-07-12 16:27:34 +02:00
|
|
|
import { useProgramScope } from '../../context/ProgramScopeContext.jsx'
|
|
|
|
|
import { getInitiative } from '../../api/initiatives.js'
|
2026-07-12 19:20:06 +02:00
|
|
|
import { getActiveWorkCycle } from '../../api/workCycles.js'
|
|
|
|
|
import { resolveMethodUiDefaults } from '../../config/methodUiDefaults.js'
|
|
|
|
|
|
|
|
|
|
function WorkAreaNav() {
|
|
|
|
|
const { initiativeId } = useProgramScope()
|
|
|
|
|
const [navItems, setNavItems] = useState(WORK_NAV_ITEMS)
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!initiativeId) {
|
|
|
|
|
setNavItems(WORK_NAV_ITEMS)
|
|
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
|
let cancelled = false
|
|
|
|
|
Promise.all([
|
|
|
|
|
getInitiative(initiativeId),
|
|
|
|
|
getActiveWorkCycle(initiativeId).catch(() => null),
|
|
|
|
|
])
|
|
|
|
|
.then(([initiative, activeCycle]) => {
|
|
|
|
|
if (cancelled) return
|
|
|
|
|
setNavItems(
|
|
|
|
|
resolveWorkNavItems({
|
|
|
|
|
archetypeKey: initiative?.archetype_key,
|
|
|
|
|
hasActiveSprint: Boolean(activeCycle?.id),
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
if (!cancelled) setNavItems(WORK_NAV_ITEMS)
|
|
|
|
|
})
|
|
|
|
|
return () => {
|
|
|
|
|
cancelled = true
|
|
|
|
|
}
|
|
|
|
|
}, [initiativeId])
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<ModeAreaNav
|
|
|
|
|
modeLabel="Ausführen"
|
|
|
|
|
items={navItems}
|
|
|
|
|
resolveActiveKey={resolveWorkNavActiveKey}
|
|
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
}
|
2026-07-08 12:55:37 +02:00
|
|
|
|
|
|
|
|
export function WorkLayout() {
|
|
|
|
|
return (
|
|
|
|
|
<div className="app-page">
|
|
|
|
|
<ModeShell modeKey="work" />
|
2026-07-12 19:20:06 +02:00
|
|
|
<ModeAreaShell nav={<WorkAreaNav />}>
|
2026-07-10 14:26:14 +02:00
|
|
|
<Outlet />
|
|
|
|
|
</ModeAreaShell>
|
2026-07-08 12:55:37 +02:00
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function WorkIndexRedirect() {
|
2026-07-12 19:20:06 +02:00
|
|
|
const { initiativeId, hrefWithScope } = useProgramScope()
|
2026-07-12 16:27:34 +02:00
|
|
|
const [target, setTarget] = useState('/work/today')
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!initiativeId) {
|
|
|
|
|
setTarget('/work/today')
|
|
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
|
let cancelled = false
|
2026-07-12 19:20:06 +02:00
|
|
|
Promise.all([
|
|
|
|
|
getInitiative(initiativeId),
|
|
|
|
|
getActiveWorkCycle(initiativeId).catch(() => null),
|
|
|
|
|
])
|
2026-07-12 16:27:34 +02:00
|
|
|
.then(([initiative, activeCycle]) => {
|
|
|
|
|
if (cancelled) return
|
2026-07-12 19:20:06 +02:00
|
|
|
const defaults = resolveMethodUiDefaults({
|
|
|
|
|
archetypeKey: initiative?.archetype_key,
|
|
|
|
|
hasActiveSprint: Boolean(activeCycle?.id),
|
|
|
|
|
})
|
|
|
|
|
setTarget(hrefWithScope(defaults.workDefaultRoute))
|
2026-07-12 16:27:34 +02:00
|
|
|
})
|
|
|
|
|
.catch(() => {
|
2026-07-12 19:20:06 +02:00
|
|
|
if (!cancelled) setTarget(hrefWithScope('/work/today'))
|
2026-07-12 16:27:34 +02:00
|
|
|
})
|
|
|
|
|
return () => {
|
|
|
|
|
cancelled = true
|
|
|
|
|
}
|
2026-07-12 19:20:06 +02:00
|
|
|
}, [initiativeId, hrefWithScope])
|
2026-07-12 16:27:34 +02:00
|
|
|
|
|
|
|
|
return <Navigate to={target} replace />
|
2026-07-08 12:55:37 +02:00
|
|
|
}
|