feat: phase 4 - frontend groups UI, permission-matrix, usePermission hook, field-level permissions tab, authStore permissions
This commit is contained in:
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user