Jelajahi Sumber

Import queries before datasource is changed

Dominik Prokop 7 tahun lalu
induk
melakukan
010f902003

+ 12 - 2
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;

+ 56 - 28
public/app/features/explore/state/actions.ts

@@ -53,6 +53,7 @@ import {
   QueryTransactionStartAction,
   ScanStopAction,
   UpdateDatasourceInstanceAction,
+  SetInitialQueriesAction,
 } from './actionTypes';
 
 type ThunkResult<R> = ThunkAction<R, StoreState, undefined, ThunkableAction>;
@@ -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<void> {
-  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));
   };
 }

+ 8 - 4
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;

+ 1 - 0
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,
     }));
   }