mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-16 16:19:09 +08:00
#47 - Adds functionality to delete a comment. Also reduces the number of watchers.
This commit is contained in:
parent
2fd421b115
commit
9558f84b97
@ -67,6 +67,14 @@ class CommentController extends Controller
|
|||||||
public function destroy($id) {
|
public function destroy($id) {
|
||||||
$comment = $this->comment->findOrFail($id);
|
$comment = $this->comment->findOrFail($id);
|
||||||
$this->checkOwnablePermission('comment-delete', $comment);
|
$this->checkOwnablePermission('comment-delete', $comment);
|
||||||
|
$this->commentRepo->delete($comment);
|
||||||
|
$comment = $this->commentRepo->getCommentById($comment->id);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => trans('entities.comment_deleted'),
|
||||||
|
'comment' => $comment
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,10 +31,26 @@ class CommentRepo {
|
|||||||
return $comment;
|
return $comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update($comment, $input) {
|
public function update($comment, $input, $activeOnly = true) {
|
||||||
$userId = user()->id;
|
$userId = user()->id;
|
||||||
$comment->updated_by = $userId;
|
$comment->updated_by = $userId;
|
||||||
$comment->fill($input);
|
$comment->fill($input);
|
||||||
|
|
||||||
|
// only update active comments by default.
|
||||||
|
$whereClause = ['active' => 1];
|
||||||
|
if (!$activeOnly) {
|
||||||
|
$whereClause = [];
|
||||||
|
}
|
||||||
|
$comment->update($whereClause);
|
||||||
|
return $comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($comment) {
|
||||||
|
$comment->text = trans('errors.cannot_add_comment_to_draft');
|
||||||
|
$comment->html = trans('errors.cannot_add_comment_to_draft');
|
||||||
|
$comment->active = false;
|
||||||
|
$userId = user()->id;
|
||||||
|
$comment->updated_by = $userId;
|
||||||
$comment->save();
|
$comment->save();
|
||||||
return $comment;
|
return $comment;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CommentsAddActiveCol extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('comments', function (Blueprint $table) {
|
||||||
|
// add column active
|
||||||
|
$table->boolean('active')->default(true);
|
||||||
|
$table->dropIndex('comments_page_id_parent_id_index');
|
||||||
|
$table->index(['page_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('comments', function (Blueprint $table) {
|
||||||
|
// reversing the schema
|
||||||
|
$table->dropIndex('comments_page_id_index');
|
||||||
|
$table->dropColumn('active');
|
||||||
|
$table->index(['page_id', 'parent_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -683,11 +683,12 @@ module.exports = function (ngApp, events) {
|
|||||||
}]);
|
}]);
|
||||||
|
|
||||||
// CommentCrudController
|
// CommentCrudController
|
||||||
ngApp.controller('CommentReplyController', ['$scope', '$http', function ($scope, $http) {
|
ngApp.controller('CommentReplyController', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
|
||||||
const MarkdownIt = require("markdown-it");
|
const MarkdownIt = require("markdown-it");
|
||||||
const md = new MarkdownIt({html: true});
|
const md = new MarkdownIt({html: true});
|
||||||
let vm = this;
|
let vm = this;
|
||||||
$scope.errors = {};
|
$scope.errors = {};
|
||||||
|
|
||||||
vm.saveComment = function () {
|
vm.saveComment = function () {
|
||||||
let pageId = $scope.comment.pageId || $scope.pageId;
|
let pageId = $scope.comment.pageId || $scope.pageId;
|
||||||
let comment = $scope.comment.text;
|
let comment = $scope.comment.text;
|
||||||
@ -713,11 +714,9 @@ module.exports = function (ngApp, events) {
|
|||||||
if (!resp.data || resp.data.status !== 'success') {
|
if (!resp.data || resp.data.status !== 'success') {
|
||||||
return events.emit('error', trans('error'));
|
return events.emit('error', trans('error'));
|
||||||
}
|
}
|
||||||
|
// hide the comments first, and then retrigger the refresh
|
||||||
if ($scope.isEdit) {
|
if ($scope.isEdit) {
|
||||||
$scope.comment.html = resp.data.comment.html;
|
updateComment($scope.comment, resp.data);
|
||||||
$scope.comment.text = resp.data.comment.text;
|
|
||||||
$scope.comment.updated = resp.data.comment.updated;
|
|
||||||
$scope.comment.updated_by = resp.data.comment.updated_by;
|
|
||||||
$scope.$emit('evt.comment-success', $scope.comment.id);
|
$scope.$emit('evt.comment-success', $scope.comment.id);
|
||||||
} else {
|
} else {
|
||||||
$scope.comment.text = '';
|
$scope.comment.text = '';
|
||||||
@ -728,6 +727,11 @@ module.exports = function (ngApp, events) {
|
|||||||
}
|
}
|
||||||
$scope.$emit('evt.comment-success', null, true);
|
$scope.$emit('evt.comment-success', null, true);
|
||||||
}
|
}
|
||||||
|
$scope.comment.is_hidden = true;
|
||||||
|
$timeout(function() {
|
||||||
|
$scope.comment.is_hidden = false;
|
||||||
|
});
|
||||||
|
|
||||||
events.emit('success', trans(resp.data.message));
|
events.emit('success', trans(resp.data.message));
|
||||||
|
|
||||||
}, checkError(errorOp));
|
}, checkError(errorOp));
|
||||||
@ -748,6 +752,24 @@ module.exports = function (ngApp, events) {
|
|||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
ngApp.controller('CommentDeleteController', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
|
||||||
|
let vm = this;
|
||||||
|
|
||||||
|
vm.delete = function(comment) {
|
||||||
|
$http.delete(window.baseUrl(`/ajax/comment/${comment.id}`)).then(resp => {
|
||||||
|
if (!resp.data || resp.data.success !== true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateComment(comment, resp.data, $timeout, true);
|
||||||
|
}, function (resp) {
|
||||||
|
if (!resp || !resp.data || resp.data.success !== true) {
|
||||||
|
events.emit('error', trans('entities.comment_delete_fail'));
|
||||||
|
} else {
|
||||||
|
events.emit('success', trans('entities.comment_delete_success'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
|
||||||
// CommentListController
|
// CommentListController
|
||||||
ngApp.controller('CommentListController', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
|
ngApp.controller('CommentListController', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
|
||||||
@ -766,6 +788,9 @@ module.exports = function (ngApp, events) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
vm.canEdit = function (comment) {
|
vm.canEdit = function (comment) {
|
||||||
|
if (!comment.active) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (vm.permissions.comment_update_all) {
|
if (vm.permissions.comment_update_all) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -774,11 +799,11 @@ module.exports = function (ngApp, events) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
|
|
||||||
vm.canComment = function () {
|
vm.canComment = function () {
|
||||||
return vm.permissions.comment_create;
|
return vm.permissions.comment_create;
|
||||||
}
|
};
|
||||||
|
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
$http.get(window.baseUrl(`/ajax/page/${$scope.pageId}/comments/`)).then(resp => {
|
$http.get(window.baseUrl(`/ajax/page/${$scope.pageId}/comments/`)).then(resp => {
|
||||||
@ -797,7 +822,7 @@ module.exports = function (ngApp, events) {
|
|||||||
} else if (vm.totalComments === 1) {
|
} else if (vm.totalComments === 1) {
|
||||||
vm.totalCommentsStr = '1 Comments';
|
vm.totalCommentsStr = '1 Comments';
|
||||||
} else {
|
} else {
|
||||||
vm.totalCommentsStr = vm.totalComments + ' Comments'
|
vm.totalCommentsStr = vm.totalComments + ' Comments';
|
||||||
}
|
}
|
||||||
}, checkError('app'));
|
}, checkError('app'));
|
||||||
});
|
});
|
||||||
@ -806,8 +831,29 @@ module.exports = function (ngApp, events) {
|
|||||||
$scope.errors[errorGroupName] = {};
|
$scope.errors[errorGroupName] = {};
|
||||||
return function(response) {
|
return function(response) {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
function updateComment(comment, resp, $timeout, isDelete) {
|
||||||
|
if (isDelete && !resp.comment.active) {
|
||||||
|
comment.html = trans('entities.comment_deleted');
|
||||||
|
}
|
||||||
|
comment.text = resp.comment.text;
|
||||||
|
comment.updated = resp.comment.updated;
|
||||||
|
comment.updated_by = resp.comment.updated_by;
|
||||||
|
comment.active = resp.comment.active;
|
||||||
|
if (isDelete && !resp.comment.active) {
|
||||||
|
comment.html = trans('entities.comment_deleted');
|
||||||
|
} else {
|
||||||
|
comment.html = resp.comment.html;
|
||||||
|
}
|
||||||
|
if (!$timeout) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
comment.is_hidden = true;
|
||||||
|
$timeout(function() {
|
||||||
|
comment.is_hidden = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -870,7 +870,7 @@ module.exports = function (ngApp, events) {
|
|||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
|
||||||
ngApp.directive('commentReplyLink', ['$document', '$compile', '$http', function ($document, $compile, $http) {
|
ngApp.directive('commentReplyLink', ['$document', '$compile', function ($document, $compile) {
|
||||||
return {
|
return {
|
||||||
scope: {
|
scope: {
|
||||||
comment: '='
|
comment: '='
|
||||||
@ -916,4 +916,24 @@ module.exports = function (ngApp, events) {
|
|||||||
$existingElement.remove();
|
$existingElement.remove();
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
ngApp.directive('commentDeleteLink', ['$window', function ($window) {
|
||||||
|
return {
|
||||||
|
controller: 'CommentDeleteController',
|
||||||
|
scope: {
|
||||||
|
comment: '='
|
||||||
|
},
|
||||||
|
link: function (scope, element, attr, ctrl) {
|
||||||
|
|
||||||
|
element.on('click', function() {
|
||||||
|
var resp = $window.confirm('This will remove the content of the comment, are you sure you want to continue?');
|
||||||
|
if (!resp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl.delete(scope.comment);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
||||||
};
|
};
|
||||||
|
@ -6,16 +6,20 @@
|
|||||||
<div class="comment-header">
|
<div class="comment-header">
|
||||||
<a href="@{{::comment.created_by.profile_url}}">@{{ ::comment.created_by.name }}</a>
|
<a href="@{{::comment.created_by.profile_url}}">@{{ ::comment.created_by.name }}</a>
|
||||||
</div>
|
</div>
|
||||||
<div ng-bind-html="comment.html" class="comment-body">
|
<div ng-bind-html="comment.html" ng-if="::comment.active" class="comment-body">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div ng-if="::!comment.active" class="comment-body">
|
||||||
|
{{ trans('entites.comment_deleted') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="comment-actions">
|
<div class="comment-actions">
|
||||||
<ul>
|
<ul ng-if="!comment.is_hidden">
|
||||||
<li ng-if="::(level < 3 && vm.canComment())"><a href="#" comment-reply-link no-comment-reply-dupe="true" comment="comment" is-reply="true">Reply</a></li>
|
<li ng-if="::(level < 3 && vm.canComment())"><a href="#" comment-reply-link no-comment-reply-dupe="true" comment="comment" is-reply="true">Reply</a></li>
|
||||||
<li ng-if="::vm.canEdit(comment)"><a href="#" comment-reply-link no-comment-reply-dupe="true" comment="comment" >Edit</a></li>
|
<li ng-if="::vm.canEdit(comment)"><a href="#" comment-reply-link no-comment-reply-dupe="true" comment="comment" >Edit</a></li>
|
||||||
|
<li ng-if="::vm.canEdit(comment, true)"><a href="#" comment-delete-link comment="comment" >Delete</a></li>
|
||||||
<li>Created <a title="@{{::comment.created.day_time_str}}" href="#comment-@{{::comment.id}}-@{{::pageId}}">@{{::comment.created.diff}}</a></li>
|
<li>Created <a title="@{{::comment.created.day_time_str}}" href="#comment-@{{::comment.id}}-@{{::pageId}}">@{{::comment.created.diff}}</a></li>
|
||||||
<li ng-if="comment.updated"><span title="@{{comment.updated.day_time_str}}">Updated @{{comment.updated.diff}} by
|
<li ng-if="::comment.updated"><span title="@{{::comment.updated.day_time_str}}">Updated @{{::comment.updated.diff}} by
|
||||||
<a href="@{{comment.updated_by.profile_url}}">@{{comment.updated_by.name}}</a></span></li>
|
<a href="@{{::comment.updated_by.profile_url}}">@{{::comment.updated_by.name}}</a></span></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="comment-box" ng-repeat="comment in comments = comment.sub_comments track by comment.id" ng-init="level = level + 1">
|
<div class="comment-box" ng-repeat="comment in comments = comment.sub_comments track by comment.id" ng-init="level = level + 1">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user