Commit 068fef8c by Torkel Ödegaard Committed by GitHub

QueryEditors: Refactoring & rewriting out dependency on PanelModel (#29419)

* Removing PanelModel usage from query rows

* More work removing dependency on panel model

* Before big change to query options

* Query options now have no dependency on panel model

* Test page is working

* Shared query now works again

* Rename component

* fix after merge

* Fixed issue with old angular editors
parent b8fec209
import React, { PureComponent } from 'react';
import { QueriesTab } from 'app/features/query/components/QueriesTab';
import { DashboardModel, PanelModel } from '../../state';
import { QueryGroup } from 'app/features/query/components/QueryGroup';
import { QueryGroupOptions } from 'app/features/query/components/QueryGroupOptions';
import { PanelModel } from '../../state';
import { DataQuery, DataSourceSelectItem } from '@grafana/data';
import { getLocationSrv } from '@grafana/runtime';
interface Props {
panel: PanelModel;
dashboard: DashboardModel;
}
export class PanelEditorQueries extends PureComponent<Props> {
interface State {
options: QueryGroupOptions;
}
export class PanelEditorQueries extends PureComponent<Props, State> {
constructor(props: Props) {
super(props);
this.state = { options: this.buildQueryOptions(props) };
}
buildQueryOptions({ panel }: Props): QueryGroupOptions {
return {
maxDataPoints: panel.maxDataPoints,
minInterval: panel.interval,
timeRange: {
from: panel.timeFrom,
shift: panel.timeShift,
hide: panel.hideTimeOverride,
},
};
}
onDataSourceChange = (ds: DataSourceSelectItem, queries: DataQuery[]) => {
const { panel } = this.props;
panel.datasource = ds.value;
panel.targets = queries;
panel.refresh();
this.forceUpdate();
};
onRunQueries = () => {
this.props.panel.refresh();
};
onQueriesChange = (queries: DataQuery[]) => {
const { panel } = this.props;
panel.targets = queries;
panel.refresh();
this.forceUpdate();
};
onOpenQueryInspector = () => {
getLocationSrv().update({
query: { inspect: this.props.panel.id, inspectTab: 'query' },
partial: true,
});
};
onQueryOptionsChange = (options: QueryGroupOptions) => {
const { panel } = this.props;
panel.timeFrom = options.timeRange?.from;
panel.timeShift = options.timeRange?.shift;
panel.hideTimeOverride = options.timeRange?.hide;
panel.interval = options.minInterval;
panel.maxDataPoints = options.maxDataPoints;
panel.refresh();
this.setState({ options: options });
};
render() {
const { panel, dashboard } = this.props;
const { panel } = this.props;
const { options } = this.state;
return <QueriesTab panel={panel} dashboard={dashboard} />;
return (
<QueryGroup
dataSourceName={panel.datasource}
options={options}
queryRunner={panel.getQueryRunner()}
queries={panel.targets}
onQueriesChange={this.onQueriesChange}
onDataSourceChange={this.onDataSourceChange}
onRunQueries={this.onRunQueries}
onOpenQueryInspector={this.onOpenQueryInspector}
onOptionsChange={this.onQueryOptionsChange}
/>
);
}
}
......@@ -76,7 +76,7 @@ export class PanelEditorTabs extends PureComponent<PanelEditorTabsProps> {
})}
</TabsBar>
<TabContent className={styles.tabContent}>
{activeTab.id === PanelEditorTabId.Query && <PanelEditorQueries panel={panel} dashboard={dashboard} />}
{activeTab.id === PanelEditorTabId.Query && <PanelEditorQueries panel={panel} />}
{activeTab.id === PanelEditorTabId.Alert && <AlertTab panel={panel} dashboard={dashboard} />}
{activeTab.id === PanelEditorTabId.Transform && <TransformationsEditor panel={panel} />}
</TabContent>
......
......@@ -132,8 +132,8 @@ export class PanelModel implements DataConfigSource {
};
fieldConfig: FieldConfigSource;
maxDataPoints?: number;
interval?: string;
maxDataPoints?: number | null;
interval?: string | null;
description?: string;
links?: DataLink[];
transparent: boolean;
......
......@@ -6,9 +6,6 @@ import _ from 'lodash';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { AngularComponent, getAngularLoader } from '@grafana/runtime';
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
// Types
import { PanelModel } from '../../dashboard/state/PanelModel';
import { ErrorBoundaryAlert, HorizontalGroup } from '@grafana/ui';
import {
DataQuery,
......@@ -25,12 +22,11 @@ import { QueryOperationRow } from 'app/core/components/QueryOperationRow/QueryOp
import { QueryOperationAction } from 'app/core/components/QueryOperationRow/QueryOperationAction';
import { DashboardModel } from '../../dashboard/state/DashboardModel';
import { selectors } from '@grafana/e2e-selectors';
import { PanelModel } from 'app/features/dashboard/state';
interface Props {
panel: PanelModel;
data: PanelData;
query: DataQuery;
dashboard?: DashboardModel;
dataSourceValue: string | null;
inMixedMode?: boolean;
id: string;
......@@ -38,6 +34,7 @@ interface Props {
onAddQuery: (query?: DataQuery) => void;
onRemoveQuery: (query: DataQuery) => void;
onChange: (query: DataQuery) => void;
onRunQuery: () => void;
}
interface State {
......@@ -72,15 +69,20 @@ export class QueryEditorRow extends PureComponent<Props, State> {
}
getAngularQueryComponentScope(): AngularQueryComponentScope {
const { panel, query, dashboard } = this.props;
const { query, onChange } = this.props;
const { datasource } = this.state;
const panel = new PanelModel({});
const dashboard = {} as DashboardModel;
return {
datasource: datasource,
target: query,
panel: panel,
dashboard: dashboard!,
refresh: () => panel.refresh(),
dashboard: dashboard,
refresh: () => {
// Old angular editors modify the query model and just call refresh
onChange(query);
},
render: () => () => console.log('legacy render function called, it does nothing'),
events: panel.events,
range: getTimeSrv().timeRange(),
......@@ -88,12 +90,12 @@ export class QueryEditorRow extends PureComponent<Props, State> {
}
async loadDatasource() {
const { query, panel, dataSourceValue } = this.props;
const { query, dataSourceValue } = this.props;
const dataSourceSrv = getDatasourceSrv();
let datasource;
try {
const datasourceName = dataSourceValue || query.datasource || panel.datasource;
const datasourceName = dataSourceValue || query.datasource;
datasource = await dataSourceSrv.get(datasourceName);
} catch (error) {
datasource = await dataSourceSrv.get();
......@@ -108,7 +110,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
componentDidUpdate(prevProps: Props) {
const { loadedDataSourceValue } = this.state;
const { data, query, panel } = this.props;
const { data, query } = this.props;
if (data !== prevProps.data) {
this.setState({ data: filterPanelDataToQuery(data, query.refId) });
......@@ -118,7 +120,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
}
if (this.angularQueryEditor) {
notifyAngularQueryEditorsOfData(panel, data, this.angularQueryEditor);
notifyAngularQueryEditorsOfData(this.angularScope?.panel!, data, this.angularQueryEditor);
}
}
......@@ -161,7 +163,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
};
onRunQuery = () => {
this.props.panel.refresh();
this.props.onRunQuery();
};
renderPluginEditor = () => {
......
......@@ -2,11 +2,8 @@
import React, { PureComponent } from 'react';
// Types
import { PanelModel } from '../../dashboard/state/PanelModel';
import { DataQuery, PanelData, DataSourceSelectItem } from '@grafana/data';
import { DashboardModel } from '../../dashboard/state/DashboardModel';
import { QueryEditorRow } from './QueryEditorRow';
import { addQuery } from 'app/core/utils/query';
import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd';
interface Props {
......@@ -15,35 +12,21 @@ interface Props {
datasource: DataSourceSelectItem;
// Query editing
onChangeQueries: (queries: DataQuery[]) => void;
onScrollBottom: () => void;
// Dashboard Configs
panel: PanelModel;
dashboard?: DashboardModel;
onQueriesChange: (queries: DataQuery[]) => void;
onAddQuery: (query: DataQuery) => void;
onRunQueries: () => void;
// Query Response Data
data: PanelData;
}
export class QueryEditorRows extends PureComponent<Props> {
onAddQuery = (query?: Partial<DataQuery>) => {
const { queries, onChangeQueries } = this.props;
onChangeQueries(addQuery(queries, query));
this.props.onScrollBottom();
};
onRemoveQuery = (query: DataQuery) => {
const { queries, onChangeQueries, panel } = this.props;
const removed = queries.filter(q => {
return q !== query;
});
onChangeQueries(removed);
panel.refresh();
this.props.onQueriesChange(this.props.queries.filter(item => item !== query));
};
onChangeQuery(query: DataQuery, index: number) {
const { queries, onChangeQueries } = this.props;
const { queries, onQueriesChange } = this.props;
const old = queries[index];
......@@ -54,7 +37,7 @@ export class QueryEditorRows extends PureComponent<Props> {
}
// update query in array
onChangeQueries(
onQueriesChange(
queries.map((item, itemIndex) => {
if (itemIndex === index) {
return query;
......@@ -65,7 +48,7 @@ export class QueryEditorRows extends PureComponent<Props> {
}
onDragEnd = (result: DropResult) => {
const { queries, onChangeQueries, panel } = this.props;
const { queries, onQueriesChange } = this.props;
if (!result || !result.destination) {
return;
......@@ -80,12 +63,12 @@ export class QueryEditorRows extends PureComponent<Props> {
const update = Array.from(queries);
const [removed] = update.splice(startIndex, 1);
update.splice(endIndex, 0, removed);
onChangeQueries(update);
panel.refresh();
onQueriesChange(update);
};
render() {
const { props } = this;
return (
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId="transformations-list" direction="vertical">
......@@ -98,13 +81,12 @@ export class QueryEditorRows extends PureComponent<Props> {
id={query.refId}
index={index}
key={query.refId}
panel={props.panel}
dashboard={props.dashboard}
data={props.data}
query={query}
onChange={query => this.onChangeQuery(query, index)}
onRemoveQuery={this.onRemoveQuery}
onAddQuery={this.onAddQuery}
onAddQuery={this.props.onAddQuery}
onRunQuery={this.props.onRunQueries}
inMixedMode={props.datasource.meta.mixed}
/>
))}
......
......@@ -2,17 +2,14 @@
import React, { PureComponent } from 'react';
// Components
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
import { QueryOptions } from './QueryOptions';
import { Button, CustomScrollbar, HorizontalGroup, Modal, stylesFactory, Field } from '@grafana/ui';
import { getLocationSrv, getDataSourceSrv } from '@grafana/runtime';
import { getDataSourceSrv } from '@grafana/runtime';
import { QueryEditorRows } from './QueryEditorRows';
// Services
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { backendSrv } from 'app/core/services/backend_srv';
import config from 'app/core/config';
// Types
import { PanelModel } from '../../dashboard/state/PanelModel';
import { DashboardModel } from '../../dashboard/state/DashboardModel';
import {
DataQuery,
DataSourceSelectItem,
......@@ -24,14 +21,23 @@ import {
import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp';
import { addQuery } from 'app/core/utils/query';
import { Unsubscribable } from 'rxjs';
import { DashboardQueryEditor, isSharedDashboardQuery } from 'app/plugins/datasource/dashboard';
import { expressionDatasource, ExpressionDatasourceID } from 'app/features/expressions/ExpressionDatasource';
import { css } from 'emotion';
import { selectors } from '@grafana/e2e-selectors';
import { PanelQueryRunner } from '../state/PanelQueryRunner';
import { QueryGroupOptions, QueryGroupOptionsEditor } from './QueryGroupOptions';
import { DashboardQueryEditor, isSharedDashboardQuery } from 'app/plugins/datasource/dashboard';
import { css } from 'emotion';
interface Props {
panel: PanelModel;
dashboard?: DashboardModel;
queryRunner: PanelQueryRunner;
queries: DataQuery[];
dataSourceName: string | null;
options: QueryGroupOptions;
onOpenQueryInspector?: () => void;
onRunQueries: () => void;
onQueriesChange: (queries: DataQuery[]) => void;
onDataSourceChange: (ds: DataSourceSelectItem, queries: DataQuery[]) => void;
onOptionsChange: (options: QueryGroupOptions) => void;
}
interface State {
......@@ -47,14 +53,14 @@ interface State {
isHelpOpen: boolean;
}
export class QueriesTab extends PureComponent<Props, State> {
export class QueryGroup extends PureComponent<Props, State> {
datasources: DataSourceSelectItem[] = getDatasourceSrv().getMetricSources();
backendSrv = backendSrv;
querySubscription: Unsubscribable | null;
state: State = {
isLoadingHelp: false,
dataSourceItem: this.findCurrentDataSource(),
dataSourceItem: this.findCurrentDataSource(this.props.dataSourceName),
helpContent: null,
isPickerOpen: false,
isAddingMixed: false,
......@@ -68,15 +74,14 @@ export class QueriesTab extends PureComponent<Props, State> {
};
async componentDidMount() {
const { panel } = this.props;
const queryRunner = panel.getQueryRunner();
const { queryRunner, dataSourceName: datasourceName } = this.props;
this.querySubscription = queryRunner.getData({ withTransforms: false, withFieldConfig: false }).subscribe({
next: (data: PanelData) => this.onPanelDataUpdate(data),
});
try {
const ds = await getDataSourceSrv().get(panel.datasource);
const ds = await getDataSourceSrv().get(datasourceName);
this.setState({ dataSource: ds });
} catch (error) {
const ds = await getDataSourceSrv().get();
......@@ -96,85 +101,62 @@ export class QueriesTab extends PureComponent<Props, State> {
this.setState({ data });
}
findCurrentDataSource(dataSourceName: string | null = this.props.panel.datasource): DataSourceSelectItem {
findCurrentDataSource(dataSourceName: string | null): DataSourceSelectItem {
return this.datasources.find(datasource => datasource.value === dataSourceName) || this.datasources[0];
}
onChangeDataSource = async (newDsItem: DataSourceSelectItem) => {
const { panel } = this.props;
let { queries } = this.props;
const { dataSourceItem } = this.state;
// switching to mixed
if (newDsItem.meta.mixed) {
// Set the datasource on all targets
panel.targets.forEach(target => {
if (target.datasource !== ExpressionDatasourceID) {
target.datasource = panel.datasource;
if (!target.datasource) {
target.datasource = config.defaultDatasource;
for (const query of queries) {
if (query.datasource !== ExpressionDatasourceID) {
query.datasource = query.datasource;
if (!query.datasource) {
query.datasource = config.defaultDatasource;
}
}
}
});
} else if (dataSourceItem) {
// if switching from mixed
if (dataSourceItem.meta.mixed) {
// Remove the explicit datasource
for (const target of panel.targets) {
if (target.datasource !== ExpressionDatasourceID) {
delete target.datasource;
for (const query of queries) {
if (query.datasource !== ExpressionDatasourceID) {
delete query.datasource;
}
}
} else if (dataSourceItem.meta.id !== newDsItem.meta.id) {
// we are changing data source type, clear queries
panel.targets = [{ refId: 'A' }];
queries = [{ refId: 'A' }];
}
}
const dataSource = await getDataSourceSrv().get(newDsItem.value);
panel.datasource = newDsItem.value;
this.props.onDataSourceChange(newDsItem, queries);
this.setState(
{
this.setState({
dataSourceItem: newDsItem,
dataSource: dataSource,
dataSourceError: undefined,
},
() => panel.refresh()
);
};
openQueryInspector = () => {
const { panel } = this.props;
getLocationSrv().update({
query: { inspect: panel.id, inspectTab: 'query' },
partial: true,
});
};
/**
* Sets the queries for the panel
*/
onUpdateQueries = (queries: DataQuery[]) => {
this.props.panel.updateQueries(queries);
// Need to force update to rerender query rows.
this.forceUpdate();
};
onAddQueryClick = () => {
if (this.state.dataSourceItem.meta.mixed) {
this.setState({ isAddingMixed: true });
return;
}
this.onUpdateQueries(addQuery(this.props.panel.targets));
this.props.onQueriesChange(addQuery(this.props.queries));
this.onScrollBottom();
};
onAddExpressionClick = () => {
this.onUpdateQueries(addQuery(this.props.panel.targets, expressionDatasource.newQuery()));
this.props.onQueriesChange(addQuery(this.props.queries, expressionDatasource.newQuery()));
this.onScrollBottom();
};
......@@ -183,8 +165,8 @@ export class QueriesTab extends PureComponent<Props, State> {
};
renderTopSection(styles: QueriesTabStyls) {
const { panel } = this.props;
const { dataSourceItem, data, dataSource, dataSourceError } = this.state;
const { onOpenQueryInspector, options, onOptionsChange } = this.props;
const { dataSourceItem, dataSource, dataSourceError, data } = this.state;
if (!dataSource) {
return null;
......@@ -211,17 +193,19 @@ export class QueriesTab extends PureComponent<Props, State> {
/>
</div>
<div className={styles.dataSourceRowItemOptions}>
<QueryOptions panel={panel} dataSource={dataSource} data={data} />
<QueryGroupOptionsEditor options={options} dataSource={dataSource} data={data} onChange={onOptionsChange} />
</div>
{onOpenQueryInspector && (
<div className={styles.dataSourceRowItem}>
<Button
variant="secondary"
onClick={this.openQueryInspector}
onClick={onOpenQueryInspector}
aria-label={selectors.components.QueryTab.queryInspectorButton}
>
Query inspector
</Button>
</div>
)}
</div>
</div>
);
......@@ -253,18 +237,18 @@ export class QueriesTab extends PureComponent<Props, State> {
};
onAddMixedQuery = (datasource: any) => {
this.props.panel.targets = addQuery(this.props.panel.targets, { datasource: datasource.name });
this.onAddQuery({ datasource: datasource.name });
this.setState({ isAddingMixed: false, scrollTop: this.state.scrollTop + 10000 });
this.forceUpdate();
};
onMixedPickerBlur = () => {
this.setState({ isAddingMixed: false });
};
onQueryChange = (query: DataQuery, index: number) => {
this.props.panel.changeQuery(query, index);
this.forceUpdate();
onAddQuery = (query: Partial<DataQuery>) => {
const { queries, onQueriesChange } = this.props;
onQueriesChange(addQuery(queries, query));
this.onScrollBottom();
};
setScrollTop = (event: React.MouseEvent<HTMLElement>) => {
......@@ -273,22 +257,21 @@ export class QueriesTab extends PureComponent<Props, State> {
};
renderQueries() {
const { panel, dashboard } = this.props;
const { onQueriesChange, queries, onRunQueries } = this.props;
const { dataSourceItem, data } = this.state;
if (isSharedDashboardQuery(dataSourceItem.name)) {
return <DashboardQueryEditor panel={panel} panelData={data} onChange={query => this.onUpdateQueries([query])} />;
return <DashboardQueryEditor queries={queries} panelData={data} onChange={onQueriesChange} />;
}
return (
<div aria-label={selectors.components.QueryTab.content}>
<QueryEditorRows
queries={panel.targets}
queries={queries}
datasource={dataSourceItem}
onChangeQueries={this.onUpdateQueries}
onScrollBottom={this.onScrollBottom}
panel={panel}
dashboard={dashboard}
onQueriesChange={onQueriesChange}
onAddQuery={this.onAddQuery}
onRunQueries={onRunQueries}
data={data}
/>
</div>
......
......@@ -34,7 +34,7 @@ export interface QueryRunnerOptions<
> {
datasource: string | DataSourceApi<TQuery, TOptions> | null;
queries: TQuery[];
panelId: number;
panelId?: number;
dashboardId?: number;
timezone: TimeZone;
timeRange: TimeRange;
......
import { EventBusExtended } from '@grafana/data';
export interface PanelModelForLegacyQueryEditors {
events: EventBusExtended;
}
import React, { FC, useState } from 'react';
import { PanelModel } from '../dashboard/state';
import { QueriesTab } from '../query/components/QueriesTab';
import {
ApplyFieldOverrideOptions,
DataQuery,
DataSourceSelectItem,
DataTransformerConfig,
dateMath,
FieldColorModeId,
PanelData,
} from '@grafana/data';
import { GraphNG, Table } from '@grafana/ui';
import { config } from 'app/core/config';
import React, { FC, useMemo, useState } from 'react';
import { useObservable } from 'react-use';
import { QueryGroup } from '../query/components/QueryGroup';
import { QueryGroupOptions } from '../query/components/QueryGroupOptions';
import { PanelQueryRunner } from '../query/state/PanelQueryRunner';
interface State {
panel: PanelModel;
queries: DataQuery[];
queryRunner: PanelQueryRunner;
dataSourceName: string | null;
queryOptions: QueryGroupOptions;
data?: PanelData;
}
export const TestStuffPage: FC = () => {
const [state] = useState<State>(getDefaultState());
const [state, setState] = useState<State>(getDefaultState());
const { queryOptions, queryRunner, queries, dataSourceName } = state;
const onDataSourceChange = (ds: DataSourceSelectItem, queries: DataQuery[]) => {
setState({
...state,
dataSourceName: ds.value,
queries: queries,
});
};
const onRunQueries = () => {
const timeRange = { from: 'now-1h', to: 'now' };
queryRunner.run({
queries,
timezone: 'browser',
datasource: dataSourceName,
timeRange: { from: dateMath.parse(timeRange.from)!, to: dateMath.parse(timeRange.to)!, raw: timeRange },
maxDataPoints: queryOptions.maxDataPoints ?? 100,
minInterval: queryOptions.minInterval,
});
};
const onQueriesChange = (queries: DataQuery[]) => {
setState({ ...state, queries: queries });
};
const onQueryOptionsChange = (queryOptions: QueryGroupOptions) => {
setState({ ...state, queryOptions });
};
/**
* Subscribe to data
*/
const observable = useMemo(() => queryRunner.getData({ withFieldConfig: true, withTransforms: true }), []);
const data = useObservable(observable);
return (
<div style={{ padding: '50px', height: '100%', flexGrow: 1 }} className="page-scrollbar-wrapper">
<h2>Hello</h2>
<div style={{ padding: '30px 50px' }} className="page-scrollbar-wrapper">
<h3>New page</h3>
<div>
<QueryGroup
options={queryOptions}
dataSourceName={dataSourceName}
queryRunner={queryRunner}
queries={queries}
onDataSourceChange={onDataSourceChange}
onRunQueries={onRunQueries}
onQueriesChange={onQueriesChange}
onOptionsChange={onQueryOptionsChange}
/>
</div>
<QueriesTab panel={state.panel} />
{data && (
<div style={{ padding: '16px' }}>
<GraphNG width={1200} height={300} data={data.series} timeRange={data.timeRange} timeZone="browser" />
<hr></hr>
<Table data={data.series[0]} width={1200} height={300} />
</div>
)}
</div>
);
};
export function getDefaultState(): State {
const panel = new PanelModel({
datasource: 'gdev-testdata',
id: 10,
targets: [],
});
const options: ApplyFieldOverrideOptions = {
fieldConfig: {
defaults: {
color: {
mode: FieldColorModeId.PaletteClassic,
},
},
overrides: [],
},
replaceVariables: (v: string) => v,
theme: config.theme,
};
const dataConfig = {
getTransformations: () => [] as DataTransformerConfig[],
getFieldOverrideOptions: () => options,
};
return {
panel,
queries: [],
dataSourceName: 'gdev-testdata',
queryRunner: new PanelQueryRunner(dataConfig),
queryOptions: {
maxDataPoints: 100,
},
};
}
......
......@@ -28,9 +28,9 @@ function getQueryDisplayText(query: DataQuery): string {
}
interface Props {
panel: PanelModel;
queries: DataQuery[];
panelData: PanelData;
onChange: (query: DashboardQuery) => void;
onChange: (queries: DataQuery[]) => void;
}
type State = {
......@@ -48,8 +48,7 @@ export class DashboardQueryEditor extends PureComponent<Props, State> {
}
getQuery(): DashboardQuery {
const { panel } = this.props;
return panel.targets[0] as DashboardQuery;
return this.props.queries[0] as DashboardQuery;
}
async componentDidMount() {
......@@ -57,10 +56,14 @@ export class DashboardQueryEditor extends PureComponent<Props, State> {
}
async componentDidUpdate(prevProps: Props) {
const { panelData } = this.props;
const { panelData, queries } = this.props;
if (queries.length < 0) {
return;
}
if (!prevProps || prevProps.panelData !== panelData) {
const query = this.props.panel.targets[0] as DashboardQuery;
const query = queries[0] as DashboardQuery;
const defaultDS = await getDatasourceSrv().get();
const dashboard = getDashboardSrv().getCurrent();
const panel = dashboard.getPanelById(query.panelId ?? -124134);
......@@ -97,10 +100,7 @@ export class DashboardQueryEditor extends PureComponent<Props, State> {
const { onChange } = this.props;
const query = this.getQuery();
query.panelId = id;
onChange(query);
// Update the
this.props.panel.refresh();
onChange([query]);
};
renderQueryData(editURL: string) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment