Skip to content

feat(apollo-vertex): add MessageThread pattern - #1549

Merged
frankkluijtmans merged 3 commits into
mainfrom
feat/apollo-vertex-message-thread
Nov 12, 2026
Merged

frankkluijtmans merged 3 commits into
mainfrom
feat/apollo-vertex-message-thread

Conversation

@frankkluijtmans

@frankkluijtmans frankkluijtmans commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds MessageThread to Apollo Vertex: an e-mail style conversation, extracted from the supplier communications thread. Follow-up to #1528.

Thread structure

MessageThreadHeader
  title · status badge · meta · actions

MessageThread  (newest first by default)
└─ message
   ├─ header toggle     avatar · sender · date
   │                    subject
   │                    excerpt (collapsed) / "to …" (expanded)
   ├─ actions           beside the header, outside the toggle
   └─ expanded body     notice · plain-text body · footer

The latest message starts expanded. Older ones collapse to sender, subject and a one-line excerpt. The header is one button that stays mounted in both states, so focus never moves. A single-message thread is always expanded and has no toggle.

Interface

Messages are plain data. The component owns layout and UI states. Only footer takes a React node (e.g. a reply form). Everything else is typed so consumers describe intent, not markup:

{
  id: "3",
  sender: "Sam Lee",
  senderEmail: "sam.lee@example.com",
  recipients: ["IT Support"],
  sentAt: "2026-11-08T08:05:00Z",
  subject: "Re: Laptop replacement request",
  body: "Could you ship the new one to the Berlin office?",
  notice: {
    status: "warning",
    label: "Address change",
    actions: [{ label: "Confirm address", onClick: confirm }],
  },
  actions: [{ label: "Forward", icon: Forward, onClick: forward }],
  footer: <ReplyForm />,
}
  • body is plain text and keeps line breaks.
  • notice is info | warning | error. Collapsed: badge. Expanded: alert with its actions.
  • MessageThreadHeader takes title, badge, meta and actions.

Expansion is designed for several use cases without extra branching:

Use case Behaviour
Live thread Appended messages expand (including batches). History prepended later stays collapsed.
Async load Mounting with [] then loading data expands only the latest.
Inbox detail key={selectedId} resets expansion per conversation.
Persist state Controlled via expandedIds / onExpandedChange.
Chat-like order order="oldest-first".

Shared Action

Action { label, onClick, disabled?, icon? } lives in lib/action.ts and is exported from the package root. It describes something the user can do; rendering stays up to the consuming component.

MessageThread uses it for notice actions, message actions and header actions (first = primary button). Other components with the same shape today (AI chat message actions, solution-tests buttons, filter options) can adopt it later without inventing another type.

Also: the Inbox demo opens conversations as a thread.

Copilot AI balanced review requested due to automatic review settings November 9, 2026 16:05
@github-actions github-actions Bot added the size:XXL 1,000+ changed lines. label Nov 9, 2026
@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex November 9, 2026 16:06 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design November 9, 2026 16:06 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs November 9, 2026 16:06 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing November 9, 2026 16:06 Destroyed
@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Dependency License Review

  • ✅ 1958 package(s) scanned
  • ✅ No license issues found
  • ⚠️ 2 package(s) excluded (see details below)
License distribution
License Packages
MIT 1722
ISC 91
Apache-2.0 57
BSD-3-Clause 28
BSD-2-Clause 23
BlueOak-1.0.0 8
MPL-2.0 4
CC0-1.0 4
MIT-0 3
MIT OR Apache-2.0 2
(MIT OR Apache-2.0) 2
Unlicense 2
LGPL-3.0-or-later 1
Python-2.0 1
CC-BY-4.0 1
(MPL-2.0 OR Apache-2.0) 1
Unknown 1
Artistic-2.0 1
(WTFPL OR MIT) 1
(BSD-2-Clause OR MIT OR Apache-2.0) 1
CC-BY-3.0 1
0BSD 1
(MIT OR CC0-1.0) 1
MIT AND ISC 1
Excluded packages
Package Version License Reason
@img/sharp-libvips-linux-x64 1.3.4 LGPL-3.0-or-later LGPL pre-built binary, not linked
khroma 2.1.0 Unknown MIT per GitHub repo, missing license field in package.json

Copilot AI 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.

🟡 Changes recommended

Batched updates leave some incoming messages collapsed, and expanding or collapsing a message replaces the focused control without restoring keyboard focus.

2 open issues
What changed in this PR

Adds Apollo Vertex’s MessageThread pattern, completing the conversation detail view introduced by the Inbox pattern in #1528.

Changes:

  • Adds message and thread headers, expandable history, per-message slots, localized labels, and unit tests.
  • Registers and exports the pattern with documentation and an interactive reply demo.
  • Updates the Inbox demo to display multi-message conversations.
File Description
packages/​apollo-vertex/​tsconfig.json Adds the message-thread import alias.
packages/​apollo-vertex/​skills/​vertex-component-catalog/​SKILL.md Adds usage guidance to the component catalog.
packages/​apollo-vertex/​registry/​message-thread/​message-thread.tsx Implements the thread, header, and expansion state.
packages/​apollo-vertex/​registry/​message-thread/​message-thread.test.tsx Tests rendering, ordering, expansion, and controlled behavior.
packages/​apollo-vertex/​registry.json Registers the pattern and its dependencies.
packages/​apollo-vertex/​locales/​en.json Adds English message-header and collapse labels.
packages/​apollo-vertex/​entries/​index.ts Exports the new components and types.
apps/​apollo-vertex/​templates/​MessageThreadTemplate.tsx Adds an interactive conversation and reply demo.
apps/​apollo-vertex/​templates/​InboxTemplate.tsx Displays selected conversations using MessageThread.
apps/​apollo-vertex/​content/​docs/​patterns/​meta.json Adds the pattern to documentation navigation.
apps/​apollo-vertex/​content/​docs/​patterns/​message-thread.mdx Documents installation, usage, slots, and API.
apps/​apollo-vertex/​content/​docs/​patterns/​inbox.mdx Links to MessageThread for conversation details.

Review effort: Balanced

@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

📊 Coverage + size by package

Per-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.

Package Coverage New-line coverage Packed (gzip) Unpacked vs main
@uipath/apollo-core — — — — —
@uipath/apollo-react — — — — —
@uipath/apollo-ui-icons — — — — —
@uipath/apollo-vertex 92.6% 100.0% (53/53) 350.1 KB 1.98 MB +4.2 KB
@uipath/apollo-wind — — — — —
@uipath/ap-chat — — — — —

"Coverage" is each package's own coverage.include scope (e.g. apollo-core instruments only scripts/). "Packed"/"Unpacked" come from npm pack --dry-run and only cover built packages — "—" means not measured this run (package not affected / not built). "vs main" is the packed (gzipped) delta against the last successful main build (the package-sizes artifact from the Release workflow); "—" there means no main baseline was available this run. The baseline is main's latest build, not this PR's exact merge-base, so it includes any drift since the branch diverged. Packages with no vitest config are omitted.

@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Storybook visual diff

✅ No stories are affected by this PR's changes; nothing to compare. Logs

Updated (PT): Nov 12, 2026, 05:37:17 AM

@frankkluijtmans
frankkluijtmans force-pushed the feat/apollo-vertex-message-thread branch from 8e8925f to 620c581 Compare November 10, 2026 14:41
Copilot AI balanced review requested due to automatic review settings November 10, 2026 14:41
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing November 10, 2026 14:41 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex November 10, 2026 14:41 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs November 10, 2026 14:41 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design November 10, 2026 14:41 Destroyed

Copilot AI 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.

🟡 Changes recommended

Batched updates expand only the latest arriving message, leaving other new messages collapsed and violating the documented behavior that each arrival opens.

1 open issue
2 resolved since last review

Review effort: Balanced

@frankkluijtmans
frankkluijtmans marked this pull request as ready for review November 10, 2026 14:46
@frankkluijtmans
frankkluijtmans requested a review from a team as a code owner November 10, 2026 14:46
@frankkluijtmans
frankkluijtmans enabled auto-merge (rebase) November 10, 2026 14:46

@ruudandriessen ruudandriessen left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks:
Its weird I can click the row to open but not to close? The component feels not really fleshed out TBH

Docs:
The usage in the docs is also weird - it's referencing some "conversation" which isnt really there? Can we instead use the real props. The fact we are mapping them already feels weird

Components:
Basically EVERYTHING is just a react node - can we not have a better interface? At this point it's not really a proper generic component - it's just a "whatever you wanna drop in goes"?

@frankkluijtmans

Copy link
Copy Markdown
Contributor Author

Looks: Its weird I can click the row to open but not to close? The component feels not really fleshed out TBH

Docs: The usage in the docs is also weird - it's referencing some "conversation" which isnt really there? Can we instead use the real props. The fact we are mapping them already feels weird

Components: Basically EVERYTHING is just a react node - can we not have a better interface? At this point it's not really a proper generic component - it's just a "whatever you wanna drop in goes"?

Looks: In it's expanded state it's not really a row anymore. I can tweak it a bit so there's a more compact e-mail header that feels like a somewhat stable toggle for expand/collapsed states.

Docs: Yeah, I can replace this hypothetical conversation object with just straight up values for the props.

Components: All of the slots aren't great. While porting I pressed on making things like status indications and custom elements as flexible as possible, but this is a bit too loose. Things like warning, error states and subject, recipients etc. can also be represented in a different way with enforced UI states.

To summarize, I'll go through the props and see what really needs to be a react node. Right now I think only actions and footer need that type to ensure it covers the supplier inbox use-case.

@frankkluijtmans
frankkluijtmans force-pushed the feat/apollo-vertex-message-thread branch from 620c581 to 63ce76d Compare November 10, 2026 15:31
Copilot AI balanced review requested due to automatic review settings November 10, 2026 15:31
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing November 10, 2026 15:31 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs November 10, 2026 16:27 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing November 10, 2026 16:27 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design November 10, 2026 16:27 Destroyed

Copilot AI 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.

🔵 Needs a closer look

The bundled LocaleProvider leaves i18next interpolation escaping enabled, causing recipient names containing ampersands or apostrophes to render as literal HTML entities in React text.

No open issues 🎉

Review effort: Balanced

@frankkluijtmans
frankkluijtmans force-pushed the feat/apollo-vertex-message-thread branch from 59e3486 to ea54257 Compare November 10, 2026 16:29
Copilot AI balanced review requested due to automatic review settings November 10, 2026 16:29
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design November 10, 2026 16:30 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs November 10, 2026 16:30 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing November 10, 2026 16:30 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex November 10, 2026 16:30 Destroyed
@frankkluijtmans

Copy link
Copy Markdown
Contributor Author

@ruudandriessen I mainly cleaned up the interface quite a bit. It was sloppy to rely on React.Node props to this extent. Only footer is left as a component prop, in supplier comms that's where we'd render the Agent Analysis and Proposed Action.

Otherwise I created a generic Action interface. We define actions all over te place and mostly in the same way. I figured we could introduce a generic interface for it. I can also follow up and replace some of the other specific action interface we don't really need.

Copilot AI 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.

🟡 Changes recommended

Recipient names are double-escaped because i18next interpolation escaping remains enabled, causing HTML entities to appear literally in message-thread text.

1 open issue

Review effort: Balanced

@frankkluijtmans
frankkluijtmans force-pushed the feat/apollo-vertex-message-thread branch from ea54257 to becd96d Compare November 10, 2026 16:37
Copilot AI balanced review requested due to automatic review settings November 10, 2026 16:37
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs November 10, 2026 16:38 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex November 10, 2026 16:38 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design November 10, 2026 16:38 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing November 10, 2026 16:38 Destroyed

Copilot AI 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.

🟡 Changes recommended

Translation interpolation HTML-escapes recipient names before React renders them as text, causing special characters to appear as literal HTML entities in message details.

1 open issue
1 resolved since last review

Review effort: Balanced

Comment thread packages/apollo-vertex/locales/en.json Resolved
Copilot AI balanced review requested due to automatic review settings November 10, 2026 16:47

Copilot AI 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.

🔵 Needs a closer look

Recipient names containing special characters are incorrectly displayed as literal HTML entities because i18next interpolation escaping remains enabled for text already safely rendered by React.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@ruudandriessen ruudandriessen left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

much nicer, but have one note; the time changes between closed/open which is weird:

image image

Same with the "to" actually 🤔

A label, a click handler and an optional disabled flag and icon, for components that take a list
of things the user can do. How the actions render stays up to each component.

Co-authored-by: Cursor <cursoragent@cursor.com>
@frankkluijtmans

frankkluijtmans commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor Author

much nicer, but have one note; the time changes between closed/open which is weird:

image image
Same with the "to" actually 🤔

Let's just always show relative time and then have a tooltip showing the full timestamp, I think that's an improvement too. With regards to the To field; I'm definitely not obfuscating the sender e-mail so then the only option would be to always show it.

Screenshot 2026-11-12 at 14 39 10

frankkluijtmans and others added 2 commits November 12, 2026 14:22
A conversation of e-mail style messages, extracted from the supplier communications thread. The
newest message starts expanded, older ones collapse to sender, subject and an excerpt, and each
message header expands and collapses it. Messages appended later open, also when several arrive at
once, and a thread that mounts empty starts once its first messages load. A message takes a typed
notice and a footer, and MessageThreadHeader shows a title, a status badge and a meta line.
Notices, messages and the header take Action lists, shown as buttons with the first as primary.

Co-authored-by: Cursor <cursoragent@cursor.com>
The demo lists conversations and opens the selected one as a MessageThread in the detail pane.

Co-authored-by: Cursor <cursoragent@cursor.com>

Copilot AI 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.

🟡 Changes recommended

Recipient names render with literal HTML entities due to interpolation escaping, and keyboard users cannot reveal the full timestamp.

1 open issue

Review effort: Balanced

This branch was successfully deployed

No deployments
preview/apollo-design — c73a6246 Deployed Nov 12, 2026 by github-actions[bot]
preview/apollo-landing — c73a6246 Deployed Nov 12, 2026 by github-actions[bot]
preview/apollo-vertex — c73a6246 Deployed Nov 12, 2026 by github-actions[bot]
preview/apollo-docs — c73a6246 Deployed Nov 12, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app:apollo-vertex size:XXL 1,000+ changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants