mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(site/src/pages/AgentsPage): add copy buttons to raw attempts (#24705)
This commit is contained in:
+14
-12
@@ -9,7 +9,7 @@ import {
|
||||
import { cn } from "#/utils/cn";
|
||||
import { DATE_FORMAT, formatDateTime, humanDuration } from "#/utils/time";
|
||||
import {
|
||||
DebugCodeBlock,
|
||||
CopyableCodeBlock,
|
||||
DebugDataSection,
|
||||
EmptyHelper,
|
||||
} from "./DebugPanelPrimitives";
|
||||
@@ -27,24 +27,23 @@ interface DebugAttemptAccordionProps {
|
||||
|
||||
interface JsonBlockProps {
|
||||
value: unknown;
|
||||
fallbackCopy: string;
|
||||
emptyMessage: string;
|
||||
copyLabel: string;
|
||||
}
|
||||
|
||||
const JsonBlock: FC<JsonBlockProps> = ({ value, fallbackCopy }) => {
|
||||
const JsonBlock: FC<JsonBlockProps> = ({ value, emptyMessage, copyLabel }) => {
|
||||
if (
|
||||
value === null ||
|
||||
value === undefined ||
|
||||
(typeof value === "string" && value.length === 0) ||
|
||||
(typeof value === "object" && Object.keys(value as object).length === 0)
|
||||
) {
|
||||
return <EmptyHelper message={fallbackCopy} />;
|
||||
return <EmptyHelper message={emptyMessage} />;
|
||||
}
|
||||
|
||||
if (typeof value === "string") {
|
||||
return <DebugCodeBlock code={value} />;
|
||||
}
|
||||
const code = safeJsonStringify(value);
|
||||
|
||||
return <DebugCodeBlock code={safeJsonStringify(value)} />;
|
||||
return <CopyableCodeBlock code={code} label={copyLabel} />;
|
||||
};
|
||||
|
||||
const getAttemptTimingLabel = (attempt: NormalizedAttempt): string => {
|
||||
@@ -79,7 +78,7 @@ export const DebugAttemptAccordion: FC<DebugAttemptAccordionProps> = ({
|
||||
Unable to parse raw attempts. Showing the original payload exactly as
|
||||
it was captured.
|
||||
</p>
|
||||
<DebugCodeBlock code={rawFallback} />
|
||||
<CopyableCodeBlock code={rawFallback} label="Copy raw attempts" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -161,19 +160,22 @@ export const DebugAttemptAccordion: FC<DebugAttemptAccordionProps> = ({
|
||||
<DebugDataSection title="Raw request">
|
||||
<JsonBlock
|
||||
value={attempt.raw_request}
|
||||
fallbackCopy="No raw request captured."
|
||||
emptyMessage="No raw request captured."
|
||||
copyLabel="Copy raw request JSON"
|
||||
/>
|
||||
</DebugDataSection>
|
||||
<DebugDataSection title="Raw response">
|
||||
<JsonBlock
|
||||
value={attempt.raw_response}
|
||||
fallbackCopy="No raw response captured."
|
||||
emptyMessage="No raw response captured."
|
||||
copyLabel="Copy raw response JSON"
|
||||
/>
|
||||
</DebugDataSection>
|
||||
<DebugDataSection title="Error">
|
||||
<JsonBlock
|
||||
value={attempt.error}
|
||||
fallbackCopy="No error captured."
|
||||
emptyMessage="No error captured."
|
||||
copyLabel="Copy raw attempt error"
|
||||
/>
|
||||
</DebugDataSection>
|
||||
</div>
|
||||
|
||||
@@ -786,6 +786,19 @@ export const MultiStepRunWithRetries: Story = {
|
||||
expect(canvas.getByText(/Attempt 2/)).toBeVisible();
|
||||
expect(canvas.getByText(/Attempt 3/)).toBeVisible();
|
||||
});
|
||||
|
||||
await user.click(canvas.getByRole("button", { name: /Attempt 1/i }));
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
canvas.getByRole("button", { name: /Copy raw request JSON/i }),
|
||||
).toBeVisible();
|
||||
expect(
|
||||
canvas.getByRole("button", { name: /Copy raw response JSON/i }),
|
||||
).toBeVisible();
|
||||
expect(
|
||||
canvas.getByRole("button", { name: /Copy raw attempt error/i }),
|
||||
).toBeVisible();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -33,10 +33,7 @@ interface DebugCodeBlockProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const DebugCodeBlock: FC<DebugCodeBlockProps> = ({
|
||||
code,
|
||||
className,
|
||||
}) => {
|
||||
const DebugCodeBlock: FC<DebugCodeBlockProps> = ({ code, className }) => {
|
||||
return (
|
||||
<pre
|
||||
className={cn(
|
||||
|
||||
Reference in New Issue
Block a user