Files
leocrm/frontend/src/hooks/useWorkspace.ts
T

77 lines
2.9 KiB
TypeScript
Raw Normal View History

import { useEffect, useCallback } from 'react';
import { useMyWorkspaces, useWorkspaceContext } from '@/api/hooks/workspaces';
import { useWorkspaceStore, type WorkspaceInfo, type WorkspaceContextState } from '@/store/workspaceStore';
import { useAuthStore } from '@/store/authStore';
/**
* Manages the active workspace for the current browser tab.
*
* Uses the central workspaceStore (Zustand) for state management.
* sessionStorage provides per-tab persistence.
* X-Workspace-ID header is sent automatically by the API client interceptor.
*
* Workspaces are UI/navigation context only — they never affect permissions.
*/
export function useWorkspace() {
const activeWorkspaceId = useWorkspaceStore(s => s.activeWorkspaceId);
const context = useWorkspaceStore(s => s.context);
const myWorkspacesFromStore = useWorkspaceStore(s => s.myWorkspaces);
const setActiveWorkspace = useWorkspaceStore(s => s.setActiveWorkspace);
const setContext = useWorkspaceStore(s => s.setContext);
const setMyWorkspaces = useWorkspaceStore(s => s.setMyWorkspaces);
const isModuleVisibleFromStore = useWorkspaceStore(s => s.isModuleVisible);
const user = useAuthStore.getState().user;
const isSystemAdmin = user?.is_system_admin;
// Fetch my workspaces and sync to store
const { data: myWorkspacesData } = useMyWorkspaces();
const { data: contextData } = useWorkspaceContext(activeWorkspaceId);
// Sync fetched workspaces to store
useEffect(() => {
if (myWorkspacesData?.items) {
setMyWorkspaces(myWorkspacesData.items as WorkspaceInfo[]);
}
}, [myWorkspacesData, setMyWorkspaces]);
// Sync fetched context to store
useEffect(() => {
if (contextData !== undefined) {
setContext(contextData as WorkspaceContextState | null);
}
}, [contextData, setContext]);
// Auto-select default workspace if none selected
useEffect(() => {
if (!activeWorkspaceId && myWorkspacesData?.items?.length) {
const defaultWs = myWorkspacesData.items.find(w => w.is_user_default) || myWorkspacesData.items[0];
if (defaultWs) {
setActiveWorkspace(defaultWs.id);
}
}
}, [activeWorkspaceId, myWorkspacesData, setActiveWorkspace]);
// Switch workspace (per-tab)
const switchWorkspace = useCallback((workspaceId: string | null) => {
setActiveWorkspace(workspaceId);
}, [setActiveWorkspace]);
// Check if a module is visible in the current workspace
const isModuleVisible = useCallback((moduleKey: string): boolean => {
return isModuleVisibleFromStore(moduleKey, isSystemAdmin);
}, [isModuleVisibleFromStore, isSystemAdmin]);
const visibleModuleKeys = useWorkspaceStore(s => s.visibleModuleKeys());
return {
activeWorkspaceId,
activeWorkspace: context,
myWorkspaces: myWorkspacesFromStore,
switchWorkspace,
isModuleVisible,
visibleModuleKeys,
hasWorkspaces: myWorkspacesFromStore.length > 0,
};
}