瀏覽代碼

Explore: Adds orgId to URL for sharing purposes (#17895)

Also replaces one-off segment detection functions in explore.ts with general purpose function
Closes #15462
kay delaney 6 年之前
父節點
當前提交
164fb13d99

+ 6 - 8
public/app/core/utils/explore.ts

@@ -162,11 +162,8 @@ export function buildQueryTransaction(
 
 export const clearQueryKeys: (query: DataQuery) => object = ({ key, refId, ...rest }) => rest;
 
-const metricProperties = ['expr', 'target', 'datasource', 'query'];
-const isMetricSegment = (segment: { [key: string]: string }) =>
-  metricProperties.some(prop => segment.hasOwnProperty(prop));
-const isUISegment = (segment: { [key: string]: string }) => segment.hasOwnProperty('ui');
-const isModeSegment = (segment: { [key: string]: string }) => segment.hasOwnProperty('mode');
+const isSegment = (segment: { [key: string]: string }, ...props: string[]) =>
+  props.some(prop => segment.hasOwnProperty(prop));
 
 enum ParseUrlStateIndex {
   RangeFrom = 0,
@@ -237,11 +234,12 @@ export function parseUrlState(initial: string | undefined): ExploreUrlState {
   };
   const datasource = parsed[ParseUrlStateIndex.Datasource];
   const parsedSegments = parsed.slice(ParseUrlStateIndex.SegmentsStart);
-  const queries = parsedSegments.filter(segment => isMetricSegment(segment));
-  const modeObj = parsedSegments.filter(segment => isModeSegment(segment))[0];
+  const metricProperties = ['expr', 'target', 'datasource', 'query'];
+  const queries = parsedSegments.filter(segment => isSegment(segment, ...metricProperties));
+  const modeObj = parsedSegments.filter(segment => isSegment(segment, 'mode'))[0];
   const mode = modeObj ? modeObj.mode : ExploreMode.Metrics;
 
-  const uiState = parsedSegments.filter(segment => isUISegment(segment))[0];
+  const uiState = parsedSegments.filter(segment => isSegment(segment, 'ui'))[0];
   const ui = uiState
     ? {
         showingGraph: uiState.ui[ParseUiStateIndex.Graph],

+ 4 - 3
public/app/features/explore/state/epics/stateSaveEpic.test.ts

@@ -15,7 +15,7 @@ describe('stateSaveEpic', () => {
             .whenActionIsDispatched(stateSaveAction())
             .thenResultingActionsEqual(
               updateLocation({
-                query: { left: '["now-6h","now","test",{"mode":null},{"ui":[true,true,true,null]}]' },
+                query: { orgId: '1', left: '["now-6h","now","test",{"mode":null},{"ui":[true,true,true,null]}]' },
                 replace: true,
               }),
               setUrlReplacedAction({ exploreId })
@@ -23,7 +23,7 @@ describe('stateSaveEpic', () => {
         });
       });
 
-      describe('and explore is splitted', () => {
+      describe('and explore is split', () => {
         it('then the correct actions are dispatched', () => {
           const { exploreId, state } = mockExploreState({ split: true });
 
@@ -32,6 +32,7 @@ describe('stateSaveEpic', () => {
             .thenResultingActionsEqual(
               updateLocation({
                 query: {
+                  orgId: '1',
                   left: '["now-6h","now","test",{"mode":null},{"ui":[true,true,true,null]}]',
                   right: '["now-6h","now","test",{"mode":null},{"ui":[true,true,true,null]}]',
                 },
@@ -51,7 +52,7 @@ describe('stateSaveEpic', () => {
           .whenActionIsDispatched(stateSaveAction())
           .thenResultingActionsEqual(
             updateLocation({
-              query: { left: '["now-6h","now","test",{"mode":null},{"ui":[true,true,true,null]}]' },
+              query: { orgId: '1', left: '["now-6h","now","test",{"mode":null},{"ui":[true,true,true,null]}]' },
               replace: false,
             })
           );

+ 2 - 1
public/app/features/explore/state/epics/stateSaveEpic.ts

@@ -31,8 +31,9 @@ export const stateSaveEpic: Epic<ActionOf<any>, ActionOf<any>, StoreState> = (ac
   return action$.ofType(stateSaveAction.type).pipe(
     mergeMap(() => {
       const { left, right, split } = state$.value.explore;
+      const orgId = state$.value.user.orgId.toString();
       const replace = left && left.urlReplaced === false;
-      const urlStates: { [index: string]: string } = {};
+      const urlStates: { [index: string]: string } = { orgId };
       const leftUrlState: ExploreUrlState = {
         datasource: left.datasourceInstance.name,
         queries: left.queries.map(clearQueryKeys),

+ 8 - 1
public/test/mocks/mockExploreState.ts

@@ -2,7 +2,7 @@ import { DataSourceApi } from '@grafana/ui/src/types/datasource';
 
 import { ExploreId, ExploreItemState, ExploreState } from 'app/types/explore';
 import { makeExploreItemState } from 'app/features/explore/state/reducers';
-import { StoreState } from 'app/types';
+import { StoreState, UserState } from 'app/types';
 import { TimeRange, dateTime } from '@grafana/ui';
 
 export const mockExploreState = (options: any = {}) => {
@@ -77,8 +77,15 @@ export const mockExploreState = (options: any = {}) => {
     right,
     split,
   };
+
+  const user: UserState = {
+    orgId: 1,
+    timeZone: 'browser',
+  };
+
   const state: Partial<StoreState> = {
     explore,
+    user,
   };
 
   return {