Skip to content

Commit b6a6b96

Browse files
authored
Merge pull request #78 from docker/cm/0.2.32
Redesign tiles
2 parents 039c96e + d4a7910 commit b6a6b96

File tree

4 files changed

+55
-45
lines changed

4 files changed

+55
-45
lines changed

src/extension/ui/src/components/tabs/ToolCatalog.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ const ToolCatalog: React.FC<ToolCatalogProps> = ({ config, setConfiguringItem, s
3737
return (
3838
<Grid2 size={{ xs: 12, sm: 6, md: 4 }} key={catalogItem.name}>
3939
<Tile
40-
openUrl={() => {
41-
client.host.openExternal(Ref.fromRef(catalogItem.ref).toURL(true));
42-
}}
4340
item={catalogItem}
4441
registered={registryItems[catalogItem.name]?.ref !== undefined}
4542
onSecretChange={onSecretChange}

src/extension/ui/src/components/tile/Tile.tsx

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CircularProgress, Dialog, DialogContent, DialogTitle, IconButton, Stack, TextField, Tooltip, Typography } from "@mui/material";
1+
import { CircularProgress, Dialog, DialogContent, DialogTitle, IconButton, Paper, Stack, TextField, Tooltip, Typography } from "@mui/material";
22
import { Card, CardActions, CardContent, CardMedia } from "@mui/material";
33
import { ReactNode, useEffect, useState } from "react";
44
import Secrets from "../../Secrets";
@@ -22,15 +22,14 @@ export interface CatalogItemWithName extends CatalogItem {
2222
}
2323

2424
export interface TileProps {
25-
openUrl: () => void;
2625
item: CatalogItemWithName;
2726
registered: boolean;
2827
onSecretChange: (secret: { name: string, value: string }) => Promise<void>;
2928
secrets: Secrets.Secret[];
3029
ActionsSlot: ReactNode
3130
}
3231

33-
const Tile = ({ openUrl, item, registered, onSecretChange, secrets, ActionsSlot }: TileProps) => {
32+
const Tile = ({ item, registered, onSecretChange, secrets, ActionsSlot }: TileProps) => {
3433
const loadAssignedSecrets = () => {
3534
const assignedSecrets = Secrets.getAssignedSecrets(item, secrets);
3635
setAssignedSecrets(assignedSecrets)
@@ -55,51 +54,55 @@ const Tile = ({ openUrl, item, registered, onSecretChange, secrets, ActionsSlot
5554
</DialogTitle>
5655
<DialogContent>
5756
<Stack direction="column" spacing={2}>
58-
{assignedSecrets?.map(secret => (
59-
<Stack key={secret.name} direction="row" spacing={2} alignItems="center">
60-
<TextField placeholder={assignedSecrets.find(s => s.name === secret.name)?.assigned ? '********' : 'Enter secret value'} type="password" key={secret.name} label={secret.name} value={changedSecrets[secret.name] || ''} onChange={(event) => setChangedSecrets({ ...changedSecrets, [secret.name]: event.target.value })} />
61-
{assignedSecrets.find(s => s.name === secret.name)?.assigned && changedSecrets[secret.name] && <IconButton onClick={() => setChangedSecrets({ ...changedSecrets, [secret.name]: undefined })}>
62-
<LockReset />
63-
</IconButton>}
64-
{changedSecrets[secret.name] && <IconButton onClick={() => {
65-
setSecretLoading(true)
66-
onSecretChange({ name: secret.name, value: changedSecrets[secret.name] || '' }).then(() => {
67-
setSecretLoading(false)
68-
const newChangedSecrets = { ...changedSecrets }
69-
delete newChangedSecrets[secret.name]
70-
setChangedSecrets(newChangedSecrets)
71-
})
72-
}}>
73-
{secretLoading ? <CircularProgress size={20} /> : <Save />}
74-
</IconButton>}
75-
</Stack>
76-
))}
57+
{assignedSecrets?.map(secret => {
58+
const isAssigned = assignedSecrets.find(s => s.name === secret.name)
59+
return (
60+
<Stack key={secret.name} direction="row" spacing={2} alignItems="center">
61+
<Typography variant="body2">{secret.name} {isAssigned?.assigned ? 'assigned' : 'not assigned'}</Typography>
62+
<TextField placeholder={isAssigned?.assigned ? '********' : 'Enter secret value'} type="password" key={secret.name} label={secret.name} value={changedSecrets[secret.name] || ''} onChange={(event) => setChangedSecrets({ ...changedSecrets, [secret.name]: event.target.value })} />
63+
{isAssigned?.assigned && changedSecrets[secret.name] && <IconButton onClick={() => setChangedSecrets({ ...changedSecrets, [secret.name]: undefined })}>
64+
<LockReset />
65+
</IconButton>}
66+
{changedSecrets[secret.name] && <IconButton onClick={() => {
67+
setSecretLoading(true)
68+
onSecretChange({ name: secret.name, value: changedSecrets[secret.name] || '' }).then(() => {
69+
setSecretLoading(false)
70+
const newChangedSecrets = { ...changedSecrets }
71+
delete newChangedSecrets[secret.name]
72+
setChangedSecrets(newChangedSecrets)
73+
})
74+
}}>
75+
{secretLoading ? <CircularProgress size={20} /> : <Save />}
76+
</IconButton>}
77+
</Stack>
78+
)
79+
})}
7780
</Stack>
7881
</DialogContent>
7982
</Dialog>
80-
<Card sx={(theme) => ({ height: 150, borderColor: registered ? theme.palette.docker.grey[600] : theme.palette.docker.grey[300], borderWidth: registered ? 1 : 0.5 })} variant="outlined" >
83+
<Card sx={(theme) => ({ height: 140, borderColor: 'divider', borderWidth: 1, borderStyle: 'solid' })} >
8184
<Stack direction="column" height="100%" sx={{ justifyContent: 'space-between' }}>
82-
<CardContent sx={{ p: 2, paddingBottom: 1, '&:hover .hover-underline': { textDecoration: 'underline' } }}>
83-
<Stack onClick={openUrl} direction="row" spacing={1} justifyContent="space-between" sx={{ cursor: 'pointer' }}>
84-
<Stack direction="column" spacing={1} >
85-
<Typography className="hover-underline" gutterBottom component="div" sx={{ fontWeight: 'bold', textTransform: 'capitalize', fontSize: '1.2em' }}>
86-
{item.name.replace('_', ' ')}
85+
<CardContent sx={{ paddingBottom: 0, paddingTop: 2 }}>
86+
<Stack direction="column" spacing={0}>
87+
<Stack direction="row" spacing={0} justifyContent="space-between">
88+
<CardMedia
89+
component="img"
90+
sx={{ width: '3em', height: '3em', padding: 1, background: 'white', borderRadius: 1, boxSizing: 'border-box', mt: -1, ml: -1 }}
91+
alt={`Icon for ${item.name}`}
92+
image={item.icon}
93+
/>
94+
<Typography gutterBottom component="div" sx={{ fontWeight: 'bold', fontSize: '1.2em' }}>
95+
{item.name}
8796
</Typography>
88-
<Tooltip title={item.description}>
89-
<Typography variant="body2" sx={{ mt: 0.5 }}>
90-
{item.description?.slice(0, 70)}...
91-
</Typography>
92-
</Tooltip>
9397
</Stack>
94-
<CardMedia
95-
component="img"
96-
sx={{ width: 50, height: 50, padding: 1, background: 'white', borderRadius: 1, boxSizing: 'border-box', mt: -1 }}
97-
alt={`Icon for ${item.name}`}
98-
image={item.icon}
99-
/>
98+
<Tooltip title={item.description}>
99+
<Typography variant="caption" sx={{ color: 'text.secondary', pt: 1 }}>
100+
{item.description?.slice(0, 70)}...
101+
</Typography>
102+
</Tooltip>
100103
</Stack>
101104
</CardContent>
102-
<CardActions sx={{ padding: 1, paddingTop: 0 }}>
105+
<CardActions sx={{ px: 1.5, height: 30 }}>
103106
{ActionsSlot}
104107
</CardActions>
105108
</Stack >

src/extension/ui/src/context/MCPClientContext.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,18 @@ export function MCPClientProvider({ children, client }: MCPClientProviderProps)
6161
);
6262

6363
if (newlyConnectedClient) {
64-
client.desktopUI.toast.success('Client Connected: ' + newlyConnectedClient.client.name + '. Restart it to load the Catalog.');
64+
if (newlyConnectedClient.client.name === 'Gordon') {
65+
client.desktopUI.toast.success('Gordon is connected to the Catalog.');
66+
} else {
67+
client.desktopUI.toast.success('Client Connected: ' + newlyConnectedClient.client.name + '. Restart it to load the Catalog.');
68+
}
6569
}
6670
if (newlyDisconnectedClient) {
67-
client.desktopUI.toast.error('Client Disconnected: ' + newlyDisconnectedClient.client.name + '. Restart it to remove the Catalog.');
71+
if (newlyDisconnectedClient.client.name === 'Gordon') {
72+
client.desktopUI.toast.error('Gordon is disconnected from the Catalog.');
73+
} else {
74+
client.desktopUI.toast.error('Client Disconnected: ' + newlyDisconnectedClient.client.name + '. Restart it to remove the Catalog.');
75+
}
6876
}
6977
}
7078

src/extension/ui/src/main.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ const queryClient = new QueryClient({
2626
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
2727
<React.StrictMode>
2828
<QueryClientProvider client={queryClient}>
29+
2930
<DockerMuiV6ThemeProvider>
31+
<CssBaseline />
3032
<App />
3133
</DockerMuiV6ThemeProvider>
3234
{localStorage.getItem('ENABLE_REACT_QUERY_DEVTOOLS') && <ReactQueryDevtools initialIsOpen={false} />}

0 commit comments

Comments
 (0)