diff --git a/ui/src/stores/sidebarSlice.ts b/ui/src/stores/sidebarSlice.ts new file mode 100644 index 00000000..51f6e0ce --- /dev/null +++ b/ui/src/stores/sidebarSlice.ts @@ -0,0 +1,19 @@ +export type SidebarSlice = { + sidebarOpen: boolean + toggleSidebar: () => void + setSidebarOpen: (open: boolean) => void +} + +type SetSidebarState = ( + partial: Partial | ((state: SidebarSlice) => Partial), +) => void + +type GetSidebarState = () => SidebarSlice + +export function createSidebarSlice(set: SetSidebarState, get: GetSidebarState): SidebarSlice { + return { + sidebarOpen: false, + toggleSidebar: () => set({ sidebarOpen: !get().sidebarOpen }), + setSidebarOpen: open => set({ sidebarOpen: open }), + } +} diff --git a/ui/src/stores/useStore.ts b/ui/src/stores/useStore.ts index b3391c9b..87e46dcd 100644 --- a/ui/src/stores/useStore.ts +++ b/ui/src/stores/useStore.ts @@ -13,6 +13,7 @@ import { llmActivityPreview } from '../lib/llmActivityPreview' import { createDeveloperModeSlice } from './developerModeSlice' import { createDirectorSlice } from './directorSlice' import { createSettingsSlice } from './settingsSlice' +import { createSidebarSlice } from './sidebarSlice' import { createThemeSlice } from './themeSlice' import { markJobsCancelling, prependJob, removeJob, updateJob, withJobs } from './jobReducers' import { @@ -2330,6 +2331,10 @@ export const useStore = create((set, get) => ({ partial => set(partial as never), () => get(), ), + ...createSidebarSlice( + partial => set(partial as never), + () => get(), + ), ...createDeveloperModeSlice( partial => set(partial as never), () => get(), @@ -3041,10 +3046,6 @@ export const useStore = create((set, get) => ({ set(s => ({ params: { ...s.params, ...partial } })) }, - sidebarOpen: false, - toggleSidebar: () => set(s => ({ sidebarOpen: !s.sidebarOpen })), - setSidebarOpen: (open) => set({ sidebarOpen: open }), - // CivitAI LoRA Browser // Director Pipeline Dashboard retakeDialogOpen: false, diff --git a/ui/tests/architectureSlices.test.mjs b/ui/tests/architectureSlices.test.mjs index 82986f2d..1a98bfb6 100644 --- a/ui/tests/architectureSlices.test.mjs +++ b/ui/tests/architectureSlices.test.mjs @@ -119,6 +119,27 @@ test('settings slice toggles open and tab through the public facade', async () = assert.equal(useStore.getState().settingsOpen, false) }) +test('sidebar slice toggles open through the public facade', async () => { + const { createSidebarSlice } = await import('../src/stores/sidebarSlice.ts') + let state + const set = update => { + const partial = typeof update === 'function' ? update(state) : update + state = { ...state, ...partial } + } + state = createSidebarSlice(set, () => state) + assert.equal(state.sidebarOpen, false) + state.toggleSidebar() + assert.equal(state.sidebarOpen, true) + state.setSidebarOpen(false) + assert.equal(state.sidebarOpen, false) + + const { useStore } = await import('../src/stores/useStore.ts') + useStore.getState().setSidebarOpen(true) + assert.equal(useStore.getState().sidebarOpen, true) + useStore.getState().toggleSidebar() + assert.equal(useStore.getState().sidebarOpen, false) +}) + test('developer-mode slice persists the local flag through the public facade', async () => { if (!globalThis.localStorage) { const { JSDOM } = await import('jsdom')