fix(list-widget): fix single field usage in list widget (#1395)
This commit is contained in:
parent
f58db5fb08
commit
06d3650fac
@ -22,9 +22,10 @@ const PreviewPaneFrame = styled(Frame)`
|
||||
`;
|
||||
|
||||
export default class PreviewPane extends React.Component {
|
||||
getWidget = (field, value, props) => {
|
||||
getWidget = (field, value, props, idx = null) => {
|
||||
const { fieldsMetaData, getAsset, entry } = props;
|
||||
const widget = resolveWidget(field.get('widget'));
|
||||
const key = idx ? field.get('name') + '_' + idx : field.get('name');
|
||||
|
||||
/**
|
||||
* Use an HOC to provide conditional updates for all previews.
|
||||
@ -32,7 +33,7 @@ export default class PreviewPane extends React.Component {
|
||||
return !widget.preview ? null : (
|
||||
<PreviewHOC
|
||||
previewComponent={widget.preview}
|
||||
key={field.get('name')}
|
||||
key={key}
|
||||
field={field}
|
||||
getAsset={getAsset}
|
||||
value={value && Map.isMap(value) ? value.get(field.get('name')) : value}
|
||||
@ -68,11 +69,16 @@ export default class PreviewPane extends React.Component {
|
||||
let field = fields && fields.find(f => f.get('name') === name);
|
||||
let value = values && values.get(field.get('name'));
|
||||
let nestedFields = field.get('fields');
|
||||
let singleField = field.get('field');
|
||||
|
||||
if (nestedFields) {
|
||||
field = field.set('fields', this.getNestedWidgets(nestedFields, value));
|
||||
}
|
||||
|
||||
if (singleField) {
|
||||
field = field.set('field', this.getSingleNested(singleField, value));
|
||||
}
|
||||
|
||||
const labelledWidgets = ['string', 'text', 'number'];
|
||||
if (Object.keys(this.inferedFields).indexOf(name) !== -1) {
|
||||
value = this.inferedFields[name].defaultPreview(value);
|
||||
@ -103,6 +109,13 @@ export default class PreviewPane extends React.Component {
|
||||
return this.widgetsForNestedFields(fields, values);
|
||||
};
|
||||
|
||||
getSingleNested = (field, values) => {
|
||||
if (List.isList(values)) {
|
||||
return values.map((value, idx) => this.getWidget(field, value, this.props, idx));
|
||||
}
|
||||
return this.getWidget(field, values, this.props);
|
||||
};
|
||||
|
||||
/**
|
||||
* Use widgetFor as a mapping function for recursive widget retrieval
|
||||
*/
|
||||
|
@ -28,30 +28,34 @@ const TopBarButton = styled.button`
|
||||
|
||||
const TopBarButtonSpan = TopBarButton.withComponent('span');
|
||||
|
||||
const DragIcon = styled(TopBarButtonSpan)`
|
||||
const DragIconContainer = styled(TopBarButtonSpan)`
|
||||
width: 100%;
|
||||
cursor: move;
|
||||
`;
|
||||
|
||||
const ListItemTopBar = ({ className, collapsed, onCollapseToggle, onRemove, dragHandleHOC }) => (
|
||||
<TopBar className={className}>
|
||||
{onCollapseToggle ? (
|
||||
<TopBarButton onClick={onCollapseToggle}>
|
||||
<Icon type="chevron" size="small" direction={collapsed ? 'right' : 'down'} />
|
||||
</TopBarButton>
|
||||
) : null}
|
||||
{dragHandleHOC ? (
|
||||
<DragIcon>
|
||||
<Icon type="drag-handle" size="small" />
|
||||
</DragIcon>
|
||||
) : null}
|
||||
{onRemove ? (
|
||||
<TopBarButton onClick={onRemove}>
|
||||
<Icon type="close" size="small" />
|
||||
</TopBarButton>
|
||||
) : null}
|
||||
</TopBar>
|
||||
);
|
||||
const ListItemTopBar = ({ className, collapsed, onCollapseToggle, onRemove, dragHandleHOC }) => {
|
||||
const DragHandle = dragHandleHOC(() => (
|
||||
<DragIconContainer>
|
||||
<Icon type="drag-handle" size="small" />
|
||||
</DragIconContainer>
|
||||
));
|
||||
|
||||
return (
|
||||
<TopBar className={className}>
|
||||
{onCollapseToggle ? (
|
||||
<TopBarButton onClick={onCollapseToggle}>
|
||||
<Icon type="chevron" size="small" direction={collapsed ? 'right' : 'down'} />
|
||||
</TopBarButton>
|
||||
) : null}
|
||||
{dragHandleHOC ? <DragHandle dragHandleHOC={dragHandleHOC} /> : null}
|
||||
{onRemove ? (
|
||||
<TopBarButton onClick={onRemove}>
|
||||
<Icon type="close" size="small" />
|
||||
</TopBarButton>
|
||||
) : null}
|
||||
</TopBar>
|
||||
);
|
||||
};
|
||||
|
||||
const StyledListItemTopBar = styled(ListItemTopBar)`
|
||||
display: flex;
|
||||
|
@ -159,16 +159,17 @@ export default class ListControl extends React.Component {
|
||||
return (fieldName, newValue, newMetadata) => {
|
||||
const { value, metadata, onChange, field } = this.props;
|
||||
const collectionName = field.get('name');
|
||||
const newObjectValue = this.getObjectValue(index).set(fieldName, newValue);
|
||||
const parsedValue =
|
||||
this.getValueType() === valueTypes.SINGLE ? newObjectValue.first() : newObjectValue;
|
||||
const newObjectValue =
|
||||
this.getValueType() === valueTypes.MULTIPLE
|
||||
? this.getObjectValue(index).set(fieldName, newValue)
|
||||
: newValue;
|
||||
const parsedMetadata = {
|
||||
[collectionName]: Object.assign(
|
||||
metadata ? metadata.toJS() : {},
|
||||
newMetadata ? newMetadata[collectionName] : {},
|
||||
),
|
||||
};
|
||||
onChange(value.set(index, parsedValue), parsedMetadata);
|
||||
onChange(value.set(index, newObjectValue), parsedMetadata);
|
||||
};
|
||||
}
|
||||
|
||||
@ -177,9 +178,10 @@ export default class ListControl extends React.Component {
|
||||
const { itemsCollapsed } = this.state;
|
||||
const { value, metadata, onChange, field } = this.props;
|
||||
const collectionName = field.get('name');
|
||||
const parsedMetadata = metadata && {
|
||||
[collectionName]: metadata.removeIn(value.get(index).valueSeq()),
|
||||
};
|
||||
const isSingleField = this.valueType === valueTypes.SINGLE;
|
||||
|
||||
const metadataRemovePath = isSingleField ? value.get(index) : value.get(index).valueSeq();
|
||||
const parsedMetadata = metadata && { [collectionName]: metadata.removeIn(metadataRemovePath) };
|
||||
|
||||
this.setState({ itemsCollapsed: itemsCollapsed.delete(index) });
|
||||
|
||||
|
@ -62,13 +62,20 @@ export default class ObjectControl extends Component {
|
||||
this.setState({ collapsed: !this.state.collapsed });
|
||||
};
|
||||
|
||||
renderFields = (multiFields, singleField) => {
|
||||
if (multiFields) {
|
||||
return multiFields.map((f, idx) => this.controlFor(f, idx));
|
||||
}
|
||||
return this.controlFor(singleField);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { field, forID, classNameWrapper, forList } = this.props;
|
||||
const { collapsed } = this.state;
|
||||
const multiFields = field.get('fields');
|
||||
const singleField = field.get('field');
|
||||
|
||||
if (multiFields) {
|
||||
if (multiFields || singleField) {
|
||||
return (
|
||||
<div
|
||||
id={forID}
|
||||
@ -82,11 +89,9 @@ export default class ObjectControl extends Component {
|
||||
onCollapseToggle={this.handleCollapseToggle}
|
||||
/>
|
||||
)}
|
||||
{collapsed ? null : multiFields.map((f, idx) => this.controlFor(f, idx))}
|
||||
{collapsed ? null : this.renderFields(multiFields, singleField)}
|
||||
</div>
|
||||
);
|
||||
} else if (singleField) {
|
||||
return this.controlFor(singleField);
|
||||
}
|
||||
|
||||
return <h3>No field(s) defined for this widget</h3>;
|
||||
|
@ -3,7 +3,9 @@ import PropTypes from 'prop-types';
|
||||
import { WidgetPreviewContainer } from 'netlify-cms-ui-default';
|
||||
|
||||
const ObjectPreview = ({ field }) => (
|
||||
<WidgetPreviewContainer>{(field && field.get('fields')) || null}</WidgetPreviewContainer>
|
||||
<WidgetPreviewContainer>
|
||||
{(field && field.get('fields')) || field.get('field') || null}
|
||||
</WidgetPreviewContainer>
|
||||
);
|
||||
|
||||
ObjectPreview.propTypes = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user