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:
psychedelicious
2025-07-09 12:38:03 +10:00
parent a48958e0d4
commit bb50f4b8a2
6 changed files with 204 additions and 148 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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