Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions src/features/editor/components/editor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ vi.mock('@/shared/state/editor-panel-layout-store', () => ({
tools: 25,
preview: 50,
properties: 25,
mainContent: 50,
timeline: 50,
mainContent: 72,
timeline: 28,
},
setPanel: vi.fn(),
}),
Expand Down Expand Up @@ -259,12 +259,6 @@ vi.mock('@/shared/ui/editor-layout', async (importOriginal) => {
const actual = await importOriginal<typeof import('@/shared/ui/editor-layout')>();
return {
...actual,
getEditorLayout: () => ({
...actual.getEditorLayout(),
timelineDefaultSize: 35,
timelineMinSize: 20,
timelineMaxSize: 60,
}),
getEditorLayoutCssVars: () => ({}),
};
});
Expand Down
48 changes: 48 additions & 0 deletions src/shared/state/editor-panel-layout-store.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { describe, expect, it } from 'vitest';
import { migrateEditorPanelLayout } from './editor-panel-layout-store';
import { EDITOR_LAYOUT } from '@/shared/ui/editor-layout';

const v1DefaultState = {
panels: {
tools: 25,
preview: 50,
properties: 25,
mainContent: 50,
timeline: 50,
},
};

describe('migrateEditorPanelLayout', () => {
it('moves an untouched v1 default split to the EDITOR_LAYOUT default', () => {
const migrated = migrateEditorPanelLayout(v1DefaultState, 1);

expect(migrated.panels?.timeline).toBe(EDITOR_LAYOUT.timelineDefaultSize);
expect(migrated.panels?.mainContent).toBe(100 - EDITOR_LAYOUT.timelineDefaultSize);
});

it('keeps main/timeline summing to 100 after migration', () => {
const migrated = migrateEditorPanelLayout(v1DefaultState, 1);

expect((migrated.panels?.mainContent ?? 0) + (migrated.panels?.timeline ?? 0)).toBe(100);
});

it('preserves the untouched sidebar panel sizes', () => {
const migrated = migrateEditorPanelLayout(v1DefaultState, 1);

expect(migrated.panels?.tools).toBe(25);
expect(migrated.panels?.preview).toBe(50);
expect(migrated.panels?.properties).toBe(25);
});

it('leaves a user-resized v1 layout alone', () => {
const resized = {
panels: { ...v1DefaultState.panels, mainContent: 40, timeline: 60 },
};

expect(migrateEditorPanelLayout(resized, 1)).toEqual(resized);
});

it('passes current-version state through untouched', () => {
expect(migrateEditorPanelLayout(v1DefaultState, 2)).toEqual(v1DefaultState);
});
});
43 changes: 40 additions & 3 deletions src/shared/state/editor-panel-layout-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import { EDITOR_LAYOUT } from '@/shared/ui/editor-layout';

export interface EditorPanelSizes {
tools: number;
Expand All @@ -19,10 +20,45 @@ const DEFAULT_PANELS: EditorPanelSizes = {
tools: 25,
preview: 50,
properties: 25,
mainContent: 50,
timeline: 50,
mainContent: 100 - EDITOR_LAYOUT.timelineDefaultSize,
timeline: EDITOR_LAYOUT.timelineDefaultSize,
};

/** The main/timeline split that version 1 of this store shipped with. */
const V1_DEFAULT_SPLIT = { mainContent: 50, timeline: 50 };

interface PersistedPanelLayout {
panels?: EditorPanelSizes;
}

/**
* Version 1 shipped a 50/50 main/timeline split. Layouts still sitting on
* that untouched default follow the new default from EDITOR_LAYOUT; anything
* the user resized themselves is left alone.
*/
export function migrateEditorPanelLayout(
persistedState: unknown,
version: number
): PersistedPanelLayout {
const state = persistedState as PersistedPanelLayout;
if (version >= 2) return state;
if (
state?.panels &&
state.panels.mainContent === V1_DEFAULT_SPLIT.mainContent &&
state.panels.timeline === V1_DEFAULT_SPLIT.timeline
) {
return {
...state,
panels: {
...state.panels,
mainContent: DEFAULT_PANELS.mainContent,
timeline: DEFAULT_PANELS.timeline,
},
};
}
return state;
}

interface EditorPanelLayoutState {
panels: EditorPanelSizes;
setPanel: (panel: EditorPanelId, size: number) => void;
Expand All @@ -44,8 +80,9 @@ export const useEditorPanelLayoutStore = create<EditorPanelLayoutState>()(
}),
{
name: 'kubeez-editor-panel-sizes',
version: 1,
version: 2,
partialize: (state) => ({ panels: state.panels }),
migrate: migrateEditorPanelLayout,
}
)
);
Loading