Skip to content

Commit

Permalink
[8.x] [kbn-grid-layout] Store rows in object instead of array (#212965)…
Browse files Browse the repository at this point in the history
… (#213162)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[kbn-grid-layout] Store rows in object instead of array
(#212965)](#212965)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Hannah
Mudge","email":"Heenawter@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-03-04T20:34:39Z","message":"[kbn-grid-layout]
Store rows in object instead of array (#212965)\n\nCloses
https://github.com/elastic/kibana/issues/211930\n\n## Summary\n\nThis PR
makes it so that `kbn-grid-layout` stores its rows as an object\n/
dictionary (`{ [key: string]: GridRowData }`) rather than an
array\n(`Array<GridRowData>`). This is a prerequisite
for\nhttps://github.com//issues/190381 , since it allows
us to\nre-order rows without re-rendering their contents. It also means
that\ndeleting a row will no longer cause the rows below it to
re-render,\nsince re-rendering is now dependant on the row's **ID**
rather than the\nrow's
order.\n\n**Before**\n\n\nhttps://github.com/user-attachments/assets/83651b24-a32c-4953-8ad5-c0eced163eb5\n\n\n**After**\n\n\nhttps://github.com/user-attachments/assets/9cef6dbc-3d62-46aa-bc40-ab24fc4e5556\n\n\n###
Checklist\n\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [x] The PR
description includes the appropriate Release Notes section,\nand the
correct `release_note:*` label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"b32f0fe1e863a599c9d61a38e99c974deec6519a","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Presentation","loe:small","release_note:skip","impact:high","Project:Collapsable
Panels","backport:version","v9.1.0","v8.19.0"],"title":"[kbn-grid-layout]
Store rows in object instead of
array","number":212965,"url":"https://github.com/elastic/kibana/pull/212965","mergeCommit":{"message":"[kbn-grid-layout]
Store rows in object instead of array (#212965)\n\nCloses
https://github.com/elastic/kibana/issues/211930\n\n## Summary\n\nThis PR
makes it so that `kbn-grid-layout` stores its rows as an object\n/
dictionary (`{ [key: string]: GridRowData }`) rather than an
array\n(`Array<GridRowData>`). This is a prerequisite
for\nhttps://github.com//issues/190381 , since it allows
us to\nre-order rows without re-rendering their contents. It also means
that\ndeleting a row will no longer cause the rows below it to
re-render,\nsince re-rendering is now dependant on the row's **ID**
rather than the\nrow's
order.\n\n**Before**\n\n\nhttps://github.com/user-attachments/assets/83651b24-a32c-4953-8ad5-c0eced163eb5\n\n\n**After**\n\n\nhttps://github.com/user-attachments/assets/9cef6dbc-3d62-46aa-bc40-ab24fc4e5556\n\n\n###
Checklist\n\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [x] The PR
description includes the appropriate Release Notes section,\nand the
correct `release_note:*` label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"b32f0fe1e863a599c9d61a38e99c974deec6519a"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/212965","number":212965,"mergeCommit":{"message":"[kbn-grid-layout]
Store rows in object instead of array (#212965)\n\nCloses
https://github.com/elastic/kibana/issues/211930\n\n## Summary\n\nThis PR
makes it so that `kbn-grid-layout` stores its rows as an object\n/
dictionary (`{ [key: string]: GridRowData }`) rather than an
array\n(`Array<GridRowData>`). This is a prerequisite
for\nhttps://github.com//issues/190381 , since it allows
us to\nre-order rows without re-rendering their contents. It also means
that\ndeleting a row will no longer cause the rows below it to
re-render,\nsince re-rendering is now dependant on the row's **ID**
rather than the\nrow's
order.\n\n**Before**\n\n\nhttps://github.com/user-attachments/assets/83651b24-a32c-4953-8ad5-c0eced163eb5\n\n\n**After**\n\n\nhttps://github.com/user-attachments/assets/9cef6dbc-3d62-46aa-bc40-ab24fc4e5556\n\n\n###
Checklist\n\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [x] The PR
description includes the appropriate Release Notes section,\nand the
correct `release_note:*` label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"b32f0fe1e863a599c9d61a38e99c974deec6519a"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Hannah Mudge <Heenawter@users.noreply.github.com>
  • Loading branch information
kibanamachine and Heenawter authored Mar 4, 2025
1 parent 03d92f8 commit 4850d36
Show file tree
Hide file tree
Showing 29 changed files with 325 additions and 286 deletions.
26 changes: 15 additions & 11 deletions examples/grid_example/public/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
*/

import deepEqual from 'fast-deep-equal';
import { cloneDeep } from 'lodash';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import ReactDOM from 'react-dom';
import { Subject, combineLatest, debounceTime, map, skip, take } from 'rxjs';
import { v4 as uuidv4 } from 'uuid';

import {
EuiBadge,
Expand Down Expand Up @@ -88,8 +90,8 @@ export const GridExample = ({
const currentPanel = panels[panelId];
const savedPanel = savedState.current.panels[panelId];
panelsAreEqual = deepEqual(
{ row: 0, ...currentPanel.gridData },
{ row: 0, ...savedPanel.gridData }
{ row: 'first', ...currentPanel.gridData },
{ row: 'first', ...savedPanel.gridData }
);
}
const hasChanges = !(panelsAreEqual && deepEqual(rows, savedState.current.rows));
Expand Down Expand Up @@ -147,15 +149,17 @@ export const GridExample = ({
);

const addNewSection = useCallback(() => {
mockDashboardApi.rows$.next([
...mockDashboardApi.rows$.getValue(),
{
title: i18n.translate('examples.gridExample.defaultSectionTitle', {
defaultMessage: 'New collapsible section',
}),
collapsed: false,
},
]);
const rows = cloneDeep(mockDashboardApi.rows$.getValue());
const id = uuidv4();
rows[id] = {
id,
order: Object.keys(rows).length,
title: i18n.translate('examples.gridExample.defaultSectionTitle', {
defaultMessage: 'New collapsible section',
}),
collapsed: false,
};
mockDashboardApi.rows$.next(rows);

// scroll to bottom after row is added
layoutUpdated$.pipe(skip(1), take(1)).subscribe(() => {
Expand Down
58 changes: 29 additions & 29 deletions examples/grid_example/public/logs_dashboard_panels.json
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@
"w": 48,
"h": 17,
"i": "4",
"row": 1
"row": "second"
},
"explicitInput": {
"id": "4",
Expand Down Expand Up @@ -1035,7 +1035,7 @@
"w": 18,
"h": 8,
"i": "05da0d2b-0145-4068-b21c-00be3184d465",
"row": 1
"row": "second"
},
"explicitInput": {
"id": "05da0d2b-0145-4068-b21c-00be3184d465",
Expand Down Expand Up @@ -1073,7 +1073,7 @@
"w": 18,
"h": 16,
"i": "b7da9075-4742-47e3-b4f8-fc9ba82de74c",
"row": 1
"row": "second"
},
"explicitInput": {
"id": "b7da9075-4742-47e3-b4f8-fc9ba82de74c",
Expand Down Expand Up @@ -1111,7 +1111,7 @@
"w": 12,
"h": 16,
"i": "5c409557-644d-4c05-a284-ffe54bb28db0",
"row": 1
"row": "second"
},
"explicitInput": {
"id": "5c409557-644d-4c05-a284-ffe54bb28db0",
Expand Down Expand Up @@ -1234,7 +1234,7 @@
"w": 6,
"h": 8,
"i": "af4b5c07-506e-44c2-b2bb-2113d0c5b274",
"row": 1
"row": "second"
},
"explicitInput": {
"id": "af4b5c07-506e-44c2-b2bb-2113d0c5b274",
Expand Down Expand Up @@ -1400,7 +1400,7 @@
"w": 6,
"h": 8,
"i": "d42c4870-c028-4d8a-abd0-0effbc190ce3",
"row": 1
"row": "second"
},
"explicitInput": {
"id": "d42c4870-c028-4d8a-abd0-0effbc190ce3",
Expand Down Expand Up @@ -1520,7 +1520,7 @@
"w": 6,
"h": 8,
"i": "4092d42c-f93b-4c71-a6db-8f12abf12791",
"row": 1
"row": "second"
},
"explicitInput": {
"id": "4092d42c-f93b-4c71-a6db-8f12abf12791",
Expand Down Expand Up @@ -1641,7 +1641,7 @@
"w": 30,
"h": 15,
"i": "15",
"row": 2
"row": "third"
},
"explicitInput": {
"id": "15",
Expand Down Expand Up @@ -1887,7 +1887,7 @@
"w": 18,
"h": 8,
"i": "4e64d6d7-4f92-4d5e-abbb-13796604db30",
"row": 2
"row": "third"
},
"explicitInput": {
"id": "4e64d6d7-4f92-4d5e-abbb-13796604db30v",
Expand Down Expand Up @@ -1925,7 +1925,7 @@
"w": 6,
"h": 7,
"i": "ddce4ad8-6a82-44f0-9995-57f46f153f50",
"row": 2
"row": "third"
},
"explicitInput": {
"id": "ddce4ad8-6a82-44f0-9995-57f46f153f50",
Expand Down Expand Up @@ -2120,7 +2120,7 @@
"w": 6,
"h": 7,
"i": "a2884704-db3b-4b92-a19a-cdfe668dec39",
"row": 2
"row": "third"
},
"explicitInput": {
"id": "a2884704-db3b-4b92-a19a-cdfe668dec39",
Expand Down Expand Up @@ -2315,7 +2315,7 @@
"w": 6,
"h": 7,
"i": "529eec49-10e2-4a40-9c77-5c81f4eb3943",
"row": 2
"row": "third"
},
"explicitInput": {
"id": "529eec49-10e2-4a40-9c77-5c81f4eb3943",
Expand Down Expand Up @@ -2510,7 +2510,7 @@
"w": 48,
"h": 12,
"i": "1d5f0b3f-d9d2-4b26-997b-83bc5ca3090b",
"row": 2
"row": "third"
},
"explicitInput": {
"id": "1d5f0b3f-d9d2-4b26-997b-83bc5ca3090b",
Expand Down Expand Up @@ -2905,7 +2905,7 @@
"w": 48,
"h": 15,
"i": "9f79ecca-123f-4098-a658-6b0e998da003",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "9f79ecca-123f-4098-a658-6b0e998da003",
Expand All @@ -2922,7 +2922,7 @@
"w": 24,
"h": 9,
"i": "7",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "7",
Expand Down Expand Up @@ -3161,7 +3161,7 @@
"w": 24,
"h": 11,
"i": "10",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "10",
Expand Down Expand Up @@ -3346,7 +3346,7 @@
"w": 24,
"h": 22,
"i": "23",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "23",
Expand All @@ -3371,7 +3371,7 @@
"w": 24,
"h": 22,
"i": "31",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "31",
Expand All @@ -3388,7 +3388,7 @@
"w": 24,
"h": 8,
"i": "6afc61f7-e2d5-45a3-9e7a-281160ad3eb9",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "6afc61f7-e2d5-45a3-9e7a-281160ad3eb9",
Expand Down Expand Up @@ -3420,7 +3420,7 @@
"w": 8,
"h": 8,
"i": "392b4936-f753-47bc-a98d-a4e41a0a4cd4",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "392b4936-f753-47bc-a98d-a4e41a0a4cd4",
Expand Down Expand Up @@ -3485,7 +3485,7 @@
"w": 8,
"h": 4,
"i": "9271deff-5a61-4665-83fc-f9fdc6bf0c0b",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "9271deff-5a61-4665-83fc-f9fdc6bf0c0b",
Expand Down Expand Up @@ -3613,7 +3613,7 @@
"w": 8,
"h": 4,
"i": "aa591c29-1a31-4ee1-a71d-b829c06fd162",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "aa591c29-1a31-4ee1-a71d-b829c06fd162",
Expand Down Expand Up @@ -3777,7 +3777,7 @@
"w": 8,
"h": 4,
"i": "b766e3b8-4544-46ed-99e6-9ecc4847e2a2",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "b766e3b8-4544-46ed-99e6-9ecc4847e2a2",
Expand Down Expand Up @@ -3905,7 +3905,7 @@
"w": 8,
"h": 4,
"i": "2e33ade5-96e5-40b4-b460-493e5d4fa834",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "2e33ade5-96e5-40b4-b460-493e5d4fa834",
Expand Down Expand Up @@ -4069,7 +4069,7 @@
"w": 24,
"h": 8,
"i": "086ac2e9-dd16-4b45-92b8-1e43ff7e3f65",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "086ac2e9-dd16-4b45-92b8-1e43ff7e3f65",
Expand Down Expand Up @@ -4190,7 +4190,7 @@
"w": 24,
"h": 28,
"i": "fb86b32f-fb7a-45cf-9511-f366fef51bbd",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "fb86b32f-fb7a-45cf-9511-f366fef51bbd",
Expand Down Expand Up @@ -4500,7 +4500,7 @@
"w": 24,
"h": 11,
"i": "0cc42484-16f7-42ec-b38c-9bf8be69cde7",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "0cc42484-16f7-42ec-b38c-9bf8be69cde7",
Expand Down Expand Up @@ -4643,7 +4643,7 @@
"w": 12,
"h": 11,
"i": "5d53db36-2d5a-4adc-af7b-cec4c1a294e0",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "5d53db36-2d5a-4adc-af7b-cec4c1a294e0",
Expand Down Expand Up @@ -4773,7 +4773,7 @@
"w": 12,
"h": 11,
"i": "ecd89a7c-9124-4472-bdc6-9bdbd70d45d5",
"row": 3
"row": "fourth"
},
"explicitInput": {
"id": "ecd89a7c-9124-4472-bdc6-9bdbd70d45d5",
Expand Down
12 changes: 6 additions & 6 deletions examples/grid_example/public/serialized_grid_layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ export function setSerializedGridLayout(state: MockSerializedDashboardState) {

const initialState: MockSerializedDashboardState = {
panels: logsPanels,
rows: [
{ title: 'Request Sizes', collapsed: false },
{ title: 'Visitors', collapsed: false },
{ title: 'Response Codes', collapsed: false },
{ title: 'Entire Flights Dashboard', collapsed: true },
],
rows: {
first: { id: 'first', order: 0, title: 'Request Sizes', collapsed: false },
second: { id: 'second', order: 1, title: 'Visitors', collapsed: false },
third: { id: 'third', order: 2, title: 'Response Codes', collapsed: false },
fourth: { id: 'fourth', order: 3, title: 'Entire Flights Dashboard', collapsed: true },
},
};
6 changes: 4 additions & 2 deletions examples/grid_example/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface DashboardGridData {

interface DashboardPanelState {
type: string;
gridData: DashboardGridData & { row?: number };
gridData: DashboardGridData & { row?: string };
explicitInput: Partial<any> & { id: string };
version?: string;
}
Expand All @@ -35,7 +35,9 @@ export interface MockedDashboardPanelMap {
[key: string]: DashboardPanelState;
}

export type MockedDashboardRowMap = Array<{ title: string; collapsed: boolean }>;
export interface MockedDashboardRowMap {
[id: string]: { id: string; order: number; title: string; collapsed: boolean };
}

export interface MockSerializedDashboardState {
panels: MockedDashboardPanelMap;
Expand Down
2 changes: 1 addition & 1 deletion examples/grid_example/public/use_mock_dashboard_api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export const useMockDashboardApi = ({
[newId]: {
type: panelPackage.panelType,
gridData: {
row: 0,
row: 'first',
x: 0,
y: 0,
w: DEFAULT_PANEL_WIDTH,
Expand Down
Loading

0 comments on commit 4850d36

Please sign in to comment.