1
- import { getLinodeInterfaces , type Linode } from '@linode/api-v4' ;
1
+ import { getLinodeInterfaces } from '@linode/api-v4' ;
2
2
import {
3
3
useAddFirewallDeviceMutation ,
4
4
useAllFirewallsQuery ,
5
5
useGrants ,
6
6
useProfile ,
7
7
} from '@linode/queries' ;
8
8
import { LinodeSelect } from '@linode/shared' ;
9
- import { ActionsPanel , Drawer , Notice , Select } from '@linode/ui' ;
9
+ import { ActionsPanel , Drawer , Notice , Select , Typography } from '@linode/ui' ;
10
10
import { getEntityIdsByPermission } from '@linode/utilities' ;
11
- import { Stack , Typography , useTheme } from '@mui/material' ;
11
+ import { useTheme } from '@mui/material' ;
12
12
import { useParams } from '@tanstack/react-router' ;
13
13
import { useSnackbar } from 'notistack' ;
14
14
import * as React from 'react' ;
@@ -20,7 +20,7 @@ import { getLinodeInterfaceType } from 'src/features/Linodes/LinodesDetail/Linod
20
20
import { getAPIErrorOrDefault } from 'src/utilities/errorUtils' ;
21
21
import { sanitizeHTML } from 'src/utilities/sanitizeHTML' ;
22
22
23
- import type { LinodeInterface } from '@linode/api-v4' ;
23
+ import type { Linode , LinodeInterface } from '@linode/api-v4' ;
24
24
25
25
interface Props {
26
26
helperText : string ;
@@ -65,14 +65,14 @@ export const AddLinodeDrawer = (props: Props) => {
65
65
const { isPending : addDeviceIsLoading , mutateAsync : addDevice } =
66
66
useAddFirewallDeviceMutation ( ) ;
67
67
68
- // keeps track of Linodes using configuration profile interfaces to add
68
+ // Keep track of Linodes to add using configuration profile interfaces
69
69
const [ linodesToAdd , setLinodesToAdd ] = React . useState < Linode [ ] > ( [ ] ) ;
70
- // keeps track of interface devices to add
70
+ // Keep track of interface devices to be added, mapping Linode ID to selected interface
71
71
const [ interfacesToAddMap , setInterfacesToAddMap ] = React . useState <
72
72
Map < number , InterfaceDeviceInfo | null >
73
73
> ( new Map ( ) ) ;
74
74
// Keep track of the linodes with multiple eligible linode interfaces to determine additional selects to show
75
- // Once an interface is selected, interfacesToAddMap will be updated
75
+ // Once an interface is selected, interfacesToAddMap will be updated for that Linode ID
76
76
const [ linodesWithMultiInterfaces , setLinodesWithMultiInterfaces ] =
77
77
React . useState < LinodeWithMultiLinodeInterfaces [ ] > ( [ ] ) ;
78
78
@@ -246,16 +246,19 @@ export const AddLinodeDrawer = (props: Props) => {
246
246
interfaceLinodes . map ( async ( linode ) => {
247
247
const linodeId = linode . id ;
248
248
const interfaces = await getLinodeInterfaces ( linodeId ) ;
249
+ // vlan interfaces cannot have a firewall assigned to them
249
250
const nonVlanInterfaces = interfaces . interfaces . filter (
250
251
( iface ) => ! iface . vlan
251
252
) ;
253
+
252
254
if ( nonVlanInterfaces . length === 1 ) {
253
255
_interfacesToAddMap . set ( linodeId , {
254
256
linodeId,
255
257
linodeLabel : linode . label ,
256
258
interfaceId : nonVlanInterfaces [ 0 ] . id ,
257
259
} ) ;
258
260
}
261
+
259
262
if ( nonVlanInterfaces . length > 1 ) {
260
263
if ( ! interfacesToAddMap . has ( linodeId ) ) {
261
264
_interfacesToAddMap . set ( linodeId , null ) ;
@@ -265,17 +268,20 @@ export const AddLinodeDrawer = (props: Props) => {
265
268
interfacesToAddMap . get ( linodeId ) ?? null
266
269
) ;
267
270
}
271
+
268
272
const interfacesWithLabels = nonVlanInterfaces . map ( ( iface ) => ( {
269
273
...iface ,
270
274
label : `${ getLinodeInterfaceType ( iface ) } Interface (ID : ${ iface . id } )` ,
271
275
value : iface . id ,
272
276
} ) ) ;
277
+
273
278
return {
274
279
linodeId,
275
280
linodeLabel : linode . label ,
276
281
linodeInterfaces : interfacesWithLabels ,
277
282
} ;
278
283
}
284
+
279
285
return null ;
280
286
} )
281
287
) ;
@@ -328,39 +334,34 @@ export const AddLinodeDrawer = (props: Props) => {
328
334
] }
329
335
/>
330
336
{ linodesWithMultiInterfaces . length > 0 && (
331
- < Typography marginTop = { 2 } >
332
- Please select the Linode Interface to add to this firewall for the
333
- below Linode(s).
337
+ < Typography marginTop = { 3 } >
338
+ { `The following ${ linodesWithMultiInterfaces . length === 1 ? 'Linode has' : 'Linodes have' }
339
+ more than one interface to which a firewall can be applied. Select which interface.` }
334
340
</ Typography >
335
341
) }
336
342
{ linodesWithMultiInterfaces . map ( ( linode ) => (
337
- < Stack key = { linode . linodeId } marginTop = { 2 } >
338
- < Typography >
339
- < strong > { linode . linodeLabel } </ strong >
340
- </ Typography >
341
- < Select
342
- label = "Interfaces"
343
- onChange = { ( e , option ) => {
344
- const updatedInterfacesToAdd = new Map ( interfacesToAddMap ) ;
345
- updatedInterfacesToAdd . set ( linode . linodeId , {
346
- linodeId : linode . linodeId ,
347
- linodeLabel : linode . linodeLabel ,
348
- interfaceId : option . value ,
349
- } ) ;
350
- setInterfacesToAddMap ( updatedInterfacesToAdd ) ;
351
- } }
352
- options = { linode . linodeInterfaces }
353
- placeholder = "Select Interface"
354
- sx = { { marginTop : - 1 } }
355
- value = {
356
- linode . linodeInterfaces . find (
357
- ( iface ) =>
358
- iface . id ===
359
- interfacesToAddMap . get ( linode . linodeId ) ?. interfaceId
360
- ) ?? null
361
- }
362
- />
363
- </ Stack >
343
+ < Select
344
+ key = { linode . linodeId }
345
+ label = { `${ linode . linodeLabel } Interface` }
346
+ onChange = { ( e , option ) => {
347
+ const updatedInterfacesToAdd = new Map ( interfacesToAddMap ) ;
348
+ updatedInterfacesToAdd . set ( linode . linodeId , {
349
+ linodeId : linode . linodeId ,
350
+ linodeLabel : linode . linodeLabel ,
351
+ interfaceId : option . value ,
352
+ } ) ;
353
+ setInterfacesToAddMap ( updatedInterfacesToAdd ) ;
354
+ } }
355
+ options = { linode . linodeInterfaces }
356
+ placeholder = "Select Interface"
357
+ value = {
358
+ linode . linodeInterfaces . find (
359
+ ( iface ) =>
360
+ iface . id ===
361
+ interfacesToAddMap . get ( linode . linodeId ) ?. interfaceId
362
+ ) ?? null
363
+ }
364
+ />
364
365
) ) }
365
366
< ActionsPanel
366
367
primaryButtonProps = { {
0 commit comments