diff --git a/web/app/(app)/workflows/page.tsx b/web/app/(app)/workflows/page.tsx
index 828b33d..a028da5 100644
--- a/web/app/(app)/workflows/page.tsx
+++ b/web/app/(app)/workflows/page.tsx
@@ -73,7 +73,7 @@ export default function WorkflowsPage() {
}
- action={{ label: "Create your first workflow", onClick: () => create() }}
+ action={{ label: "Create your first workflow", onClick: () => create(), loading: isPending }}
/>
}
>
diff --git a/web/components/ui/Async.tsx b/web/components/ui/Async.tsx
index 8850fd1..29cd1d0 100644
--- a/web/components/ui/Async.tsx
+++ b/web/components/ui/Async.tsx
@@ -63,7 +63,15 @@ export function EmptyState({
title: string;
description?: string;
icon?: React.ReactNode;
- action?: { label: string; href?: string; onClick?: () => void };
+ /*
+ * `loading` matters rather than being decoration: the empty-state button is
+ * usually the one that creates the first of something, and without it a
+ * double click creates two. A link action takes neither — there is no
+ * pending state to show for a navigation.
+ */
+ action?:
+ | { label: string; href: string; onClick?: never; loading?: never; disabled?: never }
+ | { label: string; href?: never; onClick: () => void; loading?: boolean; disabled?: boolean };
}) {
return (
@@ -80,7 +88,14 @@ export function EmptyState({
{action.label}
) : (
-