diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index a7958b1e..889a7d98 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -144,10 +144,19 @@ class IssuesController < ApplicationController else @project.issues.opened end - @issues = @issues.where(assignee_id: params[:assignee_id]) if params[:assignee_id].present? - @issues = @issues.where(milestone_id: params[:milestone_id]) if params[:milestone_id].present? @issues = @issues.tagged_with(params[:label_name]) if params[:label_name].present? @issues = @issues.includes(:author, :project).order("updated_at") + + # Filter by specific assignee_id (or lack thereof)? + if params[:assignee_id].present? + @issues = @issues.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id])) + end + + # Filter by specific milestone_id (or lack thereof)? + if params[:milestone_id].present? + @issues = @issues.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) + end + @issues end diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 177ba0c2..d4d6c2d4 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -36,4 +36,11 @@ module IssuesHelper def issue_tags @project.issues.tag_counts_on(:labels).map(&:name) end + + # Returns an OpenStruct object suitable for use by options_from_collection_for_select + # to allow filtering issues by an unassigned User or Milestone + def unassigned_filter + # Milestone uses :title, Issue uses :name + OpenStruct.new(id: 0, title: 'Unspecified', name: 'Unassigned') + end end diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml index f3c743f7..8876d24d 100644 --- a/app/views/issues/index.html.haml +++ b/app/views/issues/index.html.haml @@ -49,8 +49,8 @@ .right = form_tag project_issues_path(@project), method: :get, class: :right do = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), prompt: "Labels") - = select_tag(:assignee_id, options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee") - = select_tag(:milestone_id, options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone") + = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee") + = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone") = hidden_field_tag :f, params[:f] .clearfix diff --git a/spec/requests/issues_spec.rb b/spec/requests/issues_spec.rb index 24c21db8..15ee5d17 100644 --- a/spec/requests/issues_spec.rb +++ b/spec/requests/issues_spec.rb @@ -89,4 +89,53 @@ describe "Issues" do page.should have_content 'gitlab' end end + + describe "Filter issue" do + before do + ['foobar', 'barbaz', 'gitlab'].each do |title| + @issue = Factory :issue, + author: @user, + assignee: @user, + project: project, + title: title + end + + @issue = Issue.first + @issue.milestone = Factory(:milestone, project: project) + @issue.assignee = nil + @issue.save + end + + it "should allow filtering by issues with no specified milestone" do + visit project_issues_path(project, milestone_id: '0') + + page.should_not have_content 'foobar' + page.should have_content 'barbaz' + page.should have_content 'gitlab' + end + + it "should allow filtering by a specified milestone" do + visit project_issues_path(project, milestone_id: @issue.milestone.id) + + page.should have_content 'foobar' + page.should_not have_content 'barbaz' + page.should_not have_content 'gitlab' + end + + it "should allow filtering by issues with no specified assignee" do + visit project_issues_path(project, assignee_id: '0') + + page.should have_content 'foobar' + page.should_not have_content 'barbaz' + page.should_not have_content 'gitlab' + end + + it "should allow filtering by a specified assignee" do + visit project_issues_path(project, assignee_id: @user.id) + + page.should_not have_content 'foobar' + page.should have_content 'barbaz' + page.should have_content 'gitlab' + end + end end