From 72173acd4796c842932b96c6746a3569b30ee8f3 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Mon, 17 Mar 2025 16:03:46 -0400 Subject: [PATCH 01/17] update ordering for IP table --- .../LinodeNetworking/LinodeIPAddressRow.tsx | 10 +++++++--- .../LinodesDetail/LinodeNetworking/constants.ts | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx index 94181fd3e97..fbb835d361f 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx @@ -1,8 +1,8 @@ import { - usePreferences, + useAllIPsQuery, useLinodeIPsQuery, useLinodeQuery, - useAllIPsQuery, + usePreferences, } from '@linode/queries'; import { CircleProgress, Typography } from '@linode/ui'; import { styled } from '@mui/material/styles'; @@ -13,7 +13,9 @@ import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; import { LinkButton } from 'src/components/LinkButton'; import { TableCell } from 'src/components/TableCell'; import { StyledTableRow } from 'src/features/Linodes/LinodeEntityDetail.styles'; +import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; +import { ipTypeToText } from './constants'; import { LinodeNetworkingActionMenu } from './LinodeNetworkingActionMenu'; import type { IPAddress, IPRange } from '@linode/api-v4'; @@ -53,6 +55,8 @@ export const LinodeIPAddressRow = (props: LinodeIPAddressRowProps) => { type, } = props; + const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled(); + const { data: ips } = useLinodeIPsQuery(linodeId); const { data: maskSensitiveDataPreference } = usePreferences( (preferences) => preferences?.maskSensitiveData @@ -78,7 +82,7 @@ export const LinodeIPAddressRow = (props: LinodeIPAddressRowProps) => { {!isVPCOnlyLinode && } - {type} + {isLinodeInterfacesEnabled ? ipTypeToText[type] : type} {gateway} {subnetMask} diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts new file mode 100644 index 00000000000..7dc333d87a9 --- /dev/null +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts @@ -0,0 +1,17 @@ +import type { IPTypes } from './types'; + +// Note: when the Linode Interfaces feature flag is no longer needed, +// we can instead directly update IPTypes and relevant logic +export const ipTypeToText: Record = { + 'IPv4 – Private': 'Private – IPv4', + 'IPv4 – Public': 'Public – IPv4', + 'IPv4 – Reserved (private)': 'Reserved IPv4 (private)', + 'IPv4 – Reserved (public)': 'Reserved IPv4 (public)', + 'IPv4 – Shared': 'Shared – IPv4', + 'IPv4 – VPC': 'VPC – IPv4', + 'IPv4 – VPC – Range': 'VPC – Range – IPv4', + 'IPv6 – Link Local': 'Link Local – IPv6', + 'IPv6 – Range': 'Range – IPv6', + 'IPv6 – SLAAC': 'Public - SLAAC – IPv6', + 'VPC IPv4 – NAT': 'VPC NAT – IPv4', +}; From 7ac594f34e02963fb56d4001c8a9aef0ab9155bd Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Mon, 17 Mar 2025 16:07:29 -0400 Subject: [PATCH 02/17] update todo comment --- .../Linodes/LinodesDetail/LinodeNetworking/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts index 7dc333d87a9..88e34cfcc0b 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts @@ -1,6 +1,6 @@ import type { IPTypes } from './types'; -// Note: when the Linode Interfaces feature flag is no longer needed, +// @TODO Linode Interfaces: when the Linode Interfaces feature flag is no longer needed, // we can instead directly update IPTypes and relevant logic export const ipTypeToText: Record = { 'IPv4 – Private': 'Private – IPv4', From 80d1828d6b7c886c6a53e9d996fc40ec60f88d23 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Mon, 17 Mar 2025 17:07:42 -0400 Subject: [PATCH 03/17] update aria label/id --- .../LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx index 54c64b84a41..5fff431a8aa 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx @@ -48,7 +48,7 @@ import type { LinodeIPsResponse, } from '@linode/api-v4'; -export const ipv4TableID = 'ips'; +export const ipTableID = 'ips'; interface LinodeIPAddressesProps { linodeID: number; @@ -210,7 +210,7 @@ export const LinodeIPAddresses = (props: LinodeIPAddressesProps) => { {({ data: orderedData, handleOrderChange, order, orderBy }) => { return ( - +
Address From 1a10c2c82ba3e27d362ddb5fcb25fb12beff9800 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Mon, 17 Mar 2025 17:55:09 -0400 Subject: [PATCH 04/17] update logic to make sortable --- .../LinodeNetworking/DeleteIPDialog.tsx | 2 +- .../LinodeNetworking/DeleteRangeDialog.tsx | 2 +- .../LinodeNetworking/EditIPRDNSDrawer.tsx | 2 +- .../LinodeNetworking/EditRangeRDNSDrawer.tsx | 10 +-- .../LinodeNetworking/ExplainerCopy.tsx | 2 +- .../LinodeNetworking/IPTransfer.tsx | 14 +-- .../LinodeIPAddressRow.test.tsx | 6 +- .../LinodeNetworking/LinodeIPAddressRow.tsx | 9 +- .../LinodeIPAddresses.test.ts | 47 +++++++--- .../LinodeNetworking/LinodeIPAddresses.tsx | 88 +++++++++++++------ .../LinodeNetworkingActionMenu.tsx | 28 +++++- .../LinodeNetworking/constants.ts | 6 +- .../LinodesDetail/LinodeNetworking/types.ts | 15 ++++ 13 files changed, 159 insertions(+), 72 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/DeleteIPDialog.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/DeleteIPDialog.tsx index df8a8edd576..fd35afa240f 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/DeleteIPDialog.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/DeleteIPDialog.tsx @@ -1,9 +1,9 @@ +import { useLinodeIPDeleteMutation } from '@linode/queries'; import { ActionsPanel, Typography } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { useLinodeIPDeleteMutation } from '@linode/queries'; interface Props { address: string; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/DeleteRangeDialog.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/DeleteRangeDialog.tsx index 51a7a0b0324..c90e50b1686 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/DeleteRangeDialog.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/DeleteRangeDialog.tsx @@ -1,9 +1,9 @@ +import { useLinodeRemoveRangeMutation } from '@linode/queries'; import { ActionsPanel, Typography } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { useLinodeRemoveRangeMutation } from '@linode/queries'; import type { IPRange } from '@linode/api-v4'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/EditIPRDNSDrawer.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/EditIPRDNSDrawer.tsx index 47f83fa3580..59a55c10bc5 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/EditIPRDNSDrawer.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/EditIPRDNSDrawer.tsx @@ -1,10 +1,10 @@ +import { useLinodeIPMutation } from '@linode/queries'; import { ActionsPanel, Notice, TextField } from '@linode/ui'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { Drawer } from 'src/components/Drawer'; -import { useLinodeIPMutation } from '@linode/queries'; import { getErrorMap } from 'src/utilities/errorUtils'; import type { IPAddress } from '@linode/api-v4/lib/networking'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/EditRangeRDNSDrawer.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/EditRangeRDNSDrawer.tsx index 7e4481dfd55..9d79367d80b 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/EditRangeRDNSDrawer.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/EditRangeRDNSDrawer.tsx @@ -1,3 +1,8 @@ +import { + useAllIPsQuery, + useLinodeIPMutation, + useLinodeQuery, +} from '@linode/queries'; import { ActionsPanel, Notice, TextField, Typography } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import { useFormik } from 'formik'; @@ -5,11 +10,6 @@ import { useSnackbar } from 'notistack'; import * as React from 'react'; import { Drawer } from 'src/components/Drawer'; -import { - useLinodeQuery, - useLinodeIPMutation, - useAllIPsQuery, -} from '@linode/queries'; import { getErrorMap } from 'src/utilities/errorUtils'; import { listIPv6InRange } from './LinodeIPAddressRow'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/ExplainerCopy.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/ExplainerCopy.tsx index 4cb88752185..cea8c567faf 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/ExplainerCopy.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/ExplainerCopy.tsx @@ -1,7 +1,7 @@ +import { useLinodeQuery } from '@linode/queries'; import * as React from 'react'; import { SupportLink } from 'src/components/SupportLink'; -import { useLinodeQuery } from '@linode/queries'; import type { IPType } from './AddIPDrawer'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/IPTransfer.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/IPTransfer.tsx index 55c663d438c..3c2af86a574 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/IPTransfer.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/IPTransfer.tsx @@ -1,3 +1,10 @@ +import { + useAllIPv6RangesQuery, + useAllLinodesQuery, + useAssignAdressesMutation, + useLinodeIPsQuery, + useLinodeQuery, +} from '@linode/queries'; import { ActionsPanel, Autocomplete, @@ -12,13 +19,6 @@ import Grid from '@mui/material/Grid2'; import { styled, useTheme } from '@mui/material/styles'; import * as React from 'react'; -import { - useAllLinodesQuery, - useLinodeQuery, - useAssignAdressesMutation, - useLinodeIPsQuery, - useAllIPv6RangesQuery, -} from '@linode/queries'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; import type { APIError, IPRange } from '@linode/api-v4'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx index a00e6b8a60b..718b208aa16 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx @@ -15,9 +15,10 @@ import { LinodeIPAddressRow } from './LinodeIPAddressRow'; import type { IPAddressRowHandlers } from './LinodeIPAddressRow'; const ips = linodeIPFactory.build(); -const ipDisplay = ipResponseToDisplayRows(ips)[0]; +const ipDisplay = ipResponseToDisplayRows(false, ips)[0]; const ipDisplayVPC = vpcConfigInterfaceToDisplayRows( - linodeConfigInterfaceFactoryWithVPC.build() + linodeConfigInterfaceFactoryWithVPC.build(), + false )[0]; const handlers: IPAddressRowHandlers = { @@ -128,6 +129,7 @@ describe('LinodeIPAddressRow', () => { describe('ipResponseToDisplayRows', () => { it('should not return a Public IPv4 row if there is a VPC interface with 1:1 NAT', () => { const ipDisplays = ipResponseToDisplayRows( + false, ips, linodeConfigInterfaceFactoryWithVPC.build() ); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx index fbb835d361f..47a34613ede 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx @@ -13,9 +13,7 @@ import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; import { LinkButton } from 'src/components/LinkButton'; import { TableCell } from 'src/components/TableCell'; import { StyledTableRow } from 'src/features/Linodes/LinodeEntityDetail.styles'; -import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; -import { ipTypeToText } from './constants'; import { LinodeNetworkingActionMenu } from './LinodeNetworkingActionMenu'; import type { IPAddress, IPRange } from '@linode/api-v4'; @@ -55,15 +53,14 @@ export const LinodeIPAddressRow = (props: LinodeIPAddressRowProps) => { type, } = props; - const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled(); - const { data: ips } = useLinodeIPsQuery(linodeId); const { data: maskSensitiveDataPreference } = usePreferences( (preferences) => preferences?.maskSensitiveData ); const isOnlyPublicIP = - ips?.ipv4.public.length === 1 && type === 'IPv4 – Public'; + ips?.ipv4.public.length === 1 && + (type === 'IPv4 – Public' || type === 'Public – IPv4'); return ( { {!isVPCOnlyLinode && } - {isLinodeInterfacesEnabled ? ipTypeToText[type] : type} + {type} {gateway} {subnetMask} diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts index 4eeefcb9e3e..d2f5eec75d6 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts @@ -1,9 +1,11 @@ -import { LinodeIPsResponse } from '@linode/api-v4/lib/linodes'; - import { ipAddressFactory } from 'src/factories/networking'; -import { listIPv6InRange } from './LinodeIPAddressRow'; import { createType, ipResponseToDisplayRows } from './LinodeIPAddresses'; +import { listIPv6InRange } from './LinodeIPAddressRow'; + +import type { LinodeIPsResponse } from '@linode/api-v4/lib/linodes'; + +// @TODO Linode Interfaces - clean up test cases for IP tests once we remove feature flag describe('listIPv6InRange utility function', () => { const ipv4List = ipAddressFactory.buildList(4); @@ -62,12 +64,12 @@ describe('ipResponseToDisplayRows utility function', () => { }; it('returns a display row for each IP/range', () => { - const result = ipResponseToDisplayRows(response); + const result = ipResponseToDisplayRows(false, response); expect(result).toHaveLength(7); }); it('includes the meta _ip field for IP addresses', () => { - const result = ipResponseToDisplayRows(response); + const result = ipResponseToDisplayRows(false, response); // Check the first six rows (the IPs) for (let i = 0; i < 5; i++) { expect(result[i]._ip).toBeDefined(); @@ -75,7 +77,7 @@ describe('ipResponseToDisplayRows utility function', () => { }); it('includes the meta _range field for IP ranges', () => { - const result = ipResponseToDisplayRows(response); + const result = ipResponseToDisplayRows(false, response); // Check the last row (the IPv6 range) expect(result[6]._range).toBeDefined(); }); @@ -86,21 +88,40 @@ describe('createType utility function', () => { const publicIPv4 = ipAddressFactory.build({ public: true, type: 'ipv4' }); const privateIPv4 = ipAddressFactory.build({ public: false, type: 'ipv4' }); - expect(createType(publicIPv4, 'Public')).toBe('IPv4 – Public'); - expect(createType(privateIPv4, 'Private')).toBe('IPv4 – Private'); + expect(createType(publicIPv4, 'Public', false)).toBe('IPv4 – Public'); + expect(createType(privateIPv4, 'Private', false)).toBe('IPv4 – Private'); - expect(createType(publicIPv4, 'Reserved')).toBe('IPv4 – Reserved (public)'); - expect(createType(privateIPv4, 'Reserved')).toBe( + expect(createType(publicIPv4, 'Reserved', false)).toBe( + 'IPv4 – Reserved (public)' + ); + expect(createType(privateIPv4, 'Reserved', false)).toBe( 'IPv4 – Reserved (private)' ); - expect(createType(publicIPv4, 'Shared')).toBe('IPv4 – Shared'); + expect(createType(publicIPv4, 'Shared', false)).toBe('IPv4 – Shared'); + + // Linode Interface changes to IP types + expect(createType(publicIPv4, 'Public', true)).toBe('Public – IPv4'); + expect(createType(privateIPv4, 'Private', true)).toBe('Private – IPv4'); + + expect(createType(publicIPv4, 'Reserved', true)).toBe( + 'Reserved IPv4 (public)' + ); + expect(createType(privateIPv4, 'Reserved', true)).toBe( + 'Reserved IPv4 (private)' + ); + + expect(createType(publicIPv4, 'Shared', true)).toBe('Shared – IPv4'); }); it('creates the correct type for ipv6', () => { const ipv6 = ipAddressFactory.build({ type: 'ipv6' }); - expect(createType(ipv6, 'SLAAC')).toBe('IPv6 – SLAAC'); - expect(createType(ipv6, 'Link Local')).toBe('IPv6 – Link Local'); + expect(createType(ipv6, 'SLAAC', false)).toBe('IPv6 – SLAAC'); + expect(createType(ipv6, 'Link Local', false)).toBe('IPv6 – Link Local'); + + // Linode Interfaces related - test cases: + expect(createType(ipv6, 'SLAAC', true)).toBe('Public – SLAAC – IPv6'); + expect(createType(ipv6, 'Link Local', true)).toBe('Link Local – IPv6'); }); }); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx index 5fff431a8aa..9ff6feafc8b 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx @@ -1,3 +1,8 @@ +import { + useLinodeIPsQuery, + useLinodeQuery, + useRegionsQuery, +} from '@linode/queries'; import { Box, Button, @@ -21,13 +26,10 @@ import { TableRow } from 'src/components/TableRow'; import { TableSortCell } from 'src/components/TableSortCell'; import { useIsResourceRestricted } from 'src/hooks/useIsResourceRestricted'; import { useVPCConfigInterface } from 'src/hooks/useVPCConfigInterface'; -import { - useLinodeQuery, - useLinodeIPsQuery, - useRegionsQuery, -} from '@linode/queries'; +import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; import { AddIPDrawer } from './AddIPDrawer'; +import { ipTypeMap } from './constants'; import { DeleteIPDialog } from './DeleteIPDialog'; import { DeleteRangeDialog } from './DeleteRangeDialog'; import { EditIPRDNSDrawer } from './EditIPRDNSDrawer'; @@ -40,7 +42,7 @@ import { ViewRangeDrawer } from './ViewRangeDrawer'; import { ViewRDNSDrawer } from './ViewRDNSDrawer'; import type { IPAddressRowHandlers } from './LinodeIPAddressRow'; -import type { IPTypes } from './types'; +import type { IPTypes, UpdatedIPTypes } from './types'; import type { IPAddress, IPRange, @@ -48,7 +50,7 @@ import type { LinodeIPsResponse, } from '@linode/api-v4'; -export const ipTableID = 'ips'; +export const ipv4TableID = 'ips'; interface LinodeIPAddressesProps { linodeID: number; @@ -59,6 +61,7 @@ export const LinodeIPAddresses = (props: LinodeIPAddressesProps) => { const theme = useTheme(); const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); + const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled(); const { data: ips, error, isLoading } = useLinodeIPsQuery(linodeID); const { data: linode } = useLinodeQuery(linodeID); @@ -143,7 +146,11 @@ export const LinodeIPAddresses = (props: LinodeIPAddressesProps) => { return null; } - const ipDisplay = ipResponseToDisplayRows(ips, configInterfaceWithVPC); + const ipDisplay = ipResponseToDisplayRows( + isLinodeInterfacesEnabled, + ips, + configInterfaceWithVPC + ); return ( @@ -210,7 +217,7 @@ export const LinodeIPAddresses = (props: LinodeIPAddressesProps) => { {({ data: orderedData, handleOrderChange, order, orderBy }) => { return ( -
+
Address @@ -321,11 +328,12 @@ export interface IPDisplay { gateway: string; rdns: string; subnetMask: string; - type: IPTypes; + type: IPTypes | UpdatedIPTypes; } export const vpcConfigInterfaceToDisplayRows = ( - configInterfaceWithVPC: Interface + configInterfaceWithVPC: Interface, + isLinodeInterfacesEnabled: boolean ) => { const ipDisplay: IPDisplay[] = []; @@ -339,7 +347,7 @@ export const vpcConfigInterfaceToDisplayRows = ( if (ipv4?.vpc) { ipDisplay.push({ address: ipv4.vpc, - type: 'IPv4 – VPC', + type: isLinodeInterfacesEnabled ? 'VPC – IPv4' : 'IPv4 – VPC', ...emptyProps, }); } @@ -347,7 +355,7 @@ export const vpcConfigInterfaceToDisplayRows = ( if (ipv4?.nat_1_1) { ipDisplay.push({ address: ipv4.nat_1_1, - type: 'VPC IPv4 – NAT', + type: isLinodeInterfacesEnabled ? 'VPC NAT – IPv4' : 'VPC IPv4 – NAT', ...emptyProps, }); } @@ -356,7 +364,9 @@ export const vpcConfigInterfaceToDisplayRows = ( ip_ranges.forEach((ip_range) => { ipDisplay.push({ address: ip_range, - type: 'IPv4 – VPC – Range', + type: isLinodeInterfacesEnabled + ? 'VPC – Range – IPv4' + : 'IPv4 – VPC – Range', ...emptyProps, }); }); @@ -367,6 +377,7 @@ export const vpcConfigInterfaceToDisplayRows = ( // Takes an IP Response object and returns high-level IP display rows. export const ipResponseToDisplayRows = ( + isLinodeInterfacesEnabled: boolean, ipResponse?: LinodeIPsResponse, configInterfaceWithVPC?: Interface ): IPDisplay[] => { @@ -377,18 +388,20 @@ export const ipResponseToDisplayRows = ( const { ipv4, ipv6 } = ipResponse; const ipDisplay = [ - ...mapIPv4Display(ipv4.public, 'Public'), - ...mapIPv4Display(ipv4.private, 'Private'), - ...mapIPv4Display(ipv4.reserved, 'Reserved'), - ...mapIPv4Display(ipv4.shared, 'Shared'), + ...mapIPv4Display(ipv4.public, 'Public', isLinodeInterfacesEnabled), + ...mapIPv4Display(ipv4.private, 'Private', isLinodeInterfacesEnabled), + ...mapIPv4Display(ipv4.reserved, 'Reserved', isLinodeInterfacesEnabled), + ...mapIPv4Display(ipv4.shared, 'Shared', isLinodeInterfacesEnabled), ]; if (ipv6?.slaac) { - ipDisplay.push(ipToDisplay(ipv6.slaac, 'SLAAC')); + ipDisplay.push(ipToDisplay(ipv6.slaac, 'SLAAC', isLinodeInterfacesEnabled)); } if (ipv6?.link_local) { - ipDisplay.push(ipToDisplay(ipv6?.link_local, 'Link Local')); + ipDisplay.push( + ipToDisplay(ipv6?.link_local, 'Link Local', isLinodeInterfacesEnabled) + ); } if (configInterfaceWithVPC) { @@ -396,7 +409,12 @@ export const ipResponseToDisplayRows = ( // If there is a VPC interface with 1:1 NAT, hide the Public IPv4 IP address row ipDisplay.shift(); } - ipDisplay.push(...vpcConfigInterfaceToDisplayRows(configInterfaceWithVPC)); + ipDisplay.push( + ...vpcConfigInterfaceToDisplayRows( + configInterfaceWithVPC, + isLinodeInterfacesEnabled + ) + ); } // IPv6 ranges and pools to display in the networking table @@ -423,7 +441,9 @@ export const ipResponseToDisplayRows = ( gateway: '', rdns: '', subnetMask: '', - type: 'IPv6 – Range' as IPDisplay['type'], + type: (isLinodeInterfacesEnabled + ? 'Range – IPv6' + : 'IPv6 – Range') as IPDisplay['type'], }; }) ); @@ -439,22 +459,34 @@ type ipKey = | 'SLAAC' | 'Shared'; -const mapIPv4Display = (ips: IPAddress[], key: ipKey): IPDisplay[] => { - return ips.map((ip) => ipToDisplay(ip, key)); +const mapIPv4Display = ( + ips: IPAddress[], + key: ipKey, + isLinodeInterfacesEnabled: boolean +): IPDisplay[] => { + return ips.map((ip) => ipToDisplay(ip, key, isLinodeInterfacesEnabled)); }; -const ipToDisplay = (ip: IPAddress, key: ipKey): IPDisplay => { +const ipToDisplay = ( + ip: IPAddress, + key: ipKey, + isLinodeInterfacesEnabled: boolean +): IPDisplay => { return { _ip: ip, address: ip.address, gateway: ip.gateway ?? '', rdns: ip.rdns ?? '', subnetMask: ip.subnet_mask ?? '', - type: createType(ip, key) as IPTypes, + type: createType(ip, key, isLinodeInterfacesEnabled) as IPTypes, }; }; -export const createType = (ip: IPAddress, key: ipKey) => { +export const createType = ( + ip: IPAddress, + key: ipKey, + isLinodeInterfacesEnabled: boolean +) => { let type = ''; type += ip.type === 'ipv4' ? 'IPv4' : 'IPv6'; @@ -466,5 +498,5 @@ export const createType = (ip: IPAddress, key: ipKey) => { type += key; } - return type; + return isLinodeInterfacesEnabled ? ipTypeMap[type as IPTypes] : type; }; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx index efcf57476af..a783c8347dd 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx @@ -6,15 +6,16 @@ import * as React from 'react'; import { ActionMenu } from 'src/components/ActionMenu/ActionMenu'; import { InlineMenuAction } from 'src/components/InlineMenuAction/InlineMenuAction'; import { PUBLIC_IP_ADDRESSES_TOOLTIP_TEXT } from 'src/features/Linodes/PublicIPAddressesTooltip'; +import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; -import type { IPTypes } from './types'; +import type { IPTypes, UpdatedIPTypes } from './types'; import type { IPAddress, IPRange } from '@linode/api-v4/lib/networking'; import type { Theme } from '@mui/material/styles'; import type { Action } from 'src/components/ActionMenu/ActionMenu'; interface Props { ipAddress: IPAddress | IPRange; - ipType: IPTypes; + ipType: IPTypes | UpdatedIPTypes; isOnlyPublicIP: boolean; isVPCOnlyLinode: boolean; onEdit?: (ip: IPAddress | IPRange) => void; @@ -25,7 +26,7 @@ interface Props { export const LinodeNetworkingActionMenu = (props: Props) => { const theme = useTheme(); const matchesMdDown = useMediaQuery(theme.breakpoints.down('lg')); - + const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled(); const { ipAddress, ipType, @@ -43,9 +44,28 @@ export const LinodeNetworkingActionMenu = (props: Props) => { 'IPv4 – VPC', 'IPv6 – Link Local', 'VPC IPv4 – NAT', + // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types + ...(isLinodeInterfacesEnabled + ? [ + 'Private – IPv4', + 'Reserved IPv4 (private)', + 'Reserved IPv4 (public)', + 'VPC – IPv4', + 'Link Local – IPv6', + 'VPC NAT – IPv4', + ] + : []), ].includes(ipType); - const deletableIPTypes = ['IPv4 – Public', 'IPv4 – Private', 'IPv6 – Range']; + const deletableIPTypes = [ + 'IPv4 – Public', + 'IPv4 – Private', + 'IPv6 – Range', + // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types + ...(isLinodeInterfacesEnabled + ? ['Private – IPv4', 'Public – IPv4', 'Range – IPv6'] + : []), + ]; // if we have a 116 we don't want to give the option to remove it const is116Range = ipAddress?.prefix === 116; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts index 88e34cfcc0b..56438587cfe 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts @@ -1,8 +1,8 @@ -import type { IPTypes } from './types'; +import type { IPTypes, UpdatedIPTypes } from './types'; // @TODO Linode Interfaces: when the Linode Interfaces feature flag is no longer needed, // we can instead directly update IPTypes and relevant logic -export const ipTypeToText: Record = { +export const ipTypeMap: Record = { 'IPv4 – Private': 'Private – IPv4', 'IPv4 – Public': 'Public – IPv4', 'IPv4 – Reserved (private)': 'Reserved IPv4 (private)', @@ -12,6 +12,6 @@ export const ipTypeToText: Record = { 'IPv4 – VPC – Range': 'VPC – Range – IPv4', 'IPv6 – Link Local': 'Link Local – IPv6', 'IPv6 – Range': 'Range – IPv6', - 'IPv6 – SLAAC': 'Public - SLAAC – IPv6', + 'IPv6 – SLAAC': 'Public – SLAAC – IPv6', 'VPC IPv4 – NAT': 'VPC NAT – IPv4', }; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts index f12c35c7c2a..b15533bb756 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts @@ -10,3 +10,18 @@ export type IPTypes = | 'IPv6 – Range' | 'IPv6 – SLAAC' | 'VPC IPv4 – NAT'; + +// @TODO Linode Interfaces: when feature flag is cleaned up, we can replace IPTypes' values with these values +export type UpdatedIPTypes = + | 'Link Local – IPv6' + | 'Private – IPv4' + | 'Private – IPv4' + | 'Public – IPv4' + | 'Public – SLAAC – IPv6' + | 'Range – IPv6' + | 'Reserved IPv4 (private)' + | 'Reserved IPv4 (public)' + | 'Shared – IPv4' + | 'VPC NAT – IPv4' + | 'VPC – IPv4' + | 'VPC – Range – IPv4'; From 9e842eba05fcf8403884ae861141c3af06777d7c Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Mon, 17 Mar 2025 17:56:10 -0400 Subject: [PATCH 05/17] Added changeset: Display interface type first in Linode Network IP Addresses table --- .../.changeset/pr-11865-upcoming-features-1742248570726.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/manager/.changeset/pr-11865-upcoming-features-1742248570726.md diff --git a/packages/manager/.changeset/pr-11865-upcoming-features-1742248570726.md b/packages/manager/.changeset/pr-11865-upcoming-features-1742248570726.md new file mode 100644 index 00000000000..29d5809ce7d --- /dev/null +++ b/packages/manager/.changeset/pr-11865-upcoming-features-1742248570726.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Display interface type first in Linode Network IP Addresses table ([#11865](https://github.com/linode/manager/pull/11865)) From c83dbd94cc1e1f58a7a6cf3e8d1bc28836d51065 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 18 Mar 2025 09:47:53 -0400 Subject: [PATCH 06/17] fix cypress --- .../manager/cypress/e2e/core/linodes/linode-network.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/cypress/e2e/core/linodes/linode-network.spec.ts b/packages/manager/cypress/e2e/core/linodes/linode-network.spec.ts index 9df12ab3fa8..4ff1ae4910f 100644 --- a/packages/manager/cypress/e2e/core/linodes/linode-network.spec.ts +++ b/packages/manager/cypress/e2e/core/linodes/linode-network.spec.ts @@ -73,7 +73,7 @@ describe('IP Addresses', () => { * - Confirms the success toast message after editing RDNS */ it('checks for the toast message upon editing an RDNS', () => { - cy.findByLabelText('IPv4 Addresses') + cy.findByLabelText('Linode IP Addresses') .should('be.visible') .within(() => { // confirm table headers From 81e44397ba925e48edc8e64bde4f3ef884863274 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Thu, 20 Mar 2025 15:38:26 -0400 Subject: [PATCH 07/17] address feedback pt1 --- .../LinodeIPAddressRow.test.tsx | 15 +- .../LinodeIPAddresses.test.ts | 79 +++++++---- .../LinodeNetworking/LinodeIPAddresses.tsx | 129 ++++++++++++------ 3 files changed, 150 insertions(+), 73 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx index 718b208aa16..3c63af4373a 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx @@ -15,7 +15,10 @@ import { LinodeIPAddressRow } from './LinodeIPAddressRow'; import type { IPAddressRowHandlers } from './LinodeIPAddressRow'; const ips = linodeIPFactory.build(); -const ipDisplay = ipResponseToDisplayRows(false, ips)[0]; +const ipDisplay = ipResponseToDisplayRows({ + displayIPKeyFirst: false, + ipResponse: ips, +})[0]; const ipDisplayVPC = vpcConfigInterfaceToDisplayRows( linodeConfigInterfaceFactoryWithVPC.build(), false @@ -128,11 +131,11 @@ describe('LinodeIPAddressRow', () => { describe('ipResponseToDisplayRows', () => { it('should not return a Public IPv4 row if there is a VPC interface with 1:1 NAT', () => { - const ipDisplays = ipResponseToDisplayRows( - false, - ips, - linodeConfigInterfaceFactoryWithVPC.build() - ); + const ipDisplays = ipResponseToDisplayRows({ + configInterfaceWithVPC: linodeConfigInterfaceFactoryWithVPC.build(), + displayIPKeyFirst: false, + ipResponse: ips, + }); expect( ipDisplays.find((ipDisplay) => ipDisplay.type === 'IPv4 – Public') diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts index d2f5eec75d6..63419a3f2c3 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts @@ -64,12 +64,18 @@ describe('ipResponseToDisplayRows utility function', () => { }; it('returns a display row for each IP/range', () => { - const result = ipResponseToDisplayRows(false, response); + const result = ipResponseToDisplayRows({ + displayIPKeyFirst: false, + ipResponse: response, + }); expect(result).toHaveLength(7); }); it('includes the meta _ip field for IP addresses', () => { - const result = ipResponseToDisplayRows(false, response); + const result = ipResponseToDisplayRows({ + displayIPKeyFirst: false, + ipResponse: response, + }); // Check the first six rows (the IPs) for (let i = 0; i < 5; i++) { expect(result[i]._ip).toBeDefined(); @@ -77,7 +83,10 @@ describe('ipResponseToDisplayRows utility function', () => { }); it('includes the meta _range field for IP ranges', () => { - const result = ipResponseToDisplayRows(false, response); + const result = ipResponseToDisplayRows({ + displayIPKeyFirst: false, + ipResponse: response, + }); // Check the last row (the IPv6 range) expect(result[6]._range).toBeDefined(); }); @@ -88,40 +97,60 @@ describe('createType utility function', () => { const publicIPv4 = ipAddressFactory.build({ public: true, type: 'ipv4' }); const privateIPv4 = ipAddressFactory.build({ public: false, type: 'ipv4' }); - expect(createType(publicIPv4, 'Public', false)).toBe('IPv4 – Public'); - expect(createType(privateIPv4, 'Private', false)).toBe('IPv4 – Private'); + expect( + createType({ displayIPKeyFirst: false, ip: publicIPv4, key: 'Public' }) + ).toBe('IPv4 – Public'); + expect( + createType({ displayIPKeyFirst: false, ip: privateIPv4, key: 'Private' }) + ).toBe('IPv4 – Private'); - expect(createType(publicIPv4, 'Reserved', false)).toBe( - 'IPv4 – Reserved (public)' - ); - expect(createType(privateIPv4, 'Reserved', false)).toBe( - 'IPv4 – Reserved (private)' - ); + expect( + createType({ displayIPKeyFirst: false, ip: publicIPv4, key: 'Reserved' }) + ).toBe('IPv4 – Reserved (public)'); + expect( + createType({ displayIPKeyFirst: false, ip: privateIPv4, key: 'Reserved' }) + ).toBe('IPv4 – Reserved (private)'); - expect(createType(publicIPv4, 'Shared', false)).toBe('IPv4 – Shared'); + expect( + createType({ displayIPKeyFirst: false, ip: publicIPv4, key: 'Shared' }) + ).toBe('IPv4 – Shared'); // Linode Interface changes to IP types - expect(createType(publicIPv4, 'Public', true)).toBe('Public – IPv4'); - expect(createType(privateIPv4, 'Private', true)).toBe('Private – IPv4'); + expect( + createType({ displayIPKeyFirst: true, ip: publicIPv4, key: 'Public' }) + ).toBe('Public – IPv4'); + expect( + createType({ displayIPKeyFirst: true, ip: privateIPv4, key: 'Private' }) + ).toBe('Private – IPv4'); - expect(createType(publicIPv4, 'Reserved', true)).toBe( - 'Reserved IPv4 (public)' - ); - expect(createType(privateIPv4, 'Reserved', true)).toBe( - 'Reserved IPv4 (private)' - ); + expect( + createType({ displayIPKeyFirst: true, ip: publicIPv4, key: 'Reserved' }) + ).toBe('Reserved IPv4 (public)'); + expect( + createType({ displayIPKeyFirst: true, ip: privateIPv4, key: 'Reserved' }) + ).toBe('Reserved IPv4 (private)'); - expect(createType(publicIPv4, 'Shared', true)).toBe('Shared – IPv4'); + expect( + createType({ displayIPKeyFirst: true, ip: publicIPv4, key: 'Shared' }) + ).toBe('Shared – IPv4'); }); it('creates the correct type for ipv6', () => { const ipv6 = ipAddressFactory.build({ type: 'ipv6' }); - expect(createType(ipv6, 'SLAAC', false)).toBe('IPv6 – SLAAC'); - expect(createType(ipv6, 'Link Local', false)).toBe('IPv6 – Link Local'); + expect( + createType({ displayIPKeyFirst: false, ip: ipv6, key: 'SLAAC' }) + ).toBe('IPv6 – SLAAC'); + expect( + createType({ displayIPKeyFirst: false, ip: ipv6, key: 'Link Local' }) + ).toBe('IPv6 – Link Local'); // Linode Interfaces related - test cases: - expect(createType(ipv6, 'SLAAC', true)).toBe('Public – SLAAC – IPv6'); - expect(createType(ipv6, 'Link Local', true)).toBe('Link Local – IPv6'); + expect( + createType({ displayIPKeyFirst: true, ip: ipv6, key: 'SLAAC' }) + ).toBe('Public – SLAAC – IPv6'); + expect( + createType({ displayIPKeyFirst: true, ip: ipv6, key: 'Link Local' }) + ).toBe('Link Local – IPv6'); }); }); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx index 9ff6feafc8b..fbf22392c37 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx @@ -146,11 +146,11 @@ export const LinodeIPAddresses = (props: LinodeIPAddressesProps) => { return null; } - const ipDisplay = ipResponseToDisplayRows( - isLinodeInterfacesEnabled, - ips, - configInterfaceWithVPC - ); + const ipDisplay = ipResponseToDisplayRows({ + configInterfaceWithVPC, + displayIPKeyFirst: isLinodeInterfacesEnabled, + ipResponse: ips, + }); return ( @@ -333,7 +333,7 @@ export interface IPDisplay { export const vpcConfigInterfaceToDisplayRows = ( configInterfaceWithVPC: Interface, - isLinodeInterfacesEnabled: boolean + displayIPKeyFirst: boolean ) => { const ipDisplay: IPDisplay[] = []; @@ -347,7 +347,7 @@ export const vpcConfigInterfaceToDisplayRows = ( if (ipv4?.vpc) { ipDisplay.push({ address: ipv4.vpc, - type: isLinodeInterfacesEnabled ? 'VPC – IPv4' : 'IPv4 – VPC', + type: displayIPKeyFirst ? 'VPC – IPv4' : 'IPv4 – VPC', ...emptyProps, }); } @@ -355,7 +355,7 @@ export const vpcConfigInterfaceToDisplayRows = ( if (ipv4?.nat_1_1) { ipDisplay.push({ address: ipv4.nat_1_1, - type: isLinodeInterfacesEnabled ? 'VPC NAT – IPv4' : 'VPC IPv4 – NAT', + type: displayIPKeyFirst ? 'VPC NAT – IPv4' : 'VPC IPv4 – NAT', ...emptyProps, }); } @@ -364,9 +364,7 @@ export const vpcConfigInterfaceToDisplayRows = ( ip_ranges.forEach((ip_range) => { ipDisplay.push({ address: ip_range, - type: isLinodeInterfacesEnabled - ? 'VPC – Range – IPv4' - : 'IPv4 – VPC – Range', + type: displayIPKeyFirst ? 'VPC – Range – IPv4' : 'IPv4 – VPC – Range', ...emptyProps, }); }); @@ -376,11 +374,15 @@ export const vpcConfigInterfaceToDisplayRows = ( }; // Takes an IP Response object and returns high-level IP display rows. -export const ipResponseToDisplayRows = ( - isLinodeInterfacesEnabled: boolean, - ipResponse?: LinodeIPsResponse, - configInterfaceWithVPC?: Interface -): IPDisplay[] => { +export const ipResponseToDisplayRows = ({ + configInterfaceWithVPC, + displayIPKeyFirst, + ipResponse, +}: { + configInterfaceWithVPC?: Interface; + displayIPKeyFirst: boolean; + ipResponse?: LinodeIPsResponse; +}): IPDisplay[] => { if (!ipResponse) { return []; } @@ -388,19 +390,45 @@ export const ipResponseToDisplayRows = ( const { ipv4, ipv6 } = ipResponse; const ipDisplay = [ - ...mapIPv4Display(ipv4.public, 'Public', isLinodeInterfacesEnabled), - ...mapIPv4Display(ipv4.private, 'Private', isLinodeInterfacesEnabled), - ...mapIPv4Display(ipv4.reserved, 'Reserved', isLinodeInterfacesEnabled), - ...mapIPv4Display(ipv4.shared, 'Shared', isLinodeInterfacesEnabled), + ...mapIPv4Display({ + displayIPKeyFirst, + ips: ipv4.public, + key: 'Public', + }), + ...mapIPv4Display({ + displayIPKeyFirst, + ips: ipv4.private, + key: 'Private', + }), + ...mapIPv4Display({ + displayIPKeyFirst, + ips: ipv4.reserved, + key: 'Reserved', + }), + ...mapIPv4Display({ + displayIPKeyFirst, + ips: ipv4.shared, + key: 'Shared', + }), ]; if (ipv6?.slaac) { - ipDisplay.push(ipToDisplay(ipv6.slaac, 'SLAAC', isLinodeInterfacesEnabled)); + ipDisplay.push( + ipToDisplay({ + displayIPKeyFirst, + ip: ipv6.slaac, + key: 'SLAAC', + }) + ); } if (ipv6?.link_local) { ipDisplay.push( - ipToDisplay(ipv6?.link_local, 'Link Local', isLinodeInterfacesEnabled) + ipToDisplay({ + displayIPKeyFirst, + ip: ipv6?.link_local, + key: 'Link Local', + }) ); } @@ -412,7 +440,7 @@ export const ipResponseToDisplayRows = ( ipDisplay.push( ...vpcConfigInterfaceToDisplayRows( configInterfaceWithVPC, - isLinodeInterfacesEnabled + displayIPKeyFirst ) ); } @@ -441,7 +469,7 @@ export const ipResponseToDisplayRows = ( gateway: '', rdns: '', subnetMask: '', - type: (isLinodeInterfacesEnabled + type: (displayIPKeyFirst ? 'Range – IPv6' : 'IPv6 – Range') as IPDisplay['type'], }; @@ -459,34 +487,51 @@ type ipKey = | 'SLAAC' | 'Shared'; -const mapIPv4Display = ( - ips: IPAddress[], - key: ipKey, - isLinodeInterfacesEnabled: boolean -): IPDisplay[] => { - return ips.map((ip) => ipToDisplay(ip, key, isLinodeInterfacesEnabled)); +interface IPsToDisplayInputs { + displayIPKeyFirst: boolean; + ips: IPAddress[]; + key: ipKey; +} +interface IPToDisplayInputs { + displayIPKeyFirst: boolean; + ip: IPAddress; + key: ipKey; +} + +const mapIPv4Display = ({ + displayIPKeyFirst, + ips, + key, +}: IPsToDisplayInputs): IPDisplay[] => { + return ips.map((ip) => + ipToDisplay({ + displayIPKeyFirst, + ip, + key, + }) + ); }; -const ipToDisplay = ( - ip: IPAddress, - key: ipKey, - isLinodeInterfacesEnabled: boolean -): IPDisplay => { +const ipToDisplay = ({ + displayIPKeyFirst, + ip, + key, +}: IPToDisplayInputs): IPDisplay => { return { _ip: ip, address: ip.address, gateway: ip.gateway ?? '', rdns: ip.rdns ?? '', subnetMask: ip.subnet_mask ?? '', - type: createType(ip, key, isLinodeInterfacesEnabled) as IPTypes, + type: createType({ displayIPKeyFirst, ip, key }) as IPTypes, }; }; -export const createType = ( - ip: IPAddress, - key: ipKey, - isLinodeInterfacesEnabled: boolean -) => { +export const createType = ({ + displayIPKeyFirst, + ip, + key, +}: IPToDisplayInputs) => { let type = ''; type += ip.type === 'ipv4' ? 'IPv4' : 'IPv6'; @@ -498,5 +543,5 @@ export const createType = ( type += key; } - return isLinodeInterfacesEnabled ? ipTypeMap[type as IPTypes] : type; + return displayIPKeyFirst ? ipTypeMap[type as IPTypes] : type; }; From 9513b95872740355dc36bfe02c2dc8077ffb6f48 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Thu, 20 Mar 2025 16:51:41 -0400 Subject: [PATCH 08/17] add preference key for IP table --- .../src/features/Linodes/LinodeEntityDetailBody.tsx | 4 ++-- .../LinodeNetworking/LinodeIPAddresses.tsx | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodeEntityDetailBody.tsx b/packages/manager/src/features/Linodes/LinodeEntityDetailBody.tsx index d9034d23458..ecf93218075 100644 --- a/packages/manager/src/features/Linodes/LinodeEntityDetailBody.tsx +++ b/packages/manager/src/features/Linodes/LinodeEntityDetailBody.tsx @@ -34,7 +34,7 @@ import { StyledVPCBox, sxLastListItem, } from './LinodeEntityDetail.styles'; -import { ipv4TableID } from './LinodesDetail/LinodeNetworking/LinodeIPAddresses'; +import { ipTableId } from './LinodesDetail/LinodeNetworking/LinodeIPAddresses'; import { lishLink, sshLink } from './LinodesDetail/utilities'; import type { LinodeHandlers } from './LinodesLanding/LinodesLanding'; @@ -289,7 +289,7 @@ export const LinodeEntityDetailBody = React.memo((props: BodyProps) => { variant="body1" > View all IP Addresses diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx index fbf22392c37..6ddef9e8ed5 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx @@ -50,7 +50,7 @@ import type { LinodeIPsResponse, } from '@linode/api-v4'; -export const ipv4TableID = 'ips'; +export const ipTableId = 'ips'; interface LinodeIPAddressesProps { linodeID: number; @@ -214,10 +214,15 @@ export const LinodeIPAddresses = (props: LinodeIPAddressesProps) => { )} {/* @todo: It'd be nice if we could always sort by public -> private. */} - + {({ data: orderedData, handleOrderChange, order, orderBy }) => { return ( -
+
Address From 47792313b97d2fe04052709b46e8fe88f42370a9 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Thu, 20 Mar 2025 17:25:35 -0400 Subject: [PATCH 09/17] maybe this? --- .../LinodeNetworking/LinodeIPAddressRow.tsx | 6 ++- .../LinodeNetworking/LinodeIPAddresses.tsx | 12 +++--- .../LinodeNetworkingActionMenu.tsx | 37 +++++++------------ .../LinodeNetworking/constants.ts | 33 +++++++++++++++++ 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx index 47a34613ede..659d9f1a1f7 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx @@ -13,7 +13,9 @@ import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; import { LinkButton } from 'src/components/LinkButton'; import { TableCell } from 'src/components/TableCell'; import { StyledTableRow } from 'src/features/Linodes/LinodeEntityDetail.styles'; +import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; +import { getIPType } from './constants'; import { LinodeNetworkingActionMenu } from './LinodeNetworkingActionMenu'; import type { IPAddress, IPRange } from '@linode/api-v4'; @@ -58,9 +60,11 @@ export const LinodeIPAddressRow = (props: LinodeIPAddressRowProps) => { (preferences) => preferences?.maskSensitiveData ); + const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled(); + const isOnlyPublicIP = ips?.ipv4.public.length === 1 && - (type === 'IPv4 – Public' || type === 'Public – IPv4'); + type === getIPType.ipv4Public(isLinodeInterfacesEnabled); return ( { ipDisplay.push({ address: ip_range, - type: displayIPKeyFirst ? 'VPC – Range – IPv4' : 'IPv4 – VPC – Range', + type: getIPType.ipv4VPCRange(displayIPKeyFirst), ...emptyProps, }); }); @@ -474,9 +474,7 @@ export const ipResponseToDisplayRows = ({ gateway: '', rdns: '', subnetMask: '', - type: (displayIPKeyFirst - ? 'Range – IPv6' - : 'IPv6 – Range') as IPDisplay['type'], + type: getIPType.ipv6Range(displayIPKeyFirst) as IPDisplay['type'], }; }) ); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx index a783c8347dd..2ab63b3a683 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx @@ -8,6 +8,8 @@ import { InlineMenuAction } from 'src/components/InlineMenuAction/InlineMenuActi import { PUBLIC_IP_ADDRESSES_TOOLTIP_TEXT } from 'src/features/Linodes/PublicIPAddressesTooltip'; import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; +import { getIPType } from './constants'; + import type { IPTypes, UpdatedIPTypes } from './types'; import type { IPAddress, IPRange } from '@linode/api-v4/lib/networking'; import type { Theme } from '@mui/material/styles'; @@ -38,33 +40,22 @@ export const LinodeNetworkingActionMenu = (props: Props) => { } = props; const showEdit = ![ - 'IPv4 – Private', - 'IPv4 – Reserved (private)', - 'IPv4 – Reserved (public)', - 'IPv4 – VPC', - 'IPv6 – Link Local', - 'VPC IPv4 – NAT', - // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types - ...(isLinodeInterfacesEnabled - ? [ - 'Private – IPv4', - 'Reserved IPv4 (private)', - 'Reserved IPv4 (public)', - 'VPC – IPv4', - 'Link Local – IPv6', - 'VPC NAT – IPv4', - ] - : []), + // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types and update this array to just be something like + // ['Private – IPv4', 'Reserved IPv4 (private)', 'Reserved IPv4 (public)', 'VPC – IPv4', 'Link Local – IPv6', 'VPC NAT – IPv4',] + getIPType.ipv4Private(isLinodeInterfacesEnabled), + getIPType.ipv4ReservedPrivate(isLinodeInterfacesEnabled), + getIPType.ipv4ReservedPublic(isLinodeInterfacesEnabled), + getIPType.ipv4VPC(isLinodeInterfacesEnabled), + getIPType.ipv6LinkLocal(isLinodeInterfacesEnabled), + getIPType.vpcIPv4Nat(isLinodeInterfacesEnabled), ].includes(ipType); const deletableIPTypes = [ - 'IPv4 – Public', - 'IPv4 – Private', - 'IPv6 – Range', // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types - ...(isLinodeInterfacesEnabled - ? ['Private – IPv4', 'Public – IPv4', 'Range – IPv6'] - : []), + // and update this array to be ['Private – IPv4', 'Public – IPv4', 'Range – IPv6'] + getIPType.ipv4Private(isLinodeInterfacesEnabled), + getIPType.ipv4Public(isLinodeInterfacesEnabled), + getIPType.ipv6Range(isLinodeInterfacesEnabled), ]; // if we have a 116 we don't want to give the option to remove it diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts index 56438587cfe..dbbce9e7d03 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts @@ -15,3 +15,36 @@ export const ipTypeMap: Record = { 'IPv6 – SLAAC': 'Public – SLAAC – IPv6', 'VPC IPv4 – NAT': 'VPC NAT – IPv4', }; + +type GetIpDisplayFunction = ( + displayIPKeyFirst: boolean +) => IPTypes | UpdatedIPTypes; + +export const getIPType: Record = { + ipv4Private: (displayIPKeyFirst) => + displayIPKeyFirst ? ipTypeMap['IPv4 – Private'] : 'IPv4 – Private', + ipv4Public: (displayIPKeyFirst) => + displayIPKeyFirst ? ipTypeMap['IPv4 – Public'] : 'IPv4 – Public', + ipv4ReservedPrivate: (displayIPKeyFirst) => + displayIPKeyFirst + ? ipTypeMap['IPv4 – Reserved (private)'] + : 'IPv4 – Reserved (private)', + ipv4ReservedPublic: (displayIPKeyFirst) => + displayIPKeyFirst + ? ipTypeMap['IPv4 – Reserved (public)'] + : 'IPv4 – Reserved (public)', + ipv4Shared: (displayIPKeyFirst) => + displayIPKeyFirst ? ipTypeMap['IPv4 – Shared'] : 'IPv4 – Shared', + ipv4VPC: (displayIPKeyFirst) => + displayIPKeyFirst ? ipTypeMap['IPv4 – VPC'] : 'IPv4 – VPC', + ipv4VPCRange: (displayIPKeyFirst) => + displayIPKeyFirst ? ipTypeMap['IPv4 – VPC – Range'] : 'IPv4 – VPC – Range', + ipv6LinkLocal: (displayIPKeyFirst) => + displayIPKeyFirst ? ipTypeMap['IPv6 – Link Local'] : 'IPv6 – Link Local', + ipv6Range: (displayIPKeyFirst) => + displayIPKeyFirst ? ipTypeMap['IPv6 – Range'] : 'IPv6 – Range', + ipv6Slaac: (displayIPKeyFirst) => + displayIPKeyFirst ? ipTypeMap['IPv6 – SLAAC'] : 'IPv6 – SLAAC', + vpcIPv4Nat: (displayIPKeyFirst) => + displayIPKeyFirst ? ipTypeMap['VPC IPv4 – NAT'] : 'VPC IPv4 – NAT', +}; From fe1f0a35739e28bca5648041b49309c9a9e102b0 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Thu, 20 Mar 2025 17:39:35 -0400 Subject: [PATCH 10/17] or maybe this... --- .../LinodeNetworking/LinodeIPAddressRow.tsx | 2 +- .../LinodeNetworking/LinodeIPAddresses.tsx | 12 ++-- .../LinodeNetworkingActionMenu.tsx | 18 +++--- .../LinodeNetworking/constants.ts | 58 +++++++++---------- 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx index 659d9f1a1f7..cbf3416d1a6 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx @@ -64,7 +64,7 @@ export const LinodeIPAddressRow = (props: LinodeIPAddressRowProps) => { const isOnlyPublicIP = ips?.ipv4.public.length === 1 && - type === getIPType.ipv4Public(isLinodeInterfacesEnabled); + type === getIPType['IPv4 – Public'](isLinodeInterfacesEnabled); return ( { ipDisplay.push({ address: ip_range, - type: getIPType.ipv4VPCRange(displayIPKeyFirst), + type: getIPType['IPv4 – VPC – Range'](displayIPKeyFirst), ...emptyProps, }); }); @@ -474,7 +474,7 @@ export const ipResponseToDisplayRows = ({ gateway: '', rdns: '', subnetMask: '', - type: getIPType.ipv6Range(displayIPKeyFirst) as IPDisplay['type'], + type: getIPType['IPv6 – Range'](displayIPKeyFirst) as IPDisplay['type'], }; }) ); @@ -546,5 +546,5 @@ export const createType = ({ type += key; } - return displayIPKeyFirst ? ipTypeMap[type as IPTypes] : type; + return getIPType[type as IPTypes](displayIPKeyFirst); }; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx index 2ab63b3a683..139abd05f1b 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx @@ -42,20 +42,20 @@ export const LinodeNetworkingActionMenu = (props: Props) => { const showEdit = ![ // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types and update this array to just be something like // ['Private – IPv4', 'Reserved IPv4 (private)', 'Reserved IPv4 (public)', 'VPC – IPv4', 'Link Local – IPv6', 'VPC NAT – IPv4',] - getIPType.ipv4Private(isLinodeInterfacesEnabled), - getIPType.ipv4ReservedPrivate(isLinodeInterfacesEnabled), - getIPType.ipv4ReservedPublic(isLinodeInterfacesEnabled), - getIPType.ipv4VPC(isLinodeInterfacesEnabled), - getIPType.ipv6LinkLocal(isLinodeInterfacesEnabled), - getIPType.vpcIPv4Nat(isLinodeInterfacesEnabled), + getIPType['IPv4 – Private'](isLinodeInterfacesEnabled), + getIPType['IPv4 – Reserved (private)'](isLinodeInterfacesEnabled), + getIPType['IPv4 – Reserved (public)'](isLinodeInterfacesEnabled), + getIPType['IPv4 – VPC'](isLinodeInterfacesEnabled), + getIPType['IPv6 – Link Local'](isLinodeInterfacesEnabled), + getIPType['VPC IPv4 – NAT'](isLinodeInterfacesEnabled), ].includes(ipType); const deletableIPTypes = [ // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types // and update this array to be ['Private – IPv4', 'Public – IPv4', 'Range – IPv6'] - getIPType.ipv4Private(isLinodeInterfacesEnabled), - getIPType.ipv4Public(isLinodeInterfacesEnabled), - getIPType.ipv6Range(isLinodeInterfacesEnabled), + getIPType['IPv4 – Private'](isLinodeInterfacesEnabled), + getIPType['IPv4 – Public'](isLinodeInterfacesEnabled), + getIPType['IPv6 – Range'](isLinodeInterfacesEnabled), ]; // if we have a 116 we don't want to give the option to remove it diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts index dbbce9e7d03..6ac246fc8c2 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts @@ -1,7 +1,7 @@ import type { IPTypes, UpdatedIPTypes } from './types'; -// @TODO Linode Interfaces: when the Linode Interfaces feature flag is no longer needed, -// we can instead directly update IPTypes and relevant logic +/** Keeping this as comments for an easier overview of which IPType maps to which UpdatedIPType + export const ipTypeMap: Record = { 'IPv4 – Private': 'Private – IPv4', 'IPv4 – Public': 'Public – IPv4', @@ -16,35 +16,35 @@ export const ipTypeMap: Record = { 'VPC IPv4 – NAT': 'VPC NAT – IPv4', }; + */ + type GetIpDisplayFunction = ( displayIPKeyFirst: boolean ) => IPTypes | UpdatedIPTypes; -export const getIPType: Record = { - ipv4Private: (displayIPKeyFirst) => - displayIPKeyFirst ? ipTypeMap['IPv4 – Private'] : 'IPv4 – Private', - ipv4Public: (displayIPKeyFirst) => - displayIPKeyFirst ? ipTypeMap['IPv4 – Public'] : 'IPv4 – Public', - ipv4ReservedPrivate: (displayIPKeyFirst) => - displayIPKeyFirst - ? ipTypeMap['IPv4 – Reserved (private)'] - : 'IPv4 – Reserved (private)', - ipv4ReservedPublic: (displayIPKeyFirst) => - displayIPKeyFirst - ? ipTypeMap['IPv4 – Reserved (public)'] - : 'IPv4 – Reserved (public)', - ipv4Shared: (displayIPKeyFirst) => - displayIPKeyFirst ? ipTypeMap['IPv4 – Shared'] : 'IPv4 – Shared', - ipv4VPC: (displayIPKeyFirst) => - displayIPKeyFirst ? ipTypeMap['IPv4 – VPC'] : 'IPv4 – VPC', - ipv4VPCRange: (displayIPKeyFirst) => - displayIPKeyFirst ? ipTypeMap['IPv4 – VPC – Range'] : 'IPv4 – VPC – Range', - ipv6LinkLocal: (displayIPKeyFirst) => - displayIPKeyFirst ? ipTypeMap['IPv6 – Link Local'] : 'IPv6 – Link Local', - ipv6Range: (displayIPKeyFirst) => - displayIPKeyFirst ? ipTypeMap['IPv6 – Range'] : 'IPv6 – Range', - ipv6Slaac: (displayIPKeyFirst) => - displayIPKeyFirst ? ipTypeMap['IPv6 – SLAAC'] : 'IPv6 – SLAAC', - vpcIPv4Nat: (displayIPKeyFirst) => - displayIPKeyFirst ? ipTypeMap['VPC IPv4 – NAT'] : 'VPC IPv4 – NAT', +// @TODO Linode Interfaces: when the Linode Interfaces feature flag is no longer needed, +// we can instead directly update IPTypes and relevant logic +export const getIPType: Record = { + 'IPv4 – Private': (displayIPKeyFirst) => + displayIPKeyFirst ? 'Private – IPv4' : 'IPv4 – Private', + 'IPv4 – Public': (displayIPKeyFirst) => + displayIPKeyFirst ? 'Public – IPv4' : 'IPv4 – Public', + 'IPv4 – Reserved (private)': (displayIPKeyFirst) => + displayIPKeyFirst ? 'Reserved IPv4 (private)' : 'IPv4 – Reserved (private)', + 'IPv4 – Reserved (public)': (displayIPKeyFirst) => + displayIPKeyFirst ? 'Reserved IPv4 (public)' : 'IPv4 – Reserved (public)', + 'IPv4 – Shared': (displayIPKeyFirst) => + displayIPKeyFirst ? 'Shared – IPv4' : 'IPv4 – Shared', + 'IPv4 – VPC': (displayIPKeyFirst) => + displayIPKeyFirst ? 'VPC – IPv4' : 'IPv4 – VPC', + 'IPv4 – VPC – Range': (displayIPKeyFirst) => + displayIPKeyFirst ? 'VPC – Range – IPv4' : 'IPv4 – VPC – Range', + 'IPv6 – Link Local': (displayIPKeyFirst) => + displayIPKeyFirst ? 'Link Local – IPv6' : 'IPv6 – Link Local', + 'IPv6 – Range': (displayIPKeyFirst) => + displayIPKeyFirst ? 'Range – IPv6' : 'IPv6 – Range', + 'IPv6 – SLAAC': (displayIPKeyFirst) => + displayIPKeyFirst ? 'Public – SLAAC – IPv6' : 'IPv6 – SLAAC', + 'VPC IPv4 – NAT': (displayIPKeyFirst) => + displayIPKeyFirst ? 'VPC NAT – IPv4' : 'VPC IPv4 – NAT', }; From 71064a4668a905fd41d7c48c2368617cace23789 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Fri, 21 Mar 2025 17:37:19 -0400 Subject: [PATCH 11/17] remove function map --- .../LinodeNetworking/LinodeIPAddressRow.tsx | 7 ++-- .../LinodeNetworking/LinodeIPAddresses.tsx | 21 +++++++--- .../LinodeNetworkingActionMenu.tsx | 41 ++++++++++++++----- .../LinodeNetworking/constants.ts | 4 -- 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx index cbf3416d1a6..e7d2b71017a 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx @@ -15,7 +15,6 @@ import { TableCell } from 'src/components/TableCell'; import { StyledTableRow } from 'src/features/Linodes/LinodeEntityDetail.styles'; import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; -import { getIPType } from './constants'; import { LinodeNetworkingActionMenu } from './LinodeNetworkingActionMenu'; import type { IPAddress, IPRange } from '@linode/api-v4'; @@ -61,10 +60,12 @@ export const LinodeIPAddressRow = (props: LinodeIPAddressRowProps) => { ); const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled(); + const publicIPv4Type = isLinodeInterfacesEnabled + ? 'Public – IPv4' + : 'IPv4 – Public'; const isOnlyPublicIP = - ips?.ipv4.public.length === 1 && - type === getIPType['IPv4 – Public'](isLinodeInterfacesEnabled); + ips?.ipv4.public.length === 1 && type === publicIPv4Type; return ( { ipDisplay.push({ address: ip_range, - type: getIPType['IPv4 – VPC – Range'](displayIPKeyFirst), + type: ipv4VPCRangeType, ...emptyProps, }); }); @@ -451,6 +459,7 @@ export const ipResponseToDisplayRows = ({ } // IPv6 ranges and pools to display in the networking table + const ipv6RangeType = displayIPKeyFirst ? 'Range – IPv6' : 'IPv6 – Range'; ipDisplay.push( ...[...(ipv6 ? ipv6.global : [])].map((thisIP) => { /* If you want to surface rdns info in the future you have two options: @@ -474,7 +483,7 @@ export const ipResponseToDisplayRows = ({ gateway: '', rdns: '', subnetMask: '', - type: getIPType['IPv6 – Range'](displayIPKeyFirst) as IPDisplay['type'], + type: ipv6RangeType as IPDisplay['type'], }; }) ); @@ -546,5 +555,5 @@ export const createType = ({ type += key; } - return getIPType[type as IPTypes](displayIPKeyFirst); + return displayIPKeyFirst ? ipTypeMap[type as IPTypes] : type; }; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx index 139abd05f1b..5396e54aa66 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx @@ -8,8 +8,6 @@ import { InlineMenuAction } from 'src/components/InlineMenuAction/InlineMenuActi import { PUBLIC_IP_ADDRESSES_TOOLTIP_TEXT } from 'src/features/Linodes/PublicIPAddressesTooltip'; import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; -import { getIPType } from './constants'; - import type { IPTypes, UpdatedIPTypes } from './types'; import type { IPAddress, IPRange } from '@linode/api-v4/lib/networking'; import type { Theme } from '@mui/material/styles'; @@ -39,23 +37,44 @@ export const LinodeNetworkingActionMenu = (props: Props) => { readOnly, } = props; + const ipv4Private = isLinodeInterfacesEnabled + ? 'Private – IPv4' + : 'IPv4 – Private'; + const ipv4ReservedPrivate = isLinodeInterfacesEnabled + ? 'Reserved IPv4 (private)' + : 'IPv4 – Reserved (private)'; + const ipv4ReservedPublic = isLinodeInterfacesEnabled + ? 'Reserved IPv4 (public)' + : 'IPv4 – Reserved (public)'; + const ipv4VPC = isLinodeInterfacesEnabled ? 'VPC – IPv4' : 'IPv4 – VPC'; + const ipv6LinkLocal = isLinodeInterfacesEnabled + ? 'Link Local – IPv6' + : 'IPv6 – Link Local'; + const ipv4Nat = isLinodeInterfacesEnabled + ? 'VPC NAT – IPv4' + : 'VPC IPv4 – NAT'; + const ipv4Public = isLinodeInterfacesEnabled + ? 'Public – IPv4' + : 'IPv4 – Public'; + const ipv6Range = isLinodeInterfacesEnabled ? 'Range – IPv6' : 'IPv6 – Range'; + const showEdit = ![ // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types and update this array to just be something like + ipv4Nat, // ['Private – IPv4', 'Reserved IPv4 (private)', 'Reserved IPv4 (public)', 'VPC – IPv4', 'Link Local – IPv6', 'VPC NAT – IPv4',] - getIPType['IPv4 – Private'](isLinodeInterfacesEnabled), - getIPType['IPv4 – Reserved (private)'](isLinodeInterfacesEnabled), - getIPType['IPv4 – Reserved (public)'](isLinodeInterfacesEnabled), - getIPType['IPv4 – VPC'](isLinodeInterfacesEnabled), - getIPType['IPv6 – Link Local'](isLinodeInterfacesEnabled), - getIPType['VPC IPv4 – NAT'](isLinodeInterfacesEnabled), + ipv4Private, + ipv4ReservedPrivate, + ipv4ReservedPublic, + ipv4VPC, + ipv6LinkLocal, ].includes(ipType); const deletableIPTypes = [ // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types // and update this array to be ['Private – IPv4', 'Public – IPv4', 'Range – IPv6'] - getIPType['IPv4 – Private'](isLinodeInterfacesEnabled), - getIPType['IPv4 – Public'](isLinodeInterfacesEnabled), - getIPType['IPv6 – Range'](isLinodeInterfacesEnabled), + ipv4Private, + ipv4Public, + ipv6Range, ]; // if we have a 116 we don't want to give the option to remove it diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts index 6ac246fc8c2..9f42cb1b296 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts @@ -1,7 +1,5 @@ import type { IPTypes, UpdatedIPTypes } from './types'; -/** Keeping this as comments for an easier overview of which IPType maps to which UpdatedIPType - export const ipTypeMap: Record = { 'IPv4 – Private': 'Private – IPv4', 'IPv4 – Public': 'Public – IPv4', @@ -16,8 +14,6 @@ export const ipTypeMap: Record = { 'VPC IPv4 – NAT': 'VPC NAT – IPv4', }; - */ - type GetIpDisplayFunction = ( displayIPKeyFirst: boolean ) => IPTypes | UpdatedIPTypes; From 1128ddadea22105a4b144735ab959b8d024a8ae2 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Fri, 21 Mar 2025 17:39:11 -0400 Subject: [PATCH 12/17] add back in comment --- .../LinodeNetworking/constants.ts | 33 ++----------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts index 9f42cb1b296..56438587cfe 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts @@ -1,5 +1,7 @@ import type { IPTypes, UpdatedIPTypes } from './types'; +// @TODO Linode Interfaces: when the Linode Interfaces feature flag is no longer needed, +// we can instead directly update IPTypes and relevant logic export const ipTypeMap: Record = { 'IPv4 – Private': 'Private – IPv4', 'IPv4 – Public': 'Public – IPv4', @@ -13,34 +15,3 @@ export const ipTypeMap: Record = { 'IPv6 – SLAAC': 'Public – SLAAC – IPv6', 'VPC IPv4 – NAT': 'VPC NAT – IPv4', }; - -type GetIpDisplayFunction = ( - displayIPKeyFirst: boolean -) => IPTypes | UpdatedIPTypes; - -// @TODO Linode Interfaces: when the Linode Interfaces feature flag is no longer needed, -// we can instead directly update IPTypes and relevant logic -export const getIPType: Record = { - 'IPv4 – Private': (displayIPKeyFirst) => - displayIPKeyFirst ? 'Private – IPv4' : 'IPv4 – Private', - 'IPv4 – Public': (displayIPKeyFirst) => - displayIPKeyFirst ? 'Public – IPv4' : 'IPv4 – Public', - 'IPv4 – Reserved (private)': (displayIPKeyFirst) => - displayIPKeyFirst ? 'Reserved IPv4 (private)' : 'IPv4 – Reserved (private)', - 'IPv4 – Reserved (public)': (displayIPKeyFirst) => - displayIPKeyFirst ? 'Reserved IPv4 (public)' : 'IPv4 – Reserved (public)', - 'IPv4 – Shared': (displayIPKeyFirst) => - displayIPKeyFirst ? 'Shared – IPv4' : 'IPv4 – Shared', - 'IPv4 – VPC': (displayIPKeyFirst) => - displayIPKeyFirst ? 'VPC – IPv4' : 'IPv4 – VPC', - 'IPv4 – VPC – Range': (displayIPKeyFirst) => - displayIPKeyFirst ? 'VPC – Range – IPv4' : 'IPv4 – VPC – Range', - 'IPv6 – Link Local': (displayIPKeyFirst) => - displayIPKeyFirst ? 'Link Local – IPv6' : 'IPv6 – Link Local', - 'IPv6 – Range': (displayIPKeyFirst) => - displayIPKeyFirst ? 'Range – IPv6' : 'IPv6 – Range', - 'IPv6 – SLAAC': (displayIPKeyFirst) => - displayIPKeyFirst ? 'Public – SLAAC – IPv6' : 'IPv6 – SLAAC', - 'VPC IPv4 – NAT': (displayIPKeyFirst) => - displayIPKeyFirst ? 'VPC NAT – IPv4' : 'VPC IPv4 – NAT', -}; From b32d897878c150b1e1b17aa688c1ca7bef0766c8 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Fri, 21 Mar 2025 17:40:44 -0400 Subject: [PATCH 13/17] argh --- .../LinodeNetworking/LinodeNetworkingActionMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx index 5396e54aa66..32a1bc1d874 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx @@ -50,7 +50,7 @@ export const LinodeNetworkingActionMenu = (props: Props) => { const ipv6LinkLocal = isLinodeInterfacesEnabled ? 'Link Local – IPv6' : 'IPv6 – Link Local'; - const ipv4Nat = isLinodeInterfacesEnabled + const ipv4VPCNat = isLinodeInterfacesEnabled ? 'VPC NAT – IPv4' : 'VPC IPv4 – NAT'; const ipv4Public = isLinodeInterfacesEnabled @@ -60,12 +60,12 @@ export const LinodeNetworkingActionMenu = (props: Props) => { const showEdit = ![ // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types and update this array to just be something like - ipv4Nat, // ['Private – IPv4', 'Reserved IPv4 (private)', 'Reserved IPv4 (public)', 'VPC – IPv4', 'Link Local – IPv6', 'VPC NAT – IPv4',] ipv4Private, ipv4ReservedPrivate, ipv4ReservedPublic, ipv4VPC, + ipv4VPCNat, ipv6LinkLocal, ].includes(ipType); From bad89bcdcaef8d3270350b221e59ba4c2340c8ae Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 25 Mar 2025 16:53:47 -0400 Subject: [PATCH 14/17] lots of cleanup :)) --- .../LinodeIPAddressRow.test.tsx | 21 +-- .../LinodeNetworking/LinodeIPAddressRow.tsx | 8 +- .../LinodeIPAddresses.test.ts | 72 ++------- .../LinodeNetworking/LinodeIPAddresses.tsx | 149 ++++-------------- .../LinodeNetworkingActionMenu.test.tsx | 4 +- .../LinodeNetworkingActionMenu.tsx | 49 ++---- .../LinodeNetworking/constants.ts | 17 -- .../LinodesDetail/LinodeNetworking/types.ts | 17 +- 8 files changed, 62 insertions(+), 275 deletions(-) delete mode 100644 packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx index 3c63af4373a..e5e98fbcafd 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx @@ -15,13 +15,9 @@ import { LinodeIPAddressRow } from './LinodeIPAddressRow'; import type { IPAddressRowHandlers } from './LinodeIPAddressRow'; const ips = linodeIPFactory.build(); -const ipDisplay = ipResponseToDisplayRows({ - displayIPKeyFirst: false, - ipResponse: ips, -})[0]; +const ipDisplay = ipResponseToDisplayRows(ips)[0]; const ipDisplayVPC = vpcConfigInterfaceToDisplayRows( - linodeConfigInterfaceFactoryWithVPC.build(), - false + linodeConfigInterfaceFactoryWithVPC.build() )[0]; const handlers: IPAddressRowHandlers = { @@ -131,17 +127,16 @@ describe('LinodeIPAddressRow', () => { describe('ipResponseToDisplayRows', () => { it('should not return a Public IPv4 row if there is a VPC interface with 1:1 NAT', () => { - const ipDisplays = ipResponseToDisplayRows({ - configInterfaceWithVPC: linodeConfigInterfaceFactoryWithVPC.build(), - displayIPKeyFirst: false, - ipResponse: ips, - }); + const ipDisplays = ipResponseToDisplayRows( + ips, + linodeConfigInterfaceFactoryWithVPC.build() + ); expect( - ipDisplays.find((ipDisplay) => ipDisplay.type === 'IPv4 – Public') + ipDisplays.find((ipDisplay) => ipDisplay.type === 'Public – IPv4') ).toBeUndefined(); expect( - ipDisplays.find((ipDisplay) => ipDisplay.type === 'VPC IPv4 – NAT') + ipDisplays.find((ipDisplay) => ipDisplay.type === 'VPC NAT – IPv4') ).toBeDefined(); }); }); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx index e7d2b71017a..500656f0eba 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.tsx @@ -13,7 +13,6 @@ import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; import { LinkButton } from 'src/components/LinkButton'; import { TableCell } from 'src/components/TableCell'; import { StyledTableRow } from 'src/features/Linodes/LinodeEntityDetail.styles'; -import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; import { LinodeNetworkingActionMenu } from './LinodeNetworkingActionMenu'; @@ -59,13 +58,8 @@ export const LinodeIPAddressRow = (props: LinodeIPAddressRowProps) => { (preferences) => preferences?.maskSensitiveData ); - const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled(); - const publicIPv4Type = isLinodeInterfacesEnabled - ? 'Public – IPv4' - : 'IPv4 – Public'; - const isOnlyPublicIP = - ips?.ipv4.public.length === 1 && type === publicIPv4Type; + ips?.ipv4.public.length === 1 && type === 'Public – IPv4'; return ( { const ipv4List = ipAddressFactory.buildList(4); const ipv6Range = ipAddressFactory.build({ @@ -64,18 +62,12 @@ describe('ipResponseToDisplayRows utility function', () => { }; it('returns a display row for each IP/range', () => { - const result = ipResponseToDisplayRows({ - displayIPKeyFirst: false, - ipResponse: response, - }); + const result = ipResponseToDisplayRows(response); expect(result).toHaveLength(7); }); it('includes the meta _ip field for IP addresses', () => { - const result = ipResponseToDisplayRows({ - displayIPKeyFirst: false, - ipResponse: response, - }); + const result = ipResponseToDisplayRows(response); // Check the first six rows (the IPs) for (let i = 0; i < 5; i++) { expect(result[i]._ip).toBeDefined(); @@ -83,10 +75,7 @@ describe('ipResponseToDisplayRows utility function', () => { }); it('includes the meta _range field for IP ranges', () => { - const result = ipResponseToDisplayRows({ - displayIPKeyFirst: false, - ipResponse: response, - }); + const result = ipResponseToDisplayRows(response); // Check the last row (the IPv6 range) expect(result[6]._range).toBeDefined(); }); @@ -97,60 +86,19 @@ describe('createType utility function', () => { const publicIPv4 = ipAddressFactory.build({ public: true, type: 'ipv4' }); const privateIPv4 = ipAddressFactory.build({ public: false, type: 'ipv4' }); - expect( - createType({ displayIPKeyFirst: false, ip: publicIPv4, key: 'Public' }) - ).toBe('IPv4 – Public'); - expect( - createType({ displayIPKeyFirst: false, ip: privateIPv4, key: 'Private' }) - ).toBe('IPv4 – Private'); - - expect( - createType({ displayIPKeyFirst: false, ip: publicIPv4, key: 'Reserved' }) - ).toBe('IPv4 – Reserved (public)'); - expect( - createType({ displayIPKeyFirst: false, ip: privateIPv4, key: 'Reserved' }) - ).toBe('IPv4 – Reserved (private)'); - - expect( - createType({ displayIPKeyFirst: false, ip: publicIPv4, key: 'Shared' }) - ).toBe('IPv4 – Shared'); - - // Linode Interface changes to IP types - expect( - createType({ displayIPKeyFirst: true, ip: publicIPv4, key: 'Public' }) - ).toBe('Public – IPv4'); - expect( - createType({ displayIPKeyFirst: true, ip: privateIPv4, key: 'Private' }) - ).toBe('Private – IPv4'); + expect(createType(publicIPv4, 'Public')).toBe('Public – IPv4'); + expect(createType(privateIPv4, 'Private')).toBe('Private – IPv4'); - expect( - createType({ displayIPKeyFirst: true, ip: publicIPv4, key: 'Reserved' }) - ).toBe('Reserved IPv4 (public)'); - expect( - createType({ displayIPKeyFirst: true, ip: privateIPv4, key: 'Reserved' }) - ).toBe('Reserved IPv4 (private)'); + expect(createType(publicIPv4, 'Reserved')).toBe('Reserved IPv4 (public)'); + expect(createType(privateIPv4, 'Reserved')).toBe('Reserved IPv4 (private)'); - expect( - createType({ displayIPKeyFirst: true, ip: publicIPv4, key: 'Shared' }) - ).toBe('Shared – IPv4'); + expect(createType(publicIPv4, 'Shared')).toBe('Shared – IPv4'); }); it('creates the correct type for ipv6', () => { const ipv6 = ipAddressFactory.build({ type: 'ipv6' }); - expect( - createType({ displayIPKeyFirst: false, ip: ipv6, key: 'SLAAC' }) - ).toBe('IPv6 – SLAAC'); - expect( - createType({ displayIPKeyFirst: false, ip: ipv6, key: 'Link Local' }) - ).toBe('IPv6 – Link Local'); - - // Linode Interfaces related - test cases: - expect( - createType({ displayIPKeyFirst: true, ip: ipv6, key: 'SLAAC' }) - ).toBe('Public – SLAAC – IPv6'); - expect( - createType({ displayIPKeyFirst: true, ip: ipv6, key: 'Link Local' }) - ).toBe('Link Local – IPv6'); + expect(createType(ipv6, 'SLAAC')).toBe('Public – IPv6 (SLAAC)'); + expect(createType(ipv6, 'Link Local')).toBe('Link Local – IPv6'); }); }); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx index dc9c5113edb..c872b6726d8 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx @@ -26,10 +26,8 @@ import { TableRow } from 'src/components/TableRow'; import { TableSortCell } from 'src/components/TableSortCell'; import { useIsResourceRestricted } from 'src/hooks/useIsResourceRestricted'; import { useVPCConfigInterface } from 'src/hooks/useVPCConfigInterface'; -import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; import { AddIPDrawer } from './AddIPDrawer'; -import { ipTypeMap } from './constants'; import { DeleteIPDialog } from './DeleteIPDialog'; import { DeleteRangeDialog } from './DeleteRangeDialog'; import { EditIPRDNSDrawer } from './EditIPRDNSDrawer'; @@ -42,7 +40,7 @@ import { ViewRangeDrawer } from './ViewRangeDrawer'; import { ViewRDNSDrawer } from './ViewRDNSDrawer'; import type { IPAddressRowHandlers } from './LinodeIPAddressRow'; -import type { IPTypes, UpdatedIPTypes } from './types'; +import type { IPTypes } from './types'; import type { IPAddress, IPRange, @@ -61,7 +59,6 @@ export const LinodeIPAddresses = (props: LinodeIPAddressesProps) => { const theme = useTheme(); const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); - const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled(); const { data: ips, error, isLoading } = useLinodeIPsQuery(linodeID); const { data: linode } = useLinodeQuery(linodeID); @@ -146,11 +143,7 @@ export const LinodeIPAddresses = (props: LinodeIPAddressesProps) => { return null; } - const ipDisplay = ipResponseToDisplayRows({ - configInterfaceWithVPC, - displayIPKeyFirst: isLinodeInterfacesEnabled, - ipResponse: ips, - }); + const ipDisplay = ipResponseToDisplayRows(ips, configInterfaceWithVPC); return ( @@ -247,7 +240,7 @@ export const LinodeIPAddresses = (props: LinodeIPAddressesProps) => { {...ipDisplay} {...handlers} isVPCOnlyLinode={ - isVPCOnlyLinode && ipDisplay.type === 'IPv4 – Public' + isVPCOnlyLinode && ipDisplay.type === 'Public – IPv4' } key={`${ipDisplay.address}-${ipDisplay.type}`} linodeId={linodeID} @@ -333,12 +326,11 @@ export interface IPDisplay { gateway: string; rdns: string; subnetMask: string; - type: IPTypes | UpdatedIPTypes; + type: IPTypes; } export const vpcConfigInterfaceToDisplayRows = ( - configInterfaceWithVPC: Interface, - displayIPKeyFirst: boolean + configInterfaceWithVPC: Interface ) => { const ipDisplay: IPDisplay[] = []; @@ -349,18 +341,10 @@ export const vpcConfigInterfaceToDisplayRows = ( subnetMask: '', }; - const ipv4VPCType = displayIPKeyFirst ? 'VPC – IPv4' : 'IPv4 – VPC'; - const ipv4VPCNatType = displayIPKeyFirst - ? 'VPC NAT – IPv4' - : 'VPC IPv4 – NAT'; - const ipv4VPCRangeType = displayIPKeyFirst - ? 'VPC – Range – IPv4' - : 'IPv4 – VPC – Range'; - if (ipv4?.vpc) { ipDisplay.push({ address: ipv4.vpc, - type: ipv4VPCType, + type: 'VPC – IPv4', ...emptyProps, }); } @@ -368,7 +352,7 @@ export const vpcConfigInterfaceToDisplayRows = ( if (ipv4?.nat_1_1) { ipDisplay.push({ address: ipv4.nat_1_1, - type: ipv4VPCNatType, + type: 'VPC NAT – IPv4', ...emptyProps, }); } @@ -377,7 +361,7 @@ export const vpcConfigInterfaceToDisplayRows = ( ip_ranges.forEach((ip_range) => { ipDisplay.push({ address: ip_range, - type: ipv4VPCRangeType, + type: 'VPC – Range – IPv4', ...emptyProps, }); }); @@ -387,15 +371,10 @@ export const vpcConfigInterfaceToDisplayRows = ( }; // Takes an IP Response object and returns high-level IP display rows. -export const ipResponseToDisplayRows = ({ - configInterfaceWithVPC, - displayIPKeyFirst, - ipResponse, -}: { - configInterfaceWithVPC?: Interface; - displayIPKeyFirst: boolean; - ipResponse?: LinodeIPsResponse; -}): IPDisplay[] => { +export const ipResponseToDisplayRows = ( + ipResponse?: LinodeIPsResponse, + configInterfaceWithVPC?: Interface +): IPDisplay[] => { if (!ipResponse) { return []; } @@ -403,46 +382,18 @@ export const ipResponseToDisplayRows = ({ const { ipv4, ipv6 } = ipResponse; const ipDisplay = [ - ...mapIPv4Display({ - displayIPKeyFirst, - ips: ipv4.public, - key: 'Public', - }), - ...mapIPv4Display({ - displayIPKeyFirst, - ips: ipv4.private, - key: 'Private', - }), - ...mapIPv4Display({ - displayIPKeyFirst, - ips: ipv4.reserved, - key: 'Reserved', - }), - ...mapIPv4Display({ - displayIPKeyFirst, - ips: ipv4.shared, - key: 'Shared', - }), + ...mapIPv4Display(ipv4.public, 'Public'), + ...mapIPv4Display(ipv4.private, 'Private'), + ...mapIPv4Display(ipv4.reserved, 'Reserved'), + ...mapIPv4Display(ipv4.shared, 'Shared'), ]; if (ipv6?.slaac) { - ipDisplay.push( - ipToDisplay({ - displayIPKeyFirst, - ip: ipv6.slaac, - key: 'SLAAC', - }) - ); + ipDisplay.push(ipToDisplay(ipv6.slaac, 'SLAAC')); } if (ipv6?.link_local) { - ipDisplay.push( - ipToDisplay({ - displayIPKeyFirst, - ip: ipv6?.link_local, - key: 'Link Local', - }) - ); + ipDisplay.push(ipToDisplay(ipv6?.link_local, 'Link Local')); } if (configInterfaceWithVPC) { @@ -450,16 +401,10 @@ export const ipResponseToDisplayRows = ({ // If there is a VPC interface with 1:1 NAT, hide the Public IPv4 IP address row ipDisplay.shift(); } - ipDisplay.push( - ...vpcConfigInterfaceToDisplayRows( - configInterfaceWithVPC, - displayIPKeyFirst - ) - ); + ipDisplay.push(...vpcConfigInterfaceToDisplayRows(configInterfaceWithVPC)); } // IPv6 ranges and pools to display in the networking table - const ipv6RangeType = displayIPKeyFirst ? 'Range – IPv6' : 'IPv6 – Range'; ipDisplay.push( ...[...(ipv6 ? ipv6.global : [])].map((thisIP) => { /* If you want to surface rdns info in the future you have two options: @@ -483,7 +428,7 @@ export const ipResponseToDisplayRows = ({ gateway: '', rdns: '', subnetMask: '', - type: ipv6RangeType as IPDisplay['type'], + type: 'Range – IPv6' as IPDisplay['type'], }; }) ); @@ -499,61 +444,29 @@ type ipKey = | 'SLAAC' | 'Shared'; -interface IPsToDisplayInputs { - displayIPKeyFirst: boolean; - ips: IPAddress[]; - key: ipKey; -} -interface IPToDisplayInputs { - displayIPKeyFirst: boolean; - ip: IPAddress; - key: ipKey; -} - -const mapIPv4Display = ({ - displayIPKeyFirst, - ips, - key, -}: IPsToDisplayInputs): IPDisplay[] => { - return ips.map((ip) => - ipToDisplay({ - displayIPKeyFirst, - ip, - key, - }) - ); +const mapIPv4Display = (ips: IPAddress[], key: ipKey): IPDisplay[] => { + return ips.map((ip) => ipToDisplay(ip, key)); }; -const ipToDisplay = ({ - displayIPKeyFirst, - ip, - key, -}: IPToDisplayInputs): IPDisplay => { +const ipToDisplay = (ip: IPAddress, key: ipKey): IPDisplay => { return { _ip: ip, address: ip.address, gateway: ip.gateway ?? '', rdns: ip.rdns ?? '', subnetMask: ip.subnet_mask ?? '', - type: createType({ displayIPKeyFirst, ip, key }) as IPTypes, + type: createType(ip, key) as IPTypes, }; }; -export const createType = ({ - displayIPKeyFirst, - ip, - key, -}: IPToDisplayInputs) => { - let type = ''; - type += ip.type === 'ipv4' ? 'IPv4' : 'IPv6'; - - type += ' – '; +export const createType = (ip: IPAddress, key: ipKey) => { + if (key === 'Reserved' && ip.type === 'ipv4') { + return ip.public ? 'Reserved IPv4 (public)' : 'Reserved IPv4 (private)'; + } - if (key === 'Reserved') { - type += ip.public ? 'Reserved (public)' : 'Reserved (private)'; - } else { - type += key; + if (key === 'SLAAC') { + return 'Public – IPv6 (SLAAC)'; } - return displayIPKeyFirst ? ipTypeMap[type as IPTypes] : type; + return `${key} – ${ip.type === 'ipv4' ? 'IPv4' : 'IPv6'}`; }; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.test.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.test.tsx index bcb1d6373dc..08acd5b4331 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.test.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.test.tsx @@ -38,7 +38,7 @@ describe('LinodeNetworkingActionMenu', () => { ); @@ -54,7 +54,7 @@ describe('LinodeNetworkingActionMenu', () => { ); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx index 32a1bc1d874..e2b2748ad26 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeNetworkingActionMenu.tsx @@ -6,16 +6,15 @@ import * as React from 'react'; import { ActionMenu } from 'src/components/ActionMenu/ActionMenu'; import { InlineMenuAction } from 'src/components/InlineMenuAction/InlineMenuAction'; import { PUBLIC_IP_ADDRESSES_TOOLTIP_TEXT } from 'src/features/Linodes/PublicIPAddressesTooltip'; -import { useIsLinodeInterfacesEnabled } from 'src/utilities/linodes'; -import type { IPTypes, UpdatedIPTypes } from './types'; +import type { IPTypes } from './types'; import type { IPAddress, IPRange } from '@linode/api-v4/lib/networking'; import type { Theme } from '@mui/material/styles'; import type { Action } from 'src/components/ActionMenu/ActionMenu'; interface Props { ipAddress: IPAddress | IPRange; - ipType: IPTypes | UpdatedIPTypes; + ipType: IPTypes; isOnlyPublicIP: boolean; isVPCOnlyLinode: boolean; onEdit?: (ip: IPAddress | IPRange) => void; @@ -26,7 +25,6 @@ interface Props { export const LinodeNetworkingActionMenu = (props: Props) => { const theme = useTheme(); const matchesMdDown = useMediaQuery(theme.breakpoints.down('lg')); - const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled(); const { ipAddress, ipType, @@ -37,45 +35,16 @@ export const LinodeNetworkingActionMenu = (props: Props) => { readOnly, } = props; - const ipv4Private = isLinodeInterfacesEnabled - ? 'Private – IPv4' - : 'IPv4 – Private'; - const ipv4ReservedPrivate = isLinodeInterfacesEnabled - ? 'Reserved IPv4 (private)' - : 'IPv4 – Reserved (private)'; - const ipv4ReservedPublic = isLinodeInterfacesEnabled - ? 'Reserved IPv4 (public)' - : 'IPv4 – Reserved (public)'; - const ipv4VPC = isLinodeInterfacesEnabled ? 'VPC – IPv4' : 'IPv4 – VPC'; - const ipv6LinkLocal = isLinodeInterfacesEnabled - ? 'Link Local – IPv6' - : 'IPv6 – Link Local'; - const ipv4VPCNat = isLinodeInterfacesEnabled - ? 'VPC NAT – IPv4' - : 'VPC IPv4 – NAT'; - const ipv4Public = isLinodeInterfacesEnabled - ? 'Public – IPv4' - : 'IPv4 – Public'; - const ipv6Range = isLinodeInterfacesEnabled ? 'Range – IPv6' : 'IPv6 – Range'; - const showEdit = ![ - // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types and update this array to just be something like - // ['Private – IPv4', 'Reserved IPv4 (private)', 'Reserved IPv4 (public)', 'VPC – IPv4', 'Link Local – IPv6', 'VPC NAT – IPv4',] - ipv4Private, - ipv4ReservedPrivate, - ipv4ReservedPublic, - ipv4VPC, - ipv4VPCNat, - ipv6LinkLocal, + 'Link Local – IPv6', + 'Private – IPv4', + 'Reserved IPv4 (private)', + 'Reserved IPv4 (public)', + 'VPC NAT – IPv4', + 'VPC – IPv4', ].includes(ipType); - const deletableIPTypes = [ - // @TODO Linode Interfaces - when linode interfaces feature flag is removed, we can update IP types - // and update this array to be ['Private – IPv4', 'Public – IPv4', 'Range – IPv6'] - ipv4Private, - ipv4Public, - ipv6Range, - ]; + const deletableIPTypes = ['Private – IPv4', 'Public – IPv4', 'Range – IPv6']; // if we have a 116 we don't want to give the option to remove it const is116Range = ipAddress?.prefix === 116; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts deleted file mode 100644 index 56438587cfe..00000000000 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/constants.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { IPTypes, UpdatedIPTypes } from './types'; - -// @TODO Linode Interfaces: when the Linode Interfaces feature flag is no longer needed, -// we can instead directly update IPTypes and relevant logic -export const ipTypeMap: Record = { - 'IPv4 – Private': 'Private – IPv4', - 'IPv4 – Public': 'Public – IPv4', - 'IPv4 – Reserved (private)': 'Reserved IPv4 (private)', - 'IPv4 – Reserved (public)': 'Reserved IPv4 (public)', - 'IPv4 – Shared': 'Shared – IPv4', - 'IPv4 – VPC': 'VPC – IPv4', - 'IPv4 – VPC – Range': 'VPC – Range – IPv4', - 'IPv6 – Link Local': 'Link Local – IPv6', - 'IPv6 – Range': 'Range – IPv6', - 'IPv6 – SLAAC': 'Public – SLAAC – IPv6', - 'VPC IPv4 – NAT': 'VPC NAT – IPv4', -}; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts index b15533bb756..09a18035db4 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts @@ -1,23 +1,8 @@ export type IPTypes = - | 'IPv4 – Private' - | 'IPv4 – Public' - | 'IPv4 – Reserved (private)' - | 'IPv4 – Reserved (public)' - | 'IPv4 – Shared' - | 'IPv4 – VPC – Range' - | 'IPv4 – VPC' - | 'IPv6 – Link Local' - | 'IPv6 – Range' - | 'IPv6 – SLAAC' - | 'VPC IPv4 – NAT'; - -// @TODO Linode Interfaces: when feature flag is cleaned up, we can replace IPTypes' values with these values -export type UpdatedIPTypes = | 'Link Local – IPv6' | 'Private – IPv4' - | 'Private – IPv4' | 'Public – IPv4' - | 'Public – SLAAC – IPv6' + | 'Public – IPv6 (SLAAC)' | 'Range – IPv6' | 'Reserved IPv4 (private)' | 'Reserved IPv4 (public)' From 07623e277fd00d8f231375267e947be507c35a0a Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 25 Mar 2025 16:56:37 -0400 Subject: [PATCH 15/17] change slaac for now --- .../LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts | 2 +- .../LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx | 2 +- .../features/Linodes/LinodesDetail/LinodeNetworking/types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts index ed33cf0972d..d6f34fc8a3c 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.test.ts @@ -98,7 +98,7 @@ describe('createType utility function', () => { it('creates the correct type for ipv6', () => { const ipv6 = ipAddressFactory.build({ type: 'ipv6' }); - expect(createType(ipv6, 'SLAAC')).toBe('Public – IPv6 (SLAAC)'); + expect(createType(ipv6, 'SLAAC')).toBe('Public – IPv6 – SLAAC'); expect(createType(ipv6, 'Link Local')).toBe('Link Local – IPv6'); }); }); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx index c872b6726d8..b84b034c024 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddresses.tsx @@ -465,7 +465,7 @@ export const createType = (ip: IPAddress, key: ipKey) => { } if (key === 'SLAAC') { - return 'Public – IPv6 (SLAAC)'; + return 'Public – IPv6 – SLAAC'; } return `${key} – ${ip.type === 'ipv4' ? 'IPv4' : 'IPv6'}`; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts index 09a18035db4..b51c09fe137 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/types.ts @@ -2,7 +2,7 @@ export type IPTypes = | 'Link Local – IPv6' | 'Private – IPv4' | 'Public – IPv4' - | 'Public – IPv6 (SLAAC)' + | 'Public – IPv6 – SLAAC' | 'Range – IPv6' | 'Reserved IPv4 (private)' | 'Reserved IPv4 (public)' From aacfedb2beaaab88a0752ec640a2693491504e82 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Wed, 26 Mar 2025 09:49:18 -0400 Subject: [PATCH 16/17] fix tests --- .../manager/cypress/e2e/core/linodes/linode-network.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/manager/cypress/e2e/core/linodes/linode-network.spec.ts b/packages/manager/cypress/e2e/core/linodes/linode-network.spec.ts index e3c0de21531..0ebd42d2f3a 100644 --- a/packages/manager/cypress/e2e/core/linodes/linode-network.spec.ts +++ b/packages/manager/cypress/e2e/core/linodes/linode-network.spec.ts @@ -99,7 +99,7 @@ describe('IP Addresses', () => { .should('be.visible') .closest('tr') .within(() => { - cy.findByText('IPv4 – Public').should('be.visible'); + cy.findByText('Public – IPv4').should('be.visible'); cy.findByText(mockRDNS).should('be.visible'); // open up the edit RDNS drawer @@ -136,7 +136,7 @@ describe('IP Addresses', () => { .should('be.visible') .closest('tr') .within(() => { - cy.findByText('IPv4 – Public').should('be.visible'); + cy.findByText('Public – IPv4').should('be.visible'); ui.actionMenu .findByTitle(`Action menu for IP Address ${linodeIPv4}`) .should('be.visible'); @@ -147,7 +147,7 @@ describe('IP Addresses', () => { .should('be.visible') .closest('tr') .within(() => { - cy.findByText('IPv6 – Range').should('be.visible'); + cy.findByText('Range – IPv6').should('be.visible'); ui.actionMenu .findByTitle(`Action menu for IP Address ${_ipv6Range.range}`) .should('be.visible'); From 269652358a0f4d74e2b0898a3eae534ad8fdb23f Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Wed, 26 Mar 2025 16:05:12 -0400 Subject: [PATCH 17/17] update changeset --- ...tures-1742248570726.md => pr-11865-changed-1742248570726.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename packages/manager/.changeset/{pr-11865-upcoming-features-1742248570726.md => pr-11865-changed-1742248570726.md} (78%) diff --git a/packages/manager/.changeset/pr-11865-upcoming-features-1742248570726.md b/packages/manager/.changeset/pr-11865-changed-1742248570726.md similarity index 78% rename from packages/manager/.changeset/pr-11865-upcoming-features-1742248570726.md rename to packages/manager/.changeset/pr-11865-changed-1742248570726.md index 29d5809ce7d..c2f599dbf7d 100644 --- a/packages/manager/.changeset/pr-11865-upcoming-features-1742248570726.md +++ b/packages/manager/.changeset/pr-11865-changed-1742248570726.md @@ -1,5 +1,5 @@ --- -"@linode/manager": Upcoming Features +"@linode/manager": Changed --- Display interface type first in Linode Network IP Addresses table ([#11865](https://github.com/linode/manager/pull/11865))