update LabelSelect to use PF Select component

This commit is contained in:
Keith Grant 2020-01-07 15:20:25 -08:00
parent f923f07b79
commit 79f0f1940f

View File

@ -1,8 +1,17 @@
import React, { useState, useEffect } from 'react';
import { func, arrayOf, number, shape, string, oneOfType } from 'prop-types';
import MultiSelect from '@components/MultiSelect';
import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
import { LabelsAPI } from '@api';
function setToString(labels) {
labels.forEach(label => {
label.toString = function toString() {
return this.id;
};
});
return labels;
}
async function loadLabelOptions(setLabels, onError) {
let labels;
try {
@ -11,7 +20,7 @@ async function loadLabelOptions(setLabels, onError) {
page_size: 200,
order_by: 'name',
});
labels = data.results;
labels = setToString(data.results);
setLabels(labels);
if (data.next && data.next.includes('page=2')) {
const {
@ -21,31 +30,71 @@ async function loadLabelOptions(setLabels, onError) {
page_size: 200,
order_by: 'name',
});
labels = labels.concat(results);
setLabels(labels.concat(setToString(results)));
}
setLabels(labels);
} catch (err) {
onError(err);
}
}
function LabelSelect({ value, onChange, onError }) {
function LabelSelect({ value, placeholder, onChange, onError }) {
const [options, setOptions] = useState([]);
const [currentValue, setCurrentValue] = useState([]);
const [isExpanded, setIsExpanded] = useState(false);
const toggleExpanded = () => {
setIsExpanded(!isExpanded);
};
const handleSelect = (event, item) => {
if (currentValue.includes(item)) {
onChange(currentValue.filter(i => i.id !== item.id));
} else {
onChange(currentValue.concat(item));
}
};
useEffect(() => {
loadLabelOptions(setOptions, onError);
}, [onError]);
useEffect(() => {
if (value !== currentValue && options.length) {
const syncedValue = value.map(item =>
options.find(i => i.id === item.id)
);
setCurrentValue(syncedValue);
}
/* eslint-disable-next-line react-hooks/exhaustive-deps */
}, [value, options]);
const renderOptions = opts => {
return opts.map(option => (
<SelectOption key={option.id} value={option}>
{option.name}
</SelectOption>
));
};
return (
<MultiSelect
onChange={onChange}
value={value}
options={options}
createNewItem={name => ({
id: name,
name,
isNew: true,
})}
/>
<Select
variant={SelectVariant.typeaheadMulti}
aria-label="Select a state"
onToggle={toggleExpanded}
onSelect={handleSelect}
onClear={() => onChange([])}
onFilter={event => {
const str = event.target.value.toLowerCase();
const matches = options.filter(o => o.name.toLowerCase().includes(str));
return renderOptions(matches);
}}
selections={options.length ? setToString(currentValue) : []}
isExpanded={isExpanded}
ariaLabelledBy="label-select"
placeholderText={placeholder}
>
{renderOptions(options)}
</Select>
);
}
LabelSelect.propTypes = {
@ -55,7 +104,12 @@ LabelSelect.propTypes = {
name: string.isRequired,
})
).isRequired,
placeholder: string,
onChange: func.isRequired,
onError: func.isRequired,
};
LabelSelect.defaultProps = {
placeholder: '',
};
export default LabelSelect;