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
pull/17850/head^2
kay delaney 6 years ago committed by GitHub
parent 22e2ac270b
commit 164fb13d99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      public/app/core/utils/explore.ts
  2. 7
      public/app/features/explore/state/epics/stateSaveEpic.test.ts
  3. 3
      public/app/features/explore/state/epics/stateSaveEpic.ts
  4. 9
      public/test/mocks/mockExploreState.ts

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

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

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

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

Loading…
Cancel
Save