Dashboards: Improve lazy loading (#108854)

This commit is contained in:
Bogdan Matei
2025-08-01 10:46:41 +00:00
committed by GitHub
parent f3cd54769c
commit 88a52bb6f4
17 changed files with 264 additions and 189 deletions
@@ -14,7 +14,7 @@ test.use({
// these tests require a larger viewport
test.use({
viewport: { width: 1280, height: 1080 },
viewport: { width: 1920, height: 1080 },
});
test.describe(
@@ -124,37 +124,49 @@ test.describe(
await dashboardPage.getByGrafanaSelector(selectors.components.CanvasGridAddActions.addRow).click();
await dashboardPage.getByGrafanaSelector(selectors.components.CanvasGridAddActions.addPanel).last().click();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 2'))
).toBeVisible();
const firstRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New row'));
await expect(firstRow).toBeVisible();
await firstRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(5);
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: firstRow })
).toHaveCount(3);
const secondRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New row 1'));
await expect(secondRow).toBeVisible();
await secondRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: secondRow })
).toHaveCount(1);
const thirdRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New row 2'));
await expect(thirdRow).toBeVisible();
await thirdRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: thirdRow })
).toHaveCount(1);
// Save dashboard and reload
await saveDashboard(dashboardPage, selectors);
await page.reload();
await expect(firstRow).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 2'))
).toBeVisible();
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: firstRow })
).toHaveCount(3);
await expect(secondRow).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(5);
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: secondRow })
).toHaveCount(1);
thirdRow.scrollIntoViewIfNeeded();
await expect(thirdRow).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: thirdRow })
).toHaveCount(1);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
@@ -172,15 +184,9 @@ test.describe(
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.deleteButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.ConfirmModal.delete).click();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeHidden();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 2'))
).toBeHidden();
await expect(firstRow).toBeVisible();
await expect(secondRow).toBeHidden();
await expect(thirdRow).toBeHidden();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(3);
@@ -188,15 +194,9 @@ test.describe(
await saveDashboard(dashboardPage, selectors);
await page.reload();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeHidden();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 2'))
).toBeHidden();
await expect(firstRow).toBeVisible();
await expect(secondRow).toBeHidden();
await expect(thirdRow).toBeHidden();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(3);
@@ -224,15 +224,21 @@ test.describe(
.getByGrafanaSelector(selectors.components.CanvasGridAddActions.addRow)
.scrollIntoViewIfNeeded();
const firstRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New row'));
await expect(firstRow).toBeVisible();
firstRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: firstRow })
).toHaveCount(3);
const secondRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New row 1'));
await expect(secondRow).toBeVisible();
secondRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(6);
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: secondRow })
).toHaveCount(3);
await saveDashboard(dashboardPage, selectors);
await page.reload();
@@ -243,15 +249,18 @@ test.describe(
.last()
.scrollIntoViewIfNeeded();
await expect(firstRow).toBeVisible();
await expect(secondRow).toBeVisible();
firstRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: firstRow })
).toHaveCount(3);
secondRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(6);
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: secondRow })
).toHaveCount(3);
});
test('can duplicate a row', async ({ dashboardPage, selectors, page }) => {
@@ -274,15 +283,21 @@ test.describe(
.getByGrafanaSelector(selectors.components.CanvasGridAddActions.addRow)
.scrollIntoViewIfNeeded();
const firstRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New row'));
await expect(firstRow).toBeVisible();
firstRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: firstRow })
).toHaveCount(3);
const secondRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New row 1'));
await expect(secondRow).toBeVisible();
secondRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(6);
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: secondRow })
).toHaveCount(3);
await saveDashboard(dashboardPage, selectors);
await page.reload();
@@ -293,15 +308,18 @@ test.describe(
.last()
.scrollIntoViewIfNeeded();
await expect(firstRow).toBeVisible();
await expect(secondRow).toBeVisible();
firstRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: firstRow })
).toHaveCount(3);
secondRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(6);
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: secondRow })
).toHaveCount(3);
});
test('can collapse rows', async ({ dashboardPage, selectors, page }) => {
@@ -324,26 +342,29 @@ test.describe(
.getByGrafanaSelector(selectors.components.CanvasGridAddActions.addRow)
.scrollIntoViewIfNeeded();
const firstRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New row'));
await expect(firstRow).toBeVisible();
firstRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: firstRow })
).toHaveCount(3);
const secondRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New row 1'));
await expect(secondRow).toBeVisible();
secondRow.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(6);
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: secondRow })
).toHaveCount(3);
// Collapse rows by clicking on their titles
await dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row')).click();
await dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1')).click();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeVisible();
await expect(firstRow).toBeVisible();
await expect(secondRow).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(0);
@@ -351,12 +372,9 @@ test.describe(
await saveDashboard(dashboardPage, selectors);
await page.reload();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row'))
).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New row 1'))
).toBeVisible();
await expect(firstRow).toBeVisible();
await expect(secondRow).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(0);
@@ -684,67 +702,75 @@ test.describe(
// Select rows layout
await page.getByLabel('Rows').click();
await dashboardPage
.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New tab 1'))
.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab'))
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New tab 1'))
).toBeVisible();
await dashboardPage
.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New tab 2'))
.scrollIntoViewIfNeeded();
const firstRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New tab'));
const secondRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New tab 1'));
const thirdRow = dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New tab 2'));
firstRow.scrollIntoViewIfNeeded();
await expect(firstRow).toBeVisible();
// Wait for panels to load
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel')).first()
).toBeVisible();
await dashboardPage
.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab 1'))
.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab 1'))
).toBeVisible();
await dashboardPage
.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab 2'))
.scrollIntoViewIfNeeded();
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: firstRow })
).toHaveCount(3);
secondRow.scrollIntoViewIfNeeded();
await expect(secondRow).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab 2'))
).toBeVisible();
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: secondRow })
).toHaveCount(3);
thirdRow.scrollIntoViewIfNeeded();
await expect(thirdRow).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: thirdRow })
).toHaveCount(3);
// scroll `New row` into view - this is at the bottom of the dashboard body
await dashboardPage
.getByGrafanaSelector(selectors.components.CanvasGridAddActions.addRow)
.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(9);
await expect(dashboardPage.getByGrafanaSelector(selectors.components.CanvasGridAddActions.addRow)).toBeVisible();
await saveDashboard(dashboardPage, selectors);
await page.reload();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab'))
).toBeVisible();
await expect(firstRow).toBeVisible();
// Wait for panels to load
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel')).first()
).toBeVisible();
await dashboardPage
.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab 1'))
.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab 1'))
).toBeVisible();
await dashboardPage
.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab 2'))
.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('New tab 2'))
).toBeVisible();
// scroll last `New panel` into view - this is at the bottom of the dashboard body
await dashboardPage
.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
.last()
.scrollIntoViewIfNeeded();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(9);
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: firstRow })
).toHaveCount(3);
secondRow.scrollIntoViewIfNeeded();
await expect(secondRow).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: secondRow })
).toHaveCount(3);
thirdRow.scrollIntoViewIfNeeded();
await expect(thirdRow).toBeVisible();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'), { root: thirdRow })
).toHaveCount(3);
});
test('can group and ungroup new panels into tab with row', async ({ dashboardPage, selectors, page }) => {
@@ -10,6 +10,10 @@ test.use({
},
});
test.use({
viewport: { width: 1920, height: 1080 },
});
const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output';
const DASHBOARD_NAME = 'Test variable output';
@@ -55,7 +59,7 @@ test.describe(
const firstPreviewOption = dashboardPage
.getByGrafanaSelector(selectors.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption)
.first();
await expect(firstPreviewOption).toBeVisible();
await expect(firstPreviewOption).toBeVisible({ timeout: 15_000 });
const previewOptionText = await firstPreviewOption.textContent();
const previewOption = previewOptionText?.trim() || '';
@@ -12,6 +12,10 @@ test.use({
},
});
test.use({
viewport: { width: 1920, height: 1080 },
});
test.describe(
'Dashboard Panel Layouts',
{
@@ -171,6 +175,10 @@ test.describe(
test('can change max columns in auto grid layout', async ({ dashboardPage, selectors, page }) => {
await importTestDashboard(page, selectors, 'Set max columns');
await await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel')).first()
).toBeVisible();
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await expect(
@@ -384,6 +392,11 @@ async function importTestDashboard(page: Page, selectors: E2ESelectorGroups, tit
await page.getByTestId(selectors.components.DataSourcePicker.inputV2).click();
await page.locator('div[data-testid="data-source-card"]').first().click();
await page.getByTestId(selectors.components.ImportDashboardForm.submit).click();
const undockMenuButton = page.locator('[aria-label="Undock menu"]');
const undockMenuVisible = await undockMenuButton.isVisible();
if (undockMenuVisible) {
undockMenuButton.click();
}
}
async function saveDashboard(dashboardPage: DashboardPage, selectors: E2ESelectorGroups) {
@@ -10,6 +10,10 @@ test.use({
const PAGE_UNDER_TEST = 'edediimbjhdz4b/a-tall-dashboard';
test.use({
viewport: { width: 1920, height: 1080 },
});
test.describe(
'Dashboard panels',
{
+47 -37
View File
@@ -2,32 +2,27 @@
"apiVersion": "dashboard.grafana.app/v2beta1",
"kind": "Dashboard",
"metadata": {
"name": "fa400625-2a44-4add-a369-e6c972eb4bd6",
"generation": 1,
"creationTimestamp": "2025-05-27T11:40:22Z",
"labels": {},
"annotations": {}
"name": "addfpww",
"namespace": "default",
"uid": "AvXN09JdxuVNDqODs5IYU2iStlk5ntizuPGIfY1ywZgX",
"resourceVersion": "1",
"generation": 2,
"creationTimestamp": "2025-07-31T13:37:11Z",
"labels": {
"grafana.app/deprecatedInternalID": "6844"
},
"annotations": {
"grafana.app/createdBy": "user:cejvsh18uudxcf",
"grafana.app/updatedBy": "user:cejvsh18uudxcf",
"grafana.app/updatedTimestamp": "2025-07-31T13:37:11Z",
"grafana.app/folder": "",
"grafana.app/saved-from-ui": "Grafana v12.2.0-pre (69d1226c9a)"
}
},
"spec": {
"annotations": [
{
"kind": "AnnotationQuery",
"spec": {
"builtIn": true,
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"query": {
"group": "grafana",
"kind": "DataQuery",
"spec": {},
"version": "v0"
}
}
}
],
"annotations": [],
"cursorSync": "Off",
"description": "",
"editable": true,
"elements": {
"panel-1": {
@@ -42,6 +37,9 @@
"spec": {
"hidden": false,
"query": {
"datasource": {
"name": "PD8C576611E62080A"
},
"group": "grafana-testdata-datasource",
"kind": "DataQuery",
"spec": {},
@@ -60,7 +58,8 @@
"links": [],
"title": "New panel",
"vizConfig": {
"kind": "timeseries",
"group": "timeseries",
"kind": "VizConfig",
"spec": {
"fieldConfig": {
"defaults": {
@@ -128,9 +127,9 @@
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre"
}
}
},
"version": "12.2.0-pre"
}
}
},
@@ -146,9 +145,15 @@
"spec": {
"hidden": false,
"query": {
"datasource": {
"name": "PD8C576611E62080A"
},
"group": "grafana-testdata-datasource",
"kind": "DataQuery",
"spec": {},
"spec": {
"scenarioId": "random_walk",
"seriesCount": 1
},
"version": "v0"
},
"refId": "A"
@@ -164,7 +169,8 @@
"links": [],
"title": "New panel",
"vizConfig": {
"kind": "timeseries",
"group": "timeseries",
"kind": "VizConfig",
"spec": {
"fieldConfig": {
"defaults": {
@@ -232,9 +238,9 @@
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre"
}
}
},
"version": "12.2.0-pre"
}
}
},
@@ -250,6 +256,9 @@
"spec": {
"hidden": false,
"query": {
"datasource": {
"name": "PD8C576611E62080A"
},
"group": "grafana-testdata-datasource",
"kind": "DataQuery",
"spec": {},
@@ -268,7 +277,8 @@
"links": [],
"title": "New panel",
"vizConfig": {
"kind": "timeseries",
"group": "timeseries",
"kind": "VizConfig",
"spec": {
"fieldConfig": {
"defaults": {
@@ -336,9 +346,9 @@
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre"
}
}
},
"version": "12.2.0-pre"
}
}
}
@@ -402,7 +412,7 @@
"timezone": "browser",
"to": "now"
},
"title": "Test V2 Dashboard",
"title": "TEST!!!!",
"variables": []
},
"status": {}
+2 -2
View File
@@ -290,8 +290,8 @@
"@grafana/plugin-ui": "0.10.7",
"@grafana/prometheus": "workspace:*",
"@grafana/runtime": "workspace:*",
"@grafana/scenes": "6.28.6",
"@grafana/scenes-react": "6.28.6",
"@grafana/scenes": "6.29.0",
"@grafana/scenes-react": "6.29.0",
"@grafana/schema": "workspace:*",
"@grafana/sql": "workspace:*",
"@grafana/ui": "workspace:*",
@@ -1239,6 +1239,9 @@ export const versionedComponents = {
title: {
[MIN_GRAFANA_VERSION]: (title: string) => `data-testid dashboard-row-title-${title}`,
},
wrapper: {
'12.1.0': (title: string) => `data-testid dashboard-row-wrapper-for-${title}`,
},
},
UserProfile: {
profileSaveButton: {
@@ -88,6 +88,7 @@ import { DashboardGridItem } from './layout-default/DashboardGridItem';
import { DefaultGridLayoutManager } from './layout-default/DefaultGridLayoutManager';
import { addNewRowTo } from './layouts-shared/addNew';
import { clearClipboard } from './layouts-shared/paste';
import { getIsLazy } from './layouts-shared/utils';
import { DashboardLayoutManager } from './types/DashboardLayoutManager';
import { LayoutParent } from './types/LayoutParent';
@@ -198,7 +199,7 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> impleme
meta: {},
editable: true,
$timeRange: state.$timeRange ?? new SceneTimeRange({}),
body: state.body ?? DefaultGridLayoutManager.fromVizPanels(),
body: state.body ?? DefaultGridLayoutManager.fromVizPanels([], getIsLazy(state.preload)),
links: state.links ?? [],
...state,
editPane: new DashboardEditPane(),
@@ -22,9 +22,6 @@ export interface AutoGridLayoutState extends SceneObjectState, AutoGridLayoutOpt
*/
md?: AutoGridLayoutOptions;
/** True when the items should be lazy loaded */
isLazy?: boolean;
/** True when the items should be draggable */
isDraggable?: boolean;
@@ -1,4 +1,5 @@
import { css, cx } from '@emotion/css';
import { useMemo } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { LazyLoader, SceneComponentProps, sceneGraph } from '@grafana/scenes';
@@ -8,18 +9,21 @@ import { useHasClonedParents } from '../../utils/clone';
import { useDashboardState } from '../../utils/utils';
import { CanvasGridAddActions } from '../layouts-shared/CanvasGridAddActions';
import { dashboardCanvasAddButtonHoverStyles } from '../layouts-shared/styles';
import { getIsLazy } from '../layouts-shared/utils';
import { AutoGridLayout, AutoGridLayoutState } from './AutoGridLayout';
import { AutoGridLayoutManager } from './AutoGridLayoutManager';
export function AutoGridLayoutRenderer({ model }: SceneComponentProps<AutoGridLayout>) {
const { children, isHidden, isLazy } = model.useState();
const { children, isHidden } = model.useState();
const hasClonedParents = useHasClonedParents(model);
const styles = useStyles2(getStyles, model.state);
const { layoutOrchestrator, isEditing } = useDashboardState(model);
const { layoutOrchestrator, isEditing, preload } = useDashboardState(model);
const layoutManager = sceneGraph.getAncestor(model, AutoGridLayoutManager);
const { fillScreen } = layoutManager.useState();
const isLazy = useMemo(() => getIsLazy(preload), [preload]);
if (isHidden || !layoutOrchestrator) {
return null;
}
@@ -46,6 +46,7 @@ import { AutoGridItem } from '../layout-auto-grid/AutoGridItem';
import { CanvasGridAddActions } from '../layouts-shared/CanvasGridAddActions';
import { clearClipboard, getDashboardGridItemFromClipboard } from '../layouts-shared/paste';
import { dashboardCanvasAddButtonHoverStyles } from '../layouts-shared/styles';
import { getIsLazy } from '../layouts-shared/utils';
import { DashboardLayoutManager } from '../types/DashboardLayoutManager';
import { LayoutRegistryItem } from '../types/LayoutRegistryItem';
@@ -558,10 +559,11 @@ export class DefaultGridLayoutManager
public static createFromLayout(currentLayout: DashboardLayoutManager): DefaultGridLayoutManager {
const panels = currentLayout.getVizPanels();
return DefaultGridLayoutManager.fromVizPanels(panels);
const isLazy = getIsLazy(getDashboardSceneFor(currentLayout).state.preload)!;
return DefaultGridLayoutManager.fromVizPanels(panels, isLazy);
}
public static fromVizPanels(panels: VizPanel[] = []): DefaultGridLayoutManager {
public static fromVizPanels(panels: VizPanel[] = [], isLazy?: boolean | undefined): DefaultGridLayoutManager {
const children: DashboardGridItem[] = [];
const panelHeight = 10;
const panelWidth = GRID_COLUMN_COUNT / 3;
@@ -599,6 +601,7 @@ export class DefaultGridLayoutManager
children: children,
isDraggable: true,
isResizable: true,
isLazy,
}),
});
}
@@ -606,7 +609,8 @@ export class DefaultGridLayoutManager
public static fromGridItems(
gridItems: SceneGridItemLike[],
isDraggable?: boolean,
isResizable?: boolean
isResizable?: boolean,
isLazy?: boolean | undefined
): DefaultGridLayoutManager {
const children = gridItems.reduce<SceneGridItemLike[]>((acc, gridItem) => {
gridItem.clearParent();
@@ -620,6 +624,7 @@ export class DefaultGridLayoutManager
children,
isDraggable,
isResizable,
isLazy,
}),
});
}
@@ -83,6 +83,7 @@ export function RowItemRenderer({ model }: SceneComponentProps<RowItem>) {
setTimeout(() => onSelect?.(evt));
}}
data-testid={selectors.components.DashboardRow.wrapper(title!)}
{...dragProvided.draggableProps}
>
{(!isHeaderHidden || isEditing) && (
@@ -258,7 +258,8 @@ export class RowsLayoutManager extends SceneObjectBase<RowsLayoutManagerState> i
layout: DefaultGridLayoutManager.fromGridItems(
rowConfig.children,
rowConfig.isDraggable ?? layout.state.grid.state.isDraggable,
rowConfig.isResizable ?? layout.state.grid.state.isResizable
rowConfig.isResizable ?? layout.state.grid.state.isResizable,
layout.state.grid.state.isLazy
),
})
);
@@ -1,6 +1,7 @@
import { useEffect, useRef } from 'react';
import { SceneObject } from '@grafana/scenes';
import { contextSrv } from 'app/core/core';
import { DashboardLayoutManager, isDashboardLayoutManager } from '../types/DashboardLayoutManager';
import { isLayoutParent } from '../types/LayoutParent';
@@ -75,3 +76,8 @@ export function ungroupLayout(layout: DashboardLayoutManager, innerLayout: Dashb
layoutParent.switchLayout(innerLayout);
}
}
export function getIsLazy(preload: boolean | undefined): boolean {
// We don't want to lazy load panels in the case of image renderer
return !(preload || (contextSrv.user && contextSrv.user.authenticatedBy === 'render'));
}
@@ -9,10 +9,10 @@ import {
PanelKind,
LibraryPanelKind,
} from '@grafana/schema/dist/esm/schema/dashboard/v2';
import { contextSrv } from 'app/core/core';
import { DashboardGridItem } from '../../scene/layout-default/DashboardGridItem';
import { DefaultGridLayoutManager } from '../../scene/layout-default/DefaultGridLayoutManager';
import { getIsLazy } from '../../scene/layouts-shared/utils';
import { dashboardSceneGraph } from '../../utils/dashboardSceneGraph';
import { calculateGridItemDimensions, isLibraryPanel } from '../../utils/utils';
@@ -41,7 +41,7 @@ export function deserializeDefaultGridLayout(
}
return new DefaultGridLayoutManager({
grid: new SceneGridLayout({
isLazy: !(preload || contextSrv.user.authenticatedBy === 'render'),
isLazy: getIsLazy(preload),
children: createSceneGridLayoutForItems(layout, elements, panelIdGenerator),
}),
});
@@ -20,7 +20,6 @@ import {
SceneObjectState,
} from '@grafana/scenes';
import { isWeekStart } from '@grafana/ui';
import { contextSrv } from 'app/core/core';
import { K8S_V1_DASHBOARD_API_CONFIG } from 'app/features/dashboard/api/v1';
import {
getDashboardInteractionCallback,
@@ -50,6 +49,7 @@ import { RowRepeaterBehavior } from '../scene/layout-default/RowRepeaterBehavior
import { RowActions } from '../scene/layout-default/row-actions/RowActions';
import { RowItem } from '../scene/layout-rows/RowItem';
import { RowsLayoutManager } from '../scene/layout-rows/RowsLayoutManager';
import { getIsLazy } from '../scene/layouts-shared/utils';
import { setDashboardPanelContext } from '../scene/setDashboardPanelContext';
import { DashboardLayoutManager } from '../scene/types/DashboardLayoutManager';
import { createPanelDataProvider } from '../utils/createPanelDataProvider';
@@ -326,7 +326,7 @@ export function createDashboardSceneFromDashboardModel(oldModel: DashboardModel,
} else {
body = new DefaultGridLayoutManager({
grid: new SceneGridLayout({
isLazy: !(dto.preload || contextSrv.user.authenticatedBy === 'render'),
isLazy: getIsLazy(dto.preload),
children: createSceneObjectsForPanels(oldModel.panels),
}),
});
+11 -11
View File
@@ -3590,11 +3590,11 @@ __metadata:
languageName: unknown
linkType: soft
"@grafana/scenes-react@npm:6.28.6":
version: 6.28.6
resolution: "@grafana/scenes-react@npm:6.28.6"
"@grafana/scenes-react@npm:6.29.0":
version: 6.29.0
resolution: "@grafana/scenes-react@npm:6.29.0"
dependencies:
"@grafana/scenes": "npm:6.28.6"
"@grafana/scenes": "npm:6.29.0"
lru-cache: "npm:^10.2.2"
react-use: "npm:^17.4.0"
peerDependencies:
@@ -3606,13 +3606,13 @@ __metadata:
react: ^18.0.0
react-dom: ^18.0.0
react-router-dom: ^6.28.0
checksum: 10/55dfe20a6454f218b7c5ab2dc728678885d48e53656d046c125b555b201891e121e0960e108229372c2d70336cfe3dade9b392ed001fef90aec57cbcc13f76ca
checksum: 10/3cf401ecb143d4bf130ea406b2d6e789c1ac49f5490f4fa80e2cc330d84cee434d4543ae58ad0cae228e1b3b73972888bb95eed217a9d2fa0524088361710878
languageName: node
linkType: hard
"@grafana/scenes@npm:6.28.6":
version: 6.28.6
resolution: "@grafana/scenes@npm:6.28.6"
"@grafana/scenes@npm:6.29.0":
version: 6.29.0
resolution: "@grafana/scenes@npm:6.29.0"
dependencies:
"@floating-ui/react": "npm:^0.26.16"
"@leeoniya/ufuzzy": "npm:^1.0.16"
@@ -3632,7 +3632,7 @@ __metadata:
react: ^18.0.0
react-dom: ^18.0.0
react-router-dom: ^6.28.0
checksum: 10/fcfcf663e2eb63ad25fad27ec50af8590b1a6c9e802927e8e457bf2f81d04cf971c2f12f456a04a502c929ec7a1d50ef7118baee095134b133ecc92b269a6907
checksum: 10/ab28ab9a8612e51e189e7ae497cbe3be709515a917deb35e05be3b142c0d541acf22b441501eb6c162ba4bc7da443672ac13312b68f3dbf64ab8556aacdc2999
languageName: node
linkType: hard
@@ -18253,8 +18253,8 @@ __metadata:
"@grafana/plugin-ui": "npm:0.10.7"
"@grafana/prometheus": "workspace:*"
"@grafana/runtime": "workspace:*"
"@grafana/scenes": "npm:6.28.6"
"@grafana/scenes-react": "npm:6.28.6"
"@grafana/scenes": "npm:6.29.0"
"@grafana/scenes-react": "npm:6.29.0"
"@grafana/schema": "workspace:*"
"@grafana/sql": "workspace:*"
"@grafana/test-utils": "workspace:*"