feat(ui): better naming for panel apis

This commit is contained in:
psychedelicious
2025-07-01 20:36:51 +10:00
parent fe115ff8f9
commit dc9cd22d9d
20 changed files with 88 additions and 88 deletions

View File

@@ -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.

View File

@@ -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 (
<Flex flexDir="column" h="full" w="full" alignItems="center" gap={2}>

View File

@@ -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'),

View File

@@ -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'),

View File

@@ -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 (

View File

@@ -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<MouseEventHandler<HTMLDivElement>>(() => {
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]);

View File

@@ -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 (

View File

@@ -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'),

View File

@@ -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]
);

View File

@@ -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]);

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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],
});

View File

@@ -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<IDockviewReactProps['onReady']>(
({ 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<IGridviewReactProps['onReady']>(
({ 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<IGridviewReactProps['onReady']>(
({ 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]);

View File

@@ -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<IDockviewReactProps['onReady']>(
({ 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<IGridviewReactProps['onReady']>(
({ 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<IGridviewReactProps['onReady']>(
({ 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]);

View File

@@ -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<TabName, TabPanelApis>();
tabApi: AppTabApi | null = null;
@@ -344,4 +344,4 @@ export class PanelRegistry {
}
// Global singleton instance
export const panelRegistry = new PanelRegistry();
export const navigationApi = new AppNavigationApi();

View File

@@ -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<IGridviewReactProps['onReady']>(
({ 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<IGridviewReactProps['onReady']>(
({ 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]);

View File

@@ -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<GridviewPanelApi>,
@@ -28,7 +28,7 @@ export const useCollapsibleGridviewPanel = (
const $isCollapsed = useState(() => atom(false))[0];
const lastExpandedSizeRef = useRef<number>(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;

View File

@@ -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]);
};

View File

@@ -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<IDockviewReactProps['onReady']>(
({ 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<IGridviewReactProps['onReady']>(
({ 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<IGridviewReactProps['onReady']>(
({ 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]);