fix(AP0.8): UI-Sichtbarkeit Attention und OM-Sektionen verbessern
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Test Suite / pytest-backend (push) Successful in 57s
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 12s
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Test Suite / pytest-backend (push) Successful in 57s
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 12s
Attention-Widget an workspace.read koppeln, Vorhaben-Detail-Sektionen bei initiative.read anzeigen, App-Version im Kontext-Widget, Session-Loading-Race behoben. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
fe3bc4f057
commit
c9101db1e1
|
|
@ -41,7 +41,7 @@ import { useSession } from '../context/SessionContext.jsx'
|
||||||
|
|
||||||
export function InitiativeDetailPage() {
|
export function InitiativeDetailPage() {
|
||||||
const { id } = useParams()
|
const { id } = useParams()
|
||||||
const { context } = useSession()
|
const { context, loading: sessionLoading } = useSession()
|
||||||
const { capabilities } = useCapabilities()
|
const { capabilities } = useCapabilities()
|
||||||
const {
|
const {
|
||||||
actors,
|
actors,
|
||||||
|
|
@ -64,6 +64,7 @@ export function InitiativeDetailPage() {
|
||||||
const [hideDone, setHideDone] = useState(true)
|
const [hideDone, setHideDone] = useState(true)
|
||||||
|
|
||||||
const load = useCallback(async () => {
|
const load = useCallback(async () => {
|
||||||
|
if (sessionLoading) return
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
setError(null)
|
setError(null)
|
||||||
try {
|
try {
|
||||||
|
|
@ -75,13 +76,12 @@ export function InitiativeDetailPage() {
|
||||||
setActions(actionData)
|
setActions(actionData)
|
||||||
|
|
||||||
const loads = []
|
const loads = []
|
||||||
if (capabilities.has('kairo.blocker.read')) {
|
const canReadOm =
|
||||||
|
capabilities.has('kairo.initiative.read') ||
|
||||||
|
capabilities.has('kairo.blocker.read')
|
||||||
|
if (canReadOm) {
|
||||||
loads.push(listInitiativeBlockers(id).then(setBlockers).catch(() => setBlockers([])))
|
loads.push(listInitiativeBlockers(id).then(setBlockers).catch(() => setBlockers([])))
|
||||||
}
|
|
||||||
if (capabilities.has('kairo.backlog.read')) {
|
|
||||||
loads.push(listInitiativeBacklog(id).then(setBacklogItems).catch(() => setBacklogItems([])))
|
loads.push(listInitiativeBacklog(id).then(setBacklogItems).catch(() => setBacklogItems([])))
|
||||||
}
|
|
||||||
if (capabilities.has('kairo.milestone.read')) {
|
|
||||||
loads.push(listInitiativeMilestones(id).then(setMilestones).catch(() => setMilestones([])))
|
loads.push(listInitiativeMilestones(id).then(setMilestones).catch(() => setMilestones([])))
|
||||||
}
|
}
|
||||||
await Promise.all(loads)
|
await Promise.all(loads)
|
||||||
|
|
@ -90,7 +90,7 @@ export function InitiativeDetailPage() {
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
}, [id, capabilities])
|
}, [id, capabilities, sessionLoading])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
load()
|
load()
|
||||||
|
|
@ -405,7 +405,7 @@ export function InitiativeDetailPage() {
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{capabilities.has('kairo.milestone.read') && (
|
{capabilities.has('kairo.initiative.read') && (
|
||||||
<MilestonesSection
|
<MilestonesSection
|
||||||
milestones={milestones}
|
milestones={milestones}
|
||||||
canManage={capabilities.has('kairo.milestone.manage')}
|
canManage={capabilities.has('kairo.milestone.manage')}
|
||||||
|
|
@ -416,7 +416,7 @@ export function InitiativeDetailPage() {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{capabilities.has('kairo.backlog.read') && (
|
{capabilities.has('kairo.initiative.read') && (
|
||||||
<BacklogSection
|
<BacklogSection
|
||||||
items={backlogItems}
|
items={backlogItems}
|
||||||
canManage={capabilities.has('kairo.backlog.manage')}
|
canManage={capabilities.has('kairo.backlog.manage')}
|
||||||
|
|
@ -428,7 +428,7 @@ export function InitiativeDetailPage() {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{capabilities.has('kairo.blocker.read') && (
|
{capabilities.has('kairo.initiative.read') && (
|
||||||
<BlockersSection
|
<BlockersSection
|
||||||
blockers={blockers}
|
blockers={blockers}
|
||||||
canManage={capabilities.has('kairo.blocker.manage')}
|
canManage={capabilities.has('kairo.blocker.manage')}
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ describe('widgetRegistry', () => {
|
||||||
'kairo.action.read',
|
'kairo.action.read',
|
||||||
'kairo.initiative.read',
|
'kairo.initiative.read',
|
||||||
'kairo.workspace.read',
|
'kairo.workspace.read',
|
||||||
'kairo.attention.read',
|
|
||||||
])
|
])
|
||||||
expect(all.length).toBe(6)
|
expect(all.length).toBe(6)
|
||||||
|
|
||||||
const readOnly = getWidgetsForArea('workspace', ['kairo.initiative.read'])
|
const readOnly = getWidgetsForArea('workspace', ['kairo.initiative.read'])
|
||||||
expect(readOnly.some((w) => w.key === 'kairo.my_open_actions')).toBe(false)
|
expect(readOnly.some((w) => w.key === 'kairo.my_open_actions')).toBe(false)
|
||||||
expect(readOnly.some((w) => w.key === 'kairo.active_initiatives')).toBe(true)
|
expect(readOnly.some((w) => w.key === 'kairo.active_initiatives')).toBe(true)
|
||||||
|
expect(readOnly.some((w) => w.key === 'kairo.attention')).toBe(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ export const WIDGETS = [
|
||||||
title: 'Aufmerksamkeit',
|
title: 'Aufmerksamkeit',
|
||||||
description: 'Regelbasierte Attention-Items',
|
description: 'Regelbasierte Attention-Items',
|
||||||
area: 'workspace',
|
area: 'workspace',
|
||||||
requiredCapability: 'kairo.attention.read',
|
requiredCapability: 'kairo.workspace.read',
|
||||||
defaultOrder: 8,
|
defaultOrder: 8,
|
||||||
component: AttentionWidget,
|
component: AttentionWidget,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,17 @@
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
import { useSession } from '../context/SessionContext.jsx'
|
import { useSession } from '../context/SessionContext.jsx'
|
||||||
import { WidgetCard } from '../components/WidgetCard.jsx'
|
import { WidgetCard } from '../components/WidgetCard.jsx'
|
||||||
|
|
||||||
export function TenantContextWidget() {
|
export function TenantContextWidget() {
|
||||||
const { context, me } = useSession()
|
const { context, me } = useSession()
|
||||||
|
const [version, setVersion] = useState(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch('/api/version')
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then((data) => setVersion(data))
|
||||||
|
.catch(() => setVersion(null))
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WidgetCard title="Kontext" subtitle="Aktiver Mandant und Actor">
|
<WidgetCard title="Kontext" subtitle="Aktiver Mandant und Actor">
|
||||||
|
|
@ -28,6 +37,14 @@ export function TenantContextWidget() {
|
||||||
<dd>{context.actor.type}</dd>
|
<dd>{context.actor.type}</dd>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{version && (
|
||||||
|
<div>
|
||||||
|
<dt>App-Version</dt>
|
||||||
|
<dd className="muted">
|
||||||
|
{version.version} · Schema {version.schema}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</dl>
|
</dl>
|
||||||
)}
|
)}
|
||||||
</WidgetCard>
|
</WidgetCard>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user