Files
clawmates/frontend/src/components/dashboard/RefineDiffModal.tsx
T
Omar Sobh d8c8793c4a
ci / gates (push) Successful in 8s
ci / frontend (push) Successful in 26s
ci / rust (push) Successful in 4m25s
ci / e2e (push) Skipped
ci / publish (push) Successful in 2m46s
ci fixes: cargo fmt, eslint entities, max-lines split
CI on 6ffbe97 failed on two auto-fixable gates. Both fixed:

  * cargo fmt --all — rustfmt applied across the surface touched
    by the last ~20 commits (world.rs, security_scan.rs,
    routes/{missions,nodes,terminal}.rs, fleet_herdr.rs,
    mission_workspace.rs, benchmark_runner.rs, mission_refiner.rs,
    lib.rs, tests/mission_orchestrator.rs, cm-db/repo/{missions,teams}.rs,
    bins/clawmates-node/src/main.rs)
  * eslint apostrophe escapes in HerdrSessions + MissionWizard
  * eslint max-lines: extracted EditMissionModal + RefineDiffModal
    (each ~200 LoC) into their own files. MissionCanvas drops from
    1424 to 1026, comfortably under both the 1250 eslint cap and the
    1500 CI budget.

New files:
  frontend/src/components/dashboard/EditMissionModal.tsx  (211 LoC)
  frontend/src/components/dashboard/RefineDiffModal.tsx   (208 LoC)

Verified locally: cargo fmt --check clean, cargo check clean,
mission_orchestrator test 3/3 pass, tsc + eslint --quiet both silent.
2026-07-20 12:03:43 -07:00

212 lines
5.1 KiB
TypeScript

"use client";
// Diff modal for the mission Refine flow. Shows the original
// description (raw) side-by-side with the LLM-refined version
// (rendered as Markdown). Accept / Cancel / Restore-original.
import { MarkdownBlock } from "./MarkdownBlock";
const mono =
"ui-monospace, SFMono-Regular, SF Mono, Menlo, Monaco, Consolas, monospace";
export function RefineDiffModal({
original,
refined,
busy,
onAccept,
onCancel,
onUndoAfterAccept,
}: {
original: string;
refined: string;
busy: boolean;
onAccept: () => void;
onCancel: () => void;
onUndoAfterAccept: () => void;
}) {
return (
<div
role="dialog"
aria-modal
onClick={onCancel}
style={{
position: "fixed",
inset: 0,
background: "rgba(0,0,0,.6)",
display: "flex",
alignItems: "center",
justifyContent: "center",
zIndex: 900,
padding: 24,
}}
>
<div
onClick={(e) => e.stopPropagation()}
style={{
width: "min(1100px, 100%)",
height: "min(720px, calc(100vh - 48px))",
background: "#141419",
borderRadius: 12,
border: "1px solid rgba(255,255,255,.08)",
display: "flex",
flexDirection: "column",
}}
>
<div
style={{
padding: "12px 18px",
borderBottom: "1px solid rgba(255,255,255,.06)",
display: "flex",
alignItems: "center",
gap: 10,
}}
>
<span
style={{
fontFamily: mono,
fontSize: 10.5,
letterSpacing: ".14em",
color: "#ffb44a",
textTransform: "uppercase",
}}
>
Refine — review before/after
</span>
<span style={{ flex: 1 }} />
<button
type="button"
onClick={onUndoAfterAccept}
disabled={busy}
title="Restore the original description (drops the refinement)"
style={{
padding: "5px 12px",
borderRadius: 8,
border: "1px solid rgba(255,255,255,.1)",
background: "transparent",
color: "#a0a0a8",
fontSize: 12,
cursor: "pointer",
opacity: busy ? 0.5 : 1,
}}
>
Restore original
</button>
<button
type="button"
onClick={onCancel}
disabled={busy}
style={{
padding: "5px 12px",
borderRadius: 8,
border: "1px solid rgba(255,255,255,.1)",
background: "transparent",
color: "#a0a0a8",
fontSize: 12,
cursor: "pointer",
opacity: busy ? 0.5 : 1,
}}
>
Cancel
</button>
<button
type="button"
onClick={onAccept}
disabled={busy}
style={{
padding: "5px 14px",
borderRadius: 8,
border: "1px solid rgba(127,208,160,.5)",
background: "rgba(127,208,160,.12)",
color: "#7fd0a0",
fontSize: 12,
cursor: "pointer",
opacity: busy ? 0.5 : 1,
}}
>
{busy ? "Applying…" : "Accept"}
</button>
</div>
<div
style={{
flex: 1,
minHeight: 0,
display: "grid",
gridTemplateColumns: "1fr 1fr",
gap: 1,
background: "rgba(255,255,255,.06)",
}}
>
<DiffPane
title="Before"
color="#8a8a92"
body={original}
renderAsMarkdown={false}
/>
<DiffPane
title="After"
color="#7fd0a0"
body={refined}
renderAsMarkdown
/>
</div>
</div>
</div>
);
}
function DiffPane({
title,
color,
body,
renderAsMarkdown,
}: {
title: string;
color: string;
body: string;
renderAsMarkdown: boolean;
}) {
return (
<div
style={{
background: "#0e0e12",
display: "flex",
flexDirection: "column",
minHeight: 0,
}}
>
<div
style={{
padding: "8px 14px",
borderBottom: "1px solid rgba(255,255,255,.05)",
fontFamily: mono,
fontSize: 10,
letterSpacing: ".14em",
color,
textTransform: "uppercase",
}}
>
{title}
</div>
<div style={{ flex: 1, minHeight: 0, overflow: "auto", padding: 14 }}>
{renderAsMarkdown ? (
<MarkdownBlock source={body} />
) : (
<pre
style={{
margin: 0,
whiteSpace: "pre-wrap",
wordBreak: "break-word",
fontFamily: mono,
fontSize: 12,
color: "#cfcfd5",
lineHeight: 1.55,
}}
>
{body}
</pre>
)}
</div>
</div>
);
}