Commit 25741c97a2ae1446fe03b86cc5e0bd5f49b41cf6

Authored by Dmitriy Zaporozhets
2 parents 1c61ac1c 4f6b570f

Merge pull request #6350 from tudorpavel/filter-by-multiple-labels

Add feature to filter issues by multiple labels
app/assets/stylesheets/main/variables.scss
@@ -5,6 +5,7 @@ $primary_color: #2FA0BB; @@ -5,6 +5,7 @@ $primary_color: #2FA0BB;
5 $link_color: #3A89A3; 5 $link_color: #3A89A3;
6 $style_color: #474D57; 6 $style_color: #474D57;
7 $bg_style_color: #2299BB; 7 $bg_style_color: #2299BB;
  8 +$list-group-active-bg: $bg_style_color;
8 $hover: #D9EDF7; 9 $hover: #D9EDF7;
9 10
10 /** 11 /**
app/helpers/projects_helper.rb
@@ -64,6 +64,31 @@ module ProjectsHelper @@ -64,6 +64,31 @@ module ProjectsHelper
64 project_nav_tabs.include? name 64 project_nav_tabs.include? name
65 end 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 def project_filter_path(options={}) 92 def project_filter_path(options={})
68 exist_opts = { 93 exist_opts = {
69 state: params[:state], 94 state: params[:state],
app/views/projects/issues/_issues.html.haml
@@ -2,25 +2,6 @@ @@ -2,25 +2,6 @@
2 .check-all-holder 2 .check-all-holder
3 = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left" 3 = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left"
4 .issues-filters 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 .dropdown.inline.prepend-left-10 5 .dropdown.inline.prepend-left-10
25 %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} 6 %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
26 %i.icon-user 7 %i.icon-user
app/views/shared/_project_filter.html.haml
@@ -27,6 +27,18 @@ @@ -27,6 +27,18 @@
27 All 27 All
28 28
29 %fieldset 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 - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any? 42 - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any?
31 = link_to project_entities_path, class: 'cgray pull-right' do 43 = link_to project_entities_path, class: 'cgray pull-right' do
32 %i.icon-remove 44 %i.icon-remove
features/project/issues/filter_labels.feature 0 → 100644
@@ -0,0 +1,26 @@ @@ -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
features/steps/project/project_filter_labels.rb 0 → 100644
@@ -0,0 +1,70 @@ @@ -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