style(ConfigManager): make sections collapsible

This commit is contained in:
AnotiaWang
2025-02-25 17:08:37 +08:00
parent 50b7e3380e
commit 4a2b72445e

View File

@ -21,6 +21,19 @@
/** If loading AI models failed, use a plain input to improve UX */ /** If loading AI models failed, use a plain input to improve UX */
const isLoadAiModelsFailed = ref(false) const isLoadAiModelsFailed = ref(false)
const activeSections = ref(['0', '1'])
const settingSections = computed(() => [
{
label: t('settings.ai.provider'),
icon: 'i-lucide-bot',
slot: 'ai',
},
{
label: t('settings.webSearch.provider'),
icon: 'i-lucide-search',
slot: 'web-search',
},
])
const aiProviderOptions = computed(() => [ const aiProviderOptions = computed(() => [
{ {
label: t('settings.ai.providers.openaiCompatible.title'), label: t('settings.ai.providers.openaiCompatible.title'),
@ -170,183 +183,198 @@
<UButton icon="i-lucide-settings" /> <UButton icon="i-lucide-settings" />
<template #body> <template #body>
<div class="flex flex-col gap-y-2"> <UAccordion
v-model="activeSections"
type="multiple"
:items="settingSections"
collapsible
>
<!-- AI provider --> <!-- AI provider -->
<h3 class="font-bold">{{ $t('settings.ai.provider') }}</h3> <template #ai>
<UFormField> <div class="flex flex-col gap-y-2 mb-2">
<template v-if="selectedAiProvider?.help" #help> <UFormField>
<i18n-t <template v-if="selectedAiProvider?.help" #help>
class="whitespace-pre-wrap" <i18n-t
:keypath="selectedAiProvider.help" class="whitespace-pre-wrap"
tag="span" :keypath="selectedAiProvider.help"
tag="span"
>
<UButton
v-if="selectedAiProvider.link"
class="!p-0"
:to="selectedAiProvider.link"
target="_blank"
variant="link"
>
{{
selectedAiProvider.linkText || selectedAiProvider.link
}}
</UButton>
</i18n-t>
</template>
<USelect
v-model="config.ai.provider"
class="w-full"
:items="aiProviderOptions"
/>
</UFormField>
<UFormField
:label="$t('settings.ai.apiKey')"
:required="config.ai.provider !== 'ollama'"
> >
<UButton <PasswordInput
v-if="selectedAiProvider.link" v-model="config.ai.apiKey"
class="!p-0" class="w-full"
:to="selectedAiProvider.link" :placeholder="$t('settings.ai.apiKey')"
target="_blank" />
variant="link" </UFormField>
> <UFormField :label="$t('settings.ai.apiBase')">
{{ selectedAiProvider.linkText || selectedAiProvider.link }} <UInput
</UButton> v-model="config.ai.apiBase"
</i18n-t> class="w-full"
</template> :placeholder="aiApiBase"
<USelect />
v-model="config.ai.provider" </UFormField>
class="w-full" <UFormField :label="$t('settings.ai.model')" required>
:items="aiProviderOptions" <UInputMenu
/> v-if="aiModelOptions.length && !isLoadAiModelsFailed"
</UFormField> v-model="config.ai.model"
class="w-full"
<div class="flex flex-col gap-y-2"> :items="aiModelOptions"
<UFormField :placeholder="$t('settings.ai.model')"
:label="$t('settings.ai.apiKey')" :loading="loadingAiModels"
:required="config.ai.provider !== 'ollama'" create-item
> @create="createAndSelectAiModel"
<PasswordInput />
v-model="config.ai.apiKey" <UInput
class="w-full" v-else
:placeholder="$t('settings.ai.apiKey')" v-model="config.ai.model"
/> class="w-full"
</UFormField> :placeholder="$t('settings.ai.model')"
<UFormField :label="$t('settings.ai.apiBase')"> />
<UInput </UFormField>
v-model="config.ai.apiBase" <UFormField :label="$t('settings.ai.contextSize')">
class="w-full" <template #help>
:placeholder="aiApiBase" {{ $t('settings.ai.contextSizeHelp') }}
/> </template>
</UFormField> <UInput
<UFormField :label="$t('settings.ai.model')" required> v-model="config.ai.contextSize"
<UInputMenu class="w-26"
v-if="aiModelOptions.length && !isLoadAiModelsFailed" type="number"
v-model="config.ai.model" placeholder="128000"
class="w-full" :min="512"
:items="aiModelOptions" />
:placeholder="$t('settings.ai.model')" tokens
:loading="loadingAiModels" </UFormField>
create-item </div>
@create="createAndSelectAiModel" </template>
/>
<UInput
v-else
v-model="config.ai.model"
class="w-full"
:placeholder="$t('settings.ai.model')"
/>
</UFormField>
<UFormField :label="$t('settings.ai.contextSize')">
<template #help>
{{ $t('settings.ai.contextSizeHelp') }}
</template>
<UInput
v-model="config.ai.contextSize"
class="w-26"
type="number"
placeholder="128000"
:min="512"
/>
tokens
</UFormField>
</div>
<USeparator class="my-2" />
<!-- Web search --> <!-- Web search -->
<h3 class="font-bold"> {{ $t('settings.webSearch.provider') }} </h3> <template #web-search>
<UFormField> <div class="flex flex-col gap-y-2">
<template #help> <UFormField>
<i18n-t <template #help>
v-if="selectedWebSearchProvider?.help" <i18n-t
:keypath="selectedWebSearchProvider.help" v-if="selectedWebSearchProvider?.help"
tag="p" :keypath="selectedWebSearchProvider.help"
tag="p"
>
<UButton
class="!p-0"
:to="selectedWebSearchProvider.link"
target="_blank"
variant="link"
>
{{ selectedWebSearchProvider.link }}
</UButton>
</i18n-t>
</template>
<USelect
v-model="config.webSearch.provider"
class="w-30"
:items="webSearchProviderOptions"
/>
</UFormField>
<UFormField
:label="$t('settings.webSearch.apiKey')"
:required="!config.webSearch.apiBase"
> >
<UButton <PasswordInput
class="!p-0" v-model="config.webSearch.apiKey"
:to="selectedWebSearchProvider.link" class="w-full"
target="_blank" :placeholder="$t('settings.webSearch.apiKey')"
variant="link" />
> </UFormField>
{{ selectedWebSearchProvider.link }} <UFormField
</UButton> v-if="selectedWebSearchProvider?.supportsCustomApiBase"
</i18n-t> :label="$t('settings.webSearch.apiBase')"
</template> >
<USelect <UInput
v-model="config.webSearch.provider" v-model="config.webSearch.apiBase"
class="w-30" class="w-full"
:items="webSearchProviderOptions" :placeholder="webSearchApiBase"
/> />
</UFormField> </UFormField>
<UFormField <UFormField :label="$t('settings.webSearch.queryLanguage')">
:label="$t('settings.webSearch.apiKey')" <template #help>
:required="!config.webSearch.apiBase" <i18n-t
> class="whitespace-pre-wrap"
<PasswordInput keypath="settings.webSearch.queryLanguageHelp"
v-model="config.webSearch.apiKey" tag="p"
class="w-full" />
:placeholder="$t('settings.webSearch.apiKey')" </template>
/> <LangSwitcher
</UFormField> :value="config.webSearch.searchLanguage"
<UFormField @update="config.webSearch.searchLanguage = $event"
v-if="selectedWebSearchProvider?.supportsCustomApiBase" private
:label="$t('settings.webSearch.apiBase')" />
> </UFormField>
<UInput <UFormField :label="$t('settings.webSearch.concurrencyLimit')">
v-model="config.webSearch.apiBase" <template #help>
class="w-full" {{ $t('settings.webSearch.concurrencyLimitHelp') }}
:placeholder="webSearchApiBase" </template>
/> <UInput
</UFormField> v-model="config.webSearch.concurrencyLimit"
<UFormField :label="$t('settings.webSearch.queryLanguage')"> class="w-15"
<template #help> type="number"
<i18n-t placeholder="2"
class="whitespace-pre-wrap" :min="1"
keypath="settings.webSearch.queryLanguageHelp" :max="5"
tag="p" :step="1"
/> />
</template> </UFormField>
<LangSwitcher
:value="config.webSearch.searchLanguage"
@update="config.webSearch.searchLanguage = $event"
private
/>
</UFormField>
<UFormField :label="$t('settings.webSearch.concurrencyLimit')">
<template #help>
{{ $t('settings.webSearch.concurrencyLimitHelp') }}
</template>
<UInput
v-model="config.webSearch.concurrencyLimit"
class="w-15"
type="number"
placeholder="2"
:min="1"
:max="5"
:step="1"
/>
</UFormField>
<!-- Tavily-specific settings --> <!-- Tavily-specific settings -->
<template v-if="config.webSearch.provider === 'tavily'"> <template v-if="config.webSearch.provider === 'tavily'">
<UFormField <UFormField
:label="$t('settings.webSearch.providers.tavily.advancedSearch')" :label="
:help="$t('settings.webSearch.providers.tavily.advancedSearchHelp')" $t('settings.webSearch.providers.tavily.advancedSearch')
> "
<USwitch v-model="config.webSearch.tavilyAdvancedSearch" /> :help="
</UFormField> $t('settings.webSearch.providers.tavily.advancedSearchHelp')
<UFormField "
:label="$t('settings.webSearch.providers.tavily.searchTopic')" >
:help="$t('settings.webSearch.providers.tavily.searchTopicHelp')" <USwitch v-model="config.webSearch.tavilyAdvancedSearch" />
> </UFormField>
<USelect <UFormField
v-model="config.webSearch.tavilySearchTopic" :label="$t('settings.webSearch.providers.tavily.searchTopic')"
class="w-30" :help="
:items="tavilySearchTopicOptions" $t('settings.webSearch.providers.tavily.searchTopicHelp')
placeholder="general" "
/> >
</UFormField> <USelect
v-model="config.webSearch.tavilySearchTopic"
class="w-30"
:items="tavilySearchTopicOptions"
placeholder="general"
/>
</UFormField>
</template>
</div>
</template> </template>
</div> </UAccordion>
</template> </template>
<template #footer> <template #footer>
<div class="flex items-center justify-between gap-2 w-full"> <div class="flex items-center justify-between gap-2 w-full">
<p class="text-sm text-gray-500"> <p class="text-sm text-gray-500">