import Component from 'flarum/Component'; import Alert from 'flarum/components/Alert'; import Button from 'flarum/components/Button'; /** * The `Modal` component displays a modal dialog, wrapped in a form. Subclasses * should implement the `className`, `title`, and `content` methods. * * @abstract */ export default class Modal extends Component { constructor(...args) { super(...args); /** * An alert component to show below the header. * * @type {Alert} */ this.alert = null; } view() { if (this.alert) { this.alert.props.dismissible = false; } return ( <div className={'Modal modal-dialog ' + this.className()}> <div className="Modal-content"> <div className="Modal-close App-backControl"> {Button.component({ icon: 'times', onclick: this.hide.bind(this), className: 'Button Button--icon Button--link' })} </div> <form onsubmit={this.onsubmit.bind(this)}> <div className="Modal-header"> <h3 className="App-titleControl App-titleControl--text">{this.title()}</h3> </div> {alert ? <div className="Modal-alert">{this.alert}</div> : ''} {this.content()} </form> </div> </div> ); } /** * Get the class name to apply to the modal. * * @return {String} * @abstract */ className() { } /** * Get the title of the modal dialog. * * @return {String} * @abstract */ title() { } /** * Get the content of the modal. * * @return {VirtualElement} * @abstract */ content() { } /** * Handle the modal form's submit event. * * @param {Event} e */ onsubmit() { } /** * Focus on the first input when the modal is ready to be used. */ onready() { this.$('form :input:first').select(); } /** * Hide the modal. */ hide() { app.modal.close(); } /** * Show an alert describing errors returned from the API, and give focus to * the first relevant field. * * @param {Object} response */ handleErrors(response) { const errors = response && response.errors; if (errors) { this.alert(new Alert({ type: 'warning', message: errors.map((error, k) => [error.detail, k < errors.length - 1 ? m('br') : '']) })); } m.redraw(); if (errors) { this.$('form [name=' + errors[0].path + ']').select(); } else { this.$('form :input:first').select(); } } }