Skip to content

feat(popup): Add threaded annotations v2 popup and thread view#743

Merged
jackiejou merged 4 commits intobox:masterfrom
jackiejou:feat/threaded-annotations-v2-popup
Apr 30, 2026
Merged

feat(popup): Add threaded annotations v2 popup and thread view#743
jackiejou merged 4 commits intobox:masterfrom
jackiejou:feat/threaded-annotations-v2-popup

Conversation

@jackiejou
Copy link
Copy Markdown
Collaborator

@jackiejou jackiejou commented Apr 29, 2026

Summary

  • Add PopupReplyV2 with MessageEditorV2 from @box/threaded-annotations for creating new annotations with the v2 editor (TipTap-based, with @mention support)
  • Add PopupThreadV2 with ThreadedAnnotationsV2 for viewing existing annotation threads with reply, resolve/unresolve, and delete support
  • Add data adapters (threadedAnnotationsAdapters.ts) for converting between box-annotations and threaded-annotations data formats, including @mention markup serialization/deserialization
  • Add store actions (createReplyAction, deleteAnnotationAction, updateAnnotationAction) and reducer handling for thread operations
  • Extend AnnotationsAPI interface with createAnnotationReply, deleteAnnotation, and updateAnnotation methods
  • Add webpack externals for react, react-dom, react-intl, react-redux, @box/threaded-annotations and transitive dependencies to avoid bundling duplicates
  • Upgrade autoprefixer from 9.x to 10.x for modern CSS compatibility
  • Add externalsType: 'commonjs' to fix webpack 5 module concatenation with @-scoped packages
  • Add CSS isolation in PopupReplyV2.scss to prevent box-ui-elements global styles from leaking into Blueprint components
  • Add BlueprintModernizationProvider for modern button styling (round radius)
  • Add data-ba-annotation-id attribute to annotation targets for reliable DOM lookup
  • Fetch annotation replies when isThreadedAnnotation feature flag is enabled

All changes are gated behind the isThreadedAnnotation feature flag. V1 behavior is unchanged when the flag is off. Full test suite (940 tests) passes.

Screenshot

V1
image

PopUpReplyV2
image

PopupThreadV2
image

Test plan

  • With flag OFF: verify v1 annotation creation, highlight, region, and drawing popups work unchanged
  • With flag ON: create a new annotation and verify the MessageEditorV2 popup appears with the submit button inside the editor
  • With flag ON: click an existing annotation and verify the ThreadedAnnotationsV2 thread view appears with existing messages
  • With flag ON: post a reply in an existing thread and verify it appears
  • With flag ON: resolve/unresolve an annotation thread
  • With flag ON: delete an annotation thread via the confirmation popover
  • With flag ON: use @mentions in the editor and verify the user selector popover appears
  • Verify the popup is centered below the annotation target

Add @box/threaded-annotations and peer dependencies (blueprint-web,
blueprint-web-assets, collaboration-popover, readable-time,
user-selector) to box-annotations. (WEBAPP-49217)

Replace PopupReplyV2 stub with real ThreadedAnnotationsV2 component
that renders threaded reply UI with mention support, TipTap editor,
and annotation data adapters. (WEBAPP-49218)

Add webpack externals for @box/* packages as a temporary workaround
for webpack 4 ESM exports incompatibility (WEBAPP-57855 tracks the
webpack 5 upgrade to remove this).
Add @box/threaded-annotations integration with MessageEditorV2 for
creating annotations and ThreadedAnnotationsV2 for viewing existing
threads. Gated behind the isThreadedAnnotation feature flag.

- Add PopupReplyV2 with MessageEditorV2 for annotation creation
- Add PopupThreadV2 with ThreadedAnnotationsV2 for thread viewing
- Add data adapters for annotation-to-message conversion
- Add store actions for reply, delete, and resolve/unresolve
- Add webpack externals for shared runtime dependencies
- Add data-ba-annotation-id to annotation targets for DOM lookup
- Upgrade autoprefixer for modern CSS compatibility
- Add CSS isolation to prevent BUE style leakage into Blueprint
- Add BlueprintModernizationProvider for modern button styling
Move the isThreadedAnnotation branching from PopupReply to PopupLayer
so PopupReply is a clean v1-only component. PopupLayer now renders
PopupReplyV2 or PopupReply directly based on the feature flag.
@jackiejou jackiejou marked this pull request as ready for review April 29, 2026 22:41
@jackiejou jackiejou requested a review from a team as a code owner April 29, 2026 22:41
Comment thread src/components/Popups/PopupThreadV2.tsx Outdated
Comment thread src/components/Popups/PopupV2.tsx
Comment thread src/popup/PopupLayer.tsx
Combine the create and thread view popups into a single PopupV2
component that routes based on the presence of annotationId. Rename
PopupReplyV2.scss to PopupV2.scss. Add CSS.escape for annotation ID
DOM queries.
// TODO: PopupReplyV2 is a placeholder stub. Props (isPending, onCancel, etc.)
// are not yet forwarded and will need to be wired up when V2 is implemented.
if (props.isThreadedAnnotation) {
return <PopupReplyV2 />;
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

moved to Popupv2 and out of popupreply

() => ({
allowEmptyQuery: true,
ariaRoleDescription: intl.formatMessage(messages.ariaLabelMentionSelector),
fetchAvatarUrls: async () => ({}),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

do we not need avatars?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

we do, but the backend api endpoint does not support it atm

@jackiejou jackiejou merged commit 611a283 into box:master Apr 30, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants