@@ -5,21 +5,23 @@ import AddIcon from '@mui/icons-material/Add';
5
5
import { Ref } from '../Refs' ;
6
6
import { v1 } from "@docker/extension-api-client-types" ;
7
7
import { parse , stringify } from 'yaml' ;
8
- import { getRegistry } from '../Registry' ;
8
+ import { getRegistry , syncConfigWithRegistry , syncRegistryWithConfig } from '../Registry' ;
9
9
import { FolderOpenRounded , Search , Settings } from '@mui/icons-material' ;
10
10
import { tryRunImageSync } from '../FileWatcher' ;
11
11
import { CATALOG_URL , DD_BUILD_WITH_SECRET_SUPPORT , MCP_POLICY_NAME , POLL_INTERVAL } from '../Constants' ;
12
12
import { SecretList } from './SecretList' ;
13
13
import Secrets from '../Secrets' ;
14
+ import { ParsedParameters } from './PromptConfig' ;
14
15
15
16
interface CatalogGridProps {
16
- registryItems : { [ key : string ] : { ref : string } } ;
17
+ registryItems : { [ key : string ] : { ref : string , config : any } } ;
17
18
canRegister : boolean ;
18
19
client : v1 . DockerDesktopClient ;
19
20
onRegistryChange : ( ) => void ;
20
21
showSettings : ( ) => void ;
21
22
settingsBadgeProps : BadgeProps ;
22
23
setConfiguringItem : ( item : CatalogItemWithName ) => void ;
24
+ config : { [ key : string ] : { [ key : string ] : ParsedParameters } } ;
23
25
}
24
26
25
27
const filterCatalog = ( catalogItems : CatalogItemWithName [ ] , registryItems : { [ key : string ] : { ref : string } } , search : string ) =>
@@ -42,7 +44,8 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
42
44
onRegistryChange,
43
45
showSettings,
44
46
settingsBadgeProps,
45
- setConfiguringItem
47
+ setConfiguringItem,
48
+ config
46
49
} ) => {
47
50
const [ catalogItems , setCatalogItems ] = useState < CatalogItemWithName [ ] > ( [ ] ) ;
48
51
const [ showReloadModal , setShowReloadModal ] = useState < boolean > ( false ) ;
@@ -105,6 +108,8 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
105
108
if ( showNotification ) {
106
109
setShowReloadModal ( ! localStorage . getItem ( NEVER_SHOW_AGAIN_KEY ) ) ;
107
110
}
111
+ await syncConfigWithRegistry ( client ) ;
112
+ await syncRegistryWithConfig ( client ) ;
108
113
}
109
114
catch ( error ) {
110
115
if ( showNotification ) {
@@ -127,6 +132,8 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
127
132
client . desktopUI . toast . success ( 'Prompt unregistered successfully. Restart Claude Desktop to apply.' ) ;
128
133
onRegistryChange ( ) ;
129
134
setShowReloadModal ( ! localStorage . getItem ( NEVER_SHOW_AGAIN_KEY ) ) ;
135
+ await syncConfigWithRegistry ( client ) ;
136
+ await syncRegistryWithConfig ( client ) ;
130
137
}
131
138
catch ( error ) {
132
139
client . desktopUI . toast . error ( 'Failed to unregister prompt: ' + error )
@@ -206,27 +213,32 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
206
213
</ FormGroup >
207
214
208
215
{ tab === 0 && < Grid2 container spacing = { 1 } width = '90vw' maxWidth = { 1000 } >
209
- { filteredCatalogItems . map ( ( item ) => (
210
- < Grid2 size = { { xs : 12 , sm : 6 , md : 4 } } key = { item . name } >
211
- < CatalogItemCard
212
- setConfiguringItem = { setConfiguringItem }
213
- openUrl = { ( ) => {
214
- client . host . openExternal ( Ref . fromRef ( item . ref ) . toURL ( true ) ) ;
215
- } }
216
- item = { item }
217
- ddVersion = { ddVersion }
218
- canRegister = { canRegister }
219
- registered = { Object . keys ( registryItems ) . some ( ( i ) => i === item . name ) }
220
- register = { registerCatalogItem }
221
- unregister = { unregisterCatalogItem }
222
- onSecretChange = { async ( secret ) => {
223
- await Secrets . addSecret ( client , { name : secret . name , value : secret . value , policies : [ MCP_POLICY_NAME ] } )
224
- loadSecrets ( ) ;
225
- } }
226
- secrets = { secrets }
227
- />
228
- </ Grid2 >
229
- ) ) }
216
+ { filteredCatalogItems . map ( ( catalogItem ) => {
217
+ const expectedProperties = catalogItem . config ?. map ( ( c : { name : string , parameters : ParsedParameters } ) => Object . keys ( c . parameters ) ) . flat ( ) || [ ]
218
+ const hasAllConfig = ! expectedProperties . length || expectedProperties . every ( ( p : string ) => config [ catalogItem . name ] ?. [ p ] )
219
+ return (
220
+ < Grid2 size = { { xs : 12 , sm : 6 , md : 4 } } key = { catalogItem . name } >
221
+ < CatalogItemCard
222
+ hasAllConfig = { hasAllConfig }
223
+ setConfiguringItem = { setConfiguringItem }
224
+ openUrl = { ( ) => {
225
+ client . host . openExternal ( Ref . fromRef ( catalogItem . ref ) . toURL ( true ) ) ;
226
+ } }
227
+ item = { catalogItem }
228
+ ddVersion = { ddVersion }
229
+ canRegister = { canRegister }
230
+ registered = { Object . keys ( registryItems ) . some ( ( i ) => i === catalogItem . name ) }
231
+ register = { registerCatalogItem }
232
+ unregister = { unregisterCatalogItem }
233
+ onSecretChange = { async ( secret ) => {
234
+ await Secrets . addSecret ( client , { name : secret . name , value : secret . value , policies : [ MCP_POLICY_NAME ] } )
235
+ loadSecrets ( ) ;
236
+ } }
237
+ secrets = { secrets }
238
+ />
239
+ </ Grid2 >
240
+ )
241
+ } ) }
230
242
< Grid2 size = { 12 } >
231
243
< Card sx = { { height : '100%' , display : 'flex' , justifyContent : 'center' , alignItems : 'center' } } >
232
244
< CardContent >
@@ -240,16 +252,19 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
240
252
</ Grid2 >
241
253
</ Grid2 > }
242
254
{ tab === 1 && < Grid2 container spacing = { 1 } width = '90vw' maxWidth = { 1000 } >
243
- { Object . entries ( registryItems ) . map ( ( [ name , item ] ) => (
244
- name . toLowerCase ( ) . includes ( search . toLowerCase ( ) ) && < Grid2 size = { { xs : 12 , sm : 6 , md : 4 } } key = { name } >
245
- < CatalogItemCard ddVersion = { ddVersion } item = { catalogItems . find ( ( i ) => i . name === name ) ! } openUrl = { ( ) => {
246
- client . host . openExternal ( Ref . fromRef ( item . ref ) . toURL ( true ) ) ;
247
- } } canRegister = { canRegister } registered = { true } register = { registerCatalogItem } unregister = { unregisterCatalogItem } onSecretChange = { async ( secret ) => {
248
- await Secrets . addSecret ( client , { name : secret . name , value : secret . value , policies : [ MCP_POLICY_NAME ] } )
249
- loadSecrets ( ) ;
250
- } } secrets = { secrets } setConfiguringItem = { setConfiguringItem } />
251
- </ Grid2 >
252
- ) ) }
255
+ { Object . entries ( registryItems ) . map ( ( [ name , item ] ) => {
256
+ const hasAllConfig = item . config ?. map ( ( c : any ) => c . name ) . every ( ( c : any ) => config [ name ] ?. [ c ] )
257
+ return (
258
+ name . toLowerCase ( ) . includes ( search . toLowerCase ( ) ) && < Grid2 size = { { xs : 12 , sm : 6 , md : 4 } } key = { name } >
259
+ < CatalogItemCard hasAllConfig = { hasAllConfig } ddVersion = { ddVersion } item = { catalogItems . find ( ( i ) => i . name === name ) ! } openUrl = { ( ) => {
260
+ client . host . openExternal ( Ref . fromRef ( item . ref ) . toURL ( true ) ) ;
261
+ } } canRegister = { canRegister } registered = { true } register = { registerCatalogItem } unregister = { unregisterCatalogItem } onSecretChange = { async ( secret ) => {
262
+ await Secrets . addSecret ( client , { name : secret . name , value : secret . value , policies : [ MCP_POLICY_NAME ] } )
263
+ loadSecrets ( ) ;
264
+ } } secrets = { secrets } setConfiguringItem = { setConfiguringItem } />
265
+ </ Grid2 >
266
+ )
267
+ } ) }
253
268
</ Grid2 > }
254
269
{ tab === 2 && ddVersion && < SecretList secrets = { secrets } ddVersion = { ddVersion } /> }
255
270
</ Stack >
0 commit comments