From 266f5c027f495430841c2fc050352e5225a336ee Mon Sep 17 00:00:00 2001 From: rr- Date: Fri, 29 Apr 2016 11:48:34 +0200 Subject: [PATCH] client/tags: add tag listing --- client/css/tags.styl | 27 +++++++++++++ client/html/tag_list_header.hbs | 15 +++++++ client/html/tag_list_page.hbs | 50 ++++++++++++++++++++++++ client/js/controllers/tags_controller.js | 34 ++++++++++++++-- client/js/views/tag_list_header_view.js | 35 +++++++++++++++++ client/js/views/tag_list_page_view.js | 17 ++++++++ 6 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 client/css/tags.styl create mode 100644 client/html/tag_list_header.hbs create mode 100644 client/html/tag_list_page.hbs create mode 100644 client/js/views/tag_list_header_view.js create mode 100644 client/js/views/tag_list_page_view.js diff --git a/client/css/tags.styl b/client/css/tags.styl new file mode 100644 index 00000000..b72a8e99 --- /dev/null +++ b/client/css/tags.styl @@ -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 diff --git a/client/html/tag_list_header.hbs b/client/html/tag_list_header.hbs new file mode 100644 index 00000000..05d51e2b --- /dev/null +++ b/client/html/tag_list_header.hbs @@ -0,0 +1,15 @@ +
+
+
+
    +
  • + {{textInput id='search-text' name='search-text' value=this.searchQuery.text}} +
  • +
+
+
+ + Syntax help +
+
+
diff --git a/client/html/tag_list_page.hbs b/client/html/tag_list_page.hbs new file mode 100644 index 00000000..e5d7210f --- /dev/null +++ b/client/html/tag_list_page.hbs @@ -0,0 +1,50 @@ +
+ {{#if this.results}} + + + + + + + + + {{#each this.results}} + + + + + + + {{/each}} + +
Tag name(s)ImplicationsSuggestionsUsages
+
    + {{#each this.names}} +
  • {{this}}
  • + {{/each}} +
+
+ {{#if this.implications}} +
    + {{#each this.implications}} +
  • {{this}}
  • + {{/each}} +
+ {{else}} + - + {{/if}} +
+ {{#if this.suggestions}} +
    + {{#each this.suggestions}} +
  • {{this}}
  • + {{/each}} +
+ {{else}} + - + {{/if}} +
+ {{this.usages}} +
+ {{/if}} +
diff --git a/client/js/controllers/tags_controller.js b/client/js/controllers/tags_controller.js index 60588473..e7992140 100644 --- a/client/js/controllers/tags_controller.js +++ b/client/js/controllers/tags_controller.js @@ -1,15 +1,43 @@ 'use strict'; const page = require('page'); +const api = require('../api.js'); +const misc = require('../util/misc.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 { - registerRoutes() { - page('/tags', (ctx, next) => { this.listTagsRoute(); }); + constructor() { + 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'); + + 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, + }); } } diff --git a/client/js/views/tag_list_header_view.js b/client/js/views/tag_list_header_view.js new file mode 100644 index 00000000..1fa661af --- /dev/null +++ b/client/js/views/tag_list_header_view.js @@ -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; diff --git a/client/js/views/tag_list_page_view.js b/client/js/views/tag_list_page_view.js new file mode 100644 index 00000000..e7142fb9 --- /dev/null +++ b/client/js/views/tag_list_page_view.js @@ -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;