feat: localize custom provider name and ollama placeholder (#75)
This commit is contained in:
committed by
GitHub
Unverified
parent
9844d3de95
commit
e8915831dc
@@ -328,7 +328,7 @@ function ProviderCard({
|
||||
<div className="relative flex-1">
|
||||
<Input
|
||||
type={showKey ? 'text' : 'password'}
|
||||
placeholder={typeInfo?.requiresApiKey ? typeInfo?.placeholder : t('aiProviders.card.editKey')}
|
||||
placeholder={typeInfo?.requiresApiKey ? typeInfo?.placeholder : (typeInfo?.id === 'ollama' ? t('aiProviders.notRequired') : t('aiProviders.card.editKey'))}
|
||||
value={newKey}
|
||||
onChange={(e) => setNewKey(e.target.value)}
|
||||
className="pr-10 h-9 text-sm"
|
||||
@@ -482,7 +482,7 @@ function AddProviderDialog({ existingTypes, onClose, onAdd, onValidateKey }: Add
|
||||
|
||||
await onAdd(
|
||||
selectedType,
|
||||
name || typeInfo?.name || selectedType,
|
||||
name || (typeInfo?.id === 'custom' ? t('aiProviders.custom') : typeInfo?.name) || selectedType,
|
||||
apiKey.trim(),
|
||||
{
|
||||
baseUrl: baseUrl.trim() || undefined,
|
||||
@@ -513,7 +513,7 @@ function AddProviderDialog({ existingTypes, onClose, onAdd, onValidateKey }: Add
|
||||
key={type.id}
|
||||
onClick={() => {
|
||||
setSelectedType(type.id);
|
||||
setName(type.name);
|
||||
setName(type.id === 'custom' ? t('aiProviders.custom') : type.name);
|
||||
setBaseUrl(type.defaultBaseUrl || '');
|
||||
setModelId(type.defaultModelId || '');
|
||||
}}
|
||||
@@ -524,7 +524,7 @@ function AddProviderDialog({ existingTypes, onClose, onAdd, onValidateKey }: Add
|
||||
) : (
|
||||
<span className="text-2xl">{type.icon}</span>
|
||||
)}
|
||||
<p className="font-medium mt-2">{type.name}</p>
|
||||
<p className="font-medium mt-2">{type.id === 'custom' ? t('aiProviders.custom') : type.name}</p>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -537,7 +537,7 @@ function AddProviderDialog({ existingTypes, onClose, onAdd, onValidateKey }: Add
|
||||
<span className="text-2xl">{typeInfo?.icon}</span>
|
||||
)}
|
||||
<div>
|
||||
<p className="font-medium">{typeInfo?.name}</p>
|
||||
<p className="font-medium">{typeInfo?.id === 'custom' ? t('aiProviders.custom') : typeInfo?.name}</p>
|
||||
<button
|
||||
onClick={() => {
|
||||
setSelectedType(null);
|
||||
@@ -556,7 +556,7 @@ function AddProviderDialog({ existingTypes, onClose, onAdd, onValidateKey }: Add
|
||||
<Label htmlFor="name">{t('aiProviders.dialog.displayName')}</Label>
|
||||
<Input
|
||||
id="name"
|
||||
placeholder={typeInfo?.name}
|
||||
placeholder={typeInfo?.id === 'custom' ? t('aiProviders.custom') : typeInfo?.name}
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
/>
|
||||
@@ -568,7 +568,7 @@ function AddProviderDialog({ existingTypes, onClose, onAdd, onValidateKey }: Add
|
||||
<Input
|
||||
id="apiKey"
|
||||
type={showKey ? 'text' : 'password'}
|
||||
placeholder={typeInfo?.placeholder}
|
||||
placeholder={typeInfo?.id === 'ollama' ? t('aiProviders.notRequired') : typeInfo?.placeholder}
|
||||
value={apiKey}
|
||||
onChange={(e) => {
|
||||
setApiKey(e.target.value);
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
"title": "AI Providers",
|
||||
"description": "Configure your AI model providers and API keys",
|
||||
"add": "Add Provider",
|
||||
"custom": "Custom",
|
||||
"notRequired": "Not required",
|
||||
"empty": {
|
||||
"title": "No providers configured",
|
||||
"desc": "Add an AI provider to start using ClawX",
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
"title": "AI プロバイダー",
|
||||
"description": "AI モデルプロバイダーと API キーを設定",
|
||||
"add": "プロバイダーを追加",
|
||||
"custom": "カスタム",
|
||||
"notRequired": "不要",
|
||||
"empty": {
|
||||
"title": "プロバイダーが構成されていません",
|
||||
"desc": "ClawX の使用を開始するには AI プロバイダーを追加してください",
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
"title": "AI 模型提供商",
|
||||
"description": "配置 AI 模型提供商和 API 密钥",
|
||||
"add": "添加提供商",
|
||||
"custom": "自定义",
|
||||
"notRequired": "非必填",
|
||||
"empty": {
|
||||
"title": "未配置提供商",
|
||||
"desc": "添加 AI 提供商以开始使用 ClawX",
|
||||
|
||||
@@ -682,7 +682,7 @@ function ProviderContent({
|
||||
onApiKeyChange,
|
||||
onConfiguredChange,
|
||||
}: ProviderContentProps) {
|
||||
const { t } = useTranslation('setup');
|
||||
const { t } = useTranslation(['setup', 'settings']);
|
||||
const [showKey, setShowKey] = useState(false);
|
||||
const [validating, setValidating] = useState(false);
|
||||
const [keyValid, setKeyValid] = useState<boolean | null>(null);
|
||||
@@ -841,7 +841,7 @@ function ProviderContent({
|
||||
'provider:save',
|
||||
{
|
||||
id: providerIdForSave,
|
||||
name: selectedProviderData?.name || selectedProvider,
|
||||
name: selectedProvider === 'custom' ? t('settings:aiProviders.custom') : (selectedProviderData?.name || selectedProvider),
|
||||
type: selectedProvider,
|
||||
baseUrl: baseUrl.trim() || undefined,
|
||||
model: effectiveModelId,
|
||||
@@ -925,7 +925,7 @@ function ProviderContent({
|
||||
)}
|
||||
<span className={cn('truncate text-left', !selectedProvider && 'text-muted-foreground')}>
|
||||
{selectedProviderData
|
||||
? `${selectedProviderData.name}${selectedProviderData.model ? ` — ${selectedProviderData.model}` : ''}`
|
||||
? `${selectedProviderData.id === 'custom' ? t('settings:aiProviders.custom') : selectedProviderData.name}${selectedProviderData.model ? ` — ${selectedProviderData.model}` : ''}`
|
||||
: t('provider.selectPlaceholder')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -964,7 +964,7 @@ function ProviderContent({
|
||||
) : (
|
||||
<span className="text-sm leading-none shrink-0">{p.icon}</span>
|
||||
)}
|
||||
<span className="truncate">{p.name}{p.model ? ` — ${p.model}` : ''}</span>
|
||||
<span className="truncate">{p.id === 'custom' ? t('settings:aiProviders.custom') : p.name}{p.model ? ` — ${p.model}` : ''}</span>
|
||||
</div>
|
||||
{isSelected && <Check className="h-4 w-4 text-primary shrink-0" />}
|
||||
</button>
|
||||
@@ -1527,7 +1527,7 @@ interface CompleteContentProps {
|
||||
}
|
||||
|
||||
function CompleteContent({ selectedProvider, installedSkills }: CompleteContentProps) {
|
||||
const { t } = useTranslation('setup');
|
||||
const { t } = useTranslation(['setup', 'settings']);
|
||||
const gatewayStatus = useGatewayStore((state) => state.status);
|
||||
|
||||
const providerData = providers.find((p) => p.id === selectedProvider);
|
||||
@@ -1548,7 +1548,7 @@ function CompleteContent({ selectedProvider, installedSkills }: CompleteContentP
|
||||
<div className="flex items-center justify-between p-3 rounded-lg bg-muted/50">
|
||||
<span>{t('complete.provider')}</span>
|
||||
<span className="text-green-400">
|
||||
{providerData ? <span className="flex items-center gap-1.5">{getProviderIconUrl(providerData.id) ? <img src={getProviderIconUrl(providerData.id)} alt={providerData.name} className={`h-4 w-4 inline-block ${shouldInvertInDark(providerData.id) ? 'dark:invert' : ''}`} /> : providerData.icon} {providerData.name}</span> : '—'}
|
||||
{providerData ? <span className="flex items-center gap-1.5">{getProviderIconUrl(providerData.id) ? <img src={getProviderIconUrl(providerData.id)} alt={providerData.name} className={`h-4 w-4 inline-block ${shouldInvertInDark(providerData.id) ? 'dark:invert' : ''}`} /> : providerData.icon} {providerData.id === 'custom' ? t('settings:aiProviders.custom') : providerData.name}</span> : '—'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between p-3 rounded-lg bg-muted/50">
|
||||
|
||||
Reference in New Issue
Block a user