[#369] project issue page: comments and so on
This commit is contained in:
parent
f4c83ac86a
commit
8d9ec48ff9
|
@ -0,0 +1,29 @@
|
|||
commentService = ($http) ->
|
||||
getPath = (kind, project, commentable, id) ->
|
||||
if commentable.kind is 'issue'
|
||||
if kind is 'remove' or kind is 'update'
|
||||
return Routes.project_issue_comment_path(project, commentable.id, id)
|
||||
else if kind is 'add'
|
||||
return Routes.project_issue_comments_path(project, commentable.id)
|
||||
|
||||
{
|
||||
add: (project, commentable, body) ->
|
||||
path = getPath('add', project, commentable)
|
||||
params = { comment: { body: body }}
|
||||
$http.post(path, params)
|
||||
|
||||
update: (project, commentable, id) ->
|
||||
path = getPath('update', project, commentable, id)
|
||||
params = { comment: { body: $('#comment-'+id+'-body').val() }}
|
||||
$http.put(path, params)
|
||||
|
||||
remove: (project, commentable, id) ->
|
||||
path = getPath('remove', project, commentable, id)
|
||||
$http.delete(path)
|
||||
}
|
||||
|
||||
angular
|
||||
.module("RosaABF")
|
||||
.factory "Comment", commentService
|
||||
|
||||
commentService.$inject = ['$http']
|
|
@ -0,0 +1,104 @@
|
|||
CommentsController = (Comment, Preview, confirmMessage, $compile, $scope) ->
|
||||
|
||||
comments_list = $('#comments_list')
|
||||
|
||||
vm = this
|
||||
|
||||
vm.isDisabledNewCommentButton = ->
|
||||
vm.processing || vm.new_body is '' || !vm.new_body
|
||||
|
||||
vm.previewBody = (id) ->
|
||||
if id is 'new-comment'
|
||||
body = vm.new_body
|
||||
else
|
||||
body = $('#'+id+'-body').val()
|
||||
|
||||
if body is '' or !body
|
||||
vm.preview_body = ''
|
||||
return false
|
||||
if body is Preview.old_text
|
||||
return false
|
||||
|
||||
return false if vm.processing
|
||||
vm.processing = true
|
||||
Preview.old_text = ''
|
||||
|
||||
promise = Preview.get_preview(vm.project, body)
|
||||
promise.success( (response) ->
|
||||
vm.preview_body = response
|
||||
Preview.old_text = body
|
||||
).error( (response) ->
|
||||
vm.preview_body = 'Error :('
|
||||
)
|
||||
|
||||
vm.processing = false
|
||||
false
|
||||
|
||||
vm.toggleEditForm = (id) ->
|
||||
$('.open-comment').addClass('hidden')
|
||||
form = $('.open-comment.comment-'+id)
|
||||
if form.length is 1
|
||||
form.removeClass('hidden')
|
||||
true
|
||||
else
|
||||
false
|
||||
|
||||
vm.add = () ->
|
||||
new_id = null
|
||||
vm.processing = true
|
||||
promise = Comment.add(vm.project, vm.commentable, vm.new_body)
|
||||
promise.then (response) ->
|
||||
template = angular.element(response.data)
|
||||
linkFn = $compile(template)
|
||||
element = linkFn($scope)
|
||||
comments_list.append(element)
|
||||
|
||||
vm.new_body = ''
|
||||
new_id = comments_list.find('div.panel.panel-default:last').attr('id')
|
||||
location.hash = "#" + new_id;
|
||||
vm.processing = false
|
||||
|
||||
false
|
||||
|
||||
vm.remove = (id) ->
|
||||
return false unless confirmMessage.show()
|
||||
vm.processing = true
|
||||
promise = Comment.remove(vm.project, vm.commentable, id)
|
||||
promise.then () ->
|
||||
$('#comment'+id).remove()
|
||||
vm.processing = false
|
||||
|
||||
false
|
||||
|
||||
vm.update = (id) ->
|
||||
vm.processing = true
|
||||
promise = Comment.update(vm.project, vm.commentable, id)
|
||||
promise.then (response) ->
|
||||
form = $('#comment'+id+ ' .md_and_cm.cm-s-default').html(response.data.body)
|
||||
|
||||
vm.processing = false
|
||||
form = $('.open-comment.comment-'+id)
|
||||
if form.length is 1
|
||||
form.addClass('hidden')
|
||||
return true
|
||||
else
|
||||
return false
|
||||
|
||||
vm.init = (project, commentable = {}) ->
|
||||
vm.project = project
|
||||
vm.commentable = commentable
|
||||
vm.processing = false
|
||||
|
||||
true
|
||||
|
||||
angular
|
||||
.module("RosaABF")
|
||||
.controller "CommentsController", CommentsController
|
||||
|
||||
CommentsController.$inject = [
|
||||
'Comment'
|
||||
'Preview'
|
||||
'confirmMessage'
|
||||
'$compile'
|
||||
'$scope'
|
||||
]
|
|
@ -4,7 +4,7 @@ issueService = ($http) ->
|
|||
{
|
||||
issue: {
|
||||
title: $('#issue_title').val()
|
||||
body: $('#issue_body').val()
|
||||
body: $('#issue-body').val()
|
||||
}
|
||||
}
|
||||
else if kind is 'labels'
|
||||
|
|
|
@ -34,19 +34,20 @@ IssueController = (dataservice, $http, Issue, $rootScope, Preview, Label, confir
|
|||
vm = this
|
||||
|
||||
vm.previewBody = ->
|
||||
if vm.body is '' or !vm.body
|
||||
body = $('#issue-body').val()
|
||||
if body is '' or !body
|
||||
vm.preview_body = ''
|
||||
return false
|
||||
if vm.body is Preview.old_text
|
||||
if body is Preview.old_text
|
||||
return false
|
||||
|
||||
return false if vm.processing
|
||||
vm.processing = true
|
||||
|
||||
promise = Preview.get_preview(vm.project, vm.body)
|
||||
promise = Preview.get_preview(vm.project, body)
|
||||
promise.success( (response) ->
|
||||
vm.preview_body = response
|
||||
Preview.old_text = vm.body
|
||||
Preview.old_text = body
|
||||
).error( (response) ->
|
||||
vm.preview_body = 'Error :('
|
||||
)
|
||||
|
|
|
@ -8,17 +8,17 @@ class Projects::CommentsController < Projects::BaseController
|
|||
include CommentsHelper
|
||||
|
||||
def create
|
||||
anchor = ''
|
||||
if !@comment.set_additional_data params
|
||||
flash[:error] = I18n.t("flash.comment.save_error")
|
||||
render online: I18n.t("flash.comment.save_error"), layout: false
|
||||
elsif @comment.save
|
||||
flash[:notice] = I18n.t("flash.comment.saved")
|
||||
anchor = view_context.comment_anchor(@comment)
|
||||
locals = {
|
||||
comment: @comment,
|
||||
data: { project: @project, commentable: @commentable }
|
||||
}
|
||||
render partial: 'projects/comments/comment', locals: locals, layout: false
|
||||
else
|
||||
flash[:error] = I18n.t("flash.comment.save_error")
|
||||
flash[:warning] = @comment.errors.full_messages.join('. ')
|
||||
render online: I18n.t("flash.comment.save_error"), layout: false
|
||||
end
|
||||
redirect_to "#{project_commentable_path(@project, @commentable)}##{anchor}"
|
||||
end
|
||||
|
||||
def edit
|
||||
|
@ -28,15 +28,14 @@ class Projects::CommentsController < Projects::BaseController
|
|||
status, message = if @comment.update_attributes(params[:comment])
|
||||
[200, view_context.markdown(@comment.body)]
|
||||
else
|
||||
[400, view_context.local_alert(@comment.errors.full_messages.join('. '))]
|
||||
[422, 'error']
|
||||
end
|
||||
render inline: message, status: status
|
||||
render json: {body: message}, status: status
|
||||
end
|
||||
|
||||
def destroy
|
||||
@comment.destroy
|
||||
flash[:notice] = t("flash.comment.destroyed")
|
||||
redirect_to project_commentable_path(@project, @commentable)
|
||||
render json: nil
|
||||
end
|
||||
|
||||
def new_line
|
||||
|
|
|
@ -54,15 +54,21 @@ class CommentPresenter < ApplicationPresenter
|
|||
|
||||
def buttons
|
||||
project, commentable = options[:project], options[:commentable]
|
||||
path = helpers.project_commentable_comment_path(project, commentable, comment)
|
||||
|
||||
res = [link_to(content_tag(:i, nil, class: 'fa fa-link'), "#{helpers.project_commentable_path(project, commentable)}##{comment_anchor}", class: "#{@options[:in_discussion].present? ? 'in_discussion_' : ''}link_to_comment").html_safe]
|
||||
link_to_comment = "#{helpers.project_commentable_path(project, commentable)}##{comment_anchor}"
|
||||
klass = "#{@options[:in_discussion].present? ? 'in_discussion_' : ''}link_to_comment"
|
||||
res = [ link_to(content_tag(:i, nil, class: 'fa fa-link'),
|
||||
link_to_comment,
|
||||
class: klass).html_safe ]
|
||||
if controller.can? :update, @comment
|
||||
res << link_to(content_tag(:i, nil, class: 'fa fa-edit'), path, id: "comment-#{comment.id}", class: "edit_comment").html_safe
|
||||
res << link_to(content_tag(:i, nil, class: 'fa fa-edit'),
|
||||
"#update-comment#{comment.id}",
|
||||
'ng-click' => "commentsCtrl.toggleEditForm(#{comment_id})" ).html_safe
|
||||
end
|
||||
if controller.can? :destroy, @comment
|
||||
res << link_to(content_tag(:i, nil, class: 'fa fa-close'), path, method: "delete",
|
||||
data: { confirm: t('layout.comments.confirm_delete') }).html_safe
|
||||
res << link_to(content_tag(:i, nil, class: 'fa fa-close'),
|
||||
'',
|
||||
'ng-click' => "commentsCtrl.remove(#{comment_id})").html_safe
|
||||
end
|
||||
res
|
||||
end
|
||||
|
|
|
@ -1,32 +1,20 @@
|
|||
h3
|
||||
= t('layout.comments.new_header')
|
||||
- if Comment.issue_comment?(commentable.class)
|
||||
- new_path = project_issue_comments_path(project, commentable)
|
||||
- is_subscribed = commentable.subscribes.exists?(user_id: current_user.id)
|
||||
- subscribe_path = is_subscribed ? project_issue_subscribe_path(project, commentable, current_user.id) : project_issue_subscribes_path(project, commentable)
|
||||
- else Comment.commit_comment?(commentable.class)
|
||||
- new_path = project_commit_comments_path(project, commentable)
|
||||
- is_subscribed = Subscribe.subscribed_to_commit?(project, current_user, commentable)
|
||||
- subscribe_path = is_subscribed ? unsubscribe_commit_path(project, commentable) : subscribe_commit_path(project, commentable)
|
||||
|
||||
= simple_form_for Comment.new, url: new_path, html: { method: :post } do |f|
|
||||
= simple_form_for Comment.new, url: '', html: { method: :post } do |f|
|
||||
.panel.panel-info ng-controller = 'IssueController as issueCtrl' ng-cloak = true
|
||||
.panel-heading
|
||||
h3.panel-title
|
||||
- t('activerecord.attributes.issue.body')
|
||||
= f.label :body
|
||||
.pull-right= render 'projects/comments/button_md_help'
|
||||
.panel-body
|
||||
= render 'projects/comments/body', f: f
|
||||
= render 'projects/comments/body', f: f, id: 'new-comment', ctrl: 'commentsCtrl',
|
||||
ang_model: 'commentsCtrl.new_body'
|
||||
hr
|
||||
= f.button :submit, t('layout.create')
|
||||
button.btn.btn-primary[ ng-disabled = 'commentsCtrl.isDisabledNewCommentButton()'
|
||||
ng-click = 'commentsCtrl.add()' ]
|
||||
= t('layout.create')
|
||||
.panel-footer
|
||||
=> t('layout.comments.notifications_are')
|
||||
- if is_subscribed
|
||||
span.label.label-success>
|
||||
= t('layout.turned_on')
|
||||
= link_to t('layout.commits.unsubscribe_btn'), subscribe_path, method: :delete
|
||||
- else
|
||||
span.label.label-danger>
|
||||
= t('layout.turned_off')
|
||||
= link_to t('layout.commits.subscribe_btn'), subscribe_path, method: :post
|
||||
|
||||
== render 'projects/subscribes/subscribe_status', project: @project, commentable: @issue
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
tabset
|
||||
tab heading = t('layout.edit')
|
||||
.offset10 ng-init="issueCtrl.body = '#{f.object.body}'"
|
||||
= f.input :body, label: false,
|
||||
input_html: { rows: 10, ng_model: 'issueCtrl.body' }
|
||||
.offset10
|
||||
- if defined?(ang_model)
|
||||
= f.input :body, label: false,
|
||||
input_html: { rows: 10, id: "#{id}-body",
|
||||
'ng-model' => ang_model, 'ng-value' => ang_model }
|
||||
- else
|
||||
= f.input :body, label: false,
|
||||
input_html: { rows: 10, id: "#{id}-body" }
|
||||
|
||||
tab[ heading = t('layout.preview')
|
||||
select = 'issueCtrl.previewBody()' ]
|
||||
select = "#{ctrl}.previewBody('#{id}')" ]
|
||||
.offset10
|
||||
i.fa.fa-spinner.fa-spin.fa-lg ng-show = 'issueCtrl.processing'
|
||||
i.fa.fa-spinner.fa-spin.fa-lg ng-show = "#{ctrl}.processing"
|
||||
|
||||
div[ ng-bind-html = 'issueCtrl.preview_body'
|
||||
ng-show = '!issueCtrl.processing' ]
|
||||
div[ ng-bind-html = "#{ctrl}.preview_body"
|
||||
ng-show = "!#{ctrl}.processing" ]
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
- CommentPresenter.present(comment, data) do |presenter|
|
||||
= render 'shared/feed_message', presenter: presenter
|
||||
-unless comment.automatic
|
||||
#open-comment.comment.hidden{class: "comment-#{comment.id}"}
|
||||
=render 'projects/comments/button_md_help'
|
||||
%h3.tmargin0= t("layout.comments.edit_header")
|
||||
= simple_form_for comment, url: project_commentable_comment_path(data[:project], data[:commentable], comment), html: { class: 'form edit_comment' } do |f|
|
||||
= render "projects/comments/form", f: f, id: "#{data[:add_id]}edit_#{comment.id}"
|
||||
.comment-left
|
||||
=link_to t('layout.cancel'), '#', id: "comment-#{comment.id}", class: 'cancel_edit_comment button'
|
||||
.both
|
|
@ -0,0 +1,20 @@
|
|||
- CommentPresenter.present(comment, data) do |presenter|
|
||||
== render 'shared/feed_message', presenter: presenter
|
||||
-unless comment.automatic
|
||||
.open-comment.hidden class = "comment-#{comment.id}" id = "update-comment#{comment.id}"
|
||||
h3.tmargin0= t("layout.comments.edit_header")
|
||||
= simple_form_for comment, url: project_commentable_comment_path(data[:project], data[:commentable], comment) 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: "comment-#{comment.id}",
|
||||
ctrl: 'commentsCtrl'
|
||||
- anchor = "#comment#{comment.id}"
|
||||
a.btn.btn-primary[ ng-disabled = 'commentsCtrl.processing'
|
||||
href = anchor
|
||||
ng-click = "commentsCtrl.update(#{comment.id})" ]
|
||||
= t('layout.update')
|
||||
=< link_to t('layout.cancel'), anchor
|
|
@ -1,2 +1,2 @@
|
|||
=render 'projects/comments/body', f: f, id: id
|
||||
.comment-right= submit_tag t('layout.save'), data: {'disable-with' => t('layout.saving')}
|
||||
/.comment-right= submit_tag t('layout.save'), data: {'disable-with' => t('layout.saving')}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
%a{ name: "comments" }
|
||||
.hr
|
||||
%h3#block-list= t("layout.comments.comments_header")
|
||||
- list.each do |comment|
|
||||
-unless comment.created_from_commit_hash
|
||||
= render 'projects/comments/comment', comment: comment, data: {project: project, commentable: commentable}
|
||||
-else
|
||||
- GitPresenters::CommitAsMessagePresenter.present(nil, comment: comment) do |presenter|
|
||||
= render 'shared/feed_message', presenter: presenter, item_no: "-#{comment.id}"
|
||||
= render "projects/comments/markdown_help"
|
|
@ -0,0 +1,12 @@
|
|||
a name = 'comments'
|
||||
|
||||
h3#block-list= t("layout.comments.comments_header")
|
||||
#comments_list
|
||||
- list.each do |comment|
|
||||
-unless comment.created_from_commit_hash
|
||||
== render 'projects/comments/comment', comment: comment,
|
||||
data: { project: project, commentable: commentable }
|
||||
-else
|
||||
- GitPresenters::CommitAsMessagePresenter.present(nil, comment: comment) do |presenter|
|
||||
== render 'shared/feed_message', presenter: presenter, item_no: "-#{comment.id}"
|
||||
== render "projects/comments/markdown_help"
|
|
@ -72,6 +72,7 @@
|
|||
br
|
||||
| without syntax highlighting:
|
||||
br
|
||||
br
|
||||
| def foo:
|
||||
br
|
||||
| if not bar:
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
= f.label :body
|
||||
.pull-right= render 'projects/comments/button_md_help'
|
||||
.panel-body
|
||||
= render 'projects/comments/body', f: f
|
||||
= render 'projects/comments/body', f: f, id: 'issue', ctrl: 'issueCtrl'
|
||||
|
|
|
@ -35,10 +35,15 @@
|
|||
== render 'closed_by'
|
||||
== render 'choose_assignee'
|
||||
|
||||
== render "projects/comments/list", list: @issue.comments, project: @project, commentable: @issue
|
||||
- if current_user
|
||||
hr
|
||||
== render "projects/comments/add", project: @project, commentable: @issue if current_user
|
||||
- params = "{ kind: 'issue', id: #{@issue.serial_id} }"
|
||||
div[ ng-controller = 'CommentsController as commentsCtrl'
|
||||
ng-init = "commentsCtrl.init('#{@project.name_with_owner}', #{params})" ]
|
||||
== render "projects/comments/list", list: @issue.comments,
|
||||
project: @project, commentable: @issue
|
||||
- if current_user
|
||||
hr
|
||||
== render "projects/comments/add", project: @project, commentable: @issue
|
||||
|
||||
.col-md-9.col-sm-8.offset20 ng-show='issueCtrl.edit'
|
||||
h3= t('layout.issues.edit_header')
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
- if Comment.issue_comment?(commentable.class)
|
||||
- is_subscribed = commentable.subscribes.exists?(user_id: current_user.id)
|
||||
- subscribe_path = is_subscribed ? project_issue_subscribe_path(project, commentable, current_user.id) : project_issue_subscribes_path(project, commentable)
|
||||
- else Comment.commit_comment?(commentable.class)
|
||||
- is_subscribed = Subscribe.subscribed_to_commit?(project, current_user, commentable)
|
||||
- subscribe_path = is_subscribed ? unsubscribe_commit_path(project, commentable) : subscribe_commit_path(project, commentable)
|
||||
|
||||
- if is_subscribed
|
||||
span.label.label-success>
|
||||
= t('layout.turned_on')
|
||||
= link_to t('layout.commits.unsubscribe_btn'), subscribe_path, method: :delete
|
||||
- else
|
||||
span.label.label-danger>
|
||||
= t('layout.turned_off')
|
||||
= link_to t('layout.commits.subscribe_btn'), subscribe_path, method: :post
|
|
@ -1,29 +0,0 @@
|
|||
-if !presenter.is_reference_to_issue || can?(:show, presenter.reference_project)
|
||||
.panel.panel-default{id: presenter.comment_id? ? presenter.comment_anchor : ''}
|
||||
.panel-body
|
||||
.pull-left.roffset5
|
||||
%img{ alt: 'avatar', src: presenter.image }
|
||||
.pull-left
|
||||
%strong= presenter.header
|
||||
- if presenter.buttons?
|
||||
%span.pull-right
|
||||
|
||||
= raw presenter.buttons.join(' ').html_safe
|
||||
|
||||
= "(#{datetime_moment(presenter.date, tag: :strong)})".html_safe
|
||||
- if presenter.caption?
|
||||
.clearfix
|
||||
%span= presenter.caption
|
||||
- if presenter.expandable? and presenter.content?
|
||||
%span.data-expander.collapsed{id: "expand#{item_no}"}
|
||||
|
||||
.clearfix
|
||||
- if presenter.content?
|
||||
%div
|
||||
=presenter.issue_referenced_state if presenter.issue_referenced_state?
|
||||
.fulltext{class: "#{presenter.expandable? ? "hidden" : ''} #{presenter.caption? ? "" : "alone"}",
|
||||
id: presenter.expandable? ? "content-expand#{item_no}" : ''}
|
||||
.md_and_cm{class: presenter.is_reference_to_issue ? '' : 'cm-s-default'}
|
||||
= preserve do
|
||||
= presenter.is_reference_to_issue ? presenter.content : markdown(presenter.content)
|
||||
.clearfix
|
|
@ -0,0 +1,30 @@
|
|||
-if !presenter.is_reference_to_issue || can?(:show, presenter.reference_project)
|
||||
.panel.panel-default[ id = (presenter.comment_id? ? presenter.comment_anchor : '') ]
|
||||
.panel-body
|
||||
.pull-left.roffset5
|
||||
img alt = 'avatar' src = presenter.image
|
||||
|
||||
- if presenter.buttons?
|
||||
.pull-right
|
||||
|
|
||||
= raw presenter.buttons.join(' ').html_safe
|
||||
|
||||
.pull-left
|
||||
strong= presenter.header
|
||||
p= datetime_moment(presenter.date, tag: :strong)
|
||||
|
||||
- if presenter.caption?
|
||||
.clearfix
|
||||
span= presenter.caption
|
||||
- if presenter.expandable? and presenter.content?
|
||||
span.data-expander.collapsed[ id = "expand#{item_no}"]
|
||||
|
||||
.clearfix
|
||||
- if presenter.content?
|
||||
.offset10
|
||||
=presenter.issue_referenced_state if presenter.issue_referenced_state?
|
||||
.fulltext[ class = "#{presenter.expandable? ? "hidden" : ''} #{presenter.caption? ? "" : "alone"}"
|
||||
id = (presenter.expandable? ? "content-expand#{item_no}" : '') ]
|
||||
.md_and_cm[ class = (presenter.is_reference_to_issue ? '' : 'cm-s-default') ]
|
||||
= presenter.is_reference_to_issue ? presenter.content : markdown(presenter.content)
|
||||
.clearfix
|
|
@ -328,8 +328,8 @@ Rosa::Application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
get 'pull_requests' => 'issues#pull_requests', as: :pull_requests
|
||||
get 'labels' => 'issues#labels', as: :labels
|
||||
get 'pull_requests' => 'issues#pull_requests', as: :pull_requests
|
||||
get 'labels' => 'issues#labels', as: :labels
|
||||
post 'labels/:label_id' => 'issues#destroy_label', as: :issues_delete_label
|
||||
post 'labels/:label_id/update' => 'issues#update_label', as: :issues_update_label
|
||||
|
||||
|
|
Loading…
Reference in New Issue