Skip to content

Commit e07a0f2

Browse files
committed
Modal fixes
1 parent 3d27f8f commit e07a0f2

File tree

3 files changed

+29
-21
lines changed

3 files changed

+29
-21
lines changed

src/extension/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
IMAGE?=docker/labs-ai-tools-for-devs
2-
TAG?=0.1.2
2+
TAG?=0.1.4
33

44
BUILDER=buildx-multi-arch
55

src/extension/ui/src/App.tsx

+26-15
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import React, { useEffect, useState } from 'react';
22
import AddIcon from '@mui/icons-material/Add';
33
import { createDockerDesktopClient } from '@docker/extension-api-client';
4-
import { Stack, Typography, Button, ButtonGroup, Grid, debounce, Card, CardContent, IconButton, Alert } from '@mui/material';
4+
import { Stack, Typography, Button, ButtonGroup, Grid, debounce, Card, CardContent, IconButton, Alert, DialogTitle, Dialog, DialogContent, FormControlLabel, Checkbox } from '@mui/material';
55
import { CatalogItem, CatalogItemCard, CatalogItemWithName } from './components/PromptCard';
66
import { parse, stringify } from 'yaml';
77
import { Ref } from './Refs';
88
import { RegistrySyncStatus } from './components/RegistrySyncStatus';
99
import { getRegistry } from './Registry';
10-
import { ClaudeConfigSyncStatus } from './components/ClaudeConfigSyncStatus';
11-
import { FolderOpen, FolderOpenOutlined, FolderOpenRounded, VolumeUp } from '@mui/icons-material';
10+
import { ClaudeConfigSyncStatus, setNeverShowAgain } from './components/ClaudeConfigSyncStatus';
11+
import { FolderOpenRounded, } from '@mui/icons-material';
12+
13+
const NEVER_SHOW_AGAIN_KEY = 'registry-sync-never-show-again';
1214

1315
type RegistryItem = {
1416
ref: string;
@@ -24,25 +26,16 @@ export function App() {
2426
const [catalogItems, setCatalogItems] = useState<CatalogItemWithName[]>([]);
2527
const [canRegister, setCanRegister] = useState(false);
2628
const [registryItems, setRegistryItems] = useState<{ [key: string]: { ref: string } }>({});
27-
const [status, setStatus] = useState<{
28-
status: 'idle' | 'loading' | 'error',
29-
message: string
30-
}>({
31-
status: 'idle',
32-
message: ''
33-
});
34-
29+
const [showReloadModal, setShowReloadModal] = useState(false);
3530
const [hasConfig, setHasConfig] = useState(false);
3631

3732
const loadCatalog = async () => {
38-
setStatus({ status: 'loading', message: 'Grabbing latest prompt catalog...' });
3933
try {
4034
const response = await fetch(CATALOG_URL);
4135
const catalog = await response.text();
4236
const items = parse(catalog)['registry'] as { [key: string]: CatalogItem }
4337
const itemsWithName = Object.entries(items).map(([name, item]) => ({ name, ...item }));
4438
setCatalogItems(itemsWithName);
45-
setStatus({ status: 'idle', message: '' });
4639
}
4740
catch (error) {
4841
client.desktopUI.toast.error('Failed to get latest catalog: ' + error);
@@ -52,11 +45,9 @@ export function App() {
5245
const loadRegistry = async () => {
5346
setRegistryLoaded(false);
5447
setCanRegister(false);
55-
setStatus({ status: 'loading', message: 'Grabbing prompt registry...' });
5648
try {
5749
const result = await getRegistry(client)
5850
setRegistryItems(result || {});
59-
setStatus({ status: 'idle', message: '' });
6051
setRegistryLoaded(true);
6152

6253
}
@@ -83,6 +74,7 @@ export function App() {
8374
await client.docker.cli.exec('run', ['--rm', '-v', 'docker-prompts:/docker-prompts', '--workdir', '/docker-prompts', 'vonwig/function_write_files:latest', `'${payload}'`])
8475
client.desktopUI.toast.success('Prompt registered successfully. Restart Claude Desktop to apply.');
8576
await loadRegistry();
77+
setShowReloadModal(!localStorage.getItem(NEVER_SHOW_AGAIN_KEY));
8678
}
8779
catch (error) {
8880
client.desktopUI.toast.error('Failed to register prompt: ' + error);
@@ -102,10 +94,12 @@ export function App() {
10294
await client.docker.cli.exec('run', ['--rm', '-v', 'docker-prompts:/docker-prompts', '--workdir', '/docker-prompts', 'vonwig/function_write_files:latest', `'${payload}'`])
10395
client.desktopUI.toast.success('Prompt unregistered successfully. Restart Claude Desktop to apply.');
10496
await loadRegistry();
97+
setShowReloadModal(!localStorage.getItem(NEVER_SHOW_AGAIN_KEY));
10598
}
10699
catch (error) {
107100
client.desktopUI.toast.error('Failed to unregister prompt: ' + error)
108101
}
102+
109103
}
110104

111105
useEffect(() => {
@@ -126,8 +120,25 @@ export function App() {
126120

127121
return (
128122
<div>
123+
<Dialog open={showReloadModal} onClose={() => setShowReloadModal(false)}>
124+
<DialogTitle>Registry Updated</DialogTitle>
125+
<DialogContent>
126+
<Typography sx={{ marginBottom: 2 }}>
127+
You have updated the registry.
128+
Use the keybind {client.host.platform === 'win32' ? 'Ctrl' : '⌘'} + R to refresh MCP servers in Claude Desktop.
129+
</Typography>
130+
<Stack direction="row" justifyContent="space-between">
131+
<Button onClick={() => {
132+
setShowReloadModal(false)
133+
}}>Close</Button>
134+
<FormControlLabel control={<Checkbox defaultChecked={Boolean(localStorage.getItem(NEVER_SHOW_AGAIN_KEY))} onChange={(e) => localStorage.setItem(NEVER_SHOW_AGAIN_KEY, e.target.checked.toString())} />} label="Don't show this again" />
135+
</Stack>
136+
</DialogContent>
137+
</Dialog>
138+
129139
<Stack direction="column" spacing={1}>
130140
<div>
141+
131142
<ButtonGroup>
132143
<Button onClick={loadCatalog}>Refresh catalog</Button>
133144
<Button onClick={loadRegistry}>Refresh registry</Button>

src/extension/ui/src/components/ClaudeConfigSyncStatus.tsx

+2-5
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const getClaudeConfig = async (client: v1.DockerDesktopClient) => {
5050
return result.stdout
5151
}
5252

53-
const setNeverShowAgain = (value: boolean) => {
53+
export const setNeverShowAgain = (value: boolean) => {
5454
localStorage.setItem('claude-config-sync-status-never-show-again', value.toString())
5555
}
5656

@@ -93,7 +93,6 @@ export const ClaudeConfigSyncStatus = ({ client, setHasConfig }: { client: v1.Do
9393
const servers = claudeConfig.mcpServers
9494
if (!servers) {
9595
setStatus({ state: 'invalid', message: 'No servers found in Claude Desktop Config', color: 'error' })
96-
9796
}
9897
else {
9998
const hasDocker = Object.keys(servers).some(key => key === 'mcp_docker')
@@ -151,11 +150,9 @@ export const ClaudeConfigSyncStatus = ({ client, setHasConfig }: { client: v1.Do
151150
<DialogContent sx={{ padding: 5, mt: 2 }}>
152151
<Stack direction="column" spacing={3}>
153152
<Typography>
154-
Use the keybind {client.host.platform === 'win32' ? 'Ctrl' : '⌘'} + R to refresh MCP servers in Claude Desktop.
153+
Claude config has been updated. Please restart Claude Desktop to apply the changes.
155154
</Typography>
156155
<FormControlLabel control={<Checkbox defaultChecked={getNeverShowAgain()} onChange={(e) => setNeverShowAgain(e.target.checked)} />} label="Don't show this again" />
157-
158-
159156
<Button onClick={() => {
160157
setShowRestartModal(false)
161158
}}>Close</Button>

0 commit comments

Comments
 (0)