From 4f4facae54d76883f02f6be14645e4f2a264d92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=90=E7=BB=B4=E5=B7=A5=E7=A8=8B=E5=B8=88?= Date: Sun, 12 Jul 2026 20:40:17 +0800 Subject: [PATCH 1/2] =?UTF-8?q?[WS-90]=20frontend:=20Workflow=20Desk=20red?= =?UTF-8?q?esign=20=E2=80=94=20tokens,=20rail,=20model-only=20selector,=20?= =?UTF-8?q?graph=20stages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements the Workflow Desk redesign per ui-designer/ui-spec.md and ui-designer/design/implementation-plan.md (frontend-only; no backend or OpenAPI contract changes). - Tokens + typography: remap globals.css :root + tailwind.config.js to the Workflow Desk palette (ink #0a0d12, surface #171f2b, line #304154, mint #9bffbe action, sky-blue #8acbff flow) and add Instrument Serif / DM Mono / Noto Sans SC fonts. Mint/blue accent buttons now use dark ink text for correct contrast across all routes. - Shell: rebuild AppNavbar as a fixed desktop research rail (248px) + slim top status bar + mobile drawer; reserve rail space via desktop body padding. Admin-only gating preserved (AppNavbar.test.tsx passes). - Privacy boundary (WS-13/story-001): new ModelSelector exposes model display names only — never provider, endpoint, key state, or system-default provenance. AnalysisConfigForm step 5 now drives selection through it and drops the provider dropdown, provenance bars and inline API-key input; provider/backend_url/key are still resolved silently for the payload. ModelSelector.test.tsx proves model-name-only exposure + no-model recovery. - Graph fidelity: new lib/workflow-stages.ts encodes the real GraphSetup 5-band / 12-node model; AnalysisProgress rebuilt to 5 bands (Analyst Team → Bull/Bear debate → Research Manager → Trader → Risky/Safe/Neutral → Risk Judge) with Risk Judge split into its own terminal band. workflow-stages .test.ts asserts graph fidelity. - State primitives: add EmptyState + ErrorState (PageLoading already existed). Verification (web/frontend): npm run typecheck ✓, npm run test:run 42/42 ✓, npm run build ✓ (18 routes prerendered). npm run lint: no new errors (3 pre-existing errors in untouched files; next.config ignores eslint during build). Co-Authored-By: Claude Co-authored-by: multica-agent --- .../src/app/admin/llm-config/page.tsx | 4 +- web/frontend/src/app/admin/users/page.tsx | 2 +- web/frontend/src/app/analysis/page.tsx | 2 +- web/frontend/src/app/globals.css | 49 +- web/frontend/src/app/history/detail/page.tsx | 2 +- web/frontend/src/app/layout.tsx | 14 +- .../src/app/profile/ai-settings/page.tsx | 2 +- web/frontend/src/app/profile/page.tsx | 4 +- web/frontend/src/app/scheduled-tasks/page.tsx | 2 +- .../components/admin/ResponsiveUserCard.tsx | 2 +- .../components/admin/llm-config/ModelForm.tsx | 2 +- .../admin/llm-config/ProviderForm.tsx | 2 +- .../SystemDefaultForm.tsx | 4 +- .../analysis/AnalysisConfigForm.tsx | 261 ++----- .../components/analysis/AnalysisHistory.tsx | 2 +- .../components/analysis/AnalysisProgress.tsx | 45 +- .../components/analysis/AnalysisResults.tsx | 2 +- .../analysis/ModelSelector.test.tsx | 108 +++ .../src/components/analysis/ModelSelector.tsx | 133 ++++ .../src/components/auth/LoginForm.tsx | 8 +- .../src/components/common/AppNavbar.tsx | 703 +++++++++--------- .../src/components/conversation/Composer.tsx | 2 +- .../components/conversation/LoginNudge.tsx | 2 +- .../components/conversation/MessageBubble.tsx | 4 +- .../conversation/SessionSidebar.tsx | 2 +- .../src/components/profile/AISettingsCard.tsx | 2 +- .../src/components/profile/LocalKeyField.tsx | 4 +- .../components/profile/ProviderFormDrawer.tsx | 2 +- web/frontend/src/components/ui/EmptyState.tsx | 33 + web/frontend/src/components/ui/ErrorState.tsx | 45 ++ web/frontend/src/lib/workflow-stages.test.ts | 66 ++ web/frontend/src/lib/workflow-stages.ts | 143 ++++ web/frontend/tailwind.config.js | 82 +- 33 files changed, 1080 insertions(+), 660 deletions(-) create mode 100644 web/frontend/src/components/analysis/ModelSelector.test.tsx create mode 100644 web/frontend/src/components/analysis/ModelSelector.tsx create mode 100644 web/frontend/src/components/ui/EmptyState.tsx create mode 100644 web/frontend/src/components/ui/ErrorState.tsx create mode 100644 web/frontend/src/lib/workflow-stages.test.ts create mode 100644 web/frontend/src/lib/workflow-stages.ts diff --git a/web/frontend/src/app/admin/llm-config/page.tsx b/web/frontend/src/app/admin/llm-config/page.tsx index 6d42a22..694402c 100644 --- a/web/frontend/src/app/admin/llm-config/page.tsx +++ b/web/frontend/src/app/admin/llm-config/page.tsx @@ -228,7 +228,7 @@ export default function LLMConfigPage() { setEditingProvider(null); setShowProviderForm(true); }} - className="px-4 py-2 bg-accent-primary text-white rounded-lg hover:bg-accent-secondary transition-colors" + className="px-4 py-2 bg-accent-primary text-dark-primary rounded-lg hover:bg-accent-secondary transition-colors" > 添加供应商 @@ -261,7 +261,7 @@ export default function LLMConfigPage() { setEditingModel(null); setShowModelForm(true); }} - className="px-4 py-2 bg-accent-primary text-white rounded-lg hover:bg-accent-secondary transition-colors" + className="px-4 py-2 bg-accent-primary text-dark-primary rounded-lg hover:bg-accent-secondary transition-colors" > 添加模型 diff --git a/web/frontend/src/app/admin/users/page.tsx b/web/frontend/src/app/admin/users/page.tsx index 788a8d1..1ce3af7 100644 --- a/web/frontend/src/app/admin/users/page.tsx +++ b/web/frontend/src/app/admin/users/page.tsx @@ -377,7 +377,7 @@ export default function UserManagementPage() {

加载失败

diff --git a/web/frontend/src/app/analysis/page.tsx b/web/frontend/src/app/analysis/page.tsx index 36a08c3..71bd70e 100644 --- a/web/frontend/src/app/analysis/page.tsx +++ b/web/frontend/src/app/analysis/page.tsx @@ -148,7 +148,7 @@ function AnalysisDetailContent() { {showBackToTop && (