From 060fab8f1c26fe88a7dde7bebe6bf0c8fa374248 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Fri, 18 Oct 2019 13:09:55 +0200 Subject: [PATCH] QueryEditor: move QueryEditorRows to its own component (#19756) --- public/app/core/utils/query.ts | 6 ++ .../dashboard/panel_editor/QueriesTab.tsx | 100 ++++++++---------- .../panel_editor/QueryEditorRows.tsx | 96 +++++++++++++++++ 3 files changed, 148 insertions(+), 54 deletions(-) create mode 100644 public/app/features/dashboard/panel_editor/QueryEditorRows.tsx diff --git a/public/app/core/utils/query.ts b/public/app/core/utils/query.ts index 933a73138a8..487653b0880 100644 --- a/public/app/core/utils/query.ts +++ b/public/app/core/utils/query.ts @@ -10,3 +10,9 @@ export const getNextRefIdChar = (queries: DataQuery[]): string => { }); }); }; + +export function addQuery(queries: DataQuery[], query?: Partial): DataQuery[] { + const q = query || {}; + q.refId = getNextRefIdChar(queries); + return [...queries, q as DataQuery]; +} diff --git a/public/app/features/dashboard/panel_editor/QueriesTab.tsx b/public/app/features/dashboard/panel_editor/QueriesTab.tsx index 4ecf0bc612e..b4359ed65ea 100644 --- a/public/app/features/dashboard/panel_editor/QueriesTab.tsx +++ b/public/app/features/dashboard/panel_editor/QueriesTab.tsx @@ -16,7 +16,7 @@ import { AlphaNotice, PluginState, } from '@grafana/ui'; -import { QueryEditorRow } from './QueryEditorRow'; +import { QueryEditorRows } from './QueryEditorRows'; // Services import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getBackendSrv } from 'app/core/services/backend_srv'; @@ -26,6 +26,7 @@ import { PanelModel } from '../state/PanelModel'; import { DashboardModel } from '../state/DashboardModel'; import { LoadingState, DataTransformerConfig, DefaultTimeRange } from '@grafana/data'; import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp'; +import { addQuery } from 'app/core/utils/query'; import { Unsubscribable } from 'rxjs'; import { isSharedDashboardQuery, DashboardQueryEditor } from 'app/plugins/datasource/dashboard'; @@ -88,12 +89,13 @@ export class QueriesTab extends PureComponent { return this.datasources.find(datasource => datasource.value === panel.datasource) || this.datasources[0]; } - onChangeDataSource = (datasource: any) => { + onChangeDataSource = (datasource: DataSourceSelectItem) => { const { panel } = this.props; const { currentDS } = this.state; // switching to mixed if (datasource.meta.mixed) { + // Set the datasource on all targets panel.targets.forEach(target => { target.datasource = panel.datasource; if (!target.datasource) { @@ -103,6 +105,7 @@ export class QueriesTab extends PureComponent { } else if (currentDS) { // if switching from mixed if (currentDS.meta.mixed) { + // Remove the explicit datasource for (const target of panel.targets) { delete target.datasource; } @@ -129,9 +132,12 @@ export class QueriesTab extends PureComponent { return ; }; - onAddQuery = (query?: Partial) => { - this.props.panel.addQuery(query); - this.setState({ scrollTop: this.state.scrollTop + 100000 }); + /** + * Sets the queries for the panel + */ + onUpdateQueries = (queries: DataQuery[]) => { + this.props.panel.targets = queries; + this.forceUpdate(); }; onAddQueryClick = () => { @@ -140,27 +146,12 @@ export class QueriesTab extends PureComponent { return; } - this.onAddQuery(); + this.onUpdateQueries(addQuery(this.props.panel.targets)); + this.onScrollBottom(); }; - onRemoveQuery = (query: DataQuery) => { - const { panel } = this.props; - - const index = _.indexOf(panel.targets, query); - panel.targets.splice(index, 1); - panel.refresh(); - - this.forceUpdate(); - }; - - onMoveQuery = (query: DataQuery, direction: number) => { - const { panel } = this.props; - - const index = _.indexOf(panel.targets, query); - // @ts-ignore - _.move(panel.targets, index, index + direction); - - this.forceUpdate(); + onScrollBottom = () => { + this.setState({ scrollTop: this.state.scrollTop + 10000 }); }; renderToolbar = () => { @@ -184,7 +175,7 @@ export class QueriesTab extends PureComponent { renderMixedPicker = () => { return ( !ds.meta.mixed)} onChange={this.onAddMixedQuery} current={null} autoFocus={true} @@ -195,8 +186,9 @@ export class QueriesTab extends PureComponent { }; onAddMixedQuery = (datasource: any) => { - this.onAddQuery({ datasource: datasource.name }); + this.props.panel.targets = addQuery(this.props.panel.targets, { datasource: datasource.name }); this.setState({ isAddingMixed: false, scrollTop: this.state.scrollTop + 10000 }); + this.forceUpdate(); }; onMixedPickerBlur = () => { @@ -218,9 +210,34 @@ export class QueriesTab extends PureComponent { this.setState({ scrollTop: target.scrollTop }); }; - render() { + renderQueryBody = () => { const { panel, dashboard } = this.props; - const { currentDS, scrollTop, data } = this.state; + const { currentDS, data } = this.state; + + if (isSharedDashboardQuery(currentDS.name)) { + return this.onUpdateQueries([query])} />; + } + + return ( + <> + + + + + + ); + }; + + render() { + const { scrollTop, data } = this.state; const queryInspector: EditorToolbarView = { title: 'Query Inspector', render: this.renderQueryInspector, @@ -243,32 +260,7 @@ export class QueriesTab extends PureComponent { scrollTop={scrollTop} > <> - {isSharedDashboardQuery(currentDS.name) ? ( - this.onQueryChange(query, 0)} /> - ) : ( - <> -
- {panel.targets.map((query, index) => ( - this.onQueryChange(query, index)} - onRemoveQuery={this.onRemoveQuery} - onAddQuery={this.onAddQuery} - onMoveQuery={this.onMoveQuery} - inMixedMode={currentDS.meta.mixed} - /> - ))} -
- - - - - )} + {this.renderQueryBody()} {enableTransformations && ( void; + onScrollBottom: () => void; + + // Dashboard Configs + panel: PanelModel; + dashboard: DashboardModel; + + // Query Response Data + data: PanelData; +} + +export class QueryEditorRows extends PureComponent { + onAddQuery = (query?: Partial) => { + 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(); + }; + + onMoveQuery = (query: DataQuery, direction: number) => { + const { queries, onChangeQueries, panel } = this.props; + + const index = _.indexOf(queries, query); + // @ts-ignore + _.move(queries, index, index + direction); + onChangeQueries(queries); + panel.refresh(); + }; + + onChangeQuery(query: DataQuery, index: number) { + const { queries, onChangeQueries } = this.props; + + // ensure refId is maintained + query.refId = queries[index].refId; + + // update query in array + onChangeQueries( + queries.map((item, itemIndex) => { + if (itemIndex === index) { + return query; + } + return item; + }) + ); + } + + render() { + const { props } = this; + return ( +
+ {props.queries.map((query, index) => ( + this.onChangeQuery(query, index)} + onRemoveQuery={this.onRemoveQuery} + onAddQuery={this.onAddQuery} + onMoveQuery={this.onMoveQuery} + inMixedMode={props.datasource.meta.mixed} + /> + ))} +
+ ); + } +}