diff options
Diffstat (limited to 'frontend/src/pages/ProjectDataTab.svelte')
| -rw-r--r-- | frontend/src/pages/ProjectDataTab.svelte | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/frontend/src/pages/ProjectDataTab.svelte b/frontend/src/pages/ProjectDataTab.svelte new file mode 100644 index 0000000..e3b1923 --- /dev/null +++ b/frontend/src/pages/ProjectDataTab.svelte @@ -0,0 +1,85 @@ +<script lang="ts"> + import Status from '../components/Status.svelte'; + import DatasetCard from '../components/DatasetCard.svelte'; + import DatasetWizard from '../components/DatasetWizard.svelte'; + import { listDatasets } from '../lib/client'; + import { extractStatusMessage } from '../lib/state'; + import type { Dataset } from '../lib/types'; + + interface Props { + projectId?: string; + showWizard?: boolean; + } + let { projectId: _projectId, showWizard = false }: Props = $props(); + + let items: Dataset[] = $state([]); + let busy = $state(true); + let error: string | null = $state(null); + // svelte-ignore state_referenced_locally + let wizardOpen = $state(showWizard); + + + let refreshTimer: ReturnType<typeof setInterval> | null = null; + + $effect(() => { + void load(); + return () => { + if (refreshTimer) clearInterval(refreshTimer); + refreshTimer = null; + }; + }); + + async function load() { + error = null; + try { + const { items: got } = await listDatasets(); + items = got; + const active = got.some((d) => d.status === 'pending' || d.status === 'running'); + if (active && !refreshTimer) { + refreshTimer = setInterval(async () => { + try { + const { items: fresh } = await listDatasets(); + items = fresh; + const still = fresh.some((d) => d.status === 'pending' || d.status === 'running'); + if (!still && refreshTimer) { + clearInterval(refreshTimer); + refreshTimer = null; + } + } catch { + /* transient error, keep polling */ + } + }, 2000); + } + } catch (e) { + error = extractStatusMessage(e); + } finally { + busy = false; + } + } +</script> + +<div class="stack"> + {#if wizardOpen} + <DatasetWizard onCreated={() => void load()} /> + <button class="btn ghost" onclick={() => (wizardOpen = false)}>收起新建面板</button> + {:else} + <button class="btn primary" onclick={() => (wizardOpen = true)}>新建数据集</button> + {/if} + + <h2>我的数据集</h2> + <Status busy={busy} error={error} busyText="加载数据集列表…" empty={null} /> + + {#if !busy && !error && items.length === 0} + <Status + busy={false} + empty="还没有数据集" + emptyHint="先创建数据集:选择标的、日期范围与复权方式,提交后异步获取并给出覆盖预览" + /> + {/if} + + {#if !busy && !error && items.length > 0} + {#each items as ds (ds.id)} + <DatasetCard dsId={ds.id} /> + {/each} + {/if} +</div> |
