|
|
@@ -28,15 +28,11 @@ interface Props {
|
|
|
dashboard: DashboardModel;
|
|
|
}
|
|
|
|
|
|
-interface Help {
|
|
|
- isLoading: boolean;
|
|
|
- helpHtml: any;
|
|
|
-}
|
|
|
-
|
|
|
interface State {
|
|
|
- currentDatasource: DataSourceSelectItem;
|
|
|
- help: Help;
|
|
|
- hideTimeOverride: boolean;
|
|
|
+ currentDS: DataSourceSelectItem;
|
|
|
+ helpContent: JSX.Element;
|
|
|
+ isLoadingHelp: string;
|
|
|
+ isPickerOpen: boolean;
|
|
|
}
|
|
|
|
|
|
interface LoadingPlaceholderProps {
|
|
|
@@ -56,12 +52,10 @@ export class QueriesTab extends PureComponent<Props, State> {
|
|
|
const { panel } = props;
|
|
|
|
|
|
this.state = {
|
|
|
- currentDatasource: this.datasources.find(datasource => datasource.value === panel.datasource),
|
|
|
- help: {
|
|
|
- isLoading: false,
|
|
|
- helpHtml: null,
|
|
|
- },
|
|
|
- hideTimeOverride: false,
|
|
|
+ currentDS: this.datasources.find(datasource => datasource.value === panel.datasource),
|
|
|
+ isLoadingHelp: false,
|
|
|
+ helpContent: null,
|
|
|
+ isPickerOpen: false,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
@@ -102,7 +96,7 @@ export class QueriesTab extends PureComponent<Props, State> {
|
|
|
|
|
|
onChangeDataSource = datasource => {
|
|
|
const { panel } = this.props;
|
|
|
- const { currentDatasource } = this.state;
|
|
|
+ const { currentDS } = this.state;
|
|
|
|
|
|
// switching to mixed
|
|
|
if (datasource.meta.mixed) {
|
|
|
@@ -112,13 +106,13 @@ export class QueriesTab extends PureComponent<Props, State> {
|
|
|
target.datasource = config.defaultDatasource;
|
|
|
}
|
|
|
});
|
|
|
- } else if (currentDatasource) {
|
|
|
+ } else if (currentDS) {
|
|
|
// if switching from mixed
|
|
|
- if (currentDatasource.meta.mixed) {
|
|
|
+ if (currentDS.meta.mixed) {
|
|
|
for (const target of panel.targets) {
|
|
|
delete target.datasource;
|
|
|
}
|
|
|
- } else if (currentDatasource.meta.id !== datasource.meta.id) {
|
|
|
+ } else if (currentDS.meta.id !== datasource.meta.id) {
|
|
|
// we are changing data source type, clear queries
|
|
|
panel.targets = [{ refId: 'A' }];
|
|
|
}
|
|
|
@@ -127,128 +121,118 @@ export class QueriesTab extends PureComponent<Props, State> {
|
|
|
panel.datasource = datasource.value;
|
|
|
panel.refresh();
|
|
|
|
|
|
- this.setState(prevState => ({
|
|
|
- ...prevState,
|
|
|
- currentDatasource: datasource,
|
|
|
- }));
|
|
|
+ this.setState({
|
|
|
+ currentDS: datasource,
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
- loadHelp = () => {
|
|
|
- const { currentDatasource } = this.state;
|
|
|
- const hasHelp = currentDatasource.meta.hasQueryHelp;
|
|
|
-
|
|
|
- if (hasHelp) {
|
|
|
- this.setState(prevState => ({
|
|
|
- ...prevState,
|
|
|
- help: {
|
|
|
- helpHtml: <h2>Loading help...</h2>,
|
|
|
- isLoading: true,
|
|
|
- },
|
|
|
- }));
|
|
|
-
|
|
|
- this.backendSrv
|
|
|
- .get(`/api/plugins/${currentDatasource.meta.id}/markdown/query_help`)
|
|
|
- .then(res => {
|
|
|
- const md = new Remarkable();
|
|
|
- const helpHtml = md.render(res); // TODO: Clean out dangerous code? Previous: this.helpHtml = this.$sce.trustAsHtml(md.render(res));
|
|
|
- this.setState(prevState => ({
|
|
|
- ...prevState,
|
|
|
- help: {
|
|
|
- helpHtml: <div className="markdown-html" dangerouslySetInnerHTML={{ __html: helpHtml }} />,
|
|
|
- isLoading: false,
|
|
|
- },
|
|
|
- }));
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- this.setState(prevState => ({
|
|
|
- ...prevState,
|
|
|
- help: {
|
|
|
- helpHtml: 'Error occured when loading help',
|
|
|
- isLoading: false,
|
|
|
- },
|
|
|
- }));
|
|
|
- });
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- renderOptions = close => {
|
|
|
- const { currentDatasource } = this.state;
|
|
|
- const { queryOptions } = currentDatasource.meta;
|
|
|
- const { panel } = this.props;
|
|
|
-
|
|
|
- const onChangeFn = (panelKey: string) => {
|
|
|
- return (value: string | number) => {
|
|
|
- panel[panelKey] = value;
|
|
|
- panel.refresh();
|
|
|
- };
|
|
|
- };
|
|
|
-
|
|
|
- const allOptions = {
|
|
|
- cacheTimeout: {
|
|
|
- label: 'Cache timeout',
|
|
|
- placeholder: '60',
|
|
|
- name: 'cacheTimeout',
|
|
|
- value: panel.cacheTimeout,
|
|
|
- tooltipInfo: (
|
|
|
- <>
|
|
|
- If your time series store has a query cache this option can override the default cache timeout. Specify a
|
|
|
- numeric value in seconds.
|
|
|
- </>
|
|
|
- ),
|
|
|
- },
|
|
|
- maxDataPoints: {
|
|
|
- label: 'Max data points',
|
|
|
- placeholder: 'auto',
|
|
|
- name: 'maxDataPoints',
|
|
|
- value: panel.maxDataPoints,
|
|
|
- tooltipInfo: (
|
|
|
- <>
|
|
|
- The maximum data points the query should return. For graphs this is automatically set to one data point per
|
|
|
- pixel.
|
|
|
- </>
|
|
|
- ),
|
|
|
- },
|
|
|
- minInterval: {
|
|
|
- label: 'Min time interval',
|
|
|
- placeholder: '0',
|
|
|
- name: 'minInterval',
|
|
|
- value: panel.interval,
|
|
|
- panelKey: 'interval',
|
|
|
- tooltipInfo: (
|
|
|
- <>
|
|
|
- A lower limit for the auto group by time interval. Recommended to be set to write frequency, for example{' '}
|
|
|
- <code>1m</code> if your data is written every minute. Access auto interval via variable{' '}
|
|
|
- <code>$__interval</code> for time range string and <code>$__interval_ms</code> for numeric variable that can
|
|
|
- be used in math expressions.
|
|
|
- </>
|
|
|
- ),
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- const dsOptions = queryOptions
|
|
|
- ? Object.keys(queryOptions).map(key => {
|
|
|
- const options = allOptions[key];
|
|
|
- return <DataSourceOption key={key} {...options} onChange={onChangeFn(allOptions[key].panelKey || key)} />;
|
|
|
- })
|
|
|
- : null;
|
|
|
-
|
|
|
- return (
|
|
|
- <>
|
|
|
- <TimeRangeOptions panel={this.props.panel} />
|
|
|
- {dsOptions}
|
|
|
- </>
|
|
|
- );
|
|
|
- };
|
|
|
+ // loadHelp = () => {
|
|
|
+ // const { currentDatasource } = this.state;
|
|
|
+ // const hasHelp = currentDatasource.meta.hasQueryHelp;
|
|
|
+ //
|
|
|
+ // if (hasHelp) {
|
|
|
+ // this.setState({
|
|
|
+ // helpContent: <h2>Loading help...</h2>,
|
|
|
+ // isLoadingHelp: true
|
|
|
+ // });
|
|
|
+ //
|
|
|
+ // this.backendSrv
|
|
|
+ // .get(`/api/plugins/${currentDatasource.meta.id}/markdown/query_help`)
|
|
|
+ // .then(res => {
|
|
|
+ // const md = new Remarkable();
|
|
|
+ // const helpHtml = md.render(res); // TODO: Clean out dangerous code? Previous: this.helpHtml = this.$sce.trustAsHtml(md.render(res));
|
|
|
+ // this.setState({
|
|
|
+ // helpContent: <div className="markdown-html" dangerouslySetInnerHTML={{ __html: helpHtml }} />,
|
|
|
+ // isLoadingHelp: false
|
|
|
+ // });
|
|
|
+ // })
|
|
|
+ // .catch(() => {
|
|
|
+ // this.setState({
|
|
|
+ // helpContent: 'Error occured when loading help',
|
|
|
+ // isLoadingHelp: false,
|
|
|
+ // });
|
|
|
+ // });
|
|
|
+ // }
|
|
|
+ // };
|
|
|
+
|
|
|
+ // renderOptions = close => {
|
|
|
+ // const { currentDatasource } = this.state;
|
|
|
+ // const { queryOptions } = currentDatasource.meta;
|
|
|
+ // const { panel } = this.props;
|
|
|
+ //
|
|
|
+ // const onChangeFn = (panelKey: string) => {
|
|
|
+ // return (value: string | number) => {
|
|
|
+ // panel[panelKey] = value;
|
|
|
+ // panel.refresh();
|
|
|
+ // };
|
|
|
+ // };
|
|
|
+ //
|
|
|
+ // const allOptions = {
|
|
|
+ // cacheTimeout: {
|
|
|
+ // label: 'Cache timeout',
|
|
|
+ // placeholder: '60',
|
|
|
+ // name: 'cacheTimeout',
|
|
|
+ // value: panel.cacheTimeout,
|
|
|
+ // tooltipInfo: (
|
|
|
+ // <>
|
|
|
+ // If your time series store has a query cache this option can override the default cache timeout. Specify a
|
|
|
+ // numeric value in seconds.
|
|
|
+ // </>
|
|
|
+ // ),
|
|
|
+ // },
|
|
|
+ // maxDataPoints: {
|
|
|
+ // label: 'Max data points',
|
|
|
+ // placeholder: 'auto',
|
|
|
+ // name: 'maxDataPoints',
|
|
|
+ // value: panel.maxDataPoints,
|
|
|
+ // tooltipInfo: (
|
|
|
+ // <>
|
|
|
+ // The maximum data points the query should return. For graphs this is automatically set to one data point per
|
|
|
+ // pixel.
|
|
|
+ // </>
|
|
|
+ // ),
|
|
|
+ // },
|
|
|
+ // minInterval: {
|
|
|
+ // label: 'Min time interval',
|
|
|
+ // placeholder: '0',
|
|
|
+ // name: 'minInterval',
|
|
|
+ // value: panel.interval,
|
|
|
+ // panelKey: 'interval',
|
|
|
+ // tooltipInfo: (
|
|
|
+ // <>
|
|
|
+ // A lower limit for the auto group by time interval. Recommended to be set to write frequency, for example{' '}
|
|
|
+ // <code>1m</code> if your data is written every minute. Access auto interval via variable{' '}
|
|
|
+ // <code>$__interval</code> for time range string and <code>$__interval_ms</code> for numeric variable that can
|
|
|
+ // be used in math expressions.
|
|
|
+ // </>
|
|
|
+ // ),
|
|
|
+ // },
|
|
|
+ // };
|
|
|
+ //
|
|
|
+ // const dsOptions = queryOptions
|
|
|
+ // ? Object.keys(queryOptions).map(key => {
|
|
|
+ // const options = allOptions[key];
|
|
|
+ // return <DataSourceOption key={key} {...options} onChange={onChangeFn(allOptions[key].panelKey || key)} />;
|
|
|
+ // })
|
|
|
+ // : null;
|
|
|
+ //
|
|
|
+ // return (
|
|
|
+ // <>
|
|
|
+ // <TimeRangeOptions panel={this.props.panel} />
|
|
|
+ // {dsOptions}
|
|
|
+ // </>
|
|
|
+ // );
|
|
|
+ // };
|
|
|
|
|
|
renderQueryInspector = () => {
|
|
|
const { panel } = this.props;
|
|
|
return <QueryInspector panel={panel} LoadingPlaceholder={LoadingPlaceholder} />;
|
|
|
};
|
|
|
|
|
|
- renderHelp = () => {
|
|
|
- const { helpHtml, isLoading } = this.state.help;
|
|
|
- return isLoading ? <LoadingPlaceholder text="Loading help..." /> : helpHtml;
|
|
|
- };
|
|
|
+ // renderHelp = () => {
|
|
|
+ // const { helpHtml, isLoading } = this.state.help;
|
|
|
+ // return isLoading ? <LoadingPlaceholder text="Loading help..." /> : helpHtml;
|
|
|
+ // };
|
|
|
|
|
|
onAddQuery = (query?: DataQuery) => {
|
|
|
this.props.panel.addQuery(query);
|
|
|
@@ -280,47 +264,57 @@ export class QueriesTab extends PureComponent<Props, State> {
|
|
|
this.forceUpdate();
|
|
|
};
|
|
|
|
|
|
- render() {
|
|
|
- const { panel } = this.props;
|
|
|
- const { currentDatasource } = this.state;
|
|
|
- const { hasQueryHelp } = currentDatasource.meta;
|
|
|
-
|
|
|
- const dsInformation = {
|
|
|
- title: currentDatasource.name,
|
|
|
- imgSrc: currentDatasource.meta.info.logos.small,
|
|
|
- render: closeOpenView => (
|
|
|
- <DataSourcePicker
|
|
|
- datasources={this.datasources}
|
|
|
- onChangeDataSource={ds => {
|
|
|
- closeOpenView();
|
|
|
- this.onChangeDataSource(ds);
|
|
|
- }}
|
|
|
- />
|
|
|
- ),
|
|
|
- };
|
|
|
+ renderToolbar = () => {
|
|
|
+ const { currentDS } = this.state;
|
|
|
|
|
|
- const queryInspector = {
|
|
|
- title: 'Query Inspector',
|
|
|
- render: this.renderQueryInspector,
|
|
|
- };
|
|
|
+ return (
|
|
|
+ <DataSourcePicker
|
|
|
+ datasources={this.datasources}
|
|
|
+ onChangeDataSource={this.onChangeDataSource}
|
|
|
+ current={currentDS}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ };
|
|
|
|
|
|
- const dsHelp = {
|
|
|
- title: '',
|
|
|
- icon: 'fa fa-question',
|
|
|
- disabled: !hasQueryHelp,
|
|
|
- onClick: this.loadHelp,
|
|
|
- render: this.renderHelp,
|
|
|
- };
|
|
|
+ render() {
|
|
|
+ const { panel } = this.props;
|
|
|
|
|
|
- const options = {
|
|
|
- title: 'Time Range',
|
|
|
- icon: '',
|
|
|
- disabled: false,
|
|
|
- render: this.renderOptions,
|
|
|
- };
|
|
|
+ // const dsInformation = {
|
|
|
+ // title: currentDatasource.name,
|
|
|
+ // imgSrc: currentDatasource.meta.info.logos.small,
|
|
|
+ // render: closeOpenView => (
|
|
|
+ // <DataSourcePicker
|
|
|
+ // datasources={this.datasources}
|
|
|
+ // onChangeDataSource={ds => {
|
|
|
+ // closeOpenView();
|
|
|
+ // this.onChangeDataSource(ds);
|
|
|
+ // }}
|
|
|
+ // />
|
|
|
+ // ),
|
|
|
+ // };
|
|
|
+ //
|
|
|
+ // const queryInspector = {
|
|
|
+ // title: 'Query Inspector',
|
|
|
+ // render: this.renderQueryInspector,
|
|
|
+ // };
|
|
|
+ //
|
|
|
+ // const dsHelp = {
|
|
|
+ // title: '',
|
|
|
+ // icon: 'fa fa-question',
|
|
|
+ // disabled: !hasQueryHelp,
|
|
|
+ // onClick: this.loadHelp,
|
|
|
+ // render: this.renderHelp,
|
|
|
+ // };
|
|
|
+ //
|
|
|
+ // const options = {
|
|
|
+ // title: 'Time Range',
|
|
|
+ // icon: '',
|
|
|
+ // disabled: false,
|
|
|
+ // render: this.renderOptions,
|
|
|
+ // };
|
|
|
|
|
|
return (
|
|
|
- <EditorTabBody heading="Queries" main={dsInformation} toolbarItems={[options, queryInspector, dsHelp]}>
|
|
|
+ <EditorTabBody heading="Queries" renderToolbar={this.renderToolbar}>
|
|
|
<div className="query-editor-rows gf-form-group">
|
|
|
<div ref={element => (this.element = element)} />
|
|
|
|