client/users: add filtering

This commit is contained in:
rr- 2016-04-14 12:11:31 +02:00
parent 90559ffcdb
commit f34e83b325
11 changed files with 88 additions and 33 deletions

View file

@ -8,25 +8,19 @@ form
list-style-type: none
margin: 0
padding: 0
li
margin-top: 0.5em
label
display: block
padding: 0.5em 0
.input
margin-bottom: 1em
.buttons
margin-top: 1em
.input li:first-child label:not(.radio):not(.checkbox):not(.file-dropper),
.input li:first-child
padding-top: 0
margin-top: 0
.hint
margin-top: 0.5em
margin-bottom: 0
@ -38,17 +32,24 @@ form.tabular
ul
display: table
width: 100%
li
display: table-row
label:not(.radio):not(.checkbox):not(.file-dropper)
display: table-cell
width: 33%
.messages, .buttons
margin-left: 33%
form.horizontal
display: inline-block
margin-bottom: 1em
.input, .buttons, ul
display: inline-block
margin: 0
padding: 0
.buttons
margin-right: 0.5em
/*

View file

@ -76,11 +76,11 @@
margin: 0
padding: 0
display: flex
justify-content: center
align-content: flex-end
flex-wrap: wrap
margin: 0 -0.5em 0 -0.5em
li
flex-grow: 1
width: 20em
margin: 0 0.5em 1em 0.5em
padding: 0.75em

View file

@ -1,4 +1,5 @@
<div class='pager'>
<div class='page-header-holder'></div>
<div class='messages'></div>
<div class='page-content-holder'></div>
<div class='page-nav'></div>

View file

@ -0,0 +1,14 @@
<div class='user-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'/>
</div>
</form>
</div>

View file

@ -10,14 +10,16 @@ const topNavController = require('../controllers/top_nav_controller.js');
const pageController = require('../controllers/page_controller.js');
const RegistrationView = require('../views/registration_view.js');
const UserView = require('../views/user_view.js');
const UserListView = require('../views/user_list_view.js');
const UserListHeaderView = require('../views/user_list_header_view.js');
const UserListPageView = require('../views/user_list_page_view.js');
const EmptyView = require('../views/empty_view.js');
class UsersController {
constructor() {
this.registrationView = new RegistrationView();
this.userView = new UserView();
this.userListView = new UserListView();
this.userListHeaderView = new UserListHeaderView();
this.userListPageView = new UserListPageView();
this.emptyView = new EmptyView();
}
@ -62,8 +64,9 @@ class UsersController {
},
clientUrl: '/users/' + misc.formatSearchQuery({
text: ctx.searchQuery.text, page: '{page}'}),
initialPage: ctx.searchQuery.page,
pageRenderer: this.userListView,
searchQuery: ctx.searchQuery,
headerRenderer: this.userListHeaderView,
pageRenderer: this.userListPageView,
});
}

View file

@ -4,6 +4,17 @@ const views = require('../util/views.js');
const handlebars = require('handlebars');
const misc = require('./misc.js');
function makeLabel(options, attrs) {
if (!options.hash.text) {
return '';
}
if (!attrs) {
attrs = {};
}
attrs.for = options.hash.id;
return views.makeNonVoidElement('label', attrs, options.hash.text);
}
handlebars.registerHelper('reltime', function(time) {
return new handlebars.SafeString(
views.makeNonVoidElement(
@ -34,10 +45,7 @@ handlebars.registerHelper('radio', function(options) {
checked: options.hash.selectedValue === options.hash.value,
required: options.hash.required,
}),
views.makeNonVoidElement('label', {
for: options.hash.id,
class: 'radio',
}, options.hash.text)));
makeLabel(options, {class: 'radio'})));
});
handlebars.registerHelper('checkbox', function(options) {
@ -51,16 +59,12 @@ handlebars.registerHelper('checkbox', function(options) {
options.hash.checked : false,
required: options.hash.required,
}),
views.makeNonVoidElement('label', {
for: options.hash.id,
class: 'checkbox',
}, options.hash.text)));
makeLabel(options, {class: 'checkbox'})));
});
handlebars.registerHelper('select', function(options) {
return new handlebars.SafeString('{0}{1}'.format(
views.makeNonVoidElement(
'label', {for: options.hash.id}, options.hash.text),
makeLabel(options),
views.makeNonVoidElement(
'select',
{id: options.hash.id, name: options.hash.name},
@ -74,8 +78,7 @@ handlebars.registerHelper('select', function(options) {
handlebars.registerHelper('input', function(options) {
return new handlebars.SafeString('{0}{1}'.format(
views.makeNonVoidElement(
'label', {for: options.hash.id}, options.hash.text),
makeLabel(options),
views.makeVoidElement(
'input', {
type: options.hash.inputType,

View file

@ -2,7 +2,6 @@
const page = require('page');
const events = require('../events.js');
const misc = require('../util/misc.js');
const views = require('../util/views.js');
class EndlessPageView {
@ -85,7 +84,7 @@ class EndlessPageView {
pagesHolder.innerHTML = ctx.state.html;
window.scroll(ctx.state.scrollX, ctx.state.scrollY);
} else {
this.loadPage(pagesHolder, ctx, ctx.initialPage, true);
this.loadPage(pagesHolder, ctx, ctx.searchQuery.page, true);
}
window.addEventListener('scroll', this.updater, true);
}

View file

@ -20,8 +20,13 @@ class ManualPageView {
const target = document.getElementById('content-holder');
const source = this.holderTemplate();
const pageContentHolder = source.querySelector('.page-content-holder');
const pageHeaderHolder = source.querySelector('.page-header-holder');
const pageNav = source.querySelector('.page-nav');
const currentPage = ctx.initialPage;
const currentPage = ctx.searchQuery.page;
let headerRendererCtx = ctx;
headerRendererCtx.target = pageHeaderHolder;
ctx.headerRenderer.render(headerRendererCtx);
ctx.requestPage(currentPage).then(response => {
let pageRendererCtx = response;

View file

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

View file

@ -2,17 +2,16 @@
const views = require('../util/views.js');
class UserListView {
class UserListPageView {
constructor() {
this.template = views.getTemplate('user-list');
this.template = views.getTemplate('user-list-page');
}
render(ctx) {
const target = ctx.target;
const source = this.template(ctx);
views.listenToMessages(target);
views.showView(target, source);
}
}
module.exports = UserListView;
module.exports = UserListPageView;