Files
leocrm/frontend/src/api/hooks/workspaces.ts
T

219 lines
6.8 KiB
TypeScript
Raw Normal View History

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'] });
},
});
}
// ─── Widget Hooks ─────────────────────────────────────────────
export interface WorkspaceWidget {
id: string;
workspace_id: string;
widget_key: string;
position_x: number;
position_y: number;
width: number;
height: number;
config: Record<string, any>;
}
export function useWorkspaceWidgets(workspaceId: string | null) {
return useQuery<{ items: WorkspaceWidget[]; total: number }>({
queryKey: ['workspace-widgets', workspaceId],
queryFn: () => apiGet(`/api/v1/workspaces/${workspaceId}/widgets`),
enabled: !!workspaceId,
});
}
export function useCreateWorkspaceWidget() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ workspaceId, ...data }: {
workspaceId: string;
widget_key: string;
position_x?: number;
position_y?: number;
width?: number;
height?: number;
config?: Record<string, any>;
}) => apiPost(`/api/v1/workspaces/${workspaceId}/widgets`, data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['workspace-widgets'] });
qc.invalidateQueries({ queryKey: ['workspace-context'] });
},
});
}
export function useUpdateWorkspaceWidget() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ workspaceId, widgetId, ...data }: {
workspaceId: string;
widgetId: string;
position_x?: number;
position_y?: number;
width?: number;
height?: number;
config?: Record<string, any>;
}) => apiPut(`/api/v1/workspaces/${workspaceId}/widgets/${widgetId}`, data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['workspace-widgets'] });
qc.invalidateQueries({ queryKey: ['workspace-context'] });
},
});
}
export function useDeleteWorkspaceWidget() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ workspaceId, widgetId }: { workspaceId: string; widgetId: string }) =>
apiDelete(`/api/v1/workspaces/${workspaceId}/widgets/${widgetId}`),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['workspace-widgets'] });
qc.invalidateQueries({ queryKey: ['workspace-context'] });
},
});
}
// ─── Set Default Workspace ────────────────────────────────────
export function useSetDefaultWorkspace() {
const qc = useQueryClient();
return useMutation({
mutationFn: (workspaceId: string) =>
apiPost(`/api/v1/workspaces/${workspaceId}/set-default`),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['my-workspaces'] });
},
});
}