Dashboards: Use new sidebar in dynamic dashboards (#114245)

* Dynamic dashboards sidebar wip

* Progress

* Outline in view mode cannot change name

* Only one pane at a time

* Adding starbutton and custom precence

* undo / redo working

* Progress

* Update

* Progress

* Update

* Public badge, provisining badge

* playlist stop

* Update

* some initial unit tests

* Fix export tooltip

* Close pane when leaving edit mode if pane is an element

* Update

* e2e fixes

* fixing e2e

* Fix lint suppressions

* e2e fixes

* fixing more e2e

* fixing e2e

* fix e2e

* e2e fixes

* Fixinfg e2e

* fixing e2e
This commit is contained in:
Torkel Ödegaard
2025-11-26 14:30:18 +01:00
committed by GitHub
parent c94bf34d0b
commit f0a394e67b
41 changed files with 634 additions and 650 deletions
@@ -414,13 +414,13 @@ test.describe(
).toBeVisible();
// Go back to dashboard options
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click({ force: true });
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
// Expand layouts section
await page.getByLabel('Expand Group layout category').click();
// Select tabs layout
await page.getByLabel('Tabs').click();
await page.getByLabel('layout-selection-option-Tabs').click();
await expect(dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('New row'))).toBeVisible();
await expect(dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('New row 1'))).toBeVisible();
@@ -518,14 +518,14 @@ test.describe(
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.RowsLayout.titleInput)
.fill('Test row 1');
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.Sidebar.closePane).click();
// clear the title input to simulate no title and click away to trigger onBlur
await dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('Test row 1')).click();
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.RowsLayout.titleInput)
.fill('');
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.Sidebar.closePane).click();
// title should be set to a default name
await expect(
@@ -543,14 +543,14 @@ test.describe(
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.RowsLayout.titleInput)
.fill('Test row 2');
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.Sidebar.closePane).click();
// clear the title input to simulate no title and click away to trigger onBlur
await dashboardPage.getByGrafanaSelector(selectors.components.DashboardRow.title('Test row 2')).click();
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.RowsLayout.titleInput)
.fill('');
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.Sidebar.closePane).click();
// title should be set to a default name + 1 to avoid duplicates
await expect(
@@ -755,13 +755,13 @@ test.describe(
await expect(dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('New tab 2'))).toBeVisible();
// Go back to dashboard options
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click({ force: true });
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
// Expand layouts section
await page.getByLabel('Expand Group layout category').click();
// Select rows layout
await page.getByLabel('Rows').click();
await page.getByLabel('layout-selection-option-Rows').click();
await dashboardPage
.getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New tab 1'))
@@ -903,14 +903,14 @@ test.describe(
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.TabsLayout.titleInput)
.fill('Test tab 1');
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.Sidebar.closePane).click();
// clear the title input to simulate no title and click away to trigger onBlur
await dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('Test tab 1')).click();
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.TabsLayout.titleInput)
.fill('');
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.Sidebar.closePane).click();
// title should be set to a default name
await expect(dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('New tab'))).toBeVisible();
@@ -923,14 +923,14 @@ test.describe(
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.TabsLayout.titleInput)
.fill('Test tab 2');
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.Sidebar.closePane).click();
// clear the title input to simulate no title and click away to trigger onBlur
await dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('Test tab 2')).click();
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.TabsLayout.titleInput)
.fill('');
await dashboardPage.getByGrafanaSelector(selectors.components.EditPaneHeader.backButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.Sidebar.closePane).click();
// title should be set to a default name + 1 to avoid duplicates
await expect(dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('New tab 1'))).toBeVisible();
@@ -21,6 +21,7 @@ test.describe(
const dashboardPage = await gotoDashboardPage({ uid: PAGE_UNDER_TEST });
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.outlineButton).click();
// Should be able to click Variables item in outline to see add variable button
await dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.Outline.item('Variables')).click();
@@ -28,6 +29,8 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.addVariableButton)
).toBeVisible();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.outlineButton).click();
// Clicking a panel should scroll that panel in view
await expect(page.getByText('Dashboard panel 48')).toBeHidden();
await dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.Outline.item('Panel #48')).click();
@@ -22,6 +22,9 @@ test.describe(
const dashboardPage = await gotoDashboardPage({ uid: PAGE_UNDER_TEST });
await expect(page.getByText(DASHBOARD_NAME)).toBeVisible();
const undockButton = page.getByRole('button', { name: 'Undock menu' });
await undockButton.click();
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await page.evaluate(() => {
@@ -199,6 +199,7 @@ test.describe(
.click();
// Open the modal editor in the side pane
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.outlineButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.Outline.node('Variables')).click();
await dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.Outline.item('foo')).click();
await openModal(dashboardPage, selectors);
@@ -32,9 +32,9 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(3);
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await page.getByLabel('Expand Panel layout category').click();
await page.getByLabel('Auto grid').click();
await page.getByLabel('layout-selection-option-Auto grid').click();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
@@ -50,6 +50,7 @@ test.describe(
).toHaveCount(3);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await checkAutoGridLayoutInputs(dashboardPage, selectors);
});
@@ -63,9 +64,10 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(3);
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await page.getByLabel('Expand Panel layout category').click();
await page.getByLabel('Auto grid').click();
await page.getByLabel('layout-selection-option-Auto grid').click();
// Get initial positions - standard width should have panels on different rows
const firstPanelTop = await getPanelTop(dashboardPage, selectors);
@@ -98,6 +100,7 @@ test.describe(
await page.reload();
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await expect(
dashboardPage.getByGrafanaSelector(
@@ -123,9 +126,10 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(3);
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await page.getByLabel('Expand Panel layout category').click();
await page.getByLabel('Auto grid').click();
await page.getByLabel('layout-selection-option-Auto grid').click();
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.minColumnWidth)
@@ -134,7 +138,7 @@ test.describe(
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.customMinColumnWidth)
.fill('900');
.fill('1100');
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.customMinColumnWidth)
.blur();
@@ -148,12 +152,13 @@ test.describe(
await verifyPanelsStackedVertically(dashboardPage, selectors);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await expect(
dashboardPage.getByGrafanaSelector(
selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.customMinColumnWidth
)
).toHaveValue('900');
).toHaveValue('1100');
await verifyPanelsStackedVertically(dashboardPage, selectors);
@@ -180,9 +185,9 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(3);
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await page.getByLabel('Expand Panel layout category').click();
await page.getByLabel('Auto grid').click();
await page.getByLabel('layout-selection-option-Auto grid').click();
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.maxColumns)
@@ -198,6 +203,7 @@ test.describe(
await verifyPanelsStackedVertically(dashboardPage, selectors);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.maxColumns)
@@ -215,9 +221,9 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(3);
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await page.getByLabel('Expand Panel layout category').click();
await page.getByLabel('Auto grid').click();
await page.getByLabel('layout-selection-option-Auto grid').click();
const regularRowHeight = await getPanelHeight(dashboardPage, selectors);
@@ -250,6 +256,7 @@ test.describe(
}).toPass();
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.rowHeight)
@@ -270,9 +277,9 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(3);
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await page.getByLabel('Expand Panel layout category').click();
await page.getByLabel('Auto grid').click();
await page.getByLabel('layout-selection-option-Auto grid').click();
const regularRowHeight = await getPanelHeight(dashboardPage, selectors);
@@ -303,6 +310,7 @@ test.describe(
}).toPass();
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await expect(
dashboardPage.getByGrafanaSelector(
@@ -327,9 +335,9 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toHaveCount(3);
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await page.getByLabel('Expand Panel layout category').click();
await page.getByLabel('Auto grid').click();
await page.getByLabel('layout-selection-option-Auto grid').click();
// Set narrow column width first to ensure panels fit horizontally
await dashboardPage
@@ -357,6 +365,7 @@ test.describe(
}).toPass();
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.fillScreen)
@@ -37,9 +37,10 @@ test.describe(
},
() => {
test('can enable repeats', async ({ dashboardPage, selectors, page }) => {
await importTestDashboard(page, selectors, 'Auto grid repeats - add repeats');
await importTestDashboard(page, selectors, 'Auto-grid repeats - add repeats');
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await switchToAutoGrid(page);
@@ -70,11 +71,12 @@ test.describe(
await importTestDashboard(
page,
selectors,
'Auto grid repeats - update on variable change',
'Auto-grid repeats - update on variable change',
JSON.stringify(testV2DashWithRepeats)
);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await switchToAutoGrid(page);
await saveDashboard(dashboardPage, page, selectors);
@@ -113,6 +115,7 @@ test.describe(
);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await switchToAutoGrid(page);
@@ -138,11 +141,13 @@ test.describe(
await importTestDashboard(
page,
selectors,
'Auto grid repeats - update through panel editor',
'Auto-grid repeats - update through panel editor',
JSON.stringify(testV2DashWithRepeats)
);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await switchToAutoGrid(page);
await saveDashboard(dashboardPage, page, selectors);
await page.reload();
@@ -202,11 +207,13 @@ test.describe(
await importTestDashboard(
page,
selectors,
'Auto grid repeats - update through directly loaded panel editor',
'Auto-grid repeats - update through directly loaded panel editor',
JSON.stringify(testV2DashWithRepeats)
);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await switchToAutoGrid(page);
await saveDashboard(dashboardPage, page, selectors);
@@ -257,11 +264,12 @@ test.describe(
await importTestDashboard(
page,
selectors,
'Auto grid repeats - move repeated panels',
'Auto-grid repeats - move repeated panels',
JSON.stringify(testV2DashWithRepeats)
);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await switchToAutoGrid(page);
@@ -304,11 +312,13 @@ test.describe(
await importTestDashboard(
page,
selectors,
'Auto grid repeats - move repeated panels',
'Auto-grid repeats - move repeated panels 2',
JSON.stringify(testV2DashWithRepeats)
);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await switchToAutoGrid(page);
await saveDashboard(dashboardPage, page, selectors);
await page.reload();
@@ -332,9 +342,7 @@ test.describe(
const repeatedPanelUrl = page.url();
await dashboardPage
.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton)
.click();
await page.keyboard.press('Escape');
await dashboardPage
.getByGrafanaSelector(selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(0)}`))
@@ -367,11 +375,13 @@ test.describe(
await importTestDashboard(
page,
selectors,
'Auto grid repeats - view embedded repeated panel',
'Auto-grid repeats - view embedded repeated panel',
JSON.stringify(testV2DashWithRepeats)
);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await switchToAutoGrid(page);
await saveDashboard(dashboardPage, page, selectors);
await page.reload();
@@ -393,11 +403,13 @@ test.describe(
await importTestDashboard(
page,
selectors,
'Auto grid repeats - remove repeats',
'Auto-grid repeats - remove repeats',
JSON.stringify(testV2DashWithRepeats)
);
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
await switchToAutoGrid(page);
await saveDashboard(dashboardPage, page, selectors);
await page.reload();
@@ -453,5 +465,5 @@ test.describe(
async function switchToAutoGrid(page: Page) {
await page.getByLabel('Expand Panel layout category').click();
await page.getByLabel('Auto grid').click();
await page.getByLabel('layout-selection-option-Auto grid').click();
}
@@ -303,9 +303,7 @@ test.describe(
const repeatedPanelUrl = page.url();
await dashboardPage
.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton)
.click();
await page.keyboard.press('Escape');
await dashboardPage
.getByGrafanaSelector(selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(0)}`))
@@ -316,9 +316,7 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel'))
).toBeVisible();
await dashboardPage
.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton)
.click();
await page.keyboard.press('Escape');
// repeated panel in original tab repeat
await dashboardPage
@@ -341,9 +339,7 @@ test.describe(
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('Tab 1 - Row 2 - Panel repeat 2'))
).toBeVisible();
await dashboardPage
.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton)
.click();
await page.keyboard.press('Escape');
// repeated panel in repeated tab
await dashboardPage
@@ -21,11 +21,7 @@ test.describe(
const dashboardPage = await gotoDashboardPage({ uid: PAGE_UNDER_TEST });
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
// Check that current dashboard title is visible in breadcrumb
await expect(
dashboardPage.getByGrafanaSelector(selectors.components.Breadcrumbs.breadcrumb('Annotation filtering'))
).toBeVisible();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click();
const titleInput = page.locator('[aria-label="dashboard-options Title field property editor"] input');
await expect(titleInput).toHaveValue('Annotation filtering');
@@ -48,6 +48,7 @@ export const flows = {
},
async newEditPaneVariableClick(dashboardPage: DashboardPage, selectors: E2ESelectorGroups) {
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.outlineButton).click();
await dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.Outline.item('Variables')).click();
await dashboardPage
.getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.addVariableButton)