mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 07:03:38 +00:00
Fixes #959
This commit is contained in:
parent
02dac8e579
commit
5a9e9ef53b
@ -8,7 +8,7 @@ import React from 'react';
|
||||
import Select from 'react-select';
|
||||
import PropTypes from 'prop-types';
|
||||
import 'react-select/dist/react-select.css';
|
||||
import { isArray, isNull, isUndefined, get, findIndex } from 'lodash';
|
||||
import { cloneDeep, isArray, isNull, isUndefined, get, findIndex, includes } from 'lodash';
|
||||
|
||||
import request from 'utils/request';
|
||||
import templateObject from 'utils/templateObject';
|
||||
@ -22,17 +22,32 @@ class SelectMany extends React.Component {
|
||||
|
||||
this.state = {
|
||||
isLoading: true,
|
||||
options: [],
|
||||
toSkip: 0,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getOptions('');
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (prevState.toSkip !== this.state.toSkip) {
|
||||
this.getOptions('');
|
||||
}
|
||||
}
|
||||
|
||||
getOptions = query => {
|
||||
const params = {
|
||||
_limit: 20,
|
||||
limit: 20,
|
||||
skip: this.state.toSkip,
|
||||
source: this.props.relation.plugin || 'content-manager',
|
||||
};
|
||||
|
||||
// Set `query` parameter if necessary
|
||||
if (query) {
|
||||
delete params.limit,
|
||||
delete params.skip,
|
||||
params[`${this.props.relation.displayedAttribute}_contains`] = query;
|
||||
}
|
||||
|
||||
@ -63,7 +78,18 @@ class SelectMany extends React.Component {
|
||||
},
|
||||
];
|
||||
|
||||
return { options };
|
||||
const newOptions = cloneDeep(this.state.options);
|
||||
options.map(option => {
|
||||
// Don't add the values when searching
|
||||
if (findIndex(newOptions, o => o.value.id === option.value.id) === -1) {
|
||||
return newOptions.push(option);
|
||||
}
|
||||
});
|
||||
|
||||
return this.setState({
|
||||
options: newOptions,
|
||||
isLoading: false,
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
strapi.notification.error('content-manager.notification.error.relationship.fetch');
|
||||
@ -72,7 +98,7 @@ class SelectMany extends React.Component {
|
||||
|
||||
handleChange = value => {
|
||||
const filteredValue = value.filter(
|
||||
(data, index) => findIndex(value, o => o.value.id === data.value.id) === index,
|
||||
(data, index) => findIndex(value, o => o.value.id === data.value.id) === index
|
||||
);
|
||||
const target = {
|
||||
name: `record.${this.props.relation.alias}`,
|
||||
@ -83,6 +109,23 @@ class SelectMany extends React.Component {
|
||||
this.props.setRecordAttribute({ target });
|
||||
};
|
||||
|
||||
handleBottomScroll = () => {
|
||||
this.setState(prevState => {
|
||||
return {
|
||||
toSkip: prevState.toSkip + 20,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
handleInputChange = (value) => {
|
||||
const clonedOptions = this.state.options;
|
||||
const filteredValues = clonedOptions.filter(data => includes(data.label, value));
|
||||
|
||||
if (filteredValues.length === 0) {
|
||||
return this.getOptions(value);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const description = this.props.relation.description ? (
|
||||
<p>{this.props.relation.description}</p>
|
||||
@ -96,10 +139,13 @@ class SelectMany extends React.Component {
|
||||
<div className={`form-group ${styles.selectMany}`}>
|
||||
<label htmlFor={this.props.relation.alias}>{this.props.relation.alias}</label>
|
||||
{description}
|
||||
<Select.Async
|
||||
<Select
|
||||
onChange={this.handleChange}
|
||||
loadOptions={this.getOptions}
|
||||
options={this.state.options}
|
||||
id={this.props.relation.alias}
|
||||
isLoading={this.state.isLoading}
|
||||
onMenuScrollToBottom={this.handleBottomScroll}
|
||||
onInputChange={this.handleInputChange}
|
||||
multi
|
||||
value={
|
||||
isNull(value) || isUndefined(value) || value.size === 0
|
||||
|
||||
@ -8,7 +8,7 @@ import React from 'react';
|
||||
import Select from 'react-select';
|
||||
import PropTypes from 'prop-types';
|
||||
import 'react-select/dist/react-select.css';
|
||||
import { map, isArray, isNull, isUndefined, isFunction, get } from 'lodash';
|
||||
import { cloneDeep, map, includes, isArray, isNull, isUndefined, isFunction, get, findIndex } from 'lodash';
|
||||
|
||||
import request from 'utils/request';
|
||||
import templateObject from 'utils/templateObject';
|
||||
@ -21,17 +21,32 @@ class SelectOne extends React.Component { // eslint-disable-line react/prefer-st
|
||||
|
||||
this.state = {
|
||||
isLoading: true,
|
||||
options: [],
|
||||
toSkip: 0,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getOptions('');
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (prevState.toSkip !== this.state.toSkip) {
|
||||
this.getOptions('');
|
||||
}
|
||||
}
|
||||
|
||||
getOptions = (query) => {
|
||||
const params = {
|
||||
_limit: 20,
|
||||
limit: 20,
|
||||
skip: this.state.toSkip,
|
||||
source: this.props.relation.plugin || 'content-manager',
|
||||
};
|
||||
|
||||
// Set `query` parameter if necessary
|
||||
if (query) {
|
||||
delete params.limit,
|
||||
delete params.skip,
|
||||
params[`${this.props.relation.displayedAttribute}_contains`] = query;
|
||||
}
|
||||
|
||||
@ -55,7 +70,18 @@ class SelectOne extends React.Component { // eslint-disable-line react/prefer-st
|
||||
label: templateObject({ mainField: this.props.relation.displayedAttribute }, response).mainField,
|
||||
}];
|
||||
|
||||
return { options };
|
||||
const newOptions = cloneDeep(this.state.options);
|
||||
options.map(option => {
|
||||
// Don't add the values when searching
|
||||
if (findIndex(newOptions, o => o.value.id === option.value.id) === -1) {
|
||||
return newOptions.push(option);
|
||||
}
|
||||
});
|
||||
|
||||
return this.setState({
|
||||
options: newOptions,
|
||||
isLoading: false,
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
strapi.notification.error('content-manager.notification.relationship.fetch');
|
||||
@ -72,6 +98,23 @@ class SelectOne extends React.Component { // eslint-disable-line react/prefer-st
|
||||
this.props.setRecordAttribute({ target });
|
||||
}
|
||||
|
||||
handleBottomScroll = () => {
|
||||
this.setState(prevState => {
|
||||
return {
|
||||
toSkip: prevState.toSkip + 20,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
handleInputChange = (value) => {
|
||||
const clonedOptions = this.state.options;
|
||||
const filteredValues = clonedOptions.filter(data => includes(data.label, value));
|
||||
|
||||
if (filteredValues.length === 0) {
|
||||
return this.getOptions(value);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const description = this.props.relation.description
|
||||
? <p>{this.props.relation.description}</p>
|
||||
@ -84,9 +127,12 @@ class SelectOne extends React.Component { // eslint-disable-line react/prefer-st
|
||||
<div className={`form-group ${styles.selectOne}`}>
|
||||
<label htmlFor={this.props.relation.alias}>{this.props.relation.alias}</label>
|
||||
{description}
|
||||
<Select.Async
|
||||
<Select
|
||||
onChange={this.handleChange}
|
||||
loadOptions={this.getOptions}
|
||||
options={this.state.options}
|
||||
isLoading={this.state.isLoading}
|
||||
onMenuScrollToBottom={this.handleBottomScroll}
|
||||
onInputChange={this.handleInputChange}
|
||||
simpleValue
|
||||
value={isNull(value) || isUndefined(value) ? null : {
|
||||
value: isFunction(value.toJS) ? value.toJS() : value,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user