Skip to content

Commit

Permalink
Add sidebar with GUI filters to the search results page
Browse files Browse the repository at this point in the history
  • Loading branch information
axispx committed Oct 2, 2019
1 parent b1730d8 commit 04c3621
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 39 deletions.
22 changes: 22 additions & 0 deletions web/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,28 @@ var Funcmap = template.FuncMap{
"More": func(orig int) int {
return orig * 3
},
"IsLangFilterChecked": func(query, lang string) bool {
return strings.Contains(query, "lang:"+lang)
},
"IsRepoFilterChecked": func(query, repo string) bool {
return strings.Contains(query, "r:"+repo)
},
"Repos": func(fileMatches []*FileMatch) map[string]int {
repos := make(map[string]int)
for _, fileMatch := range fileMatches {
repos[fileMatch.Repo]++
}

return repos
},
"Languages": func(fileMatches []*FileMatch) map[string]int {
languages := make(map[string]int)
for _, fileMatch := range fileMatches {
languages[fileMatch.Language]++
}

return languages
},
"HumanUnit": func(orig int64) string {
b := orig
suffix := ""
Expand Down
167 changes: 128 additions & 39 deletions web/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,49 +205,102 @@ var TemplateText = map[string]string{
window.location.href = "/search?q=" + escape("{{.QueryStr}}" + " " + atom) +
"&" + "num=" + {{.Last.Num}};
}
function addFilter(filter) {
var searchBox = document.getElementById("navsearchbox");
var search = document.querySelector(".btn.btn-primary");
var oldQuery = searchBox.value.trim();
if (oldQuery.includes(filter)) {
searchBox.value = oldQuery.replace(filter, '');
search.click();
return;
}
searchBox.value = (oldQuery + ' ' + filter).trim();
search.click();
}
</script>
<style>
.search-main {
display: flex;
}
.container-sidebar {
flex: 1;
padding: 1rem;
}
.container-results {
flex: 3;
}
.sidebar-title {
font-weight: bold;
}
.sidebar-repo-info {
margin-bottom: 0.5rem;
display: flex;
justify-content: space-between;
}
.sidebar-count {
background-color: black;
min-width: 30px;
padding: 2.5px;
border-radius: 25%;
color: white;
}
</style>
<body id="results">
{{template "navbar" .Last}}
<div class="container-fluid container-results">
<h5>
{{if .Stats.Crashes}}<br><b>{{.Stats.Crashes}} shards crashed</b><br>{{end}}
{{ $fileCount := len .FileMatches }}
Found {{.Stats.MatchCount}} results in {{.Stats.FileCount}} files{{if or (lt $fileCount .Stats.FileCount) (or (gt .Stats.ShardsSkipped 0) (gt .Stats.FilesSkipped 0)) }},
showing top {{ $fileCount }} files (<a rel="nofollow"
href="search?q={{.Last.Query}}&num={{More .Last.Num}}">show more</a>).
{{else}}.{{end}}
</h5>
{{range .FileMatches}}
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>
{{if .URL}}<a name="{{.ResultID}}" class="result"></a><a href="{{.URL}}" >{{else}}<a name="{{.ResultID}}">{{end}}
<small>
{{.Repo}}:{{.FileName}}</a>:
<span style="font-weight: normal">[ {{if .Branches}}{{range .Branches}}<span class="label label-default">{{.}}</span>,{{end}}{{end}} ]</span>
{{if .Language}}<button
title="restrict search to files written in {{.Language}}"
onclick="zoektAddQ('lang:{{.Language}}')" class="label label-primary">language {{.Language}}</button></span>{{end}}
{{if .DuplicateID}}<a class="label label-dup" href="#{{.DuplicateID}}">Duplicate result</a>{{end}}
</small>
</th>
</tr>
</thead>
{{if not .DuplicateID}}
<tbody>
{{range .Matches}}
<tr>
<td style="background-color: rgba(238, 238, 255, 0.6);">
<pre class="inline-pre"><span class="noselect">{{if .URL}}<a href="{{.URL}}">{{end}}<u>{{.LineNum}}</u>{{if .URL}}</a>{{end}}: </span>{{range .Fragments}}{{LimitPre 100 .Pre}}<b>{{.Match}}</b>{{LimitPost 100 .Post}}{{end}}</pre>
</td>
</tr>
<div class="search-main">
{{template "sidebar" .}}
<div class="container-fluid container-results">
<h5>
{{if .Stats.Crashes}}<br><b>{{.Stats.Crashes}} shards crashed</b><br>{{end}}
{{ $fileCount := len .FileMatches }}
Found {{.Stats.MatchCount}} results in {{.Stats.FileCount}} files{{if or (lt $fileCount .Stats.FileCount) (or (gt .Stats.ShardsSkipped 0) (gt .Stats.FilesSkipped 0)) }},
showing top {{ $fileCount }} files (<a rel="nofollow"
href="search?q={{.Last.Query}}&num={{More .Last.Num}}">show more</a>).
{{else}}.{{end}}
</h5>
{{range .FileMatches}}
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>
{{if .URL}}<a name="{{.ResultID}}" class="result"></a><a href="{{.URL}}" >{{else}}<a name="{{.ResultID}}">{{end}}
<small>
{{.Repo}}:{{.FileName}}</a>:
<span style="font-weight: normal">[ {{if .Branches}}{{range .Branches}}<span class="label label-default">{{.}}</span>,{{end}}{{end}} ]</span>
{{if .Language}}<button
title="restrict search to files written in {{.Language}}"
onclick="zoektAddQ('lang:{{.Language}}')" class="label label-primary">language {{.Language}}</button></span>{{end}}
{{if .DuplicateID}}<a class="label label-dup" href="#{{.DuplicateID}}">Duplicate result</a>{{end}}
</small>
</th>
</tr>
</thead>
{{if not .DuplicateID}}
<tbody>
{{range .Matches}}
<tr>
<td style="background-color: rgba(238, 238, 255, 0.6);">
<pre class="inline-pre"><span class="noselect">{{if .URL}}<a href="{{.URL}}">{{end}}<u>{{.LineNum}}</u>{{if .URL}}</a>{{end}}: </span>{{range .Fragments}}{{LimitPre 100 .Pre}}<b>{{.Match}}</b>{{LimitPost 100 .Post}}{{end}}</pre>
</td>
</tr>
{{end}}
</tbody>
{{end}}
</tbody>
</table>
{{end}}
</table>
{{end}}
</div>
</div>
<nav class="navbar navbar-default navbar-bottom">
<div class="container">
{{template "footerBoilerplate"}}
Expand All @@ -262,12 +315,48 @@ var TemplateText = map[string]string{
</p>
</div>
</nav>
</div>
{{ template "jsdep"}}
</body>
</html>
`,

"sidebar": `
<div class="container-sidebar">
<div id="sidebar-repositories">
<p class="sidebar-title">Repositories<p>
{{range $key, $value := Repos .FileMatches}}
<div class="sidebar-repo-info">
<div>
{{if IsRepoFilterChecked $.QueryStr $key}}
<input type="checkbox" checked onclick="addFilter('r:{{$key}}')"/>
{{else}}
<input type="checkbox" onclick="addFilter('r:{{$key}}')"/>
{{end}}
{{$key}}
</div>
<div class="badge badge-pill">{{$value}}</div>
</div>
{{end}}
<hr/>
</div>
<div id="sidebar-languages">
<p class="sidebar-title">Languages<p>
{{range $key, $value := Languages .FileMatches}}
<div class="sidebar-repo-info">
<div>
{{if IsLangFilterChecked $.QueryStr $key}}
<input type="checkbox" checked onclick="addFilter('lang:{{$key}}')"/>
{{else}}
<input type="checkbox" onclick="addFilter('lang:{{$key}}')"/>
{{end}}
{{$key}}
</div>
<div class="badge badge-pill">{{$value}}</div>
</div>
{{end}}
<hr/>
</div>
</div>
`,
"repolist": `
<html>
{{template "head"}}
Expand Down

0 comments on commit 04c3621

Please sign in to comment.