feat: saved_views backend API + model + migration + frontend hooks

This commit is contained in:
Agent Zero
2026-07-28 14:36:52 +02:00
parent fa28e67fb6
commit 58b163ba78
7 changed files with 335 additions and 25 deletions
+52
View File
@@ -0,0 +1,52 @@
/**
* Saved Views API hooks — CRUD for reusable view configurations.
*/
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiGet, apiPost, apiPut, apiDelete } from './client';
export interface SavedView {
id: string;
name: string;
entity_type: string;
view_config: Record<string, any>;
user_id: string;
created_at?: string;
updated_at?: string;
}
export function useSavedViews(entityType?: string) {
const params = new URLSearchParams();
if (entityType) params.set('entity_type', entityType);
const qs = params.toString() ? `?${params.toString()}` : '';
return useQuery({
queryKey: ['saved-views', entityType],
queryFn: () => apiGet<SavedView[]>(`/saved-views${qs}`),
});
}
export function useCreateSavedView() {
const qc = useQueryClient();
return useMutation({
mutationFn: (data: { name: string; entity_type: string; view_config: Record<string, any> }) =>
apiPost<SavedView>('/saved-views', data),
onSuccess: () => qc.invalidateQueries({ queryKey: ['saved-views'] }),
});
}
export function useUpdateSavedView() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: { name?: string; view_config?: Record<string, any> } }) =>
apiPut<SavedView>(`/saved-views/${id}`, data),
onSuccess: () => qc.invalidateQueries({ queryKey: ['saved-views'] }),
});
}
export function useDeleteSavedView() {
const qc = useQueryClient();
return useMutation({
mutationFn: (id: string) => apiDelete(`/saved-views/${id}`),
onSuccess: () => qc.invalidateQueries({ queryKey: ['saved-views'] }),
});
}