feat(platform): Updates to Runner Output UI (#8717)
* feat(platform): Updates to Runner Output UI * add copy text button to output boxes * prettier --------- Co-authored-by: Aarushi <50577581+aarushik93@users.noreply.github.com>zamilmajdy/secrt-1000-add-capability-for-the-admin-to-log-in-as-other-users^2
parent
19095be249
commit
63e3244e7e
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue