Wide tables (e.g. 116 columns, 3 suggested) made curation a scroll hunt. Now the modal lists suggested columns first (stable sort on the descriptor flag, so toggling never reorders rows) and adds a filter box matching name + description, with a "shown/total" count. Selection stays keyed by column name, so the response column order is unchanged (catalog order). Applies to read-only (excluded) tables too. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
108 lines
3.0 KiB
TypeScript
108 lines
3.0 KiB
TypeScript
import { render, screen } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { SchemaColumnsDialog } from "./SchemaColumnsDialog";
|
|
import type { SchemaTable } from "../api/types";
|
|
|
|
const table: SchemaTable = {
|
|
id: "t-pat",
|
|
name: "dim_patient",
|
|
kind: "promote",
|
|
columns: [
|
|
{ name: "cod_paz", description: "Codice paziente", suggested: true },
|
|
{ name: "nome", description: "Nome", suggested: false },
|
|
],
|
|
};
|
|
|
|
test("selected column renders bold; unselected is normal; toggle fires", async () => {
|
|
const onToggle = vi.fn();
|
|
render(
|
|
<SchemaColumnsDialog
|
|
table={table}
|
|
open
|
|
readOnly={false}
|
|
selected={new Set(["cod_paz"])}
|
|
onToggle={onToggle}
|
|
onClose={() => {}}
|
|
/>
|
|
);
|
|
expect(screen.getByText("cod_paz").className).toContain("font-bold");
|
|
expect(screen.getByText("nome").className).not.toContain("font-bold");
|
|
await userEvent.click(screen.getByRole("checkbox", { name: "nome" }));
|
|
expect(onToggle).toHaveBeenCalledWith("nome");
|
|
});
|
|
|
|
test("readOnly renders no checkboxes and no bold", () => {
|
|
render(
|
|
<SchemaColumnsDialog
|
|
table={table}
|
|
open
|
|
readOnly
|
|
selected={new Set()}
|
|
onToggle={() => {}}
|
|
onClose={() => {}}
|
|
/>
|
|
);
|
|
expect(screen.queryByRole("checkbox")).toBeNull();
|
|
expect(screen.getByText("cod_paz")).toBeInTheDocument();
|
|
expect(screen.getByText("cod_paz").className).not.toContain("font-bold");
|
|
});
|
|
|
|
const wide: SchemaTable = {
|
|
id: "t",
|
|
name: "t",
|
|
kind: "promote",
|
|
columns: [
|
|
{ name: "aaa", description: "alfa", suggested: false },
|
|
{ name: "zzz_key", description: "chiave", suggested: true },
|
|
{ name: "bbb", description: "Codice beta", suggested: false },
|
|
],
|
|
};
|
|
|
|
test("suggested columns are listed first, then catalog order (stable)", () => {
|
|
render(
|
|
<SchemaColumnsDialog
|
|
table={wide}
|
|
open
|
|
readOnly={false}
|
|
selected={new Set()}
|
|
onToggle={() => {}}
|
|
onClose={() => {}}
|
|
/>
|
|
);
|
|
const order = screen.getAllByRole("checkbox").map((cb) => cb.getAttribute("aria-label"));
|
|
expect(order).toEqual(["zzz_key", "aaa", "bbb"]);
|
|
});
|
|
|
|
test("filter narrows visible columns by name", async () => {
|
|
render(
|
|
<SchemaColumnsDialog
|
|
table={wide}
|
|
open
|
|
readOnly={false}
|
|
selected={new Set()}
|
|
onToggle={() => {}}
|
|
onClose={() => {}}
|
|
/>
|
|
);
|
|
await userEvent.type(screen.getByRole("textbox", { name: /filter/i }), "zzz");
|
|
const order = screen.getAllByRole("checkbox").map((cb) => cb.getAttribute("aria-label"));
|
|
expect(order).toEqual(["zzz_key"]);
|
|
expect(screen.queryByText("aaa")).toBeNull();
|
|
});
|
|
|
|
test("filter matches the description too", async () => {
|
|
render(
|
|
<SchemaColumnsDialog
|
|
table={wide}
|
|
open
|
|
readOnly={false}
|
|
selected={new Set()}
|
|
onToggle={() => {}}
|
|
onClose={() => {}}
|
|
/>
|
|
);
|
|
await userEvent.type(screen.getByRole("textbox", { name: /filter/i }), "codice");
|
|
const order = screen.getAllByRole("checkbox").map((cb) => cb.getAttribute("aria-label"));
|
|
expect(order).toEqual(["bbb"]);
|
|
});
|