summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClement Ho <ClemMakesApps@gmail.com>2017-03-07 20:12:23 -0600
committerClement Ho <ClemMakesApps@gmail.com>2017-03-08 02:05:21 -0600
commit86a3dee278e685d935e19bde64c3543e5e1437e5 (patch)
treef094780b112f393f1135c238532ef2d98789ba35
parentbd1d778168513e3889df877911589a371277e076 (diff)
downloadgitlab-ce-fix-visual-tokens.tar.gz
Prevent visual token dropdown from opening the wrong filter dropdownfix-visual-tokens
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_utils.js54
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js2
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_manager.js9
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb30
-rw-r--r--spec/support/filtered_search_helpers.rb11
5 files changed, 81 insertions, 25 deletions
diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js b/app/assets/javascripts/filtered_search/dropdown_utils.js
index b52081df646..a5a6b56a0d3 100644
--- a/app/assets/javascripts/filtered_search/dropdown_utils.js
+++ b/app/assets/javascripts/filtered_search/dropdown_utils.js
@@ -80,30 +80,48 @@
}
// Determines the full search query (visual tokens + input)
- static getSearchQuery() {
- const tokensContainer = document.querySelector('.tokens-container');
+ static getSearchQuery(untilInput = false) {
+ const tokens = [].slice.call(document.querySelectorAll('.tokens-container li'));
const values = [];
- [].forEach.call(tokensContainer.querySelectorAll('.js-visual-token'), (token) => {
- const name = token.querySelector('.name');
- const value = token.querySelector('.value');
- const symbol = value && value.dataset.symbol ? value.dataset.symbol : '';
- let valueText = '';
+ if (untilInput) {
+ const inputIndex = _.findIndex(tokens, t => t.classList.contains('input-token'));
+ // Add one to include input-token to the tokens array
+ tokens.splice(inputIndex + 1);
+ }
- if (value && value.innerText) {
- valueText = value.innerText;
- }
-
- if (token.className.indexOf('filtered-search-token') !== -1) {
- values.push(`${name.innerText.toLowerCase()}:${symbol}${valueText}`);
- } else {
- values.push(name.innerText);
+ tokens.forEach((token) => {
+ if (token.classList.contains('js-visual-token')) {
+ const name = token.querySelector('.name');
+ const value = token.querySelector('.value');
+ const symbol = value && value.dataset.symbol ? value.dataset.symbol : '';
+ let valueText = '';
+
+ if (value && value.innerText) {
+ valueText = value.innerText;
+ }
+
+ if (token.className.indexOf('filtered-search-token') !== -1) {
+ values.push(`${name.innerText.toLowerCase()}:${symbol}${valueText}`);
+ } else {
+ values.push(name.innerText);
+ }
+ } else if (token.classList.contains('input-token')) {
+ const { isLastVisualTokenValid } =
+ gl.FilteredSearchVisualTokens.getLastVisualTokenBeforeInput();
+
+ const input = document.querySelector('.filtered-search');
+ const inputValue = input && input.value;
+
+ if (isLastVisualTokenValid) {
+ values.push(inputValue);
+ } else {
+ const previous = values.pop();
+ values.push(`${previous}${inputValue}`);
+ }
}
});
- const input = document.querySelector('.filtered-search');
- values.push(input && input.value);
-
return values.join(' ');
}
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
index 608c65c78a4..e1a97070439 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
@@ -139,7 +139,7 @@
}
setDropdown() {
- const query = gl.DropdownUtils.getSearchQuery();
+ const query = gl.DropdownUtils.getSearchQuery(true);
const { lastToken, searchToken } = this.tokenizer.processTokens(query);
if (this.currentDropdown) {
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js
index 58a984048de..638fe744668 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js
@@ -363,10 +363,13 @@
tokenChange() {
const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown];
- const currentDropdownRef = dropdown.reference;
- this.setDropdownWrapper();
- currentDropdownRef.dispatchInputEvent();
+ if (dropdown) {
+ const currentDropdownRef = dropdown.reference;
+
+ this.setDropdownWrapper();
+ currentDropdownRef.dispatchInputEvent();
+ }
}
}
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
index a78dbaf53ed..96e87c82d2c 100644
--- a/spec/features/issues/filtered_search/visual_tokens_spec.rb
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -242,6 +242,23 @@ describe 'Visual tokens', js: true, feature: true do
end
end
+ describe 'editing a search term while editing another filter token' do
+ before do
+ input_filtered_search('author assignee:', submit: false)
+ first('.tokens-container .filtered-search-term').double_click
+ end
+
+ it 'opens hint dropdown' do
+ expect(page).to have_css('#js-dropdown-hint', visible: true)
+ end
+
+ it 'opens author dropdown' do
+ find('#js-dropdown-hint .filter-dropdown .filter-dropdown-item', text: 'author').click
+
+ expect(page).to have_css('#js-dropdown-author', visible: true)
+ end
+ end
+
describe 'add new token after editing existing token' do
before do
input_filtered_search('author:@root assignee:none', submit: false)
@@ -319,4 +336,17 @@ describe 'Visual tokens', js: true, feature: true do
expect(token.find('.name').text).to eq('Author')
end
end
+
+ describe 'search using incomplete visual tokens' do
+ before do
+ input_filtered_search('author:@root assignee:none', extra_space: false)
+ end
+
+ it 'tokenizes the search term to complete visual token' do
+ expect_tokens([
+ { name: 'author', value: '@root' },
+ { name: 'assignee', value: 'none' }
+ ])
+ end
+ end
end
diff --git a/spec/support/filtered_search_helpers.rb b/spec/support/filtered_search_helpers.rb
index f21b85ec10b..6b009b132b6 100644
--- a/spec/support/filtered_search_helpers.rb
+++ b/spec/support/filtered_search_helpers.rb
@@ -4,9 +4,14 @@ module FilteredSearchHelpers
end
# Enables input to be set (similar to copy and paste)
- def input_filtered_search(search_term, submit: true)
- # Add an extra space to engage visual tokens
- filtered_search.set("#{search_term} ")
+ def input_filtered_search(search_term, submit: true, extra_space: true)
+ search = search_term
+ if extra_space
+ # Add an extra space to engage visual tokens
+ search = "#{search_term} "
+ end
+
+ filtered_search.set(search)
if submit
filtered_search.send_keys(:enter)