diff --git a/__tests__/stores/product-workspace/store.test.ts b/__tests__/stores/product-workspace/store.test.ts
index beb61f1..bfa6cfd 100644
--- a/__tests__/stores/product-workspace/store.test.ts
+++ b/__tests__/stores/product-workspace/store.test.ts
@@ -257,6 +257,35 @@ describe('selection cascade', () => {
expect(s.relations.taskIdsByStory).toEqual({})
expect(s.loading.loadedProductId).toBeNull()
})
+
+ it('setActiveProduct kan alleen context zetten zonder full backlog load', () => {
+ useProductWorkspaceStore.getState().hydrateSnapshot(
+ snapshotWith(
+ [makePbi({ id: 'p-1' })],
+ { 'p-1': [makeStory({ id: 's-1', pbi_id: 'p-1' })] },
+ { 's-1': [makeTask({ id: 't-1', story_id: 's-1' })] },
+ { id: 'prod-1', name: 'Product 1' },
+ ),
+ )
+ useProductWorkspaceStore.setState((s) => {
+ s.context.activePbiId = 'p-1'
+ s.context.activeStoryId = 's-1'
+ })
+ const fetchSpy = vi.spyOn(globalThis, 'fetch')
+
+ useProductWorkspaceStore
+ .getState()
+ .setActiveProduct(
+ { id: 'prod-1', name: 'Product 1' },
+ { load: false, preserveSelection: true },
+ )
+
+ const s = useProductWorkspaceStore.getState()
+ expect(fetchSpy).not.toHaveBeenCalled()
+ expect(s.context.activePbiId).toBe('p-1')
+ expect(s.context.activeStoryId).toBe('s-1')
+ expect(s.entities.pbisById['p-1']).toBeDefined()
+ })
})
// ─────────────────────────────────────────────────────────────────────────
diff --git a/app/(app)/products/[id]/page.tsx b/app/(app)/products/[id]/page.tsx
index 6acf005..bf38aa4 100644
--- a/app/(app)/products/[id]/page.tsx
+++ b/app/(app)/products/[id]/page.tsx
@@ -151,6 +151,7 @@ export default async function ProductBacklogPage({ params, searchParams }: Props
({ id: p.id, code: p.code, title: p.title, priority: p.priority, sort_order: p.sort_order, description: p.description, created_at: p.created_at, status: pbiStatusToApi(p.status) })),
storiesByPbi,
diff --git a/app/(mobile)/m/products/[id]/page.tsx b/app/(mobile)/m/products/[id]/page.tsx
index 7d33f06..479db27 100644
--- a/app/(mobile)/m/products/[id]/page.tsx
+++ b/app/(mobile)/m/products/[id]/page.tsx
@@ -91,6 +91,7 @@ export default async function MobileProductBacklogPage({ params, searchParams }:
({ id: p.id, code: p.code, title: p.title, priority: p.priority, sort_order: p.sort_order, description: p.description, created_at: p.created_at, status: pbiStatusToApi(p.status) })),
storiesByPbi,
diff --git a/components/shared/set-current-product.tsx b/components/shared/set-current-product.tsx
index 63aa151..94d71aa 100644
--- a/components/shared/set-current-product.tsx
+++ b/components/shared/set-current-product.tsx
@@ -8,9 +8,11 @@ import { debugProps } from '@/lib/debug'
// De voorganger (stores/product-store.ts) wordt in Story 8 (T-876) verwijderd.
export function SetCurrentProduct({ id, name }: { id: string; name: string }) {
useEffect(() => {
- useProductWorkspaceStore.getState().setActiveProduct({ id, name })
+ useProductWorkspaceStore
+ .getState()
+ .setActiveProduct({ id, name }, { load: false, preserveSelection: true })
return () => {
- useProductWorkspaceStore.getState().setActiveProduct(null)
+ useProductWorkspaceStore.getState().setActiveProduct(null, { load: false })
}
}, [id, name])
diff --git a/stores/product-workspace/store.ts b/stores/product-workspace/store.ts
index 7ca381c..103eb28 100644
--- a/stores/product-workspace/store.ts
+++ b/stores/product-workspace/store.ts
@@ -78,7 +78,10 @@ interface State {
interface Actions {
hydrateSnapshot(snapshot: ProductBacklogSnapshot): void
- setActiveProduct(product: ActiveProduct | null): void
+ setActiveProduct(
+ product: ActiveProduct | null,
+ options?: { load?: boolean; preserveSelection?: boolean },
+ ): void
setActivePbi(pbiId: string | null): void
setActiveStory(storyId: string | null): void
setActiveTask(taskId: string | null): void
@@ -223,15 +226,18 @@ export const useProductWorkspaceStore = create()(
})
},
- setActiveProduct(product) {
+ setActiveProduct(product, options) {
const requestId = newRequestId()
const productChanged = get().context.activeProduct?.id !== product?.id
+ const shouldResetSelection = productChanged || !options?.preserveSelection
set((s) => {
s.context.activeProduct = product
- s.context.activePbiId = null
- s.context.activeStoryId = null
- s.context.activeTaskId = null
+ if (shouldResetSelection) {
+ s.context.activePbiId = null
+ s.context.activeStoryId = null
+ s.context.activeTaskId = null
+ }
s.loading.activeRequestId = requestId
if (productChanged) {
@@ -252,7 +258,7 @@ export const useProductWorkspaceStore = create()(
// selectie kan herstellen. T-857: restore-flow start na ensureProductLoaded.
writeProductHint(product?.id ?? null)
- if (product) {
+ if (product && options?.load !== false) {
const productId = product.id
void (async () => {
await get().ensureProductLoaded(productId, requestId)