feat: Clear all traces for flow (#12354)

feat: add useDeleteTracesMutation for deleting traces and integrate into FlowInsightsContent
- Introduced a new mutation hook `useDeleteTracesMutation` for deleting traces via API.
- Updated `FlowInsightsContent` to include a button for clearing all records with confirmation dialog.
- Integrated success and error alerts for delete operations.
This commit is contained in:
Arek Mateusiak
2026-04-29 15:27:05 +02:00
committed by GitHub
parent 9514c9dc06
commit 760da3889b
3 changed files with 110 additions and 8 deletions

View File

@ -1,2 +1,3 @@
export * from "./use-delete-traces";
export * from "./use-get-trace";
export * from "./use-get-traces";

View File

@ -0,0 +1,20 @@
import type { useMutationFunctionType } from "@/types/api";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";
export const useDeleteTracesMutation: useMutationFunctionType<
undefined,
{ flow_id: string }
> = (options) => {
const { mutate } = UseRequestProcessor();
const deleteTracesFn = async (params: {
flow_id: string;
}): Promise<undefined> => {
await api.delete(`${getURL("TRACES")}`, { params });
return undefined;
};
return mutate(["useDeleteTracesMutation"], deleteTracesFn, options);
};

View File

@ -13,7 +13,13 @@ import {
} from "@/components/ui/accordion";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import {
Select,
@ -22,8 +28,12 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { useGetTracesQuery } from "@/controllers/API/queries/traces";
import {
useDeleteTracesMutation,
useGetTracesQuery,
} from "@/controllers/API/queries/traces";
import { TraceListItem } from "@/controllers/API/queries/traces/types";
import useAlertStore from "@/stores/alertStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { cn } from "@/utils/utils";
import { createFlowTracesColumns } from "./config/flowTraceColumns";
@ -58,9 +68,33 @@ export function FlowInsightsContent({
const [startDate, setStartDate] = useState<string>("");
const [endDateValue, setEndDateValue] = useState<string>("");
const [groupBySession, setGroupBySession] = useState<boolean>(false);
const [clearConfirmOpen, setClearConfirmOpen] = useState(false);
const flowIdFromUrl = searchParams.get("id");
const resolvedFlowId = flowId ?? currentFlowId ?? flowIdFromUrl;
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
const { mutate: deleteTraces } = useDeleteTracesMutation({
onSuccess: () => {
setSuccessData({ title: "Records cleared successfully" });
refetch();
},
onError: (error) => {
setErrorData({
title: "Error clearing records",
list: [error.message],
});
},
});
const handleClearAll = useCallback(() => {
const trustedFlowId = flowId ?? currentFlowId;
if (trustedFlowId) {
deleteTraces({ flow_id: trustedFlowId });
}
}, [flowId, currentFlowId, deleteTraces]);
const resolvedFlowName = useFlowsManagerStore((state) => {
if (!resolvedFlowId) return state.currentFlow?.name;
return state.getFlowById(resolvedFlowId)?.name ?? state.currentFlow?.name;
@ -97,16 +131,14 @@ export function FlowInsightsContent({
size: pageSize,
},
},
{ enabled: !!resolvedFlowId },
{
enabled: !!resolvedFlowId,
refetchOnMount: refreshOnMount ? "always" : true,
},
);
const rows = tracesData?.traces ?? [];
useEffect(() => {
if (!refreshOnMount) return;
refetch();
}, [refreshOnMount, refetch]);
useEffect(() => {
if (!initialTraceId) return;
setTracePanelTraceId(initialTraceId);
@ -284,6 +316,55 @@ export function FlowInsightsContent({
onEndDateChange={setEndDateValue}
/>
{totalRuns > 0 && (
<Button
variant="ghost"
className="h-8 w-8 p-0 text-destructive hover:bg-destructive/10 hover:text-destructive"
aria-label="Clear All"
onClick={(e) => {
(e.currentTarget as HTMLButtonElement).blur();
setClearConfirmOpen(true);
}}
>
<IconComponent name="Trash2" className="h-4 w-4" />
</Button>
)}
<Dialog open={clearConfirmOpen} onOpenChange={setClearConfirmOpen}>
<DialogContent className="max-w-sm">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<IconComponent
name="Trash2"
className="h-5 w-5 text-destructive"
/>
Clear All Records
</DialogTitle>
</DialogHeader>
<p className="text-sm text-muted-foreground">
Are you sure you want to clear all records? This will
permanently delete all related Flow Activity Traces and cannot
be undone.
</p>
<DialogFooter>
<Button
variant="outline"
onClick={() => setClearConfirmOpen(false)}
>
Cancel
</Button>
<Button
variant="destructive"
onClick={() => {
handleClearAll();
setClearConfirmOpen(false);
}}
>
Clear All
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<Button
variant="ghost"
size="icon"