Skip to content

Conversation

@reneshen0328
Copy link
Contributor

@reneshen0328 reneshen0328 commented Oct 2, 2025

What

  • Create utility functions to transform the API data then pass into USM shared feature
  • This PR is an extension of PR
    • Add disabledReason into sharedLink
    • Add collaborators into USM (should see the already collaborated collaborators in the UI)
  • Add more descriptive VRTs
  • Organize the helper functions into api and non-api related folders
  • Cleanup ContentSharingV2 component leveraging util functions
  • TODOs in future PR: Add notification for success and error messages

Testing

Notes: ContentSharingV2 should look like the current ContentSharing when the provided permissions are the same

  • With Collaborators
    • Screenshot 2025-10-01 at 6 18 59 PM
  • Mock disabledReason for people in this item
    • Screenshot 2025-10-01 at 6 20 43 PM

Summary by CodeRabbit

  • New Features

    • Sharing dialog now shows collaborators enriched with avatar images and expanded collaborator details.
  • Improvements

    • Sequenced loading (item → current user → collaborators → avatars) for smoother, more reliable UX.
    • Sharing options surface disabled reasons for access choices (e.g., disabled “Invited people only”).
    • Access-level mapping refined for more consistent behavior.
  • Tests / Visuals

    • Expanded unit tests, mocks, and Storybook playbacks covering collaborator and avatar flows.

@reneshen0328 reneshen0328 requested review from a team as code owners October 2, 2025 01:13
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

Walkthrough

ContentSharingV2 now performs staged data fetches: fetchItem → fetchCurrentUser → fetchCollaborators → fetchAvatars, converts collaboration responses into enriched collaborator objects (with avatar URLs) and passes them to UnifiedShareModal; new fetcher modules, types, mocks, tests, and story play functions were added. I pity the fool who doesn't!

Changes

Cohort / File(s) Summary
Component wiring
src/elements/content-sharing/ContentSharingV2.tsx
Added state/effects for avatarURLMap, collaboratorsData, and collaborators; replaced inline API calls with orchestrated fetchers (item → currentUser → collaborators → avatars); calls convertCollabsResponse; passes enriched collaborators to UnifiedShareModal; added guards/reset on API change.
API fetchers
src/elements/content-sharing/apis/*
src/elements/content-sharing/apis/index.ts
New Promise-based utilities: fetchItem, fetchCurrentUser, fetchCollaborators, fetchAvatars; select appropriate API instances and return item/user/collaborations/avatar URL map; re-exported from index.ts.
Collaborator utilities
src/elements/content-sharing/utils/convertCollaborators.ts, src/elements/content-sharing/utils/index.ts
Added convertCollab and convertCollabsResponse to normalize Collaboration → Collaborator (avatarUrl, email, flags, expiresAt, role normalization); re-exported convertCollabsResponse.
Access levels & constants
src/elements/content-sharing/utils/getAllowedAccessLevels.ts, src/elements/content-sharing/utils/convertItemResponse.ts, src/elements/content-sharing/constants.js, src/elements/content-sharing/utils/constants.ts
Moved/updated constants and mappings: new API_TO_USM_ACCESS_LEVEL_MAP and updated getAllowedAccessLevels signature to accept disabled reasons; convertItemResponse updated to pass disabled reasons; classification color map moved into constants.js; removed old constants export.
Types
src/elements/content-sharing/types.js
Added BaseFetchProps, FetchItemProps, and FetchCollaboratorsProps to type fetch function parameters.
Mocks
src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js
Expanded mock data (avatar URL map, collaborator users, collaboration responses); updated default user/item responses; extended createMockAPI to provide getFileCollaborationsAPI/getFolderCollaborationsAPI and accept collaboratorsResponse; added preconfigured mock APIs.
Tests
src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx, src/elements/content-sharing/apis/__tests__/*, src/elements/content-sharing/utils/__tests__/*
Added unit tests for fetchItem, fetchCurrentUser, fetchCollaborators, fetchAvatars, convertCollab/convertCollabsResponse, and disabled access-level reasons; updated component tests to mock and assert collaborations/avatar calls; added API test utilities.
Stories (visual tests)
src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx
Added play functions for visual scenarios: modernization, shared-link flow, and collaborators dialog using updated mocks and test helpers.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CSV2 as ContentSharingV2
  participant Fetchers as Fetchers (fetchItem, fetchCurrentUser, fetchCollaborators, fetchAvatars)
  participant Users as UsersAPI
  participant Utils as convertCollabsResponse
  participant USM as UnifiedShareModal

  User->>CSV2: open modal
  CSV2->>Fetchers: fetchItem(itemID, itemType)
  Fetchers-->>CSV2: item
  CSV2->>Fetchers: fetchCurrentUser(itemID)
  Fetchers-->>CSV2: currentUser
  CSV2->>Fetchers: fetchCollaborators(itemID, itemType)
  Fetchers-->>CSV2: collaborations
  CSV2->>Fetchers: fetchAvatars(itemID, collaborations)
  Fetchers->>Users: getAvatarUrlWithAccessToken per collaborator
  Users-->>Fetchers: avatarURLMap
  Fetchers-->>CSV2: avatarURLMap
  CSV2->>Utils: convertCollabsResponse(collaborations, avatarURLMap)
  Utils-->>CSV2: collaborators[]
  CSV2->>USM: render({ collaborators })
  Note right of CSV2: state resets and guards run on API change
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

ready-to-merge

Suggested reviewers

  • jfox-box
  • jpan-box
  • tjuanitas

Poem

I pity the fool who skips the fetch queue,
Item then user, collabs, avatars too.
Convert and enrich each teammate's view,
Unified modal pops — ready for the crew. 💪📦

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed I pity the fool who can’t see that this title clearly summarizes the main change of converting the collaboration API response in the content-sharing feature.
Description Check ✅ Passed I pity the fool who overlooks that this pull request description includes well-defined “What” and “Testing” sections and retains the required merge instructions comment, fully aligning with the repository’s template.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-convert-api-response-for-collabs

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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/elements/content-sharing/constants.js (1)

1-79: Consolidate API_TO_USM_CLASSIFICATION_COLORS_MAP into a shared module, fool! Remove the duplicate in content-sharing/constants.js and import it from one source to keep a single source of truth. I pity the fool who doesn’t!

🧹 Nitpick comments (2)
src/elements/content-sharing/ContentSharingV2.tsx (2)

76-76: Redundant guard condition, fool!

Line 76 checks item || sharedLink, but if item is set, sharedLink is also set (see handleGetItemSuccess). So checking both is redundant, sucka! You can simplify the guard to just item!

Apply this diff to simplify the guard:

-        if (!api || isEmpty(api) || item || sharedLink) return;
+        if (!api || isEmpty(api) || item) return;

86-86: Redundant guard condition, fool!

Line 86 checks item || sharedLink, but as I said before, checking both is redundant, sucka! Simplify the guard to just item!

Apply this diff to simplify the guard:

-        if (!api || isEmpty(api) || item || sharedLink || currentUser) return;
+        if (!api || isEmpty(api) || item || currentUser) return;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 230f417 and c74ab36.

📒 Files selected for processing (18)
  • src/elements/content-sharing/ContentSharingV2.tsx (4 hunks)
  • src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx (4 hunks)
  • src/elements/content-sharing/apis/fetchAvatars.ts (1 hunks)
  • src/elements/content-sharing/apis/fetchCollaborators.ts (1 hunks)
  • src/elements/content-sharing/apis/fetchCurrentUser.ts (1 hunks)
  • src/elements/content-sharing/apis/fetchItem.ts (1 hunks)
  • src/elements/content-sharing/apis/index.ts (1 hunks)
  • src/elements/content-sharing/constants.js (2 hunks)
  • src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (1 hunks)
  • src/elements/content-sharing/types.js (2 hunks)
  • src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (3 hunks)
  • src/elements/content-sharing/utils/__tests__/convertCollaborators.test.ts (1 hunks)
  • src/elements/content-sharing/utils/__tests__/getAllowedAccessLevels.test.ts (1 hunks)
  • src/elements/content-sharing/utils/constants.ts (0 hunks)
  • src/elements/content-sharing/utils/convertCollaborators.ts (1 hunks)
  • src/elements/content-sharing/utils/convertItemResponse.ts (2 hunks)
  • src/elements/content-sharing/utils/getAllowedAccessLevels.ts (1 hunks)
  • src/elements/content-sharing/utils/index.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/elements/content-sharing/utils/constants.ts
🧰 Additional context used
🧬 Code graph analysis (12)
src/elements/content-sharing/apis/fetchCurrentUser.ts (1)
src/elements/content-sharing/apis/index.ts (1)
  • fetchCurrentUser (3-3)
src/elements/content-sharing/utils/getAllowedAccessLevels.ts (1)
src/elements/content-sharing/constants.js (6)
  • ANYONE_IN_COMPANY (82-82)
  • ANYONE_IN_COMPANY (82-82)
  • ANYONE_WITH_LINK (81-81)
  • ANYONE_WITH_LINK (81-81)
  • PEOPLE_IN_ITEM (83-83)
  • PEOPLE_IN_ITEM (83-83)
src/elements/content-sharing/utils/convertCollaborators.ts (3)
src/elements/content-sharing/SharingModal.js (1)
  • currentUserID (77-77)
src/elements/content-sharing/__tests__/useAvatars.test.js (1)
  • avatarURLMap (26-26)
src/features/unified-share-modal/utils/convertData.js (1)
  • collabsAPIData (431-431)
src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx (1)
src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (2)
  • MOCK_ITEM (14-18)
  • MOCK_ITEM (14-18)
src/elements/content-sharing/constants.js (2)
src/features/unified-share-modal/utils/convertData.js (1)
  • API_TO_USM_CLASSIFICATION_COLORS_MAP (100-109)
src/features/classification/constants.js (8)
  • CLASSIFICATION_COLOR_ID_0 (78-78)
  • CLASSIFICATION_COLOR_ID_1 (79-79)
  • CLASSIFICATION_COLOR_ID_2 (80-80)
  • CLASSIFICATION_COLOR_ID_3 (81-81)
  • CLASSIFICATION_COLOR_ID_4 (82-82)
  • CLASSIFICATION_COLOR_ID_5 (83-83)
  • CLASSIFICATION_COLOR_ID_6 (84-84)
  • CLASSIFICATION_COLOR_ID_7 (85-85)
src/elements/content-sharing/utils/__tests__/convertCollaborators.test.ts (2)
src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (12)
  • collabUser1 (38-43)
  • collabUser1 (38-43)
  • mockAvatarURLMap (30-32)
  • mockAvatarURLMap (30-32)
  • mockOwnerEmail (34-34)
  • mockOwnerEmail (34-34)
  • mockCurrentUserID (36-36)
  • mockCurrentUserID (36-36)
  • collabUser2 (45-50)
  • collabUser2 (45-50)
  • collabUser3 (52-57)
  • collabUser3 (52-57)
src/elements/content-sharing/utils/convertCollaborators.ts (2)
  • convertCollab (15-50)
  • convertCollabsResponse (52-63)
src/elements/content-sharing/apis/fetchItem.ts (1)
src/elements/content-sharing/constants.js (2)
  • CONTENT_SHARING_ITEM_FIELDS (45-59)
  • CONTENT_SHARING_ITEM_FIELDS (45-59)
src/elements/content-sharing/apis/fetchAvatars.ts (2)
src/elements/content-sharing/apis/index.ts (1)
  • fetchAvatars (1-1)
src/elements/content-sharing/__tests__/useAvatars.test.js (1)
  • avatarURLMap (26-26)
src/elements/content-sharing/utils/convertItemResponse.ts (1)
src/elements/content-sharing/utils/getAllowedAccessLevels.ts (1)
  • getAllowedAccessLevels (14-35)
src/elements/content-sharing/ContentSharingV2.tsx (6)
src/features/presence/PresenceAvatarList.tsx (1)
  • Collaborator (10-18)
src/elements/content-sharing/apis/fetchItem.ts (1)
  • fetchItem (8-22)
src/elements/content-sharing/apis/fetchCurrentUser.ts (1)
  • fetchCurrentUser (7-15)
src/elements/content-sharing/apis/fetchCollaborators.ts (1)
  • fetchCollaborators (6-21)
src/elements/content-sharing/apis/fetchAvatars.ts (1)
  • fetchAvatars (3-22)
src/elements/content-sharing/utils/convertCollaborators.ts (1)
  • convertCollabsResponse (52-63)
src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (2)
src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (6)
  • mockAPIWithoutSharedLink (180-184)
  • mockAPIWithoutSharedLink (180-184)
  • mockAPIWithSharedLink (175-179)
  • mockAPIWithSharedLink (175-179)
  • mockAPIWithCollaborators (185-189)
  • mockAPIWithCollaborators (185-189)
src/elements/content-sharing/stories/ContentSharingV2.stories.tsx (1)
  • withSharedLink (9-13)
src/elements/content-sharing/utils/__tests__/getAllowedAccessLevels.test.ts (1)
src/elements/content-sharing/utils/getAllowedAccessLevels.ts (1)
  • getAllowedAccessLevels (14-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary
🔇 Additional comments (18)
src/elements/content-sharing/utils/index.ts (1)

2-2: LGTM, fool!

The export of convertCollabsResponse is clean and follows the existing pattern in this barrel file. I pity the fool who doesn't appreciate a well-organized public API surface!

src/elements/content-sharing/constants.js (1)

81-83: LGTM, fool!

These new sharing access constants are clean and well-named. They align with the unified-share-modal terminology. I pity the fool who doesn't appreciate good naming conventions!

src/elements/content-sharing/utils/convertItemResponse.ts (1)

2-2: LGTM, fool!

The import change aligns with the constant relocation, and the updated getAllowedAccessLevels call correctly passes the new disabledReasons parameter. I pity the fool who doesn't appreciate a clean refactor!

Also applies to: 12-12, 63-66

src/elements/content-sharing/utils/__tests__/getAllowedAccessLevels.test.ts (1)

25-43: LGTM, fool!

These new tests properly verify the disabledReasons handling in getAllowedAccessLevels. I pity the fool who doesn't write comprehensive tests! The coverage for the new feature looks solid.

src/elements/content-sharing/apis/index.ts (1)

1-4: LGTM, fool!

This barrel file is clean and well-organized. I pity the fool who doesn't appreciate a properly structured API surface!

src/elements/content-sharing/apis/fetchCurrentUser.ts (1)

7-15: Confirm correct fields parameter format: I pity the fool who doesn't verify whether getUser expects a comma-separated string (from .toString()) or an array.

src/elements/content-sharing/utils/convertCollaborators.ts (1)

1-13: LGTM, fool!

The imports and interface definition are clean and well-typed. I got no beef with this setup!

src/elements/content-sharing/utils/getAllowedAccessLevels.ts (2)

1-12: LGTM, fool!

The imports and the API_TO_USM_ACCESS_LEVEL_MAP constant are clean and well-structured. I got no beef with this setup!


22-34: Ignore the undefined-guard suggestion: levels is AccessLevelType[] and API_TO_USM_ACCESS_LEVEL_MAP exhaustively covers those values, so apiLevel never ends up undefined. I pity the fool who thinks otherwise!

Likely an incorrect or invalid review comment.

src/elements/content-sharing/ContentSharingV2.tsx (6)

1-14: LGTM, fool!

The imports are clean and well-structured. I got no beef with this setup!


42-48: LGTM, fool!

The state declarations for avatarURLMap, collaborators, and collaboratorsData are clean and well-typed. I got no beef with this setup!


64-72: LGTM, fool!

The reset state effect is correct and handles the API change scenario properly. I got no beef with this, sucka!


103-114: LGTM, fool!

The fetch collaborators effect is correct and includes proper error handling. I got no beef with this, sucka!


127-132: LGTM, fool!

The convert collaborators effect is correct and handles the data transformation properly. I got no beef with this, sucka!


136-153: LGTM, fool!

The render function is correct and the new collaborators prop is passed to UnifiedShareModal properly. I got no beef with this, sucka!

src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (3)

1-27: LGTM, fool!

The imports and withModernization story are clean and the play function tests the UI interactions properly. I got no beef with this setup, sucka!


29-47: LGTM, fool!

The withSharedLink story is clean and the play function tests the shared link UI interactions properly. I got no beef with this, sucka!


49-64: LGTM, fool!

The withCollaborators story is clean and the play function tests the collaborators UI interactions properly. I got no beef with this, sucka!

@reneshen0328 reneshen0328 force-pushed the feat-convert-api-response-for-collabs branch from c74ab36 to a7ecc91 Compare October 2, 2025 01:50
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (3)
src/elements/content-sharing/ContentSharingV2.tsx (3)

77-80: Missing error handling for fetchItem, fool!

I pity the fool who doesn't handle errors! Lines 78-79 call fetchItem inside an async IIFE without error handling, sucka. If fetchItem throws, the error is unhandled and may cause a crash. Add a try-catch block to handle errors gracefully!

Apply this diff to add error handling:

         (async () => {
+            try {
                 const itemData = await fetchItem({ api, itemID, itemType });
                 handleGetItemSuccess(itemData);
+            } catch (error) {
+                console.error('Failed to fetch item:', error);
+            }
         })();

95-98: Missing error handling for fetchCurrentUser, fool!

I pity the fool who doesn't handle errors! Lines 96-97 call fetchCurrentUser inside an async IIFE without error handling, sucka. If fetchCurrentUser throws, the error is unhandled and may cause a crash. Add a try-catch block to handle errors gracefully!

Apply this diff to add error handling:

         (async () => {
+            try {
                 const userData = await fetchCurrentUser({ api, itemID });
                 getUserSuccess(userData);
+            } catch (error) {
+                console.error('Failed to fetch current user:', error);
+            }
         })();

119-122: Missing error handling for fetchAvatars, fool!

I pity the fool who doesn't handle errors! Lines 120-121 call fetchAvatars inside an async IIFE without error handling, sucka. If fetchAvatars throws, the error is unhandled and may cause a crash. Add a try-catch block to handle errors gracefully!

Apply this diff to add error handling:

         (async () => {
+            try {
                 const response = await fetchAvatars({ api, itemID, collaborators: collaboratorsData.entries });
                 setAvatarURLMap(response);
+            } catch (error) {
+                console.error('Failed to fetch avatars:', error);
+                setAvatarURLMap({});
+            }
         })();
🧹 Nitpick comments (2)
src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (1)

61-76: Prefer diverse roles in mock collaborations, fool!

I pity the fool who tests only one role! All entries in MOCK_COLLABORATIONS_RESPONSE have role: 'editor', which limits test coverage, sucka. Adding variety (e.g., 'viewer', 'owner') would better exercise role-dependent logic in convertCollab and related utilities.

Apply this diff to add role variety:

 export const MOCK_COLLABORATIONS_RESPONSE = {
     entries: MOCK_COLLABORATORS.map(user => ({
         id: `record_${user.id}`,
         accessible_by: user,
         expires_at: user.expires_at,
         created_by: {
             id: mockCurrentUserID,
             login: mockOwnerEmail,
             name: 'Astronaut Otter',
             type: 'user',
         },
-        role: 'editor',
+        role: user.id === 456 ? 'editor' : user.id === 457 ? 'viewer' : 'owner',
         status: 'accepted',
         type: user.type,
     })),
 };
src/elements/content-sharing/constants.js (1)

70-79: Duplicate mapping detected, fool!

I pity the fool who maintains duplicate code! API_TO_USM_CLASSIFICATION_COLORS_MAP at lines 70-79 is identical to the mapping in src/features/unified-share-modal/utils/convertData.js (lines 99-108), sucka. This duplication makes maintenance harder and increases the risk of inconsistency if one copy is updated but not the other.

Prefer one of these solutions:

Option 1: Extract to a shared constants module (recommended):

Create src/shared/constants/classificationColors.js:

import {
    CLASSIFICATION_COLOR_ID_0,
    CLASSIFICATION_COLOR_ID_1,
    CLASSIFICATION_COLOR_ID_2,
    CLASSIFICATION_COLOR_ID_3,
    CLASSIFICATION_COLOR_ID_4,
    CLASSIFICATION_COLOR_ID_5,
    CLASSIFICATION_COLOR_ID_6,
    CLASSIFICATION_COLOR_ID_7,
} from '../../features/classification/constants';
import {
    bdlDarkBlue50,
    bdlGray20,
    bdlGreenLight50,
    bdlLightBlue50,
    bdlOrange50,
    bdlPurpleRain50,
    bdlWatermelonRed50,
    bdlYellow50,
} from '../../styles/variables';

export const API_TO_USM_CLASSIFICATION_COLORS_MAP = {
    [bdlYellow50]: CLASSIFICATION_COLOR_ID_0,
    [bdlOrange50]: CLASSIFICATION_COLOR_ID_1,
    [bdlWatermelonRed50]: CLASSIFICATION_COLOR_ID_2,
    [bdlPurpleRain50]: CLASSIFICATION_COLOR_ID_3,
    [bdlLightBlue50]: CLASSIFICATION_COLOR_ID_4,
    [bdlDarkBlue50]: CLASSIFICATION_COLOR_ID_5,
    [bdlGreenLight50]: CLASSIFICATION_COLOR_ID_6,
    [bdlGray20]: CLASSIFICATION_COLOR_ID_7,
};

Then import from both locations:

-import {
-    CLASSIFICATION_COLOR_ID_0,
-    ...
-} from '../../features/classification/constants';
-...
-export const API_TO_USM_CLASSIFICATION_COLORS_MAP = { ... };
+import { API_TO_USM_CLASSIFICATION_COLORS_MAP } from '../../shared/constants/classificationColors';
+export { API_TO_USM_CLASSIFICATION_COLORS_MAP };

Option 2: Import from the existing location if module dependencies allow:

-import {
-    CLASSIFICATION_COLOR_ID_0,
-    ...
-} from '../../features/classification/constants';
-...
-export const API_TO_USM_CLASSIFICATION_COLORS_MAP = { ... };
+export { API_TO_USM_CLASSIFICATION_COLORS_MAP } from '../../features/unified-share-modal/utils/convertData';
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c74ab36 and a7ecc91.

📒 Files selected for processing (18)
  • src/elements/content-sharing/ContentSharingV2.tsx (4 hunks)
  • src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx (4 hunks)
  • src/elements/content-sharing/apis/fetchAvatars.ts (1 hunks)
  • src/elements/content-sharing/apis/fetchCollaborators.ts (1 hunks)
  • src/elements/content-sharing/apis/fetchCurrentUser.ts (1 hunks)
  • src/elements/content-sharing/apis/fetchItem.ts (1 hunks)
  • src/elements/content-sharing/apis/index.ts (1 hunks)
  • src/elements/content-sharing/constants.js (2 hunks)
  • src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (1 hunks)
  • src/elements/content-sharing/types.js (2 hunks)
  • src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (3 hunks)
  • src/elements/content-sharing/utils/__tests__/convertCollaborators.test.ts (1 hunks)
  • src/elements/content-sharing/utils/__tests__/getAllowedAccessLevels.test.ts (1 hunks)
  • src/elements/content-sharing/utils/constants.ts (0 hunks)
  • src/elements/content-sharing/utils/convertCollaborators.ts (1 hunks)
  • src/elements/content-sharing/utils/convertItemResponse.ts (2 hunks)
  • src/elements/content-sharing/utils/getAllowedAccessLevels.ts (1 hunks)
  • src/elements/content-sharing/utils/index.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/elements/content-sharing/utils/constants.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/elements/content-sharing/apis/fetchCurrentUser.ts
  • src/elements/content-sharing/utils/convertItemResponse.ts
  • src/elements/content-sharing/utils/getAllowedAccessLevels.ts
  • src/elements/content-sharing/tests/ContentSharingV2.test.tsx
  • src/elements/content-sharing/apis/index.ts
  • src/elements/content-sharing/types.js
  • src/elements/content-sharing/apis/fetchCollaborators.ts
🧰 Additional context used
🧬 Code graph analysis (7)
src/elements/content-sharing/utils/__tests__/getAllowedAccessLevels.test.ts (2)
src/elements/content-sharing/utils/getAllowedAccessLevels.ts (1)
  • getAllowedAccessLevels (14-35)
src/elements/content-sharing/utils/index.ts (1)
  • getAllowedAccessLevels (3-3)
src/elements/content-sharing/constants.js (2)
src/features/unified-share-modal/utils/convertData.js (1)
  • API_TO_USM_CLASSIFICATION_COLORS_MAP (100-109)
src/features/classification/constants.js (8)
  • CLASSIFICATION_COLOR_ID_0 (78-78)
  • CLASSIFICATION_COLOR_ID_1 (79-79)
  • CLASSIFICATION_COLOR_ID_2 (80-80)
  • CLASSIFICATION_COLOR_ID_3 (81-81)
  • CLASSIFICATION_COLOR_ID_4 (82-82)
  • CLASSIFICATION_COLOR_ID_5 (83-83)
  • CLASSIFICATION_COLOR_ID_6 (84-84)
  • CLASSIFICATION_COLOR_ID_7 (85-85)
src/elements/content-sharing/utils/__tests__/convertCollaborators.test.ts (2)
src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (12)
  • collabUser1 (38-43)
  • collabUser1 (38-43)
  • mockAvatarURLMap (30-32)
  • mockAvatarURLMap (30-32)
  • mockOwnerEmail (34-34)
  • mockOwnerEmail (34-34)
  • mockCurrentUserID (36-36)
  • mockCurrentUserID (36-36)
  • collabUser2 (45-50)
  • collabUser2 (45-50)
  • collabUser3 (52-57)
  • collabUser3 (52-57)
src/elements/content-sharing/utils/convertCollaborators.ts (2)
  • convertCollab (15-50)
  • convertCollabsResponse (52-62)
src/elements/content-sharing/apis/fetchItem.ts (1)
src/elements/content-sharing/constants.js (2)
  • CONTENT_SHARING_ITEM_FIELDS (45-59)
  • CONTENT_SHARING_ITEM_FIELDS (45-59)
src/elements/content-sharing/ContentSharingV2.tsx (5)
src/elements/content-sharing/apis/fetchItem.ts (1)
  • fetchItem (8-22)
src/elements/content-sharing/apis/fetchCurrentUser.ts (1)
  • fetchCurrentUser (7-15)
src/elements/content-sharing/apis/fetchCollaborators.ts (1)
  • fetchCollaborators (6-21)
src/elements/content-sharing/apis/fetchAvatars.ts (1)
  • fetchAvatars (3-22)
src/elements/content-sharing/utils/convertCollaborators.ts (1)
  • convertCollabsResponse (52-62)
src/elements/content-sharing/utils/convertCollaborators.ts (3)
src/elements/content-sharing/SharingModal.js (1)
  • currentUserID (77-77)
src/elements/content-sharing/__tests__/useAvatars.test.js (1)
  • avatarURLMap (26-26)
src/elements/content-sharing/utils/index.ts (1)
  • convertCollabsResponse (2-2)
src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (2)
src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (6)
  • mockAPIWithoutSharedLink (181-185)
  • mockAPIWithoutSharedLink (181-185)
  • mockAPIWithSharedLink (176-180)
  • mockAPIWithSharedLink (176-180)
  • mockAPIWithCollaborators (186-190)
  • mockAPIWithCollaborators (186-190)
src/elements/content-sharing/stories/ContentSharingV2.stories.tsx (1)
  • withSharedLink (9-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint_test_build
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Summary
🔇 Additional comments (30)
src/elements/content-sharing/utils/__tests__/getAllowedAccessLevels.test.ts (1)

25-43: DisabledReasons mapping verified: ACCESS_OPEN→peopleWithTheLink, ACCESS_COMPANY→anyoneInCompany, ACCESS_COLLAB→peopleInThisItem—tests align with API_TO_USM_ACCESS_LEVEL_MAP. Suggest adding edge-case coverage for invalid keys, multiple disabledReasons, and null/undefined inputs.

src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (6)

38-59: LGTM, fool!

The collaborator user mocks are well-structured and provide good test data coverage for different collaboration scenarios, sucka!


82-102: LGTM, fool!

The updates to DEFAULT_USER_API_RESPONSE and DEFAULT_ITEM_API_RESPONSE align with the new features for collaborators and disabled reasons, sucka!


109-112: LGTM, fool!

The MOCK_ITEM_API_RESPONSE_WITH_COLLABORATORS mock correctly includes the collaborators field to support testing scenarios with collaborators, sucka!


141-147: LGTM, fool!

I pity the fool who forgets to add stubs! The getAvatarUrlWithAccessToken method at line 147 correctly provides the avatar URL mapping, resolving the past review concern, sucka!


150-172: LGTM, fool!

The new getFileCollaborationsAPI and getFolderCollaborationsAPI methods provide consistent mock implementations for collaborator fetching, sucka!


176-190: LGTM, fool!

The pre-configured mock APIs (mockAPIWithSharedLink, mockAPIWithoutSharedLink, mockAPIWithCollaborators) provide comprehensive coverage for different testing scenarios, sucka!

src/elements/content-sharing/utils/index.ts (1)

2-2: LGTM, fool!

The new export convertCollabsResponse correctly expands the module's public API surface to include collaboration conversion utilities, sucka!

src/elements/content-sharing/constants.js (2)

1-20: LGTM, fool!

The imports correctly bring in the classification color IDs and variables needed for the new mapping, sucka!


81-83: LGTM, fool!

The new constants ANYONE_WITH_LINK, ANYONE_IN_COMPANY, and PEOPLE_IN_ITEM are well-named and support the content-sharing enhancements, sucka!

src/elements/content-sharing/apis/fetchItem.ts (2)

8-13: LGTM, fool!

The fetchItem function return type is now Promise<Item | null>, which resolves the past review concern about type mismatch, sucka! The TYPE_FILE branch correctly calls getFileAPI().getFile with the appropriate fields.


15-21: LGTM, fool!

The TYPE_FOLDER branch and default return correctly handle folder fetching and unhandled item types, sucka!

src/elements/content-sharing/apis/fetchAvatars.ts (3)

3-5: LGTM, fool!

The initialization of usersAPI and avatarURLMap is correct, sucka!


20-21: LGTM, fool!

The use of Promise.all to wait for all avatar fetches and the return of avatarURLMap is correct, sucka!


7-18: Ignore async verification for getAvatarUrlWithAccessToken
I pity the fool who doubts this—getAvatarUrlWithAccessToken is declared async and returns a Promise in src/api/Users.js.

Likely an incorrect or invalid review comment.

src/elements/content-sharing/utils/convertCollaborators.ts (2)

15-50: LGTM, fool!

The convertCollab function correctly guards against null/undefined collabs and empty roles, resolving the past review concerns, sucka! The logic for isCurrentUser, isExternal, and avatarUrl is sound.


52-62: LGTM, fool!

The convertCollabsResponse function correctly handles missing created_by with a fallback (|| {}), resolving the past review concern, sucka! The flatMap logic correctly filters out null results from convertCollab.

src/elements/content-sharing/ContentSharingV2.tsx (7)

5-14: LGTM, fool!

The new imports for types and fetch utilities are correctly added to support the enhanced collaboration flow, sucka!


42-48: LGTM, fool!

The new state variables for avatarURLMap, collaborators, and collaboratorsData correctly support the enhanced collaboration and avatar fetching flow, sucka!


51-60: LGTM, fool!

The handleGetItemSuccess callback correctly processes the item response and sets state, sucka!


63-71: LGTM, fool!

The state reset logic correctly includes the new avatarURLMap, collaborators, and collaboratorsData state variables, sucka!


101-113: LGTM, fool!

The fetchCollaborators useEffect correctly includes error handling with a try-catch block and sets a safe fallback state on error, sucka!


126-131: LGTM, fool!

The useEffect that converts collaborators using convertCollabsResponse correctly waits for both collaboratorsData and avatarURLMap to be ready, sucka!


133-142: LGTM, fool!

The config object and the new collaborators prop correctly integrate the enhanced collaboration data into the UnifiedShareModal, sucka!

src/elements/content-sharing/utils/__tests__/convertCollaborators.test.ts (2)

14-159: LGTM, fool!

The convertCollab test suite provides comprehensive coverage for valid collaborations, edge cases (null/undefined, non-accepted status), current user identification, external user identification, avatar URL map variants, and missing expiration dates, sucka!


161-247: LGTM, fool!

The convertCollabsResponse test suite provides comprehensive coverage for converting valid collaborations, handling empty entries, and processing null avatar URL maps, sucka! The test correctly verifies that only accepted collaborations are included in the result.

src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (4)

17-26: LGTM, fool — once you fix that Storybook version!

The interaction testing logic is solid as gold chains: proper async/await, good accessibility queries with getByRole, and clear test flow (find button → click → verify modal elements). I appreciate the organized structure, sucka!

Just remember: this whole play function depends on fixing that Storybook v4 incompatibility I flagged above. Get that sorted, and you'll be ready to test!


33-46: I love it when a plan comes together, fool!

Reusing withModernization.play(context) shows you ain't duplicating code like some jibber-jabber fool! The test flow is clean: verify shared link UI → click access button → confirm the "Invited people only" option is properly disabled. This aligns with the PR's disabledReason feature.

Solid work, sucka!


53-63: Outstanding work, fool!

This test don't mess around - it verifies every piece of that collaborators UI like I verify every member of my team! You're checking the avatars button, the Manage All link, the grid structure, a specific collaborator row, AND the Done button. That's thoroughness I can respect, sucka!

The composition pattern keeps working for you too - reusing withModernization.play keeps your code tight and right!


66-74: Story metadata looks good, fool!

The default export configuration is solid - proper title, component reference, and common args for the visual regression tests. No changes needed here, sucka!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/elements/content-sharing/apis/__tests__/fetchItem.test.ts (1)

1-51: Good coverage, but I pity the fool who skips the folder error path!

These tests nail the file/folder success paths and unsupported types. However, only the file error path is tested (lines 40-49). Consider adding a corresponding test for folder API errors to ensure symmetric coverage, fool!

Add a folder error test after line 49:

+    test('should handle folder API errors', async () => {
+        const errorMock = jest.fn().mockImplementation((itemID, successCallback, errorCallback) => {
+            errorCallback(new Error('Folder API Error'));
+        });
+        const errorAPIMock = createItemAPIMock({ getFile: getDefaultFileMock }, { getFolderFields: errorMock });
+
+        await expect(fetchItem({ api: errorAPIMock, itemID: MOCK_ITEM.id, itemType: TYPE_FOLDER })).rejects.toThrow(
+            'Folder API Error',
+        );
+    });
src/elements/content-sharing/apis/__tests__/testUtils.ts (1)

1-9: Question the 500ms delay, fool!

The createSuccessMock introduces a 500ms timeout before resolving. Unless this delay is specifically testing async timing behavior, it unnecessarily slows down your test suite. I pity the fool who waits around when they don't have to!

Consider removing the timeout if it's not testing timing-specific behavior:

-export const createSuccessMock = responseFromAPI => (itemID, successFn) => {
-    return new Promise(resolve => {
-        setTimeout(() => {
-            resolve(responseFromAPI);
-        }, 500);
-    }).then(response => {
-        successFn(response);
-    });
-};
+export const createSuccessMock = responseFromAPI => (itemID, successFn) => {
+    return Promise.resolve(responseFromAPI).then(response => {
+        successFn(response);
+    });
+};
src/elements/content-sharing/apis/__tests__/fetchCollaborators.test.ts (1)

1-45: Good start, but I pity the fool who forgets error tests!

These tests cover the success paths for file/folder collaborators and correctly handle unsupported types. However, there's no test for API error scenarios (similar to what's in fetchItem.test.ts and fetchCurrentUser.test.ts). Consider adding error handling tests for consistency, fool!

Add error handling tests after line 43:

+    test('should handle file collaborations API errors', async () => {
+        const errorMock = jest.fn().mockImplementation((itemID, successCallback, errorCallback) => {
+            errorCallback(new Error('File Collaborations API Error'));
+        });
+        const errorAPIMock = createCollabAPIMock(
+            { getCollaborations: errorMock },
+            { getCollaborations: getDefaultFolderCollabMock },
+        );
+
+        await expect(fetchCollaborators({ api: errorAPIMock, itemID: MOCK_ITEM.id, itemType: TYPE_FILE })).rejects.toThrow(
+            'File Collaborations API Error',
+        );
+    });
+
+    test('should handle folder collaborations API errors', async () => {
+        const errorMock = jest.fn().mockImplementation((itemID, successCallback, errorCallback) => {
+            errorCallback(new Error('Folder Collaborations API Error'));
+        });
+        const errorAPIMock = createCollabAPIMock(
+            { getCollaborations: getDefaultFileCollabMock },
+            { getCollaborations: errorMock },
+        );
+
+        await expect(fetchCollaborators({ api: errorAPIMock, itemID: MOCK_ITEM.id, itemType: TYPE_FOLDER })).rejects.toThrow(
+            'Folder Collaborations API Error',
+        );
+    });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7ecc91 and f28bde0.

📒 Files selected for processing (5)
  • src/elements/content-sharing/apis/__tests__/fetchAvatars.test.ts (1 hunks)
  • src/elements/content-sharing/apis/__tests__/fetchCollaborators.test.ts (1 hunks)
  • src/elements/content-sharing/apis/__tests__/fetchCurrentUser.test.ts (1 hunks)
  • src/elements/content-sharing/apis/__tests__/fetchItem.test.ts (1 hunks)
  • src/elements/content-sharing/apis/__tests__/testUtils.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-02T16:47:50.687Z
Learnt from: reneshen0328
PR: box/box-ui-elements#4322
File: src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js:30-36
Timestamp: 2025-10-02T16:47:50.687Z
Learning: In src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js, mockCurrentUserID is intentionally a number (789) while DEFAULT_USER_API_RESPONSE.id is a string ('789'). This represents different stages of data transformation: mockCurrentUserID is the raw API response before conversion, and DEFAULT_USER_API_RESPONSE.id is the post-conversion state after fetchCurrentUser processes it.

Applied to files:

  • src/elements/content-sharing/apis/__tests__/fetchCurrentUser.test.ts
🧬 Code graph analysis (5)
src/elements/content-sharing/apis/__tests__/fetchItem.test.ts (1)
src/elements/content-sharing/apis/__tests__/testUtils.ts (2)
  • createSuccessMock (1-9)
  • createItemAPIMock (11-14)
src/elements/content-sharing/apis/__tests__/fetchCurrentUser.test.ts (1)
src/elements/content-sharing/apis/__tests__/testUtils.ts (2)
  • createSuccessMock (1-9)
  • createUsersAPIMock (21-23)
src/elements/content-sharing/apis/__tests__/fetchCollaborators.test.ts (1)
src/elements/content-sharing/apis/__tests__/testUtils.ts (2)
  • createSuccessMock (1-9)
  • createCollabAPIMock (16-19)
src/elements/content-sharing/apis/__tests__/fetchAvatars.test.ts (1)
src/elements/content-sharing/apis/__tests__/testUtils.ts (2)
  • createSuccessMock (1-9)
  • createUsersAPIMock (21-23)
src/elements/content-sharing/apis/__tests__/testUtils.ts (1)
src/elements/content-sidebar/versions/__tests__/VersionsSidebarAPI.test.js (1)
  • fileAPI (7-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary
🔇 Additional comments (3)
src/elements/content-sharing/apis/__tests__/fetchCurrentUser.test.ts (1)

1-34: LGTM, fool! Solid test coverage for fetchCurrentUser.

These tests cover the critical paths—success and error handling—and properly verify API invocations with correct field parameters. The mock setup is clean and reusable. I pity the fool who breaks this flow!

src/elements/content-sharing/apis/__tests__/fetchAvatars.test.ts (1)

1-95: Excellent test coverage, fool! I'm impressed!

These tests are comprehensive—covering success, partial failures, missing data, and empty arrays. The error handling verification ensures failed avatar fetches return null while allowing successful ones to proceed. I pity the fool who doesn't write tests like these!

src/elements/content-sharing/apis/__tests__/testUtils.ts (1)

11-23: LGTM! Clean mock factories, fool!

The createItemAPIMock, createCollabAPIMock, and createUsersAPIMock factories are well-structured and provide the necessary mock surfaces for testing file/folder APIs, collaborations APIs, and users API respectively. I pity the fool who doesn't reuse these utilities!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/elements/content-sharing/ContentSharingV2.tsx (1)

133-135: Drop the debug log, sucker!

I pity the fool who ships console.log in prod. Yank it before this hits master.

-    console.log('collaborators', collaborators);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f28bde0 and bbf2009.

📒 Files selected for processing (4)
  • src/elements/content-sharing/ContentSharingV2.tsx (3 hunks)
  • src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx (5 hunks)
  • src/elements/content-sharing/apis/fetchAvatars.ts (1 hunks)
  • src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/elements/content-sharing/apis/fetchAvatars.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-02T16:47:50.687Z
Learnt from: reneshen0328
PR: box/box-ui-elements#4322
File: src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js:30-36
Timestamp: 2025-10-02T16:47:50.687Z
Learning: In src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js, mockCurrentUserID is intentionally a number (789) while DEFAULT_USER_API_RESPONSE.id is a string ('789'). This represents different stages of data transformation: mockCurrentUserID is the raw API response before conversion, and DEFAULT_USER_API_RESPONSE.id is the post-conversion state after fetchCurrentUser processes it.

Applied to files:

  • src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js
🧬 Code graph analysis (2)
src/elements/content-sharing/ContentSharingV2.tsx (6)
src/features/presence/PresenceAvatarList.tsx (1)
  • Collaborator (10-18)
src/elements/content-sharing/apis/fetchItem.ts (1)
  • fetchItem (8-22)
src/elements/content-sharing/apis/fetchCurrentUser.ts (1)
  • fetchCurrentUser (7-15)
src/elements/content-sharing/apis/fetchCollaborators.ts (1)
  • fetchCollaborators (6-21)
src/elements/content-sharing/apis/fetchAvatars.ts (1)
  • fetchAvatars (3-22)
src/elements/content-sharing/utils/convertCollaborators.ts (1)
  • convertCollabsResponse (52-62)
src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx (1)
src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (6)
  • MOCK_COLLABORATIONS_RESPONSE (65-80)
  • MOCK_COLLABORATIONS_RESPONSE (65-80)
  • mockAvatarURLMap (30-32)
  • mockAvatarURLMap (30-32)
  • MOCK_ITEM (14-18)
  • MOCK_ITEM (14-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bbf2009 and 9c2f036.

📒 Files selected for processing (1)
  • src/elements/content-sharing/ContentSharingV2.tsx (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/elements/content-sharing/ContentSharingV2.tsx (5)
src/elements/content-sharing/apis/fetchItem.ts (1)
  • fetchItem (8-22)
src/elements/content-sharing/apis/fetchCurrentUser.ts (1)
  • fetchCurrentUser (7-15)
src/elements/content-sharing/apis/fetchCollaborators.ts (1)
  • fetchCollaborators (6-21)
src/elements/content-sharing/apis/fetchAvatars.ts (1)
  • fetchAvatars (3-22)
src/elements/content-sharing/utils/convertCollaborators.ts (1)
  • convertCollabsResponse (52-62)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (8)
src/elements/content-sharing/ContentSharingV2.tsx (8)

5-14: LGTM, fool!

The new imports are all necessary for the data fetching and transformation flow, sucka! Clean organization separating API utilities from conversion utilities!


42-48: LGTM, fool!

Good separation of concerns, sucka! You got raw API data (collaboratorsData), avatar mapping (avatarURLMap), and final enriched collaborators (collaborators). Clean state management!


68-70: LGTM, fool!

You're resetting all the new collaboration state when the API changes, sucka! Prevents stale data from hanging around. Clean!


77-80: Acknowledged deferred error handling, fool!

I see you're gonna handle errors in a future PR, sucka - that's cool! The fetchItem call logic looks good for now.


106-111: Good error handling, fool!

I like that you wrapped fetchCollaborators in a try-catch, sucka! Setting an empty array as fallback is solid defensive programming!


117-122: Guard logic is correct here, fool!

This guard properly waits for collaboratorsData.entries to exist before fetching avatars, sucka! The error handling is acknowledged as deferred to future PR.


125-131: LGTM, fool!

Clean enrichment logic, sucka! You're waiting for BOTH collaboratorsData AND avatarURLMap before combining them into final enriched collaborators. Smart!


142-142: LGTM, fool!

You're passing the enriched collaborators to UnifiedShareModal, sucka! Clean completion of the data pipeline!

Copy link
Contributor

@jfox-box jfox-box left a comment

Choose a reason for hiding this comment

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

LGTM, just 1 change request

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (1)

53-65: I pity the fool who forgets to wrap async operations in waitFor!

Good job usin' waitFor around your collaborators check, fool! That sharedWithAvatars button might take a hot minute to render after them avatars get fetched, so wrappin' it in waitFor prevents your test from failin' when the UI ain't ready yet.

Your test flow is clean:

  1. Open the modal (reusing withModernization.play - smart!)
  2. Wait for and click the "Shared with" button
  3. Verify all them collaborator UI elements show up

One thing though, sucka - you got waitFor wrappin' the entire block including the click and the subsequent assertions. Consider whether you need to wait for ALL of them assertions or just the initial button. If the modal opens instantly after the click, you could move some assertions outside waitFor for faster test execution.

You could restructure this to only wait for what needs waitin':

 play: async context => {
     await withModernization.play(context);
-    await waitFor(async () => {
-        const sharedWithAvatars = screen.getByRole('button', { name: 'Shared with D R D' });
-        expect(sharedWithAvatars).toBeVisible();
-        await userEvent.click(sharedWithAvatars);
-
-        expect(screen.getByRole('link', { name: 'Manage All' })).toBeVisible();
-        expect(screen.getByRole('grid', { name: 'Collaborators' })).toBeVisible();
-        expect(screen.getByRole('row', { name: /Detective Parrot/ })).toBeVisible();
-        expect(screen.getByRole('button', { name: 'Done' })).toBeVisible();
-    });
+    const sharedWithAvatars = await screen.findByRole('button', { name: 'Shared with D R D' });
+    expect(sharedWithAvatars).toBeVisible();
+    await userEvent.click(sharedWithAvatars);
+
+    expect(screen.getByRole('link', { name: 'Manage All' })).toBeVisible();
+    expect(screen.getByRole('grid', { name: 'Collaborators' })).toBeVisible();
+    expect(screen.getByRole('row', { name: /Detective Parrot/ })).toBeVisible();
+    expect(screen.getByRole('button', { name: 'Done' })).toBeVisible();
 },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec96144 and f6bd77c.

📒 Files selected for processing (1)
  • src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (2)
src/elements/content-sharing/utils/__mocks__/ContentSharingV2Mocks.js (6)
  • mockAPIWithoutSharedLink (185-189)
  • mockAPIWithoutSharedLink (185-189)
  • mockAPIWithSharedLink (180-184)
  • mockAPIWithSharedLink (180-184)
  • mockAPIWithCollaborators (190-194)
  • mockAPIWithCollaborators (190-194)
src/elements/content-sharing/stories/ContentSharingV2.stories.tsx (1)
  • withSharedLink (9-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary
🔇 Additional comments (2)
src/elements/content-sharing/stories/tests/ContentSharingV2-visual.stories.tsx (2)

17-26: This play function lookin' good, fool!

I like how you're testin' this interaction flow step by step:

  1. Find and click that button to open the modal
  2. Verify the heading, combobox, and switch all show up like they supposed to

The async/await pattern is solid, and you're using findByRole for the button (which waits automatically) and checking visibility properly. That's how a champion does it!


33-46: Smart move reusing that play function, fool!

You're callin' withModernization.play(context) first to handle the modal opening, then verifying all them shared link elements. That's good code reuse, sucka!

The test flow is solid:

  • Verify the link URL and settings button
  • Click the access dropdown
  • Check that "Invited people only" is disabled

The toHaveAttribute('aria-disabled', 'true') assertion is the right way to verify that disabled state in accessible components.

@mergify mergify bot merged commit 6937b60 into master Oct 3, 2025
10 checks passed
@mergify mergify bot deleted the feat-convert-api-response-for-collabs branch October 3, 2025 16:45
@mergify mergify bot removed the queued label Oct 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants