diff --git a/public/app/features/explore/state/actionTypes.ts b/public/app/features/explore/state/actionTypes.ts index 757f946f37a..3678aeebe7a 100644 --- a/public/app/features/explore/state/actionTypes.ts +++ b/public/app/features/explore/state/actionTypes.ts @@ -43,6 +43,7 @@ export enum ActionTypes { ToggleTable = 'explore/TOGGLE_TABLE', UpdateDatasourceInstance = 'explore/UPDATE_DATASOURCE_INSTANCE', ResetExplore = 'explore/RESET_EXPLORE', + SetInitialQueries = 'explore/SET_INITIAL_QUERIES', } export interface AddQueryRowAction { @@ -142,7 +143,7 @@ export interface LoadDatasourceSuccessAction { StartPage?: any; datasourceInstance: any; history: HistoryItem[]; - initialQueries: DataQuery[]; + // initialQueries: DataQuery[]; logsHighlighterExpressions?: any[]; showingStartPage: boolean; supportsGraph: boolean; @@ -283,6 +284,14 @@ export interface ResetExploreAction { payload: {}; } +export interface SetInitialQueriesAction { + type: ActionTypes.SetInitialQueries; + payload: { + exploreId: ExploreId; + queries: DataQuery[]; + }; +} + export type Action = | AddQueryRowAction | ChangeQueryAction @@ -312,4 +321,5 @@ export type Action = | ToggleLogsAction | ToggleTableAction | UpdateDatasourceInstanceAction - | ResetExploreAction; + | ResetExploreAction + | SetInitialQueriesAction; diff --git a/public/app/features/explore/state/actions.ts b/public/app/features/explore/state/actions.ts index 40a8f367672..2c1c2a060d6 100644 --- a/public/app/features/explore/state/actions.ts +++ b/public/app/features/explore/state/actions.ts @@ -53,6 +53,7 @@ import { QueryTransactionStartAction, ScanStopAction, UpdateDatasourceInstanceAction, + SetInitialQueriesAction, } from './actionTypes'; type ThunkResult = ThunkAction; @@ -69,10 +70,14 @@ export function addQueryRow(exploreId: ExploreId, index: number): AddQueryRowAct * Loads a new datasource identified by the given name. */ export function changeDatasource(exploreId: ExploreId, datasource: string): ThunkResult { - return async dispatch => { - const instance = await getDatasourceSrv().get(datasource); - dispatch(updateDatasourceInstance(exploreId, instance)); - dispatch(loadDatasource(exploreId, instance)); + return async (dispatch, getState) => { + const newDataSourceInstance = await getDatasourceSrv().get(datasource); + const currentDataSourceInstance = getState().explore[exploreId].datasourceInstance; + const modifiedQueries = getState().explore[exploreId].modifiedQueries; + + dispatch(importQueries(exploreId, modifiedQueries, currentDataSourceInstance, newDataSourceInstance)); + dispatch(updateDatasourceInstance(exploreId, newDataSourceInstance)); + dispatch(loadDatasource(exploreId, newDataSourceInstance)); }; } @@ -174,6 +179,7 @@ export function initializeExplore( if (exploreDatasources.length >= 1) { let instance; + if (datasourceName) { try { instance = await getDatasourceSrv().get(datasourceName); @@ -185,6 +191,7 @@ export function initializeExplore( if (!instance) { instance = await getDatasourceSrv().get(); } + dispatch(updateDatasourceInstance(exploreId, instance)); dispatch(loadDatasource(exploreId, instance)); } else { @@ -224,7 +231,10 @@ export const loadDatasourceMissing = (exploreId: ExploreId): LoadDatasourceMissi /** * Start the async process of loading a datasource to display a loading indicator */ -export const loadDatasourcePending = (exploreId: ExploreId, requestedDatasourceName: string): LoadDatasourcePendingAction => ({ +export const loadDatasourcePending = ( + exploreId: ExploreId, + requestedDatasourceName: string +): LoadDatasourcePendingAction => ({ type: ActionTypes.LoadDatasourcePending, payload: { exploreId, @@ -232,6 +242,16 @@ export const loadDatasourcePending = (exploreId: ExploreId, requestedDatasourceN }, }); +export const setInitialQueries = (exploreId: ExploreId, queries: DataQuery[]): SetInitialQueriesAction => { + return { + type: ActionTypes.SetInitialQueries, + payload: { + exploreId, + queries, + }, + }; +}; + /** * Datasource loading was successfully completed. The instance is stored in the state as well in case we need to * run datasource-specific code. Existing queries are imported to the new datasource if an importer exists, @@ -239,8 +259,8 @@ export const loadDatasourcePending = (exploreId: ExploreId, requestedDatasourceN */ export const loadDatasourceSuccess = ( exploreId: ExploreId, - instance: any, - queries: DataQuery[] + instance: any + // queries: DataQuery[] ): LoadDatasourceSuccessAction => { // Capabilities const supportsGraph = instance.meta.metrics; @@ -261,7 +281,7 @@ export const loadDatasourceSuccess = ( StartPage, datasourceInstance: instance, history, - initialQueries: queries, + // initialQueries: queries, showingStartPage: Boolean(StartPage), supportsGraph, supportsLogs, @@ -286,6 +306,29 @@ export function updateDatasourceInstance( }; } +export function importQueries( + exploreId: ExploreId, + queries: DataQuery[], + sourceDataSource: DataSourceApi, + targetDataSource: DataSourceApi +) { + return async dispatch => { + let importedQueries = queries; + // Check if queries can be imported from previously selected datasource + if (sourceDataSource.meta.id === targetDataSource.meta.id) { + // Keep same queries if same type of datasource + importedQueries = [...queries]; + } else if (targetDataSource.importQueries) { + // Datasource-specific importers + importedQueries = await targetDataSource.importQueries(queries, sourceDataSource.meta); + } else { + // Default is blank queries + importedQueries = ensureQueries(); + } + dispatch(setInitialQueries(exploreId, importedQueries)); + }; +} + /** * Main action to asynchronously load a datasource. Dispatches lots of smaller actions for feedback. */ @@ -319,21 +362,6 @@ export function loadDatasource(exploreId: ExploreId, instance: DataSourceApi): T } // Check if queries can be imported from previously selected datasource - const queries = getState().explore[exploreId].modifiedQueries; - let importedQueries = queries; - const origin = getState().explore[exploreId].datasourceInstance; - if (origin) { - if (origin.meta.id === instance.meta.id) { - // Keep same queries if same type of datasource - importedQueries = [...queries]; - } else if (instance.importQueries) { - // Datasource-specific importers - importedQueries = await instance.importQueries(queries, origin.meta); - } else { - // Default is blank queries - importedQueries = ensureQueries(); - } - } if (datasourceName !== getState().explore[exploreId].requestedDatasourceName) { // User already changed datasource again, discard results @@ -341,12 +369,12 @@ export function loadDatasource(exploreId: ExploreId, instance: DataSourceApi): T } // Reset edit state with new queries - const nextQueries = importedQueries.map((q, i) => ({ - ...importedQueries[i], - ...generateEmptyQuery(i), - })); + // const nextQueries = importedQueries.map((q, i) => ({ + // ...importedQueries[i], + // ...generateEmptyQuery(i), + // })); - dispatch(loadDatasourceSuccess(exploreId, instance, nextQueries)); + dispatch(loadDatasourceSuccess(exploreId, instance /*, nextQueries*/)); dispatch(runQueries(exploreId)); }; } diff --git a/public/app/features/explore/state/reducers.ts b/public/app/features/explore/state/reducers.ts index ad5ef8b5a71..c89307e4376 100644 --- a/public/app/features/explore/state/reducers.ts +++ b/public/app/features/explore/state/reducers.ts @@ -203,7 +203,6 @@ export const itemReducer = (state, action: Action): ExploreItemState => { StartPage, datasourceInstance, history, - initialQueries, showingStartPage, supportsGraph, supportsLogs, @@ -217,7 +216,6 @@ export const itemReducer = (state, action: Action): ExploreItemState => { StartPage, datasourceInstance, history, - initialQueries, showingStartPage, supportsGraph, supportsLogs, @@ -226,7 +224,6 @@ export const itemReducer = (state, action: Action): ExploreItemState => { datasourceMissing: false, datasourceError: null, logsHighlighterExpressions: undefined, - modifiedQueries: initialQueries.slice(), queryTransactions: [], }; } @@ -295,7 +292,6 @@ export const itemReducer = (state, action: Action): ExploreItemState => { // Append new transaction const nextQueryTransactions: QueryTransaction[] = [...remainingTransactions, transaction]; - return { ...state, queryTransactions: nextQueryTransactions, @@ -417,6 +413,14 @@ export const itemReducer = (state, action: Action): ExploreItemState => { return { ...state, ...results, queryTransactions: nextQueryTransactions, showingTable }; } + + case ActionTypes.SetInitialQueries: { + return { + ...state, + initialQueries: action.payload.queries, + modifiedQueries: action.payload.queries.slice(), + }; + } } return state; diff --git a/public/app/plugins/datasource/loki/language_provider.ts b/public/app/plugins/datasource/loki/language_provider.ts index 631e61277b8..8b50eeaad53 100644 --- a/public/app/plugins/datasource/loki/language_provider.ts +++ b/public/app/plugins/datasource/loki/language_provider.ts @@ -177,6 +177,7 @@ export default class LokiLanguageProvider extends LanguageProvider { return queries.map(query => ({ refId: query.refId, expr: '', + key: query.key, })); }