Commit 03a5df99 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'ui-right-sidebar' into 'master'

Implement new sidebar for issue and merge request pages

This is first step in implementing #3981. We don't have new dropdowns yet so I used some workarounds. 
Also I did it from linux machine without having access to design materials. So some colors/paddings might not match - but I will improve it with next iteration. 

cc @creamzy @JobV 

See merge request !2058
parents 6738b039 7cbcc21d
...@@ -47,6 +47,7 @@ v 8.3.0 (unreleased) ...@@ -47,6 +47,7 @@ v 8.3.0 (unreleased)
- Fix award-emojis Flash alert's width - Fix award-emojis Flash alert's width
- Fix deleting notes on a merge request diff - Fix deleting notes on a merge request diff
- Display referenced merge request statuses in the issue description (Greg Smethells) - Display referenced merge request statuses in the issue description (Greg Smethells)
- Implement new sidebar for issue and merge request pages
v 8.2.3 v 8.2.3
- Fix application settings cache not expiring after changes (Stan Hu) - Fix application settings cache not expiring after changes (Stan Hu)
......
...@@ -5,9 +5,9 @@ class @IssuableContext ...@@ -5,9 +5,9 @@ class @IssuableContext
new UsersSelect() new UsersSelect()
$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true}) $('select.select2').select2({width: 'resolve', dropdownAutoWidth: true})
$(".context .inline-update").on "change", "select", -> $(".issuable-sidebar .inline-update").on "change", "select", ->
$(this).submit() $(this).submit()
$(".context .inline-update").on "change", ".js-assignee", -> $(".issuable-sidebar .inline-update").on "change", ".js-assignee", ->
$(this).submit() $(this).submit()
$('.issuable-details').waitForImages -> $('.issuable-details').waitForImages ->
...@@ -18,6 +18,12 @@ class @IssuableContext ...@@ -18,6 +18,12 @@ class @IssuableContext
$('.issuable-affix').affix offset: $('.issuable-affix').affix offset:
top: -> top: ->
@top = ($('.issuable-affix').offset().top - 70) @top = ($('.issuable-affix').offset().top - 60)
bottom: -> bottom: ->
@bottom = $('.footer').outerHeight(true) @bottom = $('.footer').outerHeight(true)
$(".edit-link").click (e) ->
block = $(@).parents('.block')
block.find('.selectbox').show()
block.find('.value').hide()
block.find('.js-select2').select2("open")
...@@ -461,3 +461,9 @@ table { ...@@ -461,3 +461,9 @@ table {
visibility: hidden; visibility: hidden;
} }
} }
.content-separator {
margin-left: -$gl-padding;
margin-right: -$gl-padding;
border-top: 1px solid $border-color;
}
...@@ -181,4 +181,4 @@ ...@@ -181,4 +181,4 @@
.ajax-users-dropdown { .ajax-users-dropdown {
min-width: 250px !important; min-width: 250px !important;
} }
\ No newline at end of file
.awards {
@include clearfix;
line-height: 34px;
.award {
@include border-radius(5px);
border: 1px solid;
padding: 0px 10px;
float: left;
margin-right: 5px;
border-color: $border-color;
cursor: pointer;
&.active {
border-color: $border-gray-light;
background-color: $gray-light;
.counter {
font-weight: bold;
}
}
.icon {
float: left;
margin-right: 10px;
}
.counter {
float: left;
}
}
.awards-controls {
margin-left: 10px;
float: left;
.add-award {
font-size: 24px;
color: $gl-gray;
position: relative;
top: 2px;
&:hover,
&:link {
text-decoration: none;
}
}
.awards-menu {
padding: $gl-padding;
min-width: 214px;
> li {
cursor: pointer;
margin: 5px;
}
}
}
.awards-menu{
li {
float: left;
margin: 3px;
}
}
}
...@@ -18,26 +18,12 @@ ...@@ -18,26 +18,12 @@
&.affix { &.affix {
position: fixed; position: fixed;
top: 70px; top: 60px;
margin-right: 35px; margin-right: 35px;
} }
} }
} }
.issuable-context-title {
margin-bottom: 5px;
.avatar {
margin-left: 0;
}
label {
color: $gl-gray;
font-weight: normal;
margin-right: 4px;
}
}
.project-issuable-filter { .project-issuable-filter {
.controls { .controls {
float: right; float: right;
...@@ -50,23 +36,6 @@ ...@@ -50,23 +36,6 @@
} }
.issuable-details { .issuable-details {
.page-title {
margin-top: -$gl-padding;
padding: 7px 0;
margin-bottom: 0;
color: #5c5d5e;
font-size: 16px;
line-height: 42px;
.author {
color: #5c5d5e;
}
.issue-id {
color: #5c5d5e;
}
}
.issue-title { .issue-title {
margin: 0; margin: 0;
font-size: 23px; font-size: 23px;
...@@ -80,6 +49,21 @@ ...@@ -80,6 +49,21 @@
margin-bottom: 0; margin-bottom: 0;
} }
} }
section {
border-right: 1px solid #ECEEF1;
> .tab-content {
margin-right: 1px;
}
.issue-discussion > .gray-content-block,
> .gray-content-block {
margin-top: 0;
border-top: none;
margin-right: -15px;
}
}
} }
.issuable-filter-count { .issuable-filter-count {
...@@ -101,84 +85,72 @@ ...@@ -101,84 +85,72 @@
} }
} }
.cross-project-reference { .issuable-sidebar {
text-align: center; .block {
width: 100%; @include clearfix;
padding: $gl-padding 0;
.slead { border-bottom: 1px solid #F0F0F0;
padding: 5px;
}
span, button { &:last-child {
background-color: $background-color; border: none;
}
} }
}
.awards { .title {
@include clearfix; color: $gl-text-color;
line-height: 34px; margin-bottom: 8px;
margin: 2px 0;
.award { .avatar {
@include border-radius(5px); margin-left: 0;
}
border: 1px solid;
padding: 0px 10px;
float: left;
margin: 0 5px;
border-color: $border-color;
cursor: pointer;
&.active {
border-color: $border-gray-light;
background-color: $gray-light;
.counter { label {
font-weight: bold; font-weight: normal;
} margin-right: 4px;
} }
.icon { .edit-link {
float: left; color: $gl-gray;
margin-right: 10px;
} }
}
.cross-project-reference {
font-weight: bold;
color: $gl-link-color;
.counter { button {
float: left; float: right;
} }
} }
.awards-controls { .selectbox {
margin-left: 10px; display: none
float: left; }
.add-award { .btn-clipboard {
font-size: 24px; color: $gl-gray;
color: $gl-gray; }
position: relative;
top: 2px;
&:hover, .participants .avatar {
&:link { margin-top: 6px;
text-decoration: none; margin-right: 2px;
} }
} }
.awards-menu { .issuable-title {
padding: $gl-padding; margin: -$gl-padding;
min-width: 214px; padding: 7px $gl-padding;
margin-bottom: 0px;
border-bottom: 1px solid $border-color;
color: #5c5d5e;
font-size: 16px;
line-height: 42px;
> li { .author {
cursor: pointer; color: #5c5d5e;
margin: 5px;
}
}
} }
.awards-menu{ .issuable-id {
li { color: #5c5d5e;
float: left;
margin: 3px;
}
} }
} }
...@@ -121,10 +121,6 @@ ...@@ -121,10 +121,6 @@
} }
} }
.merge-request-details {
margin-bottom: $gl-padding;
}
.mr_source_commit, .mr_source_commit,
.mr_target_commit { .mr_target_commit {
.commit { .commit {
......
...@@ -58,7 +58,6 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -58,7 +58,6 @@ class Projects::IssuesController < Projects::ApplicationController
end end
def show def show
@participants = @issue.participants(current_user)
@note = @project.notes.new(noteable: @issue) @note = @project.notes.new(noteable: @issue)
@notes = @issue.notes.nonawards.with_associations.fresh @notes = @issue.notes.nonawards.with_associations.fresh
@noteable = @issue @noteable = @issue
......
...@@ -279,8 +279,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -279,8 +279,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end end
def define_show_vars def define_show_vars
@participants = @merge_request.participants(current_user)
# Build a note object for comment form # Build a note object for comment form
@note = @project.notes.new(noteable: @merge_request) @note = @project.notes.new(noteable: @merge_request)
@notes = @merge_request.mr_and_commit_notes.nonawards.inc_author.fresh @notes = @merge_request.mr_and_commit_notes.nonawards.inc_author.fresh
......
...@@ -5,24 +5,8 @@ ...@@ -5,24 +5,8 @@
- else - else
= link_to 'Close Issue', issue_path(@issue, issue: {state_event: :close}, status_only: true), method: :put, class: 'btn btn-grouped btn-close js-note-target-close', title: 'Close Issue' = link_to 'Close Issue', issue_path(@issue, issue: {state_event: :close}, status_only: true), method: :put, class: 'btn btn-grouped btn-close js-note-target-close', title: 'Close Issue'
= render 'shared/show_aside'
.gray-content-block.second-block.oneline-block .gray-content-block.second-block.oneline-block
.row = render 'votes/votes_block', votable: @issue
.col-md-9
.votes-holder.pull-right
#votes= render 'votes/votes_block', votable: @issue
= render "shared/issuable/participants"
.col-md-3
.input-group.cross-project-reference
%span#cross-project-reference.slead.has_tooltip{title: 'Cross-project reference'}
= cross_project_reference(@project, @issue)
= clipboard_button(clipboard_target: 'span#cross-project-reference')
.row #notes
%section.col-md-9 = render 'projects/notes/notes_with_form'
.voting_notes#notes= render 'projects/notes/notes_with_form'
%aside.col-md-3
.issuable-affix
.context
= render 'shared/issuable/context', issuable: @issue
...@@ -3,13 +3,13 @@ ...@@ -3,13 +3,13 @@
.issue .issue
.issue-details.issuable-details .issue-details.issuable-details
.page-title .issuable-title
.issue-box{ class: issue_box_class(@issue) } .issue-box{ class: issue_box_class(@issue) }
- if @issue.closed? - if @issue.closed?
Closed Closed
- else - else
Open Open
%span.issue-id Issue ##{@issue.iid} %span.issuable-id Issue ##{@issue.iid}
%span.creator %span.creator
&middot; &middot;
opened by #{link_to_member(@project, @issue.author, size: 24)} opened by #{link_to_member(@project, @issue.author, size: 24)}
...@@ -36,22 +36,29 @@ ...@@ -36,22 +36,29 @@
= icon('pencil-square-o') = icon('pencil-square-o')
Edit Edit
.gray-content-block.middle-block .row
%h2.issue-title %section.col-md-9
= markdown escape_once(@issue.title), pipeline: :single_line .gray-content-block
%div %h2.issue-title
- if @issue.description.present? = markdown escape_once(@issue.title), pipeline: :single_line
.description{class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : ''} %div
.wiki - if @issue.description.present?
= preserve do .description{class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : ''}
= markdown(@issue.description, cache_key: [@issue, "description"]) .wiki
%textarea.hidden.js-task-list-field = preserve do
= @issue.description = markdown(@issue.description, cache_key: [@issue, "description"])
%textarea.hidden.js-task-list-field
.merge-requests = @issue.description
= render 'merge_requests'
.merge-requests
- if @closed_by_merge_requests.present? = render 'merge_requests'
= render 'projects/issues/closed_by_box'
.issue-discussion - if @closed_by_merge_requests.present?
= render 'projects/issues/discussion' = render 'projects/issues/closed_by_box'
.issue-discussion
= render 'projects/issues/discussion'
%aside.col-md-3
= render 'shared/issuable/sidebar', issuable: @issue
= render 'shared/show_aside'
$('.context').html("#{escape_javascript(render 'shared/issuable/context', issuable: @issue)}"); $('.issuable-sidebar').html("#{escape_javascript(render 'shared/issuable/sidebar', issuable: @issue)}");
$('.context').effect('highlight') $('.issuable-sidebar').parent().effect('highlight')
new Issue(); new Issue();
...@@ -5,24 +5,7 @@ ...@@ -5,24 +5,7 @@
- if @merge_request.closed? - if @merge_request.closed?
= link_to 'Reopen', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request" = link_to 'Reopen', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request"
= render 'shared/show_aside' .gray-content-block.second-block.oneline-block
= render 'votes/votes_block', votable: @merge_request
.gray-content-block.middle-block.oneline-block #notes= render "projects/notes/notes_with_form"
.row
.col-md-9
.votes-holder.pull-right
#votes= render 'votes/votes_block', votable: @merge_request
= render "shared/issuable/participants"
.col-md-3
.input-group.cross-project-reference
%span#cross-project-reference.slead.has_tooltip{title: 'Cross-project reference'}
= cross_project_reference(@project, @merge_request)
= clipboard_button(clipboard_target: 'span#cross-project-reference')
.row
%section.col-md-9
.voting_notes#notes= render "projects/notes/notes_with_form"
%aside.col-md-3
.issuable-affix
.context
= render 'shared/issuable/context', issuable: @merge_request
...@@ -7,71 +7,79 @@ ...@@ -7,71 +7,79 @@
.merge-request{'data-url' => merge_request_path(@merge_request)} .merge-request{'data-url' => merge_request_path(@merge_request)}
.merge-request-details.issuable-details .merge-request-details.issuable-details
= render "projects/merge_requests/show/mr_title" = render "projects/merge_requests/show/mr_title"
= render "projects/merge_requests/show/mr_box" .row
.append-bottom-default.mr-source-target.prepend-top-default %section.col-md-9
- if @merge_request.open? = render "projects/merge_requests/show/mr_box"
.pull-right .append-bottom-default.mr-source-target.prepend-top-default
- if @merge_request.source_branch_exists? - if @merge_request.open?
= link_to "#modal_merge_info", class: "btn btn-sm", "data-toggle" => "modal" do .pull-right
= icon('cloud-download fw') - if @merge_request.source_branch_exists?
Check out branch = link_to "#modal_merge_info", class: "btn btn-sm", "data-toggle" => "modal" do
= icon('cloud-download fw')
Check out branch
%span.dropdown %span.dropdown
%a.btn.btn-sm.dropdown-toggle{ data: {toggle: :dropdown} } %a.btn.btn-sm.dropdown-toggle{ data: {toggle: :dropdown} }
= icon('download') = icon('download')
Download as Download as
%span.caret %span.caret
%ul.dropdown-menu %ul.dropdown-menu
%li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch) %li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch)
%li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff) %li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff)
.normal .normal
%span Request to merge %span Request to merge
%span.label-branch= source_branch_with_namespace(@merge_request) %span.label-branch= source_branch_with_namespace(@merge_request)
%span into %span into
= link_to namespace_project_commits_path(@project.namespace, @project, @merge_request.target_branch), class: "label-branch" do = link_to namespace_project_commits_path(@project.namespace, @project, @merge_request.target_branch), class: "label-branch" do
= @merge_request.target_branch = @merge_request.target_branch
= render "projects/merge_requests/show/how_to_merge" = render "projects/merge_requests/show/how_to_merge"
= render "projects/merge_requests/widget/show.html.haml" = render "projects/merge_requests/widget/show.html.haml"
- if @merge_request.open? && @merge_request.source_branch_exists? && @merge_request.can_be_merged? && @merge_request.can_be_merged_by?(current_user) - if @merge_request.open? && @merge_request.source_branch_exists? && @merge_request.can_be_merged? && @merge_request.can_be_merged_by?(current_user)
.light.prepend-top-default .light.prepend-top-default
You can also accept this merge request manually using the You can also accept this merge request manually using the
= succeed '.' do = succeed '.' do
= link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
- if @commits.present? - if @commits.present?
%ul.merge-request-tabs.center-top-menu.no-top.no-bottom %ul.merge-request-tabs.center-top-menu.no-top.no-bottom
%li.notes-tab %li.notes-tab
= link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#notes', action: 'notes', toggle: 'tab'} do = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#notes', action: 'notes', toggle: 'tab'} do
Discussion Discussion
%span.badge= @merge_request.mr_and_commit_notes.user.count %span.badge= @merge_request.mr_and_commit_notes.user.count
%li.commits-tab %li.commits-tab
= link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#commits', action: 'commits', toggle: 'tab'} do = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#commits', action: 'commits', toggle: 'tab'} do
Commits Commits
%span.badge= @commits.size %span.badge= @commits.size
%li.diffs-tab %li.diffs-tab
= link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do
Changes Changes
%span.badge= @merge_request.diffs.size %span.badge= @merge_request.diffs.size
- if @ci_commit - if @ci_commit
%li.builds-tab %li.builds-tab
= link_to builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#builds', action: 'builds', toggle: 'tab'} do = link_to builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#builds', action: 'builds', toggle: 'tab'} do
Builds Builds
%span.badge= @statuses.size %span.badge= @statuses.size
.tab-content .tab-content
#notes.notes.tab-pane.voting_notes #notes.notes.tab-pane.voting_notes
= render "projects/merge_requests/discussion" = render "projects/merge_requests/discussion"
#commits.commits.tab-pane #commits.commits.tab-pane
- # This tab is always loaded via AJAX - # This tab is always loaded via AJAX
#diffs.diffs.tab-pane #diffs.diffs.tab-pane
- # This tab is always loaded via AJAX - # This tab is always loaded via AJAX
#builds.builds.tab-pane #builds.builds.tab-pane
- # This tab is always loaded via AJAX - # This tab is always loaded via AJAX
.mr-loading-status
= spinner
%aside.col-md-3
= render 'shared/issuable/sidebar', issuable: @merge_request
= render 'shared/show_aside'
.mr-loading-status
= spinner
:javascript :javascript
var merge_request; var merge_request;
......
.page-title .issuable-title
.issue-box{ class: issue_box_class(@merge_request) } .issue-box{ class: issue_box_class(@merge_request) }
= @merge_request.state_human_name = @merge_request.state_human_name
%span.issue-id Merge Request ##{@merge_request.iid} %span.issuable-id Merge Request ##{@merge_request.iid}
%span.creator %span.creator
&middot; &middot;
opened by #{link_to_member(@project, @merge_request.author, size: 24)} opened by #{link_to_member(@project, @merge_request.author, size: 24)}
......
$('.context').html("#{escape_javascript(render 'shared/issuable/context', issuable: @merge_request)}"); $('.issuable-sidebar').html("#{escape_javascript(render 'shared/issuable/sidebar', issuable: @merge_request)}");
$('.context').effect('highlight') $('.issuable-sidebar').parent().effect('highlight')
merge_request = new MergeRequest(); merge_request = new MergeRequest();
= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
%div.prepend-top-default
.issuable-context-title
%label
Assignee:
- if issuable.assignee
%strong= link_to_member(@project, issuable.assignee, size: 24)
- else
none
.issuable-context-selectbox
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
= 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)
%div.prepend-top-default.clearfix
.issuable-context-title
%label
Milestone:
- 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
none
.issuable-context-selectbox
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
= 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.labels.any?
%div.prepend-top-default.clearfix
.issuable-context-title
%label Labels
.issuable-show-labels
- issuable.labels.each do |label|
= link_to_label(label)
- if current_user
- subscribed = issuable.subscribed?(current_user)
%div.prepend-top-default.clearfix
.issuable-context-title
%label Subscription
- subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed'
.subscription-status{data: {status: subscribtion_status}}
.description-block.unsubscribed{class: ( 'hidden' if subscribed )}
You're not receiving notifications from this thread.
.description-block.subscribed{class: ( 'hidden' unless subscribed )}
You're receiving notifications because you're subscribed to this thread.
%button.btn.btn-block.subscribe-button{:type => 'button'}
= icon('eye')
%span= subscribed ? 'Unsubscribe' : 'Subscribe'
:javascript
new Subscription("#{toggle_subscription_path(issuable)}");
new IssuableContext();
.participants .block.participants
%span .title
= pluralize @participants.count, "participant" = pluralize participants.count, "participant"
- @participants.each do |participant| - participants.each do |participant|
= link_to_member(@project, participant, name: false, size: 24) = link_to_member(@project, participant, name: false, size: 24)
.issuable-sidebar.issuable-affix
= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
.block
.title
Cross-project reference
.cross-project-reference
%span#cross-project-reference
= cross_project_reference(@project, issuable)
= clipboard_button(clipboard_target: 'span#cross-project-reference')
.block.assignee
.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)
- else
.light None
.selectbox
= 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.milestone
.title
%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
.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" }
= render "shared/issuable/participants", participants: issuable.participants(current_user)
- if current_user
- subscribed = issuable.subscribed?(current_user)
.block.light
.title
%label.light Notifications
- subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed'
%button.btn.btn-block.btn-gray.subscribe-button{:type => 'button'}
%span= subscribed ? 'Unsubscribe' : 'Subscribe'
.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.
:javascript
new Subscription("#{toggle_subscription_path(issuable)}");
new IssuableContext();
...@@ -69,7 +69,10 @@ describe 'Issues', feature: true do ...@@ -69,7 +69,10 @@ describe 'Issues', feature: true do
click_button 'Save changes' click_button 'Save changes'
expect(page).to have_content 'Assignee: none' page.within('.assignee') do
expect(page).to have_content 'None'
end
expect(issue.reload.assignee).to be_nil expect(issue.reload.assignee).to be_nil
end end
end end
...@@ -202,11 +205,11 @@ describe 'Issues', feature: true do ...@@ -202,11 +205,11 @@ describe 'Issues', feature: true do
it 'with dropdown menu' do it 'with dropdown menu' do
visit namespace_project_issue_path(project.namespace, project, issue) visit namespace_project_issue_path(project.namespace, project, issue)
find('.context #issue_assignee_id'). find('.issuable-sidebar #issue_assignee_id').
set project.team.members.first.id set project.team.members.first.id
click_button 'Update Issue' click_button 'Update Issue'
expect(page).to have_content 'Assignee:' expect(page).to have_content 'Assignee'
has_select?('issue_assignee_id', has_select?('issue_assignee_id',
selected: project.team.members.first.name) selected: project.team.members.first.name)
end end
...@@ -241,12 +244,16 @@ describe 'Issues', feature: true do ...@@ -241,12 +244,16 @@ describe 'Issues', feature: true do
it 'with dropdown menu' do it 'with dropdown menu' do
visit namespace_project_issue_path(project.namespace, project, issue) visit namespace_project_issue_path(project.namespace, project, issue)
find('.context'). find('.issuable-sidebar').
select(milestone.title, from: 'issue_milestone_id') select(milestone.title, from: 'issue_milestone_id')
click_button 'Update Issue' click_button 'Update Issue'
expect(page).to have_content "Milestone changed to #{milestone.title}" expect(page).to have_content "Milestone changed to #{milestone.title}"
expect(page).to have_content "Milestone: #{milestone.title}"
page.within('.milestone') do
expect(page).to have_content milestone.title
end
has_select?('issue_assignee_id', selected: milestone.title) has_select?('issue_assignee_id', selected: milestone.title)
end end
end end
...@@ -279,13 +286,19 @@ describe 'Issues', feature: true do ...@@ -279,13 +286,19 @@ describe 'Issues', feature: true do
it 'allows user to remove assignee', js: true do it 'allows user to remove assignee', js: true do
visit namespace_project_issue_path(project.namespace, project, issue) visit namespace_project_issue_path(project.namespace, project, issue)
expect(page).to have_content "Assignee: #{user2.name}"
first('#s2id_issue_assignee_id').click page.within('.assignee') do
expect(page).to have_content user2.name
end
find('.assignee .edit-link').click
sleep 2 # wait for ajax stuff to complete sleep 2 # wait for ajax stuff to complete
first('.user-result').click first('.user-result').click
expect(page).to have_content 'Assignee: none' page.within('.assignee') do
expect(page).to have_content 'None'
end
sleep 2 # wait for ajax stuff to complete sleep 2 # wait for ajax stuff to complete
expect(issue.reload.assignee).to be_nil expect(issue.reload.assignee).to be_nil
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