diff --git a/src/atoms/tableScope/ui.ts b/src/atoms/tableScope/ui.ts index aca5aae6..df14fc60 100644 --- a/src/atoms/tableScope/ui.ts +++ b/src/atoms/tableScope/ui.ts @@ -5,12 +5,6 @@ import type { PopoverProps } from "@mui/material"; import type { ColumnConfig, TableFilter } from "@src/types/table"; import { SEVERITY_LEVELS } from "@src/components/TableToolbar/CloudLogs/CloudLogSeverityIcon"; -function beforeUnloadHandler(event: BeforeUnloadEvent) { - event.preventDefault(); - return (event.returnValue = - "Are you sure you want to leave? You may have unsaved changes."); -} - /** * Open table column menu. Set to `null` to close. * @@ -112,34 +106,6 @@ export const selectedCellAtom = atom<{ columnKey: string; } | null>(null); -/* -function selectedCellBeforeUnloadHandler(event: BeforeUnloadEvent) { - event.preventDefault(); - return (event.returnValue = - "Are you sure you want to leave? You have selected a cell and will lose your position in the table."); -} -export type SelectedCell = { - path: string; - columnKey: string; -}; - -export const selectedCellAtom = atom< - SelectedCell | null, - SetStateAction ->(null, (get, set, update) => { - window.removeEventListener("beforeunload", selectedCellBeforeUnloadHandler); - if (update !== null) { - console.log("set beforeunload"); - window.addEventListener("beforeunload", selectedCellBeforeUnloadHandler); - } - - set( - selectedCellAtom, - isFunction(update) ? update(get(selectedCellAtom)) : update - ); -}); -*/ - export type CloudLogFilters = { type: "webhook" | "functions" | "audit" | "build"; timeRange: @@ -150,7 +116,7 @@ export type CloudLogFilters = { auditRowId?: string; buildLogExpanded?: number; }; - +/** Store cloud log modal filters in URL */ export const cloudLogFiltersAtom = atomWithHash( "cloudLogFilters", { diff --git a/src/hooks/useBeforeUnload.ts b/src/hooks/useBeforeUnload.ts new file mode 100644 index 00000000..9a42ba66 --- /dev/null +++ b/src/hooks/useBeforeUnload.ts @@ -0,0 +1,28 @@ +import { useEffect } from "react"; +import { useAtom, Atom } from "jotai"; +import { Scope } from "jotai/core/atom"; + +function beforeUnloadHandler(event: BeforeUnloadEvent) { + event.preventDefault(); + return (event.returnValue = + "Are you sure you want to leave? You may have unsaved changes."); +} + +/** + * Displays an alert when the user tries to leave the page + * while the atom value is not falsy + * @param atom - The atom’s value to listen to + * @param scope - The atom scope + */ +export default function useBeforeUnload(atom: Atom, scope: Scope) { + const [atomValue] = useAtom(atom, scope); + + const atomValueFalsy = !atomValue; + useEffect(() => { + if (atomValueFalsy) + window.removeEventListener("beforeunload", beforeUnloadHandler); + else window.addEventListener("beforeunload", beforeUnloadHandler); + }, [atomValueFalsy]); + + return !atomValueFalsy; +} diff --git a/src/pages/Table.tsx b/src/pages/Table.tsx index c6b5caa0..6369d720 100644 --- a/src/pages/Table.tsx +++ b/src/pages/Table.tsx @@ -21,14 +21,20 @@ import TableSourceFirestore from "@src/sources/TableSourceFirestore"; import { tableScope, tableIdAtom, - // tableSettingsAtom, tableSchemaAtom, + columnModalAtom, + tableModalAtom, } from "@src/atoms/tableScope"; +import useBeforeUnload from "@src/hooks/useBeforeUnload"; import ActionParamsProvider from "@src/components/fields/Action/FormDialog/Provider"; function TablePage() { const [tableSchema] = useAtom(tableSchemaAtom, tableScope); + // Warn user about leaving when they have a table modal open + useBeforeUnload(columnModalAtom, tableScope); + useBeforeUnload(tableModalAtom, tableScope); + // A ref to the data grid. Contains data grid functions const dataGridRef = useRef(null);