mirror of
https://github.com/ansible/awx.git
synced 2026-01-16 12:20:45 -03:30
update LabelSelect to use PF Select component
This commit is contained in:
parent
f923f07b79
commit
79f0f1940f
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user