From a6ef370aaf985537c13943e7916da69bc9d6620f Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 10 Oct 2024 14:10:17 -0600 Subject: [PATCH] Add serialization stuff --- examples/grid_example/public/app.tsx | 75 +++++++++---------- .../public/serialized_grid_layout.ts | 52 +++++++++++++ packages/kbn-grid-layout/grid/grid_layout.tsx | 49 ++++++------ packages/kbn-grid-layout/grid/types.ts | 2 +- 4 files changed, 115 insertions(+), 63 deletions(-) create mode 100644 examples/grid_example/public/serialized_grid_layout.ts diff --git a/examples/grid_example/public/app.tsx b/examples/grid_example/public/app.tsx index 6f3fedc535b5b..c20856eeec4cf 100644 --- a/examples/grid_example/public/app.tsx +++ b/examples/grid_example/public/app.tsx @@ -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, @@ -25,8 +27,14 @@ 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(uuidv4()); const [gridLayoutApi, setGridLayoutApi] = useState(); return ( @@ -34,8 +42,8 @@ export const GridExample = () => { - - + + { gridLayoutApi?.addNewPanel(`panel${(gridLayoutApi?.getPanelCount() ?? 0) + 1}`); @@ -44,19 +52,36 @@ export const GridExample = () => { Add a panel - - { - console.log(gridLayoutApi?.serializeState()); - }} - > - Serialize state - + + + + { + clearSerializedGridLayout(); + setLayoutKey(uuidv4()); // force remount of grid + }} + > + Reset + + + + { + if (gridLayoutApi) { + setSerializedGridLayout(gridLayoutApi.serializeState()); + } + }} + > + Save + + + { return ( @@ -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, diff --git a/examples/grid_example/public/serialized_grid_layout.ts b/examples/grid_example/public/serialized_grid_layout.ts new file mode 100644 index 0000000000000..2bb20052398f8 --- /dev/null +++ b/examples/grid_example/public/serialized_grid_layout.ts @@ -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' } }, + }, +]; diff --git a/packages/kbn-grid-layout/grid/grid_layout.tsx b/packages/kbn-grid-layout/grid/grid_layout.tsx index afba1bbf30820..11b4382b72076 100644 --- a/packages/kbn-grid-layout/grid/grid_layout.tsx +++ b/packages/kbn-grid-layout/grid/grid_layout.tsx @@ -92,32 +92,33 @@ export const GridLayout = forwardRef( 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, + // })), + // }; }, }; }, diff --git a/packages/kbn-grid-layout/grid/types.ts b/packages/kbn-grid-layout/grid/types.ts index e7bf772c8dfd7..7e6ad686a42ba 100644 --- a/packages/kbn-grid-layout/grid/types.ts +++ b/packages/kbn-grid-layout/grid/types.ts @@ -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 {