feat(PBI-91): expliciete schermstaat + draft-zichtbaarheid PB-page (#210)
* docs(ST-1369): plan PBI-91 — expliciete schermstaat + draft-zichtbaarheid Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(ST-1369): screen-state module — ScreenState + deriveScreenState() Pure afleidingslaag die de verspreide schermstaat-derivatie van de Product Backlog page consolideert tot één testbaar ScreenState-model. Nog geen consumers — die volgen in T-1035/T-1036. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(ST-1369): unit-tests voor deriveScreenState() Dekt alle vier de kinds (NO_SPRINT, DRAFT, ACTIVE, EDITING), de building-flag en de draft-voorrang boven een actieve sprint. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(ST-1369): SprintSwitcher op deriveScreenState + draft op trigger (G5) De trigger-knop toont nu de concept-sprint zodra er een sprint-draft loopt, niet langer alleen de (disabled) dropdown-regel. Schermstaat-afleiding loopt via de pure deriveScreenState() i.p.v. losse flags. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(ST-1369): NewSprintTrigger achter isActiveProduct-gate (G6) De "Nieuwe sprint"-knop rendert niet langer op een niet-actief product — een sprint-draft starten daar was verwarrend. page.tsx geeft de bestaande isActiveProduct-flag door. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(ST-1369): component-tests voor draft-op-trigger (G5) en isActiveProduct-gate (G6) sprint-switcher: trigger toont concept-sprint bij een pending draft, en geen concept-label zonder draft. new-sprint-trigger: nieuw testbestand — rendert niet op een niet-actief product, wel op een actief product zonder draft. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2a6386163c
commit
3d5c22382c
9 changed files with 351 additions and 8 deletions
33
stores/product-workspace/screen-state.ts
Normal file
33
stores/product-workspace/screen-state.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Expliciete schermstaat voor de Product Backlog page.
|
||||
//
|
||||
// Consolideert de vandaag verspreide schermstaat-afleiding (page.tsx,
|
||||
// sprint-switcher.tsx, new-sprint-trigger.tsx, save-sprint-button.tsx) tot één
|
||||
// pure, testbare functie. Zie docs/architecture/product-backlog-workflow.md,
|
||||
// sectie "To-be: expliciete state machine".
|
||||
//
|
||||
// PRODUCT_NOT_ACTIVE en DEMO_MODE blijven bewust BUITEN ScreenState — het zijn
|
||||
// cross-cutting gates, geen knopen in de state machine.
|
||||
|
||||
export type ScreenState =
|
||||
| { kind: 'NO_SPRINT' }
|
||||
| { kind: 'DRAFT' }
|
||||
| { kind: 'ACTIVE'; building: boolean }
|
||||
| { kind: 'EDITING'; building: boolean }
|
||||
|
||||
export interface ScreenStateInput {
|
||||
activeSprintItem: { id: string } | null // SSR-prop uit page.tsx
|
||||
buildingSprintIds: string[] // SSR-prop uit page.tsx
|
||||
hasPendingDraft: boolean // user-settings store
|
||||
pendingAdds: string[] // product-workspace store: sprintMembership.pending.adds
|
||||
pendingRemoves: string[] // product-workspace store: sprintMembership.pending.removes
|
||||
}
|
||||
|
||||
export function deriveScreenState(i: ScreenStateInput): ScreenState {
|
||||
if (i.hasPendingDraft) return { kind: 'DRAFT' } // draft wint van alles
|
||||
if (i.activeSprintItem) {
|
||||
const building = i.buildingSprintIds.includes(i.activeSprintItem.id)
|
||||
const dirty = i.pendingAdds.length > 0 || i.pendingRemoves.length > 0
|
||||
return dirty ? { kind: 'EDITING', building } : { kind: 'ACTIVE', building }
|
||||
}
|
||||
return { kind: 'NO_SPRINT' }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue