|
@@ -157,49 +157,72 @@ export function buildQueryTransaction(
|
|
|
|
|
|
|
|
export const clearQueryKeys: (query: DataQuery) => object = ({ key, refId, ...rest }) => rest;
|
|
export const clearQueryKeys: (query: DataQuery) => object = ({ key, refId, ...rest }) => rest;
|
|
|
|
|
|
|
|
-const isMetricSegment = (segment: { [key: string]: string }) => segment.hasOwnProperty('expr');
|
|
|
|
|
|
|
+const metricProperties = ['expr', 'target', 'datasource'];
|
|
|
|
|
+const isMetricSegment = (segment: { [key: string]: string }) =>
|
|
|
|
|
+ metricProperties.some(prop => segment.hasOwnProperty(prop));
|
|
|
const isUISegment = (segment: { [key: string]: string }) => segment.hasOwnProperty('ui');
|
|
const isUISegment = (segment: { [key: string]: string }) => segment.hasOwnProperty('ui');
|
|
|
|
|
|
|
|
|
|
+enum ParseUrlStateIndex {
|
|
|
|
|
+ RangeFrom = 0,
|
|
|
|
|
+ RangeTo = 1,
|
|
|
|
|
+ Datasource = 2,
|
|
|
|
|
+ SegmentsStart = 3,
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+enum ParseUiStateIndex {
|
|
|
|
|
+ Graph = 0,
|
|
|
|
|
+ Logs = 1,
|
|
|
|
|
+ Table = 2,
|
|
|
|
|
+ Strategy = 3,
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export const safeParseJson = (text: string) => {
|
|
|
|
|
+ if (!text) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ return JSON.parse(decodeURI(text));
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error(error);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
export function parseUrlState(initial: string | undefined): ExploreUrlState {
|
|
export function parseUrlState(initial: string | undefined): ExploreUrlState {
|
|
|
- let uiState = DEFAULT_UI_STATE;
|
|
|
|
|
-
|
|
|
|
|
- if (initial) {
|
|
|
|
|
- try {
|
|
|
|
|
- const parsed = JSON.parse(decodeURI(initial));
|
|
|
|
|
- if (Array.isArray(parsed)) {
|
|
|
|
|
- if (parsed.length <= 3) {
|
|
|
|
|
- throw new Error('Error parsing compact URL state for Explore.');
|
|
|
|
|
- }
|
|
|
|
|
- const range = {
|
|
|
|
|
- from: parsed[0],
|
|
|
|
|
- to: parsed[1],
|
|
|
|
|
- };
|
|
|
|
|
- const datasource = parsed[2];
|
|
|
|
|
- let queries = [];
|
|
|
|
|
-
|
|
|
|
|
- parsed.slice(3).forEach(segment => {
|
|
|
|
|
- if (isMetricSegment(segment)) {
|
|
|
|
|
- queries = [...queries, segment];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (isUISegment(segment)) {
|
|
|
|
|
- uiState = {
|
|
|
|
|
- showingGraph: segment.ui[0],
|
|
|
|
|
- showingLogs: segment.ui[1],
|
|
|
|
|
- showingTable: segment.ui[2],
|
|
|
|
|
- dedupStrategy: segment.ui[3],
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- return { datasource, queries, range, ui: uiState };
|
|
|
|
|
- }
|
|
|
|
|
- return parsed;
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- console.error(e);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const parsed = safeParseJson(initial);
|
|
|
|
|
+ const errorResult = { datasource: null, queries: [], range: DEFAULT_RANGE, ui: DEFAULT_UI_STATE };
|
|
|
|
|
+
|
|
|
|
|
+ if (!parsed) {
|
|
|
|
|
+ return errorResult;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!Array.isArray(parsed)) {
|
|
|
|
|
+ return parsed;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (parsed.length <= ParseUrlStateIndex.SegmentsStart) {
|
|
|
|
|
+ console.error('Error parsing compact URL state for Explore.');
|
|
|
|
|
+ return errorResult;
|
|
|
}
|
|
}
|
|
|
- return { datasource: null, queries: [], range: DEFAULT_RANGE, ui: uiState };
|
|
|
|
|
|
|
+
|
|
|
|
|
+ const range = {
|
|
|
|
|
+ from: parsed[ParseUrlStateIndex.RangeFrom],
|
|
|
|
|
+ to: parsed[ParseUrlStateIndex.RangeTo],
|
|
|
|
|
+ };
|
|
|
|
|
+ const datasource = parsed[ParseUrlStateIndex.Datasource];
|
|
|
|
|
+ const parsedSegments = parsed.slice(ParseUrlStateIndex.SegmentsStart);
|
|
|
|
|
+ const queries = parsedSegments.filter(segment => isMetricSegment(segment));
|
|
|
|
|
+ const uiState = parsedSegments.filter(segment => isUISegment(segment))[0];
|
|
|
|
|
+ const ui = uiState
|
|
|
|
|
+ ? {
|
|
|
|
|
+ showingGraph: uiState.ui[ParseUiStateIndex.Graph],
|
|
|
|
|
+ showingLogs: uiState.ui[ParseUiStateIndex.Logs],
|
|
|
|
|
+ showingTable: uiState.ui[ParseUiStateIndex.Table],
|
|
|
|
|
+ dedupStrategy: uiState.ui[ParseUiStateIndex.Strategy],
|
|
|
|
|
+ }
|
|
|
|
|
+ : DEFAULT_UI_STATE;
|
|
|
|
|
+
|
|
|
|
|
+ return { datasource, queries, range, ui };
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export function serializeStateToUrlParam(urlState: ExploreUrlState, compact?: boolean): string {
|
|
export function serializeStateToUrlParam(urlState: ExploreUrlState, compact?: boolean): string {
|