Merge branch '39720-group-milestone-sorting' into 'master'
Add Group Milestone sorting Closes #39720 See merge request gitlab-org/gitlab-ce!15230
This commit is contained in:
commit
e548c61334
|
|
@ -80,7 +80,8 @@ class Groups::MilestonesController < Groups::ApplicationController
|
|||
milestones = MilestonesFinder.new(search_params).execute
|
||||
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
|
||||
|
||||
def milestone
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
= render 'shared/milestones_filter', counts: @milestone_states
|
||||
|
||||
.nav-controls
|
||||
= render 'shared/milestones_sort_dropdown'
|
||||
- if can?(current_user, :admin_milestones, @group)
|
||||
= link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new"
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add dropdown sort to group milestones
|
||||
merge_request: 15230
|
||||
author: George Andrinopoulos
|
||||
type: added
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
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
|
||||
Loading…
Reference in New Issue