Email Editor

The Email Editor lets admins compose email templates that send automatically during workflows: welcome emails, reminders, acceptance letters, etc. It is a two-panel modal. The editor (subject, formatting toolbar, body) sits on the left. A live preview on the right shows how the email looks to recipients. Templates support variable injection with {{variable}} syntax. Drop in something like {{user.full_name}} and it is replaced with real values when the workflow runs. The preview also shows the email on desktop, mobile, and as plain text. Opens from the Workflow Editor when configuring an Email node.


Overview

The Email Editor is a stateless component. It receives template data and available variables as props, and emits changes via callbacks. It does not persist data. The parent (Workflow Editor) handles saving. It renders as a Dialog/modal, not a full page.

Rendering

Dialog/modal, not a standalone page

State management

Stateless. Parent owns data, editor emits changes

Entry point

Workflow Editor → Email node → Configure

Layout Anatomy

Email Editor

Title bar

Subject field

Subject

Toolbar

Body editor

Editor
Preview toggle

Live preview

Preview pane

Interactive States

Switch between states to see how the Email Editor behaves in each scenario. The mockup below is a fully styled replica.

Email Editor

Type Here

Preview will appear here

Variable System

Variables use {{variable.name}} syntax (double curly braces). They are highlighted inline in the editor and substituted with sample values in the preview.

In Editor (valid)

Dear {{user.full_name}}

In Editor (invalid)

Dear {{non existent variable}}

In Preview (substituted)

Dear Jane Doe

Property
Value

name

string
·keye.g. user.full_name

sample

string
·preview valuee.g. "Jane Doe"

description

string (optional)
·tooltip text for the variable

Formatting Toolbar

The editor uses Markdown syntax. Formatting buttons insert markdown markers around selected text.

Property
Value

S̶ Strikethrough

~~text~~

U̲ Underline

Ctrl+U

I Italic

*text*
·Ctrl+I

B Bold

**text**
·Ctrl+B

🔗 Link

[text](url)
·Ctrl+K

≡ Bullet list

- item

≡ Numbered list

1. item

" Blockquote

> text

+ / − Variable picker

toggles variable dropdown
Property
Value

Button size

28 × 28px

Button radius

4px

Default bg

transparent

Active bg

#FDEEE8primaryLight

Active color

#E8541Aprimary

Interaction Flows

Save Flow

1

Edit

Admin edits subject or body → Save button becomes enabled

2

Save

Admin clicks Save → button shows loading state, disabled

3

Success

Brief "Saved" confirmation, button resets

4

Error

Error message shown, button re-enables

Cancel with Unsaved Changes

1

Dirty

Admin edits content (dirty state)

2

Cancel

Admin clicks Cancel

3

Confirm

Dialog: "Discard changes?" with [Keep editing] and [Discard]

4

Discard

Editor closes, changes lost

5

Keep

Dialog closes, editor stays open

Send Test Email

1

Click

Admin clicks "Send Test" button

2

Input

Panel appears with email input field

3

Send

Admin types email, clicks "Send" → loading state

4

Success

"Test email sent!" message, panel closes after 2s

5

Callback

onTest callback fires with { template, recipientEmail }

Props Interface

Property
Value

template

optionalObject
·{ subject: string, body: string }

variables

requiredArray
·[{ name, sample, description }]

onChange

optionalFunction
·(template) => void

onSave

requiredFunction
·(template) => void

onCancel

requiredFunction
·() => void

onTest

requiredFunction
·({ template, recipientEmail }) => void

Component Map

Property
Value

EmailEditor

Root component. Manages local state, wires sub-components.

TemplateEditor

Left panel. Subject field, formatting toolbar, body editor.

FormattingToolbar

Toolbar row. Formatting buttons + variable picker trigger.

VariablePicker

Dropdown list of available variables. Inserts on click.

PreviewSystem

Right panel. Mode toggle + live preview frame.

PreviewFrame

Rendered preview. Handles desktop/mobile/text modes.

SendTestPanel

Inline panel for entering test recipient email.

Code

Usage inside Workflow Editor
import { Dialog } from '@mui/material';
import EmailEditor from '@/components/EmailEditor';

// Inside WorkflowEditor:
<Dialog open={emailNodeOpen} maxWidth="lg" fullWidth>
  <EmailEditor
    template={selectedNode.template}
    variables={workflowVariables}
    onSave={(template) => {
      updateNode(selectedNode.id, { template });
      setEmailNodeOpen(false);
    }}
    onCancel={() => setEmailNodeOpen(false)}
    onTest={({ template, recipientEmail }) => {
      sendTestEmail({ template, recipientEmail, workflowId });
    }}
  />
</Dialog>