112 lines
3.4 KiB
TypeScript
112 lines
3.4 KiB
TypeScript
|
|
/**
|
||
|
|
* Permission Templates API client — reusable permission presets.
|
||
|
|
*
|
||
|
|
* Backend: /api/v1/permission-templates (list, create, update, delete,
|
||
|
|
* apply). Templates define default sharing rules; applying them creates
|
||
|
|
* entity_permissions entries automatically.
|
||
|
|
* Permissions: templates:read (list) / templates:write (everything else).
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||
|
|
import { apiGet, apiPost, apiPut, apiDelete } from '@/api/client';
|
||
|
|
|
||
|
|
export type TemplateLevel = 'read' | 'write' | 'admin' | 'delete';
|
||
|
|
|
||
|
|
export interface ShareEntry {
|
||
|
|
principal_type?: string;
|
||
|
|
principal_id?: string;
|
||
|
|
level?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface PermissionTemplate {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
entity_type: string;
|
||
|
|
trigger_condition: Record<string, unknown> | null;
|
||
|
|
auto_share_with: ShareEntry[] | null;
|
||
|
|
level: TemplateLevel;
|
||
|
|
tenant_id: string;
|
||
|
|
created_at: string | null;
|
||
|
|
updated_at: string | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface TemplateListResponse {
|
||
|
|
items: PermissionTemplate[];
|
||
|
|
total: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface TemplateCreatePayload {
|
||
|
|
name: string;
|
||
|
|
entity_type: string;
|
||
|
|
level?: TemplateLevel;
|
||
|
|
trigger_condition?: Record<string, unknown> | null;
|
||
|
|
auto_share_with?: ShareEntry[] | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export type TemplateUpdatePayload = Partial<TemplateCreatePayload>;
|
||
|
|
|
||
|
|
export interface TemplateApplyPayload {
|
||
|
|
entity_type: string;
|
||
|
|
entity_id: string;
|
||
|
|
template_id?: string | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface TemplateApplyResponse {
|
||
|
|
applied: Array<Record<string, unknown>>;
|
||
|
|
count: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ─── Query hooks ─────────────────────────────────────────────
|
||
|
|
|
||
|
|
export function usePermissionTemplates(entityType?: string) {
|
||
|
|
const qs = entityType ? `?entity_type=${encodeURIComponent(entityType)}` : '';
|
||
|
|
return useQuery<TemplateListResponse>({
|
||
|
|
queryKey: ['permission-templates', entityType ?? null],
|
||
|
|
queryFn: () => apiGet<TemplateListResponse>(`/permission-templates${qs}`),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// ─── Mutation hooks ──────────────────────────────────────────
|
||
|
|
|
||
|
|
function useInvalidateTemplates() {
|
||
|
|
const qc = useQueryClient();
|
||
|
|
return () => {
|
||
|
|
qc.invalidateQueries({ queryKey: ['permission-templates'] });
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useCreatePermissionTemplate() {
|
||
|
|
const invalidate = useInvalidateTemplates();
|
||
|
|
return useMutation<PermissionTemplate, Error, TemplateCreatePayload>({
|
||
|
|
mutationFn: (data) => apiPost<PermissionTemplate>('/permission-templates', data),
|
||
|
|
onSuccess: invalidate,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useUpdatePermissionTemplate() {
|
||
|
|
const invalidate = useInvalidateTemplates();
|
||
|
|
return useMutation<
|
||
|
|
PermissionTemplate,
|
||
|
|
Error,
|
||
|
|
{ templateId: string; payload: TemplateUpdatePayload }
|
||
|
|
>({
|
||
|
|
mutationFn: ({ templateId, payload }) =>
|
||
|
|
apiPut<PermissionTemplate>(`/permission-templates/${templateId}`, payload),
|
||
|
|
onSuccess: invalidate,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useDeletePermissionTemplate() {
|
||
|
|
const invalidate = useInvalidateTemplates();
|
||
|
|
return useMutation<void, Error, string>({
|
||
|
|
mutationFn: (templateId) => apiDelete(`/permission-templates/${templateId}`),
|
||
|
|
onSuccess: invalidate,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useApplyPermissionTemplate() {
|
||
|
|
return useMutation<TemplateApplyResponse, Error, TemplateApplyPayload>({
|
||
|
|
mutationFn: (data) => apiPost<TemplateApplyResponse>('/permission-templates/apply', data),
|
||
|
|
});
|
||
|
|
}
|