[v11.4.x] Dashboards: Fixes issue with panel header showing even when hide time override was enabled (#98747)

Dashboards: Fixes issue with panel header showing even when hide time override was enabled (#95814)

* Dashboards: Fixes issue with panel header showing even when hide time override was enabled


(cherry picked from commit 6fd3620d50)

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
Ivan Ortega Alba
2025-01-09 18:30:06 +01:00
committed by GitHub
co-authored by Torkel Ödegaard
parent dab5a49df0
commit ede278c767
6 changed files with 63 additions and 22 deletions
+1
View File
@@ -7,5 +7,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
@@ -425,6 +425,22 @@ describe('PanelDataQueriesTab', () => {
expect(panel.state.$timeRange).toBeInstanceOf(PanelTimeRange);
});
it('should update hoverHeader', async () => {
const { queriesTab, panel } = await setupScene('panel-1');
panel.setState({ title: '', hoverHeader: true });
panel.state.$data?.activate();
queriesTab.onQueryOptionsChange({
dataSource: { name: 'grafana-testdata', type: 'grafana-testdata-datasource', default: true },
queries: [],
timeRange: { from: '1h' },
});
expect(panel.state.hoverHeader).toBe(false);
});
it('should update PanelTimeRange object on time options update', async () => {
const { queriesTab, panel } = await setupScene('panel-1');
@@ -24,8 +24,9 @@ import { updateQueries } from 'app/features/query/state/updateQueries';
import { isSharedDashboardQuery } from 'app/plugins/datasource/dashboard';
import { QueryGroupOptions } from 'app/types';
import { PanelTimeRange, PanelTimeRangeState } from '../../scene/PanelTimeRange';
import { PanelTimeRange } from '../../scene/PanelTimeRange';
import { getDashboardSceneFor, getPanelIdForVizPanel, getQueryRunnerFor } from '../../utils/utils';
import { getUpdatedHoverHeader } from '../getPanelFrameOptions';
import { PanelDataPaneTab, TabId, PanelDataTabHeaderProps } from './types';
@@ -190,12 +191,11 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
};
public onQueryOptionsChange = (options: QueryGroupOptions) => {
const panelObj = this.state.panelRef.resolve();
const panel = this.state.panelRef.resolve();
const dataObj = this.queryRunner;
const timeRangeObj = panelObj.state.$timeRange;
const dataObjStateUpdate: Partial<SceneQueryRunner['state']> = {};
const timeRangeObjStateUpdate: Partial<PanelTimeRangeState> = {};
const panelStateUpdate: Partial<VizPanel['state']> = {};
if (options.maxDataPoints !== dataObj.state.maxDataPoints) {
dataObjStateUpdate.maxDataPoints = options.maxDataPoints ?? undefined;
@@ -205,23 +205,16 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
dataObjStateUpdate.minInterval = options.minInterval;
}
if (options.timeRange) {
timeRangeObjStateUpdate.timeFrom = options.timeRange.from ?? undefined;
timeRangeObjStateUpdate.timeShift = options.timeRange.shift ?? undefined;
timeRangeObjStateUpdate.hideTimeOverride = options.timeRange.hide;
}
const timeFrom = options.timeRange?.from ?? undefined;
const timeShift = options.timeRange?.shift ?? undefined;
const hideTimeOverride = options.timeRange?.hide;
if (timeRangeObj instanceof PanelTimeRange) {
if (timeRangeObjStateUpdate.timeFrom !== undefined || timeRangeObjStateUpdate.timeShift !== undefined) {
// update time override
timeRangeObj.setState(timeRangeObjStateUpdate);
} else {
// remove time override
panelObj.setState({ $timeRange: undefined });
}
if (timeFrom !== undefined || timeShift !== undefined) {
panelStateUpdate.$timeRange = new PanelTimeRange({ timeFrom, timeShift, hideTimeOverride });
panelStateUpdate.hoverHeader = getUpdatedHoverHeader(panel.state.title, panelStateUpdate.$timeRange);
} else {
// no time override present on the panel, let's create one first
panelObj.setState({ $timeRange: new PanelTimeRange(timeRangeObjStateUpdate) });
panelStateUpdate.$timeRange = undefined;
panelStateUpdate.hoverHeader = getUpdatedHoverHeader(panel.state.title, undefined);
}
if (options.cacheTimeout !== dataObj?.state.cacheTimeout) {
@@ -232,6 +225,8 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
dataObjStateUpdate.queryCachingTTL = options.queryCachingTTL;
}
panel.setState(panelStateUpdate);
dataObj.setState(dataObjStateUpdate);
dataObj.runQueries();
};
@@ -1,7 +1,7 @@
import { SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { config } from '@grafana/runtime';
import { SceneObjectState, VizPanel } from '@grafana/scenes';
import { SceneTimeRangeLike, SceneObjectState, VizPanel } from '@grafana/scenes';
import { DataLinksInlineEditor, Input, TextArea, Switch, RadioButtonGroup, Select } from '@grafana/ui';
import { GenAIPanelDescriptionButton } from 'app/features/dashboard/components/GenAI/GenAIPanelDescriptionButton';
import { GenAIPanelTitleButton } from 'app/features/dashboard/components/GenAI/GenAIPanelTitleButton';
@@ -12,6 +12,7 @@ import { getPanelLinksVariableSuggestions } from 'app/features/panel/panellinks/
import { DashboardGridItem } from '../scene/DashboardGridItem';
import { VizPanelLinks } from '../scene/PanelLinks';
import { PanelTimeRange } from '../scene/PanelTimeRange';
import { vizPanelToPanel, transformSceneToSaveModel } from '../serialization/transformSceneToSaveModel';
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
import { getDashboardSceneFor } from '../utils/utils';
@@ -209,5 +210,19 @@ function DescriptionTextArea({ panel }: { panel: VizPanel }) {
}
function setPanelTitle(panel: VizPanel, title: string) {
panel.setState({ title: title, hoverHeader: title === '' });
panel.setState({ title: title, hoverHeader: getUpdatedHoverHeader(title, panel.state.$timeRange) });
}
export function getUpdatedHoverHeader(title: string, timeRange: SceneTimeRangeLike | undefined): boolean {
if (title !== '') {
return false;
}
if (timeRange instanceof PanelTimeRange && !timeRange.state.hideTimeOverride) {
if (timeRange.state.timeFrom || timeRange.state.timeShift) {
return false;
}
}
return true;
}
@@ -585,6 +585,18 @@ describe('transformSaveModelToScene', () => {
expect(vizPanel.state.hoverHeader).toEqual(true);
});
it('should set hoverHeader to true if timeFrom and hideTimeOverride is true', () => {
const panel = {
type: 'test-plugin',
timeFrom: '2h',
hideTimeOverride: true,
};
const { vizPanel } = buildGridItemForTest(panel);
expect(vizPanel.state.hoverHeader).toBe(true);
});
it('should initalize the VizPanel with min interval set', () => {
const panel = {
title: '',
@@ -291,6 +291,8 @@ export function buildGridItemForPanel(panel: PanelModel): DashboardGridItem {
titleItems.push(new PanelNotices());
const timeOverrideShown = (panel.timeFrom || panel.timeShift) && !panel.hideTimeOverride;
const vizPanelState: VizPanelState = {
key: getVizPanelKeyForPanelId(panel.id),
title: panel.title,
@@ -301,7 +303,7 @@ export function buildGridItemForPanel(panel: PanelModel): DashboardGridItem {
pluginVersion: panel.pluginVersion,
displayMode: panel.transparent ? 'transparent' : undefined,
// To be replaced with it's own option persited option instead derived
hoverHeader: !panel.title && !panel.timeFrom && !panel.timeShift,
hoverHeader: !panel.title && !timeOverrideShown,
hoverHeaderOffset: 0,
$data: createPanelDataProvider(panel),
titleItems,