Skip to content

Email Order UI — Direct Send Design

This document builds up and discusses the UI design changes needed to let users send an Email Order directly from the system — part of PDEV-969 — Enable Direct email sending for Email Orders (under the PDEV-968 umbrella). The backend send capability already exists — see the Email module API reference (POST /v1/shop-access/email/job). The work here is the front-end surface that will call it.

We start by recording the current view, then walk through the redesigned panel and its copy-only fallback.

The Email Order surface is the EmailPanel slide-over in the arda-frontend-app Order Queue (/order-queue). It opens from the right when a user orders items whose supplier order method is EMAIL. It composes a formatted order email but does not send it:

  • Header — “Order from {supplier}” (or the single item’s name) and a “{N} items to order” subtitle, with a close (X) control.
  • Body — a read-only rendering of the message: a greeting (“Hi {supplier},”), the line “I would like to order the following items:”, an items table (Item, Quantity, Taxable status, Vendor sku, Unit price), an optional “Deliver To” block, a “Best,” sign-off with the sender’s name or email, and a “Powered by Arda” badge.
  • FooterCancel and Copy to clipboard. Copy writes both a rich HTML version and a plain-text version to the clipboard.

The only outbound action is Copy to clipboard — there is no direct send. The user pastes the message into their own mail client to actually send it. Closing the gap (a real “Send” wired to the backend job endpoint) is the purpose of this project.

The screenshot below is the panel running against mock data (sample “Stark Industries” items):

Email Order panel — current view (mock data)

A working prototype of the redesigned panel — the same Email Order, now with a real Send action and an editable, mail-client-like composition surface. It runs live in this page, so you can try the interactions directly:

  • Gmail-style addresses. To, Cc, and From are recipient-chip fields. Type an address and press Enter (or comma) to add a chip, double-click a chip to edit it, and click its × — or press Backspace in the empty input — to remove it.
  • Editable content. The greeting, the introduction line, each line item’s quantity and unit price, and the sign-off are all editable: click the ✎ badge or double-click the text. An edited field shows a ↺ control that restores just that value.
  • Optional note. A free-text note sits between the items and the sign-off. It stays collapsed to a thin placeholder until you add text (click it or its ✎ badge) and holds up to five lines. It is included in the copied and printed output only when filled in.
  • Revert & undo. Revert all in the footer (shown once any field has been edited) resets every field to its default in one step; ⌘Z / Ctrl+Z undoes the most recent address change.
  • Send — HTML or plain text. Send is a split button (like the Items page’s “Add Item”): its default action sends the HTML version and fires on ⌘↵ / Ctrl+↵, while the caret menu offers Send as HTML and Send as plain text. This mirrors the two formats the user already gets from Copy.
  • Copy — both formats. Copy to clipboard (secondary) writes both a rich-HTML and a plain-text version to the clipboard, exactly as today’s EmailPanel does.

Outcomes are confirmed with a toast (e.g. “Email sent”, “Message copied to clipboard”), mirroring the arda-frontend-app pattern.

This section captures the variant for when direct send is not available — for example, a tenant whose EmailConfiguration has no authorized send address, so the panel falls back to copy-only (as today’s EmailPanel does). It starts as a copy of the mock above with direct send turned off: the Addresses section and the Send button are hidden, and Copy to clipboard becomes the default action — matching today’s copy-only EmailPanel.

The Email Order is assembled from data: the body is rendered from the selected order-queue items plus tenant/user context, and the send envelope (To, Cc, subject, from) is resolved at send time. The table lists each data-driven element, where it comes from in the system, the placeholder the live mock above uses (in mocks/_sample-order.ts), and whether the mock lets you edit it inline (double-click the value, or click its ✎ badge; “Revert all” in the footer restores every field). Static chrome — field labels and the “Powered by Arda” badge — is omitted.

ElementWhere the data comes fromMock value (this page)Editable in mock
Greeting — supplier nameThe selected item’s primary supply → Supplier (Business Affiliate) contact name (itemDetails.primarySupply.supplier)supplier constant (“Stark Industries”)Yes — the whole greeting line
Introduction lineFixed template phrasing prepended to the items tableintroDefault (“I would like to order the following items:“)Yes
Item nameItem details for each selected order-queue card (itemDetails.name)orderLines[].nameNo
QuantityPrimary supply reorder quantity — amount + unit (primarySupply.orderQuantity)orderLines[].quantityYes — per-row cell
Taxable statusItem taxable flag (item / supply attribute)orderLines[].taxableNo
Vendor SKUSupplier-specific SKU on the item’s primary supplyorderLines[].skuNo
Unit priceUnit price on the item / primary supplyorderLines[].unitPriceYes — per-row cell
Deliver-to address (optional)Tenant delivery / company addressNot modeled in mock
Signature / sign-offAuthenticated user’s name, falling back to email — from the JWT user context (userContext.name / userContext.email)senderEmail constant (“developer@arda.cards”)Yes — the multi-line sign-off block
Recipient (To)Supplier contact email (Business Affiliate). Required for direct send (PDEV-969); not wired in today’s copy-only EmailPanel.toAddresses (“orders@…”, “tony@…”)Yes — Gmail-style To chips (add / edit / remove)
Recipient (Cc)Carbon-copy recipients (e.g. the sending user). Cc handling is a design-open question for PDEV-969; not in today’s copy-only EmailPanel.ccAddresses (“developer@arda.cards”, “procurement@…”)Yes — Gmail-style Cc chips (add / edit / remove)
SubjectTenant company name + send date, composed server-sideNot modeled
From addressFixed by the tenant’s EmailConfiguration signature, synthesized server-side (one authorized address per configuration)fromAddress (“noreply@acme.dev.ardamails.com”)Yes (mock only) — single From chip; server-fixed in production