mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 08:06:19 +00:00
* feat(frontend): add English and Traditional Chinese locales * fix(frontend): capitalize the English login key label * fix(frontend): capitalize standalone English labels * feat(frontend): add reactive localization and refine admin layouts Replace DOM text translation with domain-based Vue I18n resources for English, Simplified Chinese, and Traditional Chinese. Localize shared controls, notifications, charts, and key usage while refining table alignment, menus, and compact labels. Expose semantic usage-window and trend-metric identifiers from the API. Pin the UI and workbench dependencies to published feature commits and preserve the original font defaults. Co-authored-by: Codex <noreply@openai.com> --------- Co-authored-by: Jimbb <14995924+jimbb@users.noreply.github.com> Co-authored-by: Zyy <zyycn@users.noreply.github.com> Co-authored-by: Codex <noreply@openai.com>
105 lines
3.2 KiB
Vue
105 lines
3.2 KiB
Vue
<script setup lang="ts">
|
|
import type { ClientProfileSelection, ProviderRequestProfile, ProviderRequestProfiles, XaiClientProfileSelection } from '@/api/modules/settings/profiles'
|
|
|
|
import { ZSegmented } from '@codex-proxy/ui'
|
|
import { computed, shallowRef } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { formatProviderLabel, PROVIDER_IDS, providerIcon } from '@/utils/providers'
|
|
import ClientProfileEditor from './ClientProfileEditor.vue'
|
|
import XaiClientProfileEditor from './XaiClientProfileEditor.vue'
|
|
|
|
withDefaults(defineProps<{
|
|
active?: boolean
|
|
disabled?: boolean
|
|
allowInherit?: boolean
|
|
}>(), {
|
|
active: true,
|
|
disabled: false,
|
|
allowInherit: false,
|
|
})
|
|
|
|
const { t } = useI18n({ useScope: 'global' })
|
|
|
|
const model = defineModel<ProviderRequestProfiles>({ required: true })
|
|
const provider = shallowRef<(typeof PROVIDER_IDS)[number]>('openai')
|
|
const providerOptions = PROVIDER_IDS.map(value => ({
|
|
value,
|
|
label: formatProviderLabel(value),
|
|
icon: providerIcon(value),
|
|
}))
|
|
const providerSelectorStyle = { width: `${providerOptions.length * 40}px` }
|
|
const openai = profileModel<ClientProfileSelection>('openai')
|
|
const xai = profileModel<XaiClientProfileSelection>('xai')
|
|
|
|
function profileModel<T extends object>(providerId: string) {
|
|
return computed<T | null>({
|
|
get: () => (model.value[providerId] as T | undefined) ?? null,
|
|
set: value => updateProfile(providerId, value as ProviderRequestProfile | null),
|
|
})
|
|
}
|
|
|
|
function updateProfile(providerId: string, value: ProviderRequestProfile | null) {
|
|
const profiles = { ...model.value }
|
|
if (value === null)
|
|
delete profiles[providerId]
|
|
else
|
|
profiles[providerId] = value
|
|
model.value = profiles
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="grid min-w-0 gap-4">
|
|
<div v-if="!allowInherit" class="flex flex-wrap items-start justify-between gap-3">
|
|
<slot name="heading" />
|
|
<ZSegmented
|
|
v-model="provider"
|
|
class="ml-auto max-w-full shrink-0"
|
|
:aria-label="t('settings.clientProfile.clientIdentityProvider')"
|
|
:options="providerOptions"
|
|
:disabled="disabled"
|
|
:style="providerSelectorStyle"
|
|
display="icon"
|
|
/>
|
|
</div>
|
|
<ClientProfileEditor
|
|
v-if="provider === 'openai'"
|
|
v-model="openai"
|
|
:allow-inherit="allowInherit"
|
|
:active="active"
|
|
:disabled="disabled"
|
|
>
|
|
<template #source-extra>
|
|
<ZSegmented
|
|
v-model="provider"
|
|
class="max-w-full shrink-0"
|
|
:aria-label="t('settings.clientProfile.upstreamIdentityPlatform')"
|
|
:options="providerOptions"
|
|
:disabled="disabled"
|
|
:style="providerSelectorStyle"
|
|
display="icon"
|
|
/>
|
|
</template>
|
|
</ClientProfileEditor>
|
|
<XaiClientProfileEditor
|
|
v-else
|
|
v-model="xai"
|
|
:allow-inherit="allowInherit"
|
|
:active="active"
|
|
:disabled="disabled"
|
|
>
|
|
<template #source-extra>
|
|
<ZSegmented
|
|
v-model="provider"
|
|
class="max-w-full shrink-0"
|
|
:aria-label="t('settings.clientProfile.upstreamIdentityPlatform')"
|
|
:options="providerOptions"
|
|
:disabled="disabled"
|
|
:style="providerSelectorStyle"
|
|
display="icon"
|
|
/>
|
|
</template>
|
|
</XaiClientProfileEditor>
|
|
</div>
|
|
</template>
|