diff --git a/js/src/components/app/Filename.tsx b/js/src/components/app/Filename.tsx index 14135d6b..36cc831c 100644 --- a/js/src/components/app/Filename.tsx +++ b/js/src/components/app/Filename.tsx @@ -24,11 +24,11 @@ import { Tooltip, } from "@chakra-ui/react"; import { useQueryClient } from "@tanstack/react-query"; -import { useEffect, useLayoutEffect, useRef, useState } from "react"; -import { AiOutlineSave } from "react-icons/ai"; +import { useEffect, useRef, useState } from "react"; import { IconEdit, IconSave } from "../icons"; import { AxiosError } from "axios"; import { localStorageKeys } from "@/lib/api/localStorageKeys"; +import { useChecks } from "@/lib/api/checks"; const useRecceToast = () => { const toast = useToast(); @@ -63,6 +63,24 @@ const useRecceToast = () => { return { toastSuccess, toastError }; }; +const useClosePrompt = (prompt: boolean) => { + useEffect(() => { + const handleBeforeUnload = (e: any) => { + e.preventDefault(); + }; + + if (prompt) { + window.addEventListener("beforeunload", handleBeforeUnload); + } + + return () => { + if (prompt) { + window.removeEventListener("beforeunload", handleBeforeUnload); + } + }; + }, [prompt]); +}; + interface FilenameState { newFileName: string; errorMessage?: string; @@ -76,6 +94,12 @@ export const Filename = () => { useLineageGraphContext(); const modalDisclosure = useDisclosure(); const overwriteDisclosure = useDisclosure(); + const isStateless = !fileName && !cloudMode && !isDemoSite; + const { data: checks } = useChecks(isStateless); + const hasNonPresetChecks = + checks != undefined && + checks.filter((check) => !check.is_preset).length > 0; + useClosePrompt(isStateless && hasNonPresetChecks); const [ { newFileName, errorMessage, modified, overwriteWithMethod, bypass }, @@ -165,13 +189,16 @@ export const Filename = () => { return <>; } + const titleNewInstance = + "New Instance" + (hasNonPresetChecks ? " (unsaved)" : ""); + return ( <> - {fileName ? fileName : cloudMode ? "cloud" : "New Instance"} + {fileName ? fileName : cloudMode ? "cloud" : titleNewInstance} - + { check_id: string; @@ -41,6 +43,14 @@ export async function listChecks(): Promise { return response.data; } +export function useChecks(enabled: boolean) { + return useQuery({ + queryKey: cacheKeys.checks(), + queryFn: listChecks, + enabled, + }); +} + export async function getCheck(checkId: string): Promise { const response = await axiosClient.get(`/api/checks/${checkId}`); return response.data;