This commit is contained in:
Timothy Jaeryang Baek 2025-09-14 09:08:23 +02:00
parent caaaa07232
commit 3ed0a6d11f
3 changed files with 215 additions and 203 deletions

View file

@ -919,6 +919,7 @@
<FilesOverlay show={dragged} /> <FilesOverlay show={dragged} />
<ToolServersModal bind:show={showTools} {selectedToolIds} /> <ToolServersModal bind:show={showTools} {selectedToolIds} />
<InputVariablesModal <InputVariablesModal
bind:show={showInputVariablesModal} bind:show={showInputVariablesModal}
variables={inputVariables} variables={inputVariables}

View file

@ -81,7 +81,7 @@
<div slot="content"> <div slot="content">
<DropdownMenu.Content <DropdownMenu.Content
class="w-full max-w-[200px] rounded-2xl px-1 py-1 border border-gray-100 dark:border-gray-800 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg transition" class="w-full max-w-[240px] rounded-2xl px-1 py-1 border border-gray-100 dark:border-gray-800 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg transition"
sideOffset={4} sideOffset={4}
alignOffset={-6} alignOffset={-6}
side="bottom" side="bottom"

View file

@ -18,6 +18,7 @@
import Terminal from '$lib/components/icons/Terminal.svelte'; import Terminal from '$lib/components/icons/Terminal.svelte';
import ChevronRight from '$lib/components/icons/ChevronRight.svelte'; import ChevronRight from '$lib/components/icons/ChevronRight.svelte';
import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte'; import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte';
import { crossfade, fade, fly, slide } from 'svelte/transition';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
@ -39,9 +40,10 @@
export let onClose: Function; export let onClose: Function;
let tools = null;
let show = false; let show = false;
let showAllTools = false; let tab = '';
let tools = null;
$: if (show) { $: if (show) {
init(); init();
@ -81,22 +83,23 @@
</Tooltip> </Tooltip>
<div slot="content"> <div slot="content">
<DropdownMenu.Content <DropdownMenu.Content
class="w-full max-w-[240px] rounded-2xl px-1 py-1 border border-gray-100 dark:border-gray-800 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg max-h-72 overflow-y-auto scrollbar-thin" class="w-full max-w-[240px] rounded-2xl px-1 py-1 border border-gray-100 dark:border-gray-800 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg max-h-72 overflow-y-auto overflow-x-hidden scrollbar-thin"
sideOffset={4} sideOffset={4}
alignOffset={-6} alignOffset={-6}
side="bottom" side="bottom"
align="start" align="start"
transition={flyAndScale} transition={flyAndScale}
> >
{#if tab === ''}
<div in:fly={{ x: -20, duration: 150 }}>
{#if tools} {#if tools}
{#if Object.keys(tools).length > 0} {#if Object.keys(tools).length > 0}
<button <button
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800" class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
on:click={() => { on:click={() => {
showAllTools = !showAllTools; tab = 'tools';
}} }}
> >
{#if !showAllTools}
<Wrench /> <Wrench />
<div class="flex items-center w-full justify-between"> <div class="flex items-center w-full justify-between">
@ -109,16 +112,6 @@
<ChevronRight /> <ChevronRight />
</div> </div>
</div> </div>
{:else}
<ChevronLeft />
<div class="flex items-center w-full justify-between">
<div>
{$i18n.t('Tools')}
<span class="ml-0.5 text-gray-500">{Object.keys(tools).length}</span>
</div>
</div>
{/if}
</button> </button>
{/if} {/if}
{:else} {:else}
@ -127,44 +120,6 @@
</div> </div>
{/if} {/if}
{#if showAllTools}
{#each Object.keys(tools) as toolId}
<button
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
on:click={() => {
tools[toolId].enabled = !tools[toolId].enabled;
}}
>
<div class="flex-1 truncate">
<div class="flex flex-1 gap-2 items-center">
<Tooltip content={tools[toolId]?.name ?? ''} placement="top">
<div class="shrink-0">
<Wrench />
</div>
</Tooltip>
<Tooltip content={tools[toolId]?.description ?? ''} placement="top-start">
<div class=" truncate">{tools[toolId].name}</div>
</Tooltip>
</div>
</div>
<div class=" shrink-0">
<Switch
state={tools[toolId].enabled}
on:change={async (e) => {
const state = e.detail;
await tick();
if (state) {
selectedToolIds = [...selectedToolIds, toolId];
} else {
selectedToolIds = selectedToolIds.filter((id) => id !== toolId);
}
}}
/>
</div>
</button>
{/each}
{:else}
{#if toggleFilters && toggleFilters.length > 0} {#if toggleFilters && toggleFilters.length > 0}
{#each toggleFilters.sort( (a, b) => a.name.localeCompare( b.name, undefined, { sensitivity: 'base' } ) ) as filter, filterIdx (filter.id)} {#each toggleFilters.sort( (a, b) => a.name.localeCompare( b.name, undefined, { sensitivity: 'base' } ) ) as filter, filterIdx (filter.id)}
<Tooltip content={filter?.description} placement="top-start"> <Tooltip content={filter?.description} placement="top-start">
@ -311,6 +266,62 @@
</button> </button>
</Tooltip> </Tooltip>
{/if} {/if}
</div>
{:else if tab === 'tools' && tools}
<div in:fly={{ x: 20, duration: 150 }}>
<button
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
on:click={() => {
tab = '';
}}
>
<ChevronLeft />
<div class="flex items-center w-full justify-between">
<div>
{$i18n.t('Tools')}
<span class="ml-0.5 text-gray-500">{Object.keys(tools).length}</span>
</div>
</div>
</button>
{#each Object.keys(tools) as toolId}
<button
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
on:click={() => {
tools[toolId].enabled = !tools[toolId].enabled;
}}
>
<div class="flex-1 truncate">
<div class="flex flex-1 gap-2 items-center">
<Tooltip content={tools[toolId]?.name ?? ''} placement="top">
<div class="shrink-0">
<Wrench />
</div>
</Tooltip>
<Tooltip content={tools[toolId]?.description ?? ''} placement="top-start">
<div class=" truncate">{tools[toolId].name}</div>
</Tooltip>
</div>
</div>
<div class=" shrink-0">
<Switch
state={tools[toolId].enabled}
on:change={async (e) => {
const state = e.detail;
await tick();
if (state) {
selectedToolIds = [...selectedToolIds, toolId];
} else {
selectedToolIds = selectedToolIds.filter((id) => id !== toolId);
}
}}
/>
</div>
</button>
{/each}
</div>
{/if} {/if}
</DropdownMenu.Content> </DropdownMenu.Content>
</div> </div>