mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-10 02:24:35 +08:00
feat: 增加对非数组值的处理,优化数组、文件和标签渲染器
This commit is contained in:
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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' }));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user