Add edit&delete module/task comments functionality

This required a minor fix of comments.js.
This commit is contained in:
Luka Murn 2016-08-25 09:26:45 +02:00
parent f0d9cb96fa
commit c92d016f65
6 changed files with 122 additions and 63 deletions

View file

@ -1,17 +1,19 @@
function initCommentOptions(scrollableContainer) {
function initCommentOptions(scrollableContainer, useParentOffset = true) {
document.addEventListener('scroll', function (event) {
var $target = $(event.target);
if ($target.length && $target.is(scrollableContainer)) {
scrollCommentOptions($target.find(".dropdown-comment"));
scrollCommentOptions($target.find(".dropdown-comment"), useParentOffset);
}
}, true);
}
function scrollCommentOptions(selector) {
function scrollCommentOptions(selector, useParentOffset = true) {
_.each(selector, function(el) {
var $el = $(el);
$el.find(".dropdown-menu-fixed").css("top", $el.offset().top + 20);
var offset = useParentOffset ? $el.offset().top : $el.position().top;
$el.find(".dropdown-menu-fixed")
.offset({ top: (offset + 20) });
});
}

View file

@ -1,3 +1,5 @@
//= require comments
//************************************
// CONSTANTS
//************************************
@ -321,6 +323,11 @@ function initializeFullZoom() {
// Restore draggable position
restoreDraggablePosition($("#diagram"), $("#canvas-container"));
// Initialize comments
initCommentOptions("ul.content-comments", false);
initEditComments(".panel.module-large .tab-content");
initDeleteComments(".panel.module-large .tab-content");
}
function destroyFullZoom() {
@ -337,6 +344,13 @@ function destroyFullZoom() {
$("li[data-module-id]").off("mouseenter mouseleave");
$("li[data-module-id] > span > a.canvas-center-on").off("click");
// Clean up comments listeners
$(document).off("scroll");
$(".panel.module-large .tab-content")
.off("click", "[data-action=edit-comment]");
$(".panel.module-large .tab-content")
.off("click", "[data-action=delete-comment]");
// Remember the draggable position
rememberDraggablePosition($("#diagram"), $("#canvas-container"));
}
@ -676,15 +690,13 @@ function bindFullZoomAjaxTabs() {
.on("ajax:success", function (e, data) {
if (data.html) {
var list = $form.parents("ul");
var s1 = data.html
var id = s1.substring(s1.lastIndexOf("delete(")+7,s1.lastIndexOf(")'"))
// Remove potential "no comments" element
list.parent().find(".content-comments")
.find("li.no-comments").remove();
list.parent().find(".content-comments")
.prepend("<li class='comment' id='"+id+"'>" + data.html + "</li>")
.prepend("<li class='comment'>" + data.html + "</li>")
.scrollTop(0);
list.parents("ul").find("> li.comment:gt(8)").remove();
$("#comment_message", $form).val("");
@ -730,6 +742,12 @@ function bindFullZoomAjaxTabs() {
} else {
moreBtn.attr("href", data.more_url);
}
// Reposition dropdown comment options
scrollCommentOptions(
listItem.closest(".content-comments").find(".dropdown-comment"),
false
);
}
});
}
@ -3486,43 +3504,3 @@ function showTutorial() {
var currentProjectId = $("#canvas-container").attr("data-project-id");
return tutorialProjectId == currentProjectId;
}
function module_comment_edit(id) {
document.getElementById('edit_comment_'+id).type='text';
$('#span_comment_'+id).hide();
return false;
}
function module_update_comment(id) {
if (document.getElementById('edit_comment_'+id).type=='text') {
var txt = document.getElementById('edit_comment_'+id).value;
$.ajax({
type: "POST",
url: '/projects/update_comment_modules',
dataType: 'json',
data: {id: id, msg: txt},
success: function (data) {
document.getElementById('edit_comment_'+id).type='hidden';
var txt = document.getElementById('edit_comment_'+id).value;
$('#span_comment_'+id).text(txt);
$('#span_comment_'+id).show();
}
});
}
}
function module_comment_delete(id) {
if (confirm('Are you sure you want to delete this comment?')) {
$.ajax({
type: "POST",
url: '/projects/delete_comment_modules',
dataType: 'json',
data: {id: id},
success: function (data) {
$('.content-comments').find('#'+id).remove();
}
});
}
return false;
}

View file

@ -2,6 +2,8 @@ class MyModuleCommentsController < ApplicationController
before_action :load_vars
before_action :check_view_permissions, only: [ :index ]
before_action :check_add_permissions, only: [ :new, :create ]
before_action :check_edit_permissions, only: [:edit, :update]
before_action :check_destroy_permissions, only: [:destroy]
def index
@comments = @my_module.last_comments(@last_comment_id, @per_page)
@ -77,6 +79,46 @@ class MyModuleCommentsController < ApplicationController
end
end
def edit
@update_url = my_module_my_module_comment_path(@my_module, @comment, format: :json)
respond_to do |format|
format.json do
render json: {
html: render_to_string(
partial: '/comments/edit.html.erb'
)
}
end
end
end
def update
@comment.message = comment_params[:message]
respond_to do |format|
format.json do
if @comment.save
render json: {}, status: :ok
else
render json: { errors: @comment.errors.to_hash(true) },
status: :unprocessable_entity
end
end
end
end
def destroy
respond_to do |format|
format.json do
if @comment.destroy
render json: {}, status: :ok
else
render json: { message: I18n.t('comments.delete_error') },
status: :unprocessable_entity
end
end
end
end
private
def load_vars
@ -101,6 +143,15 @@ class MyModuleCommentsController < ApplicationController
end
end
def check_edit_permissions
@comment = Comment.find_by_id(params[:id])
render_403 unless @comment.present? && can_edit_module_comment(@comment)
end
def check_destroy_permissions
@comment = Comment.find_by_id(params[:id])
render_403 unless @comment.present? && can_delete_module_comment(@comment)
end
def comment_params
params.require(:comment).permit(:message)

View file

@ -1,13 +1,39 @@
<span class="text-muted pull-right"><%= l comment.created_at, format: '%H:%M' %></span>
<strong><%= comment.user.full_name %>:</strong>
<span class="input-group">
<input type="hidden" class="form-control" id="edit_comment_<%= comment.id %>" value="<%= comment.message %>" onkeydown="if (event.keyCode==13) module_update_comment(<%= comment.id %>)" >
<span id="span_comment_<%= comment.id %>" style="display:block;width:200px;word-wrap:break-word;"><%= comment.message %></span>
<div class="input-group-btn">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown"><span class="caret"></span></button>
<ul class="dropdown-menu pull-right">
<li><a href="#" onclick='return module_comment_edit(<%= comment.id %>)'>Edit</a></li>
<li><a href="#" onclick='return module_comment_delete(<%= comment.id %>)'>Delete</a></li>
<div class="pull-right">
<span class="text-muted"><%= l comment.created_at, format: '%H:%M' %></span>
<% if can_edit_module_comment(comment) || can_delete_module_comment(comment) %>
<div class="dropdown dropdown-comment">
<a href="#"
class="dropdown-toggle"
data-role="comment-options"
type="button"
id="comment-<%= comment.id %>-dropdown"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true">
<span class="caret"></span>
</a>
<ul class="dropdown-menu dropdown-menu-fixed" aria-labelledby="comment-<%= comment.id %>-dropdown">
<li class="dropdown-header"><%= I18n.t('comments.options_dropdown.header') %></li>
<li>
<a href="#"
data-action="edit-comment"
data-url="<%= edit_my_module_my_module_comment_path(comment.my_module_comment.my_module, comment, format: :json) %>">
<%= t('comments.options_dropdown.edit') %>
</a>
</li>
<li>
<a href="#"
data-action="delete-comment"
data-url="<%= my_module_my_module_comment_path(comment.my_module_comment.my_module, comment, format: :json) %>"
data-confirm-message="<%= t('comments.delete_confirm') %>">
<%= t('comments.options_dropdown.delete') %>
</a>
</li>
</ul>
</div>
</span>
<% end %>
</div>
<strong><%= comment.user.full_name %>:</strong>
<div data-role="comment-message-container">
<p data-role="comment-message"><%= comment.message %></p>
</div>

View file

@ -7,7 +7,7 @@
<%= render 'my_module_comments/list.html.erb', comments: @comments %>
<% end %>
<% if @comments.length == @per_page %>
<li class="text-center">
<li class="comment-more text-center">
<a class="btn btn-default btn-more-comments" href="<%= more_comments_url %>" data-remote="true">
<%=t "experiments.canvas.popups.more_comments" %>
</a>

View file

@ -2,12 +2,14 @@
<% current_day = DateTime.current.strftime('%j').to_i %>
<% comments.each do |comment| %>
<li class="comment" id="<%= comment.id %>">
<% comment_day = comment.created_at.strftime('%j').to_i %>
<% if comment_day < current_day and comment_day < day %>
<% day = comment.created_at.strftime('%j').to_i %>
<p class="text-center"><%= comment.created_at.strftime('%d.%m.%Y') %></p>
<li class="comment-date-separator">
<p class="text-center"><%= comment.created_at.strftime('%d.%m.%Y') %></p>
</li>
<% end %>
<%= render 'my_module_comments/comment.html.erb', comment: comment %></li>
<!--= render 'project_comments/comment.html.erb', comment: comment %></li-->
<li class="comment">
<%= render 'my_module_comments/comment.html.erb', comment: comment %>
</li>
<% end %>