|
@@ -1,11 +1,15 @@
|
|
|
|
|
+// @ts-ignore
|
|
|
|
|
+import _ from 'lodash';
|
|
|
import {
|
|
import {
|
|
|
calculateResultsFromQueryTransactions,
|
|
calculateResultsFromQueryTransactions,
|
|
|
generateEmptyQuery,
|
|
generateEmptyQuery,
|
|
|
getIntervals,
|
|
getIntervals,
|
|
|
ensureQueries,
|
|
ensureQueries,
|
|
|
getQueryKeys,
|
|
getQueryKeys,
|
|
|
|
|
+ parseUrlState,
|
|
|
|
|
+ DEFAULT_UI_STATE,
|
|
|
} from 'app/core/utils/explore';
|
|
} from 'app/core/utils/explore';
|
|
|
-import { ExploreItemState, ExploreState, QueryTransaction } from 'app/types/explore';
|
|
|
|
|
|
|
+import { ExploreItemState, ExploreState, QueryTransaction, ExploreId, ExploreUpdateState } from 'app/types/explore';
|
|
|
import { DataQuery } from '@grafana/ui/src/types';
|
|
import { DataQuery } from '@grafana/ui/src/types';
|
|
|
|
|
|
|
|
import { HigherOrderAction, ActionTypes } from './actionTypes';
|
|
import { HigherOrderAction, ActionTypes } from './actionTypes';
|
|
@@ -28,7 +32,6 @@ import {
|
|
|
queryTransactionStartAction,
|
|
queryTransactionStartAction,
|
|
|
queryTransactionSuccessAction,
|
|
queryTransactionSuccessAction,
|
|
|
removeQueryRowAction,
|
|
removeQueryRowAction,
|
|
|
- runQueriesEmptyAction,
|
|
|
|
|
scanRangeAction,
|
|
scanRangeAction,
|
|
|
scanStartAction,
|
|
scanStartAction,
|
|
|
scanStopAction,
|
|
scanStopAction,
|
|
@@ -40,6 +43,8 @@ import {
|
|
|
updateUIStateAction,
|
|
updateUIStateAction,
|
|
|
toggleLogLevelAction,
|
|
toggleLogLevelAction,
|
|
|
} from './actionTypes';
|
|
} from './actionTypes';
|
|
|
|
|
+import { updateLocation } from 'app/core/actions/location';
|
|
|
|
|
+import { LocationUpdate } from 'app/types';
|
|
|
|
|
|
|
|
export const DEFAULT_RANGE = {
|
|
export const DEFAULT_RANGE = {
|
|
|
from: 'now-6h',
|
|
from: 'now-6h',
|
|
@@ -49,6 +54,12 @@ export const DEFAULT_RANGE = {
|
|
|
// Millies step for helper bar charts
|
|
// Millies step for helper bar charts
|
|
|
const DEFAULT_GRAPH_INTERVAL = 15 * 1000;
|
|
const DEFAULT_GRAPH_INTERVAL = 15 * 1000;
|
|
|
|
|
|
|
|
|
|
+export const makeInitialUpdateState = (): ExploreUpdateState => ({
|
|
|
|
|
+ datasource: false,
|
|
|
|
|
+ queries: false,
|
|
|
|
|
+ range: false,
|
|
|
|
|
+ ui: false,
|
|
|
|
|
+});
|
|
|
/**
|
|
/**
|
|
|
* Returns a fresh Explore area state
|
|
* Returns a fresh Explore area state
|
|
|
*/
|
|
*/
|
|
@@ -76,6 +87,8 @@ export const makeExploreItemState = (): ExploreItemState => ({
|
|
|
supportsLogs: null,
|
|
supportsLogs: null,
|
|
|
supportsTable: null,
|
|
supportsTable: null,
|
|
|
queryKeys: [],
|
|
queryKeys: [],
|
|
|
|
|
+ urlState: null,
|
|
|
|
|
+ update: makeInitialUpdateState(),
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -195,6 +208,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
initialized: true,
|
|
initialized: true,
|
|
|
queryKeys: getQueryKeys(queries, state.datasourceInstance),
|
|
queryKeys: getQueryKeys(queries, state.datasourceInstance),
|
|
|
...ui,
|
|
...ui,
|
|
|
|
|
+ update: makeInitialUpdateState(),
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
@@ -208,13 +222,23 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
.addMapper({
|
|
.addMapper({
|
|
|
filter: loadDatasourceFailureAction,
|
|
filter: loadDatasourceFailureAction,
|
|
|
mapper: (state, action): ExploreItemState => {
|
|
mapper: (state, action): ExploreItemState => {
|
|
|
- return { ...state, datasourceError: action.payload.error, datasourceLoading: false };
|
|
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...state,
|
|
|
|
|
+ datasourceError: action.payload.error,
|
|
|
|
|
+ datasourceLoading: false,
|
|
|
|
|
+ update: makeInitialUpdateState(),
|
|
|
|
|
+ };
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
.addMapper({
|
|
.addMapper({
|
|
|
filter: loadDatasourceMissingAction,
|
|
filter: loadDatasourceMissingAction,
|
|
|
mapper: (state): ExploreItemState => {
|
|
mapper: (state): ExploreItemState => {
|
|
|
- return { ...state, datasourceMissing: true, datasourceLoading: false };
|
|
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...state,
|
|
|
|
|
+ datasourceMissing: true,
|
|
|
|
|
+ datasourceLoading: false,
|
|
|
|
|
+ update: makeInitialUpdateState(),
|
|
|
|
|
+ };
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
.addMapper({
|
|
.addMapper({
|
|
@@ -253,6 +277,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
datasourceError: null,
|
|
datasourceError: null,
|
|
|
logsHighlighterExpressions: undefined,
|
|
logsHighlighterExpressions: undefined,
|
|
|
queryTransactions: [],
|
|
queryTransactions: [],
|
|
|
|
|
+ update: makeInitialUpdateState(),
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
@@ -262,7 +287,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
const { queries, queryTransactions } = state;
|
|
const { queries, queryTransactions } = state;
|
|
|
const { modification, index, modifier } = action.payload;
|
|
const { modification, index, modifier } = action.payload;
|
|
|
let nextQueries: DataQuery[];
|
|
let nextQueries: DataQuery[];
|
|
|
- let nextQueryTransactions;
|
|
|
|
|
|
|
+ let nextQueryTransactions: QueryTransaction[];
|
|
|
if (index === undefined) {
|
|
if (index === undefined) {
|
|
|
// Modify all queries
|
|
// Modify all queries
|
|
|
nextQueries = queries.map((query, i) => ({
|
|
nextQueries = queries.map((query, i) => ({
|
|
@@ -303,7 +328,12 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
filter: queryTransactionFailureAction,
|
|
filter: queryTransactionFailureAction,
|
|
|
mapper: (state, action): ExploreItemState => {
|
|
mapper: (state, action): ExploreItemState => {
|
|
|
const { queryTransactions } = action.payload;
|
|
const { queryTransactions } = action.payload;
|
|
|
- return { ...state, queryTransactions, showingStartPage: false };
|
|
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...state,
|
|
|
|
|
+ queryTransactions,
|
|
|
|
|
+ showingStartPage: false,
|
|
|
|
|
+ update: makeInitialUpdateState(),
|
|
|
|
|
+ };
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
.addMapper({
|
|
.addMapper({
|
|
@@ -319,7 +349,12 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
// Append new transaction
|
|
// Append new transaction
|
|
|
const nextQueryTransactions: QueryTransaction[] = [...remainingTransactions, transaction];
|
|
const nextQueryTransactions: QueryTransaction[] = [...remainingTransactions, transaction];
|
|
|
|
|
|
|
|
- return { ...state, queryTransactions: nextQueryTransactions, showingStartPage: false };
|
|
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...state,
|
|
|
|
|
+ queryTransactions: nextQueryTransactions,
|
|
|
|
|
+ showingStartPage: false,
|
|
|
|
|
+ update: makeInitialUpdateState(),
|
|
|
|
|
+ };
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
.addMapper({
|
|
.addMapper({
|
|
@@ -333,7 +368,14 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
queryIntervals.intervalMs
|
|
queryIntervals.intervalMs
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- return { ...state, ...results, history, queryTransactions, showingStartPage: false };
|
|
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...state,
|
|
|
|
|
+ ...results,
|
|
|
|
|
+ history,
|
|
|
|
|
+ queryTransactions,
|
|
|
|
|
+ showingStartPage: false,
|
|
|
|
|
+ update: makeInitialUpdateState(),
|
|
|
|
|
+ };
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
.addMapper({
|
|
.addMapper({
|
|
@@ -367,12 +409,6 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
- .addMapper({
|
|
|
|
|
- filter: runQueriesEmptyAction,
|
|
|
|
|
- mapper: (state): ExploreItemState => {
|
|
|
|
|
- return { ...state, queryTransactions: [] };
|
|
|
|
|
- },
|
|
|
|
|
- })
|
|
|
|
|
.addMapper({
|
|
.addMapper({
|
|
|
filter: scanRangeAction,
|
|
filter: scanRangeAction,
|
|
|
mapper: (state, action): ExploreItemState => {
|
|
mapper: (state, action): ExploreItemState => {
|
|
@@ -396,6 +432,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
scanning: false,
|
|
scanning: false,
|
|
|
scanRange: undefined,
|
|
scanRange: undefined,
|
|
|
scanner: undefined,
|
|
scanner: undefined,
|
|
|
|
|
+ update: makeInitialUpdateState(),
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
@@ -482,6 +519,41 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|
|
})
|
|
})
|
|
|
.create();
|
|
.create();
|
|
|
|
|
|
|
|
|
|
+export const updateChildRefreshState = (
|
|
|
|
|
+ state: Readonly<ExploreItemState>,
|
|
|
|
|
+ payload: LocationUpdate,
|
|
|
|
|
+ exploreId: ExploreId
|
|
|
|
|
+): ExploreItemState => {
|
|
|
|
|
+ const path = payload.path || '';
|
|
|
|
|
+ const queryState = payload.query[exploreId] as string;
|
|
|
|
|
+ if (!queryState) {
|
|
|
|
|
+ return state;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const urlState = parseUrlState(queryState);
|
|
|
|
|
+ if (!state.urlState || path !== '/explore') {
|
|
|
|
|
+ // we only want to refresh when browser back/forward
|
|
|
|
|
+ return { ...state, urlState, update: { datasource: false, queries: false, range: false, ui: false } };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const datasource = _.isEqual(urlState ? urlState.datasource : '', state.urlState.datasource) === false;
|
|
|
|
|
+ const queries = _.isEqual(urlState ? urlState.queries : [], state.urlState.queries) === false;
|
|
|
|
|
+ const range = _.isEqual(urlState ? urlState.range : DEFAULT_RANGE, state.urlState.range) === false;
|
|
|
|
|
+ const ui = _.isEqual(urlState ? urlState.ui : DEFAULT_UI_STATE, state.urlState.ui) === false;
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...state,
|
|
|
|
|
+ urlState,
|
|
|
|
|
+ update: {
|
|
|
|
|
+ ...state.update,
|
|
|
|
|
+ datasource,
|
|
|
|
|
+ queries,
|
|
|
|
|
+ range,
|
|
|
|
|
+ ui,
|
|
|
|
|
+ },
|
|
|
|
|
+ };
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Global Explore reducer that handles multiple Explore areas (left and right).
|
|
* Global Explore reducer that handles multiple Explore areas (left and right).
|
|
|
* Actions that have an `exploreId` get routed to the ExploreItemReducer.
|
|
* Actions that have an `exploreId` get routed to the ExploreItemReducer.
|
|
@@ -493,16 +565,30 @@ export const exploreReducer = (state = initialExploreState, action: HigherOrderA
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
case ActionTypes.SplitOpen: {
|
|
case ActionTypes.SplitOpen: {
|
|
|
- return { ...state, split: true, right: action.payload.itemState };
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case ActionTypes.InitializeExploreSplit: {
|
|
|
|
|
- return { ...state, split: true };
|
|
|
|
|
|
|
+ return { ...state, split: true, right: { ...action.payload.itemState } };
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
case ActionTypes.ResetExplore: {
|
|
case ActionTypes.ResetExplore: {
|
|
|
return initialExploreState;
|
|
return initialExploreState;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ case updateLocation.type: {
|
|
|
|
|
+ const { query } = action.payload;
|
|
|
|
|
+ if (!query || !query[ExploreId.left]) {
|
|
|
|
|
+ return state;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const split = query[ExploreId.right] ? true : false;
|
|
|
|
|
+ const leftState = state[ExploreId.left];
|
|
|
|
|
+ const rightState = state[ExploreId.right];
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...state,
|
|
|
|
|
+ split,
|
|
|
|
|
+ [ExploreId.left]: updateChildRefreshState(leftState, action.payload, ExploreId.left),
|
|
|
|
|
+ [ExploreId.right]: updateChildRefreshState(rightState, action.payload, ExploreId.right),
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (action.payload) {
|
|
if (action.payload) {
|