Commit 4ce034ca6526e34d71fb1a483a82be2486237e6b
Exists in
master
and in
4 other branches
Merge pull request #1247 from tsigo/feature/no_milestone_filter
Allow filtering issues that have no milestone or assignee
Showing
4 changed files
with
69 additions
and
4 deletions
Show diff stats
app/controllers/issues_controller.rb
@@ -144,10 +144,19 @@ class IssuesController < ApplicationController | @@ -144,10 +144,19 @@ class IssuesController < ApplicationController | ||
144 | else @project.issues.opened | 144 | else @project.issues.opened |
145 | end | 145 | end |
146 | 146 | ||
147 | - @issues = @issues.where(assignee_id: params[:assignee_id]) if params[:assignee_id].present? | ||
148 | - @issues = @issues.where(milestone_id: params[:milestone_id]) if params[:milestone_id].present? | ||
149 | @issues = @issues.tagged_with(params[:label_name]) if params[:label_name].present? | 147 | @issues = @issues.tagged_with(params[:label_name]) if params[:label_name].present? |
150 | @issues = @issues.includes(:author, :project).order("updated_at") | 148 | @issues = @issues.includes(:author, :project).order("updated_at") |
149 | + | ||
150 | + # Filter by specific assignee_id (or lack thereof)? | ||
151 | + if params[:assignee_id].present? | ||
152 | + @issues = @issues.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id])) | ||
153 | + end | ||
154 | + | ||
155 | + # Filter by specific milestone_id (or lack thereof)? | ||
156 | + if params[:milestone_id].present? | ||
157 | + @issues = @issues.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) | ||
158 | + end | ||
159 | + | ||
151 | @issues | 160 | @issues |
152 | end | 161 | end |
153 | 162 |
app/helpers/issues_helper.rb
@@ -36,4 +36,11 @@ module IssuesHelper | @@ -36,4 +36,11 @@ module IssuesHelper | ||
36 | def issue_tags | 36 | def issue_tags |
37 | @project.issues.tag_counts_on(:labels).map(&:name) | 37 | @project.issues.tag_counts_on(:labels).map(&:name) |
38 | end | 38 | end |
39 | + | ||
40 | + # Returns an OpenStruct object suitable for use by <tt>options_from_collection_for_select</tt> | ||
41 | + # to allow filtering issues by an unassigned User or Milestone | ||
42 | + def unassigned_filter | ||
43 | + # Milestone uses :title, Issue uses :name | ||
44 | + OpenStruct.new(id: 0, title: 'Unspecified', name: 'Unassigned') | ||
45 | + end | ||
39 | end | 46 | end |
app/views/issues/index.html.haml
@@ -49,8 +49,8 @@ | @@ -49,8 +49,8 @@ | ||
49 | .right | 49 | .right |
50 | = form_tag project_issues_path(@project), method: :get, class: :right do | 50 | = form_tag project_issues_path(@project), method: :get, class: :right do |
51 | = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), prompt: "Labels") | 51 | = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), prompt: "Labels") |
52 | - = select_tag(:assignee_id, options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee") | ||
53 | - = select_tag(:milestone_id, options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone") | 52 | + = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee") |
53 | + = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone") | ||
54 | = hidden_field_tag :f, params[:f] | 54 | = hidden_field_tag :f, params[:f] |
55 | .clearfix | 55 | .clearfix |
56 | 56 |
spec/requests/issues_spec.rb
@@ -89,4 +89,53 @@ describe "Issues" do | @@ -89,4 +89,53 @@ describe "Issues" do | ||
89 | page.should have_content 'gitlab' | 89 | page.should have_content 'gitlab' |
90 | end | 90 | end |
91 | end | 91 | end |
92 | + | ||
93 | + describe "Filter issue" do | ||
94 | + before do | ||
95 | + ['foobar', 'barbaz', 'gitlab'].each do |title| | ||
96 | + @issue = Factory :issue, | ||
97 | + author: @user, | ||
98 | + assignee: @user, | ||
99 | + project: project, | ||
100 | + title: title | ||
101 | + end | ||
102 | + | ||
103 | + @issue = Issue.first | ||
104 | + @issue.milestone = Factory(:milestone, project: project) | ||
105 | + @issue.assignee = nil | ||
106 | + @issue.save | ||
107 | + end | ||
108 | + | ||
109 | + it "should allow filtering by issues with no specified milestone" do | ||
110 | + visit project_issues_path(project, milestone_id: '0') | ||
111 | + | ||
112 | + page.should_not have_content 'foobar' | ||
113 | + page.should have_content 'barbaz' | ||
114 | + page.should have_content 'gitlab' | ||
115 | + end | ||
116 | + | ||
117 | + it "should allow filtering by a specified milestone" do | ||
118 | + visit project_issues_path(project, milestone_id: @issue.milestone.id) | ||
119 | + | ||
120 | + page.should have_content 'foobar' | ||
121 | + page.should_not have_content 'barbaz' | ||
122 | + page.should_not have_content 'gitlab' | ||
123 | + end | ||
124 | + | ||
125 | + it "should allow filtering by issues with no specified assignee" do | ||
126 | + visit project_issues_path(project, assignee_id: '0') | ||
127 | + | ||
128 | + page.should have_content 'foobar' | ||
129 | + page.should_not have_content 'barbaz' | ||
130 | + page.should_not have_content 'gitlab' | ||
131 | + end | ||
132 | + | ||
133 | + it "should allow filtering by a specified assignee" do | ||
134 | + visit project_issues_path(project, assignee_id: @user.id) | ||
135 | + | ||
136 | + page.should_not have_content 'foobar' | ||
137 | + page.should have_content 'barbaz' | ||
138 | + page.should have_content 'gitlab' | ||
139 | + end | ||
140 | + end | ||
92 | end | 141 | end |