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

Resolve "Simplify milestone summary"

Closes #23674

See merge request !10096
This commit is contained in:
Jacob Schatz 2017-03-29 21:53:10 +00:00
commit f7fefe82e5
13 changed files with 207 additions and 109 deletions

View file

@ -33,6 +33,8 @@
/* global ProjectShow */
/* global Labels */
/* global Shortcuts */
/* global Sidebar */
import Issue from './issue';
import BindInOut from './behaviors/bind_in_out';
@ -118,6 +120,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'groups:milestones:show':
case 'dashboard:milestones:show':
new Milestone();
new Sidebar();
break;
case 'dashboard:todos:index':
new gl.Todos();

View file

@ -52,67 +52,63 @@
}
}
.milestone-summary {
.milestone-sidebar {
.gutter-toggle {
margin-bottom: 10px;
}
.milestone-progress {
.title {
padding-top: 5px;
}
.progress {
height: 6px;
margin: 0;
}
}
.collapsed-milestone-date {
font-size: 12px;
}
.milestone-date {
display: block;
}
.date-separator {
line-height: 5px;
}
.remaining-days strong {
font-weight: normal;
}
.milestone-stat {
white-space: nowrap;
margin-right: 10px;
&.with-drilldown {
margin-right: 2px;
}
float: left;
margin-right: 14px;
}
.remaining-days {
color: $orange-600;
.milestone-stat:last-child {
margin-right: 0;
}
.milestone-stats-and-buttons {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
.milestone-progress {
.sidebar-collapsed-icon {
clear: both;
padding: 15px 5px 5px;
@media (min-width: $screen-xs-min) {
justify-content: space-between;
flex-wrap: nowrap;
}
}
.milestone-progress-buttons {
order: 1;
margin-top: 10px;
@media (min-width: $screen-xs-min) {
order: 2;
margin-top: 0;
flex-shrink: 0;
}
.btn {
float: left;
margin-right: $btn-side-margin;
&:last-child {
margin-right: 0;
.progress {
margin: 5px 0;
}
}
}
.milestone-stats {
order: 2;
width: 100%;
padding: 7px 0;
flex-shrink: 1;
@media (min-width: $screen-xs-min) {
// when displayed on one line stats go first, buttons second
order: 1;
.right-sidebar-collapsed & {
.reference {
border-top: 1px solid $border-gray-normal;
}
}
.progress {
width: 100%;
margin: 15px 0;
}
}
.issues-sortable-list,

View file

@ -19,8 +19,8 @@ module MilestonesHelper
end
end
def milestones_browse_issuables_path(milestone, type:)
opts = { milestone_title: milestone.title }
def milestones_browse_issuables_path(milestone, state: nil, type:)
opts = { milestone_title: milestone.title, state: state }
if @project
polymorphic_path([@project.namespace.becomes(Namespace), @project, type], opts)

View file

@ -6,7 +6,8 @@ module NavHelper
current_path?('merge_requests#builds') ||
current_path?('merge_requests#conflicts') ||
current_path?('merge_requests#pipelines') ||
current_path?('issues#show')
current_path?('issues#show') ||
current_path?('milestones#show')
if cookies[:collapsed_gutter] == 'true'
"page-gutter right-sidebar-collapsed"
else

View file

@ -1,5 +1,5 @@
- header_title "Milestones", dashboard_milestones_path
= 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/sidebar', milestone: @milestone, affix_offset: 51

View file

@ -4,5 +4,5 @@
= page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test?
= 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/sidebar', milestone: @milestone, affix_offset: 102

View file

@ -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
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? ) }
%h2.title
= markdown_field(@milestone, :title)
@ -53,5 +56,5 @@
.alert.alert-success.prepend-top-default
%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/sidebar', milestone: @milestone, project: @project, affix_offset: 153

View file

@ -0,0 +1,131 @@
- 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")

View file

@ -1,45 +0,0 @@
- 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)

View file

@ -3,6 +3,9 @@
- group = local_assigns[:group]
.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'}" }
- if milestone.closed?
Closed

View file

@ -0,0 +1,4 @@
---
title: Move milestone summary content into the sidebar
merge_request: 10096
author:

View file

@ -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
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
expect(page).to have_link(issue.title, href: namespace_project_issue_path(issue.project.namespace, issue.project, issue))
end

View file

@ -23,12 +23,14 @@ feature 'Project milestone', :feature do
end
it 'shows issues stats' do
expect(page).to have_content 'issues:'
expect(find('.milestone-sidebar')).to have_content 'Issues 0'
end
it 'shows Browse Issues button' do
within('#content-body') do
expect(page).to have_link 'Browse Issues'
it 'shows link to browse and add issues' do
within('.milestone-sidebar') do
expect(page).to have_link 'New issue'
expect(page).to have_link 'Open: 0'
expect(page).to have_link 'Closed: 0'
end
end
end
@ -48,12 +50,12 @@ feature 'Project milestone', :feature do
end
it 'hides issues stats' do
expect(page).to have_no_content 'issues:'
expect(find('.milestone-sidebar')).not_to have_content 'Issues 0'
end
it 'hides Browse Issues button' do
within('#content-body') do
expect(page).not_to have_link 'Browse Issues'
it 'hides new issue button' do
within('.milestone-sidebar') do
expect(page).not_to have_link 'New issue'
end
end