summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_manager.js26
-rw-r--r--app/assets/stylesheets/framework/filters.scss16
-rw-r--r--changelogs/unreleased/31757-single-click-on-filter-in-search-bar-to-activate-dropdown.yml4
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb4
-rw-r--r--spec/javascripts/filtered_search/filtered_search_manager_spec.js36
5 files changed, 22 insertions, 64 deletions
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js
index 3be889c684b..72214321be1 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js
@@ -105,11 +105,9 @@ class FilteredSearchManager {
this.filteredSearchInput.addEventListener('click', this.tokenChange);
this.filteredSearchInput.addEventListener('keyup', this.tokenChange);
this.filteredSearchInput.addEventListener('focus', this.addInputContainerFocusWrapper);
- this.tokensContainer.addEventListener('click', FilteredSearchManager.selectToken);
this.tokensContainer.addEventListener('click', this.removeTokenWrapper);
- this.tokensContainer.addEventListener('dblclick', this.editTokenWrapper);
+ this.tokensContainer.addEventListener('click', this.editTokenWrapper);
this.clearSearchButton.addEventListener('click', this.onClearSearchWrapper);
- document.addEventListener('click', gl.FilteredSearchVisualTokens.unselectTokens);
document.addEventListener('click', this.unselectEditTokensWrapper);
document.addEventListener('click', this.removeInputContainerFocusWrapper);
document.addEventListener('keydown', this.removeSelectedTokenKeydownWrapper);
@@ -127,11 +125,9 @@ class FilteredSearchManager {
this.filteredSearchInput.removeEventListener('click', this.tokenChange);
this.filteredSearchInput.removeEventListener('keyup', this.tokenChange);
this.filteredSearchInput.removeEventListener('focus', this.addInputContainerFocusWrapper);
- this.tokensContainer.removeEventListener('click', FilteredSearchManager.selectToken);
this.tokensContainer.removeEventListener('click', this.removeTokenWrapper);
- this.tokensContainer.removeEventListener('dblclick', this.editTokenWrapper);
+ this.tokensContainer.removeEventListener('click', this.editTokenWrapper);
this.clearSearchButton.removeEventListener('click', this.onClearSearchWrapper);
- document.removeEventListener('click', gl.FilteredSearchVisualTokens.unselectTokens);
document.removeEventListener('click', this.unselectEditTokensWrapper);
document.removeEventListener('click', this.removeInputContainerFocusWrapper);
document.removeEventListener('keydown', this.removeSelectedTokenKeydownWrapper);
@@ -207,23 +203,13 @@ class FilteredSearchManager {
}
}
- static selectToken(e) {
- const button = e.target.closest('.selectable');
- const removeButtonSelected = e.target.closest('.remove-token');
-
- if (!removeButtonSelected && button) {
- e.preventDefault();
- e.stopPropagation();
- gl.FilteredSearchVisualTokens.selectToken(button);
- }
- }
-
removeToken(e) {
const removeButtonSelected = e.target.closest('.remove-token');
if (removeButtonSelected) {
e.preventDefault();
- e.stopPropagation();
+ // Prevent editToken from being triggered after token is removed
+ e.stopImmediatePropagation();
const button = e.target.closest('.selectable');
gl.FilteredSearchVisualTokens.selectToken(button, true);
@@ -245,10 +231,12 @@ class FilteredSearchManager {
editToken(e) {
const token = e.target.closest('.js-visual-token');
- const sanitizedTokenName = token.querySelector('.name').textContent.trim();
+ const sanitizedTokenName = token && token.querySelector('.name').textContent.trim();
const canEdit = this.canEdit && this.canEdit(sanitizedTokenName);
if (token && canEdit) {
+ e.preventDefault();
+ e.stopPropagation();
gl.FilteredSearchVisualTokens.editToken(token);
this.tokenChange();
}
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index acf5de0e3b5..cfbaaaa04c7 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -142,15 +142,17 @@
}
}
}
+}
- .selected {
- .name {
- background-color: $filter-name-selected-color;
- }
+.filtered-search-token:hover,
+.filtered-search-token .selected,
+.filtered-search-term .selected {
+ .name {
+ background-color: $filter-name-selected-color;
+ }
- .value-container {
- background-color: $filter-value-selected-color;
- }
+ .value-container {
+ background-color: $filter-value-selected-color;
}
}
diff --git a/changelogs/unreleased/31757-single-click-on-filter-in-search-bar-to-activate-dropdown.yml b/changelogs/unreleased/31757-single-click-on-filter-in-search-bar-to-activate-dropdown.yml
new file mode 100644
index 00000000000..48b8a8507ec
--- /dev/null
+++ b/changelogs/unreleased/31757-single-click-on-filter-in-search-bar-to-activate-dropdown.yml
@@ -0,0 +1,4 @@
+---
+title: Single click on filter to open filtered search dropdown
+merge_request:
+author:
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
index dbbafc9e004..ff32b0c7d11 100644
--- a/spec/features/issues/filtered_search/visual_tokens_spec.rb
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -34,7 +34,7 @@ describe 'Visual tokens', js: true, feature: true do
describe 'editing author token' do
before do
input_filtered_search('author:@root assignee:none', submit: false)
- first('.tokens-container .filtered-search-token').double_click
+ first('.tokens-container .filtered-search-token').click
end
it 'opens author dropdown' do
@@ -331,7 +331,7 @@ describe 'Visual tokens', js: true, feature: true do
it 'does not tokenize incomplete token' do
filtered_search.send_keys('author:')
- find('#content-body').click
+ find('body').click
token = page.all('.tokens-container .js-visual-token')[1]
expect_filtered_search_input_empty
diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
index 6e59ee96c6b..9c8629ef9f0 100644
--- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
@@ -316,42 +316,6 @@ describe('Filtered Search Manager', () => {
});
});
- describe('unselects token', () => {
- beforeEach(() => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '~bug', true)}
- ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '~awesome')}
- `);
- });
-
- it('unselects token when input is clicked', () => {
- const selectedToken = tokensContainer.querySelector('.js-visual-token .selected');
-
- expect(selectedToken.classList.contains('selected')).toEqual(true);
- expect(gl.FilteredSearchVisualTokens.unselectTokens).not.toHaveBeenCalled();
-
- // Click directly on input attached to document
- // so that the click event will propagate properly
- document.querySelector('.filtered-search').click();
-
- expect(gl.FilteredSearchVisualTokens.unselectTokens).toHaveBeenCalled();
- expect(selectedToken.classList.contains('selected')).toEqual(false);
- });
-
- it('unselects token when document.body is clicked', () => {
- const selectedToken = tokensContainer.querySelector('.js-visual-token .selected');
-
- expect(selectedToken.classList.contains('selected')).toEqual(true);
- expect(gl.FilteredSearchVisualTokens.unselectTokens).not.toHaveBeenCalled();
-
- document.body.click();
-
- expect(selectedToken.classList.contains('selected')).toEqual(false);
- expect(gl.FilteredSearchVisualTokens.unselectTokens).toHaveBeenCalled();
- });
- });
-
describe('toggleInputContainerFocus', () => {
it('toggles on focus', () => {
input.focus();