Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
gitlab-ce
Commits
513cdda3
Commit
513cdda3
authored
Dec 12, 2016
by
Clement Ho
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor filtered search manager
parent
f4db7572
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
185 additions
and
157 deletions
+185
-157
app/assets/javascripts/filtered_search/dropdown_hint.js.es6
app/assets/javascripts/filtered_search/dropdown_hint.js.es6
+1
-1
app/assets/javascripts/filtered_search/dropdown_non_user.js.es6
...sets/javascripts/filtered_search/dropdown_non_user.js.es6
+1
-1
app/assets/javascripts/filtered_search/dropdown_user.js.es6
app/assets/javascripts/filtered_search/dropdown_user.js.es6
+1
-1
app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
...vascripts/filtered_search/filtered_search_dropdown.js.es6
+1
-1
app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
...s/filtered_search/filtered_search_dropdown_manager.js.es6
+174
-0
app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
...avascripts/filtered_search/filtered_search_manager.js.es6
+7
-153
No files found.
app/assets/javascripts/filtered_search/dropdown_hint.js.es6
View file @
513cdda3
...
...
@@ -42,7 +42,7 @@
const tag = selected.querySelector('.js-filter-tag').innerText.trim();
if (tag.length) {
gl.FilteredSearchManager.addWordToInput(this.getSelectedText(token));
gl.FilteredSearch
Dropdown
Manager.addWordToInput(this.getSelectedText(token));
}
this.dismissDropdown();
this.dispatchInputEvent();
...
...
app/assets/javascripts/filtered_search/dropdown_non_user.js.es6
View file @
513cdda3
...
...
@@ -25,7 +25,7 @@
if (!dataValueSet) {
const title = e.detail.selected.querySelector('.js-data-value').innerText.trim();
const name = `${this.symbol}${this.getEscapedText(title)}`;
gl.FilteredSearchManager.addWordToInput(this.getSelectedText(name));
gl.FilteredSearch
Dropdown
Manager.addWordToInput(this.getSelectedText(name));
}
this.dismissDropdown(!dataValueSet);
...
...
app/assets/javascripts/filtered_search/dropdown_user.js.es6
View file @
513cdda3
...
...
@@ -27,7 +27,7 @@
if (!dataValueSet) {
const username = e.detail.selected.querySelector('.dropdown-light-content').innerText.trim();
gl.FilteredSearchManager.addWordToInput(this.getSelectedText(username));
gl.FilteredSearch
Dropdown
Manager.addWordToInput(this.getSelectedText(username));
}
this.dismissDropdown(!dataValueSet);
...
...
app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
View file @
513cdda3
...
...
@@ -57,7 +57,7 @@
const dataValue = selected.getAttribute('data-value');
if (dataValue) {
gl.FilteredSearchManager.addWordToInput(dataValue);
gl.FilteredSearch
Dropdown
Manager.addWordToInput(dataValue);
}
return dataValue !== null;
...
...
app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
0 → 100644
View file @
513cdda3
/* eslint-disable no-param-reassign */
((global) => {
class FilteredSearchDropdownManager {
constructor() {
this.tokenizer = gl.FilteredSearchTokenizer;
this.filteredSearchInput = document.querySelector('.filtered-search');
this.cleanupWrapper = this.cleanup.bind(this);
document.addEventListener('page:fetch', this.cleanupWrapper);
}
cleanup() {
if (this.droplab) {
this.droplab.destroy();
this.droplab = null;
}
this.setupMapping();
document.removeEventListener('page:fetch', this.cleanupWrapper);
}
setupMapping() {
this.mapping = {
author: {
reference: null,
gl: 'DropdownUser',
element: document.querySelector('#js-dropdown-author'),
},
assignee: {
reference: null,
gl: 'DropdownUser',
element: document.querySelector('#js-dropdown-assignee'),
},
milestone: {
reference: null,
gl: 'DropdownNonUser',
extraArguments: ['milestones.json', '%'],
element: document.querySelector('#js-dropdown-milestone'),
},
label: {
reference: null,
gl: 'DropdownNonUser',
extraArguments: ['labels.json', '~'],
element: document.querySelector('#js-dropdown-label'),
},
hint: {
reference: null,
gl: 'DropdownHint',
element: document.querySelector('#js-dropdown-hint'),
},
}
}
static addWordToInput(word, addSpace) {
const filteredSearchInput = document.querySelector('.filtered-search')
const filteredSearchValue = filteredSearchInput.value;
const hasExistingValue = filteredSearchValue.length !== 0;
const { lastToken } = gl.FilteredSearchTokenizer.processTokens(filteredSearchValue);
if (lastToken.hasOwnProperty('key')) {
console.log(lastToken);
// Spaces inside the token means that the token value will be escaped by quotes
const hasQuotes = lastToken.value.indexOf(' ') !== -1;
const lengthToRemove = hasQuotes ? lastToken.value.length + 2 : lastToken.value.length;
filteredSearchInput.value = filteredSearchValue.slice(0, -1 * (lengthToRemove));
}
filteredSearchInput.value += hasExistingValue && addSpace ? ` ${word}` : word;
}
updateCurrentDropdownOffset() {
this.updateDropdownOffset(this.currentDropdown);
}
updateDropdownOffset(key) {
const filterIconPadding = 27;
const offset = gl.text.getTextWidth(this.filteredSearchInput.value, this.font) + filterIconPadding;
this.mapping[key].reference.setOffset(offset);
}
load(key, firstLoad = false) {
console.log(`🦄 load ${key} dropdown`);
const glClass = this.mapping[key].gl;
const element = this.mapping[key].element;
let forceShowList = false;
if (!this.mapping[key].reference) {
var dl = this.droplab;
const defaultArguments = [null, dl, element, this.filteredSearchInput];
const glArguments = defaultArguments.concat(this.mapping[key].extraArguments || []);
this.mapping[key].reference = new (Function.prototype.bind.apply(gl[glClass], glArguments));
}
if (firstLoad) {
this.mapping[key].reference.configure();
}
if (this.currentDropdown === 'hint') {
// Clicked from hint dropdown
forceShowList = true;
}
this.updateDropdownOffset(key);
this.mapping[key].reference.render(firstLoad, forceShowList);
this.currentDropdown = key;
}
loadDropdown(dropdownName = '') {
let firstLoad = false;
if(!this.droplab) {
firstLoad = true;
this.droplab = new DropLab();
}
if (!this.font) {
this.font = window.getComputedStyle(this.filteredSearchInput).font;
}
const match = gl.FilteredSearchTokenKeys.get().filter(value => value.key === dropdownName.toLowerCase())[0];
const shouldOpenFilterDropdown = match && this.currentDropdown !== match.key && this.mapping.hasOwnProperty(match.key);
const shouldOpenHintDropdown = !match && this.currentDropdown !== 'hint';
if (shouldOpenFilterDropdown || shouldOpenHintDropdown) {
const key = match && match.hasOwnProperty('key') ? match.key : 'hint';
this.load(key, firstLoad);
}
gl.droplab = this.droplab;
}
setDropdown() {
const { lastToken } = this.tokenizer.processTokens(this.filteredSearchInput.value);
if (typeof lastToken === 'string') {
// Token is not fully initialized yet
// because it has no value
// Eg. token = 'label:'
const { tokenKey } = this.tokenizer.parseToken(lastToken);
this.loadDropdown(tokenKey);
} else if (lastToken.hasOwnProperty('key')) {
// Token has been initialized into an object
// because it has a value
this.loadDropdown(lastToken.key);
} else {
this.loadDropdown('hint');
}
}
resetDropdowns() {
// Force current dropdown to hide
this.mapping[this.currentDropdown].reference.hideDropdown();
// Re-Load dropdown
this.setDropdown();
// Reset filters for current dropdown
this.mapping[this.currentDropdown].reference.resetFilters();
// Reposition dropdown so that it is aligned with cursor
this.updateDropdownOffset(this.currentDropdown);
}
destroyDroplab() {
this.droplab.destroy();
}
}
global.FilteredSearchDropdownManager = FilteredSearchDropdownManager;
})(window.gl || (window.gl = {}));
app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
View file @
513cdda3
...
...
@@ -75,159 +75,24 @@
this.tokenizer = gl.FilteredSearchTokenizer;
this.filteredSearchInput = document.querySelector('.filtered-search');
this.clearSearchButton = document.querySelector('.clear-search');
this.dropdownManager = new gl.FilteredSearchDropdownManager();
this.setupMapping();
this.
dropdownManager.
setupMapping();
this.bindEvents();
loadSearchParamsFromURL();
this.setDropdown();
this.
dropdownManager.
setDropdown();
this.cleanupWrapper = this.cleanup.bind(this);
document.addEventListener('page:fetch', this.cleanupWrapper);
}
cleanup() {
console.log('cleanup')
if (this.droplab) {
this.droplab.destroy();
this.droplab = null;
}
this.setupMapping();
this.unbindEvents();
document.removeEventListener('page:fetch', this.cleanupWrapper);
}
setupMapping() {
this.mapping = {
author: {
reference: null,
gl: 'DropdownUser',
element: document.querySelector('#js-dropdown-author'),
},
assignee: {
reference: null,
gl: 'DropdownUser',
element: document.querySelector('#js-dropdown-assignee'),
},
milestone: {
reference: null,
gl: 'DropdownNonUser',
extraArguments: ['milestones.json', '%'],
element: document.querySelector('#js-dropdown-milestone'),
},
label: {
reference: null,
gl: 'DropdownNonUser',
extraArguments: ['labels.json', '~'],
element: document.querySelector('#js-dropdown-label'),
},
hint: {
reference: null,
gl: 'DropdownHint',
element: document.querySelector('#js-dropdown-hint'),
},
}
}
static addWordToInput(word, addSpace) {
const filteredSearchInput = document.querySelector('.filtered-search')
const filteredSearchValue = filteredSearchInput.value;
const hasExistingValue = filteredSearchValue.length !== 0;
const { lastToken } = gl.FilteredSearchTokenizer.processTokens(filteredSearchValue);
if (lastToken.hasOwnProperty('key')) {
console.log(lastToken);
// Spaces inside the token means that the token value will be escaped by quotes
const hasQuotes = lastToken.value.indexOf(' ') !== -1;
const lengthToRemove = hasQuotes ? lastToken.value.length + 2 : lastToken.value.length;
filteredSearchInput.value = filteredSearchValue.slice(0, -1 * (lengthToRemove));
}
filteredSearchInput.value += hasExistingValue && addSpace ? ` ${word}` : word;
}
updateDropdownOffset(key) {
const filterIconPadding = 27;
const offset = gl.text.getTextWidth(this.filteredSearchInput.value, this.font) + filterIconPadding;
this.mapping[key].reference.setOffset(offset);
}
load(key, firstLoad = false) {
console.log(`🦄 load ${key} dropdown`);
const glClass = this.mapping[key].gl;
const element = this.mapping[key].element;
let forceShowList = false;
if (!this.mapping[key].reference) {
var dl = this.droplab;
const defaultArguments = [null, dl, element, this.filteredSearchInput];
const glArguments = defaultArguments.concat(this.mapping[key].extraArguments || []);
this.mapping[key].reference = new (Function.prototype.bind.apply(gl[glClass], glArguments));
}
if (firstLoad) {
this.mapping[key].reference.configure();
}
if (this.currentDropdown === 'hint') {
// Clicked from hint dropdown
forceShowList = true;
}
this.updateDropdownOffset(key);
this.mapping[key].reference.render(firstLoad, forceShowList);
this.currentDropdown = key;
}
loadDropdown(dropdownName = '') {
let firstLoad = false;
if(!this.droplab) {
firstLoad = true;
this.droplab = new DropLab();
}
if (!this.font) {
this.font = window.getComputedStyle(this.filteredSearchInput).font;
}
const match = gl.FilteredSearchTokenKeys.get().filter(value => value.key === dropdownName.toLowerCase())[0];
const shouldOpenFilterDropdown = match && this.currentDropdown !== match.key && this.mapping.hasOwnProperty(match.key);
const shouldOpenHintDropdown = !match && this.currentDropdown !== 'hint';
if (shouldOpenFilterDropdown || shouldOpenHintDropdown) {
const key = match && match.hasOwnProperty('key') ? match.key : 'hint';
this.load(key, firstLoad);
}
gl.droplab = this.droplab;
}
setDropdown() {
const { lastToken } = this.tokenizer.processTokens(this.filteredSearchInput.value);
if (typeof lastToken === 'string') {
// Token is not fully initialized yet
// because it has no value
// Eg. token = 'label:'
const { tokenKey } = this.tokenizer.parseToken(lastToken);
this.loadDropdown(tokenKey);
} else if (lastToken.hasOwnProperty('key')) {
// Token has been initialized into an object
// because it has a value
this.loadDropdown(lastToken.key);
} else {
this.loadDropdown('hint');
}
}
bindEvents() {
this.setDropdownWrapper = this.
setDropdown.bind(this
);
this.setDropdownWrapper = this.
dropdownManager.setDropdown.bind(this.dropdownManager
);
this.checkForEnterWrapper = this.checkForEnter.bind(this);
this.clearSearchWrapper = this.clearSearch.bind(this);
this.checkForBackspaceWrapper = this.checkForBackspace.bind(this);
...
...
@@ -254,24 +119,13 @@
this.filteredSearchInput.value = '';
this.clearSearchButton.classList.add('hidden');
// Force current dropdown to hide
this.mapping[this.currentDropdown].reference.hideDropdown();
// Re-Load dropdown
this.setDropdown();
// Reset filters for current dropdown
this.mapping[this.currentDropdown].reference.resetFilters();
// Reposition dropdown so that it is aligned with cursor
this.updateDropdownOffset(this.currentDropdown);
this.dropdownManager.resetDropdowns();
}
checkForBackspace(e) {
if (e.keyCode === 8) {
// Reposition dropdown so that it is aligned with cursor
this.
updateDropdownOffset(this.currentDropdown
);
this.
dropdownManager.updateCurrentDropdownOffset(
);
}
}
...
...
@@ -282,7 +136,7 @@
e.preventDefault();
// Prevent droplab from opening dropdown
this.drop
lab.destroy
();
this.drop
downManager.destroyDroplab
();
this.search();
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment