refactor: unify data preparations and research input snapshots
Deploy production / deploy (push) Successful in 53s

This commit is contained in:
yuxuanhui
2026-09-12 01:24:02 +08:00
parent 849f86fef7
commit 394438e753
82 changed files with 4146 additions and 2076 deletions
+31 -28
View File
@@ -1,3 +1,7 @@
import {
ResearchDataInput,
researchSelection,
} from "../preparations/ResearchDataInput";
import { ResearchList, ResearchDetail } from "./ResearchList";
import { ResearchSelect } from "./ResearchSelect";
import { useEffect, useRef, useState } from "react";
@@ -101,7 +105,7 @@ export function ResearchWorkspace({
api<{ items: Asset[]; total: number }>(
`/research/assets?kind=template&limit=25&offset=${assetPage * 25}&q=${encodeURIComponent(search)}`,
),
api<{ items: InputSnapshot[] }>("/research/inputs"),
Promise.resolve({ items: inputs }),
api<{ items: typeof history; total: number }>(
`/research/experiments?limit=25&offset=${historyPage * 25}`,
),
@@ -129,7 +133,11 @@ export function ResearchWorkspace({
research_asset_id: asset?.id,
research_experiment_id: experiment?.id,
alpha_id: parent.split(/[,,\s]+/)[0] || undefined,
template_input_id: inputIds.length === 1 ? inputIds[0] : undefined,
input_snapshot_id:
inputIds.length === 1 &&
!inputs.find((i) => i.id === inputIds[0])?.preparation_ref
? inputIds[0]
: undefined,
});
}, [active, page, asset?.id, experiment?.id, parent, inputIds, onContext]);
useEffect(() => {
@@ -180,17 +188,6 @@ export function ResearchWorkspace({
setMethod("structure");
}
}, [active, action]);
function selectInputs(ids: string[]) {
setInputIds(ids);
const first = inputs.find((item) => item.id === ids[0]);
if (first)
setSettings((old) => ({
...old,
region: first.scope.region,
universe: first.scope.universe,
delay: first.scope.delay,
}));
}
async function refreshSettings() {
const data = await post<{
content: {
@@ -236,7 +233,7 @@ export function ResearchWorkspace({
const next = await post<Asset>("/research/generate", {
name: template.name,
hypothesis,
input_ids: inputIds,
...researchSelection(inputIds, inputs),
parent_alpha_ids: parent ? parent.split(/[,,\s]+/).filter(Boolean) : [],
method: page === "variants" ? "structure" : "template",
});
@@ -274,7 +271,7 @@ export function ResearchWorkspace({
const next = await post<Experiment>("/research/experiments", {
asset_id: asset!.id,
version: asset!.version,
input_ids: inputIds,
...researchSelection(inputIds, inputs),
hypothesis,
settings,
mode,
@@ -580,20 +577,26 @@ export function ResearchWorkspace({
)}
<label>
固定研究输入
<ResearchSelect
multiple
filter
label="固定研究输入"
value={inputIds}
optionList={inputs.map((input) => ({
value: input.id,
label: `${input.dataset_id} · ${input.scope.region}/${input.scope.universe}/D${input.scope.delay} · ${input.field_ids.length} 字段 · ${input.id.slice(0, 8)}`,
}))}
onChange={(value) => selectInputs(value as string[])}
<ResearchDataInput
label="选择数据准备"
ids={inputIds}
inputs={inputs}
onChange={(ids, rows) => {
setInputs(rows);
setInputIds(ids);
const first = rows.find((r) => r.id === ids[0]);
if (first)
setSettings((old) => ({
...old,
region: first.scope.region,
universe: first.scope.universe,
delay: first.scope.delay,
}));
}}
/>
</label>
<p className="research-hint">
在数据目录中保存字段选择。跨数据集分别关联输入,跨市场使用目标范围的独立输入。
从数据准备选择集合;每个集合可包含同范围下多个数据集的字段。
</p>
{page === "variants" && method === "settings" ? (
<label>
@@ -624,7 +627,7 @@ export function ResearchWorkspace({
references={[
...selectedInputs.map((input) => ({
id: input.id,
name: `${input.dataset_id} · ${input.scope.region}/${input.scope.universe}/D${input.scope.delay} · ${input.field_ids.length} 字段 · ${input.id}`,
name: `${input.name} · ${input.scope.region}/${input.scope.universe}/D${input.scope.delay} · ${input.field_ids.length} 字段 · ${input.id}`,
})),
...(page === "variants" && parent
? [
@@ -857,7 +860,7 @@ export function ResearchWorkspace({
setExperiment(
await post("/research/variants/settings", {
alpha_id: parent,
input_ids: inputIds,
...researchSelection(inputIds, inputs),
...(hypothesis ? { hypothesis } : {}),
}),
);