Commit c7c8e469 authored by Micaël Bergeron's avatar Micaël Bergeron Committed by Ezekiel Kigbo

Add a clear button on the Search filter

This commit adds clear buttons on the Group and Project filters for
the search page.

This enables the user to remove a filter in a single click instead of
having to wait for the dropdown to fully load.
parent 2e1b16f4
...@@ -4,6 +4,7 @@ import { deprecatedCreateFlash as Flash } from '~/flash'; ...@@ -4,6 +4,7 @@ import { deprecatedCreateFlash as Flash } from '~/flash';
import Api from '~/api'; import Api from '~/api';
import { __ } from '~/locale'; import { __ } from '~/locale';
import Project from '~/pages/projects/project'; import Project from '~/pages/projects/project';
import { visitUrl } from '~/lib/utils/url_utility';
import refreshCounts from './refresh_counts'; import refreshCounts from './refresh_counts';
import setHighlightClass from './highlight_blob_search_result'; import setHighlightClass from './highlight_blob_search_result';
...@@ -86,6 +87,10 @@ export default class Search { ...@@ -86,6 +87,10 @@ export default class Search {
$(document) $(document)
.off('click', this.searchClear) .off('click', this.searchClear)
.on('click', this.searchClear, this.clearSearchField.bind(this)); .on('click', this.searchClear, this.clearSearchField.bind(this));
$('a.js-search-clear')
.off('click', this.clearSearchFilter)
.on('click', this.clearSearchFilter);
} }
static submitSearch() { static submitSearch() {
...@@ -108,6 +113,17 @@ export default class Search { ...@@ -108,6 +113,17 @@ export default class Search {
.focus(); .focus();
} }
// We need to manually follow the link on the anchors
// that have this event bound, as their `click` default
// behavior is prevented by the toggle logic.
/* eslint-disable-next-line class-methods-use-this */
clearSearchFilter(ev) {
const $target = $(ev.currentTarget);
visitUrl($target.href);
ev.stopPropagation();
}
getProjectsData(term) { getProjectsData(term) {
return new Promise(resolve => { return new Promise(resolve => {
if (this.groupId) { if (this.groupId) {
......
...@@ -198,6 +198,15 @@ input[type='checkbox']:hover { ...@@ -198,6 +198,15 @@ input[type='checkbox']:hover {
} }
} }
.search-clear {
position: absolute;
right: 10px;
top: 9px;
padding: 0;
line-height: 0;
background: none;
border: 0;
}
.search-icon { .search-icon {
position: absolute; position: absolute;
...@@ -247,14 +256,7 @@ input[type='checkbox']:hover { ...@@ -247,14 +256,7 @@ input[type='checkbox']:hover {
} }
.search-clear { .search-clear {
position: absolute;
right: 10px;
top: 9px;
padding: 0;
color: $gray-darkest; color: $gray-darkest;
line-height: 0;
background: none;
border: 0;
&:hover, &:hover,
&:focus { &:focus {
......
...@@ -2,15 +2,14 @@ ...@@ -2,15 +2,14 @@
= hidden_field_tag :group_id, params[:group_id] = hidden_field_tag :group_id, params[:group_id]
- if params[:project_id].present? - if params[:project_id].present?
= hidden_field_tag :project_id, params[:project_id] = hidden_field_tag :project_id, params[:project_id]
.dropdown.form-group.mb-lg-0.mx-lg-1 .dropdown.form-group.mb-lg-0.mx-lg-1{ data: { testid: "group-filter" } }
%label.d-block{ for: "dashboard_search_group" } %label.d-block{ for: "dashboard_search_group" }
= _("Group") = _("Group")
%button.dropdown-menu-toggle.js-search-group-dropdown.mt-0{ type: "button", id: "dashboard_search_group", data: { toggle: "dropdown", group_id: params[:group_id] } } %button.dropdown-menu-toggle.gl-display-inline-flex.js-search-group-dropdown.gl-mt-0{ type: "button", id: "dashboard_search_group", data: { toggle: "dropdown", group_id: params[:group_id] } }
%span.dropdown-toggle-text %span.dropdown-toggle-text.gl-flex-grow-1.str-truncated-100
- if @group.present? = @group&.name || _("Any")
= @group.name - if @group.present?
- else = link_to sprite_icon("clear"), url_for(safe_params.except(:project_id, :group_id)), class: 'search-clear js-search-clear has-tooltip', title: _('Clear')
= _("Any")
= icon("chevron-down") = icon("chevron-down")
.dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-right .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-right
= dropdown_title(_("Filter results by group")) = dropdown_title(_("Filter results by group"))
...@@ -21,12 +20,11 @@ ...@@ -21,12 +20,11 @@
.dropdown.project-filter.form-group.mb-lg-0.mx-lg-1 .dropdown.project-filter.form-group.mb-lg-0.mx-lg-1
%label.d-block{ for: "dashboard_search_project" } %label.d-block{ for: "dashboard_search_project" }
= _("Project") = _("Project")
%button.dropdown-menu-toggle.js-search-project-dropdown.mt-0{ type: "button", id: "dashboard_search_project", data: { toggle: "dropdown"} } %button.dropdown-menu-toggle.gl-display-inline-flex.js-search-project-dropdown.gl-mt-0{ type: "button", id: "dashboard_search_project", data: { toggle: "dropdown", target: '.project-filter' } }
%span.dropdown-toggle-text %span.dropdown-toggle-text.gl-flex-grow-1.str-truncated-100
- if @project.present? = @project&.full_name || _("Any")
= @project.full_name - if @project.present?
- else = link_to sprite_icon("clear"), url_for(safe_params.except(:project_id)), class: 'search-clear js-search-clear has-tooltip', title: _('Clear')
= _("Any")
= icon("chevron-down") = icon("chevron-down")
.dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-right .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-right
= dropdown_title(_("Filter results by project")) = dropdown_title(_("Filter results by project"))
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
.position-relative .position-relative
= search_field_tag :search, params[:search], placeholder: _("Search for projects, issues, etc."), class: "form-control search-text-input js-search-input", id: "dashboard_search", autofocus: true, spellcheck: false = search_field_tag :search, params[:search], placeholder: _("Search for projects, issues, etc."), class: "form-control search-text-input js-search-input", id: "dashboard_search", autofocus: true, spellcheck: false
= sprite_icon('search', css_class: 'search-icon') = sprite_icon('search', css_class: 'search-icon')
%button.search-clear.js-search-clear{ class: ("hidden" if !params[:search].present?), type: "button", tabindex: "-1" } %button.search-clear.js-search-clear{ class: [("hidden" if params[:search].blank?), "has-tooltip"], type: "button", tabindex: "-1", title: _('Clear') }
= sprite_icon('clear') = sprite_icon('clear')
%span.sr-only %span.sr-only
= _("Clear search") = _("Clear search")
......
---
title: Add buttons in the Search page to clear Group and Project filters
merge_request: 42897
author:
type: added
...@@ -12,12 +12,12 @@ RSpec.describe 'User uses search filters', :js do ...@@ -12,12 +12,12 @@ RSpec.describe 'User uses search filters', :js do
project.add_reporter(user) project.add_reporter(user)
group.add_owner(user) group.add_owner(user)
sign_in(user) sign_in(user)
visit(search_path)
end end
context 'when filtering by group' do context 'when filtering by group' do
it 'shows group projects' do it 'shows group projects' do
visit search_path
find('.js-search-group-dropdown').click find('.js-search-group-dropdown').click
wait_for_requests wait_for_requests
...@@ -36,10 +36,27 @@ RSpec.describe 'User uses search filters', :js do ...@@ -36,10 +36,27 @@ RSpec.describe 'User uses search filters', :js do
expect(page).to have_link(group_project.full_name) expect(page).to have_link(group_project.full_name)
end end
end end
context 'when the group filter is set' do
before do
visit search_path(search: "test", group_id: group.id, project_id: project.id)
end
describe 'clear filter button' do
it 'removes Group and Project filters' do
link = find('[data-testid="group-filter"] .js-search-clear')
params = CGI.parse(URI.parse(link[:href]).query)
expect(params).not_to include(:group_id, :project_id)
end
end
end
end end
context 'when filtering by project' do context 'when filtering by project' do
it 'shows a project' do it 'shows a project' do
visit search_path
page.within('.project-filter') do page.within('.project-filter') do
find('.js-search-project-dropdown').click find('.js-search-project-dropdown').click
...@@ -50,5 +67,22 @@ RSpec.describe 'User uses search filters', :js do ...@@ -50,5 +67,22 @@ RSpec.describe 'User uses search filters', :js do
expect(find('.js-search-project-dropdown')).to have_content(project.full_name) expect(find('.js-search-project-dropdown')).to have_content(project.full_name)
end end
context 'when the project filter is set' do
before do
visit search_path(search: "test", project_id: project.id)
end
let(:query) { { project_id: project.id } }
describe 'clear filter button' do
it 'removes Project filters' do
link = find('.project-filter .js-search-clear')
params = CGI.parse(URI.parse(link[:href]).query)
expect(params).not_to include(:project_id)
end
end
end
end end
end end
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