fix: restore polished account experience and align AI with Lark design

This commit is contained in:
yuxuanhui
2026-09-07 23:31:23 +08:00
parent 3f3d417296
commit 7dcf46836f
23 changed files with 1669 additions and 807 deletions
+54 -52
View File
@@ -8,20 +8,13 @@ import {
Input,
Modal,
Popover,
Pagination,
Select,
Table,
Tag,
TextArea,
Toast,
} from "@douyinfe/semi-ui-19";
import {
IconSearch,
IconRefresh,
IconDownload,
IconPlus,
IconSetting,
IconStar,
} from "@douyinfe/semi-icons";
import type { ColumnProps } from "@douyinfe/semi-ui-19/lib/es/table/interface";
import {
api,
@@ -145,6 +138,16 @@ export function AlphaPage({
state: "",
});
const [localVersion, setLocalVersion] = useState(0);
const tablePanel = useRef<HTMLElement>(null);
const [compact, setCompact] = useState(
() => matchMedia("(max-width: 760px)").matches,
);
useEffect(() => {
const media = matchMedia("(max-width: 760px)");
const change = () => setCompact(media.matches);
media.addEventListener("change", change);
return () => media.removeEventListener("change", change);
}, []);
useEffect(() => {
if (account) {
setPageSize(account.page_size);
@@ -227,6 +230,7 @@ export function AlphaPage({
}, [query, version, localVersion]);
useEffect(() => {
setSelected([]);
tablePanel.current?.querySelector(".semi-table-body")?.scrollTo({ top: 0 });
}, [query]);
function updateDraft(key: string, value: unknown) {
setDraft((previous) => ({
@@ -291,18 +295,16 @@ export function AlphaPage({
render: (_, row) => (
<button
className="alpha-link"
title={`${row!.id} · ${row!.alpha_type ?? ""}`}
onClick={() => {
setDetailId(row!.id);
onOverlay();
}}
>
<span>
{row!.research.favorite && <IconStar className="favorite-icon" />}
{row!.research.favorite && <Tag size="small">收藏</Tag>}
{row!.name || row!.id}
</span>
<small>
{row!.name ? row!.id : (row!.alpha_type ?? "未提供类型")}
</small>
</button>
),
},
@@ -323,7 +325,7 @@ export function AlphaPage({
render: (_, row) => (
<div className="stacked-cell">
<span>{row!.region ?? "—"}</span>
<small>{row!.universe ?? "—"}</small>
<span className="muted"> / {row!.universe ?? "—"}</span>
</div>
),
},
@@ -334,10 +336,11 @@ export function AlphaPage({
render: (_, row) => (
<div className="stacked-cell">
<span>{row!.status ?? "未提供"}</span>
<small>
{row!.stage ?? "—"}
{row!.hidden ? " · 已隐藏" : ""}
</small>
<span className="muted">
{" "}
· {row!.stage ?? "—"}
{row!.hidden ? " · 隐藏" : ""}
</span>
</div>
),
},
@@ -393,9 +396,9 @@ export function AlphaPage({
render: (_, row) => formatTime(row!.date_created, account?.timezone),
},
];
const columns = columnDefinitions.filter((column) =>
visibleColumns.includes(String(column.key)),
);
const columns = columnDefinitions
.filter((column) => visibleColumns.includes(String(column.key)))
.map((column) => (compact ? { ...column, fixed: undefined } : column));
const activeFilterCount = Object.values(filters).filter(Boolean).length;
const options = (key: string) =>
(Array.isArray(facets[key]) ? (facets[key] as string[]) : []).map(
@@ -408,17 +411,14 @@ export function AlphaPage({
<>
<div className="page-heading">
<div>
<div className="eyebrow">ALPHA LIBRARY</div>
<h1>Alpha 管理</h1>
<p>集中查看平台信号,记录每一步研究判断。</p>
</div>
<div className="inline-actions">
<Button icon={<IconPlus />} onClick={() => setImporting(true)}>
<Button type="tertiary" onClick={() => setImporting(true)}>
导入 Alpha ID
</Button>
<Button
theme="solid"
icon={<IconRefresh />}
loading={busy === "full_sync"}
disabled={!connected}
onClick={() => void newTask("full_sync")}
@@ -466,7 +466,7 @@ export function AlphaPage({
/>
)}
{error && <Banner type="danger" description={error} />}
<section className="library-panel">
<section className="library-panel" ref={tablePanel}>
<form
className="filter-panel"
onSubmit={(e) => {
@@ -477,7 +477,6 @@ export function AlphaPage({
<div className="primary-filters">
<Input
aria-label="搜索 Alpha"
prefix={<IconSearch />}
placeholder="搜索 ID、名称或表达式"
value={draft.q ?? ""}
onChange={(v) => updateDraft("q", v)}
@@ -510,7 +509,7 @@ export function AlphaPage({
<Button htmlType="submit" theme="solid">
查询
</Button>
<Button theme="borderless" onClick={clearFilters}>
<Button type="tertiary" theme="borderless" onClick={clearFilters}>
重置
</Button>
</div>
@@ -632,6 +631,7 @@ export function AlphaPage({
{selected.length > 0 && (
<>
<Button
type="tertiary"
size="small"
onClick={() => {
setBulkVersions(
@@ -648,6 +648,7 @@ export function AlphaPage({
批量编辑
</Button>
<Button
type="tertiary"
size="small"
disabled={!connected}
loading={busy === "alpha_refresh"}
@@ -690,7 +691,7 @@ export function AlphaPage({
}}
/>
<a href={`/api/v1/alphas/export?${query}`}>
<Button icon={<IconDownload />} size="small">
<Button type="tertiary" size="small">
导出
</Button>
</a>
@@ -722,11 +723,9 @@ export function AlphaPage({
</div>
}
>
<Button
aria-label="显示列设置"
icon={<IconSetting />}
size="small"
/>
<Button type="tertiary" aria-label="显示列设置" size="small">
列设置
</Button>
</Popover>
</div>
</div>
@@ -735,32 +734,21 @@ export function AlphaPage({
dataSource={data.items}
rowKey="id"
loading={loading}
size="middle"
className="alpha-table"
size="small"
scroll={{
y: "max(260px, calc(100vh - 670px))",
y: "100%",
x: columns.reduce((sum, c) => sum + Number(c.width || 120), 0) + 60,
}}
rowSelection={{
selectedRowKeys: selected,
onChange: (keys) => setSelected((keys ?? []).map(String)),
fixed: true,
}}
pagination={{
currentPage: page,
pageSize,
total: data.total,
showSizeChanger: true,
pageSizeOpts: [25, 50, 100],
onPageChange: (next) => setPage(next),
onPageSizeChange: (size) => {
setPageSize(size);
setPage(1);
},
fixed: !compact,
}}
pagination={false}
empty={
<Empty
className="alpha-empty"
image={<div className="empty-alpha">α</div>}
title={
activeFilterCount
? "没有符合条件的 Alpha"
@@ -774,10 +762,24 @@ export function AlphaPage({
/>
}
/>
<footer className="table-pagination" aria-label="Alpha 分页">
<span className="muted">共 {data.total.toLocaleString()} 条</span>
<Pagination
size={compact ? "small" : "default"}
currentPage={page}
pageSize={pageSize}
total={data.total}
showSizeChanger
pageSizeOpts={[25, 50, 100]}
preventPageChangeOnPageSizeChange
onPageChange={setPage}
onPageSizeChange={(size) => {
setPageSize(size);
setPage(1);
}}
/>
</footer>
</section>
<p className="page-footnote">
平台数据与本地研究记录独立保存 · 记录不因再次同步而覆盖
</p>
<Modal
title="导入 Alpha ID"
visible={importing && !overlaySuspended}