From a981a8bba468bbc3268812653597e1f306a3a7f9 Mon Sep 17 00:00:00 2001 From: Doug Beatty <123423698+wcatbb@users.noreply.github.com> Date: Sun, 12 Apr 2026 00:12:56 -0500 Subject: [PATCH] Improve template template loading and debounced search --- apps/web/src/pages/workflows/[id].tsx | 125 +++++++++++++++++++------- 1 file changed, 92 insertions(+), 33 deletions(-) diff --git a/apps/web/src/pages/workflows/[id].tsx b/apps/web/src/pages/workflows/[id].tsx index 4288b89..b3c38e8 100644 --- a/apps/web/src/pages/workflows/[id].tsx +++ b/apps/web/src/pages/workflows/[id].tsx @@ -56,7 +56,7 @@ import { } from 'lucide-react'; import Link from 'next/link'; import {useRouter} from 'next/router'; -import {useEffect, useState} from 'react'; +import {useCallback, useEffect, useRef, useState} from 'react'; import {toast} from 'sonner'; import useSWR from 'swr'; import {WorkflowBuilder} from '../../components/WorkflowBuilder'; @@ -1004,7 +1004,7 @@ function AddStepDialog({open, onOpenChange, workflowId, onSuccess}: AddStepDialo const [isSubmitting, setIsSubmitting] = useState(false); - const {data: templatesData} = useSWR>('/templates?pageSize=100'); + // templates fetched on-demand by TemplateSearchPicker const {data: workflow} = useSWR(workflowId ? `/workflows/${workflowId}` : null); // Fetch available event names when dialog opens @@ -1340,21 +1340,7 @@ function AddStepDialog({open, onOpenChange, workflowId, onSuccess}: AddStepDialo - +

The email template to use for this step

@@ -1872,6 +1858,93 @@ function AddStepDialog({open, onOpenChange, workflowId, onSuccess}: AddStepDialo ); } +// TemplateSearchPicker — server-side debounced search, replaces the static { setOpen(true); setDebouncedQuery(query); }} + onBlur={() => setTimeout(() => setOpen(false), 150)} + placeholder="Search templates…" + autoComplete="off" + /> + {open && ( +
+ {isLoading ? ( +
Searching…
+ ) : !data?.data.length ? ( +
No templates found
+ ) : ( + + + + {data.data.map(t => ( + { + onChange(t.id); + setQuery(t.name); + setOpen(false); + }} + > + {t.name} + {t.type} + + ))} + + + + )} + {(data?.total ?? 0) > 20 && ( +
+ Showing 20 of {data!.total} — type to narrow results +
+ )} +
+ )} + + ); +} + // Edit Step Dialog Component interface EditStepDialogProps { step: WorkflowStep & {template?: {id: string; name: string} | null}; @@ -2073,7 +2146,7 @@ function EditStepDialog({step, workflowId, open, onOpenChange, onSuccess}: EditS // EXIT fields const [exitReason, setExitReason] = useState(String(config?.reason || 'completed')); - const {data: templatesData} = useSWR>('/templates?pageSize=100'); + // templates fetched on-demand by TemplateSearchPicker const {data: workflow} = useSWR(workflowId ? `/workflows/${workflowId}` : null); // Fetch available event names when dialog opens @@ -2359,21 +2432,7 @@ function EditStepDialog({step, workflowId, open, onOpenChange, onSuccess}: EditS - +

The email template to use for this step