Commit 1957dde4 authored by Sean McGivern's avatar Sean McGivern

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
parents b0905366 50a8f16e
...@@ -5,6 +5,7 @@ class Dashboard::MilestonesController < Dashboard::ApplicationController ...@@ -5,6 +5,7 @@ class Dashboard::MilestonesController < Dashboard::ApplicationController
def index def index
respond_to do |format| respond_to do |format|
format.html do format.html do
@milestone_states = GlobalMilestone.states_count(@projects)
@milestones = Kaminari.paginate_array(milestones).page(params[:page]) @milestones = Kaminari.paginate_array(milestones).page(params[:page])
end end
format.json do format.json do
......
...@@ -6,6 +6,7 @@ class Groups::MilestonesController < Groups::ApplicationController ...@@ -6,6 +6,7 @@ class Groups::MilestonesController < Groups::ApplicationController
def index def index
respond_to do |format| respond_to do |format|
format.html do format.html do
@milestone_states = GlobalMilestone.states_count(@projects)
@milestones = Kaminari.paginate_array(milestones).page(params[:page]) @milestones = Kaminari.paginate_array(milestones).page(params[:page])
end end
end end
......
...@@ -28,6 +28,28 @@ class GlobalMilestone ...@@ -28,6 +28,28 @@ class GlobalMilestone
new(title, child_milestones) new(title, child_milestones)
end 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) def initialize(title, milestones)
@title = title @title = title
@name = title @name = title
......
- page_title "Milestones" - page_title 'Milestones'
- header_title "Milestones", dashboard_milestones_path - header_title 'Milestones', dashboard_milestones_path
.top-area .top-area
= render 'shared/milestones_filter' = render 'shared/milestones_filter', counts: @milestone_states
.nav-controls .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 .milestones
%ul.content-list %ul.content-list
...@@ -15,4 +15,4 @@ ...@@ -15,4 +15,4 @@
- else - else
- @milestones.each do |milestone| - @milestones.each do |milestone|
= render 'milestone', milestone: milestone = render 'milestone', milestone: milestone
= paginate @milestones, theme: "gitlab" = paginate @milestones, theme: 'gitlab'
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
= render "groups/head_issues" = render "groups/head_issues"
.top-area .top-area
= render 'shared/milestones_filter' = render 'shared/milestones_filter', counts: @milestone_states
.nav-controls .nav-controls
- if can?(current_user, :admin_milestones, @group) - if can?(current_user, :admin_milestones, @group)
......
- @no_container = true - @no_container = true
- page_title "Milestones" - page_title 'Milestones'
= render "projects/issues/head" = render 'projects/issues/head'
%div{ class: container_class } %div{ class: container_class }
.top-area .top-area
= render 'shared/milestones_filter' = render 'shared/milestones_filter', counts: milestone_counts(@project.milestones)
.nav-controls .nav-controls
- if can?(current_user, :admin_milestone, @project) - 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 New Milestone
.milestones .milestones
...@@ -19,4 +19,4 @@ ...@@ -19,4 +19,4 @@
%li %li
.nothing-here-block No milestones to show .nothing-here-block No milestones to show
= paginate @milestones, theme: "gitlab" = paginate @milestones, theme: 'gitlab'
- if @project
- counts = milestone_counts(@project.milestones)
%ul.nav-links %ul.nav-links
%li{ class: milestone_class_for_state(params[:state], 'opened', true) }> %li{ class: milestone_class_for_state(params[:state], 'opened', true) }>
= link_to milestones_filter_path(state: 'opened') do = link_to milestones_filter_path(state: 'opened') do
Open Open
- if @project
%span.badge= counts[:opened] %span.badge= counts[:opened]
%li{ class: milestone_class_for_state(params[:state], 'closed') }> %li{ class: milestone_class_for_state(params[:state], 'closed') }>
= link_to milestones_filter_path(state: 'closed') do = link_to milestones_filter_path(state: 'closed') do
Closed Closed
- if @project
%span.badge= counts[:closed] %span.badge= counts[:closed]
%li{ class: milestone_class_for_state(params[:state], 'all') }> %li{ class: milestone_class_for_state(params[:state], 'all') }>
= link_to milestones_filter_path(state: 'all') do = link_to milestones_filter_path(state: 'all') do
All All
- if @project
%span.badge= counts[:all] %span.badge= counts[:all]
---
title: Add dashboard and group milestones count badges
merge_request: 9836
author: Alex Braha Stoll
...@@ -92,6 +92,41 @@ describe GlobalMilestone, models: true do ...@@ -92,6 +92,41 @@ describe GlobalMilestone, models: true do
end end
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 describe '#initialize' do
let(:milestone1_project1) { create(:milestone, title: "Milestone v1.2", project: project1) } let(:milestone1_project1) { create(:milestone, title: "Milestone v1.2", project: project1) }
let(:milestone1_project2) { create(:milestone, title: "Milestone v1.2", project: project2) } let(:milestone1_project2) { create(:milestone, title: "Milestone v1.2", project: project2) }
...@@ -127,4 +162,32 @@ describe GlobalMilestone, models: true do ...@@ -127,4 +162,32 @@ describe GlobalMilestone, models: true do
expect(global_milestone.safe_title).to eq('git-test') expect(global_milestone.safe_title).to eq('git-test')
end end
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 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