diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-18 12:03:32 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-18 12:03:32 +0800 |
| commit | 61f5c545953bb4ee20b123bf9671ac35d7f1f3c1 (patch) | |
| tree | 9ede3483db5f7e0d81189f2d29514892b8f77867 /frontend/src/components/ProjectMetricRow.svelte | |
| parent | 1f16a357213611a6d7f84e506064fc0d9c6317c6 (diff) | |
| download | strategy-lab-61f5c545953bb4ee20b123bf9671ac35d7f1f3c1.tar.gz | |
[变更性质] feat(frontend)
[新增功能] round3 页面组件全量迁移 shadcn-svelte(12 页面 + Modal/DatasetWizard/DatasetCard/Status)
[实现方案] .btn→Button、.banner→Alert、table.data→Table.Root、.badge→Badge、.tabs→Tabs.Root、.metric-card/form.card→Card.Root;ProjectStrategyTab div 配对修复
[影响范围] src/pages/*.svelte、src/components/*.svelte
Diffstat (limited to 'frontend/src/components/ProjectMetricRow.svelte')
| -rw-r--r-- | frontend/src/components/ProjectMetricRow.svelte | 83 |
1 files changed, 35 insertions, 48 deletions
diff --git a/frontend/src/components/ProjectMetricRow.svelte b/frontend/src/components/ProjectMetricRow.svelte index 7980622..6dd3f0e 100644 --- a/frontend/src/components/ProjectMetricRow.svelte +++ b/frontend/src/components/ProjectMetricRow.svelte @@ -1,7 +1,8 @@ <script lang="ts"> - // 首页指标卡行(leader round2 spec §1) + // 首页指标卡行(round2 spec §1;round3 迁移 shadcn-svelte Card) // 数据通过 props 注入(ProjectsPage 拉取并共享聚合输入,见 dashboardMetrics.ts)。 import { aggregateDashboard } from '../lib/dashboardMetrics'; + import * as Card from '$lib/components/ui/card'; interface Props { /** 注入的聚合输入;null/undefined 视为"取不到"(占位 -) */ @@ -15,33 +16,34 @@ const metric = $derived(aggregateDashboard({ projects, datasets, runs, usage })); </script> -<div class="metric-row" role="list" aria-label="工作台概览"> - <div class="metric-card" data-testid="metric-card" role="listitem"> - <span class="mlabel">我的项目</span> - <span class="mvalue">{metric.projectCount}</span> + <div class="metric-row" role="list" aria-label="工作台概览"> + <Card.Root class="metric-r3" size="sm" data-testid="metric-card" role="listitem"> + <span class="mlabel">我的项目</span> + <span class="mvalue">{metric.projectCount}</span> + </Card.Root> + <Card.Root class="metric-r3" size="sm" data-testid="metric-card" role="listitem"> + <span class="mlabel">数据集</span> + <span class="mvalue">{metric.datasetCount}</span> + </Card.Root> + <Card.Root class="metric-r3" size="sm" data-testid="metric-card" role="listitem"> + <span class="mlabel">回测</span> + <span class="mvalue"> + <span class="run-split"><i>运行中</i> {metric.runningRuns}</span> + <span class="run-split"><i>已完成</i> {metric.doneRuns}</span> + </span> + </Card.Root> + <Card.Root + class="metric-r3" + size="sm" + data-testid="metric-card" + role="listitem" + data-todo={metric.usageLabel === '-' ? 'TODO: /api/ai/usage 未返回 totals.requests(使用记录为空)时保持占位 -' : undefined} + > + <span class="mlabel">AI 用量</span> + <span class="mvalue">{metric.usageLabel}</span> + {#if metric.usageTokens}<span class="mvalue-sub">{metric.usageTokens}</span>{/if} + </Card.Root> </div> - <div class="metric-card" data-testid="metric-card" role="listitem"> - <span class="mlabel">数据集</span> - <span class="mvalue">{metric.datasetCount}</span> - </div> - <div class="metric-card" data-testid="metric-card" role="listitem"> - <span class="mlabel">回测</span> - <span class="mvalue"> - <span class="run-split"><i>运行中</i> {metric.runningRuns}</span> - <span class="run-split"><i>已完成</i> {metric.doneRuns}</span> - </span> - </div> - <div - class="metric-card" - data-testid="metric-card" - role="listitem" - data-todo={metric.usageLabel === '-' ? 'TODO: /api/ai/usage 未返回 totals.requests(使用记录为空)时保持占位 -' : undefined} - > - <span class="mlabel">AI 用量</span> - <span class="mvalue">{metric.usageLabel}</span> - {#if metric.usageTokens}<span class="mvalue-sub">{metric.usageTokens}</span>{/if} - </div> -</div> <style> .metric-row { @@ -50,26 +52,12 @@ gap: 0.6rem; margin-bottom: 1.1rem; } - .metric-card { - background: var(--surface); - border: 1px solid var(--border); - border-radius: calc(var(--radius) * 1.4); - padding: 0.65rem 0.85rem; - display: flex; - flex-direction: column; - gap: 0.1rem; + .metric-row :global(.metric-r3) { + gap: 0.12rem; min-width: 0; - transition: box-shadow 150ms ease, transform 150ms ease; } - /* 桌面端 hover 轻微上浮阴影 */ - @media (hover: hover) and (min-width: 768px) { - .metric-card:hover { - box-shadow: var(--shadow); - transform: translateY(-1px); - } - } - .metric-card .mvalue { - font-size: 1.35rem; + .metric-row :global(.metric-r3 .mvalue) { + font-size: 1.5rem; font-weight: 700; letter-spacing: -0.01em; color: var(--foreground); @@ -77,7 +65,6 @@ line-height: 1.2; overflow-wrap: anywhere; } - .run-split { display: inline-flex; align-items: baseline; gap: 0.3rem; } - .run-split i { font-style: normal; font-size: 0.68rem; color: var(--text-3); font-weight: 500; } - .mvalue-sub { font-size: 0.72rem; color: var(--text-3); } + + .mvalue-sub { color: var(--text-3); } </style> |
