|
|
@@ -12,7 +12,7 @@ import {
|
|
|
QueryHintGetter,
|
|
|
QueryHint,
|
|
|
} from 'app/types/explore';
|
|
|
-import { RawTimeRange, DataQuery } from 'app/types/series';
|
|
|
+import { TimeRange, DataQuery } from 'app/types/series';
|
|
|
import store from 'app/core/store';
|
|
|
import {
|
|
|
DEFAULT_RANGE,
|
|
|
@@ -30,6 +30,8 @@ import IndicatorsContainer from 'app/core/components/Picker/IndicatorsContainer'
|
|
|
import NoOptionsMessage from 'app/core/components/Picker/NoOptionsMessage';
|
|
|
import TableModel, { mergeTablesIntoModel } from 'app/core/table_model';
|
|
|
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
|
|
+import { Emitter } from 'app/core/utils/emitter';
|
|
|
+import * as dateMath from 'app/core/utils/datemath';
|
|
|
|
|
|
import Panel from './Panel';
|
|
|
import QueryRows from './QueryRows';
|
|
|
@@ -88,6 +90,7 @@ interface ExploreProps {
|
|
|
*/
|
|
|
export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|
|
el: any;
|
|
|
+ exploreEvents: Emitter;
|
|
|
/**
|
|
|
* Current query expressions of the rows including their modifications, used for running queries.
|
|
|
* Not kept in component state to prevent edit-render roundtrips.
|
|
|
@@ -132,6 +135,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|
|
};
|
|
|
}
|
|
|
this.modifiedQueries = initialQueries.slice();
|
|
|
+ this.exploreEvents = new Emitter();
|
|
|
}
|
|
|
|
|
|
async componentDidMount() {
|
|
|
@@ -155,19 +159,20 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|
|
} else {
|
|
|
datasource = await datasourceSrv.get();
|
|
|
}
|
|
|
- if (!datasource.meta.explore) {
|
|
|
- datasource = await datasourceSrv.get(datasources[0].name);
|
|
|
- }
|
|
|
await this.setDatasource(datasource);
|
|
|
} else {
|
|
|
this.setState({ datasourceMissing: true });
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ componentWillUnmount() {
|
|
|
+ this.exploreEvents.removeAllListeners();
|
|
|
+ }
|
|
|
+
|
|
|
async setDatasource(datasource: any, origin?: DataSource) {
|
|
|
const supportsGraph = datasource.meta.metrics;
|
|
|
const supportsLogs = datasource.meta.logs;
|
|
|
- const supportsTable = datasource.meta.metrics;
|
|
|
+ const supportsTable = datasource.meta.tables;
|
|
|
const datasourceId = datasource.meta.id;
|
|
|
let datasourceError = null;
|
|
|
|
|
|
@@ -317,8 +322,14 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- onChangeTime = (nextRange: RawTimeRange) => {
|
|
|
- const range: RawTimeRange = {
|
|
|
+ // onChangeTime = (nextRange: RawTimeRange) => {
|
|
|
+ // const range: RawTimeRange = {
|
|
|
+ // ...nextRange,
|
|
|
+ // };
|
|
|
+ // this.setState({ range }, () => this.onSubmit());
|
|
|
+ // };
|
|
|
+ onChangeTime = (nextRange: TimeRange) => {
|
|
|
+ const range: TimeRange = {
|
|
|
...nextRange,
|
|
|
};
|
|
|
this.setState({ range }, () => this.onSubmit());
|
|
|
@@ -538,8 +549,8 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|
|
];
|
|
|
|
|
|
// Clone range for query request
|
|
|
- const queryRange: RawTimeRange = { ...range };
|
|
|
-
|
|
|
+ // const queryRange: RawTimeRange = { ...range };
|
|
|
+ // const { from, to, raw } = this.timeSrv.timeRange();
|
|
|
// Datasource is using `panelId + query.refId` for cancellation logic.
|
|
|
// Using `format` here because it relates to the view panel that the request is for.
|
|
|
const panelId = queryOptions.format;
|
|
|
@@ -549,7 +560,12 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|
|
intervalMs,
|
|
|
panelId,
|
|
|
targets: configuredQueries, // Datasources rely on DataQueries being passed under the targets key.
|
|
|
- range: queryRange,
|
|
|
+ range: {
|
|
|
+ from: dateMath.parse(range.from, false),
|
|
|
+ to: dateMath.parse(range.to, true),
|
|
|
+ raw: range,
|
|
|
+ },
|
|
|
+ rangeRaw: range,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
@@ -696,17 +712,19 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|
|
}
|
|
|
const { datasource } = this.state;
|
|
|
const datasourceId = datasource.meta.id;
|
|
|
- // Run all queries concurrently
|
|
|
+ // Run all queries concurrentlyso
|
|
|
queries.forEach(async (query, rowIndex) => {
|
|
|
const transaction = this.startQueryTransaction(query, rowIndex, resultType, queryOptions);
|
|
|
try {
|
|
|
const now = Date.now();
|
|
|
const res = await datasource.query(transaction.options);
|
|
|
+ this.exploreEvents.emit('data-received', res);
|
|
|
const latency = Date.now() - now;
|
|
|
const results = resultGetter ? resultGetter(res.data) : res.data;
|
|
|
this.completeQueryTransaction(transaction.id, results, latency, queries, datasourceId);
|
|
|
this.setState({ graphRange: transaction.options.range });
|
|
|
} catch (response) {
|
|
|
+ this.exploreEvents.emit('data-error', response);
|
|
|
this.failQueryTransaction(transaction.id, response, datasourceId);
|
|
|
}
|
|
|
});
|
|
|
@@ -759,7 +777,10 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|
|
const graphResult = _.flatten(
|
|
|
queryTransactions.filter(qt => qt.resultType === 'Graph' && qt.done && qt.result).map(qt => qt.result)
|
|
|
);
|
|
|
- const tableResult = mergeTablesIntoModel(
|
|
|
+
|
|
|
+ //Temp solution... How do detect if ds supports table format?
|
|
|
+ let tableResult;
|
|
|
+ tableResult = mergeTablesIntoModel(
|
|
|
new TableModel(),
|
|
|
...queryTransactions.filter(qt => qt.resultType === 'Table' && qt.done && qt.result).map(qt => qt.result)
|
|
|
);
|
|
|
@@ -858,6 +879,8 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|
|
onExecuteQuery={this.onSubmit}
|
|
|
onRemoveQueryRow={this.onRemoveQueryRow}
|
|
|
transactions={queryTransactions}
|
|
|
+ exploreEvents={this.exploreEvents}
|
|
|
+ range={range}
|
|
|
/>
|
|
|
<main className="m-t-2">
|
|
|
<ErrorBoundary>
|