mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
fix(ui): prevent panels from growing on init
This works but I think a better solution is to use dockview's provided serialization API to store and restore layouts.
This commit is contained in:
@@ -81,6 +81,9 @@ const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
focusRegion: 'launchpad',
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, LAUNCHPAD_PANEL_ID, launchpad, {
|
||||
isActive: true,
|
||||
});
|
||||
|
||||
const workspace = api.addPanel<PanelParameters>({
|
||||
id: WORKSPACE_PANEL_ID,
|
||||
@@ -96,6 +99,7 @@ const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
referencePanel: launchpad.id,
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, WORKSPACE_PANEL_ID, workspace);
|
||||
|
||||
const viewer = api.addPanel<PanelParameters>({
|
||||
id: VIEWER_PANEL_ID,
|
||||
@@ -111,11 +115,6 @@ const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
referencePanel: launchpad.id,
|
||||
},
|
||||
});
|
||||
|
||||
launchpad.api.setActive();
|
||||
|
||||
navigationApi.registerPanel(tab, LAUNCHPAD_PANEL_ID, launchpad);
|
||||
navigationApi.registerPanel(tab, WORKSPACE_PANEL_ID, workspace);
|
||||
navigationApi.registerPanel(tab, VIEWER_PANEL_ID, viewer);
|
||||
|
||||
return { launchpad, workspace, viewer } satisfies Record<string, IDockviewPanel>;
|
||||
@@ -167,18 +166,10 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
focusRegion: 'gallery',
|
||||
},
|
||||
});
|
||||
|
||||
const layers = api.addPanel<PanelParameters>({
|
||||
id: LAYERS_PANEL_ID,
|
||||
component: LAYERS_PANEL_ID,
|
||||
minimumHeight: LAYERS_PANEL_MIN_HEIGHT_PX,
|
||||
params: {
|
||||
tab,
|
||||
focusRegion: 'layers',
|
||||
},
|
||||
position: {
|
||||
direction: 'below',
|
||||
referencePanel: gallery.id,
|
||||
navigationApi.registerPanel(tab, GALLERY_PANEL_ID, gallery, {
|
||||
dimensions: {
|
||||
height: GALLERY_PANEL_DEFAULT_HEIGHT_PX,
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -195,14 +186,27 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
referencePanel: gallery.id,
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, BOARDS_PANEL_ID, boards, {
|
||||
dimensions: {
|
||||
height: CANVAS_BOARD_PANEL_DEFAULT_HEIGHT_PX,
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
gallery.api.setSize({ height: GALLERY_PANEL_DEFAULT_HEIGHT_PX, width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
boards.api.setSize({ height: CANVAS_BOARD_PANEL_DEFAULT_HEIGHT_PX, width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
|
||||
// Register panels with navigation API
|
||||
navigationApi.registerPanel(tab, GALLERY_PANEL_ID, gallery);
|
||||
const layers = api.addPanel<PanelParameters>({
|
||||
id: LAYERS_PANEL_ID,
|
||||
component: LAYERS_PANEL_ID,
|
||||
minimumHeight: LAYERS_PANEL_MIN_HEIGHT_PX,
|
||||
params: {
|
||||
tab,
|
||||
focusRegion: 'layers',
|
||||
},
|
||||
position: {
|
||||
direction: 'below',
|
||||
referencePanel: gallery.id,
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, LAYERS_PANEL_ID, layers);
|
||||
navigationApi.registerPanel(tab, BOARDS_PANEL_ID, boards);
|
||||
|
||||
return { gallery, layers, boards } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
@@ -240,8 +244,6 @@ const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
focusRegion: 'settings',
|
||||
},
|
||||
});
|
||||
|
||||
// Register panel with navigation API
|
||||
navigationApi.registerPanel(tab, SETTINGS_PANEL_ID, settings);
|
||||
|
||||
return { settings } satisfies Record<string, IGridviewPanel>;
|
||||
@@ -273,12 +275,13 @@ const rootPanelComponents: RootLayoutGridviewComponents = {
|
||||
[RIGHT_PANEL_ID]: RightPanel,
|
||||
};
|
||||
|
||||
const initializeRootPanelLayout = (api: GridviewApi) => {
|
||||
const initializeRootPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
const main = api.addPanel({
|
||||
id: MAIN_PANEL_ID,
|
||||
component: MAIN_PANEL_ID,
|
||||
priority: LayoutPriority.High,
|
||||
});
|
||||
navigationApi.registerPanel(tab, MAIN_PANEL_ID, main);
|
||||
|
||||
const left = api.addPanel({
|
||||
id: LEFT_PANEL_ID,
|
||||
@@ -289,6 +292,11 @@ const initializeRootPanelLayout = (api: GridviewApi) => {
|
||||
referencePanel: main.id,
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, LEFT_PANEL_ID, left, {
|
||||
dimensions: {
|
||||
width: LEFT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
const right = api.addPanel({
|
||||
id: RIGHT_PANEL_ID,
|
||||
@@ -299,20 +307,18 @@ const initializeRootPanelLayout = (api: GridviewApi) => {
|
||||
referencePanel: main.id,
|
||||
},
|
||||
});
|
||||
|
||||
left.api.setSize({ width: LEFT_PANEL_MIN_SIZE_PX });
|
||||
right.api.setSize({ width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
|
||||
navigationApi.registerPanel('canvas', LEFT_PANEL_ID, left);
|
||||
navigationApi.registerPanel('canvas', MAIN_PANEL_ID, main);
|
||||
navigationApi.registerPanel('canvas', RIGHT_PANEL_ID, right);
|
||||
navigationApi.registerPanel(tab, RIGHT_PANEL_ID, right, {
|
||||
dimensions: {
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
return { main, left, right } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
|
||||
export const CanvasTabAutoLayout = memo(() => {
|
||||
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
|
||||
initializeRootPanelLayout(api);
|
||||
initializeRootPanelLayout('canvas', api);
|
||||
}, []);
|
||||
|
||||
useEffect(
|
||||
|
||||
@@ -75,6 +75,9 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
focusRegion: 'launchpad',
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, LAUNCHPAD_PANEL_ID, launchpad, {
|
||||
isActive: true,
|
||||
});
|
||||
|
||||
const viewer = api.addPanel<PanelParameters>({
|
||||
id: VIEWER_PANEL_ID,
|
||||
@@ -90,10 +93,6 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
referencePanel: launchpad.id,
|
||||
},
|
||||
});
|
||||
|
||||
launchpad.api.setActive();
|
||||
|
||||
navigationApi.registerPanel(tab, LAUNCHPAD_PANEL_ID, launchpad);
|
||||
navigationApi.registerPanel(tab, VIEWER_PANEL_ID, viewer);
|
||||
|
||||
return { launchpad, viewer } satisfies Record<string, IDockviewPanel>;
|
||||
@@ -144,6 +143,12 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
focusRegion: 'gallery',
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, GALLERY_PANEL_ID, gallery, {
|
||||
dimensions: {
|
||||
height: GALLERY_PANEL_DEFAULT_HEIGHT_PX,
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
const boards = api.addPanel<PanelParameters>({
|
||||
id: BOARDS_PANEL_ID,
|
||||
@@ -158,13 +163,12 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
referencePanel: gallery.id,
|
||||
},
|
||||
});
|
||||
|
||||
gallery.api.setSize({ height: GALLERY_PANEL_DEFAULT_HEIGHT_PX, width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
boards.api.setSize({ height: BOARD_PANEL_DEFAULT_HEIGHT_PX, width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
|
||||
// Register panels with navigation API
|
||||
navigationApi.registerPanel(tab, GALLERY_PANEL_ID, gallery);
|
||||
navigationApi.registerPanel(tab, BOARDS_PANEL_ID, boards);
|
||||
navigationApi.registerPanel(tab, BOARDS_PANEL_ID, boards, {
|
||||
dimensions: {
|
||||
height: BOARD_PANEL_DEFAULT_HEIGHT_PX,
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
return { gallery, boards } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
@@ -202,8 +206,6 @@ const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
focusRegion: 'settings',
|
||||
},
|
||||
});
|
||||
|
||||
// Register panel with navigation API
|
||||
navigationApi.registerPanel(tab, SETTINGS_PANEL_ID, settings);
|
||||
|
||||
return { settings } satisfies Record<string, IGridviewPanel>;
|
||||
@@ -235,14 +237,15 @@ const rootPanelComponents: RootLayoutGridviewComponents = {
|
||||
[RIGHT_PANEL_ID]: RightPanel,
|
||||
};
|
||||
|
||||
const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
|
||||
const main = layoutApi.addPanel<PanelParameters>({
|
||||
const initializeRootPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
const main = api.addPanel<PanelParameters>({
|
||||
id: MAIN_PANEL_ID,
|
||||
component: MAIN_PANEL_ID,
|
||||
priority: LayoutPriority.High,
|
||||
});
|
||||
navigationApi.registerPanel(tab, MAIN_PANEL_ID, main);
|
||||
|
||||
const left = layoutApi.addPanel<PanelParameters>({
|
||||
const left = api.addPanel<PanelParameters>({
|
||||
id: LEFT_PANEL_ID,
|
||||
component: LEFT_PANEL_ID,
|
||||
minimumWidth: LEFT_PANEL_MIN_SIZE_PX,
|
||||
@@ -251,8 +254,13 @@ const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
|
||||
referencePanel: main.id,
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, LEFT_PANEL_ID, left, {
|
||||
dimensions: {
|
||||
width: LEFT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
const right = layoutApi.addPanel<PanelParameters>({
|
||||
const right = api.addPanel<PanelParameters>({
|
||||
id: RIGHT_PANEL_ID,
|
||||
component: RIGHT_PANEL_ID,
|
||||
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
@@ -261,20 +269,18 @@ const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
|
||||
referencePanel: main.id,
|
||||
},
|
||||
});
|
||||
|
||||
left.api.setSize({ width: LEFT_PANEL_MIN_SIZE_PX });
|
||||
right.api.setSize({ width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
|
||||
navigationApi.registerPanel('generate', LEFT_PANEL_ID, left);
|
||||
navigationApi.registerPanel('generate', MAIN_PANEL_ID, main);
|
||||
navigationApi.registerPanel('generate', RIGHT_PANEL_ID, right);
|
||||
navigationApi.registerPanel(tab, RIGHT_PANEL_ID, right, {
|
||||
dimensions: {
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
return { main, left, right } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
|
||||
export const GenerateTabAutoLayout = memo(() => {
|
||||
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
|
||||
initializeRootPanelLayout(api);
|
||||
initializeRootPanelLayout('generate', api);
|
||||
}, []);
|
||||
|
||||
useEffect(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { createDeferredPromise, type Deferred } from 'common/util/createDeferredPromise';
|
||||
import { DockviewPanel, GridviewPanel, type IDockviewPanel, type IGridviewPanel } from 'dockview';
|
||||
import type { ActiveEvent, IDockviewPanel, IGridviewPanel, PanelDimensionChangeEvent } from 'dockview';
|
||||
import { DockviewPanel, GridviewPanel } from 'dockview';
|
||||
import { debounce } from 'es-toolkit';
|
||||
import type { StoredDockviewPanelState, StoredGridviewPanelState, TabName } from 'features/ui/store/uiTypes';
|
||||
import type { Atom } from 'nanostores';
|
||||
@@ -18,6 +19,12 @@ const log = logger('system');
|
||||
|
||||
type PanelType = IGridviewPanel | IDockviewPanel;
|
||||
|
||||
type StateForPanelType<T> = T extends IGridviewPanel
|
||||
? Omit<StoredGridviewPanelState, 'id' | 'type'>
|
||||
: T extends IDockviewPanel
|
||||
? Omit<StoredDockviewPanelState, 'id' | 'type'>
|
||||
: never;
|
||||
|
||||
/**
|
||||
* An object that represents a promise that is waiting for a panel to be registered and ready.
|
||||
*
|
||||
@@ -142,7 +149,11 @@ export class NavigationApi {
|
||||
* - If the panel has a stored state, it is restored to those dimensions.
|
||||
* - If the stored state has dimensions of 0, it is assumed that the panel was collapsed by the user.
|
||||
*/
|
||||
_initGridviewPanelStorage = (key: string, panel: IGridviewPanel) => {
|
||||
_initGridviewPanelStorage = (
|
||||
key: string,
|
||||
panel: IGridviewPanel,
|
||||
defaultState?: StateForPanelType<IGridviewPanel>
|
||||
) => {
|
||||
if (!this._app) {
|
||||
log.error('App not connected');
|
||||
return;
|
||||
@@ -150,6 +161,16 @@ export class NavigationApi {
|
||||
const storedState = this._app.panelStorage.get(key);
|
||||
if (!storedState) {
|
||||
log.debug('No stored state for panel, setting initial state');
|
||||
|
||||
if (defaultState && defaultState.dimensions) {
|
||||
if (defaultState.dimensions.width === 0) {
|
||||
panel.api.setConstraints({ minimumWidth: 0, maximumWidth: 0 });
|
||||
}
|
||||
if (defaultState.dimensions.height === 0) {
|
||||
panel.api.setConstraints({ minimumHeight: 0, maximumHeight: 0 });
|
||||
}
|
||||
panel.api.setSize(defaultState.dimensions);
|
||||
}
|
||||
const { height, width } = panel.api;
|
||||
this._app.panelStorage.set(key, {
|
||||
id: key,
|
||||
@@ -183,20 +204,21 @@ export class NavigationApi {
|
||||
|
||||
panel.api.setSize(storedState.dimensions);
|
||||
}
|
||||
const { dispose } = panel.api.onDidDimensionsChange(
|
||||
debounce(({ width, height }) => {
|
||||
log.debug({ key, width, height }, 'Panel dimensions changed');
|
||||
if (!this._app) {
|
||||
log.error('App not connected');
|
||||
return;
|
||||
}
|
||||
this._app.panelStorage.set(key, {
|
||||
id: key,
|
||||
type: 'gridview-panel',
|
||||
dimensions: { width, height },
|
||||
});
|
||||
}, 1000)
|
||||
);
|
||||
|
||||
const onDidDimensionsChange = ({ width, height }: PanelDimensionChangeEvent) => {
|
||||
log.debug({ key, width, height }, 'Panel dimensions changed');
|
||||
if (!this._app) {
|
||||
log.error('App not connected');
|
||||
return;
|
||||
}
|
||||
this._app.panelStorage.set(key, {
|
||||
id: key,
|
||||
type: 'gridview-panel',
|
||||
dimensions: { width, height },
|
||||
});
|
||||
};
|
||||
|
||||
const { dispose } = panel.api.onDidDimensionsChange(debounce(onDidDimensionsChange, 1000));
|
||||
|
||||
return dispose;
|
||||
};
|
||||
@@ -207,13 +229,21 @@ export class NavigationApi {
|
||||
* - If the panel has no stored state, it saves its current active state.
|
||||
* - If the panel has a stored state, it restores that state.
|
||||
*/
|
||||
_initDockviewPanelStorage = (key: string, panel: IDockviewPanel) => {
|
||||
_initDockviewPanelStorage = (
|
||||
key: string,
|
||||
panel: IDockviewPanel,
|
||||
defaultState?: StateForPanelType<IDockviewPanel>
|
||||
) => {
|
||||
if (!this._app) {
|
||||
log.error('App not connected');
|
||||
return;
|
||||
}
|
||||
const storedState = this._app.panelStorage.get(key);
|
||||
if (!storedState) {
|
||||
if (defaultState && defaultState.isActive) {
|
||||
panel.api.setActive();
|
||||
}
|
||||
|
||||
const { isActive } = panel.api;
|
||||
this._app.panelStorage.set(key, {
|
||||
id: key,
|
||||
@@ -231,19 +261,19 @@ export class NavigationApi {
|
||||
}
|
||||
}
|
||||
|
||||
const { dispose } = panel.api.onDidActiveChange(
|
||||
debounce(({ isActive }) => {
|
||||
if (!this._app) {
|
||||
log.error('App not connected');
|
||||
return;
|
||||
}
|
||||
this._app.panelStorage.set(key, {
|
||||
id: key,
|
||||
type: 'dockview-panel',
|
||||
isActive,
|
||||
});
|
||||
}, 1000)
|
||||
);
|
||||
const onDidActiveChange = ({ isActive }: ActiveEvent) => {
|
||||
if (!this._app) {
|
||||
log.error('App not connected');
|
||||
return;
|
||||
}
|
||||
this._app.panelStorage.set(key, {
|
||||
id: key,
|
||||
type: 'dockview-panel',
|
||||
isActive,
|
||||
});
|
||||
};
|
||||
|
||||
const { dispose } = panel.api.onDidActiveChange(debounce(onDidActiveChange, 1000));
|
||||
|
||||
return dispose;
|
||||
};
|
||||
@@ -251,11 +281,11 @@ export class NavigationApi {
|
||||
/**
|
||||
* Helper function to initialize storage for a panel based on its type.
|
||||
*/
|
||||
_initPanelStorage = (key: string, panel: PanelType) => {
|
||||
_initPanelStorage = <T extends PanelType>(key: string, panel: T, defaultState?: StateForPanelType<T>) => {
|
||||
if (panel instanceof GridviewPanel) {
|
||||
return this._initGridviewPanelStorage(key, panel);
|
||||
return this._initGridviewPanelStorage(key, panel, defaultState as StateForPanelType<IGridviewPanel>);
|
||||
} else if (panel instanceof DockviewPanel) {
|
||||
return this._initDockviewPanelStorage(key, panel);
|
||||
return this._initDockviewPanelStorage(key, panel, defaultState as StateForPanelType<IDockviewPanel>);
|
||||
} else {
|
||||
log.error(`Unsupported panel type: ${panel.constructor.name}`);
|
||||
return;
|
||||
@@ -270,12 +300,17 @@ export class NavigationApi {
|
||||
* @param panel - The panel instance
|
||||
* @returns Cleanup function to unregister the panel
|
||||
*/
|
||||
registerPanel = (tab: TabName, panelId: string, panel: PanelType): (() => void) => {
|
||||
registerPanel = <T extends PanelType>(
|
||||
tab: TabName,
|
||||
panelId: string,
|
||||
panel: T,
|
||||
defaultState?: StateForPanelType<T>
|
||||
): (() => void) => {
|
||||
const key = this._getPanelKey(tab, panelId);
|
||||
|
||||
this.panels.set(key, panel);
|
||||
|
||||
const cleanupPanelStorage = this._initPanelStorage(key, panel);
|
||||
const cleanupPanelStorage = this._initPanelStorage(key, panel, defaultState);
|
||||
|
||||
// Resolve any pending waiters for this panel, notifying them that the panel is now registered.
|
||||
const waiter = this.waiters.get(key);
|
||||
|
||||
@@ -75,6 +75,9 @@ const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
focusRegion: 'launchpad',
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, LAUNCHPAD_PANEL_ID, launchpad, {
|
||||
isActive: true,
|
||||
});
|
||||
|
||||
const viewer = api.addPanel<PanelParameters>({
|
||||
id: VIEWER_PANEL_ID,
|
||||
@@ -90,10 +93,6 @@ const initializeCenterPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
referencePanel: launchpad.id,
|
||||
},
|
||||
});
|
||||
|
||||
launchpad.api.setActive();
|
||||
|
||||
navigationApi.registerPanel(tab, LAUNCHPAD_PANEL_ID, launchpad);
|
||||
navigationApi.registerPanel(tab, VIEWER_PANEL_ID, viewer);
|
||||
|
||||
return { launchpad, viewer } satisfies Record<string, IDockviewPanel>;
|
||||
@@ -143,6 +142,12 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
focusRegion: 'gallery',
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, GALLERY_PANEL_ID, gallery, {
|
||||
dimensions: {
|
||||
height: GALLERY_PANEL_DEFAULT_HEIGHT_PX,
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
const boards = api.addPanel<PanelParameters>({
|
||||
id: BOARDS_PANEL_ID,
|
||||
@@ -157,13 +162,12 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
referencePanel: gallery.id,
|
||||
},
|
||||
});
|
||||
|
||||
gallery.api.setSize({ height: GALLERY_PANEL_DEFAULT_HEIGHT_PX, width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
boards.api.setSize({ height: BOARD_PANEL_DEFAULT_HEIGHT_PX, width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
|
||||
// Register panels with navigation API
|
||||
navigationApi.registerPanel(tab, GALLERY_PANEL_ID, gallery);
|
||||
navigationApi.registerPanel(tab, BOARDS_PANEL_ID, boards);
|
||||
navigationApi.registerPanel(tab, BOARDS_PANEL_ID, boards, {
|
||||
dimensions: {
|
||||
height: BOARD_PANEL_DEFAULT_HEIGHT_PX,
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
return { gallery, boards } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
@@ -201,8 +205,6 @@ const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
focusRegion: 'settings',
|
||||
},
|
||||
});
|
||||
|
||||
// Register panel with navigation API
|
||||
navigationApi.registerPanel(tab, SETTINGS_PANEL_ID, settings);
|
||||
|
||||
return { settings } satisfies Record<string, IGridviewPanel>;
|
||||
@@ -235,14 +237,15 @@ const rootPanelComponents: RootLayoutGridviewComponents = {
|
||||
[RIGHT_PANEL_ID]: RightPanel,
|
||||
};
|
||||
|
||||
const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
|
||||
const main = layoutApi.addPanel({
|
||||
const initializeRootPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
const main = api.addPanel({
|
||||
id: MAIN_PANEL_ID,
|
||||
component: MAIN_PANEL_ID,
|
||||
priority: LayoutPriority.High,
|
||||
});
|
||||
navigationApi.registerPanel(tab, MAIN_PANEL_ID, main);
|
||||
|
||||
const left = layoutApi.addPanel({
|
||||
const left = api.addPanel({
|
||||
id: LEFT_PANEL_ID,
|
||||
component: LEFT_PANEL_ID,
|
||||
minimumWidth: LEFT_PANEL_MIN_SIZE_PX,
|
||||
@@ -251,8 +254,13 @@ const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
|
||||
referencePanel: main.id,
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, LEFT_PANEL_ID, left, {
|
||||
dimensions: {
|
||||
width: LEFT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
const right = layoutApi.addPanel({
|
||||
const right = api.addPanel({
|
||||
id: RIGHT_PANEL_ID,
|
||||
component: RIGHT_PANEL_ID,
|
||||
minimumWidth: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
@@ -261,20 +269,18 @@ const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
|
||||
referencePanel: main.id,
|
||||
},
|
||||
});
|
||||
|
||||
left.api.setSize({ width: LEFT_PANEL_MIN_SIZE_PX });
|
||||
right.api.setSize({ width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
|
||||
navigationApi.registerPanel('upscaling', LEFT_PANEL_ID, left);
|
||||
navigationApi.registerPanel('upscaling', MAIN_PANEL_ID, main);
|
||||
navigationApi.registerPanel('upscaling', RIGHT_PANEL_ID, right);
|
||||
navigationApi.registerPanel(tab, RIGHT_PANEL_ID, right, {
|
||||
dimensions: {
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
return { main, left, right } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
|
||||
export const UpscalingTabAutoLayout = memo(() => {
|
||||
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
|
||||
initializeRootPanelLayout(api);
|
||||
initializeRootPanelLayout('upscaling', api);
|
||||
}, []);
|
||||
|
||||
useEffect(
|
||||
|
||||
@@ -78,6 +78,9 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
focusRegion: 'launchpad',
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, LAUNCHPAD_PANEL_ID, launchpad, {
|
||||
isActive: true,
|
||||
});
|
||||
|
||||
const workspace = api.addPanel<PanelParameters>({
|
||||
id: WORKSPACE_PANEL_ID,
|
||||
@@ -93,6 +96,7 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
referencePanel: launchpad.id,
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, WORKSPACE_PANEL_ID, workspace);
|
||||
|
||||
const viewer = api.addPanel<PanelParameters>({
|
||||
id: VIEWER_PANEL_ID,
|
||||
@@ -108,11 +112,6 @@ const initializeMainPanelLayout = (tab: TabName, api: DockviewApi) => {
|
||||
referencePanel: launchpad.id,
|
||||
},
|
||||
});
|
||||
|
||||
launchpad.api.setActive();
|
||||
|
||||
navigationApi.registerPanel(tab, LAUNCHPAD_PANEL_ID, launchpad);
|
||||
navigationApi.registerPanel(tab, WORKSPACE_PANEL_ID, workspace);
|
||||
navigationApi.registerPanel(tab, VIEWER_PANEL_ID, viewer);
|
||||
|
||||
return { launchpad, workspace, viewer } satisfies Record<string, IDockviewPanel>;
|
||||
@@ -163,6 +162,12 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
focusRegion: 'gallery',
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, GALLERY_PANEL_ID, gallery, {
|
||||
dimensions: {
|
||||
height: GALLERY_PANEL_DEFAULT_HEIGHT_PX,
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
const boards = api.addPanel<PanelParameters>({
|
||||
id: BOARDS_PANEL_ID,
|
||||
@@ -177,13 +182,12 @@ const initializeRightPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
referencePanel: gallery.id,
|
||||
},
|
||||
});
|
||||
|
||||
gallery.api.setSize({ height: GALLERY_PANEL_DEFAULT_HEIGHT_PX, width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
boards.api.setSize({ height: BOARD_PANEL_DEFAULT_HEIGHT_PX, width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
|
||||
// Register panels with navigation API
|
||||
navigationApi.registerPanel(tab, GALLERY_PANEL_ID, gallery);
|
||||
navigationApi.registerPanel(tab, BOARDS_PANEL_ID, boards);
|
||||
navigationApi.registerPanel(tab, BOARDS_PANEL_ID, boards, {
|
||||
dimensions: {
|
||||
height: BOARD_PANEL_DEFAULT_HEIGHT_PX,
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
return { gallery, boards } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
@@ -221,8 +225,6 @@ const initializeLeftPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
focusRegion: 'settings',
|
||||
},
|
||||
});
|
||||
|
||||
// Register panel with navigation API
|
||||
navigationApi.registerPanel(tab, SETTINGS_PANEL_ID, settings);
|
||||
|
||||
return { settings } satisfies Record<string, IGridviewPanel>;
|
||||
@@ -254,12 +256,14 @@ const rootPanelComponents: RootLayoutGridviewComponents = {
|
||||
[RIGHT_PANEL_ID]: RightPanel,
|
||||
};
|
||||
|
||||
const initializeRootPanelLayout = (api: GridviewApi) => {
|
||||
const initializeRootPanelLayout = (tab: TabName, api: GridviewApi) => {
|
||||
const main = api.addPanel({
|
||||
id: MAIN_PANEL_ID,
|
||||
component: MAIN_PANEL_ID,
|
||||
priority: LayoutPriority.High,
|
||||
});
|
||||
navigationApi.registerPanel(tab, MAIN_PANEL_ID, main);
|
||||
|
||||
const left = api.addPanel({
|
||||
id: LEFT_PANEL_ID,
|
||||
component: LEFT_PANEL_ID,
|
||||
@@ -269,6 +273,12 @@ const initializeRootPanelLayout = (api: GridviewApi) => {
|
||||
referencePanel: MAIN_PANEL_ID,
|
||||
},
|
||||
});
|
||||
navigationApi.registerPanel(tab, LEFT_PANEL_ID, left, {
|
||||
dimensions: {
|
||||
width: LEFT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
const right = api.addPanel({
|
||||
id: RIGHT_PANEL_ID,
|
||||
component: RIGHT_PANEL_ID,
|
||||
@@ -278,20 +288,18 @@ const initializeRootPanelLayout = (api: GridviewApi) => {
|
||||
referencePanel: MAIN_PANEL_ID,
|
||||
},
|
||||
});
|
||||
|
||||
left.api.setSize({ width: LEFT_PANEL_MIN_SIZE_PX });
|
||||
right.api.setSize({ width: RIGHT_PANEL_MIN_SIZE_PX });
|
||||
|
||||
navigationApi.registerPanel('workflows', LEFT_PANEL_ID, left);
|
||||
navigationApi.registerPanel('workflows', MAIN_PANEL_ID, main);
|
||||
navigationApi.registerPanel('workflows', RIGHT_PANEL_ID, right);
|
||||
navigationApi.registerPanel(tab, RIGHT_PANEL_ID, right, {
|
||||
dimensions: {
|
||||
width: RIGHT_PANEL_MIN_SIZE_PX,
|
||||
},
|
||||
});
|
||||
|
||||
return { main, left, right } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
|
||||
export const WorkflowsTabAutoLayout = memo(() => {
|
||||
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
|
||||
initializeRootPanelLayout(api);
|
||||
initializeRootPanelLayout('workflows', api);
|
||||
}, []);
|
||||
|
||||
useEffect(
|
||||
|
||||
@@ -10,11 +10,6 @@ const zPartialDimensions = z.object({
|
||||
height: z.number().optional(),
|
||||
});
|
||||
|
||||
const zDimensions = z.object({
|
||||
width: z.number(),
|
||||
height: z.number(),
|
||||
});
|
||||
|
||||
const zDockviewPanelState = z.object({
|
||||
id: z.string(),
|
||||
type: z.literal('dockview-panel'),
|
||||
@@ -25,7 +20,7 @@ export type StoredDockviewPanelState = z.infer<typeof zDockviewPanelState>;
|
||||
const zGridviewPanelState = z.object({
|
||||
id: z.string(),
|
||||
type: z.literal('gridview-panel'),
|
||||
dimensions: zDimensions,
|
||||
dimensions: zPartialDimensions,
|
||||
});
|
||||
export type StoredGridviewPanelState = z.infer<typeof zGridviewPanelState>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user