feat: 增加对非数组值的处理,优化数组、文件和标签渲染器

This commit is contained in:
catlog22
2026-02-07 22:26:11 +08:00
parent ece02ab32a
commit dc9a1a1efb
4 changed files with 42 additions and 19 deletions

View File

@@ -58,6 +58,10 @@ function StringRenderer({ value, className }: { value: string; className?: strin
}
function ArrayRenderer({ value, className }: { value: unknown[]; className?: string }) {
if (!Array.isArray(value)) {
return <FieldRenderer value={value} type="auto" className={className} />;
}
if (value.length === 0) {
return <span className="text-muted-foreground italic">Empty</span>;
}
@@ -98,6 +102,10 @@ function ObjectRenderer({ value, className }: { value: Record<string, unknown>;
}
function FilesRenderer({ value, className }: { value: Array<{ path: string }>; className?: string }) {
if (!Array.isArray(value)) {
return <FieldRenderer value={value} type="auto" className={className} />;
}
if (value.length === 0) {
return <span className="text-muted-foreground italic">No files</span>;
}
@@ -118,6 +126,10 @@ function FilesRenderer({ value, className }: { value: Array<{ path: string }>; c
}
function TagsRenderer({ value, className }: { value: string[]; className?: string }) {
if (!Array.isArray(value)) {
return <FieldRenderer value={value} type="auto" className={className} />;
}
if (value.length === 0) {
return <span className="text-muted-foreground italic">No tags</span>;
}

View File

@@ -10,7 +10,7 @@ import {
RefreshCw,
} from 'lucide-react';
import { Button } from '@/components/ui/Button';
import { TabsNavigation, type TabItem } from '@/components/ui/TabsNavigation';
import { TabsNavigation } from '@/components/ui/TabsNavigation';
import {
ProviderList,
ProviderModal,
@@ -25,7 +25,7 @@ import {
ManageModelsModal,
} from '@/components/api-settings';
import { ConfigSync } from '@/components/shared';
import { useProviders, useEndpoints, useModelPools, useCliSettings } from '@/hooks/useApiSettings';
import { useProviders, useEndpoints, useModelPools, useCliSettings, useSyncApiConfig } from '@/hooks/useApiSettings';
import { useNotifications } from '@/hooks/useNotifications';
// Tab type definitions
@@ -35,6 +35,7 @@ export function ApiSettingsPage() {
const { formatMessage } = useIntl();
const { success, error } = useNotifications();
const [activeTab, setActiveTab] = useState<TabType>('providers');
const syncMutation = useSyncApiConfig();
// Get providers, endpoints, model pools, and CLI settings data
const { providers } = useProviders();
@@ -170,10 +171,19 @@ export function ApiSettingsPage() {
// Sync to CodexLens handler
const handleSyncToCodexLens = async (providerId: string) => {
const providerName = providers.find((p) => p.id === providerId)?.name ?? providerId;
try {
// TODO: Implement actual sync API call
// For now, just show a success message
success(formatMessage({ id: 'apiSettings.messages.configSynced' }));
const result = await syncMutation.mutateAsync();
const messageParts = [
providerName,
result.yamlPath ?? result.message,
].filter(Boolean);
success(
formatMessage({ id: 'apiSettings.messages.configSynced' }),
messageParts.length > 0 ? messageParts.join('\n') : undefined
);
} catch (err) {
error(formatMessage({ id: 'apiSettings.providers.saveError' }));
}

View File

@@ -25,6 +25,7 @@ import {
Package,
Home,
Folder,
FolderOpen,
Calendar,
File,
ArrowUpCircle,
@@ -36,6 +37,7 @@ import { Input } from '@/components/ui/Input';
import { Badge } from '@/components/ui/Badge';
import { ThemeSelector } from '@/components/shared/ThemeSelector';
import { useTheme } from '@/hooks';
import { toast } from 'sonner';
import { useConfigStore, selectCliTools, selectDefaultCliTool, selectUserPreferences } from '@/stores/configStore';
import type { CliToolConfig, UserPreferences } from '@/types/store';
import { cn } from '@/lib/utils';
@@ -60,9 +62,6 @@ import {
const ENV_FILE_TOOLS = new Set(['gemini', 'qwen', 'opencode']);
/** Tools that use --settings for Claude CLI settings file */
const SETTINGS_FILE_TOOLS = new Set(['claude']);
/** Tools that don't need any config file */
const NO_CONFIG_FILE_TOOLS = new Set(['codex']);
function getConfigFileType(toolId: string): 'envFile' | 'settingsFile' | 'none' {
if (ENV_FILE_TOOLS.has(toolId)) return 'envFile';
if (SETTINGS_FILE_TOOLS.has(toolId)) return 'settingsFile';
@@ -874,18 +873,13 @@ export function SettingsPage() {
throw new Error(`HTTP ${res.status}`);
}
// Show success notification via a brief visual indicator
const toast = document.createElement('div');
toast.className = 'fixed bottom-4 right-4 z-50 bg-green-600 text-white px-4 py-2 rounded-lg shadow-lg text-sm animate-in fade-in slide-in-from-bottom-2';
toast.textContent = formatMessage({ id: 'settings.cliTools.configSaved' });
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 3000);
toast.success(formatMessage({ id: 'settings.cliTools.configSaved' }), {
description: toolId,
});
} catch {
const toast = document.createElement('div');
toast.className = 'fixed bottom-4 right-4 z-50 bg-red-600 text-white px-4 py-2 rounded-lg shadow-lg text-sm animate-in fade-in slide-in-from-bottom-2';
toast.textContent = formatMessage({ id: 'settings.cliTools.configSaveError' });
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 4000);
toast.error(formatMessage({ id: 'settings.cliTools.configSaveError' }), {
description: toolId,
});
} finally {
setSavingTools((prev) => {
const next = new Set(prev);

View File

@@ -43,6 +43,13 @@ const defaultCliTools: Record<string, CliToolConfig> = {
tags: [],
type: 'builtin',
},
opencode: {
enabled: true,
primaryModel: 'opencode/glm-4.7-free',
secondaryModel: 'opencode/glm-4.7-free',
tags: [],
type: 'builtin',
},
};
// Default API endpoints