diff --git a/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx b/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx index c6685d5e09a..fcf4e26ada4 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx @@ -250,7 +250,7 @@ export class PanelEditorUnconnected extends PureComponent { } if (tableViewEnabled) { - return ; + return ; } return ( diff --git a/public/app/features/dashboard/components/PanelEditor/PanelEditorTableView.tsx b/public/app/features/dashboard/components/PanelEditor/PanelEditorTableView.tsx index 42ecc77740b..ebddedc2918 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelEditorTableView.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelEditorTableView.tsx @@ -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({ 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; } diff --git a/public/app/features/dashboard/dashgrid/PanelChrome.tsx b/public/app/features/dashboard/dashgrid/PanelChrome.tsx index 086d75bec42..0c5d542db1a 100644 --- a/public/app/features/dashboard/dashgrid/PanelChrome.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChrome.tsx @@ -240,21 +240,7 @@ export class PanelChrome extends Component { 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) => ({ diff --git a/public/app/features/dashboard/state/PanelModel.test.ts b/public/app/features/dashboard/state/PanelModel.test.ts index 6315ac68371..f95bb7ca598 100644 --- a/public/app/features/dashboard/state/PanelModel.test.ts +++ b/public/app/features/dashboard/state/PanelModel.test.ts @@ -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(); + }); + }); }); }); diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index ebdd84ab2b5..65383643ad3 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -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());