Skip to content

Conversation

@reneshen0328
Copy link
Contributor

@reneshen0328 reneshen0328 commented Oct 17, 2025

What

Before this PR: when user type in already exists managed user's email into the collaboration section and press enter, the collaborator will be created as an external (new) user.
After this PR: getMarkerBasedUsersAPI (created and used by existing contentSharingV1) is called, the contactService object which returns getContactByEmail is passed in successfully, and the in the UI when user type in already exists managed user's email into the collaboration section and press enter, the collaborator should be returned as an API entry hence treat the email input as a managed user (without the isExternal icon).

Testing:

Screen.Recording.2025-10-16.at.9.16.13.PM.mov

Summary by CodeRabbit

  • New Features

    • Feature-flagged email-based contact lookup added, with localized "Group" label and improved single-email handling.
  • Public API

    • Contact service exposes an email-lookup path and a new conversion helper for email-based results; public types/options updated to support the V2 path.
  • Tests

    • Tests migrated to React Testing Library hooks, expanded to cover V2 email flows, transformed/empty/error cases, and include per-test mock cleanup.

@reneshen0328 reneshen0328 requested review from a team as code owners October 17, 2025 04:15
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 17, 2025

Walkthrough

Adds feature-flagged email-based contact retrieval (V2) and conversion, exposes getContactByEmail from the contact service, updates converters and i18n label, migrates tests to React Testing Library renderHook, and adjusts types/exports to include the new contact-by-email flow.

Changes

Cohort / File(s) Summary
Test suite migrations
src/elements/content-sharing/__tests__/useContactsByEmail.test.js, src/elements/content-sharing/hooks/__tests__/useContactService.test.ts
Replaced Enzyme mounts with React Testing Library renderHook/act; removed FakeComponent/button-click flows; added per-test setup/teardown and jest.resetAllMocks; renamed spies to mocks; added V2 scenarios (transformed/empty/error) and updated assertions to reflect hook-based returns.
Contact service hook implementation
src/elements/content-sharing/hooks/useContactService.ts
Added useIntl/formatMessage, imported convertUserContactByEmailResponse, wired useContactsByEmail, introduced getContactByEmail, and returned { contactService: { getContactByEmail, getContacts } }; transformUsers now uses converters and localized group label.
Email-based contact retrieval hook
src/elements/content-sharing/hooks/useContactsByEmail.js
Added isContentSharingV2Enabled option and GetContactByEmailFnType; implemented dual-path logic (V2 uses getUsersInEnterprise by email; legacy V1 uses filter_term with first email); hook returns appropriate function type or null.
Contact conversion utilities & tests
src/elements/content-sharing/utils/convertContactServiceData.ts, src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts
Updated convertGroupContactsResponse to accept a second parameter (email/group label) and set group value to group id; added and exported convertUserContactByEmailResponse which maps first API entry to a contact; added tests for empty/valid/missing/undefined login cases.
Utils exports
src/elements/content-sharing/utils/index.ts
Re-exported convertUserContactByEmailResponse alongside existing converters.
Types
src/elements/content-sharing/types.js
Added GetContactByEmailFnType describing the new V2 function signature exposed by the hooks.
Messages
src/elements/content-sharing/messages.js
Added groupContactLabel i18n message used when constructing localized group display text.
UI wiring
src/elements/content-sharing/SharingModal.js
Updated to accept the union getContactsByEmail / getContactByEmail function type; adjusted state initializations (formatting) and propagated the broader function type through props to UnifiedShareModal.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant ContactService as useContactService
    participant Hook as useContactsByEmail
    participant API as getUsersInEnterprise
    participant Converter as convertUserContactByEmailResponse

    Client->>ContactService: call getContactByEmail(email)
    ContactService->>Hook: request (isContentSharingV2Enabled?, transformUsers)

    alt V2 enabled
        Hook->>API: getUsersInEnterprise({ filter_term: email })
        API-->>Hook: users array
        Hook->>Converter: convert first entry
        Converter-->>Hook: contact object
    else V1 (legacy)
        Hook->>API: getUsersInEnterprise({ filter_term: parsedFilterTerm })
        API-->>Hook: users array
        Hook->>Hook: apply legacy transformUsers (filter_term first email)
    end

    Hook-->>ContactService: resolved contact(s)
    ContactService-->>Client: return contact(s)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

ready-to-merge

Suggested reviewers

  • jfox-box
  • tjuanitas
  • jpan-box

Poem

🐇 I hopped through hooks and tests with cheer,

A flag, a converter, an email near,
Types snug, messages in place,
Tests now tidy, code keeps pace,
Thump-thump — new contacts, hoppity-dear!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feat(content-sharing): Create contact service getContactByEmail" directly and clearly reflects the main objective of this changeset. The title accurately describes the primary change—creating a new getContactByEmail method in the contact service—which aligns with the extensive modifications across multiple files to introduce email-based contact retrieval functionality. The title is specific, concise, and follows conventional commit formatting, making it easily scannable in commit history.
Description Check ✅ Passed The pull request description provides meaningful content explaining both the problem and solution: it describes the behavior before the PR (managed user emails incorrectly treated as external users), the expected behavior after (managed users correctly identified via the new getContactByEmail), and includes a testing video link. While the description also contains the template's procedural guidance about the ready-to-merge label and approval troubleshooting, the core informational sections clearly communicate the change's purpose and impact, meeting the basic requirements for a complete pull request description.
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 create-contact-service-getContactByEmail

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: 5

🧹 Nitpick comments (4)
src/elements/content-sharing/hooks/useContactService.ts (1)

1-2: Add minimal TypeScript annotations to avoid implicit any

This .ts file has untyped params/return. If noImplicitAny is enabled, builds may fail. Consider adding lightweight types.

Example:

// outside selected lines; illustration only
type ContactService = {
    getContacts: (...args: any[]) => any;
    getContactByEmail: (...args: any[]) => any;
};

export const useContactService = (api: any, itemId: string, currentUserId: string): { contactService: ContactService } => { /* ... */ };

If API types exist, replace any with those types.

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

337-435: Deduplicate/clarify two “undefined login” tests and add multi-entry case

You currently have overlapping tests for missing/undefined login; one is duplicated and named the same.

Apply:

-            test('should handle user contact with undefined login field', () => {
-                const contactsApiData = {
-                    entries: [
-                        {
-                            id: 'user-1',
-                            name: 'Jane Smith',
-                            type: 'user',
-                        },
-                    ],
-                };
-
-                const result = convertUserContactByEmailResponse(contactsApiData);
-
-                expect(result).toEqual({
-                    id: 'user-1',
-                    email: '',
-                    name: 'Jane Smith',
-                    type: 'user',
-                    value: '',
-                });
-            });
+            // already covered by "missing login field"

Optionally, assert first-entry selection:

// inside the same describe
test('should return first entry when multiple are present', () => {
    const contactsApiData = {
        entries: [
            { id: 'user-1', login: 'a@example.com', name: 'A', type: 'user' },
            { id: 'user-2', login: 'b@example.com', name: 'B', type: 'user' },
        ],
    };
    expect(convertUserContactByEmailResponse(contactsApiData)).toEqual({
        id: 'user-1',
        email: 'a@example.com',
        name: 'A',
        type: 'user',
        value: 'a@example.com',
    });
});
src/elements/content-sharing/hooks/useContactsByEmail.js (1)

25-27: Allow runtime flag changes (optional)

The early return prevents re-binding when isContentSharingV2Enabled flips at runtime. If flags can change, set the function on each change.

Example:

-    React.useEffect(() => {
-        if (getContactsByEmail) return;
+    React.useEffect(() => {
         // ...
-        isContentSharingV2Enabled
-            ? setGetContactsByEmail(getContactsByEmailV2)
-            : setGetContactsByEmail(updatedGetContactsByEmailFn);
-    }, [api, getContactsByEmail, handleError, handleSuccess, isContentSharingV2Enabled, itemID, transformUsers]);
+        const fn = isContentSharingV2Enabled ? getContactsByEmailV2 : updatedGetContactsByEmailFn;
+        setGetContactsByEmail(() => fn);
+    }, [api, handleError, handleSuccess, isContentSharingV2Enabled, itemID, transformUsers]);

Also applies to: 73-76

src/elements/content-sharing/__tests__/useContactsByEmail.test.js (1)

227-232: Consider using waitFor instead of hardcoded setTimeout.

Using a hardcoded 100ms delay with setTimeout can lead to flaky tests if the async operation takes longer. React Testing Library provides waitFor utility for more reliable async testing.

Apply this diff to use waitFor:

+        await act(async () => {
+            await result.current({ emails: [MOCK_EMAIL] });
+        });

-        result.current({ emails: [MOCK_EMAIL] });
-
-        // Wait a short time to ensure handleError is called
-        await act(async () => {
-            await new Promise(resolve => setTimeout(resolve, 100));
-        });
+        // The error should be called synchronously or very quickly
+        await new Promise(resolve => setTimeout(resolve, 0));

Alternatively, if the hook doesn't return a promise rejection, you could import and use waitFor:

import { renderHook, act, waitFor } from '@testing-library/react';

// In the test:
await act(async () => {
    result.current({ emails: [MOCK_EMAIL] });
});

await waitFor(() => {
    expect(handleError).toHaveBeenCalled();
});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae6ccc and 8f8aa55.

📒 Files selected for processing (7)
  • src/elements/content-sharing/__tests__/useContactsByEmail.test.js (6 hunks)
  • src/elements/content-sharing/hooks/__tests__/useContactService.test.ts (1 hunks)
  • src/elements/content-sharing/hooks/useContactService.ts (2 hunks)
  • src/elements/content-sharing/hooks/useContactsByEmail.js (2 hunks)
  • src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts (2 hunks)
  • src/elements/content-sharing/utils/convertContactServiceData.ts (1 hunks)
  • src/elements/content-sharing/utils/index.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-02T16:47:50.715Z
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.715Z
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/__tests__/convertContactServiceData.test.ts
🧬 Code graph analysis (6)
src/elements/content-sharing/utils/convertContactServiceData.ts (1)
src/elements/content-sharing/utils/index.ts (1)
  • convertUserContactByEmailResponse (5-5)
src/elements/content-sharing/hooks/useContactsByEmail.js (1)
src/elements/content-sharing/hooks/useContacts.js (2)
  • noop (20-27)
  • resolveAPICall (34-45)
src/elements/content-sharing/hooks/__tests__/useContactService.test.ts (2)
src/elements/content-sharing/utils/convertContactServiceData.ts (3)
  • convertGroupContactsResponse (38-57)
  • convertUserContactsResponse (9-33)
  • convertUserContactByEmailResponse (63-78)
src/elements/content-sharing/hooks/useContactService.ts (1)
  • useContactService (5-19)
src/elements/content-sharing/__tests__/useContactsByEmail.test.js (2)
src/features/unified-share-modal/utils/__mocks__/USMMocks.js (3)
  • MOCK_CONTACTS_BY_EMAIL_CONVERTED_RESPONSE (598-635)
  • MOCK_CONTACTS_API_RESPONSE (415-535)
  • MOCK_ITEM_ID (53-53)
src/features/unified-share-modal/utils/convertData.js (2)
  • email (530-530)
  • email (553-553)
src/elements/content-sharing/hooks/useContactService.ts (2)
src/elements/content-sharing/utils/convertContactServiceData.ts (1)
  • convertUserContactByEmailResponse (63-78)
src/elements/content-sharing/utils/index.ts (1)
  • convertUserContactByEmailResponse (5-5)
src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts (2)
src/elements/content-sharing/utils/convertContactServiceData.ts (1)
  • convertUserContactByEmailResponse (63-78)
src/elements/content-sharing/utils/index.ts (1)
  • convertUserContactByEmailResponse (5-5)
🪛 Biome (2.1.2)
src/elements/content-sharing/hooks/useContactsByEmail.js

[error] 41-41: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 42-42: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 48-48: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 51-51: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)

⏰ 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 (6)
src/elements/content-sharing/utils/index.ts (1)

3-7: Re-export looks correct

Public surface expansion to include convertUserContactByEmailResponse aligns with usages.

src/elements/content-sharing/hooks/useContactService.ts (1)

13-18: Verification confirms change is safe and additive

Search results show:

  • contactService properties are not accessed in ContentSharingV2.tsx (the sole call site), so no strict type patterns depend on an exact method set.
  • No type assertions or exhaustive object checks detected.
  • The expanded contactService object with getContactByEmail and getContacts is purely additive and safe.

The original review assessment stands: the wiring is correct and poses no risk to existing call sites.

src/elements/content-sharing/__tests__/useContactsByEmail.test.js (1)

3-3: LGTM! Clean migration to React Testing Library.

The migration from Enzyme to React Testing Library using renderHook and act is well executed. The test patterns correctly handle async operations and properly verify hook behavior.

Also applies to: 38-60, 62-84

src/elements/content-sharing/hooks/__tests__/useContactService.test.ts (3)

38-55: LGTM! Comprehensive test coverage for contactService integration.

The test correctly verifies that both getContactByEmail and getContacts are exposed through the contact service, and validates that the underlying hooks are called with appropriate parameters including the V2 flag and transform functions.


57-87: LGTM! Thorough validation of transform function wiring.

The test comprehensively validates that transform functions passed to both useContacts and useContactsByEmail correctly invoke their respective conversion utilities (convertUserContactsResponse, convertGroupContactsResponse, and convertUserContactByEmailResponse) with appropriate parameters.


3-7: LGTM! Clean integration of getContactByEmail support.

The additions properly extend the test suite to cover the new getContactByEmail functionality, including appropriate mocks for useContactsByEmail and convertUserContactByEmailResponse. The variable renaming (mockItemId, mockCurrentUserId) improves consistency with TypeScript naming conventions.

Also applies to: 20-21, 28-28, 31-31

Copy link
Contributor

@tjuanitas tjuanitas left a comment

Choose a reason for hiding this comment

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

you might have to walk me through this PR. feel a little lost

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

Caution

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

⚠️ Outside diff range comments (2)
src/elements/content-sharing/__tests__/useContactsByEmail.test.js (1)

51-56: Fix Jest matcher usage.

Use expect.any(Function) instead of expect.anything(Function). The latter is invalid and will fail.

- expect.anything(Function),
+ expect.any(Function),

Apply to all occurrences in this test file (shown line ranges).

Also applies to: 75-80, 166-171, 234-239

src/elements/content-sharing/hooks/useContactsByEmail.js (1)

22-28: Return type/state type mismatch when V2 is enabled.

Hook returns GetContactsByEmailFnType | null, but in V2 you assign a GetContactByEmailFnType. Make the return/state a union to keep Flow happy.

-): GetContactsByEmailFnType | null {
-    const [getContactsByEmail, setGetContactsByEmail] = React.useState<null | GetContactsByEmailFnType>(null);
+): GetContactsByEmailFnType | GetContactByEmailFnType | null {
+    const [getContactsByEmail, setGetContactsByEmail] =
+        React.useState<null | GetContactsByEmailFnType | GetContactByEmailFnType>(null);
♻️ Duplicate comments (3)
src/elements/content-sharing/__tests__/useContactsByEmail.test.js (1)

177-201: V2 “email not provided” test calls with an object; align with V2 API and intent.

The test name states “email is not provided” but it invokes result.current({ emails: [MOCK_EMAIL] }), which is not a missing email and also mismatches the V2 string signature.

Use an empty string (or undefined) and assert no API call/transform, e.g.:

-            let contacts;
-            await act(async () => {
-                contacts = await result.current({ emails: [MOCK_EMAIL] });
-            });
-
-            expect(handleSuccess).toHaveBeenCalledWith(EMPTY_USERS);
-            expect(mockTransformUsers).not.toHaveBeenCalled();
-            expect(contacts).toEqual({});
+            let contacts;
+            await act(async () => {
+                contacts = await result.current('');
+            });
+
+            expect(getUsersInEnterprise).not.toHaveBeenCalled();
+            expect(handleSuccess).not.toHaveBeenCalled();
+            expect(mockTransformUsers).not.toHaveBeenCalled();
+            expect(contacts).toEqual({});
src/elements/content-sharing/hooks/useContactsByEmail.js (2)

46-63: Normalize V2 to accept both a string email and the V1 object shape.

Avoid breaking callers when toggling the flag. Parse a string or { emails: string[] } uniformly.

-        if (isContentSharingV2Enabled) {
-            const getContactsByEmailV2: GetContactByEmailFnType = () => email => {
-                if (!email) {
-                    return Promise.resolve({});
-                }
-
-                return new Promise(resolve => {
-                    api.getMarkerBasedUsersAPI(false).getUsersInEnterprise(
-                        itemID,
-                        response => resolveAPICall(resolve, response, transformUsers),
-                        handleError,
-                        { filter_term: email },
-                    );
-                });
-            };
+        if (isContentSharingV2Enabled) {
+            const getContactsByEmailV2 = () => (input) => {
+                const email =
+                    typeof input === 'string'
+                        ? input
+                        : (input && Array.isArray(input.emails) && input.emails[0]) || '';
+                if (!email) return Promise.resolve({});
+
+                return new Promise(resolve => {
+                    api.getMarkerBasedUsersAPI(false).getUsersInEnterprise(
+                        itemID,
+                        response => resolveAPICall(resolve, response, transformUsers),
+                        handleError,
+                        { filter_term: email },
+                    );
+                });
+            };

64-79: Fix V1 inline param type to match actual usage.

{ [emails: string]: string } is not the intended shape; you index into filterTerm.emails as an array.

-            const updatedGetContactsByEmailFn: GetContactsByEmailFnType =
-                () => (filterTerm: { [emails: string]: string }) => {
+            const updatedGetContactsByEmailFn: GetContactsByEmailFnType =
+                () => (filterTerm: { emails: Array<string> }) => {
                     if (!filterTerm || !Array.isArray(filterTerm.emails) || !filterTerm.emails.length) {
                         return Promise.resolve({});
                     }
                     const parsedFilterTerm = filterTerm.emails[0];
🧹 Nitpick comments (2)
src/elements/content-sharing/__tests__/useContactsByEmail.test.js (1)

218-233: Remove timer-based flakiness; await error with Testing Library helpers.

Replace the manual timeout with waitFor for deterministic async assertions.

-import { renderHook, act } from '@testing-library/react';
+import { renderHook, act, waitFor } from '@testing-library/react';
@@
-    // Wait a short time to ensure handleError is called
-    await act(async () => {
-        await new Promise(resolve => setTimeout(resolve, 100));
-    });
+    await waitFor(() => expect(handleError).toHaveBeenCalled());
src/elements/content-sharing/hooks/useContactsByEmail.js (1)

30-33: Consider useMemo to avoid stale function when the flag changes.

The early return prevents updating the function if isContentSharingV2Enabled flips after mount. Prefer deriving the function with useMemo keyed by the flag and deps to avoid setState loops.

I can provide a useMemo variant if you want to adopt it now.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f8aa55 and c5532e3.

📒 Files selected for processing (4)
  • src/elements/content-sharing/__tests__/useContactsByEmail.test.js (6 hunks)
  • src/elements/content-sharing/hooks/useContactsByEmail.js (3 hunks)
  • src/elements/content-sharing/types.js (1 hunks)
  • src/elements/content-sharing/utils/convertContactServiceData.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/elements/content-sharing/utils/convertContactServiceData.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-02T16:47:50.715Z
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.715Z
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/__tests__/useContactsByEmail.test.js
🧬 Code graph analysis (3)
src/elements/content-sharing/__tests__/useContactsByEmail.test.js (3)
src/features/unified-share-modal/utils/__mocks__/USMMocks.js (3)
  • MOCK_CONTACTS_BY_EMAIL_CONVERTED_RESPONSE (598-635)
  • MOCK_CONTACTS_API_RESPONSE (415-535)
  • MOCK_ITEM_ID (53-53)
src/elements/content-sharing/__tests__/SharingModal.test.js (1)
  • createAPIMock (76-89)
src/features/unified-share-modal/utils/convertData.js (2)
  • email (530-530)
  • email (553-553)
src/elements/content-sharing/types.js (1)
src/features/unified-share-modal/utils/convertData.js (2)
  • email (530-530)
  • email (553-553)
src/elements/content-sharing/hooks/useContactsByEmail.js (1)
src/elements/content-sharing/hooks/useContacts.js (2)
  • noop (20-27)
  • resolveAPICall (34-45)
🪛 Biome (2.1.2)
src/elements/content-sharing/types.js

[error] 143-143: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)

src/elements/content-sharing/hooks/useContactsByEmail.js

[error] 7-12: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 47-47: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 64-64: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 65-65: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 71-71: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 74-74: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)

⏰ 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

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

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/utils/convertContactServiceData.ts (1)

38-56: Remove or correct the misleading inline comment referencing non-existent isUserContactType.

The code is functionally correct—the email field intentionally uses the display string (e.g., 'Group') for groups rather than an email address, as evidenced by tests and usage in useContactService.ts. However, the inline comment at line 50 references isUserContactType, which does not exist anywhere in the codebase. This misleading comment should be removed or rewritten to accurately explain that the display string is used because groups don't have email addresses.

Additionally, the parameter name formatMessage is confusing since it receives a pre-formatted string (e.g., formatMessage(messages.contactServiceGroupDisplayText)), not a function. Consider renaming it to groupDisplayText for clarity.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5532e3 and e3de11c.

⛔ Files ignored due to path filters (1)
  • i18n/en-US.properties is excluded by !i18n/**
📒 Files selected for processing (5)
  • src/elements/content-sharing/hooks/__tests__/useContactService.test.ts (1 hunks)
  • src/elements/content-sharing/hooks/useContactService.ts (1 hunks)
  • src/elements/content-sharing/messages.js (1 hunks)
  • src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts (5 hunks)
  • src/elements/content-sharing/utils/convertContactServiceData.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/elements/content-sharing/hooks/useContactService.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-02T16:47:50.715Z
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.715Z
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/__tests__/convertContactServiceData.test.ts
🧬 Code graph analysis (3)
src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts (1)
src/elements/content-sharing/utils/convertContactServiceData.ts (2)
  • convertGroupContactsResponse (38-57)
  • convertUserContactByEmailResponse (62-77)
src/elements/content-sharing/utils/convertContactServiceData.ts (1)
src/elements/content-sharing/utils/index.ts (2)
  • convertGroupContactsResponse (4-4)
  • convertUserContactByEmailResponse (5-5)
src/elements/content-sharing/hooks/__tests__/useContactService.test.ts (2)
src/elements/content-sharing/utils/convertContactServiceData.ts (3)
  • convertGroupContactsResponse (38-57)
  • convertUserContactsResponse (9-33)
  • convertUserContactByEmailResponse (62-77)
src/elements/content-sharing/hooks/useContactService.ts (1)
  • useContactService (9-26)
⏰ 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 (8)
src/elements/content-sharing/messages.js (1)

62-66: LGTM! Clean i18n message addition.

The new contactServiceGroupDisplayText message follows the existing pattern and provides proper localization support for group contacts.

src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts (3)

2-6: LGTM! Import correctly updated.

The import statement properly includes the new convertUserContactByEmailResponse function.


210-210: LGTM! Tests correctly updated for signature change.

The tests properly reflect the updated convertGroupContactsResponse signature, passing the formatMessage parameter and expecting the value field to be the group ID instead of the literal 'Group' string.

Also applies to: 236-236, 244-244, 251-251, 291-291, 328-328


337-366: LGTM! Comprehensive basic test coverage.

The tests for convertUserContactByEmailResponse properly cover the empty entries case and valid conversion scenario.

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

59-77: LGTM! Docstring correctly updated and implementation is sound.

The function properly:

  • Extracts the first entry from the API response
  • Returns an empty object when no entries are present
  • Handles missing/undefined login with a default empty string
  • Returns a single contact object with the correct structure

The docstring accurately reflects the implementation, addressing the previous review feedback.

src/elements/content-sharing/hooks/__tests__/useContactService.test.ts (3)

1-32: LGTM! Test setup properly updated.

The imports, mocks, and variable naming improvements (ID → Id) are all correct and follow best practices.


38-55: LGTM! Comprehensive test coverage for both retrieval methods.

The test properly verifies that both useContacts and useContactsByEmail are called with correct parameters and that the returned contactService object exposes both functions.


57-87: LGTM! Transform functions thoroughly tested.

The test properly verifies that all three transform functions (users, groups, and contact-by-email) are called with the correct data and parameters:

  • convertUserContactsResponse with user data and current user ID
  • convertGroupContactsResponse with group data and 'Group' display text
  • convertUserContactByEmailResponse with email-based contact data

@reneshen0328 reneshen0328 force-pushed the create-contact-service-getContactByEmail branch from 407e091 to 000a4f0 Compare October 17, 2025 17:36
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

♻️ Duplicate comments (1)
src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts (1)

368-410: Remove duplicate test case.

Lines 368-388 and 390-410 are duplicate tests. Both test the exact same scenario: an entry object without a login field. In JavaScript, a missing property and an undefined property are identical—both resolve to undefined. These tests use the same input data and assert the same output.

Apply this diff to remove the duplicate:

-            test('should handle user contact with undefined login field', () => {
-                const contactsApiData = {
-                    entries: [
-                        {
-                            id: 'user-1',
-                            name: 'Jane Smith',
-                            type: 'user',
-                        },
-                    ],
-                };
-
-                const result = convertUserContactByEmailResponse(contactsApiData);
-
-                expect(result).toEqual({
-                    id: 'user-1',
-                    email: '',
-                    name: 'Jane Smith',
-                    type: 'user',
-                    value: '',
-                });
-            });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 407e091 and 000a4f0.

📒 Files selected for processing (2)
  • src/elements/content-sharing/__tests__/useContactsByEmail.test.js (6 hunks)
  • src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts (5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-02T16:47:50.715Z
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.715Z
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/__tests__/useContactsByEmail.test.js
  • src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts
🧬 Code graph analysis (2)
src/elements/content-sharing/__tests__/useContactsByEmail.test.js (3)
src/features/unified-share-modal/utils/__mocks__/USMMocks.js (3)
  • MOCK_CONTACTS_BY_EMAIL_CONVERTED_RESPONSE (598-635)
  • MOCK_CONTACTS_API_RESPONSE (415-535)
  • MOCK_ITEM_ID (53-53)
src/elements/content-sharing/__tests__/SharingModal.test.js (1)
  • createAPIMock (76-89)
src/features/unified-share-modal/utils/convertData.js (2)
  • email (530-530)
  • email (553-553)
src/elements/content-sharing/utils/__tests__/convertContactServiceData.test.ts (2)
src/elements/content-sharing/utils/index.ts (2)
  • convertGroupContactsResponse (4-4)
  • convertUserContactByEmailResponse (5-5)
src/elements/content-sharing/utils/convertContactServiceData.ts (2)
  • convertGroupContactsResponse (38-57)
  • convertUserContactByEmailResponse (62-77)
⏰ 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 (3)
src/elements/content-sharing/__tests__/useContactsByEmail.test.js (1)

135-175: LGTM! V2 path test correctly extracts and uses email field.

The test correctly destructures login as email (line 137) and passes a plain string email to the V2 API (line 163), matching the expected signature.

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

206-254: LGTM! Group conversion tests correctly updated for new signature.

The tests properly pass the formatMessage parameter and validate that value now contains the group ID rather than a static string.


337-366: LGTM! Basic conversion tests for convertUserContactByEmailResponse.

Tests correctly validate empty input returns an empty object and valid input is properly transformed with login mapped to email and value.

tjuanitas
tjuanitas previously approved these changes Oct 17, 2025
Copy link
Contributor

@tjuanitas tjuanitas left a comment

Choose a reason for hiding this comment

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

nits

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

♻️ Duplicate comments (2)
src/elements/content-sharing/hooks/useContactsByEmail.js (2)

48-64: V2 function signature breaks existing consumers.

The V2 implementation expects a plain string email, but consumers (e.g., UnifiedShareForm.js:278) call with { emails: [email] } (the V1 signature). Toggling isContentSharingV2Enabled at runtime will cause type errors and unexpected behavior.

Per past review comments, unify the signatures. Apply this refactor to make V2 accept the V1 input shape:

-        if (isContentSharingV2Enabled) {
-            const getContactsByEmailV2: GetContactByEmailFnType = () => email => {
-                if (!email) {
+        if (isContentSharingV2Enabled) {
+            const getContactsByEmailV2: GetContactsByEmailFnType = () => filterTerm => {
+                // Support both V1 object shape and plain string for compatibility
+                const email = typeof filterTerm === 'string' 
+                    ? filterTerm 
+                    : (filterTerm && Array.isArray(filterTerm.emails) && filterTerm.emails[0]) || '';
+                
+                if (!email) {
                     return Promise.resolve({});
                 }
 
                 return new Promise(resolve => {
                     api.getMarkerBasedUsersAPI(false).getUsersInEnterprise(
                         itemID,
                         response => resolveAPICall(resolve, response, transformUsers),
                         handleError,
                         { filter_term: email },
                     );
                 });
             };
 
             setGetContactsByEmail(getContactsByEmailV2);

65-84: Fix incorrect type signature for filterTerm.

Line 67 uses { [emails: string]: string }, which is invalid index signature syntax. The code clearly expects { emails: Array<string> } based on the runtime checks at lines 68-70.

Apply this fix:

-            const updatedGetContactsByEmailFn: GetContactsByEmailFnType =
-                () => (filterTerm: { [emails: string]: string }) => {
+            const updatedGetContactsByEmailFn: GetContactsByEmailFnType =
+                () => (filterTerm: { emails: Array<string> }) => {
                     if (!filterTerm || !Array.isArray(filterTerm.emails) || !filterTerm.emails.length) {
                         return Promise.resolve({});
                     }

Additionally, update the type definition in src/elements/content-sharing/types.js to match.

🧹 Nitpick comments (1)
src/elements/content-sharing/hooks/useContactsByEmail.js (1)

7-12: Polymorphic return type may complicate consumer code.

The return type GetContactsByEmailFnType | GetContactByEmailFnType | null means consumers must determine which function signature they're receiving at runtime. This can lead to type narrowing issues and fragile consumer code.

Consider one of these alternatives:

  1. Return a single function type with a unified signature (preferred)
  2. Return an object with explicitly named methods: { getByEmail, getByEmails }

Also applies to: 20-20, 26-29

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 000a4f0 and f172e4c.

⛔ Files ignored due to path filters (1)
  • i18n/en-US.properties is excluded by !i18n/**
📒 Files selected for processing (4)
  • src/elements/content-sharing/hooks/useContactService.ts (1 hunks)
  • src/elements/content-sharing/hooks/useContactsByEmail.js (2 hunks)
  • src/elements/content-sharing/messages.js (1 hunks)
  • src/elements/content-sharing/utils/convertContactServiceData.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/elements/content-sharing/messages.js
  • src/elements/content-sharing/utils/convertContactServiceData.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/elements/content-sharing/hooks/useContactService.ts (2)
src/elements/content-sharing/utils/convertContactServiceData.ts (3)
  • convertUserContactsResponse (9-33)
  • convertGroupContactsResponse (38-57)
  • convertUserContactByEmailResponse (62-77)
src/elements/content-sharing/messages.js (1)
  • messages (3-67)
src/elements/content-sharing/hooks/useContactsByEmail.js (2)
src/elements/content-sharing/SharingModal.js (1)
  • getContactsByEmail (94-94)
src/elements/content-sharing/hooks/useContacts.js (2)
  • noop (20-27)
  • resolveAPICall (34-45)
🪛 Biome (2.1.2)
src/elements/content-sharing/hooks/useContactsByEmail.js

[error] 7-12: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 23-23: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 24-24: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 25-25: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 26-26: return types can only be used in TypeScript files

(parse)


[error] 29-29: Expected an identifier, an array pattern, or an object pattern but instead found '>'.

Expected an identifier, an array pattern, or an object pattern here.

(parse)


[error] 49-49: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 66-66: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 67-67: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 73-73: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 76-76: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)

⏰ 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 (6)
src/elements/content-sharing/hooks/useContactService.ts (4)

1-4: LGTM! Clean import additions.

The new imports for localization (useIntl) and email-based contact retrieval (useContactsByEmail, convertUserContactByEmailResponse) are all properly used in the file.


10-16: Excellent localization improvement.

The use of useIntl and formatMessage follows react-intl v5 best practices and properly internationalizes the group contact label.


24-24: LGTM! API surface expanded correctly.

Exposing both getContactByEmail and getContacts aligns with the PR objectives and provides a clear, consistent API for consumers.


19-22: ****

The hardcoding of isContentSharingV2Enabled: true is intentional and correct. useContactService is a V2-specific service wrapper that enforces V2 behavior. The underlying hooks (useContacts and useContactsByEmail) accept this flag as a configurable parameter, but useContactService is designed to wrap them and always use V2. This is evidenced by:

  • The hook is imported and used only in ContentSharingV2.tsx, indicating V2-specific context
  • The function signature accepts only (api, itemId, currentUserId) with no feature flag parameter
  • The design properly separates concerns: low-level hooks are flexible; high-level service enforces specific behavior

If V1 behavior were needed, a separate hook or different wrapper would be created. No changes required.

Likely an incorrect or invalid review comment.

src/elements/content-sharing/hooks/useContactsByEmail.js (2)

85-85: LGTM! Dependency array correctly updated.

Including isContentSharingV2Enabled in the dependencies ensures the effect re-runs when the feature flag changes, properly switching between V1 and V2 implementations.


1-90: Note: Biome lint errors are false positives.

The static analysis hints flagging "TypeScript only syntax" are incorrect. This file uses Flow type annotations (note // @flow at line 1), which Biome is misidentifying as TypeScript. These errors can be safely ignored, or configure Biome to recognize Flow syntax.

@reneshen0328 reneshen0328 force-pushed the create-contact-service-getContactByEmail branch from f172e4c to 4d26ec8 Compare October 17, 2025 18:56
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 (2)
src/elements/content-sharing/utils/convertContactServiceData.ts (1)

59-61: Docstring still missing empty-state detail (follow‑up to prior comment)

Add that the function returns {} when no entries are present to match implementation.

Apply:

- * Convert an enterprise users API response into a single internal USM contact object (from the first entry).
+ * Convert an enterprise users API response into a single internal USM contact object (from the first entry).
+ * Returns {} when no entries are present.
src/elements/content-sharing/hooks/useContactsByEmail.js (1)

66-83: Fix Flow type for filterTerm; indexer is incorrect

The inline type { [emails: string]: string } contradicts usage. Use { emails: Array<string> }.

-            const updatedGetContactsByEmailFn: GetContactsByEmailFnType =
-                () => (filterTerm: { [emails: string]: string }) => {
+            const updatedGetContactsByEmailFn: GetContactsByEmailFnType =
+                () => (filterTerm: { emails: Array<string> }) => {
                     if (!filterTerm || !Array.isArray(filterTerm.emails) || !filterTerm.emails.length) {
                         return Promise.resolve({});
                     }
                     const parsedFilterTerm = filterTerm.emails[0];

Additionally, if Biome parses this file, ensure it’s configured for Flow or move type annotations off inline params into variable declarations to avoid parse errors.

🧹 Nitpick comments (4)
src/elements/content-sharing/utils/convertContactServiceData.ts (2)

38-56: Group “email” field holds a label; confirm no downstream relies on a valid email

You’re placing a localized label in the email field to satisfy avatar rendering. Verify no consumers validate/sanitize this as an actual email (dedupe keys, mailto links, etc.). If any do, consider a dedicated displayLabel while keeping email undefined for groups.


62-77: Add explicit TS types to stabilize API surface

Return type is currently implicit and unions {} with a contact shape. Define and use a Contact type (or existing USM type) and annotate the function to return Contact | {} for clarity, or prefer Contact | null to avoid ambiguous empty-object checks.

+type USMContact = {
+  id: string,
+  email: string,
+  name: string,
+  type: string,
+  value: string,
+};
-export const convertUserContactByEmailResponse = contactsApiData => {
+export const convertUserContactByEmailResponse = (contactsApiData: { entries?: Array<any> }): USMContact | {} => {
src/elements/content-sharing/hooks/useContactsByEmail.js (2)

20-30: Return type union is fine; consider simplifying by returning a single normalized adapter

To reduce branching at call sites, you can always return a V1-shaped function and adapt inputs internally (see V2 comment below).


1-12: Linter/parser config note

Imports and annotations are Flow; if your pipeline runs Biome without Flow support, you’ll get parse errors. Either enable Flow parsing or let ESLint/Flow handle these files.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f172e4c and 4d26ec8.

⛔ Files ignored due to path filters (1)
  • i18n/en-US.properties is excluded by !i18n/**
📒 Files selected for processing (5)
  • src/elements/content-sharing/SharingModal.js (3 hunks)
  • src/elements/content-sharing/hooks/useContactService.ts (1 hunks)
  • src/elements/content-sharing/hooks/useContactsByEmail.js (2 hunks)
  • src/elements/content-sharing/messages.js (1 hunks)
  • src/elements/content-sharing/utils/convertContactServiceData.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/elements/content-sharing/messages.js
🧰 Additional context used
🧬 Code graph analysis (4)
src/elements/content-sharing/hooks/useContactsByEmail.js (2)
src/elements/content-sharing/SharingModal.js (1)
  • getContactsByEmail (91-93)
src/elements/content-sharing/hooks/useContacts.js (2)
  • noop (20-27)
  • resolveAPICall (34-45)
src/elements/content-sharing/utils/convertContactServiceData.ts (1)
src/elements/content-sharing/utils/index.ts (2)
  • convertGroupContactsResponse (4-4)
  • convertUserContactByEmailResponse (5-5)
src/elements/content-sharing/hooks/useContactService.ts (2)
src/elements/content-sharing/utils/convertContactServiceData.ts (3)
  • convertUserContactsResponse (9-33)
  • convertGroupContactsResponse (38-57)
  • convertUserContactByEmailResponse (62-77)
src/elements/content-sharing/messages.js (1)
  • messages (3-67)
src/elements/content-sharing/SharingModal.js (3)
src/elements/content-sharing/hooks/useSharedLink.js (3)
  • changeSharedLinkAccessLevel (35-38)
  • changeSharedLinkPermissionLevel (39-42)
  • onSubmitSettings (43-43)
src/elements/content-sharing/hooks/useContacts.js (1)
  • getContacts (19-19)
src/elements/content-sharing/hooks/useContactsByEmail.js (1)
  • getContactsByEmail (27-29)
🪛 Biome (2.1.2)
src/elements/content-sharing/hooks/useContactsByEmail.js

[error] 7-12: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 23-23: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 24-24: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 25-25: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 26-26: return types can only be used in TypeScript files

(parse)


[error] 29-29: Expected an identifier, an array pattern, or an object pattern but instead found '>'.

Expected an identifier, an array pattern, or an object pattern here.

(parse)


[error] 49-49: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 66-66: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 67-67: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 73-73: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 76-76: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)

src/elements/content-sharing/SharingModal.js

[error] 93-93: Expected an identifier, an array pattern, or an object pattern but instead found '>'.

Expected an identifier, an array pattern, or an object pattern here.

(parse)


[error] 193-193: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 201-201: return type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)

⏰ 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 (6)
src/elements/content-sharing/SharingModal.js (2)

84-87: No functional change; state initializers look fine

Refactor is formatting-only and OK.


91-93: Union typing for getContactsByEmail is fine; ensure downstream prop typing matches

UnifiedShareModal must accept a function of either signature. Please confirm its prop types and call sites handle both shapes.

src/elements/content-sharing/hooks/useContactService.ts (2)

10-17: Localized group label wiring looks good

Passing a localized label to the group converter is correct and keeps UI consistent.


19-25: Confirm mixed return shapes are handled by consumers

getContactByEmail returns a single contact object (or {}), while getContacts returns arrays. Ensure all call sites (USM/contact service adapters) branch correctly on the path and don’t assume an array.

src/elements/content-sharing/hooks/useContactsByEmail.js (2)

35-46: Empty-state normalization for V1 vs V2

resolveAPICall returns {} when no entries; legacy V1 callers may expect an array. Confirm all consumers of V1 path handle {} (or switch V1 to return [] for empty to preserve the original contract).


85-88: LGTM on effect guard

Early-return when function exists prevents redefinition; dependencies look correct.

@mergify mergify bot added the queued label Oct 17, 2025
@mergify mergify bot merged commit 05b50cd into master Oct 17, 2025
11 checks passed
@mergify mergify bot deleted the create-contact-service-getContactByEmail branch October 17, 2025 20:30
@mergify mergify bot removed the queued label Oct 17, 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