fix(widget-relation): set initial metadata value (#4182)
This commit is contained in:
parent
8d693caebd
commit
4a510f3a9b
@ -73,7 +73,6 @@ function getSelectedValue({ value, options, isMultiple }) {
|
||||
}
|
||||
|
||||
export default class RelationControl extends React.Component {
|
||||
didInitialSearch = false;
|
||||
mounted = false;
|
||||
|
||||
state = {
|
||||
@ -106,17 +105,19 @@ export default class RelationControl extends React.Component {
|
||||
// if the field has a previous value perform an initial search based on the value field
|
||||
// this is required since each search is limited by optionsLength so the selected value
|
||||
// might not show up on the search
|
||||
const { forID, field, value, query } = this.props;
|
||||
const { forID, field, value, query, onChange } = this.props;
|
||||
const collection = field.get('collection');
|
||||
const file = field.get('file');
|
||||
const initialSearchValues = this.isMultiple() ? getSelectedOptions(value) : [value];
|
||||
const initialSearchValues = value && (this.isMultiple() ? getSelectedOptions(value) : [value]);
|
||||
if (initialSearchValues && initialSearchValues.length > 0) {
|
||||
const metadata = {};
|
||||
const allOptions = await Promise.all(
|
||||
initialSearchValues.map((v, index) => {
|
||||
return query(forID, collection, [field.get('valueField')], v, file, 1).then(
|
||||
({ payload }) => {
|
||||
const hits = payload.response?.hits || [];
|
||||
const options = this.parseHitOptions(hits);
|
||||
metadata[v] = hits[0]?.data;
|
||||
return { options, index };
|
||||
},
|
||||
);
|
||||
@ -127,6 +128,13 @@ export default class RelationControl extends React.Component {
|
||||
...sortBy(allOptions, ({ index }) => index).map(({ options }) => options),
|
||||
);
|
||||
this.mounted && this.setState({ initialOptions });
|
||||
|
||||
//set metadata
|
||||
onChange(value, {
|
||||
[field.get('name')]: {
|
||||
[field.get('collection')]: metadata,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,33 +142,6 @@ export default class RelationControl extends React.Component {
|
||||
this.mounted = false;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
/**
|
||||
* Load extra post data into the store after first query.
|
||||
*/
|
||||
if (this.didInitialSearch) return;
|
||||
const { value, field, forID, queryHits, onChange } = this.props;
|
||||
|
||||
if (queryHits !== prevProps.queryHits && queryHits.get(forID)) {
|
||||
this.didInitialSearch = true;
|
||||
const valueField = field.get('valueField');
|
||||
const hits = queryHits.get(forID);
|
||||
if (value) {
|
||||
const listValue = List.isList(value) ? value : List([value]);
|
||||
listValue.forEach(val => {
|
||||
const hit = hits.find(hit => this.parseNestedFields(hit, valueField) === val);
|
||||
if (hit) {
|
||||
onChange(value, {
|
||||
[field.get('name')]: {
|
||||
[field.get('collection')]: { [val]: hit.data },
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleChange = selectedOption => {
|
||||
const { onChange, field } = this.props;
|
||||
let value;
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { fromJS, Map } from 'immutable';
|
||||
import { last } from 'lodash';
|
||||
import { render, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { NetlifyCmsWidgetRelation } from '../';
|
||||
|
||||
@ -85,6 +84,10 @@ const generateHits = length => {
|
||||
collection: 'posts',
|
||||
data: { title: 'YAML post', slug: 'post-yaml', body: 'Body yaml' },
|
||||
},
|
||||
{
|
||||
collection: 'posts',
|
||||
data: { title: 'JSON post', slug: 'post-json', body: 'Body json' },
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
@ -166,12 +169,14 @@ class RelationController extends React.Component {
|
||||
hits = nestedFileCollectionHits;
|
||||
} else if (file === 'simple_file') {
|
||||
hits = simpleFileCollectionHits;
|
||||
} else if (term === 'YAML') {
|
||||
hits = [last(queryHits)];
|
||||
} else if (term === 'Nested') {
|
||||
} else if (term === 'JSON post') {
|
||||
hits = [queryHits[queryHits.length - 1]];
|
||||
} else if (term === 'YAML' || term === 'YAML post') {
|
||||
hits = [queryHits[queryHits.length - 2]];
|
||||
} else if (term === 'Deeply nested') {
|
||||
} else if (term === 'Nested') {
|
||||
hits = [queryHits[queryHits.length - 3]];
|
||||
} else if (term === 'Deeply nested') {
|
||||
hits = [queryHits[queryHits.length - 4]];
|
||||
}
|
||||
|
||||
hits = hits.slice(0, optionsLength);
|
||||
@ -411,24 +416,23 @@ describe('Relation widget', () => {
|
||||
|
||||
it('should update metadata for initial preview', async () => {
|
||||
const field = fromJS({ ...fieldConfig, multiple: true });
|
||||
const value = fromJS(['Post # 1', 'Post # 2']);
|
||||
const { getByText, onChangeSpy, setQueryHitsSpy } = setup({ field, value });
|
||||
const metadata1 = {
|
||||
post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } },
|
||||
const value = fromJS(['YAML post', 'JSON post']);
|
||||
const { getByText, onChangeSpy } = setup({ field, value });
|
||||
const metadata = {
|
||||
post: {
|
||||
posts: {
|
||||
'YAML post': { title: 'YAML post', slug: 'post-yaml', body: 'Body yaml' },
|
||||
'JSON post': { title: 'JSON post', slug: 'post-json', body: 'Body json' },
|
||||
},
|
||||
},
|
||||
};
|
||||
const metadata2 = {
|
||||
post: { posts: { 'Post # 2': { title: 'Post # 2', slug: 'post-number-2' } } },
|
||||
};
|
||||
|
||||
setQueryHitsSpy(generateHits(2));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText('Post # 1 post-number-1')).toBeInTheDocument();
|
||||
expect(getByText('Post # 2 post-number-2')).toBeInTheDocument();
|
||||
expect(getByText('YAML post post-yaml')).toBeInTheDocument();
|
||||
expect(getByText('JSON post post-json')).toBeInTheDocument();
|
||||
|
||||
expect(onChangeSpy).toHaveBeenCalledTimes(2);
|
||||
expect(onChangeSpy).toHaveBeenCalledWith(value, metadata1);
|
||||
expect(onChangeSpy).toHaveBeenCalledWith(value, metadata2);
|
||||
expect(onChangeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(onChangeSpy).toHaveBeenCalledWith(value, metadata);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user