mirror of
https://github.com/gitbucket/gitbucket.git
synced 2026-05-08 01:37:34 +02:00
Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4088b2c1e8 | ||
|
|
919d55c002 | ||
|
|
068bbd0c3b | ||
|
|
9f50528192 | ||
|
|
4c149cf01c | ||
|
|
c86c706406 | ||
|
|
3b0a0f55b5 | ||
|
|
4232b8184e | ||
|
|
e5f3dfe293 | ||
|
|
22af94d36a | ||
|
|
d6b6781861 | ||
|
|
2222299793 | ||
|
|
fdd9a184b5 | ||
|
|
99492e3f8e | ||
|
|
a42c40bbc1 | ||
|
|
2794f9fcfc | ||
|
|
28c0262e74 | ||
|
|
8634191bd2 | ||
|
|
f73c86d533 | ||
|
|
f042d709ac | ||
|
|
e2a6149a93 | ||
|
|
b2a7e2c7e2 | ||
|
|
89fc143075 | ||
|
|
a754a92799 | ||
|
|
dc26fcf609 | ||
|
|
b9db57eeef | ||
|
|
9b377c727d | ||
|
|
e5b8d81bb4 | ||
|
|
c85b31a7d5 | ||
|
|
6580e5458a | ||
|
|
4e4e65eaa6 | ||
|
|
9d19aad384 | ||
|
|
c16a9f234b | ||
|
|
ace551c33d | ||
|
|
1e6e686692 | ||
|
|
afdcc3f7c0 | ||
|
|
00e64bc46c | ||
|
|
a959e1820f | ||
|
|
3dfbdbfe51 | ||
|
|
5c46dc0bd3 | ||
|
|
db60db674f | ||
|
|
687a4f14e1 | ||
|
|
bb10365b8b | ||
|
|
74ed3bf6a0 | ||
|
|
d1d7fdc488 | ||
|
|
67775a4c62 | ||
|
|
317b5cb096 | ||
|
|
2929517d7e | ||
|
|
51e788396d | ||
|
|
1321653bf6 | ||
|
|
3899854854 | ||
|
|
c0ca842ba7 | ||
|
|
24b05d28db | ||
|
|
f0268b105c | ||
|
|
0a46e180a9 | ||
|
|
e6a215a9c3 | ||
|
|
8ca7117065 | ||
|
|
ba0a07b835 | ||
|
|
4a35b65c2c | ||
|
|
5b658ef6ff | ||
|
|
e9ff24d9a7 | ||
|
|
a92051a4c3 |
@@ -1,5 +1,4 @@
|
||||
language: scala
|
||||
sudo: false
|
||||
script:
|
||||
- . env.sh
|
||||
- sbt test
|
||||
|
||||
12
README.md
12
README.md
@@ -14,12 +14,13 @@ The current version of GitBucket provides a basic features below:
|
||||
- Wiki
|
||||
- Issues
|
||||
- Fork / Pull request
|
||||
- Mail notification
|
||||
- Email notification
|
||||
- Activity timeline
|
||||
- User management (for Administrators)
|
||||
- Group (like Organization in Github)
|
||||
- Group (like Organization in GitHub)
|
||||
- LDAP integration
|
||||
- Gravatar support
|
||||
- Plug-in system
|
||||
|
||||
Following features are not implemented, but we will make them in the future release!
|
||||
|
||||
@@ -79,6 +80,13 @@ Run the following commands in `Terminal` to
|
||||
- start gitbucket: `launchctl load ~/Library/LaunchAgents/gitbucket.plist`
|
||||
- stop gitbucket: `launchctl unload ~/Library/LaunchAgents/gitbucket.plist`
|
||||
|
||||
Plug-ins
|
||||
--------
|
||||
GitBucket has the plug-in system to extend GitBucket from outside of GitBucket. Some plug-ins are available now:
|
||||
|
||||
- [gitbucket-gist-plugin](https://github.com/takezoe/gitbucket-gist-plugin)
|
||||
- [gitbucket-announce-plugin](https://github.com/McFoggy/gitbucket-announce-plugin)
|
||||
|
||||
Release Notes
|
||||
--------
|
||||
### 3.5 - 1 Aug 2015
|
||||
|
||||
@@ -44,7 +44,7 @@ GITBUCKET_WAR_DIR=$GITBUCKET_DIR/lib
|
||||
GITBUCKET_WAR_FILE=$GITBUCKET_WAR_DIR/gitbucket.war
|
||||
|
||||
# GitBucket version to fetch when installing
|
||||
GITBUCKET_VERSION=2.1
|
||||
GITBUCKET_VERSION=3.5
|
||||
|
||||
#
|
||||
# End of configuration section. Ignore this part
|
||||
|
||||
@@ -2,7 +2,7 @@ Automatic Schema Updating
|
||||
========
|
||||
GitBucket uses H2 database to manage project and account data. GitBucket updates database schema automatically in the first run after the upgrading.
|
||||
|
||||
To release a new version of GitBucket, add the version definition to the [servlet.AutoUpdate](https://github.com/takezoe/gitbucket/blob/master/src/main/scala/servlet/AutoUpdateListener.scala) at first.
|
||||
To release a new version of GitBucket, add the version definition to the [gitbucket.core.servlet.AutoUpdate](https://github.com/takezoe/gitbucket/blob/master/src/main/scala/gitbucket/core/servlet/AutoUpdate.scala) at first.
|
||||
|
||||
```scala
|
||||
object AutoUpdate {
|
||||
|
||||
3
env.sh
3
env.sh
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
export GITBUCKET_VERSION=`cat project/build.scala | grep 'val Version' | cut -d \" -f 2`
|
||||
echo "GITBUCKET_VERSION: $GITBUCKET_VERSION"
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -10,7 +10,7 @@ import sbtassembly.AssemblyKeys._
|
||||
object MyBuild extends Build {
|
||||
val Organization = "gitbucket"
|
||||
val Name = "gitbucket"
|
||||
val Version = "3.5.0"
|
||||
val Version = "3.6.0"
|
||||
val ScalaVersion = "2.11.6"
|
||||
val ScalatraVersion = "2.3.1"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
. ../env.sh
|
||||
. ./env.sh
|
||||
|
||||
cd ../
|
||||
./sbt.sh clean assembly
|
||||
|
||||
3
release/env.sh
Normal file
3
release/env.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
export GITBUCKET_VERSION=`cat ../project/build.scala | grep 'val Version' | cut -d \" -f 2`
|
||||
echo "GITBUCKET_VERSION: $GITBUCKET_VERSION"
|
||||
@@ -3,13 +3,13 @@ D="$(dirname "$0")"
|
||||
D="$(cd "${D}"; pwd)"
|
||||
DD="$(dirname "${D}")"
|
||||
(
|
||||
for f in "${DD}/env.sh" "${D}/build.xml"; do
|
||||
for f in "${D}/env.sh" "${D}/build.xml"; do
|
||||
if [ ! -s "${f}" ]; then
|
||||
echo >&2 "$0: Unable to access file '${f}'"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
. "${D}/env.sh"
|
||||
cd "${DD}"
|
||||
. "${DD}/env.sh"
|
||||
ant -f "${D}/build.xml" all
|
||||
)
|
||||
|
||||
@@ -32,6 +32,7 @@ class ScalatraBootstrap extends LifeCycle {
|
||||
context.mount(new DashboardController, "/*")
|
||||
context.mount(new UserManagementController, "/*")
|
||||
context.mount(new SystemSettingsController, "/*")
|
||||
context.mount(new PluginsController, "/*")
|
||||
context.mount(new AccountController, "/*")
|
||||
context.mount(new RepositoryViewerController, "/*")
|
||||
context.mount(new WikiController, "/*")
|
||||
|
||||
@@ -15,7 +15,7 @@ case class ApiRepository(
|
||||
default_branch: String,
|
||||
owner: ApiUser) {
|
||||
val forks_count = forks
|
||||
val watchers_coun = watchers
|
||||
val watchers_count = watchers
|
||||
val url = ApiPath(s"/api/v3/repos/${full_name}")
|
||||
val http_url = ApiPath(s"/git/${full_name}.git")
|
||||
val clone_url = ApiPath(s"/git/${full_name}.git")
|
||||
|
||||
@@ -257,6 +257,12 @@ trait IssuesControllerBase extends ControllerBase {
|
||||
} getOrElse NotFound
|
||||
})
|
||||
|
||||
ajaxPost("/:owner/:repository/issues/new/label")(collaboratorsOnly { repository =>
|
||||
val labelNames = params("labelNames").split(",")
|
||||
val labels = getLabels(repository.owner, repository.name).filter(x => labelNames.contains(x.labelName))
|
||||
html.labellist(labels)
|
||||
})
|
||||
|
||||
ajaxPost("/:owner/:repository/issues/:id/label/new")(collaboratorsOnly { repository =>
|
||||
defining(params("id").toInt){ issueId =>
|
||||
registerIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt)
|
||||
@@ -459,7 +465,11 @@ trait IssuesControllerBase extends ControllerBase {
|
||||
"issues",
|
||||
searchIssue(condition, false, (page - 1) * IssueLimit, IssueLimit, owner -> repoName),
|
||||
page,
|
||||
(getCollaborators(owner, repoName) :+ owner).sorted,
|
||||
if(!getAccountByUserName(owner).exists(_.isGroupAccount)){
|
||||
(getCollaborators(owner, repoName) :+ owner).sorted
|
||||
} else {
|
||||
getCollaborators(owner, repoName)
|
||||
},
|
||||
getMilestones(owner, repoName),
|
||||
getLabels(owner, repoName),
|
||||
countIssue(condition.copy(state = "open" ), false, owner -> repoName),
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package gitbucket.core.controller
|
||||
|
||||
import gitbucket.core.admin.plugins.html
|
||||
import gitbucket.core.plugin.PluginRegistry
|
||||
import gitbucket.core.util.AdminAuthenticator
|
||||
|
||||
class PluginsController extends ControllerBase with AdminAuthenticator {
|
||||
get("/admin/plugins")(adminOnly {
|
||||
html.plugins(PluginRegistry().getPlugins())
|
||||
})
|
||||
}
|
||||
@@ -46,7 +46,10 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
"requestRepositoryName" -> trim(text(required, maxlength(100))),
|
||||
"requestBranch" -> trim(text(required, maxlength(100))),
|
||||
"commitIdFrom" -> trim(text(required, maxlength(40))),
|
||||
"commitIdTo" -> trim(text(required, maxlength(40)))
|
||||
"commitIdTo" -> trim(text(required, maxlength(40))),
|
||||
"assignedUserName" -> trim(optional(text())),
|
||||
"milestoneId" -> trim(optional(number())),
|
||||
"labelNames" -> trim(optional(text()))
|
||||
)(PullRequestForm.apply)
|
||||
|
||||
val mergeForm = mapping(
|
||||
@@ -62,7 +65,11 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
requestRepositoryName: String,
|
||||
requestBranch: String,
|
||||
commitIdFrom: String,
|
||||
commitIdTo: String)
|
||||
commitIdTo: String,
|
||||
assignedUserName: Option[String],
|
||||
milestoneId: Option[Int],
|
||||
labelNames: Option[String]
|
||||
)
|
||||
|
||||
case class MergeForm(message: String)
|
||||
|
||||
@@ -176,7 +183,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
pullreq,
|
||||
statuses,
|
||||
repository,
|
||||
s"${context.baseUrl}/git/${pullreq.requestUserName}/${pullreq.requestRepositoryName}.git")
|
||||
getRepository(pullreq.requestUserName, pullreq.requestRepositoryName, context.baseUrl).get)
|
||||
}
|
||||
} getOrElse NotFound
|
||||
})
|
||||
@@ -307,32 +314,44 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
originRepository.owner, originRepository.name, originId,
|
||||
forkedRepository.owner, forkedRepository.name, forkedId)
|
||||
|
||||
(oldGit.getRepository.resolve(rootId), newGit.getRepository.resolve(forkedId))
|
||||
(Option(oldGit.getRepository.resolve(rootId)), Option(newGit.getRepository.resolve(forkedId)))
|
||||
} else {
|
||||
// Commit id
|
||||
(oldGit.getRepository.resolve(originId), newGit.getRepository.resolve(forkedId))
|
||||
(Option(oldGit.getRepository.resolve(originId)), Option(newGit.getRepository.resolve(forkedId)))
|
||||
}
|
||||
|
||||
val (commits, diffs) = getRequestCompareInfo(
|
||||
originRepository.owner, originRepository.name, oldId.getName,
|
||||
forkedRepository.owner, forkedRepository.name, newId.getName)
|
||||
(oldId, newId) match {
|
||||
case (Some(oldId), Some(newId)) => {
|
||||
val (commits, diffs) = getRequestCompareInfo(
|
||||
originRepository.owner, originRepository.name, oldId.getName,
|
||||
forkedRepository.owner, forkedRepository.name, newId.getName)
|
||||
|
||||
html.compare(
|
||||
commits,
|
||||
diffs,
|
||||
(forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
|
||||
case (Some(userName), Some(repositoryName)) => (userName, repositoryName) :: getForkedRepositories(userName, repositoryName)
|
||||
case _ => (forkedRepository.owner, forkedRepository.name) :: getForkedRepositories(forkedRepository.owner, forkedRepository.name)
|
||||
},
|
||||
commits.flatten.map(commit => getCommitComments(forkedRepository.owner, forkedRepository.name, commit.id, false)).flatten.toList,
|
||||
originId,
|
||||
forkedId,
|
||||
oldId.getName,
|
||||
newId.getName,
|
||||
forkedRepository,
|
||||
originRepository,
|
||||
forkedRepository,
|
||||
hasWritePermission(forkedRepository.owner, forkedRepository.name, context.loginAccount))
|
||||
html.compare(
|
||||
commits,
|
||||
diffs,
|
||||
(forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
|
||||
case (Some(userName), Some(repositoryName)) => (userName, repositoryName) :: getForkedRepositories(userName, repositoryName)
|
||||
case _ => (forkedRepository.owner, forkedRepository.name) :: getForkedRepositories(forkedRepository.owner, forkedRepository.name)
|
||||
},
|
||||
commits.flatten.map(commit => getCommitComments(forkedRepository.owner, forkedRepository.name, commit.id, false)).flatten.toList,
|
||||
originId,
|
||||
forkedId,
|
||||
oldId.getName,
|
||||
newId.getName,
|
||||
forkedRepository,
|
||||
originRepository,
|
||||
forkedRepository,
|
||||
hasWritePermission(originRepository.owner, originRepository.name, context.loginAccount),
|
||||
(getCollaborators(originRepository.owner, originRepository.name) ::: (if(getAccountByUserName(originRepository.owner).get.isGroupAccount) Nil else List(originRepository.owner))).sorted,
|
||||
getMilestones(originRepository.owner, originRepository.name),
|
||||
getLabels(originRepository.owner, originRepository.name)
|
||||
)
|
||||
}
|
||||
case (oldId, newId) =>
|
||||
redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/" +
|
||||
s"${originOwner}:${oldId.map(_ => originId).getOrElse(originRepository.repository.defaultBranch)}..." +
|
||||
s"${forkedOwner}:${newId.map(_ => forkedId).getOrElse(forkedRepository.repository.defaultBranch)}")
|
||||
}
|
||||
}
|
||||
}) getOrElse NotFound
|
||||
})
|
||||
@@ -368,46 +387,61 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
})
|
||||
|
||||
post("/:owner/:repository/pulls/new", pullRequestForm)(referrersOnly { (form, repository) =>
|
||||
val loginUserName = context.loginAccount.get.userName
|
||||
defining(repository.owner, repository.name){ case (owner, name) =>
|
||||
val writable = hasWritePermission(owner, name, context.loginAccount)
|
||||
val loginUserName = context.loginAccount.get.userName
|
||||
|
||||
val issueId = createIssue(
|
||||
owner = repository.owner,
|
||||
repository = repository.name,
|
||||
loginUser = loginUserName,
|
||||
title = form.title,
|
||||
content = form.content,
|
||||
assignedUserName = None,
|
||||
milestoneId = None,
|
||||
isPullRequest = true)
|
||||
val issueId = createIssue(
|
||||
owner = repository.owner,
|
||||
repository = repository.name,
|
||||
loginUser = loginUserName,
|
||||
title = form.title,
|
||||
content = form.content,
|
||||
assignedUserName = if(writable) form.assignedUserName else None,
|
||||
milestoneId = if(writable) form.milestoneId else None,
|
||||
isPullRequest = true)
|
||||
|
||||
createPullRequest(
|
||||
originUserName = repository.owner,
|
||||
originRepositoryName = repository.name,
|
||||
issueId = issueId,
|
||||
originBranch = form.targetBranch,
|
||||
requestUserName = form.requestUserName,
|
||||
requestRepositoryName = form.requestRepositoryName,
|
||||
requestBranch = form.requestBranch,
|
||||
commitIdFrom = form.commitIdFrom,
|
||||
commitIdTo = form.commitIdTo)
|
||||
createPullRequest(
|
||||
originUserName = repository.owner,
|
||||
originRepositoryName = repository.name,
|
||||
issueId = issueId,
|
||||
originBranch = form.targetBranch,
|
||||
requestUserName = form.requestUserName,
|
||||
requestRepositoryName = form.requestRepositoryName,
|
||||
requestBranch = form.requestBranch,
|
||||
commitIdFrom = form.commitIdFrom,
|
||||
commitIdTo = form.commitIdTo)
|
||||
|
||||
// fetch requested branch
|
||||
fetchAsPullRequest(repository.owner, repository.name, form.requestUserName, form.requestRepositoryName, form.requestBranch, issueId)
|
||||
|
||||
// record activity
|
||||
recordPullRequestActivity(repository.owner, repository.name, loginUserName, issueId, form.title)
|
||||
|
||||
// call web hook
|
||||
callPullRequestWebHook("opened", repository, issueId, context.baseUrl, context.loginAccount.get)
|
||||
|
||||
// notifications
|
||||
getIssue(repository.owner, repository.name, issueId.toString) foreach { issue =>
|
||||
Notifier().toNotify(repository, issue, form.content.getOrElse("")){
|
||||
Notifier.msgPullRequest(s"${context.baseUrl}/${repository.owner}/${repository.name}/pull/${issueId}")
|
||||
// insert labels
|
||||
if(writable){
|
||||
form.labelNames.map { value =>
|
||||
val labels = getLabels(owner, name)
|
||||
value.split(",").foreach { labelName =>
|
||||
labels.find(_.labelName == labelName).map { label =>
|
||||
registerIssueLabel(repository.owner, repository.name, issueId, label.labelId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
redirect(s"/${repository.owner}/${repository.name}/pull/${issueId}")
|
||||
// fetch requested branch
|
||||
fetchAsPullRequest(owner, name, form.requestUserName, form.requestRepositoryName, form.requestBranch, issueId)
|
||||
|
||||
// record activity
|
||||
recordPullRequestActivity(owner, name, loginUserName, issueId, form.title)
|
||||
|
||||
// call web hook
|
||||
callPullRequestWebHook("opened", repository, issueId, context.baseUrl, context.loginAccount.get)
|
||||
|
||||
// notifications
|
||||
getIssue(owner, name, issueId.toString) foreach { issue =>
|
||||
Notifier().toNotify(repository, issue, form.content.getOrElse("")){
|
||||
Notifier.msgPullRequest(s"${context.baseUrl}/${owner}/${name}/pull/${issueId}")
|
||||
}
|
||||
}
|
||||
|
||||
redirect(s"/${owner}/${name}/pull/${issueId}")
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -459,7 +493,11 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
"pulls",
|
||||
searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName),
|
||||
page,
|
||||
(getCollaborators(owner, repoName) :+ owner).sorted,
|
||||
if(!getAccountByUserName(owner).exists(_.isGroupAccount)){
|
||||
(getCollaborators(owner, repoName) :+ owner).sorted
|
||||
} else {
|
||||
getCollaborators(owner, repoName)
|
||||
},
|
||||
getMilestones(owner, repoName),
|
||||
getLabels(owner, repoName),
|
||||
countIssue(condition.copy(state = "open" ), true, owner -> repoName),
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.apache.commons.io.FileUtils
|
||||
import org.eclipse.jgit.api.{ArchiveCommand, Git}
|
||||
import org.eclipse.jgit.archive.{TgzFormat, ZipFormat}
|
||||
import org.eclipse.jgit.dircache.DirCache
|
||||
import org.eclipse.jgit.errors.MissingObjectException
|
||||
import org.eclipse.jgit.lib._
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
import org.eclipse.jgit.treewalk._
|
||||
@@ -249,7 +250,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
)
|
||||
|
||||
redirect(s"/${repository.owner}/${repository.name}/blob/${form.branch}/${
|
||||
if(form.path.length == 0) form.newFileName else s"${form.path}/${form.newFileName}"
|
||||
if(form.path.length == 0) urlEncode(form.newFileName) else s"${form.path}/${urlEncode(form.newFileName)}"
|
||||
}")
|
||||
})
|
||||
|
||||
@@ -270,7 +271,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
)
|
||||
|
||||
redirect(s"/${repository.owner}/${repository.name}/blob/${form.branch}/${
|
||||
if(form.path.length == 0) form.newFileName else s"${form.path}/${form.newFileName}"
|
||||
if(form.path.length == 0) urlEncode(form.newFileName) else s"${form.path}/${urlEncode(form.newFileName)}"
|
||||
}")
|
||||
})
|
||||
|
||||
@@ -344,16 +345,21 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
get("/:owner/:repository/commit/:id")(referrersOnly { repository =>
|
||||
val id = params("id")
|
||||
|
||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
|
||||
defining(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))){ revCommit =>
|
||||
JGitUtil.getDiffs(git, id) match { case (diffs, oldCommitId) =>
|
||||
html.commit(id, new JGitUtil.CommitInfo(revCommit),
|
||||
JGitUtil.getBranchesOfCommit(git, revCommit.getName),
|
||||
JGitUtil.getTagsOfCommit(git, revCommit.getName),
|
||||
getCommitComments(repository.owner, repository.name, id, false),
|
||||
repository, diffs, oldCommitId, hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||
try {
|
||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||
defining(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))) { revCommit =>
|
||||
JGitUtil.getDiffs(git, id) match {
|
||||
case (diffs, oldCommitId) =>
|
||||
html.commit(id, new JGitUtil.CommitInfo(revCommit),
|
||||
JGitUtil.getBranchesOfCommit(git, revCommit.getName),
|
||||
JGitUtil.getTagsOfCommit(git, revCommit.getName),
|
||||
getCommitComments(repository.owner, repository.name, id, false),
|
||||
repository, diffs, oldCommitId, hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
case e:MissingObjectException => NotFound
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ object AutoUpdate {
|
||||
* The history of versions. A head of this sequence is the current BitBucket version.
|
||||
*/
|
||||
val versions = Seq(
|
||||
new Version(3, 6),
|
||||
new Version(3, 5),
|
||||
new Version(3, 4),
|
||||
new Version(3, 3),
|
||||
|
||||
@@ -10,28 +10,64 @@ trait LinkConverter { self: RequestCache =>
|
||||
* Converts issue id, username and commit id to link.
|
||||
*/
|
||||
protected def convertRefsLinks(value: String, repository: RepositoryService.RepositoryInfo,
|
||||
issueIdPrefix: String = "#", escapeHtml: Boolean = true)(implicit context: Context): String = {
|
||||
issueIdPrefix: String = "#", escapeHtml: Boolean = true)(implicit context: Context): String = {
|
||||
|
||||
// escape HTML tags
|
||||
val escaped = if(escapeHtml) value.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """) else value
|
||||
|
||||
escaped
|
||||
// convert issue id to link
|
||||
.replaceBy(("(?<=(^|\\W))" + issueIdPrefix + "([0-9]+)(?=(\\W|$))").r){ m =>
|
||||
getIssue(repository.owner, repository.name, m.group(2)) match {
|
||||
case Some(issue) if(issue.isPullRequest)
|
||||
=> Some(s"""<a href="${context.path}/${repository.owner}/${repository.name}/pull/${m.group(2)}">#${m.group(2)}</a>""")
|
||||
case Some(_) => Some(s"""<a href="${context.path}/${repository.owner}/${repository.name}/issues/${m.group(2)}">#${m.group(2)}</a>""")
|
||||
case None => Some(s"""#${m.group(2)}""")
|
||||
}
|
||||
// convert username/project@SHA to link
|
||||
.replaceBy("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)/([a-zA-Z0-9\\-_\\.]+)@([a-f0-9]{40})(?=(\\W|$))".r){ m =>
|
||||
getAccountByUserName(m.group(2)).map { _ =>
|
||||
s"""<a href="${context.path}/${m.group(2)}/${m.group(3)}/commit/${m.group(4)}">${m.group(2)}/${m.group(3)}@${m.group(4).substring(0, 7)}</a>"""
|
||||
}
|
||||
}
|
||||
|
||||
// convert username/project#Num to link
|
||||
.replaceBy( ("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)/([a-zA-Z0-9\\-_\\.]+)" + issueIdPrefix + "([0-9]+)(?=(\\W|$))").r){ m =>
|
||||
getIssue(m.group(2), m.group(3), m.group(4)) match {
|
||||
case Some(issue) if (issue.isPullRequest)
|
||||
=> Some( s"""<a href="${context.path}/${m.group(2)}/${m.group(3)}/pull/${m.group(4)}">${m.group(2)}/${m.group(3)}#${m.group(4)}</a>""")
|
||||
case Some(_) => Some( s"""<a href="${context.path}/${m.group(2)}/${m.group(3)}/issues/${m.group(4)}">${m.group(2)}/${m.group(3)}#${m.group(4)}</a>""")
|
||||
case None => Some( s"""${m.group(2)}/${m.group(3)}#${m.group(4)}""")
|
||||
}
|
||||
}
|
||||
|
||||
// convert username@SHA to link
|
||||
.replaceBy( ("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)@([a-f0-9]{40})(?=(\\W|$))").r ) { m =>
|
||||
getAccountByUserName(m.group(2)).map { _ =>
|
||||
s"""<a href="${context.path}/${m.group(2)}/${repository.name}/commit/${m.group(3)}">${m.group(2)}@${m.group(3).substring(0, 7)}</a>"""
|
||||
}
|
||||
}
|
||||
|
||||
// convert username#Num to link
|
||||
.replaceBy( ("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)" + issueIdPrefix + "([0-9]+)(?=(\\W|$))").r ) { m =>
|
||||
getIssue(m.group(2), repository.name, m.group(3)) match {
|
||||
case Some(issue) if(issue.isPullRequest)
|
||||
=> Some(s"""<a href="${context.path}/${m.group(2)}/${repository.name}/pull/${m.group(3)}">${m.group(2)}#${m.group(3)}</a>""")
|
||||
case Some(_) => Some(s"""<a href="${context.path}/${m.group(2)}/${repository.name}/issues/${m.group(3)}">${m.group(2)}#${m.group(3)}</a>""")
|
||||
case None => Some(s"""${m.group(2)}#${m.group(3)}""")
|
||||
}
|
||||
}
|
||||
|
||||
// convert issue id to link
|
||||
.replaceBy(("(?<=(^|\\W))(GH-|" + issueIdPrefix + ")([0-9]+)(?=(\\W|$))").r){ m =>
|
||||
getIssue(repository.owner, repository.name, m.group(3)) match {
|
||||
case Some(issue) if(issue.isPullRequest)
|
||||
=> Some(s"""<a href="${context.path}/${repository.owner}/${repository.name}/pull/${m.group(3)}">${m.group(2)}${m.group(3)}</a>""")
|
||||
case Some(_) => Some(s"""<a href="${context.path}/${repository.owner}/${repository.name}/issues/${m.group(3)}">${m.group(2)}${m.group(3)}</a>""")
|
||||
case None => Some(s"""${m.group(2)}${m.group(3)}""")
|
||||
}
|
||||
}
|
||||
|
||||
// convert @username to link
|
||||
.replaceBy("(?<=(^|\\W))@([a-zA-Z0-9\\-_]+)(?=(\\W|$))".r){ m =>
|
||||
.replaceBy("(?<=(^|\\W))@([a-zA-Z0-9\\-_\\.]+)(?=(\\W|$))".r){ m =>
|
||||
getAccountByUserName(m.group(2)).map { _ =>
|
||||
s"""<a href="${context.path}/${m.group(2)}">@${m.group(2)}</a>"""
|
||||
}
|
||||
}
|
||||
|
||||
// convert commit id to link
|
||||
.replaceAll("(?<=(^|\\W))([a-f0-9]{40})(?=(\\W|$))", s"""<a href="${context.path}/${repository.owner}/${repository.name}/commit/$$2">$$2</a>""")
|
||||
.replaceAll("(?<=(^|[^\\w/@]))([a-f0-9]{40})(?=(\\W|$))", s"""<a href="${context.path}/${repository.owner}/${repository.name}/commit/$$2">$$2</a>""")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
</div>
|
||||
<div class="block">
|
||||
@if(account.url.isDefined){
|
||||
<div><i class="icon-home"></i> <a href="@account.url">@account.url</a></div>
|
||||
<div><i class="octicon octicon-home"></i> <a href="@account.url">@account.url</a></div>
|
||||
}
|
||||
<div><i class="icon-time"></i> <span class="muted">Joined on</span> @date(account.registeredDate)</div>
|
||||
<div><i class="octicon octicon-clock"></i> <span class="muted">Joined on</span> @date(account.registeredDate)</div>
|
||||
</div>
|
||||
@if(groupNames.nonEmpty){
|
||||
<div>
|
||||
|
||||
@@ -13,7 +13,7 @@ isCreateRepoOptionPublic: Boolean)(implicit context: gitbucket.core.controller.C
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="javascript:void(0);" data-name="@loginAccount.get.userName"><i class="icon-ok"></i> <span>@avatar(loginAccount.get.userName, 20) @loginAccount.get.userName</span></a></li>
|
||||
<li><a href="javascript:void(0);" data-name="@loginAccount.get.userName"><i class="octicon octicon-check"></i> <span>@avatar(loginAccount.get.userName, 20) @loginAccount.get.userName</span></a></li>
|
||||
@groupNames.map { groupName =>
|
||||
<li><a href="javascript:void(0);" data-name="@groupName"><i class="icon-white"></i> <span>@avatar(groupName, 20) @groupName</span></a></li>
|
||||
}
|
||||
@@ -40,7 +40,7 @@ isCreateRepoOptionPublic: Boolean)(implicit context: gitbucket.core.controller.C
|
||||
<fieldset>
|
||||
<label class="radio">
|
||||
<input type="radio" name="isPrivate" value="true" @if(!isCreateRepoOptionPublic){checked}>
|
||||
<span class="strong"><i class="icon-lock"></i> </i> Private</span><br>
|
||||
<span class="strong"><i class="octicon octicon-lock"></i> </i> Private</span><br>
|
||||
<div>
|
||||
<span>Only collaborators can read this repository.</span>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="block-header">
|
||||
<a href="@url(repository)">@repository.name</a>
|
||||
@if(repository.repository.isPrivate){
|
||||
<i class="icon-lock"></i>
|
||||
<i class="octicon octicon-lock"></i>
|
||||
}
|
||||
</div>
|
||||
@if(repository.repository.originUserName.isDefined){
|
||||
|
||||
@@ -3,19 +3,20 @@
|
||||
<div class="container">
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<div class="box">
|
||||
<ul class="nav nav-tabs nav-stacked side-menu">
|
||||
<li@if(active=="users"){ class="active"}>
|
||||
<a href="@path/admin/users">User Management</a>
|
||||
</li>
|
||||
<li@if(active=="system"){ class="active"}>
|
||||
<a href="@path/admin/system">System Settings</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@path/console/login.jsp">H2 Console</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="nav nav-tabs nav-stacked side-menu" id="system-admin-menu-container">
|
||||
<li@if(active=="users"){ class="active"}>
|
||||
<a href="@path/admin/users">User Management</a>
|
||||
</li>
|
||||
<li@if(active=="system"){ class="active"}>
|
||||
<a href="@path/admin/system">System Settings</a>
|
||||
</li>
|
||||
<li@if(active=="plugins"){ class="active"}>
|
||||
<a href="@path/admin/plugins">Plugins</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="@path/console/login.jsp">H2 Console</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="span9">
|
||||
@body
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
@(plugins: List[gitbucket.core.plugin.PluginInfo])(implicit context: gitbucket.core.controller.Context)
|
||||
@import context._
|
||||
@import gitbucket.core.view.helpers._
|
||||
@html.main("Plugins"){
|
||||
@admin.html.menu("plugins") {
|
||||
<h1>Installed plugins</h1>
|
||||
|
||||
@if(plugins.size > 0) {
|
||||
<ul>
|
||||
@plugins.map {plugin =>
|
||||
<li><a href="#@plugin.pluginId">@plugin.pluginId:@plugin.version</a></li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
@plugins.map {plugin =>
|
||||
<div class="box">
|
||||
<div class="box-header">@plugin.pluginName</div>
|
||||
<div class="box-content">
|
||||
<p><span class="strong">Id: </span>@plugin.pluginId</p>
|
||||
<p><span class="strong">Version: </span>@plugin.version</p>
|
||||
<p><span class="strong">Name: </span>@plugin.pluginName</p>
|
||||
<p class="muted">@plugin.description</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
} else {
|
||||
<p>No plugin detected on your gitbucket installation.</p>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,9 +280,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<fieldset>
|
||||
<div class="align-right" style="margin-top: 20px;">
|
||||
<input type="submit" class="btn btn-success" value="Apply changes"/>
|
||||
</fieldset>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
<div>
|
||||
<hr>
|
||||
@if(!account.isGroupAccount){
|
||||
<i class="icon-envelope"></i> @account.mailAddress
|
||||
<i class="octicon octicon-mail"></i> @account.mailAddress
|
||||
}
|
||||
@account.url.map { url =>
|
||||
<i class="icon-home"></i> @url
|
||||
<i class="octicon octicon-home"></i> @url
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
@helper.html.dropdown(
|
||||
value = if(branch.length == 40) branch.substring(0, 10) else branch,
|
||||
prefix = if(branch.length == 40) "tree" else if(repository.branchList.contains(branch)) "branch" else "tree",
|
||||
mini = true
|
||||
mini = false
|
||||
) {
|
||||
<li><div id="branch-control-title">Switch branches<button id="branch-control-close" class="pull-right">×</button></div></li>
|
||||
<li><input id="branch-control-input" type="text" placeholder="Find or create branch ..."/></li>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@(condition: => Boolean)
|
||||
@if(condition){
|
||||
<i class="icon-ok"></i>
|
||||
<i class="octicon octicon-check"></i>
|
||||
} else {
|
||||
<i class="icon-white"></i>
|
||||
}
|
||||
@@ -24,8 +24,8 @@
|
||||
</span>
|
||||
<span class="pull-right">
|
||||
@if(hasWritePermission || loginAccount.map(_.userName == comment.commentedUserName).getOrElse(false)){
|
||||
<a href="#" data-comment-id="@comment.commentId"><i class="icon-pencil"></i></a>
|
||||
<a href="#" data-comment-id="@comment.commentId"><i class="icon-remove-circle"></i></a>
|
||||
<a href="#" data-comment-id="@comment.commentId"><i class="octicon octicon-pencil"></i></a>
|
||||
<a href="#" data-comment-id="@comment.commentId"><i class="octicon octicon-x"></i></a>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@(id: String, value: String)(html: Html)
|
||||
<div class="input-append" style="margin-bottom: 0px;">
|
||||
@(id: String, value: String, prepend: Boolean = false)(html: Html)
|
||||
<div class="input-append @if(prepend){input-prepend}" style="margin-bottom: 0px;">
|
||||
@html
|
||||
<span id="@id" class="add-on btn" data-clipboard-text="@value" data-placement="bottom" title="copy to clipboard"><i class="icon-check"></i></span>
|
||||
<span id="@id" class="add-on btn" data-clipboard-text="@value" data-placement="bottom" title="copy to clipboard"><i class="octicon octicon-clippy"></i></span>
|
||||
</div>
|
||||
<script>
|
||||
// copy to clipboard
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@import gitbucket.core.view.helpers
|
||||
<div id="@name" class="input-append date" data-date-format="yyyy-mm-dd" data-date="@value.map(helpers.date)">
|
||||
<input class="span2" name="@name" type="text" readonly="" value="@value.map(helpers.date)" size="16"/>
|
||||
<span class="add-on"><i class="icon-calendar"></i></span>
|
||||
<span class="add-on"><i class="octicon octicon-calendar"></i></span>
|
||||
</div>
|
||||
<script>
|
||||
$(function(){
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
@if(flat){style="border: none; background-color: #eee;"}
|
||||
class="dropdown-toggle @if(!flat){btn} else {flat} @if(mini){btn-mini} else {btn-small}" data-toggle="dropdown">
|
||||
@if(value.isEmpty){
|
||||
<i class="icon-cog"></i>
|
||||
<i class="octicon octicon-gear"></i>
|
||||
} else {
|
||||
@if(prefix.nonEmpty){
|
||||
<span class="muted">@prefix:</span>
|
||||
|
||||
@@ -24,57 +24,64 @@
|
||||
@if(loginAccount.isEmpty){
|
||||
@signinform(settings)
|
||||
} else {
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th class="metal">
|
||||
<div class="pull-right">
|
||||
<a href="@path/new" class="btn btn-success btn-mini">New repository</a>
|
||||
</div>
|
||||
Your repositories (@userRepositories.size)
|
||||
</th>
|
||||
</tr>
|
||||
<div class="box-header">
|
||||
<div class="pull-right">
|
||||
<a href="@path/new" class="btn btn-success btn-mini">New repository</a>
|
||||
</div>
|
||||
<span class="strong">Your repositories</span> <span class="label">@userRepositories.size</span>
|
||||
</div>
|
||||
@if(userRepositories.isEmpty){
|
||||
<tr>
|
||||
<td>No repositories</td>
|
||||
</tr>
|
||||
<div class="box-content-bottom">
|
||||
No repositories
|
||||
</div>
|
||||
} else {
|
||||
@userRepositories.map { repository =>
|
||||
<tr>
|
||||
<td>
|
||||
@helper.html.repositoryicon(repository, false)
|
||||
@if(repository.owner == loginAccount.get.userName){
|
||||
<a href="@url(repository)"><span class="strong">@repository.name</span></a>
|
||||
} else {
|
||||
<a href="@url(repository)">@repository.owner/<span class="strong">@repository.name</span></a>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<div class="box-content-bottom" style="padding: 0px;">
|
||||
@defining(20){ max =>
|
||||
@userRepositories.zipWithIndex.map { case (repository, i) =>
|
||||
<div class="box-content-row repo-link" style="@if(i > max - 1){display:none;}">
|
||||
@helper.html.repositoryicon(repository, false)
|
||||
@if(repository.owner == loginAccount.get.userName){
|
||||
<a href="@url(repository)"><span class="strong">@repository.name</span></a>
|
||||
} else {
|
||||
<a href="@url(repository)">@repository.owner/<span class="strong">@repository.name</span></a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@if(userRepositories.size > max){
|
||||
<div class="box-content-row show-more">
|
||||
<a href="javascript:void(0);" id="show-more-repos">Show more @{userRepositories.size - max} pages...</a>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</table>
|
||||
}
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th class="metal">
|
||||
Recent updated repositories
|
||||
</th>
|
||||
</tr>
|
||||
@if(recentRepositories.isEmpty){
|
||||
<tr>
|
||||
<td>No repositories</td>
|
||||
</tr>
|
||||
} else {
|
||||
<div class="box-header">
|
||||
<span class="strong">Recent updated repositories</span>
|
||||
</div>
|
||||
@if(recentRepositories.isEmpty){
|
||||
<div class="box-content-bottom">
|
||||
No repositories
|
||||
</div>
|
||||
} else {
|
||||
<div class="box-content-bottom" style="padding: 0px;">
|
||||
@recentRepositories.map { repository =>
|
||||
<tr>
|
||||
<td>
|
||||
@helper.html.repositoryicon(repository, false)
|
||||
<a href="@url(repository)">@repository.owner/<span class="strong">@repository.name</span></a>
|
||||
</td>
|
||||
</tr>
|
||||
<div class="box-content-row">
|
||||
@helper.html.repositoryicon(repository, false)
|
||||
<a href="@url(repository)">@repository.owner/<span class="strong">@repository.name</span></a>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<script>
|
||||
$(function(){
|
||||
$('#show-more-repos').click(function(e){
|
||||
$('div.repo-link').show();
|
||||
$(e.target).parents('div.show-more').remove();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -8,7 +8,7 @@
|
||||
<hr/><br/>
|
||||
<form method="POST" validate="true">
|
||||
<div class="issue-avatar-image">@avatar(loginAccount.get.userName, 48)</div>
|
||||
<div class="box issue-comment-box">
|
||||
<div class="issue-comment-box">
|
||||
<div class="box-content">
|
||||
@helper.html.preview(
|
||||
repository = repository,
|
||||
@@ -17,18 +17,18 @@
|
||||
enableRefsLink = true,
|
||||
enableTaskList = true,
|
||||
hasWritePermission = hasWritePermission,
|
||||
style = "width: 635px; height: 100px; max-height: 150px;",
|
||||
style = "",
|
||||
elastic = true
|
||||
)
|
||||
<div style="text-align: right;">
|
||||
<input type="hidden" name="issueId" value="@issue.issueId"/>
|
||||
<input type="submit" class="btn btn-success" formaction="@url(repository)/issue_comments/new" value="Comment"/>
|
||||
@if((reopenable || !issue.closed) && (hasWritePermission || issue.openedUserName == loginAccount.get.userName)){
|
||||
<input type="submit" class="btn" formaction="@url(repository)/issue_comments/state" value="@{if(issue.closed) "Reopen" else "Close"}" id="action"/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<input type="hidden" name="issueId" value="@issue.issueId"/>
|
||||
<input type="submit" class="btn btn-success" formaction="@url(repository)/issue_comments/new" value="Comment"/>
|
||||
@if((reopenable || !issue.closed) && (hasWritePermission || issue.openedUserName == loginAccount.get.userName)){
|
||||
<input type="submit" class="btn" formaction="@url(repository)/issue_comments/state" value="@{if(issue.closed) "Reopen" else "Close"}" id="action"/>
|
||||
}
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
<script>
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
@import gitbucket.core.model.CommitComment
|
||||
@if(issue.isDefined){
|
||||
<div class="issue-avatar-image">@avatar(issue.get.openedUserName, 48)</div>
|
||||
<div class="box issue-comment-box">
|
||||
<div class="box-header-small">
|
||||
<div class="issue-comment-box">
|
||||
<div class="box-header">
|
||||
@user(issue.get.openedUserName, styleClass="username strong") <span class="muted">commented @helper.html.datetimeago(issue.get.registeredDate)</span>
|
||||
<span class="pull-right">
|
||||
@if(hasWritePermission || loginAccount.map(_.userName == issue.get.openedUserName).getOrElse(false)){
|
||||
<a href="#" data-issue-id="@issue.get.issueId"><i class="icon-pencil" aria-label="Edit"></i></a>
|
||||
<a href="#" data-issue-id="@issue.get.issueId"><i class="octicon octicon-pencil" aria-label="Edit"></i></a>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
<div class="box-content issue-content markdown-body" id="issueContent">
|
||||
<div class="box-content-bottom issue-content markdown-body" id="issueContent">
|
||||
@markdown(issue.get.content getOrElse "No description provided.", repository, false, true, true, hasWritePermission)
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
@if(comment.action != "close" && comment.action != "reopen" && comment.action != "delete_branch"){
|
||||
<div class="issue-avatar-image">@avatar(comment.commentedUserName, 48)</div>
|
||||
<div class="box issue-comment-box" id="comment-@comment.commentId">
|
||||
<div class="box-header-small">
|
||||
<div class="box-header">
|
||||
@user(comment.commentedUserName, styleClass="username strong")
|
||||
<span class="muted">
|
||||
@if(comment.action == "comment"){
|
||||
@@ -41,12 +41,12 @@
|
||||
<span class="pull-right">
|
||||
@if(comment.action != "commit" && comment.action != "merge" && comment.action != "refer"
|
||||
&& (hasWritePermission || loginAccount.map(_.userName == comment.commentedUserName).getOrElse(false))){
|
||||
<a href="#" data-comment-id="@comment.commentId"><i class="icon-pencil" aria-label="Edit"></i></a>
|
||||
<a href="#" data-comment-id="@comment.commentId"><i class="icon-remove-circle" aria-label="Remove"></i></a>
|
||||
<a href="#" data-comment-id="@comment.commentId"><i class="octicon octicon-pencil" aria-label="Edit"></i></a>
|
||||
<a href="#" data-comment-id="@comment.commentId"><i class="octicon octicon-x" aria-label="Remove"></i></a>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
<div class="box-content"class="issue-content" id="commentContent-@comment.commentId">
|
||||
<div class="box-content-bottom issue-content" id="commentContent-@comment.commentId">
|
||||
@if(comment.action == "commit" && comment.content.split(" ").last.matches("[a-f0-9]{40}")){
|
||||
@defining(comment.content.substring(comment.content.length - 40)){ id =>
|
||||
<div class="pull-right"><a href="@path/@repository.owner/@repository.name/commit/@id" class="monospace">@id.substring(0, 7)</a></div>
|
||||
@@ -78,8 +78,8 @@
|
||||
</div>
|
||||
}
|
||||
@if(comment.action == "close" || comment.action == "close_comment"){
|
||||
<div class="small issue-comment-action">
|
||||
<span class="label label-important">Closed</span>
|
||||
<div class="issue-comment-action">
|
||||
<i class="octicon octicon-circle-slash danger"></i>
|
||||
@avatar(comment.commentedUserName, 20)
|
||||
@if(issue.isDefined && issue.get.isPullRequest){
|
||||
@user(comment.commentedUserName, styleClass="username strong") closed the pull request @helper.html.datetimeago(comment.registeredDate)
|
||||
@@ -89,14 +89,14 @@
|
||||
</div>
|
||||
}
|
||||
@if(comment.action == "reopen" || comment.action == "reopen_comment"){
|
||||
<div class="small issue-comment-action">
|
||||
<span class="label label-success">Reopened</span>
|
||||
<div class="issue-comment-action issue-reopened">
|
||||
<i class="octicon octicon-primitive-dot"></i>
|
||||
@avatar(comment.commentedUserName, 20)
|
||||
@user(comment.commentedUserName, styleClass="username strong") reopened the issue @helper.html.datetimeago(comment.registeredDate)
|
||||
</div>
|
||||
}
|
||||
@if(comment.action == "delete_branch"){
|
||||
<div class="small issue-comment-action">
|
||||
<div class="issue-comment-action">
|
||||
<span class="label">Deleted</span>
|
||||
@avatar(comment.commentedUserName, 20)
|
||||
@user(comment.commentedUserName, styleClass="username strong") deleted the <span class="label label-info monospace">@pullreq.map(_.requestBranch)</span> branch @helper.html.datetimeago(comment.registeredDate)
|
||||
@@ -110,7 +110,7 @@
|
||||
<script>
|
||||
$(function(){
|
||||
@if(issue.isDefined){
|
||||
$('.issue-comment-box i.icon-pencil').click(function(){
|
||||
$('.issue-comment-box i.octicon-pencil').click(function(){
|
||||
var id = $(this).closest('a').data('comment-id');
|
||||
var url = '@url(repository)/issue_comments/_data/' + id;
|
||||
var $content = $('#commentContent-' + id);
|
||||
@@ -130,7 +130,7 @@ $(function(){
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('.issue-comment-box i.icon-remove-circle').click(function(){
|
||||
$('.issue-comment-box i.octicon-x').click(function(){
|
||||
if(confirm('Are you sure you want to delete this?')) {
|
||||
var id = $(this).closest('a').data('comment-id');
|
||||
$.post('@url(repository)/issue_comments/delete/' + id,
|
||||
@@ -144,7 +144,7 @@ $(function(){
|
||||
return false;
|
||||
});
|
||||
}
|
||||
$(document).on('click', '.commit-comment-box i.icon-pencil', function(){
|
||||
$(document).on('click', '.commit-comment-box i.octicon-pencil', function(){
|
||||
var id = $(this).closest('a').data('comment-id');
|
||||
var url = '@url(repository)/commit_comments/_data/' + id;
|
||||
var $content = $('.commit-commentContent-' + id, $(this).closest('.box'));
|
||||
@@ -158,7 +158,7 @@ $(function(){
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$(document).on('click', '.commit-comment-box i.icon-remove-circle', function(){
|
||||
$(document).on('click', '.commit-comment-box i.octicon-x', function(){
|
||||
if(confirm('Are you sure you want to delete this?')) {
|
||||
var id = $(this).closest('a').data('comment-id');
|
||||
$.post('@url(repository)/commit_comments/delete/' + id,
|
||||
|
||||
@@ -10,148 +10,33 @@
|
||||
@navigation("issues", false, repository)
|
||||
<br/><br/><hr style="margin-bottom: 10px;">
|
||||
<form action="@url(repository)/issues/new" method="POST" validate="true">
|
||||
<div class="row-fluid">
|
||||
<div class="span9">
|
||||
<div class="issue-avatar-image">@avatar(loginAccount.get.userName, 48)</div>
|
||||
<div class="box issue-box">
|
||||
<div class="box-content">
|
||||
<span id="error-title" class="error"></span>
|
||||
<input type="text" name="title" value="" placeholder="Title" style="width: 565px;" autofocus/>
|
||||
<div>
|
||||
<span id="label-assigned">No one is assigned</span>
|
||||
@if(hasWritePermission){
|
||||
<input type="hidden" name="assignedUserName" value=""/>
|
||||
@helper.html.dropdown() {
|
||||
<li><a href="javascript:void(0);" class="assign" data-name=""><i class="icon-remove-circle"></i> Clear assignee</a></li>
|
||||
@collaborators.map { collaborator =>
|
||||
<li><a href="javascript:void(0);" class="assign" data-name="@collaborator"><i class="icon-while"></i>@avatar(collaborator, 20) @collaborator</a></li>
|
||||
}
|
||||
}
|
||||
}
|
||||
<div class="pull-right">
|
||||
<span id="label-milestone">No milestone</span>
|
||||
@if(hasWritePermission){
|
||||
<input type="hidden" name="milestoneId" value=""/>
|
||||
@helper.html.dropdown() {
|
||||
<li><a href="javascript:void(0);" class="milestone" data-id=""><i class="icon-remove-circle"></i> Clear this milestone</a></li>
|
||||
@milestones.filter(_.closedDate.isEmpty).map { milestone =>
|
||||
<li>
|
||||
<a href="javascript:void(0);" class="milestone" data-id="@milestone.milestoneId" data-title="@milestone.title">
|
||||
<i class="icon-while"></i> @milestone.title
|
||||
<div class="small" style="padding-left: 20px;">
|
||||
@milestone.dueDate.map { dueDate =>
|
||||
@if(isPast(dueDate)){
|
||||
<i class="octicon octicon-alert" style="color:#BD2C00;"></i><span class="milestone-alert">Due by @date(dueDate)</span>
|
||||
} else {
|
||||
<span class="muted">Due by @date(dueDate)</span>
|
||||
}
|
||||
}.getOrElse {
|
||||
<span class="muted">No due date</span>
|
||||
}
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
}
|
||||
<div class="row-fluid">
|
||||
<div class="span10">
|
||||
<div class="issue-avatar-image">@avatar(loginAccount.get.userName, 48)</div>
|
||||
<div class="box issue-box">
|
||||
<div class="box-content">
|
||||
<span id="error-title" class="error"></span>
|
||||
<input type="text" name="title" value="" placeholder="Title" style="width: 690px;" autofocus/>
|
||||
@helper.html.preview(
|
||||
repository = repository,
|
||||
content = "",
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableTaskList = true,
|
||||
hasWritePermission = hasWritePermission,
|
||||
style = "width: 690px; height: 200px; max-height: 250px;",
|
||||
elastic = true
|
||||
)
|
||||
<div class="align-right">
|
||||
<input type="submit" class="btn btn-success" value="Submit new issue"/>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
@helper.html.preview(
|
||||
repository = repository,
|
||||
content = "",
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableTaskList = true,
|
||||
hasWritePermission = hasWritePermission,
|
||||
style = "width: 565px; height: 200px; max-height: 250px;",
|
||||
elastic = true
|
||||
)
|
||||
</div>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<input type="submit" class="btn btn-success" value="Submit new issue"/>
|
||||
<div class="span2">
|
||||
@issueinfo(None, Nil, Nil, collaborators, milestones.map(x => (x, 0, 0)), labels, hasWritePermission, repository)
|
||||
</div>
|
||||
</div>
|
||||
<div class="span3">
|
||||
@if(hasWritePermission){
|
||||
<span class="strong">Labels</span>
|
||||
<div>
|
||||
<div id="label-list">
|
||||
<ul class="label-list nav nav-pills nav-stacked">
|
||||
@labels.map { label =>
|
||||
<li>
|
||||
<a href="javascript:void(0);" class="toggle-label" data-label="@label.labelName" data-bgcolor="@label.color" data-fgcolor="@label.fontColor">
|
||||
<span style="background-color: #@label.color;" class="label-color"> </span>
|
||||
@label.labelName
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
<input type="hidden" name="labelNames" value=""/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
<script>
|
||||
$(function(){
|
||||
$('a.assign').click(function(){
|
||||
var userName = $(this).data('name');
|
||||
$('a.assign i.icon-ok').attr('class', 'icon-white');
|
||||
|
||||
if(userName == ''){
|
||||
$('#label-assigned').text('No one will be assigned');
|
||||
} else {
|
||||
$('#label-assigned').html($('<span>')
|
||||
.append($('<a class="username strong">').attr('href', '@path/' + userName).text(userName))
|
||||
.append(' will be assigned'));
|
||||
$('a.assign[data-name=' + jqSelectorEscape(userName) + '] i').attr('class', 'icon-ok');
|
||||
}
|
||||
$('input[name=assignedUserName]').val(userName);
|
||||
});
|
||||
|
||||
$('a.milestone').click(function(){
|
||||
var title = $(this).data('title');
|
||||
var milestoneId = $(this).data('id');
|
||||
$('a.milestone i.icon-ok').attr('class', 'icon-white');
|
||||
|
||||
if(milestoneId == ''){
|
||||
$('#label-milestone').text('No milestone');
|
||||
} else {
|
||||
$('#label-milestone').html($('<span class="strong">').text(title));
|
||||
$('a.milestone[data-id=' + milestoneId + '] i').attr('class', 'icon-ok');
|
||||
}
|
||||
$('input[name=milestoneId]').val(milestoneId);
|
||||
});
|
||||
|
||||
$('a.toggle-label').click(function(){
|
||||
if($(this).data('selected') == true){
|
||||
$(this).css({
|
||||
'background-color': 'white',
|
||||
'color' : 'black',
|
||||
'font-weight' : 'normal'
|
||||
});
|
||||
$(this).data('selected', false);
|
||||
} else {
|
||||
$(this).css({
|
||||
'background-color': '#' + $(this).data('bgcolor'),
|
||||
'color' : '#' + $(this).data('fgcolor'),
|
||||
'font-weight' : 'bold'
|
||||
});
|
||||
$(this).data('selected', true);
|
||||
}
|
||||
|
||||
var labelNames = Array();
|
||||
$('a.toggle-label').each(function(i, e){
|
||||
if($(e).data('selected') == true){
|
||||
labelNames.push($(e).data('label'));
|
||||
}
|
||||
});
|
||||
$('input[name=labelNames]').val(labelNames.join(','));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@import context._
|
||||
<span id="error-edit-content-@commentId" class="error"></span>
|
||||
@helper.html.attached(owner, repository){
|
||||
<textarea style="width: 635px; height: 100px;" id="edit-content-@commentId">@content</textarea>
|
||||
<textarea id="edit-content-@commentId">@content</textarea>
|
||||
}
|
||||
<div>
|
||||
<input type="button" id="cancel-comment-@commentId" class="btn btn-small btn-danger" value="Cancel"/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@(content: Option[String], issueId: Int, owner: String, repository: String)(implicit context: gitbucket.core.controller.Context)
|
||||
@import context._
|
||||
@helper.html.attached(owner, repository){
|
||||
<textarea style="width: 635px; height: 100px; max-height: 300px;" id="edit-content">@content.getOrElse("")</textarea>
|
||||
<textarea id="edit-content">@content.getOrElse("")</textarea>
|
||||
}
|
||||
<div>
|
||||
<input type="button" id="cancel-issue" class="btn btn-small btn-danger" value="Cancel"/>
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
<div>
|
||||
<div class="show-title pull-right">
|
||||
@if(hasWritePermission || loginAccount.map(_.userName == issue.openedUserName).getOrElse(false)){
|
||||
<a class="btn btn-small" href="#" id="edit">Edit</a>
|
||||
<a class="btn" href="#" id="edit">Edit</a>
|
||||
}
|
||||
<a class="btn btn-small btn-success" href="@url(repository)/issues/new">New issue</a>
|
||||
<a class="btn btn-success" href="@url(repository)/issues/new">New issue</a>
|
||||
</div>
|
||||
<div class="edit-title pull-right" style="display: none;">
|
||||
<a class="btn" href="#" id="update">Save</a> <a href="#" id="cancel">Cancel</a>
|
||||
@@ -45,13 +45,14 @@
|
||||
</span>
|
||||
<br/><br/>
|
||||
<hr>
|
||||
<br/>
|
||||
<div class="row-fluid">
|
||||
<div class="span10">
|
||||
@commentlist(Some(issue), comments, hasWritePermission, repository)
|
||||
@commentform(issue, true, hasWritePermission, repository)
|
||||
</div>
|
||||
<div class="span2">
|
||||
@issueinfo(issue, comments, issueLabels, collaborators, milestones, labels, hasWritePermission, repository)
|
||||
@issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, labels, hasWritePermission, repository)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@(issue: gitbucket.core.model.Issue,
|
||||
@(issue: Option[gitbucket.core.model.Issue],
|
||||
comments: List[gitbucket.core.model.Comment],
|
||||
issueLabels: List[gitbucket.core.model.Label],
|
||||
collaborators: List[String],
|
||||
@@ -6,6 +6,7 @@
|
||||
labels: List[gitbucket.core.model.Label],
|
||||
hasWritePermission: Boolean,
|
||||
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
|
||||
@import context._
|
||||
@import gitbucket.core.view.helpers._
|
||||
<div style="margin-bottom: 8px;">
|
||||
<span class="muted small strong">Labels</span>
|
||||
@@ -22,6 +23,9 @@
|
||||
</li>
|
||||
}
|
||||
}
|
||||
@if(issue.isEmpty){
|
||||
<input type="hidden" name="labelNames" value=""/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -34,11 +38,14 @@
|
||||
@if(hasWritePermission){
|
||||
<div class="pull-right">
|
||||
@helper.html.dropdown(right = true) {
|
||||
<li><a href="javascript:void(0);" class="milestone" data-id=""><i class="icon-remove-circle"></i> Clear this milestone</a></li>
|
||||
<li><a href="javascript:void(0);" class="milestone" data-id=""><i class="octicon octicon-x"></i> Clear this milestone</a></li>
|
||||
@milestones.filter(_._1.closedDate.isEmpty).map { case (milestone, _, _) =>
|
||||
<li>
|
||||
<a href="javascript:void(0);" class="milestone" data-id="@milestone.milestoneId" data-title="@milestone.title">
|
||||
@helper.html.checkicon(Some(milestone.milestoneId) == issue.milestoneId) @milestone.title
|
||||
@issue.map { issue =>
|
||||
@helper.html.checkicon(Some(milestone.milestoneId) == issue.milestoneId)
|
||||
}
|
||||
@milestone.title
|
||||
<div class="small" style="padding-left: 20px;">
|
||||
@milestone.dueDate.map { dueDate =>
|
||||
@if(isPast(dueDate)){
|
||||
@@ -58,14 +65,14 @@
|
||||
}
|
||||
</div>
|
||||
<div id="milestone-progress-area">
|
||||
@issue.milestoneId.map { milestoneId =>
|
||||
@issue.flatMap(_.milestoneId).map { milestoneId =>
|
||||
@milestones.collect { case (milestone, openCount, closeCount) if(milestone.milestoneId == milestoneId) =>
|
||||
@issues.milestones.html.progress(openCount + closeCount, closeCount)
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<span id="label-milestone">
|
||||
@issue.milestoneId.map { milestoneId =>
|
||||
@issue.flatMap(_.milestoneId).map { milestoneId =>
|
||||
@milestones.collect { case (milestone, _, _) if(milestone.milestoneId == milestoneId) =>
|
||||
<span class="strong small">@milestone.title</span>
|
||||
}
|
||||
@@ -73,17 +80,20 @@
|
||||
<span class="muted small">No milestone</span>
|
||||
}
|
||||
</span>
|
||||
@if(issue.isEmpty){
|
||||
<input type="hidden" name="milestoneId" value=""/>
|
||||
}
|
||||
<hr/>
|
||||
<div style="margin-bottom: 8px;">
|
||||
<span class="muted small strong">Assignee</span>
|
||||
@if(hasWritePermission){
|
||||
<div class="pull-right">
|
||||
@helper.html.dropdown(right = true) {
|
||||
<li><a href="javascript:void(0);" class="assign" data-name=""><i class="icon-remove-circle"></i> Clear assignee</a></li>
|
||||
<li><a href="javascript:void(0);" class="assign" data-name=""><i class="octicon octicon-x"></i> Clear assignee</a></li>
|
||||
@collaborators.map { collaborator =>
|
||||
<li>
|
||||
<a href="javascript:void(0);" class="assign" data-name="@collaborator">
|
||||
@helper.html.checkicon(Some(collaborator) == issue.assignedUserName)@avatar(collaborator, 20) @collaborator
|
||||
@helper.html.checkicon(issue.exists(_.assignedUserName == collaborator))@avatar(collaborator, 20) @collaborator
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
@@ -92,39 +102,37 @@
|
||||
}
|
||||
</div>
|
||||
<span id="label-assigned">
|
||||
@issue.assignedUserName.map { userName =>
|
||||
@issue.flatMap(_.assignedUserName).map { userName =>
|
||||
@avatar(userName, 20) @user(userName, styleClass="username strong small")
|
||||
}.getOrElse{
|
||||
<span class="muted small">No one</span>
|
||||
}
|
||||
</span>
|
||||
<hr/>
|
||||
<div style="margin-bottom: 8px;">
|
||||
@defining((issue.openedUserName :: comments.map(_.commentedUserName)).distinct){ participants =>
|
||||
<div class="muted small strong">@participants.size @plural(participants.size, "participant")</div>
|
||||
@participants.map { participant => @avatarLink(participant, 20, tooltip = true) }
|
||||
}
|
||||
</div>
|
||||
@if(issue.isEmpty){
|
||||
<input type="hidden" name="assignedUserName" value=""/>
|
||||
}
|
||||
@issue.map { issue =>
|
||||
<hr/>
|
||||
<div style="margin-bottom: 8px;">
|
||||
@defining((issue.openedUserName :: comments.map(_.commentedUserName)).distinct){ participants =>
|
||||
<div class="muted small strong">@participants.size @plural(participants.size, "participant")</div>
|
||||
@participants.map { participant =>
|
||||
@avatarLink(participant, 20, tooltip = true)
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<script>
|
||||
$(function(){
|
||||
@issue.map { issue =>
|
||||
$('a.toggle-label').click(function(){
|
||||
var path, icon;
|
||||
var i = $(this).children('i');
|
||||
if(i.hasClass('icon-ok')){
|
||||
path = 'delete';
|
||||
icon = 'icon-white';
|
||||
} else {
|
||||
path = 'new';
|
||||
icon = 'icon-ok';
|
||||
}
|
||||
var path = switchLabel($(this));
|
||||
$.post('@url(repository)/issues/@issue.issueId/label/' + path,
|
||||
{
|
||||
labelId : $(this).data('label-id')
|
||||
},
|
||||
function(data){
|
||||
i.removeClass().addClass(icon);
|
||||
$('ul.label-list').empty().html(data);
|
||||
});
|
||||
{ labelId : $(this).data('label-id') },
|
||||
function(data){
|
||||
$('ul.label-list').empty().html(data);
|
||||
}
|
||||
);
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -132,42 +140,92 @@ $(function(){
|
||||
var title = $(this).data('title');
|
||||
var milestoneId = $(this).data('id');
|
||||
$.post('@url(repository)/issues/@issue.issueId/milestone',
|
||||
{
|
||||
milestoneId: milestoneId
|
||||
},
|
||||
function(data){
|
||||
console.log(data);
|
||||
$('a.milestone i.icon-ok').attr('class', 'icon-white');
|
||||
if(milestoneId == ''){
|
||||
$('#label-milestone').html($('<span class="muted small">').text('No milestone'));
|
||||
$('#milestone-progress-area').empty();
|
||||
} else {
|
||||
$('#label-milestone').html($('<span class="strong small">').text(title));
|
||||
$('#milestone-progress-area').html(data);
|
||||
$('a.milestone[data-id=' + milestoneId + '] i').attr('class', 'icon-ok');
|
||||
{ milestoneId: milestoneId },
|
||||
function(data){
|
||||
displayMilestone(title, milestoneId, data);
|
||||
}
|
||||
});
|
||||
);
|
||||
});
|
||||
|
||||
$('a.assign').click(function(){
|
||||
var $this = $(this);
|
||||
var userName = $this.data('name');
|
||||
$.post('@url(repository)/issues/@issue.issueId/assign',
|
||||
{
|
||||
assignedUserName: userName
|
||||
},
|
||||
function(){
|
||||
$('a.assign i.icon-ok').attr('class', 'icon-white');
|
||||
if(userName == ''){
|
||||
$('#label-assigned').html($('<span class="muted small">').text('No one'));
|
||||
} else {
|
||||
$('#label-assigned').empty()
|
||||
.append($this.find('img.avatar-mini').clone(false)).append(' ')
|
||||
.append($('<a class="username strong small">').attr('href', '@context.path/' + userName).text(userName));
|
||||
$('a.assign[data-name=' + jqSelectorEscape(userName) + '] i').attr('class', 'icon-ok');
|
||||
{ assignedUserName: userName },
|
||||
function(){
|
||||
displayAssignee($this, userName);
|
||||
}
|
||||
);
|
||||
});
|
||||
}.getOrElse {
|
||||
$('a.toggle-label').click(function(){
|
||||
switchLabel($(this));
|
||||
var labelNames = Array();
|
||||
$('a.toggle-label').each(function(i, e){
|
||||
if($(e).children('i').hasClass('icon-ok') == true){
|
||||
labelNames.push($(e).text().trim());
|
||||
}
|
||||
});
|
||||
$('input[name=labelNames]').val(labelNames.join(','));
|
||||
|
||||
$.post('@url(repository)/issues/new/label',
|
||||
{ labelNames : labelNames.join(',') },
|
||||
function(data){
|
||||
$('ul.label-list').empty().html(data);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('a.milestone').click(function(){
|
||||
var title = $(this).data('title');
|
||||
var milestoneId = $(this).data('id');
|
||||
displayMilestone(title, milestoneId);
|
||||
$('input[name=milestoneId]').val(milestoneId);
|
||||
});
|
||||
|
||||
$('a.assign').click(function(){
|
||||
var $this = $(this);
|
||||
var userName = $this.data('name');
|
||||
displayAssignee($this, userName);
|
||||
$('input[name=assignedUserName]').val(userName);
|
||||
});
|
||||
}
|
||||
|
||||
function switchLabel($this){
|
||||
var i = $this.children('i');
|
||||
if(i.hasClass('icon-ok')){
|
||||
i.removeClass().addClass('icon-white');
|
||||
return 'delete';
|
||||
} else {
|
||||
i.removeClass().addClass('icon-ok');
|
||||
return 'new';
|
||||
}
|
||||
}
|
||||
|
||||
function displayMilestone(title, milestoneId, progress){
|
||||
$('a.milestone i.icon-ok').attr('class', 'icon-white');
|
||||
if(milestoneId == ''){
|
||||
$('#label-milestone').html($('<span class="muted small">').text('No milestone'));
|
||||
$('#milestone-progress-area').empty();
|
||||
} else {
|
||||
$('#label-milestone').html($('<span class="strong small">').text(title));
|
||||
if(progress){
|
||||
$('#milestone-progress-area').html(progress);
|
||||
}
|
||||
$('a.milestone[data-id=' + milestoneId + '] i').attr('class', 'icon-ok');
|
||||
}
|
||||
}
|
||||
|
||||
function displayAssignee($this, userName){
|
||||
$('a.assign i.icon-ok').attr('class', 'icon-white');
|
||||
if(userName == ''){
|
||||
$('#label-assigned').html($('<span class="muted small">').text('No one'));
|
||||
} else {
|
||||
$('#label-assigned').empty()
|
||||
.append($this.find('img.avatar-mini').clone(false)).append(' ')
|
||||
.append($('<a class="username strong small">').attr('href', '@context.path/' + userName).text(userName));
|
||||
$('a.assign[data-name=' + jqSelectorEscape(userName) + '] i').attr('class', 'icon-ok');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
}
|
||||
}
|
||||
@helper.html.dropdown("Assignee", flat = true) {
|
||||
<li><a href="javascript:void(0);" class="toggle-assign" data-name=""><i class="icon-remove-circle"></i> Clear assignee</a></li>
|
||||
<li><a href="javascript:void(0);" class="toggle-assign" data-name=""><i class="octicon octicon-x"></i> Clear assignee</a></li>
|
||||
@collaborators.map { collaborator =>
|
||||
<li><a href="javascript:void(0);" class="toggle-assign" data-name="@collaborator"><i class="icon-white"></i>@avatar(collaborator, 20) @collaborator</a></li>
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<form id="search" action="@path/search" method="POST">
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<div class="container" style="width: 920px;">
|
||||
<div class="container" style="width: 980px;">
|
||||
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
@@ -66,15 +66,16 @@
|
||||
<div class="nav-collapse collapse pull-right header-menu">
|
||||
@if(loginAccount.isDefined){
|
||||
<div class="btn-group" style="margin-top: 0px;">
|
||||
<a class="dropdown-toggle menu" data-toggle="dropdown" href="#"><i class="octicon octicon-plus" style="font-size: 20px; vertical-align: top; margin-top: 10px;"></i><span class="caret" style="vertical-align: middle;"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<a class="dropdown-toggle menu" data-toggle="dropdown" href="#"><i class="octicon octicon-plus" style="font-size: 20px; vertical-align: middle;height:20px !important;"></i><span class="caret" style="vertical-align: middle;"></span></a>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
<li><a href="@path/new">New repository</a></li>
|
||||
<li><a href="@path/groups/new">New group</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="btn-group" style="margin-top: 0px;">
|
||||
<a class="dropdown-toggle menu" data-toggle="dropdown" href="#" data-toggle="tooltip" data-placement="bottom" title="Signed is as @loginAccount.get.userName">@avatar(loginAccount.get.userName, 16)<span class="caret" style="vertical-align: middle;"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<ul class="dropdown-menu pull-right">
|
||||
<li><a href="@url(loginAccount.get.userName)">Your profile</a></li>
|
||||
<li><a href="@url(loginAccount.get.userName)/_edit">Account settings</a></li>
|
||||
@if(loginAccount.get.isAdmin){
|
||||
<li><a href="@path/admin/users">System administration</a></li>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
@sidemenu(path: String, name: String, icon: String, label: String, count: Int = 0) = {
|
||||
<li @if(active == name){class="active"} @if(!expand){data-toggle="tooltip" data-placement="left" data-original-title="@label"}>
|
||||
<div class="@if(active == name){margin} else {gradient} pull-left"></div>
|
||||
<a href="@url(repository)@path">
|
||||
<i class="menu-icon @if(active == name){menu-icon-active} octicon octicon-@{icon} "></i>
|
||||
@if(expand){ @label}
|
||||
@@ -40,7 +39,7 @@
|
||||
<span class="add-on count"><a href="@url(repository)/network/members">@repository.forkedCount</a></span>
|
||||
</div>
|
||||
@if(loginAccount.isDefined && isNoGroup){
|
||||
<form id="fork-form" method="post" action="@path/@repository.owner/@repository.name/fork">
|
||||
<form id="fork-form" method="post" action="@path/@repository.owner/@repository.name/fork" style="display: none;">
|
||||
<input type="hidden" name="account" value="@loginAccount.get.userName"/>
|
||||
</form>
|
||||
}
|
||||
@@ -100,7 +99,7 @@
|
||||
@repository.repository.description.map { description =>
|
||||
<p class="description">@description</p>
|
||||
}
|
||||
<div style="border: 1px solid #eee; padding: 4px; margin-bottom: 10px;">
|
||||
<div style="margin-bottom: 10px;" class="box-content">
|
||||
<table class="fill-width">
|
||||
<tr>
|
||||
<td style="width: 33%; text-align: center;">
|
||||
|
||||
@@ -4,32 +4,42 @@
|
||||
@import context._
|
||||
@import gitbucket.core.view.helpers._
|
||||
@import gitbucket.core.model._
|
||||
<div class="box">
|
||||
<table class="table table-file-list" style="border: 1px solid silver;">
|
||||
@commits.map { day =>
|
||||
<tr>
|
||||
<th colspan="4" class="box-header" style="font-weight: normal;">@date(day.head.commitTime)</th>
|
||||
</tr>
|
||||
@day.map { commit =>
|
||||
<tr>
|
||||
<td style="width: 20%;">
|
||||
@avatar(commit, 20)
|
||||
@user(commit.authorName, commit.authorEmailAddress, "username")
|
||||
</td>
|
||||
<td>@commit.shortMessage</td>
|
||||
<td style="width: 10%; text-align: right">
|
||||
<span class="badge" style="display: inline">@if(comments.isDefined){
|
||||
@comments.get.flatMap @{
|
||||
case comment: CommitComment => Some(comment)
|
||||
case other => None
|
||||
}.count(t => t.commitId == commit.id && !t.pullRequest)
|
||||
}</span>
|
||||
</td>
|
||||
<td style="width: 10%; text-align: right;">
|
||||
<a href="@url(repository)/commit/@commit.id" class="monospace">@commit.id.substring(0, 7)</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<div class="commit-list">
|
||||
@commits.map { day =>
|
||||
<div class="muted" style="background-color: white;">
|
||||
<i class="octicon octicon-git-commit"></i> Commits on @date(day.head.commitTime)
|
||||
</div>
|
||||
<div class="box-commits">
|
||||
@day.map { commit =>
|
||||
<div class="box-content-row" style="padding: 8px;">
|
||||
<ul class="nav nav-pills-group pull-right" style="margin-top: 2px; margin-bottom: 0px; margin-right: 4px;">
|
||||
<li class="first"><a href="@url(repository)/commit/@commit.id" class="link monospace">@commit.id.substring(0, 7)</a></li>
|
||||
<li class="last"><a href="@url(repository)/tree/@commit.id" style="padding-top: 9px; padding-bottom: 10px;"><i class="octicon octicon-code link"></i></a></li>
|
||||
</ul>
|
||||
<div>
|
||||
<div class="commit-avatar-image">@avatar(commit, 40)</div>
|
||||
<div class="commit-message-box">
|
||||
<a href="@url(repository)/commit/@commit.id" class="commit-message" style="font-weight: bold;">@link(commit.summary, repository)</a>
|
||||
@if(commit.description.isDefined){
|
||||
<a href="javascript:void(0)" onclick="$('#description-@commit.id').toggle();" class="omit">...</a>
|
||||
}
|
||||
<br>
|
||||
@if(commit.description.isDefined){
|
||||
<pre id="description-@commit.id" style="display: none;" class="commit-description">@link(commit.description.get, repository)</pre>
|
||||
}
|
||||
<div class="small">
|
||||
@user(commit.authorName, commit.authorEmailAddress, "username")
|
||||
<span class="muted">authored @helper.html.datetimeago(commit.authorTime)</span>
|
||||
@if(commit.isDifferentFromAuthor) {
|
||||
<span class="octicon octicon-arrow-right" style="margin-top : -2px;"></span>
|
||||
@user(commit.committerName, commit.committerEmailAddress, "username")
|
||||
<span class="muted">committed @helper.html.datetimeago(commit.authorTime)</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -9,18 +9,16 @@
|
||||
repository: gitbucket.core.service.RepositoryService.RepositoryInfo,
|
||||
originRepository: gitbucket.core.service.RepositoryService.RepositoryInfo,
|
||||
forkedRepository: gitbucket.core.service.RepositoryService.RepositoryInfo,
|
||||
hasWritePermission: Boolean)(implicit context: gitbucket.core.controller.Context)
|
||||
hasOriginWritePermission: Boolean,
|
||||
collaborators: List[String],
|
||||
milestones: List[gitbucket.core.model.Milestone],
|
||||
labels: List[gitbucket.core.model.Label])(implicit context: gitbucket.core.controller.Context)
|
||||
@import context._
|
||||
@import gitbucket.core.view.helpers._
|
||||
@html.main(s"Pull Requests - ${repository.owner}/${repository.name}", Some(repository)){
|
||||
@html.menu("pulls", repository){
|
||||
<div class="pullreq-info">
|
||||
<div id="compare-info">
|
||||
<a href="#" id="edit-compare-condition" class="btn btn-mini pull-right">Edit</a>
|
||||
<span class="label label-info monospace">@originRepository.owner:@originId</span> ... <span class="label label-info monospace">@forkedRepository.owner:@forkedId</span>
|
||||
</div>
|
||||
<div id="compare-edit" style="display: none;">
|
||||
<a href="#" id="cancel-condition-editing" class="pull-right"><i class="icon-remove-circle"></i></a>
|
||||
<div id="compare-edit">
|
||||
@helper.html.dropdown(originRepository.owner + "/" + originRepository.name, "base fork") {
|
||||
@members.map { case (owner, name) =>
|
||||
<li><a href="#" class="origin-owner" data-owner="@owner" data-name="@name">@helper.html.checkicon(owner == originRepository.owner) @owner/@name</a></li>
|
||||
@@ -43,41 +41,52 @@
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@if(commits.nonEmpty && hasWritePermission){
|
||||
<div style="margin-bottom: 10px;" id="create-pull-request">
|
||||
<a href="#" class="btn btn-success" id="show-form">Create pull request</a>
|
||||
<div class="check-conflict" style="display: none;">
|
||||
<img src="@assets/common/images/indicator.gif"/> Checking...
|
||||
</div>
|
||||
<div id="pull-request-form" class="box" style="display: none;">
|
||||
<div class="box-content">
|
||||
<form method="POST" action="@path/@originRepository.owner/@originRepository.name/pulls/new" validate="true">
|
||||
<div style="width: 240px; position: absolute; margin-left: 610px;">
|
||||
<div class="check-conflict" style="display: none;">
|
||||
<img src="@assets/common/images/indicator.gif"/> Checking...
|
||||
</div>
|
||||
@if(commits.nonEmpty && loginAccount.isDefined){
|
||||
<div style="margin-bottom: 10px; padding: 8px; background-color: #fff9ea" id="create-pull-request" class="box-content">
|
||||
<a href="#" class="btn btn-success" id="show-form">Create pull request</a>
|
||||
|
||||
<span class="muted">Discuss and review the changes in this comparison with others.</span>
|
||||
</div>
|
||||
<div id="pull-request-form" @*class="box"*@ style="display: none; margin-bottom: 20px;">
|
||||
<form method="POST" action="@path/@originRepository.owner/@originRepository.name/pulls/new" validate="true">
|
||||
<div class="row-fluid">
|
||||
<div class="span10">
|
||||
<div class="issue-avatar-image">@avatar(loginAccount.get.userName, 48)</div>
|
||||
<div class="box issue-box">
|
||||
<div class="box-content">
|
||||
<span class="error" id="error-title"></span>
|
||||
<input type="text" name="title" style="width: 690px" placeholder="Title"/>
|
||||
@helper.html.preview(
|
||||
repository = repository,
|
||||
content = "",
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableTaskList = true,
|
||||
hasWritePermission = true,
|
||||
style = "width: 690px; height: 200px;"
|
||||
)
|
||||
<input type="hidden" name="targetUserName" value="@originRepository.owner"/>
|
||||
<input type="hidden" name="targetBranch" value="@originId"/>
|
||||
<input type="hidden" name="requestUserName" value="@forkedRepository.owner"/>
|
||||
<input type="hidden" name="requestRepositoryName" value="@forkedRepository.name"/>
|
||||
<input type="hidden" name="requestBranch" value="@forkedId"/>
|
||||
<input type="hidden" name="commitIdFrom" value="@sourceId"/>
|
||||
<input type="hidden" name="commitIdTo" value="@commitId"/>
|
||||
<div class="align-right">
|
||||
<input type="submit" class="btn btn-success" value="Create pull request"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 600px; border-right: 1px solid #d4d4d4;">
|
||||
<span class="error" id="error-title"></span>
|
||||
<input type="text" name="title" style="width: 580px" placeholder="Title"/>
|
||||
@helper.html.preview(
|
||||
repository = repository,
|
||||
content = "",
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableTaskList = true,
|
||||
hasWritePermission = hasWritePermission,
|
||||
style = "width: 580px; height: 200px;"
|
||||
)
|
||||
<input type="hidden" name="targetUserName" value="@originRepository.owner"/>
|
||||
<input type="hidden" name="targetBranch" value="@originId"/>
|
||||
<input type="hidden" name="requestUserName" value="@forkedRepository.owner"/>
|
||||
<input type="hidden" name="requestRepositoryName" value="@forkedRepository.name"/>
|
||||
<input type="hidden" name="requestBranch" value="@forkedId"/>
|
||||
<input type="hidden" name="commitIdFrom" value="@sourceId"/>
|
||||
<input type="hidden" name="commitIdTo" value="@commitId"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="span2">
|
||||
@issues.html.issueinfo(None, Nil, Nil, collaborators, milestones.map((_, 0, 0)), labels, hasOriginWritePermission, repository)
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
@if(commits.isEmpty){
|
||||
@@ -90,72 +99,119 @@
|
||||
</tr>
|
||||
</table>
|
||||
} else {
|
||||
@pulls.html.commits(commits, Some(comments), repository)
|
||||
@helper.html.diff(diffs, repository, Some(commitId), Some(sourceId), true, None, hasWritePermission, false)
|
||||
<div style="margin-bottom: 10px;" class="box-content">
|
||||
<table class="fill-width">
|
||||
<tr>
|
||||
<td style="width: 25%; text-align: center;">
|
||||
<i class="octicon octicon-commit"></i>
|
||||
@defining(commits.flatten){ commits =>
|
||||
<strong>@commits.size</strong> @plural(commits.size, "commit")
|
||||
}
|
||||
</td>
|
||||
<td style="width: 25%; text-align: center;">
|
||||
<i class="octicon octicon-diff"></i>
|
||||
<strong>@diffs.size</strong> @plural(diffs.size, "file") changed
|
||||
</td>
|
||||
<td style="width: 25%; text-align: center;">
|
||||
<i class="octicon octicon-comment"></i>
|
||||
@defining(comments.collect { case c: gitbucket.core.model.CommitComment => c }){ comments =>
|
||||
<strong>@comments.size</strong> commit @plural(comments.size, "comment")
|
||||
}
|
||||
</td>
|
||||
<td style="width: 25%; text-align: center;">
|
||||
<i class="octicon octicon-organization"></i>
|
||||
@defining(commits.flatMap(_.map(_.authorEmailAddress)).distinct){ contributors =>
|
||||
<strong>@contributors.size</strong> @plural(contributors.size, "contributor")
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="box" style="margin-bottom: 20px;">
|
||||
@commits.map { day =>
|
||||
<div style="margin-top: 8px; margin-bottom: 8px;" class="muted">
|
||||
Commits on @date(day.head.commitTime)
|
||||
</div>
|
||||
<table style="width: 100%;">
|
||||
@day.map { commit =>
|
||||
<tr>
|
||||
<td style="width: 20%;">
|
||||
<i class="octicon octicon-git-commit"></i>
|
||||
@avatar(commit, 20)
|
||||
@user(commit.authorName, commit.authorEmailAddress, "username strong")
|
||||
</td>
|
||||
<td><span class="monospace">@commit.shortMessage</span></td>
|
||||
@*
|
||||
<span class="badge" style="display: inline">@if(comments.isDefined){
|
||||
@comments.get.flatMap @{
|
||||
case comment: CommitComment => Some(comment)
|
||||
case other => None
|
||||
}.count(t => t.commitId == commit.id && !t.pullRequest)
|
||||
}</span>
|
||||
*@
|
||||
<td style="width: 10%; text-align: right;">
|
||||
<a href="@url(repository)/commit/@commit.id" class="monospace">@commit.id.substring(0, 7)</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
@helper.html.diff(diffs, repository, Some(commitId), Some(sourceId), true, None, false, false)
|
||||
<p>Showing you all comments on commits in this comparison.</p>
|
||||
@issues.html.commentlist(None, comments, hasWritePermission, repository, None)
|
||||
@issues.html.commentlist(None, comments, false, repository, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
<script>
|
||||
$(function(){
|
||||
$('#edit-compare-condition').click(function(){
|
||||
$('#compare-info').hide();
|
||||
$('#compare-edit').show();
|
||||
});
|
||||
|
||||
$('#cancel-condition-editing').click(function(){
|
||||
$('#compare-info').show();
|
||||
$('#compare-edit').hide();
|
||||
});
|
||||
|
||||
$('a.origin-owner, a.forked-owner, a.origin-branch, a.forked-branch').click(function(){
|
||||
var e = $(this);
|
||||
e.parents('ul').find('i').attr('class', 'icon-white');
|
||||
e.find('i').attr('class', 'icon-ok');
|
||||
e.find('i').attr('class', 'octicon-check');
|
||||
e.parents('div.btn-group').find('button span.strong').text(e.text());
|
||||
|
||||
@if(members.isEmpty){
|
||||
location.href = '@url(repository)/compare/' +
|
||||
$.trim($('i.icon-ok').parents('a.origin-branch').data('branch')) + '...' +
|
||||
$.trim($('i.icon-ok').parents('a.forked-branch').data('branch'));
|
||||
$.trim($('i.octicon-check').parents('a.origin-branch').data('branch')) + '...' +
|
||||
$.trim($('i.octicon-check').parents('a.forked-branch').data('branch'));
|
||||
} else {
|
||||
location.href = '@path/' +
|
||||
$.trim($('i.icon-ok').parents('a.forked-owner' ).data('owner')) + '/' +
|
||||
$.trim($('i.icon-ok').parents('a.forked-owner' ).data('name')) +'/compare/' +
|
||||
$.trim($('i.icon-ok').parents('a.origin-owner' ).data('owner')) + ':' +
|
||||
$.trim($('i.icon-ok').parents('a.origin-branch').data('branch')) + '...' +
|
||||
$.trim($('i.icon-ok').parents('a.forked-owner' ).data('owner')) + ':' +
|
||||
$.trim($('i.icon-ok').parents('a.forked-branch').data('branch'));
|
||||
$.trim($('i.octicon-check').parents('a.forked-owner' ).data('owner')) + '/' +
|
||||
$.trim($('i.octicon-check').parents('a.forked-owner' ).data('name')) +'/compare/' +
|
||||
$.trim($('i.octicon-check').parents('a.origin-owner' ).data('owner')) + ':' +
|
||||
$.trim($('i.octicon-check').parents('a.origin-branch').data('branch')) + '...' +
|
||||
$.trim($('i.octicon-check').parents('a.forked-owner' ).data('owner')) + ':' +
|
||||
$.trim($('i.octicon-check').parents('a.forked-branch').data('branch'));
|
||||
}
|
||||
});
|
||||
|
||||
$('#show-form').click(function(){
|
||||
$(this).hide();
|
||||
$('#create-pull-request').hide();
|
||||
$('#pull-request-form').show();
|
||||
});
|
||||
if(location.search.substr(1).split("&").indexOf("expand=1")!=-1){
|
||||
$('#show-form').click();
|
||||
}
|
||||
|
||||
@if(hasWritePermission){
|
||||
@if(loginAccount.isDefined){
|
||||
function checkConflict(from, to){
|
||||
$('.check-conflict').show();
|
||||
$.get('@url(repository)/compare/' + from + '...' + to + '/mergecheck',
|
||||
$.get('@url(forkedRepository)/compare/' + from + '...' + to + '/mergecheck',
|
||||
function(data){ $('.check-conflict').html(data); });
|
||||
}
|
||||
|
||||
@if(members.isEmpty){
|
||||
checkConflict(
|
||||
$.trim($('i.icon-ok').parents('a.origin-branch').data('branch')),
|
||||
$.trim($('i.icon-ok').parents('a.forked-branch').data('branch'))
|
||||
$.trim($('i.octicon-check').parents('a.origin-branch').data('branch')),
|
||||
$.trim($('i.octicon-check').parents('a.forked-branch').data('branch'))
|
||||
);
|
||||
} else {
|
||||
checkConflict(
|
||||
$.trim($('i.icon-ok').parents('a.origin-owner' ).data('owner')) + ":" +
|
||||
$.trim($('i.icon-ok').parents('a.origin-branch').data('branch')),
|
||||
$.trim($('i.icon-ok').parents('a.forked-owner' ).data('owner')) + ":" +
|
||||
$.trim($('i.icon-ok').parents('a.forked-branch').data('branch'))
|
||||
$.trim($('i.octicon-check').parents('a.origin-owner' ).data('owner')) + ":" +
|
||||
$.trim($('i.octicon-check').parents('a.origin-branch').data('branch')),
|
||||
$.trim($('i.octicon-check').parents('a.forked-owner' ).data('owner')) + ":" +
|
||||
$.trim($('i.octicon-check').parents('a.forked-branch').data('branch'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
}
|
||||
</div>
|
||||
<div class="span2">
|
||||
@issues.html.issueinfo(issue, comments, issueLabels, collaborators, milestones, labels, hasWritePermission, repository)
|
||||
@issues.html.issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, labels, hasWritePermission, repository)
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
@(hasConflict: Boolean)
|
||||
@if(hasConflict){
|
||||
<h4>We can’t automatically merge these branches</h4>
|
||||
<p>Don't worry, you can still submit the pull request.</p>
|
||||
} else {
|
||||
<h4 style="color: #468847;">Able to merge</h4>
|
||||
<p>These branches can be automatically merged.</p>
|
||||
}
|
||||
<input type="submit" class="btn btn-success btn-block" value="Create pull request"/>
|
||||
<div style="margin-top: 8px;">
|
||||
@if(hasConflict){
|
||||
<i class="octicon octicon-x" style="color: #bd2c00"></i>
|
||||
<span class="strong" style="color: #bd2c00;">Can’t automatically merge.</span>
|
||||
<span class="muted">Don’t worry, you can still create the pull request.</span>
|
||||
} else {
|
||||
<i class="octicon octicon-check" style="color: #6cc644"></i>
|
||||
<span class="strong" style="color: #6cc644">Able to merge.</span>
|
||||
<span class="muted">These branches can be automatically merged.</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
issue: gitbucket.core.model.Issue,
|
||||
pullreq: gitbucket.core.model.PullRequest,
|
||||
statuses: List[model.CommitStatus],
|
||||
repository: gitbucket.core.service.RepositoryService.RepositoryInfo,
|
||||
requestRepositoryUrl: String)(implicit context: gitbucket.core.controller.Context)
|
||||
originRepository: gitbucket.core.service.RepositoryService.RepositoryInfo,
|
||||
forkedRepository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
|
||||
@import gitbucket.core.service.SystemSettingsService
|
||||
@import context._
|
||||
@import gitbucket.core.view.helpers._
|
||||
@import model.CommitState
|
||||
@@ -22,100 +23,101 @@
|
||||
@status.description.map{ desc => <span class="muted">— @desc</span> }
|
||||
</div>
|
||||
}
|
||||
}else{
|
||||
@defining(statuses.groupBy(_.state)){ stateMap => @defining(CommitState.combine(stateMap.keySet)){ state =>
|
||||
<div class="build-status-item">
|
||||
<a class="pull-right" id="toggle-all-checks"></a>
|
||||
<span class="build-status-icon text-@{state.name}">@commitStateIcon(state)</span>
|
||||
<strong class="text-@{state.name}">@commitStateText(state, pullreq.commitIdTo)</strong>
|
||||
<span class="text-@{state.name}">— @{stateMap.map{ case (keyState, states) => states.size+" "+keyState.name }.mkString(", ")} checks</span>
|
||||
</div>
|
||||
<div class="build-statuses-list" style="@if(state==CommitState.SUCCESS){ display:none; }else{ }">
|
||||
@statuses.map{ status =>
|
||||
} else {
|
||||
@defining(statuses.groupBy(_.state)){ stateMap =>
|
||||
@defining(CommitState.combine(stateMap.keySet)){ state =>
|
||||
<div class="build-status-item">
|
||||
@status.targetUrl.map{ url => <a class="pull-right" href="@url">Details</a> }
|
||||
<span class="build-status-icon text-@{status.state.name}">@commitStateIcon(status.state)</span>
|
||||
<span class="text-@{status.state.name}">@status.context</span>
|
||||
@status.description.map{ desc => <span class="muted">— @desc</span> }
|
||||
<a class="pull-right" id="toggle-all-checks"></a>
|
||||
<span class="build-status-icon text-@{state.name}">@commitStateIcon(state)</span>
|
||||
<strong class="text-@{state.name}">@commitStateText(state, pullreq.commitIdTo)</strong>
|
||||
<span class="text-@{state.name}">— @{stateMap.map{ case (keyState, states) => states.size+" "+keyState.name }.mkString(", ")} checks</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
} }
|
||||
<div class="build-statuses-list" style="@if(state==CommitState.SUCCESS){ display:none; }else{ }">
|
||||
@statuses.map{ status =>
|
||||
<div class="build-status-item">
|
||||
@status.targetUrl.map{ url => <a class="pull-right" href="@url">Details</a> }
|
||||
<span class="build-status-icon text-@{status.state.name}">@commitStateIcon(status.state)</span>
|
||||
<span class="text-@{status.state.name}">@status.context</span>
|
||||
@status.description.map{ desc => <span class="muted">— @desc</span> }
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="pull-right">
|
||||
<input type="button" class="btn @if(!hasProblem){ btn-success }" id="merge-pull-request-button" value="Merge pull request"@if(hasConflict){ disabled="true"}/>
|
||||
</div>
|
||||
<div>
|
||||
@if(hasConflict){
|
||||
<span class="strong">We can’t automatically merge this pull request.</span>
|
||||
} else{ @if(hasProblem){
|
||||
<span class="strong">Merge with caution!</span>
|
||||
} else {
|
||||
<span class="strong">This pull request can be automatically merged.</span>
|
||||
} }
|
||||
</div>
|
||||
<div class="small">
|
||||
@if(hasConflict){
|
||||
<a href="#" id="show-command-line">Use the command line</a> to resolve conflicts before continuing.
|
||||
} else {
|
||||
You can also merge branches on the <a href="#" id="show-command-line">command line</a>.
|
||||
}
|
||||
</div>
|
||||
<div id="command-line" style="display: none;">
|
||||
<hr>
|
||||
@if(hasConflict){
|
||||
<span class="strong">Checkout via command line</span>
|
||||
<p>
|
||||
If you cannot merge a pull request automatically here, you have the option of checking
|
||||
it out via command line to resolve conflicts and perform a manual merge.
|
||||
</p>
|
||||
} else {
|
||||
<span class="strong">Merging via command line</span>
|
||||
<p>
|
||||
If you do not want to use the merge button or an automatic merge cannot be performed,
|
||||
you can perform a manual merge on the command line.
|
||||
</p>
|
||||
}
|
||||
@helper.html.copy("repository-url-copy", requestRepositoryUrl){
|
||||
<input type="text" style="width: 500px;" value="@requestRepositoryUrl" id="repository-url" readonly>
|
||||
}
|
||||
<div>
|
||||
<p>
|
||||
<span class="strong">Step 1:</span> Check out a new branch to test the changes — run this from your project directory
|
||||
</p>
|
||||
@defining(s"git checkout -b ${pullreq.requestUserName}-${pullreq.requestBranch} ${pullreq.branch}"){ command =>
|
||||
@helper.html.copy("merge-command-copy-1", command){
|
||||
<pre style="width: 500px; float: left;">@command</pre>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<span class="strong">Step 2:</span> Bring in @{pullreq.requestUserName}'s changes and test
|
||||
</p>
|
||||
@defining(s"git pull ${requestRepositoryUrl} ${pullreq.requestBranch}"){ command =>
|
||||
@helper.html.copy("merge-command-copy-2", command){
|
||||
<pre style="width: 500px; float: left;">@command</pre>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<span class="strong">Step 3:</span> Merge the changes and update the server
|
||||
</p>
|
||||
@defining(s"git checkout ${pullreq.branch}\ngit merge ${pullreq.requestUserName}-${pullreq.requestBranch}\ngit push origin ${pullreq.branch}"){ command =>
|
||||
@helper.html.copy("merge-command-copy-3", command){
|
||||
<pre style="width: 500px; float: left;">@command</pre>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pull-right">
|
||||
<input type="button" class="btn @if(!hasProblem){ btn-success }" id="merge-pull-request-button" value="Merge pull request"@if(hasConflict){ disabled="true"}/>
|
||||
</div>
|
||||
<div>
|
||||
@if(hasConflict){
|
||||
<span class="strong">We can’t automatically merge this pull request.</span>
|
||||
} else {
|
||||
@if(hasProblem){
|
||||
<span class="strong">Merge with caution!</span>
|
||||
} else {
|
||||
<span class="strong">This pull request can be automatically merged.</span>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div class="small">
|
||||
@if(hasConflict){
|
||||
<a href="#" id="show-command-line">Use the command line</a> to resolve conflicts before continuing.
|
||||
} else {
|
||||
You can also merge branches on the <a href="#" id="show-command-line">command line</a>.
|
||||
}
|
||||
</div>
|
||||
<div id="command-line" style="display: none;">
|
||||
<hr>
|
||||
@if(hasConflict){
|
||||
<span class="strong">Checkout via command line</span>
|
||||
<p>
|
||||
If you cannot merge a pull request automatically here, you have the option of checking
|
||||
it out via command line to resolve conflicts and perform a manual merge.
|
||||
</p>
|
||||
} else {
|
||||
<span class="strong">Merging via command line</span>
|
||||
<p>
|
||||
If you do not want to use the merge button or an automatic merge cannot be performed,
|
||||
you can perform a manual merge on the command line.
|
||||
</p>
|
||||
}
|
||||
@helper.html.copy("repository-url-copy", forkedRepository.httpUrl, true){
|
||||
<div class="btn-group" data-toggle="buttons-radio">
|
||||
<button class="btn btn-small active" type="button" id="repository-url-http">HTTP</button>
|
||||
@if(settings.ssh && loginAccount.isDefined){
|
||||
<button class="btn btn-small" type="button" id="repository-url-ssh" style="border-radius: 0px;">SSH</button>
|
||||
}
|
||||
</div>
|
||||
<input type="text" style="width: 500px;" value="@forkedRepository.httpUrl" id="repository-url" readonly>
|
||||
}
|
||||
<div>
|
||||
<p>
|
||||
<span class="strong">Step 1:</span> From your project repository, check out a new branch and test the changes.
|
||||
</p>
|
||||
@defining(s"git checkout -b ${pullreq.requestUserName}-${pullreq.requestBranch} ${pullreq.branch}\n" +
|
||||
s"git pull ${forkedRepository.httpUrl} ${pullreq.requestBranch}"){ command =>
|
||||
@helper.html.copy("merge-command-copy-1", command){
|
||||
<pre style="width: 600px; float: left; font-size: 12px; border-radius: 3px 0px 3px 3px;" id="merge-command">@Html(command)</pre>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<span class="strong">Step 2:</span> Merge the changes and update on the server.
|
||||
</p>
|
||||
@defining(s"git checkout ${pullreq.branch}\ngit merge --no-ff ${pullreq.requestUserName}-${pullreq.requestBranch}\n" +
|
||||
s"git push origin ${pullreq.branch}"){ command =>
|
||||
@helper.html.copy("merge-command-copy-2", command){
|
||||
<pre style="width: 600px; float: left; font-size: 12px; border-radius: 3px 0px 3px 3px;">@command</pre>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="confirm-merge-form" style="display: none;">
|
||||
<form method="POST" action="@url(repository)/pull/@pullreq.issueId/merge">
|
||||
<form method="POST" action="@url(originRepository)/pull/@pullreq.issueId/merge">
|
||||
<div class="strong">
|
||||
Merge pull request #@issue.issueId from @{pullreq.requestUserName}/@{pullreq.requestBranch}
|
||||
</div>
|
||||
@@ -149,5 +151,31 @@ $(function(){
|
||||
$('#merge-pull-request').hide();
|
||||
$('#confirm-merge-form').show();
|
||||
});
|
||||
|
||||
@if(settings.ssh && loginAccount.isDefined){
|
||||
$('#repository-url-http').click(function(){
|
||||
// Update URL box
|
||||
$('#repository-url').val('@forkedRepository.httpUrl');
|
||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||
// Update command guidance
|
||||
$('#merge-command').text($('#merge-command').text().replace(
|
||||
'@forkedRepository.sshUrl(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), loginAccount.get.userName)',
|
||||
'@forkedRepository.httpUrl'
|
||||
));
|
||||
$('#merge-command-copy-1').attr('data-clipboard-text', $('#merge-command').text());
|
||||
});
|
||||
|
||||
$('#repository-url-ssh').click(function(){
|
||||
// Update URL box
|
||||
$('#repository-url').val('@forkedRepository.sshUrl(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), loginAccount.get.userName)');
|
||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||
// Update command guidance
|
||||
$('#merge-command').text($('#merge-command').text().replace(
|
||||
'@forkedRepository.httpUrl',
|
||||
'@forkedRepository.sshUrl(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), loginAccount.get.userName)'
|
||||
));
|
||||
$('#merge-command-copy-1').attr('data-clipboard-text', $('#merge-command').text());
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -18,9 +18,9 @@
|
||||
<div>
|
||||
<div class="show-title pull-right">
|
||||
@if(hasWritePermission || loginAccount.map(_.userName == issue.openedUserName).getOrElse(false)){
|
||||
<a class="btn btn-small" href="#" id="edit">Edit</a>
|
||||
<a class="btn" href="#" id="edit">Edit</a>
|
||||
}
|
||||
<a class="btn btn-small btn-success" href="@url(repository)/issues/new">New issue</a>
|
||||
<a class="btn btn-success" href="@url(repository)/issues/new">New issue</a>
|
||||
</div>
|
||||
<div class="edit-title pull-right" style="display: none;">
|
||||
<a class="btn" href="#" id="update">Save</a> <a href="#" id="cancel">Cancel</a>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
@html.menu("code", repository){
|
||||
<div class="head">
|
||||
<div class="pull-right hide-if-blame"><div class="btn-group">
|
||||
<a href="@url(repository)/find/@encodeRefName(branch)" class="btn btn-mini" data-toggle="tooltip" data-placement="bottom" data-hotkey="t" title="Quickly jump between files"><i class="icon icon-th-list"></i></a>
|
||||
<a href="@url(repository)/find/@encodeRefName(branch)" class="btn btn-mini" data-toggle="tooltip" data-placement="bottom" data-hotkey="t" title="Quickly jump between files"><i class="octicon octicon-list-unordered"></i></a>
|
||||
</div></div>
|
||||
<div class="line-age-legend">
|
||||
<span>Newer</span>
|
||||
@@ -47,57 +47,50 @@
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered blobview">
|
||||
<tr>
|
||||
<th style="font-weight: normal;">
|
||||
<div class="pull-left">
|
||||
@avatar(latestCommit, 20)
|
||||
@user(latestCommit.authorName, latestCommit.authorEmailAddress, "username strong")
|
||||
<span class="muted">@helper.html.datetimeago(latestCommit.commitTime)</span>
|
||||
<a href="@url(repository)/commit/@latestCommit.id" class="commit-message">@link(latestCommit.summary, repository)</a>
|
||||
</div>
|
||||
<div class="btn-group pull-right">
|
||||
@if(hasWritePermission && content.viewType == "text" && repository.branchList.contains(branch)){
|
||||
<a class="btn btn-mini" href="@url(repository)/edit/@encodeRefName(branch)/@pathList.mkString("/")">Edit</a>
|
||||
}
|
||||
<a class="btn btn-mini" href="?raw=true">Raw</a>
|
||||
@if(content.viewType == "text"){
|
||||
<a class="btn btn-mini blame-action" href="@url(repository)/blame/@latestCommit.id/@pathList.mkString("/")" data-url="@url(repository)/get-blame/@latestCommit.id/@pathList.mkString("/")" data-repository="@url(repository)">Blame</a>
|
||||
}
|
||||
<a class="btn btn-mini" href="@url(repository)/commits/@encodeRefName(branch)/@pathList.mkString("/")">History</a>
|
||||
@if(hasWritePermission){
|
||||
<a class="btn btn-mini btn-danger" href="@url(repository)/remove/@encodeRefName(branch)/@pathList.mkString("/")">Delete</a>
|
||||
}
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
@if(content.viewType == "text"){
|
||||
@defining(isRenderable(pathList.reverse.head)){ isRrenderable =>
|
||||
@if(!isBlame && isRrenderable) {
|
||||
<div class="box-content markdown-body" style="border: none; padding-left: 16px; padding-right: 16px;">
|
||||
@renderMarkup(pathList, content.content.get, branch, repository, false, false, true)
|
||||
</div>
|
||||
} else {
|
||||
<pre class="prettyprint linenums blob @if(!isRrenderable){ no-renderable } ">@content.content.get</pre>
|
||||
}
|
||||
}
|
||||
}
|
||||
@if(content.viewType == "image"){
|
||||
<img src="?raw=true"/>
|
||||
}
|
||||
@if(content.viewType == "large" || content.viewType == "binary"){
|
||||
<div style="text-align: center; padding-top: 20px; padding-bottom: 20px;">
|
||||
<a href="?raw=true">View Raw</a><br>
|
||||
<br>
|
||||
(Sorry about that, but we can't show files that are this big right now)
|
||||
<div class="box-header">
|
||||
@avatar(latestCommit, 20)
|
||||
@user(latestCommit.authorName, latestCommit.authorEmailAddress, "username strong")
|
||||
<span class="muted">@helper.html.datetimeago(latestCommit.commitTime)</span>
|
||||
<a href="@url(repository)/commit/@latestCommit.id" class="commit-message">@link(latestCommit.summary, repository)</a>
|
||||
<div class="btn-group pull-right">
|
||||
@if(hasWritePermission && content.viewType == "text" && repository.branchList.contains(branch)){
|
||||
<a class="btn btn-mini" href="@url(repository)/edit/@encodeRefName(branch)/@pathList.mkString("/")">Edit</a>
|
||||
}
|
||||
<a class="btn btn-mini" href="?raw=true">Raw</a>
|
||||
@if(content.viewType == "text"){
|
||||
<a class="btn btn-mini blame-action" href="@url(repository)/blame/@latestCommit.id/@pathList.mkString("/")" data-url="@url(repository)/get-blame/@latestCommit.id/@pathList.mkString("/")" data-repository="@url(repository)">Blame</a>
|
||||
}
|
||||
<a class="btn btn-mini" href="@url(repository)/commits/@encodeRefName(branch)/@pathList.mkString("/")">History</a>
|
||||
@if(hasWritePermission && repository.branchList.contains(branch)){
|
||||
<a class="btn btn-mini btn-danger" href="@url(repository)/remove/@encodeRefName(branch)/@pathList.mkString("/")">Delete</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@if(content.viewType == "text"){
|
||||
@defining(isRenderable(pathList.reverse.head)){ isRrenderable =>
|
||||
@if(!isBlame && isRrenderable) {
|
||||
<div class="box-content-bottom markdown-body" style="padding-left: 16px; padding-right: 16px;">
|
||||
@renderMarkup(pathList, content.content.get, branch, repository, false, false, true)
|
||||
</div>
|
||||
} else {
|
||||
<div class="box-content-bottom">
|
||||
<pre class="prettyprint linenums blob @if(!isRrenderable){ no-renderable } ">@content.content.get</pre>
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
}
|
||||
}
|
||||
@if(content.viewType == "image"){
|
||||
<div class="box-content-bottom">
|
||||
<img src="?raw=true"/>
|
||||
</div>
|
||||
}
|
||||
@if(content.viewType == "large" || content.viewType == "binary"){
|
||||
<div class="box-content-bottom" style="text-align: center; padding-top: 20px; padding-bottom: 20px;">
|
||||
<a href="?raw=true">View Raw</a><br>
|
||||
<br>
|
||||
(Sorry about that, but we can't show files that are this big right now)
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
<script src="@assets/vendors/jquery/jquery.ba-hashchange.js"></script>
|
||||
@@ -111,36 +104,38 @@ $(window).load(function(){
|
||||
function updateSourceLineNum(){
|
||||
$('.source-line-num').remove();
|
||||
var pos = pre.find('ol.linenums').position();
|
||||
$('<div class="source-line-num">').css({
|
||||
height:pre.height(),
|
||||
width:'48px',
|
||||
cursor:'pointer',
|
||||
position: 'absolute',
|
||||
top : pos.top + 'px',
|
||||
left : pos.left + 'px'
|
||||
}).click(function(e){
|
||||
$(window).hashchange(function(){})
|
||||
var pos = $(this).data("pos");
|
||||
if(!pos){
|
||||
pos = $('ol.linenums li').map(function(){ return {id:$(this).attr("id"),top:$(this).position().top} }).toArray();
|
||||
$(this).data("pos",pos);
|
||||
}
|
||||
for(var i=0;i<pos.length-1;i++){
|
||||
if(pos[i+1].top>e.pageY){
|
||||
break;
|
||||
if(pos){
|
||||
$('<div class="source-line-num">').css({
|
||||
height : pre.height(),
|
||||
width : '48px',
|
||||
cursor : 'pointer',
|
||||
position: 'absolute',
|
||||
top : pos.top + 'px',
|
||||
left : pos.left + 'px'
|
||||
}).click(function(e){
|
||||
$(window).hashchange(function(){})
|
||||
var pos = $(this).data("pos");
|
||||
if(!pos){
|
||||
pos = $('ol.linenums li').map(function(){ return { id: $(this).attr("id"), top: $(this).position().top} }).toArray();
|
||||
$(this).data("pos",pos);
|
||||
}
|
||||
}
|
||||
var line = pos[i].id.replace(/^L/,'');
|
||||
var hash = location.hash;
|
||||
if(e.shiftKey == true && hash.match(/#L\d+(-L\d+)?/)){
|
||||
var lines = hash.split('-');
|
||||
location.hash = lines[0] + '-L' + line;
|
||||
} else {
|
||||
var p = $("#L"+line).attr('id',"");
|
||||
location.hash = '#L' + line;
|
||||
p.attr('id','L'+line);
|
||||
}
|
||||
}).appendTo(pre);
|
||||
for(var i = 0; i < pos.length-1; i++){
|
||||
if(pos[i + 1].top > e.pageY){
|
||||
break;
|
||||
}
|
||||
}
|
||||
var line = pos[i].id.replace(/^L/,'');
|
||||
var hash = location.hash;
|
||||
if(e.shiftKey == true && hash.match(/#L\d+(-L\d+)?/)){
|
||||
var lines = hash.split('-');
|
||||
location.hash = lines[0] + '-L' + line;
|
||||
} else {
|
||||
var p = $("#L"+line).attr('id',"");
|
||||
location.hash = '#L' + line;
|
||||
p.attr('id','L'+line);
|
||||
}
|
||||
}).appendTo(pre);
|
||||
}
|
||||
}
|
||||
var repository = $('.blame-action').data('repository');
|
||||
$('.blame-action').click(function(e){
|
||||
@@ -152,11 +147,11 @@ $(window).load(function(){
|
||||
});
|
||||
|
||||
function updateBlame(){
|
||||
var m = /^\/(blame|blob)(\/.*)$/.exec(location.href.substring(repository.length));
|
||||
var m = /\/(blame|blob)(\/.*)$/.exec(location.href);
|
||||
var mode = m[1];
|
||||
$('.blame-action').toggleClass("active", mode=='blame').attr('href', repository + (m[1]=='blame'?'/blob':'/blame')+m[2]);
|
||||
if(pre.parents("td").find(".blame").length){
|
||||
pre.parents("div.container").toggleClass("blame-container", mode=='blame');
|
||||
$('.blame-action').toggleClass("active", mode=='blame').attr('href', repository + (m[1] == 'blame' ? '/blob' : '/blame') + m[2]);
|
||||
if(pre.parents("div.box-content-bottom").find(".blame").length){
|
||||
pre.parents("div.container").toggleClass("blame-container", mode == 'blame');
|
||||
updateSourceLineNum();
|
||||
return;
|
||||
}
|
||||
@@ -164,47 +159,47 @@ $(window).load(function(){
|
||||
updateSourceLineNum();
|
||||
return;
|
||||
}
|
||||
$(document.body).toggleClass('no-box-shadow',document.body.style.boxShadow===undefined);
|
||||
$(document.body).toggleClass('no-box-shadow', document.body.style.boxShadow===undefined);
|
||||
$('.blame-action').addClass("active");
|
||||
var base = $('<div class="blame">').css({height:pre.height()}).prependTo(pre.parents("td")[0]);
|
||||
var base = $('<div class="blame">').css({height: pre.height()}).prependTo(pre.parents("div.box-content-bottom"));
|
||||
base.parents("div.container").addClass("blame-container");
|
||||
updateSourceLineNum();
|
||||
$.get($('.blame-action').data('url')).done(function(data){
|
||||
var blame = data.blame;
|
||||
var index = [];
|
||||
for(var i=0;i<blame.length;i++){
|
||||
for(var j=0;j<blame[i].lines.length;j++){
|
||||
index[blame[i].lines[j]]=blame[i];
|
||||
for(var i = 0; i < blame.length; i++){
|
||||
for(var j = 0; j < blame[i].lines.length; j++){
|
||||
index[blame[i].lines[j]] = blame[i];
|
||||
}
|
||||
}
|
||||
var blame, lastDiv, now=new Date().getTime();
|
||||
var blame, lastDiv, now = new Date().getTime();
|
||||
|
||||
$('pre.prettyprint ol.linenums li').each(function(i, e){
|
||||
var p=$(e).position();
|
||||
var h=$(e).height();
|
||||
var p = $(e).position();
|
||||
var h = $(e).height();
|
||||
if(blame == index[i]){
|
||||
lastDiv.css("min-height",(p.top+h+1) - lastDiv.position().top);
|
||||
lastDiv.css("min-height",(p.top + h + 1) - lastDiv.position().top);
|
||||
}else{
|
||||
$(e).addClass('blame-sep')
|
||||
blame = index[i];
|
||||
var sha = $('<div class="blame-sha">')
|
||||
.append($('<a>').attr("href",data.root+'/commit/'+blame.id).text(blame.id.substr(0,7)));
|
||||
.append($('<a>').attr("href", data.root + '/commit/' + blame.id).text(blame.id.substr(0,7)));
|
||||
if(blame.prev){
|
||||
sha.append($('<br />'))
|
||||
.append($('<a class="muted-link">').text('prev').attr("href",data.root+'/blame/'+blame.prev+'/'+(blame.prevPath||data.path)));
|
||||
.append($('<a class="muted-link">').text('prev').attr("href", data.root + '/blame/' + blame.prev + '/' + (blame.prevPath || data.path)));
|
||||
}
|
||||
lastDiv = $('<div class="blame-info">')
|
||||
.addClass('heat'+Math.min(10,Math.max(1,Math.ceil((now-blame.commited)/(24*3600*1000*70)))))
|
||||
.toggleClass('blame-last',blame.id==data.last)
|
||||
.addClass('heat' + Math.min(10, Math.max(1, Math.ceil((now - blame.commited) / (24 * 3600 * 1000 * 70)))))
|
||||
.toggleClass('blame-last', blame.id == data.last)
|
||||
.data('line', (i + 1))
|
||||
.css({
|
||||
"top" : p.top + 'px',
|
||||
"min-height" : h+'px'
|
||||
"top" : p.top + 'px',
|
||||
"min-height" : h + 'px'
|
||||
})
|
||||
.append(sha)
|
||||
.append($(blame.avatar).addClass('avatar').css({"float":"left"}))
|
||||
.append($(blame.avatar).addClass('avatar').css({"float": "left"}))
|
||||
.append($('<div class="blame-commit-title">').text(blame.message))
|
||||
.append($('<div class="muted">').html(blame.author+ " authed "+blame.authed))
|
||||
.append($('<div class="muted">').html(blame.author + " authed " + blame.authed))
|
||||
.appendTo(base);
|
||||
}
|
||||
});
|
||||
@@ -214,6 +209,8 @@ $(window).load(function(){
|
||||
updateBlame();
|
||||
});
|
||||
|
||||
var scrolling = false;
|
||||
|
||||
/**
|
||||
* Hightlight lines which are specified by URL hash.
|
||||
*/
|
||||
@@ -224,7 +221,7 @@ function updateHighlighting(){
|
||||
var lines = hash.substr(1).split('-');
|
||||
if(lines.length == 1){
|
||||
$('#' + lines[0]).addClass('highlight');
|
||||
if(!updateHighlighting.scrolling){
|
||||
if(!scrolling){
|
||||
$(window).scrollTop($('#' + lines[0]).offset().top - 40);
|
||||
}
|
||||
} else if(lines.length > 1){
|
||||
@@ -233,11 +230,11 @@ function updateHighlighting(){
|
||||
for(var i = start; i <= end; i++){
|
||||
$('#L' + i).addClass('highlight');
|
||||
}
|
||||
if(!updateHighlighting.scrolling){
|
||||
if(!scrolling){
|
||||
$(window).scrollTop($('#L' + start).offset().top - 40);
|
||||
}
|
||||
}
|
||||
updateHighlighting.scrolling = true;
|
||||
scrolling = true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -35,7 +35,7 @@
|
||||
}.getOrElse {
|
||||
encodeRefName(repository.repository.defaultBranch)
|
||||
}}...@{encodeRefName(branch.name)}?expand=1" class="btn btn-small">New Pull Request</a>
|
||||
}else{
|
||||
} else {
|
||||
<a href="@url(repository)/compare/@{repository.repository.parentUserName.map { parent =>
|
||||
urlEncode(parent) + ":" + encodeRefName(repository.repository.defaultBranch)
|
||||
}.getOrElse {
|
||||
@@ -45,9 +45,9 @@
|
||||
}
|
||||
@if(hasWritePermission){
|
||||
@if(prs.map(!_._2.closed).getOrElse(false)){
|
||||
<a class="btn disabled btn-mini" data-toggle="tooltip" title="You can’t delete this branch because it has an open pull request"><i class="icon icon-trash icon-white"></i></a>
|
||||
<a class="btn disabled btn-mini" data-toggle="tooltip" title="You can’t delete this branch because it has an open pull request"><i class="octicon octicon-trashcan"></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>
|
||||
<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="octicon octicon-trashcan"></i></a>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
@html.menu("code", repository){
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th>
|
||||
<th class="box-header">
|
||||
<div class="pull-right align-right">
|
||||
<a href="@url(repository)/tree/@commit.id" class="btn btn-small">Browse code</a>
|
||||
</div>
|
||||
@@ -74,7 +74,7 @@
|
||||
</div>
|
||||
@if(commit.isDifferentFromAuthor) {
|
||||
<div class="committer">
|
||||
<span class="icon-arrow-right"></span>
|
||||
<span class="octicon octicon-arrow-right"></span>
|
||||
<span>@user(commit.committerName, commit.committerEmailAddress, "username strong")</span>
|
||||
<span class="muted"> committed @helper.html.datetimeago(commit.commitTime)</span>
|
||||
</div>
|
||||
|
||||
@@ -10,72 +10,81 @@
|
||||
@html.main(s"${repository.owner}/${repository.name}", Some(repository)) {
|
||||
@html.menu("code", repository){
|
||||
<div class="head">
|
||||
@helper.html.branchcontrol(
|
||||
branch,
|
||||
repository,
|
||||
hasWritePermission
|
||||
){
|
||||
@repository.branchList.map { x =>
|
||||
<li><a href="@url(repository)/commits/@encodeRefName(x)">@helper.html.checkicon(x == branch) @x</a></li>
|
||||
}
|
||||
}
|
||||
@if(pathList.isEmpty){
|
||||
<a href="@url(repository)/tree/@encodeRefName(branch)">@repository.name</a> / Commit History
|
||||
@helper.html.branchcontrol(
|
||||
branch,
|
||||
repository,
|
||||
hasWritePermission
|
||||
){
|
||||
@repository.branchList.map { x =>
|
||||
<li><a href="@url(repository)/commits/@encodeRefName(x)">@helper.html.checkicon(x == branch) @x</a></li>
|
||||
}
|
||||
}
|
||||
}
|
||||
@if(pathList.nonEmpty){
|
||||
<span class="muted">History for</span>
|
||||
<a href="@url(repository)/tree/@encodeRefName(branch)">@repository.name</a> /
|
||||
<a class="strong" href="@url(repository)/tree/@encodeRefName(branch)">@repository.name</a> /
|
||||
@pathList.zipWithIndex.map { case (section, i) =>
|
||||
@if(i == pathList.length - 1){
|
||||
@section
|
||||
<span class="strong">@section</span>
|
||||
} else {
|
||||
<a href="@url(repository)/tree/@encodeRefName(branch)/@pathList.take(i + 1).mkString("/")">@section</a> /
|
||||
<a class="strong" href="@url(repository)/tree/@encodeRefName(branch)/@pathList.take(i + 1).mkString("/")">@section</a> /
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
@commits.map { day =>
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th>@date(day.head.commitTime)</th>
|
||||
</tr>
|
||||
@day.map { commit =>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="pull-right align-right">
|
||||
<a href="@url(repository)/commit/@commit.id" class="btn btn-small monospace">@commit.id.substring(0, 10)</a><br>
|
||||
<a href="@url(repository)/tree/@commit.id" class="small">Browse code</a>
|
||||
</div>
|
||||
<div>
|
||||
<div class="commit-avatar-image">@avatar(commit, 40)</div>
|
||||
<div class="commit-message-box">
|
||||
<a href="@url(repository)/commit/@commit.id" class="commit-message" style="font-weight: bold;">@link(commit.summary, repository)</a>
|
||||
@if(commit.description.isDefined){
|
||||
<a href="javascript:void(0)" onclick="$('#description-@commit.id').toggle();" class="omit">...</a>
|
||||
}
|
||||
<br>
|
||||
@if(commit.description.isDefined){
|
||||
<pre id="description-@commit.id" style="display: none;" class="commit-description">@link(commit.description.get, repository)</pre>
|
||||
}
|
||||
<div class="small">
|
||||
@user(commit.authorName, commit.authorEmailAddress, "username")
|
||||
<span class="muted">authored @helper.html.datetimeago(commit.authorTime)</span>
|
||||
@if(commit.isDifferentFromAuthor) {
|
||||
<span class="icon-arrow-right" style="margin-top : -2px ;"></span>
|
||||
@user(commit.committerName, commit.committerEmailAddress, "username")
|
||||
<span class="muted">committed @helper.html.datetimeago(commit.authorTime)</span>
|
||||
<div class="commit-list">
|
||||
@commits.map { day =>
|
||||
<div class="muted" style="background-color: white;">
|
||||
<i class="octicon octicon-git-commit"></i> Commits on @date(day.head.commitTime)
|
||||
</div>
|
||||
<div class="box-commits">
|
||||
@day.map { commit =>
|
||||
<div class="box-content-row" style="padding: 8px;">
|
||||
<ul class="nav nav-pills-group pull-right" style="margin-top: 2px; margin-bottom: 0px; margin-right: 4px;">
|
||||
<li class="first"><a href="@url(repository)/commit/@commit.id" class="link monospace">@commit.id.substring(0, 7)</a></li>
|
||||
<li class="last"><a href="@url(repository)/tree/@commit.id" style="padding-top: 9px; padding-bottom: 10px;"><i class="octicon octicon-code link"></i></a></li>
|
||||
</ul>
|
||||
<div>
|
||||
<div class="commit-avatar-image">@avatar(commit, 40)</div>
|
||||
<div class="commit-message-box">
|
||||
<a href="@url(repository)/commit/@commit.id" class="commit-message" style="font-weight: bold;">@link(commit.summary, repository)</a>
|
||||
@if(commit.description.isDefined){
|
||||
<a href="javascript:void(0)" onclick="$('#description-@commit.id').toggle();" class="omit">...</a>
|
||||
}
|
||||
<br>
|
||||
@if(commit.description.isDefined){
|
||||
<pre id="description-@commit.id" style="display: none;" class="commit-description">@link(commit.description.get, repository)</pre>
|
||||
}
|
||||
<div class="small">
|
||||
@user(commit.authorName, commit.authorEmailAddress, "username")
|
||||
<span class="muted">authored @helper.html.datetimeago(commit.authorTime)</span>
|
||||
@if(commit.isDifferentFromAuthor) {
|
||||
<span class="octicon octicon-arrow-right" style="margin-top : -2px;"></span>
|
||||
@user(commit.committerName, commit.committerEmailAddress, "username")
|
||||
<span class="muted">committed @helper.html.datetimeago(commit.authorTime)</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="pagination" style="text-align: center; margin-top: 30px">
|
||||
<ul>
|
||||
@if(page <= 1){
|
||||
<li class="disabled"><span>Newer</span></li>
|
||||
} else {
|
||||
<li><a href="?page=@{page - 1}">Newer</a></li>
|
||||
}
|
||||
</table>
|
||||
}
|
||||
<div class="btn-group">
|
||||
<button class="btn" onclick="location.href='?page=@{page - 1}'"@if(page <= 1){ disabled="true"}>< Newer</button>
|
||||
<button class="btn" onclick="location.href='?page=@{page + 1}'"@if(!hasNext){ disabled="true"}>Older ></button>
|
||||
@if(!hasNext){
|
||||
<li class="disabled"><span>Older</span></li>
|
||||
} else {
|
||||
<li><a href="?page=@{page + 1}">Older</a></li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
@html.menu("code", repository, Some(branch), pathList.isEmpty, groupNames.isEmpty, info, error){
|
||||
<div class="head">
|
||||
<div class="pull-right"><div class="btn-group">
|
||||
<a href="@url(repository)/find/@encodeRefName(branch)" class="btn btn-mini" data-toggle="tooltip" data-placement="bottom" data-hotkey="t" title="Quickly jump between files"><i class="icon icon-th-list"></i></a>
|
||||
<a href="@url(repository)/find/@encodeRefName(branch)" class="btn btn-small" data-toggle="tooltip" data-placement="bottom" data-hotkey="t" title="Quickly jump between files"><i class="octicon octicon-list-unordered"></i></a>
|
||||
@if(pathList.nonEmpty){
|
||||
<a href="@url(repository)/commits/@encodeRefName(branch)/@pathList.mkString("/")" class="btn btn-mini" data-toggle="tooltip" data-placement="bottom" title="Browse commits for this branch"><i class="icon icon-time"></i></a>
|
||||
<a href="@url(repository)/commits/@encodeRefName(branch)/@pathList.mkString("/")" class="btn btn-small" data-toggle="tooltip" data-placement="bottom" title="Browse commits for this branch"><i class="octicon octicon-clock"></i></a>
|
||||
}
|
||||
</div></div>
|
||||
@branchPullRequest.map{ case (pullRequest, issue) =>
|
||||
<a href="@url(repository)/pull/@pullRequest.issueId" class="btn btn-pullrequest-branch btn-mini" title="@issue.title" data-toggle="tooltip">#@pullRequest.issueId</a>
|
||||
<a href="@url(repository)/pull/@pullRequest.issueId" class="btn btn-small btn-pullrequest-branch" title="@issue.title" data-toggle="tooltip">#@pullRequest.issueId</a>
|
||||
}.getOrElse{
|
||||
<a href="@url(repository)/compare?head=@urlEncode(encodeRefName(branch))" class="btn btn-success btn-mini"><i class="icon-white icon-retweet" data-toggle="tooltip" title="Compare, review, create a pull request"></i></a>
|
||||
<a href="@url(repository)/compare?head=@urlEncode(encodeRefName(branch))" class="btn btn-small btn-success"><i class="octicon octicon-git-compare" data-toggle="tooltip" title="Compare, review, create a pull request"></i></a>
|
||||
}
|
||||
@helper.html.branchcontrol(
|
||||
branch,
|
||||
@@ -44,7 +44,7 @@
|
||||
</div>
|
||||
<table class="table table-file-list">
|
||||
<tr>
|
||||
<th colspan="4" style="font-weight: normal;">
|
||||
<th colspan="4" style="font-weight: normal; border: none;">
|
||||
<a href="@url(repository)/commit/@latestCommit.id" class="commit-message">@link(latestCommit.summary, repository)</a>
|
||||
@if(latestCommit.description.isDefined){
|
||||
<a href="javascript:void(0)" onclick="$('#description-@latestCommit.id').toggle();" class="omit">...</a>
|
||||
@@ -66,7 +66,7 @@
|
||||
</div>
|
||||
@if(latestCommit.isDifferentFromAuthor) {
|
||||
<div class="committer">
|
||||
<span class="icon-arrow-right"></span>
|
||||
<span class="octicon octicon-arrow-right"></span>
|
||||
<span>@user(latestCommit.committerName, latestCommit.committerEmailAddress, "username strong")</span>
|
||||
<span class="muted"> committed @helper.html.datetimeago(latestCommit.commitTime)</span>
|
||||
</div>
|
||||
@@ -77,7 +77,7 @@
|
||||
</tr>
|
||||
@if(pathList.size > 0){
|
||||
<tr>
|
||||
<td width="16"></td>
|
||||
<td width="16" class="file-icon"></td>
|
||||
<td><a href="@url(repository)@if(pathList.size > 1){/tree/@encodeRefName(branch)/@pathList.init.mkString("/")}">..</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
@@ -85,7 +85,7 @@
|
||||
}
|
||||
@files.map { file =>
|
||||
<tr>
|
||||
<td width="16">
|
||||
<td width="16" class="file-icon">
|
||||
@if(file.isDirectory){
|
||||
@if(file.linkUrl.isDefined){
|
||||
<i class="octicon octicon-file-symlink-directory"></i>
|
||||
@@ -96,7 +96,7 @@
|
||||
<i class="octicon octicon-file-text"></i>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<td class="content-name">
|
||||
@if(file.isDirectory){
|
||||
@if(file.linkUrl.isDefined){
|
||||
<a href="@file.linkUrl">
|
||||
@@ -118,8 +118,8 @@
|
||||
}
|
||||
</td>
|
||||
<td class="mute">
|
||||
<a href="@url(repository)/commit/@file.commitId" class="commit-message">@link(file.message, repository)</a>
|
||||
[@user(file.author, file.mailAddress)]
|
||||
<a href="@url(repository)/commit/@file.commitId" class="commit-message shorten-text" title="@file.message">@link(file.message, repository)</a>
|
||||
<span class="commit-author">[@user(file.author, file.mailAddress)]</span>
|
||||
</td>
|
||||
<td style="text-align: right;">@helper.html.datetimeago(file.time, false)</td>
|
||||
</tr>
|
||||
@@ -128,7 +128,7 @@
|
||||
@readme.map { case(filePath, content) =>
|
||||
<div id="readme">
|
||||
<div class="box-header">@filePath.reverse.head</div>
|
||||
<div class="box-content markdown-body">@renderMarkup(filePath, content, branch, repository, false, false, true)</div>
|
||||
<div class="box-content-bottom markdown-body" style="padding-left: 16px; padding-right: 16px;">@renderMarkup(filePath, content, branch, repository, false, false, true)</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
<table id="tree-finder-results" class="table table-file-list" data-url="@url(repository)/tree-list/@treeId">
|
||||
<tbody class="tree-browser-result-template">
|
||||
<tr class="tree-browser-result">
|
||||
<td class="icon"><span class="icon icon-chevron-right"></span></td>
|
||||
<td class="icon"><img src="@assets/common/images/file.png"/></td>
|
||||
<td class="icon"><span class="octicon octicon-chevron-right"></span></td>
|
||||
<td class="icon"><i class="octicon octicon-file-text"></i></td>
|
||||
<td>
|
||||
<a href="@url(repository)/blob/@encodeRefName(branch)"></a>
|
||||
</td>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
Opened by <a href="@url(issue.openedUserName)" class="username">@issue.openedUserName</a>
|
||||
@helper.html.datetimeago(issue.registeredDate)
|
||||
@if(issue.commentCount > 0){
|
||||
<i class="icon-comment"></i><span class="strong">@issue.commentCount</span> @plural(issue.commentCount, "comment")
|
||||
<i class="octicon octicon-comment"></i><span class="strong">@issue.commentCount</span> @plural(issue.commentCount, "comment")
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -91,9 +91,9 @@
|
||||
</div>
|
||||
</div>
|
||||
*@
|
||||
<fieldset>
|
||||
<div class="align-right" style="margin-top: 20px;">
|
||||
<input type="submit" class="btn btn-success" value="Apply changes"/>
|
||||
</fieldset>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
@(systemSettings: gitbucket.core.service.SystemSettingsService.SystemSettings)(implicit context: gitbucket.core.controller.Context)
|
||||
@import context._
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th class="metal">
|
||||
@if(systemSettings.allowAccountRegistration){
|
||||
<div class="pull-right">
|
||||
<a href="@path/register" class="btn btn-mini">Create new account</a>
|
||||
</div>
|
||||
}
|
||||
Sign in
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<form action="@path/signin" method="POST" validate="true">
|
||||
<label for="userName">Username:</label>
|
||||
<span id="error-userName" class="error"></span>
|
||||
<input type="text" name="userName" id="userName" style="width: 95%" autofocus/>
|
||||
<label for="password">Password:</label>
|
||||
<span id="error-password" class="error"></span>
|
||||
<input type="password" name="password" id="password" style="width: 95%"/>
|
||||
<div>
|
||||
<input type="submit" class="btn btn-success" value="Sign in"/>
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="box-header">
|
||||
@if(systemSettings.allowAccountRegistration){
|
||||
<div class="pull-right">
|
||||
<a href="@path/register" class="btn btn-mini">Create new account</a>
|
||||
</div>
|
||||
}
|
||||
<span class="strong">Sign in</span>
|
||||
</div>
|
||||
<div class="box-content-bottom">
|
||||
<form action="@path/signin" method="POST" validate="true">
|
||||
<label for="userName">Username:</label>
|
||||
<span id="error-userName" class="error"></span>
|
||||
<input type="text" name="userName" id="userName" style="width: 95%" autofocus/>
|
||||
<label for="password">Password:</label>
|
||||
<span id="error-password" class="error"></span>
|
||||
<input type="password" name="password" id="password" style="width: 95%"/>
|
||||
<div>
|
||||
<input type="submit" class="btn btn-success" value="Sign in"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</ul>
|
||||
<form action="@url(repository)/wiki/@if(page.isEmpty){_new} else {_edit}" method="POST" validate="true">
|
||||
<span id="error-pageName" class="error"></span>
|
||||
<input type="text" name="pageName" value="@pageName" style="width: 850px; font-weight: bold;" placeholder="Input a page name."/>
|
||||
<input type="text" name="pageName" value="@pageName" style="width: 910px; font-weight: bold;" placeholder="Input a page name."/>
|
||||
@helper.html.preview(
|
||||
repository = repository,
|
||||
content = page.map(_.content).getOrElse(""),
|
||||
@@ -29,11 +29,11 @@
|
||||
enableRefsLink = false,
|
||||
enableTaskList = false,
|
||||
hasWritePermission = false,
|
||||
style = "width: 850px; height: 400px;",
|
||||
style = "width: 910px; height: 400px;",
|
||||
styleClass = "monospace",
|
||||
placeholder = ""
|
||||
)
|
||||
<input type="text" name="message" value="" style="width: 850px;" placeholder="Write a small message here explaining this change. (Optional)"/>
|
||||
<input type="text" name="message" value="" style="width: 910px;" placeholder="Write a small message here explaining this change. (Optional)"/>
|
||||
<input type="hidden" name="currentPageName" value="@pageName"/>
|
||||
<input type="hidden" name="id" value="@page.map(_.id)"/>
|
||||
<input type="submit" value="Save" class="btn btn-success">
|
||||
|
||||
@@ -25,20 +25,23 @@
|
||||
</li>
|
||||
</ul>
|
||||
<div style="width: 200px;" class="pull-right">
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th class="metal">Pages <span class="label">@pages.length</span></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<ul style="margin-left: 0px; margin-bottom: 0px; word-break: break-all; width: 182px;">
|
||||
@pages.map { page =>
|
||||
<li style="margin-left:0px; list-style-type: none;"><a href="@url(repository)/wiki/@urlEncode(page)">@page</a></li>
|
||||
}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@defining(15){ max =>
|
||||
<div class="box-header">
|
||||
<span class="strong">Pages</span> <span class="label">@pages.length</span>
|
||||
</div>
|
||||
<div class="box-content-bottom" style="padding: 0px;">
|
||||
@pages.zipWithIndex.map { case (page, i) =>
|
||||
<div class="box-content-row page-link" style="border: none; @if(i > max - 1){display:none;}">
|
||||
<a href="@url(repository)/wiki/@urlEncode(page)" class="strong">@page</a>
|
||||
</div>
|
||||
}
|
||||
@if(pages.size > max){
|
||||
<div class="box-content-row show-more">
|
||||
<a href="javascript:void(0);" id="show-more-pages">Show more @{pages.size - max} pages...</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="small">
|
||||
<strong>Clone this wiki locally</strong>
|
||||
</div>
|
||||
@@ -58,9 +61,14 @@
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@if(settings.ssh && loginAccount.isDefined){
|
||||
<script>
|
||||
$(function(){
|
||||
<script>
|
||||
$(function(){
|
||||
$('#show-more-pages').click(function(e){
|
||||
$('div.page-link').show();
|
||||
$(e.target).parents('div.show-more').remove();
|
||||
});
|
||||
|
||||
@if(settings.ssh && loginAccount.isDefined){
|
||||
$('#repository-url-http').click(function(){
|
||||
$('#repository-url').val('@httpUrl(repository)');
|
||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||
@@ -69,6 +77,6 @@
|
||||
$('#repository-url').val('@sshUrl(repository, settings, loginAccount.get.userName)');
|
||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -60,6 +60,10 @@ h6 {
|
||||
.head .octicon,.head .mega-octicon{
|
||||
color : #BBB;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
/* ======================================================================== */
|
||||
/* Global Header */
|
||||
/* ======================================================================== */
|
||||
@@ -131,15 +135,6 @@ a.global-header-menu {
|
||||
line-height: 3.5;
|
||||
}
|
||||
|
||||
/*
|
||||
img.plugin-global-menu {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
*/
|
||||
|
||||
/* ======================================================================== */
|
||||
/* General Styles */
|
||||
/* ======================================================================== */
|
||||
@@ -155,7 +150,7 @@ div.head div.forked {
|
||||
}
|
||||
|
||||
div.container {
|
||||
width: 920px;
|
||||
width: 980px;
|
||||
}
|
||||
|
||||
div.container-wide {
|
||||
@@ -184,6 +179,12 @@ span.error {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.shorten-text {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a.commit-message, a.commit-id, a.username, a.issue-comment-count {
|
||||
color: #333333;
|
||||
}
|
||||
@@ -199,6 +200,15 @@ a.omit:hover {
|
||||
background-color: #aaa;
|
||||
}
|
||||
|
||||
div.show-more {
|
||||
text-align: center;
|
||||
border-top: 1px solid silver;
|
||||
}
|
||||
|
||||
div.show-more a {
|
||||
color: #7aa1d3;
|
||||
}
|
||||
|
||||
span.count-right {
|
||||
float: right;
|
||||
font-weight: bold;
|
||||
@@ -227,82 +237,81 @@ h3 {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
div.box {
|
||||
background-color: #efefef;
|
||||
padding: 2px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
div.box-header {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
background-color: #e0e0e0;
|
||||
background-image: -moz-linear-gradient(#fafafa, #e0e0e0);
|
||||
background-image: -webkit-linear-gradient(#fafafa, #e0e0e0);
|
||||
background-image: linear-gradient(#fafafa, #e0e0e0);
|
||||
background-repeat: repeat-x;
|
||||
background-color: #f5f5f5;
|
||||
margin: 0;
|
||||
border-top-left-radius: 1px;
|
||||
border-top-right-radius: 1px;
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
border: 1px solid #d8d8d8;
|
||||
border-bottom: none;
|
||||
padding: 8px 10px 8px 10px;
|
||||
text-shadow: 0 1px 0 #fff
|
||||
}
|
||||
|
||||
div.box-header-small {
|
||||
background-color: #e0e0e0;
|
||||
background-image: -moz-linear-gradient(#fafafa, #e0e0e0);
|
||||
background-image: -webkit-linear-gradient(#fafafa, #e0e0e0);
|
||||
background-image: linear-gradient(#fafafa, #e0e0e0);
|
||||
background-repeat: repeat-x;
|
||||
margin: 0;
|
||||
border-top-left-radius: 1px;
|
||||
border-top-right-radius: 1px;
|
||||
border: 1px solid #d8d8d8;
|
||||
border-bottom: none;
|
||||
padding: 6px 4px 6px 4px;
|
||||
text-shadow: 0 1px 0 #fff
|
||||
padding: 8px 8px 8px 8px;
|
||||
}
|
||||
|
||||
.inline-comment div.box-header-small {
|
||||
background: #f2f8fa;
|
||||
}
|
||||
|
||||
.commit-list {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.commit-list::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 6px;
|
||||
z-index: -1;
|
||||
display: block;
|
||||
width: 2px;
|
||||
content: "";
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
|
||||
ul.nav-pills-group .link {
|
||||
color: #4078c0;
|
||||
}
|
||||
|
||||
div.box-commits {
|
||||
background-color: white;
|
||||
border: 1px solid #d8d8d8;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
div.box-content {
|
||||
background-color: white;
|
||||
border: 1px solid #d8d8d8;
|
||||
padding: 4px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
th.box-header {
|
||||
background-color: #e0e0e0;
|
||||
background-image: -moz-linear-gradient(#fafafa, #e0e0e0);
|
||||
background-image: -webkit-linear-gradient(#fafafa, #e0e0e0);
|
||||
background-image: linear-gradient(#fafafa, #e0e0e0);
|
||||
background-repeat: repeat-x;
|
||||
margin: 0;
|
||||
border-top-left-radius: 1px;
|
||||
border-top-right-radius: 1px;
|
||||
div > div.box-content-row:nth-of-type(1) {
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.box-content-row {
|
||||
border-top: 1px solid #d8d8d8;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
div.box-content-bottom {
|
||||
background-color: white;
|
||||
border: 1px solid #d8d8d8;
|
||||
border-bottom: none;
|
||||
text-shadow: 0 1px 0 #fff
|
||||
padding: 4px;
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
table.table th.box-header {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
th.box-header .octicon {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
th.metal {
|
||||
background-color: #e0e0e0;
|
||||
background-image: -moz-linear-gradient(#fafafa, #e8e8e8);
|
||||
background-image: -webkit-linear-gradient(#fafafa, #e8e8e8);
|
||||
background-image: linear-gradient(#fafafa, #e8e8e8);
|
||||
background-repeat: repeat-x;
|
||||
margin: 0;
|
||||
border-top-left-radius: 1px;
|
||||
border-top-right-radius: 1px;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
dl {
|
||||
@@ -374,6 +383,22 @@ span.highlight {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn .octicon {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.btn-success .octicon {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-warning .octicon {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-danger .octicon {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Side Menu */
|
||||
/****************************************************************************/
|
||||
@@ -381,23 +406,30 @@ ul.sidemenu {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
ul.sidemenu a:hover{
|
||||
ul.sidemenu a {
|
||||
display: block;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
ul.sidemenu a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul.sidemenu li.active {
|
||||
border-top: 1px solid #eee;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-right: 2px solid #bb4444;
|
||||
border-right: 3px solid #bb4444;
|
||||
border-left: 1px solid white;
|
||||
}
|
||||
|
||||
ul.sidemenu div.gradient {
|
||||
width: 5px;
|
||||
height: 30px;
|
||||
background: linear-gradient(to right, #eee, #fff);
|
||||
margin-right: 4px;
|
||||
border-left: 1px solid #eee;
|
||||
ul.sidemenu li.active a {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
ul.sidemenu {
|
||||
background-image: -webkit-linear-gradient(left, #f6f6f6 0%, #fff 8px);
|
||||
background-image: linear-gradient(to right, #f6f6f6 0%, #fff 8px);
|
||||
box-shadow: inset 1px 0 0 #eee;
|
||||
}
|
||||
|
||||
ul.sidemenu div.margin {
|
||||
@@ -408,8 +440,6 @@ ul.sidemenu div.margin {
|
||||
}
|
||||
|
||||
ul.sidemenu li {
|
||||
line-height: 30px;
|
||||
height: 30px;
|
||||
border-left: 1px solid #eee;
|
||||
margin-left:0px;
|
||||
border-right: 2px solid white;
|
||||
@@ -485,36 +515,24 @@ ul.nav-stacked.side-menu li.active a:hover {
|
||||
}
|
||||
|
||||
.nav-tabs.nav-stacked.side-menu > li:first-child > a {
|
||||
-webkit-border-top-right-radius: 0px;
|
||||
|
||||
border-top-right-radius: 0px;
|
||||
-webkit-border-top-left-radius: 0px;
|
||||
|
||||
border-top-left-radius: 0px;
|
||||
-moz-border-radius-topright: 0px;
|
||||
-moz-border-radius-topleft: 0px;
|
||||
border-top-right-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
}
|
||||
|
||||
.nav-tabs.nav-stacked.side-menu > li:last-child > a {
|
||||
-webkit-border-bottom-right-radius: 0px;
|
||||
|
||||
border-bottom-right-radius: 0px;
|
||||
-webkit-border-bottom-left-radius: 0px;
|
||||
|
||||
border-bottom-left-radius: 0px;
|
||||
-moz-border-radius-bottomright: 0px;
|
||||
-moz-border-radius-bottomleft: 0px;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Repositories */
|
||||
/****************************************************************************/
|
||||
div.repository-icon {
|
||||
position: absolute;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
div.repository-content {
|
||||
margin-left: 40px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.branches .muted-link{
|
||||
@@ -604,15 +622,11 @@ p.description {
|
||||
a.header-link {
|
||||
color: #888;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
a.header-link i.octicon {
|
||||
opacity: 0.5;
|
||||
display: block;
|
||||
}
|
||||
|
||||
a.header-link strong {
|
||||
color: black;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
a.header-link:hover {
|
||||
@@ -639,14 +653,17 @@ a.header-link:hover i.octicon-x{
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
table.blobview {
|
||||
table-layout: fixed;
|
||||
}
|
||||
*/
|
||||
|
||||
table.table-file-list {
|
||||
margin-bottom: 0px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
table.table-file-list th, table.table-file-list td {
|
||||
@@ -665,6 +682,25 @@ table.table-file-list td {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
table.table-file-list .file-icon {
|
||||
padding-right: 1px;
|
||||
}
|
||||
|
||||
table.table-file-list .content-name {
|
||||
max-width: 180px;
|
||||
}
|
||||
|
||||
table.table-file-list .commit-message {
|
||||
max-width: 415px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
table.table-file-list .commit-author {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
th, td, .table th, .table td {
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
@@ -876,6 +912,10 @@ a.issue-title {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
.label-success {
|
||||
background-color: #6cc644;
|
||||
}
|
||||
|
||||
ul.label-list {
|
||||
list-style-type: none;
|
||||
padding-left: 0px;
|
||||
@@ -979,8 +1019,16 @@ div.issue-info {
|
||||
}
|
||||
|
||||
div.issue-content {
|
||||
padding: 8px;
|
||||
background-color: #fbfbfb;
|
||||
padding: 13px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
div.issue-content p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
div.issue-content p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h4#issueTitle {
|
||||
@@ -1007,17 +1055,47 @@ div.issue-participants {
|
||||
|
||||
div.issue-comment-box, div.commit-comment-box {
|
||||
margin-bottom: 15px;
|
||||
margin-left: 50px;
|
||||
margin-left: 70px;
|
||||
max-width: 820px;
|
||||
}
|
||||
|
||||
div.issue-comment-box textarea {
|
||||
width: 670px;
|
||||
height: 100px;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
div.issue-comment-action {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 0px;
|
||||
margin-left: 70px;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 4px solid #ddd;
|
||||
}
|
||||
|
||||
div.issue-comment-action .octicon {
|
||||
border-radius: 50%;
|
||||
background-color: #f3f3f3;
|
||||
color: #767676;
|
||||
font-size: 18px;
|
||||
margin-right: 7px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
|
||||
div.issue-reopened .octicon {
|
||||
background-color: #6cc644;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.issue-comment-action .octicon.danger {
|
||||
background-color: #bd2c00;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.nav-pills > li > span.issue-label {
|
||||
display: block;
|
||||
padding: 0px 8px 2px 8px;
|
||||
@@ -1406,6 +1484,7 @@ div.markdown-body {
|
||||
font: 15px Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
div.markdown-body h1 {
|
||||
border-bottom: 1px solid #ddd;
|
||||
font-size: 2.5em;
|
||||
@@ -1676,9 +1755,12 @@ h6 a.markdown-anchor-link {
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
/*
|
||||
div.container.blame-container{
|
||||
width:1270px;
|
||||
}
|
||||
*/
|
||||
|
||||
.line-age-legend {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -231,13 +231,13 @@ body {
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0088cc;
|
||||
color: #4078c0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus {
|
||||
color: #005580;
|
||||
color: #4078c0;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class JsonFormatSpec extends Specification {
|
||||
"default_branch" : "master",
|
||||
"owner" : $apiUserJson,
|
||||
"forks_count" : 0,
|
||||
"watchers_coun" : 0,
|
||||
"watchers_count" : 0,
|
||||
"url" : "${context.baseUrl}/api/v3/repos/octocat/Hello-World",
|
||||
"http_url" : "${context.baseUrl}/git/octocat/Hello-World.git",
|
||||
"clone_url" : "${context.baseUrl}/git/octocat/Hello-World.git",
|
||||
|
||||
Reference in New Issue
Block a user