Explore: deprecate compact URL encoding & dafault to extended (#44385)

This commit is contained in:
Giordano Ricci 2022-01-27 11:23:56 +00:00 committed by GitHub
parent 465ed9f5d3
commit ea48d131ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 20 deletions

View File

@ -199,19 +199,12 @@ export const urlUtil = {
* Create an string that is used in URL to represent the Explore state. This is basically just a stringified json * Create an string that is used in URL to represent the Explore state. This is basically just a stringified json
* that is that used as a state of a single Explore pane so it does not represent full Explore URL. * that is that used as a state of a single Explore pane so it does not represent full Explore URL.
* *
* There are 2 versions of this, normal and compact. Normal is just the same object stringified while compact turns
* properties of the object into array where the order is significant.
* @param urlState * @param urlState
* @param compact * @param compact this parameter is deprecated and will be removed in a future release.
*/ */
export function serializeStateToUrlParam(urlState: ExploreUrlState, compact?: boolean): string { export function serializeStateToUrlParam(urlState: ExploreUrlState, compact?: boolean): string {
if (compact) { if (compact !== undefined) {
const compactState: unknown[] = [urlState.range.from, urlState.range.to, urlState.datasource, ...urlState.queries]; console.warn('`compact` parameter is deprecated and will be removed in a future release');
// only serialize panel state if we have at least one non-default panel configuration
if (urlState.panelsState !== undefined) {
compactState.push({ __panelsState: urlState.panelsState });
}
return JSON.stringify(compactState);
} }
return JSON.stringify(urlState); return JSON.stringify(urlState);
} }

View File

@ -114,6 +114,7 @@ describe('state functions', () => {
); );
}); });
// TODO: remove in 9.0
it('returns url parameter value for a state object', () => { it('returns url parameter value for a state object', () => {
const state = { const state = {
...DEFAULT_EXPLORE_STATE, ...DEFAULT_EXPLORE_STATE,
@ -134,7 +135,7 @@ describe('state functions', () => {
}, },
}; };
expect(serializeStateToUrlParam(state, true)).toBe( expect(serializeStateToUrlParam(state, true)).toBe(
'["now-5h","now","foo",{"expr":"metric{test=\\"a/b\\"}","refId":"A"},{"expr":"super{foo=\\"x/z\\"}","refId":"B"}]' '{"datasource":"foo","queries":[{"expr":"metric{test=\\"a/b\\"}","refId":"A"},{"expr":"super{foo=\\"x/z\\"}","refId":"B"}],"range":{"from":"now-5h","to":"now"}}'
); );
}); });
}); });
@ -164,6 +165,7 @@ describe('state functions', () => {
expect(state).toMatchObject(parsed); expect(state).toMatchObject(parsed);
}); });
// TODO: remove in 9.0
it('can parse the compact serialized state into the original state', () => { it('can parse the compact serialized state into the original state', () => {
const state = { const state = {
...DEFAULT_EXPLORE_STATE, ...DEFAULT_EXPLORE_STATE,

View File

@ -214,7 +214,7 @@ export const createUrlFromRichHistory = (query: RichHistoryQuery) => {
context: 'explore', context: 'explore',
}; };
const serializedState = serializeStateToUrlParam(exploreState, true); const serializedState = serializeStateToUrlParam(exploreState);
const baseUrl = /.*(?=\/explore)/.exec(`${window.location.href}`)![0]; const baseUrl = /.*(?=\/explore)/.exec(`${window.location.href}`)![0];
const url = urlUtil.renderUrl(`${baseUrl}/explore`, { left: serializedState }); const url = urlUtil.renderUrl(`${baseUrl}/explore`, { left: serializedState });
return url; return url;

View File

@ -12,6 +12,7 @@ import {
FieldType, FieldType,
QueryEditorProps, QueryEditorProps,
ScopedVars, ScopedVars,
serializeStateToUrlParam,
} from '@grafana/data'; } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@ -66,13 +67,23 @@ describe('Wrapper', () => {
// At this point url should be initialised to some defaults // At this point url should be initialised to some defaults
expect(locationService.getSearchObject()).toEqual({ expect(locationService.getSearchObject()).toEqual({
orgId: '1', orgId: '1',
left: JSON.stringify(['now-1h', 'now', 'loki', { refId: 'A' }]), left: serializeStateToUrlParam({
datasource: 'loki',
queries: [{ refId: 'A' }],
range: { from: 'now-1h', to: 'now' },
}),
}); });
expect(datasources.loki.query).not.toBeCalled(); expect(datasources.loki.query).not.toBeCalled();
}); });
it('runs query when url contains query and renders results', async () => { it('runs query when url contains query and renders results', async () => {
const query = { left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}', refId: 'A' }]) }; const query = {
left: serializeStateToUrlParam({
datasource: 'loki',
queries: [{ refId: 'A', expr: '{ label="value"}' }],
range: { from: 'now-1h', to: 'now' },
}),
};
const { datasources, store } = setup({ query }); const { datasources, store } = setup({ query });
(datasources.loki.query as Mock).mockReturnValueOnce(makeLogsQueryResponse()); (datasources.loki.query as Mock).mockReturnValueOnce(makeLogsQueryResponse());
@ -155,7 +166,11 @@ describe('Wrapper', () => {
expect(datasources.elastic.query).not.toBeCalled(); expect(datasources.elastic.query).not.toBeCalled();
expect(locationService.getSearchObject()).toEqual({ expect(locationService.getSearchObject()).toEqual({
orgId: '1', orgId: '1',
left: JSON.stringify(['now-1h', 'now', 'elastic', { refId: 'A' }]), left: serializeStateToUrlParam({
datasource: 'elastic',
queries: [{ refId: 'A' }],
range: { from: 'now-1h', to: 'now' },
}),
}); });
}); });
@ -172,8 +187,16 @@ describe('Wrapper', () => {
it('inits with two panes if specified in url', async () => { it('inits with two panes if specified in url', async () => {
const query = { const query = {
left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}', refId: 'A' }]), left: serializeStateToUrlParam({
right: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'error', refId: 'A' }]), datasource: 'loki',
queries: [{ refId: 'A', expr: '{ label="value"}' }],
range: { from: 'now-1h', to: 'now' },
}),
right: serializeStateToUrlParam({
datasource: 'elastic',
queries: [{ refId: 'A', expr: 'error' }],
range: { from: 'now-1h', to: 'now' },
}),
}; };
const { datasources } = setup({ query }); const { datasources } = setup({ query });

View File

@ -64,10 +64,10 @@ export const stateSave = (options?: { replace?: boolean }): ThunkResult<void> =>
const orgId = getState().user.orgId.toString(); const orgId = getState().user.orgId.toString();
const urlStates: { [index: string]: string | null } = { orgId }; const urlStates: { [index: string]: string | null } = { orgId };
urlStates.left = serializeStateToUrlParam(getUrlStateFromPaneState(left), true); urlStates.left = serializeStateToUrlParam(getUrlStateFromPaneState(left));
if (right) { if (right) {
urlStates.right = serializeStateToUrlParam(getUrlStateFromPaneState(right), true); urlStates.right = serializeStateToUrlParam(getUrlStateFromPaneState(right));
} else { } else {
urlStates.right = null; urlStates.right = null;
} }
@ -103,7 +103,7 @@ export const splitOpen: SplitOpen = (options): ThunkResult<void> => {
}; };
} }
const urlState = serializeStateToUrlParam(rightUrlState, true); const urlState = serializeStateToUrlParam(rightUrlState);
locationService.partial({ right: urlState }, true); locationService.partial({ right: urlState }, true);
}; };
}; };