feat(web): authoring query/mutation hooks + MSW handlers + shadcn select/checkbox/alert-dialog

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 00:22:59 +02:00
parent f3bab3336c
commit b23a48c310
9 changed files with 647 additions and 13 deletions
+104
View File
@@ -95,3 +95,107 @@ export function useLogout() {
onSuccess: () => qc.setQueryData(["me"], null),
});
}
type ObjectCreateRequest = components["schemas"]["ObjectCreateRequest"];
type ObjectUpdateRequest = components["schemas"]["ObjectUpdateRequest"];
export function useTerms(vocabularyId: string | null | undefined) {
return useQuery({
queryKey: ["terms", vocabularyId],
enabled: !!vocabularyId,
queryFn: async () => {
const { data, error } = await api.GET("/api/admin/vocabularies/{id}/terms", {
params: { path: { id: vocabularyId! } },
});
if (error || !data) throw new Error("failed to load terms");
return data;
},
staleTime: 5 * 60 * 1000,
});
}
export function useAuthorities(kind: string | null | undefined) {
return useQuery({
queryKey: ["authorities", kind],
enabled: !!kind,
queryFn: async () => {
const { data, error } = await api.GET("/api/admin/authorities", {
params: { query: { kind: kind! } },
});
if (error || !data) throw new Error("failed to load authorities");
return data;
},
staleTime: 5 * 60 * 1000,
});
}
export function useCreateObject() {
const qc = useQueryClient();
return useMutation({
mutationFn: async (body: ObjectCreateRequest) => {
const { data, error } = await api.POST("/api/admin/objects", { body });
if (error || !data) throw new Error("create failed");
return data;
},
onSuccess: () => qc.invalidateQueries({ queryKey: ["objects"] }),
});
}
export function useUpdateObject() {
const qc = useQueryClient();
return useMutation({
mutationFn: async ({ id, body }: { id: string; body: ObjectUpdateRequest }) => {
const { response } = await api.PUT("/api/admin/objects/{id}", {
params: { path: { id } },
body,
});
if (response.status !== 204) throw new Error("update failed");
},
onSuccess: (_d, { id }) => {
void qc.invalidateQueries({ queryKey: ["objects"] });
void qc.invalidateQueries({ queryKey: ["object", id] });
},
});
}
export function useSetFields() {
const qc = useQueryClient();
return useMutation({
mutationFn: async ({ id, fields }: { id: string; fields: Record<string, unknown> }) => {
const { response } = await api.PUT("/api/admin/objects/{id}/fields", {
params: { path: { id } },
body: fields as Record<string, never>,
});
if (response.status !== 204) throw new Error("set fields failed");
},
onSuccess: (_d, { id }) => {
void qc.invalidateQueries({ queryKey: ["object", id] });
},
});
}
export function useDeleteObject() {
const qc = useQueryClient();
return useMutation({
mutationFn: async (id: string) => {
const { response } = await api.DELETE("/api/admin/objects/{id}", {
params: { path: { id } },
});
if (response.status !== 204) throw new Error("delete failed");
},
onSuccess: () => qc.invalidateQueries({ queryKey: ["objects"] }),
});
}