Commit 34edb3ab authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'feature/jschatz1/issuable-sidebar' into 'master'

Implement new design for issue and merge request right sidebar

Fixes #3981 



See merge request !2645
parents c5ed929d 2e6c5fb2
...@@ -215,4 +215,76 @@ $ -> ...@@ -215,4 +215,76 @@ $ ->
$this = $(this) $this = $(this)
$this.attr 'value', $this.val() $this.attr 'value', $this.val()
$(document).on 'breakpoint:change', (e, breakpoint) ->
if breakpoint is 'sm' or breakpoint is 'xs'
$gutterIcon = $('.gutter-toggle').find('i')
if $gutterIcon.hasClass('fa-angle-double-right')
$gutterIcon.closest('a').trigger('click')
$(document).on 'click', 'aside .gutter-toggle', (e) ->
e.preventDefault()
$this = $(this)
$thisIcon = $this.find 'i'
if $thisIcon.hasClass('fa-angle-double-right')
$thisIcon.removeClass('fa-angle-double-right')
.addClass('fa-angle-double-left')
$this
.closest('aside')
.removeClass('right-sidebar-expanded')
.addClass('right-sidebar-collapsed')
$('.page-with-sidebar')
.removeClass('right-sidebar-expanded')
.addClass('right-sidebar-collapsed')
else
$thisIcon.removeClass('fa-angle-double-left')
.addClass('fa-angle-double-right')
$this
.closest('aside')
.removeClass('right-sidebar-collapsed')
.addClass('right-sidebar-expanded')
$('.page-with-sidebar')
.removeClass('right-sidebar-collapsed')
.addClass('right-sidebar-expanded')
$.cookie("collapsed_gutter",
$('.right-sidebar')
.hasClass('right-sidebar-collapsed'), { path: '/' })
bootstrapBreakpoint = undefined;
checkBootstrapBreakpoints = ->
if $('.device-xs').is(':visible')
bootstrapBreakpoint = "xs"
else if $('.device-sm').is(':visible')
bootstrapBreakpoint = "sm"
else if $('.device-md').is(':visible')
bootstrapBreakpoint = "md"
else if $('.device-lg').is(':visible')
bootstrapBreakpoint = "lg"
setBootstrapBreakpoints = ->
if $('.device-xs').length
return
$("body")
.append('<div class="device-xs visible-xs"></div>'+
'<div class="device-sm visible-sm"></div>'+
'<div class="device-md visible-md"></div>'+
'<div class="device-lg visible-lg"></div>')
checkBootstrapBreakpoints()
fitSidebarForSize = ->
oldBootstrapBreakpoint = bootstrapBreakpoint
checkBootstrapBreakpoints()
if bootstrapBreakpoint != oldBootstrapBreakpoint
$(document).trigger('breakpoint:change', [bootstrapBreakpoint])
checkInitialSidebarSize = ->
if bootstrapBreakpoint is "xs" or "sm"
$(document).trigger('breakpoint:change', [bootstrapBreakpoint])
$(window).on "resize", (e) ->
fitSidebarForSize()
setBootstrapBreakpoints()
checkInitialSidebarSize()
new Aside() new Aside()
...@@ -10,19 +10,7 @@ class @IssuableContext ...@@ -10,19 +10,7 @@ class @IssuableContext
$(".issuable-sidebar .inline-update").on "change", ".js-assignee", -> $(".issuable-sidebar .inline-update").on "change", ".js-assignee", ->
$(this).submit() $(this).submit()
$('.issuable-details').waitForImages -> $(document).on "click",".edit-link", (e) ->
$('.issuable-affix').on 'affix.bs.affix', ->
$(@).width($(@).outerWidth())
.on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
$(@).width('')
$('.issuable-affix').affix offset:
top: ->
@top = ($('.issuable-affix').offset().top - 70)
bottom: ->
@bottom = $('.footer').outerHeight(true)
$(".edit-link").click (e) ->
block = $(@).parents('.block') block = $(@).parents('.block')
block.find('.selectbox').show() block.find('.selectbox').show()
block.find('.value').hide() block.find('.value').hide()
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
@include border-radius(3px); @include border-radius(3px);
font-size: $gl-font-size; font-size: $gl-font-size;
font-weight: 500; font-weight: 500;
padding: $gl-vert-padding $gl-padding; padding: $gl-vert-padding $gl-btn-padding;
&:focus, &:focus,
&:active { &:active {
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
display: block; display: block;
float: left; float: left;
padding: 0 $gl-padding; padding: 0 $gl-btn-padding;
font-weight: normal; font-weight: normal;
margin-right: 10px; margin-right: 10px;
font-size: $gl-font-size; font-size: $gl-font-size;
......
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
display: none; display: none;
} }
aside { aside:not(.right-sidebar){
display: none; display: none;
} }
......
...@@ -200,6 +200,14 @@ ...@@ -200,6 +200,14 @@
} }
} }
@mixin expanded-gutter {
padding-right: $gutter_width;
}
@mixin collapsed-gutter {
padding-right: $sidebar_collapsed_width;
}
@mixin collapsed-sidebar { @mixin collapsed-sidebar {
padding-left: $sidebar_collapsed_width; padding-left: $sidebar_collapsed_width;
...@@ -266,6 +274,7 @@ ...@@ -266,6 +274,7 @@
background: #f2f6f7; background: #f2f6f7;
} }
// page is small enough
@media (max-width: $screen-md-max) { @media (max-width: $screen-md-max) {
.page-sidebar-collapsed { .page-sidebar-collapsed {
@include collapsed-sidebar; @include collapsed-sidebar;
...@@ -275,12 +284,32 @@ ...@@ -275,12 +284,32 @@
@include collapsed-sidebar; @include collapsed-sidebar;
} }
.page-gutter {
&.right-sidebar-collapsed {
@include collapsed-gutter;
}
&.right-sidebar-expanded {
@include expanded-gutter;
}
}
.collapse-nav { .collapse-nav {
display: none; display: none;
} }
} }
// page is large enough
@media(min-width: $screen-md-max) { @media(min-width: $screen-md-max) {
.page-gutter {
&.right-sidebar-collapsed {
@include collapsed-gutter;
}
&.right-sidebar-expanded {
@include expanded-gutter;
}
}
.page-sidebar-collapsed { .page-sidebar-collapsed {
@include collapsed-sidebar; @include collapsed-sidebar;
} }
...@@ -288,4 +317,4 @@ ...@@ -288,4 +317,4 @@
.page-sidebar-expanded { .page-sidebar-expanded {
@include expanded-sidebar; @include expanded-sidebar;
} }
} }
\ No newline at end of file
...@@ -12,6 +12,9 @@ $gl-font-size: 15px; ...@@ -12,6 +12,9 @@ $gl-font-size: 15px;
$list-font-size: 15px; $list-font-size: 15px;
$sidebar_collapsed_width: 62px; $sidebar_collapsed_width: 62px;
$sidebar_width: 230px; $sidebar_width: 230px;
$gutter_collapsed_width: 62px;
$gutter_width: 312px;
$gutter_inner_width: 280px;
$avatar_radius: 50%; $avatar_radius: 50%;
$code_font_size: 13px; $code_font_size: 13px;
$code_line_height: 1.5; $code_line_height: 1.5;
...@@ -22,6 +25,7 @@ $header-height: 58px; ...@@ -22,6 +25,7 @@ $header-height: 58px;
$fixed-layout-width: 1280px; $fixed-layout-width: 1280px;
$gl-gray: #5a5a5a; $gl-gray: #5a5a5a;
$gl-padding: 16px; $gl-padding: 16px;
$gl-btn-padding: 10px;
$gl-vert-padding: 6px; $gl-vert-padding: 6px;
$gl-padding-top:10px; $gl-padding-top:10px;
$gl-avatar-size: 46px; $gl-avatar-size: 46px;
...@@ -36,11 +40,12 @@ $white-light: #FFFFFF; ...@@ -36,11 +40,12 @@ $white-light: #FFFFFF;
$white-normal: #ededed; $white-normal: #ededed;
$white-dark: #ededed; $white-dark: #ededed;
$gray-light: #f7f7f7; $gray-light: #faf9f9;
$gray-normal: #ededed; $gray-normal: #f5f5f5;
$gray-dark: #ededed; $gray-dark: #ededed;
$gray-darkest: #c9c9c9;
$green-light: #31AF64; $green-light: #38ae67;
$green-normal: #2FAA60; $green-normal: #2FAA60;
$green-dark: #2CA05B; $green-dark: #2CA05B;
...@@ -52,7 +57,7 @@ $blue-medium-light: #3498CB; ...@@ -52,7 +57,7 @@ $blue-medium-light: #3498CB;
$blue-medium: #2F8EBF; $blue-medium: #2F8EBF;
$blue-medium-dark: #2D86B4; $blue-medium-dark: #2D86B4;
$orange-light: #FC6443; $orange-light: rgba(252, 109, 38, 0.80);
$orange-normal: #E75E40; $orange-normal: #E75E40;
$orange-dark: #CE5237; $orange-dark: #CE5237;
...@@ -64,8 +69,8 @@ $border-white-light: #F1F2F4; ...@@ -64,8 +69,8 @@ $border-white-light: #F1F2F4;
$border-white-normal: #D6DAE2; $border-white-normal: #D6DAE2;
$border-white-dark: #C6CACF; $border-white-dark: #C6CACF;
$border-gray-light: #d1d1d1; $border-gray-light: rgba(0, 0, 0, 0.06);
$border-gray-normal: #D6DAE2; $border-gray-normal: rgba(0, 0, 0, 0.10);;
$border-gray-dark: #C6CACF; $border-gray-dark: #C6CACF;
$border-green-light: #2FAA60; $border-green-light: #2FAA60;
...@@ -76,7 +81,7 @@ $border-blue-light: #2D9FD8; ...@@ -76,7 +81,7 @@ $border-blue-light: #2D9FD8;
$border-blue-normal: #2897CE; $border-blue-normal: #2897CE;
$border-blue-dark: #258DC1; $border-blue-dark: #258DC1;
$border-orange-light: #ED5C3D; $border-orange-light: #fc6d26;
$border-orange-normal: #CE5237; $border-orange-normal: #CE5237;
$border-orange-dark: #C14E35; $border-orange-dark: #C14E35;
......
...@@ -42,8 +42,6 @@ ...@@ -42,8 +42,6 @@
.issuable-details { .issuable-details {
section { section {
border-right: 1px solid $border-white-light;
.issuable-discussion { .issuable-discussion {
margin-right: 1px; margin-right: 1px;
} }
...@@ -73,11 +71,35 @@ ...@@ -73,11 +71,35 @@
.block { .block {
@include clearfix; @include clearfix;
padding: $gl-padding 0; padding: $gl-padding 0;
border-bottom: 1px solid #F0F0F0; border-bottom: 1px solid $border-gray-light;
// This prevents the mess when resizing the sidebar
// of elements repositioning themselves..
width: $gutter_inner_width;
overflow-x: hidden;
// --
&:first-child {
padding-top: 5px;
}
&:last-child { &:last-child {
border: none; border: none;
} }
span {
margin-top: 7px;
display: inline-block;
}
.issuable-count {
}
.gutter-toggle {
margin-left: 20px;
border-left: 1px solid $border-gray-light;
padding-left: 10px;
}
} }
.title { .title {
...@@ -133,3 +155,92 @@ ...@@ -133,3 +155,92 @@
margin-right: 2px; margin-right: 2px;
} }
} }
.right-sidebar {
position: fixed;
top: 58px;
right: 0;
height: 100%;
transition-duration: .3s;
background: $gray-light;
overflow: scroll;
padding: 10px 20px;
&.right-sidebar-expanded {
width: $gutter_width;
hr {
display: none;
}
}
.subscribe-button {
span {
margin-top: 0;
}
}
&.right-sidebar-collapsed {
width: $sidebar_collapsed_width;
padding-top: 0;
overflow-x: hidden;
hr {
margin: 0;
color: $gray-normal;
border-color: $gray-normal;
width: 62px;
margin-left: -20px
}
.block {
border-bottom: none;
padding: 15px 0 0 0;
}
}
.btn {
background: $gray-normal;
border: 1px solid $border-gray-normal;
}
&.right-sidebar-collapsed {
.issuable-count,
.issuable-nav,
.assignee > *,
.milestone > *,
.labels > *,
.participants > *,
.light > *,
.project-reference > * {
display: none;
}
.gutter-toggle {
margin-left: -$gutter_inner_width + 4;
}
.sidebar-collapsed-icon {
display: block;
float: left;
width: 62px;
text-align: center;
margin-left: -19px;
padding-bottom: 10px;
color: #999999;
span {
display: block;
margin-top: 0;
}
}
}
&.right-sidebar-expanded {
.sidebar-collapsed-icon {
display: none;
}
}
}
\ No newline at end of file
...@@ -293,6 +293,76 @@ module ApplicationHelper ...@@ -293,6 +293,76 @@ module ApplicationHelper
end end
end end
def issuable_link_next(project,issuable)
if project.nil?
nil
elsif current_controller?(:issues)
namespace_project_issue_path(project.namespace, project, next_issuable_for(project, issuable.id).try(:iid))
elsif current_controller?(:merge_requests)
namespace_project_merge_request_path(project.namespace, project, next_issuable_for(project, issuable.id).try(:iid))
end
end
def issuable_link_prev(project,issuable)
if project.nil?
nil
elsif current_controller?(:issues)
namespace_project_issue_path(project.namespace, project, prev_issuable_for(project, issuable.id).try(:iid))
elsif current_controller?(:merge_requests)
namespace_project_merge_request_path(project.namespace, project, prev_issuable_for(project, issuable.id).try(:iid))
end
end
def issuable_count(entity, project)
if project.nil?
0
elsif current_controller?(:issues)
project.issues.send(entity).count
elsif current_controller?(:merge_requests)
project.merge_requests.send(entity).count
end
end
def next_issuable_for(project, id)
if project.nil?
nil
elsif current_controller?(:issues)
project.issues.where("id > ?", id).last
elsif current_controller?(:merge_requests)
project.merge_requests.where("id > ?", id).last
end
end
def has_next_issuable?(project, id)
if project.nil?
nil
elsif current_controller?(:issues)
project.issues.where("id > ?", id).last
elsif current_controller?(:merge_requests)
project.merge_requests.where("id > ?", id).last
end
end
def prev_issuable_for(project, id)
if project.nil?
nil
elsif current_controller?(:issues)
project.issues.where("id < ?", id).first
elsif current_controller?(:merge_requests)
project.merge_requests.where("id < ?", id).first
end
end
def has_prev_issuable?(project, id)
if project.nil?
nil
elsif current_controller?(:issues)
project.issues.where("id < ?", id).first
elsif current_controller?(:merge_requests)
project.merge_requests.where("id < ?", id).first
end
end
def state_filters_text_for(entity, project) def state_filters_text_for(entity, project)
titles = { titles = {
opened: "Open" opened: "Open"
......
...@@ -3,6 +3,18 @@ module NavHelper ...@@ -3,6 +3,18 @@ module NavHelper
cookies[:collapsed_nav] == 'true' cookies[:collapsed_nav] == 'true'
end end
def sidebar_gutter_collapsed_class
if cookies[:collapsed_gutter] == 'true'
"right-sidebar-collapsed"
else
"right-sidebar-expanded"
end
end
def sidebar_gutter_collapsed?
cookies[:collapsed_gutter] == 'true'
end
def nav_sidebar_class def nav_sidebar_class
if nav_menu_collapsed? if nav_menu_collapsed?
"sidebar-collapsed" "sidebar-collapsed"
...@@ -19,6 +31,17 @@ module NavHelper ...@@ -19,6 +31,17 @@ module NavHelper
end end
end end
def page_gutter_class
if current_path?('merge_requests#show') || current_path?('issues#show')
if cookies[:collapsed_gutter] == 'true'
"page-gutter right-sidebar-collapsed"
else
"page-gutter right-sidebar-expanded"
end
end
end
def nav_header_class def nav_header_class
if nav_menu_collapsed? if nav_menu_collapsed?
"header-collapsed" "header-collapsed"
......
...@@ -20,6 +20,12 @@ module ProjectsHelper ...@@ -20,6 +20,12 @@ module ProjectsHelper
end end
end end
def link_to_member_avatar(author, opts = {})
default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" }
opts = default_opts.merge(opts)
image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar]
end
def link_to_member(project, author, opts = {}) def link_to_member(project, author, opts = {})
default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" } default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" }
opts = default_opts.merge(opts) opts = default_opts.merge(opts)
......
.page-with-sidebar{ class: page_sidebar_class } .page-with-sidebar{ class: "#{page_sidebar_class} #{page_gutter_class}" }
= render "layouts/broadcast" = render "layouts/broadcast"
.sidebar-wrapper.nicescroll{ class: nav_sidebar_class } .sidebar-wrapper.nicescroll{ class: nav_sidebar_class }
.header-logo .header-logo
......
...@@ -54,11 +54,8 @@ ...@@ -54,11 +54,8 @@
= render 'votes/votes_block', votable: @issue = render 'votes/votes_block', votable: @issue
.row .row
%section.col-md-9 %section.col-md-12
.issuable-discussion .issuable-discussion
= render 'projects/issues/discussion' = render 'projects/issues/discussion'
%aside.col-md-3 = render 'shared/issuable/sidebar', issuable: @issue
= render 'shared/issuable/sidebar', issuable: @issue \ No newline at end of file
= render 'shared/show_aside'
$('.issuable-sidebar').html("#{escape_javascript(render 'shared/issuable/sidebar', issuable: @issue)}"); $('aside.right-sidebar')[0].outerHTML = "#{escape_javascript(render 'shared/issuable/sidebar', issuable: @issue)}";
$('.issuable-sidebar').parent().effect('highlight') $('aside.right-sidebar').effect('highlight');
new Issue(); new Issue();
\ No newline at end of file
...@@ -70,12 +70,9 @@ ...@@ -70,12 +70,9 @@
= render 'votes/votes_block', votable: @merge_request = render 'votes/votes_block', votable: @merge_request
.row .row
%section.col-md-9 %section.col-md-12
.issuable-discussion .issuable-discussion
= render "projects/merge_requests/discussion" = render "projects/merge_requests/discussion"
%aside.col-md-3
= render 'shared/issuable/sidebar', issuable: @merge_request
= render 'shared/show_aside'
#commits.commits.tab-pane #commits.commits.tab-pane
- # This tab is always loaded via AJAX - # This tab is always loaded via AJAX
...@@ -87,6 +84,8 @@ ...@@ -87,6 +84,8 @@
.mr-loading-status .mr-loading-status
= spinner = spinner
= render 'shared/issuable/sidebar', issuable: @merge_request
:javascript :javascript
var merge_request; var merge_request;
......
$('.issuable-sidebar').html("#{escape_javascript(render 'shared/issuable/sidebar', issuable: @merge_request)}"); $('aside.right-sidebar')[0].outerHTML= "#{escape_javascript(render 'shared/issuable/sidebar', issuable: @merge_request)}";
$('.issuable-sidebar').parent().effect('highlight') $('aside.right-sidebar').effect('highlight')
merge_request = new MergeRequest(); merge_request = new MergeRequest();
.block.participants .block.participants
.sidebar-collapsed-icon
= icon('users')
%span
= participants.count
.title .title
= pluralize participants.count, "participant" = pluralize participants.count, "participant"
- participants.each do |participant| - participants.each do |participant|
......
.issuable-sidebar.issuable-affix %aside.right-sidebar{ class: sidebar_gutter_collapsed_class }
= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f| .issuable-sidebar
.block.assignee .block
.title %span.issuable-count.pull-left
%label = issuable.iid
Assignee of
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) = issuable_count(:all, @project)
.pull-right %span.pull-right
= link_to 'Edit', '#', class: 'edit-link' %a.gutter-toggle{href: '#'}
.value - if sidebar_gutter_collapsed?
- if issuable.assignee = icon('angle-double-left')
%strong= link_to_member(@project, issuable.assignee, size: 24) - else
- if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee) = icon('angle-double-right')
%a.pull-right.cannot-be-merged{href: '#', data: {toggle: 'tooltip'}, title: 'Not allowed to merge'} .issuable-nav.pull-right.btn-group{role: 'group', "aria-label" => '...'}
= icon('exclamation-triangle') - if has_prev_issuable?(@project, issuable.id)
= link_to 'Prev', issuable_link_prev(@project, issuable), class: 'btn btn-default'
- else - else
.light None %a.btn.btn-default.disabled{href: '#'}
Prev
- if has_next_issuable?(@project, issuable.id)
= link_to 'Next', issuable_link_next(@project, issuable), class: 'btn btn-default'
- else
%a.btn.btn-default.disabled{href: '#'}
Next
.selectbox = form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
= users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true, current_user: true, first_user: true) .block.assignee
.sidebar-collapsed-icon
- if issuable.assignee
= link_to_member_avatar(issuable.assignee, size: 24)
- else
= icon('user')
.title
%label
Assignee
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
.pull-right
= link_to 'Edit', '#', class: 'edit-link'
.value
- if issuable.assignee
%strong= link_to_member(@project, issuable.assignee, size: 24)
- if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee)
%a.pull-right.cannot-be-merged{href: '#', data: {toggle: 'tooltip'}, title: 'Not allowed to merge'}
= icon('exclamation-triangle')
- else
.light None
.block.milestone .selectbox
.title = users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true, current_user: true, first_user: true)
%label
Milestone
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
.pull-right
= link_to 'Edit', '#', class: 'edit-link'
.value
- if issuable.milestone
%span.back-to-milestone
= link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do
%strong
= icon('clock-o')
= issuable.milestone.title
- else
.light None
.selectbox
= f.select(:milestone_id, milestone_options(issuable), { include_blank: true }, { class: 'select2 select2-compact js-select2 js-milestone', data: { placeholder: 'Select milestone' }})
= hidden_field_tag :issuable_context
= f.submit class: 'btn hide'
- if issuable.project.labels.any? .block.milestone
.block .sidebar-collapsed-icon
= icon('balance-scale')
%span
- if issuable.milestone
= issuable.milestone.title
- else
No
.title .title
%label Labels %label
Milestone
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
.pull-right .pull-right
= link_to 'Edit', '#', class: 'edit-link' = link_to 'Edit', '#', class: 'edit-link'
.value.issuable-show-labels .value
- if issuable.labels.any? - if issuable.milestone
- issuable.labels.each do |label| %span.back-to-milestone
= link_to_label(label) = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do
%strong
= icon('clock-o')
= issuable.milestone.title
- else - else
.light None .light None
.selectbox .selectbox
= f.collection_select :label_ids, issuable.project.labels.all, :id, :name, = f.select(:milestone_id, milestone_options(issuable), { include_blank: true }, { class: 'select2 select2-compact js-select2 js-milestone', data: { placeholder: 'Select milestone' }})
{ selected: issuable.label_ids }, multiple: true, class: 'select2 js-select2', data: { placeholder: "Select labels" } = hidden_field_tag :issuable_context
= f.submit class: 'btn hide'
= render "shared/issuable/participants", participants: issuable.participants(current_user) - if issuable.project.labels.any?
.block.labels
.sidebar-collapsed-icon
= icon('tags')
%span
= issuable.labels.count
.title
%label Labels
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
.pull-right
= link_to 'Edit', '#', class: 'edit-link'
.value.issuable-show-labels
- if issuable.labels.any?
- issuable.labels.each do |label|
= link_to_label(label)
- else
.light None
.selectbox
= f.collection_select :label_ids, issuable.project.labels.all, :id, :name,
{ selected: issuable.label_ids }, multiple: true, class: 'select2 js-select2', data: { placeholder: "Select labels" }
- if current_user = render "shared/issuable/participants", participants: issuable.participants(current_user)
- subscribed = issuable.subscribed?(current_user) %hr
.block.light - if current_user
.title - subscribed = issuable.subscribed?(current_user)
%label.light Notifications .block.light
- subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed' .sidebar-collapsed-icon
%button.btn.btn-block.btn-gray.subscribe-button{:type => 'button'} = icon('rss')
%span= subscribed ? 'Unsubscribe' : 'Subscribe' .title
.subscription-status{data: {status: subscribtion_status}} %label.light Notifications
.unsubscribed{class: ( 'hidden' if subscribed )} - subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed'
You're not receiving notifications from this thread. %button.btn.btn-block.btn-gray.subscribe-button{:type => 'button'}
.subscribed{class: ( 'hidden' unless subscribed )} %span= subscribed ? 'Unsubscribe' : 'Subscribe'
You're receiving notifications because you're subscribed to this thread. .subscription-status{data: {status: subscribtion_status}}
.unsubscribed{class: ( 'hidden' if subscribed )}
You're not receiving notifications from this thread.
.subscribed{class: ( 'hidden' unless subscribed )}
You're receiving notifications because you're subscribed to this thread.
- project_ref = cross_project_reference(@project, issuable) - project_ref = cross_project_reference(@project, issuable)
.block .block.project-reference
.title .sidebar-collapsed-icon
.cross-project-reference = icon('clipboard')
%span .title
Reference: .cross-project-reference
%cite{title: project_ref} %span
= project_ref Reference:
= clipboard_button(clipboard_text: project_ref) %cite{title: project_ref}
= project_ref
= clipboard_button(clipboard_text: project_ref)
:javascript :javascript
new Subscription("#{toggle_subscription_path(issuable)}"); new Subscription("#{toggle_subscription_path(issuable)}");
new IssuableContext(); new IssuableContext();
\ No newline at end of file \ No newline at end of file
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