fix(netlify-cms-core): fix fields metadata for objects and lists (#2011)
This commit is contained in:
parent
ff73175244
commit
2d1d1c13df
@ -137,13 +137,13 @@
|
||||
const RelationKitchenSinkPostPreview = createClass({
|
||||
render: function() {
|
||||
// When a post is selected from the relation field, all of it's data
|
||||
// will be available in the metadata nested under the collection name,
|
||||
// and then further nested under the value specified in `valueField`.
|
||||
// will be available in the field's metadata nested under the collection
|
||||
// name, and then further nested under the value specified in `valueField`.
|
||||
// In this case, the post would be nested under "posts" and then under
|
||||
// the title of the selected post, since our `valueField` in the config
|
||||
// is "title".
|
||||
const postValue = this.props.entry.getIn(['data', 'post']);
|
||||
const post = this.props.fieldsMetaData.getIn(['posts', postValue]);
|
||||
const { value, fieldsMetaData } = this.props;
|
||||
const post = fieldsMetaData && fieldsMetaData.getIn(['posts', value]);
|
||||
const style = { border: '2px solid #ccc', borderRadius: '8px', padding: '20px' };
|
||||
return post ? h('div', { style: style },
|
||||
h('h2', {}, 'Related Post'),
|
||||
|
@ -195,7 +195,7 @@ export default class Widget extends Component {
|
||||
*/
|
||||
onChangeObject = (fieldName, newValue, newMetadata) => {
|
||||
const newObjectValue = this.getObjectValue().set(fieldName, newValue);
|
||||
return this.props.onChange(newObjectValue, newMetadata);
|
||||
return this.props.onChange(newObjectValue, { [this.props.field.get('name')]: newMetadata });
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -22,8 +22,8 @@ const PreviewPaneFrame = styled(Frame)`
|
||||
`;
|
||||
|
||||
export default class PreviewPane extends React.Component {
|
||||
getWidget = (field, value, props, idx = null) => {
|
||||
const { fieldsMetaData, getAsset, entry } = props;
|
||||
getWidget = (field, value, metadata, props, idx = null) => {
|
||||
const { getAsset, entry } = props;
|
||||
const widget = resolveWidget(field.get('widget'));
|
||||
const key = idx ? field.get('name') + '_' + idx : field.get('name');
|
||||
|
||||
@ -37,9 +37,8 @@ export default class PreviewPane extends React.Component {
|
||||
field={field}
|
||||
getAsset={getAsset}
|
||||
value={value && Map.isMap(value) ? value.get(field.get('name')) : value}
|
||||
metadata={fieldsMetaData && fieldsMetaData.get(field.get('name'))}
|
||||
entry={entry}
|
||||
fieldsMetaData={fieldsMetaData}
|
||||
fieldsMetaData={metadata}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -63,20 +62,26 @@ export default class PreviewPane extends React.Component {
|
||||
* object and list type fields. Used internally to retrieve widgets, and also
|
||||
* exposed for use in custom preview templates.
|
||||
*/
|
||||
widgetFor = (name, fields = this.props.fields, values = this.props.entry.get('data')) => {
|
||||
widgetFor = (
|
||||
name,
|
||||
fields = this.props.fields,
|
||||
values = this.props.entry.get('data'),
|
||||
fieldsMetaData = this.props.fieldsMetaData,
|
||||
) => {
|
||||
// We retrieve the field by name so that this function can also be used in
|
||||
// custom preview templates, where the field object can't be passed in.
|
||||
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');
|
||||
let metadata = fieldsMetaData && fieldsMetaData.get(field.get('name'), Map());
|
||||
|
||||
if (nestedFields) {
|
||||
field = field.set('fields', this.getNestedWidgets(nestedFields, value));
|
||||
field = field.set('fields', this.getNestedWidgets(nestedFields, value, metadata));
|
||||
}
|
||||
|
||||
if (singleField) {
|
||||
field = field.set('field', this.getSingleNested(singleField, value));
|
||||
field = field.set('field', this.getSingleNested(singleField, value, metadata));
|
||||
}
|
||||
|
||||
const labelledWidgets = ['string', 'text', 'number'];
|
||||
@ -94,33 +99,35 @@ export default class PreviewPane extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
return value ? this.getWidget(field, value, this.props) : null;
|
||||
return value ? this.getWidget(field, value, metadata, this.props) : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves widgets for nested fields (children of object/list fields)
|
||||
*/
|
||||
getNestedWidgets = (fields, values) => {
|
||||
getNestedWidgets = (fields, values, fieldsMetaData) => {
|
||||
// Fields nested within a list field will be paired with a List of value Maps.
|
||||
if (List.isList(values)) {
|
||||
return values.map(value => this.widgetsForNestedFields(fields, value));
|
||||
return values.map(value => this.widgetsForNestedFields(fields, value, fieldsMetaData));
|
||||
}
|
||||
// Fields nested within an object field will be paired with a single Map of values.
|
||||
return this.widgetsForNestedFields(fields, values);
|
||||
return this.widgetsForNestedFields(fields, values, fieldsMetaData);
|
||||
};
|
||||
|
||||
getSingleNested = (field, values) => {
|
||||
getSingleNested = (field, values, fieldsMetaData) => {
|
||||
if (List.isList(values)) {
|
||||
return values.map((value, idx) => this.getWidget(field, value, this.props, idx));
|
||||
return values.map((value, idx) =>
|
||||
this.getWidget(field, value, fieldsMetaData.get(field.get('name')), this.props, idx),
|
||||
);
|
||||
}
|
||||
return this.getWidget(field, values, this.props);
|
||||
return this.getWidget(field, values, fieldsMetaData.get(field.get('name')), this.props);
|
||||
};
|
||||
|
||||
/**
|
||||
* Use widgetFor as a mapping function for recursive widget retrieval
|
||||
*/
|
||||
widgetsForNestedFields = (fields, values) => {
|
||||
return fields.map(field => this.widgetFor(field.get('name'), fields, values));
|
||||
widgetsForNestedFields = (fields, values, fieldsMetaData) => {
|
||||
return fields.map(field => this.widgetFor(field.get('name'), fields, values, fieldsMetaData));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -130,10 +137,11 @@ export default class PreviewPane extends React.Component {
|
||||
* TODO: see if widgetFor can now provide this functionality for preview templates
|
||||
*/
|
||||
widgetsFor = name => {
|
||||
const { fields, entry } = this.props;
|
||||
const { fields, entry, fieldsMetaData } = this.props;
|
||||
const field = fields.find(f => f.get('name') === name);
|
||||
const nestedFields = field && field.get('fields');
|
||||
const value = entry.getIn(['data', field.get('name')]);
|
||||
const metadata = fieldsMetaData.get(field.get('name'), Map());
|
||||
|
||||
if (List.isList(value)) {
|
||||
return value.map(val => {
|
||||
@ -142,7 +150,7 @@ export default class PreviewPane extends React.Component {
|
||||
Map(
|
||||
nestedFields.map((f, i) => [
|
||||
f.get('name'),
|
||||
<div key={i}>{this.getWidget(f, val, this.props)}</div>,
|
||||
<div key={i}>{this.getWidget(f, val, metadata.get(f.get('name')), this.props)}</div>,
|
||||
]),
|
||||
);
|
||||
return Map({ data: val, widgets });
|
||||
@ -153,7 +161,12 @@ export default class PreviewPane extends React.Component {
|
||||
data: value,
|
||||
widgets:
|
||||
nestedFields &&
|
||||
Map(nestedFields.map(f => [f.get('name'), this.getWidget(f, value, this.props)])),
|
||||
Map(
|
||||
nestedFields.map(f => [
|
||||
f.get('name'),
|
||||
this.getWidget(f, value, metadata.get(f.get('name')), this.props),
|
||||
]),
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -201,10 +201,7 @@ export default class ListControl extends React.Component {
|
||||
? this.getObjectValue(index).set(fieldName, newValue)
|
||||
: newValue;
|
||||
const parsedMetadata = {
|
||||
[collectionName]: Object.assign(
|
||||
metadata ? metadata.toJS() : {},
|
||||
newMetadata ? newMetadata[collectionName] : {},
|
||||
),
|
||||
[collectionName]: Object.assign(metadata ? metadata.toJS() : {}, newMetadata || {}),
|
||||
};
|
||||
onChange(value.set(index, newObjectValue), parsedMetadata);
|
||||
};
|
||||
@ -283,6 +280,7 @@ export default class ListControl extends React.Component {
|
||||
classNameWrapper,
|
||||
editorControl,
|
||||
onValidateObject,
|
||||
metadata,
|
||||
clearFieldErrors,
|
||||
fieldsErrors,
|
||||
controlRef,
|
||||
@ -320,6 +318,7 @@ export default class ListControl extends React.Component {
|
||||
onChangeObject={this.handleChangeFor(index)}
|
||||
editorControl={editorControl}
|
||||
resolveWidget={resolveWidget}
|
||||
metadata={metadata}
|
||||
forList
|
||||
onValidateObject={onValidateObject}
|
||||
clearFieldErrors={clearFieldErrors}
|
||||
|
@ -69,6 +69,7 @@ export default class ObjectControl extends Component {
|
||||
onChangeObject,
|
||||
onValidateObject,
|
||||
clearFieldErrors,
|
||||
metadata,
|
||||
fieldsErrors,
|
||||
editorControl: EditorControl,
|
||||
controlRef,
|
||||
@ -87,6 +88,7 @@ export default class ObjectControl extends Component {
|
||||
value={fieldValue}
|
||||
onChange={onChangeObject}
|
||||
clearFieldErrors={clearFieldErrors}
|
||||
fieldsMetaData={metadata}
|
||||
fieldsErrors={fieldsErrors}
|
||||
onValidate={onValidateObject}
|
||||
processControlRef={controlRef && controlRef.bind(this)}
|
||||
|
@ -95,7 +95,9 @@ export default class RelationControl extends React.Component {
|
||||
if (suggestion && suggestion.length === 1) {
|
||||
const val = this.getSuggestionValue(suggestion[0]);
|
||||
this.props.onChange(val, {
|
||||
[this.props.field.get('collection')]: { [val]: suggestion[0].data },
|
||||
[this.props.field.get('name')]: {
|
||||
[this.props.field.get('collection')]: { [val]: suggestion[0].data },
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -108,7 +110,9 @@ export default class RelationControl extends React.Component {
|
||||
onSuggestionSelected = (event, { suggestion }) => {
|
||||
const value = this.getSuggestionValue(suggestion);
|
||||
this.props.onChange(value, {
|
||||
[this.props.field.get('collection')]: { [value]: suggestion.data },
|
||||
[this.props.field.get('name')]: {
|
||||
[this.props.field.get('collection')]: { [value]: suggestion.data },
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user