fix: restore polished account experience and align AI with Lark design
This commit is contained in:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user