feat: folder permissions (ACLs) - share folders with users/groups, inherit to subfolders, permission dialog UI

This commit is contained in:
Agent Zero
2026-07-28 23:58:19 +02:00
parent 784a771039
commit cc021cda99
12 changed files with 1185 additions and 4 deletions
+69
View File
@@ -112,3 +112,72 @@ export function useMoveContactToFolder() {
},
});
}
// ── Folder Permissions ──
export function useFolderPermissions(folderId: string | null) {
return useQuery({
queryKey: ['folderPermissions', folderId],
queryFn: async () => {
if (!folderId) return { items: [], total: 0 };
const res = await apiGet<{ items: import('./contactFolders').FolderPermission[]; total: number }>(
`/contact-folders/${folderId}/permissions`
);
return res;
},
enabled: !!folderId,
});
}
export function useCreateFolderPermission() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({
folderId,
data,
}: {
folderId: string;
data: {
user_id?: string;
group_id?: string;
permission_level: string;
inherit_to_subfolders?: boolean;
};
}) => apiPost(`/contact-folders/${folderId}/permissions`, data),
onSuccess: (_data, vars) => {
queryClient.invalidateQueries({ queryKey: ['folderPermissions', vars.folderId] });
queryClient.invalidateQueries({ queryKey: ['contactFolders'] });
},
});
}
export function useUpdateFolderPermission() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({
folderId,
permissionId,
data,
}: {
folderId: string;
permissionId: string;
data: { permission_level: string; inherit_to_subfolders?: boolean };
}) => apiPut(`/contact-folders/${folderId}/permissions/${permissionId}`, data),
onSuccess: (_data, vars) => {
queryClient.invalidateQueries({ queryKey: ['folderPermissions', vars.folderId] });
queryClient.invalidateQueries({ queryKey: ['contactFolders'] });
},
});
}
export function useDeleteFolderPermission() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ folderId, permissionId }: { folderId: string; permissionId: string }) =>
apiDelete(`/contact-folders/${folderId}/permissions/${permissionId}`),
onSuccess: (_data, vars) => {
queryClient.invalidateQueries({ queryKey: ['folderPermissions', vars.folderId] });
queryClient.invalidateQueries({ queryKey: ['contactFolders'] });
},
});
}