b3e0c00c87
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
112 lines
3.0 KiB
TypeScript
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,
|
|
};
|
|
});
|