From dc9cd22d9d98003f5fb50e5b1e000624fae6c2b1 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:36:51 +1000 Subject: [PATCH] feat(ui): better naming for panel apis --- .../src/app/components/GlobalHookIsolator.tsx | 4 ++-- .../SimpleSession/CanvasLaunchpadPanel.tsx | 4 ++-- .../ImageMenuItemNewCanvasFromImageSubMenu.tsx | 10 +++++----- .../ImageMenuItemNewLayerFromImageSubMenu.tsx | 12 ++++++------ .../ImageMenuItemOpenInViewer.tsx | 4 ++-- .../components/ImageGrid/GalleryImage.tsx | 4 ++-- .../GalleryImageOpenInViewerIconButton.tsx | 4 ++-- .../ImageViewer/CurrentImageButtons.tsx | 4 ++-- .../sidePanel/WorkflowViewEditToggleButton.tsx | 6 +++--- .../web/src/features/queue/hooks/useInvoke.ts | 10 +++++----- .../ui/components/FloatingLeftPanelButtons.tsx | 6 +++--- .../components/FloatingRightPanelButtons.tsx | 6 +++--- .../ui/layouts/PanelHotkeysLogical.tsx | 18 +++++++++--------- .../ui/layouts/canvas-tab-auto-layout.tsx | 14 +++++++------- .../ui/layouts/generate-tab-auto-layout.tsx | 14 +++++++------- .../panelApiRegistry.ts => navigation-api.ts} | 6 +++--- .../ui/layouts/upscaling-tab-auto-layout.tsx | 14 +++++++------- .../layouts/use-collapsible-gridview-panel.ts | 12 ++++++------ ...egistry-init.tsx => use-navigation-api.tsx} | 10 +++++----- .../ui/layouts/workflows-tab-auto-layout.tsx | 14 +++++++------- 20 files changed, 88 insertions(+), 88 deletions(-) rename invokeai/frontend/web/src/features/ui/layouts/{panel-registry/panelApiRegistry.ts => navigation-api.ts} (98%) rename invokeai/frontend/web/src/features/ui/layouts/{panel-registry/use-panel-registry-init.tsx => use-navigation-api.tsx} (71%) diff --git a/invokeai/frontend/web/src/app/components/GlobalHookIsolator.tsx b/invokeai/frontend/web/src/app/components/GlobalHookIsolator.tsx index 7fa0805327..35e6862fdf 100644 --- a/invokeai/frontend/web/src/app/components/GlobalHookIsolator.tsx +++ b/invokeai/frontend/web/src/app/components/GlobalHookIsolator.tsx @@ -17,7 +17,7 @@ import { useWorkflowBuilderWatcher } from 'features/nodes/components/sidePanel/w import { useReadinessWatcher } from 'features/queue/store/readiness'; import { configChanged } from 'features/system/store/configSlice'; import { selectLanguage } from 'features/system/store/systemSelectors'; -import { usePanelRegistryInit } from 'features/ui/layouts/panel-registry/use-panel-registry-init'; +import { useNavigationApi } from 'features/ui/layouts/use-navigation-api'; import i18n from 'i18n'; import { memo, useEffect } from 'react'; import { useGetOpenAPISchemaQuery } from 'services/api/endpoints/appInfo'; @@ -44,7 +44,7 @@ export const GlobalHookIsolator = memo( useGetOpenAPISchemaQuery(); useSyncLoggingConfig(); useCloseChakraTooltipsOnDragFix(); - usePanelRegistryInit(); + useNavigationApi(); // Persistent subscription to the queue counts query - canvas relies on this to know if there are pending // and/or in progress canvas sessions. diff --git a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/CanvasLaunchpadPanel.tsx b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/CanvasLaunchpadPanel.tsx index f2633d1950..a5f091c9e8 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/CanvasLaunchpadPanel.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/CanvasLaunchpadPanel.tsx @@ -1,6 +1,6 @@ import { Button, Flex, Grid, Heading, Text } from '@invoke-ai/ui-library'; import { useAutoLayoutContext } from 'features/ui/layouts/auto-layout-context'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { WORKSPACE_PANEL_ID } from 'features/ui/layouts/shared'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -15,7 +15,7 @@ export const CanvasLaunchpadPanel = memo(() => { const { t } = useTranslation(); const { tab } = useAutoLayoutContext(); const focusCanvas = useCallback(() => { - panelRegistry.focusPanelInTab(tab, WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab(tab, WORKSPACE_PANEL_ID); }, [tab]); return ( diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemNewCanvasFromImageSubMenu.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemNewCanvasFromImageSubMenu.tsx index 500bc7b857..8d8e25552e 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemNewCanvasFromImageSubMenu.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemNewCanvasFromImageSubMenu.tsx @@ -5,7 +5,7 @@ import { useCanvasIsBusySafe } from 'features/controlLayers/hooks/useCanvasIsBus import { useImageDTOContext } from 'features/gallery/contexts/ImageDTOContext'; import { newCanvasFromImage } from 'features/imageActions/actions'; import { toast } from 'features/toast/toast'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { WORKSPACE_PANEL_ID } from 'features/ui/layouts/shared'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -21,7 +21,7 @@ export const ImageMenuItemNewCanvasFromImageSubMenu = memo(() => { const onClickNewCanvasWithRasterLayerFromImage = useCallback(async () => { const { dispatch, getState } = store; await newCanvasFromImage({ imageDTO, withResize: false, type: 'raster_layer', dispatch, getState }); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), @@ -32,7 +32,7 @@ export const ImageMenuItemNewCanvasFromImageSubMenu = memo(() => { const onClickNewCanvasWithControlLayerFromImage = useCallback(async () => { const { dispatch, getState } = store; await newCanvasFromImage({ imageDTO, withResize: false, type: 'control_layer', dispatch, getState }); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), @@ -43,7 +43,7 @@ export const ImageMenuItemNewCanvasFromImageSubMenu = memo(() => { const onClickNewCanvasWithRasterLayerFromImageWithResize = useCallback(async () => { const { dispatch, getState } = store; await newCanvasFromImage({ imageDTO, withResize: true, type: 'raster_layer', dispatch, getState }); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), @@ -54,7 +54,7 @@ export const ImageMenuItemNewCanvasFromImageSubMenu = memo(() => { const onClickNewCanvasWithControlLayerFromImageWithResize = useCallback(async () => { const { dispatch, getState } = store; await newCanvasFromImage({ imageDTO, withResize: true, type: 'control_layer', dispatch, getState }); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemNewLayerFromImageSubMenu.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemNewLayerFromImageSubMenu.tsx index d3befb17ba..fb5571a121 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemNewLayerFromImageSubMenu.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemNewLayerFromImageSubMenu.tsx @@ -7,7 +7,7 @@ import { useImageDTOContext } from 'features/gallery/contexts/ImageDTOContext'; import { sentImageToCanvas } from 'features/gallery/store/actions'; import { createNewCanvasEntityFromImage } from 'features/imageActions/actions'; import { toast } from 'features/toast/toast'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { WORKSPACE_PANEL_ID } from 'features/ui/layouts/shared'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -24,7 +24,7 @@ export const ImageMenuItemNewLayerFromImageSubMenu = memo(() => { const { dispatch, getState } = store; createNewCanvasEntityFromImage({ imageDTO, type: 'raster_layer', dispatch, getState }); dispatch(sentImageToCanvas()); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), @@ -36,7 +36,7 @@ export const ImageMenuItemNewLayerFromImageSubMenu = memo(() => { const { dispatch, getState } = store; createNewCanvasEntityFromImage({ imageDTO, type: 'control_layer', dispatch, getState }); dispatch(sentImageToCanvas()); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), @@ -48,7 +48,7 @@ export const ImageMenuItemNewLayerFromImageSubMenu = memo(() => { const { dispatch, getState } = store; createNewCanvasEntityFromImage({ imageDTO, type: 'inpaint_mask', dispatch, getState }); dispatch(sentImageToCanvas()); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), @@ -60,7 +60,7 @@ export const ImageMenuItemNewLayerFromImageSubMenu = memo(() => { const { dispatch, getState } = store; createNewCanvasEntityFromImage({ imageDTO, type: 'regional_guidance', dispatch, getState }); dispatch(sentImageToCanvas()); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), @@ -72,7 +72,7 @@ export const ImageMenuItemNewLayerFromImageSubMenu = memo(() => { const { dispatch, getState } = store; createNewCanvasEntityFromImage({ imageDTO, type: 'regional_guidance_with_reference_image', dispatch, getState }); dispatch(sentImageToCanvas()); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemOpenInViewer.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemOpenInViewer.tsx index 586abf56c7..bd016b9c6d 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemOpenInViewer.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageMenuItemOpenInViewer.tsx @@ -2,7 +2,7 @@ import { useAppDispatch } from 'app/store/storeHooks'; import { IconMenuItem } from 'common/components/IconMenuItem'; import { useImageDTOContext } from 'features/gallery/contexts/ImageDTOContext'; import { imageSelected, imageToCompareChanged } from 'features/gallery/store/gallerySlice'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { VIEWER_PANEL_ID } from 'features/ui/layouts/shared'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -15,7 +15,7 @@ export const ImageMenuItemOpenInViewer = memo(() => { const onClick = useCallback(() => { dispatch(imageToCompareChanged(null)); dispatch(imageSelected(imageDTO.image_name)); - panelRegistry.focusPanelInActiveTab(VIEWER_PANEL_ID); + navigationApi.focusPanelInActiveTab(VIEWER_PANEL_ID); }, [dispatch, imageDTO]); return ( diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImage.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImage.tsx index eb1d9d6863..b0000fbe44 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImage.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImage.tsx @@ -21,7 +21,7 @@ import { selectSelection, } from 'features/gallery/store/gallerySelectors'; import { imageToCompareChanged, selectGallerySlice, selectionChanged } from 'features/gallery/store/gallerySlice'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { VIEWER_PANEL_ID } from 'features/ui/layouts/shared'; import type { MouseEvent, MouseEventHandler } from 'react'; import { memo, useCallback, useEffect, useMemo, useState } from 'react'; @@ -238,7 +238,7 @@ export const GalleryImage = memo(({ imageDTO }: Props) => { const onDoubleClick = useCallback>(() => { store.dispatch(imageToCompareChanged(null)); - panelRegistry.focusPanelInActiveTab(VIEWER_PANEL_ID); + navigationApi.focusPanelInActiveTab(VIEWER_PANEL_ID); }, [store]); const dataTestId = useMemo(() => getGalleryImageDataTestId(imageDTO.image_name), [imageDTO.image_name]); diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImageOpenInViewerIconButton.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImageOpenInViewerIconButton.tsx index e363370289..aba327e867 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImageOpenInViewerIconButton.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImageOpenInViewerIconButton.tsx @@ -1,7 +1,7 @@ import { useAppDispatch } from 'app/store/storeHooks'; import { DndImageIcon } from 'features/dnd/DndImageIcon'; import { imageSelected, imageToCompareChanged } from 'features/gallery/store/gallerySlice'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { VIEWER_PANEL_ID } from 'features/ui/layouts/shared'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -19,7 +19,7 @@ export const GalleryImageOpenInViewerIconButton = memo(({ imageDTO }: Props) => const onClick = useCallback(() => { dispatch(imageToCompareChanged(null)); dispatch(imageSelected(imageDTO.image_name)); - panelRegistry.focusPanelInActiveTab(VIEWER_PANEL_ID); + navigationApi.focusPanelInActiveTab(VIEWER_PANEL_ID); }, [dispatch, imageDTO]); return ( diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx index 4dc69aa609..aaf0e5e08b 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx @@ -11,7 +11,7 @@ import { $hasTemplates } from 'features/nodes/store/nodesSlice'; import { PostProcessingPopover } from 'features/parameters/components/PostProcessing/PostProcessingPopover'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { toast } from 'features/toast/toast'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { WORKSPACE_PANEL_ID } from 'features/ui/layouts/shared'; import { selectShouldShowProgressInViewer } from 'features/ui/store/uiSelectors'; import { memo, useCallback } from 'react'; @@ -57,7 +57,7 @@ export const CurrentImageButtons = memo(() => { getState, dispatch, }); - panelRegistry.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('canvas', WORKSPACE_PANEL_ID); toast({ id: 'SENT_TO_CANVAS', title: t('toast.sentToCanvas'), diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowViewEditToggleButton.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowViewEditToggleButton.tsx index 4b063209a6..7dfe45873d 100644 --- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowViewEditToggleButton.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowViewEditToggleButton.tsx @@ -1,7 +1,7 @@ import { IconButton } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { selectWorkflowMode, workflowModeChanged } from 'features/nodes/store/workflowLibrarySlice'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { WORKSPACE_PANEL_ID } from 'features/ui/layouts/shared'; import { setActiveTab } from 'features/ui/store/uiSlice'; import type { MouseEventHandler } from 'react'; @@ -21,7 +21,7 @@ export const WorkflowViewEditToggleButton = memo(() => { dispatch(setActiveTab('workflows')); dispatch(workflowModeChanged('edit')); // Focus the Workflow Editor panel - panelRegistry.focusPanelInTab('workflows', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('workflows', WORKSPACE_PANEL_ID); }, [dispatch] ); @@ -33,7 +33,7 @@ export const WorkflowViewEditToggleButton = memo(() => { dispatch(setActiveTab('workflows')); dispatch(workflowModeChanged('view')); // Focus the Image Viewer panel - panelRegistry.focusPanelInTab('workflows', WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab('workflows', WORKSPACE_PANEL_ID); }, [dispatch] ); diff --git a/invokeai/frontend/web/src/features/queue/hooks/useInvoke.ts b/invokeai/frontend/web/src/features/queue/hooks/useInvoke.ts index 8b6f744511..4c445c878e 100644 --- a/invokeai/frontend/web/src/features/queue/hooks/useInvoke.ts +++ b/invokeai/frontend/web/src/features/queue/hooks/useInvoke.ts @@ -5,7 +5,7 @@ import { withResultAsync } from 'common/util/result'; import { useIsWorkflowEditorLocked } from 'features/nodes/hooks/useIsWorkflowEditorLocked'; import { useEnqueueWorkflows } from 'features/queue/hooks/useEnqueueWorkflows'; import { $isReadyToEnqueue } from 'features/queue/store/readiness'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { VIEWER_PANEL_ID, WORKSPACE_PANEL_ID } from 'features/ui/layouts/shared'; import { selectActiveTab } from 'features/ui/store/uiSelectors'; import { useCallback } from 'react'; @@ -63,18 +63,18 @@ export const useInvoke = () => { const enqueueBack = useCallback(() => { enqueue(false, false); if (tabName === 'generate' || tabName === 'workflows' || tabName === 'upscaling') { - panelRegistry.focusPanelInTab(tabName, VIEWER_PANEL_ID); + navigationApi.focusPanelInTab(tabName, VIEWER_PANEL_ID); } else if (tabName === 'canvas') { - panelRegistry.focusPanelInTab(tabName, WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab(tabName, WORKSPACE_PANEL_ID); } }, [enqueue, tabName]); const enqueueFront = useCallback(() => { enqueue(true, false); if (tabName === 'generate' || tabName === 'workflows' || tabName === 'upscaling') { - panelRegistry.focusPanelInTab(tabName, VIEWER_PANEL_ID); + navigationApi.focusPanelInTab(tabName, VIEWER_PANEL_ID); } else if (tabName === 'canvas') { - panelRegistry.focusPanelInTab(tabName, WORKSPACE_PANEL_ID); + navigationApi.focusPanelInTab(tabName, WORKSPACE_PANEL_ID); } }, [enqueue, tabName]); diff --git a/invokeai/frontend/web/src/features/ui/components/FloatingLeftPanelButtons.tsx b/invokeai/frontend/web/src/features/ui/components/FloatingLeftPanelButtons.tsx index 5d57d9aa37..b38b30f635 100644 --- a/invokeai/frontend/web/src/features/ui/components/FloatingLeftPanelButtons.tsx +++ b/invokeai/frontend/web/src/features/ui/components/FloatingLeftPanelButtons.tsx @@ -6,7 +6,7 @@ import { InvokeButtonTooltip } from 'features/queue/components/InvokeButtonToolt import { useDeleteCurrentQueueItem } from 'features/queue/hooks/useDeleteCurrentQueueItem'; import { useInvoke } from 'features/queue/hooks/useInvoke'; import { useAutoLayoutContext } from 'features/ui/layouts/auto-layout-context'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { @@ -57,10 +57,10 @@ const ToggleLeftPanelButton = memo(() => { const { tab } = useAutoLayoutContext(); const onClick = useCallback(() => { - if (panelRegistry.tabApi?.getTab() !== tab) { + if (navigationApi.tabApi?.getTab() !== tab) { return; } - panelRegistry.toggleLeftPanelInTab(tab); + navigationApi.toggleLeftPanelInTab(tab); }, [tab]); return ( diff --git a/invokeai/frontend/web/src/features/ui/components/FloatingRightPanelButtons.tsx b/invokeai/frontend/web/src/features/ui/components/FloatingRightPanelButtons.tsx index 2bc0938e4f..6fb1c67129 100644 --- a/invokeai/frontend/web/src/features/ui/components/FloatingRightPanelButtons.tsx +++ b/invokeai/frontend/web/src/features/ui/components/FloatingRightPanelButtons.tsx @@ -1,6 +1,6 @@ import { Flex, IconButton, Tooltip } from '@invoke-ai/ui-library'; import { useAutoLayoutContext } from 'features/ui/layouts/auto-layout-context'; -import { panelRegistry } from 'features/ui/layouts/panel-registry/panelApiRegistry'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { PiImagesSquareBold } from 'react-icons/pi'; @@ -19,10 +19,10 @@ const ToggleRightPanelButton = memo(() => { const { tab } = useAutoLayoutContext(); const onClick = useCallback(() => { - if (panelRegistry.tabApi?.getTab() !== tab) { + if (navigationApi.tabApi?.getTab() !== tab) { return; } - panelRegistry.toggleLeftPanelInTab(tab); + navigationApi.toggleLeftPanelInTab(tab); }, [tab]); return ( diff --git a/invokeai/frontend/web/src/features/ui/layouts/PanelHotkeysLogical.tsx b/invokeai/frontend/web/src/features/ui/layouts/PanelHotkeysLogical.tsx index 6c3e6a5f15..82f0cc72a7 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/PanelHotkeysLogical.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/PanelHotkeysLogical.tsx @@ -1,8 +1,8 @@ import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData'; +import { navigationApi } from 'features/ui/layouts/navigation-api'; import { memo } from 'react'; import { useAutoLayoutContext } from './auto-layout-context'; -import { panelRegistry } from './panel-registry/panelApiRegistry'; export const PanelHotkeysLogical = memo(() => { const { tab } = useAutoLayoutContext(); @@ -11,10 +11,10 @@ export const PanelHotkeysLogical = memo(() => { category: 'app', id: 'toggleLeftPanel', callback: () => { - if (panelRegistry.tabApi?.getTab() !== tab) { + if (navigationApi.tabApi?.getTab() !== tab) { return; } - panelRegistry.toggleLeftPanelInTab(tab); + navigationApi.toggleLeftPanelInTab(tab); }, dependencies: [tab], }); @@ -22,10 +22,10 @@ export const PanelHotkeysLogical = memo(() => { category: 'app', id: 'toggleRightPanel', callback: () => { - if (panelRegistry.tabApi?.getTab() !== tab) { + if (navigationApi.tabApi?.getTab() !== tab) { return; } - panelRegistry.toggleRightPanelInTab(tab); + navigationApi.toggleRightPanelInTab(tab); }, dependencies: [tab], }); @@ -33,10 +33,10 @@ export const PanelHotkeysLogical = memo(() => { category: 'app', id: 'resetPanelLayout', callback: () => { - if (panelRegistry.tabApi?.getTab() !== tab) { + if (navigationApi.tabApi?.getTab() !== tab) { return; } - panelRegistry.resetPanelsInTab(tab); + navigationApi.resetPanelsInTab(tab); }, dependencies: [tab], }); @@ -44,10 +44,10 @@ export const PanelHotkeysLogical = memo(() => { category: 'app', id: 'togglePanels', callback: () => { - if (panelRegistry.tabApi?.getTab() !== tab) { + if (navigationApi.tabApi?.getTab() !== tab) { return; } - panelRegistry.toggleBothPanelsInTab(tab); + navigationApi.toggleBothPanelsInTab(tab); }, dependencies: [tab], }); diff --git a/invokeai/frontend/web/src/features/ui/layouts/canvas-tab-auto-layout.tsx b/invokeai/frontend/web/src/features/ui/layouts/canvas-tab-auto-layout.tsx index 599950cf1f..b817bafb5d 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/canvas-tab-auto-layout.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/canvas-tab-auto-layout.tsx @@ -29,7 +29,7 @@ import { memo, useCallback, useEffect, useRef, useState } from 'react'; import { CanvasTabLeftPanel } from './CanvasTabLeftPanel'; import { CanvasWorkspacePanel } from './CanvasWorkspacePanel'; -import { panelRegistry } from './panel-registry/panelApiRegistry'; +import { navigationApi } from './navigation-api'; import { PanelHotkeysLogical } from './PanelHotkeysLogical'; import { BOARD_PANEL_DEFAULT_HEIGHT_PX, @@ -121,7 +121,7 @@ const MainPanel = memo(() => { const onReady = useCallback( ({ api }) => { const panels = initializeCenterPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'main', api); + navigationApi.registerPanel(tab, 'main', api); panels.launchpad.api.setActive(); const disposables = [ @@ -217,7 +217,7 @@ const RightPanel = memo(() => { const onReady = useCallback( ({ api }) => { initializeRightPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'right', api); + navigationApi.registerPanel(tab, 'right', api); }, [tab] ); @@ -255,7 +255,7 @@ const LeftPanel = memo(() => { const onReady = useCallback( ({ api }) => { initializeLeftPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'left', api); + navigationApi.registerPanel(tab, 'left', api); }, [tab] ); @@ -323,11 +323,11 @@ export const CanvasTabAutoLayout = memo(() => { return; } initializeRootPanelLayout(rootApi); - panelRegistry.registerPanel('canvas', 'root', rootApi); - panelRegistry.focusPanelInTab('canvas', LAUNCHPAD_PANEL_ID, false); + navigationApi.registerPanel('canvas', 'root', rootApi); + navigationApi.focusPanelInTab('canvas', LAUNCHPAD_PANEL_ID, false); return () => { - panelRegistry.unregisterTab('canvas'); + navigationApi.unregisterTab('canvas'); }; }, [rootApi]); diff --git a/invokeai/frontend/web/src/features/ui/layouts/generate-tab-auto-layout.tsx b/invokeai/frontend/web/src/features/ui/layouts/generate-tab-auto-layout.tsx index 1e85066860..47aad70113 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/generate-tab-auto-layout.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/generate-tab-auto-layout.tsx @@ -27,7 +27,7 @@ import { dockviewTheme } from 'features/ui/styles/theme'; import { memo, useCallback, useEffect, useRef, useState } from 'react'; import { GenerateTabLeftPanel } from './GenerateTabLeftPanel'; -import { panelRegistry } from './panel-registry/panelApiRegistry'; +import { navigationApi } from './navigation-api'; import { PanelHotkeysLogical } from './PanelHotkeysLogical'; import { BOARD_PANEL_DEFAULT_HEIGHT_PX, @@ -100,7 +100,7 @@ const MainPanel = memo(() => { const onReady = useCallback( ({ api }) => { const { launchpad } = initializeMainPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'main', api); + navigationApi.registerPanel(tab, 'main', api); launchpad.api.setActive(); const disposables = [ @@ -182,7 +182,7 @@ const RightPanel = memo(() => { const onReady = useCallback( ({ api }) => { initializeRightPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'right', api); + navigationApi.registerPanel(tab, 'right', api); }, [tab] ); @@ -220,7 +220,7 @@ const LeftPanel = memo(() => { const onReady = useCallback( ({ api }) => { initializeLeftPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'left', api); + navigationApi.registerPanel(tab, 'left', api); }, [tab] ); @@ -288,11 +288,11 @@ export const GenerateTabAutoLayout = memo(() => { return; } initializeRootPanelLayout(rootApi); - panelRegistry.registerPanel('generate', 'root', rootApi); - panelRegistry.focusPanelInTab('generate', LAUNCHPAD_PANEL_ID, false); + navigationApi.registerPanel('generate', 'root', rootApi); + navigationApi.focusPanelInTab('generate', LAUNCHPAD_PANEL_ID, false); return () => { - panelRegistry.unregisterTab('generate'); + navigationApi.unregisterTab('generate'); }; }, [rootApi]); diff --git a/invokeai/frontend/web/src/features/ui/layouts/panel-registry/panelApiRegistry.ts b/invokeai/frontend/web/src/features/ui/layouts/navigation-api.ts similarity index 98% rename from invokeai/frontend/web/src/features/ui/layouts/panel-registry/panelApiRegistry.ts rename to invokeai/frontend/web/src/features/ui/layouts/navigation-api.ts index fa90866d71..a62ab50183 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/panel-registry/panelApiRegistry.ts +++ b/invokeai/frontend/web/src/features/ui/layouts/navigation-api.ts @@ -25,9 +25,9 @@ type AppTabApi = { }; /** - * Global registry for all panel APIs across all tabs + * Global API for managing application navigation and tab panels. */ -export class PanelRegistry { +export class AppNavigationApi { private tabPanelApis = new Map(); tabApi: AppTabApi | null = null; @@ -344,4 +344,4 @@ export class PanelRegistry { } // Global singleton instance -export const panelRegistry = new PanelRegistry(); +export const navigationApi = new AppNavigationApi(); diff --git a/invokeai/frontend/web/src/features/ui/layouts/upscaling-tab-auto-layout.tsx b/invokeai/frontend/web/src/features/ui/layouts/upscaling-tab-auto-layout.tsx index c8249811c1..694ade17fd 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/upscaling-tab-auto-layout.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/upscaling-tab-auto-layout.tsx @@ -26,7 +26,7 @@ import type { TabName } from 'features/ui/store/uiTypes'; import { dockviewTheme } from 'features/ui/styles/theme'; import { memo, useCallback, useEffect, useRef, useState } from 'react'; -import { panelRegistry } from './panel-registry/panelApiRegistry'; +import { navigationApi } from './navigation-api'; import { PanelHotkeysLogical } from './PanelHotkeysLogical'; import { BOARD_PANEL_DEFAULT_HEIGHT_PX, @@ -100,7 +100,7 @@ const MainPanel = memo(() => { ({ api }) => { const panels = initializeCenterPanelLayout(tab, api); panels.launchpad.api.setActive(); - panelRegistry.registerPanel(tab, 'main', api); + navigationApi.registerPanel(tab, 'main', api); const disposables = [ api.onWillShowOverlay((e) => { @@ -181,7 +181,7 @@ const RightPanel = memo(() => { const onReady = useCallback( ({ api }) => { initializeRightPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'right', api); + navigationApi.registerPanel(tab, 'right', api); }, [tab] ); @@ -219,7 +219,7 @@ const LeftPanel = memo(() => { const onReady = useCallback( ({ api }) => { initializeLeftPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'left', api); + navigationApi.registerPanel(tab, 'left', api); }, [tab] ); @@ -288,11 +288,11 @@ export const UpscalingTabAutoLayout = memo(() => { return; } initializeRootPanelLayout(rootApi); - panelRegistry.registerPanel('upscaling', 'root', rootApi); - panelRegistry.focusPanelInTab('upscaling', LAUNCHPAD_PANEL_ID, false); + navigationApi.registerPanel('upscaling', 'root', rootApi); + navigationApi.focusPanelInTab('upscaling', LAUNCHPAD_PANEL_ID, false); return () => { - panelRegistry.unregisterTab('upscaling'); + navigationApi.unregisterTab('upscaling'); }; }, [rootApi]); diff --git a/invokeai/frontend/web/src/features/ui/layouts/use-collapsible-gridview-panel.ts b/invokeai/frontend/web/src/features/ui/layouts/use-collapsible-gridview-panel.ts index 5913aac254..d8c6c00ca3 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/use-collapsible-gridview-panel.ts +++ b/invokeai/frontend/web/src/features/ui/layouts/use-collapsible-gridview-panel.ts @@ -3,8 +3,8 @@ import type { TabName } from 'features/ui/store/uiTypes'; import { atom } from 'nanostores'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import type { TabPanelApis } from './panel-registry/panelApiRegistry'; -import { panelRegistry } from './panel-registry/panelApiRegistry'; +import type { TabPanelApis } from './navigation-api'; +import { navigationApi } from './navigation-api'; const getIsCollapsed = ( panel: IGridviewPanel, @@ -28,7 +28,7 @@ export const useCollapsibleGridviewPanel = ( const $isCollapsed = useState(() => atom(false))[0]; const lastExpandedSizeRef = useRef(0); const collapse = useCallback(() => { - const api = panelRegistry.getTabPanelApis(tab)?.[rootPanelId]; + const api = navigationApi.getTabPanelApis(tab)?.[rootPanelId]; if (!api) { return; } @@ -47,7 +47,7 @@ export const useCollapsibleGridviewPanel = ( }, [collapsedSize, orientation, panelId, rootPanelId, tab]); const expand = useCallback(() => { - const api = panelRegistry.getTabPanelApis(tab)?.[rootPanelId]; + const api = navigationApi.getTabPanelApis(tab)?.[rootPanelId]; if (!api) { return; @@ -64,7 +64,7 @@ export const useCollapsibleGridviewPanel = ( }, [defaultSize, orientation, panelId, rootPanelId, tab]); const toggle = useCallback(() => { - const api = panelRegistry.getTabPanelApis(tab)?.[rootPanelId]; + const api = navigationApi.getTabPanelApis(tab)?.[rootPanelId]; if (!api) { return; @@ -82,7 +82,7 @@ export const useCollapsibleGridviewPanel = ( }, [tab, rootPanelId, panelId, orientation, collapsedSize, expand, collapse]); useEffect(() => { - const api = panelRegistry.getTabPanelApis(tab)?.[rootPanelId]; + const api = navigationApi.getTabPanelApis(tab)?.[rootPanelId]; if (!api) { return; diff --git a/invokeai/frontend/web/src/features/ui/layouts/panel-registry/use-panel-registry-init.tsx b/invokeai/frontend/web/src/features/ui/layouts/use-navigation-api.tsx similarity index 71% rename from invokeai/frontend/web/src/features/ui/layouts/panel-registry/use-panel-registry-init.tsx rename to invokeai/frontend/web/src/features/ui/layouts/use-navigation-api.tsx index 4acddf05ff..1cbc29e8e2 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/panel-registry/use-panel-registry-init.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/use-navigation-api.tsx @@ -5,13 +5,13 @@ import { setActiveTab } from 'features/ui/store/uiSlice'; import type { TabName } from 'features/ui/store/uiTypes'; import { useEffect, useMemo } from 'react'; -import { panelRegistry } from './panelApiRegistry'; +import { navigationApi } from './navigation-api'; /** - * Hook that initializes the global panel registry with the Redux store. + * Hook that initializes the global navigation API with callbacks to access and modify the active tab. */ -export const usePanelRegistryInit = () => { - useAssertSingleton('usePanelRegistryInit'); +export const useNavigationApi = () => { + useAssertSingleton('useNavigationApi'); const store = useAppStore(); const tabApi = useMemo( () => ({ @@ -26,6 +26,6 @@ export const usePanelRegistryInit = () => { ); useEffect(() => { - panelRegistry.setTabApi(tabApi); + navigationApi.setTabApi(tabApi); }, [store, tabApi]); }; diff --git a/invokeai/frontend/web/src/features/ui/layouts/workflows-tab-auto-layout.tsx b/invokeai/frontend/web/src/features/ui/layouts/workflows-tab-auto-layout.tsx index cbfccde7de..638f97b9d1 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/workflows-tab-auto-layout.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/workflows-tab-auto-layout.tsx @@ -28,7 +28,7 @@ import type { TabName } from 'features/ui/store/uiTypes'; import { dockviewTheme } from 'features/ui/styles/theme'; import { memo, useCallback, useEffect, useRef, useState } from 'react'; -import { panelRegistry } from './panel-registry/panelApiRegistry'; +import { navigationApi } from './navigation-api'; import { PanelHotkeysLogical } from './PanelHotkeysLogical'; import { BOARD_PANEL_DEFAULT_HEIGHT_PX, @@ -118,7 +118,7 @@ const MainPanel = memo(() => { const onReady = useCallback( ({ api }) => { const panels = initializeMainPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'main', api); + navigationApi.registerPanel(tab, 'main', api); panels.launchpad.api.setActive(); const disposables = [ @@ -200,7 +200,7 @@ const RightPanel = memo(() => { const onReady = useCallback( ({ api }) => { initializeRightPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'right', api); + navigationApi.registerPanel(tab, 'right', api); }, [tab] ); @@ -238,7 +238,7 @@ const LeftPanel = memo(() => { const onReady = useCallback( ({ api }) => { initializeLeftPanelLayout(tab, api); - panelRegistry.registerPanel(tab, 'left', api); + navigationApi.registerPanel(tab, 'left', api); }, [tab] ); @@ -302,11 +302,11 @@ export const WorkflowsTabAutoLayout = memo(() => { return; } initializeRootPanelLayout(rootApi); - panelRegistry.registerPanel('workflows', 'root', rootApi); - panelRegistry.focusPanelInTab('workflows', LAUNCHPAD_PANEL_ID, false); + navigationApi.registerPanel('workflows', 'root', rootApi); + navigationApi.focusPanelInTab('workflows', LAUNCHPAD_PANEL_ID, false); return () => { - panelRegistry.unregisterTab('workflows'); + navigationApi.unregisterTab('workflows'); }; }, [rootApi]);