Skip to content

[chore] Split the trigger drawers and management section - #5571

Open
ardaerzin wants to merge 4 commits into
release/v0.106.2from
fe-chore/trigger-drawers-split
Open

[chore] Split the trigger drawers and management section#5571
ardaerzin wants to merge 4 commits into
release/v0.106.2from
fe-chore/trigger-drawers-split

Conversation

@ardaerzin

Copy link
Copy Markdown
Contributor

Context

Three files in the agent triggers feature had grown past the point where anyone could scan them: TriggerSubscriptionDrawer.tsx at 2089 lines, TriggerScheduleDrawer.tsx at 1153, and TriggerManagementSection.tsx at 1040. Together they held 29 inline components.

Changes

Each file becomes a composition root plus co-located modules.

TriggerSubscriptionDrawer.tsx  2089 -> 69   + drawers/subscription/ (11 modules)
TriggerScheduleDrawer.tsx      1153 -> 53   + drawers/schedule/ (7 modules)
TriggerManagementSection.tsx   1040 -> 377  + triggerManagement/ (6 modules)

The area already had a good set of shared primitives (MasterDetailRail, useDraftMasterDetail, DrawerFooter, RunVersionField, EventSourcePicker, SectionRail, RailField, ActiveToggle) and all three files were already consuming them correctly. There were no duplicated re-implementations to collapse, so every extracted module keeps importing the same primitives. No new overlapping abstraction was added.

Two genuine cross-drawer duplicates moved to drawers/shared/: RequiredTitle and normalizeJson.

Three near-duplicates deliberately stayed per-drawer, because sharing them would cost more than it saves:

  • MAX_DRAFTS and SHOW_LIST_RAIL hold the same values but carry different documenting comments. Merging them would delete one.
  • applicationRevisionAdapter is a module-level singleton. Merging the two would change adapter identity from two instances to one, which is a behaviour change with no payoff.
  • extractBoundRevId exists in the subscription drawer, while the schedule drawer writes the same three-key fallback inline. Replacing the inline version would be a rewrite, not a move.

Public surface is unchanged. Both drawers keep their default export, and useAgentTriggers and AddTriggerDropdown are re-exported from TriggerManagementSection.tsx, so no importer changed.

Tests

  • pnpm --filter @agenta/entity-ui exec tsc --noEmit passes, as do @agenta/oss and @agenta/ee.
  • pnpm lint-fix across the repo makes no changes. Prettier clean.
  • Effect bodies, dependency arrays and lazy initializers moved verbatim, comments included. That includes the large commented-out blocks from [fix] Unblock editing schedule and subscription triggers #5552, which are load-bearing (they carry "restore with the call site below").
  • Rebuilt against current release/v0.106.1 rather than rebased. [fix] Unblock editing schedule and subscription triggers #5552 changed the binding logic inside the regions this refactor deletes, so a naive replay would have dropped that fix. Verified line by line: of 86 lines [fix] Unblock editing schedule and subscription triggers #5552 added, 84 are present verbatim. The two that differ are the same import closer, which correctly became "../shared/RunVersionField" one directory deeper. extractBoundWorkflowId, isRunVersionBound, extractDefaultBindId, the storedReferences/versionChosen derivation and hideEnvironment all land in the module that now owns them.

Not runtime verified. The gates above are static.

What to QA

  • From a playground, open Schedules. The master detail rail lists existing schedules and the form edits on the right.
  • Edit an existing schedule and an existing subscription, then save. Both still save, which is the [fix] Unblock editing schedule and subscription triggers #5552 fix this branch had to preserve.
  • Create a new subscription and bind a workflow version. The Deployed option stays hidden, and saving without a binding still shows "Bind a workflow".
  • Run in playground from the schedule footer, and Run from a subscription row.
  • Regression: open Triggers from project settings, where there is no playground. Both drawers stay single create and edit forms with no rail.
  • Regression: the smart header in the subscription drawer still switches when you browse sources. Its atoms moved into subscription/constants.ts and are read by two modules.

Two drawer roots and the management section become composition roots plus
co-located modules. The existing shared primitives (MasterDetailRail,
useDraftMasterDetail, DrawerFooter, RunVersionField, EventSourcePicker,
SectionRail/RailField, ActiveToggle) were already used correctly, so every
extracted module keeps importing them — no new overlapping abstraction.

  TriggerSubscriptionDrawer.tsx  2089 -> 69   + drawers/subscription/ (11)
  TriggerScheduleDrawer.tsx      1153 -> 53   + drawers/schedule/ (7)
  TriggerManagementSection.tsx   1040 -> 377  + triggerManagement/ (6)

Two genuine cross-drawer duplicates move to drawers/shared/: RequiredTitle
and normalizeJson. Three near-duplicates deliberately stay per-drawer:
MAX_DRAFTS/SHOW_LIST_RAIL (same values, different documenting comments),
applicationRevisionAdapter (a module singleton — merging would change
adapter identity), and extractBoundRevId (the schedule drawer writes the
same fallback inline; replacing it would be a rewrite, not a move).

Split against current content so #5552 (unblock editing schedule and
subscription triggers) survives: extractBoundWorkflowId/isRunVersionBound,
extractDefaultBindId, the storedReferences/versionChosen derivation and the
hidden Deployed option all land in the module that now owns them. Verified
line-by-line against the upstream diff.

Public surface unchanged: both drawers keep their default export, and
useAgentTriggers / AddTriggerDropdown are re-exported from
TriggerManagementSection.tsx.
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Jul 30, 2026
@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview Jul 30, 2026 6:13pm

Request Review

@dosubot dosubot Bot added Frontend refactoring A code change that neither fixes a bug nor adds a feature labels Jul 30, 2026
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added streamlined trigger management with app and scheduled trigger creation.
    • Added provider-grouped subscriptions with active, paused, run, and management controls.
    • Added playground testing for subscriptions and schedules using real or sampled events.
    • Added schedule forms with cron timing, active windows, workflow versions, message composition, and JSON editing.
    • Added subscription forms with event source selection, filters, input mapping, previews, and workflow binding.
    • Added clearer event mapping tools, including template placeholders, sample payload previews, and validation feedback.

Walkthrough

The pull request extracts trigger-management and gateway-trigger drawer logic into focused React components. It adds standalone forms, source and mapping editors, schedule controls, provider grouping, and playground execution flows while preserving the existing drawer entry points.

Changes

Trigger management experience

Layer / File(s) Summary
Trigger scoping and management UI
web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/TriggerManagementSection.tsx, web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/*
Trigger scoping, provider grouping, trigger creation, row rendering, and subscription run controls move into dedicated modules.
Provider groups and playground runs
web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/*
Provider groups persist expansion state and expose sampled-event loading and simulated playground runs.

Gateway trigger drawers

Layer / File(s) Summary
Subscription drawer shell and source selection
web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerSubscriptionDrawer.tsx, web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/*, web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/*
The subscription drawer routes playground and settings modes to separate content and form components. Source browsing, connection summaries, list management, shared atoms, and helper utilities are added.
Subscription creation, mapping, and execution
web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/*
SubscriptionForm handles bindings, validation, persistence, sampled deliveries, mapping composition, token editing, and playground execution.
Schedule drawer lifecycle and list management
web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerScheduleDrawer.tsx, web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/*
The schedule drawer routes playground state to ScheduleDrawerContent and settings state to ScheduleForm. Drafts, schedules, deletion, and list rendering are separated into components.
Schedule editing and playground execution
web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/*
ScheduleForm adds schedule binding, validation, dirty-state tracking, active-window editing, message composition, persistence, and playground execution.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • Agenta-AI/agenta#4883: Directly refactors the trigger-management and subscription/schedule drawer implementations.
  • Agenta-AI/agenta#5306: Modifies the same trigger-management components, including useAgentTriggers and AppTriggerProviderGroups.
  • Agenta-AI/agenta#5552: Overlaps with the extracted drawer components and message-editing logic.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary refactor of splitting the trigger drawers and management section.
Description check ✅ Passed The description directly explains the file-splitting refactor, preserved exports, validation, and QA scope.
Docstring Coverage ✅ Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 60.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fe-chore/trigger-drawers-split

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-production-ccfb.up.railway.app/w
Project agenta-oss-pr-5571
Image tag pr-5571-a0a939b
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-07-31T10:27:00.349Z

@ardaerzin
ardaerzin changed the base branch from release/v0.106.1 to release/v0.106.2 July 30, 2026 18:12
@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
putComment timed out

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (4)
web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/AppTriggerProviderGroups.tsx (1)

108-114: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Reuse a connections map instead of a linear find per row.

providerGroups already builds connById; hoisting it to its own memo lets connectionLabel be O(1) and drops the duplicate map construction.

♻️ Suggested change
+    const connById = useMemo(() => new Map(connections.map((c) => [c.id, c] as const)), [
+        connections,
+    ])
     const connectionLabel = useCallback(
         (connectionId?: string) => {
-            const c = connections.find((conn) => conn.id === connectionId)
+            const c = connectionId ? connById.get(connectionId) : undefined
             return c ? c.name || c.slug || c.integration_key : undefined
         },
-        [connections],
+        [connById],
     )
web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/useAgentTriggers.ts (1)

43-62: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use workflowMolecule.selectors.artifactName for the bound workflow label.

defaultBoundLabel is user-facing, but deriving it from revision.name conflicts with the codebase’s explicit artifact name selector and the “use workflow artifact names for workflow display labels” guideline. Use the workflow molecule’s artifactName selector here so the drawer binds to the normalized artifact name instead of a raw revision name.

Source: Coding guidelines

web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/PillEditor.tsx (1)

86-114: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Missing dependency array — this effect re-runs on every render.

insertApi.current only needs reassigning when insertApi, makePill, or commit change.

♻️ Proposed change
-    })
+    }, [insertApi, makePill, commit])
web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/ScheduleDrawerContent.tsx (1)

34-96: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Skip the schedules list fetch when the drawer is not in playground mode.

useTriggerSchedules() is called unconditionally, but the settings path only renders a single ScheduleForm and never needs the full list or draft master-detail state. Add a caller-controlled enabled: !!playgroundEntityId option (or equivalent disabled atom) to useTriggerSchedules() so settings-mode create/edit drawer opens avoid fetching the full schedules list.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: be6b10ad-dd29-4c71-afbd-e6b9bd5769e1

📥 Commits

Reviewing files that changed from the base of the PR and between a0ef2cc and 0748386.

📒 Files selected for processing (29)
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/TriggerManagementSection.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/AddTriggerDropdown.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/AppTriggerProviderGroups.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/SubscriptionChildRow.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/SubscriptionRunPopover.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/TriggerRow.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/useAgentTriggers.ts
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerScheduleDrawer.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerSubscriptionDrawer.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/MessageComposer.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/RunInPlaygroundButton.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/ScheduleDrawerContent.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/ScheduleForm.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/SchedulesList.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/WindowField.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/constants.ts
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/RequiredTitle.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/normalizeJson.ts
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/InputsMappingField.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/MappingSection.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/PillEditor.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/RunSubscriptionButton.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SourceBrowsePage.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SourceField.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SubscriptionDrawerContent.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SubscriptionForm.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SubscriptionsList.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/constants.ts
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/helpers.ts

Comment on lines +87 to +89
useEffect(() => {
onErrorChange(parseError)
}, [parseError, onErrorChange])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Duplicate error ownership: parent overwrites this field's message.

In the non-agent path, MappingSection also validates value and calls onErrorChange (MappingSection.tsx Lines 85-96). Child effects flush before the parent's, so the parent wins: the detailed parser message is replaced by "Invalid JSON", and "Mapping must be a JSON object or a selector string" is cleared to null (parent's JSON.parse succeeds for arrays/strings). Let one owner validate — e.g. skip the parent's JSON effect when InputsMappingField is rendered.

@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Four defects the split surfaced, all pre-existing:

- Create was unreachable when the source is pre-seeded. The catalog opens the
  subscription drawer with connection + event + default binding, which is exactly
  the create baseline, so `isDirty` stayed false and Create never enabled. Create
  now gates on completeness (source + version chosen); Save still gates on dirty.
  Same change in the schedule form, which had the identical defect.
- The mapping field had two error owners. `MappingSection`'s JSON effect flushes
  after `InputsMappingField`'s, so it replaced the parser's message with "Invalid
  JSON" and cleared "Mapping must be a JSON object or a selector string" outright
  (its `JSON.parse` succeeds for arrays). The parent now defers to the child on
  the non-agent path.
- Edit-mode prefill reset the form on refetch. Every trigger mutation invalidates
  the detail query by prefix, so a background refetch re-ran the prefill and
  overwrote edits in progress. Both forms now hydrate once per loaded id; the
  subscription's `trigger_config` prefill folds into that same hydration.
- The pill composer accepted rich paste. Pasted markup landed in the
  contenteditable verbatim, where `serialize` collapses nested elements to "\n".
  Paste is now plain text inserted at the caret; the Enter handler reuses it.

Plus: bind the default label to the workflow artifact name instead of
`revision.name`, hoist the settings/playground split to the drawer roots so
settings stops mounting the list query and master-detail state, and hoist the
connections map in the provider groups.
@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SubscriptionForm.tsx (1)

436-443: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Call onSaved after a playground draft is created.

When a draft is created, this path calls onClose() and never calls onSaved(savedId). SubscriptionDrawerContent passes onSaved to handleDraftSaved, which must replace the draft with the saved subscription. The current flow closes the drawer instead.

Proposed fix
-            if (!isEdit) {
-                // A newly created trigger dismisses the drawer; it now shows in the triggers list.
-                onClose()
-            } else if (onSaved && savedId) {
+            if (onSaved && savedId) {
                 onSaved(savedId)
             } else {
                 onClose()
             }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5ea24b4a-59fe-43a3-8c52-33baed556f44

📥 Commits

Reviewing files that changed from the base of the PR and between 0748386 and 5b1ae8c.

📒 Files selected for processing (10)
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/AppTriggerProviderGroups.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/useAgentTriggers.ts
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerScheduleDrawer.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerSubscriptionDrawer.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/ScheduleDrawerContent.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/ScheduleForm.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/MappingSection.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/PillEditor.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SubscriptionDrawerContent.tsx
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SubscriptionForm.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerScheduleDrawer.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/AppTriggerProviderGroups.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/triggerManagement/useAgentTriggers.ts
  • web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/MappingSection.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Frontend refactoring A code change that neither fixes a bug nor adds a feature size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant