diff --git a/doc/comment_action.md b/doc/comment_action.md index d56bd7e..5e306e8 100644 --- a/doc/comment_action.md +++ b/doc/comment_action.md @@ -6,17 +6,22 @@ To determine if it was any operation, you see the `ACTION` column. And in the case of some actions, `CONTENT` column value contains additional information. -|ACTION |CONTENT | -|---------------|-----------------| -|comment |comment | -|close_comment |comment | -|reopen_comment |comment | -|close |"Close" | -|reopen |"Reopen" | -|commit |comment commitId | -|merge |comment | -|delete_branch |branchName | -|refer |issueId:title | +|ACTION |CONTENT | +|-------------------|------------------------| +|comment |comment | +|close_comment |comment | +|reopen_comment |comment | +|close |"Close" | +|reopen |"Reopen" | +|commit |comment commitId | +|merge |comment | +|delete_branch |branchName | +|refer |issueId:title | +|add_label |labelName | +|delete_label |labelName | +|change_priority |oldPriority:priority | +|change_milestone|oldMilestone:milestone| +|assign |oldAssigned:assigned | ### comment @@ -54,3 +59,23 @@ This value is saved when other issue or issue comment contains reference to the issue like `#issueId`. At the same time, store id and title of the referrer issue as `id:title`. + +### add_label + +This value is saved when users have added the label. + +### delete_label + +This value is saved when users have deleted the label. + +### change_priority + +This value is saved when users have changed the priority. + +### change_milestone + +This value is saved when users have changed the milestone. + +### assign + +This value is saved when users have assign issue/PR to user or remove the assign. diff --git a/src/main/scala/gitbucket/core/controller/DashboardController.scala b/src/main/scala/gitbucket/core/controller/DashboardController.scala index 81e3085..f422ba5 100644 --- a/src/main/scala/gitbucket/core/controller/DashboardController.scala +++ b/src/main/scala/gitbucket/core/controller/DashboardController.scala @@ -8,7 +8,7 @@ class DashboardController extends DashboardControllerBase with IssuesService with PullRequestService with RepositoryService with AccountService with CommitsService - with UsersAuthenticator + with LabelsService with PrioritiesService with MilestonesService with UsersAuthenticator trait DashboardControllerBase extends ControllerBase { self: IssuesService with PullRequestService with RepositoryService with AccountService diff --git a/src/main/scala/gitbucket/core/controller/IssuesController.scala b/src/main/scala/gitbucket/core/controller/IssuesController.scala index 4472863..ba23f9d 100644 --- a/src/main/scala/gitbucket/core/controller/IssuesController.scala +++ b/src/main/scala/gitbucket/core/controller/IssuesController.scala @@ -271,25 +271,25 @@ ajaxPost("/:owner/:repository/issues/:id/label/new")(writableUsersOnly { repository => defining(params("id").toInt){ issueId => - registerIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt) + registerIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt, true) html.labellist(getIssueLabels(repository.owner, repository.name, issueId)) } }) ajaxPost("/:owner/:repository/issues/:id/label/delete")(writableUsersOnly { repository => defining(params("id").toInt){ issueId => - deleteIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt) + deleteIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt, true) html.labellist(getIssueLabels(repository.owner, repository.name, issueId)) } }) ajaxPost("/:owner/:repository/issues/:id/assign")(writableUsersOnly { repository => - updateAssignedUserName(repository.owner, repository.name, params("id").toInt, assignedUserName("assignedUserName")) + updateAssignedUserName(repository.owner, repository.name, params("id").toInt, assignedUserName("assignedUserName"), true) Ok("updated") }) ajaxPost("/:owner/:repository/issues/:id/milestone")(writableUsersOnly { repository => - updateMilestoneId(repository.owner, repository.name, params("id").toInt, milestoneId("milestoneId")) + updateMilestoneId(repository.owner, repository.name, params("id").toInt, milestoneId("milestoneId"), true) milestoneId("milestoneId").map { milestoneId => getMilestonesWithIssueCount(repository.owner, repository.name) .find(_._1.milestoneId == milestoneId).map { case (_, openCount, closeCount) => @@ -299,7 +299,8 @@ }) ajaxPost("/:owner/:repository/issues/:id/priority")(writableUsersOnly { repository => - updatePriorityId(repository.owner, repository.name, params("id").toInt, priorityId("priorityId")) + val priority = priorityId("priorityId") + updatePriorityId(repository.owner, repository.name, params("id").toInt, priority, true) Ok("updated") }) diff --git a/src/main/scala/gitbucket/core/controller/LabelsController.scala b/src/main/scala/gitbucket/core/controller/LabelsController.scala index 4f42475..9ab083e 100644 --- a/src/main/scala/gitbucket/core/controller/LabelsController.scala +++ b/src/main/scala/gitbucket/core/controller/LabelsController.scala @@ -1,7 +1,7 @@ package gitbucket.core.controller import gitbucket.core.issues.labels.html -import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, LabelsService} +import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, LabelsService, MilestonesService, PrioritiesService} import gitbucket.core.util.{ReferrerAuthenticator, WritableUsersAuthenticator} import gitbucket.core.util.Implicits._ import gitbucket.core.util.SyntaxSugars._ @@ -10,8 +10,9 @@ import org.scalatra.Ok class LabelsController extends LabelsControllerBase - with LabelsService with IssuesService with RepositoryService with AccountService -with ReferrerAuthenticator with WritableUsersAuthenticator + with IssuesService with RepositoryService with AccountService + with LabelsService with PrioritiesService with MilestonesService + with ReferrerAuthenticator with WritableUsersAuthenticator trait LabelsControllerBase extends ControllerBase { self: LabelsService with IssuesService with RepositoryService diff --git a/src/main/scala/gitbucket/core/controller/PrioritiesController.scala b/src/main/scala/gitbucket/core/controller/PrioritiesController.scala index dee6cbb..2141ffe 100644 --- a/src/main/scala/gitbucket/core/controller/PrioritiesController.scala +++ b/src/main/scala/gitbucket/core/controller/PrioritiesController.scala @@ -1,7 +1,7 @@ package gitbucket.core.controller import gitbucket.core.issues.priorities.html -import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, PrioritiesService} +import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, LabelsService, MilestonesService, PrioritiesService} import gitbucket.core.util.{ReferrerAuthenticator, WritableUsersAuthenticator} import gitbucket.core.util.Implicits._ import gitbucket.core.util.SyntaxSugars._ @@ -10,8 +10,9 @@ import org.scalatra.Ok class PrioritiesController extends PrioritiesControllerBase - with PrioritiesService with IssuesService with RepositoryService with AccountService -with ReferrerAuthenticator with WritableUsersAuthenticator + with IssuesService with RepositoryService with AccountService + with LabelsService with PrioritiesService with MilestonesService + with ReferrerAuthenticator with WritableUsersAuthenticator trait PrioritiesControllerBase extends ControllerBase { self: PrioritiesService with IssuesService with RepositoryService diff --git a/src/main/scala/gitbucket/core/service/IssuesService.scala b/src/main/scala/gitbucket/core/service/IssuesService.scala index 2283c17..f081d9c 100644 --- a/src/main/scala/gitbucket/core/service/IssuesService.scala +++ b/src/main/scala/gitbucket/core/service/IssuesService.scala @@ -4,6 +4,7 @@ import gitbucket.core.util.StringUtil._ import gitbucket.core.util.Implicits._ import gitbucket.core.util.SyntaxSugars._ +import gitbucket.core.controller.Context import gitbucket.core.model.{Issue, PullRequest, IssueComment, IssueLabel, Label, Account, Repository, CommitState, Role} import gitbucket.core.model.Profile._ import gitbucket.core.model.Profile.profile._ @@ -11,7 +12,7 @@ import gitbucket.core.model.Profile.dateColumnType trait IssuesService { - self: AccountService with RepositoryService => + self: AccountService with RepositoryService with LabelsService with PrioritiesService with MilestonesService => import IssuesService._ def getIssue(owner: String, repository: String, issueId: String)(implicit s: Session) = @@ -321,11 +322,35 @@ } get } - def registerIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int)(implicit s: Session): Int = { + def registerIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int, insertComment: Boolean = false)(implicit context: Context, s: Session): Int = { + if (insertComment) { + IssueComments insert IssueComment( + userName = owner, + repositoryName = repository, + issueId = issueId, + action = "add_label", + commentedUserName = context.loginAccount.map(_.userName).getOrElse("Unknown user"), + content = getLabel(owner, repository, labelId).map(_.labelName).getOrElse("Unknown label"), + registeredDate = currentDate, + updatedDate = currentDate + ) + } IssueLabels insert IssueLabel(owner, repository, issueId, labelId) } - def deleteIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int)(implicit s: Session): Int = { + def deleteIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int, insertComment: Boolean = false)(implicit context: Context, s: Session): Int = { + if (insertComment) { + IssueComments insert IssueComment( + userName = owner, + repositoryName = repository, + issueId = issueId, + action = "delete_label", + commentedUserName = context.loginAccount.map(_.userName).getOrElse("Unknown user"), + content = getLabel(owner, repository, labelId).map(_.labelName).getOrElse("Unknown label"), + registeredDate = currentDate, + updatedDate = currentDate + ) + } IssueLabels filter(_.byPrimaryKey(owner, repository, issueId, labelId)) delete } @@ -350,15 +375,57 @@ .update(title, content, currentDate) } - def updateAssignedUserName(owner: String, repository: String, issueId: Int, assignedUserName: Option[String])(implicit s: Session): Int = { + def updateAssignedUserName(owner: String, repository: String, issueId: Int, assignedUserName: Option[String], insertComment: Boolean = false)(implicit context: Context, s: Session): Int = { + if (insertComment) { + val oldAssigned = getIssue(owner, repository, s"${issueId}").get.assignedUserName.getOrElse("Not assigned") + val assigned = assignedUserName.getOrElse("Not assigned") + IssueComments insert IssueComment( + userName = owner, + repositoryName = repository, + issueId = issueId, + action = "assign", + commentedUserName = context.loginAccount.map(_.userName).getOrElse("Unknown user"), + content = s"${oldAssigned}:${assigned}", + registeredDate = currentDate, + updatedDate = currentDate + ) + } Issues.filter(_.byPrimaryKey(owner, repository, issueId)).map(t => (t.assignedUserName?, t.updatedDate)).update(assignedUserName, currentDate) } - def updateMilestoneId(owner: String, repository: String, issueId: Int, milestoneId: Option[Int])(implicit s: Session): Int = { + def updateMilestoneId(owner: String, repository: String, issueId: Int, milestoneId: Option[Int], insertComment: Boolean = false)(implicit context: Context, s: Session): Int = { + if (insertComment) { + val oldMilestoneName = getIssue(owner, repository, s"${issueId}").get.milestoneId.map(getMilestone(owner, repository, _).map(_.title).getOrElse("Unknown milestone")).getOrElse("No milestone") + val milestoneName = milestoneId.map(getMilestone(owner, repository, _).map(_.title).getOrElse("Unknown milestone")).getOrElse("No milestone") + IssueComments insert IssueComment( + userName = owner, + repositoryName = repository, + issueId = issueId, + action = "change_milestone", + commentedUserName = context.loginAccount.map(_.userName).getOrElse("Unknown user"), + content = s"${oldMilestoneName}:${milestoneName}", + registeredDate = currentDate, + updatedDate = currentDate + ) + } Issues.filter(_.byPrimaryKey(owner, repository, issueId)).map(t => (t.milestoneId?, t.updatedDate)).update(milestoneId, currentDate) } - def updatePriorityId(owner: String, repository: String, issueId: Int, priorityId: Option[Int])(implicit s: Session): Int = { + def updatePriorityId(owner: String, repository: String, issueId: Int, priorityId: Option[Int], insertComment: Boolean = false)(implicit context: Context, s: Session): Int = { + if (insertComment) { + val oldPriorityName = getIssue(owner, repository, s"${issueId}").get.priorityId.map(getPriority(owner, repository, _).map(_.priorityName).getOrElse("Unknown priority")).getOrElse("No priority") + val priorityName = priorityId.map(getPriority(owner, repository, _).map(_.priorityName).getOrElse("Unknown priority")).getOrElse("No priority") + IssueComments insert IssueComment( + userName = owner, + repositoryName = repository, + issueId = issueId, + action = "change_priority", + commentedUserName = context.loginAccount.map(_.userName).getOrElse("Unknown user"), + content = s"${oldPriorityName}:${priorityName}", + registeredDate = currentDate, + updatedDate = currentDate + ) + } Issues.filter(_.byPrimaryKey(owner, repository, issueId)).map(t => (t.priorityId?, t.updatedDate)).update(priorityId, currentDate) } diff --git a/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala b/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala index 1583e76..eac61a0 100644 --- a/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala +++ b/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala @@ -185,7 +185,8 @@ class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl: String, sshUrl: Option[String]) extends PostReceiveHook with PreReceiveHook with RepositoryService with AccountService with IssuesService with ActivityService with PullRequestService with WebHookService - with WebHookPullRequestService with CommitsService { + with LabelsService with PrioritiesService with MilestonesService + with WebHookPullRequestService with CommitsService { private val logger = LoggerFactory.getLogger(classOf[CommitLogHook]) private var existIds: Seq[String] = Nil diff --git a/src/main/twirl/gitbucket/core/issues/commentlist.scala.html b/src/main/twirl/gitbucket/core/issues/commentlist.scala.html index 6f913c9..fe7d81f 100644 --- a/src/main/twirl/gitbucket/core/issues/commentlist.scala.html +++ b/src/main/twirl/gitbucket/core/issues/commentlist.scala.html @@ -34,32 +34,185 @@ @comments.map { case comment: gitbucket.core.model.IssueComment => { - @if(comment.action != "close" && comment.action != "reopen" && comment.action != "delete_branch" - && comment.action != "commit" && comment.action != "refer"){ -
@pullreq.map(_.commitIdTo.substring(0, 7))
into + @if(pullreq.get.requestUserName == repository.owner){ +@pullreq.map(_.branch)
from@pullreq.map(_.requestBranch)
+ } else { +@pullreq.map(_.userName):@pullreq.map(_.branch)
from@pullreq.map(_.requestUserName):@pullreq.map(_.requestBranch)
+ } + @gitbucket.core.helper.html.datetimeago(comment.registeredDate) +@pullreq.map(_.requestBranch)
branch + @gitbucket.core.helper.html.datetimeago(comment.registeredDate) +@comment.content
label + @gitbucket.core.helper.html.datetimeago(comment.registeredDate) +@comment.content
label + @gitbucket.core.helper.html.datetimeago(comment.registeredDate) +@comment.content.split(":")(0)
to@comment.content.split(":")(1)
+ @gitbucket.core.helper.html.datetimeago(comment.registeredDate) +@comment.content.split(":")(0)
to@comment.content.split(":")(1)
+ @gitbucket.core.helper.html.datetimeago(comment.registeredDate) +@comment.content.split(":")(0)
to@comment.content.split(":")(1)
+ @gitbucket.core.helper.html.datetimeago(comment.registeredDate) +@pullreq.map(_.commitIdTo.substring(0, 7))
into - @if(pullreq.get.requestUserName == repository.owner){ -@pullreq.map(_.branch)
from@pullreq.map(_.requestBranch)
- } else { -@pullreq.map(_.userName):@pullreq.map(_.branch)
from@pullreq.map(_.requestUserName):@pullreq.map(_.requestBranch)
- } - @gitbucket.core.helper.html.datetimeago(comment.registeredDate) -@pullreq.map(_.requestBranch)
branch - @gitbucket.core.helper.html.datetimeago(comment.registeredDate) -