Commit ef91fadb authored by Clement Ho's avatar Clement Ho

Merge branch 'rest-of-dispatcher' into 'master'

Rest of Dispatcher Refactor

See merge request gitlab-org/gitlab-ce!16659
parents ace12dd1 bd8290d9
...@@ -4,7 +4,7 @@ import NewCommitForm from '../new_commit_form'; ...@@ -4,7 +4,7 @@ import NewCommitForm from '../new_commit_form';
import EditBlob from './edit_blob'; import EditBlob from './edit_blob';
import BlobFileDropzone from '../blob/blob_file_dropzone'; import BlobFileDropzone from '../blob/blob_file_dropzone';
$(() => { export default () => {
const editBlobForm = $('.js-edit-blob-form'); const editBlobForm = $('.js-edit-blob-form');
const uploadBlobForm = $('.js-upload-blob-form'); const uploadBlobForm = $('.js-upload-blob-form');
const deleteBlobForm = $('.js-delete-blob-form'); const deleteBlobForm = $('.js-delete-blob-form');
...@@ -34,4 +34,4 @@ $(() => { ...@@ -34,4 +34,4 @@ $(() => {
if (deleteBlobForm.length) { if (deleteBlobForm.length) {
new NewCommitForm(deleteBlobForm); new NewCommitForm(deleteBlobForm);
} }
}); };
/* eslint-disable class-methods-use-this */ /* eslint-disable class-methods-use-this */
import FilteredSearchContainer from '../filtered_search/container'; import FilteredSearchContainer from '../filtered_search/container';
import FilteredSearchManager from '../filtered_search/filtered_search_manager';
export default class FilteredSearchBoards extends gl.FilteredSearchManager { export default class FilteredSearchBoards extends FilteredSearchManager {
constructor(store, updateUrl = false, cantEdit = []) { constructor(store, updateUrl = false, cantEdit = []) {
super('boards'); super('boards');
......
...@@ -174,11 +174,6 @@ var Dispatcher; ...@@ -174,11 +174,6 @@ var Dispatcher;
.catch(fail); .catch(fail);
shortcut_handler = true; shortcut_handler = true;
break; break;
case 'help:index':
import('./pages/help')
.then(callDefault)
.catch(fail);
break;
case 'search:show': case 'search:show':
import('./pages/search/show') import('./pages/search/show')
.then(callDefault) .then(callDefault)
......
...@@ -4,10 +4,7 @@ function addMousetrapClick(el, key) { ...@@ -4,10 +4,7 @@ function addMousetrapClick(el, key) {
el.addEventListener('click', () => Mousetrap.trigger(key)); el.addEventListener('click', () => Mousetrap.trigger(key));
} }
function domContentLoaded() { export default () => {
addMousetrapClick(document.querySelector('.js-trigger-shortcut'), '?'); addMousetrapClick(document.querySelector('.js-trigger-shortcut'), '?');
addMousetrapClick(document.querySelector('.js-trigger-search-bar'), 's'); addMousetrapClick(document.querySelector('.js-trigger-search-bar'), 's');
} };
document.addEventListener('DOMContentLoaded', domContentLoaded);
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import FilteredSearchTokenizer from '../filtered_search_tokenizer';
export default { export default {
name: 'RecentSearchesDropdownContent', name: 'RecentSearchesDropdownContent',
...@@ -23,7 +24,7 @@ export default { ...@@ -23,7 +24,7 @@ export default {
processedItems() { processedItems() {
return this.items.map((item) => { return this.items.map((item) => {
const { tokens, searchToken } const { tokens, searchToken }
= gl.FilteredSearchTokenizer.processTokens(item, this.allowedKeys); = FilteredSearchTokenizer.processTokens(item, this.allowedKeys);
const resultantTokens = tokens.map(token => ({ const resultantTokens = tokens.map(token => ({
prefix: `${token.key}:`, prefix: `${token.key}:`,
......
import Flash from '../flash'; import Flash from '../flash';
import Ajax from '../droplab/plugins/ajax'; import Ajax from '../droplab/plugins/ajax';
import Filter from '../droplab/plugins/filter'; import Filter from '../droplab/plugins/filter';
import './filtered_search_dropdown'; import FilteredSearchDropdown from './filtered_search_dropdown';
import DropdownUtils from './dropdown_utils';
class DropdownEmoji extends gl.FilteredSearchDropdown { export default class DropdownEmoji extends FilteredSearchDropdown {
constructor(options = {}) { constructor(options = {}) {
super(options); super(options);
this.config = { this.config = {
...@@ -49,7 +50,7 @@ class DropdownEmoji extends gl.FilteredSearchDropdown { ...@@ -49,7 +50,7 @@ class DropdownEmoji extends gl.FilteredSearchDropdown {
itemClicked(e) { itemClicked(e) {
super.itemClicked(e, (selected) => { super.itemClicked(e, (selected) => {
const name = selected.querySelector('.js-data-value').innerText.trim(); const name = selected.querySelector('.js-data-value').innerText.trim();
return gl.DropdownUtils.getEscapedText(name); return DropdownUtils.getEscapedText(name);
}); });
} }
...@@ -76,6 +77,3 @@ class DropdownEmoji extends gl.FilteredSearchDropdown { ...@@ -76,6 +77,3 @@ class DropdownEmoji extends gl.FilteredSearchDropdown {
.addHook(this.input, this.dropdown, [Ajax, Filter], this.config).init(); .addHook(this.input, this.dropdown, [Ajax, Filter], this.config).init();
} }
} }
window.gl = window.gl || {};
gl.DropdownEmoji = DropdownEmoji;
import Filter from '~/droplab/plugins/filter'; import Filter from '~/droplab/plugins/filter';
import './filtered_search_dropdown'; import FilteredSearchDropdown from './filtered_search_dropdown';
import DropdownUtils from './dropdown_utils';
import FilteredSearchDropdownManager from './filtered_search_dropdown_manager';
import FilteredSearchVisualTokens from './filtered_search_visual_tokens';
class DropdownHint extends gl.FilteredSearchDropdown { export default class DropdownHint extends FilteredSearchDropdown {
constructor(options = {}) { constructor(options = {}) {
const { input, tokenKeys } = options; const { input, tokenKeys } = options;
super(options); super(options);
this.config = { this.config = {
Filter: { Filter: {
template: 'hint', template: 'hint',
filterFunction: gl.DropdownUtils.filterHint.bind(null, { filterFunction: DropdownUtils.filterHint.bind(null, {
input, input,
allowedKeys: tokenKeys.getKeys(), allowedKeys: tokenKeys.getKeys(),
}), }),
...@@ -45,10 +48,10 @@ class DropdownHint extends gl.FilteredSearchDropdown { ...@@ -45,10 +48,10 @@ class DropdownHint extends gl.FilteredSearchDropdown {
}); });
if (searchTerms.length > 0) { if (searchTerms.length > 0) {
gl.FilteredSearchVisualTokens.addSearchVisualToken(searchTerms.join(' ')); FilteredSearchVisualTokens.addSearchVisualToken(searchTerms.join(' '));
} }
gl.FilteredSearchDropdownManager.addWordToInput(token.replace(':', ''), '', false, this.container); FilteredSearchDropdownManager.addWordToInput(token.replace(':', ''), '', false, this.container);
} }
this.dismissDropdown(); this.dismissDropdown();
this.dispatchInputEvent(); this.dispatchInputEvent();
...@@ -73,6 +76,3 @@ class DropdownHint extends gl.FilteredSearchDropdown { ...@@ -73,6 +76,3 @@ class DropdownHint extends gl.FilteredSearchDropdown {
this.droplab.addHook(this.input, this.dropdown, [Filter], this.config).init(); this.droplab.addHook(this.input, this.dropdown, [Filter], this.config).init();
} }
} }
window.gl = window.gl || {};
gl.DropdownHint = DropdownHint;
import Flash from '../flash'; import Flash from '../flash';
import Ajax from '../droplab/plugins/ajax'; import Ajax from '../droplab/plugins/ajax';
import Filter from '../droplab/plugins/filter'; import Filter from '../droplab/plugins/filter';
import './filtered_search_dropdown'; import FilteredSearchDropdown from './filtered_search_dropdown';
import DropdownUtils from './dropdown_utils';
class DropdownNonUser extends gl.FilteredSearchDropdown { export default class DropdownNonUser extends FilteredSearchDropdown {
constructor(options = {}) { constructor(options = {}) {
const { input, endpoint, symbol, preprocessing } = options; const { input, endpoint, symbol, preprocessing } = options;
super(options); super(options);
...@@ -21,7 +22,7 @@ class DropdownNonUser extends gl.FilteredSearchDropdown { ...@@ -21,7 +22,7 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
}, },
}, },
Filter: { Filter: {
filterFunction: gl.DropdownUtils.filterWithSymbol.bind(null, this.symbol, input), filterFunction: DropdownUtils.filterWithSymbol.bind(null, this.symbol, input),
template: 'title', template: 'title',
}, },
}; };
...@@ -30,7 +31,7 @@ class DropdownNonUser extends gl.FilteredSearchDropdown { ...@@ -30,7 +31,7 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
itemClicked(e) { itemClicked(e) {
super.itemClicked(e, (selected) => { super.itemClicked(e, (selected) => {
const title = selected.querySelector('.js-data-value').innerText.trim(); const title = selected.querySelector('.js-data-value').innerText.trim();
return `${this.symbol}${gl.DropdownUtils.getEscapedText(title)}`; return `${this.symbol}${DropdownUtils.getEscapedText(title)}`;
}); });
} }
...@@ -45,6 +46,3 @@ class DropdownNonUser extends gl.FilteredSearchDropdown { ...@@ -45,6 +46,3 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
.addHook(this.input, this.dropdown, [Ajax, Filter], this.config).init(); .addHook(this.input, this.dropdown, [Ajax, Filter], this.config).init();
} }
} }
window.gl = window.gl || {};
gl.DropdownNonUser = DropdownNonUser;
import Flash from '../flash'; import Flash from '../flash';
import AjaxFilter from '../droplab/plugins/ajax_filter'; import AjaxFilter from '../droplab/plugins/ajax_filter';
import './filtered_search_dropdown'; import FilteredSearchDropdown from './filtered_search_dropdown';
import { addClassIfElementExists } from '../lib/utils/dom_utils'; import { addClassIfElementExists } from '../lib/utils/dom_utils';
import DropdownUtils from './dropdown_utils';
import FilteredSearchTokenizer from './filtered_search_tokenizer';
class DropdownUser extends gl.FilteredSearchDropdown { export default class DropdownUser extends FilteredSearchDropdown {
constructor(options = {}) { constructor(options = {}) {
const { tokenKeys } = options; const { tokenKeys } = options;
super(options); super(options);
...@@ -56,8 +58,8 @@ class DropdownUser extends gl.FilteredSearchDropdown { ...@@ -56,8 +58,8 @@ class DropdownUser extends gl.FilteredSearchDropdown {
} }
getSearchInput() { getSearchInput() {
const query = gl.DropdownUtils.getSearchInput(this.input); const query = DropdownUtils.getSearchInput(this.input);
const { lastToken } = gl.FilteredSearchTokenizer.processTokens(query, this.tokenKeys.get()); const { lastToken } = FilteredSearchTokenizer.processTokens(query, this.tokenKeys.get());
let value = lastToken || ''; let value = lastToken || '';
...@@ -78,6 +80,3 @@ class DropdownUser extends gl.FilteredSearchDropdown { ...@@ -78,6 +80,3 @@ class DropdownUser extends gl.FilteredSearchDropdown {
this.droplab.addHook(this.input, this.dropdown, [AjaxFilter], this.config).init(); this.droplab.addHook(this.input, this.dropdown, [AjaxFilter], this.config).init();
} }
} }
window.gl = window.gl || {};
gl.DropdownUser = DropdownUser;
import _ from 'underscore'; import _ from 'underscore';
import FilteredSearchContainer from './container'; import FilteredSearchContainer from './container';
import FilteredSearchTokenizer from './filtered_search_tokenizer';
import FilteredSearchDropdownManager from './filtered_search_dropdown_manager';
import FilteredSearchVisualTokens from './filtered_search_visual_tokens';
class DropdownUtils { export default class DropdownUtils {
static getEscapedText(text) { static getEscapedText(text) {
let escapedText = text; let escapedText = text;
const hasSpace = text.indexOf(' ') !== -1; const hasSpace = text.indexOf(' ') !== -1;
...@@ -24,7 +27,7 @@ class DropdownUtils { ...@@ -24,7 +27,7 @@ class DropdownUtils {
static filterWithSymbol(filterSymbol, input, item) { static filterWithSymbol(filterSymbol, input, item) {
const updatedItem = item; const updatedItem = item;
const searchInput = gl.DropdownUtils.getSearchInput(input); const searchInput = DropdownUtils.getSearchInput(input);
const title = updatedItem.title.toLowerCase(); const title = updatedItem.title.toLowerCase();
let value = searchInput.toLowerCase(); let value = searchInput.toLowerCase();
...@@ -114,9 +117,9 @@ class DropdownUtils { ...@@ -114,9 +117,9 @@ class DropdownUtils {
static filterHint(config, item) { static filterHint(config, item) {
const { input, allowedKeys } = config; const { input, allowedKeys } = config;
const updatedItem = item; const updatedItem = item;
const searchInput = gl.DropdownUtils.getSearchQuery(input); const searchInput = DropdownUtils.getSearchQuery(input);
const { lastToken, tokens } = const { lastToken, tokens } =
gl.FilteredSearchTokenizer.processTokens(searchInput, allowedKeys); FilteredSearchTokenizer.processTokens(searchInput, allowedKeys);
const lastKey = lastToken.key || lastToken || ''; const lastKey = lastToken.key || lastToken || '';
const allowMultiple = item.type === 'array'; const allowMultiple = item.type === 'array';
const itemInExistingTokens = tokens.some(t => t.key === item.hint); const itemInExistingTokens = tokens.some(t => t.key === item.hint);
...@@ -140,7 +143,7 @@ class DropdownUtils { ...@@ -140,7 +143,7 @@ class DropdownUtils {
const dataValue = selected.getAttribute('data-value'); const dataValue = selected.getAttribute('data-value');
if (dataValue) { if (dataValue) {
gl.FilteredSearchDropdownManager.addWordToInput(filter, dataValue, true); FilteredSearchDropdownManager.addWordToInput(filter, dataValue, true);
} }
// Return boolean based on whether it was set // Return boolean based on whether it was set
...@@ -190,7 +193,7 @@ class DropdownUtils { ...@@ -190,7 +193,7 @@ class DropdownUtils {
} }
} else if (token.classList.contains('input-token')) { } else if (token.classList.contains('input-token')) {
const { isLastVisualTokenValid } = const { isLastVisualTokenValid } =
gl.FilteredSearchVisualTokens.getLastVisualTokenBeforeInput(); FilteredSearchVisualTokens.getLastVisualTokenBeforeInput();
const input = FilteredSearchContainer.container.querySelector('.filtered-search'); const input = FilteredSearchContainer.container.querySelector('.filtered-search');
const inputValue = input && input.value; const inputValue = input && input.value;
...@@ -211,7 +214,7 @@ class DropdownUtils { ...@@ -211,7 +214,7 @@ class DropdownUtils {
static getSearchInput(filteredSearchInput) { static getSearchInput(filteredSearchInput) {
const inputValue = filteredSearchInput.value; const inputValue = filteredSearchInput.value;
const { right } = gl.DropdownUtils.getInputSelectionPosition(filteredSearchInput); const { right } = DropdownUtils.getInputSelectionPosition(filteredSearchInput);
return inputValue.slice(0, right); return inputValue.slice(0, right);
} }
...@@ -252,6 +255,3 @@ class DropdownUtils { ...@@ -252,6 +255,3 @@ class DropdownUtils {
}; };
} }
} }
window.gl = window.gl || {};
gl.DropdownUtils = DropdownUtils;
import DropdownUtils from './dropdown_utils';
import FilteredSearchDropdownManager from './filtered_search_dropdown_manager';
const DATA_DROPDOWN_TRIGGER = 'data-dropdown-trigger'; const DATA_DROPDOWN_TRIGGER = 'data-dropdown-trigger';
class FilteredSearchDropdown { export default class FilteredSearchDropdown {
constructor({ droplab, dropdown, input, filter }) { constructor({ droplab, dropdown, input, filter }) {
this.droplab = droplab; this.droplab = droplab;
this.hookId = input && input.id; this.hookId = input && input.id;
...@@ -30,11 +33,11 @@ class FilteredSearchDropdown { ...@@ -30,11 +33,11 @@ class FilteredSearchDropdown {
const { selected } = e.detail; const { selected } = e.detail;
if (selected.tagName === 'LI' && selected.innerHTML) { if (selected.tagName === 'LI' && selected.innerHTML) {
const dataValueSet = gl.DropdownUtils.setDataValueIfSelected(this.filter, selected); const dataValueSet = DropdownUtils.setDataValueIfSelected(this.filter, selected);
if (!dataValueSet) { if (!dataValueSet) {
const value = getValueFunction(selected); const value = getValueFunction(selected);
gl.FilteredSearchDropdownManager.addWordToInput(this.filter, value, true); FilteredSearchDropdownManager.addWordToInput(this.filter, value, true);
} }
this.resetFilters(); this.resetFilters();
...@@ -117,6 +120,3 @@ class FilteredSearchDropdown { ...@@ -117,6 +120,3 @@ class FilteredSearchDropdown {
} }
} }
} }
window.gl = window.gl || {};
gl.FilteredSearchDropdown = FilteredSearchDropdown;
import _ from 'underscore'; import _ from 'underscore';
import DropLab from '~/droplab/drop_lab'; import DropLab from '~/droplab/drop_lab';
import FilteredSearchContainer from './container'; import FilteredSearchContainer from './container';
import FilteredSearchTokenKeys from './filtered_search_token_keys';
class FilteredSearchDropdownManager { import DropdownUtils from './dropdown_utils';
import DropdownHint from './dropdown_hint';
import DropdownEmoji from './dropdown_emoji';
import DropdownNonUser from './dropdown_non_user';
import DropdownUser from './dropdown_user';
import FilteredSearchVisualTokens from './filtered_search_visual_tokens';
export default class FilteredSearchDropdownManager {
constructor(baseEndpoint = '', tokenizer, page, isGroup, filteredSearchTokenKeys) { constructor(baseEndpoint = '', tokenizer, page, isGroup, filteredSearchTokenKeys) {
this.container = FilteredSearchContainer.container; this.container = FilteredSearchContainer.container;
this.baseEndpoint = baseEndpoint.replace(/\/$/, ''); this.baseEndpoint = baseEndpoint.replace(/\/$/, '');
this.tokenizer = tokenizer; this.tokenizer = tokenizer;
this.filteredSearchTokenKeys = filteredSearchTokenKeys; this.filteredSearchTokenKeys = filteredSearchTokenKeys || FilteredSearchTokenKeys;
this.filteredSearchInput = this.container.querySelector('.filtered-search'); this.filteredSearchInput = this.container.querySelector('.filtered-search');
this.page = page; this.page = page;
...@@ -33,24 +40,24 @@ class FilteredSearchDropdownManager { ...@@ -33,24 +40,24 @@ class FilteredSearchDropdownManager {
const allowedMappings = { const allowedMappings = {
hint: { hint: {
reference: null, reference: null,
gl: 'DropdownHint', gl: DropdownHint,
element: this.container.querySelector('#js-dropdown-hint'), element: this.container.querySelector('#js-dropdown-hint'),
}, },
}; };
const availableMappings = { const availableMappings = {
author: { author: {
reference: null, reference: null,
gl: 'DropdownUser', gl: DropdownUser,
element: this.container.querySelector('#js-dropdown-author'), element: this.container.querySelector('#js-dropdown-author'),
}, },
assignee: { assignee: {
reference: null, reference: null,
gl: 'DropdownUser', gl: DropdownUser,
element: this.container.querySelector('#js-dropdown-assignee'), element: this.container.querySelector('#js-dropdown-assignee'),
}, },
milestone: { milestone: {
reference: null, reference: null,
gl: 'DropdownNonUser', gl: DropdownNonUser,
extraArguments: { extraArguments: {
endpoint: `${this.baseEndpoint}/milestones.json`, endpoint: `${this.baseEndpoint}/milestones.json`,
symbol: '%', symbol: '%',
...@@ -59,17 +66,17 @@ class FilteredSearchDropdownManager { ...@@ -59,17 +66,17 @@ class FilteredSearchDropdownManager {
}, },
label: { label: {
reference: null, reference: null,
gl: 'DropdownNonUser', gl: DropdownNonUser,
extraArguments: { extraArguments: {
endpoint: `${this.baseEndpoint}/labels.json`, endpoint: `${this.baseEndpoint}/labels.json`,
symbol: '~', symbol: '~',
preprocessing: gl.DropdownUtils.duplicateLabelPreprocessing, preprocessing: DropdownUtils.duplicateLabelPreprocessing,
}, },
element: this.container.querySelector('#js-dropdown-label'), element: this.container.querySelector('#js-dropdown-label'),
}, },
'my-reaction': { 'my-reaction': {
reference: null, reference: null,
gl: 'DropdownEmoji', gl: DropdownEmoji,
element: this.container.querySelector('#js-dropdown-my-reaction'), element: this.container.querySelector('#js-dropdown-my-reaction'),
}, },
}; };
...@@ -86,11 +93,11 @@ class FilteredSearchDropdownManager { ...@@ -86,11 +93,11 @@ class FilteredSearchDropdownManager {
static addWordToInput(tokenName, tokenValue = '', clicked = false) { static addWordToInput(tokenName, tokenValue = '', clicked = false) {
const input = FilteredSearchContainer.container.querySelector('.filtered-search'); const input = FilteredSearchContainer.container.querySelector('.filtered-search');
gl.FilteredSearchVisualTokens.addFilterVisualToken(tokenName, tokenValue); FilteredSearchVisualTokens.addFilterVisualToken(tokenName, tokenValue);
input.value = ''; input.value = '';
if (clicked) { if (clicked) {
gl.FilteredSearchVisualTokens.moveInputToTheRight(); FilteredSearchVisualTokens.moveInputToTheRight();
} }
} }
...@@ -131,9 +138,9 @@ class FilteredSearchDropdownManager { ...@@ -131,9 +138,9 @@ class FilteredSearchDropdownManager {
const extraArguments = mappingKey.extraArguments || {}; const extraArguments = mappingKey.extraArguments || {};
const glArguments = Object.assign({}, defaultArguments, extraArguments); const glArguments = Object.assign({}, defaultArguments, extraArguments);
// Passing glArguments to `new gl[glClass](<arguments>)` // Passing glArguments to `new glClass(<arguments>)`
mappingKey.reference = mappingKey.reference =
new (Function.prototype.bind.apply(gl[glClass], [null, glArguments]))(); new (Function.prototype.bind.apply(glClass, [null, glArguments]))();
} }
if (firstLoad) { if (firstLoad) {
...@@ -171,7 +178,7 @@ class FilteredSearchDropdownManager { ...@@ -171,7 +178,7 @@ class FilteredSearchDropdownManager {
} }
setDropdown() { setDropdown() {
const query = gl.DropdownUtils.getSearchQuery(true); const query = DropdownUtils.getSearchQuery(true);
const { lastToken, searchToken } = const { lastToken, searchToken } =
this.tokenizer.processTokens(query, this.filteredSearchTokenKeys.getKeys()); this.tokenizer.processTokens(query, this.filteredSearchTokenKeys.getKeys());
...@@ -216,6 +223,3 @@ class FilteredSearchDropdownManager { ...@@ -216,6 +223,3 @@ class FilteredSearchDropdownManager {
this.droplab.destroy(); this.droplab.destroy();
} }
} }
window.gl = window.gl || {};
gl.FilteredSearchDropdownManager = FilteredSearchDropdownManager;
import './filtered_search_token_keys'; import './filtered_search_token_keys';
class FilteredSearchTokenizer { export default class FilteredSearchTokenizer {
static processTokens(input, allowedKeys) { static processTokens(input, allowedKeys) {
// Regex extracts `(token):(symbol)(value)` // Regex extracts `(token):(symbol)(value)`
// Values that start with a double quote must end in a double quote (same for single) // Values that start with a double quote must end in a double quote (same for single)
...@@ -50,6 +50,3 @@ class FilteredSearchTokenizer { ...@@ -50,6 +50,3 @@ class FilteredSearchTokenizer {
}; };
} }
} }
window.gl = window.gl || {};
gl.FilteredSearchTokenizer = FilteredSearchTokenizer;
...@@ -3,8 +3,9 @@ import AjaxCache from '../lib/utils/ajax_cache'; ...@@ -3,8 +3,9 @@ import AjaxCache from '../lib/utils/ajax_cache';
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';
import DropdownUtils from './dropdown_utils';
class FilteredSearchVisualTokens { export default class FilteredSearchVisualTokens {
static getLastVisualTokenBeforeInput() { static getLastVisualTokenBeforeInput() {
const inputLi = FilteredSearchContainer.container.querySelector('.input-token'); const inputLi = FilteredSearchContainer.container.querySelector('.input-token');
const lastVisualToken = inputLi && inputLi.previousElementSibling; const lastVisualToken = inputLi && inputLi.previousElementSibling;
...@@ -74,7 +75,7 @@ class FilteredSearchVisualTokens { ...@@ -74,7 +75,7 @@ class FilteredSearchVisualTokens {
let processed = labels; let processed = labels;
if (!labels.preprocessed) { if (!labels.preprocessed) {
processed = gl.DropdownUtils.duplicateLabelPreprocessing(labels); processed = DropdownUtils.duplicateLabelPreprocessing(labels);
AjaxCache.override(labelsEndpoint, processed); AjaxCache.override(labelsEndpoint, processed);
processed.preprocessed = true; processed.preprocessed = true;
} }
...@@ -90,7 +91,7 @@ class FilteredSearchVisualTokens { ...@@ -90,7 +91,7 @@ class FilteredSearchVisualTokens {
return AjaxCache.retrieve(labelsEndpoint) return AjaxCache.retrieve(labelsEndpoint)
.then(FilteredSearchVisualTokens.preprocessLabel.bind(null, labelsEndpoint)) .then(FilteredSearchVisualTokens.preprocessLabel.bind(null, labelsEndpoint))
.then((labels) => { .then((labels) => {
const matchingLabel = (labels || []).find(label => `~${gl.DropdownUtils.getEscapedText(label.title)}` === tokenValue); const matchingLabel = (labels || []).find(label => `~${DropdownUtils.getEscapedText(label.title)}` === tokenValue);
if (!matchingLabel) { if (!matchingLabel) {
return; return;
...@@ -259,11 +260,11 @@ class FilteredSearchVisualTokens { ...@@ -259,11 +260,11 @@ class FilteredSearchVisualTokens {
static tokenizeInput() { static tokenizeInput() {
const input = FilteredSearchContainer.container.querySelector('.filtered-search'); const input = FilteredSearchContainer.container.querySelector('.filtered-search');
const { isLastVisualTokenValid } = const { isLastVisualTokenValid } =
gl.FilteredSearchVisualTokens.getLastVisualTokenBeforeInput(); FilteredSearchVisualTokens.getLastVisualTokenBeforeInput();
if (input.value) { if (input.value) {
if (isLastVisualTokenValid) { if (isLastVisualTokenValid) {
gl.FilteredSearchVisualTokens.addSearchVisualToken(input.value); FilteredSearchVisualTokens.addSearchVisualToken(input.value);
} else { } else {
FilteredSearchVisualTokens.addValueToPreviousVisualTokenElement(input.value); FilteredSearchVisualTokens.addValueToPreviousVisualTokenElement(input.value);
} }
...@@ -324,12 +325,12 @@ class FilteredSearchVisualTokens { ...@@ -324,12 +325,12 @@ class FilteredSearchVisualTokens {
if (!tokenContainer.lastElementChild.isEqualNode(inputLi)) { if (!tokenContainer.lastElementChild.isEqualNode(inputLi)) {
const { isLastVisualTokenValid } = const { isLastVisualTokenValid } =
gl.FilteredSearchVisualTokens.getLastVisualTokenBeforeInput(); FilteredSearchVisualTokens.getLastVisualTokenBeforeInput();
if (!isLastVisualTokenValid) { if (!isLastVisualTokenValid) {
const lastPartial = gl.FilteredSearchVisualTokens.getLastTokenPartial(); const lastPartial = FilteredSearchVisualTokens.getLastTokenPartial();
gl.FilteredSearchVisualTokens.removeLastTokenPartial(); FilteredSearchVisualTokens.removeLastTokenPartial();
gl.FilteredSearchVisualTokens.addSearchVisualToken(lastPartial); FilteredSearchVisualTokens.addSearchVisualToken(lastPartial);
} }
tokenContainer.removeChild(inputLi); tokenContainer.removeChild(inputLi);
...@@ -337,6 +338,3 @@ class FilteredSearchVisualTokens { ...@@ -337,6 +338,3 @@ class FilteredSearchVisualTokens {
} }
} }
} }
window.gl = window.gl || {};
gl.FilteredSearchVisualTokens = FilteredSearchVisualTokens;
// We will render the icons list here // We will render the icons list here
if ($('#user-content-gitlab-icons').length > 0) { export default () => {
const $iconsHeader = $('#user-content-gitlab-icons'); if ($('#user-content-gitlab-icons').length > 0) {
const $iconsList = $('<div id="iconsList">ICONS</div>'); const $iconsHeader = $('#user-content-gitlab-icons');
$($iconsList).insertAfter($iconsHeader.parent()); const $iconsList = $('<div id="iconsList">ICONS</div>');
} $($iconsList).insertAfter($iconsHeader.parent());
}
};
import initGroupsList from '../../../../groups'; import initGroupsList from '~/groups';
export default () => { export default initGroupsList;
initGroupsList();
};
...@@ -5,7 +5,7 @@ import notificationsDropdown from '~/notifications_dropdown'; ...@@ -5,7 +5,7 @@ import notificationsDropdown from '~/notifications_dropdown';
import NotificationsForm from '~/notifications_form'; import NotificationsForm from '~/notifications_form';
import ProjectsList from '~/projects_list'; import ProjectsList from '~/projects_list';
import ShortcutsNavigation from '~/shortcuts_navigation'; import ShortcutsNavigation from '~/shortcuts_navigation';
import initGroupsList from '../../../groups'; import initGroupsList from '~/groups';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const newGroupChildWrapper = document.querySelector('.js-new-project-subgroup'); const newGroupChildWrapper = document.querySelector('.js-new-project-subgroup');
......
import VersionCheckImage from '../../version_check_image';
export default () => VersionCheckImage.bindErrorEvent($('img.js-version-status-badge'));
import VersionCheckImage from '~/version_check_image';
import docs from '~/docs/docs_bundle';
document.addEventListener('DOMContentLoaded', () => {
docs();
VersionCheckImage.bindErrorEvent($('img.js-version-status-badge'));
});
import initHelp from '~/help/help';
document.addEventListener('DOMContentLoaded', initHelp);
import initUIKit from '~/ui_development_kit';
document.addEventListener('DOMContentLoaded', initUIKit);
import initGitLabImportProject from '~/projects/project_import_gitlab_project';
document.addEventListener('DOMContentLoaded', initGitLabImportProject);
import initProfileAccount from '~/profile/account';
document.addEventListener('DOMContentLoaded', initProfileAccount);
import initBlobBundle from '~/blob_edit/blob_bundle';
document.addEventListener('DOMContentLoaded', initBlobBundle);
import initBlobBundle from '~/blob_edit/blob_bundle';
document.addEventListener('DOMContentLoaded', initBlobBundle);
...@@ -3,6 +3,7 @@ import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater'; ...@@ -3,6 +3,7 @@ import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater';
import ShortcutsNavigation from '~/shortcuts_navigation'; import ShortcutsNavigation from '~/shortcuts_navigation';
import ShortcutsBlob from '~/shortcuts_blob'; import ShortcutsBlob from '~/shortcuts_blob';
import BlobForkSuggestion from '~/blob/blob_fork_suggestion'; import BlobForkSuggestion from '~/blob/blob_fork_suggestion';
import initBlobBundle from '~/blob_edit/blob_bundle';
export default () => { export default () => {
new LineHighlighter(); // eslint-disable-line no-new new LineHighlighter(); // eslint-disable-line no-new
...@@ -30,4 +31,6 @@ export default () => { ...@@ -30,4 +31,6 @@ export default () => {
suggestionSections: document.querySelectorAll('.js-file-fork-suggestion-section'), suggestionSections: document.querySelectorAll('.js-file-fork-suggestion-section'),
actionTextPieces: document.querySelectorAll('.js-file-fork-suggestion-section-action'), actionTextPieces: document.querySelectorAll('.js-file-fork-suggestion-section-action'),
}).init(); }).init();
initBlobBundle();
}; };
import Vue from 'vue'; import Vue from 'vue';
import initBlob from '~/blob_edit/blob_bundle';
import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue'; import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import TreeView from '../../../../tree'; import TreeView from '../../../../tree';
import ShortcutsNavigation from '../../../../shortcuts_navigation'; import ShortcutsNavigation from '../../../../shortcuts_navigation';
...@@ -14,6 +15,7 @@ export default () => { ...@@ -14,6 +15,7 @@ export default () => {
$('#tree-slider').waitForImages(() => $('#tree-slider').waitForImages(() =>
ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath)); ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath));
initBlob();
const commitPipelineStatusEl = document.querySelector('.js-commit-pipeline-status'); const commitPipelineStatusEl = document.querySelector('.js-commit-pipeline-status');
const statusLink = document.querySelector('.commit-actions .ci-status-link'); const statusLink = document.querySelector('.commit-actions .ci-status-link');
if (statusLink != null) { if (statusLink != null) {
......
import '~/filtered_search/dropdown_emoji'; import FilteredSearchManager from '~/filtered_search/filtered_search_manager';
import '~/filtered_search/dropdown_hint';
import '~/filtered_search/dropdown_non_user';
import '~/filtered_search/dropdown_user';
import '~/filtered_search/dropdown_utils';
import '~/filtered_search/filtered_search_dropdown_manager';
import '~/filtered_search/filtered_search_dropdown';
import '~/filtered_search/filtered_search_manager';
import '~/filtered_search/filtered_search_tokenizer';
import '~/filtered_search/filtered_search_visual_tokens';
export default ({ page }) => { export default ({ page }) => {
const filteredSearchEnabled = gl.FilteredSearchManager && document.querySelector('.filtered-search'); const filteredSearchEnabled = FilteredSearchManager && document.querySelector('.filtered-search');
if (filteredSearchEnabled) { if (filteredSearchEnabled) {
const filteredSearchManager = new gl.FilteredSearchManager({ page }); const filteredSearchManager = new FilteredSearchManager({ page });
filteredSearchManager.setup(); filteredSearchManager.setup();
} }
}; };
import Vue from 'vue'; import Vue from 'vue';
import Translate from '~/vue_shared/translate'; import Translate from '~/vue_shared/translate';
import deleteAccountModal from './components/delete_account_modal.vue'; import deleteAccountModal from './components/delete_account_modal.vue';
Vue.use(Translate); export default () => {
Vue.use(Translate);
const deleteAccountButton = document.getElementById('delete-account-button'); const deleteAccountButton = document.getElementById('delete-account-button');
const deleteAccountModalEl = document.getElementById('delete-account-modal'); const deleteAccountModalEl = document.getElementById('delete-account-modal');
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new Vue({ new Vue({
el: deleteAccountModalEl, el: deleteAccountModalEl,
components: { components: {
deleteAccountModal, deleteAccountModal,
}, },
mounted() { mounted() {
deleteAccountButton.classList.remove('disabled'); deleteAccountButton.classList.remove('disabled');
}, },
render(createElement) { render(createElement) {
return createElement('delete-account-modal', { return createElement('delete-account-modal', {
props: { props: {
actionUrl: deleteAccountModalEl.dataset.actionUrl, actionUrl: deleteAccountModalEl.dataset.actionUrl,
confirmWithPassword: !!deleteAccountModalEl.dataset.confirmWithPassword, confirmWithPassword: !!deleteAccountModalEl.dataset.confirmWithPassword,
username: deleteAccountModalEl.dataset.username, username: deleteAccountModalEl.dataset.username,
}, },
}); });
}, },
}); });
};
import { getParameterValues } from '../lib/utils/url_utility'; import { getParameterValues } from '../lib/utils/url_utility';
const bindEvents = () => { export default () => {
const path = getParameterValues('path')[0]; const path = getParameterValues('path')[0];
// get the path url and append it in the inputS // get the path url and append it in the inputS
$('.js-path-name').val(path); $('.js-path-name').val(path);
}; };
document.addEventListener('DOMContentLoaded', bindEvents);
export default {
bindEvents,
};
/* eslint-disable no-return-assign, one-var, no-var, no-underscore-dangle, one-var-declaration-per-line, no-unused-vars, no-cond-assign, consistent-return, object-shorthand, prefer-arrow-callback, func-names, space-before-function-paren, prefer-template, quotes, class-methods-use-this, no-sequences, wrap-iife, no-lonely-if, no-else-return, no-param-reassign, vars-on-top, max-len */ /* eslint-disable no-return-assign, one-var, no-var, no-underscore-dangle, one-var-declaration-per-line, no-unused-vars, no-cond-assign, consistent-return, object-shorthand, prefer-arrow-callback, func-names, space-before-function-paren, prefer-template, quotes, class-methods-use-this, no-sequences, wrap-iife, no-lonely-if, no-else-return, no-param-reassign, vars-on-top, max-len */
import axios from './lib/utils/axios_utils'; import axios from './lib/utils/axios_utils';
import DropdownUtils from './filtered_search/dropdown_utils';
import { isInGroupsPage, isInProjectPage, getGroupSlug, getProjectSlug } from './lib/utils/common_utils'; import { isInGroupsPage, isInProjectPage, getGroupSlug, getProjectSlug } from './lib/utils/common_utils';
/** /**
......
import Api from './api'; import Api from './api';
document.addEventListener('DOMContentLoaded', () => { export default () => {
$('#js-project-dropdown').glDropdown({ $('#js-project-dropdown').glDropdown({
data: (term, callback) => { data: (term, callback) => {
Api.projects(term, { Api.projects(term, {
...@@ -19,4 +19,4 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -19,4 +19,4 @@ document.addEventListener('DOMContentLoaded', () => {
id: data => data.id, id: data => data.id,
isSelected: data => (data.id === 2), isSelected: data => (data.id === 2),
}); });
}); };
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'common_vue'
= webpack_bundle_tag 'filtered_search'
- if group_issues_exists - if group_issues_exists
.top-area .top-area
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'common_vue'
= webpack_bundle_tag 'filtered_search'
- if @group_merge_requests.empty? - if @group_merge_requests.empty?
= render 'shared/empty_states/merge_requests', project_select_button: true = render 'shared/empty_states/merge_requests', project_select_button: true
......
= webpack_bundle_tag 'docs'
%div %div
- if Gitlab::CurrentSettings.help_page_text.present? - if Gitlab::CurrentSettings.help_page_text.present?
= markdown_field(Gitlab::CurrentSettings.current_application_settings, :help_page_text) = markdown_field(Gitlab::CurrentSettings.current_application_settings, :help_page_text)
......
- content_for :page_specific_javascripts do
= webpack_bundle_tag 'help'
- page_title @path.split("/").reverse.map(&:humanize) - page_title @path.split("/").reverse.map(&:humanize)
.documentation.wiki.prepend-top-default .documentation.wiki.prepend-top-default
= markdown @markdown = markdown @markdown
- page_title "GitLab Import" - page_title "GitLab Import"
- header_title "Projects", root_path - header_title "Projects", root_path
- content_for :page_specific_javascripts do
= webpack_bundle_tag 'project_import_gl'
%h3.page-title %h3.page-title
= icon('gitlab') = icon('gitlab')
......
...@@ -102,6 +102,3 @@ ...@@ -102,6 +102,3 @@
%p %p
= s_("Profiles|You don't have access to delete this user.") = s_("Profiles|You don't have access to delete this user.")
.append-bottom-default .append-bottom-default
- content_for :page_specific_javascripts do
= webpack_bundle_tag('account')
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.modal-dialog.modal-lg .modal-dialog.modal-lg
.modal-content .modal-content
.modal-header .modal-header
%a.close{ href: "#", "data-dismiss" => "modal" } × %a.close{ href: "#", "data-dismiss" => "modal" } &times;
%h3.page-title= title %h3.page-title= title
.modal-body .modal-body
= form_tag form_path, method: method, class: 'js-quick-submit js-upload-blob-form form-horizontal', data: { method: method } do = form_tag form_path, method: method, class: 'js-quick-submit js-upload-blob-form form-horizontal', data: { method: method } do
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
- page_title "Edit", @blob.path, @ref - page_title "Edit", @blob.path, @ref
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_tag('lib/ace.js') = page_specific_javascript_tag('lib/ace.js')
= webpack_bundle_tag('blob')
%div{ class: container_class } %div{ class: container_class }
- if @conflict - if @conflict
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
- page_title "New File", @path.presence, @ref - page_title "New File", @path.presence, @ref
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_tag('lib/ace.js') = page_specific_javascript_tag('lib/ace.js')
= webpack_bundle_tag('blob')
.editor-title-row .editor-title-row
%h3.page-title.blob-new-page-title %h3.page-title.blob-new-page-title
New file New file
......
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
- page_title @blob.path, @ref - page_title @blob.path, @ref
- content_for :page_specific_javascripts do
= webpack_bundle_tag 'blob'
%div{ class: container_class } %div{ class: container_class }
= render 'projects/last_push' = render 'projects/last_push'
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'common_vue'
= webpack_bundle_tag 'filtered_search'
%div{ class: container_class } %div{ class: container_class }
= render 'projects/last_push' = render 'projects/last_push'
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'common_vue'
= webpack_bundle_tag 'filtered_search'
= webpack_bundle_tag 'boards' = webpack_bundle_tag 'boards'
%script#js-board-template{ type: "text/x-template" }= render "shared/boards/components/board" %script#js-board-template{ type: "text/x-template" }= render "shared/boards/components/board"
......
...@@ -24,7 +24,7 @@ module.exports = function(config) { ...@@ -24,7 +24,7 @@ module.exports = function(config) {
var karmaConfig = { var karmaConfig = {
basePath: ROOT_PATH, basePath: ROOT_PATH,
browsers: ['ChromeHeadlessCustom'], browsers: ['ChromeHeadlessCustom'],
customLaunchers: { customLaunchers: {
ChromeHeadlessCustom: { ChromeHeadlessCustom: {
base: 'ChromeHeadless', base: 'ChromeHeadless',
......
...@@ -48,7 +48,6 @@ var config = { ...@@ -48,7 +48,6 @@ var config = {
}, },
context: path.join(ROOT_PATH, 'app/assets/javascripts'), context: path.join(ROOT_PATH, 'app/assets/javascripts'),
entry: { entry: {
account: './profile/account/index.js',
balsamiq_viewer: './blob/balsamiq_viewer.js', balsamiq_viewer: './blob/balsamiq_viewer.js',
blob: './blob_edit/blob_bundle.js', blob: './blob_edit/blob_bundle.js',
boards: './boards/boards_bundle.js', boards: './boards/boards_bundle.js',
...@@ -57,7 +56,6 @@ var config = { ...@@ -57,7 +56,6 @@ var config = {
cycle_analytics: './cycle_analytics/cycle_analytics_bundle.js', cycle_analytics: './cycle_analytics/cycle_analytics_bundle.js',
commit_pipelines: './commit/pipelines/pipelines_bundle.js', commit_pipelines: './commit/pipelines/pipelines_bundle.js',
deploy_keys: './deploy_keys/index.js', deploy_keys: './deploy_keys/index.js',
docs: './docs/docs_bundle.js',
diff_notes: './diff_notes/diff_notes_bundle.js', diff_notes: './diff_notes/diff_notes_bundle.js',
environments: './environments/environments_bundle.js', environments: './environments/environments_bundle.js',
environments_folder: './environments/folder/environments_folder_bundle.js', environments_folder: './environments/folder/environments_folder_bundle.js',
......
import '~/filtered_search/dropdown_utils'; import DropdownUtils from '~/filtered_search/dropdown_utils';
import '~/filtered_search/filtered_search_tokenizer'; import DropdownUser from '~/filtered_search/dropdown_user';
import '~/filtered_search/filtered_search_dropdown'; import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer';
import '~/filtered_search/dropdown_user';
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys'; import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
describe('Dropdown User', () => { describe('Dropdown User', () => {
...@@ -10,18 +8,18 @@ describe('Dropdown User', () => { ...@@ -10,18 +8,18 @@ describe('Dropdown User', () => {
let dropdownUser; let dropdownUser;
beforeEach(() => { beforeEach(() => {
spyOn(gl.DropdownUser.prototype, 'bindEvents').and.callFake(() => {}); spyOn(DropdownUser.prototype, 'bindEvents').and.callFake(() => {});
spyOn(gl.DropdownUser.prototype, 'getProjectId').and.callFake(() => {}); spyOn(DropdownUser.prototype, 'getProjectId').and.callFake(() => {});
spyOn(gl.DropdownUser.prototype, 'getGroupId').and.callFake(() => {}); spyOn(DropdownUser.prototype, 'getGroupId').and.callFake(() => {});
spyOn(gl.DropdownUtils, 'getSearchInput').and.callFake(() => {}); spyOn(DropdownUtils, 'getSearchInput').and.callFake(() => {});
dropdownUser = new gl.DropdownUser({ dropdownUser = new DropdownUser({
tokenKeys: FilteredSearchTokenKeys, tokenKeys: FilteredSearchTokenKeys,
}); });
}); });
it('should not return the double quote found in value', () => { it('should not return the double quote found in value', () => {
spyOn(gl.FilteredSearchTokenizer, 'processTokens').and.returnValue({ spyOn(FilteredSearchTokenizer, 'processTokens').and.returnValue({
lastToken: '"johnny appleseed', lastToken: '"johnny appleseed',
}); });
...@@ -29,7 +27,7 @@ describe('Dropdown User', () => { ...@@ -29,7 +27,7 @@ describe('Dropdown User', () => {
}); });
it('should not return the single quote found in value', () => { it('should not return the single quote found in value', () => {
spyOn(gl.FilteredSearchTokenizer, 'processTokens').and.returnValue({ spyOn(FilteredSearchTokenizer, 'processTokens').and.returnValue({
lastToken: '\'larry boy', lastToken: '\'larry boy',
}); });
...@@ -39,22 +37,22 @@ describe('Dropdown User', () => { ...@@ -39,22 +37,22 @@ describe('Dropdown User', () => {
describe('config AjaxFilter\'s endpoint', () => { describe('config AjaxFilter\'s endpoint', () => {
beforeEach(() => { beforeEach(() => {
spyOn(gl.DropdownUser.prototype, 'bindEvents').and.callFake(() => {}); spyOn(DropdownUser.prototype, 'bindEvents').and.callFake(() => {});
spyOn(gl.DropdownUser.prototype, 'getProjectId').and.callFake(() => {}); spyOn(DropdownUser.prototype, 'getProjectId').and.callFake(() => {});
spyOn(gl.DropdownUser.prototype, 'getGroupId').and.callFake(() => {}); spyOn(DropdownUser.prototype, 'getGroupId').and.callFake(() => {});
}); });
it('should return endpoint', () => { it('should return endpoint', () => {
window.gon = { window.gon = {
relative_url_root: '', relative_url_root: '',
}; };
const dropdown = new gl.DropdownUser(); const dropdown = new DropdownUser();
expect(dropdown.config.AjaxFilter.endpoint).toBe('/autocomplete/users.json'); expect(dropdown.config.AjaxFilter.endpoint).toBe('/autocomplete/users.json');
}); });
it('should return endpoint when relative_url_root is undefined', () => { it('should return endpoint when relative_url_root is undefined', () => {
const dropdown = new gl.DropdownUser(); const dropdown = new DropdownUser();
expect(dropdown.config.AjaxFilter.endpoint).toBe('/autocomplete/users.json'); expect(dropdown.config.AjaxFilter.endpoint).toBe('/autocomplete/users.json');
}); });
...@@ -63,7 +61,7 @@ describe('Dropdown User', () => { ...@@ -63,7 +61,7 @@ describe('Dropdown User', () => {
window.gon = { window.gon = {
relative_url_root: '/gitlab_directory', relative_url_root: '/gitlab_directory',
}; };
const dropdown = new gl.DropdownUser(); const dropdown = new DropdownUser();
expect(dropdown.config.AjaxFilter.endpoint).toBe('/gitlab_directory/autocomplete/users.json'); expect(dropdown.config.AjaxFilter.endpoint).toBe('/gitlab_directory/autocomplete/users.json');
}); });
...@@ -84,7 +82,7 @@ describe('Dropdown User', () => { ...@@ -84,7 +82,7 @@ describe('Dropdown User', () => {
loadFixtures(fixtureTemplate); loadFixtures(fixtureTemplate);
authorFilterDropdownElement = document.querySelector('#js-dropdown-author'); authorFilterDropdownElement = document.querySelector('#js-dropdown-author');
const dummyInput = document.createElement('div'); const dummyInput = document.createElement('div');
dropdown = new gl.DropdownUser({ dropdown = new DropdownUser({
dropdown: authorFilterDropdownElement, dropdown: authorFilterDropdownElement,
input: dummyInput, input: dummyInput,
}); });
......
import '~/filtered_search/filtered_search_visual_tokens'; import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dropdown_manager';
import '~/filtered_search/filtered_search_tokenizer';
import '~/filtered_search/filtered_search_dropdown_manager';
describe('Filtered Search Dropdown Manager', () => { describe('Filtered Search Dropdown Manager', () => {
beforeEach(() => { beforeEach(() => {
...@@ -28,7 +26,7 @@ describe('Filtered Search Dropdown Manager', () => { ...@@ -28,7 +26,7 @@ describe('Filtered Search Dropdown Manager', () => {
describe('input has no existing value', () => { describe('input has no existing value', () => {
it('should add just tokenName', () => { it('should add just tokenName', () => {
gl.FilteredSearchDropdownManager.addWordToInput('milestone'); FilteredSearchDropdownManager.addWordToInput('milestone');
const token = document.querySelector('.tokens-container .js-visual-token'); const token = document.querySelector('.tokens-container .js-visual-token');
...@@ -38,7 +36,7 @@ describe('Filtered Search Dropdown Manager', () => { ...@@ -38,7 +36,7 @@ describe('Filtered Search Dropdown Manager', () => {
}); });
it('should add tokenName and tokenValue', () => { it('should add tokenName and tokenValue', () => {
gl.FilteredSearchDropdownManager.addWordToInput('label'); FilteredSearchDropdownManager.addWordToInput('label');
let token = document.querySelector('.tokens-container .js-visual-token'); let token = document.querySelector('.tokens-container .js-visual-token');
...@@ -46,9 +44,9 @@ describe('Filtered Search Dropdown Manager', () => { ...@@ -46,9 +44,9 @@ describe('Filtered Search Dropdown Manager', () => {
expect(token.querySelector('.name').innerText).toBe('label'); expect(token.querySelector('.name').innerText).toBe('label');
expect(getInputValue()).toBe(''); expect(getInputValue()).toBe('');
gl.FilteredSearchDropdownManager.addWordToInput('label', 'none'); FilteredSearchDropdownManager.addWordToInput('label', 'none');
// We have to get that reference again // We have to get that reference again
// Because gl.FilteredSearchDropdownManager deletes the previous token // Because FilteredSearchDropdownManager deletes the previous token
token = document.querySelector('.tokens-container .js-visual-token'); token = document.querySelector('.tokens-container .js-visual-token');
expect(token.classList.contains('filtered-search-token')).toEqual(true); expect(token.classList.contains('filtered-search-token')).toEqual(true);
...@@ -61,7 +59,7 @@ describe('Filtered Search Dropdown Manager', () => { ...@@ -61,7 +59,7 @@ describe('Filtered Search Dropdown Manager', () => {
describe('input has existing value', () => { describe('input has existing value', () => {
it('should be able to just add tokenName', () => { it('should be able to just add tokenName', () => {
setInputValue('a'); setInputValue('a');
gl.FilteredSearchDropdownManager.addWordToInput('author'); FilteredSearchDropdownManager.addWordToInput('author');
const token = document.querySelector('.tokens-container .js-visual-token'); const token = document.querySelector('.tokens-container .js-visual-token');
...@@ -71,10 +69,10 @@ describe('Filtered Search Dropdown Manager', () => { ...@@ -71,10 +69,10 @@ describe('Filtered Search Dropdown Manager', () => {
}); });
it('should replace tokenValue', () => { it('should replace tokenValue', () => {
gl.FilteredSearchDropdownManager.addWordToInput('author'); FilteredSearchDropdownManager.addWordToInput('author');
setInputValue('roo'); setInputValue('roo');
gl.FilteredSearchDropdownManager.addWordToInput(null, '@root'); FilteredSearchDropdownManager.addWordToInput(null, '@root');
const token = document.querySelector('.tokens-container .js-visual-token'); const token = document.querySelector('.tokens-container .js-visual-token');
...@@ -85,10 +83,10 @@ describe('Filtered Search Dropdown Manager', () => { ...@@ -85,10 +83,10 @@ describe('Filtered Search Dropdown Manager', () => {
}); });
it('should add tokenValues containing spaces', () => { it('should add tokenValues containing spaces', () => {
gl.FilteredSearchDropdownManager.addWordToInput('label'); FilteredSearchDropdownManager.addWordToInput('label');
setInputValue('"test '); setInputValue('"test ');
gl.FilteredSearchDropdownManager.addWordToInput('label', '~\'"test me"\''); FilteredSearchDropdownManager.addWordToInput('label', '~\'"test me"\'');
const token = document.querySelector('.tokens-container .js-visual-token'); const token = document.querySelector('.tokens-container .js-visual-token');
......
...@@ -5,9 +5,10 @@ import RecentSearchesServiceError from '~/filtered_search/services/recent_search ...@@ -5,9 +5,10 @@ import RecentSearchesServiceError from '~/filtered_search/services/recent_search
import RecentSearchesRoot from '~/filtered_search/recent_searches_root'; import RecentSearchesRoot from '~/filtered_search/recent_searches_root';
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys'; import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
import '~/lib/utils/common_utils'; import '~/lib/utils/common_utils';
import '~/filtered_search/filtered_search_tokenizer'; import DropdownUtils from '~/filtered_search/dropdown_utils';
import '~/filtered_search/filtered_search_dropdown_manager'; import FilteredSearchVisualTokens from '~/filtered_search/filtered_search_visual_tokens';
import '~/filtered_search/filtered_search_manager'; import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dropdown_manager';
import FilteredSearchManager from '~/filtered_search/filtered_search_manager';
import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper'; import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper';
describe('Filtered Search Manager', () => { describe('Filtered Search Manager', () => {
...@@ -49,21 +50,21 @@ describe('Filtered Search Manager', () => { ...@@ -49,21 +50,21 @@ describe('Filtered Search Manager', () => {
</div> </div>
`); `);
spyOn(gl.FilteredSearchDropdownManager.prototype, 'setDropdown').and.callFake(() => {}); spyOn(FilteredSearchDropdownManager.prototype, 'setDropdown').and.callFake(() => {});
}); });
const initializeManager = () => { const initializeManager = () => {
/* eslint-disable jasmine/no-unsafe-spy */ /* eslint-disable jasmine/no-unsafe-spy */
spyOn(gl.FilteredSearchManager.prototype, 'loadSearchParamsFromURL').and.callFake(() => {}); spyOn(FilteredSearchManager.prototype, 'loadSearchParamsFromURL').and.callFake(() => {});
spyOn(gl.FilteredSearchManager.prototype, 'tokenChange').and.callFake(() => {}); spyOn(FilteredSearchManager.prototype, 'tokenChange').and.callFake(() => {});
spyOn(gl.FilteredSearchDropdownManager.prototype, 'updateDropdownOffset').and.callFake(() => {}); spyOn(FilteredSearchDropdownManager.prototype, 'updateDropdownOffset').and.callFake(() => {});
spyOn(gl.utils, 'getParameterByName').and.returnValue(null); spyOn(gl.utils, 'getParameterByName').and.returnValue(null);
spyOn(gl.FilteredSearchVisualTokens, 'unselectTokens').and.callThrough(); spyOn(FilteredSearchVisualTokens, 'unselectTokens').and.callThrough();
/* eslint-enable jasmine/no-unsafe-spy */ /* eslint-enable jasmine/no-unsafe-spy */
input = document.querySelector('.filtered-search'); input = document.querySelector('.filtered-search');
tokensContainer = document.querySelector('.tokens-container'); tokensContainer = document.querySelector('.tokens-container');
manager = new gl.FilteredSearchManager({ page }); manager = new FilteredSearchManager({ page });
manager.setup(); manager.setup();
}; };
...@@ -81,7 +82,7 @@ describe('Filtered Search Manager', () => { ...@@ -81,7 +82,7 @@ describe('Filtered Search Manager', () => {
}); });
it('should instantiate RecentSearchesStore with isLocalStorageAvailable', () => { it('should instantiate RecentSearchesStore with isLocalStorageAvailable', () => {
manager = new gl.FilteredSearchManager({ page }); manager = new FilteredSearchManager({ page });
expect(RecentSearchesService.isAvailable).toHaveBeenCalled(); expect(RecentSearchesService.isAvailable).toHaveBeenCalled();
expect(recentSearchesStoreSrc.default).toHaveBeenCalledWith({ expect(recentSearchesStoreSrc.default).toHaveBeenCalledWith({
...@@ -93,7 +94,7 @@ describe('Filtered Search Manager', () => { ...@@ -93,7 +94,7 @@ describe('Filtered Search Manager', () => {
describe('setup', () => { describe('setup', () => {
beforeEach(() => { beforeEach(() => {
manager = new gl.FilteredSearchManager({ page }); manager = new FilteredSearchManager({ page });
}); });
it('should not instantiate Flash if an RecentSearchesServiceError is caught', () => { it('should not instantiate Flash if an RecentSearchesServiceError is caught', () => {
...@@ -108,7 +109,7 @@ describe('Filtered Search Manager', () => { ...@@ -108,7 +109,7 @@ describe('Filtered Search Manager', () => {
describe('searchState', () => { describe('searchState', () => {
beforeEach(() => { beforeEach(() => {
spyOn(gl.FilteredSearchManager.prototype, 'search').and.callFake(() => {}); spyOn(FilteredSearchManager.prototype, 'search').and.callFake(() => {});
initializeManager(); initializeManager();
}); });
...@@ -134,7 +135,7 @@ describe('Filtered Search Manager', () => { ...@@ -134,7 +135,7 @@ describe('Filtered Search Manager', () => {
}; };
manager.searchState(e); manager.searchState(e);
expect(gl.FilteredSearchManager.prototype.search).not.toHaveBeenCalled(); expect(FilteredSearchManager.prototype.search).not.toHaveBeenCalled();
}); });
it('should call search when there is state', () => { it('should call search when there is state', () => {
...@@ -149,7 +150,7 @@ describe('Filtered Search Manager', () => { ...@@ -149,7 +150,7 @@ describe('Filtered Search Manager', () => {
}; };
manager.searchState(e); manager.searchState(e);
expect(gl.FilteredSearchManager.prototype.search).toHaveBeenCalledWith('opened'); expect(FilteredSearchManager.prototype.search).toHaveBeenCalledWith('opened');
}); });
}); });
...@@ -251,44 +252,44 @@ describe('Filtered Search Manager', () => { ...@@ -251,44 +252,44 @@ describe('Filtered Search Manager', () => {
}); });
it('removes last token', () => { it('removes last token', () => {
spyOn(gl.FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough(); spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough();
dispatchBackspaceEvent(input, 'keyup'); dispatchBackspaceEvent(input, 'keyup');
dispatchBackspaceEvent(input, 'keyup'); dispatchBackspaceEvent(input, 'keyup');
expect(gl.FilteredSearchVisualTokens.removeLastTokenPartial).toHaveBeenCalled(); expect(FilteredSearchVisualTokens.removeLastTokenPartial).toHaveBeenCalled();
}); });
it('sets the input', () => { it('sets the input', () => {
spyOn(gl.FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough(); spyOn(FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough();
dispatchDeleteEvent(input, 'keyup'); dispatchDeleteEvent(input, 'keyup');
dispatchDeleteEvent(input, 'keyup'); dispatchDeleteEvent(input, 'keyup');
expect(gl.FilteredSearchVisualTokens.getLastTokenPartial).toHaveBeenCalled(); expect(FilteredSearchVisualTokens.getLastTokenPartial).toHaveBeenCalled();
expect(input.value).toEqual('~bug'); expect(input.value).toEqual('~bug');
}); });
}); });
it('does not remove token or change input when there is existing input', () => { it('does not remove token or change input when there is existing input', () => {
spyOn(gl.FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough(); spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough();
spyOn(gl.FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough(); spyOn(FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough();
input.value = 'text'; input.value = 'text';
dispatchDeleteEvent(input, 'keyup'); dispatchDeleteEvent(input, 'keyup');
expect(gl.FilteredSearchVisualTokens.removeLastTokenPartial).not.toHaveBeenCalled(); expect(FilteredSearchVisualTokens.removeLastTokenPartial).not.toHaveBeenCalled();
expect(gl.FilteredSearchVisualTokens.getLastTokenPartial).not.toHaveBeenCalled(); expect(FilteredSearchVisualTokens.getLastTokenPartial).not.toHaveBeenCalled();
expect(input.value).toEqual('text'); expect(input.value).toEqual('text');
}); });
it('does not remove previous token on single backspace press', () => { it('does not remove previous token on single backspace press', () => {
spyOn(gl.FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough(); spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough();
spyOn(gl.FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough(); spyOn(FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough();
input.value = 't'; input.value = 't';
dispatchDeleteEvent(input, 'keyup'); dispatchDeleteEvent(input, 'keyup');
expect(gl.FilteredSearchVisualTokens.removeLastTokenPartial).not.toHaveBeenCalled(); expect(FilteredSearchVisualTokens.removeLastTokenPartial).not.toHaveBeenCalled();
expect(gl.FilteredSearchVisualTokens.getLastTokenPartial).not.toHaveBeenCalled(); expect(FilteredSearchVisualTokens.getLastTokenPartial).not.toHaveBeenCalled();
expect(input.value).toEqual('t'); expect(input.value).toEqual('t');
}); });
}); });
...@@ -309,7 +310,7 @@ describe('Filtered Search Manager', () => { ...@@ -309,7 +310,7 @@ describe('Filtered Search Manager', () => {
describe('unselected token', () => { describe('unselected token', () => {
beforeEach(() => { beforeEach(() => {
spyOn(gl.FilteredSearchManager.prototype, 'removeSelectedToken').and.callThrough(); spyOn(FilteredSearchManager.prototype, 'removeSelectedToken').and.callThrough();
tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML( tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', 'none'), FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', 'none'),
...@@ -380,16 +381,16 @@ describe('Filtered Search Manager', () => { ...@@ -380,16 +381,16 @@ describe('Filtered Search Manager', () => {
describe('removeSelectedToken', () => { describe('removeSelectedToken', () => {
beforeEach(() => { beforeEach(() => {
spyOn(gl.FilteredSearchVisualTokens, 'removeSelectedToken').and.callThrough(); spyOn(FilteredSearchVisualTokens, 'removeSelectedToken').and.callThrough();
spyOn(gl.FilteredSearchManager.prototype, 'handleInputPlaceholder').and.callThrough(); spyOn(FilteredSearchManager.prototype, 'handleInputPlaceholder').and.callThrough();
spyOn(gl.FilteredSearchManager.prototype, 'toggleClearSearchButton').and.callThrough(); spyOn(FilteredSearchManager.prototype, 'toggleClearSearchButton').and.callThrough();
initializeManager(); initializeManager();
}); });
it('calls FilteredSearchVisualTokens.removeSelectedToken', () => { it('calls FilteredSearchVisualTokens.removeSelectedToken', () => {
manager.removeSelectedToken(); manager.removeSelectedToken();
expect(gl.FilteredSearchVisualTokens.removeSelectedToken).toHaveBeenCalled(); expect(FilteredSearchVisualTokens.removeSelectedToken).toHaveBeenCalled();
}); });
it('calls handleInputPlaceholder', () => { it('calls handleInputPlaceholder', () => {
...@@ -421,12 +422,12 @@ describe('Filtered Search Manager', () => { ...@@ -421,12 +422,12 @@ describe('Filtered Search Manager', () => {
manager.filteredSearchInput.value = inputValue; manager.filteredSearchInput.value = inputValue;
manager.filteredSearchInput.dispatchEvent(new Event('input')); manager.filteredSearchInput.dispatchEvent(new Event('input'));
expect(gl.DropdownUtils.getSearchQuery()).toEqual(inputValue); expect(DropdownUtils.getSearchQuery()).toEqual(inputValue);
manager.clearSearchButton.click(); manager.clearSearchButton.click();
expect(manager.filteredSearchInput.value).toEqual(''); expect(manager.filteredSearchInput.value).toEqual('');
expect(gl.DropdownUtils.getSearchQuery()).toEqual(''); expect(DropdownUtils.getSearchQuery()).toEqual('');
}); });
}); });
......
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys'; import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
import '~/filtered_search/filtered_search_tokenizer'; import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer';
describe('Filtered Search Tokenizer', () => { describe('Filtered Search Tokenizer', () => {
const allowedKeys = FilteredSearchTokenKeys.getKeys(); const allowedKeys = FilteredSearchTokenKeys.getKeys();
describe('processTokens', () => { describe('processTokens', () => {
it('returns for input containing only search value', () => { it('returns for input containing only search value', () => {
const results = gl.FilteredSearchTokenizer.processTokens('searchTerm', allowedKeys); const results = FilteredSearchTokenizer.processTokens('searchTerm', allowedKeys);
expect(results.searchToken).toBe('searchTerm'); expect(results.searchToken).toBe('searchTerm');
expect(results.tokens.length).toBe(0); expect(results.tokens.length).toBe(0);
expect(results.lastToken).toBe(results.searchToken); expect(results.lastToken).toBe(results.searchToken);
}); });
it('returns for input containing only tokens', () => { it('returns for input containing only tokens', () => {
const results = gl.FilteredSearchTokenizer const results = FilteredSearchTokenizer
.processTokens('author:@root label:~"Very Important" milestone:%v1.0 assignee:none', allowedKeys); .processTokens('author:@root label:~"Very Important" milestone:%v1.0 assignee:none', allowedKeys);
expect(results.searchToken).toBe(''); expect(results.searchToken).toBe('');
expect(results.tokens.length).toBe(4); expect(results.tokens.length).toBe(4);
...@@ -37,7 +37,7 @@ describe('Filtered Search Tokenizer', () => { ...@@ -37,7 +37,7 @@ describe('Filtered Search Tokenizer', () => {
}); });
it('returns for input starting with search value and ending with tokens', () => { it('returns for input starting with search value and ending with tokens', () => {
const results = gl.FilteredSearchTokenizer const results = FilteredSearchTokenizer
.processTokens('searchTerm anotherSearchTerm milestone:none', allowedKeys); .processTokens('searchTerm anotherSearchTerm milestone:none', allowedKeys);
expect(results.searchToken).toBe('searchTerm anotherSearchTerm'); expect(results.searchToken).toBe('searchTerm anotherSearchTerm');
expect(results.tokens.length).toBe(1); expect(results.tokens.length).toBe(1);
...@@ -48,7 +48,7 @@ describe('Filtered Search Tokenizer', () => { ...@@ -48,7 +48,7 @@ describe('Filtered Search Tokenizer', () => {
}); });
it('returns for input starting with tokens and ending with search value', () => { it('returns for input starting with tokens and ending with search value', () => {
const results = gl.FilteredSearchTokenizer const results = FilteredSearchTokenizer
.processTokens('assignee:@user searchTerm', allowedKeys); .processTokens('assignee:@user searchTerm', allowedKeys);
expect(results.searchToken).toBe('searchTerm'); expect(results.searchToken).toBe('searchTerm');
...@@ -60,7 +60,7 @@ describe('Filtered Search Tokenizer', () => { ...@@ -60,7 +60,7 @@ describe('Filtered Search Tokenizer', () => {
}); });
it('returns for input containing search value wrapped between tokens', () => { it('returns for input containing search value wrapped between tokens', () => {
const results = gl.FilteredSearchTokenizer const results = FilteredSearchTokenizer
.processTokens('author:@root label:~"Won\'t fix" searchTerm anotherSearchTerm milestone:none', allowedKeys); .processTokens('author:@root label:~"Won\'t fix" searchTerm anotherSearchTerm milestone:none', allowedKeys);
expect(results.searchToken).toBe('searchTerm anotherSearchTerm'); expect(results.searchToken).toBe('searchTerm anotherSearchTerm');
...@@ -81,7 +81,7 @@ describe('Filtered Search Tokenizer', () => { ...@@ -81,7 +81,7 @@ describe('Filtered Search Tokenizer', () => {
}); });
it('returns for input containing search value in between tokens', () => { it('returns for input containing search value in between tokens', () => {
const results = gl.FilteredSearchTokenizer const results = FilteredSearchTokenizer
.processTokens('author:@root searchTerm assignee:none anotherSearchTerm label:~Doing', allowedKeys); .processTokens('author:@root searchTerm assignee:none anotherSearchTerm label:~Doing', allowedKeys);
expect(results.searchToken).toBe('searchTerm anotherSearchTerm'); expect(results.searchToken).toBe('searchTerm anotherSearchTerm');
expect(results.tokens.length).toBe(3); expect(results.tokens.length).toBe(3);
...@@ -101,14 +101,14 @@ describe('Filtered Search Tokenizer', () => { ...@@ -101,14 +101,14 @@ describe('Filtered Search Tokenizer', () => {
}); });
it('returns search value for invalid tokens', () => { it('returns search value for invalid tokens', () => {
const results = gl.FilteredSearchTokenizer.processTokens('fake:token', allowedKeys); const results = FilteredSearchTokenizer.processTokens('fake:token', allowedKeys);
expect(results.lastToken).toBe('fake:token'); expect(results.lastToken).toBe('fake:token');
expect(results.searchToken).toBe('fake:token'); expect(results.searchToken).toBe('fake:token');
expect(results.tokens.length).toEqual(0); expect(results.tokens.length).toEqual(0);
}); });
it('returns search value and token for mix of valid and invalid tokens', () => { it('returns search value and token for mix of valid and invalid tokens', () => {
const results = gl.FilteredSearchTokenizer.processTokens('label:real fake:token', allowedKeys); const results = FilteredSearchTokenizer.processTokens('label:real fake:token', allowedKeys);
expect(results.tokens.length).toEqual(1); expect(results.tokens.length).toEqual(1);
expect(results.tokens[0].key).toBe('label'); expect(results.tokens[0].key).toBe('label');
expect(results.tokens[0].value).toBe('real'); expect(results.tokens[0].value).toBe('real');
...@@ -118,13 +118,13 @@ describe('Filtered Search Tokenizer', () => { ...@@ -118,13 +118,13 @@ describe('Filtered Search Tokenizer', () => {
}); });
it('returns search value for invalid symbols', () => { it('returns search value for invalid symbols', () => {
const results = gl.FilteredSearchTokenizer.processTokens('std::includes', allowedKeys); const results = FilteredSearchTokenizer.processTokens('std::includes', allowedKeys);
expect(results.lastToken).toBe('std::includes'); expect(results.lastToken).toBe('std::includes');
expect(results.searchToken).toBe('std::includes'); expect(results.searchToken).toBe('std::includes');
}); });
it('removes duplicated values', () => { it('removes duplicated values', () => {
const results = gl.FilteredSearchTokenizer.processTokens('label:~foo label:~foo', allowedKeys); const results = FilteredSearchTokenizer.processTokens('label:~foo label:~foo', allowedKeys);
expect(results.tokens.length).toBe(1); expect(results.tokens.length).toBe(1);
expect(results.tokens[0].key).toBe('label'); expect(results.tokens[0].key).toBe('label');
expect(results.tokens[0].value).toBe('foo'); expect(results.tokens[0].value).toBe('foo');
......
...@@ -2,11 +2,12 @@ import _ from 'underscore'; ...@@ -2,11 +2,12 @@ import _ from 'underscore';
import AjaxCache from '~/lib/utils/ajax_cache'; import AjaxCache from '~/lib/utils/ajax_cache';
import UsersCache from '~/lib/utils/users_cache'; import UsersCache from '~/lib/utils/users_cache';
import '~/filtered_search/filtered_search_visual_tokens'; import FilteredSearchVisualTokens from '~/filtered_search/filtered_search_visual_tokens';
import DropdownUtils from '~/filtered_search//dropdown_utils';
import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper'; import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper';
describe('Filtered Search Visual Tokens', () => { describe('Filtered Search Visual Tokens', () => {
const subject = gl.FilteredSearchVisualTokens; const subject = FilteredSearchVisualTokens;
const findElements = (tokenElement) => { const findElements = (tokenElement) => {
const tokenNameElement = tokenElement.querySelector('.name'); const tokenNameElement = tokenElement.querySelector('.name');
...@@ -860,25 +861,25 @@ describe('Filtered Search Visual Tokens', () => { ...@@ -860,25 +861,25 @@ describe('Filtered Search Visual Tokens', () => {
it('does not preprocess more than once', () => { it('does not preprocess more than once', () => {
let labels = []; let labels = [];
spyOn(gl.DropdownUtils, 'duplicateLabelPreprocessing').and.callFake(() => []); spyOn(DropdownUtils, 'duplicateLabelPreprocessing').and.callFake(() => []);
labels = gl.FilteredSearchVisualTokens.preprocessLabel(endpoint, labels); labels = FilteredSearchVisualTokens.preprocessLabel(endpoint, labels);
gl.FilteredSearchVisualTokens.preprocessLabel(endpoint, labels); FilteredSearchVisualTokens.preprocessLabel(endpoint, labels);
expect(gl.DropdownUtils.duplicateLabelPreprocessing.calls.count()).toEqual(1); expect(DropdownUtils.duplicateLabelPreprocessing.calls.count()).toEqual(1);
}); });
describe('not preprocessed before', () => { describe('not preprocessed before', () => {
it('returns preprocessed labels', () => { it('returns preprocessed labels', () => {
let labels = []; let labels = [];
expect(labels.preprocessed).not.toEqual(true); expect(labels.preprocessed).not.toEqual(true);
labels = gl.FilteredSearchVisualTokens.preprocessLabel(endpoint, labels); labels = FilteredSearchVisualTokens.preprocessLabel(endpoint, labels);
expect(labels.preprocessed).toEqual(true); expect(labels.preprocessed).toEqual(true);
}); });
it('overrides AjaxCache with preprocessed results', () => { it('overrides AjaxCache with preprocessed results', () => {
spyOn(AjaxCache, 'override').and.callFake(() => {}); spyOn(AjaxCache, 'override').and.callFake(() => {});
gl.FilteredSearchVisualTokens.preprocessLabel(endpoint, []); FilteredSearchVisualTokens.preprocessLabel(endpoint, []);
expect(AjaxCache.override.calls.count()).toEqual(1); expect(AjaxCache.override.calls.count()).toEqual(1);
}); });
}); });
...@@ -926,7 +927,7 @@ describe('Filtered Search Visual Tokens', () => { ...@@ -926,7 +927,7 @@ describe('Filtered Search Visual Tokens', () => {
}; };
const findLabel = tokenValue => labelData.find( const findLabel = tokenValue => labelData.find(
label => tokenValue === `~${gl.DropdownUtils.getEscapedText(label.title)}`, label => tokenValue === `~${DropdownUtils.getEscapedText(label.title)}`,
); );
it('updates the color of a label token', (done) => { it('updates the color of a label token', (done) => {
......
...@@ -10,7 +10,7 @@ describe('Import Gitlab project', () => { ...@@ -10,7 +10,7 @@ describe('Import Gitlab project', () => {
<input class="js-path-name" /> <input class="js-path-name" />
`); `);
projectImportGitlab.bindEvents(); projectImportGitlab();
}); });
afterEach(() => { afterEach(() => {
......
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