feat(campaigns): Redesign Campaign Step Editor UI #151
Merged
Conversation
…S body - Redesign StepCard to match Apollo-style layout: header with toggle/breadcrumb/collapse, variant tabs (Test A), and a split panel (editor left, preview right) - Replace plain textarea with EditorJS rich text editor - Add live preview panel with contact selector, desktop/mobile toggle, and block-aware PreviewBody renderer - Add touchType field (new_thread / reply_to_thread) to StepFormState - Use callback ref pattern to fix EditorJS stale closure issue with onChange/onReady - Remove AI-related UI (Assisted/Prompt tabs, Write with AI button, AI opener toggle) - Remove custom toolbar; EditorJS native toolbar handles formatting - Fix footer overflow by removing stats labels row Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4d160c4 to
0c86b5f
Compare
- Remove stale DOMParser declaration left from merge conflict - Fix no-array-index-key: use block.id and item text as stable keys - Fix label-has-associated-control: add htmlFor/id pairs for Subject and Type fields Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace static wait label with editable number input + unit dropdown (minutes / hours / days) so each step's delay can be configured - Hide the Subject field when touchType is reply_to_thread, matching Apollo's behaviour where replies inherit the thread subject Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
anujeet98
reviewed
Jun 5, 2026
| waitMode: step.wait_mode as 'day' | 'hour' | 'minute', | ||
| apolloTouchId: touch?.id, | ||
| apolloTemplateId: touch?.emailer_template_id, | ||
| touchType: 'new_thread', |
Contributor
There was a problem hiding this comment.
TouchType should load the value from api response.
touchType: (touch?.type as 'new_thread' | 'reply_to_thread') ?? 'new_thread',
anujeet98
reviewed
Jun 5, 2026
|
|
||
| // EditorJS list v2 stores items as { content: string; items: [] }, | ||
| // while v1 stored plain strings. Handle both. | ||
| function extractListItemText( |
Contributor
There was a problem hiding this comment.
This is doing same as listItemText (duplicate)
can remove this method
anujeet98
requested changes
Jun 5, 2026
| return html.replace(/<[^>]*>/g, ''); | ||
| } | ||
|
|
||
| function outputDataToText(data: OutputData): string { |
Contributor
There was a problem hiding this comment.
outputDataToText strips all HTML tags and joins blocks with \n, storing plain text in step.bodyHtml. But the backend passes bodyHtml directly to Apollo as body_html, which expects HTML. This means formatting is lost and the email doesn't not render correctly.
- Load touchType from API response instead of hardcoding 'new_thread' - Remove extractListItemText (duplicate of listItemText) - Replace outputDataToText with outputDataToHtml so bodyHtml stores proper HTML for Apollo's body_html field, preserving formatting Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
anujeet98
approved these changes
Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Redesigns the campaign step editor (
StepCard) to match Apollo's native email step UI — a split-panel layout with a rich text editor on the leftand a live email preview on the right.
Changes
Layout & Structure
Step N: Automatic email / Test A), timing label (Send email in immediately), and a collapse/expand buttonRich Text Editor
<textarea>body with the existing EditorJS component (@editorjs/editorjs)onEditorChangeRef) to fix EditorJS's stale closure issue — the capturedonChange/onReadycallbacks alwayscall through to the latest handler, ensuring
previewDatastate is always up to dateonReadyseeds the preview immediately on load (EditorJS doesn't fireonChangeon init)Live Preview Panel
OutputDatablocks directly with aPreviewBodycomponent that handles paragraphs, headers, ordered/unordered lists,checklists, quotes, code, and delimiters
{{variables}}with example values (e.g.{{first_name}}→Example)Data Model
touchType: 'new_thread' | 'reply_to_thread'toStepFormState(was previously hardcoded instepsToPayload)outputDataToTextserialiser handles both EditorJS list v1 (plain strings) and v2 ({ content: string }objects) item formatsRemoved
{},*, calendar icons)- Scheduled - Delivered - Bounce …) that was overflowingFiles Changed
apps/web/src/components/Campaigns/campaign-shared.tsxStepCard, newPreviewBodycomponent, updatedStepFormState,outputDataToTextserialiserTesting
body_htmlloads into EditorJS; preview seeds on loadstepsToPayloadproduces correct API payload withtouchTypeScreenshot