feat(frontend/library): Make agent input fields expandable (#9650)

- Resolves #9622

### Changes 🏗️

- Add pop-out button + modal to input fields in Agent Run Draft view on
`/library/agents/[id]`
- Fix `icon`-variant button styling

![the expand button on the input
fields](https://github.com/user-attachments/assets/00be33fe-44d1-490a-9cab-9696df8f6e6f)
![the expanded input modal that
appears](https://github.com/user-attachments/assets/787f33b9-d884-467b-b99b-dcbec8a1d059)

### Checklist 📋

#### For code changes:
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
  - Go to an agent's page -> click "+ New run"
    - [x] -> pop-out button should show on all input fields
- Enter a value in one of the inputs; click the pop-out button on that
input
    - [x] -> input modal with large text field should open
- [x] -> the value you just entered should be present in the modal's
text field
  - Edit the value & click "Save"
    - [x] -> the modal should close
- [x] -> the value in the corresponding input field should be updated
This commit is contained in:
Reinier van der Leer
2025-03-18 15:52:30 +01:00
committed by GitHub
parent 067983eb80
commit a187e87741
2 changed files with 84 additions and 13 deletions

View File

@@ -6,9 +6,17 @@ import { GraphExecutionID, GraphMeta } from "@/lib/autogpt-server-api";
import type { ButtonAction } from "@/components/agptui/types";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button, ButtonProps } from "@/components/agptui/Button";
import { LocalValuedInput } from "@/components/ui/input";
import { Pencil2Icon } from "@radix-ui/react-icons";
import { Textarea } from "@/components/ui/textarea";
import { IconPlay } from "@/components/ui/icons";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/agptui/Button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
export default function AgentRunDraftView({
graph,
@@ -23,6 +31,27 @@ export default function AgentRunDraftView({
const agentInputs = graph.input_schema.properties;
const [inputValues, setInputValues] = useState<Record<string, any>>({});
const [expandedInputKey, setExpandedInputKey] = useState<string | null>(null);
const [tempInputValue, setTempInputValue] = useState("");
const openInputPopout = useCallback(
(key: string) => {
setTempInputValue(inputValues[key] || "");
setExpandedInputKey(key);
},
[inputValues],
);
const closeInputPopout = useCallback(() => {
setExpandedInputKey(null);
}, []);
const saveAndCloseInputPopout = useCallback(() => {
if (!expandedInputKey) return;
setInputValues((obj) => ({ ...obj, [expandedInputKey]: tempInputValue }));
closeInputPopout();
}, [expandedInputKey, tempInputValue, closeInputPopout]);
const doRun = useCallback(
() =>
@@ -61,22 +90,64 @@ export default function AgentRunDraftView({
<label className="text-sm font-medium">
{inputSubSchema.title || key}
</label>
<Input
// TODO: render specific inputs based on input types
defaultValue={
"default" in inputSubSchema ? inputSubSchema.default : ""
}
className="rounded-full"
onChange={(e) =>
setInputValues((obj) => ({ ...obj, [key]: e.target.value }))
}
/>
<div className="nodrag relative">
<LocalValuedInput
// TODO: render specific inputs based on input types
defaultValue={
"default" in inputSubSchema ? inputSubSchema.default : ""
}
value={inputValues[key] ?? undefined}
className="rounded-full"
onChange={(e) =>
setInputValues((obj) => ({
...obj,
[key]: e.target.value,
}))
}
/>
<Button
variant="ghost"
size="icon"
className="absolute inset-1 left-auto h-7 w-8 rounded-full"
onClick={() => openInputPopout(key)}
title="Open a larger textbox input"
>
<Pencil2Icon className="m-0 p-0" />
</Button>
</div>
</div>
))}
</CardContent>
</Card>
</div>
{/* Pop-out Long Input Modal */}
<Dialog
open={expandedInputKey !== null}
onOpenChange={(open) => !open && closeInputPopout()}
>
<DialogContent className="sm:max-w-[720px]">
<DialogHeader>
<DialogTitle>
Edit {expandedInputKey && agentInputs[expandedInputKey].title}
</DialogTitle>
</DialogHeader>
<Textarea
value={tempInputValue}
onChange={(e) => setTempInputValue(e.target.value)}
className="min-h-[320px]"
/>
<div className="flex justify-end gap-2">
<Button onClick={closeInputPopout}>Cancel</Button>
<Button variant="primary" onClick={saveAndCloseInputPopout}>
Save
</Button>
</div>
</DialogContent>
</Dialog>
{/* Actions */}
<aside className="w-48 xl:w-56">
<div className="flex flex-col gap-8">

View File

@@ -29,7 +29,7 @@ const buttonVariants = cva(
lg: "h-12 px-5 py-2.5 rounded-full text-lg",
primary:
"h-10 w-28 rounded-full sm:h-12 sm:w-32 md:h-[4.375rem] md:w-[11rem] lg:h-[3.125rem] lg:w-[7rem]",
icon: "h-10 w-10",
icon: "h-10 w-10 justify-center",
card: "h-12 p-5 agpt-rounded-card justify-center text-lg",
},
},