Skip to content
Snippets Groups Projects
Commit ed12dafb authored by Hermann's avatar Hermann
Browse files

add 'Create new User' modal

parent 9e296cf3
No related branches found
No related tags found
No related merge requests found
import { LoginScreen } from './login'; import { LoginScreen } from './login';
import TableView from './views/tableView'; import TableView from './views/tableView';
import { UserModal, UserTable } from './userTool'; import { UserModal, UserTable, NewUser } from './userTool';
import Sidebar from './sidebar'; import Sidebar from './sidebar';
const m = require('mithril'); const m = require('mithril');
...@@ -31,6 +31,7 @@ function layoutWith(view) { ...@@ -31,6 +31,7 @@ function layoutWith(view) {
m.route(root, '/users', { m.route(root, '/users', {
'/users': layoutWith(UserTable), '/users': layoutWith(UserTable),
'/users/:id': layoutWith(UserModal), '/users/:id': layoutWith(UserModal),
'/newusers': layoutWith(NewUser),
'/events': layoutWith({ '/events': layoutWith({
view() { view() {
return m(TableView, { return m(TableView, {
......
...@@ -73,19 +73,7 @@ class UserEdit extends EditView { ...@@ -73,19 +73,7 @@ class UserEdit extends EditView {
super(vnode, 'users'); super(vnode, 'users');
} }
view() { getForm() {
// 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', [ return m('form', [
m('div.row', [ m('div.row', [
m(inputGroup, this.bind({ m(inputGroup, this.bind({
...@@ -109,12 +97,59 @@ class UserEdit extends EditView { ...@@ -109,12 +97,59 @@ class UserEdit extends EditView {
})), })),
]), ]),
m('span', JSON.stringify(this.data)), 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, 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 { export class UserModal {
constructor() { constructor() {
this.edit = false; this.edit = false;
......
...@@ -16,7 +16,11 @@ export class EditView extends ItemView { ...@@ -16,7 +16,11 @@ export class EditView extends ItemView {
// state for validation // state for validation
this.valid = valid; this.valid = valid;
this.ajv = new Ajv({ missingRefs: 'ignore' }); this.ajv = new Ajv({
missingRefs: 'ignore',
errorDataPath: 'property',
allErrors: true,
});
this.errors = {}; this.errors = {};
// callback when edit is finished // callback when edit is finished
...@@ -24,12 +28,14 @@ export class EditView extends ItemView { ...@@ -24,12 +28,14 @@ export class EditView extends ItemView {
} }
oninit() { oninit() {
// load data for item if (this.id) {
getSession().then((apiSession) => { // load data for item
this.loadItemData(apiSession); getSession().then((apiSession) => {
}).catch(() => { this.loadItemData(apiSession);
m.route.set('/login'); }).catch(() => {
}); m.route.set('/login');
});
}
// load schema // load schema
m.request('http://amiv-api.ethz.ch/docs/api-docs').then((schema) => { m.request('http://amiv-api.ethz.ch/docs/api-docs').then((schema) => {
const objectSchema = schema.definitions[ const objectSchema = schema.definitions[
...@@ -52,15 +58,21 @@ export class EditView extends ItemView { ...@@ -52,15 +58,21 @@ export class EditView extends ItemView {
// validate against schema // validate against schema
const validate = this.ajv.getSchema('schema'); const validate = this.ajv.getSchema('schema');
this.valid = validate(this.data); this.valid = validate(this.data);
console.log(validate.schema);
// get errors of this field console.log(validate.errors);
let errors = []; if (this.valid) {
if (!this.valid) { Object.keys(this.errors).forEach((field) => {
errors = validate.errors.filter(error => this.errors[field] = [];
`.${e.target.name}` === error.dataPath); });
errors = errors.map(error => error.message); } 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], getErrors: () => this.errors[attrs.name],
value: this.data[attrs.name], value: this.data[attrs.name],
...@@ -71,7 +83,7 @@ export class EditView extends ItemView { ...@@ -71,7 +83,7 @@ export class EditView extends ItemView {
return boundFormelement; return boundFormelement;
} }
patchOnClick(patchableFields) { patchOnClick(patchableFields, callback) {
return { return {
onclick: () => { onclick: () => {
if (this.changed) { if (this.changed) {
...@@ -85,14 +97,32 @@ export class EditView extends ItemView { ...@@ -85,14 +97,32 @@ export class EditView extends ItemView {
apiSession.patch(`${this.resource}/${this.id}`, patchData, { apiSession.patch(`${this.resource}/${this.id}`, patchData, {
headers: { 'If-Match': this.data._etag }, headers: { 'If-Match': this.data._etag },
}).then(() => { this.callback(); }); }).then(() => { callback(); });
}); });
} else { } 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 { export class inputGroup {
...@@ -107,11 +137,12 @@ export class inputGroup { ...@@ -107,11 +137,12 @@ export class inputGroup {
view(vnode) { view(vnode) {
// set display-settings accoridng to error-state // set display-settings accoridng to error-state
let errorField = null; 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(); const errors = this.getErrors();
if (errors.length > 0) { if (errors.length > 0) {
errorField = m('span.help-block', `Error: ${errors.join(', ')}`); errorField = m('span.help-block', `Error: ${errors.join(', ')}`);
groupClasses.push('has-error'); groupClasses += ' has-error';
} }
return m('div.form-group', { class: groupClasses }, [ return m('div.form-group', { class: groupClasses }, [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment