phase5: workspace frontend — API hooks, useWorkspace hook, WorkspaceSwitcher, Sidebar workspace filter
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useMyWorkspaces, useWorkspaceContext, type WorkspaceContext } from '@/api/hooks/workspaces';
|
||||
|
||||
const STORAGE_KEY = 'leocrm-active-workspace';
|
||||
|
||||
/**
|
||||
* Manages the active workspace for the current browser tab.
|
||||
*
|
||||
* Uses sessionStorage (per-tab, not shared across tabs) to store the active workspace ID.
|
||||
* Sends X-Workspace-ID header on workspace-aware requests.
|
||||
*
|
||||
* Workspaces are UI/navigation context only — they never affect permissions.
|
||||
*/
|
||||
export function useWorkspace() {
|
||||
const [activeWorkspaceId, setActiveWorkspaceId] = useState<string | null>(() => {
|
||||
return sessionStorage.getItem(STORAGE_KEY);
|
||||
});
|
||||
|
||||
const { data: myWorkspaces } = useMyWorkspaces();
|
||||
const { data: context } = useWorkspaceContext(activeWorkspaceId);
|
||||
|
||||
// Auto-select default workspace if none selected
|
||||
useEffect(() => {
|
||||
if (!activeWorkspaceId && myWorkspaces?.items?.length) {
|
||||
const defaultWs = myWorkspaces.items.find(w => w.is_user_default) || myWorkspaces.items[0];
|
||||
if (defaultWs) {
|
||||
setActiveWorkspaceId(defaultWs.id);
|
||||
sessionStorage.setItem(STORAGE_KEY, defaultWs.id);
|
||||
}
|
||||
}
|
||||
}, [activeWorkspaceId, myWorkspaces]);
|
||||
|
||||
// Switch workspace (per-tab)
|
||||
const switchWorkspace = useCallback((workspaceId: string | null) => {
|
||||
if (workspaceId) {
|
||||
sessionStorage.setItem(STORAGE_KEY, workspaceId);
|
||||
} else {
|
||||
sessionStorage.removeItem(STORAGE_KEY);
|
||||
}
|
||||
setActiveWorkspaceId(workspaceId);
|
||||
}, []);
|
||||
|
||||
// Get visible module keys from workspace context
|
||||
const visibleModuleKeys: Set<string> = new Set(
|
||||
context?.modules?.map(m => m.module_key) || []
|
||||
);
|
||||
|
||||
// Check if a module is visible in the current workspace
|
||||
const isModuleVisible = useCallback((moduleKey: string): boolean => {
|
||||
// If no workspace context, show all (backward compatible)
|
||||
if (!context?.workspace_id || !context?.modules?.length) return true;
|
||||
return visibleModuleKeys.has(moduleKey);
|
||||
}, [context, visibleModuleKeys]);
|
||||
|
||||
return {
|
||||
activeWorkspaceId,
|
||||
activeWorkspace: context,
|
||||
myWorkspaces: myWorkspaces?.items || [],
|
||||
switchWorkspace,
|
||||
isModuleVisible,
|
||||
visibleModuleKeys,
|
||||
hasWorkspaces: (myWorkspaces?.items?.length || 0) > 0,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user