feat: expand intelligent investigation workspace
Generic Container CI/CD / test-build-publish (push) Successful in 1m52s
Frontend CI/CD / build-test-publish-and-deploy (push) Successful in 1m52s

This commit is contained in:
2026-10-30 17:30:19 +08:00
parent ddd03dbff6
commit c0e4231b83
223 changed files with 13155 additions and 5304 deletions
@@ -43,24 +43,22 @@ describe("controlled native answer state", () => {
expect(screen.getByLabelText("其他资料")).toHaveValue("");
});
it("keeps chart data-tab search across data refresh and clears row selection without remounting", () => {
it("keeps chart data-tab search across data refresh without remounting", () => {
const current = chart();
const state = normalizeAnswerViewState(current.spec);
if (state.nodes.node.type === "Chart") state.nodes.node.view = "table";
const { rerender } = render(<AnswerUiView block={current} viewState={state} />);
const search = screen.getByRole("textbox", { name: "搜索压力" });
fireEvent.change(search, { target: { value: "一" } });
fireEvent.click(screen.getByRole("checkbox", { name: "选择第 1 行" }));
expect(screen.getByRole("checkbox", { name: "选择第 1 行" })).toBeChecked();
// A local owner can omit the external snapshot while keeping the same block instance.
rerender(<AnswerUiView block={chart(["一", "三"])} />);
expect(screen.getByRole("textbox", { name: "搜索压力" })).toBe(search);
expect(search).toHaveValue("一");
expect(screen.getByRole("checkbox", { name: "选择第 1 行" })).not.toBeChecked();
expect(screen.queryByRole("checkbox")).not.toBeInTheDocument();
expect(screen.getByRole("tab", { name: "数据" })).toHaveAttribute("aria-selected", "true");
});
it("restores chart data selections atomically when a delayed snapshot changes hidden series and range", () => {
it("restores chart search and sort while discarding legacy row selection", () => {
const current = block("Chart", { title: "压力", chart_type: "line", x_data: ["08:00", "09:00", "10:00"], series: [{ name: "入口", data: [1, 2, 3] }, { name: "出口", data: [3, 4, 5] }], source: "测试" });
const changed = vi.fn();
const { rerender } = render(<AnswerUiView block={current} viewState={normalizeAnswerViewState(current.spec)} onViewStateChange={changed} />);
@@ -68,15 +66,15 @@ describe("controlled native answer state", () => {
table: { query: "09:00", sort: { column: 1, descending: true }, selection: [1] } } } });
rerender(<AnswerUiView block={current} viewState={restored} onViewStateChange={changed} />);
expect(screen.getByRole("textbox", { name: "搜索压力" })).toHaveValue("09:00");
expect(screen.getByRole("checkbox", { name: "选择第 2 行" })).toBeChecked();
expect(screen.queryByRole("checkbox")).not.toBeInTheDocument();
expect(screen.getByRole("columnheader", { name: "入口" })).toHaveAttribute("aria-sort", "descending");
expect(screen.queryByRole("columnheader", { name: "出口" })).not.toBeInTheDocument();
expect(changed).not.toHaveBeenCalled();
// A subsequent deliberate series change clears invalid derived-table indices.
// A subsequent deliberate series change clears the derived table sort.
fireEvent.click(screen.getByRole("button", { name: "出口" }));
expect(screen.getByRole("checkbox", { name: "选择第 2 行" })).not.toBeChecked();
expect(screen.queryByRole("checkbox")).not.toBeInTheDocument();
expect(screen.getByRole("textbox", { name: "搜索压力" })).toHaveValue("09:00");
expect(changed).toHaveBeenLastCalledWith(expect.anything(), ["/nodes/node/hidden", "/nodes/node/table/sort", "/nodes/node/table/selection"]);
expect(changed).toHaveBeenLastCalledWith(expect.anything(), ["/nodes/node/hidden", "/nodes/node/table/sort"]);
});
it("preserves form drafts during streaming repeats and drops a draft when the field kind changes", () => {