@@ -110,10 +110,13 @@ const ConfigurationModal = ({
110110
111111 useEffect ( ( ) => {
112112 setLocalSecrets (
113- catalogItem . secrets . reduce ( ( acc , secret ) => {
114- acc [ secret . name ] = secret . assigned ? ASSIGNED_SECRET_PLACEHOLDER : '' ;
115- return acc ;
116- } , { } as { [ key : string ] : string | undefined } )
113+ catalogItem . secrets . reduce (
114+ ( acc , secret ) => {
115+ acc [ secret . name ] = secret . assigned ? ASSIGNED_SECRET_PLACEHOLDER : '' ;
116+ return acc ;
117+ } ,
118+ { } as { [ key : string ] : string | undefined } ,
119+ ) ,
117120 ) ;
118121 } , [ catalogItem . secrets ] ) ;
119122
@@ -184,16 +187,18 @@ const ConfigurationModal = ({
184187 >
185188 {
186189 // TODO: Figure out if catalog icon is actually optional, and if so, find a good fallback.
187- catalogItem . icon && < Avatar
188- variant = "square"
189- src = { image }
190- alt = { catalogItem . name }
191- sx = { {
192- width : 40 ,
193- height : 40 ,
194- borderRadius : 1 ,
195- } }
196- />
190+ catalogItem . icon && (
191+ < Avatar
192+ variant = "square"
193+ src = { image }
194+ alt = { catalogItem . name }
195+ sx = { {
196+ width : 40 ,
197+ height : 40 ,
198+ borderRadius : 1 ,
199+ } }
200+ />
201+ )
197202 }
198203 { catalogItem . title }
199204 < Tooltip
@@ -329,10 +334,11 @@ const ConfigurationModal = ({
329334 </ Typography >
330335 </ TableCell >
331336 < TableCell >
332- { catalogItem . readme && (
337+ { ( catalogItem . readme && (
333338 < Link
334339 onClick = { ( ) =>
335- client . host . openExternal ( `${ catalogItem . readme } #tool-${ tool . name . replaceAll ( ' ' , '-' ) } `
340+ client . host . openExternal (
341+ `${ catalogItem . readme } #tool-${ tool . name . replaceAll ( ' ' , '-' ) } ` ,
336342 )
337343 }
338344 href = "#"
@@ -342,21 +348,21 @@ const ConfigurationModal = ({
342348 Documentation
343349 < Launch />
344350 </ Link >
345- ) || (
346- < Link
347- onClick = { ( ) =>
348- client . host . openExternal (
349- `https://raw.githubusercontent.com/docker/labs-ai-tools-for-devs/refs/heads/main/${ new URLSearchParams ( catalogItem . ref . split ( '?' ) [ 1 ] ) . get ( 'path' ) } `
350- )
351- }
352- href = "#"
353- target = "_blank"
354- sx = { { fontSize : 12 } }
355- >
356- Documentation
357- < Launch />
358- </ Link >
359- ) }
351+ ) ) || (
352+ < Link
353+ onClick = { ( ) =>
354+ client . host . openExternal (
355+ `https://raw.githubusercontent.com/docker/labs-ai-tools-for-devs/refs/heads/main/${ new URLSearchParams ( catalogItem . ref . split ( '?' ) [ 1 ] ) . get ( 'path' ) } ` ,
356+ )
357+ }
358+ href = "#"
359+ target = "_blank"
360+ sx = { { fontSize : 12 } }
361+ >
362+ Documentation
363+ < Launch />
364+ </ Link >
365+ ) }
360366 </ TableCell >
361367 </ TableRow >
362368 ) ) }
@@ -376,122 +382,119 @@ const ConfigurationModal = ({
376382 >
377383 < Stack direction = "column" spacing = { 2 } >
378384 < ConfigEditor catalogItem = { catalogItem } client = { client } />
379- { ddInfo ?. hasSecretSupport &&
380- catalogItem . secrets &&
381- catalogItem . secrets ?. length > 0 && (
382- < Stack spacing = { 1 } >
383- < Typography variant = "subtitle2" > Secrets</ Typography >
384- { ! ddInfo && ! ddInfoLoading && (
385- < Alert severity = "error" >
386- Failed to get Docker Desktop version
387- </ Alert >
388- ) }
389- { ddInfo && ! ddInfo ?. hasSecretSupport && (
390- < Alert severity = "error" >
391- { getUnsupportedSecretMessage ( ddInfo ?. parsedVersion ) }
392- </ Alert >
393- ) }
394- < Stack >
395- { ddInfo ?. hasSecretSupport &&
396- catalogItem . secrets &&
397- catalogItem . secrets ?. length > 0 &&
398- catalogItem . secrets . map ( ( secret , index ) => {
399- const secretEdited =
400- ( secret . assigned &&
401- localSecrets [ secret . name ] !==
385+ { catalogItem . secrets && catalogItem . secrets . length > 0 && (
386+ < Stack spacing = { 1 } >
387+ < Typography variant = "subtitle2" > Secrets</ Typography >
388+ { ! ddInfo && ! ddInfoLoading && (
389+ < Alert severity = "error" >
390+ Failed to get Docker Desktop version
391+ </ Alert >
392+ ) }
393+ { ddInfo && ! ddInfo ?. hasSecretSupport && (
394+ < Alert severity = "error" >
395+ { getUnsupportedSecretMessage ( ddInfo ?. parsedVersion ) }
396+ </ Alert >
397+ ) }
398+ < Stack >
399+ { ddInfo ?. hasSecretSupport &&
400+ catalogItem . secrets &&
401+ catalogItem . secrets ?. length > 0 &&
402+ catalogItem . secrets . map ( ( secret , index ) => {
403+ const secretEdited =
404+ ( secret . assigned &&
405+ localSecrets [ secret . name ] !==
402406 ASSIGNED_SECRET_PLACEHOLDER ) ||
403- ( ! secret . assigned &&
404- localSecrets [ secret . name ] !== '' ) ;
405- return (
406- < Stack
407+ ( ! secret . assigned &&
408+ localSecrets [ secret . name ] !== '' ) ;
409+ return (
410+ < Stack
411+ key = { secret . name }
412+ direction = "row"
413+ spacing = { 2 }
414+ sx = { {
415+ alignItems : 'center' ,
416+ } }
417+ >
418+ < TextField
419+ size = "small"
420+ inputRef = { ( element ) =>
421+ ( inputRefs . current [ index ] = element )
422+ }
423+ disabled = { secret . assigned }
407424 key = { secret . name }
408- direction = "row"
409- spacing = { 2 }
410- sx = { {
411- alignItems : 'center' ,
425+ label = { `${ secret . name } (required)` }
426+ value = { localSecrets [ secret . name ] }
427+ fullWidth
428+ onChange = { ( e ) => {
429+ setLocalSecrets ( {
430+ ...localSecrets ,
431+ [ secret . name ] : e . target . value ,
432+ } ) ;
412433 } }
413- >
414- < TextField
434+ type = "password"
435+ />
436+ { secret . assigned && ! secretEdited && (
437+ < IconButton
415438 size = "small"
416- inputRef = { ( element ) =>
417- ( inputRefs . current [ index ] = element )
418- }
419- disabled = { secret . assigned }
420- key = { secret . name }
421- label = { `${ secret . name } (required)` }
422- value = { localSecrets [ secret . name ] }
423- fullWidth
424- onChange = { ( e ) => {
439+ onClick = { ( ) => {
425440 setLocalSecrets ( {
426441 ...localSecrets ,
427- [ secret . name ] : e . target . value ,
442+ [ secret . name ] : '' ,
443+ } ) ;
444+ // We need to enable the input to be able to focus on it
445+ inputRefs . current [ index ] . disabled = false ;
446+ inputRefs . current [ index ] . focus ( ) ;
447+ mutateSecret . mutateAsync ( {
448+ name : secret . name ,
449+ value : undefined ,
450+ policies : [ MCP_POLICY_NAME ] ,
428451 } ) ;
429452 } }
430- type = "password"
431- />
432- { secret . assigned && ! secretEdited && (
433- < IconButton
434- size = "small"
435- onClick = { ( ) => {
436- setLocalSecrets ( {
437- ...localSecrets ,
438- [ secret . name ] : '' ,
439- } ) ;
440- // We need to enable the input to be able to focus on it
441- inputRefs . current [ index ] . disabled =
442- false ;
443- inputRefs . current [ index ] . focus ( ) ;
444- mutateSecret . mutateAsync ( {
445- name : secret . name ,
446- value : undefined ,
447- policies : [ MCP_POLICY_NAME ] ,
448- } ) ;
449- } }
450- >
451- < EditOutlinedIcon fontSize = "small" />
452- </ IconButton >
453+ >
454+ < EditOutlinedIcon fontSize = "small" />
455+ </ IconButton >
456+ ) }
457+ { secretEdited &&
458+ localSecrets [ secret . name ] !== '' && (
459+ < Stack direction = "row" spacing = { 1 } >
460+ < IconButton
461+ size = "small"
462+ onClick = { async ( ) => {
463+ await mutateSecret . mutateAsync ( {
464+ name : secret . name ,
465+ value : localSecrets [ secret . name ] ! ,
466+ policies : [ MCP_POLICY_NAME ] ,
467+ } ) ;
468+ } }
469+ >
470+ < CheckOutlined
471+ fontSize = "small"
472+ sx = { { color : 'success.main' } }
473+ />
474+ </ IconButton >
475+ < IconButton
476+ size = "small"
477+ onClick = { async ( ) => {
478+ inputRefs . current [ index ] . focus ( ) ;
479+ setLocalSecrets ( {
480+ ...localSecrets ,
481+ [ secret . name ] : '' ,
482+ } ) ;
483+ } }
484+ >
485+ < CloseOutlined
486+ fontSize = "small"
487+ sx = { { color : 'error.main' } }
488+ />
489+ </ IconButton >
490+ </ Stack >
453491 ) }
454- { secretEdited &&
455- localSecrets [ secret . name ] !== '' && (
456- < Stack direction = "row" spacing = { 1 } >
457- < IconButton
458- size = "small"
459- onClick = { async ( ) => {
460- await mutateSecret . mutateAsync ( {
461- name : secret . name ,
462- value : localSecrets [ secret . name ] ! ,
463- policies : [ MCP_POLICY_NAME ] ,
464- } ) ;
465- } }
466- >
467- < CheckOutlined
468- fontSize = "small"
469- sx = { { color : 'success.main' } }
470- />
471- </ IconButton >
472- < IconButton
473- size = "small"
474- onClick = { async ( ) => {
475- inputRefs . current [ index ] . focus ( ) ;
476- setLocalSecrets ( {
477- ...localSecrets ,
478- [ secret . name ] : '' ,
479- } ) ;
480- } }
481- >
482- < CloseOutlined
483- fontSize = "small"
484- sx = { { color : 'error.main' } }
485- />
486- </ IconButton >
487- </ Stack >
488- ) }
489- </ Stack >
490- ) ;
491- } ) }
492- </ Stack >
492+ </ Stack >
493+ ) ;
494+ } ) }
493495 </ Stack >
494- ) }
496+ </ Stack >
497+ ) }
495498 </ Stack >
496499 </ Stack >
497500 </ TabPanel >
0 commit comments