UNPKG

@exivity/proton

Version:
190 lines (162 loc) 4.55 kB
import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import { withData } from 'react-orbitjs' import { Crud, withCrudConsumer } from '@exivity/proton' class _Entity extends PureComponent { constructor (props) { super(props) const recordNotFoundInCache = props.id && !props._entity this.state = { idReference: props.id, recordReference: props._entity, _entity: props._entity || props.buildRecord('_entity'), loading: recordNotFoundInCache, error: false } } static getDerivedStateFromProps (props, state) { const newIdProp = !!props.id && props.id !== state.idReference const buildRecord = !props.id && props.id !== state.idReference const newRecord = !!props._entity && (props._entity !== state.recordReference) const recordNotFoundInCache = props.id && !props._entity if (buildRecord) { const _entity = props.buildRecord('_entity') return { idReference: props.id, recordReference: _entity, _entity, loading: false, error: false } } if (newIdProp) { if (recordNotFoundInCache) { return { idReference: props.id, recordReference: null, _entity: null, loading: true, error: false } } return { idReference: props.id, recordReference: props._entity, _entity: props._entity, loading: false, error: false } } if (newRecord) { return { idReference: props.id, recordReference: props._entity, _entity: props._entity, loading: false, error: false } } return null } componentDidMount () { const { loading } = this.state if (loading) { this.queryStoreById(this.props.id) } } componentDidUpdate () { const { loading } = this.state if (loading) { this.queryStoreById(this.props.id) } } queryStoreById = (id) => { this.props.queryStore(q => q.findRecord({ type: '_entity', id })) .then(() => this.setState({ loading: false })) .catch((error) => { this.setState({ loading: false, error }) }) } setAttribute = (attribute) => (value) => { this.setState(({ _entity }) => ({ _entity: { ..._entity, attributes: { ..._entity.attributes, [attribute]: value } } })) } setRelationship = (relationship) => (value) => { this.setState(({ _entity }) => ({ _entity: { ..._entity, relationships: { ..._entity.relationships, [relationship]: { data: value } } } })) } onRemove = (...args) => { const { onRemove } = this.props this.setState({ recordReference: null, _entity: null, error: { message: 'Record has been removed' } }) onRemove && onRemove(...args) } render () { const { _entity, loading, error } = this.state return ( <Crud {...this.props} onRemove={this.onRemove}> {({ build, add, update, remove }) => this.props.children({ loading, error, _entity: _entity ? { ..._entity, setAttribute: this.setAttribute, setRelationship: this.setRelationship, save: _entity && !_entity.id ? (...args) => add(_entity, ...args) : (...args) => update(_entity, ...args), remove: (...args) => remove(_entity, ...args), } : null })} </Crud> ) } } const mapRecordsToProps = (ownProps) => { if (ownProps.id) { return { _entity: q => q.findRecord({ type: '_entity', id: ownProps.id }) } } return {} } const WithConsumer = withCrudConsumer(_Entity) export default withData(mapRecordsToProps)(WithConsumer) _Entity.propTypes = { _entity: PropTypes.object, id: PropTypes.string, buildRecord: PropTypes.func, addRecord: PropTypes.func, updateRecord: PropTypes.func, removeRecord: PropTypes.func, beforeAdd: PropTypes.func, onAdd: PropTypes.func, beforeUpdate: PropTypes.func, onUpdate: PropTypes.func, beforeRemove: PropTypes.func, onRemove: PropTypes.func }