From 71a61d424fa85aed5f8bda9cc4e695486166f822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B4nio=20Alexandre=20Borges=20Lima?= <104531655+AntonioABLima@users.noreply.github.com> Date: Wed, 4 Feb 2026 17:47:13 -0300 Subject: [PATCH] fix: modal autofocus close button (#11425) * fix: improve focus behavior in FlowLogsModal * fix: improve focus behavior in SaveChangesModal * refactor: extract onOpenAutoFocus handlers * check if element exists before prevent * [autofix.ci] apply automated fixes --------- Co-authored-by: Cristhian Zanforlin Lousa Co-authored-by: Carlos Coelho <80289056+carlosrcoelho@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- src/frontend/src/modals/baseModal/index.tsx | 4 ++++ .../src/modals/confirmationModal/index.tsx | 8 +++++++- .../src/modals/flowLogsModal/index.tsx | 18 +++++++++++++++++- .../src/modals/saveChangesModal/index.tsx | 11 ++++++++++- src/frontend/src/types/components/index.ts | 1 + src/frontend/tests/core/features/logs.spec.ts | 4 +++- 6 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/modals/baseModal/index.tsx b/src/frontend/src/modals/baseModal/index.tsx index 16260140b5..b57b42ab3c 100644 --- a/src/frontend/src/modals/baseModal/index.tsx +++ b/src/frontend/src/modals/baseModal/index.tsx @@ -217,6 +217,7 @@ interface BaseModalProps { type?: "modal" | "dialog" | "full-screen"; onSubmit?: () => void; onEscapeKeyDown?: (e: KeyboardEvent) => void; + onOpenAutoFocus?: (e: Event) => void; closeButtonClassName?: string; dialogContentWithouFixed?: boolean; } @@ -230,6 +231,7 @@ function BaseModal({ type = "dialog", onSubmit, onEscapeKeyDown, + onOpenAutoFocus, closeButtonClassName, dialogContentWithouFixed = false, }: BaseModalProps) { @@ -290,6 +292,7 @@ function BaseModal({ e.stopPropagation()} onEscapeKeyDown={onEscapeKeyDown} + onOpenAutoFocus={onOpenAutoFocus} className={contentClasses} closeButtonClassName={closeButtonClassName} > @@ -311,6 +314,7 @@ function BaseModal({ e.stopPropagation()} onEscapeKeyDown={onEscapeKeyDown} + onOpenAutoFocus={onOpenAutoFocus} className={contentClasses} closeButtonClassName={closeButtonClassName} > diff --git a/src/frontend/src/modals/confirmationModal/index.tsx b/src/frontend/src/modals/confirmationModal/index.tsx index b28e323678..e7a510313b 100644 --- a/src/frontend/src/modals/confirmationModal/index.tsx +++ b/src/frontend/src/modals/confirmationModal/index.tsx @@ -41,6 +41,7 @@ function ConfirmationModal({ index, onConfirm, open, + onOpenAutoFocus, onClose, onCancel, ...props @@ -78,7 +79,12 @@ function ConfirmationModal({ }; return ( - + {triggerChild} {title} diff --git a/src/frontend/src/modals/flowLogsModal/index.tsx b/src/frontend/src/modals/flowLogsModal/index.tsx index 152d2846c1..78ca6671b0 100644 --- a/src/frontend/src/modals/flowLogsModal/index.tsx +++ b/src/frontend/src/modals/flowLogsModal/index.tsx @@ -90,9 +90,25 @@ export default function FlowLogsModal({ } }, []); + const handleOpenAutoFocus = useCallback((e: Event) => { + const viewport = document.querySelector( + ".ag-body-viewport", + ) as HTMLElement | null; + if (viewport) { + e.preventDefault(); + viewport.focus(); + } + // If viewport doesn't exist (empty table), let default focus behavior happen + }, []); + return ( <> - + {children}
diff --git a/src/frontend/src/modals/saveChangesModal/index.tsx b/src/frontend/src/modals/saveChangesModal/index.tsx index c47923b16c..de7f110638 100644 --- a/src/frontend/src/modals/saveChangesModal/index.tsx +++ b/src/frontend/src/modals/saveChangesModal/index.tsx @@ -1,5 +1,5 @@ import { truncate } from "lodash"; -import { useState } from "react"; +import { useCallback, useState } from "react"; import ForwardedIconComponent from "@/components/common/genericIconComponent"; import Loading from "@/components/ui/loading"; import ConfirmationModal from "../confirmationModal"; @@ -20,6 +20,14 @@ export function SaveChangesModal({ autoSave: boolean; }): JSX.Element { const [saving, setSaving] = useState(false); + + const handleOpenAutoFocus = useCallback((e: Event) => { + e.preventDefault(); + ( + document.querySelector('[data-testid="replace-button"]') as HTMLElement + )?.focus(); + }, []); + return ( {autoSave ? ( diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index c59751fb29..1f0af0a6a5 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -407,6 +407,7 @@ export type ConfirmationModalType = { | "small-h-full" | "medium-h-full"; onEscapeKeyDown?: (e: KeyboardEvent) => void; + onOpenAutoFocus?: (e: Event) => void; }; export type UserManagementType = { diff --git a/src/frontend/tests/core/features/logs.spec.ts b/src/frontend/tests/core/features/logs.spec.ts index 90445a3386..204b05e670 100644 --- a/src/frontend/tests/core/features/logs.spec.ts +++ b/src/frontend/tests/core/features/logs.spec.ts @@ -89,7 +89,9 @@ test( await expect( page.getByText("timestamp", { exact: true }).last(), ).toBeAttached(); - await expect(page.getByText("text", { exact: true }).last()).toBeAttached(); + await expect( + page.getByText("files", { exact: true }).last(), + ).toBeAttached(); await expect( page.getByText("sender", { exact: true }).last(), ).toBeAttached();