Read about our upcoming Code of Conduct on this issue

Commit e549bee9 authored by Kushal Pandya's avatar Kushal Pandya
Browse files

Merge branch 'kp-add-query-param-support-search-token-endpoint' into 'master'

Add support for query params for labels endpoint

See merge request gitlab-org/gitlab-ce!17477
......@@ -16,6 +16,7 @@ export default class FilteredSearchDropdownManager {
page,
isGroup,
isGroupAncestor,
isGroupDecendent,
filteredSearchTokenKeys,
}) {
this.container = FilteredSearchContainer.container;
......@@ -26,6 +27,7 @@ export default class FilteredSearchDropdownManager {
this.page = page;
this.groupsOnly = isGroup;
this.groupAncestor = isGroupAncestor;
this.isGroupDecendent = isGroupDecendent;
this.setupMapping();
......
......@@ -22,11 +22,13 @@ export default class FilteredSearchManager {
page,
isGroup = false,
isGroupAncestor = false,
isGroupDecendent = false,
filteredSearchTokenKeys = FilteredSearchTokenKeys,
stateFiltersSelector = '.issues-state-filters',
}) {
this.isGroup = isGroup;
this.isGroupAncestor = isGroupAncestor;
this.isGroupDecendent = isGroupDecendent;
this.states = ['opened', 'closed', 'merged', 'all'];
this.page = page;
......
import _ from 'underscore';
import AjaxCache from '../lib/utils/ajax_cache';
import AjaxCache from '~/lib/utils/ajax_cache';
import { objectToQueryString } from '~/lib/utils/common_utils';
import Flash from '../flash';
import FilteredSearchContainer from './container';
import UsersCache from '../lib/utils/users_cache';
......@@ -16,6 +17,21 @@ export default class FilteredSearchVisualTokens {
};
}
/**
* Returns a computed API endpoint
* and query string composed of values from endpointQueryParams
* @param {String} endpoint
* @param {String} endpointQueryParams
*/
static getEndpointWithQueryParams(endpoint, endpointQueryParams) {
if (!endpointQueryParams) {
return endpoint;
}
const queryString = objectToQueryString(JSON.parse(endpointQueryParams));
return `${endpoint}?${queryString}`;
}
static unselectTokens() {
const otherTokens = FilteredSearchContainer.container.querySelectorAll('.js-visual-token .selectable.selected');
[].forEach.call(otherTokens, t => t.classList.remove('selected'));
......@@ -86,7 +102,10 @@ export default class FilteredSearchVisualTokens {
static updateLabelTokenColor(tokenValueContainer, tokenValue) {
const filteredSearchInput = FilteredSearchContainer.container.querySelector('.filtered-search');
const baseEndpoint = filteredSearchInput.dataset.baseEndpoint;
const labelsEndpoint = `${baseEndpoint}/labels.json`;
const labelsEndpoint = FilteredSearchVisualTokens.getEndpointWithQueryParams(
`${baseEndpoint}/labels.json`,
filteredSearchInput.dataset.endpointQueryParams,
);
return AjaxCache.retrieve(labelsEndpoint)
.then(FilteredSearchVisualTokens.preprocessLabel.bind(null, labelsEndpoint))
......
......@@ -302,6 +302,14 @@ export const parseQueryStringIntoObject = (query = '') => {
}, {});
};
/**
* Converts object with key-value pairs
* into query-param string
*
* @param {Object} params
*/
export const objectToQueryString = (params = {}) => Object.keys(params).map(param => `${param}=${params[param]}`).join('&');
export const buildUrlWithCurrentLocation = param => (param ? `${window.location.pathname}${param}` : window.location.pathname);
/**
......
......@@ -5,6 +5,7 @@ export default ({
filteredSearchTokenKeys,
isGroup,
isGroupAncestor,
isGroupDecendent,
stateFiltersSelector,
}) => {
const filteredSearchEnabled = FilteredSearchManager && document.querySelector('.filtered-search');
......@@ -13,6 +14,7 @@ export default ({
page,
isGroup,
isGroupAncestor,
isGroupDecendent,
filteredSearchTokenKeys,
stateFiltersSelector,
});
......
......@@ -128,6 +128,24 @@ describe('Filtered Search Visual Tokens', () => {
});
});
describe('getEndpointWithQueryParams', () => {
it('returns `endpoint` string as is when second param `endpointQueryParams` is undefined, null or empty string', () => {
const endpoint = 'foo/bar/labels.json';
expect(subject.getEndpointWithQueryParams(endpoint)).toBe(endpoint);
expect(subject.getEndpointWithQueryParams(endpoint, null)).toBe(endpoint);
expect(subject.getEndpointWithQueryParams(endpoint, '')).toBe(endpoint);
});
it('returns `endpoint` string with values of `endpointQueryParams`', () => {
const endpoint = 'foo/bar/labels.json';
const singleQueryParams = '{"foo":"true"}';
const multipleQueryParams = '{"foo":"true","bar":"true"}';
expect(subject.getEndpointWithQueryParams(endpoint, singleQueryParams)).toBe(`${endpoint}?foo=true`);
expect(subject.getEndpointWithQueryParams(endpoint, multipleQueryParams)).toBe(`${endpoint}?foo=true&bar=true`);
});
});
describe('unselectTokens', () => {
it('does nothing when there are no tokens', () => {
const beforeHTML = tokensContainer.innerHTML;
......
......@@ -166,6 +166,21 @@ describe('common_utils', () => {
});
});
describe('objectToQueryString', () => {
it('returns empty string when `param` is undefined, null or empty string', () => {
expect(commonUtils.objectToQueryString()).toBe('');
expect(commonUtils.objectToQueryString('')).toBe('');
});
it('returns query string with values of `params`', () => {
const singleQueryParams = { foo: true };
const multipleQueryParams = { foo: true, bar: true };
expect(commonUtils.objectToQueryString(singleQueryParams)).toBe('foo=true');
expect(commonUtils.objectToQueryString(multipleQueryParams)).toBe('foo=true&bar=true');
});
});
describe('buildUrlWithCurrentLocation', () => {
it('should build an url with current location and given parameters', () => {
expect(commonUtils.buildUrlWithCurrentLocation()).toEqual(window.location.pathname);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment