"use client"; /** * Automations editor — TRIGGERS section (1..3, OR-semantics). * Per-type config inputs per @factory/shared/automation trigger schemas: * RECORD_CREATED / PAGE_CREATED / FORM_SUBMITTED / MANUAL / SCHEDULE: * optional databaseId (record/form ones); SCHEDULE adds cron + timezone. * RECORD_UPDATED / PROPERTY_CHANGED: optional `properties` (comma list; * REQUIRED non-empty for PROPERTY_CHANGED). * WEBHOOK: read-only URL + webhookId + "Regenerate secret" button. */ import { useEffect, useState } from "react"; import { Loader2, Plus, RefreshCw, Trash2 } from "lucide-react"; import { workspaceApi } from "@/lib/api"; import { inputCls } from "@/components/settings/settings-shell"; import { AUTOMATION_MAX_TRIGGERS, AUTOMATION_TRIGGER_TYPES, TRIGGER_LABELS, type AutomationTriggerType, type TriggerDraft } from "./lib"; const SELECT_TYPES = new Set(["RECORD_CREATED", "RECORD_UPDATED", "PROPERTY_CHANGED", "FORM_SUBMITTED"]); interface TriggerEditorProps { triggers: TriggerDraft[]; onChange: (triggers: TriggerDraft[]) => void; workspaceId: string; /** Webhook secret regeneration (parent owns the mutation + one-time reveal). */ onRegenerateWebhook?: () => void; regenerating?: boolean; } export function TriggerEditor({ triggers, onChange, workspaceId, onRegenerateWebhook, regenerating }: TriggerEditorProps) { const [databases, setDatabases] = useState<{ id: string; title: string }[]>([]); useEffect(() => { if (!workspaceId) return; workspaceApi .databases(workspaceId, { limit: 100 }) .then((dbs) => setDatabases(dbs.map((d) => ({ id: d.id, title: d.title })))) .catch(() => setDatabases([])); }, [workspaceId]); const update = (i: number, patch: Partial) => { const next = [...triggers]; next[i] = { ...next[i]!, ...patch }; onChange(next); }; const updateConfig = (i: number, key: string, value: string) => { const t = triggers[i]!; update(i, { config: { ...t.config, [key]: value } }); }; const add = () => { if (triggers.length >= AUTOMATION_MAX_TRIGGERS) return; onChange([...triggers, { type: "MANUAL", config: {} }]); }; const remove = (i: number) => onChange(triggers.filter((_t, idx) => idx !== i)); return (
{triggers.length === 0 &&

No triggers yet — the automation only runs manually via the Run now button.

} {triggers.map((t, i) => (
{i + 1}.
{SELECT_TYPES.has(t.type) && ( )} {(t.type === "RECORD_UPDATED" || t.type === "PROPERTY_CHANGED") && ( )} {t.type === "SCHEDULE" && ( <> )} {t.type === "WEBHOOK" && (
{t.config.webhookId ? ( <>
{String(t.config.url ?? "")} {onRegenerateWebhook && ( )}

POST to this URL with the X-FS-Signature header. webhookId: {String(t.config.webhookId)}

) : (

The webhook URL + a one-time secret are generated when you save.

)}
)} {(t.type === "PAGE_CREATED" || t.type === "MANUAL") && (

No extra configuration.

)}
))} {triggers.length < AUTOMATION_MAX_TRIGGERS && ( )}
); }