diff --git a/packages/manager/.changeset/pr-11007-fixed-1727295720802.md b/packages/manager/.changeset/pr-11007-fixed-1727295720802.md new file mode 100644 index 00000000000..d7da0fae5e6 --- /dev/null +++ b/packages/manager/.changeset/pr-11007-fixed-1727295720802.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Fixed +--- + +Value selection issue in ImageSelect ([#11007](https://github.com/linode/manager/pull/11007)) diff --git a/packages/manager/src/features/Images/ImageSelect.tsx b/packages/manager/src/features/Images/ImageSelect.tsx index 6bbd7435f7a..a13dc0cfa42 100644 --- a/packages/manager/src/features/Images/ImageSelect.tsx +++ b/packages/manager/src/features/Images/ImageSelect.tsx @@ -67,11 +67,11 @@ export const ImageSelect = (props: MultiProps | Props) => { }} > { + onChange={(_, value) => { if (isMulti && Array.isArray(value)) { onSelect((value ?? []) as Image[]); } else if (!isMulti) { - onSelect(value as Image); + onSelect((value as Image) ?? null); } }} textFieldProps={{ @@ -80,8 +80,9 @@ export const ImageSelect = (props: MultiProps | Props) => { }} value={ isMulti - ? options.filter((o) => value?.includes(o.id)) ?? [] - : options.find((o) => o.id === value) ?? null + ? options.filter((option) => value?.includes(option.id)) ?? [] + : options.find((option) => option.id === value) ?? + (value ? null : undefined) } disableCloseOnSelect={false} disableSelectAll @@ -97,5 +98,3 @@ export const ImageSelect = (props: MultiProps | Props) => { ); }; - -export default ImageSelect; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/ImageAndPassword.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/ImageAndPassword.tsx index ef341b06ae1..9a7a5ac9c4e 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/ImageAndPassword.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/ImageAndPassword.tsx @@ -15,7 +15,7 @@ interface Props { authorizedUsers: string[]; imageFieldError?: string; linodeId: number; - onImageChange: (selected: Image) => void; + onImageChange: (image: Image) => void; onPasswordChange: (password: string) => void; password: string; passwordError?: string; @@ -38,6 +38,7 @@ export const ImageAndPassword = (props: Props) => { const { data: profile } = useProfile(); const { data: imagesData, error: imagesError } = useAllImagesQuery(); + const _imagesError = imagesError ? getAPIErrorOrDefault(imagesError, 'Unable to load Images')[0]?.reason : undefined; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/CreateDiskDrawer.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/CreateDiskDrawer.tsx index debb1f4dd72..2d0aee0b60a 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/CreateDiskDrawer.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/CreateDiskDrawer.tsx @@ -1,4 +1,3 @@ -import { Disk, Linode } from '@linode/api-v4/lib/linodes'; import { CreateLinodeDiskFromImageSchema, CreateLinodeDiskSchema, @@ -12,7 +11,7 @@ import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Drawer } from 'src/components/Drawer'; import { FormHelperText } from 'src/components/FormHelperText'; import { InputAdornment } from 'src/components/InputAdornment'; -import { Mode, ModeSelect } from 'src/components/ModeSelect/ModeSelect'; +import { ModeSelect } from 'src/components/ModeSelect/ModeSelect'; import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useEventsPollingActions } from 'src/queries/events/events'; @@ -26,6 +25,8 @@ import { handleAPIErrors } from 'src/utilities/formikErrorUtils'; import { ImageAndPassword } from '../LinodeSettings/ImageAndPassword'; import type { Image } from '@linode/api-v4'; +import type { Disk, Linode } from '@linode/api-v4/lib/linodes'; +import type { Mode } from 'src/components/ModeSelect/ModeSelect'; type FileSystem = 'ext3' | 'ext4' | 'initrd' | 'raw' | 'swap'; @@ -172,8 +173,8 @@ export const CreateDiskDrawer = (props: Props) => { imageFieldError={ formik.touched.image ? formik.errors.image : undefined } - onImageChange={(selected: Image) => - formik.setFieldValue('image', selected?.id ?? null) + onImageChange={(image: Image) => + formik.setFieldValue('image', image?.id ?? null) } onPasswordChange={(root_pass: string) => formik.setFieldValue('root_pass', root_pass) diff --git a/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.tsx b/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.tsx index 0f0d68a2a1d..5a736e413ec 100644 --- a/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.tsx +++ b/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.tsx @@ -5,7 +5,7 @@ import { InputAdornment } from 'src/components/InputAdornment'; import { Paper } from 'src/components/Paper'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; -import ImageSelect from 'src/features/Images/ImageSelect'; +import { ImageSelect } from 'src/features/Images/ImageSelect'; import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor'; import { @@ -174,5 +174,3 @@ export const StackScriptForm = React.memo((props: Props) => { ); }); - -export default React.memo(StackScriptForm); diff --git a/packages/validation/.changeset/pr-11007-changed-1727366867981.md b/packages/validation/.changeset/pr-11007-changed-1727366867981.md new file mode 100644 index 00000000000..8dffd7546c0 --- /dev/null +++ b/packages/validation/.changeset/pr-11007-changed-1727366867981.md @@ -0,0 +1,5 @@ +--- +"@linode/validation": Changed +--- + +Update validation schema to account for clearing value in ImageSelect ([#11007](https://github.com/linode/manager/pull/11007)) diff --git a/packages/validation/src/linodes.schema.ts b/packages/validation/src/linodes.schema.ts index 8fe805e134a..712b534098a 100644 --- a/packages/validation/src/linodes.schema.ts +++ b/packages/validation/src/linodes.schema.ts @@ -518,6 +518,8 @@ export const UpdateLinodeDiskSchema = object({ export const CreateLinodeDiskFromImageSchema = CreateLinodeDiskSchema.clone().shape( { - image: string().required('An image is required.'), + image: string() + .required('An image is required.') + .typeError('An image is required.'), } );