Skip to content

Commit 4e28003

Browse files
author
colinmcneil
committed
More catalog-oriented CSS tweaks
1 parent efe1a16 commit 4e28003

File tree

2 files changed

+55
-50
lines changed

2 files changed

+55
-50
lines changed

src/extension/ui/src/components/CatalogGrid.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React, { useEffect, useState } from 'react';
2-
import { Card, CardContent, IconButton, Alert, Stack, Button, Typography, Grid2, Select, MenuItem, FormControl, InputLabel, Switch, FormGroup, FormControlLabel, Dialog, DialogTitle, DialogContent, Checkbox, Badge, BadgeProps, Link, TextField, Tabs, Tab, Tooltip } from '@mui/material';
2+
import { Card, CardContent, IconButton, Alert, Stack, Button, Typography, Grid2, Select, MenuItem, FormControl, InputLabel, Switch, FormGroup, FormControlLabel, Dialog, DialogTitle, DialogContent, Checkbox, Badge, BadgeProps, Link, TextField, Tabs, Tab, Tooltip, InputAdornment } from '@mui/material';
33
import { CatalogItemWithName, CatalogItemCard, CatalogItem } from './PromptCard';
44
import AddIcon from '@mui/icons-material/Add';
55
import { Ref } from '../Refs';
66
import { v1 } from "@docker/extension-api-client-types";
77
import { parse, stringify } from 'yaml';
88
import { getRegistry } from '../Registry';
9-
import { FolderOpenRounded, Settings } from '@mui/icons-material';
9+
import { FolderOpenRounded, Search, Settings } from '@mui/icons-material';
1010
import { tryRunImageSync } from '../FileWatcher';
1111
import { CATALOG_URL, POLL_INTERVAL } from '../Constants';
1212

@@ -143,10 +143,10 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
143143
<Typography sx={{ width: '100%' }}>You have some prompts registered which are not available in the catalog.</Typography>
144144
</Alert>}
145145
<Tabs value={tab} onChange={(e, v) => setTab(v)} sx={{ mb: 0, mt: 1 }}>
146-
<Tooltip title="These are all of the prompts you have available across the catalog.">
146+
<Tooltip title="These are all of the tiles you have available across the catalog.">
147147
<Tab sx={{ fontSize: '1.5em' }} label="Available" />
148148
</Tooltip>
149-
<Tooltip title="These are prompts which you have allowed MCP clients to use.">
149+
<Tooltip title="These are tiles which you have allowed MCP clients to use.">
150150
<Tab sx={{ fontSize: '1.5em' }} label="Allowed" />
151151
</Tooltip>
152152
</Tabs>
@@ -167,7 +167,7 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
167167
</Stack>
168168
</FormGroup >
169169

170-
{tab === 0 && <Grid2 container spacing={2} width='100%' maxWidth={1000}>
170+
{tab === 0 && <Grid2 container spacing={1} width='90vw' maxWidth={1000}>
171171
{filteredCatalogItems.map((item) => (
172172
<Grid2 size={{ xs: 12, sm: 6, md: 4 }} key={item.name}>
173173
<CatalogItemCard
@@ -194,9 +194,9 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({
194194
</Card>
195195
</Grid2>
196196
</Grid2>}
197-
{tab === 1 && <Grid2 container spacing={2} width='100%' maxWidth={1000}>
197+
{tab === 1 && <Grid2 container spacing={1} width='90vw' maxWidth={1000}>
198198
{Object.entries(registryItems).map(([name, item]) => (
199-
<Grid2 size={{ xs: 12, sm: 6, md: 4 }} key={name}>
199+
name.toLowerCase().includes(search.toLowerCase()) && <Grid2 size={{ xs: 12, sm: 6, md: 4 }} key={name}>
200200
<CatalogItemCard item={catalogItems.find((i) => i.name === name)!} openUrl={() => {
201201
client.host.openExternal(Ref.fromRef(item.ref).toURL(true));
202202
}} canRegister={canRegister} registered={true} register={registerCatalogItem} unregister={unregisterCatalogItem} />

src/extension/ui/src/components/PromptCard.tsx

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import { Badge, CircularProgress, Stack, Tooltip } from "@mui/material";
1+
import { Badge, CircularProgress, Stack, Switch, Tooltip } from "@mui/material";
22
import Button from '@mui/material/Button';
33
import { Card, CardActions, CardContent, CardMedia, Typography } from "@mui/material";
44
import { Ref } from "../Refs";
55
import { useState } from "react";
66
import { trackEvent } from "../Usage";
77
import { Article, AttachFile, Build, LockRounded } from "@mui/icons-material";
88

9+
const iconSize = 16
10+
911
export interface CatalogItem {
1012
description?: string;
1113
icon?: string;
@@ -23,42 +25,45 @@ export interface CatalogItemWithName extends CatalogItem {
2325
export function CatalogItemCard({ openUrl, item, canRegister, registered, register, unregister }: { openUrl: () => void, item: CatalogItemWithName, canRegister: boolean, registered: boolean, register: (item: CatalogItemWithName) => Promise<void>, unregister: (item: CatalogItemWithName) => Promise<void> }) {
2426
const [isRegistering, setIsRegistering] = useState(false)
2527
return (
26-
<Card sx={(theme) => ({ height: '100%', borderColor: registered ? theme.palette.docker.grey[600] : theme.palette.docker.grey[400], borderWidth: registered ? 2 : 1 })} variant="outlined" >
28+
<Card sx={(theme) => ({ height: 150, borderColor: registered ? theme.palette.docker.grey[600] : theme.palette.docker.grey[300], borderWidth: registered ? 1 : 0.5 })} variant="outlined" >
2729
<Stack direction="column" height="100%" sx={{ justifyContent: 'space-between' }}>
28-
<CardContent>
29-
<a href="">
30-
<Stack onClick={openUrl} direction="row" spacing={2} justifyContent="space-between" sx={{ cursor: 'pointer' }}>
31-
<Typography gutterBottom variant="h5" component="div" sx={{ fontWeight: 'bold', textTransform: 'capitalize' }}>
30+
<CardContent sx={{ p: 2, paddingBottom: 1, '&:hover .hover-underline': { textDecoration: 'underline' } }}>
31+
<Stack onClick={openUrl} direction="row" spacing={1} justifyContent="space-between" sx={{ cursor: 'pointer' }}>
32+
<Stack direction="column" spacing={1} >
33+
<Typography className="hover-underline" gutterBottom component="div" sx={{ fontWeight: 'bold', textTransform: 'capitalize', fontSize: '1.2em' }}>
3234
{item.name.replace('_', ' ')}
3335
</Typography>
34-
<CardMedia
35-
component="img"
36-
sx={{ width: 50, height: 50, padding: 1, background: 'white', borderRadius: 1 }}
37-
alt={`Icon for ${item.name}`}
38-
image={item.icon}
39-
/>
36+
<Tooltip title={item.description}>
37+
<Typography variant="body2" sx={{ mt: 0.5 }}>
38+
{item.description?.slice(0, 70)}...
39+
</Typography>
40+
</Tooltip>
41+
4042
</Stack>
41-
</a>
42-
<Typography variant="body2" sx={{ mt: 0.5 }}>
43-
{item.description}
44-
</Typography>
43+
<CardMedia
44+
component="img"
45+
sx={{ width: 50, height: 50, padding: 1, background: 'white', borderRadius: 1, boxSizing: 'border-box', mt: -1 }}
46+
alt={`Icon for ${item.name}`}
47+
image={item.icon}
48+
/>
49+
</Stack>
4550
</CardContent>
46-
<CardActions sx={{ pt: 0 }}>
51+
<CardActions sx={{ padding: 2, paddingTop: 0 }}>
4752
<Stack direction="row" spacing={2} sx={{ alignItems: 'center', justifyContent: 'space-between', width: '100%' }}>
48-
<Stack direction="row" spacing={2}>
53+
<Stack direction="row" spacing={2} >
4954
<Tooltip title="Prompts">
5055
<Badge badgeContent={item.prompts || "0"} color="primary">
51-
<Article />
56+
<Article sx={{ fontSize: iconSize }} />
5257
</Badge>
5358
</Tooltip>
5459
<Tooltip title="Resources">
5560
<Badge badgeContent={item.resources?.length || "0"} color="secondary">
56-
<AttachFile />
61+
<AttachFile sx={{ fontSize: iconSize }} />
5762
</Badge>
5863
</Tooltip>
5964
<Tooltip title="Tools">
6065
<Badge badgeContent={item.tools?.length || "0"} color="success">
61-
<Build />
66+
<Build sx={{ fontSize: iconSize }} />
6267
</Badge>
6368
</Tooltip>
6469
{item.secrets?.length && (
@@ -69,32 +74,32 @@ export function CatalogItemCard({ openUrl, item, canRegister, registered, regist
6974
))}
7075
</Stack>}>
7176
<Badge badgeContent={item.secrets?.length || "0"} color="warning">
72-
<LockRounded />
77+
<LockRounded sx={{ fontSize: iconSize }} />
7378
</Badge>
7479
</Tooltip>
7580
)}
7681
</Stack>
77-
<Button
78-
size="small"
79-
color={registered ? 'error' : 'primary'}
80-
variant={registered ? 'outlined' : 'contained'}
81-
onClick={() => {
82-
trackEvent('registry-changed', { name: item.name, ref: item.ref, action: registered ? 'remove' : 'add' });
83-
setIsRegistering(true)
84-
if (registered) {
85-
unregister(item).then(() => {
86-
setIsRegistering(false)
87-
})
88-
} else {
89-
register(item).then(() => {
90-
setIsRegistering(false)
91-
})
92-
}
93-
}}
94-
disabled={!canRegister || isRegistering}
95-
>
96-
{isRegistering ? <CircularProgress size={20} /> : registered ? 'Block' : 'Allow'}
97-
</Button>
82+
<Tooltip title={registered ? "Blocking this tile will remove its tools, resources and prompts from being used in any MCP clients you have connected." : "Allowing this tile will expose its tools, resources and prompts to any MCP clients you have connected."}>
83+
{isRegistering ? <CircularProgress size={20} /> : <Switch
84+
size="small"
85+
color={registered ? 'success' : 'primary'}
86+
checked={registered}
87+
onChange={(event, checked) => {
88+
trackEvent('registry-changed', { name: item.name, ref: item.ref, action: registered ? 'remove' : 'add' });
89+
setIsRegistering(true)
90+
if (registered) {
91+
unregister(item).then(() => {
92+
setIsRegistering(false)
93+
})
94+
} else {
95+
register(item).then(() => {
96+
setIsRegistering(false)
97+
})
98+
}
99+
}}
100+
disabled={!canRegister || isRegistering}
101+
/>}
102+
</Tooltip>
98103
</Stack>
99104

100105
</CardActions>

0 commit comments

Comments
 (0)