Skip to content

Commit 17118a0

Browse files
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.
1 parent 24788e3 commit 17118a0

13 files changed

+99
-54
lines changed

invokeai/frontend/web/src/features/ui/layouts/AutoLayoutPanelContainer.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useAppSelector } from 'app/store/storeHooks';
33
import { useFocusRegion, useIsRegionFocused } from 'common/hooks/focus';
44
import type { IDockviewPanelProps, IGridviewPanelProps } from 'dockview';
55
import { selectSystemShouldEnableHighlightFocusedRegions } from 'features/system/store/systemSlice';
6-
import type { PanelParameters } from 'features/ui/layouts/auto-layout-context';
6+
import type { DockviewPanelParameters, GridviewPanelParameters } from 'features/ui/layouts/auto-layout-context';
77
import type { PropsWithChildren } from 'react';
88
import { memo, useRef } from 'react';
99

@@ -30,8 +30,8 @@ const sx: SystemStyleObject = {
3030
export const AutoLayoutPanelContainer = memo(
3131
(
3232
props:
33-
| PropsWithChildren<IDockviewPanelProps<PanelParameters>>
34-
| PropsWithChildren<IGridviewPanelProps<PanelParameters>>
33+
| PropsWithChildren<IDockviewPanelProps<DockviewPanelParameters>>
34+
| PropsWithChildren<IGridviewPanelProps<GridviewPanelParameters>>
3535
) => {
3636
const ref = useRef<HTMLDivElement>(null);
3737
const shouldHighlightFocusedRegions = useAppSelector(selectSystemShouldEnableHighlightFocusedRegions);

invokeai/frontend/web/src/features/ui/layouts/DockviewTab.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ import { setFocusedRegion } from 'common/hooks/focus';
33
import { useCallbackOnDragEnter } from 'common/hooks/useCallbackOnDragEnter';
44
import type { IDockviewPanelHeaderProps } from 'dockview';
55
import { memo, useCallback, useRef } from 'react';
6+
import { useTranslation } from 'react-i18next';
67

7-
import type { PanelParameters } from './auto-layout-context';
8+
import type { DockviewPanelParameters } from './auto-layout-context';
89

9-
export const DockviewTab = memo((props: IDockviewPanelHeaderProps<PanelParameters>) => {
10+
export const DockviewTab = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
11+
const { t } = useTranslation();
1012
const ref = useRef<HTMLDivElement>(null);
1113
const setActive = useCallback(() => {
1214
if (!props.api.isActive) {
@@ -23,7 +25,7 @@ export const DockviewTab = memo((props: IDockviewPanelHeaderProps<PanelParameter
2325
return (
2426
<Flex ref={ref} alignItems="center" h="full" onPointerDown={onPointerDown}>
2527
<Text userSelect="none" px={4}>
26-
{props.api.title ?? props.api.id}
28+
{t(props.params.i18nKey)}
2729
</Text>
2830
</Flex>
2931
);

invokeai/frontend/web/src/features/ui/layouts/DockviewTabCanvasViewer.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import type { IDockviewPanelHeaderProps } from 'dockview';
55
import { useCurrentQueueItemDestination } from 'features/queue/hooks/useCurrentQueueItemDestination';
66
import ProgressBar from 'features/system/components/ProgressBar';
77
import { memo, useCallback, useRef } from 'react';
8+
import { useTranslation } from 'react-i18next';
89
import { useIsGenerationInProgress } from 'services/api/endpoints/queue';
910

10-
import type { PanelParameters } from './auto-layout-context';
11+
import type { DockviewPanelParameters } from './auto-layout-context';
1112

12-
export const DockviewTabCanvasViewer = memo((props: IDockviewPanelHeaderProps<PanelParameters>) => {
13+
export const DockviewTabCanvasViewer = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
14+
const { t } = useTranslation();
1315
const isGenerationInProgress = useIsGenerationInProgress();
1416
const currentQueueItemDestination = useCurrentQueueItemDestination();
1517

@@ -29,7 +31,7 @@ export const DockviewTabCanvasViewer = memo((props: IDockviewPanelHeaderProps<Pa
2931
return (
3032
<Flex ref={ref} position="relative" alignItems="center" h="full" onPointerDown={onPointerDown}>
3133
<Text userSelect="none" px={4}>
32-
{props.api.title ?? props.api.id}
34+
{t(props.params.i18nKey)}
3335
</Text>
3436
{currentQueueItemDestination === 'canvas' && isGenerationInProgress && (
3537
<ProgressBar position="absolute" bottom={0} left={0} right={0} h={1} borderRadius="none" />

invokeai/frontend/web/src/features/ui/layouts/DockviewTabCanvasWorkspace.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import { selectCanvasSessionId } from 'features/controlLayers/store/canvasStagin
77
import { useCurrentQueueItemDestination } from 'features/queue/hooks/useCurrentQueueItemDestination';
88
import ProgressBar from 'features/system/components/ProgressBar';
99
import { memo, useCallback, useRef } from 'react';
10+
import { useTranslation } from 'react-i18next';
1011
import { useIsGenerationInProgress } from 'services/api/endpoints/queue';
1112

12-
import type { PanelParameters } from './auto-layout-context';
13+
import type { DockviewPanelParameters } from './auto-layout-context';
1314

14-
export const DockviewTabCanvasWorkspace = memo((props: IDockviewPanelHeaderProps<PanelParameters>) => {
15+
export const DockviewTabCanvasWorkspace = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
16+
const { t } = useTranslation();
1517
const isGenerationInProgress = useIsGenerationInProgress();
1618
const canvasSessionId = useAppSelector(selectCanvasSessionId);
1719
const currentQueueItemDestination = useCurrentQueueItemDestination();
@@ -32,7 +34,7 @@ export const DockviewTabCanvasWorkspace = memo((props: IDockviewPanelHeaderProps
3234
return (
3335
<Flex ref={ref} position="relative" alignItems="center" h="full" onPointerDown={onPointerDown}>
3436
<Text userSelect="none" px={4}>
35-
{props.api.title ?? props.api.id}
37+
{t(props.params.i18nKey)}
3638
</Text>
3739
{currentQueueItemDestination === canvasSessionId && isGenerationInProgress && (
3840
<ProgressBar position="absolute" bottom={0} left={0} right={0} h={1} borderRadius="none" />

invokeai/frontend/web/src/features/ui/layouts/DockviewTabLaunchpad.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { IDockviewPanelHeaderProps } from 'dockview';
66
import { selectActiveTab } from 'features/ui/store/uiSelectors';
77
import type { TabName } from 'features/ui/store/uiTypes';
88
import { memo, useCallback, useRef } from 'react';
9+
import { useTranslation } from 'react-i18next';
910
import type { IconType } from 'react-icons';
1011
import {
1112
PiBoundingBoxBold,
@@ -16,6 +17,8 @@ import {
1617
PiTextAaBold,
1718
} from 'react-icons/pi';
1819

20+
import type { DockviewPanelParameters } from './auto-layout-context';
21+
1922
const TAB_ICONS: Record<TabName, IconType> = {
2023
generate: PiTextAaBold,
2124
canvas: PiBoundingBoxBold,
@@ -25,7 +28,8 @@ const TAB_ICONS: Record<TabName, IconType> = {
2528
queue: PiQueueBold,
2629
};
2730

28-
export const DockviewTabLaunchpad = memo((props: IDockviewPanelHeaderProps) => {
31+
export const DockviewTabLaunchpad = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
32+
const { t } = useTranslation();
2933
const ref = useRef<HTMLDivElement>(null);
3034
const activeTab = useAppSelector(selectActiveTab);
3135

@@ -44,7 +48,7 @@ export const DockviewTabLaunchpad = memo((props: IDockviewPanelHeaderProps) => {
4448
return (
4549
<Flex ref={ref} alignItems="center" h="full" px={4} gap={3} onPointerDown={onPointerDown}>
4650
<Icon as={TAB_ICONS[activeTab]} color="invokeYellow.300" boxSize={5} />
47-
<Text userSelect="none">{props.api.title ?? props.api.id}</Text>
51+
<Text userSelect="none">{t(props.params.i18nKey)}</Text>
4852
</Flex>
4953
);
5054
});

invokeai/frontend/web/src/features/ui/layouts/DockviewTabProgress.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import { useCallbackOnDragEnter } from 'common/hooks/useCallbackOnDragEnter';
44
import type { IDockviewPanelHeaderProps } from 'dockview';
55
import ProgressBar from 'features/system/components/ProgressBar';
66
import { memo, useCallback, useRef } from 'react';
7+
import { useTranslation } from 'react-i18next';
78
import { useIsGenerationInProgress } from 'services/api/endpoints/queue';
89

9-
import type { PanelParameters } from './auto-layout-context';
10+
import type { DockviewPanelParameters } from './auto-layout-context';
1011

11-
export const DockviewTabProgress = memo((props: IDockviewPanelHeaderProps<PanelParameters>) => {
12+
export const DockviewTabProgress = memo((props: IDockviewPanelHeaderProps<DockviewPanelParameters>) => {
13+
const { t } = useTranslation();
1214
const isGenerationInProgress = useIsGenerationInProgress();
1315

1416
const ref = useRef<HTMLDivElement>(null);
@@ -27,7 +29,7 @@ export const DockviewTabProgress = memo((props: IDockviewPanelHeaderProps<PanelP
2729
return (
2830
<Flex ref={ref} position="relative" alignItems="center" h="full" onPointerDown={onPointerDown}>
2931
<Text userSelect="none" px={4}>
30-
{props.api.title ?? props.api.id}
32+
{t(props.params.i18nKey)}
3133
</Text>
3234
{isGenerationInProgress && (
3335
<ProgressBar position="absolute" bottom={0} left={0} right={0} h={1} borderRadius="none" />

invokeai/frontend/web/src/features/ui/layouts/auto-layout-context.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,30 @@ export const useAutoLayoutContext = () => {
2727
return value;
2828
};
2929

30-
export type PanelParameters = {
30+
export type DockviewPanelParameters = {
3131
tab: TabName;
3232
focusRegion: FocusRegionName;
33+
i18nKey: string;
3334
};
3435

35-
export type AutoLayoutGridviewComponents = Record<string, FunctionComponent<IGridviewPanelProps<PanelParameters>>>;
36-
export type AutoLayoutDockviewComponents = Record<string, FunctionComponent<IDockviewPanelProps<PanelParameters>>>;
37-
export type RootLayoutGridviewComponents = Record<string, FunctionComponent<IGridviewPanelProps<PanelParameters>>>;
38-
type PanelProps = IDockviewPanelProps<PanelParameters> | IGridviewPanelProps<PanelParameters>;
36+
export type GridviewPanelParameters = {
37+
tab: TabName;
38+
focusRegion: FocusRegionName;
39+
};
40+
41+
export type AutoLayoutGridviewComponents = Record<
42+
string,
43+
FunctionComponent<IGridviewPanelProps<GridviewPanelParameters>>
44+
>;
45+
export type AutoLayoutDockviewComponents = Record<
46+
string,
47+
FunctionComponent<IDockviewPanelProps<DockviewPanelParameters>>
48+
>;
49+
export type RootLayoutGridviewComponents = Record<
50+
string,
51+
FunctionComponent<IGridviewPanelProps<GridviewPanelParameters>>
52+
>;
53+
type PanelProps = IDockviewPanelProps<DockviewPanelParameters> | IGridviewPanelProps<GridviewPanelParameters>;
3954

4055
export const withPanelContainer = (Component: FunctionComponent) =>
4156
/* eslint-disable-next-line react/display-name */

invokeai/frontend/web/src/features/ui/layouts/canvas-tab-auto-layout.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightP
99
import type {
1010
AutoLayoutDockviewComponents,
1111
AutoLayoutGridviewComponents,
12-
PanelParameters,
12+
DockviewPanelParameters,
13+
GridviewPanelParameters,
1314
RootLayoutGridviewComponents,
1415
} from 'features/ui/layouts/auto-layout-context';
1516
import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context';
@@ -63,40 +64,43 @@ const mainPanelComponents: AutoLayoutDockviewComponents = {
6364

6465
const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
6566
navigationApi.registerContainer(tab, 'main', api, () => {
66-
const launchpad = api.addPanel<PanelParameters>({
67+
const launchpad = api.addPanel<DockviewPanelParameters>({
6768
id: LAUNCHPAD_PANEL_ID,
6869
component: LAUNCHPAD_PANEL_ID,
6970
title: t('ui.panels.launchpad'),
7071
tabComponent: DOCKVIEW_TAB_LAUNCHPAD_ID,
7172
params: {
7273
tab,
7374
focusRegion: 'launchpad',
75+
i18nKey: 'ui.panels.launchpad',
7476
},
7577
});
7678

77-
api.addPanel<PanelParameters>({
79+
api.addPanel<DockviewPanelParameters>({
7880
id: WORKSPACE_PANEL_ID,
7981
component: WORKSPACE_PANEL_ID,
8082
title: t('ui.panels.canvas'),
8183
tabComponent: DOCKVIEW_TAB_CANVAS_WORKSPACE_ID,
8284
params: {
8385
tab,
8486
focusRegion: 'canvas',
87+
i18nKey: 'ui.panels.canvas',
8588
},
8689
position: {
8790
direction: 'within',
8891
referencePanel: launchpad.id,
8992
},
9093
});
9194

92-
api.addPanel<PanelParameters>({
95+
api.addPanel<DockviewPanelParameters>({
9396
id: VIEWER_PANEL_ID,
9497
component: VIEWER_PANEL_ID,
9598
title: t('ui.panels.imageViewer'),
9699
tabComponent: DOCKVIEW_TAB_CANVAS_VIEWER_ID,
97100
params: {
98101
tab,
99102
focusRegion: 'viewer',
103+
i18nKey: 'ui.panels.imageViewer',
100104
},
101105
position: {
102106
direction: 'within',
@@ -145,7 +149,7 @@ const rightPanelComponents: AutoLayoutGridviewComponents = {
145149

146150
const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
147151
navigationApi.registerContainer(tab, 'right', api, () => {
148-
const gallery = api.addPanel<PanelParameters>({
152+
const gallery = api.addPanel<GridviewPanelParameters>({
149153
id: GALLERY_PANEL_ID,
150154
component: GALLERY_PANEL_ID,
151155
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,
@@ -156,7 +160,7 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
156160
},
157161
});
158162

159-
const boards = api.addPanel<PanelParameters>({
163+
const boards = api.addPanel<GridviewPanelParameters>({
160164
id: BOARDS_PANEL_ID,
161165
component: BOARDS_PANEL_ID,
162166
minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX,
@@ -170,7 +174,7 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
170174
},
171175
});
172176

173-
api.addPanel<PanelParameters>({
177+
api.addPanel<GridviewPanelParameters>({
174178
id: LAYERS_PANEL_ID,
175179
component: LAYERS_PANEL_ID,
176180
minimumHeight: LAYERS_PANEL_MIN_HEIGHT_PX,
@@ -215,7 +219,7 @@ const leftPanelComponents: AutoLayoutGridviewComponents = {
215219

216220
const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
217221
navigationApi.registerContainer(tab, 'left', api, () => {
218-
api.addPanel<PanelParameters>({
222+
api.addPanel<GridviewPanelParameters>({
219223
id: SETTINGS_PANEL_ID,
220224
component: SETTINGS_PANEL_ID,
221225
params: {

invokeai/frontend/web/src/features/ui/layouts/generate-tab-auto-layout.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightP
88
import type {
99
AutoLayoutDockviewComponents,
1010
AutoLayoutGridviewComponents,
11-
PanelParameters,
11+
DockviewPanelParameters,
12+
GridviewPanelParameters,
1213
RootLayoutGridviewComponents,
1314
} from 'features/ui/layouts/auto-layout-context';
1415
import { AutoLayoutProvider, useAutoLayoutContext, withPanelContainer } from 'features/ui/layouts/auto-layout-context';
@@ -57,25 +58,27 @@ const mainPanelComponents: AutoLayoutDockviewComponents = {
5758

5859
const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
5960
navigationApi.registerContainer(tab, 'main', api, () => {
60-
const launchpad = api.addPanel<PanelParameters>({
61+
const launchpad = api.addPanel<DockviewPanelParameters>({
6162
id: LAUNCHPAD_PANEL_ID,
6263
component: LAUNCHPAD_PANEL_ID,
6364
title: t('ui.panels.launchpad'),
6465
tabComponent: DOCKVIEW_TAB_LAUNCHPAD_ID,
6566
params: {
6667
tab,
6768
focusRegion: 'launchpad',
69+
i18nKey: 'ui.panels.launchpad',
6870
},
6971
});
7072

71-
api.addPanel<PanelParameters>({
73+
api.addPanel<DockviewPanelParameters>({
7274
id: VIEWER_PANEL_ID,
7375
component: VIEWER_PANEL_ID,
7476
title: t('ui.panels.imageViewer'),
7577
tabComponent: DOCKVIEW_TAB_PROGRESS_ID,
7678
params: {
7779
tab,
7880
focusRegion: 'viewer',
81+
i18nKey: 'ui.panels.imageViewer',
7982
},
8083
position: {
8184
direction: 'within',
@@ -123,7 +126,7 @@ const rightPanelComponents: AutoLayoutGridviewComponents = {
123126

124127
const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
125128
navigationApi.registerContainer(tab, 'right', api, () => {
126-
const gallery = api.addPanel<PanelParameters>({
129+
const gallery = api.addPanel<GridviewPanelParameters>({
127130
id: GALLERY_PANEL_ID,
128131
component: GALLERY_PANEL_ID,
129132
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,
@@ -134,7 +137,7 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
134137
},
135138
});
136139

137-
const boards = api.addPanel<PanelParameters>({
140+
const boards = api.addPanel<GridviewPanelParameters>({
138141
id: BOARDS_PANEL_ID,
139142
component: BOARDS_PANEL_ID,
140143
minimumHeight: BOARD_PANEL_MIN_HEIGHT_PX,
@@ -179,7 +182,7 @@ const leftPanelComponents: AutoLayoutGridviewComponents = {
179182

180183
const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
181184
navigationApi.registerContainer(tab, 'left', api, () => {
182-
api.addPanel<PanelParameters>({
185+
api.addPanel<GridviewPanelParameters>({
183186
id: SETTINGS_PANEL_ID,
184187
component: SETTINGS_PANEL_ID,
185188
params: {
@@ -218,13 +221,13 @@ const rootPanelComponents: RootLayoutGridviewComponents = {
218221

219222
const initializeRootPanelLayout = (tab: TabName, api: GridviewApi) => {
220223
navigationApi.registerContainer(tab, 'root', api, () => {
221-
const main = api.addPanel<PanelParameters>({
224+
const main = api.addPanel<GridviewPanelParameters>({
222225
id: MAIN_PANEL_ID,
223226
component: MAIN_PANEL_ID,
224227
priority: LayoutPriority.High,
225228
});
226229

227-
const left = api.addPanel<PanelParameters>({
230+
const left = api.addPanel<GridviewPanelParameters>({
228231
id: LEFT_PANEL_ID,
229232
component: LEFT_PANEL_ID,
230233
minimumWidth: LEFT_PANEL_MIN_SIZE_PX,
@@ -234,7 +237,7 @@ const initializeRootPanelLayout = (tab: TabName, api: GridviewApi) => {
234237
},
235238
});
236239

237-
const right = api.addPanel<PanelParameters>({
240+
const right = api.addPanel<GridviewPanelParameters>({
238241
id: RIGHT_PANEL_ID,
239242
component: RIGHT_PANEL_ID,
240243
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,

0 commit comments

Comments
 (0)