kopia lustrzana https://github.com/OpenDroneMap/WebODM
198 wiersze
6.6 KiB
JavaScript
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>×</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;
|