Skip to content

Commit

Permalink
refactor: [M3-6903] - Replace Select with Autocomplete in: volumes (#…
Browse files Browse the repository at this point in the history
…10437)

* change: [M3-6903] - Replace instances in: volumes

* Replace Select with Autocomplete

* Reuse ConfigSelect in AttachVolumeDrawer

* Added changeset: Replace Select with Autocomplete in: volumes

* PR feedback: @bnussman @DevDW @HanaXu

* code cleanup
  • Loading branch information
cpathipa authored May 30, 2024
1 parent 1a1067b commit 5561201
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tech Stories
---

Replace Select with Autocomplete in: volumes ([#10437](https://github.com/linode/manager/pull/10437))
76 changes: 33 additions & 43 deletions packages/manager/src/features/Volumes/AttachVolumeDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { Volume } from '@linode/api-v4';
import { styled } from '@mui/material/styles';
import { useFormik } from 'formik';
import { useSnackbar } from 'notistack';
import * as React from 'react';
import { number, object } from 'yup';

import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel';
import { Drawer } from 'src/components/Drawer';
import Select, { Item } from 'src/components/EnhancedSelect';
import { FormControl } from 'src/components/FormControl';
import { FormHelperText } from 'src/components/FormHelperText';
import { Notice } from 'src/components/Notice/Notice';
import { LinodeSelect } from 'src/features/Linodes/LinodeSelect/LinodeSelect';
import { useEventsPollingActions } from 'src/queries/events/events';
import { useAllLinodeConfigsQuery } from 'src/queries/linodes/configs';
import { useGrants } from 'src/queries/profile';
import { useAttachVolumeMutation } from 'src/queries/volumes/volumes';
import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor';

import { ConfigSelect } from './VolumeDrawer/ConfigSelect';

interface Props {
onClose: () => void;
open: boolean;
Expand Down Expand Up @@ -58,27 +58,10 @@ export const AttachVolumeDrawer = React.memo((props: Props) => {
});
},
validateOnBlur: false,
validateOnChange: false,
validateOnChange: true,
validationSchema: AttachVolumeValidationSchema,
});

const { data, isLoading: configsLoading } = useAllLinodeConfigsQuery(
formik.values.linode_id,
formik.values.linode_id !== -1
);

const configs = data ?? [];

const configChoices = configs.map((config) => {
return { label: config.label, value: `${config.id}` };
});

React.useEffect(() => {
if (configs.length === 1) {
formik.setFieldValue('config_id', configs[0].id);
}
}, [configs]);

const reset = () => {
formik.resetForm();
};
Expand Down Expand Up @@ -121,14 +104,18 @@ export const AttachVolumeDrawer = React.memo((props: Props) => {
)}
{generalError && <Notice text={generalError} variant="error" />}
<LinodeSelect
errorText={
formik.touched.linode_id && formik.errors.linode_id
? formik.errors.linode_id
: linodeError
}
onSelectionChange={(linode) => {
if (linode !== null) {
formik.setFieldValue('linode_id', linode.id);
}
}}
clearable={false}
disabled={isReadOnly}
errorText={formik.errors.linode_id ?? linodeError}
filter={{ region: volume?.region }}
noMarginTop
value={formik.values.linode_id}
Expand All @@ -138,27 +125,24 @@ export const AttachVolumeDrawer = React.memo((props: Props) => {
Only Linodes in this Volume&rsquo;s region are displayed.
</FormHelperText>
)}
{/* Config Selection */}
<FormControl fullWidth>
<Select
onChange={(item: Item<string>) =>
formik.setFieldValue('config_id', Number(item.value))
}
value={configChoices.find(
(item) => item.value === String(formik.values.config_id)
)}
disabled={isReadOnly || formik.values.linode_id === -1}
errorText={formik.errors.config_id ?? configError}
id="config_id"
isClearable={false}
isLoading={configsLoading}
label="Config"
name="config_id"
noMarginTop
options={configChoices}
placeholder="Select a Config"
/>
</FormControl>
<StyledConfigSelect
error={
formik.touched.config_id && formik.errors.config_id
? formik.errors.config_id
: configError
}
linodeId={
formik.values.linode_id === -1 ? null : formik.values.linode_id
}
onChange={(id: number) => {
formik.setFieldValue('config_id', +id);
}}
disabled={isReadOnly || formik.values.linode_id === -1}
name="configId"
onBlur={() => null}
value={formik.values.config_id}
/>

<ActionsPanel
primaryButtonProps={{
'data-testid': 'submit',
Expand All @@ -177,3 +161,9 @@ export const AttachVolumeDrawer = React.memo((props: Props) => {
</Drawer>
);
});

const StyledConfigSelect = styled(ConfigSelect, {
label: 'StyledConfigSelect',
})(() => ({
p: { marginLeft: 0 },
}));
2 changes: 1 addition & 1 deletion packages/manager/src/features/Volumes/VolumeCreate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ export const VolumeCreate = () => {
)}
</Box>
<ConfigSelect
disabled={doesNotHavePermission}
disabled={doesNotHavePermission || config_id === null}
error={touched.config_id ? errors.config_id : undefined}
linodeId={linode_id}
name="configId"
Expand Down
33 changes: 16 additions & 17 deletions packages/manager/src/features/Volumes/VolumeDrawer/ConfigSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';

import Select, { Item } from 'src/components/EnhancedSelect/Select';
import { Autocomplete } from 'src/components/Autocomplete/Autocomplete';
import { FormControl } from 'src/components/FormControl';
import { useAllLinodeConfigsQuery } from 'src/queries/linodes/configs';

Expand Down Expand Up @@ -43,39 +43,38 @@ export const ConfigSelect = React.memo((props: Props) => {
}
}

if (linodeId === null) {
return null;
}

return (
<FormControl
fullWidth={width ? false : true}
style={{ marginTop: 20, width }}
>
<Select
<Autocomplete
errorText={
error ?? configsError
? 'An error occurred while retrieving configs for this Linode.'
: undefined
}
noOptionsMessage={
() =>
!configs || configs.length == 0
? 'No configs are available for this Linode.'
: 'No options.' // No matches for search
noOptionsText={
!configs || configs.length == 0
? 'No configs are available for this Linode.'
: 'No options.'
}
onChange={(e: Item<number>) => {
onChange(+e.value);
onChange={(_, selected) => {
onChange(+selected.value);
}}
value={
value && value !== -1
? configList?.find((thisConfig) => thisConfig.value === value)
: { label: '', value: -1 }
}
disableClearable
id={name}
isClearable={false}
isOptionEqualToValue={(option, value) => option.value === value.value}
label="Config"
name={name}
noMarginTop
onBlur={onBlur}
options={configList}
options={configList ?? []}
placeholder="Select a Config"
value={configList?.find((thisConfig) => thisConfig.value === value)}
{...rest}
/>
</FormControl>
Expand Down

0 comments on commit 5561201

Please sign in to comment.