ui: ESLint config updates (#27700)
* chore: Spacing between sibling elements in html markup * chore: Formatting and linting rules
This commit is contained in:
@@ -123,21 +123,21 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="mx-auto flex h-full w-full flex-col md:pl-8" in:fade={{ duration: 150 }}>
|
||||
<div in:fade={{ duration: 150 }} class="mx-auto flex h-full w-full flex-col md:pl-8">
|
||||
<div class="flex flex-1 flex-col gap-4 md:flex-row">
|
||||
<SettingsChatDesktopSidebar
|
||||
sections={SETTINGS_CHAT_SECTIONS}
|
||||
isActive={(section: SettingsSection) => section.slug === activeSlug}
|
||||
getHref={getSectionHref ??
|
||||
((section: SettingsSection) => RouterService.settings(section.slug))}
|
||||
isActive={(section: SettingsSection) => section.slug === activeSlug}
|
||||
sections={SETTINGS_CHAT_SECTIONS}
|
||||
/>
|
||||
|
||||
<SettingsChatMobileHeader
|
||||
sections={SETTINGS_CHAT_SECTIONS}
|
||||
isActive={(section: SettingsSection) => section.slug === activeSlug}
|
||||
bind:this={mobileHeader}
|
||||
getHref={getSectionHref ??
|
||||
((section: SettingsSection) => RouterService.settings(section.slug))}
|
||||
bind:this={mobileHeader}
|
||||
isActive={(section: SettingsSection) => section.slug === activeSlug}
|
||||
sections={SETTINGS_CHAT_SECTIONS}
|
||||
/>
|
||||
|
||||
<div class="mx-auto max-w-3xl flex-1">
|
||||
@@ -145,6 +145,7 @@
|
||||
<div class="grid">
|
||||
<div class="mb-6 flex items-center gap-2 border-b border-border/30 pb-6 md:flex">
|
||||
<currentSection.icon class="h-5 w-5" />
|
||||
|
||||
<h3 class="text-lg font-semibold">{currentSection.title}</h3>
|
||||
</div>
|
||||
|
||||
@@ -163,7 +164,7 @@
|
||||
|
||||
{#if currentSection.slug === SETTINGS_SECTION_SLUGS.GENERAL}
|
||||
<div class="flex justify-end">
|
||||
<Button variant="outline" onclick={() => window.location.reload()}>
|
||||
<Button onclick={() => window.location.reload()} variant="outline">
|
||||
<RefreshCw class="h-3 w-3" />
|
||||
Reload app
|
||||
</Button>
|
||||
|
||||
@@ -66,13 +66,14 @@
|
||||
})()}
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<Label for={field.key} class="flex items-center gap-1.5 text-sm font-medium">
|
||||
<Label class="flex items-center gap-1.5 text-sm font-medium" for={field.key}>
|
||||
{field.label}
|
||||
|
||||
{#if field.isExperimental}
|
||||
<FlaskConical class="h-3.5 w-3.5 text-muted-foreground" />
|
||||
{/if}
|
||||
</Label>
|
||||
|
||||
{#if isCustomRealTime}
|
||||
<SettingsChatParameterSourceIndicator />
|
||||
{/if}
|
||||
@@ -80,9 +81,9 @@
|
||||
|
||||
<div class="relative w-full">
|
||||
<Input
|
||||
autocomplete={field.isPrivate ? 'new-password' : undefined}
|
||||
id={field.key}
|
||||
type={field.isPrivate ? 'password' : field.isPositiveInteger ? 'number' : 'text'}
|
||||
autocomplete={field.isPrivate ? 'new-password' : undefined}
|
||||
{...field.isPositiveInteger
|
||||
? {
|
||||
min: String(field.min ?? 1),
|
||||
@@ -90,28 +91,30 @@
|
||||
...(field.max != null ? { max: String(field.max) } : {})
|
||||
}
|
||||
: {}}
|
||||
value={currentValue}
|
||||
class="w-full {isCustomRealTime ? 'pr-8' : ''}"
|
||||
oninput={(e) => onConfigChange(field.key, e.currentTarget.value)}
|
||||
placeholder={currentModelParams[field.key] != null
|
||||
? `Default: ${normalizeFloatingPoint(currentModelParams[field.key])}`
|
||||
: (field.placeholder ?? '')}
|
||||
class="w-full {isCustomRealTime ? 'pr-8' : ''}"
|
||||
value={currentValue}
|
||||
/>
|
||||
|
||||
{#if isCustomRealTime}
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Reset to default"
|
||||
class="absolute top-1/2 right-2 inline-flex h-5 w-5 -translate-y-1/2 items-center justify-center rounded transition-colors hover:bg-muted"
|
||||
onclick={() => {
|
||||
settingsStore.resetParameterToServerDefault(field.key);
|
||||
onConfigChange(field.key, '');
|
||||
}}
|
||||
class="absolute top-1/2 right-2 inline-flex h-5 w-5 -translate-y-1/2 items-center justify-center rounded transition-colors hover:bg-muted"
|
||||
aria-label="Reset to default"
|
||||
title="Reset to default"
|
||||
type="button"
|
||||
>
|
||||
<RotateCcw class="h-3 w-3" />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if field.help || SETTING_CONFIG_INFO[field.key]}
|
||||
<p class="mt-1 text-xs text-muted-foreground">
|
||||
{@html field.help || SETTING_CONFIG_INFO[field.key]}
|
||||
@@ -119,7 +122,7 @@
|
||||
{/if}
|
||||
{:else if field.type === SettingsFieldType.TEXTAREA}
|
||||
{#if field.label}
|
||||
<Label for={field.key} class="block flex items-center gap-1.5 text-sm font-medium">
|
||||
<Label class="block flex items-center gap-1.5 text-sm font-medium" for={field.key}>
|
||||
{field.label}
|
||||
|
||||
{#if field.isExperimental}
|
||||
@@ -129,11 +132,11 @@
|
||||
{/if}
|
||||
|
||||
<Textarea
|
||||
class="min-h-[10rem] w-full md:max-w-3xl"
|
||||
id={field.key}
|
||||
value={String(localConfig[field.key] ?? '')}
|
||||
onchange={(e) => onConfigChange(field.key, e.currentTarget.value)}
|
||||
placeholder=""
|
||||
class="min-h-[10rem] w-full md:max-w-3xl"
|
||||
value={String(localConfig[field.key] ?? '')}
|
||||
/>
|
||||
|
||||
{#if field.help || SETTING_CONFIG_INFO[field.key]}
|
||||
@@ -145,13 +148,13 @@
|
||||
{#if field.key === SETTINGS_KEYS.SYSTEM_MESSAGE}
|
||||
<div class="mt-3 flex items-center gap-2">
|
||||
<Checkbox
|
||||
id="showSystemMessage"
|
||||
checked={Boolean(localConfig.showSystemMessage ?? true)}
|
||||
id="showSystemMessage"
|
||||
onCheckedChange={(checked) =>
|
||||
onConfigChange(SETTINGS_KEYS.SHOW_SYSTEM_MESSAGE, Boolean(checked))}
|
||||
/>
|
||||
|
||||
<Label for="showSystemMessage" class="cursor-pointer text-sm font-normal">
|
||||
<Label class="cursor-pointer text-sm font-normal" for="showSystemMessage">
|
||||
Show system message in conversations
|
||||
</Label>
|
||||
</div>
|
||||
@@ -172,21 +175,20 @@
|
||||
})()}
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<Label for={field.key} class="flex items-center gap-1.5 text-sm font-medium">
|
||||
<Label class="flex items-center gap-1.5 text-sm font-medium" for={field.key}>
|
||||
{field.label}
|
||||
|
||||
{#if field.isExperimental}
|
||||
<FlaskConical class="h-3.5 w-3.5 text-muted-foreground" />
|
||||
{/if}
|
||||
</Label>
|
||||
|
||||
{#if isCustomRealTime}
|
||||
<SettingsChatParameterSourceIndicator />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<Select.Root
|
||||
type="single"
|
||||
value={currentValue}
|
||||
onValueChange={(value) => {
|
||||
if (field.key === SETTINGS_KEYS.THEME && value && onThemeChange) {
|
||||
onThemeChange(value);
|
||||
@@ -194,6 +196,8 @@
|
||||
onConfigChange(field.key, value);
|
||||
}
|
||||
}}
|
||||
type="single"
|
||||
value={currentValue}
|
||||
>
|
||||
<div class="relative w-full md:w-auto">
|
||||
<Select.Trigger class="w-full">
|
||||
@@ -206,25 +210,27 @@
|
||||
{selectedOption?.label || `Select ${field.label.toLowerCase()}`}
|
||||
</div>
|
||||
</Select.Trigger>
|
||||
|
||||
{#if isCustomRealTime}
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Reset to default"
|
||||
class="absolute top-1/2 right-8 inline-flex h-5 w-5 -translate-y-1/2 items-center justify-center rounded transition-colors hover:bg-muted"
|
||||
onclick={() => {
|
||||
settingsStore.resetParameterToServerDefault(field.key);
|
||||
onConfigChange(field.key, '');
|
||||
}}
|
||||
class="absolute top-1/2 right-8 inline-flex h-5 w-5 -translate-y-1/2 items-center justify-center rounded transition-colors hover:bg-muted"
|
||||
aria-label="Reset to default"
|
||||
title="Reset to default"
|
||||
type="button"
|
||||
>
|
||||
<RotateCcw class="h-3 w-3" />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<Select.Content>
|
||||
{#if field.options}
|
||||
{#each field.options as option (option.value)}
|
||||
<Select.Item value={option.value} label={option.label}>
|
||||
<Select.Item label={option.label} value={option.value}>
|
||||
<div class="flex items-center gap-2">
|
||||
{#if option.icon}
|
||||
{@const IconComponent = option.icon}
|
||||
@@ -237,6 +243,7 @@
|
||||
{/if}
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
|
||||
{#if field.help || SETTING_CONFIG_INFO[field.key]}
|
||||
<p class="mt-1 text-xs text-muted-foreground">
|
||||
{field.help || SETTING_CONFIG_INFO[field.key]}
|
||||
@@ -258,20 +265,21 @@
|
||||
|
||||
<RadioGroup.Root
|
||||
class="gap-4"
|
||||
value={currentMode}
|
||||
onValueChange={(value) => {
|
||||
for (const opt of radioOptions) {
|
||||
onConfigChange(opt.key, opt.value === value);
|
||||
}
|
||||
}}
|
||||
value={currentMode}
|
||||
>
|
||||
{#each radioOptions as opt (opt.value)}
|
||||
{@const itemId = `${field.key}-${opt.value}`}
|
||||
<div class="flex items-center gap-2">
|
||||
<RadioGroup.Item value={opt.value} id={itemId} />
|
||||
<RadioGroup.Item id={itemId} value={opt.value} />
|
||||
|
||||
<Label
|
||||
for={itemId}
|
||||
class="flex cursor-pointer items-center gap-1.5 text-sm font-normal"
|
||||
for={itemId}
|
||||
>
|
||||
{opt.label}
|
||||
|
||||
@@ -291,16 +299,16 @@
|
||||
{:else if field.type === SettingsFieldType.CHECKBOX}
|
||||
<div class="flex items-start space-x-3">
|
||||
<Checkbox
|
||||
id={field.key}
|
||||
checked={Boolean(localConfig[field.key])}
|
||||
onCheckedChange={(checked) => onConfigChange(field.key, checked)}
|
||||
class="mt-1"
|
||||
id={field.key}
|
||||
onCheckedChange={(checked) => onConfigChange(field.key, checked)}
|
||||
/>
|
||||
|
||||
<div class="space-y-1">
|
||||
<label
|
||||
for={field.key}
|
||||
class="flex cursor-pointer items-center gap-1.5 pt-1 pb-0.5 text-sm leading-none font-medium"
|
||||
for={field.key}
|
||||
>
|
||||
{field.label}
|
||||
|
||||
|
||||
+24
-24
@@ -261,92 +261,92 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="space-y-12" in:fade={{ duration: 150 }}>
|
||||
<div in:fade={{ duration: 150 }} class="space-y-12">
|
||||
<SettingsGroup title="Conversations">
|
||||
<SettingsChatImportExportSection
|
||||
title="Export"
|
||||
description="Download your conversations as a ZIP of JSONL files. This includes all messages, attachments, and conversation history."
|
||||
IconComponent={Download}
|
||||
buttonText="Export conversations"
|
||||
description="Download your conversations as a ZIP of JSONL files. This includes all messages, attachments, and conversation history."
|
||||
onclick={handleExportClick}
|
||||
summary={{ items: exportedConversations, show: showExportSummary, verb: 'Exported' }}
|
||||
title="Export"
|
||||
/>
|
||||
|
||||
<SettingsChatImportExportSection
|
||||
title="Import"
|
||||
description="Import one or more conversations from a previously exported ZIP or JSONL file. This will merge with your existing conversations."
|
||||
IconComponent={Upload}
|
||||
buttonText="Import conversations"
|
||||
description="Import one or more conversations from a previously exported ZIP or JSONL file. This will merge with your existing conversations."
|
||||
onclick={handleImportClick}
|
||||
summary={{ items: importedConversations, show: showImportSummary, verb: 'Imported' }}
|
||||
title="Import"
|
||||
/>
|
||||
|
||||
<SettingsChatImportExportSection
|
||||
title="Delete All"
|
||||
description="Permanently delete all conversations and their messages. This action cannot be undone. Consider exporting your conversations first if you want to keep a backup."
|
||||
IconComponent={Trash2}
|
||||
buttonText="Delete all conversations"
|
||||
onclick={handleDeleteAllClick}
|
||||
titleClass="text-destructive"
|
||||
buttonVariant="destructive"
|
||||
buttonClass="text-destructive-foreground justify-start justify-self-start bg-destructive hover:bg-destructive/80 md:w-auto"
|
||||
buttonText="Delete all conversations"
|
||||
buttonVariant="destructive"
|
||||
description="Permanently delete all conversations and their messages. This action cannot be undone. Consider exporting your conversations first if you want to keep a backup."
|
||||
onclick={handleDeleteAllClick}
|
||||
title="Delete All"
|
||||
titleClass="text-destructive"
|
||||
/>
|
||||
</SettingsGroup>
|
||||
|
||||
<SettingsGroup title="Settings">
|
||||
<SettingsChatImportExportSection
|
||||
title="Export"
|
||||
description="Export your chat settings and preferences as a JSON file."
|
||||
IconComponent={Download}
|
||||
buttonText="Export settings"
|
||||
description="Export your chat settings and preferences as a JSON file."
|
||||
onclick={handleSettingsExport}
|
||||
summary={{ items: [], show: showSettingsExportSummary, verb: 'Exported' }}
|
||||
title="Export"
|
||||
/>
|
||||
|
||||
<SettingsChatImportExportSection
|
||||
title="Import"
|
||||
description="Import chat settings from a previously exported JSON file. This will merge with your existing settings."
|
||||
IconComponent={Upload}
|
||||
buttonText="Import settings"
|
||||
description="Import chat settings from a previously exported JSON file. This will merge with your existing settings."
|
||||
onclick={handleSettingsImport}
|
||||
summary={{ items: [], show: showSettingsImportSummary, verb: 'Imported' }}
|
||||
title="Import"
|
||||
/>
|
||||
</SettingsGroup>
|
||||
</div>
|
||||
|
||||
<DialogExportSettings
|
||||
bind:open={showSettingsExportDialog}
|
||||
bind:includeSensitiveData
|
||||
onConfirm={handleSettingsExportConfirm}
|
||||
bind:open={showSettingsExportDialog}
|
||||
onCancel={handleSettingsExportCancel}
|
||||
onConfirm={handleSettingsExportConfirm}
|
||||
/>
|
||||
|
||||
<DialogConversationSelection
|
||||
bind:open={showExportDialog}
|
||||
conversations={availableConversations}
|
||||
{messageCountMap}
|
||||
mode={ConversationSelectionMode.EXPORT}
|
||||
bind:open={showExportDialog}
|
||||
onCancel={() => (showExportDialog = false)}
|
||||
onConfirm={handleExportConfirm}
|
||||
/>
|
||||
|
||||
<DialogConversationSelection
|
||||
bind:open={showImportDialog}
|
||||
conversations={availableConversations}
|
||||
{messageCountMap}
|
||||
mode={ConversationSelectionMode.IMPORT}
|
||||
bind:open={showImportDialog}
|
||||
onCancel={() => (showImportDialog = false)}
|
||||
onConfirm={handleImportConfirm}
|
||||
/>
|
||||
|
||||
<DialogConfirmation
|
||||
bind:open={showDeleteDialog}
|
||||
title="Delete all conversations"
|
||||
description="Are you sure you want to delete all conversations? This action cannot be undone and will permanently remove all your conversations and messages."
|
||||
confirmText="Delete All"
|
||||
cancelText="Cancel"
|
||||
variant="destructive"
|
||||
confirmText="Delete All"
|
||||
description="Are you sure you want to delete all conversations? This action cannot be undone and will permanently remove all your conversations and messages."
|
||||
icon={Trash2}
|
||||
onConfirm={handleDeleteAllConfirm}
|
||||
onCancel={handleDeleteAllCancel}
|
||||
onConfirm={handleDeleteAllConfirm}
|
||||
title="Delete all conversations"
|
||||
variant="destructive"
|
||||
/>
|
||||
|
||||
+1
-1
@@ -10,8 +10,8 @@
|
||||
</script>
|
||||
|
||||
<Badge
|
||||
variant="secondary"
|
||||
class="h-5 bg-orange-100 px-1.5 py-0.5 text-xs text-orange-800 dark:bg-orange-900 dark:text-orange-200 {className}"
|
||||
variant="secondary"
|
||||
>
|
||||
<Wrench class="mr-1 h-3 w-3" />
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<div class="space-y-2">
|
||||
{#each groups as group (group.key)}
|
||||
{@const isExpanded = expandedGroups.has(group.key)}
|
||||
<Collapsible.Root open={isExpanded} onOpenChange={() => toggleExpanded(group.key)}>
|
||||
<Collapsible.Root onOpenChange={() => toggleExpanded(group.key)} open={isExpanded}>
|
||||
<Collapsible.Trigger
|
||||
class="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm hover:bg-muted/50"
|
||||
>
|
||||
@@ -42,14 +42,14 @@
|
||||
<span class="inline-flex min-w-0 items-center gap-1.5 font-medium">
|
||||
{#if group.source === 'mcp'}
|
||||
<McpServerIdentity
|
||||
displayName={group.label}
|
||||
{faviconUrl}
|
||||
iconClass={ICON_CLASS_DEFAULT}
|
||||
iconRounded="rounded-sm"
|
||||
showVersion={false}
|
||||
displayName={group.label}
|
||||
{faviconUrl}
|
||||
/>
|
||||
{:else}
|
||||
<TruncatedText text={group.label} class="font-medium" />
|
||||
<TruncatedText class="font-medium" text={group.label} />
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
@@ -63,7 +63,9 @@
|
||||
<!-- Header row -->
|
||||
<div class="flex items-center gap-2 px-2 py-1 text-xs text-muted-foreground">
|
||||
<span class="min-w-0 flex-1">Tool</span>
|
||||
|
||||
<span class="w-16 shrink-0 text-center">Enabled</span>
|
||||
|
||||
<span class="w-20 shrink-0 text-center">Always allow</span>
|
||||
</div>
|
||||
|
||||
@@ -84,20 +86,22 @@
|
||||
{#if IconComponent}
|
||||
<IconComponent class={ICON_CLASS_DEFAULT} />
|
||||
{/if}
|
||||
<TruncatedText text={displayLabel} class="min-w-0" showTooltip={true} />
|
||||
|
||||
<TruncatedText class="min-w-0" showTooltip={true} text={displayLabel} />
|
||||
</span>
|
||||
|
||||
<div class="flex w-16 shrink-0 justify-center">
|
||||
<Checkbox
|
||||
checked={isEnabled}
|
||||
onCheckedChange={() => toolsStore.toggleTool(entry.key)}
|
||||
class={ICON_CLASS_DEFAULT}
|
||||
onCheckedChange={() => toolsStore.toggleTool(entry.key)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex w-20 shrink-0 justify-center">
|
||||
<Checkbox
|
||||
checked={isAlwaysAllowed}
|
||||
class={ICON_CLASS_DEFAULT}
|
||||
onCheckedChange={() => {
|
||||
if (isAlwaysAllowed) {
|
||||
permissionsStore.revokeTool(permissionKey);
|
||||
@@ -105,7 +109,6 @@
|
||||
permissionsStore.allowTool(permissionKey);
|
||||
}
|
||||
}}
|
||||
class={ICON_CLASS_DEFAULT}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
href={getHref(section)}
|
||||
>
|
||||
<section.icon class={ICON_CLASS_DEFAULT} />
|
||||
|
||||
<span class="ml-2">{section.title}</span>
|
||||
</a>
|
||||
{:else}
|
||||
@@ -44,6 +45,7 @@
|
||||
onclick={() => onSectionChange?.(section.title)}
|
||||
>
|
||||
<section.icon class={ICON_CLASS_DEFAULT} />
|
||||
|
||||
<span class="ml-2">{section.title}</span>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
</div>
|
||||
|
||||
<div class="border-b border-border/30 py-2">
|
||||
<ScrollCarousel {carousel} alwaysShowArrows containerClass="py-2" innerClass="gap-2">
|
||||
<ScrollCarousel alwaysShowArrows {carousel} containerClass="py-2" innerClass="gap-2">
|
||||
{#each sections as section (section.title)}
|
||||
{#if getHref}
|
||||
<a
|
||||
@@ -61,6 +61,7 @@
|
||||
}}
|
||||
>
|
||||
<section.icon class="{ICON_CLASS_DEFAULT} flex-shrink-0" />
|
||||
|
||||
<span>{section.title}</span>
|
||||
</a>
|
||||
{:else}
|
||||
@@ -77,6 +78,7 @@
|
||||
}}
|
||||
>
|
||||
<section.icon class="{ICON_CLASS_DEFAULT} flex-shrink-0" />
|
||||
|
||||
<span>{section.title}</span>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<div class="sticky bottom-0 mx-auto mt-4 flex w-full justify-between p-6">
|
||||
<div class="flex gap-2">
|
||||
<Button variant="outline" onclick={handleResetClick}>
|
||||
<Button onclick={handleResetClick} variant="outline">
|
||||
<RotateCcw class="h-3 w-3" />
|
||||
|
||||
Reset to default
|
||||
@@ -45,14 +45,17 @@
|
||||
<AlertDialog.Content>
|
||||
<AlertDialog.Header>
|
||||
<AlertDialog.Title>Reset Settings to Default</AlertDialog.Title>
|
||||
|
||||
<AlertDialog.Description>
|
||||
Are you sure you want to reset all settings to their default values? This will reset all
|
||||
parameters to the values provided by the server's /props endpoint and remove all your custom
|
||||
configurations.
|
||||
</AlertDialog.Description>
|
||||
</AlertDialog.Header>
|
||||
|
||||
<AlertDialog.Footer>
|
||||
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
|
||||
|
||||
<AlertDialog.Action onclick={handleConfirmReset}>Reset to Default</AlertDialog.Action>
|
||||
</AlertDialog.Footer>
|
||||
</AlertDialog.Content>
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
<div in:fade={{ duration: 150 }} class="flex min-h-[calc(100dvh-4rem)] flex-col">
|
||||
<div class="fixed top-4.5 right-4 z-50 md:hidden">
|
||||
<ActionIcon icon={X} tooltip="Close" onclick={handleClose} />
|
||||
<ActionIcon icon={X} onclick={handleClose} tooltip="Close" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
@@ -102,7 +102,7 @@
|
||||
</Empty.Header>
|
||||
|
||||
<Empty.Content>
|
||||
<Button size="sm" onclick={() => (isAddingServer = true)}>
|
||||
<Button onclick={() => (isAddingServer = true)} size="sm">
|
||||
<Plus />
|
||||
|
||||
Add New Server
|
||||
@@ -120,8 +120,8 @@
|
||||
<McpServerCardSkeleton />
|
||||
{:else}
|
||||
<McpServerCard
|
||||
{server}
|
||||
enabled={conversationsStore.preferences.isMcpServerEnabledForChat(server.id)}
|
||||
onDelete={() => mcpStore.removeServer(server.id)}
|
||||
onToggle={async () => {
|
||||
const wasEnabled = conversationsStore.preferences.isMcpServerEnabledForChat(
|
||||
server.id
|
||||
@@ -137,7 +137,7 @@
|
||||
}
|
||||
}}
|
||||
onUpdate={(updates) => mcpStore.updateServer(server.id, updates)}
|
||||
onDelete={() => mcpStore.removeServer(server.id)}
|
||||
{server}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
@@ -155,7 +155,7 @@
|
||||
</Empty.Header>
|
||||
|
||||
<Empty.Content>
|
||||
<Button size="sm" onclick={() => (isAddingServer = true)}>
|
||||
<Button onclick={() => (isAddingServer = true)} size="sm">
|
||||
<Plus />
|
||||
|
||||
Add New Server
|
||||
|
||||
Reference in New Issue
Block a user