Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(platform): Updates to Runner Output UI #8717

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect, useRef } from "react";
import {
Sheet,
SheetContent,
Expand All @@ -10,6 +10,9 @@ import { ScrollArea } from "@/components/ui/scroll-area";
import { BlockIORootSchema } from "@/lib/autogpt-server-api/types";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Clipboard } from "lucide-react";
import { useToast } from "@/components/ui/use-toast";

export interface BlockOutput {
id: string;
Expand All @@ -29,11 +32,20 @@ interface OutputModalProps {
const formatOutput = (output: any): string => {
if (typeof output === "object") {
try {
if (
Array.isArray(output) &&
output.every((item) => typeof item === "string")
) {
return output.join("\n").replace(/\\n/g, "\n");
}
return JSON.stringify(output, null, 2);
} catch (error) {
return `Error formatting output: ${(error as Error).message}`;
}
}
if (typeof output === "string") {
return output.replace(/\\n/g, "\n");
}
return String(output);
};

Expand All @@ -42,11 +54,28 @@ export function RunnerOutputUI({
onClose,
blockOutputs,
}: OutputModalProps) {
const { toast } = useToast();

const copyOutput = (name: string, output: any) => {
const formattedOutput = formatOutput(output);
navigator.clipboard.writeText(formattedOutput).then(() => {
toast({
title: `"${name}" output copied to clipboard!`,
duration: 2000,
});
});
};

const adjustTextareaHeight = (textarea: HTMLTextAreaElement) => {
textarea.style.height = "auto";
textarea.style.height = `${textarea.scrollHeight}px`;
};

return (
<Sheet open={isOpen} onOpenChange={onClose}>
<SheetContent
side="right"
className="flex h-full w-full flex-col overflow-hidden sm:max-w-[500px]"
className="flex h-full w-full flex-col overflow-hidden sm:max-w-[600px]"
>
<SheetHeader className="px-2 py-2">
<SheetTitle className="text-xl">Run Outputs</SheetTitle>
Expand All @@ -70,11 +99,38 @@ export function RunnerOutputUI({
</Label>
)}

<div className="rounded-md bg-gray-100 p-2">
<div className="group relative rounded-md bg-gray-100 p-2">
<Button
className="absolute right-1 top-1 z-10 m-1 hidden p-2 group-hover:block"
variant="outline"
size="icon"
onClick={() =>
copyOutput(
block.hardcodedValues.name || "Unnamed Output",
block.result,
)
}
title="Copy Output"
>
<Clipboard size={18} />
</Button>
<Textarea
readOnly
value={formatOutput(block.result ?? "No output yet")}
className="resize-none whitespace-pre-wrap break-words border-none bg-transparent text-sm"
className="w-full resize-none whitespace-pre-wrap break-words border-none bg-transparent text-sm"
style={{
height: "auto",
minHeight: "2.5rem",
maxHeight: "400px",
}}
ref={(el) => {
if (el) {
adjustTextareaHeight(el);
if (el.scrollHeight > 400) {
el.style.height = "400px";
}
}
}}
/>
</div>
</div>
Expand Down
Loading