From ed12dafbba3441203ff409fd847fa2358d1d62e3 Mon Sep 17 00:00:00 2001 From: Hermann Blum <hermannsblum@yahoo.de> Date: Fri, 1 Dec 2017 16:31:39 +0100 Subject: [PATCH] add 'Create new User' modal --- src/index.js | 3 +- src/userTool.js | 63 ++++++++++++++++++++++++++++++--------- src/views/editView.js | 69 +++++++++++++++++++++++++++++++------------ 3 files changed, 101 insertions(+), 34 deletions(-) diff --git a/src/index.js b/src/index.js index ce76ae1..e3c3fee 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ import { LoginScreen } from './login'; import TableView from './views/tableView'; -import { UserModal, UserTable } from './userTool'; +import { UserModal, UserTable, NewUser } from './userTool'; import Sidebar from './sidebar'; const m = require('mithril'); @@ -31,6 +31,7 @@ function layoutWith(view) { m.route(root, '/users', { '/users': layoutWith(UserTable), '/users/:id': layoutWith(UserModal), + '/newusers': layoutWith(NewUser), '/events': layoutWith({ view() { return m(TableView, { diff --git a/src/userTool.js b/src/userTool.js index df07a7e..64a5eb0 100644 --- a/src/userTool.js +++ b/src/userTool.js @@ -73,19 +73,7 @@ class UserEdit extends EditView { super(vnode, 'users'); } - view() { - // do not render anything if there is no data yet - if (!this.data) return m.trust(''); - - // UPDATE button is inactive if form is not valid - const buttonArgs = this.patchOnClick([ - 'lastname', 'firstname', 'email', 'membership', 'gender']); - const updateButton = m( - 'div.btn.btn-warning', - this.valid ? buttonArgs : { disabled: 'disabled' }, - 'Update', - ); - + getForm() { return m('form', [ m('div.row', [ m(inputGroup, this.bind({ @@ -109,12 +97,59 @@ class UserEdit extends EditView { })), ]), m('span', JSON.stringify(this.data)), - m('span', JSON.stringify(this.errorLists)), + m('span', JSON.stringify(this.errors)), + ]); + } + + view() { + // do not render anything if there is no data yet + if (!this.data) return m.trust(''); + + // UPDATE button is inactive if form is not valid + const buttonArgs = this.patchOnClick([ + 'lastname', 'firstname', 'email', 'membership', 'gender']); + const updateButton = m( + 'div.btn.btn-warning', + this.valid ? buttonArgs : { disabled: 'disabled' }, + 'Update', + ); + + return m('form', [ + this.getForm(), updateButton, ]); } } +export class NewUser extends UserEdit { + constructor(vnode) { + super(vnode); + this.data = { + gender: 'male', + membership: 'regular', + }; + this.valid = false; + } + + view() { + // UPDATE button is inactive if form is not valid + const buttonArgs = this.createOnClick( + ['lastname', 'firstname', 'email', 'membership', 'gender'], + (response) => { m.route.set(`/users/${response.data._id}`); }, + ); + const postButton = m( + 'div.btn.btn-warning', + this.valid ? buttonArgs : { disabled: 'disabled' }, + 'Create', + ); + + return m('form', [ + this.getForm(), + postButton, + ]); + } +} + export class UserModal { constructor() { this.edit = false; diff --git a/src/views/editView.js b/src/views/editView.js index 46d07d7..61805ac 100644 --- a/src/views/editView.js +++ b/src/views/editView.js @@ -16,7 +16,11 @@ export class EditView extends ItemView { // state for validation this.valid = valid; - this.ajv = new Ajv({ missingRefs: 'ignore' }); + this.ajv = new Ajv({ + missingRefs: 'ignore', + errorDataPath: 'property', + allErrors: true, + }); this.errors = {}; // callback when edit is finished @@ -24,12 +28,14 @@ export class EditView extends ItemView { } oninit() { - // load data for item - getSession().then((apiSession) => { - this.loadItemData(apiSession); - }).catch(() => { - m.route.set('/login'); - }); + if (this.id) { + // load data for item + getSession().then((apiSession) => { + this.loadItemData(apiSession); + }).catch(() => { + m.route.set('/login'); + }); + } // load schema m.request('http://amiv-api.ethz.ch/docs/api-docs').then((schema) => { const objectSchema = schema.definitions[ @@ -52,15 +58,21 @@ export class EditView extends ItemView { // validate against schema const validate = this.ajv.getSchema('schema'); this.valid = validate(this.data); + console.log(validate.schema); - // get errors of this field - let errors = []; - if (!this.valid) { - errors = validate.errors.filter(error => - `.${e.target.name}` === error.dataPath); - errors = errors.map(error => error.message); + console.log(validate.errors); + if (this.valid) { + Object.keys(this.errors).forEach((field) => { + this.errors[field] = []; + }); + } else { + // get errors for respective fields + Object.keys(this.errors).forEach((field) => { + const errors = validate.errors.filter(error => + `.${field}` === error.dataPath); + this.errors[field] = errors.map(error => error.message); + }); } - this.errors[e.target.name] = errors; }, getErrors: () => this.errors[attrs.name], value: this.data[attrs.name], @@ -71,7 +83,7 @@ export class EditView extends ItemView { return boundFormelement; } - patchOnClick(patchableFields) { + patchOnClick(patchableFields, callback) { return { onclick: () => { if (this.changed) { @@ -85,14 +97,32 @@ export class EditView extends ItemView { apiSession.patch(`${this.resource}/${this.id}`, patchData, { headers: { 'If-Match': this.data._etag }, - }).then(() => { this.callback(); }); + }).then(() => { callback(); }); }); } else { - this.callback(); + callback(); } }, }; } + + createOnClick(fields, callback) { + return { + onclick: () => { + getSession().then((apiSession) => { + // fields like `_id` are not patchable and would lead to an error + // We therefore only send patchable fields + const postData = {}; + fields.forEach((key) => { + postData[key] = this.data[key]; + }); + + apiSession.post(this.resource, postData) + .then(response => { callback(response); }); + }); + }, + }; + } } export class inputGroup { @@ -107,11 +137,12 @@ export class inputGroup { view(vnode) { // set display-settings accoridng to error-state let errorField = null; - const groupClasses = vnode.attrs.classes ? vnode.attrs.classes : []; + let groupClasses = vnode.attrs.classes ? vnode.attrs.classes : ''; + console.log(groupClasses) const errors = this.getErrors(); if (errors.length > 0) { errorField = m('span.help-block', `Error: ${errors.join(', ')}`); - groupClasses.push('has-error'); + groupClasses += ' has-error'; } return m('div.form-group', { class: groupClasses }, [ -- GitLab