mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
fix: multi valued query variables did not work correctly, fixes #10539
This commit is contained in:
52
public/app/core/utils/url.ts
Normal file
52
public/app/core/utils/url.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @preserve jquery-param (c) 2015 KNOWLEDGECODE | MIT
|
||||
*/
|
||||
|
||||
export function toUrlParams(a) {
|
||||
let s = [];
|
||||
let rbracket = /\[\]$/;
|
||||
|
||||
let isArray = function(obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object Array]';
|
||||
};
|
||||
|
||||
let add = function(k, v) {
|
||||
v = typeof v === 'function' ? v() : v === null ? '' : v === undefined ? '' : v;
|
||||
s[s.length] = encodeURIComponent(k) + '=' + encodeURIComponent(v);
|
||||
};
|
||||
|
||||
let buildParams = function(prefix, obj) {
|
||||
var i, len, key;
|
||||
|
||||
if (prefix) {
|
||||
if (isArray(obj)) {
|
||||
for (i = 0, len = obj.length; i < len; i++) {
|
||||
if (rbracket.test(prefix)) {
|
||||
add(prefix, obj[i]);
|
||||
} else {
|
||||
buildParams(prefix, obj[i]);
|
||||
}
|
||||
}
|
||||
} else if (obj && String(obj) === '[object Object]') {
|
||||
for (key in obj) {
|
||||
buildParams(prefix + '[' + key + ']', obj[key]);
|
||||
}
|
||||
} else {
|
||||
add(prefix, obj);
|
||||
}
|
||||
} else if (isArray(obj)) {
|
||||
for (i = 0, len = obj.length; i < len; i++) {
|
||||
add(obj[i].name, obj[i].value);
|
||||
}
|
||||
} else {
|
||||
for (key in obj) {
|
||||
buildParams(key, obj[key]);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
||||
return buildParams('', a)
|
||||
.join('&')
|
||||
.replace(/%20/g, '+');
|
||||
}
|
||||
26
public/app/stores/ViewStore/ViewStore.jest.ts
Normal file
26
public/app/stores/ViewStore/ViewStore.jest.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { ViewStore } from './ViewStore';
|
||||
import { toJS } from 'mobx';
|
||||
|
||||
describe('ViewStore', () => {
|
||||
let store;
|
||||
|
||||
beforeAll(() => {
|
||||
store = ViewStore.create({
|
||||
path: '',
|
||||
query: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('Can update path and query', () => {
|
||||
store.updatePathAndQuery('/hello', { key: 1, otherParam: 'asd' });
|
||||
expect(store.path).toBe('/hello');
|
||||
expect(store.query.get('key')).toBe(1);
|
||||
expect(store.currentUrl).toBe('/hello?key=1&otherParam=asd');
|
||||
});
|
||||
|
||||
it('Query can contain arrays', () => {
|
||||
store.updatePathAndQuery('/hello', { values: ['A', 'B'] });
|
||||
expect(store.query.get('values').toJS()).toMatchObject(['A', 'B']);
|
||||
expect(store.currentUrl).toBe('/hello?values=A&values=B');
|
||||
});
|
||||
});
|
||||
@@ -1,15 +1,9 @@
|
||||
import { types } from 'mobx-state-tree';
|
||||
import { toJS } from 'mobx';
|
||||
import { toUrlParams } from 'app/core/utils/url';
|
||||
|
||||
const QueryValueType = types.union(types.string, types.boolean, types.number);
|
||||
const urlParameterize = queryObj => {
|
||||
const keys = Object.keys(queryObj);
|
||||
const newQuery = keys.reduce((acc: string, key: string, idx: number) => {
|
||||
const preChar = idx === 0 ? '?' : '&';
|
||||
return acc + preChar + key + '=' + queryObj[key];
|
||||
}, '');
|
||||
|
||||
return newQuery;
|
||||
};
|
||||
const QueryInnerValueType = types.union(types.string, types.boolean, types.number);
|
||||
const QueryValueType = types.union(QueryInnerValueType, types.array(QueryInnerValueType));
|
||||
|
||||
export const ViewStore = types
|
||||
.model({
|
||||
@@ -21,7 +15,7 @@ export const ViewStore = types
|
||||
let path = self.path;
|
||||
|
||||
if (self.query.size) {
|
||||
path += urlParameterize(self.query.toJS());
|
||||
path += '?' + toUrlParams(toJS(self.query));
|
||||
}
|
||||
return path;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user