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");
|
||||
expect(renderers).toHaveLength(3);
|
||||
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[2].querySelector("td")).not.toBeNull();
|
||||
expect(renderers[2].querySelector("pre")).not.toBeNull();
|
||||
|
||||
@@ -39,7 +39,7 @@ export function formatModelActivity(text: string): string {
|
||||
function MarkdownBody({ entry }: { entry: ActivityEntry }) {
|
||||
const tone = entry.kind === "thinking" ? "text-muted-foreground" : "text-foreground";
|
||||
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>
|
||||
</div>
|
||||
);
|
||||
@@ -47,7 +47,7 @@ function MarkdownBody({ entry }: { entry: ActivityEntry }) {
|
||||
|
||||
function ActivityRow({ entry }: { entry: ActivityEntry }) {
|
||||
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">
|
||||
<span className="text-foreground/80">{ACTIVITY_LABELS[entry.kind]}</span>
|
||||
{entry.phase && <span aria-label={`Phase ${entry.phase}`}>{entry.phase}</span>}
|
||||
@@ -79,8 +79,8 @@ export function ModelActivityPanel({
|
||||
|
||||
return (
|
||||
<aside className={desktopSplit
|
||||
? "static z-auto flex 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"
|
||||
? "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 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">
|
||||
<h2 className="font-heading text-sm font-semibold text-foreground">Model activity</h2>
|
||||
@@ -93,7 +93,7 @@ export function ModelActivityPanel({
|
||||
data-testid="activity-scroll"
|
||||
tabIndex={0}
|
||||
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) => {
|
||||
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_promoted", subject: "fact_a" },
|
||||
{ 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: "column_excluded", subject: "fact_a.note", detail: "Non **pertinente**" },
|
||||
].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(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();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -38,6 +38,10 @@ const HIDDEN_DECISION_TYPES = new Set([
|
||||
"table_approved",
|
||||
"table_promoted",
|
||||
"column_promoted",
|
||||
"cte_approved",
|
||||
"sql_approved",
|
||||
"datamart_requested",
|
||||
"datamart_declined",
|
||||
]);
|
||||
|
||||
function DocBody({ doc }: { doc: SessionDocument }) {
|
||||
|
||||
Reference in New Issue
Block a user