1
1
import { createDockerDesktopClient } from '@docker/extension-api-client' ;
2
2
import { ExecResult } from '@docker/extension-api-client-types/dist/v0' ;
3
3
import FolderOpenRounded from '@mui/icons-material/FolderOpenRounded' ;
4
- import { Alert , AlertTitle , Badge , Box , Button , Checkbox , CircularProgress , Dialog , DialogContent , DialogTitle , FormControlLabel , FormGroup , OutlinedInput , Stack , Switch , Tab , Tabs , Typography } from '@mui/material' ;
4
+ import SwapVert from '@mui/icons-material/SwapVert' ;
5
+ import { Alert , AlertTitle , Badge , Box , Button , Checkbox , CircularProgress , Dialog , DialogContent , DialogTitle , Divider , FormControlLabel , FormGroup , IconButton , Menu , MenuItem , OutlinedInput , Stack , Switch , Tab , Tabs , Typography } from '@mui/material' ;
5
6
import React , { Suspense , useEffect , useState , useCallback , useMemo } from 'react' ;
7
+
6
8
import { CATALOG_LAYOUT_SX } from '../Constants' ;
7
9
import { MCPClientState } from '../MCPClients' ;
8
10
import { CatalogItemRichened } from '../types/catalog' ;
@@ -43,6 +45,10 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
43
45
const [ tab , setTab ] = useState < number > ( 0 ) ;
44
46
const [ ddVersion , setDdVersion ] = useState < { version : string , build : number } | null > ( null ) ;
45
47
const [ showMine , setShowMine ] = useState < boolean > ( localStorage . getItem ( 'showMine' ) === 'true' ) ;
48
+ const [ openMenus , setOpenMenus ] = useState < { [ key : string ] : { anchorEl : HTMLElement | null , open : boolean } } > ( {
49
+ 'demo-customized-menu' : { anchorEl : null , open : false }
50
+ } ) ;
51
+ const [ sort , setSort ] = useState < 'name-asc' | 'name-desc' | 'date-desc' > ( 'date-desc' ) ;
46
52
47
53
const loadDDVersion = useCallback ( async ( ) => {
48
54
try {
@@ -134,12 +140,52 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
134
140
< FormGroup >
135
141
< Stack direction = "row" spacing = { 1 } alignItems = 'center' justifyContent = "space-evenly" >
136
142
< OutlinedInput size = "small" type = "search" placeholder = "Search" sx = { { width : 380 } } value = { search } onChange = { ( e ) => setSearch ( e . target . value ) } />
143
+ < IconButton
144
+ size = "small"
145
+ id = "demo-customized-button"
146
+ aria-controls = { openMenus [ 'demo-customized-menu' ] ? 'demo-customized-menu' : undefined }
147
+ aria-haspopup = "true"
148
+ aria-expanded = { openMenus [ 'demo-customized-menu' ] ? 'true' : undefined }
149
+ onClick = { ( e ) => setOpenMenus ( { ...openMenus , 'demo-customized-menu' : { anchorEl : e . currentTarget , open : ! openMenus [ 'demo-customized-menu' ] . open } } ) }
150
+ >
151
+ < SwapVert fontSize = "small" />
152
+ </ IconButton >
137
153
< FormControlLabel control = { < Switch checked = { showMine } onChange = { ( e ) => {
138
154
setShowMine ( e . target . checked )
139
155
localStorage . setItem ( 'showMine' , e . target . checked . toString ( ) )
140
156
} } /> } label = "Show only enabled tools" />
141
157
</ Stack >
142
158
</ FormGroup >
159
+
160
+ < Menu
161
+ id = "demo-customized-menu"
162
+ MenuListProps = { {
163
+ 'aria-labelledby' : 'demo-customized-button' ,
164
+ } }
165
+ anchorEl = { openMenus [ 'demo-customized-menu' ] . anchorEl || undefined }
166
+ open = { openMenus [ 'demo-customized-menu' ] . open }
167
+ onClose = { ( ) => setOpenMenus ( { ...openMenus , 'demo-customized-menu' : { anchorEl : null , open : false } } ) }
168
+ >
169
+ < MenuItem sx = { { fontWeight : sort === 'date-desc' ? 'bold' : 'normal' } } onClick = { ( ) => {
170
+ setOpenMenus ( { ...openMenus , 'demo-customized-menu' : { anchorEl : null , open : false } } )
171
+ setSort ( 'date-desc' )
172
+ } } disableRipple >
173
+ ⏰ Most Recent
174
+ </ MenuItem >
175
+ < Divider sx = { { my : 0.5 } } />
176
+ < MenuItem sx = { { fontWeight : sort === 'name-asc' ? 'bold' : 'normal' } } onClick = { ( ) => {
177
+ setOpenMenus ( { ...openMenus , 'demo-customized-menu' : { anchorEl : null , open : false } } )
178
+ setSort ( 'name-asc' )
179
+ } } disableRipple >
180
+ Name (A-Z)
181
+ </ MenuItem >
182
+ < MenuItem sx = { { fontWeight : sort === 'name-desc' ? 'bold' : 'normal' } } onClick = { ( ) => {
183
+ setOpenMenus ( { ...openMenus , 'demo-customized-menu' : { anchorEl : null , open : false } } )
184
+ setSort ( 'name-desc' )
185
+ } } disableRipple >
186
+ Name (Z-A)
187
+ </ MenuItem >
188
+ </ Menu >
143
189
</ Stack >
144
190
}
145
191
@@ -150,6 +196,7 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
150
196
search = { search }
151
197
showMine = { showMine }
152
198
client = { client }
199
+ sort = { sort }
153
200
/>
154
201
) }
155
202
{ tab === 1 && (
0 commit comments