diff options
author | Fatih Acet <acetfatih@gmail.com> | 2016-09-24 10:49:45 +0000 |
---|---|---|
committer | Fatih Acet <acetfatih@gmail.com> | 2016-09-24 10:49:45 +0000 |
commit | 513629f3467a740231fa531637f3577c41f8d1bf (patch) | |
tree | 70e92c1b80f2663525dbbc19ab38e994020245a9 | |
parent | d4007fd4a618bad42aa187be9b7a0e9cc22aa006 (diff) | |
parent | 8499de19c9bca4c43378b8a9cf2b6705f9cab647 (diff) | |
download | gitlab-ce-513629f3467a740231fa531637f3577c41f8d1bf.tar.gz |
Merge branch 'gitlab-ce-milestone-tab-badges' into 'master'
Milestone tab badges
### What does this MR do?
Adds count badges to the tabs on the Milestone page to mirror the Issue page.
### Are there points in the code the reviewer needs to double check?
CSS: Padding was added to the `.milestone` element to make expired milestones look good.
### Why was this MR needed?
For consistency with other tabs
### What are the relevant issue numbers?
Closes #20114
### Screenshots (if relevant)
**Before**
<img src="/uploads/1f75853a863a9058ee409916b7ee4057/Screen_Shot_2016-07-22_at_13.22.20.png" width="362">
**After**
<img src="/uploads/8a058290850f571db249dd9b23f5138d/Screen_Shot_2016-07-22_at_13.21.58.png" width="303">


### Does this MR meet the acceptance criteria?
- [x] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG) entry added
- [ ] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
- [ ] API support added
- Tests
- [x] Added for this feature/bug
- [x] All builds are passing
- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if you do - rebase it please)
- [ ] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
See merge request !5946
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/milestone.scss | 27 | ||||
-rw-r--r-- | app/helpers/milestones_helper.rb | 24 | ||||
-rw-r--r-- | app/views/shared/_milestones_filter.html.haml | 15 | ||||
-rw-r--r-- | app/views/shared/milestones/_milestone.html.haml | 2 | ||||
-rw-r--r-- | spec/factories/milestones.rb | 7 | ||||
-rw-r--r-- | spec/helpers/milestones_helper_spec.rb | 33 |
7 files changed, 98 insertions, 11 deletions
diff --git a/CHANGELOG b/CHANGELOG index 3394a6bdf05..1ebed18ebb4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -87,6 +87,7 @@ v 8.12.0 - Fix markdown anchor icon interaction (ClemMakesApps) - Test migration paths from 8.5 until current release !4874 - Replace animateEmoji timeout with eventListener (ClemMakesApps) + - Show badges in Milestone tabs. !5946 (Dan Rowden) - Optimistic locking for Issues and Merge Requests (title and description overriding prevention) - Require confirmation when not logged in for unsubscribe links !6223 (Maximiliano Perez Coto) - Add `wiki_page_events` to project hook APIs (Ben Boeckel) diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss index b94f524b513..6b865730487 100644 --- a/app/assets/stylesheets/pages/milestone.scss +++ b/app/assets/stylesheets/pages/milestone.scss @@ -2,13 +2,17 @@ max-width: 90%; } -li.milestone { - h4 { - font-weight: bold; - } +.milestones { + .milestone { + padding: 10px 16px; + + h4 { + font-weight: bold; + } - .progress { - height: 6px; + .progress { + height: 6px; + } } } @@ -64,3 +68,14 @@ li.milestone { border-bottom: 1px solid $border-color; padding: 20px 0; } + +@media (max-width: $screen-sm-min) { + .milestone-actions { + @include clearfix(); + padding-top: $gl-vert-padding; + + .btn:first-child { + margin-left: 0; + } + } +} diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb index b3e6e468ecd..a11c313a6b8 100644 --- a/app/helpers/milestones_helper.rb +++ b/app/helpers/milestones_helper.rb @@ -35,6 +35,30 @@ module MilestonesHelper milestone.issues.with_label(label.title).send(state).size end + # Returns count of milestones for different states + # Uses explicit hash keys as the 'opened' state URL params differs from the db value + # and we need to add the total + def milestone_counts(milestones) + counts = milestones.reorder(nil).group(:state).count + + { + opened: counts['active'] || 0, + closed: counts['closed'] || 0, + all: counts.values.sum || 0 + } + end + + # Show 'active' class if provided GET param matches check + # `or_blank` allows the function to return 'active' when given an empty param + # Could be refactored to be simpler but that may make it harder to read + def milestone_class_for_state(param, check, match_blank_param = false) + if match_blank_param + 'active' if param.blank? || param == check + else + 'active' if param == check + end + end + def milestone_progress_bar(milestone) options = { class: 'progress-bar progress-bar-success', diff --git a/app/views/shared/_milestones_filter.html.haml b/app/views/shared/_milestones_filter.html.haml index cf16c203f9c..73d288e2236 100644 --- a/app/views/shared/_milestones_filter.html.haml +++ b/app/views/shared/_milestones_filter.html.haml @@ -1,10 +1,19 @@ +- if @project + - counts = milestone_counts(@project.milestones) + %ul.nav-links - %li{class: ("active" if params[:state].blank? || params[:state] == 'opened')} + %li{class: milestone_class_for_state(params[:state], 'opened', true)} = link_to milestones_filter_path(state: 'opened') do Open - %li{class: ("active" if params[:state] == 'closed')} + - if @project + %span.badge #{counts[:opened]} + %li{class: milestone_class_for_state(params[:state], 'closed')} = link_to milestones_filter_path(state: 'closed') do Closed - %li{class: ("active" if params[:state] == 'all')} + - if @project + %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]} diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml index acc3ccf4dcf..3dccfb147bf 100644 --- a/app/views/shared/milestones/_milestone.html.haml +++ b/app/views/shared/milestones/_milestone.html.haml @@ -33,7 +33,7 @@ - if @project .row .col-sm-6= render('shared/milestone_expired', milestone: milestone) - .col-sm-6 + .col-sm-6.milestone-actions - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? = link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-xs btn-grouped" do Edit diff --git a/spec/factories/milestones.rb b/spec/factories/milestones.rb index e9e85962fe4..84da71ed6dc 100644 --- a/spec/factories/milestones.rb +++ b/spec/factories/milestones.rb @@ -3,10 +3,15 @@ FactoryGirl.define do title project + trait :active do + state "active" + end + trait :closed do - state :closed + state "closed" end + factory :active_milestone, traits: [:active] factory :closed_milestone, traits: [:closed] end end diff --git a/spec/helpers/milestones_helper_spec.rb b/spec/helpers/milestones_helper_spec.rb new file mode 100644 index 00000000000..28c2268f8d0 --- /dev/null +++ b/spec/helpers/milestones_helper_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe MilestonesHelper do + describe '#milestone_counts' do + let(:project) { FactoryGirl.create(:project) } + let(:counts) { helper.milestone_counts(project.milestones) } + + context 'when there are milestones' do + let!(:milestone_1) { FactoryGirl.create(:active_milestone, project: project) } + let!(:milestone_2) { FactoryGirl.create(:active_milestone, project: project) } + let!(:milestone_3) { FactoryGirl.create(:closed_milestone, project: project) } + + it 'returns the correct counts' do + expect(counts).to eq(opened: 2, closed: 1, all: 3) + end + end + + context 'when there are only milestones of one type' do + let!(:milestone_1) { FactoryGirl.create(:active_milestone, project: project) } + let!(:milestone_2) { FactoryGirl.create(:active_milestone, project: project) } + + it 'returns the correct counts' do + expect(counts).to eq(opened: 2, closed: 0, all: 2) + end + end + + context 'when there are no milestones' do + it 'returns the correct counts' do + expect(counts).to eq(opened: 0, closed: 0, all: 0) + end + end + end +end |