fix: refine session report and live activity layout
This commit is contained in:
@@ -54,6 +54,10 @@ test("uses the activity-only Markdown wrapping renderer for long content", () =>
|
|||||||
const renderers = document.querySelectorAll(".thot-activity-prose");
|
const renderers = document.querySelectorAll(".thot-activity-prose");
|
||||||
expect(renderers).toHaveLength(3);
|
expect(renderers).toHaveLength(3);
|
||||||
expect(renderers[0]).toHaveClass("thot-prose");
|
expect(renderers[0]).toHaveClass("thot-prose");
|
||||||
|
for (const renderer of renderers) {
|
||||||
|
expect(renderer).toHaveClass("min-w-0", "w-full", "max-w-none");
|
||||||
|
expect(renderer).not.toHaveClass("max-w-[74ch]");
|
||||||
|
}
|
||||||
expect(renderers[1].querySelector("code")).not.toBeNull();
|
expect(renderers[1].querySelector("code")).not.toBeNull();
|
||||||
expect(renderers[2].querySelector("td")).not.toBeNull();
|
expect(renderers[2].querySelector("td")).not.toBeNull();
|
||||||
expect(renderers[2].querySelector("pre")).not.toBeNull();
|
expect(renderers[2].querySelector("pre")).not.toBeNull();
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export function formatModelActivity(text: string): string {
|
|||||||
function MarkdownBody({ entry }: { entry: ActivityEntry }) {
|
function MarkdownBody({ entry }: { entry: ActivityEntry }) {
|
||||||
const tone = entry.kind === "thinking" ? "text-muted-foreground" : "text-foreground";
|
const tone = entry.kind === "thinking" ? "text-muted-foreground" : "text-foreground";
|
||||||
return (
|
return (
|
||||||
<div className={`thot-prose thot-activity-prose max-w-[74ch] text-sm ${tone}`}>
|
<div className={`thot-prose thot-activity-prose min-w-0 w-full max-w-none text-sm ${tone}`}>
|
||||||
<ReactMarkdown remarkPlugins={[remarkGfm]}>{formatModelActivity(entry.text)}</ReactMarkdown>
|
<ReactMarkdown remarkPlugins={[remarkGfm]}>{formatModelActivity(entry.text)}</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -47,7 +47,7 @@ function MarkdownBody({ entry }: { entry: ActivityEntry }) {
|
|||||||
|
|
||||||
function ActivityRow({ entry }: { entry: ActivityEntry }) {
|
function ActivityRow({ entry }: { entry: ActivityEntry }) {
|
||||||
return (
|
return (
|
||||||
<article className="border-b border-border/50 py-2 last:border-b-0">
|
<article className="w-full min-w-0 border-b border-border/50 py-2 last:border-b-0">
|
||||||
<div className="mb-1 flex flex-wrap items-center gap-1 text-[0.65rem] font-semibold uppercase tracking-[0.08em] text-muted-foreground">
|
<div className="mb-1 flex flex-wrap items-center gap-1 text-[0.65rem] font-semibold uppercase tracking-[0.08em] text-muted-foreground">
|
||||||
<span className="text-foreground/80">{ACTIVITY_LABELS[entry.kind]}</span>
|
<span className="text-foreground/80">{ACTIVITY_LABELS[entry.kind]}</span>
|
||||||
{entry.phase && <span aria-label={`Phase ${entry.phase}`}>{entry.phase}</span>}
|
{entry.phase && <span aria-label={`Phase ${entry.phase}`}>{entry.phase}</span>}
|
||||||
@@ -79,8 +79,8 @@ export function ModelActivityPanel({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className={desktopSplit
|
<aside className={desktopSplit
|
||||||
? "static z-auto flex w-[var(--activity-panel-width)] shrink-0 flex-col border-r-0 bg-sidebar"
|
? "static z-auto flex min-w-0 w-[var(--activity-panel-width)] shrink-0 flex-col border-r-0 bg-sidebar"
|
||||||
: "fixed inset-y-0 left-0 z-30 flex w-[min(90vw,24rem)] shrink-0 flex-col border-r border-border bg-sidebar"
|
: "fixed inset-y-0 left-0 z-30 flex min-w-0 w-[min(90vw,24rem)] shrink-0 flex-col border-r border-border bg-sidebar"
|
||||||
}>
|
}>
|
||||||
<div className="flex items-center justify-between border-b border-border/60 px-3 py-2">
|
<div className="flex items-center justify-between border-b border-border/60 px-3 py-2">
|
||||||
<h2 className="font-heading text-sm font-semibold text-foreground">Model activity</h2>
|
<h2 className="font-heading text-sm font-semibold text-foreground">Model activity</h2>
|
||||||
@@ -93,7 +93,7 @@ export function ModelActivityPanel({
|
|||||||
data-testid="activity-scroll"
|
data-testid="activity-scroll"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
aria-label="Model activity timeline"
|
aria-label="Model activity timeline"
|
||||||
className="flex-1 overflow-y-auto px-3 py-2 outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/40"
|
className="w-full min-w-0 flex-1 overflow-y-auto px-3 py-2 outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/40"
|
||||||
onScroll={(event) => {
|
onScroll={(event) => {
|
||||||
followRef.current = isNearBottom(event.currentTarget);
|
followRef.current = isNearBottom(event.currentTarget);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -174,6 +174,10 @@ test("never renders technical approval, promotion, or memory decisions", async (
|
|||||||
{ type: "table_approved", subject: "fact_a" },
|
{ type: "table_approved", subject: "fact_a" },
|
||||||
{ type: "table_promoted", subject: "fact_a" },
|
{ type: "table_promoted", subject: "fact_a" },
|
||||||
{ type: "column_promoted", subject: "fact_a.id" },
|
{ type: "column_promoted", subject: "fact_a.id" },
|
||||||
|
{ type: "cte_approved", subject: "eventi_device" },
|
||||||
|
{ type: "sql_approved", subject: "phase:7" },
|
||||||
|
{ type: "datamart_requested", subject: "phase:8" },
|
||||||
|
{ type: "datamart_declined", subject: "phase:8" },
|
||||||
{ type: "memory_promoted", subject: "concetto" },
|
{ type: "memory_promoted", subject: "concetto" },
|
||||||
{ type: "column_excluded", subject: "fact_a.note", detail: "Non **pertinente**" },
|
{ type: "column_excluded", subject: "fact_a.note", detail: "Non **pertinente**" },
|
||||||
].map((decision) => JSON.stringify(decision)).join("\n");
|
].map((decision) => JSON.stringify(decision)).join("\n");
|
||||||
@@ -189,7 +193,17 @@ test("never renders technical approval, promotion, or memory decisions", async (
|
|||||||
|
|
||||||
expect(await screen.findByText("column excluded")).toBeInTheDocument();
|
expect(await screen.findByText("column excluded")).toBeInTheDocument();
|
||||||
expect(screen.getByText("pertinente").tagName).toBe("STRONG");
|
expect(screen.getByText("pertinente").tagName).toBe("STRONG");
|
||||||
for (const hidden of ["phase approved", "table approved", "table promoted", "column promoted", "memory promoted"]) {
|
for (const hidden of [
|
||||||
|
"phase approved",
|
||||||
|
"table approved",
|
||||||
|
"table promoted",
|
||||||
|
"column promoted",
|
||||||
|
"cte approved",
|
||||||
|
"sql approved",
|
||||||
|
"datamart requested",
|
||||||
|
"datamart declined",
|
||||||
|
"memory promoted",
|
||||||
|
]) {
|
||||||
expect(screen.queryByText(hidden)).not.toBeInTheDocument();
|
expect(screen.queryByText(hidden)).not.toBeInTheDocument();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ const HIDDEN_DECISION_TYPES = new Set([
|
|||||||
"table_approved",
|
"table_approved",
|
||||||
"table_promoted",
|
"table_promoted",
|
||||||
"column_promoted",
|
"column_promoted",
|
||||||
|
"cte_approved",
|
||||||
|
"sql_approved",
|
||||||
|
"datamart_requested",
|
||||||
|
"datamart_declined",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function DocBody({ doc }: { doc: SessionDocument }) {
|
function DocBody({ doc }: { doc: SessionDocument }) {
|
||||||
|
|||||||
@@ -85,6 +85,10 @@ def _rich_session(tmp_path):
|
|||||||
_decision(6, "table_promoted", "fact_procedure"),
|
_decision(6, "table_promoted", "fact_procedure"),
|
||||||
_decision(7, "column_promoted", "fact_procedure.status"),
|
_decision(7, "column_promoted", "fact_procedure.status"),
|
||||||
_decision(8, "column_excluded", "fact_procedure.note", "Non pertinente"),
|
_decision(8, "column_excluded", "fact_procedure.note", "Non pertinente"),
|
||||||
|
_decision(9, "cte_approved", "eventi_device"),
|
||||||
|
_decision(10, "sql_approved", "phase:7"),
|
||||||
|
_decision(11, "datamart_requested", "phase:8"),
|
||||||
|
_decision(12, "datamart_declined", "phase:8"),
|
||||||
]
|
]
|
||||||
(session_dir / "question.md").write_text(question)
|
(session_dir / "question.md").write_text(question)
|
||||||
(session_dir / "sql_final.sql").write_text("SELECT COUNT(*) FROM fact_procedure")
|
(session_dir / "sql_final.sql").write_text("SELECT COUNT(*) FROM fact_procedure")
|
||||||
@@ -160,6 +164,10 @@ def test_build_documents_groups_memories_and_filters_summary_decisions(tmp_path)
|
|||||||
"phase_approved",
|
"phase_approved",
|
||||||
"table_promoted",
|
"table_promoted",
|
||||||
"column_promoted",
|
"column_promoted",
|
||||||
|
"cte_approved",
|
||||||
|
"sql_approved",
|
||||||
|
"datamart_requested",
|
||||||
|
"datamart_declined",
|
||||||
):
|
):
|
||||||
assert hidden not in decisions
|
assert hidden not in decisions
|
||||||
|
|
||||||
|
|||||||
@@ -162,6 +162,10 @@ _SUMMARY_HIDDEN_TYPES = _MEMORY_TYPES | frozenset(
|
|||||||
"table_approved",
|
"table_approved",
|
||||||
"table_promoted",
|
"table_promoted",
|
||||||
"column_promoted",
|
"column_promoted",
|
||||||
|
"cte_approved",
|
||||||
|
"sql_approved",
|
||||||
|
"datamart_requested",
|
||||||
|
"datamart_declined",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user