Skip to content

feat(activity-feed-v2): add contact mapping utility for task modal v2#4657

Open
jackiejou wants to merge 1 commit into
box:masterfrom
jackiejou:feat/task-modal-v2-contact-mapping
Open

feat(activity-feed-v2): add contact mapping utility for task modal v2#4657
jackiejou wants to merge 1 commit into
box:masterfrom
jackiejou:feat/task-modal-v2-contact-mapping

Conversation

@jackiejou

@jackiejou jackiejou commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a pure-functional contact-shape mapper utility for the V2 task modal. Three exported functions convert between the existing approver-selector shape (SelectorItem<UserMini | GroupMini> returned by the file collaborators API) and @box/user-selector's UserContactType, and back into the TaskCollabAssignee shape the create-task / edit-task callbacks expect.

This is the second step in the V2 task modal migration (groundwork for the upcoming TaskFormV2 work). No UI, no callers wired up yet.

Changes

  • src/elements/content-sidebar/activity-feed-v2/task-modal-v2/utils/contactMapping.ts exports:
    • mapCollaboratorToUserContact — selector item → UserContactType (group → empty email, user → preserves email, numeric id coercion with 0 fallback for non-numeric ids).
    • mapUserContactToAssigneeUserContactTypeTaskCollabAssignee with the new-approver permission shape (can_delete: false, can_update: false).
    • mapAssigneeToUserContactTaskCollabAssigneeUserContactType, used to seed selected users when editing an existing task.
  • Co-located unit tests in utils/__tests__/contactMapping.test.ts.

Design notes

  • Runtime vs Flow type for TaskCollabAssignee.target. Flow types target as UserMini, but groups are also valid at runtime (the file collaborators endpoint returns both when include_groups=true, and v1 sets target: pill.item directly). The TS mapper widens to UserMini | GroupMini to reflect reality.
  • value format <name>-<id> matches the precedent set by @box/unified-share-modal (useContactService.ts:42) so selected-user state has a stable unique key.
  • Numeric id coercion. UserContactType.id is number, but UserMini.id / GroupMini.id are string. The mapper coerces via Number() and falls back to 0 if the source id is not numeric (matches the unified-share-modal pattern for external/no-account contacts).
  • Group → empty email mirrors the unified-share-modal useContactService behavior. getContactsAvatarUrls (which the V2 form will wire up later) filters out groups via email === '' to avoid 404s on the avatar endpoint.

Test plan

Test scenarios covered:

  • user mapping both directions
  • group mapping both directions
  • missing email on group (and on a user with no email)
  • non-numeric id fallback to 0
  • round-trip equivalence for both users and groups (SelectorItemUserContactTypeTaskCollabAssigneeUserContactType)

Follow-ups

  • TaskFormV2 built on UserSelectorContainer and Blueprint form primitives (next PR)
  • Wire TaskFormV2 into TaskModalV2 with edit-mode prefill and submit handling
  • Switch ActivityFeedV2.tsx to render TaskModalV2
  • Manual a11y and visual smoke test pass

Summary by CodeRabbit

  • New Features
    • Added bidirectional mapping utilities between task collaborators/assignees and user contact selections, now supporting both individual users and groups.
    • Standardizes how identifiers and display values are preserved across conversions.
  • Bug Fixes
    • Improves handling of non-numeric or empty identifiers (keeps raw values for accuracy) and defaults missing email to empty.
    • Throws when collaborator selection data is missing.
  • Tests
    • Added Jest coverage for user/group mapping, round-trip stability, and edge cases for identifier parsing and payload generation.

@jackiejou jackiejou requested review from a team as code owners June 26, 2026 21:35
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 20afb608-c71d-40ba-b593-33e54889262d

📥 Commits

Reviewing files that changed from the base of the PR and between b1a0da4 and fc0a7b3.

📒 Files selected for processing (2)
  • src/elements/content-sidebar/activity-feed-v2/task-modal-v2/utils/__tests__/contactMapping.test.ts
  • src/elements/content-sidebar/activity-feed-v2/task-modal-v2/utils/contactMapping.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/elements/content-sidebar/activity-feed-v2/task-modal-v2/utils/tests/contactMapping.test.ts

Walkthrough

Adds contact-mapping helpers for collaborator, contact, and assignee conversions, including group support, raw ID preservation, and Jest coverage for the mapping paths.

Changes

Contact mapping utilities

Layer / File(s) Summary
Mapping helpers and conversions
src/elements/content-sidebar/activity-feed-v2/task-modal-v2/utils/contactMapping.ts
SelectorItem, UserContactType, and TaskCollabAssignee are mapped in both directions with numeric ID normalization, group/user target selection, and fixed collaborator metadata.
Mapping tests
src/elements/content-sidebar/activity-feed-v2/task-modal-v2/utils/__tests__/contactMapping.test.ts
A Jest suite covers user and group mappings, non-numeric ID fallback, missing email handling, and round-trip conversions through the mapping chain.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Suggested reviewers

  • jpan-box
  • jfox-box

Poem

A bunny hops through contacts bright,
With IDs that bounce to numbers right.
User, group, and assignee cheer,
Round-trip paths are crisp and clear.
🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the new contact-mapping utility added for task modal v2.
Description check ✅ Passed The description is structured and detailed, covering summary, changes, design notes, tests, and follow-ups.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jackiejou jackiejou force-pushed the feat/task-modal-v2-contact-mapping branch from b2f63ed to de59f8d Compare June 26, 2026 21:36

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/elements/content-sidebar/activity-feed-v2/task-modal-v2/utils/contactMapping.ts`:
- Around line 12-15: The ID mapping in toContactId is lossy because non-numeric
collaborator IDs are converted to 0, which later becomes target.id = '0' in
mapUserContactToAssignee and breaks the original identifier. Update the
contactMapping flow so mapCollaboratorToUserContact and mapUserContactToAssignee
preserve the raw collaborator/group ID string end-to-end instead of parsing it
to a number, and adjust the affected contact/assignee types accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d7f01392-719a-4b45-b76f-c1716842e67a

📥 Commits

Reviewing files that changed from the base of the PR and between 56a423e and b2f63ed.

📒 Files selected for processing (2)
  • src/elements/content-sidebar/activity-feed-v2/task-modal-v2/utils/__tests__/contactMapping.test.ts
  • src/elements/content-sidebar/activity-feed-v2/task-modal-v2/utils/contactMapping.ts

@jackiejou jackiejou force-pushed the feat/task-modal-v2-contact-mapping branch from de59f8d to b1a0da4 Compare June 26, 2026 21:57
@jackiejou jackiejou force-pushed the feat/task-modal-v2-contact-mapping branch from b1a0da4 to fc0a7b3 Compare June 26, 2026 22:09
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.

2 participants