Files
server/core/src/stores/layoutStore.ts
T
2026-08-09 23:18:39 -04:00

112 lines
3.0 KiB
TypeScript

import { ref, watch } from 'vue';
import { defineStore } from 'pinia';
import { useUserStore } from './userStore';
import { useTenantStore } from './tenantStore';
export type MenuMode = 'apps' | 'user-settings' | 'admin-settings';
export type ThemeMode = 'light' | 'dark' | 'system';
export const useLayoutStore = defineStore('layout', () => {
// Loading state
const isLoading = ref(false);
// Sidebar state - initialize from settings or defaults
const userStore = useUserStore();
const tenantStore = useTenantStore();
function booleanSetting(key: string, fallback: boolean): boolean {
const value = userStore.getSetting(key);
return typeof value === 'boolean' ? value : fallback;
}
function themeSetting(value: unknown): ThemeMode | null {
return value === 'light' || value === 'dark' || value === 'system' ? value : null;
}
function initialTheme(): ThemeMode {
return (
themeSetting(userStore.getSetting('theme')) ??
themeSetting(tenantStore.getSetting('theme_default_mode')) ??
'system'
);
}
const sidebarDrawer = ref<boolean>(booleanSetting('sidebar_drawer', true));
const miniSidebar = ref<boolean>(booleanSetting('mini_sidebar', true));
const menuMode = ref<MenuMode>('apps');
// Theme mode - user choice, falling back to the tenant default
const theme = ref<ThemeMode>(initialTheme());
let hydratingFromSettings = false;
// Watch and sync sidebar state to settings
watch(sidebarDrawer, (value) => {
if (hydratingFromSettings) return;
userStore.setSetting('sidebar_drawer', value);
}, { flush: 'sync' });
watch(miniSidebar, (value) => {
if (hydratingFromSettings) return;
userStore.setSetting('mini_sidebar', value);
}, { flush: 'sync' });
watch(theme, (value) => {
if (hydratingFromSettings) return;
userStore.setSetting('theme', value);
}, { flush: 'sync' });
function hydrateFromSettings() {
hydratingFromSettings = true;
try {
sidebarDrawer.value = booleanSetting('sidebar_drawer', true);
miniSidebar.value = booleanSetting('mini_sidebar', true);
theme.value = initialTheme();
} finally {
hydratingFromSettings = false;
}
}
// Actions
function toggleSidebarDrawer() {
sidebarDrawer.value = !sidebarDrawer.value;
}
function setMiniSidebar(value: boolean) {
miniSidebar.value = value;
}
function setTheme(value: ThemeMode) {
theme.value = value;
}
function setMenuMode(value: MenuMode) {
menuMode.value = value;
}
function toggleMenuMode() {
// Cycle through: apps -> user-settings -> admin-settings -> apps
const modes: MenuMode[] = ['apps', 'user-settings', 'admin-settings'];
const currentIndex = modes.indexOf(menuMode.value);
const nextIndex = (currentIndex + 1) % modes.length;
menuMode.value = modes[nextIndex];
}
return {
// State
isLoading,
sidebarDrawer,
miniSidebar,
menuMode,
theme,
// Actions
toggleSidebarDrawer,
setMiniSidebar,
setMenuMode,
toggleMenuMode,
setTheme,
hydrateFromSettings,
};
});