Skip to content

Commit

Permalink
enhance: update workflow step UX
Browse files Browse the repository at this point in the history
- adding a step auto-adds a generic step. No longer need to specify step type when adding
- step types can be updated via dropdown on the step list item
  • Loading branch information
ryanhopperlowe committed Dec 31, 2024
1 parent c85722d commit e159925
Show file tree
Hide file tree
Showing 12 changed files with 547 additions and 674 deletions.
6 changes: 4 additions & 2 deletions ui/admin/app/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { forwardRef, useImperativeHandle } from "react";

import { cn } from "~/lib/utils";

// note: use outline instead of ring to avoid overriding the ring from the outline variant
const textareaVariants = cva(
"flex w-full rounded-md bg-transparent text-sm placeholder:text-muted-foreground has-[:focus-visible]:ring-1 has-[:focus-visible]:ring-ring group group-disabled:cursor-not-allowed group-disabled:bg-opacity-50",
"flex w-full rounded-md bg-transparent text-sm placeholder:text-muted-foreground has-[:focus-visible]:outline has-[:focus-visible]:outline-1 has-[:focus-visible]:outline-ring group group-disabled:cursor-not-allowed group-disabled:bg-opacity-50",
{
variants: {
variant: {
outlined: "border border-input shadow-sm",
// note: use inset ring instead of border so that the wrapper doesn't add any extra height or width
outlined: "ring-1 ring-inset ring-input",
flat: "border-none shadow-none bg-muted",
},
},
Expand Down
135 changes: 9 additions & 126 deletions ui/admin/app/components/workflow/steps/AddStep.tsx
Original file line number Diff line number Diff line change
@@ -1,140 +1,23 @@
import { ArrowRight, GitFork, Plus, RotateCw } from "lucide-react";
import { useMemo, useState } from "react";
import useSWR from "swr";
import { PlusIcon } from "lucide-react";

import {
ToolReference,
toolReferenceToTemplate,
} from "~/lib/model/toolReferences";
import { Step, getDefaultStep } from "~/lib/model/workflows";
import { ToolReferenceService } from "~/lib/service/api/toolreferenceService";

import { Button } from "~/components/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "~/components/ui/dialog";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import { ScrollArea } from "~/components/ui/scroll-area";
import { StepTemplateCard } from "~/components/workflow/steps/StepTemplateCard";

type StepType = "regular" | "if" | "while" | "template";

interface AddStepButtonProps {
onAddStep: (newStep: Step) => void;
className?: string;
}

export function AddStepButton({ onAddStep, className }: AddStepButtonProps) {
const [open, setOpen] = useState(false);
const [isTemplateModalOpen, setIsTemplateModalOpen] = useState(false);

const getStepTemplates = useSWR(
ToolReferenceService.getToolReferences.key("stepTemplate"),
() => ToolReferenceService.getToolReferences("stepTemplate")
);

const stepTemplates = useMemo(() => {
if (!getStepTemplates.data) return [];
return getStepTemplates.data;
}, [getStepTemplates.data]);

const createNewStep = (type: StepType) => {
if (type === "template") {
setIsTemplateModalOpen(true);
} else {
const newStep = getDefaultStep();

if (type === "if") {
newStep.if = { condition: "", steps: [], else: [] };
} else if (type === "while") {
newStep.while = { condition: "", maxLoops: 0, steps: [] };
}

onAddStep(newStep);
setOpen(false);
}
};

const handleStepTemplateSelection = (stepTemplate: ToolReference) => {
const newStep: Step = {
id: Date.now().toString(),
name: stepTemplate.name,
description: "",
template: toolReferenceToTemplate(stepTemplate),
cache: false,
temperature: 0,
tools: [],
agents: [],
workflows: [],
};
onAddStep(newStep);
setIsTemplateModalOpen(false);
};

return (
<>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button variant="ghost" className={className}>
<Plus /> Add Step
</Button>
</PopoverTrigger>

<PopoverContent
className="w-22 bg-secondary dark:bg-zinc-800 shadow-2xl"
side="top"
>
<div className="grid gap-4">
<Button
className="dark:bg-zinc-600 dark:text-white"
onClick={() => createNewStep("while")}
>
<RotateCw className="w-4 h-4 mr-2" /> While
</Button>
<Button
className="dark:bg-zinc-600 dark:text-white"
onClick={() => createNewStep("if")}
>
<GitFork className="w-4 h-4 mr-2" /> If
</Button>
<Button
className="dark:bg-zinc-600 dark:text-white"
onClick={() => createNewStep("regular")}
>
<ArrowRight className="w-4 h-4 mr-2" /> Step
</Button>
</div>
</PopoverContent>
</Popover>

<Dialog
open={isTemplateModalOpen}
onOpenChange={setIsTemplateModalOpen}
>
<DialogContent className="min-w-[50vw] max-h-[80vh]">
<DialogHeader>
<DialogTitle>Select a Template</DialogTitle>
</DialogHeader>
<ScrollArea className="grid gap-4 h-[70vh]">
{stepTemplates.map((template, index) => (
<StepTemplateCard
key={index}
stepTemplate={template}
onClick={() =>
handleStepTemplateSelection(template)
}
/>
))}
</ScrollArea>
</DialogContent>
</Dialog>
</>
<Button
variant="ghost"
className={className}
startContent={<PlusIcon />}
onClick={() => onAddStep(getDefaultStep())}
>
Add Step
</Button>
);
}
154 changes: 0 additions & 154 deletions ui/admin/app/components/workflow/steps/If.tsx

This file was deleted.

Loading

0 comments on commit e159925

Please sign in to comment.