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 {
|
export default class RelationControl extends React.Component {
|
||||||
didInitialSearch = false;
|
|
||||||
mounted = false;
|
mounted = false;
|
||||||
|
|
||||||
state = {
|
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
|
// 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
|
// this is required since each search is limited by optionsLength so the selected value
|
||||||
// might not show up on the search
|
// 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 collection = field.get('collection');
|
||||||
const file = field.get('file');
|
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) {
|
if (initialSearchValues && initialSearchValues.length > 0) {
|
||||||
|
const metadata = {};
|
||||||
const allOptions = await Promise.all(
|
const allOptions = await Promise.all(
|
||||||
initialSearchValues.map((v, index) => {
|
initialSearchValues.map((v, index) => {
|
||||||
return query(forID, collection, [field.get('valueField')], v, file, 1).then(
|
return query(forID, collection, [field.get('valueField')], v, file, 1).then(
|
||||||
({ payload }) => {
|
({ payload }) => {
|
||||||
const hits = payload.response?.hits || [];
|
const hits = payload.response?.hits || [];
|
||||||
const options = this.parseHitOptions(hits);
|
const options = this.parseHitOptions(hits);
|
||||||
|
metadata[v] = hits[0]?.data;
|
||||||
return { options, index };
|
return { options, index };
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -127,6 +128,13 @@ export default class RelationControl extends React.Component {
|
|||||||
...sortBy(allOptions, ({ index }) => index).map(({ options }) => options),
|
...sortBy(allOptions, ({ index }) => index).map(({ options }) => options),
|
||||||
);
|
);
|
||||||
this.mounted && this.setState({ initialOptions });
|
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;
|
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 => {
|
handleChange = selectedOption => {
|
||||||
const { onChange, field } = this.props;
|
const { onChange, field } = this.props;
|
||||||
let value;
|
let value;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { fromJS, Map } from 'immutable';
|
import { fromJS, Map } from 'immutable';
|
||||||
import { last } from 'lodash';
|
|
||||||
import { render, fireEvent, waitFor } from '@testing-library/react';
|
import { render, fireEvent, waitFor } from '@testing-library/react';
|
||||||
import { NetlifyCmsWidgetRelation } from '../';
|
import { NetlifyCmsWidgetRelation } from '../';
|
||||||
|
|
||||||
@ -85,6 +84,10 @@ const generateHits = length => {
|
|||||||
collection: 'posts',
|
collection: 'posts',
|
||||||
data: { title: 'YAML post', slug: 'post-yaml', body: 'Body yaml' },
|
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;
|
hits = nestedFileCollectionHits;
|
||||||
} else if (file === 'simple_file') {
|
} else if (file === 'simple_file') {
|
||||||
hits = simpleFileCollectionHits;
|
hits = simpleFileCollectionHits;
|
||||||
} else if (term === 'YAML') {
|
} else if (term === 'JSON post') {
|
||||||
hits = [last(queryHits)];
|
hits = [queryHits[queryHits.length - 1]];
|
||||||
} else if (term === 'Nested') {
|
} else if (term === 'YAML' || term === 'YAML post') {
|
||||||
hits = [queryHits[queryHits.length - 2]];
|
hits = [queryHits[queryHits.length - 2]];
|
||||||
} else if (term === 'Deeply nested') {
|
} else if (term === 'Nested') {
|
||||||
hits = [queryHits[queryHits.length - 3]];
|
hits = [queryHits[queryHits.length - 3]];
|
||||||
|
} else if (term === 'Deeply nested') {
|
||||||
|
hits = [queryHits[queryHits.length - 4]];
|
||||||
}
|
}
|
||||||
|
|
||||||
hits = hits.slice(0, optionsLength);
|
hits = hits.slice(0, optionsLength);
|
||||||
@ -411,24 +416,23 @@ describe('Relation widget', () => {
|
|||||||
|
|
||||||
it('should update metadata for initial preview', async () => {
|
it('should update metadata for initial preview', async () => {
|
||||||
const field = fromJS({ ...fieldConfig, multiple: true });
|
const field = fromJS({ ...fieldConfig, multiple: true });
|
||||||
const value = fromJS(['Post # 1', 'Post # 2']);
|
const value = fromJS(['YAML post', 'JSON post']);
|
||||||
const { getByText, onChangeSpy, setQueryHitsSpy } = setup({ field, value });
|
const { getByText, onChangeSpy } = setup({ field, value });
|
||||||
const metadata1 = {
|
const metadata = {
|
||||||
post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } },
|
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(() => {
|
await waitFor(() => {
|
||||||
expect(getByText('Post # 1 post-number-1')).toBeInTheDocument();
|
expect(getByText('YAML post post-yaml')).toBeInTheDocument();
|
||||||
expect(getByText('Post # 2 post-number-2')).toBeInTheDocument();
|
expect(getByText('JSON post post-json')).toBeInTheDocument();
|
||||||
|
|
||||||
expect(onChangeSpy).toHaveBeenCalledTimes(2);
|
expect(onChangeSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(onChangeSpy).toHaveBeenCalledWith(value, metadata1);
|
expect(onChangeSpy).toHaveBeenCalledWith(value, metadata);
|
||||||
expect(onChangeSpy).toHaveBeenCalledWith(value, metadata2);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user