[#369] pull request page: discussion tab

This commit is contained in:
Alexander Machehin 2014-12-18 14:59:02 +05:00
parent 648881531c
commit 9cc4e2d27c
18 changed files with 247 additions and 87 deletions

View File

@ -11,6 +11,16 @@ commentService = ($http) ->
params = { comment: { body: body }} params = { comment: { body: body }}
$http.post(path, params) $http.post(path, params)
addInline: (project, commentable, body, params) ->
path = getPath('add', project, commentable)
params = {
comment: { body: body },
in_reply: params.in_reply,
line: params.line,
path: params.path
}
$http.post(path, params)
update: (project, commentable, id) -> update: (project, commentable, id) ->
path = getPath('update', project, commentable, id) path = getPath('update', project, commentable, id)
params = { comment: { body: $('#comment-'+id+'-body').val() }} params = { comment: { body: $('#comment-'+id+'-body').val() }}

View File

@ -1,15 +1,36 @@
CommentsController = (Comment, Preview, confirmMessage, $compile, $scope) -> CommentsController = (Comment, Preview, confirmMessage, $compile, $scope) ->
list = null inlineCommentParams = {}
list = null
new_inline_form = $('.new_inline_comment_form.hidden')
compileHTML = (data) ->
template = angular.element(data)
linkFn = $compile(template)
linkFn($scope)
setInlineCommentParams = (params) ->
inlineCommentParams = params
findInlineComments = (params) ->
if params.in_reply
$('#comment'+params.in_reply).parents('tr').find('td .line-comment:last')
else
$()
vm = this vm = this
vm.isDisabledNewInlineCommentButton = ->
vm.processing || vm.new_inline_body is '' || !vm.new_inline_body
vm.isDisabledNewCommentButton = -> vm.isDisabledNewCommentButton = ->
vm.processing || vm.new_body is '' || !vm.new_body vm.processing || vm.new_body is '' || !vm.new_body
vm.previewBody = (id) -> vm.previewBody = (id) ->
if id is 'new-comment' if id is 'new-comment'
body = vm.new_body body = vm.new_body
else if id is 'new-inline-comment'
body = vm.new_inline_body
else else
body = $('#'+id+'-body').val() body = $('#'+id+'-body').val()
@ -43,19 +64,15 @@ CommentsController = (Comment, Preview, confirmMessage, $compile, $scope) ->
else else
false false
vm.add = () -> vm.add = ->
new_id = null
vm.processing = true vm.processing = true
promise = Comment.add(vm.project, vm.commentable, vm.new_body) promise = Comment.add(vm.project, vm.commentable, vm.new_body)
promise.then (response) -> promise.then (response) ->
template = angular.element(response.data) element = compileHTML(response.data.html)
linkFn = $compile(template)
element = linkFn($scope)
list.append(element) list.append(element)
vm.new_body = '' vm.new_body = ''
new_id = template.find('div.panel.panel-default:last').attr('id') location.hash = "#comment" + response.data.id;
location.hash = "#" + new_id;
vm.processing = false vm.processing = false
false false
@ -84,11 +101,50 @@ CommentsController = (Comment, Preview, confirmMessage, $compile, $scope) ->
else else
return false return false
vm.showInlineForm = (params = {}) ->
line_comments = findInlineComments(params)
return false if line_comments.count is 0
vm.new_inline_body = null
vm.hideInlineForm()
setInlineCommentParams(params)
new_form = new_inline_form.html()
new_form = compileHTML(new_form)
line_comments.append(new_form)
line_comments.find('#new_inline_comment').addClass('cloned')
true
vm.hideInlineForm = ->
$('#new_inline_comment.cloned').remove()
inlineCommentParams = {}
false
vm.hideInlineCommentButton = (params = {}) ->
_.isEqual(inlineCommentParams, params)
vm.addInline = ->
inline_comments = findInlineComments(inlineCommentParams)
return false if inline_comments.count is 0
vm.processing = true
promise = Comment.addInline(vm.project, vm.commentable, vm.new_inline_body, inlineCommentParams)
promise.then (response) ->
element = compileHTML(response.data.html)
vm.hideInlineForm()
inline_comments.append(element)
vm.new_inline_body = ''
location.hash = "#comment" + response.data.id;
vm.processing = false
false
vm.init = (project, commentable = {}) -> vm.init = (project, commentable = {}) ->
vm.project = project vm.project = project
vm.commentable = commentable vm.commentable = commentable
vm.processing = false vm.processing = false
vm.k = 10
if commentable.kind is 'issue' if commentable.kind is 'issue'
list = $('#comments_list') list = $('#comments_list')
else if commentable.kind is 'pull' else if commentable.kind is 'pull'

View File

@ -0,0 +1,60 @@
table.table.diff.inline
border: 1px solid #DDD
tr.changes
pre
padding: 0
margin: 0
background: none
border: none
.diff-content
padding: 0
margin: 0
tr
td.header
background: whitesmoke
padding: 0 0 0 10px
td.code, td.line_numbers
padding: 0 0 0 10px
border-top: none
td.line_numbers
background-color: #ECECEC
border-right: 1px solid #DDD
text-align: right
vertical-align: middle
padding: 0 6px
td.code.del
background-color: #FFDDDD
.idiff
background-color: #F2ACAD
td.code.ins
background-color: #DDFFDD
td.code.highlight-line
background-color: #FFFFCC
tr.inline-comments
border-top: 1px solid #DDD
.add_line-comment
position: absolute
width: 25px
height: 18px
margin-left: -103px
margin-top: 0
cursor: pointer
opacity: 0
filter: alpha(Opacity=0)
-moz-opacity: 0
tr:hover .add_line-comment
opacity: 1
filter: alpha(Opacity=100)
-moz-opacity: 1

View File

@ -8,16 +8,19 @@ class Projects::CommentsController < Projects::BaseController
include CommentsHelper include CommentsHelper
def create def create
if !@comment.set_additional_data params respond_to do |format|
render online: I18n.t("flash.comment.save_error"), layout: false if !@comment.set_additional_data params
elsif @comment.save format.json {
locals = { render json: {
comment: @comment, error: I18n.t("flash.comment.save_error"),
data: { project: @project, commentable: @commentable } message: @comment.errors.full_messages
} }
render partial: 'projects/comments/comment', locals: locals, layout: false }
else elsif @comment.save
render online: I18n.t("flash.comment.save_error"), layout: false format.json {}
else
format.json { render json: { error: I18n.t("flash.comment.save_error") }, status: 422 }
end
end end
end end
@ -38,11 +41,6 @@ class Projects::CommentsController < Projects::BaseController
render json: nil render json: nil
end end
def new_line
@path = view_context.project_commentable_comments_path(@project, @commentable)
render layout: false
end
protected protected
def find_commentable def find_commentable

View File

@ -36,7 +36,7 @@ module DiffHelper
end end
prepare(args.merge({filepath: filepath, comments: comments, in_discussion: in_discussion})) prepare(args.merge({filepath: filepath, comments: comments, in_discussion: in_discussion}))
res = '<table class="diff inline" cellspacing="0" cellpadding="0" ng-non-bindable>' res = '<table class="table diff inline" cellspacing="0" cellpadding="0">'
res << '<tbody>' res << '<tbody>'
res << renderer(diff_display.data) #diff_display.render(Git::Diff::InlineCallback.new comments, path) res << renderer(diff_display.data) #diff_display.render(Git::Diff::InlineCallback.new comments, path)
res << tr_line_comments(comments) if in_discussion res << tr_line_comments(comments) if in_discussion
@ -76,8 +76,8 @@ module DiffHelper
<td class='line_numbers'></td> <td class='line_numbers'></td>
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number}
<td class='code ins'> <td class='code ins'>
#{line_comment} #{line_comment_icon}
<pre>#{render_line(line)}</pre> <pre ng-non-bindable>#{render_line(line)}</pre>
</td> </td>
</tr> </tr>
#{render_line_comments}" #{render_line_comments}"
@ -89,8 +89,8 @@ module DiffHelper
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number}
<td class='line_numbers'></td> <td class='line_numbers'></td>
<td class='code del'> <td class='code del'>
#{line_comment} #{line_comment_icon}
<pre>#{render_line(line)}</pre> <pre ng-non-bindable>#{render_line(line)}</pre>
</td> </td>
</tr> </tr>
#{render_line_comments}" #{render_line_comments}"
@ -98,12 +98,12 @@ module DiffHelper
def modline(line) def modline(line)
set_line_number set_line_number
"<tr clas='chanes line'> "<tr clas='changes line'>
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number}
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number}
<td class='code unchanged modline'> <td class='code unchanged modline'>
#{line_comment} #{line_comment_icon}
<pre>#{render_line(line)}</pre> <pre ng-non-bindable>#{render_line(line)}</pre>
</td> </td>
</tr> </tr>
#{render_line_comments}" #{render_line_comments}"
@ -115,8 +115,8 @@ module DiffHelper
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number}
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number}
<td class='code unchanged unmodline'> <td class='code unchanged unmodline'>
#{line_comment} #{line_comment_icon}
<pre>#{render_line(line)}</pre> <pre ng-non-bindable>#{render_line(line)}</pre>
</td> </td>
</tr> </tr>
#{render_line_comments}" #{render_line_comments}"
@ -132,11 +132,11 @@ module DiffHelper
def nonewlineline(line) def nonewlineline(line)
set_line_number set_line_number
"<tr class='changes'> "<tr class='changes' ng-non-bindable>
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number}
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number}
<td class='code modline unmodline'> <td class='code modline unmodline'>
#{line_comment} #{line_comment_icon}
<pre>#{render_line(line)}</pre> <pre>#{render_line(line)}</pre>
</td> </td>
</tr> </tr>
@ -226,9 +226,14 @@ module DiffHelper
@num_line = @num_line.succ @num_line = @num_line.succ
end end
def line_comment def line_comment_icon
return if @no_commit_comment || (@in_discussion && @add_reply_id && @line_comments[0].data[:line].to_i != @num_line) return if @no_commit_comment || (@in_discussion && @add_reply_id && @line_comments[0].data[:line].to_i != @num_line)
link_to image_tag('line_comment.png', alt: t('layout.comments.new_header')), new_comment_path, class: 'add_line-comment' if current_user if current_user
link_to image_tag('line_comment.png', alt: t('layout.comments.new_header')),
'#new_inline_comment',
class: 'add_line-comment',
'ng-click' => "commentsCtrl.showInlineForm(#{new_inline_comment_params.to_json})"
end
end end
def render_line_comments def render_line_comments
@ -246,24 +251,34 @@ module DiffHelper
def tr_line_comments comments def tr_line_comments comments
return if @no_commit_comment return if @no_commit_comment
res="<tr class='inline-comments'> res="<tr class='line-comments'>
<td class='line_numbers' colspan='2'>#{comments.count}</td> <td class='line_numbers' colspan='2'>#{comments.count}</td>
<td>" <td>"
comments.each do |comment| comments.each do |comment|
res << "<div class='line-comments'> res << "<div class='line-comment'>
#{render 'projects/comments/comment', comment: comment, data: {project: @project, commentable: @commentable, add_anchor: 'inline', in_discussion: @in_discussion}} #{render 'projects/comments/comment', comment: comment, data: {project: @project, commentable: @commentable, add_anchor: 'inline', in_discussion: @in_discussion}}
</div>" </div>"
end end
res << link_to(t('layout.comments.new_inline'), new_comment_path, class: 'new_inline_comment button') if current_user if current_user
res << link_to( t('layout.comments.new_inline'),
'#new_inline_comment',
class: 'btn btn-primary',
'ng-click' => "commentsCtrl.showInlineForm(#{new_inline_comment_params.to_json})",
'ng-hide' => "commentsCtrl.hideInlineCommentButton(#{new_inline_comment_params.to_json})" )
end
res << "</td></tr>" res << "</td></tr>"
end end
# def new_comment_path
# hash = {path: @filepath, line: @num_line}
# if @commentable.is_a? Issue
# project_new_line_pull_comment_path(@project, @commentable, hash.merge({in_reply: @add_reply_id}))
# elsif @commentable.is_a? Grit::Commit
# new_line_commit_comment_path(@project, @commentable, hash)
# end
# end
def new_comment_path def new_inline_comment_params
hash = {path: @filepath, line: @num_line} { path: @filepath, line: @num_line, in_reply: @add_reply_id }
if @commentable.is_a? Issue
project_new_line_pull_comment_path(@project, @commentable, hash.merge({in_reply: @add_reply_id}))
elsif @commentable.is_a? Grit::Commit
new_line_commit_comment_path(@project, @commentable, hash)
end
end end
end end

View File

@ -9,7 +9,7 @@ h3
.pull-right= render 'projects/comments/button_md_help' .pull-right= render 'projects/comments/button_md_help'
.panel-body .panel-body
= render 'projects/comments/body', f: f, id: 'new-comment', ctrl: 'commentsCtrl', = render 'projects/comments/body', f: f, id: 'new-comment', ctrl: 'commentsCtrl',
ang_model: 'commentsCtrl.new_body' ang_model: 'new_body'
hr hr
button.btn.btn-primary[ ng-disabled = 'commentsCtrl.isDisabledNewCommentButton()' button.btn.btn-primary[ ng-disabled = 'commentsCtrl.isDisabledNewCommentButton()'
ng-click = 'commentsCtrl.add()' ] ng-click = 'commentsCtrl.add()' ]

View File

@ -4,7 +4,7 @@ tabset
- if defined?(ang_model) - if defined?(ang_model)
= f.input :body, label: false, = f.input :body, label: false,
input_html: { rows: 10, id: "#{id}-body", input_html: { rows: 10, id: "#{id}-body",
'ng-model' => ang_model, 'ng-value' => ang_model } 'ng-model' => "#{ctrl}.#{ang_model}", 'ng-value' => "#{ctrl}.#{ang_model}" }
- else - else
= f.input :body, label: false, = f.input :body, label: false,
input_html: { rows: 10, id: "#{id}-body" } input_html: { rows: 10, id: "#{id}-body" }

View File

@ -1,5 +1,5 @@
- CommentPresenter.present(comment, data) do |presenter| - CommentPresenter.present(comment, data) do |presenter|
== render 'shared/feed_message', presenter: presenter == render 'shared/feed_message.html.slim', presenter: presenter
-unless comment.automatic -unless comment.automatic
.open-comment.hidden class = "comment-#{comment.id}" id = "update-comment#{comment.id}" .open-comment.hidden class = "comment-#{comment.id}" id = "update-comment#{comment.id}"
h3.tmargin0= t("layout.comments.edit_header") h3.tmargin0= t("layout.comments.edit_header")
@ -8,9 +8,9 @@
.panel-heading .panel-heading
h3.panel-title h3.panel-title
= f.label :body = f.label :body
.pull-right== render 'projects/comments/button_md_help' .pull-right== render 'projects/comments/button_md_help.html.slim'
.panel-body .panel-body
== render 'projects/comments/body', f: f, id: "comment-#{comment.id}", == render 'projects/comments/body.html.slim', f: f, id: "comment-#{comment.id}",
ctrl: 'commentsCtrl' ctrl: 'commentsCtrl'
- anchor = "#comment#{comment.id}" - anchor = "#comment#{comment.id}"
a.btn.btn-primary[ ng-disabled = 'commentsCtrl.processing' a.btn.btn-primary[ ng-disabled = 'commentsCtrl.processing'

View File

@ -0,0 +1,4 @@
.line-comment
- locals = { comment: @comment, data: { project: @project, commentable: @commentable }}
== render 'projects/comments/comment.html.slim', locals

View File

@ -0,0 +1,19 @@
.new_inline_comment_form.hidden
#new_inline_comment
h3
= t('layout.comments.new_header')
= simple_form_for Comment.new, url: '', html: { method: :post } do |f|
.panel.panel-info
.panel-heading
h3.panel-title
= f.label :body
.pull-right= render 'projects/comments/button_md_help'
.panel-body
= render 'projects/comments/body', f: f, id: 'new-inline-comment', ctrl: 'commentsCtrl',
ang_model: 'new_inline_body'
hr
button.btn.btn-primary[ ng-disabled = 'commentsCtrl.isDisabledNewInlineCommentButton()'
ng-click = 'commentsCtrl.addInline()' ]
= t('layout.create')
=< link_to t('layout.cancel'), '', 'ng-click' => 'commentsCtrl.hideInlineForm()'

View File

@ -0,0 +1,2 @@
json.id @comment.id
json.html render partial: 'projects/comments/line_comment.html.slim'

View File

@ -1,11 +0,0 @@
#open-comment.comment.view.new_line_comment
=render 'projects/comments/button_md_help'
%h3.tmargin0= t("layout.comments.new_header")
= form_for :comment, url: @path, method: :post, html: { class: :form } do |f|
= render "projects/comments/form", f: f, id: 'new_line'
.comment-left
=link_to t('layout.cancel'), '#', class: 'cancel_inline_comment button'
=hidden_field_tag :path, params[:path]
=hidden_field_tag :line, params[:line]
=hidden_field_tag :in_reply, params[:in_reply] if params[:in_reply].present?
.both

View File

@ -18,5 +18,5 @@ div.commits_activity
data-toggle = 'collapse' data-toggle = 'collapse'
data-target = "#content-expand#{item_no}" ] data-target = "#content-expand#{item_no}" ]
- if presenter.content? - if presenter.content?
.collapse[ id = (presenter.expandable? ? "content-expand#{item_no}" : '') ] .collapse id = (presenter.expandable? ? "content-expand#{item_no}" : '')
.cm-s-default.md_and_cm= markdown presenter.content .cm-s-default.md_and_cm= markdown presenter.content

View File

@ -9,7 +9,6 @@ hr
-unless item.created_from_commit_hash -unless item.created_from_commit_hash
== render 'projects/comments/comment', comment: item, data: {project: @project, commentable: @commentable} == render 'projects/comments/comment', comment: item, data: {project: @project, commentable: @commentable}
-else -else
div[] there!
- GitPresenters::CommitAsMessagePresenter.present(nil, comment: item) do |presenter| - GitPresenters::CommitAsMessagePresenter.present(nil, comment: item) do |presenter|
== render 'shared/feed_message', presenter: presenter, item_no: "-#{item.id}" == render 'shared/feed_message', presenter: presenter, item_no: "-#{item.id}"
-elsif item.is_a? Grit::Commit -elsif item.is_a? Grit::Commit
@ -19,10 +18,13 @@ hr
-commits_queue.clear -commits_queue.clear
-unless item[1].first.data[:actual] -unless item[1].first.data[:actual]
-exp_id = "expand-comment#{item[1].first.id}" -exp_id = "expand-comment#{item[1].first.id}"
.activity .activity.panel.panel-default
=t '.show_outdated_diff' .panel-heading
span.data-expander.collapsed[ id = exp_id] &nbsp; => t '.show_outdated_diff'
.hidden id = "content-#{exp_id}" span>[ class = 'glyphicon glyphicon-chevron-down pointer'
data-toggle = 'collapse'
data-target = "#content-#{exp_id}" ]
.panel-body.collapse id = "content-#{exp_id}"
== render 'projects/pull_requests/discussion_comments', item: item, diff_counter: diff_counter == render 'projects/pull_requests/discussion_comments', item: item, diff_counter: diff_counter
-else -else
== render 'projects/pull_requests/discussion_comments', item: item, diff_counter: diff_counter == render 'projects/pull_requests/discussion_comments', item: item, diff_counter: diff_counter

View File

@ -1,15 +0,0 @@
-comment = item[1].first
.file
.top
.l=comment.data[:view_path]
-if comment.actual_inline_comment? @pull.diff
.r=link_to t("layout.pull_requests.view_full_changes"),
"#{project_commentable_path(@project, @commentable)}##{comment_anchor(comment)}",
class: 'link_to_full_changes'
-else
.r
=t'projects.pull_requests.outdated_diff'
=image_tag 'x.png'
.clear
.diff_data=render_diff(comment.inline_diff, diff_counter: diff_counter, comments: item[1], filepath: comment.data[:path], diff_prefix: 'discussion')

View File

@ -0,0 +1,18 @@
-comment = item[1].first
.panel.panel-default
.panel-heading
=comment.data[:view_path]
.pull-right
-if comment.actual_inline_comment? @pull.diff
= link_to t("layout.pull_requests.view_full_changes"),
"#{project_commentable_path(@project, @commentable)}##{comment_anchor(comment)}",
class: 'link_to_full_changes'
-else
=> t'projects.pull_requests.outdated_diff'
.fa.fa-close.fa-lg.text-danger
== render_diff(comment.inline_diff,
diff_counter: diff_counter,
comments: item[1],
filepath: comment.data[:path],
diff_prefix: 'discussion')

View File

@ -25,12 +25,15 @@ div[ ng-controller = 'PullRequestController'
#pull-activity== render 'activity' #pull-activity== render 'activity'
- if current_user - if current_user
hr hr
== render "projects/comments/add", project: @project, commentable: @issue == render 'projects/comments/add', project: @project, commentable: @issue
/ /
.pull_status .pull_status
== render 'status' == render 'status'
/ /
== render 'diff_commits_tabs' unless @pull.already? == render 'diff_commits_tabs' unless @pull.already?
div ng-non-bindable = true
== render 'projects/comments/new_line'
- content_for :additional_scripts do - content_for :additional_scripts do
== render 'projects/issues/init_service.js.erb' == render 'projects/issues/init_service.js.erb'

View File

@ -346,7 +346,6 @@ Rosa::Application.routes.draw do
end end
post '/preview' => 'projects#preview', as: 'md_preview' post '/preview' => 'projects#preview', as: 'md_preview'
post 'refs_list' => 'projects#refs_list', as: 'refs_list' post 'refs_list' => 'projects#refs_list', as: 'refs_list'
get '/pull_requests/:issue_id/add_line_comments(.:format)' => "comments#new_line", as: :new_line_pull_comment
put 'schedule' => 'projects#schedule' put 'schedule' => 'projects#schedule'
end end