fix(web): render media card outputs with the URL-based previews
The media pipeline moved image and file previews to the artifact route, so they no longer take a bot or group target. The media card still passed one, which no longer type-checks; only its follow-up actions need the target. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
This commit is contained in:
parent
46349acbd1
commit
0c2b6dd666
@ -29,7 +29,6 @@ vi.mock("../../lib/artifact-url", () => ({
|
|||||||
|
|
||||||
import { exportPresetsFor, isActiveMediaStatus, MediaCardView } from "./MediaCard";
|
import { exportPresetsFor, isActiveMediaStatus, MediaCardView } from "./MediaCard";
|
||||||
|
|
||||||
const target = { groupId: "group-1" };
|
|
||||||
const video = {
|
const video = {
|
||||||
artifactId: "video-1",
|
artifactId: "video-1",
|
||||||
kind: "video" as const,
|
kind: "video" as const,
|
||||||
@ -64,7 +63,7 @@ describe("media card", () => {
|
|||||||
["failed", "Failed"],
|
["failed", "Failed"],
|
||||||
["cancelled", "Cancelled"],
|
["cancelled", "Cancelled"],
|
||||||
] as const)("labels a %s job as %s", (status, label) => {
|
] as const)("labels a %s job as %s", (status, label) => {
|
||||||
const html = renderToString(<MediaCardView block={block({ status })} target={target} />);
|
const html = renderToString(<MediaCardView block={block({ status })} />);
|
||||||
expect(html).toContain(`data-status="${status}"`);
|
expect(html).toContain(`data-status="${status}"`);
|
||||||
expect(html).toContain(label);
|
expect(html).toContain(label);
|
||||||
expect(html).toContain("Cut the intro");
|
expect(html).toContain("Cut the intro");
|
||||||
@ -74,7 +73,6 @@ describe("media card", () => {
|
|||||||
const html = renderToString(
|
const html = renderToString(
|
||||||
<MediaCardView
|
<MediaCardView
|
||||||
block={block({ status: "running", progress: 0.42, outputs: [video] })}
|
block={block({ status: "running", progress: 0.42, outputs: [video] })}
|
||||||
target={target}
|
|
||||||
available={everything}
|
available={everything}
|
||||||
onAction={noop}
|
onAction={noop}
|
||||||
/>,
|
/>,
|
||||||
@ -88,21 +86,14 @@ describe("media card", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("leaves the progress value out when the backend does not report one", () => {
|
it("leaves the progress value out when the backend does not report one", () => {
|
||||||
const html = renderToString(
|
const html = renderToString(<MediaCardView block={block({ status: "waiting" })} />);
|
||||||
<MediaCardView block={block({ status: "waiting" })} target={target} />,
|
|
||||||
);
|
|
||||||
expect(html).toContain('role="progressbar"');
|
expect(html).toContain('role="progressbar"');
|
||||||
expect(html).not.toContain("aria-valuenow");
|
expect(html).not.toContain("aria-valuenow");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("offers download, export and transcribe for a finished video", () => {
|
it("offers download, export and transcribe for a finished video", () => {
|
||||||
const html = renderToString(
|
const html = renderToString(
|
||||||
<MediaCardView
|
<MediaCardView block={block({ outputs: [video] })} available={everything} onAction={noop} />,
|
||||||
block={block({ outputs: [video] })}
|
|
||||||
target={target}
|
|
||||||
available={everything}
|
|
||||||
onAction={noop}
|
|
||||||
/>,
|
|
||||||
);
|
);
|
||||||
expect(html).toContain('data-player="video"');
|
expect(html).toContain('data-player="video"');
|
||||||
expect(html).toContain('href="/artifact/video-1?download=1"');
|
expect(html).toContain('href="/artifact/video-1?download=1"');
|
||||||
@ -119,7 +110,6 @@ describe("media card", () => {
|
|||||||
const onlyTranscribe = renderToString(
|
const onlyTranscribe = renderToString(
|
||||||
<MediaCardView
|
<MediaCardView
|
||||||
block={block({ outputs: [audio] })}
|
block={block({ outputs: [audio] })}
|
||||||
target={target}
|
|
||||||
available={{ export: true, transcribe: true }}
|
available={{ export: true, transcribe: true }}
|
||||||
onAction={noop}
|
onAction={noop}
|
||||||
/>,
|
/>,
|
||||||
@ -129,7 +119,7 @@ describe("media card", () => {
|
|||||||
expect(onlyTranscribe).not.toContain("Export");
|
expect(onlyTranscribe).not.toContain("Export");
|
||||||
|
|
||||||
const nothingAvailable = renderToString(
|
const nothingAvailable = renderToString(
|
||||||
<MediaCardView block={block({ outputs: [video] })} target={target} onAction={noop} />,
|
<MediaCardView block={block({ outputs: [video] })} onAction={noop} />,
|
||||||
);
|
);
|
||||||
expect(nothingAvailable).toContain("Download clip.mp4");
|
expect(nothingAvailable).toContain("Download clip.mp4");
|
||||||
expect(nothingAvailable).not.toContain("Export");
|
expect(nothingAvailable).not.toContain("Export");
|
||||||
@ -147,7 +137,6 @@ describe("media card", () => {
|
|||||||
{ ...video, artifactId: "vtt-1", kind: "file", name: "clip.vtt" },
|
{ ...video, artifactId: "vtt-1", kind: "file", name: "clip.vtt" },
|
||||||
],
|
],
|
||||||
})}
|
})}
|
||||||
target={target}
|
|
||||||
available={everything}
|
available={everything}
|
||||||
onAction={noop}
|
onAction={noop}
|
||||||
/>,
|
/>,
|
||||||
@ -160,10 +149,7 @@ describe("media card", () => {
|
|||||||
|
|
||||||
it("shows why a job failed", () => {
|
it("shows why a job failed", () => {
|
||||||
const html = renderToString(
|
const html = renderToString(
|
||||||
<MediaCardView
|
<MediaCardView block={block({ status: "failed", error: "GPU server is unreachable" })} />,
|
||||||
block={block({ status: "failed", error: "GPU server is unreachable" })}
|
|
||||||
target={target}
|
|
||||||
/>,
|
|
||||||
);
|
);
|
||||||
expect(html).toContain("GPU server is unreachable");
|
expect(html).toContain("GPU server is unreachable");
|
||||||
});
|
});
|
||||||
|
|||||||
@ -174,12 +174,10 @@ function OutputActions({
|
|||||||
*/
|
*/
|
||||||
export function MediaCardView({
|
export function MediaCardView({
|
||||||
block,
|
block,
|
||||||
target,
|
|
||||||
available = NOTHING_AVAILABLE,
|
available = NOTHING_AVAILABLE,
|
||||||
onAction,
|
onAction,
|
||||||
}: {
|
}: {
|
||||||
block: MediaJobBlock;
|
block: MediaJobBlock;
|
||||||
target: ArtifactTarget;
|
|
||||||
available?: MediaCardAvailability;
|
available?: MediaCardAvailability;
|
||||||
/** Starts a follow-up job or cancels this one; rejects with a message to show. */
|
/** Starts a follow-up job or cancels this one; rejects with a message to show. */
|
||||||
onAction?: (action: MediaCardAction) => Promise<void>;
|
onAction?: (action: MediaCardAction) => Promise<void>;
|
||||||
@ -263,7 +261,6 @@ export function MediaCardView({
|
|||||||
{images.map((output) => (
|
{images.map((output) => (
|
||||||
<ArtifactImage
|
<ArtifactImage
|
||||||
key={output.artifactId}
|
key={output.artifactId}
|
||||||
target={target}
|
|
||||||
artifactId={output.artifactId}
|
artifactId={output.artifactId}
|
||||||
name={output.name}
|
name={output.name}
|
||||||
/>
|
/>
|
||||||
@ -288,7 +285,6 @@ export function MediaCardView({
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<ArtifactFileCard
|
<ArtifactFileCard
|
||||||
target={target}
|
|
||||||
artifactId={output.artifactId}
|
artifactId={output.artifactId}
|
||||||
name={output.name}
|
name={output.name}
|
||||||
mimeType={output.mimeType}
|
mimeType={output.mimeType}
|
||||||
@ -386,5 +382,5 @@ export function MediaCard({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return <MediaCardView block={block} target={target} available={available} onAction={onAction} />;
|
return <MediaCardView block={block} available={available} onAction={onAction} />;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user