Something went wrong on our end
editView.js 3.71 KiB
import m from 'mithril';
import { IconButton, Toolbar, ToolbarTitle, Button } from 'polythene-mithril';
import { Form } from 'amiv-web-ui-components';
// eslint-disable-next-line import/extensions
import { apiUrl } from 'networkConfig';
import ItemView from './itemView';
import { icons } from './elements';
import { colors } from '../style';
// Mapper for resource vs schema-object names
const objectNameForResource = {
users: 'User',
groupmembershipds: 'Groupmembership',
groups: 'Group',
eventsignups: 'Eventsignup',
events: 'Event',
};
export default class EditView extends ItemView {
/**
* Extension of ItemView to edit a data item
*
* Requires:
* - call constructor with vnode, resource, (valid, false by default)
* - vnode.attrs.onfinish has to be a callback function that is called after
* the edit is finished
* @param {object} vnode [as provided by mithril]
* @param {string} resource [the API resource of this view, e.g. 'events']
* @param {object} embedded [any embedding query that should be added
* to API requests for this resource]
*/
constructor(vnode,) {
super(vnode);
// the form is valid in case that the item controller is in edit mode
const validInitially = this.controller.modus === 'edit';
// start a form to collect the submit data
this.form = new Form({}, validInitially, Object.assign({}, this.controller.data));
}
oninit() {
// load schema
m.request(`${apiUrl}/docs/api-docs`).then((schema) => {
this.form.setSchema(schema.definitions[objectNameForResource[this.resource]]);
}).catch((error) => { console.log(error); });
}
/**
* Submit the changed version of this.data
*
* @param {Boolean} true if the data should be send as FormData instead of
* JSON. Necessary in cases where files are included in the
* changes.
*/
submit(formData = false) {
if (Object.keys(this.form.data).length > 0) {
let request;
if (this.controller.modus === 'edit') {
// if id is known, this is a patch to an existing item
request = this.controller.patch(this.form.data, formData);
} else {
request = this.controller.post(this.form.data);
}
request.catch((error) => {
console.log(error);
// Process the API error
if ('_issues' in error) {
// there are problems with some fields, display them
Object.keys(error._issues).forEach((field) => {
this.form.errors[field] = [error._issues[field]];
this.form.valid = false;
});
console.log(this.form.errors);
m.redraw();
} else {
console.log(error);
}
});
} else {
this.controller.changeModus('view');
}
}
beforeSubmit() {
this.submit();
}
layout(children, buttonLabel = 'submit') {
return m('div', { style: { 'background-color': 'white' } }, [
m(Toolbar, { style: { 'background-color': colors.orange } }, [
m(IconButton, {
icon: { svg: { content: m.trust(icons.clear) } },
events: { onclick: () => { this.controller.cancel(); } },
}),
m(ToolbarTitle, `${((this.controller.modus === 'new') ? 'New' : 'Edit')}` +
` ${this.resource.charAt(0).toUpperCase()}${this.resource.slice(1, -1)}`),
m(Button, {
className: 'blue-button-filled',
extraWide: true,
label: buttonLabel,
disabled: !this.form.valid,
events: { onclick: () => { this.beforeSubmit(); } },
}),
]),
m('div.maincontainer', {
style: { height: 'calc(100vh - 130px)', 'overflow-y': 'scroll', padding: '10px' },
}, children),
]);
}
}