mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard: Fix Table view when editing causes the panel data to not update (#34998)
* Dashboard: Fix Table view when editing causes the panel data to not update - Add event subscription on PanelEditorTableView - Extract runAllPanelQueries into Panel Model in order to use it on PanelChrome and PanelEditorTableView - Add simple unit test for runAllQueryPaneQueries
This commit is contained in:
parent
22544bd135
commit
ff03b456f1
@ -250,7 +250,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tableViewEnabled) {
|
if (tableViewEnabled) {
|
||||||
return <PanelEditorTableView width={width} height={height} panel={panel} />;
|
return <PanelEditorTableView width={width} height={height} panel={panel} dashboard={dashboard} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,23 +1,39 @@
|
|||||||
import { PanelChrome } from '@grafana/ui';
|
import { PanelChrome } from '@grafana/ui';
|
||||||
import { PanelRenderer } from 'app/features/panel/PanelRenderer';
|
import { PanelRenderer } from 'app/features/panel/PanelRenderer';
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { PanelModel } from '../../state';
|
import { PanelModel, DashboardModel } from '../../state';
|
||||||
import { usePanelLatestData } from './usePanelLatestData';
|
import { usePanelLatestData } from './usePanelLatestData';
|
||||||
import { PanelOptions } from 'app/plugins/panel/table/models.gen';
|
import { PanelOptions } from 'app/plugins/panel/table/models.gen';
|
||||||
|
import { RefreshEvent } from 'app/types/events';
|
||||||
|
import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel';
|
||||||
|
import { getTimeSrv, TimeSrv } from '../../services/TimeSrv';
|
||||||
interface Props {
|
interface Props {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
|
dashboard: DashboardModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PanelEditorTableView({ width, height, panel }: Props) {
|
export function PanelEditorTableView({ width, height, panel, dashboard }: Props) {
|
||||||
const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, true);
|
const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, false);
|
||||||
const [options, setOptions] = useState<PanelOptions>({
|
const [options, setOptions] = useState<PanelOptions>({
|
||||||
frameIndex: 0,
|
frameIndex: 0,
|
||||||
showHeader: true,
|
showHeader: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Subscribe to panel event
|
||||||
|
useEffect(() => {
|
||||||
|
const timeSrv: TimeSrv = getTimeSrv();
|
||||||
|
const timeData = applyPanelTimeOverrides(panel, timeSrv.timeRange());
|
||||||
|
|
||||||
|
const sub = panel.events.subscribe(RefreshEvent, () => {
|
||||||
|
panel.runAllPanelQueries(dashboard.id, dashboard.getTimezone(), timeData, width);
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
sub.unsubscribe();
|
||||||
|
};
|
||||||
|
}, [panel, dashboard, width]);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -240,21 +240,7 @@ export class PanelChrome extends Component<Props, State> {
|
|||||||
if (this.state.refreshWhenInView) {
|
if (this.state.refreshWhenInView) {
|
||||||
this.setState({ refreshWhenInView: false });
|
this.setState({ refreshWhenInView: false });
|
||||||
}
|
}
|
||||||
|
panel.runAllPanelQueries(this.props.dashboard.id, this.props.dashboard.getTimezone(), timeData, width);
|
||||||
panel.getQueryRunner().run({
|
|
||||||
datasource: panel.datasource,
|
|
||||||
queries: panel.targets,
|
|
||||||
panelId: panel.editSourceId || panel.id,
|
|
||||||
dashboardId: this.props.dashboard.id,
|
|
||||||
timezone: this.props.dashboard.getTimezone(),
|
|
||||||
timeRange: timeData.timeRange,
|
|
||||||
timeInfo: timeData.timeInfo,
|
|
||||||
maxDataPoints: panel.maxDataPoints || width,
|
|
||||||
minInterval: panel.interval,
|
|
||||||
scopedVars: panel.scopedVars,
|
|
||||||
cacheTimeout: panel.cacheTimeout,
|
|
||||||
transformations: panel.transformations,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// The panel should render on refresh as well if it doesn't have a query, like clock panel
|
// The panel should render on refresh as well if it doesn't have a query, like clock panel
|
||||||
this.setState((prevState) => ({
|
this.setState((prevState) => ({
|
||||||
|
@ -7,6 +7,8 @@ import {
|
|||||||
PanelProps,
|
PanelProps,
|
||||||
standardEditorsRegistry,
|
standardEditorsRegistry,
|
||||||
standardFieldConfigEditorRegistry,
|
standardFieldConfigEditorRegistry,
|
||||||
|
dateTime,
|
||||||
|
TimeRange,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { ComponentClass } from 'react';
|
import { ComponentClass } from 'react';
|
||||||
import { PanelQueryRunner } from '../../query/state/PanelQueryRunner';
|
import { PanelQueryRunner } from '../../query/state/PanelQueryRunner';
|
||||||
@ -17,6 +19,7 @@ import { variableAdapters } from '../../variables/adapters';
|
|||||||
import { createQueryVariableAdapter } from '../../variables/query/adapter';
|
import { createQueryVariableAdapter } from '../../variables/query/adapter';
|
||||||
import { mockStandardFieldConfigOptions } from '../../../../test/helpers/fieldConfig';
|
import { mockStandardFieldConfigOptions } from '../../../../test/helpers/fieldConfig';
|
||||||
import { queryBuilder } from 'app/features/variables/shared/testing/builders';
|
import { queryBuilder } from 'app/features/variables/shared/testing/builders';
|
||||||
|
import { TimeOverrideResult } from '../utils/panel';
|
||||||
|
|
||||||
standardFieldConfigEditorRegistry.setInit(() => mockStandardFieldConfigOptions());
|
standardFieldConfigEditorRegistry.setInit(() => mockStandardFieldConfigOptions());
|
||||||
standardEditorsRegistry.setInit(() => mockStandardFieldConfigOptions());
|
standardEditorsRegistry.setInit(() => mockStandardFieldConfigOptions());
|
||||||
@ -457,6 +460,32 @@ describe('PanelModel', () => {
|
|||||||
expect(title).toEqual('Multi value variable A + B A + B %7BA%2CB%7D');
|
expect(title).toEqual('Multi value variable A + B A + B %7BA%2CB%7D');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('runAllPanelQueries', () => {
|
||||||
|
it('when called then it should call all pending queries', () => {
|
||||||
|
model.getQueryRunner = jest.fn().mockReturnValue({
|
||||||
|
run: jest.fn(),
|
||||||
|
});
|
||||||
|
const dashboardId = 123;
|
||||||
|
const dashboardTimezone = 'browser';
|
||||||
|
const width = 860;
|
||||||
|
const timeData = {
|
||||||
|
timeInfo: '',
|
||||||
|
timeRange: {
|
||||||
|
from: dateTime([2019, 1, 11, 12, 0]),
|
||||||
|
to: dateTime([2019, 1, 11, 18, 0]),
|
||||||
|
raw: {
|
||||||
|
from: 'now-6h',
|
||||||
|
to: 'now',
|
||||||
|
},
|
||||||
|
} as TimeRange,
|
||||||
|
} as TimeOverrideResult;
|
||||||
|
|
||||||
|
model.runAllPanelQueries(dashboardId, dashboardTimezone, timeData, width);
|
||||||
|
|
||||||
|
expect(model.getQueryRunner).toBeCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@ import {
|
|||||||
} from './getPanelOptionsWithDefaults';
|
} from './getPanelOptionsWithDefaults';
|
||||||
import { QueryGroupOptions } from 'app/types';
|
import { QueryGroupOptions } from 'app/types';
|
||||||
import { PanelModelLibraryPanel } from '../../library-panels/types';
|
import { PanelModelLibraryPanel } from '../../library-panels/types';
|
||||||
|
|
||||||
export interface GridPos {
|
export interface GridPos {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
@ -47,6 +46,8 @@ export interface GridPos {
|
|||||||
static?: boolean;
|
static?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import { TimeOverrideResult } from '../utils/panel';
|
||||||
|
|
||||||
const notPersistedProperties: { [str: string]: boolean } = {
|
const notPersistedProperties: { [str: string]: boolean } = {
|
||||||
events: true,
|
events: true,
|
||||||
isViewing: true,
|
isViewing: true,
|
||||||
@ -292,6 +293,23 @@ export class PanelModel implements DataConfigSource {
|
|||||||
this.gridPos.h = newPos.h;
|
this.gridPos.h = newPos.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runAllPanelQueries(dashboardId: number, dashboardTimezone: string, timeData: TimeOverrideResult, width: number) {
|
||||||
|
this.getQueryRunner().run({
|
||||||
|
datasource: this.datasource,
|
||||||
|
queries: this.targets,
|
||||||
|
panelId: this.editSourceId || this.id,
|
||||||
|
dashboardId: dashboardId,
|
||||||
|
timezone: dashboardTimezone,
|
||||||
|
timeRange: timeData.timeRange,
|
||||||
|
timeInfo: timeData.timeInfo,
|
||||||
|
maxDataPoints: this.maxDataPoints || width,
|
||||||
|
minInterval: this.interval,
|
||||||
|
scopedVars: this.scopedVars,
|
||||||
|
cacheTimeout: this.cacheTimeout,
|
||||||
|
transformations: this.transformations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.hasRefreshed = true;
|
this.hasRefreshed = true;
|
||||||
this.events.publish(new RefreshEvent());
|
this.events.publish(new RefreshEvent());
|
||||||
|
Loading…
Reference in New Issue
Block a user