@webmcp-auto-ui/ui 2.5.10 → 2.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ Requires Svelte 5 and Tailwind CSS.
|
|
|
66
66
|
<StatCard spec={{ label: 'Users', value: '8 204', variant: 'success', delta: '+3.2%' }} />
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
Each component accepts a `spec` prop (rich widgets) or `data` prop (simple blocks). See the
|
|
69
|
+
Each component accepts a `spec` prop (rich widgets) or `data` prop (simple blocks). See the showcase app at `:3010` for all components with live data.
|
|
70
70
|
|
|
71
71
|
## License
|
|
72
72
|
|
package/package.json
CHANGED
|
@@ -11,9 +11,10 @@
|
|
|
11
11
|
name: string;
|
|
12
12
|
servers?: ConnectedServerInfo[];
|
|
13
13
|
onserverclick?: (url: string) => void;
|
|
14
|
+
onclick?: () => void;
|
|
14
15
|
class?: string;
|
|
15
16
|
}
|
|
16
|
-
let { connecting, connected, name, servers = [], onserverclick, class: cls = '' }: Props = $props();
|
|
17
|
+
let { connecting, connected, name, servers = [], onserverclick, onclick, class: cls = '' }: Props = $props();
|
|
17
18
|
|
|
18
19
|
let dropdownOpen = $state(false);
|
|
19
20
|
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
class="text-[10px] text-teal font-mono cursor-pointer hover:underline select-none"
|
|
46
47
|
onclick={toggleDropdown}
|
|
47
48
|
>
|
|
48
|
-
multi-
|
|
49
|
+
multi-server ({servers.length})
|
|
49
50
|
</span>
|
|
50
51
|
|
|
51
52
|
{#if dropdownOpen}
|
|
@@ -61,14 +62,26 @@
|
|
|
61
62
|
>
|
|
62
63
|
<span class="w-1.5 h-1.5 rounded-full bg-teal flex-shrink-0"></span>
|
|
63
64
|
<span class="truncate flex-1">{server.name}</span>
|
|
64
|
-
<span class="text-text2 text-[10px] flex-shrink-0">{server.toolCount}
|
|
65
|
+
<span class="text-text2 text-[10px] flex-shrink-0">{server.toolCount} tools</span>
|
|
65
66
|
</button>
|
|
66
67
|
{/each}
|
|
68
|
+
{#if onclick}
|
|
69
|
+
<button
|
|
70
|
+
class="w-full flex items-center gap-2 px-3 py-1.5 text-left font-mono text-xs text-accent hover:bg-surface2 transition-colors border-t border-border"
|
|
71
|
+
onclick={(e) => { e.stopPropagation(); dropdownOpen = false; onclick?.(); }}
|
|
72
|
+
>
|
|
73
|
+
Browse recipes
|
|
74
|
+
</button>
|
|
75
|
+
{/if}
|
|
67
76
|
</div>
|
|
68
77
|
{/if}
|
|
69
78
|
{:else}
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
80
|
+
<span
|
|
81
|
+
class="text-[10px] text-text2 font-mono {connected && onclick ? 'cursor-pointer hover:underline' : ''}"
|
|
82
|
+
onclick={() => { if (connected) onclick?.(); }}
|
|
83
|
+
>
|
|
84
|
+
{connecting ? 'connecting\u2026' : connected ? name : 'not connected'}
|
|
72
85
|
</span>
|
|
73
86
|
{/if}
|
|
74
87
|
</div>
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
onconnect?: (url: string) => void;
|
|
15
15
|
onconnectall?: () => void;
|
|
16
16
|
ondisconnect?: (url: string) => void;
|
|
17
|
+
recipeCountByServer?: Record<string, number>;
|
|
18
|
+
onrecipeclick?: (url: string) => void;
|
|
19
|
+
toolCountByServer?: Record<string, number>;
|
|
20
|
+
ontoolclick?: (url: string) => void;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
let {
|
|
@@ -23,6 +27,10 @@
|
|
|
23
27
|
onconnect,
|
|
24
28
|
onconnectall,
|
|
25
29
|
ondisconnect,
|
|
30
|
+
recipeCountByServer,
|
|
31
|
+
onrecipeclick,
|
|
32
|
+
toolCountByServer,
|
|
33
|
+
ontoolclick,
|
|
26
34
|
}: Props = $props();
|
|
27
35
|
|
|
28
36
|
const allConnected = $derived(
|
|
@@ -65,6 +73,25 @@
|
|
|
65
73
|
<div class="flex-1 min-w-0 flex flex-col">
|
|
66
74
|
<span class="font-mono text-xs font-medium text-text1">{server.name}</span>
|
|
67
75
|
<span class="text-[10px] text-text2 truncate">{server.description}</span>
|
|
76
|
+
{#if connected && (recipeCountByServer?.[server.url] || toolCountByServer?.[server.url])}
|
|
77
|
+
<span class="flex items-center gap-1.5 mt-0.5">
|
|
78
|
+
{#if recipeCountByServer?.[server.url]}
|
|
79
|
+
<button class="text-[10px] font-mono text-accent hover:underline"
|
|
80
|
+
onclick={(e) => { e.stopPropagation(); onrecipeclick?.(server.url); }}>
|
|
81
|
+
{recipeCountByServer[server.url]} recipes
|
|
82
|
+
</button>
|
|
83
|
+
{/if}
|
|
84
|
+
{#if recipeCountByServer?.[server.url] && toolCountByServer?.[server.url]}
|
|
85
|
+
<span class="text-[10px] text-text2">·</span>
|
|
86
|
+
{/if}
|
|
87
|
+
{#if toolCountByServer?.[server.url]}
|
|
88
|
+
<button class="text-[10px] font-mono text-accent hover:underline"
|
|
89
|
+
onclick={(e) => { e.stopPropagation(); ontoolclick?.(server.url); }}>
|
|
90
|
+
{toolCountByServer[server.url]} tools
|
|
91
|
+
</button>
|
|
92
|
+
{/if}
|
|
93
|
+
</span>
|
|
94
|
+
{/if}
|
|
68
95
|
</div>
|
|
69
96
|
|
|
70
97
|
<!-- action -->
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
{/if}
|
|
237
237
|
</section>
|
|
238
238
|
|
|
239
|
-
<!-- Cache (disabled for WASM/Gemma — prompt caching is
|
|
239
|
+
<!-- Cache (disabled for WASM/Gemma — prompt caching is provider-dependent) -->
|
|
240
240
|
<label class="flex items-center gap-2.5 select-none" class:cursor-pointer={modelType !== 'wasm'} class:opacity-40={modelType === 'wasm'}>
|
|
241
241
|
<input
|
|
242
242
|
type="checkbox"
|
|
@@ -246,7 +246,7 @@
|
|
|
246
246
|
/>
|
|
247
247
|
<span class="text-xs font-mono text-text1">Prompt caching</span>
|
|
248
248
|
{#if modelType === 'wasm'}
|
|
249
|
-
<span class="text-[10px] font-mono text-text2/50 ml-auto">
|
|
249
|
+
<span class="text-[10px] font-mono text-text2/50 ml-auto">remote API only</span>
|
|
250
250
|
{:else}
|
|
251
251
|
<span class="text-[10px] font-mono text-text2 ml-auto">saves ~80% tokens</span>
|
|
252
252
|
{/if}
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
let current = $state(0);
|
|
15
15
|
let timer: ReturnType<typeof setInterval> | null = null;
|
|
16
16
|
|
|
17
|
-
function goTo(i: number) {
|
|
17
|
+
function goTo(i: number, userInitiated = false) {
|
|
18
18
|
current = Math.max(0, Math.min(i, slides.length - 1));
|
|
19
|
-
onslidechange?.(slides[current], current);
|
|
19
|
+
if (userInitiated) onslidechange?.(slides[current], current);
|
|
20
20
|
resetAuto();
|
|
21
21
|
}
|
|
22
|
-
function prev() { goTo(current > 0 ? current - 1 : slides.length - 1); }
|
|
22
|
+
function prev() { goTo(current > 0 ? current - 1 : slides.length - 1, true); }
|
|
23
23
|
function next() { goTo(current < slides.length - 1 ? current + 1 : 0); }
|
|
24
24
|
|
|
25
25
|
function resetAuto() {
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
|
|
73
73
|
{#if slides.length > 1}
|
|
74
74
|
<button class="absolute left-2 top-1/2 -translate-y-1/2 w-7 h-7 rounded-full bg-black/40 text-white flex items-center justify-center hover:bg-black/60 text-sm" onclick={prev}>‹</button>
|
|
75
|
-
<button class="absolute right-2 top-1/2 -translate-y-1/2 w-7 h-7 rounded-full bg-black/40 text-white flex items-center justify-center hover:bg-black/60 text-sm" onclick={
|
|
75
|
+
<button class="absolute right-2 top-1/2 -translate-y-1/2 w-7 h-7 rounded-full bg-black/40 text-white flex items-center justify-center hover:bg-black/60 text-sm" onclick={() => goTo(current < slides.length - 1 ? current + 1 : 0, true)}>›</button>
|
|
76
76
|
{/if}
|
|
77
77
|
</div>
|
|
78
78
|
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
<div class="flex justify-center gap-1.5 mt-2">
|
|
81
81
|
{#each slides as _, i}
|
|
82
82
|
<button class="w-2 h-2 rounded-full transition-colors {i === current ? 'bg-accent' : 'bg-border2'}"
|
|
83
|
-
onclick={() => goTo(i)}></button>
|
|
83
|
+
onclick={() => goTo(i, true)}></button>
|
|
84
84
|
{/each}
|
|
85
85
|
</div>
|
|
86
86
|
{/if}
|