diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c25110a1e4..621d401224c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Event entities should only be linked for true labels - Radio button hover effect #9031 - Prevent form submission unless action was taken (IP transfer & IP sharing modals) #5976 +- Inability to edit and save Linode Configurations #9053 ### Tech Stories: - MUIv5 Migration - Components > CircleProgress #9028 diff --git a/packages/api-v4/src/linodes/types.ts b/packages/api-v4/src/linodes/types.ts index c0832fbc4bc..77e1aba696e 100644 --- a/packages/api-v4/src/linodes/types.ts +++ b/packages/api-v4/src/linodes/types.ts @@ -149,10 +149,14 @@ export type LinodeStatus = export type InterfacePurpose = 'public' | 'vlan'; export interface Interface { + id: number; label: string | null; purpose: InterfacePurpose; ipam_address: string | null; } + +export type InterfacePayload = Omit; + export interface Config { id: number; kernel: string; @@ -261,7 +265,7 @@ export interface LinodeConfigCreationData { devtmpfs_automount: boolean; }; root_device: string; - interfaces?: Interface[]; + interfaces?: InterfacePayload[]; } export interface PriceObject { diff --git a/packages/manager/src/factories/linodeConfigInterfaceFactory.ts b/packages/manager/src/factories/linodeConfigInterfaceFactory.ts index 20a3bf30408..68506f4ecdd 100644 --- a/packages/manager/src/factories/linodeConfigInterfaceFactory.ts +++ b/packages/manager/src/factories/linodeConfigInterfaceFactory.ts @@ -3,6 +3,7 @@ import { Interface } from '@linode/api-v4/lib/linodes/types'; export const LinodeConfigInterfaceFactory = Factory.Sync.makeFactory( { + id: Factory.each((i) => i), label: Factory.each((i) => `interface-${i}`), purpose: 'vlan', ipam_address: '10.0.0.1/24', diff --git a/packages/manager/src/features/linodes/LinodesCreate/LinodeCreate.tsx b/packages/manager/src/features/linodes/LinodesCreate/LinodeCreate.tsx index 30712691ebb..7da0da6494f 100644 --- a/packages/manager/src/features/linodes/LinodesCreate/LinodeCreate.tsx +++ b/packages/manager/src/features/linodes/LinodesCreate/LinodeCreate.tsx @@ -1,4 +1,4 @@ -import { Interface, restoreBackup } from '@linode/api-v4/lib/linodes'; +import { InterfacePayload, restoreBackup } from '@linode/api-v4/lib/linodes'; import { Tag } from '@linode/api-v4/lib/tags/types'; import { Theme } from '@mui/material/styles'; import { createStyles, withStyles, WithStyles } from '@mui/styles'; @@ -151,7 +151,7 @@ interface Props { showGeneralError?: boolean; vlanLabel: string | null; ipamAddress: string | null; - handleVLANChange: (updatedInterface: Interface) => void; + handleVLANChange: (updatedInterface: InterfacePayload) => void; showAgreement: boolean; showApiAwarenessModal: boolean; handleAgreementChange: () => void; @@ -870,7 +870,7 @@ export class LinodeCreate extends React.PureComponent< } } -const defaultPublicInterface: Interface = { +const defaultPublicInterface: InterfacePayload = { purpose: 'public', label: '', ipam_address: '', diff --git a/packages/manager/src/features/linodes/LinodesDetail/LinodeSettings/InterfaceSelect.tsx b/packages/manager/src/features/linodes/LinodesDetail/LinodeSettings/InterfaceSelect.tsx index 0569ec07eeb..b6966d1b525 100644 --- a/packages/manager/src/features/linodes/LinodesDetail/LinodeSettings/InterfaceSelect.tsx +++ b/packages/manager/src/features/linodes/LinodesDetail/LinodeSettings/InterfaceSelect.tsx @@ -1,4 +1,7 @@ -import { Interface, InterfacePurpose } from '@linode/api-v4/lib/linodes/types'; +import { + InterfacePayload, + InterfacePurpose, +} from '@linode/api-v4/lib/linodes/types'; import * as React from 'react'; import Divider from 'src/components/core/Divider'; import { makeStyles } from '@mui/styles'; @@ -32,7 +35,7 @@ export interface Props { // To allow for empty slots, which the API doesn't account for export type ExtendedPurpose = InterfacePurpose | 'none'; -export interface ExtendedInterface extends Omit { +export interface ExtendedInterface extends Omit { purpose: ExtendedPurpose; } diff --git a/packages/manager/src/features/linodes/LinodesDetail/LinodeSettings/LinodeConfigDialog.tsx b/packages/manager/src/features/linodes/LinodesDetail/LinodeSettings/LinodeConfigDialog.tsx index c26acb74f20..0a3928edace 100644 --- a/packages/manager/src/features/linodes/LinodesDetail/LinodeSettings/LinodeConfigDialog.tsx +++ b/packages/manager/src/features/linodes/LinodesDetail/LinodeSettings/LinodeConfigDialog.tsx @@ -196,7 +196,10 @@ const interfacesToState = (interfaces?: Interface[]) => { if (!interfaces || interfaces.length === 0) { return defaultInterfaceList; } - return padInterfaceList(interfaces); + const interfacesPayload = interfaces.map( + ({ ipam_address, label, purpose }) => ({ ipam_address, label, purpose }) + ); + return padInterfaceList(interfacesPayload); }; const interfacesToPayload = (interfaces?: ExtendedInterface[]) => { @@ -425,6 +428,7 @@ const LinodeConfigDialog: React.FC = (props) => { (thisOption) => thisOption.value === config?.root_device ) ); + resetForm({ values: { useCustomRoot: isUsingCustomRoot(config.root_device),