add dialog for confirmation of code cache deletion (#3641)

This commit is contained in:
Shuchang Zheng
2025-10-07 18:16:19 -07:00
committed by GitHub
parent 360def0de5
commit 2b81a1090e
2 changed files with 94 additions and 26 deletions

View File

@@ -198,6 +198,34 @@ function Workspace({
splitLeft: useRef<HTMLInputElement>(null), splitLeft: useRef<HTMLInputElement>(null),
}; };
const handleOnSave = async () => {
const errors = getWorkflowErrors(nodes);
if (errors.length > 0) {
toast({
title: "Encountered error while trying to save workflow:",
description: (
<div className="space-y-2">
{errors.map((error) => (
<p key={error}>{error}</p>
))}
</div>
),
variant: "destructive",
});
return;
}
await saveWorkflow.mutateAsync();
workflowChangesStore.setSaidOkToCodeCacheDeletion(false);
queryClient.invalidateQueries({
queryKey: ["cache-key-values", workflowPermanentId, cacheKey],
});
setCacheKeyValueFilter("");
};
useEffect(() => { useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") { if (event.key === "Escape") {
@@ -802,6 +830,39 @@ function Workspace({
</DialogContent> </DialogContent>
</Dialog> </Dialog>
{/* confirm code cache deletion dialog */}
<Dialog
open={workflowChangesStore.showConfirmCodeCacheDeletion}
onOpenChange={(open) => {
!open && workflowChangesStore.setShowConfirmCodeCacheDeletion(false);
!open && workflowChangesStore.setSaidOkToCodeCacheDeletion(false);
}}
>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure?</DialogTitle>
<DialogDescription>
Saving will delete cached code, and Skyvern will re-generate it in
the next run. Proceed?
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="secondary">Cancel</Button>
</DialogClose>
<Button
variant="default"
onClick={async () => {
workflowChangesStore.setSaidOkToCodeCacheDeletion(true);
await handleOnSave();
}}
>
Yes
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
{/* cache key value delete dialog */} {/* cache key value delete dialog */}
<Dialog <Dialog
open={openConfirmCacheKeyValueDeleteDialogue} open={openConfirmCacheKeyValueDeleteDialogue}
@@ -914,30 +975,7 @@ function Workspace({
}); });
} }
}} }}
onSave={async () => { onSave={async () => await handleOnSave()}
const errors = getWorkflowErrors(nodes);
if (errors.length > 0) {
toast({
title: "Can not save workflow because of errors:",
description: (
<div className="space-y-2">
{errors.map((error) => (
<p key={error}>{error}</p>
))}
</div>
),
variant: "destructive",
});
return;
}
await saveWorkflow.mutateAsync();
queryClient.invalidateQueries({
queryKey: ["cache-key-values", workflowPermanentId, cacheKey],
});
setCacheKeyValueFilter("");
}}
onRun={() => { onRun={() => {
closeWorkflowPanel(); closeWorkflowPanel();
}} }}

View File

@@ -28,15 +28,21 @@ type WorkflowHasChangesStore = {
getSaveData: () => SaveData | null; getSaveData: () => SaveData | null;
hasChanges: boolean; hasChanges: boolean;
saveIsPending: boolean; saveIsPending: boolean;
saidOkToCodeCacheDeletion: boolean;
showConfirmCodeCacheDeletion: boolean;
setGetSaveData: (getSaveData: () => SaveData) => void; setGetSaveData: (getSaveData: () => SaveData) => void;
setHasChanges: (hasChanges: boolean) => void; setHasChanges: (hasChanges: boolean) => void;
setSaveIsPending: (isPending: boolean) => void; setSaveIsPending: (isPending: boolean) => void;
setSaidOkToCodeCacheDeletion: (saidOkToCodeCacheDeletion: boolean) => void;
setShowConfirmCodeCacheDeletion: (show: boolean) => void;
}; };
const useWorkflowHasChangesStore = create<WorkflowHasChangesStore>((set) => { const useWorkflowHasChangesStore = create<WorkflowHasChangesStore>((set) => {
return { return {
hasChanges: false, hasChanges: false,
saveIsPending: false, saveIsPending: false,
saidOkToCodeCacheDeletion: false,
showConfirmCodeCacheDeletion: false,
getSaveData: () => null, getSaveData: () => null,
setGetSaveData: (getSaveData: () => SaveData) => { setGetSaveData: (getSaveData: () => SaveData) => {
set({ getSaveData }); set({ getSaveData });
@@ -47,14 +53,25 @@ const useWorkflowHasChangesStore = create<WorkflowHasChangesStore>((set) => {
setSaveIsPending: (isPending: boolean) => { setSaveIsPending: (isPending: boolean) => {
set({ saveIsPending: isPending }); set({ saveIsPending: isPending });
}, },
setSaidOkToCodeCacheDeletion: (saidOkToCodeCacheDeletion: boolean) => {
set({ saidOkToCodeCacheDeletion });
},
setShowConfirmCodeCacheDeletion: (show: boolean) => {
set({ showConfirmCodeCacheDeletion: show });
},
}; };
}); });
const useWorkflowSave = () => { const useWorkflowSave = () => {
const credentialGetter = useCredentialGetter(); const credentialGetter = useCredentialGetter();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { getSaveData, setHasChanges, setSaveIsPending } = const {
useWorkflowHasChangesStore(); getSaveData,
saidOkToCodeCacheDeletion,
setHasChanges,
setSaveIsPending,
setShowConfirmCodeCacheDeletion,
} = useWorkflowHasChangesStore();
const saveWorkflowMutation = useMutation({ const saveWorkflowMutation = useMutation({
mutationFn: async () => { mutationFn: async () => {
@@ -136,6 +153,11 @@ const useWorkflowSave = () => {
headers: { headers: {
"Content-Type": "text/plain", "Content-Type": "text/plain",
}, },
params: {
delete_code_cache_is_ok: saidOkToCodeCacheDeletion
? "true"
: "false",
},
}, },
); );
}, },
@@ -169,6 +191,14 @@ const useWorkflowSave = () => {
onError: (error: AxiosError) => { onError: (error: AxiosError) => {
const detail = (error.response?.data as { detail?: string })?.detail; const detail = (error.response?.data as { detail?: string })?.detail;
if (
detail &&
detail.startsWith("No confirmation for code cache deletion")
) {
setShowConfirmCodeCacheDeletion(true);
return;
}
toast({ toast({
title: "Error", title: "Error",
description: detail ? detail : error.message, description: detail ? detail : error.message,