mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-02 19:45:57 +01:00
Pagination for repository search results.
This commit is contained in:
@@ -43,9 +43,16 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
|
|||||||
}
|
}
|
||||||
|
|
||||||
get("/:owner/:repository/search")(referrersOnly { repository =>
|
get("/:owner/:repository/search")(referrersOnly { repository =>
|
||||||
import SearchCache._
|
import RepositorySearch._
|
||||||
val query = params("q").trim
|
val query = params("q").trim
|
||||||
val target = params.getOrElse("type", "code")
|
val target = params.getOrElse("type", "code")
|
||||||
|
val page = try {
|
||||||
|
val i = params.getOrElse("page", "1").toInt
|
||||||
|
if(i <= 0) 1 else i
|
||||||
|
} catch {
|
||||||
|
case e: NumberFormatException => 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val SearchResult(files, issues) = cache.get(repository.owner, repository.name, query)
|
val SearchResult(files, issues) = cache.get(repository.owner, repository.name, query)
|
||||||
|
|
||||||
@@ -59,15 +66,19 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
|
|||||||
issue.registeredDate,
|
issue.registeredDate,
|
||||||
commentCount,
|
commentCount,
|
||||||
getHighlightText(content, query)._1)
|
getHighlightText(content, query)._1)
|
||||||
}, files.size, query, repository)
|
}, files.size, query, page, repository)
|
||||||
case _ =>
|
case _ =>
|
||||||
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
|
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
|
||||||
val commits = JGitUtil.getLatestCommitFromPaths(git, files.toList.map(_._1), "HEAD")
|
val commits = JGitUtil.getLatestCommitFromPaths(git, files.toList.map(_._1), "HEAD")
|
||||||
|
|
||||||
search.html.code(files.toList.map { case (path, text) =>
|
search.html.code(files.toList.map { case (path, text) =>
|
||||||
val (highlightText, lineNumber) = getHighlightText(text, query)
|
val (highlightText, lineNumber) = getHighlightText(text, query)
|
||||||
FileSearchResult(path, commits(path).getCommitterIdent.getWhen, highlightText, lineNumber)
|
FileSearchResult(
|
||||||
}, issues.size, query, repository)
|
path,
|
||||||
|
commits(path).getCommitterIdent.getWhen,
|
||||||
|
highlightText,
|
||||||
|
lineNumber)
|
||||||
|
}, issues.size, query, page, repository)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -104,7 +115,10 @@ case class FileSearchResult(
|
|||||||
highlightText: String,
|
highlightText: String,
|
||||||
highlightLineNumber: Int)
|
highlightLineNumber: Int)
|
||||||
|
|
||||||
object SearchCache extends IssuesService {
|
object RepositorySearch extends IssuesService {
|
||||||
|
|
||||||
|
val CodeLimit = 10
|
||||||
|
val IssueLimit = 10
|
||||||
|
|
||||||
case class SearchResult(
|
case class SearchResult(
|
||||||
files: List[(String, String)],
|
files: List[(String, String)],
|
||||||
@@ -117,7 +131,6 @@ object SearchCache extends IssuesService {
|
|||||||
.build(
|
.build(
|
||||||
new CacheLoader[(String, String, String), SearchResult]() {
|
new CacheLoader[(String, String, String), SearchResult]() {
|
||||||
override def load(key: (String, String, String)) = {
|
override def load(key: (String, String, String)) = {
|
||||||
println("** Cache is reloaded! **")
|
|
||||||
val (owner, repository, query) = key
|
val (owner, repository, query) = key
|
||||||
val issues = if(query.isEmpty) Nil else searchIssuesByKeyword(owner, repository, query)
|
val issues = if(query.isEmpty) Nil else searchIssuesByKeyword(owner, repository, query)
|
||||||
val files = if(query.isEmpty) Nil else searchRepositoryFiles(owner, repository, query)
|
val files = if(query.isEmpty) Nil else searchRepositoryFiles(owner, repository, query)
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
@(page: Int, count: Int, limit: Int, width: Int, baseURL: String)
|
@(page: Int, count: Int, limit: Int, width: Int, baseURL: String)
|
||||||
@defining(view.Pagination(page, count, service.IssuesService.IssueLimit, width)){ p =>
|
@defining(view.Pagination(page, count, limit, width)){ p =>
|
||||||
@if(p.count > p.limit){
|
@if(p.count > p.limit){
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
<ul>
|
<ul>
|
||||||
@if(page == 1){
|
@if(page == 1){
|
||||||
<li class="disabled"><span>◀</span></li>
|
<li class="disabled"><span>◀</span></li>
|
||||||
} else {
|
} else {
|
||||||
<li><a href="@baseURL&page=@(page - 1)">◀</a></li>
|
<li><a href="@baseURL&page=@(page - 1)">◀</a></li>
|
||||||
}
|
}
|
||||||
@for(i <- 1 to p.max){
|
@for(i <- 1 to p.max){
|
||||||
@if(i == p.max && p.omitRight){
|
@if(i == p.max && p.omitRight){
|
||||||
<li><span>…</span></li>
|
<li><span>…</span></li>
|
||||||
}
|
}
|
||||||
@if(i == page){
|
@if(i == page){
|
||||||
<li class="active"><span>@i</span></li>
|
<li class="active"><span>@i</span></li>
|
||||||
} else {
|
} else {
|
||||||
@if(p.visibleFor(i)){
|
@if(p.visibleFor(i)){
|
||||||
<li><a href="@baseURL&page=@i">@i</a></li>
|
<li><a href="@baseURL&page=@i">@i</a></li>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@if(i == 1 && p.omitLeft){
|
@if(i == 1 && p.omitLeft){
|
||||||
<li><span>…</span></li>
|
<li><span>…</span></li>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@if(page == p.max){
|
@if(page == p.max){
|
||||||
<li class="disabled"><span>▶</span></li>
|
<li class="disabled"><span>▶</span></li>
|
||||||
} else {
|
} else {
|
||||||
<li><a href="@baseURL&page=@(page + 1)">▶</a></li>
|
<li><a href="@baseURL&page=@(page + 1)">▶</a></li>
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
@(files: List[app.FileSearchResult], issueCount: Int, query: String, repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context)
|
@(files: List[app.FileSearchResult],
|
||||||
|
issueCount: Int,
|
||||||
|
query: String,
|
||||||
|
page: Int,
|
||||||
|
repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context)
|
||||||
@import context._
|
@import context._
|
||||||
@import view.helpers._
|
@import view.helpers._
|
||||||
@html.main("Search Results", Some(repository)){
|
@html.main("Search Results", Some(repository)){
|
||||||
@@ -8,12 +12,14 @@
|
|||||||
} else {
|
} else {
|
||||||
<h4>We've found @files.size code @plural(files.size, "result")</h4>
|
<h4>We've found @files.size code @plural(files.size, "result")</h4>
|
||||||
}
|
}
|
||||||
@files.map { file =>
|
@files.drop((page - 1) * app.RepositorySearch.CodeLimit).take(app.RepositorySearch.CodeLimit).map { file =>
|
||||||
<div>
|
<div>
|
||||||
<h5><a href="@url(repository)/blob/@repository.repository.defaultBranch/@file.path">@file.path</a></h5>
|
<h5><a href="@url(repository)/blob/@repository.repository.defaultBranch/@file.path">@file.path</a></h5>
|
||||||
<div class="small muted">Latest commit at @datetime(file.lastModified)</div>
|
<div class="small muted">Latest commit at @datetime(file.lastModified)</div>
|
||||||
<pre class="prettyprint linenums:@file.highlightLineNumber" style="padding-left: 25px;">@Html(file.highlightText)</pre>
|
<pre class="prettyprint linenums:@file.highlightLineNumber" style="padding-left: 25px;">@Html(file.highlightText)</pre>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@helper.html.paginator(page, files.size, app.RepositorySearch.CodeLimit, 10,
|
||||||
|
s"${url(repository)}/search?q=${urlEncode(query)}&type=code")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
@(issues: List[app.IssueSearchResult], fileCount: Int, query: String, repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context)
|
@(issues: List[app.IssueSearchResult],
|
||||||
|
fileCount: Int,
|
||||||
|
query: String,
|
||||||
|
page: Int,
|
||||||
|
repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context)
|
||||||
@import context._
|
@import context._
|
||||||
@import view.helpers._
|
@import view.helpers._
|
||||||
@html.main("Search Results", Some(repository)){
|
@html.main("Search Results", Some(repository)){
|
||||||
@@ -8,10 +12,10 @@
|
|||||||
} else {
|
} else {
|
||||||
<h4>We've found @issues.size code @plural(issues.size, "result")</h4>
|
<h4>We've found @issues.size code @plural(issues.size, "result")</h4>
|
||||||
}
|
}
|
||||||
@issues.map { issue =>
|
@issues.drop((page - 1) * app.RepositorySearch.IssueLimit).take(app.RepositorySearch.IssueLimit).map { issue =>
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<div class="pull-right muted">#@issue.issueId</div>
|
<div class="pull-right muted">#@issue.issueId</div>
|
||||||
<h4><a href="@url(repository)/issues/@issue.issueId">@issue.title</a></h4>
|
<h4 style="margin-top: 0px;"><a href="@url(repository)/issues/@issue.issueId">@issue.title</a></h4>
|
||||||
<pre>@Html(issue.highlightText)</pre>
|
<pre>@Html(issue.highlightText)</pre>
|
||||||
<div class="small muted">
|
<div class="small muted">
|
||||||
Opened by <a href="@url(issue.openedUserName)" class="username">@issue.openedUserName</a>
|
Opened by <a href="@url(issue.openedUserName)" class="username">@issue.openedUserName</a>
|
||||||
@@ -22,5 +26,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@helper.html.paginator(page, issues.size, app.RepositorySearch.IssueLimit, 10,
|
||||||
|
s"${url(repository)}/search?q=${urlEncode(query)}&type=issue")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user