Wizard: Switch from deprecated select in ActivationKeys
This replaces a deprecated select in `ActivationKeys` for a non-deprecated one.
This commit is contained in:
parent
a34d5895d9
commit
0431ac98dc
4 changed files with 108 additions and 38 deletions
|
|
@ -4,14 +4,16 @@ import {
|
|||
Alert,
|
||||
FormGroup,
|
||||
Spinner,
|
||||
Select,
|
||||
SelectList,
|
||||
SelectOption,
|
||||
Text,
|
||||
TextContent,
|
||||
MenuToggleElement,
|
||||
MenuToggle,
|
||||
TextInputGroup,
|
||||
TextInputGroupMain,
|
||||
} from '@patternfly/react-core';
|
||||
import {
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
} from '@patternfly/react-core/deprecated';
|
||||
import { addNotification } from '@redhat-cloud-services/frontend-components-notifications/redux';
|
||||
|
||||
import ManageKeysButton from './components/ManageKeysButton';
|
||||
|
|
@ -43,6 +45,8 @@ const ActivationKeysList = () => {
|
|||
|
||||
const { isProd } = useGetEnvironment();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [inputValue, setInputValue] = useState<string>('');
|
||||
const [filterValue, setFilterValue] = useState<string>('');
|
||||
|
||||
const {
|
||||
data: activationKeys,
|
||||
|
|
@ -69,6 +73,36 @@ const ActivationKeysList = () => {
|
|||
}
|
||||
}, [dispatch, isProd]);
|
||||
|
||||
const [selectOptions, setSelectOptions] = useState<(string | undefined)[]>(
|
||||
activationKeys?.body ? activationKeys.body.map((key) => key.name) : []
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
let filteredKeys = activationKeys?.body?.map((key) => key.name);
|
||||
|
||||
if (filterValue) {
|
||||
filteredKeys = activationKeys?.body
|
||||
?.map((key) => key.name)
|
||||
.filter((keyName: string) =>
|
||||
String(keyName).toLowerCase().includes(filterValue.toLowerCase())
|
||||
);
|
||||
if (filteredKeys && !filteredKeys.length) {
|
||||
filteredKeys = [`No results found for "${filterValue}"`];
|
||||
}
|
||||
if (!isOpen) {
|
||||
setIsOpen(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredKeys) {
|
||||
setSelectOptions(filteredKeys);
|
||||
}
|
||||
|
||||
// This useEffect hook should run *only* on when the filter value changes.
|
||||
// eslint's exhaustive-deps rule does not support this use.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [filterValue]);
|
||||
|
||||
const setActivationKey = (
|
||||
_event: React.MouseEvent<Element, MouseEvent>,
|
||||
selection: string
|
||||
|
|
@ -136,18 +170,33 @@ const ActivationKeysList = () => {
|
|||
}
|
||||
}, [isSuccessActivationKeys]);
|
||||
|
||||
const setSelectOptions = () => {
|
||||
const selectOptions = [];
|
||||
const onTextInputChange = (_event: React.FormEvent, value: string) => {
|
||||
setInputValue(value);
|
||||
setFilterValue(value);
|
||||
|
||||
if (value !== activationKey) {
|
||||
dispatch(changeActivationKey(''));
|
||||
}
|
||||
};
|
||||
|
||||
const prepareSelectOptions = () => {
|
||||
const selectOptionsElement = [];
|
||||
|
||||
if (isSuccessActivationKeys) {
|
||||
activationKeys?.body?.map((key, index) =>
|
||||
selectOptions.push(<SelectOption key={index} value={key.name} />)
|
||||
selectOptions.map((key, index) =>
|
||||
selectOptionsElement.push(
|
||||
<SelectOption key={index} value={key}>
|
||||
{key}
|
||||
</SelectOption>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!isSuccessActivationKeys && isFetchingActivationKeys) {
|
||||
selectOptions.push(
|
||||
selectOptionsElement.push(
|
||||
<SelectOption
|
||||
key={'Fetching'}
|
||||
isNoResultsOption={true}
|
||||
key="Fetching"
|
||||
value="loader"
|
||||
data-testid="activation-keys-loading"
|
||||
>
|
||||
<Spinner size="md" />
|
||||
|
|
@ -155,9 +204,40 @@ const ActivationKeysList = () => {
|
|||
);
|
||||
}
|
||||
|
||||
return selectOptions;
|
||||
return selectOptionsElement;
|
||||
};
|
||||
|
||||
const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (
|
||||
<MenuToggle
|
||||
ref={toggleRef}
|
||||
variant="typeahead"
|
||||
onClick={handleToggle}
|
||||
isExpanded={isOpen}
|
||||
data-testid="activation-key-select"
|
||||
isDisabled={
|
||||
!isSuccessActivationKeys || registrationType === 'register-later'
|
||||
}
|
||||
ouiaId="activation_key_select"
|
||||
>
|
||||
<TextInputGroup isPlain>
|
||||
<TextInputGroupMain
|
||||
value={
|
||||
activationKey
|
||||
? registrationType === 'register-later'
|
||||
? ''
|
||||
: activationKey
|
||||
: inputValue
|
||||
}
|
||||
onClick={handleToggle}
|
||||
onChange={onTextInputChange}
|
||||
autoComplete="off"
|
||||
placeholder="Select activation key"
|
||||
isExpanded={isOpen}
|
||||
/>
|
||||
</TextInputGroup>
|
||||
</MenuToggle>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormGroup
|
||||
|
|
@ -169,21 +249,15 @@ const ActivationKeysList = () => {
|
|||
data-testid="subscription-activation-key"
|
||||
>
|
||||
<Select
|
||||
ouiaId="activation_key_select"
|
||||
variant={SelectVariant.typeahead}
|
||||
onToggle={handleToggle}
|
||||
onSelect={setActivationKey}
|
||||
selections={
|
||||
registrationType === 'register-later' ? '' : activationKey
|
||||
}
|
||||
isScrollable
|
||||
isOpen={isOpen}
|
||||
placeholderText="Select activation key"
|
||||
typeAheadAriaLabel="Select activation key"
|
||||
isDisabled={
|
||||
!isSuccessActivationKeys || registrationType === 'register-later'
|
||||
}
|
||||
selected={activationKey}
|
||||
onSelect={setActivationKey}
|
||||
onOpenChange={handleToggle}
|
||||
toggle={toggle}
|
||||
shouldFocusFirstItemOnOpen={false}
|
||||
>
|
||||
{setSelectOptions()}
|
||||
<SelectList>{prepareSelectOptions()}</SelectList>
|
||||
</Select>
|
||||
<TextContent>
|
||||
<Text>
|
||||
|
|
|
|||
|
|
@ -411,9 +411,7 @@ describe('Import modal', () => {
|
|||
'automatically-register-radio'
|
||||
);
|
||||
expect(registrationCheckbox).toHaveFocus();
|
||||
await screen.findByRole('textbox', {
|
||||
name: 'Select activation key',
|
||||
});
|
||||
await screen.findByPlaceholderText('Select activation key');
|
||||
|
||||
// OpenScap
|
||||
await clickNext();
|
||||
|
|
|
|||
|
|
@ -144,9 +144,7 @@ describe('Keyboard accessibility', () => {
|
|||
'automatically-register-radio'
|
||||
);
|
||||
expect(registrationCheckbox).toHaveFocus();
|
||||
await screen.findByRole('textbox', {
|
||||
name: 'Select activation key',
|
||||
});
|
||||
await screen.findByPlaceholderText('Select activation key');
|
||||
await clickNext();
|
||||
|
||||
// TODO: Focus on textbox on OpenSCAP step
|
||||
|
|
|
|||
|
|
@ -73,9 +73,9 @@ const deselectPredictiveAnalytics = async () => {
|
|||
|
||||
const openActivationKeyDropdown = async () => {
|
||||
const user = userEvent.setup();
|
||||
const activationKeyDropdown = await screen.findByRole('textbox', {
|
||||
name: 'Select activation key',
|
||||
});
|
||||
const activationKeyDropdown = await screen.findByPlaceholderText(
|
||||
'Select activation key'
|
||||
);
|
||||
user.click(activationKeyDropdown);
|
||||
};
|
||||
|
||||
|
|
@ -197,9 +197,9 @@ describe('Step Registration', () => {
|
|||
).not.toBeInTheDocument()
|
||||
);
|
||||
await waitFor(async () =>
|
||||
expect(
|
||||
await screen.findByRole('button', { name: /options menu/i })
|
||||
).toBeDisabled()
|
||||
expect(await screen.findByTestId('activation-key-select')).toHaveClass(
|
||||
'pf-m-disabled'
|
||||
)
|
||||
);
|
||||
await goToReviewStep();
|
||||
await screen.findByText('Register the system later');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue