2017-09-09 19:39:10 -06:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import React, { Component } from 'react';
|
2016-10-28 04:51:37 +02:00
|
|
|
import { Map } from 'immutable';
|
|
|
|
import { resolveWidget } from '../Widgets';
|
|
|
|
|
|
|
|
export default class ObjectControl extends Component {
|
|
|
|
static propTypes = {
|
|
|
|
onChange: PropTypes.func.isRequired,
|
2017-01-10 22:23:22 -02:00
|
|
|
onAddAsset: PropTypes.func.isRequired,
|
2017-03-15 14:30:41 -04:00
|
|
|
onRemoveAsset: PropTypes.func.isRequired,
|
2017-01-10 22:23:22 -02:00
|
|
|
getAsset: PropTypes.func.isRequired,
|
2017-05-19 12:52:47 -04:00
|
|
|
value: PropTypes.oneOfType([
|
|
|
|
PropTypes.node,
|
|
|
|
PropTypes.object,
|
|
|
|
PropTypes.bool,
|
|
|
|
]),
|
2017-01-16 16:52:59 -02:00
|
|
|
field: PropTypes.object,
|
2017-06-04 17:20:40 +02:00
|
|
|
forID: PropTypes.string,
|
2017-03-15 14:30:41 -04:00
|
|
|
className: PropTypes.string,
|
2016-10-28 04:51:37 +02:00
|
|
|
};
|
|
|
|
|
2017-09-25 14:19:24 -04:00
|
|
|
/**
|
|
|
|
* In case the `onChange` function is frozen by a child widget implementation,
|
|
|
|
* e.g. when debounced, always get the latest object value instead of usin
|
|
|
|
* `this.props.value` directly.
|
|
|
|
*/
|
|
|
|
getObjectValue = () => this.props.value;
|
|
|
|
|
2016-10-28 04:51:37 +02:00
|
|
|
controlFor(field) {
|
2017-01-10 22:23:22 -02:00
|
|
|
const { onAddAsset, onRemoveAsset, getAsset, value, onChange } = this.props;
|
2017-06-28 16:12:35 -04:00
|
|
|
if (field.get('widget') === 'hidden') {
|
|
|
|
return null;
|
|
|
|
}
|
2016-10-28 04:51:37 +02:00
|
|
|
const widget = resolveWidget(field.get('widget') || 'string');
|
2016-11-29 20:18:01 -02:00
|
|
|
const fieldValue = value && Map.isMap(value) ? value.get(field.get('name')) : value;
|
2016-10-28 04:51:37 +02:00
|
|
|
|
2017-10-18 09:29:38 -07:00
|
|
|
return (<div className="nc-controlPane-widget" key={field.get('name')}>
|
|
|
|
<div className="nc-controlPane-control" key={field.get('name')}>
|
|
|
|
<label className="nc-controlPane-label" htmlFor={field.get('name')}>{field.get('label')}</label>
|
2016-10-28 04:51:37 +02:00
|
|
|
{
|
|
|
|
React.createElement(widget.control, {
|
2017-03-15 14:30:41 -04:00
|
|
|
id: field.get('name'),
|
2016-10-28 04:51:37 +02:00
|
|
|
field,
|
|
|
|
value: fieldValue,
|
2016-12-29 17:18:24 -02:00
|
|
|
onChange: (val, metadata) => {
|
2017-09-25 14:19:24 -04:00
|
|
|
onChange((this.getObjectValue() || Map()).set(field.get('name'), val), metadata);
|
2016-10-28 04:51:37 +02:00
|
|
|
},
|
2017-01-10 22:23:22 -02:00
|
|
|
onAddAsset,
|
|
|
|
onRemoveAsset,
|
|
|
|
getAsset,
|
2017-05-19 12:52:47 -04:00
|
|
|
forID: field.get('name'),
|
2016-10-28 04:51:37 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
</div>
|
2016-10-28 10:21:13 +02:00
|
|
|
</div>);
|
2016-10-28 04:51:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2017-01-19 14:26:49 -02:00
|
|
|
const { field, forID } = this.props;
|
2016-11-29 20:18:01 -02:00
|
|
|
const multiFields = field.get('fields');
|
|
|
|
const singleField = field.get('field');
|
2017-03-15 14:30:41 -04:00
|
|
|
const className = this.props.className || '';
|
2016-10-28 04:51:37 +02:00
|
|
|
|
2016-11-29 20:18:01 -02:00
|
|
|
if (multiFields) {
|
2017-10-18 09:29:38 -07:00
|
|
|
return (<div id={forID} className={`${ className } nc-objectControl-root`}>
|
2017-03-15 14:30:41 -04:00
|
|
|
{multiFields.map(f => this.controlFor(f))}
|
2016-11-29 20:18:01 -02:00
|
|
|
</div>);
|
|
|
|
} else if (singleField) {
|
|
|
|
return this.controlFor(singleField);
|
2016-10-28 04:51:37 +02:00
|
|
|
}
|
|
|
|
|
2016-11-29 20:18:01 -02:00
|
|
|
return <h3>No field(s) defined for this widget</h3>;
|
2016-10-28 04:51:37 +02:00
|
|
|
}
|
|
|
|
}
|