diff --git a/src/renderer/src/components/automations/use-automations-page-escape.ts b/src/renderer/src/components/automations/use-automations-page-escape.ts index 3f0f8a69ada..03f1f239f73 100644 --- a/src/renderer/src/components/automations/use-automations-page-escape.ts +++ b/src/renderer/src/components/automations/use-automations-page-escape.ts @@ -1,4 +1,5 @@ import { useEffect } from 'react' +import { hasVisibleOverlay } from '@/lib/visible-overlay' import type { AutomationsPageLocalState } from './use-automations-page-local-state' import type { AutomationsPageStoreState } from './use-automations-page-store-state' @@ -9,10 +10,21 @@ export function useAutomationsPageEscape({ store: AutomationsPageStoreState local: AutomationsPageLocalState }): void { - const { closeAutomationsPage } = store - const { createOpen, deleteTarget, externalDeleteTarget } = local + const { activeModal, closeAutomationsPage } = store + const { + createOpen, + deleteTarget, + externalDeleteTarget, + isDetailOpen, + selectedAutomationRunPageId, + selectedExternalRunPage, + setActivePaneTab, + setIsDetailOpen, + setSelectedAutomationRunPageId, + setSelectedExternalRunPage + } = local useEffect(() => { - if (createOpen || deleteTarget || externalDeleteTarget) { + if (createOpen || deleteTarget || externalDeleteTarget || activeModal !== 'none') { return } @@ -21,6 +33,11 @@ export function useAutomationsPageEscape({ return } + // Popovers and menus are outside the store modal registry and own Escape. + if (hasVisibleOverlay()) { + return + } + const target = event.target if (target instanceof Element) { // Fields that clear their own value on Escape consume this press. @@ -44,11 +61,39 @@ export function useAutomationsPageEscape({ } } + if (isDetailOpen) { + event.preventDefault() + if (selectedExternalRunPage) { + setSelectedExternalRunPage(null) + return + } + if (selectedAutomationRunPageId) { + setSelectedAutomationRunPageId(null) + return + } + setIsDetailOpen(false) + setActivePaneTab('overview') + return + } + event.preventDefault() closeAutomationsPage() } window.addEventListener('keydown', onKeyDown, { capture: true }) return () => window.removeEventListener('keydown', onKeyDown, { capture: true }) - }, [closeAutomationsPage, createOpen, deleteTarget, externalDeleteTarget]) + }, [ + activeModal, + closeAutomationsPage, + createOpen, + deleteTarget, + externalDeleteTarget, + isDetailOpen, + selectedAutomationRunPageId, + selectedExternalRunPage, + setActivePaneTab, + setIsDetailOpen, + setSelectedAutomationRunPageId, + setSelectedExternalRunPage + ]) } diff --git a/src/renderer/src/components/automations/use-automations-page-store-state.ts b/src/renderer/src/components/automations/use-automations-page-store-state.ts index e5893ca0390..1dbca5005c8 100644 --- a/src/renderer/src/components/automations/use-automations-page-store-state.ts +++ b/src/renderer/src/components/automations/use-automations-page-store-state.ts @@ -30,6 +30,7 @@ export function useAutomationsPageStoreState() { const openSettingsPage = useAppStore((s) => s.openSettingsPage) const openSettingsTarget = useAppStore((s) => s.openSettingsTarget) const closeAutomationsPage = useAppStore((s) => s.closeAutomationsPage) + const activeModal = useAppStore((s) => s.activeModal) const sshConnectionStates = useAppStore((s) => s.sshConnectionStates) const sshTargetLabels = useAppStore((s) => s.sshTargetLabels) const runtimeEnvironments = useAppStore((s) => s.runtimeEnvironments) @@ -78,6 +79,7 @@ export function useAutomationsPageStoreState() { openSettingsPage, openSettingsTarget, closeAutomationsPage, + activeModal, sshConnectionStates, sshTargetLabels, runtimeEnvironments,