Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion docs/design/automations-ux-rework/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Current state

Checkpoints 1 and 2 implemented in code and linted. Checkpoint 3 not started.
Checkpoints 1, 2, and 3 implemented in code. Checkpoint 3 logs UI redesigned for clarity.

## Checkpoint 1: Remove gate, auto-ping, restore test button

Expand All @@ -26,6 +26,18 @@ Checkpoints 1 and 2 implemented in code and linted. Checkpoint 3 not started.
| 2.5 Add `testDraftAutomationAtom` | Completed | Drawer uses a dedicated draft test atom. |
| 2.6 Enable test button for drafts in drawer | Completed | Test now uses current form values in both create and edit mode. |

## Checkpoint 3: Delivery logs in the drawer

| Task | Status | Notes |
|------|--------|-------|
| 3.1 Add frontend delivery query client | Completed | `queryWebhookDeliveries` added to the automations API client. |
| 3.2 Add delivery query atom family | Completed | Delivery logs are fetched per subscription via `automationDeliveriesAtomFamily`. |
| 3.3 Build logs tab UI | Completed | Drawer now renders a `Logs` tab for persisted automations. |
| 3.4 Delivery detail view | Completed | Simplified: removed overview/JSON tabs, now shows raw JSON directly via `SimpleSharedEditor`. |
| 3.5 Constrain scrolling to the list/detail panes | Completed | Prevented the full drawer tab from growing/scrolling when logs increase; the delivery list now owns list overflow while the JSON editor scrolls internally. |
| 3.6 Redesign delivery list items | Completed | Replaced opaque button rows with `ListItem`-pattern styling: left-border accent on selection, status dots, design-token colors (`bgColors`, `textColors`, `borderColors` from `@agenta/ui`), keyboard navigation, hover feedback. |
| 3.7 Widen drawer layout | Completed | Drawer width increased to accommodate config and log inspection. |

## Decisions log

| Date | Decision | Rationale |
Expand All @@ -36,3 +48,7 @@ Checkpoints 1 and 2 implemented in code and linted. Checkpoint 3 not started.
| 2026-03-13 | Table status stays `Active` in checkpoint 1 | Avoids implying that saved automations are blocked before the log UI exists. |
| 2026-03-13 | Test-draft bypasses event bus entirely | Direct HTTP call via extracted `execute_webhook_request`. No persisted subscription needed. |
| 2026-03-13 | Test button always tests form values | In edit mode, draft testing uses the current form state rather than the persisted subscription. |
| 2026-03-13 | Logs live only on persisted automations | Draft tests are ephemeral, so the drawer exposes logs only after a subscription has been created. |
| 2026-03-13 | Simplify delivery detail to raw JSON only | Overview tab with separate fields added unnecessary complexity; raw JSON is more useful for debugging. |
| 2026-03-13 | Use design tokens for list items | Replaced hard-coded `bg-white` / CSS variable approach with `@agenta/ui` tokens for theme consistency. |
| 2026-03-13 | Deliveries list loads the newest 25 logs | `queryWebhookDeliveries` already supports `Windowing`, but the current drawer uses a simple first page (`limit=25`, `order=descending`) until we add explicit pagination/load-more UX. |
224 changes: 150 additions & 74 deletions web/oss/src/components/Automations/AutomationDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {createElement, useCallback, useEffect, useMemo, useState} from "react"

import {BookOpen} from "@phosphor-icons/react"
import {Button, Collapse, Form, Input, message, Select, Tooltip, Typography} from "antd"
import {Button, Collapse, Form, Input, message, Select, Tabs, Tooltip, Typography} from "antd"
import {useAtom, useSetAtom} from "jotai"

import EnhancedDrawer from "@/oss/components/EnhancedUIs/Drawer"
Expand All @@ -25,6 +25,7 @@ import {

import {AUTOMATION_SCHEMA, EVENT_OPTIONS} from "./assets/constants"
import {AutomationFieldRenderer} from "./AutomationFieldRenderer"
import AutomationLogsTab from "./AutomationLogsTab"
import {RequestPreview} from "./RequestPreview"
import {buildSubscription} from "./utils/buildSubscription"
import {AUTOMATION_TEST_FAILURE_MESSAGE, handleTestResult} from "./utils/handleTestResult"
Expand All @@ -33,6 +34,7 @@ const AutomationDrawer = ({onSuccess}: {onSuccess: () => void}) => {
const [form] = Form.useForm()
const [open, setOpen] = useAtom(isAutomationDrawerOpenAtom)
const [initialValues, setEditingWebhook] = useAtom(editingAutomationAtom)
const [activeTab, setActiveTab] = useState("configuration")
const [isTesting, setIsTesting] = useState(false)
const [isSubmitting, setIsSubmitting] = useState(false)
const setCreatedWebhookSecret = useSetAtom(createdWebhookSecretAtom)
Expand All @@ -52,10 +54,13 @@ const AutomationDrawer = ({onSuccess}: {onSuccess: () => void}) => {

useEffect(() => {
if (!open) {
setActiveTab("configuration")
form.resetFields()
return
}

setActiveTab("configuration")

if (initialValues) {
// Determine provider via heuristic since no meta field is stored.
let isGitHub = false
Expand Down Expand Up @@ -156,6 +161,13 @@ const AutomationDrawer = ({onSuccess}: {onSuccess: () => void}) => {

try {
setIsTesting(true)

if (activeTab === "logs" && initialValues?.id) {
const response = await testAutomation(initialValues.id)
handleTestResult(response)
return
}

const {payload} = await buildPayloadFromForm()
const response = await testDraftAutomation(payload)
handleTestResult(response)
Expand All @@ -166,7 +178,14 @@ const AutomationDrawer = ({onSuccess}: {onSuccess: () => void}) => {
} finally {
setIsTesting(false)
}
}, [buildPayloadFromForm, open, testDraftAutomation])
}, [
activeTab,
buildPayloadFromForm,
initialValues?.id,
open,
testAutomation,
testDraftAutomation,
])

const handleOk = useCallback(async () => {
try {
Expand Down Expand Up @@ -258,6 +277,127 @@ const AutomationDrawer = ({onSuccess}: {onSuccess: () => void}) => {
? "https://agenta.ai/docs/prompt-engineering/integrating-prompts/github"
: "https://agenta.ai/docs/prompt-engineering/integrating-prompts/webhooks"

const drawerTabs = useMemo(
() => [
{
key: "configuration",
label: "Configuration",
children: (
<div className="flex flex-col gap-3">
<div className="mb-4 text-gray-500">
Set up an automation to trigger external services when specific events
occur within Agenta.
</div>

<Form
form={form}
layout="vertical"
requiredMark={false}
onValuesChange={(changedValues) => {
if (changedValues.provider) {
setSelectedProvider(changedValues.provider)
}
}}
>
<div className="flex flex-col gap-3">
<Form.Item
name="provider"
label="Webhook Type"
initialValue="webhook"
className="!mb-0"
>
<Select
disabled={isEdit}
options={providerOptions}
placeholder="Select webhook/github"
/>
</Form.Item>

<Form.Item
name="name"
label="Webhook Name"
className="!mb-0"
rules={[{required: true, message: "Please enter a name"}]}
>
<Input placeholder="Production deploy hook" />
</Form.Item>

<Form.Item
name="events"
label="Event Types"
className="!mb-0"
rules={[
{
required: true,
message: "Please select at least one event",
},
]}
>
<Select
mode="multiple"
placeholder="Select events"
options={EVENT_OPTIONS}
/>
</Form.Item>

{selectedProviderConfig && (
<>
<div className="mt-4 mb-2">
<Typography.Text
type="secondary"
className="font-medium"
>
{selectedProviderConfig.subtitle}
</Typography.Text>
</div>
<AutomationFieldRenderer
fields={selectedProviderConfig.fields}
isEditMode={isEdit}
/>
</>
)}

<Collapse
className="[&_.ant-collapse-content]:bg-transparent"
size="small"
>
<Collapse.Panel
header="Example Request"
key="preview"
forceRender
>
<RequestPreview form={form} />
</Collapse.Panel>
</Collapse>
</div>
</Form>
</div>
),
},
...(initialValues?.id
? [
{
key: "logs",
label: "Logs",
children:
activeTab === "logs" ? (
<AutomationLogsTab subscriptionId={initialValues.id} />
) : null,
},
]
: []),
],
[
activeTab,
form,
initialValues?.id,
isEdit,
providerOptions,
selectedProviderConfig,
setSelectedProvider,
],
)

return (
<>
<EnhancedDrawer
Expand All @@ -277,7 +417,7 @@ const AutomationDrawer = ({onSuccess}: {onSuccess: () => void}) => {
}
open={open}
onClose={onCancel}
width={450}
width={840}
destroyOnHidden
footer={
<div className="flex items-center justify-between gap-2">
Expand All @@ -297,78 +437,14 @@ const AutomationDrawer = ({onSuccess}: {onSuccess: () => void}) => {
</div>
}
>
<div className="mb-4 text-gray-500">
Set up an automation to trigger external services when specific events occur
within Agenta.
<div className="h-full min-h-0 [&_.ant-tabs-content]:h-full [&_.ant-tabs-content-holder]:h-full [&_.ant-tabs-tabpane]:h-full">
<Tabs
activeKey={activeTab}
onChange={setActiveTab}
items={drawerTabs}
className="h-full"
/>
</div>

<Form
form={form}
layout="vertical"
requiredMark={false}
onValuesChange={(changedValues) => {
if (changedValues.provider) {
setSelectedProvider(changedValues.provider)
}
}}
>
<div className="flex flex-col gap-3">
<Form.Item
name="provider"
label="Webhook Type"
initialValue="webhook"
className="!mb-0"
>
<Select
disabled={isEdit}
options={providerOptions}
placeholder="Select webhook/github"
/>
</Form.Item>

<Form.Item
name="name"
label="Webhook Name"
className="!mb-0"
rules={[{required: true, message: "Please enter a name"}]}
>
<Input placeholder="Production deploy hook" />
</Form.Item>

<Form.Item
name="events"
label="Event Types"
className="!mb-0"
rules={[{required: true, message: "Please select at least one event"}]}
>
<Select
mode="multiple"
placeholder="Select events"
options={EVENT_OPTIONS}
/>
</Form.Item>

{selectedProviderConfig && (
<>
<div className="mt-4 mb-2">
<Typography.Text type="secondary" className="font-medium">
{selectedProviderConfig.subtitle}
</Typography.Text>
</div>
<AutomationFieldRenderer
fields={selectedProviderConfig.fields}
isEditMode={isEdit}
/>
</>
)}

<Collapse className="[&_.ant-collapse-content]:bg-transparent" size="small">
<Collapse.Panel header="Example Request" key="preview" forceRender>
<RequestPreview form={form} />
</Collapse.Panel>
</Collapse>
</div>
</Form>
</EnhancedDrawer>
</>
)
Expand Down
Loading
Loading