feat(ui): 自研 Celadon 组件族入库与 AntD 消费全量替换 - base(Kbd/StatusBadge/IconButton/ToolButton)+product(EmptyState/Callout/SegmentedControl/Checkbox/Select/Tooltip/Switch), composio 视觉基底, globals.css 覆盖清理 (ADR-0008)
This commit is contained in:
1 parent
30f58aaa08
commit
5c6612c5dd
128 files changed
+2791
-737
No files matched your search
@@ -1,4 +1,6 @@
|
||||
import { App, Button, Form, Input, Popconfirm, Segmented, Select, Switch } from "antd";
|
||||
import { App, Button, Form, Input, Popconfirm, Select } from "antd";
|
||||
import { Switch } from "@/components/ui/base/switch";
|
||||
import { SegmentedControl } from "@/components/ui/base/segmented-control";
|
||||
import { Copy, Download, Plus, RefreshCw, Trash2 } from "lucide-react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -237,8 +239,8 @@ export function ComfyUIBridgeSettingsPane() {
|
||||
<h4 className="text-sm font-semibold">安装 Bridge</h4>
|
||||
<p className="mt-1 text-xs text-foreground/60">在能访问 ComfyUI 的机器上运行;Windows 使用独立程序,Linux 使用对应架构的原生程序,不需要安装 Node.js、npm 或项目源码。</p>
|
||||
</div>
|
||||
<Segmented
|
||||
size="small"
|
||||
<SegmentedControl
|
||||
size="sm"
|
||||
value={bridgePlatform}
|
||||
options={[
|
||||
{ label: "Windows", value: "windows" },
|
||||
@@ -250,8 +252,8 @@ export function ComfyUIBridgeSettingsPane() {
|
||||
{bridgePlatform === "linux" ? (
|
||||
<div className="mt-3 flex flex-wrap items-center gap-2 text-xs text-foreground/65">
|
||||
<span>Linux 架构:</span>
|
||||
<Segmented
|
||||
size="small"
|
||||
<SegmentedControl
|
||||
size="sm"
|
||||
value={linuxArchitecture}
|
||||
options={[
|
||||
{ label: "x64", value: "amd64" },
|
||||
@@ -370,7 +372,7 @@ export function ComfyUIBridgeSettingsPane() {
|
||||
<Input value={config.workflowId} placeholder="workflow.json" onChange={(event) => update({ workflowId: event.target.value })} onBlur={(event) => selectWorkflow(event.target.value.trim())} />
|
||||
</Form.Item>
|
||||
<div className="workflow-workspace-tabs lg:col-span-12">
|
||||
<Segmented
|
||||
<SegmentedControl
|
||||
block
|
||||
value={workspaceMode}
|
||||
options={[
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { App, Button, Input, Select } from "antd";
|
||||
import { App, Button, Input } from "antd";
|
||||
import { Select } from "@/components/ui/base/select";
|
||||
import { Activity, CheckCircle2, Clock3, Download, FileText, ShieldCheck } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
@@ -12,7 +13,7 @@ type DiagnosticsPanelProps = {
|
||||
|
||||
type DiagnosticRange = "15m" | "30m" | "1h" | "24h";
|
||||
|
||||
const rangeOptions = [
|
||||
const rangeOptions: { value: DiagnosticRange; label: string }[] = [
|
||||
{ value: "15m", label: "最近 15 分钟" },
|
||||
{ value: "30m", label: "最近 30 分钟" },
|
||||
{ value: "1h", label: "最近 1 小时" },
|
||||
@@ -98,9 +99,9 @@ export default function DiagnosticsPanel({ taskId, projectId }: DiagnosticsPanel
|
||||
<span className="rounded-full bg-foreground/[.045] px-2.5 py-1 text-[var(--fs-tiny)] font-medium text-foreground/48">最长 24 小时</span>
|
||||
</div>
|
||||
<div className="mt-4 grid gap-4 md:grid-cols-[minmax(0,230px)_minmax(0,1fr)] md:items-end">
|
||||
<label className="block" htmlFor="diagnostic-range">
|
||||
<label className="block">
|
||||
<span className="mb-2 block text-xs font-semibold text-foreground/65">时间范围</span>
|
||||
<Select id="diagnostic-range" className="w-full" value={range} options={rangeOptions} onChange={setRange} />
|
||||
<Select ariaLabel="时间范围" className="w-full" value={range} options={rangeOptions} onChange={(value) => { const next = rangeOptions.find((option) => option.value === value)?.value; if (next) setRange(next); }} />
|
||||
</label>
|
||||
<div className="rounded-lg border border-border/55 bg-foreground/[.025] px-3.5 py-3" aria-live="polite">
|
||||
<div className="flex items-center gap-2 text-sm font-medium text-foreground/78">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { App, Button, Form, Input, InputNumber, Select } from "antd";
|
||||
import { App, Button, Form, Input, InputNumber } from "antd";
|
||||
import { Select } from "@/components/ui/base/select";
|
||||
import { ArrowLeft, Boxes, Bug, Cloud, MessageSquareText, MonitorUp, RadioTower, SlidersHorizontal, SquareTerminal, Workflow } from "lucide-react";
|
||||
import { useEffect, useMemo, useState, type ReactNode } from "react";
|
||||
import { useNavigate, useSearchParams } from "react-router";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { App, Button, Popconfirm, Tag, Typography } from "antd";
|
||||
import { StatusBadge } from "@/components/ui/base/badges";
|
||||
import { CheckCircle2, Copy, ExternalLink, LogIn, LogOut, RefreshCw, Server, SquareTerminal } from "lucide-react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
|
||||
@@ -172,9 +173,7 @@ export function LocalCliSettings() {
|
||||
<h2 id="local-runtime-title" className="text-base font-semibold">
|
||||
{LOCAL_CLI_SETTINGS_COPY.runtimeTitle}
|
||||
</h2>
|
||||
<Tag color={presentation.runtime.tone} className="m-0">
|
||||
{presentation.runtime.label}
|
||||
</Tag>
|
||||
<StatusBadge variant="filled" className="m-0" tone={presentation.runtime.tone === "processing" ? "loading" : presentation.runtime.tone === "default" ? "neutral" : presentation.runtime.tone} label={presentation.runtime.label} />
|
||||
<p className="min-w-0 text-sm text-foreground/60">{connection === "connected" ? LOCAL_CLI_SETTINGS_COPY.runtimeConnected : runtimeError || LOCAL_CLI_SETTINGS_COPY.runtimeDetecting}</p>
|
||||
<p className="basis-full text-xs leading-5 text-foreground/55">{LOCAL_CLI_SETTINGS_COPY.runtimeSafety}</p>
|
||||
</div>
|
||||
@@ -195,9 +194,7 @@ export function LocalCliSettings() {
|
||||
<h2 id="dreamina-cli-title" className="text-base font-semibold">
|
||||
Dreamina CLI
|
||||
</h2>
|
||||
<Tag color={presentation.dreamina.tone} className="m-0">
|
||||
{presentation.dreamina.label}
|
||||
</Tag>
|
||||
<StatusBadge variant="filled" className="m-0" tone={presentation.dreamina.tone === "processing" ? "loading" : presentation.dreamina.tone === "default" ? "neutral" : presentation.dreamina.tone} label={presentation.dreamina.label} />
|
||||
{status?.version ? <Tag className="m-0">v{status.version}</Tag> : null}
|
||||
{presentation.dreamina.creditLabel ? (
|
||||
<Tag color="blue" className="m-0">
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { Alert, App, Button, Input, Segmented, Select, Skeleton, Tabs, Tag } from "antd";
|
||||
import { App, Button, Input, Skeleton, Tabs } from "antd";
|
||||
import { Select } from "@/components/ui/base/select";
|
||||
import { SegmentedControl } from "@/components/ui/base/segmented-control";
|
||||
import { StatusBadge } from "@/components/ui/base/badges";
|
||||
import { Callout } from "@/components/ui/product/callout";
|
||||
import { RotateCcw, Save, ShieldCheck, Undo2 } from "lucide-react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
@@ -136,7 +140,7 @@ export function PromptPreferencesPane() {
|
||||
if (loadError && preferences.length === 0) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center gap-3 py-16">
|
||||
<Alert type="error" showIcon message="加载提示词偏好失败" description={loadError} />
|
||||
<Callout tone="error" title="加载提示词偏好失败">{loadError}</Callout>
|
||||
<Button icon={<RotateCcw className="size-4" />} onClick={() => void reload()}>重试</Button>
|
||||
</div>
|
||||
);
|
||||
@@ -152,9 +156,9 @@ export function PromptPreferencesPane() {
|
||||
<header className="shrink-0 pb-4">
|
||||
<div className="flex flex-wrap items-end justify-between gap-4">
|
||||
<div className="min-w-0 flex-1">
|
||||
<label className="mb-2 block text-xs font-medium text-foreground/55" htmlFor="prompt-template-select">提示词模板</label>
|
||||
<label className="mb-2 block text-xs font-medium text-foreground/55">提示词模板</label>
|
||||
<Select
|
||||
id="prompt-template-select"
|
||||
ariaLabel="提示词模板"
|
||||
className="w-full max-w-md"
|
||||
value={selectedOperation}
|
||||
onChange={selectOperation}
|
||||
@@ -175,17 +179,17 @@ export function PromptPreferencesPane() {
|
||||
<div className="min-w-0">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<h2 className="text-base font-semibold">{selected.definition.label}</h2>
|
||||
<Tag variant="filled">平台 v{selected.template?.version || "--"}</Tag>
|
||||
<Tag variant="filled">{outputLabel}</Tag>
|
||||
{dirty ? <Tag variant="filled" color="warning">未保存</Tag> : null}
|
||||
<StatusBadge variant="filled" tone="neutral" label={`平台 v${selected.template?.version || "--"}`} />
|
||||
<StatusBadge variant="filled" tone="neutral" label={outputLabel} />
|
||||
{dirty ? <StatusBadge variant="filled" tone="warning" label="未保存" /> : null}
|
||||
</div>
|
||||
<p className="mt-1 text-xs leading-5 text-foreground/55">{selected.definition.description}</p>
|
||||
</div>
|
||||
<Segmented value={mode} options={modeOptions} onChange={(value) => setMode(value as CustomizationMode)} />
|
||||
<SegmentedControl value={mode} options={modeOptions} onChange={(value) => setMode(value as CustomizationMode)} />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{selected.outdated ? <Alert className="mt-4" type="warning" showIcon title="平台模板已更新" description="当前高级改写基于旧版本。可以保留现有改写,或恢复平台后再基于新版本调整。" /> : null}
|
||||
{selected.outdated ? <Callout className="mt-4" tone="warning" title="平台模板已更新">当前高级改写基于旧版本。可以保留现有改写,或恢复平台后再基于新版本调整。</Callout> : null}
|
||||
|
||||
<div className="grid min-h-0 flex-1 gap-4 pt-4 lg:grid-cols-3">
|
||||
<section className="flex min-h-0 flex-col lg:col-span-2">
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { App, AutoComplete, Button, Form, Input, Popconfirm, Select, Segmented, Switch } from "antd";
|
||||
import { App, AutoComplete, Button, Form, Input, Popconfirm } from "antd";
|
||||
import { Switch } from "@/components/ui/base/switch";
|
||||
import { Select } from "@/components/ui/base/select";
|
||||
import { SegmentedControl } from "@/components/ui/base/segmented-control";
|
||||
import { RefreshCw, Trash2 } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
@@ -258,7 +261,7 @@ export function RunningHubSettingsPane() {
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="类型" className="mb-0 lg:col-span-3">
|
||||
<Segmented
|
||||
<SegmentedControl
|
||||
block
|
||||
value={kind}
|
||||
options={[
|
||||
@@ -293,7 +296,7 @@ export function RunningHubSettingsPane() {
|
||||
</div>
|
||||
</Form.Item>
|
||||
<div className="workflow-workspace-tabs lg:col-span-12">
|
||||
<Segmented
|
||||
<SegmentedControl
|
||||
block
|
||||
value={workspaceMode}
|
||||
options={[
|
||||
|
||||
Reference in new issue
Block a user