OpenDroneMap-WebODM/app/static/app/js/components/FormDialog.jsx

198 wiersze
6.6 KiB
JavaScript

import React from 'react';
import ErrorMessage from './ErrorMessage';
import '../css/FormDialog.scss';
import PropTypes from 'prop-types';
import $ from 'jquery';
import { _ } from '../classes/gettext';
class FormDialog extends React.Component {
static defaultProps = {
title: _("Title"),
saveLabel: _("Save"),
savingLabel: _("Saving…"),
saveIcon: "glyphicon glyphicon-plus",
deleteWarning: _("Are you sure?"),
show: false
};
static propTypes = {
getFormData: PropTypes.func.isRequired,
reset: PropTypes.func,
saveAction: PropTypes.func.isRequired,
onShow: PropTypes.func,
onHide: PropTypes.func,
deleteAction: PropTypes.func,
title: PropTypes.string,
saveLabel: PropTypes.string,
savingLabel: PropTypes.string,
saveIcon: PropTypes.string,
deleteWarning: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool
]),
show: PropTypes.bool
};
constructor(props){
super(props);
this.state = {
showModal: props.show,
saving: false,
deleting: false,
error: ""
};
this.setModal = this.setModal.bind(this);
this.show = this.show.bind(this);
this.hide = this.hide.bind(this);
this.handleSave = this.handleSave.bind(this);
this.handleDelete = this.handleDelete.bind(this);
}
setModal(domNode){
this.modal = domNode;
}
componentDidMount(){
this._mounted = true;
$(this.modal)
// Ensure state is kept up to date when
// the user presses the escape key
.on('hidden.bs.modal', (e) => {
this.hide();
})
// Autofocus
.on('shown.bs.modal', (e) => {
if (this.props.onShow) this.props.onShow();
});
this.componentDidUpdate();
}
componentWillUnmount(){
this._mounted = false;
$(this.modal).off('hidden.bs.modal hidden.bs.modal')
.modal('hide');
}
componentDidUpdate(){
if (this.state.showModal){
$(this.modal).modal('show');
}else{
$(this.modal).modal('hide');
}
}
show(){
if (this.props.reset) this.props.reset();
this.setState({showModal: true, saving: false, error: ""});
}
hide(){
this.setState({showModal: false});
if (this.props.onHide) this.props.onHide();
if (this.serverRequest){
this.serverRequest.abort();
this.serverRequest = null;
}
}
handleSave(e){
e.preventDefault();
this.setState({saving: true});
let formData = {};
if (this.props.getFormData) formData = this.props.getFormData();
this.serverRequest = this.props.saveAction(formData);
if (this.serverRequest){
this.serverRequest.fail(e => {
this.setState({error: e.message || (e.responseJSON || {}).detail || e.responseText || _("Could not apply changes")});
}).always(() => {
this.setState({saving: false});
this.serverRequest = null;
}).done(() => {
this.hide();
});
}else{
this.setState({saving: false});
this.hide();
}
}
handleDelete(){
if (this.props.deleteAction){
if (this.props.deleteWarning === false || window.confirm(this.props.deleteWarning)){
this.setState({deleting: true});
this.props.deleteAction()
.fail(e => {
if (this._mounted) this.setState({error: e.message || (e.responseJSON || {}).detail || e.responseText || _("Could not delete item")});
}).always(() => {
if (this._mounted) this.setState({deleting: false});
});
}
}
}
render(){
return (
<div ref={this.setModal}
className="modal form-dialog" tabIndex="-1"
data-backdrop="static"
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" onClick={this.hide}><span>&times;</span></button>
<h4 className="modal-title">{this.props.title}</h4>
</div>
<div className="modal-body">
<ErrorMessage bind={[this, "error"]} />
<div className="form-horizontal" onSubmit={this.handleSave}>
{this.props.children}
</div>
</div>
<div className="modal-footer">
<div className="pull-right">
<button type="button" className="btn btn-default" onClick={this.hide} disabled={this.state.saving}>{_("Cancel")}</button>
<button type="button" className="btn btn-primary save" onClick={this.handleSave} disabled={this.state.saving}>
{this.state.saving ?
<span>
<i className="fa fa-circle-notch fa-spin"></i> {this.props.savingLabel}
</span>
: <span>
<i className={this.props.saveIcon}></i> {this.props.saveLabel}
</span>}
</button>
</div>
{this.props.deleteAction ?
<div className="text-left">
<button
disabled={this.state.deleting}
className="btn btn-danger"
onClick={this.handleDelete}>
{this.state.deleting ?
<span>
<i className="fa fa-circle-notch fa-spin"></i> {_("Deleting...")}
</span>
: <span>
<i className="glyphicon glyphicon-trash"></i> {_("Delete")}
</span>}
</button>
</div>
: ""}
</div>
</div>
</div>
</div>
);
}
}
export default FormDialog;