291 lines
8.7 KiB
TypeScript
291 lines
8.7 KiB
TypeScript
import { SceneCSSGridLayout, SceneGridLayout } from '@grafana/scenes';
|
|
import { DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0';
|
|
|
|
import { DefaultGridLayoutManager } from '../../scene/layout-default/DefaultGridLayoutManager';
|
|
import { ResponsiveGridLayoutManager } from '../../scene/layout-responsive-grid/ResponsiveGridLayoutManager';
|
|
import { RowItem } from '../../scene/layout-rows/RowItem';
|
|
import { RowItemRepeaterBehavior } from '../../scene/layout-rows/RowItemRepeaterBehavior';
|
|
import { RowsLayoutManager } from '../../scene/layout-rows/RowsLayoutManager';
|
|
|
|
import { RowsLayoutSerializer } from './RowsLayoutSerializer';
|
|
|
|
describe('deserialization', () => {
|
|
it('should deserialize rows layout with default grid child', () => {
|
|
const layout: DashboardV2Spec['layout'] = {
|
|
kind: 'RowsLayout',
|
|
spec: {
|
|
rows: [
|
|
{
|
|
kind: 'RowsLayoutRow',
|
|
spec: {
|
|
title: 'Row 1',
|
|
collapsed: false,
|
|
layout: { kind: 'GridLayout', spec: { items: [] } },
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const serializer = new RowsLayoutSerializer();
|
|
const deserialized = serializer.deserialize(layout, {}, false);
|
|
expect(deserialized).toBeInstanceOf(RowsLayoutManager);
|
|
expect(deserialized.state.rows[0].state.layout).toBeInstanceOf(DefaultGridLayoutManager);
|
|
});
|
|
|
|
it('should deserialize rows layout with responsive grid child', () => {
|
|
const layout: DashboardV2Spec['layout'] = {
|
|
kind: 'RowsLayout',
|
|
spec: {
|
|
rows: [
|
|
{
|
|
kind: 'RowsLayoutRow',
|
|
spec: {
|
|
title: 'Row 1',
|
|
collapsed: false,
|
|
layout: {
|
|
kind: 'ResponsiveGridLayout',
|
|
spec: {
|
|
row: 'minmax(min-content, max-content)',
|
|
col: 'repeat(auto-fit, minmax(400px, 1fr))',
|
|
items: [],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const serializer = new RowsLayoutSerializer();
|
|
const deserialized = serializer.deserialize(layout, {}, false);
|
|
expect(deserialized).toBeInstanceOf(RowsLayoutManager);
|
|
expect(deserialized.state.rows[0].state.layout).toBeInstanceOf(ResponsiveGridLayoutManager);
|
|
});
|
|
|
|
it('should handle multiple rows with different layouts', () => {
|
|
const layout: DashboardV2Spec['layout'] = {
|
|
kind: 'RowsLayout',
|
|
spec: {
|
|
rows: [
|
|
{
|
|
kind: 'RowsLayoutRow',
|
|
spec: {
|
|
title: 'Row 1',
|
|
collapsed: false,
|
|
layout: {
|
|
kind: 'ResponsiveGridLayout',
|
|
spec: {
|
|
row: 'minmax(min-content, max-content)',
|
|
col: 'repeat(auto-fit, minmax(400px, 1fr))',
|
|
items: [],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
kind: 'RowsLayoutRow',
|
|
spec: {
|
|
title: 'Row 2',
|
|
collapsed: true,
|
|
layout: { kind: 'GridLayout', spec: { items: [] } },
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const serializer = new RowsLayoutSerializer();
|
|
const deserialized = serializer.deserialize(layout, {}, false);
|
|
expect(deserialized).toBeInstanceOf(RowsLayoutManager);
|
|
expect(deserialized.state.rows).toHaveLength(2);
|
|
expect(deserialized.state.rows[0].state.layout).toBeInstanceOf(ResponsiveGridLayoutManager);
|
|
expect(deserialized.state.rows[1].state.layout).toBeInstanceOf(DefaultGridLayoutManager);
|
|
expect(deserialized.state.rows[0].state.isCollapsed).toBe(false);
|
|
expect(deserialized.state.rows[1].state.isCollapsed).toBe(true);
|
|
});
|
|
|
|
it('should handle 0 rows', () => {
|
|
const layout: DashboardV2Spec['layout'] = {
|
|
kind: 'RowsLayout',
|
|
spec: {
|
|
rows: [],
|
|
},
|
|
};
|
|
const serializer = new RowsLayoutSerializer();
|
|
const deserialized = serializer.deserialize(layout, {}, false);
|
|
expect(deserialized).toBeInstanceOf(RowsLayoutManager);
|
|
expect(deserialized.state.rows).toHaveLength(0);
|
|
});
|
|
|
|
it('should deserialize row with repeat behavior', () => {
|
|
const layout: DashboardV2Spec['layout'] = {
|
|
kind: 'RowsLayout',
|
|
spec: {
|
|
rows: [
|
|
{
|
|
kind: 'RowsLayoutRow',
|
|
spec: {
|
|
title: 'Repeated Row',
|
|
collapsed: false,
|
|
layout: { kind: 'GridLayout', spec: { items: [] } },
|
|
repeat: { value: 'foo', mode: 'variable' },
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const serializer = new RowsLayoutSerializer();
|
|
const deserialized = serializer.deserialize(layout, {}, false);
|
|
|
|
expect(deserialized).toBeInstanceOf(RowsLayoutManager);
|
|
expect(deserialized.state.rows).toHaveLength(1);
|
|
|
|
const row = deserialized.state.rows[0];
|
|
expect(row.state.$behaviors).toBeDefined();
|
|
const behaviors = row.state.$behaviors ?? [];
|
|
expect(behaviors).toHaveLength(1);
|
|
const repeaterBehavior = behaviors[0] as RowItemRepeaterBehavior;
|
|
expect(repeaterBehavior).toBeInstanceOf(RowItemRepeaterBehavior);
|
|
expect(repeaterBehavior.state.variableName).toBe('foo');
|
|
});
|
|
});
|
|
|
|
describe('serialization', () => {
|
|
it('should serialize basic row layout', () => {
|
|
const rowsLayout = new RowsLayoutManager({
|
|
rows: [
|
|
new RowItem({
|
|
title: 'Row 1',
|
|
isCollapsed: false,
|
|
layout: new DefaultGridLayoutManager({
|
|
grid: new SceneGridLayout({
|
|
children: [],
|
|
isDraggable: true,
|
|
isResizable: true,
|
|
}),
|
|
}),
|
|
}),
|
|
],
|
|
});
|
|
|
|
const serializer = new RowsLayoutSerializer();
|
|
const serialized = serializer.serialize(rowsLayout);
|
|
|
|
expect(serialized).toEqual({
|
|
kind: 'RowsLayout',
|
|
spec: {
|
|
rows: [
|
|
{
|
|
kind: 'RowsLayoutRow',
|
|
spec: {
|
|
title: 'Row 1',
|
|
collapsed: false,
|
|
layout: { kind: 'GridLayout', spec: { items: [] } },
|
|
},
|
|
},
|
|
],
|
|
},
|
|
});
|
|
});
|
|
|
|
it('should serialize row with repeat behavior', () => {
|
|
const rowsLayout = new RowsLayoutManager({
|
|
rows: [
|
|
new RowItem({
|
|
title: 'Repeated Row',
|
|
isCollapsed: false,
|
|
layout: new DefaultGridLayoutManager({
|
|
grid: new SceneGridLayout({
|
|
children: [],
|
|
isDraggable: true,
|
|
isResizable: true,
|
|
}),
|
|
}),
|
|
$behaviors: [new RowItemRepeaterBehavior({ variableName: 'foo' })],
|
|
}),
|
|
],
|
|
});
|
|
|
|
const serializer = new RowsLayoutSerializer();
|
|
const serialized = serializer.serialize(rowsLayout);
|
|
|
|
expect(serialized).toEqual({
|
|
kind: 'RowsLayout',
|
|
spec: {
|
|
rows: [
|
|
{
|
|
kind: 'RowsLayoutRow',
|
|
spec: {
|
|
title: 'Repeated Row',
|
|
collapsed: false,
|
|
layout: { kind: 'GridLayout', spec: { items: [] } },
|
|
repeat: { value: 'foo', mode: 'variable' },
|
|
},
|
|
},
|
|
],
|
|
},
|
|
});
|
|
});
|
|
|
|
it('should serialize multiple rows with different layouts', () => {
|
|
const rowsLayout = new RowsLayoutManager({
|
|
rows: [
|
|
new RowItem({
|
|
title: 'Row 1',
|
|
isCollapsed: false,
|
|
layout: new ResponsiveGridLayoutManager({
|
|
layout: new SceneCSSGridLayout({
|
|
children: [],
|
|
templateColumns: 'repeat(auto-fit, minmax(400px, 1fr))',
|
|
autoRows: 'minmax(min-content, max-content)',
|
|
}),
|
|
}),
|
|
}),
|
|
new RowItem({
|
|
title: 'Row 2',
|
|
isCollapsed: true,
|
|
layout: new DefaultGridLayoutManager({
|
|
grid: new SceneGridLayout({
|
|
children: [],
|
|
isDraggable: true,
|
|
isResizable: true,
|
|
}),
|
|
}),
|
|
}),
|
|
],
|
|
});
|
|
|
|
const serializer = new RowsLayoutSerializer();
|
|
const serialized = serializer.serialize(rowsLayout);
|
|
|
|
expect(serialized).toEqual({
|
|
kind: 'RowsLayout',
|
|
spec: {
|
|
rows: [
|
|
{
|
|
kind: 'RowsLayoutRow',
|
|
spec: {
|
|
title: 'Row 1',
|
|
collapsed: false,
|
|
layout: {
|
|
kind: 'ResponsiveGridLayout',
|
|
spec: {
|
|
row: 'minmax(min-content, max-content)',
|
|
col: 'repeat(auto-fit, minmax(400px, 1fr))',
|
|
items: [],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
kind: 'RowsLayoutRow',
|
|
spec: {
|
|
title: 'Row 2',
|
|
collapsed: true,
|
|
layout: { kind: 'GridLayout', spec: { items: [] } },
|
|
},
|
|
},
|
|
],
|
|
},
|
|
});
|
|
});
|
|
});
|