← Files NGS Analysis WorkbenchARCHIVED FILE
src/report/ReportArtifactRow.tsx
2.05 KB · Sep 30, 2026 · 23:20 UTC
import { Icon, type IconName } from "../design-system/Icon";
import { useState } from "react";
import { CopyButton } from "../components/CopyButton";
import ui from "../styles/ui.module.css";
import styles from "./AnalysisReport.module.css";
import { humanize, joinRunPath } from "./format";
import type { ReportArtifact } from "./types";
export function ReportArtifactRow({
artifact,
onOpen,
runDirectory,
}: {
artifact: ReportArtifact;
onOpen?: (artifact: ReportArtifact) => void | Promise<void>;
runDirectory: string;
}) {
const [opening, setOpening] = useState(false);
const canOpen = Boolean(onOpen && artifact.openUrl);
const canCopy = Boolean(artifact.path && !canOpen);
const openLabel = "Open";
return (
<div className={styles.artifactRow}>
<KindMark kind={artifact.kind} />
<div className={styles.artifactCopy}>
<strong>{artifact.title}</strong>
<p>{artifact.description}</p>
<small>
{humanize(artifact.kind)}
{artifact.size ? ` · ${artifact.size}` : ""}
</small>
</div>
{canOpen ? (
<button
aria-label={`${openLabel} ${artifact.title}`}
className={`${ui.button} ${ui.buttonQuiet}`}
disabled={opening}
onClick={() => {
setOpening(true);
void Promise.resolve(onOpen?.(artifact)).finally(() =>
setOpening(false),
);
}}
type="button"
>
{opening ? "Opening…" : openLabel}
</button>
) : canCopy && artifact.path ? (
<CopyButton
value={joinRunPath(runDirectory, artifact.path)}
accessibleLabel={`Copy path for ${artifact.title}`}
/>
) : null}
</div>
);
}
function KindMark({ kind }: { kind: string }) {
const name: IconName =
kind === "html_report" || kind === "localhost_app"
? "bar-chart"
: kind === "table"
? "square-grid"
: "upload-documents";
return (
<span className={styles.kindMark}>
<Icon name={name} size={20} />
</span>
);
}
SHA-256: 5e51009774cc344dcc5d855ac2c29b2d95f713d058eb813b7bc3aeb3a20c0234