Browse Source

fix(dashboard): Prevent navigation blocker on creating entity

Michael Bromley 8 months ago
parent
commit
b5851d5c22

+ 20 - 10
packages/dashboard/src/lib/components/shared/navigation-confirmation.tsx

@@ -1,9 +1,9 @@
-import { Trans } from "@/lib/trans.js";
-import { useBlocker } from "@tanstack/react-router";
-import { UseFormReturn } from "react-hook-form";
+import { Trans } from '@/lib/trans.js';
+import { useBlocker } from '@tanstack/react-router';
+import { UseFormReturn } from 'react-hook-form';
 
-import { Button } from "../ui/button.js";
-import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog.js";
+import { Button } from '../ui/button.js';
+import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '../ui/dialog.js';
 
 export interface NavigationConfirmationProps {
     form: UseFormReturn<any>;
@@ -12,19 +12,29 @@ export interface NavigationConfirmationProps {
 /**
  * Navigation confirmation dialog that blocks navigation when the form is dirty.
  */
-export function NavigationConfirmation(props: NavigationConfirmationProps) {
+export function NavigationConfirmation(props: Readonly<NavigationConfirmationProps>) {
     const { proceed, reset, status } = useBlocker({
-        shouldBlockFn: () => props.form.formState.isDirty,
+        shouldBlockFn: (args) => {
+            // When a new entity is being created, we don't want to block navigation
+            // to the newly-created entity page.
+            const isNavigatingToNewlyCreatedEntity = args.current.fullPath === args.next.fullPath
+                && args.current.params.id === 'new' && args.next.params.id !== 'new'
+            if (isNavigatingToNewlyCreatedEntity) {
+                return false;
+            }
+            return props.form.formState.isDirty;
+        },
         withResolver: true,
         enableBeforeUnload: true,
-    })
+    });
     return (
         <Dialog open={status === 'blocked'} onOpenChange={reset}>
             <DialogContent className="sm:max-w-[425px]">
                 <DialogHeader>
                     <DialogTitle><Trans>Confirm navigation</Trans></DialogTitle>
                     <DialogDescription>
-                        <Trans>Are you sure you want to navigate away from this page? Any unsaved changes will be lost.</Trans>
+                        <Trans>Are you sure you want to navigate away from this page? Any unsaved changes will be
+                            lost.</Trans>
                     </DialogDescription>
                 </DialogHeader>
                 <DialogFooter>
@@ -35,5 +45,5 @@ export function NavigationConfirmation(props: NavigationConfirmationProps) {
                 </DialogFooter>
             </DialogContent>
         </Dialog>
-    )
+    );
 }