aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web
diff options
context:
space:
mode:
authorAdrian-Ryan Acala <github@adrianacala.com>2025-06-07 08:29:50 -0700
committerGitHub <noreply@github.com>2025-06-07 16:29:50 +0100
commitf53ad0a1bf373e4064ff3e142bfce4b27e4ef9d5 (patch)
treed6c73b00fdfe19ee7f4d30b3a9481a5c72fc240d /apps/web
parent090c0d1c3c1b6bf2f569eb4c9e1164523f048319 (diff)
downloadkarakeep-f53ad0a1bf373e4064ff3e142bfce4b27e4ef9d5.tar.zst
fix: preserve unsaved title changes when modifying bookmark tags in the edit dialog (#1515)
* feat: preserve unsaved title changes when modifying bookmark tags Prevents loss of unsaved title edits when users interact with tag selectors or other UI elements. Adds useDialogFormReset hook to maintain form state consistency across component re-renders. Fixes #1339 * Revert unnecessary modifications --------- Co-authored-by: Mohamed Bassem <me@mbassem.com>
Diffstat (limited to 'apps/web')
-rw-r--r--apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx11
-rw-r--r--apps/web/lib/hooks/useDialogFormReset.ts27
2 files changed, 32 insertions, 6 deletions
diff --git a/apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx b/apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx
index f0ede24e..021a7b05 100644
--- a/apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx
+++ b/apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx
@@ -27,6 +27,7 @@ import {
} from "@/components/ui/popover";
import { Textarea } from "@/components/ui/textarea";
import { toast } from "@/components/ui/use-toast";
+import { useDialogFormReset } from "@/lib/hooks/useDialogFormReset";
import { useTranslation } from "@/lib/i18n/client";
import { cn } from "@/lib/utils";
import { zodResolver } from "@hookform/resolvers/zod";
@@ -124,12 +125,10 @@ export function EditBookmarkDialog({
updateBookmarkMutate(payload);
}
- // Reset form when bookmark data changes externally or dialog reopens
- React.useEffect(() => {
- if (open) {
- form.reset(bookmarkToDefault(bookmark));
- }
- }, [bookmark, form, open]);
+ // Reset form only when dialog is initially opened to preserve unsaved changes
+ // This prevents losing unsaved title edits when tags are updated, which would
+ // cause the bookmark prop to change and trigger a form reset
+ useDialogFormReset(open, form, bookmarkToDefault(bookmark));
const isLink = bookmark.content.type === BookmarkTypes.LINK;
const isAsset = bookmark.content.type === BookmarkTypes.ASSET;
diff --git a/apps/web/lib/hooks/useDialogFormReset.ts b/apps/web/lib/hooks/useDialogFormReset.ts
new file mode 100644
index 00000000..de087ca9
--- /dev/null
+++ b/apps/web/lib/hooks/useDialogFormReset.ts
@@ -0,0 +1,27 @@
+import type { FieldValues, UseFormReturn } from "react-hook-form";
+import { useEffect, useRef } from "react";
+
+/**
+ * Custom hook to handle form reset behavior in dialogs
+ * Only resets the form when the dialog transitions from closed to open,
+ * preventing loss of unsaved changes when external data updates occur
+ *
+ * @param open - Dialog open state
+ * @param form - React Hook Form instance
+ * @param resetData - Data to reset the form with
+ */
+export function useDialogFormReset<T extends FieldValues>(
+ open: boolean,
+ form: UseFormReturn<T>,
+ resetData: T,
+) {
+ const prevOpenRef = useRef(open);
+
+ useEffect(() => {
+ // Only reset form when transitioning from closed to open, not on data updates
+ if (open && !prevOpenRef.current) {
+ form.reset(resetData);
+ }
+ prevOpenRef.current = open;
+ }, [open, form, resetData]);
+}