feat: add versioned research templates and alpha variants

This commit is contained in:
yuxuanhui
2026-09-08 21:29:21 +08:00
parent b604e6050e
commit f89ae211d2
55 changed files with 5650 additions and 435 deletions
+21 -126
View File
@@ -4,14 +4,12 @@ import {
Banner,
Button,
Input,
Select,
Spin,
Tag,
Toast,
} from "@douyinfe/semi-ui-19";
import { api, displayValue, formatTime, patch, post } from "../api";
import { api, displayValue, formatTime, post } from "../api";
import type { Account, AccountUsage } from "../types";
import { ModelSettingsPanel } from "../ai/ModelSettingsPanel";
const connectionLabels: Record<string, string> = {
connected: "已连接",
@@ -57,29 +55,9 @@ export function AccountPage({
const [password, setPassword] = useState("");
const [busy, setBusy] = useState("");
const [settingsOpen, setSettingsOpen] = useState(false);
const [preferences, setPreferences] = useState({
display_name: "研究员",
theme: "light",
timezone: "Asia/Shanghai",
page_size: 25,
});
useEffect(() => {
if (account) setEmail(account.email ?? "");
}, [account?.email]);
useEffect(() => {
if (account)
setPreferences({
display_name: account.display_name,
theme: account.theme,
timezone: account.timezone,
page_size: account.page_size,
});
}, [
account?.display_name,
account?.theme,
account?.timezone,
account?.page_size,
]);
if (!account)
return (
<div className="screen-center">
@@ -161,29 +139,6 @@ export function AccountPage({
];
return (
<>
<div className="page-heading">
<h1>个人信息</h1>
<div className="inline-actions">
<Button
type="tertiary"
disabled={!account.configured || blocked}
loading={busy === "profile"}
aria-label="刷新个人资料"
onClick={() =>
void action("profile", () => post("/account/refresh"))
}
>
刷新资料
</Button>
<Button
type="tertiary"
aria-expanded={settingsOpen || !account.configured}
onClick={() => setSettingsOpen(!settingsOpen)}
>
连接设置
</Button>
</div>
</div>
{account.connection_error && (
<Banner
type={
@@ -251,6 +206,26 @@ export function AccountPage({
有效期 {duration(account.session.total_seconds)}
</span>
</div>
<div className="inline-actions">
<Button
type="tertiary"
disabled={!account.configured || blocked}
loading={busy === "profile"}
aria-label="刷新个人资料"
onClick={() =>
void action("profile", () => post("/account/refresh"))
}
>
刷新资料
</Button>
<Button
type="tertiary"
aria-expanded={settingsOpen || !account.configured}
onClick={() => setSettingsOpen(!settingsOpen)}
>
连接设置
</Button>
</div>
</section>
{(settingsOpen || !account.configured) && (
<section
@@ -448,86 +423,6 @@ export function AccountPage({
</p>
))}
</section>
<ModelSettingsPanel />
<section className="account-section full-width">
<div className="section-heading">
<h2>工作空间偏好</h2>
<span className="muted">
更新于 {formatTime(account.last_synced_at, account.timezone)}
</span>
</div>
<form
className="preferences-form"
onSubmit={(e) => {
e.preventDefault();
void action("preferences", () =>
patch("/account/preferences", preferences),
);
}}
>
<div className="preferences-grid">
<label>
显示名称
<Input
aria-label="显示名称"
value={preferences.display_name}
onChange={(display_name) =>
setPreferences({ ...preferences, display_name })
}
/>
</label>
<label>
主题
<Select
aria-label="主题"
value={preferences.theme}
optionList={[
{ value: "light", label: "浅色" },
{ value: "dark", label: "深色" },
]}
onChange={(theme) =>
setPreferences({ ...preferences, theme: String(theme) })
}
/>
</label>
<label>
时区
<Input
aria-label="时区"
value={preferences.timezone}
onChange={(timezone) =>
setPreferences({ ...preferences, timezone })
}
/>
</label>
<label>
每页数量
<Select
aria-label="每页数量"
value={preferences.page_size}
optionList={[25, 50, 100].map((value) => ({
value,
label: `${value} 条`,
}))}
onChange={(page_size) =>
setPreferences({
...preferences,
page_size: Number(page_size),
})
}
/>
</label>
</div>
<Button
htmlType="submit"
theme="solid"
loading={busy === "preferences"}
disabled={Boolean(busy)}
>
保存偏好
</Button>
</form>
</section>
</div>
</>
);
+8
View File
@@ -27,6 +27,7 @@ import {
} from "../api";
import type { Account, Job } from "../types";
import type { PageContext, UIAction } from "../ai/types";
import { FieldAvailability } from "../research/FieldAvailability";
import "./dataset.css";
type Scope = {
@@ -1237,6 +1238,13 @@ export function DatasetPage({
</dd>
</div>
</dl>
{detail?.field && (
<FieldAvailability
key={`${detail.field}:${scopeQuery}`}
field={detail.field}
scope={scope}
/>
)}
{conflict && (
<Banner
type="warning"