2025-04-01 10:38:02 +09:00

76 lines
2.8 KiB
TypeScript

import { SceneCSSGridLayout } from '@grafana/scenes';
import { DashboardV2Spec, ResponsiveGridLayoutItemKind } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0';
import { ResponsiveGridItem } from '../../scene/layout-responsive-grid/ResponsiveGridItem';
import { ResponsiveGridLayoutManager } from '../../scene/layout-responsive-grid/ResponsiveGridLayoutManager';
import { DashboardLayoutManager, LayoutManagerSerializer } from '../../scene/types/DashboardLayoutManager';
import { getGridItemKeyForPanelId } from '../../utils/utils';
import { buildVizPanel } from './utils';
export class ResponsiveGridLayoutSerializer implements LayoutManagerSerializer {
serialize(layoutManager: ResponsiveGridLayoutManager): DashboardV2Spec['layout'] {
return {
kind: 'ResponsiveGridLayout',
spec: {
col:
layoutManager.state.layout.state.templateColumns?.toString() ??
ResponsiveGridLayoutManager.defaultCSS.templateColumns,
row: layoutManager.state.layout.state.autoRows?.toString() ?? ResponsiveGridLayoutManager.defaultCSS.autoRows,
items: layoutManager.state.layout.state.children.map((child) => {
if (!(child instanceof ResponsiveGridItem)) {
throw new Error('Expected ResponsiveGridItem');
}
const layoutItem: ResponsiveGridLayoutItemKind = {
kind: 'ResponsiveGridLayoutItem',
spec: {
element: {
kind: 'ElementReference',
name: child.state?.body?.state.key ?? 'DefaultName',
},
},
};
if (child.state.variableName) {
layoutItem.spec.repeat = {
mode: 'variable',
value: child.state.variableName,
};
}
return layoutItem;
}),
},
};
}
deserialize(layout: DashboardV2Spec['layout'], elements: DashboardV2Spec['elements']): DashboardLayoutManager {
if (layout.kind !== 'ResponsiveGridLayout') {
throw new Error('Invalid layout kind');
}
const children = layout.spec.items.map((item) => {
const panel = elements[item.spec.element.name];
if (!panel) {
throw new Error(`Panel with uid ${item.spec.element.name} not found in the dashboard elements`);
}
if (panel.kind !== 'Panel') {
throw new Error(`Unsupported element kind: ${panel.kind}`);
}
return new ResponsiveGridItem({
key: getGridItemKeyForPanelId(panel.spec.id),
body: buildVizPanel(panel),
variableName: item.spec.repeat?.value,
});
});
return new ResponsiveGridLayoutManager({
layout: new SceneCSSGridLayout({
templateColumns: layout.spec.col,
autoRows: layout.spec.row,
children,
}),
});
}
}