From 606afb279d9519acdf855a457af79f5e7cf908fa Mon Sep 17 00:00:00 2001 From: Meutel Date: Sun, 6 Aug 2017 17:18:27 +0200 Subject: [PATCH] Factorize JS --- assets/js/bouquins.js | 252 +++++++++++++++++------------------------- 1 file changed, 100 insertions(+), 152 deletions(-) diff --git a/assets/js/bouquins.js b/assets/js/bouquins.js index 7a32933..6d89b5a 100644 --- a/assets/js/bouquins.js +++ b/assets/js/bouquins.js @@ -1,51 +1,90 @@ var bus = new Vue(); +// COMMONS // + +var BOOKS = 'books', AUTHORS = 'authors', SERIES = 'series'; +var BOUQUINS_TYPES = { + books: { icon: 'book', singular: 'livre', plural: 'livres', + tab_cols: [ { id: 'title', name: 'Titre', sort: 'title' }, + { id: 'authors', name: 'Auteur(s)' }, + { id: 'series', name: 'Serie' } ] }, + authors: { icon: 'user', singular: 'auteur', plural: 'auteurs', + tab_cols: [ { id: 'author_name', name: 'Nom', sort: 'name' }, + { id: 'count', name: 'Livre(s)' } ] }, + series: { icon: 'list', singular: 'serie', plural: 'series', + tab_cols: [ { id: 'serie_name', name: 'Nom', sort: 'name' }, + { id: 'count', name: 'Livre(s)' }, + { id: 'authors', name: 'Auteur(s)' } ] } +}; +function ty(type) { + if (BOUQUINS_TYPES[type]) return BOUQUINS_TYPES[type] + console.log("ERROR: Unknown type: " + type); + return {} +} +function icon(type) { + return ty(type).icon; +} +function iconClass(type) { + return 'glyphicon glyphicon-' + icon(type); +} +function url(type, id) { + if (id) return ty(type) ? '/'+type+'/'+id:''; + return ty(type) ? '/'+type+'/':''; +} +function label(type, count) { + return count == 1 ? ty(type).singular : ty(type).plural; +} +function stdError(code, resp) { + console.log('ERROR ' + code + ': ' + resp); +} +function sendQuery(url, error, success) { + var xmh = new XMLHttpRequest(); + var v; + xmh.onreadystatechange = function() { + v = xmh.responseText; + if (xmh.readyState === 4 && xmh.status === 200) { + var res; + try { + res = JSON.parse(v); + } catch (err) { + if (null !== error) + error(err.name, err.message); + } + if (null !== success) + success(res); + } else if (xmh.readyState === 4) { + if (null !== error) + error(xmh.status, v); + } + }; + xmh.open('GET', url, true); + xmh.setRequestHeader('Accept','application/json'); + xmh.send(null); +} + // COMPONENTS // Vue.component('results-list', { template: '#results-list-template', props: ['results', 'count', 'type'], methods: { - url: function(item) { - return '/'+this.type+'/'+item.id; - }, + url: function(item) { return url(this.type, item.id); }, label: function(item) { switch (this.type) { - case 'books': + case BOOKS: return item.title; - case 'authors': - case 'series': + case AUTHORS: + case SERIES: return item.name; default: return ''; } }, iconClass: function() { - return 'glyphicon glyphicon-' + this.icon(); - }, - icon: function() { - switch (this.type) { - case 'books': - return 'book'; - case 'authors': - return 'user'; - case 'series': - return 'list'; - default: - return ''; - } + return iconClass(this.type); }, countlabel: function() { - switch (this.type) { - case 'books': - return this.count > 1 ? 'livres' : 'livre'; - case 'authors': - return this.count > 1 ? 'auteurs' : 'auteur'; - case 'series': - return this.count > 1 ? 'series' : 'serie'; - default: - return ''; - } + return label(this.type, this.count); } } }); @@ -64,20 +103,11 @@ Vue.component('result-cell', { }, props: ['item', 'col'], methods: { - bookUrl: function(id) { - return '/books/' + id; - }, - authorUrl: function(id) { - return '/authors/' + id; - }, - seriesUrl: function(id) { - return '/series/' + id; - }, - link: function(h, icon, text, url) { + link: function(h, type, text, id) { return [ - h('span',{ attrs: { class: 'glyphicon glyphicon-'+icon } },''), + h('span',{ attrs: { class: iconClass(type) } },''), ' ', - h('a', { attrs: { href: url } }, text) + h('a', { attrs: { href: url(type, id) } }, text) ]; }, badge: function(h, num) { @@ -86,19 +116,19 @@ Vue.component('result-cell', { cellContent: function(h) { switch (this.col.id) { case 'author_name': - return this.link(h, 'user', this.item.name, this.authorUrl(this.item.id)); + return this.link(h, AUTHORS, this.item.name, this.item.id); case 'serie_name': - return this.link(h, 'list', this.item.name, this.authorUrl(this.item.id)); + return this.link(h, SERIES, this.item.name, this.item.id); case 'count': return this.item.count; case 'title': - return this.link(h, 'book', this.item.title, this.bookUrl(this.item.id)); + return this.link(h, BOOKS, this.item.title, this.item.id); case 'authors': var elts = []; var authors = this.item.authors; if (authors) { for (i=0;i