mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-03 03:55:58 +01:00
Assign, milestone and labels are available in Issue creation.
This commit is contained in:
@@ -14,13 +14,26 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
self: IssuesService with RepositoryService with LabelsService with MilestonesService
|
self: IssuesService with RepositoryService with LabelsService with MilestonesService
|
||||||
with UsersOnlyAuthenticator =>
|
with UsersOnlyAuthenticator =>
|
||||||
|
|
||||||
case class IssueForm(title: String, content: Option[String])
|
case class IssueCreateForm(title: String, content: Option[String],
|
||||||
|
assignedUserName: Option[String], milestoneId: Option[Int], labelNames: Option[String])
|
||||||
|
|
||||||
|
case class IssueEditForm(title: String, content: Option[String])
|
||||||
|
|
||||||
case class CommentForm(issueId: Int, content: String)
|
case class CommentForm(issueId: Int, content: String)
|
||||||
|
|
||||||
val form = mapping(
|
val issueCreateForm = mapping(
|
||||||
|
"title" -> trim(label("Title", text(required))),
|
||||||
|
"content" -> trim(optional(text())),
|
||||||
|
"assignedUserName" -> trim(optional(text())),
|
||||||
|
"milestoneId" -> trim(optional(number())),
|
||||||
|
"labelNames" -> trim(optional(text()))
|
||||||
|
)(IssueCreateForm.apply)
|
||||||
|
|
||||||
|
val issueEditForm = mapping(
|
||||||
"title" -> trim(label("Title", text(required))),
|
"title" -> trim(label("Title", text(required))),
|
||||||
"content" -> trim(optional(text()))
|
"content" -> trim(optional(text()))
|
||||||
)(IssueForm.apply)
|
)(IssueEditForm.apply)
|
||||||
|
|
||||||
val commentForm = mapping(
|
val commentForm = mapping(
|
||||||
"issueId" -> label("Issue Id", number()),
|
"issueId" -> label("Issue Id", number()),
|
||||||
"content" -> trim(label("Comment", text(required)))
|
"content" -> trim(label("Comment", text(required)))
|
||||||
@@ -63,16 +76,27 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// TODO requires users only and readable repository checking
|
// TODO requires users only and readable repository checking
|
||||||
post("/:owner/:repository/issues/new", form)( usersOnly { form =>
|
post("/:owner/:repository/issues/new", issueCreateForm)( usersOnly { form =>
|
||||||
val owner = params("owner")
|
val owner = params("owner")
|
||||||
val repository = params("repository")
|
val repository = params("repository")
|
||||||
|
|
||||||
redirect("/%s/%s/issues/%d".format(owner, repository,
|
val issueId = createIssue(owner, repository, context.loginAccount.get.userName,
|
||||||
createIssue(owner, repository, context.loginAccount.get.userName, form.title, form.content)))
|
form.title, form.content, form.assignedUserName, form.milestoneId)
|
||||||
|
|
||||||
|
form.labelNames.map { value =>
|
||||||
|
val labels = getLabels(owner, repository)
|
||||||
|
value.split(",").foreach { labelName =>
|
||||||
|
labels.find(_.labelName == labelName).map { label =>
|
||||||
|
registerIssueLabel(owner, repository, issueId, label.labelId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
redirect("/%s/%s/issues/%d".format(owner, repository, issueId))
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO Authenticator
|
// TODO Authenticator
|
||||||
ajaxPost("/:owner/:repository/issues/edit/:id", form){ form =>
|
ajaxPost("/:owner/:repository/issues/edit/:id", issueEditForm){ form =>
|
||||||
val owner = params("owner")
|
val owner = params("owner")
|
||||||
val repository = params("repository")
|
val repository = params("repository")
|
||||||
val issueId = params("id").toInt
|
val issueId = params("id").toInt
|
||||||
|
|||||||
@@ -160,8 +160,8 @@ trait IssuesService {
|
|||||||
} exists, condition.labels.nonEmpty)
|
} exists, condition.labels.nonEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
def createIssue(owner: String, repository: String, loginUser: String,
|
def createIssue(owner: String, repository: String, loginUser: String, title: String, content: Option[String],
|
||||||
title: String, content: Option[String]) =
|
assignedUserName: Option[String], milestoneId: Option[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]
|
||||||
.firstOption.filter { id =>
|
.firstOption.filter { id =>
|
||||||
@@ -170,8 +170,8 @@ trait IssuesService {
|
|||||||
repository,
|
repository,
|
||||||
id,
|
id,
|
||||||
loginUser,
|
loginUser,
|
||||||
None,
|
milestoneId,
|
||||||
None,
|
assignedUserName,
|
||||||
title,
|
title,
|
||||||
content,
|
content,
|
||||||
false,
|
false,
|
||||||
@@ -184,6 +184,9 @@ trait IssuesService {
|
|||||||
}.map(_.issueId).update(id) > 0
|
}.map(_.issueId).update(id) > 0
|
||||||
} get
|
} get
|
||||||
|
|
||||||
|
def registerIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int): Unit =
|
||||||
|
IssueLabels.* insert (IssueLabel(owner, repository, issueId, labelId))
|
||||||
|
|
||||||
def createComment(owner: String, repository: String, loginUser: String,
|
def createComment(owner: String, repository: String, loginUser: String,
|
||||||
issueId: Int, content: String, action: Option[String]) =
|
issueId: Int, content: String, action: Option[String]) =
|
||||||
IssueComments.autoInc insert (
|
IssueComments.autoInc insert (
|
||||||
|
|||||||
@@ -4,10 +4,9 @@
|
|||||||
@html.main("New Issue - " + repository.owner + "/" + repository.name){
|
@html.main("New Issue - " + repository.owner + "/" + repository.name){
|
||||||
@html.header("issues", repository)
|
@html.header("issues", repository)
|
||||||
@tab("", repository)
|
@tab("", repository)
|
||||||
|
<form action="@url(repository)/issues/new" method="POST" validate="true">
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span9">
|
<div class="span9">
|
||||||
<form action="@url(repository)/issues/new" method="POST" validate="true">
|
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-content">
|
<div class="box-content">
|
||||||
<span id="error-title" class="error"></span>
|
<span id="error-title" class="error"></span>
|
||||||
@@ -51,7 +50,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="submit" class="btn btn-success" value="Submit new issue"/>
|
<input type="submit" class="btn btn-success" value="Submit new issue"/>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="span3">
|
<div class="span3">
|
||||||
<strong>Add Labels</strong>
|
<strong>Add Labels</strong>
|
||||||
@@ -72,6 +70,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
}
|
}
|
||||||
<script>
|
<script>
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|||||||
Reference in New Issue
Block a user