2018-03-22 19:22:54 +09:00
|
|
|
import React, { PureComponent } from 'react';
|
2018-03-24 11:16:11 +09:00
|
|
|
import PropTypes from 'prop-types';
|
2018-03-22 19:22:54 +09:00
|
|
|
import { Components, registerComponent } from 'meteor/vulcan:core';
|
|
|
|
|
2018-03-28 16:47:10 +09:00
|
|
|
const FormNestedItem = ({ nestedFields, name, path, removeItem, itemIndex, ...props }, { errors }) => {
|
2018-03-22 19:22:54 +09:00
|
|
|
return (
|
2018-03-25 12:13:30 +09:00
|
|
|
<div className="form-nested-item">
|
2018-03-23 08:51:24 +09:00
|
|
|
<div className="form-nested-item-inner">
|
|
|
|
{nestedFields.map((field, i) => {
|
2018-03-25 10:54:45 +09:00
|
|
|
return (
|
|
|
|
<Components.FormComponent
|
|
|
|
key={i}
|
|
|
|
{...props}
|
|
|
|
{...field}
|
|
|
|
path={`${path}.${field.name}`}
|
|
|
|
itemIndex={itemIndex}
|
|
|
|
/>
|
|
|
|
);
|
2018-03-23 08:51:24 +09:00
|
|
|
})}
|
|
|
|
</div>
|
|
|
|
<div className="form-nested-item-remove">
|
2018-04-23 09:47:04 +09:00
|
|
|
<Components.Button
|
2018-03-28 16:47:10 +09:00
|
|
|
className="form-nested-button"
|
2018-04-23 09:47:04 +09:00
|
|
|
variant="danger"
|
|
|
|
size="small"
|
2018-03-23 08:51:24 +09:00
|
|
|
onClick={() => {
|
|
|
|
removeItem(name);
|
|
|
|
}}
|
|
|
|
>
|
2018-03-28 16:47:10 +09:00
|
|
|
<Components.IconRemove height={12} width={12} />
|
2018-04-23 09:47:04 +09:00
|
|
|
</Components.Button>
|
2018-03-23 08:51:24 +09:00
|
|
|
</div>
|
2018-03-25 10:54:45 +09:00
|
|
|
<div className="form-nested-item-deleted-overlay" />
|
2018-03-22 19:22:54 +09:00
|
|
|
</div>
|
2018-03-23 08:51:24 +09:00
|
|
|
);
|
|
|
|
};
|
2018-03-22 19:22:54 +09:00
|
|
|
|
2018-03-25 10:54:45 +09:00
|
|
|
FormNestedItem.contextTypes = {
|
|
|
|
errors: PropTypes.array,
|
|
|
|
};
|
|
|
|
|
2018-03-22 19:22:54 +09:00
|
|
|
registerComponent('FormNestedItem', FormNestedItem);
|
|
|
|
|
2018-03-23 08:51:24 +09:00
|
|
|
class FormNested extends PureComponent {
|
2018-03-23 15:46:31 +09:00
|
|
|
addItem = () => {
|
2018-03-25 10:54:45 +09:00
|
|
|
this.props.updateCurrentValues({ [`${this.props.path}.${this.props.value.length}`]: {} });
|
2018-03-23 08:51:24 +09:00
|
|
|
};
|
2018-03-22 19:22:54 +09:00
|
|
|
|
2018-03-23 15:46:31 +09:00
|
|
|
removeItem = index => {
|
2018-03-25 10:54:45 +09:00
|
|
|
this.props.updateCurrentValues({ [`${this.props.path}.${index}`]: null });
|
2018-03-23 08:51:24 +09:00
|
|
|
};
|
2018-03-22 19:22:54 +09:00
|
|
|
|
2018-03-24 11:16:11 +09:00
|
|
|
/*
|
|
|
|
|
|
|
|
Go through this.context.deletedValues and see if any value matches both the current field
|
|
|
|
and the given index (ex: if we want to know if the second address is deleted, we
|
|
|
|
look for the presence of 'addresses.1')
|
|
|
|
*/
|
|
|
|
isDeleted = index => {
|
2018-03-25 10:54:45 +09:00
|
|
|
return this.context.deletedValues.includes(`${this.props.path}.${index}`);
|
2018-03-24 11:16:11 +09:00
|
|
|
};
|
|
|
|
|
2018-03-22 19:22:54 +09:00
|
|
|
render() {
|
2018-04-21 18:24:54 +09:00
|
|
|
// do not pass FormNested's own value, input and inputProperties props down
|
|
|
|
const properties = _.omit(this.props, 'value', 'input', 'inputProperties');
|
2018-03-27 08:25:16 +09:00
|
|
|
|
2018-03-22 19:22:54 +09:00
|
|
|
return (
|
|
|
|
<div className="form-group row form-nested">
|
|
|
|
<label className="control-label col-sm-3">{this.props.label}</label>
|
|
|
|
<div className="col-sm-9">
|
2018-03-23 08:51:24 +09:00
|
|
|
{this.props.value &&
|
2018-03-25 10:54:45 +09:00
|
|
|
this.props.value.map(
|
|
|
|
(subDocument, i) =>
|
|
|
|
!this.isDeleted(i) && (
|
|
|
|
<FormNestedItem
|
2018-03-27 08:25:16 +09:00
|
|
|
{...properties}
|
2018-03-25 10:54:45 +09:00
|
|
|
key={i}
|
|
|
|
itemIndex={i}
|
|
|
|
path={`${this.props.path}.${i}`}
|
|
|
|
removeItem={() => {
|
|
|
|
this.removeItem(i);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
)}
|
2018-03-28 16:47:10 +09:00
|
|
|
<Button bsSize="small" bsStyle="success" onClick={this.addItem} className="form-nested-button">
|
|
|
|
<Components.IconAdd height={12} width={12} />
|
2018-03-23 08:51:24 +09:00
|
|
|
</Button>
|
2018-03-22 19:22:54 +09:00
|
|
|
</div>
|
|
|
|
</div>
|
2018-03-23 08:51:24 +09:00
|
|
|
);
|
2018-03-22 19:22:54 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-24 11:16:11 +09:00
|
|
|
FormNested.contextTypes = {
|
2018-03-25 10:54:45 +09:00
|
|
|
deletedValues: PropTypes.array,
|
|
|
|
};
|
2018-03-24 11:16:11 +09:00
|
|
|
|
2018-03-23 08:51:24 +09:00
|
|
|
registerComponent('FormNested', FormNested);
|
2018-03-28 16:47:10 +09:00
|
|
|
|
|
|
|
const IconAdd = ({ width = 24, height = 24 }) => (
|
|
|
|
<svg width={width} height={height} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
|
|
|
<path d="M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z" />
|
|
|
|
</svg>
|
|
|
|
);
|
|
|
|
|
|
|
|
registerComponent('IconAdd', IconAdd);
|
|
|
|
|
|
|
|
const IconRemove = ({ width = 24, height = 24 }) => (
|
|
|
|
<svg width={width} height={height} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
|
|
|
<path d="M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z" />
|
|
|
|
</svg>
|
|
|
|
);
|
|
|
|
|
|
|
|
registerComponent('IconRemove', IconRemove);
|