phase5: workspace frontend — API hooks, useWorkspace hook, WorkspaceSwitcher, Sidebar workspace filter
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { apiGet, apiPost, apiPut, apiDelete } from '@/api/client';
|
||||
|
||||
export interface WorkspaceModule {
|
||||
id?: string;
|
||||
module_key: string;
|
||||
is_visible: boolean;
|
||||
menu_order: number;
|
||||
config: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface Workspace {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
description: string | null;
|
||||
is_default: boolean;
|
||||
is_active: boolean;
|
||||
created_by: string | null;
|
||||
created_at: string | null;
|
||||
updated_at: string | null;
|
||||
modules?: WorkspaceModule[];
|
||||
user_count?: number;
|
||||
}
|
||||
|
||||
export interface MyWorkspace extends Workspace {
|
||||
role: 'member' | 'manager';
|
||||
is_user_default: boolean;
|
||||
}
|
||||
|
||||
export interface WorkspaceContext {
|
||||
workspace_id: string | null;
|
||||
name?: string;
|
||||
icon?: string;
|
||||
role?: string;
|
||||
modules: { module_key: string; menu_order: number; config: Record<string, any> }[];
|
||||
widgets: { id: string; widget_key: string; position_x: number; position_y: number; width: number; height: number; config: Record<string, any> }[];
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export function useWorkspaces() {
|
||||
return useQuery<{ items: Workspace[]; total: number }>({
|
||||
queryKey: ['workspaces'],
|
||||
queryFn: () => apiGet('/api/v1/workspaces'),
|
||||
});
|
||||
}
|
||||
|
||||
export function useMyWorkspaces() {
|
||||
return useQuery<{ items: MyWorkspace[]; total: number }>({
|
||||
queryKey: ['my-workspaces'],
|
||||
queryFn: () => apiGet('/api/v1/workspaces/my'),
|
||||
});
|
||||
}
|
||||
|
||||
export function useWorkspaceContext(workspaceId: string | null) {
|
||||
return useQuery<WorkspaceContext>({
|
||||
queryKey: ['workspace-context', workspaceId],
|
||||
queryFn: () => apiGet('/api/v1/workspaces/context', {
|
||||
headers: workspaceId ? { 'X-Workspace-ID': workspaceId } : {},
|
||||
}),
|
||||
enabled: !!workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
export function useCreateWorkspace() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (data: { name: string; icon?: string; description?: string; is_default?: boolean }) =>
|
||||
apiPost('/api/v1/workspaces', data),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['workspaces'] });
|
||||
qc.invalidateQueries({ queryKey: ['my-workspaces'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useUpdateWorkspace() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, ...data }: { id: string; name?: string; icon?: string; description?: string; is_default?: boolean; is_active?: boolean }) =>
|
||||
apiPut(`/api/v1/workspaces/${id}`, data),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['workspaces'] });
|
||||
qc.invalidateQueries({ queryKey: ['my-workspaces'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useDeleteWorkspace() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (id: string) => apiDelete(`/api/v1/workspaces/${id}`),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['workspaces'] });
|
||||
qc.invalidateQueries({ queryKey: ['my-workspaces'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useSetWorkspaceModules() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ workspaceId, modules }: { workspaceId: string; modules: WorkspaceModule[] }) =>
|
||||
apiPost(`/api/v1/workspaces/${workspaceId}/modules`, { modules }),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['workspaces'] });
|
||||
qc.invalidateQueries({ queryKey: ['my-workspaces'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useAssignWorkspaceUser() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ workspaceId, userId, role }: { workspaceId: string; userId: string; role?: string }) =>
|
||||
apiPost(`/api/v1/workspaces/${workspaceId}/users`, { user_id: userId, role: role || 'member' }),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['workspaces'] });
|
||||
qc.invalidateQueries({ queryKey: ['my-workspaces'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useRemoveWorkspaceUser() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ workspaceId, userId }: { workspaceId: string; userId: string }) =>
|
||||
apiDelete(`/api/v1/workspaces/${workspaceId}/users/${userId}`),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['workspaces'] });
|
||||
qc.invalidateQueries({ queryKey: ['my-workspaces'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user