@lyra/form-builder
Version:
Lyra form builder
214 lines (181 loc) • 6.17 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
var _throttle2 = require('lodash/throttle');
var _throttle3 = _interopRequireDefault(_throttle2);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _subscriptionManager = require('../utils/subscriptionManager');
var _subscriptionManager2 = _interopRequireDefault(_subscriptionManager);
var _PatchEvent = require('../PatchEvent');
var _PatchEvent2 = _interopRequireDefault(_PatchEvent);
var _client = require('part:@lyra/base/client');
var _client2 = _interopRequireDefault(_client);
var _formBuilderValueStore = require('./formBuilderValueStore');
var _LyraFormBuilderContext = require('./LyraFormBuilderContext');
var _LyraFormBuilderContext2 = _interopRequireDefault(_LyraFormBuilderContext);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*:: type State = {
isLoading: boolean,
isSaving: boolean,
value: ?any,
deletedSnapshot: ?any
}*/
// Provides a utility component for easy editing a value of a schema type with the form builder
// Manages server sync, mutations, etc. and passes a value + onChange to a child component
// Note: Experimental, and likely to change in the future
/*:: type Props = {
documentId: string,
typeName: string,
schema: Object,
children: Function
}*/
function getInitialState() /*: State*/ {
return {
isLoading: true,
isSaving: false,
value: null,
deletedSnapshot: null
};
}
class WithFormBuilderValue extends _react2.default.PureComponent /*:: <
Props,
State
>*/ {
constructor(...args) {
var _temp;
return _temp = super(...args), this.subscriptions = (0, _subscriptionManager2.default)('documentEvents', 'commit'), this.state = getInitialState(), this.patchChannel = _LyraFormBuilderContext2.default.createPatchChannel(), this.handleDocumentEvent = (event /*: {type: string, document: any}*/) => {
switch (event.type) {
case 'snapshot':
{
this.setState({
isLoading: false,
value: event.document ? event.document : null
});
break;
}
case 'rebase':
{
this.setState({
value: event.document
});
break;
}
case 'mutation':
{
this.handleIncomingMutationEvent(event);
break;
}
case 'create':
{
this.setState({
value: event.document
});
break;
}
default:
{
// eslint-disable-next-line no-console
console.log('Unhandled document event type "%s"', event.type, event);
}
}
}, this.commit = (0, _throttle3.default)(() => {
this.setState({ isSaving: true });
this.subscriptions.replace('commit', this.document.commit().subscribe({
next: () => {
// todo
},
error: _error => {
// todo
},
complete: () => {
this.setState({ isSaving: false });
}
}));
}, 1000, { leading: true, trailing: true }), this.handleChange = (event /*: PatchEvent*/) => {
if (!this.state.value) {
this.document.createIfNotExists({
_id: this.props.documentId,
_type: this.props.typeName
});
}
this.document.patch(event.patches);
this.commit();
}, this.handleDelete = () => {
return _client2.default.observable.delete(this.props.documentId);
}, this.handleCreate = (document /*: any*/) => {
this.document.create(document);
this.commit();
}, _temp;
}
checkoutDocument(documentId /*: string*/) {
this.document = (0, _formBuilderValueStore.checkout)(documentId);
this.subscriptions.replace('documentEvents', this.document.events.subscribe({
next: this.handleDocumentEvent
// error: this.handleDocumentError
}));
}
componentWillUnmount() {
this.subscriptions.unsubscribeAll();
}
componentWillMount() {
this.checkoutDocument(this.props.documentId);
}
componentWillReceiveProps(nextProps /*: Props*/) {
if (nextProps.documentId !== this.props.documentId) {
this.setState(getInitialState());
this.checkoutDocument(nextProps.documentId);
}
}
handleIncomingMutationEvent(event /*: any*/) {
// Broadcast incoming patches to input components that applies patches on their own
// Note: This is *experimental* and likely to change in the near future
this.patchChannel.receivePatches({
patches: event.patches,
snapshot: event.document
});
this.setState({
deletedSnapshot: event.deletedSnapshot,
value: event.document
});
}
render() {
var _props = this.props;
const typeName = _props.typeName,
documentId = _props.documentId,
schema = _props.schema,
children = _props.children;
var _state = this.state;
const isLoading = _state.isLoading,
isSaving = _state.isSaving,
value = _state.value,
deletedSnapshot = _state.deletedSnapshot;
return _react2.default.createElement(
_LyraFormBuilderContext2.default,
{
value: value,
schema: schema,
patchChannel: this.patchChannel
},
children({
value: value,
isLoading: isLoading,
isSaving: isSaving,
deletedSnapshot: deletedSnapshot,
documentId: documentId,
type: schema.get(typeName),
onChange: this.handleChange,
onDelete: this.handleDelete,
onCreate: this.handleCreate
})
);
}
}
exports.default = WithFormBuilderValue;
WithFormBuilderValue.childContextTypes = {
formBuilder: _propTypes2.default.object
};