import { useEffect, useMemo, useState } from "react"; import { ChevronDown, ChevronRight } from "lucide-react"; import { syncRoutineVariablesWithTemplate, type RoutineVariable } from "@paperclipai/shared"; import { Badge } from "@/components/ui/badge"; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; const variableTypes: RoutineVariable["type"][] = ["text", "textarea", "number", "boolean", "select"]; function serializeVariables(value: RoutineVariable[]) { return JSON.stringify(value); } function parseSelectOptions(value: string) { return value .split(",") .map((entry) => entry.trim()) .filter(Boolean); } function updateVariableList( variables: RoutineVariable[], name: string, mutate: (variable: RoutineVariable) => RoutineVariable, ) { return variables.map((variable) => (variable.name === name ? mutate(variable) : variable)); } export function RoutineVariablesEditor({ description, value, onChange, }: { description: string; value: RoutineVariable[]; onChange: (value: RoutineVariable[]) => void; }) { const [open, setOpen] = useState(true); const syncedVariables = useMemo( () => syncRoutineVariablesWithTemplate(description, value), [description, value], ); const syncedSignature = serializeVariables(syncedVariables); const currentSignature = serializeVariables(value); useEffect(() => { if (syncedSignature !== currentSignature) { onChange(syncedVariables); } }, [currentSignature, onChange, syncedSignature, syncedVariables]); if (syncedVariables.length === 0) { return null; } return (

Variables

Detected from `{"{{name}}"}` placeholders in the routine instructions.

{open ? : }
{syncedVariables.map((variable) => (
{`{{${variable.name}}}`} Prompt the user for this value before each manual run.
onChange(updateVariableList(syncedVariables, variable.name, (current) => ({ ...current, label: event.target.value || null, })))} placeholder={variable.name.replaceAll("_", " ")} />
{variable.type === "textarea" ? (