@@ -24,6 +24,7 @@ import { CatalogItemRichened } from '../types/catalog';
2424import OAuthProviders from './tabs/OAuthProviders' ;
2525import ToolCatalog from './tabs/ToolCatalog' ;
2626import YourClients from './tabs/YourClients' ;
27+ import { DeprecationNotice } from './DeprecationNotice' ;
2728
2829// Initialize the Docker Desktop client
2930const client = createDockerDesktopClient ( ) ;
@@ -36,6 +37,10 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({ appProps }) => {
3637 // Extract all the values we need from appProps
3738 const { catalogItems, registryItems } = appProps ;
3839
40+ const [ hasSeenDeprecationNotice , setHasSeenDeprecationNotice ] = useState (
41+ localStorage . getItem ( 'extensionDeprecationNotice' ) === 'true' ,
42+ ) ;
43+
3944 const [ search , setSearch ] = useState < string > ( '' ) ;
4045 const [ tab , setTab ] = useState < number > ( 0 ) ;
4146 const [ openMenus , setOpenMenus ] = useState < {
@@ -78,168 +83,201 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({ appProps }) => {
7883 >
7984 < Typography variant = "h3" > Docker MCP Toolkit</ Typography >
8085 < Typography sx = { { color : 'text.secondary' } } >
81- Browse and connect Dockerized MCP servers to your favorite MCP clients.
86+ Browse and connect Dockerized MCP servers to your favorite MCP
87+ clients.
8288 </ Typography >
8389 </ Stack >
84- { hasOutOfCatalog && (
85- < Alert
86- action = {
87- < Button
88- startIcon = { < FolderOpenRounded /> }
89- variant = "outlined"
90- color = "secondary"
91- onClick = { ( ) => {
92- client . desktopUI . navigate . viewVolume ( 'docker-prompts' ) ;
93- } }
94- >
95- registry.yaml
96- </ Button >
97- }
98- severity = "info"
99- >
100- < Typography sx = { { width : '100%' } } >
101- You have some prompts registered which are not available in the
102- catalog.
103- </ Typography >
104- </ Alert >
105- ) }
10690
107- < Stack spacing = { 2 } sx = { { width : 'fit-content' , alignSelf : 'center' } } >
108- < Box
109- sx = { {
110- position : 'sticky' ,
111- top : 0 ,
112- zIndex : 1000 ,
113- backgroundColor : 'background.default' ,
114- } }
115- >
116- < Tabs
117- value = { tab }
118- onChange = { ( _ , newValue ) => setTab ( newValue ) }
119- sx = { CATALOG_LAYOUT_SX }
91+ { ! hasSeenDeprecationNotice ? (
92+ < DeprecationNotice onClose = { ( ) => setHasSeenDeprecationNotice ( true ) } />
93+ ) : (
94+ < >
95+ < Alert
96+ severity = "info"
97+ action = {
98+ < Button
99+ variant = "outlined"
100+ onClick = { ( ) => setHasSeenDeprecationNotice ( false ) }
101+ >
102+ See the notice
103+ </ Button >
104+ }
120105 >
121- < Tab label = "MCP Servers" />
122- < Tab label = "MCP Clients" />
123- { /* <Tab label="OAuth Providers" /> */ }
124- </ Tabs >
125- { tab === 0 && (
126- < Stack
127- direction = "row"
128- spacing = { 1 }
129- alignItems = "center"
130- sx = { { mt : 1 , py : 1 , ...CATALOG_LAYOUT_SX } }
106+ Docker MCP Toolkit is now{ ' ' }
107+ < strong > generally available and integrated</ strong > with Docker
108+ Desktop 4.42 and later.
109+ </ Alert >
110+ { hasOutOfCatalog && (
111+ < Alert
112+ action = {
113+ < Button
114+ startIcon = { < FolderOpenRounded /> }
115+ variant = "outlined"
116+ color = "secondary"
117+ onClick = { ( ) => {
118+ client . desktopUI . navigate . viewVolume ( 'docker-prompts' ) ;
119+ } }
120+ >
121+ registry.yaml
122+ </ Button >
123+ }
124+ severity = "info"
125+ >
126+ < Typography sx = { { width : '100%' } } >
127+ You have some prompts registered which are not available in the
128+ catalog.
129+ </ Typography >
130+ </ Alert >
131+ ) }
132+
133+ < Stack spacing = { 2 } sx = { { width : 'fit-content' , alignSelf : 'center' } } >
134+ < Box
135+ sx = { {
136+ position : 'sticky' ,
137+ top : 0 ,
138+ zIndex : 1000 ,
139+ backgroundColor : 'background.default' ,
140+ } }
131141 >
132- < FormGroup >
142+ < Tabs
143+ value = { tab }
144+ onChange = { ( _ , newValue ) => setTab ( newValue ) }
145+ sx = { CATALOG_LAYOUT_SX }
146+ >
147+ < Tab label = "MCP Servers" />
148+ < Tab label = "MCP Clients" />
149+ { /* <Tab label="OAuth Providers" /> */ }
150+ </ Tabs >
151+ { tab === 0 && (
133152 < Stack
134153 direction = "row"
135154 spacing = { 1 }
136155 alignItems = "center"
137- justifyContent = "space-evenly"
156+ sx = { { mt : 1 , py : 1 , ... CATALOG_LAYOUT_SX } }
138157 >
139- < OutlinedInput
140- startAdornment = { < SearchIcon color = "secondary" /> }
141- size = "small"
142- type = "search"
143- placeholder = "Search"
144- sx = { { width : 380 } }
145- value = { search }
146- onChange = { ( e ) => setSearch ( e . target . value ) }
147- />
148- < IconButton
149- size = "small"
150- id = "demo-customized-button"
151- aria-controls = {
152- openMenus [ 'demo-customized-menu' ]
153- ? 'demo-customized-menu'
154- : undefined
155- }
156- aria-haspopup = "true"
157- aria-expanded = {
158- openMenus [ 'demo-customized-menu' ] ? 'true' : undefined
158+ < FormGroup >
159+ < Stack
160+ direction = "row"
161+ spacing = { 1 }
162+ alignItems = "center"
163+ justifyContent = "space-evenly"
164+ >
165+ < OutlinedInput
166+ startAdornment = { < SearchIcon color = "secondary" /> }
167+ size = "small"
168+ type = "search"
169+ placeholder = "Search"
170+ sx = { { width : 380 } }
171+ value = { search }
172+ onChange = { ( e ) => setSearch ( e . target . value ) }
173+ />
174+ < IconButton
175+ size = "small"
176+ id = "demo-customized-button"
177+ aria-controls = {
178+ openMenus [ 'demo-customized-menu' ]
179+ ? 'demo-customized-menu'
180+ : undefined
181+ }
182+ aria-haspopup = "true"
183+ aria-expanded = {
184+ openMenus [ 'demo-customized-menu' ] ? 'true' : undefined
185+ }
186+ onClick = { ( e ) =>
187+ setOpenMenus ( {
188+ ...openMenus ,
189+ 'demo-customized-menu' : {
190+ anchorEl : e . currentTarget ,
191+ open : ! openMenus [ 'demo-customized-menu' ] . open ,
192+ } ,
193+ } )
194+ }
195+ >
196+ < SwapVert fontSize = "small" />
197+ </ IconButton >
198+ </ Stack >
199+ </ FormGroup >
200+
201+ < Menu
202+ id = "demo-customized-menu"
203+ MenuListProps = { {
204+ 'aria-labelledby' : 'demo-customized-button' ,
205+ } }
206+ anchorEl = {
207+ openMenus [ 'demo-customized-menu' ] . anchorEl || undefined
159208 }
160- onClick = { ( e ) =>
209+ open = { openMenus [ 'demo-customized-menu' ] . open }
210+ onClose = { ( ) =>
161211 setOpenMenus ( {
162212 ...openMenus ,
163- 'demo-customized-menu' : {
164- anchorEl : e . currentTarget ,
165- open : ! openMenus [ 'demo-customized-menu' ] . open ,
166- } ,
213+ 'demo-customized-menu' : { anchorEl : null , open : false } ,
167214 } )
168215 }
169216 >
170- < SwapVert fontSize = "small" />
171- </ IconButton >
217+ < MenuItem
218+ sx = { {
219+ fontWeight : sort === 'name-asc' ? 'bold' : 'normal' ,
220+ } }
221+ onClick = { ( ) => {
222+ setOpenMenus ( {
223+ ...openMenus ,
224+ 'demo-customized-menu' : {
225+ anchorEl : null ,
226+ open : false ,
227+ } ,
228+ } ) ;
229+ setSort ( 'name-asc' ) ;
230+ } }
231+ disableRipple
232+ >
233+ Name (A-Z)
234+ </ MenuItem >
235+ < MenuItem
236+ sx = { {
237+ fontWeight : sort === 'name-desc' ? 'bold' : 'normal' ,
238+ } }
239+ onClick = { ( ) => {
240+ setOpenMenus ( {
241+ ...openMenus ,
242+ 'demo-customized-menu' : {
243+ anchorEl : null ,
244+ open : false ,
245+ } ,
246+ } ) ;
247+ setSort ( 'name-desc' ) ;
248+ } }
249+ disableRipple
250+ >
251+ Name (Z-A)
252+ </ MenuItem >
253+ </ Menu >
172254 </ Stack >
173- </ FormGroup >
174-
175- < Menu
176- id = "demo-customized-menu"
177- MenuListProps = { {
178- 'aria-labelledby' : 'demo-customized-button' ,
179- } }
180- anchorEl = {
181- openMenus [ 'demo-customized-menu' ] . anchorEl || undefined
182- }
183- open = { openMenus [ 'demo-customized-menu' ] . open }
184- onClose = { ( ) =>
185- setOpenMenus ( {
186- ...openMenus ,
187- 'demo-customized-menu' : { anchorEl : null , open : false } ,
188- } )
189- }
190- >
191- < MenuItem
192- sx = { { fontWeight : sort === 'name-asc' ? 'bold' : 'normal' } }
193- onClick = { ( ) => {
194- setOpenMenus ( {
195- ...openMenus ,
196- 'demo-customized-menu' : { anchorEl : null , open : false } ,
197- } ) ;
198- setSort ( 'name-asc' ) ;
199- } }
200- disableRipple
201- >
202- Name (A-Z)
203- </ MenuItem >
204- < MenuItem
205- sx = { { fontWeight : sort === 'name-desc' ? 'bold' : 'normal' } }
206- onClick = { ( ) => {
207- setOpenMenus ( {
208- ...openMenus ,
209- 'demo-customized-menu' : { anchorEl : null , open : false } ,
210- } ) ;
211- setSort ( 'name-desc' ) ;
212- } }
213- disableRipple
214- >
215- Name (Z-A)
216- </ MenuItem >
217- </ Menu >
218- </ Stack >
219- ) }
220- </ Box >
221- < Suspense
222- fallback = {
223- < Box sx = { { display : 'flex' , justifyContent : 'center' , p : 4 } } >
224- < CircularProgress />
225- </ Box >
226- }
227- >
228- { tab === 0 && (
229- < ToolCatalog search = { search } client = { client } sort = { sort } />
230- ) }
231- { tab === 1 && < YourClients appProps = { appProps } /> }
232- </ Suspense >
233- < Suspense
234- fallback = {
235- < Box sx = { { display : 'flex' , justifyContent : 'center' , p : 4 } } >
236- < CircularProgress />
255+ ) }
237256 </ Box >
238- }
239- >
240- { tab === 2 && < OAuthProviders client = { client } /> }
241- </ Suspense >
242- </ Stack >
257+ < Suspense
258+ fallback = {
259+ < Box sx = { { display : 'flex' , justifyContent : 'center' , p : 4 } } >
260+ < CircularProgress />
261+ </ Box >
262+ }
263+ >
264+ { tab === 0 && (
265+ < ToolCatalog search = { search } client = { client } sort = { sort } />
266+ ) }
267+ { tab === 1 && < YourClients appProps = { appProps } /> }
268+ </ Suspense >
269+ < Suspense
270+ fallback = {
271+ < Box sx = { { display : 'flex' , justifyContent : 'center' , p : 4 } } >
272+ < CircularProgress />
273+ </ Box >
274+ }
275+ >
276+ { tab === 2 && < OAuthProviders client = { client } /> }
277+ </ Suspense >
278+ </ Stack >
279+ </ >
280+ ) }
243281 </ Stack >
244282 ) ;
245283} ;
0 commit comments