mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-18 11:20:38 +01:00
Improve issue comment management (#2588)
This commit is contained in:
@@ -112,6 +112,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
getLabels(owner, name),
|
getLabels(owner, name),
|
||||||
isIssueEditable(repository),
|
isIssueEditable(repository),
|
||||||
isIssueManageable(repository),
|
isIssueManageable(repository),
|
||||||
|
isIssueCommentManageable(repository),
|
||||||
repository
|
repository
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -238,8 +239,8 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
defining(repository.owner, repository.name) {
|
defining(repository.owner, repository.name) {
|
||||||
case (owner, name) =>
|
case (owner, name) =>
|
||||||
getComment(owner, name, params("id")).map { comment =>
|
getComment(owner, name, params("id")).map { comment =>
|
||||||
if (isEditableContent(owner, name, comment.commentedUserName)) {
|
if (isDeletableComment(owner, name, comment.commentedUserName)) {
|
||||||
Ok(deleteComment(comment.issueId, comment.commentId))
|
Ok(deleteComment(repository.owner, repository.name, comment.issueId, comment.commentId))
|
||||||
} else Unauthorized()
|
} else Unauthorized()
|
||||||
} getOrElse NotFound()
|
} getOrElse NotFound()
|
||||||
}
|
}
|
||||||
@@ -496,4 +497,13 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
): Boolean = {
|
): Boolean = {
|
||||||
hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
|
hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether an issue comment is deletable by a logged-in user.
|
||||||
|
*/
|
||||||
|
private def isDeletableComment(owner: String, repository: String, author: String)(
|
||||||
|
implicit context: Context
|
||||||
|
): Boolean = {
|
||||||
|
hasOwnerRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ trait HandleCommentService {
|
|||||||
): Option[IssueComment] = context.loginAccount.flatMap { _ =>
|
): Option[IssueComment] = context.loginAccount.flatMap { _ =>
|
||||||
comment.action match {
|
comment.action match {
|
||||||
case "comment" =>
|
case "comment" =>
|
||||||
val deleteResult = deleteComment(comment.issueId, comment.commentId)
|
val deleteResult = deleteComment(repoInfo.owner, repoInfo.name, comment.issueId, comment.commentId)
|
||||||
val registry = PluginRegistry()
|
val registry = PluginRegistry()
|
||||||
val hooks: Seq[IssueHook] = if (issue.isPullRequest) registry.getPullRequestHooks else registry.getIssueHooks
|
val hooks: Seq[IssueHook] = if (issue.isPullRequest) registry.getPullRequestHooks else registry.getIssueHooks
|
||||||
hooks.foreach(_.deletedComment(comment.commentId, issue, repoInfo))
|
hooks.foreach(_.deletedComment(comment.commentId, issue, repoInfo))
|
||||||
|
|||||||
@@ -74,6 +74,13 @@ trait IssueCreationService {
|
|||||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
|
hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether an logged-in user can manage issues comment.
|
||||||
|
*/
|
||||||
|
protected def isIssueCommentManageable(repository: RepositoryInfo)(implicit context: Context, s: Session): Boolean = {
|
||||||
|
hasOwnerRole(repository.owner, repository.name, context.loginAccount)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether an logged-in user can post issues.
|
* Tests whether an logged-in user can post issues.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -660,7 +660,10 @@ trait IssuesService {
|
|||||||
IssueComments.filter(_.byPrimaryKey(commentId)).map(t => (t.content, t.updatedDate)).update(content, currentDate)
|
IssueComments.filter(_.byPrimaryKey(commentId)).map(t => (t.content, t.updatedDate)).update(content, currentDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
def deleteComment(issueId: Int, commentId: Int)(implicit s: Session): Int = {
|
def deleteComment(owner: String, repository: String, issueId: Int, commentId: Int)(
|
||||||
|
implicit context: Context,
|
||||||
|
s: Session
|
||||||
|
): Int = {
|
||||||
Issues.filter(_.issueId === issueId.bind).map(_.updatedDate).update(currentDate)
|
Issues.filter(_.issueId === issueId.bind).map(_.updatedDate).update(currentDate)
|
||||||
IssueComments.filter(_.byPrimaryKey(commentId)).firstOption match {
|
IssueComments.filter(_.byPrimaryKey(commentId)).firstOption match {
|
||||||
case Some(c) if c.action == "reopen_comment" =>
|
case Some(c) if c.action == "reopen_comment" =>
|
||||||
@@ -669,6 +672,16 @@ trait IssuesService {
|
|||||||
IssueComments.filter(_.byPrimaryKey(commentId)).map(t => (t.content, t.action)).update("Close", "close")
|
IssueComments.filter(_.byPrimaryKey(commentId)).map(t => (t.content, t.action)).update("Close", "close")
|
||||||
case Some(_) =>
|
case Some(_) =>
|
||||||
IssueComments.filter(_.byPrimaryKey(commentId)).delete
|
IssueComments.filter(_.byPrimaryKey(commentId)).delete
|
||||||
|
IssueComments insert IssueComment(
|
||||||
|
userName = owner,
|
||||||
|
repositoryName = repository,
|
||||||
|
issueId = issueId,
|
||||||
|
action = "delete_comment",
|
||||||
|
commentedUserName = context.loginAccount.map(_.userName).getOrElse("Unknown user"),
|
||||||
|
content = s"",
|
||||||
|
registeredDate = currentDate,
|
||||||
|
updatedDate = currentDate
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -254,6 +254,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
case "delete_comment" => {
|
||||||
|
<div class="discussion-item discussion-item-delete-comment">
|
||||||
|
<div class="discussion-item-header">
|
||||||
|
<span class="discussion-item-icon"><i class="octicon octicon-trashcan"></i></span>
|
||||||
|
@helpers.avatar(comment.commentedUserName, 16)
|
||||||
|
@helpers.user(comment.commentedUserName, styleClass="username strong")
|
||||||
|
deleted the comment
|
||||||
|
@gitbucket.core.helper.html.datetimeago(comment.registeredDate)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
case _ => {
|
case _ => {
|
||||||
@showFormattedComment(comment)
|
@showFormattedComment(comment)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
labels: List[gitbucket.core.model.Label],
|
labels: List[gitbucket.core.model.Label],
|
||||||
isEditable: Boolean,
|
isEditable: Boolean,
|
||||||
isManageable: Boolean,
|
isManageable: Boolean,
|
||||||
|
isCommentManageable: Boolean,
|
||||||
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
|
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
|
||||||
@import gitbucket.core.view.helpers
|
@import gitbucket.core.view.helpers
|
||||||
@gitbucket.core.html.main(s"${issue.title} - Issue #${issue.issueId} - ${repository.owner}/${repository.name}", Some(repository)){
|
@gitbucket.core.html.main(s"${issue.title} - Issue #${issue.issueId} - ${repository.owner}/${repository.name}", Some(repository)){
|
||||||
@@ -51,7 +52,7 @@
|
|||||||
<hr>
|
<hr>
|
||||||
<div style="margin-top: 15px;">
|
<div style="margin-top: 15px;">
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
@gitbucket.core.issues.html.commentlist(Some(issue), comments, isManageable, repository)
|
@gitbucket.core.issues.html.commentlist(Some(issue), comments, isCommentManageable, repository)
|
||||||
@gitbucket.core.issues.html.commentform(issue, true, isEditable, isManageable, repository)
|
@gitbucket.core.issues.html.commentform(issue, true, isEditable, isManageable, repository)
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
|
|||||||
@@ -950,6 +950,12 @@ pre.reset.discussion-item-content-text{
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.discussion-item-delete-comment .discussion-item-icon {
|
||||||
|
background-color: #767676;
|
||||||
|
padding-top: 1px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.priority-sort-handle {
|
.priority-sort-handle {
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
|
|||||||
Reference in New Issue
Block a user