@@ -5,21 +5,23 @@ import AddIcon from '@mui/icons-material/Add';
55import { Ref } from '../Refs' ;
66import { v1 } from "@docker/extension-api-client-types" ;
77import { parse , stringify } from 'yaml' ;
8- import { getRegistry } from '../Registry' ;
8+ import { getRegistry , syncConfigWithRegistry , syncRegistryWithConfig } from '../Registry' ;
99import { FolderOpenRounded , Search , Settings } from '@mui/icons-material' ;
1010import { tryRunImageSync } from '../FileWatcher' ;
1111import { CATALOG_URL , DD_BUILD_WITH_SECRET_SUPPORT , MCP_POLICY_NAME , POLL_INTERVAL } from '../Constants' ;
1212import { SecretList } from './SecretList' ;
1313import Secrets from '../Secrets' ;
14+ import { ParsedParameters } from './PromptConfig' ;
1415
1516interface CatalogGridProps {
16- registryItems : { [ key : string ] : { ref : string } } ;
17+ registryItems : { [ key : string ] : { ref : string , config : any } } ;
1718 canRegister : boolean ;
1819 client : v1 . DockerDesktopClient ;
1920 onRegistryChange : ( ) => void ;
2021 showSettings : ( ) => void ;
2122 settingsBadgeProps : BadgeProps ;
2223 setConfiguringItem : ( item : CatalogItemWithName ) => void ;
24+ config : { [ key : string ] : { [ key : string ] : ParsedParameters } } ;
2325}
2426
2527const filterCatalog = ( catalogItems : CatalogItemWithName [ ] , registryItems : { [ key : string ] : { ref : string } } , search : string ) =>
@@ -42,7 +44,8 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
4244 onRegistryChange,
4345 showSettings,
4446 settingsBadgeProps,
45- setConfiguringItem
47+ setConfiguringItem,
48+ config
4649} ) => {
4750 const [ catalogItems , setCatalogItems ] = useState < CatalogItemWithName [ ] > ( [ ] ) ;
4851 const [ showReloadModal , setShowReloadModal ] = useState < boolean > ( false ) ;
@@ -105,6 +108,8 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
105108 if ( showNotification ) {
106109 setShowReloadModal ( ! localStorage . getItem ( NEVER_SHOW_AGAIN_KEY ) ) ;
107110 }
111+ await syncConfigWithRegistry ( client ) ;
112+ await syncRegistryWithConfig ( client ) ;
108113 }
109114 catch ( error ) {
110115 if ( showNotification ) {
@@ -127,6 +132,8 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
127132 client . desktopUI . toast . success ( 'Prompt unregistered successfully. Restart Claude Desktop to apply.' ) ;
128133 onRegistryChange ( ) ;
129134 setShowReloadModal ( ! localStorage . getItem ( NEVER_SHOW_AGAIN_KEY ) ) ;
135+ await syncConfigWithRegistry ( client ) ;
136+ await syncRegistryWithConfig ( client ) ;
130137 }
131138 catch ( error ) {
132139 client . desktopUI . toast . error ( 'Failed to unregister prompt: ' + error )
@@ -206,27 +213,32 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
206213 </ FormGroup >
207214
208215 { 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+ } ) }
230242 < Grid2 size = { 12 } >
231243 < Card sx = { { height : '100%' , display : 'flex' , justifyContent : 'center' , alignItems : 'center' } } >
232244 < CardContent >
@@ -240,16 +252,19 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
240252 </ Grid2 >
241253 </ Grid2 > }
242254 { 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+ } ) }
253268 </ Grid2 > }
254269 { tab === 2 && ddVersion && < SecretList secrets = { secrets } ddVersion = { ddVersion } /> }
255270 </ Stack >
0 commit comments