From 8f1b664b2fe8e53d51b71b7bf35f22211a77afcd Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Wed, 27 May 2026 19:15:08 +0200 Subject: [PATCH] feat(navigator): add currentTabCode + currentFilter to UI store (P2 prep) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit setTab(code) atomically updates currentTabCode and resets currentFilter to '' — switching tabs starts a fresh search context. setFilter(value) updates only the filter — the user is typing in the same tab. TDD: 3 new cases (16 total in navigatorUiStore.test). --- src/hooks/navigator/navigatorUiStore.test.ts | 33 +++++++++++++++++++- src/hooks/navigator/navigatorUiStore.ts | 10 +++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/hooks/navigator/navigatorUiStore.test.ts b/src/hooks/navigator/navigatorUiStore.test.ts index ebc41fa..36a7450 100644 --- a/src/hooks/navigator/navigatorUiStore.test.ts +++ b/src/hooks/navigator/navigatorUiStore.test.ts @@ -10,7 +10,9 @@ const INITIAL = { isOpenSavesSearches: false, isLoading: false, needsInit: true, - needsSearch: false + needsSearch: false, + currentTabCode: '', + currentFilter: '' }; describe('useNavigatorUiStore', () => @@ -32,6 +34,8 @@ describe('useNavigatorUiStore', () => expect(s.isLoading).toBe(false); expect(s.needsInit).toBe(true); expect(s.needsSearch).toBe(false); + expect(s.currentTabCode).toBe(''); + expect(s.currentFilter).toBe(''); }); describe('show / hide / toggle', () => @@ -141,4 +145,31 @@ describe('useNavigatorUiStore', () => expect(useNavigatorUiStore.getState().needsSearch).toBe(false); }); }); + + describe('tab + filter', () => + { + it("setTab('public') sets currentTabCode and clears currentFilter", () => + { + useNavigatorUiStore.setState({ currentTabCode: 'events', currentFilter: 'habbo' }); + useNavigatorUiStore.getState().setTab('public'); + expect(useNavigatorUiStore.getState().currentTabCode).toBe('public'); + expect(useNavigatorUiStore.getState().currentFilter).toBe(''); + }); + + it("setFilter('cocco') sets currentFilter without touching tab", () => + { + useNavigatorUiStore.getState().setTab('events'); + useNavigatorUiStore.getState().setFilter('cocco'); + expect(useNavigatorUiStore.getState().currentTabCode).toBe('events'); + expect(useNavigatorUiStore.getState().currentFilter).toBe('cocco'); + }); + + it('setTab on same code still resets currentFilter', () => + { + useNavigatorUiStore.setState({ currentTabCode: 'public', currentFilter: 'test' }); + useNavigatorUiStore.getState().setTab('public'); + expect(useNavigatorUiStore.getState().currentTabCode).toBe('public'); + expect(useNavigatorUiStore.getState().currentFilter).toBe(''); + }); + }); }); diff --git a/src/hooks/navigator/navigatorUiStore.ts b/src/hooks/navigator/navigatorUiStore.ts index 527aab7..709207a 100644 --- a/src/hooks/navigator/navigatorUiStore.ts +++ b/src/hooks/navigator/navigatorUiStore.ts @@ -10,6 +10,8 @@ export type NavigatorUiState = { isLoading: boolean; needsInit: boolean; needsSearch: boolean; + currentTabCode: string; + currentFilter: string; }; export type NavigatorUiActions = { @@ -28,6 +30,8 @@ export type NavigatorUiActions = { markInitDone(): void; requestSearch(): void; consumeSearchRequest(): void; + setTab(code: string): void; + setFilter(value: string): void; }; export const useNavigatorUiStore = createNitroStore()((set) => ({ @@ -40,6 +44,8 @@ export const useNavigatorUiStore = createNitroStore set({ isVisible: true, needsSearch: true }), hide: () => set({ isVisible: false }), @@ -57,5 +63,7 @@ export const useNavigatorUiStore = createNitroStore set({ isReady: true }), markInitDone: () => set({ needsInit: false }), requestSearch: () => set({ needsSearch: true }), - consumeSearchRequest: () => set({ needsSearch: false }) + consumeSearchRequest: () => set({ needsSearch: false }), + setTab: (code) => set({ currentTabCode: code, currentFilter: '' }), + setFilter: (value) => set({ currentFilter: value }) }));