gitlab-org--gitlab-foss/app/assets/javascripts/filtered_search/filtered_search_dropdown.js...

134 lines
3.7 KiB
JavaScript
Raw Normal View History

2016-12-02 21:04:10 +00:00
/* eslint-disable no-param-reassign */
((global) => {
const DATA_DROPDOWN_TRIGGER = 'data-dropdown-trigger';
class FilteredSearchDropdown {
2016-12-08 21:36:54 +00:00
constructor(droplab, dropdown, input) {
this.droplab = droplab;
2016-12-02 21:04:10 +00:00
this.hookId = 'filtered-search';
this.input = input;
this.dropdown = dropdown;
this.bindEvents();
}
bindEvents() {
2016-12-09 17:44:09 +00:00
this.itemClickedWrapper = this.itemClicked.bind(this);
this.dropdown.addEventListener('click.dl', this.itemClickedWrapper);
2016-12-02 21:04:10 +00:00
}
unbindEvents() {
2016-12-09 17:44:09 +00:00
this.dropdown.removeEventListener('click.dl', this.itemClickedWrapper);
}
getCurrentHook() {
return this.droplab.hooks.filter(h => h.id === this.hookId)[0];
2016-12-02 21:04:10 +00:00
}
2016-12-06 18:57:07 +00:00
getEscapedText(text) {
let escapedText = text;
// Encapsulate value with quotes if it has spaces
if (text.indexOf(' ') !== -1) {
if (text.indexOf('"') !== -1) {
// Use single quotes if value contains double quotes
escapedText = `'${text}'`;
} else {
// Known side effect: values's with both single and double quotes
// won't escape properly
escapedText = `"${text}"`;
}
}
return escapedText;
}
2016-12-02 21:04:10 +00:00
getSelectedText(selectedToken) {
// TODO: Get last word from FilteredSearchTokenizer
const lastWord = this.input.value.split(' ').last();
const lastWordIndex = selectedToken.indexOf(lastWord);
return lastWordIndex === -1 ? selectedToken : selectedToken.slice(lastWord.length);
}
itemClicked(e) {
// Overridden by dropdown sub class
}
2016-12-09 17:44:09 +00:00
renderContent() {
// Overriden by dropdown sub class
}
2016-12-02 21:04:10 +00:00
setAsDropdown() {
this.input.setAttribute(DATA_DROPDOWN_TRIGGER, `#${this.listId}`);
}
setOffset(offset = 0) {
this.dropdown.style.left = `${offset}px`;
}
setDataValueIfSelected(selected) {
const dataValue = selected.getAttribute('data-value');
if (dataValue) {
gl.FilteredSearchManager.addWordToInput(dataValue);
}
return dataValue !== null;
}
2016-12-09 17:44:09 +00:00
dismissDropdown() {
this.input.focus();
// Propogate input change to FilteredSearchManager
// so that it can determine which dropdowns to open
this.input.dispatchEvent(new Event('input'));
}
2016-12-02 21:04:10 +00:00
2016-12-08 21:36:54 +00:00
render(forceRenderContent) {
2016-12-02 21:04:10 +00:00
this.setAsDropdown();
const firstTimeInitialized = this.getCurrentHook() === undefined;
2016-12-08 21:36:54 +00:00
if (firstTimeInitialized || forceRenderContent) {
2016-12-02 21:04:10 +00:00
this.renderContent();
} else if(this.getCurrentHook().list.list.id !== this.listId) {
2016-12-08 21:36:54 +00:00
// this.droplab.changeHookList(this.hookId, `#${this.listId}`);
2016-12-02 21:04:10 +00:00
this.renderContent();
}
2016-12-07 18:55:03 +00:00
}
resetFilters() {
const currentHook = this.getCurrentHook();
if (currentHook) {
const list = currentHook.list;
if (list.data) {
const data = list.data.map((item) => {
item.droplab_hidden = false;
});
list.render(data);
}
}
2016-12-02 21:04:10 +00:00
}
2016-12-08 21:36:54 +00:00
2016-12-09 17:44:09 +00:00
filterWithSymbol(filterSymbol, item, query) {
2016-12-08 21:36:54 +00:00
const { value } = gl.FilteredSearchTokenizer.getLastTokenObject(query);
const valueWithoutColon = value.slice(1).toLowerCase();
const prefix = valueWithoutColon[0];
const valueWithoutPrefix = valueWithoutColon.slice(1);
const title = item.title.toLowerCase();
2016-12-09 17:44:09 +00:00
// Eg. filterSymbol = ~ for labels
const matchWithoutPrefix = prefix === filterSymbol && title.indexOf(valueWithoutPrefix) !== -1;
2016-12-08 21:36:54 +00:00
const match = title.indexOf(valueWithoutColon) !== -1;
item.droplab_hidden = !match && !matchWithoutPrefix;
return item;
}
2016-12-02 21:04:10 +00:00
}
global.FilteredSearchDropdown = FilteredSearchDropdown;
})(window.gl || (window.gl = {}));