Merge branch 'adam-count-badges-group-dashboard-milestones' into 'master'

Add count badges to both dashboard and group milestones

Closes #24421

See merge request !9836
This commit is contained in:
Sean McGivern 2017-03-14 08:33:13 +00:00
commit 1957dde410
9 changed files with 105 additions and 20 deletions

View file

@ -5,6 +5,7 @@ class Dashboard::MilestonesController < Dashboard::ApplicationController
def index
respond_to do |format|
format.html do
@milestone_states = GlobalMilestone.states_count(@projects)
@milestones = Kaminari.paginate_array(milestones).page(params[:page])
end
format.json do

View file

@ -6,6 +6,7 @@ class Groups::MilestonesController < Groups::ApplicationController
def index
respond_to do |format|
format.html do
@milestone_states = GlobalMilestone.states_count(@projects)
@milestones = Kaminari.paginate_array(milestones).page(params[:page])
end
end

View file

@ -28,6 +28,28 @@ class GlobalMilestone
new(title, child_milestones)
end
def self.states_count(projects)
relation = MilestonesFinder.new.execute(projects, state: 'all')
milestones_by_state_and_title = relation.reorder(nil).group(:state, :title).count
opened = count_by_state(milestones_by_state_and_title, 'active')
closed = count_by_state(milestones_by_state_and_title, 'closed')
all = milestones_by_state_and_title.map { |(_, title), _| title }.uniq.count
{
opened: opened,
closed: closed,
all: all
}
end
def self.count_by_state(milestones_by_state_and_title, state)
milestones_by_state_and_title.count do |(milestone_state, _), _|
milestone_state == state
end
end
private_class_method :count_by_state
def initialize(title, milestones)
@title = title
@name = title

View file

@ -1,11 +1,11 @@
- page_title "Milestones"
- header_title "Milestones", dashboard_milestones_path
- page_title 'Milestones'
- header_title 'Milestones', dashboard_milestones_path
.top-area
= render 'shared/milestones_filter'
= render 'shared/milestones_filter', counts: @milestone_states
.nav-controls
= render 'shared/new_project_item_select', path: 'milestones/new', label: "New Milestone", include_groups: true
= render 'shared/new_project_item_select', path: 'milestones/new', label: 'New Milestone', include_groups: true
.milestones
%ul.content-list
@ -15,4 +15,4 @@
- else
- @milestones.each do |milestone|
= render 'milestone', milestone: milestone
= paginate @milestones, theme: "gitlab"
= paginate @milestones, theme: 'gitlab'

View file

@ -2,7 +2,7 @@
= render "groups/head_issues"
.top-area
= render 'shared/milestones_filter'
= render 'shared/milestones_filter', counts: @milestone_states
.nav-controls
- if can?(current_user, :admin_milestones, @group)

View file

@ -1,14 +1,14 @@
- @no_container = true
- page_title "Milestones"
= render "projects/issues/head"
- page_title 'Milestones'
= render 'projects/issues/head'
%div{ class: container_class }
.top-area
= render 'shared/milestones_filter'
= render 'shared/milestones_filter', counts: milestone_counts(@project.milestones)
.nav-controls
- if can?(current_user, :admin_milestone, @project)
= link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "btn btn-new", title: "New Milestone" do
= link_to new_namespace_project_milestone_path(@project.namespace, @project), class: 'btn btn-new', title: 'New Milestone' do
New Milestone
.milestones
@ -19,4 +19,4 @@
%li
.nothing-here-block No milestones to show
= paginate @milestones, theme: "gitlab"
= paginate @milestones, theme: 'gitlab'

View file

@ -1,19 +1,13 @@
- if @project
- counts = milestone_counts(@project.milestones)
%ul.nav-links
%li{ class: milestone_class_for_state(params[:state], 'opened', true) }>
= link_to milestones_filter_path(state: 'opened') do
Open
- if @project
%span.badge= counts[:opened]
%span.badge= counts[:opened]
%li{ class: milestone_class_for_state(params[:state], 'closed') }>
= link_to milestones_filter_path(state: 'closed') do
Closed
- if @project
%span.badge= counts[:closed]
%span.badge= counts[:closed]
%li{ class: milestone_class_for_state(params[:state], 'all') }>
= link_to milestones_filter_path(state: 'all') do
All
- if @project
%span.badge= counts[:all]
%span.badge= counts[:all]

View file

@ -0,0 +1,4 @@
---
title: Add dashboard and group milestones count badges
merge_request: 9836
author: Alex Braha Stoll

View file

@ -92,6 +92,41 @@ describe GlobalMilestone, models: true do
end
end
describe '.states_count' do
context 'when the projects have milestones' do
before do
create(:closed_milestone, title: 'Active Group Milestone', project: project3)
create(:active_milestone, title: 'Active Group Milestone', project: project1)
create(:active_milestone, title: 'Active Group Milestone', project: project2)
create(:closed_milestone, title: 'Closed Group Milestone', project: project1)
create(:closed_milestone, title: 'Closed Group Milestone', project: project2)
create(:closed_milestone, title: 'Closed Group Milestone', project: project3)
end
it 'returns the quantity of global milestones in each possible state' do
expected_count = { opened: 1, closed: 2, all: 2 }
count = GlobalMilestone.states_count(Project.all)
expect(count).to eq(expected_count)
end
end
context 'when the projects do not have milestones' do
before do
project1
end
it 'returns 0 as the quantity of global milestones in each state' do
expected_count = { opened: 0, closed: 0, all: 0 }
count = GlobalMilestone.states_count(Project.all)
expect(count).to eq(expected_count)
end
end
end
describe '#initialize' do
let(:milestone1_project1) { create(:milestone, title: "Milestone v1.2", project: project1) }
let(:milestone1_project2) { create(:milestone, title: "Milestone v1.2", project: project2) }
@ -127,4 +162,32 @@ describe GlobalMilestone, models: true do
expect(global_milestone.safe_title).to eq('git-test')
end
end
describe '#state' do
context 'when at least one milestone is active' do
it 'returns active' do
title = 'Active Group Milestone'
milestones = [
create(:active_milestone, title: title),
create(:closed_milestone, title: title)
]
global_milestone = GlobalMilestone.new(title, milestones)
expect(global_milestone.state).to eq('active')
end
end
context 'when all milestones are closed' do
it 'returns closed' do
title = 'Closed Group Milestone'
milestones = [
create(:closed_milestone, title: title),
create(:closed_milestone, title: title)
]
global_milestone = GlobalMilestone.new(title, milestones)
expect(global_milestone.state).to eq('closed')
end
end
end
end