Commit 25741c97a2ae1446fe03b86cc5e0bd5f49b41cf6
Exists in
spb-stable
and in
3 other branches
Merge pull request #6350 from tudorpavel/filter-by-multiple-labels
Add feature to filter issues by multiple labels
Showing
6 changed files
with
134 additions
and
19 deletions
Show diff stats
app/assets/stylesheets/main/variables.scss
app/helpers/projects_helper.rb
| ... | ... | @@ -64,6 +64,31 @@ module ProjectsHelper |
| 64 | 64 | project_nav_tabs.include? name |
| 65 | 65 | end |
| 66 | 66 | |
| 67 | + def selected_label?(label_name) | |
| 68 | + params[:label_name].to_s.split(',').include?(label_name) | |
| 69 | + end | |
| 70 | + | |
| 71 | + def labels_filter_path(label_name) | |
| 72 | + label_name = | |
| 73 | + if selected_label?(label_name) | |
| 74 | + params[:label_name].split(',').reject { |l| l == label_name }.join(',') | |
| 75 | + elsif params[:label_name].present? | |
| 76 | + "#{params[:label_name]},#{label_name}" | |
| 77 | + else | |
| 78 | + label_name | |
| 79 | + end | |
| 80 | + | |
| 81 | + project_filter_path(label_name: label_name) | |
| 82 | + end | |
| 83 | + | |
| 84 | + def label_filter_class(label_name) | |
| 85 | + if selected_label?(label_name) | |
| 86 | + 'list-group-item active' | |
| 87 | + else | |
| 88 | + 'list-group-item' | |
| 89 | + end | |
| 90 | + end | |
| 91 | + | |
| 67 | 92 | def project_filter_path(options={}) |
| 68 | 93 | exist_opts = { |
| 69 | 94 | state: params[:state], | ... | ... |
app/views/projects/issues/_issues.html.haml
| ... | ... | @@ -2,25 +2,6 @@ |
| 2 | 2 | .check-all-holder |
| 3 | 3 | = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left" |
| 4 | 4 | .issues-filters |
| 5 | - .dropdown.inline | |
| 6 | - %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} | |
| 7 | - %i.icon-tags | |
| 8 | - %span.light labels: | |
| 9 | - - if params[:label_name].present? | |
| 10 | - %strong= params[:label_name] | |
| 11 | - - else | |
| 12 | - Any | |
| 13 | - %b.caret | |
| 14 | - %ul.dropdown-menu | |
| 15 | - %li | |
| 16 | - = link_to project_filter_path(label_name: nil) do | |
| 17 | - Any | |
| 18 | - - issue_label_names.each do |label_name| | |
| 19 | - %li | |
| 20 | - = link_to project_filter_path(label_name: label_name) do | |
| 21 | - %span{class: "label #{label_css_class(label_name)}"} | |
| 22 | - %i.icon-tag | |
| 23 | - = label_name | |
| 24 | 5 | .dropdown.inline.prepend-left-10 |
| 25 | 6 | %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} |
| 26 | 7 | %i.icon-user | ... | ... |
app/views/shared/_project_filter.html.haml
| ... | ... | @@ -27,6 +27,18 @@ |
| 27 | 27 | All |
| 28 | 28 | |
| 29 | 29 | %fieldset |
| 30 | + %legend Labels | |
| 31 | + %ul.list-group | |
| 32 | + - issue_label_names.each do |label_name| | |
| 33 | + = link_to labels_filter_path(label_name), class: label_filter_class(label_name) do | |
| 34 | + %span{class: "label #{label_css_class(label_name)}"} | |
| 35 | + %i.icon-tag | |
| 36 | + = label_name | |
| 37 | + - if selected_label?(label_name) | |
| 38 | + .pull-right | |
| 39 | + %i.icon-remove | |
| 40 | + | |
| 41 | + %fieldset | |
| 30 | 42 | - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any? |
| 31 | 43 | = link_to project_entities_path, class: 'cgray pull-right' do |
| 32 | 44 | %i.icon-remove | ... | ... |
| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | +Feature: Project Filter Labels | |
| 2 | + Background: | |
| 3 | + Given I sign in as a user | |
| 4 | + And I own project "Shop" | |
| 5 | + And project "Shop" has issue "Bugfix1" with tags: "bug", "feature" | |
| 6 | + And project "Shop" has issue "Bugfix2" with tags: "bug", "enhancement" | |
| 7 | + And project "Shop" has issue "Feature1" with tags: "feature" | |
| 8 | + Given I visit project "Shop" issues page | |
| 9 | + | |
| 10 | + Scenario: I should see project issues | |
| 11 | + Then I should see "bug" in labels filter | |
| 12 | + And I should see "feature" in labels filter | |
| 13 | + And I should see "enhancement" in labels filter | |
| 14 | + | |
| 15 | + Scenario: I filter by one label | |
| 16 | + Given I click link "bug" | |
| 17 | + Then I should see "Bugfix1" in issues list | |
| 18 | + And I should see "Bugfix2" in issues list | |
| 19 | + And I should not see "Feature1" in issues list | |
| 20 | + | |
| 21 | + Scenario: I filter by two labels | |
| 22 | + Given I click link "bug" | |
| 23 | + And I click link "feature" | |
| 24 | + Then I should see "Bugfix1" in issues list | |
| 25 | + And I should not see "Bugfix2" in issues list | |
| 26 | + And I should not see "Feature1" in issues list | ... | ... |
| ... | ... | @@ -0,0 +1,70 @@ |
| 1 | +class ProjectFilterLabels < Spinach::FeatureSteps | |
| 2 | + include SharedAuthentication | |
| 3 | + include SharedProject | |
| 4 | + include SharedPaths | |
| 5 | + | |
| 6 | + Then 'I should see "bug" in labels filter' do | |
| 7 | + within ".list-group" do | |
| 8 | + page.should have_content "bug" | |
| 9 | + end | |
| 10 | + end | |
| 11 | + | |
| 12 | + And 'I should see "feature" in labels filter' do | |
| 13 | + within ".list-group" do | |
| 14 | + page.should have_content "feature" | |
| 15 | + end | |
| 16 | + end | |
| 17 | + | |
| 18 | + And 'I should see "enhancement" in labels filter' do | |
| 19 | + within ".list-group" do | |
| 20 | + page.should have_content "enhancement" | |
| 21 | + end | |
| 22 | + end | |
| 23 | + | |
| 24 | + Then 'I should see "Bugfix1" in issues list' do | |
| 25 | + within ".issues-list" do | |
| 26 | + page.should have_content "Bugfix1" | |
| 27 | + end | |
| 28 | + end | |
| 29 | + | |
| 30 | + And 'I should see "Bugfix2" in issues list' do | |
| 31 | + within ".issues-list" do | |
| 32 | + page.should have_content "Bugfix2" | |
| 33 | + end | |
| 34 | + end | |
| 35 | + | |
| 36 | + And 'I should not see "Bugfix2" in issues list' do | |
| 37 | + within ".issues-list" do | |
| 38 | + page.should_not have_content "Bugfix2" | |
| 39 | + end | |
| 40 | + end | |
| 41 | + | |
| 42 | + And 'I should not see "Feature1" in issues list' do | |
| 43 | + within ".issues-list" do | |
| 44 | + page.should_not have_content "Feature1" | |
| 45 | + end | |
| 46 | + end | |
| 47 | + | |
| 48 | + Given 'I click link "bug"' do | |
| 49 | + click_link "bug" | |
| 50 | + end | |
| 51 | + | |
| 52 | + Given 'I click link "feature"' do | |
| 53 | + click_link "feature" | |
| 54 | + end | |
| 55 | + | |
| 56 | + And 'project "Shop" has issue "Bugfix1" with tags: "bug", "feature"' do | |
| 57 | + project = Project.find_by(name: "Shop") | |
| 58 | + create(:issue, title: "Bugfix1", project: project, label_list: ['bug', 'feature']) | |
| 59 | + end | |
| 60 | + | |
| 61 | + And 'project "Shop" has issue "Bugfix2" with tags: "bug", "enhancement"' do | |
| 62 | + project = Project.find_by(name: "Shop") | |
| 63 | + create(:issue, title: "Bugfix2", project: project, label_list: ['bug', 'enhancement']) | |
| 64 | + end | |
| 65 | + | |
| 66 | + And 'project "Shop" has issue "Feature1" with tags: "feature"' do | |
| 67 | + project = Project.find_by(name: "Shop") | |
| 68 | + create(:issue, title: "Feature1", project: project, label_list: 'feature') | |
| 69 | + end | |
| 70 | +end | ... | ... |