From 8eb99ed0f8814b6234efa466a5855f6d203ad85a Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 11 Jun 2026 14:55:19 -0700 Subject: [PATCH] FN-6217: prevent visibility-driven quick entry focus Limit Quick Entry focus restoration to successful submissions instead of dashboard visibility changes. - Gate desktop focus restoration behind an in-component successful submit marker. - Remove the stale touch-driven suppressRefocus blur/timer path so touch actions do not force unexpected blurs. - Cover mount, remount, mobile, submit, duplicate-confirm, Escape, Plan, and Subtask focus behavior in QuickEntryBox tests. - Add a patch changeset for the published CLI package. Files changed: .changeset/FN-6217-quick-entry-focus.md | 5 + .../dashboard/app/components/QuickEntryBox.tsx | 36 ++--- .../components/__tests__/QuickEntryBox.test.tsx | 167 +++++++++++++++++++-- 3 files changed, 174 insertions(+), 34 deletions(-) Fusion-Task-Id: FN-6217 Fusion-Task-Lineage: cf8c55c0-583e-42f5-98af-8f3406c86d8c --- .changeset/FN-6217-quick-entry-focus.md | 5 + .../app/components/QuickEntryBox.tsx | 36 ++-- .../__tests__/QuickEntryBox.test.tsx | 173 ++++++++++++++++-- 3 files changed, 177 insertions(+), 37 deletions(-) create mode 100644 .changeset/FN-6217-quick-entry-focus.md diff --git a/.changeset/FN-6217-quick-entry-focus.md b/.changeset/FN-6217-quick-entry-focus.md new file mode 100644 index 0000000000..41b8f7ad1e --- /dev/null +++ b/.changeset/FN-6217-quick-entry-focus.md @@ -0,0 +1,5 @@ +--- +"@runfusion/fusion": patch +--- + +Quick Entry no longer auto-focuses when the board or dashboard becomes visible. diff --git a/packages/dashboard/app/components/QuickEntryBox.tsx b/packages/dashboard/app/components/QuickEntryBox.tsx index f2520b6122..4399da6389 100644 --- a/packages/dashboard/app/components/QuickEntryBox.tsx +++ b/packages/dashboard/app/components/QuickEntryBox.tsx @@ -105,8 +105,8 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels, const textareaRef = useRef(null); const fileInputRef = useRef(null); const touchButtonRef = useRef(null); - const suppressRefocusRef = useRef(false); const justResetRef = useRef(false); + const justSubmittedRef = useRef(false); const previousProjectIdRef = useRef(projectId); const [pendingImages, setPendingImages] = useState([]); const pendingImagesRef = useRef([]); @@ -321,17 +321,20 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels, } }, [description, isExpanded, autoResize]); - // Restore focus after submission completes (when textarea is re-enabled) + // Restore focus after an in-component submission completes (when textarea is re-enabled). useEffect(() => { - if (!isSubmitting && description === "" && textareaRef.current) { - // Use setTimeout to ensure focus happens after React re-enables the textarea - const focusTimeout = setTimeout(() => { - if (typeof window !== "undefined" && window.innerWidth > MOBILE_BREAKPOINT_PX) { - textareaRef.current?.focus(); - } - }, 0); - return () => clearTimeout(focusTimeout); + if (!justSubmittedRef.current || isSubmitting || description !== "" || !textareaRef.current) { + return; } + + justSubmittedRef.current = false; + // Use setTimeout to ensure focus happens after React re-enables the textarea. + const focusTimeout = setTimeout(() => { + if (typeof window !== "undefined" && window.innerWidth > MOBILE_BREAKPOINT_PX) { + textareaRef.current?.focus(); + } + }, 0); + return () => clearTimeout(focusTimeout); }, [isSubmitting, description]); // Clear dep search when dropdown closes @@ -541,6 +544,7 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels, } } resetForm(); + justSubmittedRef.current = true; } catch (err) { setDescription(originalDescription); addToast(getErrorMessage(err) || t("tasks.createFailed", "Failed to create task"), "error"); @@ -737,11 +741,6 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels, }, []); const handleFocus = useCallback(() => { - if (suppressRefocusRef.current) { - textareaRef.current?.blur(); - return; - } - // Auto-expand on focus when autoExpand prop is true (default) if (autoExpand) { setIsExpanded(true); @@ -1497,20 +1496,13 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels, e.preventDefault(); } touchButtonRef.current = button; - suppressRefocusRef.current = true; } }} onTouchEnd={() => { touchButtonRef.current = null; - window.setTimeout(() => { - suppressRefocusRef.current = false; - }, 150); }} onTouchCancel={() => { touchButtonRef.current = null; - window.setTimeout(() => { - suppressRefocusRef.current = false; - }, 150); }} >