simplifies react select pattern
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import React, { Component, useState, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Cookies from 'universal-cookie';
|
||||
import some from 'async-some';
|
||||
import ReactSelect from '../../../modules/ReactSelect';
|
||||
import useFieldType from '../../useFieldType';
|
||||
import getSanitizedConfig from '../../../../config/getSanitizedConfig';
|
||||
import Label from '../../Label';
|
||||
import Error from '../../Error';
|
||||
import some from 'async-some';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -28,8 +28,9 @@ class Relationship extends Component {
|
||||
|
||||
this.state = {
|
||||
relations,
|
||||
search: '',
|
||||
lastFullyLoadedRelation: -1,
|
||||
lastPageLoaded: 1,
|
||||
lastLoadedPage: 1,
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
@@ -39,14 +40,14 @@ class Relationship extends Component {
|
||||
}
|
||||
|
||||
getNextOptions = () => {
|
||||
const { relations, lastFullyLoadedRelation, lastPageLoaded } = this.state;
|
||||
const { relations, lastFullyLoadedRelation, lastLoadedPage } = this.state;
|
||||
const token = cookies.get('token');
|
||||
|
||||
const relationsToSearch = relations.slice(lastFullyLoadedRelation + 1);
|
||||
|
||||
if (relationsToSearch.length > 0) {
|
||||
some(relationsToSearch, async (relation, callback) => {
|
||||
const response = await fetch(`${serverURL}/${relation}?limit=${maxResultsPerRequest}&page=${lastPageLoaded}`, {
|
||||
const response = await fetch(`${serverURL}/${relation}?limit=${maxResultsPerRequest}&page=${lastLoadedPage}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
@@ -71,7 +72,7 @@ class Relationship extends Component {
|
||||
this.addOptions(data, relation);
|
||||
this.setState({
|
||||
lastFullyLoadedRelation: relations.indexOf(relation),
|
||||
lastPageLoaded: 1,
|
||||
lastLoadedPage: 1,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -118,12 +119,13 @@ class Relationship extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
return foundValue;
|
||||
return foundValue || null;
|
||||
}
|
||||
|
||||
addOptions = (data, relation) => {
|
||||
const { hasMultipleRelations } = this.props;
|
||||
const { lastPageLoaded, options } = this.state;
|
||||
const { lastLoadedPage, options } = this.state;
|
||||
const collection = collections.find(collection => collection.slug === relation);
|
||||
|
||||
if (!hasMultipleRelations) {
|
||||
this.setState({
|
||||
@@ -137,7 +139,6 @@ class Relationship extends Component {
|
||||
});
|
||||
} else {
|
||||
const allOptionGroups = [...options];
|
||||
const collection = collections.find(collection => collection.slug === relation);
|
||||
const optionsToAddTo = allOptionGroups.find(optionGroup => optionGroup.label === collection.labels.plural);
|
||||
|
||||
const newOptions = data.docs.map((doc) => {
|
||||
@@ -170,12 +171,17 @@ class Relationship extends Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
lastPageLoaded: lastPageLoaded + 1,
|
||||
lastLoadedPage: lastLoadedPage + 1,
|
||||
});
|
||||
}
|
||||
|
||||
handleInputChange = (search) => {
|
||||
this.setState({
|
||||
search
|
||||
})
|
||||
}
|
||||
|
||||
handleMenuScrollToBottom = () => {
|
||||
const { lastPageLoaded, lastFullyLoadedRelation } = this.state;
|
||||
this.getNextOptions();
|
||||
}
|
||||
|
||||
@@ -205,6 +211,8 @@ class Relationship extends Component {
|
||||
// eslint-disable-next-line prefer-template
|
||||
const fieldWidth = width ? width + '%' : null;
|
||||
|
||||
const valueToRender = this.findValueInOptions(options, value);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes}
|
||||
@@ -223,11 +231,12 @@ class Relationship extends Component {
|
||||
required={required}
|
||||
/>
|
||||
<ReactSelect
|
||||
onInputChange={this.handleInputChange}
|
||||
onChange={onFieldChange}
|
||||
formatValue={this.formatSelectedValue}
|
||||
onMenuScrollToBottom={this.handleMenuScrollToBottom}
|
||||
findValueInOptions={this.findValueInOptions}
|
||||
value={value}
|
||||
value={valueToRender}
|
||||
showError={showError}
|
||||
disabled={formProcessing}
|
||||
options={options}
|
||||
|
||||
@@ -10,6 +10,14 @@ import './index.scss';
|
||||
const defaultError = 'Please make a selection.';
|
||||
const defaultValidate = value => value.length > 0;
|
||||
|
||||
const findValueToRender = (options, value, hasMany) => {
|
||||
if (hasMany && Array.isArray(value)) {
|
||||
return value.map(subValue => options.find(option => option.value === subValue));
|
||||
}
|
||||
|
||||
return options.find(option => option.value === value);
|
||||
};
|
||||
|
||||
const Select = (props) => {
|
||||
const {
|
||||
name,
|
||||
@@ -44,6 +52,8 @@ const Select = (props) => {
|
||||
|
||||
const fieldWidth = width ? `${width}%` : undefined;
|
||||
|
||||
const valueToRender = findValueToRender(options, value, hasMany);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes}
|
||||
@@ -62,15 +72,8 @@ const Select = (props) => {
|
||||
required={required}
|
||||
/>
|
||||
<ReactSelect
|
||||
findValueInOptions={(reactSelectOptions, reactSelectValue) => {
|
||||
if (hasMany && Array.isArray(reactSelectValue)) {
|
||||
return reactSelectValue.map(subValue => reactSelectOptions.find(option => option.value === subValue));
|
||||
}
|
||||
|
||||
return reactSelectOptions.find(option => option.value === reactSelectValue);
|
||||
}}
|
||||
onChange={onFieldChange}
|
||||
value={value}
|
||||
value={valueToRender}
|
||||
showError={showError}
|
||||
disabled={formProcessing}
|
||||
options={options}
|
||||
|
||||
@@ -14,7 +14,6 @@ const ReactSelect = (props) => {
|
||||
value,
|
||||
disabled,
|
||||
formatValue,
|
||||
findValueInOptions,
|
||||
} = props;
|
||||
|
||||
const classes = [
|
||||
@@ -22,16 +21,10 @@ const ReactSelect = (props) => {
|
||||
showError && 'react-select--error',
|
||||
].filter(Boolean).join(' ');
|
||||
|
||||
let valueToRender = value;
|
||||
|
||||
if (findValueInOptions && typeof findValueInOptions === 'function') {
|
||||
valueToRender = findValueInOptions(options, value);
|
||||
}
|
||||
|
||||
return (
|
||||
<Select
|
||||
{...props}
|
||||
value={valueToRender}
|
||||
value={value}
|
||||
onChange={(selected) => {
|
||||
if (formatValue) {
|
||||
onChange(formatValue(selected));
|
||||
@@ -78,7 +71,6 @@ ReactSelect.defaultProps = {
|
||||
showError: false,
|
||||
disabled: false,
|
||||
formatValue: null,
|
||||
findValueInOptions: null,
|
||||
};
|
||||
|
||||
ReactSelect.propTypes = {
|
||||
@@ -87,7 +79,6 @@ ReactSelect.propTypes = {
|
||||
PropTypes.array,
|
||||
PropTypes.shape({}),
|
||||
]),
|
||||
findValueInOptions: PropTypes.func,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
showError: PropTypes.bool,
|
||||
|
||||
Reference in New Issue
Block a user