@@ -4,15 +4,8 @@ import {
4
4
Typography ,
5
5
Paper ,
6
6
Divider ,
7
- Switch ,
8
- FormControlLabel ,
9
7
TextField ,
10
8
Button ,
11
- Select ,
12
- MenuItem ,
13
- FormControl ,
14
- InputLabel ,
15
- Grid ,
16
9
Accordion ,
17
10
AccordionSummary ,
18
11
AccordionDetails ,
@@ -21,41 +14,32 @@ import {
21
14
List ,
22
15
ListItem ,
23
16
ListItemText ,
24
- ListItemSecondaryAction ,
25
17
Chip ,
26
- Card ,
27
- CardContent ,
28
18
Stack ,
29
19
Grid2 ,
30
- ListItemIcon ,
31
- ButtonGroup ,
32
- Link
20
+ Link ,
21
+ CircularProgress
33
22
} from '@mui/material' ;
34
23
import {
35
24
ExpandMore as ExpandMoreIcon ,
36
- Save as SaveIcon ,
37
- Refresh as RefreshIcon ,
38
- Info as InfoIcon ,
39
- Add as AddIcon ,
40
- Delete as DeleteIcon ,
41
- Edit as EditIcon ,
42
25
ContentCopy ,
43
- RemoveCircleOutline ,
44
- ConnectWithoutContact ,
45
26
LinkOff ,
46
27
LinkRounded ,
47
- Delete
28
+ SaveOutlined
48
29
} from '@mui/icons-material' ;
49
30
import { DOCKER_MCP_CONFIG , MCPClient } from '../Constants' ;
50
31
import { client } from '../App' ;
32
+ import { MCPClientState } from '../MCPClients' ;
51
33
52
- const Settings = ( { settings, setSettings, mcpClientStates } : { settings : { showModal : boolean , pollIntervalSeconds : number } , setSettings : ( settings : any ) => void , mcpClientStates : { [ name : string ] : { exists : boolean , configured : boolean , error ?: string } } } ) => {
34
+ const Settings = ( { settings, setSettings, mcpClientStates, onUpdate } : { onUpdate : ( ) => Promise < void > , settings : { showModal : boolean , pollIntervalSeconds : number } , setSettings : ( settings : any ) => void , mcpClientStates : { [ name : string ] : MCPClientState } } ) => {
53
35
54
36
const updateAndSaveSettings = ( settings : any ) => {
55
37
setSettings ( settings ) ;
56
38
localStorage . setItem ( 'settings' , JSON . stringify ( settings ) ) ;
57
39
}
58
40
41
+ const [ buttonsLoading , setButtonsLoading ] = useState < { [ name : string ] : boolean } > ( { } ) ;
42
+
59
43
return (
60
44
< Stack direction = "column" spacing = { 1 } justifyContent = 'center' alignItems = 'center' >
61
45
{ /* MCP Clients Section */ }
@@ -70,39 +54,57 @@ const Settings = ({ settings, setSettings, mcpClientStates }: { settings: { show
70
54
< AccordionDetails >
71
55
< Paper elevation = { 0 } sx = { { p : 2 } } >
72
56
< List >
73
- { Object . entries ( mcpClientStates ) . map ( ( [ name , state ] ) => (
57
+ { Object . entries ( mcpClientStates ) . map ( ( [ name , mcpClientState ] ) => (
74
58
< ListItem key = { name } secondaryAction = {
75
59
< >
76
- { state . exists && state . configured &&
77
- < Button color = "warning" variant = "outlined" size = "small" >
60
+ { mcpClientState . exists && mcpClientState . configured &&
61
+ < Button onClick = { async ( ) => {
62
+ setButtonsLoading ( { ...buttonsLoading , [ name ] : true } ) ;
63
+ await mcpClientState . disconnect ( client )
64
+ await onUpdate ( ) ;
65
+ setButtonsLoading ( { ...buttonsLoading , [ name ] : false } ) ;
66
+ } } disabled = { buttonsLoading [ name ] } color = "warning" variant = "outlined" size = "small" >
78
67
< Stack direction = "row" alignItems = "center" spacing = { 1 } >
79
68
< Typography > Disconnect</ Typography >
80
69
< LinkOff />
70
+ { buttonsLoading [ name ] && < CircularProgress size = { 16 } /> }
81
71
</ Stack >
82
72
</ Button >
83
73
}
84
- { state . exists && ! state . configured &&
85
- < Button color = "primary" variant = "outlined" size = "small" >
74
+ { mcpClientState . exists && ! mcpClientState . configured &&
75
+ < Button onClick = { async ( ) => {
76
+ setButtonsLoading ( { ...buttonsLoading , [ name ] : true } ) ;
77
+ await mcpClientState . connect ( client )
78
+ await onUpdate ( ) ;
79
+ setButtonsLoading ( { ...buttonsLoading , [ name ] : false } ) ;
80
+ } } disabled = { buttonsLoading [ name ] } color = "primary" variant = "outlined" size = "small" >
86
81
< Stack direction = "row" alignItems = "center" spacing = { 1 } >
87
82
< Typography > Connect</ Typography >
88
83
< LinkRounded />
84
+ { buttonsLoading [ name ] && < CircularProgress size = { 16 } /> }
89
85
</ Stack >
90
86
</ Button >
91
87
}
92
- { ! state . exists &&
93
- < Button color = "error" variant = "outlined" size = "small" >
88
+ { ! mcpClientState . exists &&
89
+ < Button color = "error" variant = "outlined" size = "small" onClick = { async ( ) => {
90
+ setButtonsLoading ( { ...buttonsLoading , [ name ] : true } ) ;
91
+ await mcpClientState . connect ( client )
92
+ await onUpdate ( ) ;
93
+ setButtonsLoading ( { ...buttonsLoading , [ name ] : false } ) ;
94
+ } } >
94
95
< Stack direction = "row" alignItems = "center" spacing = { 1 } >
96
+ < SaveOutlined />
95
97
< Typography > Write Config</ Typography >
96
- < SaveIcon />
98
+ { buttonsLoading [ name ] && < CircularProgress size = { 16 } /> }
97
99
</ Stack >
98
100
</ Button >
99
101
}
100
102
</ >
101
103
} >
102
104
< ListItemText primary = { < Stack direction = "row" alignItems = "center" spacing = { 1 } >
103
105
< Typography variant = "h4" > { name } </ Typography >
104
- { ! state . exists && < Chip label = 'No Config Found' color = 'error' /> }
105
- { state . exists && < Chip label = { state . configured ? 'Connected' : 'Disconnected' } color = { state . configured ? 'success' : 'error' } /> }
106
+ { ! mcpClientState . exists && < Chip label = 'No Config Found' color = 'error' /> }
107
+ { mcpClientState . exists && < Chip label = { mcpClientState . configured ? 'Connected' : 'Disconnected' } color = { mcpClientState . configured ? 'success' : 'error' } /> }
106
108
</ Stack > } />
107
109
</ ListItem >
108
110
) ) }
0 commit comments