mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-08 06:25:51 +01:00
Priorities now integrated with issues.
This commit is contained in:
@@ -20,13 +20,13 @@ import org.scalatra.BadRequest
|
|||||||
class AccountController extends AccountControllerBase
|
class AccountController extends AccountControllerBase
|
||||||
with AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService
|
with AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService
|
||||||
with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator
|
with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator
|
||||||
with AccessTokenService with WebHookService with RepositoryCreationService
|
with AccessTokenService with WebHookService with PrioritiesService with RepositoryCreationService
|
||||||
|
|
||||||
|
|
||||||
trait AccountControllerBase extends AccountManagementControllerBase {
|
trait AccountControllerBase extends AccountManagementControllerBase {
|
||||||
self: AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService
|
self: AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService
|
||||||
with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator
|
with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator
|
||||||
with AccessTokenService with WebHookService with RepositoryCreationService =>
|
with AccessTokenService with WebHookService with PrioritiesService with RepositoryCreationService =>
|
||||||
|
|
||||||
case class AccountNewForm(userName: String, password: String, fullName: String, mailAddress: String,
|
case class AccountNewForm(userName: String, password: String, fullName: String, mailAddress: String,
|
||||||
description: Option[String], url: Option[String], fileId: Option[String])
|
description: Option[String], url: Option[String], fileId: Option[String])
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class ApiController extends ApiControllerBase
|
|||||||
with WebHookIssueCommentService
|
with WebHookIssueCommentService
|
||||||
with WikiService
|
with WikiService
|
||||||
with ActivityService
|
with ActivityService
|
||||||
|
with PrioritiesService
|
||||||
with OwnerAuthenticator
|
with OwnerAuthenticator
|
||||||
with UsersAuthenticator
|
with UsersAuthenticator
|
||||||
with GroupManagerAuthenticator
|
with GroupManagerAuthenticator
|
||||||
@@ -52,6 +53,7 @@ trait ApiControllerBase extends ControllerBase {
|
|||||||
with RepositoryCreationService
|
with RepositoryCreationService
|
||||||
with IssueCreationService
|
with IssueCreationService
|
||||||
with HandleCommentService
|
with HandleCommentService
|
||||||
|
with PrioritiesService
|
||||||
with OwnerAuthenticator
|
with OwnerAuthenticator
|
||||||
with UsersAuthenticator
|
with UsersAuthenticator
|
||||||
with GroupManagerAuthenticator
|
with GroupManagerAuthenticator
|
||||||
@@ -365,6 +367,7 @@ trait ApiControllerBase extends ControllerBase {
|
|||||||
data.body,
|
data.body,
|
||||||
data.assignees.headOption,
|
data.assignees.headOption,
|
||||||
milestone.map(_.milestoneId),
|
milestone.map(_.milestoneId),
|
||||||
|
None,
|
||||||
data.labels,
|
data.labels,
|
||||||
loginAccount)
|
loginAccount)
|
||||||
JsonFormat(ApiIssue(issue, RepositoryName(repository), ApiUser(loginAccount)))
|
JsonFormat(ApiIssue(issue, RepositoryName(repository), ApiUser(loginAccount)))
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class IssuesController extends IssuesControllerBase
|
|||||||
with PullRequestService
|
with PullRequestService
|
||||||
with WebHookIssueCommentService
|
with WebHookIssueCommentService
|
||||||
with CommitsService
|
with CommitsService
|
||||||
|
with PrioritiesService
|
||||||
|
|
||||||
trait IssuesControllerBase extends ControllerBase {
|
trait IssuesControllerBase extends ControllerBase {
|
||||||
self: IssuesService
|
self: IssuesService
|
||||||
@@ -41,10 +42,11 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
with ReferrerAuthenticator
|
with ReferrerAuthenticator
|
||||||
with WritableUsersAuthenticator
|
with WritableUsersAuthenticator
|
||||||
with PullRequestService
|
with PullRequestService
|
||||||
with WebHookIssueCommentService =>
|
with WebHookIssueCommentService
|
||||||
|
with PrioritiesService =>
|
||||||
|
|
||||||
case class IssueCreateForm(title: String, content: Option[String],
|
case class IssueCreateForm(title: String, content: Option[String],
|
||||||
assignedUserName: Option[String], milestoneId: Option[Int], labelNames: Option[String])
|
assignedUserName: Option[String], milestoneId: Option[Int], priorityId: Option[Int], labelNames: Option[String])
|
||||||
case class CommentForm(issueId: Int, content: String)
|
case class CommentForm(issueId: Int, content: String)
|
||||||
case class IssueStateForm(issueId: Int, content: Option[String])
|
case class IssueStateForm(issueId: Int, content: Option[String])
|
||||||
|
|
||||||
@@ -53,6 +55,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
"content" -> trim(optional(text())),
|
"content" -> trim(optional(text())),
|
||||||
"assignedUserName" -> trim(optional(text())),
|
"assignedUserName" -> trim(optional(text())),
|
||||||
"milestoneId" -> trim(optional(number())),
|
"milestoneId" -> trim(optional(number())),
|
||||||
|
"priorityId" -> trim(optional(number())),
|
||||||
"labelNames" -> trim(optional(text()))
|
"labelNames" -> trim(optional(text()))
|
||||||
)(IssueCreateForm.apply)
|
)(IssueCreateForm.apply)
|
||||||
|
|
||||||
@@ -94,6 +97,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
getIssueLabels(owner, name, issueId.toInt),
|
getIssueLabels(owner, name, issueId.toInt),
|
||||||
getAssignableUserNames(owner, name),
|
getAssignableUserNames(owner, name),
|
||||||
getMilestonesWithIssueCount(owner, name),
|
getMilestonesWithIssueCount(owner, name),
|
||||||
|
getPriorities(owner, name),
|
||||||
getLabels(owner, name),
|
getLabels(owner, name),
|
||||||
isIssueEditable(repository),
|
isIssueEditable(repository),
|
||||||
isIssueManageable(repository),
|
isIssueManageable(repository),
|
||||||
@@ -109,6 +113,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
html.create(
|
html.create(
|
||||||
getAssignableUserNames(owner, name),
|
getAssignableUserNames(owner, name),
|
||||||
getMilestones(owner, name),
|
getMilestones(owner, name),
|
||||||
|
getPriorities(owner, name),
|
||||||
getLabels(owner, name),
|
getLabels(owner, name),
|
||||||
isIssueManageable(repository),
|
isIssueManageable(repository),
|
||||||
getContentTemplate(repository, "ISSUE_TEMPLATE"),
|
getContentTemplate(repository, "ISSUE_TEMPLATE"),
|
||||||
@@ -125,6 +130,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
form.content,
|
form.content,
|
||||||
form.assignedUserName,
|
form.assignedUserName,
|
||||||
form.milestoneId,
|
form.milestoneId,
|
||||||
|
form.priorityId,
|
||||||
form.labelNames.toArray.flatMap(_.split(",")),
|
form.labelNames.toArray.flatMap(_.split(",")),
|
||||||
context.loginAccount.get)
|
context.loginAccount.get)
|
||||||
|
|
||||||
@@ -291,6 +297,11 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
} getOrElse Ok()
|
} getOrElse Ok()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ajaxPost("/:owner/:repository/issues/:id/priority")(writableUsersOnly { repository =>
|
||||||
|
updatePriorityId(repository.owner, repository.name, params("id").toInt, priorityId("priorityId"))
|
||||||
|
Ok("updated")
|
||||||
|
})
|
||||||
|
|
||||||
post("/:owner/:repository/issues/batchedit/state")(writableUsersOnly { repository =>
|
post("/:owner/:repository/issues/batchedit/state")(writableUsersOnly { repository =>
|
||||||
defining(params.get("value")){ action =>
|
defining(params.get("value")){ action =>
|
||||||
action match {
|
action match {
|
||||||
@@ -335,6 +346,14 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
post("/:owner/:repository/issues/batchedit/priority")(writableUsersOnly { repository =>
|
||||||
|
defining(priorityId("value")){ value =>
|
||||||
|
executeBatch(repository) {
|
||||||
|
updatePriorityId(repository.owner, repository.name, _, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
get("/:owner/:repository/_attached/:file")(referrersOnly { repository =>
|
get("/:owner/:repository/_attached/:file")(referrersOnly { repository =>
|
||||||
(Directory.getAttachedDir(repository.owner, repository.name) match {
|
(Directory.getAttachedDir(repository.owner, repository.name) match {
|
||||||
case dir if(dir.exists && dir.isDirectory) =>
|
case dir if(dir.exists && dir.isDirectory) =>
|
||||||
@@ -348,6 +367,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
val assignedUserName = (key: String) => params.get(key) filter (_.trim != "")
|
val assignedUserName = (key: String) => params.get(key) filter (_.trim != "")
|
||||||
val milestoneId: String => Option[Int] = (key: String) => params.get(key).flatMap(_.toIntOpt)
|
val milestoneId: String => Option[Int] = (key: String) => params.get(key).flatMap(_.toIntOpt)
|
||||||
|
val priorityId: String => Option[Int] = (key: String) => params.get(key).flatMap(_.toIntOpt)
|
||||||
|
|
||||||
private def executeBatch(repository: RepositoryService.RepositoryInfo)(execute: Int => Unit) = {
|
private def executeBatch(repository: RepositoryService.RepositoryInfo)(execute: Int => Unit) = {
|
||||||
params("checked").split(',') map(_.toInt) foreach execute
|
params("checked").split(',') map(_.toInt) foreach execute
|
||||||
@@ -370,6 +390,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
page,
|
page,
|
||||||
getAssignableUserNames(owner, repoName),
|
getAssignableUserNames(owner, repoName),
|
||||||
getMilestones(owner, repoName),
|
getMilestones(owner, repoName),
|
||||||
|
getPriorities(owner, repoName),
|
||||||
getLabels(owner, repoName),
|
getLabels(owner, repoName),
|
||||||
countIssue(condition.copy(state = "open" ), false, owner -> repoName),
|
countIssue(condition.copy(state = "open" ), false, owner -> repoName),
|
||||||
countIssue(condition.copy(state = "closed"), false, owner -> repoName),
|
countIssue(condition.copy(state = "closed"), false, owner -> repoName),
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ trait PrioritiesControllerBase extends ControllerBase {
|
|||||||
get("/:owner/:repository/issues/priorities")(referrersOnly { repository =>
|
get("/:owner/:repository/issues/priorities")(referrersOnly { repository =>
|
||||||
html.list(
|
html.list(
|
||||||
getPriorities(repository.owner, repository.name),
|
getPriorities(repository.owner, repository.name),
|
||||||
Map.empty, // TODO
|
countIssueGroupByPriorities(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
|
||||||
repository,
|
repository,
|
||||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||||
})
|
})
|
||||||
@@ -40,7 +40,7 @@ trait PrioritiesControllerBase extends ControllerBase {
|
|||||||
val priorityId = createPriority(repository.owner, repository.name, form.priorityName, form.color.substring(1))
|
val priorityId = createPriority(repository.owner, repository.name, form.priorityName, form.color.substring(1))
|
||||||
html.priority(
|
html.priority(
|
||||||
getPriority(repository.owner, repository.name, priorityId).get,
|
getPriority(repository.owner, repository.name, priorityId).get,
|
||||||
Map.empty, // TODO,
|
countIssueGroupByPriorities(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
|
||||||
repository,
|
repository,
|
||||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||||
})
|
})
|
||||||
@@ -55,7 +55,7 @@ trait PrioritiesControllerBase extends ControllerBase {
|
|||||||
updatePriority(repository.owner, repository.name, params("priorityId").toInt, form.priorityName, form.color.substring(1))
|
updatePriority(repository.owner, repository.name, params("priorityId").toInt, form.priorityName, form.color.substring(1))
|
||||||
html.priority(
|
html.priority(
|
||||||
getPriority(repository.owner, repository.name, params("priorityId").toInt).get,
|
getPriority(repository.owner, repository.name, params("priorityId").toInt).get,
|
||||||
Map.empty, // TODO,
|
countIssueGroupByPriorities(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
|
||||||
repository,
|
repository,
|
||||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ class PullRequestsController extends PullRequestsControllerBase
|
|||||||
with RepositoryService with AccountService with IssuesService with PullRequestService with MilestonesService with LabelsService
|
with RepositoryService with AccountService with IssuesService with PullRequestService with MilestonesService with LabelsService
|
||||||
with CommitsService with ActivityService with WebHookPullRequestService
|
with CommitsService with ActivityService with WebHookPullRequestService
|
||||||
with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator
|
with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator
|
||||||
with CommitStatusService with MergeService with ProtectedBranchService
|
with CommitStatusService with MergeService with ProtectedBranchService with PrioritiesService
|
||||||
|
|
||||||
|
|
||||||
trait PullRequestsControllerBase extends ControllerBase {
|
trait PullRequestsControllerBase extends ControllerBase {
|
||||||
self: RepositoryService with AccountService with IssuesService with MilestonesService with LabelsService
|
self: RepositoryService with AccountService with IssuesService with MilestonesService with LabelsService
|
||||||
with CommitsService with ActivityService with PullRequestService with WebHookPullRequestService
|
with CommitsService with ActivityService with PullRequestService with WebHookPullRequestService
|
||||||
with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator
|
with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator
|
||||||
with CommitStatusService with MergeService with ProtectedBranchService =>
|
with CommitStatusService with MergeService with ProtectedBranchService with PrioritiesService =>
|
||||||
|
|
||||||
val pullRequestForm = mapping(
|
val pullRequestForm = mapping(
|
||||||
"title" -> trim(label("Title" , text(required, maxlength(100)))),
|
"title" -> trim(label("Title" , text(required, maxlength(100)))),
|
||||||
@@ -45,6 +45,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
"commitIdTo" -> trim(text(required, maxlength(40))),
|
"commitIdTo" -> trim(text(required, maxlength(40))),
|
||||||
"assignedUserName" -> trim(optional(text())),
|
"assignedUserName" -> trim(optional(text())),
|
||||||
"milestoneId" -> trim(optional(number())),
|
"milestoneId" -> trim(optional(number())),
|
||||||
|
"priorityId" -> trim(optional(number())),
|
||||||
"labelNames" -> trim(optional(text()))
|
"labelNames" -> trim(optional(text()))
|
||||||
)(PullRequestForm.apply)
|
)(PullRequestForm.apply)
|
||||||
|
|
||||||
@@ -64,6 +65,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
commitIdTo: String,
|
commitIdTo: String,
|
||||||
assignedUserName: Option[String],
|
assignedUserName: Option[String],
|
||||||
milestoneId: Option[Int],
|
milestoneId: Option[Int],
|
||||||
|
priorityId: Option[Int],
|
||||||
labelNames: Option[String]
|
labelNames: Option[String]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -93,6 +95,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
getIssueLabels(owner, name, issueId),
|
getIssueLabels(owner, name, issueId),
|
||||||
getAssignableUserNames(owner, name),
|
getAssignableUserNames(owner, name),
|
||||||
getMilestonesWithIssueCount(owner, name),
|
getMilestonesWithIssueCount(owner, name),
|
||||||
|
getPriorities(owner, name),
|
||||||
getLabels(owner, name),
|
getLabels(owner, name),
|
||||||
commits,
|
commits,
|
||||||
diffs,
|
diffs,
|
||||||
@@ -390,6 +393,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
hasDeveloperRole(originRepository.owner, originRepository.name, context.loginAccount),
|
hasDeveloperRole(originRepository.owner, originRepository.name, context.loginAccount),
|
||||||
getAssignableUserNames(originRepository.owner, originRepository.name),
|
getAssignableUserNames(originRepository.owner, originRepository.name),
|
||||||
getMilestones(originRepository.owner, originRepository.name),
|
getMilestones(originRepository.owner, originRepository.name),
|
||||||
|
getPriorities(originRepository.owner, originRepository.name),
|
||||||
getLabels(originRepository.owner, originRepository.name)
|
getLabels(originRepository.owner, originRepository.name)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -445,6 +449,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
content = form.content,
|
content = form.content,
|
||||||
assignedUserName = if (manageable) form.assignedUserName else None,
|
assignedUserName = if (manageable) form.assignedUserName else None,
|
||||||
milestoneId = if (manageable) form.milestoneId else None,
|
milestoneId = if (manageable) form.milestoneId else None,
|
||||||
|
priorityId = if (manageable) form.priorityId else None,
|
||||||
isPullRequest = true)
|
isPullRequest = true)
|
||||||
|
|
||||||
createPullRequest(
|
createPullRequest(
|
||||||
@@ -518,6 +523,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
page,
|
page,
|
||||||
getAssignableUserNames(owner, repoName),
|
getAssignableUserNames(owner, repoName),
|
||||||
getMilestones(owner, repoName),
|
getMilestones(owner, repoName),
|
||||||
|
getPriorities(owner, repoName),
|
||||||
getLabels(owner, repoName),
|
getLabels(owner, repoName),
|
||||||
countIssue(condition.copy(state = "open" ), true, owner -> repoName),
|
countIssue(condition.copy(state = "open" ), true, owner -> repoName),
|
||||||
countIssue(condition.copy(state = "closed"), true, owner -> repoName),
|
countIssue(condition.copy(state = "closed"), true, owner -> repoName),
|
||||||
|
|||||||
@@ -13,12 +13,13 @@ trait IssueComponent extends TemplateComponent { self: Profile =>
|
|||||||
def byPrimaryKey(owner: String, repository: String) = byRepository(owner, repository)
|
def byPrimaryKey(owner: String, repository: String) = byRepository(owner, repository)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IssueOutline(tag: Tag) extends Table[(String, String, Int, Int)](tag, "ISSUE_OUTLINE_VIEW") with IssueTemplate {
|
class IssueOutline(tag: Tag) extends Table[(String, String, Int, Int, Int)](tag, "ISSUE_OUTLINE_VIEW") with IssueTemplate {
|
||||||
val commentCount = column[Int]("COMMENT_COUNT")
|
val commentCount = column[Int]("COMMENT_COUNT")
|
||||||
def * = (userName, repositoryName, issueId, commentCount)
|
val priority = column[Int]("PRIORITY")
|
||||||
|
def * = (userName, repositoryName, issueId, commentCount, priority)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Issues(tag: Tag) extends Table[Issue](tag, "ISSUE") with IssueTemplate with MilestoneTemplate {
|
class Issues(tag: Tag) extends Table[Issue](tag, "ISSUE") with IssueTemplate with MilestoneTemplate with PriorityTemplate {
|
||||||
val openedUserName = column[String]("OPENED_USER_NAME")
|
val openedUserName = column[String]("OPENED_USER_NAME")
|
||||||
val assignedUserName = column[String]("ASSIGNED_USER_NAME")
|
val assignedUserName = column[String]("ASSIGNED_USER_NAME")
|
||||||
val title = column[String]("TITLE")
|
val title = column[String]("TITLE")
|
||||||
@@ -27,7 +28,7 @@ trait IssueComponent extends TemplateComponent { self: Profile =>
|
|||||||
val registeredDate = column[java.util.Date]("REGISTERED_DATE")
|
val registeredDate = column[java.util.Date]("REGISTERED_DATE")
|
||||||
val updatedDate = column[java.util.Date]("UPDATED_DATE")
|
val updatedDate = column[java.util.Date]("UPDATED_DATE")
|
||||||
val pullRequest = column[Boolean]("PULL_REQUEST")
|
val pullRequest = column[Boolean]("PULL_REQUEST")
|
||||||
def * = (userName, repositoryName, issueId, openedUserName, milestoneId.?, assignedUserName.?, title, content.?, closed, registeredDate, updatedDate, pullRequest) <> (Issue.tupled, Issue.unapply)
|
def * = (userName, repositoryName, issueId, openedUserName, milestoneId.?, priorityId.?, assignedUserName.?, title, content.?, closed, registeredDate, updatedDate, pullRequest) <> (Issue.tupled, Issue.unapply)
|
||||||
|
|
||||||
def byPrimaryKey(owner: String, repository: String, issueId: Int) = byIssue(owner, repository, issueId)
|
def byPrimaryKey(owner: String, repository: String, issueId: Int) = byIssue(owner, repository, issueId)
|
||||||
}
|
}
|
||||||
@@ -39,6 +40,7 @@ case class Issue(
|
|||||||
issueId: Int,
|
issueId: Int,
|
||||||
openedUserName: String,
|
openedUserName: String,
|
||||||
milestoneId: Option[Int],
|
milestoneId: Option[Int],
|
||||||
|
priorityId: Option[Int],
|
||||||
assignedUserName: Option[String],
|
assignedUserName: Option[String],
|
||||||
title: String,
|
title: String,
|
||||||
content: Option[String],
|
content: Option[String],
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ trait IssueCreationService {
|
|||||||
self: RepositoryService with WebHookIssueCommentService with LabelsService with IssuesService with ActivityService =>
|
self: RepositoryService with WebHookIssueCommentService with LabelsService with IssuesService with ActivityService =>
|
||||||
|
|
||||||
def createIssue(repository: RepositoryInfo, title:String, body:Option[String],
|
def createIssue(repository: RepositoryInfo, title:String, body:Option[String],
|
||||||
assignee: Option[String], milestoneId: Option[Int], labelNames: Seq[String],
|
assignee: Option[String], milestoneId: Option[Int], priorityId: Option[Int], labelNames: Seq[String],
|
||||||
loginAccount: Account)(implicit context: Context, s: Session) : Issue = {
|
loginAccount: Account)(implicit context: Context, s: Session) : Issue = {
|
||||||
|
|
||||||
val owner = repository.owner
|
val owner = repository.owner
|
||||||
@@ -23,7 +23,8 @@ trait IssueCreationService {
|
|||||||
// insert issue
|
// insert issue
|
||||||
val issueId = insertIssue(owner, name, userName, title, body,
|
val issueId = insertIssue(owner, name, userName, title, body,
|
||||||
if (manageable) assignee else None,
|
if (manageable) assignee else None,
|
||||||
if (manageable) milestoneId else None)
|
if (manageable) milestoneId else None,
|
||||||
|
if (manageable) priorityId else None)
|
||||||
val issue: Issue = getIssue(owner, name, issueId.toString).get
|
val issue: Issue = getIssue(owner, name, issueId.toString).get
|
||||||
|
|
||||||
// insert labels
|
// insert labels
|
||||||
|
|||||||
@@ -97,6 +97,30 @@ trait IssuesService {
|
|||||||
.list.toMap
|
.list.toMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Map which contains issue count for each priority.
|
||||||
|
*
|
||||||
|
* @param owner the repository owner
|
||||||
|
* @param repository the repository name
|
||||||
|
* @param condition the search condition
|
||||||
|
* @return the Map which contains issue count for each priority (key is priority name, value is issue count)
|
||||||
|
*/
|
||||||
|
def countIssueGroupByPriorities(owner: String, repository: String, condition: IssueSearchCondition,
|
||||||
|
filterUser: Map[String, String])(implicit s: Session): Map[String, Int] = {
|
||||||
|
|
||||||
|
searchIssueQuery(Seq(owner -> repository), condition.copy(labels = Set.empty), false)
|
||||||
|
.join(Priorities).on { case t1 ~ t2 =>
|
||||||
|
t1.byPriority(t2.userName, t2.repositoryName, t2.priorityId)
|
||||||
|
}
|
||||||
|
.groupBy { case t1 ~ t2 =>
|
||||||
|
t2.priorityName
|
||||||
|
}
|
||||||
|
.map { case priorityName ~ t =>
|
||||||
|
priorityName -> t.length
|
||||||
|
}
|
||||||
|
.list.toMap
|
||||||
|
}
|
||||||
|
|
||||||
def getCommitStatues(userName: String, repositoryName: String, issueId: Int)(implicit s: Session): Option[CommitStatusInfo] = {
|
def getCommitStatues(userName: String, repositoryName: String, issueId: Int)(implicit s: Session): Option[CommitStatusInfo] = {
|
||||||
val status = PullRequests
|
val status = PullRequests
|
||||||
.filter { pr =>
|
.filter { pr =>
|
||||||
@@ -139,18 +163,20 @@ trait IssuesService {
|
|||||||
.joinLeft (IssueLabels) .on { case t1 ~ t2 ~ i ~ t3 => t1.byIssue(t3.userName, t3.repositoryName, t3.issueId) }
|
.joinLeft (IssueLabels) .on { case t1 ~ t2 ~ i ~ t3 => t1.byIssue(t3.userName, t3.repositoryName, t3.issueId) }
|
||||||
.joinLeft (Labels) .on { case t1 ~ t2 ~ i ~ t3 ~ t4 => t3.map(_.byLabel(t4.userName, t4.repositoryName, t4.labelId)) }
|
.joinLeft (Labels) .on { case t1 ~ t2 ~ i ~ t3 ~ t4 => t3.map(_.byLabel(t4.userName, t4.repositoryName, t4.labelId)) }
|
||||||
.joinLeft (Milestones) .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 => t1.byMilestone(t5.userName, t5.repositoryName, t5.milestoneId) }
|
.joinLeft (Milestones) .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 => t1.byMilestone(t5.userName, t5.repositoryName, t5.milestoneId) }
|
||||||
.sortBy { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 => i asc }
|
.joinLeft (Priorities) .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 => t1.byPriority(t6.userName, t6.repositoryName, t6.priorityId) }
|
||||||
.map { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 =>
|
.sortBy { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 => i asc }
|
||||||
(t1, t2.commentCount, t4.map(_.labelId), t4.map(_.labelName), t4.map(_.color), t5.map(_.title))
|
.map { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 =>
|
||||||
|
(t1, t2.commentCount, t4.map(_.labelId), t4.map(_.labelName), t4.map(_.color), t5.map(_.title), t6.map(_.priorityName))
|
||||||
}
|
}
|
||||||
.list
|
.list
|
||||||
.splitWith { (c1, c2) => c1._1.userName == c2._1.userName && c1._1.repositoryName == c2._1.repositoryName && c1._1.issueId == c2._1.issueId }
|
.splitWith { (c1, c2) => c1._1.userName == c2._1.userName && c1._1.repositoryName == c2._1.repositoryName && c1._1.issueId == c2._1.issueId }
|
||||||
|
|
||||||
result.map { issues => issues.head match {
|
result.map { issues => issues.head match {
|
||||||
case (issue, commentCount, _, _, _, milestone) =>
|
case (issue, commentCount, _, _, _, milestone, priority) =>
|
||||||
IssueInfo(issue,
|
IssueInfo(issue,
|
||||||
issues.flatMap { t => t._3.map (Label(issue.userName, issue.repositoryName, _, t._4.get, t._5.get))} toList,
|
issues.flatMap { t => t._3.map (Label(issue.userName, issue.repositoryName, _, t._4.get, t._5.get))} toList,
|
||||||
milestone,
|
milestone,
|
||||||
|
priority,
|
||||||
commentCount,
|
commentCount,
|
||||||
getCommitStatues(issue.userName, issue.repositoryName, issue.issueId))
|
getCommitStatues(issue.userName, issue.repositoryName, issue.issueId))
|
||||||
}} toList
|
}} toList
|
||||||
@@ -204,6 +230,10 @@ trait IssuesService {
|
|||||||
case "asc" => t1.updatedDate asc
|
case "asc" => t1.updatedDate asc
|
||||||
case "desc" => t1.updatedDate desc
|
case "desc" => t1.updatedDate desc
|
||||||
}
|
}
|
||||||
|
case "priority" => condition.direction match {
|
||||||
|
case "asc" => t2.priority asc
|
||||||
|
case "desc" => t2.priority desc
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.drop(offset).take(limit).zipWithIndex
|
.drop(offset).take(limit).zipWithIndex
|
||||||
@@ -219,6 +249,7 @@ trait IssuesService {
|
|||||||
.foldLeft[Rep[Boolean]](false) ( _ || _ ) &&
|
.foldLeft[Rep[Boolean]](false) ( _ || _ ) &&
|
||||||
(t1.closed === (condition.state == "closed").bind) &&
|
(t1.closed === (condition.state == "closed").bind) &&
|
||||||
(t1.milestoneId.? isEmpty, condition.milestone == Some(None)) &&
|
(t1.milestoneId.? isEmpty, condition.milestone == Some(None)) &&
|
||||||
|
(t1.priorityId.? isEmpty, condition.priority == Some(None)) &&
|
||||||
(t1.assignedUserName.? isEmpty, condition.assigned == Some(None)) &&
|
(t1.assignedUserName.? isEmpty, condition.assigned == Some(None)) &&
|
||||||
(t1.openedUserName === condition.author.get.bind, condition.author.isDefined) &&
|
(t1.openedUserName === condition.author.get.bind, condition.author.isDefined) &&
|
||||||
(t1.pullRequest === pullRequest.bind) &&
|
(t1.pullRequest === pullRequest.bind) &&
|
||||||
@@ -227,6 +258,11 @@ trait IssuesService {
|
|||||||
(t2.byPrimaryKey(t1.userName, t1.repositoryName, t1.milestoneId)) &&
|
(t2.byPrimaryKey(t1.userName, t1.repositoryName, t1.milestoneId)) &&
|
||||||
(t2.title === condition.milestone.get.get.bind)
|
(t2.title === condition.milestone.get.get.bind)
|
||||||
} exists, condition.milestone.flatten.isDefined) &&
|
} exists, condition.milestone.flatten.isDefined) &&
|
||||||
|
// Priority filter
|
||||||
|
(Priorities filter { t2 =>
|
||||||
|
(t2.byPrimaryKey(t1.userName, t1.repositoryName, t1.priorityId)) &&
|
||||||
|
(t2.priorityName === condition.priority.get.get.bind)
|
||||||
|
} exists, condition.priority.flatten.isDefined) &&
|
||||||
// Assignee filter
|
// Assignee filter
|
||||||
(t1.assignedUserName === condition.assigned.get.get.bind, condition.assigned.flatten.isDefined) &&
|
(t1.assignedUserName === condition.assigned.get.get.bind, condition.assigned.flatten.isDefined) &&
|
||||||
// Label filter
|
// Label filter
|
||||||
@@ -253,7 +289,7 @@ trait IssuesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def insertIssue(owner: String, repository: String, loginUser: String, title: String, content: Option[String],
|
def insertIssue(owner: String, repository: String, loginUser: String, title: String, content: Option[String],
|
||||||
assignedUserName: Option[String], milestoneId: Option[Int],
|
assignedUserName: Option[String], milestoneId: Option[Int], priorityId: Option[Int],
|
||||||
isPullRequest: Boolean = false)(implicit s: Session): Int = {
|
isPullRequest: Boolean = false)(implicit s: Session): Int = {
|
||||||
// next id number
|
// next id number
|
||||||
sql"SELECT ISSUE_ID + 1 FROM ISSUE_ID WHERE USER_NAME = $owner AND REPOSITORY_NAME = $repository FOR UPDATE".as[Int]
|
sql"SELECT ISSUE_ID + 1 FROM ISSUE_ID WHERE USER_NAME = $owner AND REPOSITORY_NAME = $repository FOR UPDATE".as[Int]
|
||||||
@@ -264,6 +300,7 @@ trait IssuesService {
|
|||||||
id,
|
id,
|
||||||
loginUser,
|
loginUser,
|
||||||
milestoneId,
|
milestoneId,
|
||||||
|
priorityId,
|
||||||
assignedUserName,
|
assignedUserName,
|
||||||
title,
|
title,
|
||||||
content,
|
content,
|
||||||
@@ -316,6 +353,10 @@ trait IssuesService {
|
|||||||
Issues.filter (_.byPrimaryKey(owner, repository, issueId)).map(_.milestoneId?).update (milestoneId)
|
Issues.filter (_.byPrimaryKey(owner, repository, issueId)).map(_.milestoneId?).update (milestoneId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def updatePriorityId(owner: String, repository: String, issueId: Int, priorityId: Option[Int])(implicit s: Session): Int = {
|
||||||
|
Issues.filter (_.byPrimaryKey(owner, repository, issueId)).map(_.priorityId?).update (priorityId)
|
||||||
|
}
|
||||||
|
|
||||||
def updateComment(commentId: Int, content: String)(implicit s: Session): Int = {
|
def updateComment(commentId: Int, content: String)(implicit s: Session): Int = {
|
||||||
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)
|
||||||
}
|
}
|
||||||
@@ -430,6 +471,7 @@ object IssuesService {
|
|||||||
case class IssueSearchCondition(
|
case class IssueSearchCondition(
|
||||||
labels: Set[String] = Set.empty,
|
labels: Set[String] = Set.empty,
|
||||||
milestone: Option[Option[String]] = None,
|
milestone: Option[Option[String]] = None,
|
||||||
|
priority: Option[Option[String]] = None,
|
||||||
author: Option[String] = None,
|
author: Option[String] = None,
|
||||||
assigned: Option[Option[String]] = None,
|
assigned: Option[Option[String]] = None,
|
||||||
mentioned: Option[String] = None,
|
mentioned: Option[String] = None,
|
||||||
@@ -459,6 +501,10 @@ object IssuesService {
|
|||||||
case Some(x) => s"milestone:${x}"
|
case Some(x) => s"milestone:${x}"
|
||||||
case None => "no:milestone"
|
case None => "no:milestone"
|
||||||
}},
|
}},
|
||||||
|
priority.map { _ match {
|
||||||
|
case Some(x) => s"priority:${x}"
|
||||||
|
case None => "no:priority"
|
||||||
|
}},
|
||||||
(sort, direction) match {
|
(sort, direction) match {
|
||||||
case ("created" , "desc") => None
|
case ("created" , "desc") => None
|
||||||
case ("created" , "asc" ) => Some("sort:created-asc")
|
case ("created" , "asc" ) => Some("sort:created-asc")
|
||||||
@@ -466,6 +512,8 @@ object IssuesService {
|
|||||||
case ("comments", "asc" ) => Some("sort:comments-asc")
|
case ("comments", "asc" ) => Some("sort:comments-asc")
|
||||||
case ("updated" , "desc") => Some("sort:updated-desc")
|
case ("updated" , "desc") => Some("sort:updated-desc")
|
||||||
case ("updated" , "asc" ) => Some("sort:updated-asc")
|
case ("updated" , "asc" ) => Some("sort:updated-asc")
|
||||||
|
case ("priority", "desc") => Some("sort:priority-desc")
|
||||||
|
case ("priority", "asc" ) => Some("sort:priority-asc")
|
||||||
case x => throw new MatchError(x)
|
case x => throw new MatchError(x)
|
||||||
},
|
},
|
||||||
visibility.map(visibility => s"visibility:${visibility}")
|
visibility.map(visibility => s"visibility:${visibility}")
|
||||||
@@ -480,6 +528,10 @@ object IssuesService {
|
|||||||
case Some(x) => "milestone=" + urlEncode(x)
|
case Some(x) => "milestone=" + urlEncode(x)
|
||||||
case None => "milestone=none"
|
case None => "milestone=none"
|
||||||
},
|
},
|
||||||
|
priority.map {
|
||||||
|
case Some(x) => "priority=" + urlEncode(x)
|
||||||
|
case None => "priority=none"
|
||||||
|
},
|
||||||
author .map(x => "author=" + urlEncode(x)),
|
author .map(x => "author=" + urlEncode(x)),
|
||||||
assigned.map {
|
assigned.map {
|
||||||
case Some(x) => "assigned=" + urlEncode(x)
|
case Some(x) => "assigned=" + urlEncode(x)
|
||||||
@@ -512,6 +564,10 @@ object IssuesService {
|
|||||||
case "none" => None
|
case "none" => None
|
||||||
case x => Some(x)
|
case x => Some(x)
|
||||||
},
|
},
|
||||||
|
param(request, "priority").map {
|
||||||
|
case "none" => None
|
||||||
|
case x => Some(x)
|
||||||
|
},
|
||||||
param(request, "author"),
|
param(request, "author"),
|
||||||
param(request, "assigned").map {
|
param(request, "assigned").map {
|
||||||
case "none" => None
|
case "none" => None
|
||||||
@@ -519,7 +575,7 @@ object IssuesService {
|
|||||||
},
|
},
|
||||||
param(request, "mentioned"),
|
param(request, "mentioned"),
|
||||||
param(request, "state", Seq("open", "closed")).getOrElse("open"),
|
param(request, "state", Seq("open", "closed")).getOrElse("open"),
|
||||||
param(request, "sort", Seq("created", "comments", "updated")).getOrElse("created"),
|
param(request, "sort", Seq("created", "comments", "updated", "priority")).getOrElse("created"),
|
||||||
param(request, "direction", Seq("asc", "desc")).getOrElse("desc"),
|
param(request, "direction", Seq("asc", "desc")).getOrElse("desc"),
|
||||||
param(request, "visibility"),
|
param(request, "visibility"),
|
||||||
param(request, "groups").map(_.split(",").toSet).getOrElse(Set.empty)
|
param(request, "groups").map(_.split(",").toSet).getOrElse(Set.empty)
|
||||||
@@ -535,6 +591,6 @@ object IssuesService {
|
|||||||
|
|
||||||
case class CommitStatusInfo(count: Int, successCount: Int, context: Option[String], state: Option[CommitState], targetUrl: Option[String], description: Option[String])
|
case class CommitStatusInfo(count: Int, successCount: Int, context: Option[String], state: Option[CommitState], targetUrl: Option[String], description: Option[String])
|
||||||
|
|
||||||
case class IssueInfo(issue: Issue, labels: List[Label], milestone: Option[String], commentCount: Int, status:Option[CommitStatusInfo])
|
case class IssueInfo(issue: Issue, labels: List[Label], milestone: Option[String], priority: Option[String], commentCount: Int, status:Option[CommitStatusInfo])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,11 @@ trait PrioritiesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def deletePriority(owner: String, repository: String, priorityId: Int)(implicit s: Session): Unit = {
|
def deletePriority(owner: String, repository: String, priorityId: Int)(implicit s: Session): Unit = {
|
||||||
// TODO update affected issues
|
Issues.filter(_.byRepository(owner, repository))
|
||||||
|
.filter(_.priorityId === priorityId)
|
||||||
|
.map(_.priorityId?)
|
||||||
|
.update(None)
|
||||||
|
|
||||||
Priorities.filter(_.byPrimaryKey(owner, repository, priorityId)).delete
|
Priorities.filter(_.byPrimaryKey(owner, repository, priorityId)).delete
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import org.eclipse.jgit.dircache.DirCache
|
|||||||
import org.eclipse.jgit.lib.{FileMode, Constants}
|
import org.eclipse.jgit.lib.{FileMode, Constants}
|
||||||
|
|
||||||
trait RepositoryCreationService {
|
trait RepositoryCreationService {
|
||||||
self: AccountService with RepositoryService with LabelsService with WikiService with ActivityService =>
|
self: AccountService with RepositoryService with LabelsService with WikiService with ActivityService with PrioritiesService =>
|
||||||
|
|
||||||
def createRepository(loginAccount: Account, owner: String, name: String, description: Option[String], isPrivate: Boolean, createReadme: Boolean)
|
def createRepository(loginAccount: Account, owner: String, name: String, description: Option[String], isPrivate: Boolean, createReadme: Boolean)
|
||||||
(implicit s: Session) {
|
(implicit s: Session) {
|
||||||
@@ -30,6 +30,9 @@ trait RepositoryCreationService {
|
|||||||
// Insert default labels
|
// Insert default labels
|
||||||
insertDefaultLabels(owner, name)
|
insertDefaultLabels(owner, name)
|
||||||
|
|
||||||
|
// Insert default priorities
|
||||||
|
insertDefaultPriorities(owner, name)
|
||||||
|
|
||||||
// Create the actual repository
|
// Create the actual repository
|
||||||
val gitdir = getRepositoryDir(owner, name)
|
val gitdir = getRepositoryDir(owner, name)
|
||||||
JGitUtil.initRepository(gitdir)
|
JGitUtil.initRepository(gitdir)
|
||||||
@@ -74,5 +77,9 @@ trait RepositoryCreationService {
|
|||||||
createLabel(userName, repositoryName, "wontfix", "ffffff")
|
createLabel(userName, repositoryName, "wontfix", "ffffff")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def insertDefaultPriorities(userName: String, repositoryName: String)(implicit s: Session): Unit = {
|
||||||
|
createPriority(userName, repositoryName, "high", "fc2929")
|
||||||
|
createPriority(userName, repositoryName, "medium", "fcc629")
|
||||||
|
createPriority(userName, repositoryName, "low", "acacac")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@issues.map { case IssueInfo(issue, labels, milestone, commentCount, commitStatus) =>
|
@issues.map { case IssueInfo(issue, labels, milestone, priority, commentCount, commitStatus) =>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding-top: 12px; padding-bottom: 12px;">
|
<td style="padding-top: 12px; padding-bottom: 12px;">
|
||||||
<a href="@context.path/@issue.userName/@issue.repositoryName">@issue.userName/@issue.repositoryName</a> ・
|
<a href="@context.path/@issue.userName/@issue.repositoryName">@issue.userName/@issue.repositoryName</a> ・
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
@(collaborators: List[String],
|
@(collaborators: List[String],
|
||||||
milestones: List[gitbucket.core.model.Milestone],
|
milestones: List[gitbucket.core.model.Milestone],
|
||||||
|
priorities: List[gitbucket.core.model.Priority],
|
||||||
labels: List[gitbucket.core.model.Label],
|
labels: List[gitbucket.core.model.Label],
|
||||||
isManageable: Boolean,
|
isManageable: Boolean,
|
||||||
content: String,
|
content: String,
|
||||||
@@ -29,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
@gitbucket.core.issues.html.issueinfo(None, Nil, Nil, collaborators, milestones.map(x => (x, 0, 0)), labels, isManageable, repository)
|
@gitbucket.core.issues.html.issueinfo(None, Nil, Nil, collaborators, milestones.map(x => (x, 0, 0)), priorities, labels, isManageable, repository)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
issueLabels: List[gitbucket.core.model.Label],
|
issueLabels: List[gitbucket.core.model.Label],
|
||||||
collaborators: List[String],
|
collaborators: List[String],
|
||||||
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
|
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
|
||||||
|
priorities: List[gitbucket.core.model.Priority],
|
||||||
labels: List[gitbucket.core.model.Label],
|
labels: List[gitbucket.core.model.Label],
|
||||||
isEditable: Boolean,
|
isEditable: Boolean,
|
||||||
isManageable: Boolean,
|
isManageable: Boolean,
|
||||||
@@ -54,7 +55,7 @@
|
|||||||
@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">
|
||||||
@gitbucket.core.issues.html.issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, labels, isManageable, repository)
|
@gitbucket.core.issues.html.issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, priorities, labels, isManageable, repository)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
issueLabels: List[gitbucket.core.model.Label],
|
issueLabels: List[gitbucket.core.model.Label],
|
||||||
collaborators: List[String],
|
collaborators: List[String],
|
||||||
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
|
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
|
||||||
|
priorities: List[gitbucket.core.model.Priority],
|
||||||
labels: List[gitbucket.core.model.Label],
|
labels: List[gitbucket.core.model.Label],
|
||||||
isManageable: Boolean,
|
isManageable: 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)
|
||||||
@@ -32,6 +33,40 @@
|
|||||||
@gitbucket.core.issues.html.labellist(issueLabels)
|
@gitbucket.core.issues.html.labellist(issueLabels)
|
||||||
</ul>
|
</ul>
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
<div style="margin-bottom: 14px;">
|
||||||
|
<span class="muted small strong">Priority</span>
|
||||||
|
@if(isManageable){
|
||||||
|
<div class="pull-right">
|
||||||
|
@gitbucket.core.helper.html.dropdown("Edit", right = true, filter = ("priority", "Filter Priority")) {
|
||||||
|
<li><a href="javascript:void(0);" class="priority" data-id=""><i class="octicon octicon-x"></i> Clear priority</a></li>
|
||||||
|
@priorities.map { priority =>
|
||||||
|
<li>
|
||||||
|
<a href="javascript:void(0);" class="priority" data-id="@priority.priorityId" data-name="@priority.priorityName" data-color="#@priority.color" data-font-color="#@priority.fontColor">
|
||||||
|
@gitbucket.core.helper.html.checkicon(issue.flatMap(is => is.priorityId).map(id => id == priority.priorityId).getOrElse(false))
|
||||||
|
<span class="label" style="background-color: #@priority.color;"> </span>
|
||||||
|
@priority.priorityName
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<span id="label-priority">
|
||||||
|
@issue.flatMap(_.priorityId).map { priorityId =>
|
||||||
|
@priorities.collect { case priority if(priority.priorityId == priorityId) =>
|
||||||
|
<a class="issue-priority" style="background-color: #@priority.color; color: #@priority.fontColor;" href="@helpers.url(repository)/issues?priority=@helpers.urlEncode(priority.priorityName)&state=open">@priority.priorityName</a>
|
||||||
|
}
|
||||||
|
}.getOrElse {
|
||||||
|
<span class="muted small">No priority</span>
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
@if(issue.isEmpty){
|
||||||
|
<input type="hidden" name="priorityId" value=""/>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
|
||||||
<div style="margin-bottom: 14px;">
|
<div style="margin-bottom: 14px;">
|
||||||
<span class="muted small strong">Milestone</span>
|
<span class="muted small strong">Milestone</span>
|
||||||
@if(isManageable){
|
@if(isManageable){
|
||||||
@@ -152,6 +187,19 @@ $(function(){
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('a.priority').click(function(){
|
||||||
|
var priorityName = $(this).data('name');
|
||||||
|
var priorityId = $(this).data('id');
|
||||||
|
var color = $(this).data('color');
|
||||||
|
var fontColor = $(this).data('font-color');
|
||||||
|
$.post('@helpers.url(repository)/issues/@issue.issueId/priority',
|
||||||
|
{ priorityId: priorityId },
|
||||||
|
function(data){
|
||||||
|
displayPriority(priorityName, priorityId, color, fontColor);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
$('a.assign').click(function(){
|
$('a.assign').click(function(){
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
var userName = $this.data('name');
|
var userName = $this.data('name');
|
||||||
@@ -188,6 +236,15 @@ $(function(){
|
|||||||
$('input[name=milestoneId]').val(milestoneId);
|
$('input[name=milestoneId]').val(milestoneId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('a.priority').click(function(){
|
||||||
|
var priorityName = $(this).data('name');
|
||||||
|
var priorityId = $(this).data('id');
|
||||||
|
var color = $(this).data('color');
|
||||||
|
var fontColor = $(this).data('font-color');
|
||||||
|
displayPriority(priorityName, priorityId, color, fontColor);
|
||||||
|
$('input[name=priorityId]').val(priorityId);
|
||||||
|
});
|
||||||
|
|
||||||
$('a.assign').click(function(){
|
$('a.assign').click(function(){
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
var userName = $this.data('name');
|
var userName = $this.data('name');
|
||||||
@@ -222,6 +279,22 @@ $(function(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function displayPriority(priorityName, priorityId, color, fontColor){
|
||||||
|
$('a.priority i.octicon-check').removeClass('octicon-check');
|
||||||
|
if(priorityId == ''){
|
||||||
|
$('#label-priority').html($('<span class="muted small">').text('No priority'));
|
||||||
|
} else {
|
||||||
|
$('#label-priority').html($('<a class="issue-priority">').text(priorityName)
|
||||||
|
.attr('href', '@helpers.url(repository)/issues?priority=' + encodeURIComponent(priorityName) + '&state=open')
|
||||||
|
.css({
|
||||||
|
"background-color": color,
|
||||||
|
"color": fontColor
|
||||||
|
}));
|
||||||
|
|
||||||
|
$('a.priority[data-id=' + priorityId + '] i').addClass('octicon-check');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function displayAssignee($this, userName){
|
function displayAssignee($this, userName){
|
||||||
$('a.assign i.octicon-check').removeClass('octicon-check');
|
$('a.assign i.octicon-check').removeClass('octicon-check');
|
||||||
if(userName == ''){
|
if(userName == ''){
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
page: Int,
|
page: Int,
|
||||||
collaborators: List[String],
|
collaborators: List[String],
|
||||||
milestones: List[gitbucket.core.model.Milestone],
|
milestones: List[gitbucket.core.model.Milestone],
|
||||||
|
priorities: List[gitbucket.core.model.Priority],
|
||||||
labels: List[gitbucket.core.model.Label],
|
labels: List[gitbucket.core.model.Label],
|
||||||
openCount: Int,
|
openCount: Int,
|
||||||
closedCount: Int,
|
closedCount: Int,
|
||||||
@@ -38,7 +39,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</form>
|
</form>
|
||||||
@gitbucket.core.issues.html.listparts(target, issues, page, openCount, closedCount, condition, collaborators, milestones, labels, Some(repository), isManageable)
|
@gitbucket.core.issues.html.listparts(target, issues, page, openCount, closedCount, condition, collaborators, milestones, priorities, labels, Some(repository), isManageable)
|
||||||
@if(isManageable){
|
@if(isManageable){
|
||||||
<form id="batcheditForm" method="POST">
|
<form id="batcheditForm" method="POST">
|
||||||
<input type="hidden" name="value"/>
|
<input type="hidden" name="value"/>
|
||||||
@@ -119,6 +120,9 @@ $(function(){
|
|||||||
$('a.toggle-milestone').click(function(){
|
$('a.toggle-milestone').click(function(){
|
||||||
submitBatchEdit('@helpers.url(repository)/issues/batchedit/milestone', $(this).data('id'));
|
submitBatchEdit('@helpers.url(repository)/issues/batchedit/milestone', $(this).data('id'));
|
||||||
});
|
});
|
||||||
|
$('a.toggle-priority').click(function(){
|
||||||
|
submitBatchEdit('@helpers.url(repository)/issues/batchedit/priority', $(this).data('id'));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
condition: gitbucket.core.service.IssuesService.IssueSearchCondition,
|
condition: gitbucket.core.service.IssuesService.IssueSearchCondition,
|
||||||
collaborators: List[String] = Nil,
|
collaborators: List[String] = Nil,
|
||||||
milestones: List[gitbucket.core.model.Milestone] = Nil,
|
milestones: List[gitbucket.core.model.Milestone] = Nil,
|
||||||
|
priorities: List[gitbucket.core.model.Priority] = Nil,
|
||||||
labels: List[gitbucket.core.model.Label] = Nil,
|
labels: List[gitbucket.core.model.Label] = Nil,
|
||||||
repository: Option[gitbucket.core.service.RepositoryService.RepositoryInfo] = None,
|
repository: Option[gitbucket.core.service.RepositoryService.RepositoryInfo] = None,
|
||||||
isManageable: Boolean = false)(implicit context: gitbucket.core.controller.Context)
|
isManageable: Boolean = false)(implicit context: gitbucket.core.controller.Context)
|
||||||
@@ -48,6 +49,22 @@
|
|||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@gitbucket.core.helper.html.dropdown("Priority", filter = ("priority", "Find Priority...")) {
|
||||||
|
<li>
|
||||||
|
<a href="@condition.copy(priority = (if(condition.priority == Some(None)) None else Some(None))).toURL">
|
||||||
|
@gitbucket.core.helper.html.checkicon(condition.priority == Some(None)) Issues with no priority
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
@priorities.map { priority =>
|
||||||
|
<li>
|
||||||
|
<a href="@condition.copy(priority = (if(condition.priority == Some(Some(priority.priorityName))) None else Some(Some(priority.priorityName)))).toURL">
|
||||||
|
@gitbucket.core.helper.html.checkicon(condition.priority == Some(Some(priority.priorityName)))
|
||||||
|
<span style="background-color: #@priority.color;" class="label-color"> </span>
|
||||||
|
@priority.priorityName
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
}
|
||||||
@gitbucket.core.helper.html.dropdown("Milestone", filter = ("milestone", "Find Milestone...")) {
|
@gitbucket.core.helper.html.dropdown("Milestone", filter = ("milestone", "Find Milestone...")) {
|
||||||
<li>
|
<li>
|
||||||
<a href="@condition.copy(milestone = (if(condition.milestone == Some(None)) None else Some(None))).toURL">
|
<a href="@condition.copy(milestone = (if(condition.milestone == Some(None)) None else Some(None))).toURL">
|
||||||
@@ -88,6 +105,16 @@
|
|||||||
@gitbucket.core.helper.html.checkicon(condition.sort == "created" && condition.direction == "asc") Oldest
|
@gitbucket.core.helper.html.checkicon(condition.sort == "created" && condition.direction == "asc") Oldest
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="@condition.copy(sort="priority", direction="asc").toURL">
|
||||||
|
@gitbucket.core.helper.html.checkicon(condition.sort == "priority" && condition.direction == "asc") Highest priority
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="@condition.copy(sort="priority", direction="desc" ).toURL">
|
||||||
|
@gitbucket.core.helper.html.checkicon(condition.sort == "priority" && condition.direction == "desc") Lowest priority
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="@condition.copy(sort="comments", direction="desc").toURL">
|
<a href="@condition.copy(sort="comments", direction="desc").toURL">
|
||||||
@gitbucket.core.helper.html.checkicon(condition.sort == "comments" && condition.direction == "desc") Most commented
|
@gitbucket.core.helper.html.checkicon(condition.sort == "comments" && condition.direction == "desc") Most commented
|
||||||
@@ -127,6 +154,14 @@
|
|||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@gitbucket.core.helper.html.dropdown("Priority", filter = ("priority", "Find Priority...")) {
|
||||||
|
<li><a href="javascript:void(0);" class="toggle-priority" data-id="">No priority</a></li>
|
||||||
|
@priorities.map { priority =>
|
||||||
|
<li><a href="javascript:void(0);" class="toggle-priority" data-id="@priority.priorityId">
|
||||||
|
<span style="background-color: #@priority.color;" class="label"> </span>
|
||||||
|
@priority.priorityName</a></li>
|
||||||
|
}
|
||||||
|
}
|
||||||
@gitbucket.core.helper.html.dropdown("Milestone", filter = ("milestone", "Find Milestone...")) {
|
@gitbucket.core.helper.html.dropdown("Milestone", filter = ("milestone", "Find Milestone...")) {
|
||||||
<li><a href="javascript:void(0);" class="toggle-milestone" data-id="">No milestone</a></li>
|
<li><a href="javascript:void(0);" class="toggle-milestone" data-id="">No milestone</a></li>
|
||||||
@milestones.filter(_.closedDate.isEmpty).map { milestone =>
|
@milestones.filter(_.closedDate.isEmpty).map { milestone =>
|
||||||
@@ -171,7 +206,7 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@issues.map { case IssueInfo(issue, labels, milestone, commentCount, commitStatus) =>
|
@issues.map { case IssueInfo(issue, labels, milestone, priority, commentCount, commitStatus) =>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding-top: 12px; padding-bottom: 12px;">
|
<td style="padding-top: 12px; padding-bottom: 12px;">
|
||||||
@if(isManageable){
|
@if(isManageable){
|
||||||
@@ -208,6 +243,10 @@
|
|||||||
</span>
|
</span>
|
||||||
<div class="small muted" style="margin-left: 12px; margin-top: 2px;">
|
<div class="small muted" style="margin-left: 12px; margin-top: 2px;">
|
||||||
#@issue.issueId opened @gitbucket.core.helper.html.datetimeago(issue.registeredDate) by @helpers.user(issue.openedUserName, styleClass="username")
|
#@issue.issueId opened @gitbucket.core.helper.html.datetimeago(issue.registeredDate) by @helpers.user(issue.openedUserName, styleClass="username")
|
||||||
|
@priority.map(priority => priorities.filter(p => p.priorityName == priority).head).map { priority =>
|
||||||
|
<span style="margin: 20px;"><a href="@condition.copy(priority = Some(Some(priority.priorityName))).toURL" class="username"><i class="octicon octicon-flame"></i>
|
||||||
|
<span class="issue-priority issue-priority-inline" style="background-color: #@priority.color; color: #@priority.fontColor;">@priority.priorityName</span></a></span>
|
||||||
|
}
|
||||||
@milestone.map { milestone =>
|
@milestone.map { milestone =>
|
||||||
<span style="margin: 20px;"><a href="@condition.copy(milestone = Some(Some(milestone))).toURL" class="username"><i class="octicon octicon-milestone"></i> @milestone</a></span>
|
<span style="margin: 20px;"><a href="@condition.copy(milestone = Some(Some(milestone))).toURL" class="username"><i class="octicon octicon-milestone"></i> @milestone</a></span>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
hasOriginWritePermission: Boolean,
|
hasOriginWritePermission: Boolean,
|
||||||
collaborators: List[String],
|
collaborators: List[String],
|
||||||
milestones: List[gitbucket.core.model.Milestone],
|
milestones: List[gitbucket.core.model.Milestone],
|
||||||
|
priorities: List[gitbucket.core.model.Priority],
|
||||||
labels: List[gitbucket.core.model.Label])(implicit context: gitbucket.core.controller.Context)
|
labels: List[gitbucket.core.model.Label])(implicit context: gitbucket.core.controller.Context)
|
||||||
@import gitbucket.core.view.helpers
|
@import gitbucket.core.view.helpers
|
||||||
@gitbucket.core.html.main(s"Pull requests - ${repository.owner}/${repository.name}", Some(repository)){
|
@gitbucket.core.html.main(s"Pull requests - ${repository.owner}/${repository.name}", Some(repository)){
|
||||||
@@ -81,7 +82,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
@gitbucket.core.issues.html.issueinfo(None, Nil, Nil, collaborators, milestones.map((_, 0, 0)), labels, hasOriginWritePermission, repository)
|
@gitbucket.core.issues.html.issueinfo(None, Nil, Nil, collaborators, milestones.map((_, 0, 0)), priorities, labels, hasOriginWritePermission, repository)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
issueLabels: List[gitbucket.core.model.Label],
|
issueLabels: List[gitbucket.core.model.Label],
|
||||||
collaborators: List[String],
|
collaborators: List[String],
|
||||||
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
|
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
|
||||||
|
priorities: List[gitbucket.core.model.Priority],
|
||||||
labels: List[gitbucket.core.model.Label],
|
labels: List[gitbucket.core.model.Label],
|
||||||
isEditable: Boolean,
|
isEditable: Boolean,
|
||||||
isManageable: Boolean,
|
isManageable: Boolean,
|
||||||
@@ -45,7 +46,7 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
@gitbucket.core.issues.html.issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, labels, isManageable, repository)
|
@gitbucket.core.issues.html.issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, priorities, labels, isManageable, repository)
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
issueLabels: List[gitbucket.core.model.Label],
|
issueLabels: List[gitbucket.core.model.Label],
|
||||||
collaborators: List[String],
|
collaborators: List[String],
|
||||||
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
|
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
|
||||||
|
priorities: List[gitbucket.core.model.Priority],
|
||||||
labels: List[gitbucket.core.model.Label],
|
labels: List[gitbucket.core.model.Label],
|
||||||
dayByDayCommits: Seq[Seq[gitbucket.core.util.JGitUtil.CommitInfo]],
|
dayByDayCommits: Seq[Seq[gitbucket.core.util.JGitUtil.CommitInfo]],
|
||||||
diffs: Seq[gitbucket.core.util.JGitUtil.DiffInfo],
|
diffs: Seq[gitbucket.core.util.JGitUtil.DiffInfo],
|
||||||
@@ -85,7 +86,7 @@
|
|||||||
@flash.get("info").map{ info =>
|
@flash.get("info").map{ info =>
|
||||||
<div class="alert alert-info">@info</div>
|
<div class="alert alert-info">@info</div>
|
||||||
}
|
}
|
||||||
@gitbucket.core.pulls.html.conversation(issue, pullreq, commits, comments, issueLabels, collaborators, milestones, labels, isEditable, isManageable, isManageableForkedRepository, repository, forkedRepository)
|
@gitbucket.core.pulls.html.conversation(issue, pullreq, commits, comments, issueLabels, collaborators, milestones, priorities, labels, isEditable, isManageable, isManageableForkedRepository, repository, forkedRepository)
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane" id="commits">
|
<div class="tab-pane" id="commits">
|
||||||
@if(commits.nonEmpty){
|
@if(commits.nonEmpty){
|
||||||
|
|||||||
@@ -823,7 +823,7 @@ div.issue-comment-action .octicon.danger {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-pills > li > span.issue-label {
|
.nav-pills > li > span.issue-label, .issue-priority {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0px 8px 2px 8px;
|
padding: 0px 8px 2px 8px;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
@@ -832,6 +832,15 @@ div.issue-comment-action .octicon.danger {
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.issue-priority {
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.issue-priority-inline {
|
||||||
|
font-size: 100%;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
div.attachable {
|
div.attachable {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ trait ServiceSpecBase {
|
|||||||
content = None,
|
content = None,
|
||||||
assignedUserName = None,
|
assignedUserName = None,
|
||||||
milestoneId = None,
|
milestoneId = None,
|
||||||
|
priorityId = None,
|
||||||
isPullRequest = true)
|
isPullRequest = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user