feat: phase 4 - frontend groups UI, permission-matrix, usePermission hook, field-level permissions tab, authStore permissions

This commit is contained in:
Agent Zero
2026-07-15 23:27:11 +02:00
parent beaca24480
commit bb6466b53d
7 changed files with 1055 additions and 30 deletions
+105
View File
@@ -88,10 +88,18 @@ export interface PermissionItem {
plugin_name?: string;
}
export interface FieldDefinition {
module: string;
field: string;
label: string;
sensitivity: string;
}
export interface PermissionsResponse {
system: PermissionItem[];
plugins: PermissionItem[];
all: PermissionItem[];
field_definitions?: FieldDefinition[];
}
export interface Plugin {
@@ -907,3 +915,100 @@ export function useDeleteAddress() {
},
});
}
// ════════════════════════════════════════════════════════════════════════════
// Group hooks
// ════════════════════════════════════════════════════════════════════════════
export interface Group {
id: string;
name: string;
description: string | null;
permissions: Record<string, any>;
denied_permissions: string[];
field_permissions: Record<string, any>;
permission_version: number;
}
export interface GroupMember {
user_id: string;
email: string;
name: string;
is_active: boolean;
}
export function useGroups() {
return useQuery({
queryKey: ['groups'],
queryFn: () => apiGet<{ items: Group[] }>('/groups'),
});
}
export function useCreateGroup() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: Partial<Group>) => apiPost('/groups', data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['groups'] });
},
});
}
export function useUpdateGroup() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: Partial<Group> }) =>
apiPatch(`/groups/${id}`, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['groups'] });
},
});
}
export function useDeleteGroup() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: string) => apiDelete(`/groups/${id}`),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['groups'] });
},
});
}
export function useGroupMembers(groupId: string | null) {
return useQuery({
queryKey: ['groupMembers', groupId],
queryFn: () => apiGet<{ items: GroupMember[] }>(`/groups/${groupId}/members`),
enabled: !!groupId,
});
}
export function useAddGroupMember() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ groupId, userId }: { groupId: string; userId: string }) =>
apiPost(`/groups/${groupId}/members`, { user_id: userId }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['groupMembers'] });
},
});
}
export function useRemoveGroupMember() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ groupId, userId }: { groupId: string; userId: string }) =>
apiDelete(`/groups/${groupId}/members/${userId}`),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['groupMembers'] });
},
});
}
export function useUserGroups(userId: string | null) {
return useQuery({
queryKey: ['userGroups', userId],
queryFn: () => apiGet<{ items: Group[] }>(`/groups/user/${userId}`),
enabled: !!userId,
});
}