diff --git a/e2e-playwright/dashboard-new-layouts/dashboard-group-panels.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboard-group-panels.spec.ts index 12023c9de6c..9824d0d08df 100644 --- a/e2e-playwright/dashboard-new-layouts/dashboard-group-panels.spec.ts +++ b/e2e-playwright/dashboard-new-layouts/dashboard-group-panels.spec.ts @@ -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 }) => { diff --git a/e2e-playwright/dashboard-new-layouts/dashboards-edit-query-variables.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboards-edit-query-variables.spec.ts index 6c55988a309..2e6b80b7b3c 100644 --- a/e2e-playwright/dashboard-new-layouts/dashboards-edit-query-variables.spec.ts +++ b/e2e-playwright/dashboard-new-layouts/dashboards-edit-query-variables.spec.ts @@ -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() || ''; diff --git a/e2e-playwright/dashboard-new-layouts/dashboards-panel-layouts.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboards-panel-layouts.spec.ts index 78889efbbbe..6cd56e19a11 100644 --- a/e2e-playwright/dashboard-new-layouts/dashboards-panel-layouts.spec.ts +++ b/e2e-playwright/dashboard-new-layouts/dashboards-panel-layouts.spec.ts @@ -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) { diff --git a/e2e-playwright/dashboard-new-layouts/dashboards-remove-panel.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboards-remove-panel.spec.ts index 5b5202f1455..61fb78ab5a7 100644 --- a/e2e-playwright/dashboard-new-layouts/dashboards-remove-panel.spec.ts +++ b/e2e-playwright/dashboard-new-layouts/dashboards-remove-panel.spec.ts @@ -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', { diff --git a/e2e-playwright/dashboards/TestV2Dashboard.json b/e2e-playwright/dashboards/TestV2Dashboard.json index 25917da59fa..e4b81d82bf4 100644 --- a/e2e-playwright/dashboards/TestV2Dashboard.json +++ b/e2e-playwright/dashboards/TestV2Dashboard.json @@ -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": {} diff --git a/package.json b/package.json index 5d74735f039..cc339866f02 100644 --- a/package.json +++ b/package.json @@ -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:*", diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index adf4f2efbfe..9ac23a5b24c 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -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: { diff --git a/public/app/features/dashboard-scene/scene/DashboardScene.tsx b/public/app/features/dashboard-scene/scene/DashboardScene.tsx index 662d92a32df..48581e303ae 100644 --- a/public/app/features/dashboard-scene/scene/DashboardScene.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardScene.tsx @@ -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 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(), diff --git a/public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridLayout.tsx b/public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridLayout.tsx index be19f886d83..b96550cfa22 100644 --- a/public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridLayout.tsx +++ b/public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridLayout.tsx @@ -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; diff --git a/public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridLayoutRenderer.tsx b/public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridLayoutRenderer.tsx index 7f66994354d..2a44564b536 100644 --- a/public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridLayoutRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridLayoutRenderer.tsx @@ -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) { - 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; } diff --git a/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx b/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx index b85cb2bcf4b..76fffddd0a5 100644 --- a/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx +++ b/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx @@ -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((acc, gridItem) => { gridItem.clearParent(); @@ -620,6 +624,7 @@ export class DefaultGridLayoutManager children, isDraggable, isResizable, + isLazy, }), }); } diff --git a/public/app/features/dashboard-scene/scene/layout-rows/RowItemRenderer.tsx b/public/app/features/dashboard-scene/scene/layout-rows/RowItemRenderer.tsx index b03b8b26e26..affa68d54ea 100644 --- a/public/app/features/dashboard-scene/scene/layout-rows/RowItemRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/layout-rows/RowItemRenderer.tsx @@ -83,6 +83,7 @@ export function RowItemRenderer({ model }: SceneComponentProps) { setTimeout(() => onSelect?.(evt)); }} + data-testid={selectors.components.DashboardRow.wrapper(title!)} {...dragProvided.draggableProps} > {(!isHeaderHidden || isEditing) && ( diff --git a/public/app/features/dashboard-scene/scene/layout-rows/RowsLayoutManager.tsx b/public/app/features/dashboard-scene/scene/layout-rows/RowsLayoutManager.tsx index 34b2a9e3a1a..1b04a9d6c23 100644 --- a/public/app/features/dashboard-scene/scene/layout-rows/RowsLayoutManager.tsx +++ b/public/app/features/dashboard-scene/scene/layout-rows/RowsLayoutManager.tsx @@ -258,7 +258,8 @@ export class RowsLayoutManager extends SceneObjectBase 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 ), }) ); diff --git a/public/app/features/dashboard-scene/scene/layouts-shared/utils.ts b/public/app/features/dashboard-scene/scene/layouts-shared/utils.ts index 41402564081..eac9ff86333 100644 --- a/public/app/features/dashboard-scene/scene/layouts-shared/utils.ts +++ b/public/app/features/dashboard-scene/scene/layouts-shared/utils.ts @@ -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')); +} diff --git a/public/app/features/dashboard-scene/serialization/layoutSerializers/DefaultGridLayoutSerializer.ts b/public/app/features/dashboard-scene/serialization/layoutSerializers/DefaultGridLayoutSerializer.ts index 8688d1cbb08..e19059547b7 100644 --- a/public/app/features/dashboard-scene/serialization/layoutSerializers/DefaultGridLayoutSerializer.ts +++ b/public/app/features/dashboard-scene/serialization/layoutSerializers/DefaultGridLayoutSerializer.ts @@ -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), }), }); diff --git a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts index b7af7080ea8..8657af91ba1 100644 --- a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts +++ b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts @@ -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), }), }); diff --git a/yarn.lock b/yarn.lock index a0ac7fc9772..a9cb48e452e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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:*"