Commit e548c613 authored by Sean McGivern's avatar Sean McGivern

Merge branch '39720-group-milestone-sorting' into 'master'

Add Group Milestone sorting

Closes #39720

See merge request gitlab-org/gitlab-ce!15230
parents 13cfcfc2 a4d71cba
...@@ -80,7 +80,8 @@ class Groups::MilestonesController < Groups::ApplicationController ...@@ -80,7 +80,8 @@ class Groups::MilestonesController < Groups::ApplicationController
milestones = MilestonesFinder.new(search_params).execute milestones = MilestonesFinder.new(search_params).execute
legacy_milestones = GroupMilestone.build_collection(group, group_projects, params) legacy_milestones = GroupMilestone.build_collection(group, group_projects, params)
milestones + legacy_milestones @sort = params[:sort] || 'due_date_asc'
MilestoneArray.sort(milestones + legacy_milestones, @sort)
end end
def milestone def milestone
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
= render 'shared/milestones_filter', counts: @milestone_states = render 'shared/milestones_filter', counts: @milestone_states
.nav-controls .nav-controls
= render 'shared/milestones_sort_dropdown'
- if can?(current_user, :admin_milestones, @group) - if can?(current_user, :admin_milestones, @group)
= link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new" = link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new"
......
---
title: Add dropdown sort to group milestones
merge_request: 15230
author: George Andrinopoulos
type: added
module MilestoneArray
class << self
def sort(array, sort_method)
case sort_method
when 'due_date_asc'
sort_asc_nulls_last(array, 'due_date')
when 'due_date_desc'
sort_desc_nulls_last(array, 'due_date')
when 'start_date_asc'
sort_asc_nulls_last(array, 'start_date')
when 'start_date_desc'
sort_desc_nulls_last(array, 'start_date')
when 'name_asc'
sort_asc(array, 'title')
when 'name_desc'
sort_asc(array, 'title').reverse
else
array
end
end
private
def sort_asc_nulls_last(array, attribute)
attribute = attribute.to_sym
array.select(&attribute).sort_by(&attribute) + array.reject(&attribute)
end
def sort_desc_nulls_last(array, attribute)
attribute = attribute.to_sym
array.select(&attribute).sort_by(&attribute).reverse + array.reject(&attribute)
end
def sort_asc(array, attribute)
array.sort_by(&attribute.to_sym)
end
end
end
require 'spec_helper'
feature 'Milestones sorting', :js do
let(:group) { create(:group) }
let!(:project) { create(:project_empty_repo, group: group) }
let!(:other_project) { create(:project_empty_repo, group: group) }
let!(:project_milestone1) { create(:milestone, project: project, title: 'v1.0', due_date: 10.days.from_now) }
let!(:other_project_milestone1) { create(:milestone, project: other_project, title: 'v1.0', due_date: 10.days.from_now) }
let!(:project_milestone2) { create(:milestone, project: project, title: 'v2.0', due_date: 5.days.from_now) }
let!(:other_project_milestone2) { create(:milestone, project: other_project, title: 'v2.0', due_date: 5.days.from_now) }
let!(:group_milestone) { create(:milestone, group: group, title: 'v3.0', due_date: 7.days.from_now) }
let(:user) { create(:group_member, :master, user: create(:user), group: group ).user }
before do
sign_in(user)
end
scenario 'visit group milestones and sort by due_date_asc' do
visit group_milestones_path(group)
expect(page).to have_button('Due soon')
# assert default sorting
within '.milestones' do
expect(page.all('ul.content-list > li').first.text).to include('v2.0')
expect(page.all('ul.content-list > li')[1].text).to include('v3.0')
expect(page.all('ul.content-list > li').last.text).to include('v1.0')
end
click_button 'Due soon'
sort_options = find('ul.dropdown-menu-sort li').all('a').collect(&:text)
expect(sort_options[0]).to eq('Due soon')
expect(sort_options[1]).to eq('Due later')
expect(sort_options[2]).to eq('Start soon')
expect(sort_options[3]).to eq('Start later')
expect(sort_options[4]).to eq('Name, ascending')
expect(sort_options[5]).to eq('Name, descending')
click_link 'Due later'
expect(page).to have_button('Due later')
within '.milestones' do
expect(page.all('ul.content-list > li').first.text).to include('v1.0')
expect(page.all('ul.content-list > li')[1].text).to include('v3.0')
expect(page.all('ul.content-list > li').last.text).to include('v2.0')
end
end
end
require 'spec_helper'
describe MilestoneArray do
let(:object1) { instance_double("BirdMilestone", due_date: Time.now, start_date: Time.now - 15.days, title: 'v2.0') }
let(:object2) { instance_double("CatMilestone", due_date: Time.now - 1.day, start_date: nil, title: 'v1.0') }
let(:object3) { instance_double("DogMilestone", due_date: nil, start_date: Time.now - 30.days, title: 'v3.0') }
let(:array) { [object1, object3, object2] }
describe '#sort' do
it 'reorders array with due date in ascending order with nulls last' do
expect(described_class.sort(array, 'due_date_asc')).to eq([object2, object1, object3])
end
it 'reorders array with due date in desc order with nulls last' do
expect(described_class.sort(array, 'due_date_desc')).to eq([object1, object2, object3])
end
it 'reorders array with start date in ascending order with nulls last' do
expect(described_class.sort(array, 'start_date_asc')).to eq([object3, object1, object2])
end
it 'reorders array with start date in descending order with nulls last' do
expect(described_class.sort(array, 'start_date_desc')).to eq([object1, object3, object2])
end
it 'reorders array with title in ascending order' do
expect(described_class.sort(array, 'name_asc')).to eq([object2, object1, object3])
end
it 'reorders array with title in descending order' do
expect(described_class.sort(array, 'name_desc')).to eq([object3, object1, object2])
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment