feat(ui): dynamic dockview tab title translations

Requires a ui slice migration and reset of users's layout settings to
get the right titles into dockview params state, which is persisted.
This commit is contained in:
psychedelicious
2025-08-11 12:39:57 +10:00
parent 24788e3c83
commit 17118a04bd
13 changed files with 99 additions and 54 deletions

View File

@@ -3,7 +3,7 @@ import { useAppSelector } from 'app/store/storeHooks';
import { useFocusRegion, useIsRegionFocused } from 'common/hooks/focus'; import { useFocusRegion, useIsRegionFocused } from 'common/hooks/focus';
import type { IDockviewPanelProps, IGridviewPanelProps } from 'dockview'; import type { IDockviewPanelProps, IGridviewPanelProps } from 'dockview';
import { selectSystemShouldEnableHighlightFocusedRegions } from 'features/system/store/systemSlice'; import { selectSystemShouldEnableHighlightFocusedRegions } from 'features/system/store/systemSlice';
import type { PanelParameters } from 'features/ui/layouts/auto-layout-context'; import type { DockviewPanelParameters, GridviewPanelParameters } from 'features/ui/layouts/auto-layout-context';
import type { PropsWithChildren } from 'react'; import type { PropsWithChildren } from 'react';
import { memo, useRef } from 'react'; import { memo, useRef } from 'react';
@@ -30,8 +30,8 @@ const sx: SystemStyleObject = {
export const AutoLayoutPanelContainer = memo( export const AutoLayoutPanelContainer = memo(
( (
props: props:
| PropsWithChildren<IDockviewPanelProps<PanelParameters>> | PropsWithChildren<IDockviewPanelProps<DockviewPanelParameters>>
| PropsWithChildren<IGridviewPanelProps<PanelParameters>> | PropsWithChildren<IGridviewPanelProps<GridviewPanelParameters>>
) => { ) => {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const shouldHighlightFocusedRegions = useAppSelector(selectSystemShouldEnableHighlightFocusedRegions); const shouldHighlightFocusedRegions = useAppSelector(selectSystemShouldEnableHighlightFocusedRegions);

View File

@@ -3,10 +3,12 @@ import { setFocusedRegion } from 'common/hooks/focus';
import { useCallbackOnDragEnter } from 'common/hooks/useCallbackOnDragEnter'; import { useCallbackOnDragEnter } from 'common/hooks/useCallbackOnDragEnter';
import type { IDockviewPanelHeaderProps } from 'dockview'; import type { IDockviewPanelHeaderProps } from 'dockview';
import { memo, useCallback, useRef } from 'react'; import { memo, useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import type { PanelParameters } from './auto-layout-context'; import type { DockviewPanelParameters } from './auto-layout-context';
export const DockviewTab = memo((props: IDockviewPanelHeaderProps<PanelParameters>) => { export const DockviewTab = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
const { t } = useTranslation();
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const setActive = useCallback(() => { const setActive = useCallback(() => {
if (!props.api.isActive) { if (!props.api.isActive) {
@@ -23,7 +25,7 @@ export const DockviewTab = memo((props: IDockviewPanelHeaderProps<PanelParameter
return ( return (
<Flex ref={ref} alignItems="center" h="full" onPointerDown={onPointerDown}> <Flex ref={ref} alignItems="center" h="full" onPointerDown={onPointerDown}>
<Text userSelect="none" px={4}> <Text userSelect="none" px={4}>
{props.api.title ?? props.api.id} {t(props.params.i18nKey)}
</Text> </Text>
</Flex> </Flex>
); );

View File

@@ -5,11 +5,13 @@ import type { IDockviewPanelHeaderProps } from 'dockview';
import { useCurrentQueueItemDestination } from 'features/queue/hooks/useCurrentQueueItemDestination'; import { useCurrentQueueItemDestination } from 'features/queue/hooks/useCurrentQueueItemDestination';
import ProgressBar from 'features/system/components/ProgressBar'; import ProgressBar from 'features/system/components/ProgressBar';
import { memo, useCallback, useRef } from 'react'; import { memo, useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useIsGenerationInProgress } from 'services/api/endpoints/queue'; import { useIsGenerationInProgress } from 'services/api/endpoints/queue';
import type { PanelParameters } from './auto-layout-context'; import type { DockviewPanelParameters } from './auto-layout-context';
export const DockviewTabCanvasViewer = memo((props: IDockviewPanelHeaderProps<PanelParameters>) => { export const DockviewTabCanvasViewer = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
const { t } = useTranslation();
const isGenerationInProgress = useIsGenerationInProgress(); const isGenerationInProgress = useIsGenerationInProgress();
const currentQueueItemDestination = useCurrentQueueItemDestination(); const currentQueueItemDestination = useCurrentQueueItemDestination();
@@ -29,7 +31,7 @@ export const DockviewTabCanvasViewer = memo((props: IDockviewPanelHeaderProps<Pa
return ( return (
<Flex ref={ref} position="relative" alignItems="center" h="full" onPointerDown={onPointerDown}> <Flex ref={ref} position="relative" alignItems="center" h="full" onPointerDown={onPointerDown}>
<Text userSelect="none" px={4}> <Text userSelect="none" px={4}>
{props.api.title ?? props.api.id} {t(props.params.i18nKey)}
</Text> </Text>
{currentQueueItemDestination === 'canvas' && isGenerationInProgress && ( {currentQueueItemDestination === 'canvas' && isGenerationInProgress && (
<ProgressBar position="absolute" bottom={0} left={0} right={0} h={1} borderRadius="none" /> <ProgressBar position="absolute" bottom={0} left={0} right={0} h={1} borderRadius="none" />

View File

@@ -7,11 +7,13 @@ import { selectCanvasSessionId } from 'features/controlLayers/store/canvasStagin
import { useCurrentQueueItemDestination } from 'features/queue/hooks/useCurrentQueueItemDestination'; import { useCurrentQueueItemDestination } from 'features/queue/hooks/useCurrentQueueItemDestination';
import ProgressBar from 'features/system/components/ProgressBar'; import ProgressBar from 'features/system/components/ProgressBar';
import { memo, useCallback, useRef } from 'react'; import { memo, useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useIsGenerationInProgress } from 'services/api/endpoints/queue'; import { useIsGenerationInProgress } from 'services/api/endpoints/queue';
import type { PanelParameters } from './auto-layout-context'; import type { DockviewPanelParameters } from './auto-layout-context';
export const DockviewTabCanvasWorkspace = memo((props: IDockviewPanelHeaderProps<PanelParameters>) => { export const DockviewTabCanvasWorkspace = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
const { t } = useTranslation();
const isGenerationInProgress = useIsGenerationInProgress(); const isGenerationInProgress = useIsGenerationInProgress();
const canvasSessionId = useAppSelector(selectCanvasSessionId); const canvasSessionId = useAppSelector(selectCanvasSessionId);
const currentQueueItemDestination = useCurrentQueueItemDestination(); const currentQueueItemDestination = useCurrentQueueItemDestination();
@@ -32,7 +34,7 @@ export const DockviewTabCanvasWorkspace = memo((props: IDockviewPanelHeaderProps
return ( return (
<Flex ref={ref} position="relative" alignItems="center" h="full" onPointerDown={onPointerDown}> <Flex ref={ref} position="relative" alignItems="center" h="full" onPointerDown={onPointerDown}>
<Text userSelect="none" px={4}> <Text userSelect="none" px={4}>
{props.api.title ?? props.api.id} {t(props.params.i18nKey)}
</Text> </Text>
{currentQueueItemDestination === canvasSessionId && isGenerationInProgress && ( {currentQueueItemDestination === canvasSessionId && isGenerationInProgress && (
<ProgressBar position="absolute" bottom={0} left={0} right={0} h={1} borderRadius="none" /> <ProgressBar position="absolute" bottom={0} left={0} right={0} h={1} borderRadius="none" />

View File

@@ -6,6 +6,7 @@ import type { IDockviewPanelHeaderProps } from 'dockview';
import { selectActiveTab } from 'features/ui/store/uiSelectors'; import { selectActiveTab } from 'features/ui/store/uiSelectors';
import type { TabName } from 'features/ui/store/uiTypes'; import type { TabName } from 'features/ui/store/uiTypes';
import { memo, useCallback, useRef } from 'react'; import { memo, useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import type { IconType } from 'react-icons'; import type { IconType } from 'react-icons';
import { import {
PiBoundingBoxBold, PiBoundingBoxBold,
@@ -16,6 +17,8 @@ import {
PiTextAaBold, PiTextAaBold,
} from 'react-icons/pi'; } from 'react-icons/pi';
import type { DockviewPanelParameters } from './auto-layout-context';
const TAB_ICONS: Record<TabName, IconType> = { const TAB_ICONS: Record<TabName, IconType> = {
generate: PiTextAaBold, generate: PiTextAaBold,
canvas: PiBoundingBoxBold, canvas: PiBoundingBoxBold,
@@ -25,7 +28,8 @@ const TAB_ICONS: Record<TabName, IconType> = {
queue: PiQueueBold, queue: PiQueueBold,
}; };
export const DockviewTabLaunchpad = memo((props: IDockviewPanelHeaderProps) => { export const DockviewTabLaunchpad = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
const { t } = useTranslation();
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const activeTab = useAppSelector(selectActiveTab); const activeTab = useAppSelector(selectActiveTab);
@@ -44,7 +48,7 @@ export const DockviewTabLaunchpad = memo((props: IDockviewPanelHeaderProps) => {
return ( return (
<Flex ref={ref} alignItems="center" h="full" px={4} gap={3} onPointerDown={onPointerDown}> <Flex ref={ref} alignItems="center" h="full" px={4} gap={3} onPointerDown={onPointerDown}>
<Icon as={TAB_ICONS[activeTab]} color="invokeYellow.300" boxSize={5} /> <Icon as={TAB_ICONS[activeTab]} color="invokeYellow.300" boxSize={5} />
<Text userSelect="none">{props.api.title ?? props.api.id}</Text> <Text userSelect="none">{t(props.params.i18nKey)}</Text>
</Flex> </Flex>
); );
}); });

View File

@@ -4,11 +4,13 @@ import { useCallbackOnDragEnter } from 'common/hooks/useCallbackOnDragEnter';
import type { IDockviewPanelHeaderProps } from 'dockview'; import type { IDockviewPanelHeaderProps } from 'dockview';
import ProgressBar from 'features/system/components/ProgressBar'; import ProgressBar from 'features/system/components/ProgressBar';
import { memo, useCallback, useRef } from 'react'; import { memo, useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useIsGenerationInProgress } from 'services/api/endpoints/queue'; import { useIsGenerationInProgress } from 'services/api/endpoints/queue';
import type { PanelParameters } from './auto-layout-context'; import type { DockviewPanelParameters } from './auto-layout-context';
export const DockviewTabProgress = memo((props: IDockviewPanelHeaderProps<PanelParameters>) => { export const DockviewTabProgress = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
const { t } = useTranslation();
const isGenerationInProgress = useIsGenerationInProgress(); const isGenerationInProgress = useIsGenerationInProgress();
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
@@ -27,7 +29,7 @@ export const DockviewTabProgress = memo((props: IDockviewPanelHeaderProps<PanelP
return ( return (
<Flex ref={ref} position="relative" alignItems="center" h="full" onPointerDown={onPointerDown}> <Flex ref={ref} position="relative" alignItems="center" h="full" onPointerDown={onPointerDown}>
<Text userSelect="none" px={4}> <Text userSelect="none" px={4}>
{props.api.title ?? props.api.id} {t(props.params.i18nKey)}
</Text> </Text>
{isGenerationInProgress && ( {isGenerationInProgress && (
<ProgressBar position="absolute" bottom={0} left={0} right={0} h={1} borderRadius="none" /> <ProgressBar position="absolute" bottom={0} left={0} right={0} h={1} borderRadius="none" />

View File

@@ -27,15 +27,30 @@ export const useAutoLayoutContext = () => {
return value; return value;
}; };
export type PanelParameters = { export type DockviewPanelParameters = {
tab: TabName;
focusRegion: FocusRegionName;
i18nKey: string;
};
export type GridviewPanelParameters = {
tab: TabName; tab: TabName;
focusRegion: FocusRegionName; focusRegion: FocusRegionName;
}; };
export type AutoLayoutGridviewComponents = Record<string, FunctionComponent<IGridviewPanelProps<PanelParameters>>>; export type AutoLayoutGridviewComponents = Record<
export type AutoLayoutDockviewComponents = Record<string, FunctionComponent<IDockviewPanelProps<PanelParameters>>>; string,
export type RootLayoutGridviewComponents = Record<string, FunctionComponent<IGridviewPanelProps<PanelParameters>>>; FunctionComponent<IGridviewPanelProps<GridviewPanelParameters>>
type PanelProps = IDockviewPanelProps<PanelParameters> | IGridviewPanelProps<PanelParameters>; >;
export type AutoLayoutDockviewComponents = Record<
string,
FunctionComponent<IDockviewPanelProps<DockviewPanelParameters>>
>;
export type RootLayoutGridviewComponents = Record<
string,
FunctionComponent<IGridviewPanelProps<GridviewPanelParameters>>
>;
type PanelProps = IDockviewPanelProps<DockviewPanelParameters> | IGridviewPanelProps<GridviewPanelParameters>;
export const withPanelContainer = (Component: FunctionComponent) => export const withPanelContainer = (Component: FunctionComponent) =>
/* eslint-disable-next-line react/display-name */ /* eslint-disable-next-line react/display-name */

View File

@@ -9,7 +9,8 @@ import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightP
import type { import type {
AutoLayoutDockviewComponents, AutoLayoutDockviewComponents,
AutoLayoutGridviewComponents, AutoLayoutGridviewComponents,
PanelParameters, DockviewPanelParameters,
GridviewPanelParameters,
RootLayoutGridviewComponents, RootLayoutGridviewComponents,
} from 'features/ui/layouts/auto-layout-context'; } from 'features/ui/layouts/auto-layout-context';
import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context'; import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context';
@@ -63,7 +64,7 @@ const mainPanelComponents: AutoLayoutDockviewComponents = {
const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => { const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
navigationApi.registerContainer(tab, 'main', api, () => { navigationApi.registerContainer(tab, 'main', api, () => {
const launchpad = api.addPanel<PanelParameters>({ const launchpad = api.addPanel<DockviewPanelParameters>({
id: LAUNCHPAD_PANEL_ID, id: LAUNCHPAD_PANEL_ID,
component: LAUNCHPAD_PANEL_ID, component: LAUNCHPAD_PANEL_ID,
title: t('ui.panels.launchpad'), title: t('ui.panels.launchpad'),
@@ -71,10 +72,11 @@ const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'launchpad', focusRegion: 'launchpad',
i18nKey: 'ui.panels.launchpad',
}, },
}); });
api.addPanel<PanelParameters>({ api.addPanel<DockviewPanelParameters>({
id: WORKSPACE_PANEL_ID, id: WORKSPACE_PANEL_ID,
component: WORKSPACE_PANEL_ID, component: WORKSPACE_PANEL_ID,
title: t('ui.panels.canvas'), title: t('ui.panels.canvas'),
@@ -82,6 +84,7 @@ const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'canvas', focusRegion: 'canvas',
i18nKey: 'ui.panels.canvas',
}, },
position: { position: {
direction: 'within', direction: 'within',
@@ -89,7 +92,7 @@ const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
}, },
}); });
api.addPanel<PanelParameters>({ api.addPanel<DockviewPanelParameters>({
id: VIEWER_PANEL_ID, id: VIEWER_PANEL_ID,
component: VIEWER_PANEL_ID, component: VIEWER_PANEL_ID,
title: t('ui.panels.imageViewer'), title: t('ui.panels.imageViewer'),
@@ -97,6 +100,7 @@ const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'viewer', focusRegion: 'viewer',
i18nKey: 'ui.panels.imageViewer',
}, },
position: { position: {
direction: 'within', direction: 'within',
@@ -145,7 +149,7 @@ const rightPanelComponents: AutoLayoutGridviewComponents = {
const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => { const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
navigationApi.registerContainer(tab, 'right', api, () => { navigationApi.registerContainer(tab, 'right', api, () => {
const gallery = api.addPanel<PanelParameters>({ const gallery = api.addPanel<GridviewPanelParameters>({
id: GALLERY_PANEL_ID, id: GALLERY_PANEL_ID,
component: GALLERY_PANEL_ID, component: GALLERY_PANEL_ID,
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX, minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,
@@ -156,7 +160,7 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
}, },
}); });
const boards = api.addPanel<PanelParameters>({ const boards = api.addPanel<GridviewPanelParameters>({
id: BOARDS_PANEL_ID, id: BOARDS_PANEL_ID,
component: BOARDS_PANEL_ID, component: BOARDS_PANEL_ID,
minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX, minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX,
@@ -170,7 +174,7 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
}, },
}); });
api.addPanel<PanelParameters>({ api.addPanel<GridviewPanelParameters>({
id: LAYERS_PANEL_ID, id: LAYERS_PANEL_ID,
component: LAYERS_PANEL_ID, component: LAYERS_PANEL_ID,
minimumHeight: LAYERS_PANEL_MIN_HEIGHT_PX, minimumHeight: LAYERS_PANEL_MIN_HEIGHT_PX,
@@ -215,7 +219,7 @@ const leftPanelComponents: AutoLayoutGridviewComponents = {
const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => { const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
navigationApi.registerContainer(tab, 'left', api, () => { navigationApi.registerContainer(tab, 'left', api, () => {
api.addPanel<PanelParameters>({ api.addPanel<GridviewPanelParameters>({
id: SETTINGS_PANEL_ID, id: SETTINGS_PANEL_ID,
component: SETTINGS_PANEL_ID, component: SETTINGS_PANEL_ID,
params: { params: {

View File

@@ -8,7 +8,8 @@ import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightP
import type { import type {
AutoLayoutDockviewComponents, AutoLayoutDockviewComponents,
AutoLayoutGridviewComponents, AutoLayoutGridviewComponents,
PanelParameters, DockviewPanelParameters,
GridviewPanelParameters,
RootLayoutGridviewComponents, RootLayoutGridviewComponents,
} from 'features/ui/layouts/auto-layout-context'; } from 'features/ui/layouts/auto-layout-context';
import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context'; import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context';
@@ -57,7 +58,7 @@ const mainPanelComponents: AutoLayoutDockviewComponents = {
const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => { const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
navigationApi.registerContainer(tab, 'main', api, () => { navigationApi.registerContainer(tab, 'main', api, () => {
const launchpad = api.addPanel<PanelParameters>({ const launchpad = api.addPanel<DockviewPanelParameters>({
id: LAUNCHPAD_PANEL_ID, id: LAUNCHPAD_PANEL_ID,
component: LAUNCHPAD_PANEL_ID, component: LAUNCHPAD_PANEL_ID,
title: t('ui.panels.launchpad'), title: t('ui.panels.launchpad'),
@@ -65,10 +66,11 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'launchpad', focusRegion: 'launchpad',
i18nKey: 'ui.panels.launchpad',
}, },
}); });
api.addPanel<PanelParameters>({ api.addPanel<DockviewPanelParameters>({
id: VIEWER_PANEL_ID, id: VIEWER_PANEL_ID,
component: VIEWER_PANEL_ID, component: VIEWER_PANEL_ID,
title: t('ui.panels.imageViewer'), title: t('ui.panels.imageViewer'),
@@ -76,6 +78,7 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'viewer', focusRegion: 'viewer',
i18nKey: 'ui.panels.imageViewer',
}, },
position: { position: {
direction: 'within', direction: 'within',
@@ -123,7 +126,7 @@ const rightPanelComponents: AutoLayoutGridviewComponents = {
const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => { const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
navigationApi.registerContainer(tab, 'right', api, () => { navigationApi.registerContainer(tab, 'right', api, () => {
const gallery = api.addPanel<PanelParameters>({ const gallery = api.addPanel<GridviewPanelParameters>({
id: GALLERY_PANEL_ID, id: GALLERY_PANEL_ID,
component: GALLERY_PANEL_ID, component: GALLERY_PANEL_ID,
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX, minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,
@@ -134,7 +137,7 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
}, },
}); });
const boards = api.addPanel<PanelParameters>({ const boards = api.addPanel<GridviewPanelParameters>({
id: BOARDS_PANEL_ID, id: BOARDS_PANEL_ID,
component: BOARDS_PANEL_ID, component: BOARDS_PANEL_ID,
minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX, minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX,
@@ -179,7 +182,7 @@ const leftPanelComponents: AutoLayoutGridviewComponents = {
const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => { const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
navigationApi.registerContainer(tab, 'left', api, () => { navigationApi.registerContainer(tab, 'left', api, () => {
api.addPanel<PanelParameters>({ api.addPanel<GridviewPanelParameters>({
id: SETTINGS_PANEL_ID, id: SETTINGS_PANEL_ID,
component: SETTINGS_PANEL_ID, component: SETTINGS_PANEL_ID,
params: { params: {
@@ -218,13 +221,13 @@ const rootPanelComponents: RootLayoutGridviewComponents = {
const initializeRootPanelLayout = (tab: TabName, api: GridviewApi) => { const initializeRootPanelLayout = (tab: TabName, api: GridviewApi) => {
navigationApi.registerContainer(tab, 'root', api, () => { navigationApi.registerContainer(tab, 'root', api, () => {
const main = api.addPanel<PanelParameters>({ const main = api.addPanel<GridviewPanelParameters>({
id: MAIN_PANEL_ID, id: MAIN_PANEL_ID,
component: MAIN_PANEL_ID, component: MAIN_PANEL_ID,
priority: LayoutPriority.High, priority: LayoutPriority.High,
}); });
const left = api.addPanel<PanelParameters>({ const left = api.addPanel<GridviewPanelParameters>({
id: LEFT_PANEL_ID, id: LEFT_PANEL_ID,
component: LEFT_PANEL_ID, component: LEFT_PANEL_ID,
minimumWidth: LEFT_PANEL_MIN_SIZE_PX, minimumWidth: LEFT_PANEL_MIN_SIZE_PX,
@@ -234,7 +237,7 @@ const initializeRootPanelLayout = (tab: TabName, api: GridviewApi) => {
}, },
}); });
const right = api.addPanel<PanelParameters>({ const right = api.addPanel<GridviewPanelParameters>({
id: RIGHT_PANEL_ID, id: RIGHT_PANEL_ID,
component: RIGHT_PANEL_ID, component: RIGHT_PANEL_ID,
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX, minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,

View File

@@ -8,7 +8,8 @@ import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightP
import type { import type {
AutoLayoutDockviewComponents, AutoLayoutDockviewComponents,
AutoLayoutGridviewComponents, AutoLayoutGridviewComponents,
PanelParameters, DockviewPanelParameters,
GridviewPanelParameters,
RootLayoutGridviewComponents, RootLayoutGridviewComponents,
} from 'features/ui/layouts/auto-layout-context'; } from 'features/ui/layouts/auto-layout-context';
import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context'; import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context';
@@ -57,7 +58,7 @@ const mainPanelComponents: AutoLayoutDockviewComponents = {
const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => { const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
navigationApi.registerContainer(tab, 'main', api, () => { navigationApi.registerContainer(tab, 'main', api, () => {
const launchpad = api.addPanel<PanelParameters>({ const launchpad = api.addPanel<DockviewPanelParameters>({
id: LAUNCHPAD_PANEL_ID, id: LAUNCHPAD_PANEL_ID,
component: LAUNCHPAD_PANEL_ID, component: LAUNCHPAD_PANEL_ID,
title: t('ui.panels.launchpad'), title: t('ui.panels.launchpad'),
@@ -65,10 +66,11 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'launchpad', focusRegion: 'launchpad',
i18nKey: 'ui.panels.launchpad',
}, },
}); });
api.addPanel<PanelParameters>({ api.addPanel<DockviewPanelParameters>({
id: VIEWER_PANEL_ID, id: VIEWER_PANEL_ID,
component: VIEWER_PANEL_ID, component: VIEWER_PANEL_ID,
title: t('ui.panels.imageViewer'), title: t('ui.panels.imageViewer'),
@@ -76,6 +78,7 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'viewer', focusRegion: 'viewer',
i18nKey: 'ui.panels.imageViewer',
}, },
position: { position: {
direction: 'within', direction: 'within',
@@ -121,7 +124,7 @@ const rightPanelComponents: AutoLayoutGridviewComponents = {
const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => { const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
navigationApi.registerContainer(tab, 'right', api, () => { navigationApi.registerContainer(tab, 'right', api, () => {
const gallery = api.addPanel<PanelParameters>({ const gallery = api.addPanel<GridviewPanelParameters>({
id: GALLERY_PANEL_ID, id: GALLERY_PANEL_ID,
component: GALLERY_PANEL_ID, component: GALLERY_PANEL_ID,
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX, minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,
@@ -132,7 +135,7 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
}, },
}); });
const boards = api.addPanel<PanelParameters>({ const boards = api.addPanel<GridviewPanelParameters>({
id: BOARDS_PANEL_ID, id: BOARDS_PANEL_ID,
component: BOARDS_PANEL_ID, component: BOARDS_PANEL_ID,
minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX, minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX,
@@ -177,7 +180,7 @@ const leftPanelComponents: AutoLayoutGridviewComponents = {
const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => { const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
navigationApi.registerContainer(tab, 'left', api, () => { navigationApi.registerContainer(tab, 'left', api, () => {
api.addPanel<PanelParameters>({ api.addPanel<GridviewPanelParameters>({
id: SETTINGS_PANEL_ID, id: SETTINGS_PANEL_ID,
component: SETTINGS_PANEL_ID, component: SETTINGS_PANEL_ID,
params: { params: {

View File

@@ -10,7 +10,8 @@ import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightP
import type { import type {
AutoLayoutDockviewComponents, AutoLayoutDockviewComponents,
AutoLayoutGridviewComponents, AutoLayoutGridviewComponents,
PanelParameters, DockviewPanelParameters,
GridviewPanelParameters,
RootLayoutGridviewComponents, RootLayoutGridviewComponents,
} from 'features/ui/layouts/auto-layout-context'; } from 'features/ui/layouts/auto-layout-context';
import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context'; import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context';
@@ -60,7 +61,7 @@ const mainPanelComponents: AutoLayoutDockviewComponents = {
const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => { const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
navigationApi.registerContainer(tab, 'main', api, () => { navigationApi.registerContainer(tab, 'main', api, () => {
const launchpad = api.addPanel<PanelParameters>({ const launchpad = api.addPanel<DockviewPanelParameters>({
id: LAUNCHPAD_PANEL_ID, id: LAUNCHPAD_PANEL_ID,
component: LAUNCHPAD_PANEL_ID, component: LAUNCHPAD_PANEL_ID,
title: t('ui.panels.launchpad'), title: t('ui.panels.launchpad'),
@@ -68,10 +69,11 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'launchpad', focusRegion: 'launchpad',
i18nKey: 'ui.panels.launchpad',
}, },
}); });
api.addPanel<PanelParameters>({ api.addPanel<DockviewPanelParameters>({
id: WORKSPACE_PANEL_ID, id: WORKSPACE_PANEL_ID,
component: WORKSPACE_PANEL_ID, component: WORKSPACE_PANEL_ID,
title: t('ui.panels.workflowEditor'), title: t('ui.panels.workflowEditor'),
@@ -79,6 +81,7 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'workflows', focusRegion: 'workflows',
i18nKey: 'ui.panels.workflowEditor',
}, },
position: { position: {
direction: 'within', direction: 'within',
@@ -86,7 +89,7 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
}, },
}); });
api.addPanel<PanelParameters>({ api.addPanel<DockviewPanelParameters>({
id: VIEWER_PANEL_ID, id: VIEWER_PANEL_ID,
component: VIEWER_PANEL_ID, component: VIEWER_PANEL_ID,
title: t('ui.panels.imageViewer'), title: t('ui.panels.imageViewer'),
@@ -94,6 +97,7 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
params: { params: {
tab, tab,
focusRegion: 'viewer', focusRegion: 'viewer',
i18nKey: 'ui.panels.imageViewer',
}, },
position: { position: {
direction: 'within', direction: 'within',
@@ -141,7 +145,7 @@ const rightPanelComponents: AutoLayoutGridviewComponents = {
const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => { const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
navigationApi.registerContainer(tab, 'right', api, () => { navigationApi.registerContainer(tab, 'right', api, () => {
const gallery = api.addPanel<PanelParameters>({ const gallery = api.addPanel<GridviewPanelParameters>({
id: GALLERY_PANEL_ID, id: GALLERY_PANEL_ID,
component: GALLERY_PANEL_ID, component: GALLERY_PANEL_ID,
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX, minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,
@@ -152,7 +156,7 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
}, },
}); });
const boards = api.addPanel<PanelParameters>({ const boards = api.addPanel<GridviewPanelParameters>({
id: BOARDS_PANEL_ID, id: BOARDS_PANEL_ID,
component: BOARDS_PANEL_ID, component: BOARDS_PANEL_ID,
minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX, minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX,
@@ -197,7 +201,7 @@ const leftPanelComponents: AutoLayoutGridviewComponents = {
const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => { const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
navigationApi.registerContainer(tab, 'left', api, () => { navigationApi.registerContainer(tab, 'left', api, () => {
api.addPanel<PanelParameters>({ api.addPanel<GridviewPanelParameters>({
id: SETTINGS_PANEL_ID, id: SETTINGS_PANEL_ID,
component: SETTINGS_PANEL_ID, component: SETTINGS_PANEL_ID,
params: { params: {

View File

@@ -105,6 +105,10 @@ export const uiSliceConfig: SliceConfig<typeof slice> = {
state.activeTab = 'canvas'; state.activeTab = 'canvas';
state._version = 3; state._version = 3;
} }
if (state._version === 3) {
state.panels = {};
state._version = 4;
}
return zUIState.parse(state); return zUIState.parse(state);
}, },
persistDenylist: ['shouldShowImageDetails'], persistDenylist: ['shouldShowImageDetails'],

View File

@@ -13,7 +13,7 @@ const zSerializable = z.any().refine(isPlainObject);
export type Serializable = z.infer<typeof zSerializable>; export type Serializable = z.infer<typeof zSerializable>;
export const zUIState = z.object({ export const zUIState = z.object({
_version: z.literal(3), _version: z.literal(4),
activeTab: zTabName, activeTab: zTabName,
shouldShowImageDetails: z.boolean(), shouldShowImageDetails: z.boolean(),
shouldShowProgressInViewer: z.boolean(), shouldShowProgressInViewer: z.boolean(),
@@ -26,7 +26,7 @@ export const zUIState = z.object({
}); });
export type UIState = z.infer<typeof zUIState>; export type UIState = z.infer<typeof zUIState>;
export const getInitialUIState = (): UIState => ({ export const getInitialUIState = (): UIState => ({
_version: 3 as const, _version: 4 as const,
activeTab: 'generate' as const, activeTab: 'generate' as const,
shouldShowImageDetails: false, shouldShowImageDetails: false,
shouldShowProgressInViewer: true, shouldShowProgressInViewer: true,