client/tags: add tag listing

This commit is contained in:
rr- 2016-04-29 11:48:34 +02:00
parent c55fb2ef41
commit 266f5c027f
6 changed files with 175 additions and 3 deletions

27
client/css/tags.styl Normal file
View File

@ -0,0 +1,27 @@
@import colors
.tag-list
table
width: 100%
text-align: left
.usages
text-align: center
ul
list-style-type: none
margin: 0
padding: 0
display: inline
li
padding: 0
display: inline
&:not(:last-child):after
content: ', '
.tag-list-header
text-align: left
form
width: auto
input[name=search-text]
max-width: 15em
.append
font-size: 0.95em
color: $inactive-link-color

View File

@ -0,0 +1,15 @@
<div class='tag-list-header'>
<form class='horizontal'>
<div class='input'>
<ul>
<li>
{{textInput id='search-text' name='search-text' value=this.searchQuery.text}}
</li>
</ul>
</div>
<div class='buttons'>
<input type='submit' value='Search'/>
<a class='append' href='/help/search/tags'>Syntax help</a>
</div>
</form>
</div>

View File

@ -0,0 +1,50 @@
<div class='tag-list'>
{{#if this.results}}
<table>
<thead>
<th class='names'>Tag name(s)</th>
<th class='implications'>Implications</th>
<th class='suggestions'>Suggestions</th>
<th class='usages'>Usages</th>
</thead>
<tbody>
{{#each this.results}}
<tr>
<td class='names'>
<ul>
{{#each this.names}}
<li><a href='/tag/{{this}}'>{{this}}</a></li>
{{/each}}
</ul>
</td>
<td class='implications'>
{{#if this.implications}}
<ul>
{{#each this.implications}}
<li><a href='/tag/{{this}}'>{{this}}</a></li>
{{/each}}
</ul>
{{else}}
-
{{/if}}
</td>
<td class='suggestions'>
{{#if this.suggestions}}
<ul>
{{#each this.suggestions}}
<li><a href='/tag/{{this}}'>{{this}}</a></li>
{{/each}}
</ul>
{{else}}
-
{{/if}}
</td>
<td class='usages'>
{{this.usages}}
</td>
</tr>
{{/each}}
</tbody>
</table>
{{/if}}
</div>

View File

@ -1,15 +1,43 @@
'use strict'; 'use strict';
const page = require('page'); const page = require('page');
const api = require('../api.js');
const misc = require('../util/misc.js');
const topNavController = require('../controllers/top_nav_controller.js'); const topNavController = require('../controllers/top_nav_controller.js');
const pageController = require('../controllers/page_controller.js');
const TagListHeaderView = require('../views/tag_list_header_view.js');
const TagListPageView = require('../views/tag_list_page_view.js');
class TagsController { class TagsController {
registerRoutes() { constructor() {
page('/tags', (ctx, next) => { this.listTagsRoute(); }); this.tagListHeaderView = new TagListHeaderView();
this.tagListPageView = new TagListPageView();
} }
listTagsRoute() { registerRoutes() {
page(
'/tags/:query?',
(ctx, next) => { misc.parseSearchQueryRoute(ctx, next); },
(ctx, next) => { this.listTagsRoute(ctx, next); });
}
listTagsRoute(ctx, next) {
topNavController.activate('tags'); topNavController.activate('tags');
pageController.run({
state: ctx.state,
requestPage: page => {
return api.get(
'/tags/?query={text}&page={page}&pageSize=50'.format({
text: ctx.searchQuery.text,
page: page}));
},
clientUrl: '/tags/' + misc.formatSearchQuery({
text: ctx.searchQuery.text, page: '{page}'}),
searchQuery: ctx.searchQuery,
headerRenderer: this.tagListHeaderView,
pageRenderer: this.tagListPageView,
});
} }
} }

View File

@ -0,0 +1,35 @@
'use strict';
const page = require('page');
const keyboard = require('../util/keyboard.js');
const misc = require('../util/misc.js');
const views = require('../util/views.js');
class TagListHeaderView {
constructor() {
this.template = views.getTemplate('tag-list-header');
}
render(ctx) {
const target = ctx.target;
const source = this.template(ctx);
const form = source.querySelector('form');
keyboard.bind('q', () => {
form.querySelector('input').focus();
});
form.addEventListener('submit', e => {
e.preventDefault();
const searchTextInput = form.querySelector('[name=search-text]');
const text = searchTextInput.value;
searchTextInput.blur();
page('/tags/' + misc.formatSearchQuery({text: text}));
});
views.showView(target, source);
}
}
module.exports = TagListHeaderView;

View File

@ -0,0 +1,17 @@
'use strict';
const views = require('../util/views.js');
class TagListPageView {
constructor() {
this.template = views.getTemplate('tag-list-page');
}
render(ctx) {
const target = ctx.target;
const source = this.template(ctx);
views.showView(target, source);
}
}
module.exports = TagListPageView;