feat(ai): keep provider headers visible

This commit is contained in:
Guoyu Su authored and GitHub committed 2026-08-18 22:04:53 +08:00
1 parent aeba7d81ad
commit 27fd668758
2 files changed
+5 -4

No files matched your search

@@ -2934,8 +2934,8 @@ async function openExternalUrl(url: string) {
<input v-model="modelSearchQuery" type="text" :placeholder="t('ai.searchModels')" class="w-full rounded-sm border bg-background py-1.5 pl-7 pr-2 text-xs outline-none focus:ring-1 focus:ring-primary" @click.stop /> <input v-model="modelSearchQuery" type="text" :placeholder="t('ai.searchModels')" class="w-full rounded-sm border bg-background py-1.5 pl-7 pr-2 text-xs outline-none focus:ring-1 focus:ring-primary" @click.stop />
</div> </div>
<div class="max-h-80 overflow-auto"> <div class="max-h-80 overflow-auto">
<template v-for="(config, configIndex) in configuredProviders" :key="config.id"> <div v-for="(config, configIndex) in configuredProviders" :key="config.id" class="relative">
<button type="button" class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-xs text-foreground hover:bg-muted" :aria-expanded="!isModelConfigCollapsed(config.id)" @click="toggleModelConfig(config.id)"> <button type="button" class="sticky top-0 z-10 flex w-full items-center gap-2 rounded-sm bg-popover px-2 py-1.5 text-left text-xs text-foreground hover:bg-muted" :aria-expanded="!isModelConfigCollapsed(config.id)" @click="toggleModelConfig(config.id)">
<ChevronRight class="h-3.5 w-3.5 shrink-0 transition-transform" :class="{ 'rotate-90': !isModelConfigCollapsed(config.id) }" /> <ChevronRight class="h-3.5 w-3.5 shrink-0 transition-transform" :class="{ 'rotate-90': !isModelConfigCollapsed(config.id) }" />
<AiProviderLogo :provider="config.provider" :label="AI_PROVIDER_PRESETS[config.provider]?.label ?? config.provider" :icon-slug="AI_PROVIDER_PRESETS[config.provider]?.iconSlug" class="h-3.5 w-3.5 shrink-0" /> <AiProviderLogo :provider="config.provider" :label="AI_PROVIDER_PRESETS[config.provider]?.label ?? config.provider" :icon-slug="AI_PROVIDER_PRESETS[config.provider]?.iconSlug" class="h-3.5 w-3.5 shrink-0" />
<span class="min-w-0 flex-1 truncate font-medium">{{ config.name }}</span> <span class="min-w-0 flex-1 truncate font-medium">{{ config.name }}</span>
@@ -2984,7 +2984,7 @@ async function openExternalUrl(url: string) {
</button> </button>
</div> </div>
<div v-if="configIndex < configuredProviders.length - 1" class="my-1 border-t" /> <div v-if="configIndex < configuredProviders.length - 1" class="my-1 border-t" />
</template> </div>
</div> </div>
<div v-if="settings.activeModel" class="border-t pt-1"> <div v-if="settings.activeModel" class="border-t pt-1">
<Popover v-model:open="effortMenuOpen"> <Popover v-model:open="effortMenuOpen">
+2 -1
View File
@@ -64,7 +64,8 @@ test("AI model menu separates provider groups from model selections", () => {
const selectorEnd = source.indexOf("</template>", source.indexOf("</Popover>", selectorStart)); const selectorEnd = source.indexOf("</template>", source.indexOf("</Popover>", selectorStart));
const selector = source.slice(selectorStart, selectorEnd); const selector = source.slice(selectorStart, selectorEnd);
assert.match(selector, /v-for="\(config, configIndex\) in configuredProviders"/); assert.match(selector, /<div v-for="\(config, configIndex\) in configuredProviders" :key="config\.id" class="relative">/);
assert.match(selector, /class="sticky top-0 z-10 flex w-full items-center gap-2 rounded-sm bg-popover/);
assert.match(selector, /class="ml-5 border-l border-border\/60 pl-1"/); assert.match(selector, /class="ml-5 border-l border-border\/60 pl-1"/);
assert.match(selector, /v-if="configIndex < configuredProviders\.length - 1" class="my-1 border-t"/); assert.match(selector, /v-if="configIndex < configuredProviders\.length - 1" class="my-1 border-t"/);
assert.doesNotMatch(selector, /bg-accent text-accent-foreground.*config\.id === settings\.activeModel/); assert.doesNotMatch(selector, /bg-accent text-accent-foreground.*config\.id === settings\.activeModel/);