diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2013-11-23 12:10:58 -0800 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2013-11-23 12:10:58 -0800 |
commit | 4a1dc7326479d8fe54f888f5622c0d2a56bca8ad (patch) | |
tree | aed06ad1307b7698a08fc209f4e4e0af13e90c62 | |
parent | abc5edab55ca46657e4ccea552838b9b8d96757f (diff) | |
parent | b76948e6c92ce445249116ef86dbbd4d0b57573a (diff) | |
download | gitlab-ce-4a1dc7326479d8fe54f888f5622c0d2a56bca8ad.tar.gz |
Merge pull request #5661 from jasonblanchard/sorting-project-issues
Added sorting to project issues page
-rw-r--r-- | CHANGELOG | 3 | ||||
-rw-r--r-- | app/contexts/issues/list_context.rb | 18 | ||||
-rw-r--r-- | app/controllers/projects/issues_controller.rb | 3 | ||||
-rw-r--r-- | app/helpers/projects_helper.rb | 2 | ||||
-rw-r--r-- | app/views/projects/issues/_issues.html.haml | 20 | ||||
-rw-r--r-- | spec/contexts/issues/list_context_spec.rb | 77 | ||||
-rw-r--r-- | spec/features/issues_spec.rb | 83 |
7 files changed, 206 insertions, 0 deletions
diff --git a/CHANGELOG b/CHANGELOG index 30710fcebf2..592db6ea714 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +v 6.4.0 + - Added sorting to project issues page + v 6.3.0 - API for adding gitlab-ci service - Init script now waits for pids to appear after (re)starting before reporting status (Rovanion Luckey) diff --git a/app/contexts/issues/list_context.rb b/app/contexts/issues/list_context.rb index da2eed0e259..fd27356d1cd 100644 --- a/app/contexts/issues/list_context.rb +++ b/app/contexts/issues/list_context.rb @@ -29,8 +29,26 @@ module Issues if params[:milestone_id].present? @issues = @issues.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) end + + # Sort by :sort param + @issues = sort(@issues, params[:sort]) @issues end + + private + + def sort(issues, condition) + case condition + when 'newest' then issues.except(:order).order('created_at DESC') + when 'oldest' then issues.except(:order).order('created_at ASC') + when 'recently_updated' then issues.except(:order).order('updated_at DESC') + when 'last_updated' then issues.except(:order).order('updated_at ASC') + when 'milestone_due_soon' then issues.except(:order).joins(:milestone).order("milestones.due_date ASC") + when 'milestone_due_later' then issues.except(:order).joins(:milestone).order("milestones.due_date DESC") + else issues + end + end + end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index e8f845b2d17..e03d54cddc1 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -23,6 +23,9 @@ class Projects::IssuesController < Projects::ApplicationController assignee_id, milestone_id = params[:assignee_id], params[:milestone_id] @assignee = @project.team.find(assignee_id) if assignee_id.present? && !assignee_id.to_i.zero? @milestone = @project.milestones.find(milestone_id) if milestone_id.present? && !milestone_id.to_i.zero? + sort_param = params[:sort] || 'newest' + @sort = sort_param.humanize unless sort_param.empty? + respond_to do |format| format.html # index.html.erb diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index ee0e6816742..6b6903c0b2c 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -70,6 +70,8 @@ module ProjectsHelper scope: params[:scope], label_name: params[:label_name], milestone_id: params[:milestone_id], + assignee_id: params[:assignee_id], + sort: params[:sort], } options = exist_opts.merge(options) diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml index 427d6533134..0022f82a399 100644 --- a/app/views/projects/issues/_issues.html.haml +++ b/app/views/projects/issues/_issues.html.haml @@ -78,6 +78,26 @@ %strong= milestone.title %small.light= milestone.expires_at + .dropdown.inline.prepend-left-10 + %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"} + %span.light sort: + = @sort + %b.caret + %ul.dropdown-menu + %li + = link_to project_filter_path(sort: 'newest') do + Newest + = link_to project_filter_path(sort: 'oldest') do + Oldest + = link_to project_filter_path(sort: 'recently_updated') do + Recently updated + = link_to project_filter_path(sort: 'last_updated') do + Last updated + = link_to project_filter_path(sort: 'milestone_due_soon') do + Milestone due soon + = link_to project_filter_path(sort: 'milestone_due_later') do + Milestone due later + %ul.well-list.issues-list = render @issues diff --git a/spec/contexts/issues/list_context_spec.rb b/spec/contexts/issues/list_context_spec.rb new file mode 100644 index 00000000000..63f2f3859fa --- /dev/null +++ b/spec/contexts/issues/list_context_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper' + +describe Issues::ListContext do + + let(:user) { create(:user) } + let(:project) { create(:project, creator: user) } + + titles = ['foo','bar','baz'] + titles.each_with_index do |title, index| + let!(title.to_sym) { create(:issue, title: title, project: project, created_at: Time.now - (index * 60)) } + end + + describe 'sorting' do + + it 'sorts by newest' do + params = {:sort => 'newest'} + + issues = Issues::ListContext.new(project, user, params).execute + issues.first.should eq foo + end + + it 'sorts by oldest' do + params = {:sort => 'oldest'} + + issues = Issues::ListContext.new(project, user, params).execute + issues.first.should eq baz + end + + it 'sorts by recently updated' do + params = {:sort => 'recently_updated'} + baz.updated_at = Time.now + 10 + baz.save + + issues = Issues::ListContext.new(project, user, params).execute + issues.first.should eq baz + end + + it 'sorts by least recently updated' do + params = {:sort => 'last_updated'} + bar.updated_at = Time.now - 10 + bar.save + + issues = Issues::ListContext.new(project, user, params).execute + issues.first.should eq bar + end + + describe 'sorting by milestone' do + + let(:newer_due_milestone) { create(:milestone, :due_date => '2013-12-11') } + let(:later_due_milestone) { create(:milestone, :due_date => '2013-12-12') } + + before :each do + foo.milestone = newer_due_milestone + foo.save + bar.milestone = later_due_milestone + bar.save + end + + it 'sorts by most recently due milestone' do + params = {:sort => 'milestone_due_soon'} + + issues = Issues::ListContext.new(project, user, params).execute + issues.first.should eq foo + + end + + it 'sorts by least recently due milestone' do + params = {:sort => 'milestone_due_later'} + + issues = Issues::ListContext.new(project, user, params).execute + issues.first.should eq bar + end + + end + end + +end diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 8cb984946b4..5b1a14a1ca2 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -95,4 +95,87 @@ describe "Issues" do page.should have_content 'gitlab' end end + + describe 'filter issue' do + titles = ['foo','bar','baz'] + titles.each_with_index do |title, index| + let!(title.to_sym) { create(:issue, title: title, project: project, created_at: Time.now - (index * 60)) } + end + let(:newer_due_milestone) { create(:milestone, :due_date => '2013-12-11') } + let(:later_due_milestone) { create(:milestone, :due_date => '2013-12-12') } + + it 'sorts by newest' do + visit project_issues_path(project, sort: 'newest') + + page.should have_selector("ul.issues-list li:first-child", :text => 'foo') + page.should have_selector("ul.issues-list li:last-child", :text => 'baz') + end + + it 'sorts by oldest' do + visit project_issues_path(project, sort: 'oldest') + + page.should have_selector("ul.issues-list li:first-child", :text => 'baz') + page.should have_selector("ul.issues-list li:last-child", :text => 'foo') + end + + it 'sorts by most recently updated' do + baz.updated_at = Time.now + 100 + baz.save + visit project_issues_path(project, sort: 'recently_updated') + + page.should have_selector("ul.issues-list li:first-child", :text => 'baz') + end + + it 'sorts by least recently updated' do + baz.updated_at = Time.now - 100 + baz.save + visit project_issues_path(project, sort: 'last_updated') + + page.should have_selector("ul.issues-list li:first-child", :text => 'baz') + end + + describe 'sorting by milestone' do + + before :each do + foo.milestone = newer_due_milestone + foo.save + bar.milestone = later_due_milestone + bar.save + end + + it 'sorts by recently due milestone' do + visit project_issues_path(project, sort: 'milestone_due_soon') + + page.should have_selector("ul.issues-list li:first-child", :text => 'foo') + end + + it 'sorts by least recently due milestone' do + visit project_issues_path(project, sort: 'milestone_due_later') + + page.should have_selector("ul.issues-list li:first-child", :text => 'bar') + end + end + + describe 'combine filter and sort' do + + let(:user2) { create(:user) } + + before :each do + foo.assignee = user2 + foo.save + bar.assignee = user2 + bar.save + end + + it 'sorts with a filter applied' do + visit project_issues_path(project, sort: 'oldest', assignee_id: user2.id) + + page.should have_selector("ul.issues-list li:first-child", :text => 'bar') + page.should have_selector("ul.issues-list li:last-child", :text => 'foo') + page.should_not have_content 'baz' + + end + end + end + end |