Skip to content

Commit

Permalink
Add serialization stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Heenawter committed Oct 28, 2024
1 parent 62d63ac commit a6ef370
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 63 deletions.
75 changes: 37 additions & 38 deletions examples/grid_example/public/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import { GridLayout, type GridLayoutData, type GridLayoutApi } from '@kbn/grid-layout';
import { v4 as uuidv4 } from 'uuid';

import { GridLayout, type GridLayoutApi } from '@kbn/grid-layout';
import { AppMountParameters } from '@kbn/core-application-browser';
import {
EuiButton,
Expand All @@ -25,17 +27,23 @@ import {
DASHBOARD_GRID_HEIGHT,
DASHBOARD_MARGIN_SIZE,
} from '@kbn/grid-layout/grid/constants';
import {
clearSerializedGridLayout,
getSerializedGridLayout,
setSerializedGridLayout,
} from './serialized_grid_layout';

export const GridExample = () => {
const [layoutKey, setLayoutKey] = useState<string>(uuidv4());
const [gridLayoutApi, setGridLayoutApi] = useState<GridLayoutApi | null>();

return (
<EuiProvider>
<EuiPageTemplate grow={false} offset={0} restrictWidth={false}>
<EuiPageTemplate.Header iconType={'dashboardApp'} pageTitle="Grid Layout Example" />
<EuiPageTemplate.Section color="subdued">
<EuiFlexGroup>
<EuiFlexItem>
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiButton
onClick={() => {
gridLayoutApi?.addNewPanel(`panel${(gridLayoutApi?.getPanelCount() ?? 0) + 1}`);
Expand All @@ -44,19 +52,36 @@ export const GridExample = () => {
Add a panel
</EuiButton>
</EuiFlexItem>
<EuiFlexItem>
<EuiButton
onClick={() => {
console.log(gridLayoutApi?.serializeState());
}}
>
Serialize state
</EuiButton>
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="xs">
<EuiFlexItem grow={false}>
<EuiButtonEmpty
onClick={() => {
clearSerializedGridLayout();
setLayoutKey(uuidv4()); // force remount of grid
}}
>
Reset
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
onClick={() => {
if (gridLayoutApi) {
setSerializedGridLayout(gridLayoutApi.serializeState());
}
}}
>
Save
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<GridLayout
// onLayoutChange
key={layoutKey}
ref={setGridLayoutApi}
renderPanelContents={(id) => {
return (
Expand All @@ -73,33 +98,7 @@ export const GridExample = () => {
);
}}
getCreationOptions={() => {
const initialLayout: GridLayoutData = [
{
title: 'Large section',
isCollapsed: false,
panels: {
panel1: { column: 0, row: 0, width: 12, height: 6, id: 'panel1' },
panel2: { column: 0, row: 6, width: 8, height: 4, id: 'panel2' },
panel3: { column: 8, row: 6, width: 12, height: 4, id: 'panel3' },
panel4: { column: 0, row: 10, width: 48, height: 4, id: 'panel4' },
panel5: { column: 12, row: 0, width: 36, height: 6, id: 'panel5' },
panel6: { column: 24, row: 6, width: 24, height: 4, id: 'panel6' },
panel7: { column: 20, row: 6, width: 4, height: 2, id: 'panel7' },
panel8: { column: 20, row: 8, width: 4, height: 2, id: 'panel8' },
},
},
{
title: 'Small section',
isCollapsed: false,
panels: { panel9: { column: 0, row: 0, width: 12, height: 16, id: 'panel9' } },
},
{
title: 'Another small section',
isCollapsed: false,
panels: { panel10: { column: 24, row: 0, width: 12, height: 6, id: 'panel10' } },
},
];

const initialLayout = getSerializedGridLayout();
return {
gridSettings: {
gutterSize: DASHBOARD_MARGIN_SIZE,
Expand Down
52 changes: 52 additions & 0 deletions examples/grid_example/public/serialized_grid_layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { type GridLayoutData } from '@kbn/grid-layout';

const STATE_SESSION_STORAGE_KEY = 'kibana.examples.gridExample.state';

export function clearSerializedGridLayout() {
sessionStorage.removeItem(STATE_SESSION_STORAGE_KEY);
}

export function getSerializedGridLayout(): GridLayoutData {
const serializedStateJSON = sessionStorage.getItem(STATE_SESSION_STORAGE_KEY);
return serializedStateJSON ? JSON.parse(serializedStateJSON) : initialGridLayout;
}

export function setSerializedGridLayout(layout: GridLayoutData) {
sessionStorage.setItem(STATE_SESSION_STORAGE_KEY, JSON.stringify(layout));
}

const initialGridLayout: GridLayoutData = [
{
title: 'Large section',
isCollapsed: false,
panels: {
panel1: { column: 0, row: 0, width: 12, height: 6, id: 'panel1' },
panel2: { column: 0, row: 6, width: 8, height: 4, id: 'panel2' },
panel3: { column: 8, row: 6, width: 12, height: 4, id: 'panel3' },
panel4: { column: 0, row: 10, width: 48, height: 4, id: 'panel4' },
panel5: { column: 12, row: 0, width: 36, height: 6, id: 'panel5' },
panel6: { column: 24, row: 6, width: 24, height: 4, id: 'panel6' },
panel7: { column: 20, row: 6, width: 4, height: 2, id: 'panel7' },
panel8: { column: 20, row: 8, width: 4, height: 2, id: 'panel8' },
},
},
{
title: 'Small section',
isCollapsed: false,
panels: { panel9: { column: 0, row: 0, width: 12, height: 16, id: 'panel9' } },
},
{
title: 'Another small section',
isCollapsed: false,
panels: { panel10: { column: 24, row: 0, width: 12, height: 6, id: 'panel10' } },
},
];
49 changes: 25 additions & 24 deletions packages/kbn-grid-layout/grid/grid_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,32 +92,33 @@ export const GridLayout = forwardRef<GridLayoutApi, GridLayoutProps>(

serializeState: () => {
const currentLayout = gridLayoutStateManager.gridLayout$.getValue();
return currentLayout;

const serializePanelRows = (row: GridRowData, rowIndex: number) => {
const panels = row.panels;
const gridData: { [key: string]: any } = {};
Object.keys(panels).forEach((key) => {
const panel = panels[key];
gridData[key] = {
row: rowIndex,
i: key,
x: panel.column,
y: panel.row,
w: panel.width,
h: panel.height,
};
});
return gridData;
};
// const serializePanelRows = (row: GridRowData, rowIndex: number) => {
// const panels = row.panels;
// const gridData: { [key: string]: any } = {};
// Object.keys(panels).forEach((key) => {
// const panel = panels[key];
// gridData[key] = {
// row: rowIndex,
// i: key,
// x: panel.column,
// y: panel.row,
// w: panel.width,
// h: panel.height,
// };
// });
// return gridData;
// };

return {
panels: currentLayout.map(serializePanelRows),
rows: currentLayout.map((row, index) => ({
i: index,
title: row.title,
isCollapsed: row.isCollapsed,
})),
};
// return {
// panels: currentLayout.map(serializePanelRows),
// rows: currentLayout.map((row, index) => ({
// i: index,
// title: row.title,
// isCollapsed: row.isCollapsed,
// })),
// };
},
};
},
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-grid-layout/grid/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface GridLayoutApi {
addNewPanel: (id: string, placementStrategy?: PanelPlacementStrategy) => void;
getPanelCount: () => number;
removePanel: (panelId: string) => void;
serializeState: () => void;
serializeState: () => GridLayoutData;
}

export interface GridCoordinate {
Expand Down

0 comments on commit a6ef370

Please sign in to comment.