mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 09:55:06 +03:00
## Problem When editing email templates or edge functions, users may navigate away from the page without a warning indicating they may loose their changes. This is because we only handle the `beforeunload` event when we should also handle NextJS routing events. This is actually done for the observability reports. ## Solution Extract the logic from the observability reports into a reusable component and use it where needed ## How to test On staging, for each case: - Authentication email templates - Observability reports - Edge functions creation - Edge functions edition Test: - Modify the template/report/function - Navigate away using either the sidebar link, the browser back button or closing the tab - Cancel navigation in the confirmation dialog - Navigation should be prevented and you should not loose your changes Test: - Modify the template/report/function - Navigate away using either the sidebar link, the browser back button or closing the tab - Confirm navigation in the confirmation dialog - Navigation should not be prevented and you should have lost your changes
81 lines
2.1 KiB
TypeScript
81 lines
2.1 KiB
TypeScript
'use client'
|
|
|
|
import { useCallback, useEffect, useRef, type ReactNode } from 'react'
|
|
|
|
import { type ConfirmOnCloseModalProps } from 'hooks/ui/useConfirmOnClose'
|
|
import {
|
|
AlertDialog,
|
|
AlertDialogAction,
|
|
AlertDialogCancel,
|
|
AlertDialogContent,
|
|
AlertDialogDescription,
|
|
AlertDialogFooter,
|
|
AlertDialogHeader,
|
|
AlertDialogTitle,
|
|
} from 'ui'
|
|
|
|
export interface DiscardChangesConfirmationDialogProps extends ConfirmOnCloseModalProps {
|
|
title?: ReactNode
|
|
description?: ReactNode
|
|
confirmLabel?: ReactNode
|
|
cancelLabel?: ReactNode
|
|
size?: React.ComponentProps<typeof AlertDialogContent>['size']
|
|
}
|
|
|
|
export const DiscardChangesConfirmationDialog = ({
|
|
visible,
|
|
onClose,
|
|
onCancel,
|
|
title = 'Unsaved changes',
|
|
description = 'You have unsaved changes. Are you sure you want to discard them?',
|
|
confirmLabel = 'Discard changes',
|
|
cancelLabel = 'Keep editing',
|
|
size = 'tiny',
|
|
}: DiscardChangesConfirmationDialogProps) => {
|
|
const isConfirmingRef = useRef(false)
|
|
|
|
useEffect(() => {
|
|
if (visible) {
|
|
isConfirmingRef.current = false
|
|
}
|
|
}, [visible])
|
|
|
|
const handleConfirm = useCallback(() => {
|
|
isConfirmingRef.current = true
|
|
onClose()
|
|
}, [onClose])
|
|
|
|
const handleOpenChange = useCallback(
|
|
(open: boolean) => {
|
|
if (open) return
|
|
|
|
if (isConfirmingRef.current) {
|
|
isConfirmingRef.current = false
|
|
return
|
|
}
|
|
|
|
onCancel()
|
|
},
|
|
[onCancel]
|
|
)
|
|
|
|
return (
|
|
<AlertDialog open={visible} onOpenChange={handleOpenChange}>
|
|
<AlertDialogContent size={size}>
|
|
<AlertDialogHeader>
|
|
<AlertDialogTitle>{title}</AlertDialogTitle>
|
|
{description !== undefined && description !== null && (
|
|
<AlertDialogDescription>{description}</AlertDialogDescription>
|
|
)}
|
|
</AlertDialogHeader>
|
|
<AlertDialogFooter>
|
|
<AlertDialogCancel>{cancelLabel}</AlertDialogCancel>
|
|
<AlertDialogAction variant="danger" onClick={handleConfirm}>
|
|
{confirmLabel}
|
|
</AlertDialogAction>
|
|
</AlertDialogFooter>
|
|
</AlertDialogContent>
|
|
</AlertDialog>
|
|
)
|
|
}
|