diff options
Diffstat (limited to 'frontend/src/pages/ProjectsPage.svelte')
| -rw-r--r-- | frontend/src/pages/ProjectsPage.svelte | 77 |
1 files changed, 47 insertions, 30 deletions
diff --git a/frontend/src/pages/ProjectsPage.svelte b/frontend/src/pages/ProjectsPage.svelte index b29a856..13525b6 100644 --- a/frontend/src/pages/ProjectsPage.svelte +++ b/frontend/src/pages/ProjectsPage.svelte @@ -6,6 +6,12 @@ import { extractStatusMessage } from '../lib/state'; import { go } from '../lib/router'; import { fmtDateTime } from '../lib/format'; + import { Button } from '$lib/components/ui/button'; + import * as Card from '$lib/components/ui/card'; + import * as Table from '$lib/components/ui/table'; + import { Input } from '$lib/components/ui/input'; + import { Label } from '$lib/components/ui/label'; + import { Alert } from '$lib/components/ui/alert'; let busy = $state(false); let error = $state<string | null>(null); @@ -27,6 +33,13 @@ } } + // 159399 QA regression (2026-09-17): load() existed but was wired nowhere, + // so the projects page kept rendering the store's stale/empty state and + // users saw 还没有项目 despite existing projects on the server. + $effect(() => { + void load(); + }); + async function create(e: SubmitEvent) { e.preventDefault(); if (!newName.trim()) return; @@ -49,9 +62,9 @@ <Page title="我的项目" subtitle="每个项目持有独立的策略代码版本、数据集与回测记录"> {#snippet actions()} - <button class="btn primary" onclick={() => (showCreate = !showCreate)} aria-expanded={showCreate}> + <Button variant={showCreate ? 'outline' : 'default'} onclick={() => (showCreate = !showCreate)} aria-expanded={showCreate}> {showCreate ? '取消新建' : '新建项目'} - </button> + </Button> {/snippet} <div class="stack"> @@ -60,18 +73,18 @@ <form class="card stack" onsubmit={create}> <h2>新建项目</h2> <div> - <label for="pn">项目名称</label> - <input id="pn" bind:value={newName} required placeholder="例如:双均线ETF轮动" /> + <Label for="pn">项目名称</Label> + <Input id="pn" bind:value={newName} required placeholder="例如:双均线ETF轮动" class="mt-1" /> </div> <div> - <label for="pd">简介(可选)</label> - <input id="pd" bind:value={newDesc} placeholder="一句话说明研究思路" /> + <Label for="pd">简介(可选)</Label> + <Input id="pd" bind:value={newDesc} placeholder="一句话说明研究思路" class="mt-1" /> </div> - {#if createErr}<div class="banner error" role="alert">{createErr}</div>{/if} + {#if createErr}<Alert variant="destructive" class="banner error" role="alert">{createErr}</Alert>{/if} <div class="row"> - <button type="submit" class="btn primary" disabled={creating || !newName.trim()}> + <Button type="submit" disabled={creating || !newName.trim()}> {creating ? '创建中…' : '创建项目'} - </button> + </Button> </div> </form> {/if} @@ -81,32 +94,36 @@ {/if} {#if projectsStore.all.length > 0} - <div class="card" style="padding:0.4rem 0.6rem;"> - <table class="data"> - <thead> - <tr> - <th>名称</th> - <th>简介</th> - <th>版本代</th> - <th>最近更新</th> - </tr> - </thead> - <tbody> + <Card.Root size="sm"> + <Table.Root> + <Table.Header> + <Table.Row> + <Table.Head>名称</Table.Head> + <Table.Head>简介</Table.Head> + <Table.Head>版本代</Table.Head> + <Table.Head>最近更新</Table.Head> + </Table.Row> + </Table.Header> + <Table.Body> {#each projectsStore.all as p (p.id)} - <tr> - <td><a href={`#/projects/${p.id}/data`} class="p-name">{p.name}</a></td> - <td class="hint">{p.description ?? '—'}</td> - <td class="num">{p.draft_generation ?? '—'}</td> - <td>{fmtDateTime(p.updated_at)}</td> - </tr> + <Table.Row> + <Table.Cell> + <a href={`#/projects/${p.id}/data`} class="p-name">{p.name}</a> + </Table.Cell> + <Table.Cell class="hint">{p.description ?? '—'}</Table.Cell> + <Table.Cell class="num">{p.draft_generation ?? '—'}</Table.Cell> + <Table.Cell>{fmtDateTime(p.updated_at)}</Table.Cell> + </Table.Row> {/each} - </tbody> - </table> - </div> + </Table.Body> + </Table.Root> + </Card.Root> {/if} </div> </Page> <style> - .p-name { font-weight: 600; } + .p-name { font-weight: 600; color: var(--teal-strong); } + .p-name:hover { text-decoration: underline; } + form.card h2 { margin-bottom: 0.2rem; } </style> |
