@bigfishtv/cockpit
Version:
250 lines (212 loc) • 8.04 kB
JavaScript
'use strict';
exports.__esModule = true;
exports.default = undefined;
var _class, _temp;
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactForms = require('@bigfishtv/react-forms');
var _xhrUtils = require('../../api/xhrUtils');
var _componentUtils = require('../../utils/componentUtils');
var _reactFormsCakephp = require('react-forms-cakephp');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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; }
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 () {
(0, _xhrUtils.post)({
quiet: true,
url: _this.getSubmitUrl(),
data: _this.state.formValue.value,
callback: function callback(data, response) {
_this.onChange((0, _reactForms.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((0, _reactForms.createValue)({
schema: _this.props.schema,
value: _this.state.formValue.value,
onChange: _this.onChange,
params: { forceShowErrors: true },
errorList: (0, _reactFormsCakephp.validationErrors)(response.data.data.errors)
}));
}
_this.props.onSubmitError && _this.props.onSubmitError(response);
_this.setState({ submitStatus: 'failed' });
}
});
});
};
_this.state = {
data: {},
loading: !!props.dataUrl,
formValue: (0, _reactForms.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;
(0, _xhrUtils.get)({
url: url,
callback: function callback(data, responseData) {
_this2.setState({
data: responseData,
loading: false,
formValue: (0, _reactForms.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: (0, _reactForms.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 _react2.default.createElement(
_reactForms.Fieldset,
formProps,
(0, _componentUtils.renderComponent)(render, childProps) || this.props.children
);
};
return Form;
}(_react.Component), _class.propTypes = {
dataUrl: _propTypes2.default.string,
defaultValue: _propTypes2.default.object,
value: _propTypes2.default.object,
schema: _propTypes2.default.object,
submitUrl: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.func]),
onLoad: _propTypes2.default.func,
onBeforeChange: _propTypes2.default.func,
onChange: _propTypes2.default.func,
onBeforeSubmit: _propTypes2.default.func,
onSubmitSuccess: _propTypes2.default.func,
onSubmitError: _propTypes2.default.func,
confirmDirty: _propTypes2.default.bool,
confirmMessage: _propTypes2.default.string,
valueMapper: _propTypes2.default.func,
render: _propTypes2.default.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: _propTypes2.default.shape({
history: _propTypes2.default.shape({
block: _propTypes2.default.func
})
})
}, _temp);
exports.default = Form;