Skip to content

Commit b32f0fe

Browse files
[kbn-grid-layout] Store rows in object instead of array (elastic#212965)
Closes elastic#211930 ## Summary This PR makes it so that `kbn-grid-layout` stores its rows as an object / dictionary (`{ [key: string]: GridRowData }`) rather than an array (`Array<GridRowData>`). This is a prerequisite for elastic#190381 , since it allows us to re-order rows without re-rendering their contents. It also means that deleting a row will no longer cause the rows below it to re-render, since re-rendering is now dependant on the row's **ID** rather than the row's order. **Before** https://github.com/user-attachments/assets/83651b24-a32c-4953-8ad5-c0eced163eb5 **After** https://github.com/user-attachments/assets/9cef6dbc-3d62-46aa-bc40-ab24fc4e5556 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: kibanamachine <[email protected]>
1 parent ef0c364 commit b32f0fe

29 files changed

+325
-286
lines changed

examples/grid_example/public/app.tsx

+15-11
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
*/
99

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

1517
import {
1618
EuiBadge,
@@ -88,8 +90,8 @@ export const GridExample = ({
8890
const currentPanel = panels[panelId];
8991
const savedPanel = savedState.current.panels[panelId];
9092
panelsAreEqual = deepEqual(
91-
{ row: 0, ...currentPanel.gridData },
92-
{ row: 0, ...savedPanel.gridData }
93+
{ row: 'first', ...currentPanel.gridData },
94+
{ row: 'first', ...savedPanel.gridData }
9395
);
9496
}
9597
const hasChanges = !(panelsAreEqual && deepEqual(rows, savedState.current.rows));
@@ -147,15 +149,17 @@ export const GridExample = ({
147149
);
148150

149151
const addNewSection = useCallback(() => {
150-
mockDashboardApi.rows$.next([
151-
...mockDashboardApi.rows$.getValue(),
152-
{
153-
title: i18n.translate('examples.gridExample.defaultSectionTitle', {
154-
defaultMessage: 'New collapsible section',
155-
}),
156-
collapsed: false,
157-
},
158-
]);
152+
const rows = cloneDeep(mockDashboardApi.rows$.getValue());
153+
const id = uuidv4();
154+
rows[id] = {
155+
id,
156+
order: Object.keys(rows).length,
157+
title: i18n.translate('examples.gridExample.defaultSectionTitle', {
158+
defaultMessage: 'New collapsible section',
159+
}),
160+
collapsed: false,
161+
};
162+
mockDashboardApi.rows$.next(rows);
159163

160164
// scroll to bottom after row is added
161165
layoutUpdated$.pipe(skip(1), take(1)).subscribe(() => {

examples/grid_example/public/logs_dashboard_panels.json

+29-29
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@
10041004
"w": 48,
10051005
"h": 17,
10061006
"i": "4",
1007-
"row": 1
1007+
"row": "second"
10081008
},
10091009
"explicitInput": {
10101010
"id": "4",
@@ -1035,7 +1035,7 @@
10351035
"w": 18,
10361036
"h": 8,
10371037
"i": "05da0d2b-0145-4068-b21c-00be3184d465",
1038-
"row": 1
1038+
"row": "second"
10391039
},
10401040
"explicitInput": {
10411041
"id": "05da0d2b-0145-4068-b21c-00be3184d465",
@@ -1073,7 +1073,7 @@
10731073
"w": 18,
10741074
"h": 16,
10751075
"i": "b7da9075-4742-47e3-b4f8-fc9ba82de74c",
1076-
"row": 1
1076+
"row": "second"
10771077
},
10781078
"explicitInput": {
10791079
"id": "b7da9075-4742-47e3-b4f8-fc9ba82de74c",
@@ -1111,7 +1111,7 @@
11111111
"w": 12,
11121112
"h": 16,
11131113
"i": "5c409557-644d-4c05-a284-ffe54bb28db0",
1114-
"row": 1
1114+
"row": "second"
11151115
},
11161116
"explicitInput": {
11171117
"id": "5c409557-644d-4c05-a284-ffe54bb28db0",
@@ -1234,7 +1234,7 @@
12341234
"w": 6,
12351235
"h": 8,
12361236
"i": "af4b5c07-506e-44c2-b2bb-2113d0c5b274",
1237-
"row": 1
1237+
"row": "second"
12381238
},
12391239
"explicitInput": {
12401240
"id": "af4b5c07-506e-44c2-b2bb-2113d0c5b274",
@@ -1400,7 +1400,7 @@
14001400
"w": 6,
14011401
"h": 8,
14021402
"i": "d42c4870-c028-4d8a-abd0-0effbc190ce3",
1403-
"row": 1
1403+
"row": "second"
14041404
},
14051405
"explicitInput": {
14061406
"id": "d42c4870-c028-4d8a-abd0-0effbc190ce3",
@@ -1520,7 +1520,7 @@
15201520
"w": 6,
15211521
"h": 8,
15221522
"i": "4092d42c-f93b-4c71-a6db-8f12abf12791",
1523-
"row": 1
1523+
"row": "second"
15241524
},
15251525
"explicitInput": {
15261526
"id": "4092d42c-f93b-4c71-a6db-8f12abf12791",
@@ -1641,7 +1641,7 @@
16411641
"w": 30,
16421642
"h": 15,
16431643
"i": "15",
1644-
"row": 2
1644+
"row": "third"
16451645
},
16461646
"explicitInput": {
16471647
"id": "15",
@@ -1887,7 +1887,7 @@
18871887
"w": 18,
18881888
"h": 8,
18891889
"i": "4e64d6d7-4f92-4d5e-abbb-13796604db30",
1890-
"row": 2
1890+
"row": "third"
18911891
},
18921892
"explicitInput": {
18931893
"id": "4e64d6d7-4f92-4d5e-abbb-13796604db30v",
@@ -1925,7 +1925,7 @@
19251925
"w": 6,
19261926
"h": 7,
19271927
"i": "ddce4ad8-6a82-44f0-9995-57f46f153f50",
1928-
"row": 2
1928+
"row": "third"
19291929
},
19301930
"explicitInput": {
19311931
"id": "ddce4ad8-6a82-44f0-9995-57f46f153f50",
@@ -2120,7 +2120,7 @@
21202120
"w": 6,
21212121
"h": 7,
21222122
"i": "a2884704-db3b-4b92-a19a-cdfe668dec39",
2123-
"row": 2
2123+
"row": "third"
21242124
},
21252125
"explicitInput": {
21262126
"id": "a2884704-db3b-4b92-a19a-cdfe668dec39",
@@ -2315,7 +2315,7 @@
23152315
"w": 6,
23162316
"h": 7,
23172317
"i": "529eec49-10e2-4a40-9c77-5c81f4eb3943",
2318-
"row": 2
2318+
"row": "third"
23192319
},
23202320
"explicitInput": {
23212321
"id": "529eec49-10e2-4a40-9c77-5c81f4eb3943",
@@ -2510,7 +2510,7 @@
25102510
"w": 48,
25112511
"h": 12,
25122512
"i": "1d5f0b3f-d9d2-4b26-997b-83bc5ca3090b",
2513-
"row": 2
2513+
"row": "third"
25142514
},
25152515
"explicitInput": {
25162516
"id": "1d5f0b3f-d9d2-4b26-997b-83bc5ca3090b",
@@ -2905,7 +2905,7 @@
29052905
"w": 48,
29062906
"h": 15,
29072907
"i": "9f79ecca-123f-4098-a658-6b0e998da003",
2908-
"row": 3
2908+
"row": "fourth"
29092909
},
29102910
"explicitInput": {
29112911
"id": "9f79ecca-123f-4098-a658-6b0e998da003",
@@ -2922,7 +2922,7 @@
29222922
"w": 24,
29232923
"h": 9,
29242924
"i": "7",
2925-
"row": 3
2925+
"row": "fourth"
29262926
},
29272927
"explicitInput": {
29282928
"id": "7",
@@ -3161,7 +3161,7 @@
31613161
"w": 24,
31623162
"h": 11,
31633163
"i": "10",
3164-
"row": 3
3164+
"row": "fourth"
31653165
},
31663166
"explicitInput": {
31673167
"id": "10",
@@ -3346,7 +3346,7 @@
33463346
"w": 24,
33473347
"h": 22,
33483348
"i": "23",
3349-
"row": 3
3349+
"row": "fourth"
33503350
},
33513351
"explicitInput": {
33523352
"id": "23",
@@ -3371,7 +3371,7 @@
33713371
"w": 24,
33723372
"h": 22,
33733373
"i": "31",
3374-
"row": 3
3374+
"row": "fourth"
33753375
},
33763376
"explicitInput": {
33773377
"id": "31",
@@ -3388,7 +3388,7 @@
33883388
"w": 24,
33893389
"h": 8,
33903390
"i": "6afc61f7-e2d5-45a3-9e7a-281160ad3eb9",
3391-
"row": 3
3391+
"row": "fourth"
33923392
},
33933393
"explicitInput": {
33943394
"id": "6afc61f7-e2d5-45a3-9e7a-281160ad3eb9",
@@ -3420,7 +3420,7 @@
34203420
"w": 8,
34213421
"h": 8,
34223422
"i": "392b4936-f753-47bc-a98d-a4e41a0a4cd4",
3423-
"row": 3
3423+
"row": "fourth"
34243424
},
34253425
"explicitInput": {
34263426
"id": "392b4936-f753-47bc-a98d-a4e41a0a4cd4",
@@ -3485,7 +3485,7 @@
34853485
"w": 8,
34863486
"h": 4,
34873487
"i": "9271deff-5a61-4665-83fc-f9fdc6bf0c0b",
3488-
"row": 3
3488+
"row": "fourth"
34893489
},
34903490
"explicitInput": {
34913491
"id": "9271deff-5a61-4665-83fc-f9fdc6bf0c0b",
@@ -3613,7 +3613,7 @@
36133613
"w": 8,
36143614
"h": 4,
36153615
"i": "aa591c29-1a31-4ee1-a71d-b829c06fd162",
3616-
"row": 3
3616+
"row": "fourth"
36173617
},
36183618
"explicitInput": {
36193619
"id": "aa591c29-1a31-4ee1-a71d-b829c06fd162",
@@ -3777,7 +3777,7 @@
37773777
"w": 8,
37783778
"h": 4,
37793779
"i": "b766e3b8-4544-46ed-99e6-9ecc4847e2a2",
3780-
"row": 3
3780+
"row": "fourth"
37813781
},
37823782
"explicitInput": {
37833783
"id": "b766e3b8-4544-46ed-99e6-9ecc4847e2a2",
@@ -3905,7 +3905,7 @@
39053905
"w": 8,
39063906
"h": 4,
39073907
"i": "2e33ade5-96e5-40b4-b460-493e5d4fa834",
3908-
"row": 3
3908+
"row": "fourth"
39093909
},
39103910
"explicitInput": {
39113911
"id": "2e33ade5-96e5-40b4-b460-493e5d4fa834",
@@ -4069,7 +4069,7 @@
40694069
"w": 24,
40704070
"h": 8,
40714071
"i": "086ac2e9-dd16-4b45-92b8-1e43ff7e3f65",
4072-
"row": 3
4072+
"row": "fourth"
40734073
},
40744074
"explicitInput": {
40754075
"id": "086ac2e9-dd16-4b45-92b8-1e43ff7e3f65",
@@ -4190,7 +4190,7 @@
41904190
"w": 24,
41914191
"h": 28,
41924192
"i": "fb86b32f-fb7a-45cf-9511-f366fef51bbd",
4193-
"row": 3
4193+
"row": "fourth"
41944194
},
41954195
"explicitInput": {
41964196
"id": "fb86b32f-fb7a-45cf-9511-f366fef51bbd",
@@ -4500,7 +4500,7 @@
45004500
"w": 24,
45014501
"h": 11,
45024502
"i": "0cc42484-16f7-42ec-b38c-9bf8be69cde7",
4503-
"row": 3
4503+
"row": "fourth"
45044504
},
45054505
"explicitInput": {
45064506
"id": "0cc42484-16f7-42ec-b38c-9bf8be69cde7",
@@ -4643,7 +4643,7 @@
46434643
"w": 12,
46444644
"h": 11,
46454645
"i": "5d53db36-2d5a-4adc-af7b-cec4c1a294e0",
4646-
"row": 3
4646+
"row": "fourth"
46474647
},
46484648
"explicitInput": {
46494649
"id": "5d53db36-2d5a-4adc-af7b-cec4c1a294e0",
@@ -4773,7 +4773,7 @@
47734773
"w": 12,
47744774
"h": 11,
47754775
"i": "ecd89a7c-9124-4472-bdc6-9bdbd70d45d5",
4776-
"row": 3
4776+
"row": "fourth"
47774777
},
47784778
"explicitInput": {
47794779
"id": "ecd89a7c-9124-4472-bdc6-9bdbd70d45d5",

examples/grid_example/public/serialized_grid_layout.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ export function setSerializedGridLayout(state: MockSerializedDashboardState) {
2828

2929
const initialState: MockSerializedDashboardState = {
3030
panels: logsPanels,
31-
rows: [
32-
{ title: 'Request Sizes', collapsed: false },
33-
{ title: 'Visitors', collapsed: false },
34-
{ title: 'Response Codes', collapsed: false },
35-
{ title: 'Entire Flights Dashboard', collapsed: true },
36-
],
31+
rows: {
32+
first: { id: 'first', order: 0, title: 'Request Sizes', collapsed: false },
33+
second: { id: 'second', order: 1, title: 'Visitors', collapsed: false },
34+
third: { id: 'third', order: 2, title: 'Response Codes', collapsed: false },
35+
fourth: { id: 'fourth', order: 3, title: 'Entire Flights Dashboard', collapsed: true },
36+
},
3737
};

examples/grid_example/public/types.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export interface DashboardGridData {
2626

2727
interface DashboardPanelState {
2828
type: string;
29-
gridData: DashboardGridData & { row?: number };
29+
gridData: DashboardGridData & { row?: string };
3030
explicitInput: Partial<any> & { id: string };
3131
version?: string;
3232
}
@@ -35,7 +35,9 @@ export interface MockedDashboardPanelMap {
3535
[key: string]: DashboardPanelState;
3636
}
3737

38-
export type MockedDashboardRowMap = Array<{ title: string; collapsed: boolean }>;
38+
export interface MockedDashboardRowMap {
39+
[id: string]: { id: string; order: number; title: string; collapsed: boolean };
40+
}
3941

4042
export interface MockSerializedDashboardState {
4143
panels: MockedDashboardPanelMap;

examples/grid_example/public/use_mock_dashboard_api.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export const useMockDashboardApi = ({
9999
[newId]: {
100100
type: panelPackage.panelType,
101101
gridData: {
102-
row: 0,
102+
row: 'first',
103103
x: 0,
104104
y: 0,
105105
w: DEFAULT_PANEL_WIDTH,

0 commit comments

Comments
 (0)