diff --git a/packages/grafana-e2e-selectors/src/selectors/pages.ts b/packages/grafana-e2e-selectors/src/selectors/pages.ts index ac6a7e7e30f..cf0f9b53f2c 100644 --- a/packages/grafana-e2e-selectors/src/selectors/pages.ts +++ b/packages/grafana-e2e-selectors/src/selectors/pages.ts @@ -180,6 +180,13 @@ export const Pages = { Annotations: { marker: 'data-testid annotation-marker', }, + Rows: { + Repeated: { + ConfigSection: { + warningMessage: 'data-testid Repeated rows warning message', + }, + }, + }, }, Dashboards: { url: '/dashboards', diff --git a/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx b/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx index ae7153af8af..52cbaa67caa 100644 --- a/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx +++ b/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx @@ -2,6 +2,8 @@ import { screen, render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; +import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard/types'; + import { PanelModel } from '../../state/PanelModel'; import { DashboardRow } from './DashboardRow'; @@ -17,6 +19,7 @@ describe('DashboardRow', () => { canEdit: true, }, events: { subscribe: jest.fn() }, + getRowPanels: () => [], }; panel = new PanelModel({ collapsed: false }); @@ -67,4 +70,28 @@ describe('DashboardRow', () => { expect(screen.queryByRole('button', { name: 'Delete row' })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Row options' })).not.toBeInTheDocument(); }); + + it('Should return warning message when row panel has a panel with dashboard ds set', async () => { + const panel = new PanelModel({ + datasource: { + type: 'datasource', + uid: SHARED_DASHBOARD_QUERY, + }, + }); + const rowPanel = new PanelModel({ collapsed: true, panels: [panel] }); + const dashboardRow = new DashboardRow({ panel: rowPanel, dashboard: dashboardMock }); + expect(dashboardRow.getWarning()).toBeDefined(); + }); + + it('Should not return warning message when row panel does not have a panel with dashboard ds set', async () => { + const panel = new PanelModel({ + datasource: { + type: 'datasource', + uid: 'ds-uid', + }, + }); + const rowPanel = new PanelModel({ collapsed: true, panels: [panel] }); + const dashboardRow = new DashboardRow({ panel: rowPanel, dashboard: dashboardMock }); + expect(dashboardRow.getWarning()).not.toBeDefined(); + }); }); diff --git a/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx b/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx index 8ce01c3f128..a8f871d11a6 100644 --- a/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx +++ b/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx @@ -1,4 +1,5 @@ import classNames from 'classnames'; +import { indexOf } from 'lodash'; import React from 'react'; import { Unsubscribable } from 'rxjs'; @@ -6,6 +7,7 @@ import { selectors } from '@grafana/e2e-selectors'; import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; import { Icon } from '@grafana/ui'; import appEvents from 'app/core/app_events'; +import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard/types'; import { ShowConfirmModalEvent } from '../../../../types/events'; import { DashboardModel } from '../../state/DashboardModel'; @@ -38,6 +40,23 @@ export class DashboardRow extends React.Component { this.props.dashboard.toggleRow(this.props.panel); }; + getWarning = () => { + const panels = !!this.props.panel.panels?.length + ? this.props.panel.panels + : this.props.dashboard.getRowPanels(indexOf(this.props.dashboard.panels, this.props.panel)); + const isAnyPanelUsingDashboardDS = panels.some((p) => p.datasource?.uid === SHARED_DASHBOARD_QUERY); + if (isAnyPanelUsingDashboardDS) { + return ( +

+ Panels in this row use the {SHARED_DASHBOARD_QUERY} data source. These panels will reference the panel in the + original row, not the ones in the repeated rows. +

+ ); + } + + return undefined; + }; + onUpdate = (title: string, repeat?: string | null) => { this.props.panel.setProperty('title', title); this.props.panel.setProperty('repeat', repeat ?? undefined); @@ -94,6 +113,7 @@ export class DashboardRow extends React.Component { title={this.props.panel.title} repeat={this.props.panel.repeat} onUpdate={this.onUpdate} + warning={this.getWarning()} />