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
pull/35039/head
Maria Alexandra 4 years ago committed by GitHub
parent 22544bd135
commit ff03b456f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx
  2. 26
      public/app/features/dashboard/components/PanelEditor/PanelEditorTableView.tsx
  3. 16
      public/app/features/dashboard/dashgrid/PanelChrome.tsx
  4. 29
      public/app/features/dashboard/state/PanelModel.test.ts
  5. 20
      public/app/features/dashboard/state/PanelModel.ts

@ -250,7 +250,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
}
if (tableViewEnabled) {
return <PanelEditorTableView width={width} height={height} panel={panel} />;
return <PanelEditorTableView width={width} height={height} panel={panel} dashboard={dashboard} />;
}
return (

@ -1,23 +1,39 @@
import { PanelChrome } from '@grafana/ui';
import { PanelRenderer } from 'app/features/panel/PanelRenderer';
import React, { useState } from 'react';
import { PanelModel } from '../../state';
import React, { useEffect, useState } from 'react';
import { PanelModel, DashboardModel } from '../../state';
import { usePanelLatestData } from './usePanelLatestData';
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 {
width: number;
height: number;
panel: PanelModel;
dashboard: DashboardModel;
}
export function PanelEditorTableView({ width, height, panel }: Props) {
const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, true);
export function PanelEditorTableView({ width, height, panel, dashboard }: Props) {
const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, false);
const [options, setOptions] = useState<PanelOptions>({
frameIndex: 0,
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) {
return null;
}

@ -240,21 +240,7 @@ export class PanelChrome extends Component<Props, State> {
if (this.state.refreshWhenInView) {
this.setState({ refreshWhenInView: false });
}
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,
});
panel.runAllPanelQueries(this.props.dashboard.id, this.props.dashboard.getTimezone(), timeData, width);
} else {
// The panel should render on refresh as well if it doesn't have a query, like clock panel
this.setState((prevState) => ({

@ -7,6 +7,8 @@ import {
PanelProps,
standardEditorsRegistry,
standardFieldConfigEditorRegistry,
dateTime,
TimeRange,
} from '@grafana/data';
import { ComponentClass } from 'react';
import { PanelQueryRunner } from '../../query/state/PanelQueryRunner';
@ -17,6 +19,7 @@ import { variableAdapters } from '../../variables/adapters';
import { createQueryVariableAdapter } from '../../variables/query/adapter';
import { mockStandardFieldConfigOptions } from '../../../../test/helpers/fieldConfig';
import { queryBuilder } from 'app/features/variables/shared/testing/builders';
import { TimeOverrideResult } from '../utils/panel';
standardFieldConfigEditorRegistry.setInit(() => mockStandardFieldConfigOptions());
standardEditorsRegistry.setInit(() => mockStandardFieldConfigOptions());
@ -457,6 +460,32 @@ describe('PanelModel', () => {
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';
import { QueryGroupOptions } from 'app/types';
import { PanelModelLibraryPanel } from '../../library-panels/types';
export interface GridPos {
x: number;
y: number;
@ -47,6 +46,8 @@ export interface GridPos {
static?: boolean;
}
import { TimeOverrideResult } from '../utils/panel';
const notPersistedProperties: { [str: string]: boolean } = {
events: true,
isViewing: true,
@ -292,6 +293,23 @@ export class PanelModel implements DataConfigSource {
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() {
this.hasRefreshed = true;
this.events.publish(new RefreshEvent());

Loading…
Cancel
Save