Commit 8510f0cd by Torkel Ödegaard Committed by GitHub

Merge pull request #15084 from grafana/fix/explore-datasource-change

Update datasource before the loading has started
parents a7b486d9 a1a905cb
......@@ -45,7 +45,6 @@ interface ExploreProps {
datasourceLoading: boolean | null;
datasourceMissing: boolean;
exploreId: ExploreId;
initialDatasource?: string;
initialQueries: DataQuery[];
initializeExplore: typeof initializeExplore;
initialized: boolean;
......@@ -251,7 +250,6 @@ function mapStateToProps(state: StoreState, { exploreId }) {
datasourceInstance,
datasourceLoading,
datasourceMissing,
initialDatasource,
initialQueries,
initialized,
range,
......@@ -266,7 +264,6 @@ function mapStateToProps(state: StoreState, { exploreId }) {
datasourceInstance,
datasourceLoading,
datasourceMissing,
initialDatasource,
initialQueries,
initialized,
range,
......
// Types
import { Emitter } from 'app/core/core';
import { RawTimeRange, TimeRange, DataQuery, DataSourceSelectItem } from '@grafana/ui/src/types';
import { RawTimeRange, TimeRange, DataQuery, DataSourceSelectItem, DataSourceApi } from '@grafana/ui/src/types';
import {
ExploreId,
ExploreItemState,
......@@ -41,6 +41,7 @@ export enum ActionTypes {
ToggleGraph = 'explore/TOGGLE_GRAPH',
ToggleLogs = 'explore/TOGGLE_LOGS',
ToggleTable = 'explore/TOGGLE_TABLE',
UpdateDatasourceInstance = 'explore/UPDATE_DATASOURCE_INSTANCE',
ResetExplore = 'explore/RESET_EXPLORE',
}
......@@ -100,7 +101,6 @@ export interface InitializeExploreAction {
payload: {
exploreId: ExploreId;
containerWidth: number;
datasource: string;
eventBridge: Emitter;
exploreDatasources: DataSourceSelectItem[];
queries: DataQuery[];
......@@ -124,7 +124,7 @@ export interface LoadDatasourcePendingAction {
type: ActionTypes.LoadDatasourcePending;
payload: {
exploreId: ExploreId;
datasourceName: string;
requestedDatasourceName: string;
};
}
......@@ -142,7 +142,6 @@ export interface LoadDatasourceSuccessAction {
StartPage?: any;
datasourceInstance: any;
history: HistoryItem[];
initialDatasource: string;
initialQueries: DataQuery[];
logsHighlighterExpressions?: any[];
showingStartPage: boolean;
......@@ -271,6 +270,14 @@ export interface ToggleLogsAction {
};
}
export interface UpdateDatasourceInstanceAction {
type: ActionTypes.UpdateDatasourceInstance;
payload: {
exploreId: ExploreId;
datasourceInstance: DataSourceApi;
};
}
export interface ResetExploreAction {
type: ActionTypes.ResetExplore;
payload: {};
......@@ -304,4 +311,5 @@ export type Action =
| ToggleGraphAction
| ToggleLogsAction
| ToggleTableAction
| UpdateDatasourceInstanceAction
| ResetExploreAction;
......@@ -4,6 +4,8 @@ import { ThunkAction } from 'redux-thunk';
// Services & Utils
import store from 'app/core/store';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { Emitter } from 'app/core/core';
import {
LAST_USED_DATASOURCE_KEY,
clearQueryKeys,
......@@ -21,8 +23,14 @@ import { updateLocation } from 'app/core/actions';
// Types
import { StoreState } from 'app/types';
import { DataQuery, DataSourceSelectItem, QueryHint } from '@grafana/ui/src/types';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import {
RawTimeRange,
TimeRange,
DataSourceApi,
DataQuery,
DataSourceSelectItem,
QueryHint,
} from '@grafana/ui/src/types';
import {
ExploreId,
ExploreUrlState,
......@@ -32,8 +40,6 @@ import {
QueryTransaction,
} from 'app/types/explore';
import { Emitter } from 'app/core/core';
import { RawTimeRange, TimeRange, DataSourceApi } from '@grafana/ui';
import {
Action as ThunkableAction,
ActionTypes,
......@@ -46,6 +52,7 @@ import {
LoadDatasourceSuccessAction,
QueryTransactionStartAction,
ScanStopAction,
UpdateDatasourceInstanceAction,
} from './actionTypes';
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, ThunkableAction>;
......@@ -64,6 +71,7 @@ export function addQueryRow(exploreId: ExploreId, index: number): AddQueryRowAct
export function changeDatasource(exploreId: ExploreId, datasource: string): ThunkResult<void> {
return async dispatch => {
const instance = await getDatasourceSrv().get(datasource);
dispatch(updateDatasourceInstance(exploreId, instance));
dispatch(loadDatasource(exploreId, instance));
};
}
......@@ -136,7 +144,7 @@ export function highlightLogsExpression(exploreId: ExploreId, expressions: strin
*/
export function initializeExplore(
exploreId: ExploreId,
datasource: string,
datasourceName: string,
queries: DataQuery[],
range: RawTimeRange,
containerWidth: number,
......@@ -156,7 +164,7 @@ export function initializeExplore(
payload: {
exploreId,
containerWidth,
datasource,
datasourceName,
eventBridge,
exploreDatasources,
queries,
......@@ -166,9 +174,9 @@ export function initializeExplore(
if (exploreDatasources.length >= 1) {
let instance;
if (datasource) {
if (datasourceName) {
try {
instance = await getDatasourceSrv().get(datasource);
instance = await getDatasourceSrv().get(datasourceName);
} catch (error) {
console.error(error);
}
......@@ -177,6 +185,7 @@ export function initializeExplore(
if (!instance) {
instance = await getDatasourceSrv().get();
}
dispatch(updateDatasourceInstance(exploreId, instance));
dispatch(loadDatasource(exploreId, instance));
} else {
dispatch(loadDatasourceMissing(exploreId));
......@@ -215,11 +224,11 @@ export const loadDatasourceMissing = (exploreId: ExploreId): LoadDatasourceMissi
/**
* Start the async process of loading a datasource to display a loading indicator
*/
export const loadDatasourcePending = (exploreId: ExploreId, datasourceName: string): LoadDatasourcePendingAction => ({
export const loadDatasourcePending = (exploreId: ExploreId, requestedDatasourceName: string): LoadDatasourcePendingAction => ({
type: ActionTypes.LoadDatasourcePending,
payload: {
exploreId,
datasourceName,
requestedDatasourceName,
},
});
......@@ -252,7 +261,6 @@ export const loadDatasourceSuccess = (
StartPage,
datasourceInstance: instance,
history,
initialDatasource: instance.name,
initialQueries: queries,
showingStartPage: Boolean(StartPage),
supportsGraph,
......@@ -263,6 +271,22 @@ export const loadDatasourceSuccess = (
};
/**
* Updates datasource instance before datasouce loading has started
*/
export function updateDatasourceInstance(
exploreId: ExploreId,
instance: DataSourceApi
): UpdateDatasourceInstanceAction {
return {
type: ActionTypes.UpdateDatasourceInstance,
payload: {
exploreId,
datasourceInstance: instance,
},
};
}
/**
* Main action to asynchronously load a datasource. Dispatches lots of smaller actions for feedback.
*/
export function loadDatasource(exploreId: ExploreId, instance: DataSourceApi): ThunkResult<void> {
......
......@@ -24,6 +24,7 @@ export const makeExploreItemState = (): ExploreItemState => ({
StartPage: undefined,
containerWidth: 0,
datasourceInstance: null,
requestedDatasourceName: null,
datasourceError: null,
datasourceLoading: null,
datasourceMissing: false,
......@@ -162,20 +163,28 @@ export const itemReducer = (state, action: Action): ExploreItemState => {
}
case ActionTypes.InitializeExplore: {
const { containerWidth, datasource, eventBridge, exploreDatasources, queries, range } = action.payload;
const { containerWidth, eventBridge, exploreDatasources, queries, range } = action.payload;
return {
...state,
containerWidth,
eventBridge,
exploreDatasources,
range,
initialDatasource: datasource,
initialQueries: queries,
initialized: true,
modifiedQueries: queries.slice(),
};
}
case ActionTypes.UpdateDatasourceInstance: {
const { datasourceInstance } = action.payload;
return {
...state,
datasourceInstance,
datasourceName: datasourceInstance.name,
};
}
case ActionTypes.LoadDatasourceFailure: {
return { ...state, datasourceError: action.payload.error, datasourceLoading: false };
}
......@@ -185,7 +194,7 @@ export const itemReducer = (state, action: Action): ExploreItemState => {
}
case ActionTypes.LoadDatasourcePending: {
return { ...state, datasourceLoading: true, requestedDatasourceName: action.payload.datasourceName };
return { ...state, datasourceLoading: true, requestedDatasourceName: action.payload.requestedDatasourceName };
}
case ActionTypes.LoadDatasourceSuccess: {
......@@ -194,7 +203,6 @@ export const itemReducer = (state, action: Action): ExploreItemState => {
StartPage,
datasourceInstance,
history,
initialDatasource,
initialQueries,
showingStartPage,
supportsGraph,
......@@ -209,7 +217,6 @@ export const itemReducer = (state, action: Action): ExploreItemState => {
StartPage,
datasourceInstance,
history,
initialDatasource,
initialQueries,
showingStartPage,
supportsGraph,
......
......@@ -110,7 +110,11 @@ export interface ExploreItemState {
/**
* Datasource instance that has been selected. Datasource-specific logic can be run on this object.
*/
datasourceInstance: DataSourceApi;
datasourceInstance: DataSourceApi | null;
/**
* Current data source name or null if default
*/
requestedDatasourceName: string | null;
/**
* Error to be shown when datasource loading or testing failed.
*/
......@@ -140,10 +144,6 @@ export interface ExploreItemState {
*/
history: HistoryItem[];
/**
* Initial datasource for this Explore, e.g., set via URL.
*/
initialDatasource?: string;
/**
* Initial queries for this Explore, e.g., set via URL. Each query will be
* converted to a query row. Query edits should be tracked in `modifiedQueries` though.
*/
......@@ -182,12 +182,6 @@ export interface ExploreItemState {
*/
queryTransactions: QueryTransaction[];
/**
* Tracks datasource when selected in the datasource selector.
* Allows the selection to be discarded if something went wrong during the asynchronous
* loading of the datasource.
*/
requestedDatasourceName?: string;
/**
* Time range for this Explore. Managed by the time picker and used by all query runs.
*/
range: TimeRange | RawTimeRange;
......
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