add action link to pull request.

This commit is contained in:
nazoking
2015-01-30 00:30:11 +09:00
parent 0acbaeae86
commit 5f5cc8d454
5 changed files with 103 additions and 67 deletions

View File

@@ -21,7 +21,7 @@ import service.WebHookService.WebHookPayload
class RepositoryViewerController extends RepositoryViewerControllerBase
with RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService
/**
@@ -29,7 +29,7 @@ class RepositoryViewerController extends RepositoryViewerControllerBase
*/
trait RepositoryViewerControllerBase extends ControllerBase {
self: RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator =>
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService =>
ArchiveCommand.registerFormat("zip", new ZipFormat)
ArchiveCommand.registerFormat("tar.gz", new TgzFormat)
@@ -325,6 +325,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
get("/:owner/:repository/branches")(referrersOnly { repository =>
val branches = JGitUtil.getBranches(repository.owner, repository.name, repository.repository.defaultBranch)
.sortBy(br => (br.mergeInfo.isEmpty, br.commitTime))
.map(br => br -> getPullRequestByRequestCommit(repository.owner, repository.name, repository.repository.defaultBranch, br.name, br.commitId))
.reverse
repo.html.branches(branches, hasWritePermission(repository.owner, repository.name, context.loginAccount), repository)
})

View File

@@ -81,6 +81,25 @@ trait PullRequestService { self: IssuesService =>
.map { case (t1, t2) => t1 }
.list
def getPullRequestByRequestCommit(userName: String, repositoryName: String, toBranch:String, fromBranch: String, commitId: String)
(implicit s: Session): Option[(PullRequest, Issue)] = {
if(toBranch == fromBranch){
None
} else {
PullRequests
.innerJoin(Issues).on { (t1, t2) => t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId) }
.filter { case (t1, t2) =>
(t1.userName === userName.bind) &&
(t1.repositoryName === repositoryName.bind) &&
(t1.branch === toBranch.bind) &&
(t1.requestUserName === userName.bind) &&
(t1.requestRepositoryName === repositoryName.bind) &&
(t1.requestBranch === fromBranch.bind) &&
(t1.commitIdTo === commitId.bind)
}
.firstOption
}
}
}
object PullRequestService {

View File

@@ -135,7 +135,7 @@ object JGitUtil {
case class BranchMergeInfo(ahead: Int, behind: Int, isMerged: Boolean)
case class BranchInfo(name: String, committerName: String, commitTime: Date, committerEmailAddress:String, mergeInfo: Option[BranchMergeInfo])
case class BranchInfo(name: String, committerName: String, commitTime: Date, committerEmailAddress:String, mergeInfo: Option[BranchMergeInfo], commitId: String)
/**
* Returns RevCommit from the commit or tag id.
@@ -721,7 +721,7 @@ object JGitUtil {
behind = RevWalkUtils.count(walk, defaultCommit, mergeBase),
isMerged = walk.isMergedInto(branchCommit, defaultCommit)))
}
BranchInfo(branchName, committer, when, committerEmail, mergeInfo)
BranchInfo(branchName, committer, when, committerEmail, mergeInfo, ref.getObjectId.name)
} finally {
walk.dispose();
}

View File

@@ -1,4 +1,4 @@
@(branchInfo: Seq[util.JGitUtil.BranchInfo],
@(branchInfo: Seq[(util.JGitUtil.BranchInfo, Option[(model.PullRequest, model.Issue)])],
hasWritePermission: Boolean,
repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context)
@import context._
@@ -6,20 +6,37 @@
@html.main(s"${repository.owner}/${repository.name}", Some(repository)) {
@html.menu("code", repository){
<h1>Branches</h1>
<table class="table table-bordered table-hover table-issues">
<table class="table table-bordered table-hover table-issues branches">
<thead>
<tr>
<th style="background: #f5f5f5;color: #666;">All branches</th>
</tr>
</thead>
<tbody>
@branchInfo.map { branch =>
@branchInfo.map { case (branch, prs) =>
<tr><td style="padding: 12px;">
<div class="branch-action">
@branch.mergeInfo.map{ info =>
@prs.map{ case (pull, issue) =>
<a href="@url(repository)/pull/@issue.issueId" title="@issue.title">#@issue.issueId</a>
@if(issue.closed) {
@if(info.isMerged){
<a href="@url(repository)/pull/@issue.issueId" title="@issue.title" class="label label-info">Merged</a>
}else{
<a href="@url(repository)/pull/@issue.issueId" title="@issue.title" class="label label-important">Closed</a>
}
} else {
<a href="@url(repository)/pull/@issue.issueId" title="@issue.title" class="label label-success">Open</a>
}
}.getOrElse{
<a href="@url(repository)/compare/@{encodeRefName(repository.repository.defaultBranch)}...@{encodeRefName(branch.name)}" class="btn btn-small">Compare</a>
}
@if(hasWritePermission){
<a href="@url(repository)/delete/@encodeRefName(branch.name)" class="btn @if(info.isMerged){ btn-warning }else{ btn-danger } delete-branch btn-mini" data-name="@branch.name" @if(info.isMerged){ title="merged branch" }><i class="icon icon-trash icon-white"></i></a>
@if(prs.map(!_._2.closed).getOrElse(false)){
<a class="btn disabled btn-mini" data-toggle="tooltip" title="You cant delete this branch because it has an open pull request"><i class="icon icon-trash icon-white"></i></a>
}else{
<a href="@url(repository)/delete/@encodeRefName(branch.name)" class="btn @if(info.isMerged){ btn-warning }else{ btn-danger } delete-branch btn-mini" data-name="@branch.name" @if(info.isMerged){ data-toggle="tooltip" title="this branch is merged" }><i class="icon icon-trash icon-white"></i></a>
}
}
}
</div>
@@ -57,63 +74,6 @@ $(function(){
var branchName = $(e.target).data('name');
return confirm('Are you sure you want to remove the ' + branchName + ' branch?');
});
$('*[data-toggle=tooltip]').tooltip();
$('*[data-toggle=tooltip]').tooltip().css("white-space","nowrap");
});
</script>
<style>
.muted-link{
color: #777;
}
.muted-link:hover{
color: #4183c4;
}
.branch-details{
display: inline-block;
width: 490px;
margin-right: 10px;
}
.branch-name{
color: #4183c4;
display: inline-block;
padding: 2px 6px;
font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
background-color: rgba(209,227,237,0.5);
border-radius: 3px;
}
.branch-meta{
color: #aaa;
font-size: 12px;
line-height: 20px;
}
.branch-action{
display: inline-block;
float: right;
position: relative;
top: -3px;
height: 20px;
}
.branch-a-b-count{
display: inline-block;
vertical-align: middle;
width: 181px;
text-align: center;
color: rgba(0,0,0,0.5);
}
.a-b-count-widget{
font-size: 10px;
}
.a-b-count-widget .count-half{
width:90px;
position: relative;
text-align: right;
float: left;
}
.a-b-count-widget .count-half:last-child {
text-align: left;
border-left: 1px solid #bbb;
}
.a-b-count-widget .count-half .count-value{
padding: 0 3px;
}
</style>

View File

@@ -472,6 +472,62 @@ div.repository-content {
margin-left: 40px;
}
.branches .muted-link{
color: #777;
}
.branches .muted-link:hover{
color: #4183c4;
}
.branches .branch-details{
display: inline-block;
width: 490px;
margin-right: 10px;
}
.branches .branch-name{
color: #4183c4;
display: inline-block;
padding: 2px 6px;
font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
background-color: rgba(209,227,237,0.5);
border-radius: 3px;
}
.branches .branch-meta{
color: #aaa;
font-size: 12px;
line-height: 20px;
}
.branches .branch-action{
display: inline-block;
float: right;
position: relative;
top: -3px;
height: 20px;
}
.branches .branch-a-b-count{
display: inline-block;
vertical-align: middle;
width: 181px;
text-align: center;
color: rgba(0,0,0,0.5);
}
.branches .a-b-count-widget{
font-size: 10px;
}
.branches .a-b-count-widget .count-half{
width:90px;
position: relative;
text-align: right;
float: left;
}
.branches .a-b-count-widget .count-half:last-child {
text-align: left;
border-left: 1px solid #bbb;
}
.branches .a-b-count-widget .count-half .count-value{
padding: 0 3px;
}
/****************************************************************************/
/* Activity */
/****************************************************************************/