simplifies react select pattern

This commit is contained in:
James
2020-01-26 21:54:48 -05:00
parent ded81a3997
commit 49741f3003
3 changed files with 32 additions and 29 deletions

View File

@@ -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}

View File

@@ -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}

View File

@@ -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,