Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 10x 2x 8x 8x 7x 7x 1x 7x 7x | import type { JSX } from "react";
import styles from "./WorkpadPanel.module.scss";
/** Props for the WorkpadPanel component. */
export interface WorkpadPanelProps {
/** Raw JSON string from the task's workpad field. */
workpad: string;
}
/** Parsed workpad shape. */
interface ParsedWorkpad {
status?: string;
summary?: string;
extra?: Record<string, unknown>;
}
/**
* Displays a task's workpad (persistent structured context).
* Pure presentational — accepts the raw JSON string and renders
* status, summary, and extra fields if present.
*/
export function WorkpadPanel({ workpad }: WorkpadPanelProps): JSX.Element | undefined {
if (!workpad) {
return undefined;
}
let parsed: ParsedWorkpad;
try {
const raw: unknown = JSON.parse(workpad);
Iif (raw === undefined || raw === null || typeof raw !== "object" || Array.isArray(raw)) {
return undefined;
}
parsed = raw as ParsedWorkpad;
} catch {
return (
<div className={styles.workpadSection} data-testid="workpad-panel">
<div className={styles.workpadLabel}>Workpad</div>
<div className={styles.workpadExtra}>{workpad}</div>
</div>
);
}
Iif (!parsed.status && !parsed.summary && !parsed.extra) {
return undefined;
}
return (
<div className={styles.workpadSection} data-testid="workpad-panel">
<div className={styles.workpadLabel}>Workpad</div>
{parsed.status && (
<div className={styles.workpadStatus} data-testid="workpad-status">
{parsed.status}
</div>
)}
{parsed.summary && (
<div className={styles.workpadSummary} data-testid="workpad-summary">
{parsed.summary}
</div>
)}
{parsed.extra && Object.keys(parsed.extra).length > 0 && (
<div className={styles.workpadExtra} data-testid="workpad-extra">
{JSON.stringify(parsed.extra, null, 2)}
</div>
)}
</div>
);
}
|