@bigfishtv/cockpit
Version:
235 lines (206 loc) • 7.4 kB
JavaScript
var _class, _temp;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { createValue, Fieldset } from '@bigfishtv/react-forms';
import { post, get } from '../../api/xhrUtils';
import { renderComponent } from '../../utils/componentUtils';
import { validationErrors } from 'react-forms-cakephp';
var Form = (_temp = _class = function (_Component) {
_inherits(Form, _Component);
function Form(props) {
_classCallCheck(this, Form);
var _this = _possibleConstructorReturn(this, _Component.call(this, props));
_this.confirmUnload = function (e) {
if (!_this.shouldBlockNavigation()) return;(e || window.event).returnValue = _this.props.confirmMessage; //Gecko + IE
return _this.props.confirmMessage;
};
_this.onChange = function (nextFormValue) {
if (_this.props.onBeforeChange) {
nextFormValue = _this.props.onBeforeChange(nextFormValue);
if (nextFormValue === false) {
return;
}
}
_this.setState({
dirty: true,
formValue: nextFormValue,
submitStatus: _this.state.submitStatus != 'busy' ? 'ready' : 'busy'
});
_this.props.onChange && _this.props.onChange(nextFormValue.value);
};
_this.handleSubmit = function (event) {
event.preventDefault();
if (_this.state.submitStatus == 'busy') return;
if (_this.props.onBeforeSubmit && _this.props.onBeforeSubmit(_this.state.formValue.value) === false) {
return;
}
_this.setState({
submitStatus: 'busy'
}, function () {
post({
quiet: true,
url: _this.getSubmitUrl(),
data: _this.state.formValue.value,
callback: function callback(data, response) {
_this.onChange(createValue({
schema: _this.props.schema,
value: data,
onChange: _this.onChange
}));
_this.setState({ submitStatus: 'success', dirty: false });
_this.props.onSubmitSuccess && _this.props.onSubmitSuccess(data, response);
},
callbackError: function callbackError(response) {
if (response.data && response.data.data && response.data.data.errors) {
_this.onChange(createValue({
schema: _this.props.schema,
value: _this.state.formValue.value,
onChange: _this.onChange,
params: { forceShowErrors: true },
errorList: validationErrors(response.data.data.errors)
}));
}
_this.props.onSubmitError && _this.props.onSubmitError(response);
_this.setState({ submitStatus: 'failed' });
}
});
});
};
_this.state = {
data: {},
loading: !!props.dataUrl,
formValue: createValue({
schema: props.schema,
value: props.value || props.defaultValue,
onChange: _this.onChange
}),
dirty: false,
submitStatus: 'ready'
};
if (props.dataUrl) {
_this.loadData(props.dataUrl);
}
return _this;
}
Form.prototype.loadData = function loadData(url) {
var _this2 = this;
get({
url: url,
callback: function callback(data, responseData) {
_this2.setState({
data: responseData,
loading: false,
formValue: createValue({
schema: _this2.props.schema,
value: _this2.props.valueMapper(responseData),
onChange: _this2.onChange
})
});
_this2.props.onLoad && _this2.props.onLoad(_this2.props.valueMapper(responseData), responseData);
}
});
};
Form.prototype.componentDidMount = function componentDidMount() {
window.addEventListener('beforeunload', this.confirmUnload);
};
Form.prototype.componentWillUnmount = function componentWillUnmount() {
window.removeEventListener('beforeunload', this.confirmUnload);
this.unblock && this.unblock();
};
Form.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
if (nextProps.value !== this.props.value) {
this.setState({
dirty: false,
formValue: createValue({
schema: nextProps.schema,
value: nextProps.value,
onChange: this.onChange
})
});
}
if (nextProps.dataUrl && nextProps.dataUrl !== this.props.dataUrl) {
this.loadData(nextProps.dataUrl);
}
};
Form.prototype.componentDidUpdate = function componentDidUpdate() {
this.reactRouterConfirmUnload();
};
Form.prototype.reactRouterConfirmUnload = function reactRouterConfirmUnload() {
// compatibility with react router v4
if (this.context && this.context.router) {
var shouldBlock = this.shouldBlockNavigation();
if (shouldBlock && !this.unblock) {
this.unblock = this.context.router.history.block(this.props.confirmMessage);
} else if (!shouldBlock && this.unblock) {
this.unblock();
this.unblock = null;
}
}
};
Form.prototype.shouldBlockNavigation = function shouldBlockNavigation() {
return this.props.confirmDirty && this.state.dirty && !window.dontPromptChanges;
};
Form.prototype.getSubmitUrl = function getSubmitUrl() {
if (typeof this.props.submitUrl == 'function') {
return this.props.submitUrl(this.state.formValue.value);
} else {
return this.props.submitUrl;
}
};
Form.prototype.render = function render() {
var render = this.props.render;
var formProps = {
// className,
stylesheet: { Root: 'form' },
formValue: this.state.formValue,
onSubmit: this.handleSubmit
};
var childProps = {
data: this.state.data,
loading: this.state.loading,
dirty: this.state.dirty,
submitStatus: this.state.submitStatus,
// also send these to child props?
formValue: this.state.formValue,
onSubmit: this.handleSubmit
};
return React.createElement(
Fieldset,
formProps,
renderComponent(render, childProps) || this.props.children
);
};
return Form;
}(Component), _class.propTypes = {
dataUrl: PropTypes.string,
defaultValue: PropTypes.object,
value: PropTypes.object,
schema: PropTypes.object,
submitUrl: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
onLoad: PropTypes.func,
onBeforeChange: PropTypes.func,
onChange: PropTypes.func,
onBeforeSubmit: PropTypes.func,
onSubmitSuccess: PropTypes.func,
onSubmitError: PropTypes.func,
confirmDirty: PropTypes.bool,
confirmMessage: PropTypes.string,
valueMapper: PropTypes.func,
render: PropTypes.func
}, _class.defaultProps = {
confirmDirty: true,
valueMapper: function valueMapper(data) {
return data.data || data;
},
confirmMessage: 'You have unsaved changes! If you leave this page, your changes will be lost!'
}, _class.contextTypes = {
router: PropTypes.shape({
history: PropTypes.shape({
block: PropTypes.func
})
})
}, _temp);
export { Form as default };