Commit f7fefe82 authored by Jacob Schatz's avatar Jacob Schatz

Merge branch '23674-simplify-milestone-summary' into 'master'

Resolve "Simplify milestone summary"

Closes #23674

See merge request !10096
parents 3e1fb2a5 48a30a7a
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
/* global ProjectShow */ /* global ProjectShow */
/* global Labels */ /* global Labels */
/* global Shortcuts */ /* global Shortcuts */
/* global Sidebar */
import Issue from './issue'; import Issue from './issue';
import BindInOut from './behaviors/bind_in_out'; import BindInOut from './behaviors/bind_in_out';
...@@ -118,6 +120,7 @@ const ShortcutsBlob = require('./shortcuts_blob'); ...@@ -118,6 +120,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'groups:milestones:show': case 'groups:milestones:show':
case 'dashboard:milestones:show': case 'dashboard:milestones:show':
new Milestone(); new Milestone();
new Sidebar();
break; break;
case 'dashboard:todos:index': case 'dashboard:todos:index':
new gl.Todos(); new gl.Todos();
......
...@@ -52,66 +52,62 @@ ...@@ -52,66 +52,62 @@
} }
} }
.milestone-summary { .milestone-sidebar {
.milestone-stat { .gutter-toggle {
white-space: nowrap; margin-bottom: 10px;
margin-right: 10px; }
&.with-drilldown { .milestone-progress {
margin-right: 2px; .title {
padding-top: 5px;
} }
}
.remaining-days { .progress {
color: $orange-600; height: 6px;
margin: 0;
}
} }
.milestone-stats-and-buttons { .collapsed-milestone-date {
display: flex; font-size: 12px;
justify-content: flex-start; }
flex-wrap: wrap;
@media (min-width: $screen-xs-min) { .milestone-date {
justify-content: space-between; display: block;
flex-wrap: nowrap;
}
} }
.milestone-progress-buttons { .date-separator {
order: 1; line-height: 5px;
margin-top: 10px; }
@media (min-width: $screen-xs-min) { .remaining-days strong {
order: 2; font-weight: normal;
margin-top: 0; }
flex-shrink: 0;
}
.btn { .milestone-stat {
float: left; float: left;
margin-right: $btn-side-margin; margin-right: 14px;
}
&:last-child { .milestone-stat:last-child {
margin-right: 0; margin-right: 0;
}
}
} }
.milestone-stats { .milestone-progress {
order: 2; .sidebar-collapsed-icon {
width: 100%; clear: both;
padding: 7px 0; padding: 15px 5px 5px;
flex-shrink: 1;
@media (min-width: $screen-xs-min) { .progress {
// when displayed on one line stats go first, buttons second margin: 5px 0;
order: 1; }
} }
} }
.progress { .right-sidebar-collapsed & {
width: 100%; .reference {
margin: 15px 0; border-top: 1px solid $border-gray-normal;
}
} }
} }
......
...@@ -19,8 +19,8 @@ module MilestonesHelper ...@@ -19,8 +19,8 @@ module MilestonesHelper
end end
end end
def milestones_browse_issuables_path(milestone, type:) def milestones_browse_issuables_path(milestone, state: nil, type:)
opts = { milestone_title: milestone.title } opts = { milestone_title: milestone.title, state: state }
if @project if @project
polymorphic_path([@project.namespace.becomes(Namespace), @project, type], opts) polymorphic_path([@project.namespace.becomes(Namespace), @project, type], opts)
......
...@@ -6,7 +6,8 @@ module NavHelper ...@@ -6,7 +6,8 @@ module NavHelper
current_path?('merge_requests#builds') || current_path?('merge_requests#builds') ||
current_path?('merge_requests#conflicts') || current_path?('merge_requests#conflicts') ||
current_path?('merge_requests#pipelines') || current_path?('merge_requests#pipelines') ||
current_path?('issues#show') current_path?('issues#show') ||
current_path?('milestones#show')
if cookies[:collapsed_gutter] == 'true' if cookies[:collapsed_gutter] == 'true'
"page-gutter right-sidebar-collapsed" "page-gutter right-sidebar-collapsed"
else else
......
- header_title "Milestones", dashboard_milestones_path - header_title "Milestones", dashboard_milestones_path
= render 'shared/milestones/top', milestone: @milestone = render 'shared/milestones/top', milestone: @milestone
= render 'shared/milestones/summary', milestone: @milestone
= render 'shared/milestones/tabs', milestone: @milestone, show_full_project_name: true = render 'shared/milestones/tabs', milestone: @milestone, show_full_project_name: true
= render 'shared/milestones/sidebar', milestone: @milestone, affix_offset: 51
...@@ -4,5 +4,5 @@ ...@@ -4,5 +4,5 @@
= page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test? = page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test?
= render 'shared/milestones/top', milestone: @milestone, group: @group = render 'shared/milestones/top', milestone: @milestone, group: @group
= render 'shared/milestones/summary', milestone: @milestone
= render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true = render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true
= render 'shared/milestones/sidebar', milestone: @milestone, affix_offset: 102
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
= link_to namespace_project_milestone_path(@project.namespace, @project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-danger" do = link_to namespace_project_milestone_path(@project.namespace, @project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-danger" do
Delete Delete
%a.btn.btn-default.btn-grouped.pull-right.visible-xs-block.js-sidebar-toggle{ href: "#" }
= icon('angle-double-left')
.detail-page-description.milestone-detail{ class: ('hide-bottom-border' unless @milestone.description.present? ) } .detail-page-description.milestone-detail{ class: ('hide-bottom-border' unless @milestone.description.present? ) }
%h2.title %h2.title
= markdown_field(@milestone, :title) = markdown_field(@milestone, :title)
...@@ -53,5 +56,5 @@ ...@@ -53,5 +56,5 @@
.alert.alert-success.prepend-top-default .alert.alert-success.prepend-top-default
%span All issues for this milestone are closed. You may close this milestone now. %span All issues for this milestone are closed. You may close this milestone now.
= render 'shared/milestones/summary', milestone: @milestone, project: @project
= render 'shared/milestones/tabs', milestone: @milestone = render 'shared/milestones/tabs', milestone: @milestone
= render 'shared/milestones/sidebar', milestone: @milestone, project: @project, affix_offset: 153
- affix_offset = local_assigns.fetch(:affix_offset, "102")
- project = local_assigns[:project]
%aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => affix_offset, "spy" => "affix" }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
.issuable-sidebar.milestone-sidebar
.block.milestone-progress.issuable-sidebar-header
%a.gutter-toggle.pull-right.js-sidebar-toggle{ role: "button", href: "#", "aria-label" => "Toggle sidebar" }
= sidebar_gutter_toggle_icon
.sidebar-collapsed-icon
%span== #{milestone.percent_complete(current_user)}%
= milestone_progress_bar(milestone)
.title.hide-collapsed
%strong.bold== #{milestone.percent_complete(current_user)}%
%span.hide-collapsed
complete
.value.hide-collapsed
= milestone_progress_bar(milestone)
.block.start_date.hide-collapsed
.title
Start date
- if @project && can?(current_user, :admin_milestone, @project)
= link_to 'Edit', edit_namespace_project_milestone_path(@project.namespace, @project, @milestone), class: 'edit-link pull-right'
.value
%span.value-content
- if milestone.start_date
%span.bold= milestone.start_date.to_s(:medium)
- else
%span.no-value No start date
.block.due_date
.sidebar-collapsed-icon
= icon('calendar', 'aria-hidden': 'true')
%span.collapsed-milestone-date
- if milestone.start_date && milestone.due_date
- if milestone.start_date.year == milestone.due_date.year
.milestone-date= milestone.start_date.strftime('%b %-d')
- else
.milestone-date= milestone.start_date.strftime('%b %-d %Y')
.date-separator -
.due_date= milestone.due_date.strftime('%b %-d %Y')
- elsif milestone.start_date
From
.milestone-date= milestone.start_date.strftime('%b %-d %Y')
- elsif milestone.due_date
Until
.milestone-date= milestone.due_date.strftime('%b %-d %Y')
- else
None
.title.hide-collapsed
Due date
- if @project && can?(current_user, :admin_milestone, @project)
= link_to 'Edit', edit_namespace_project_milestone_path(@project.namespace, @project, @milestone), class: 'edit-link pull-right'
.value.hide-collapsed
%span.value-content
- if milestone.due_date
%span.bold= milestone.due_date.to_s(:medium)
- else
%span.no-value No due date
- remaining_days = milestone_remaining_days(milestone)
- if remaining_days.present?
= surround '(', ')' do
%span.remaining-days= remaining_days
- if !project || can?(current_user, :read_issue, project)
.block
.sidebar-collapsed-icon
%strong
= icon('hashtag', 'aria-hidden': 'true')
%span= milestone.issues_visible_to_user(current_user).count
.title.hide-collapsed
Issues
%span.badge= milestone.issues_visible_to_user(current_user).count
- if project && can?(current_user, :create_issue, project)
= link_to new_namespace_project_issue_path(project.namespace, project, issue: { milestone_id: milestone.id }), class: "pull-right", title: "New Issue" do
New issue
.value.hide-collapsed.bold
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :issues) do
Open:
= milestone.issues_visible_to_user(current_user).opened.count
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :issues, state: 'closed') do
Closed:
= milestone.issues_visible_to_user(current_user).closed.count
.block
.sidebar-collapsed-icon
%strong
= icon('exclamation', 'aria-hidden': 'true')
%span= milestone.issues_visible_to_user(current_user).count
.title.hide-collapsed
Merge requests
%span.badge= milestone.merge_requests.count
.value.hide-collapsed.bold
- if !project || can?(current_user, :read_merge_request, project)
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :merge_requests) do
Open:
= milestone.merge_requests.opened.count
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'closed') do
Closed:
= milestone.merge_requests.closed.count
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'merged') do
Merged:
= milestone.merge_requests.merged.count
- else
%span.milestone-stat
Open:
= milestone.merge_requests.opened.count
%span.milestone-stat
Closed:
= milestone.merge_requests.closed.count
%span.milestone-stat
Merged:
= milestone.merge_requests.merged.count
- milestone_ref = milestone.try(:to_reference, full: true)
- if milestone_ref.present?
.block.reference
.sidebar-collapsed-icon.dont-change-state
= clipboard_button(clipboard_text: milestone_ref, title: "Copy reference to clipboard", placement: "left")
.cross-project-reference.hide-collapsed
%span
Reference:
%cite{ title: milestone_ref }
= milestone_ref
= clipboard_button(clipboard_text: milestone_ref, title: "Copy reference to clipboard", placement: "left")
- project = local_assigns[:project]
.context.prepend-top-default
.milestone-summary
%h4 Progress
.milestone-stats-and-buttons
.milestone-stats
- if !project || can?(current_user, :read_issue, project)
%span.milestone-stat.with-drilldown
%strong= milestone.issues_visible_to_user(current_user).size
issues:
%span.milestone-stat
%strong= milestone.issues_visible_to_user(current_user).opened.size
open and
%strong= milestone.issues_visible_to_user(current_user).closed.size
closed
%span.milestone-stat.with-drilldown
%strong= milestone.merge_requests.size
merge requests:
%span.milestone-stat
%strong= milestone.merge_requests.opened.size
open and
%strong= milestone.merge_requests.merged.size
merged
%span.milestone-stat
%strong== #{milestone.percent_complete(current_user)}%
complete
- remaining_days = milestone_remaining_days(milestone)
- if remaining_days.present?
%span.milestone-stat
%span.remaining-days= remaining_days
.milestone-progress-buttons
%span.tab-issues-buttons
- if project
- if can?(current_user, :create_issue, project)
= link_to new_namespace_project_issue_path(project.namespace, project, issue: { milestone_id: milestone.id }), class: "btn", title: "New Issue" do
New Issue
- if can?(current_user, :read_issue, project)
= link_to 'Browse Issues', milestones_browse_issuables_path(milestone, type: :issues), class: "btn"
%span.tab-merge-requests-buttons.hidden
= link_to 'Browse Merge Requests', milestones_browse_issuables_path(milestone, type: :merge_requests), class: "btn"
= milestone_progress_bar(milestone)
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
- group = local_assigns[:group] - group = local_assigns[:group]
.detail-page-header .detail-page-header
%a.btn.btn-default.btn-grouped.pull-right.visible-xs-block.js-sidebar-toggle{ href: "#" }
= icon('angle-double-left')
.status-box{ class: "status-box-#{milestone.closed? ? 'closed' : 'open'}" } .status-box{ class: "status-box-#{milestone.closed? ? 'closed' : 'open'}" }
- if milestone.closed? - if milestone.closed?
Closed Closed
......
---
title: Move milestone summary content into the sidebar
merge_request: 10096
author:
...@@ -36,7 +36,7 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps ...@@ -36,7 +36,7 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps
step 'I should see group milestone with all issues and MRs assigned to that milestone' do step 'I should see group milestone with all issues and MRs assigned to that milestone' do
expect(page).to have_content('Milestone GL-113') expect(page).to have_content('Milestone GL-113')
expect(page).to have_content('3 issues: 3 open and 0 closed') expect(page).to have_content('Issues 3 Open: 3 Closed: 0')
issue = Milestone.find_by(name: 'GL-113').issues.first issue = Milestone.find_by(name: 'GL-113').issues.first
expect(page).to have_link(issue.title, href: namespace_project_issue_path(issue.project.namespace, issue.project, issue)) expect(page).to have_link(issue.title, href: namespace_project_issue_path(issue.project.namespace, issue.project, issue))
end end
......
...@@ -23,12 +23,14 @@ feature 'Project milestone', :feature do ...@@ -23,12 +23,14 @@ feature 'Project milestone', :feature do
end end
it 'shows issues stats' do it 'shows issues stats' do
expect(page).to have_content 'issues:' expect(find('.milestone-sidebar')).to have_content 'Issues 0'
end end
it 'shows Browse Issues button' do it 'shows link to browse and add issues' do
within('#content-body') do within('.milestone-sidebar') do
expect(page).to have_link 'Browse Issues' expect(page).to have_link 'New issue'
expect(page).to have_link 'Open: 0'
expect(page).to have_link 'Closed: 0'
end end
end end
end end
...@@ -48,12 +50,12 @@ feature 'Project milestone', :feature do ...@@ -48,12 +50,12 @@ feature 'Project milestone', :feature do
end end
it 'hides issues stats' do it 'hides issues stats' do
expect(page).to have_no_content 'issues:' expect(find('.milestone-sidebar')).not_to have_content 'Issues 0'
end end
it 'hides Browse Issues button' do it 'hides new issue button' do
within('#content-body') do within('.milestone-sidebar') do
expect(page).not_to have_link 'Browse Issues' expect(page).not_to have_link 'New issue'
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