Commit c9660b45 authored by Kushal Pandya's avatar Kushal Pandya

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
parents 98fecb5f ca430d24
...@@ -16,6 +16,7 @@ export default class FilteredSearchDropdownManager { ...@@ -16,6 +16,7 @@ export default class FilteredSearchDropdownManager {
page, page,
isGroup, isGroup,
isGroupAncestor, isGroupAncestor,
isGroupDecendent,
filteredSearchTokenKeys, filteredSearchTokenKeys,
}) { }) {
this.container = FilteredSearchContainer.container; this.container = FilteredSearchContainer.container;
...@@ -26,6 +27,7 @@ export default class FilteredSearchDropdownManager { ...@@ -26,6 +27,7 @@ export default class FilteredSearchDropdownManager {
this.page = page; this.page = page;
this.groupsOnly = isGroup; this.groupsOnly = isGroup;
this.groupAncestor = isGroupAncestor; this.groupAncestor = isGroupAncestor;
this.isGroupDecendent = isGroupDecendent;
this.setupMapping(); this.setupMapping();
......
...@@ -22,11 +22,13 @@ export default class FilteredSearchManager { ...@@ -22,11 +22,13 @@ export default class FilteredSearchManager {
page, page,
isGroup = false, isGroup = false,
isGroupAncestor = false, isGroupAncestor = false,
isGroupDecendent = false,
filteredSearchTokenKeys = FilteredSearchTokenKeys, filteredSearchTokenKeys = FilteredSearchTokenKeys,
stateFiltersSelector = '.issues-state-filters', stateFiltersSelector = '.issues-state-filters',
}) { }) {
this.isGroup = isGroup; this.isGroup = isGroup;
this.isGroupAncestor = isGroupAncestor; this.isGroupAncestor = isGroupAncestor;
this.isGroupDecendent = isGroupDecendent;
this.states = ['opened', 'closed', 'merged', 'all']; this.states = ['opened', 'closed', 'merged', 'all'];
this.page = page; this.page = page;
......
import _ from 'underscore'; 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 Flash from '../flash';
import FilteredSearchContainer from './container'; import FilteredSearchContainer from './container';
import UsersCache from '../lib/utils/users_cache'; import UsersCache from '../lib/utils/users_cache';
...@@ -16,6 +17,21 @@ export default class FilteredSearchVisualTokens { ...@@ -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() { static unselectTokens() {
const otherTokens = FilteredSearchContainer.container.querySelectorAll('.js-visual-token .selectable.selected'); const otherTokens = FilteredSearchContainer.container.querySelectorAll('.js-visual-token .selectable.selected');
[].forEach.call(otherTokens, t => t.classList.remove('selected')); [].forEach.call(otherTokens, t => t.classList.remove('selected'));
...@@ -86,7 +102,10 @@ export default class FilteredSearchVisualTokens { ...@@ -86,7 +102,10 @@ export default class FilteredSearchVisualTokens {
static updateLabelTokenColor(tokenValueContainer, tokenValue) { static updateLabelTokenColor(tokenValueContainer, tokenValue) {
const filteredSearchInput = FilteredSearchContainer.container.querySelector('.filtered-search'); const filteredSearchInput = FilteredSearchContainer.container.querySelector('.filtered-search');
const baseEndpoint = filteredSearchInput.dataset.baseEndpoint; const baseEndpoint = filteredSearchInput.dataset.baseEndpoint;
const labelsEndpoint = `${baseEndpoint}/labels.json`; const labelsEndpoint = FilteredSearchVisualTokens.getEndpointWithQueryParams(
`${baseEndpoint}/labels.json`,
filteredSearchInput.dataset.endpointQueryParams,
);
return AjaxCache.retrieve(labelsEndpoint) return AjaxCache.retrieve(labelsEndpoint)
.then(FilteredSearchVisualTokens.preprocessLabel.bind(null, labelsEndpoint)) .then(FilteredSearchVisualTokens.preprocessLabel.bind(null, labelsEndpoint))
......
...@@ -302,6 +302,14 @@ export const parseQueryStringIntoObject = (query = '') => { ...@@ -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); export const buildUrlWithCurrentLocation = param => (param ? `${window.location.pathname}${param}` : window.location.pathname);
/** /**
......
...@@ -5,6 +5,7 @@ export default ({ ...@@ -5,6 +5,7 @@ export default ({
filteredSearchTokenKeys, filteredSearchTokenKeys,
isGroup, isGroup,
isGroupAncestor, isGroupAncestor,
isGroupDecendent,
stateFiltersSelector, stateFiltersSelector,
}) => { }) => {
const filteredSearchEnabled = FilteredSearchManager && document.querySelector('.filtered-search'); const filteredSearchEnabled = FilteredSearchManager && document.querySelector('.filtered-search');
...@@ -13,6 +14,7 @@ export default ({ ...@@ -13,6 +14,7 @@ export default ({
page, page,
isGroup, isGroup,
isGroupAncestor, isGroupAncestor,
isGroupDecendent,
filteredSearchTokenKeys, filteredSearchTokenKeys,
stateFiltersSelector, stateFiltersSelector,
}); });
......
...@@ -128,6 +128,24 @@ describe('Filtered Search Visual Tokens', () => { ...@@ -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', () => { describe('unselectTokens', () => {
it('does nothing when there are no tokens', () => { it('does nothing when there are no tokens', () => {
const beforeHTML = tokensContainer.innerHTML; const beforeHTML = tokensContainer.innerHTML;
......
...@@ -166,6 +166,21 @@ describe('common_utils', () => { ...@@ -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', () => { describe('buildUrlWithCurrentLocation', () => {
it('should build an url with current location and given parameters', () => { it('should build an url with current location and given parameters', () => {
expect(commonUtils.buildUrlWithCurrentLocation()).toEqual(window.location.pathname); 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