Skip to content

feat(Content-sharing): Add event callbacks to Content Sharing#4477

Open
reneshen0328 wants to merge 1 commit intomasterfrom
add-content-sharing-callbacks
Open

feat(Content-sharing): Add event callbacks to Content Sharing#4477
reneshen0328 wants to merge 1 commit intomasterfrom
add-content-sharing-callbacks

Conversation

@reneshen0328
Copy link
Contributor

@reneshen0328 reneshen0328 commented Mar 11, 2026

What

  • Error case: Item fetch fails → white screen with notification → consumer needs to know to ex. close webview/ render notification
  • Success case: User completes action (e.g., "Invite People") → USM closes → consumer needs to know to ex. close webview/ render notification
  • Loading case: When Item is fetching -> white screen with no loading indicator (currently) -> consumer needs to know it's loading to ex. add loading indicator

Summary by CodeRabbit

Release Notes

  • New Features
    • Content sharing modal now supports event callbacks for enhanced control flow: onClose triggers when the modal closes, onLoad executes when item data is successfully retrieved, and onError activates when item data fails to load. These additions enable better integration with external systems and improved error handling.

@reneshen0328 reneshen0328 requested review from a team as code owners March 11, 2026 22:07
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 11, 2026

Walkthrough

The PR adds three new optional callbacks to ContentSharingV2: onLoad (invoked after successful item fetch), onError (invoked on fetch failure), and onClose (invoked when modal closes). These callbacks are wired through component props and lifecycle events, plus corresponding test coverage is added.

Changes

Cohort / File(s) Summary
ContentSharingV2 Component
src/elements/content-sharing/ContentSharingV2.tsx
Added three new public callback props (onClose, onError, onLoad), threaded them through component lifecycle events around item fetching and modal state changes. Updated error notification payload with styledText field, adjusted dependency arrays, and added handleOpenChange to connect UnifiedShareModal's onOpenChange to the onClose callback.
ContentSharingV2 Tests
src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx
Added new "callback props" test suite with onLoad and onError mocks and error simulation to verify callbacks fire correctly on successful item load and error scenarios.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested labels

ready-to-merge

Suggested reviewers

  • jfox-box
  • tjuanitas
  • jpan-box

Poem

🐰 Hark! A modal now whispers its secrets,
With callbacks that dance through the event landscape,
onLoad, onError, onClose—three messengers hop,
Through ContentSharingV2's halls they prance with delight,
Bringing lifecycle clarity to the sharing song! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding event callbacks to the Content Sharing component, which is the primary focus of the PR.
Description check ✅ Passed The description provides clear context for the three callback scenarios (error, success, loading) and explains why consumers need these callbacks, though it lacks structured sections.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-content-sharing-callbacks

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

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

257-290: Consider adding test coverage for onClose callback.

The new onClose prop is added to ContentSharingV2 but has no corresponding test coverage in this suite. Consider adding a test that simulates modal close and verifies onClose is invoked.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx` around
lines 257 - 290, Add a test for the new onClose prop on ContentSharingV2 by
rendering the component with a jest.fn() passed as onClose via renderComponent({
onClose }), then simulate the user closing the modal (e.g., click the modal
close button or backdrop using the same query used elsewhere in the suite) and
await a waitFor(() => expect(onClose).toHaveBeenCalled()) to assert it was
invoked; ensure the test isolates onClose (use fresh jest.fn()) and does not
rely on other callbacks.
src/elements/content-sharing/ContentSharingV2.tsx (2)

193-193: Remove onError from dependency array—it's unused in this effect.

The useEffect for fetching the current user (lines 170-193) does not invoke onError anywhere in its body, yet onError is included in the dependency array. This causes unnecessary effect re-runs when the onError prop reference changes.

Proposed fix
-    }, [api, currentUser, item, itemId, itemType, sharedLink, getError, onError]);
+    }, [api, currentUser, item, itemId, itemType, sharedLink, getError]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/elements/content-sharing/ContentSharingV2.tsx` at line 193, The useEffect
in ContentSharingV2.tsx that fetches the current user includes onError in its
dependency array but never uses it; remove onError from the dependency array of
that useEffect so the dependencies are [api, currentUser, item, itemId,
itemType, sharedLink, getError] (leave the effect body and getError usage
unchanged) to prevent unnecessary re-renders when the onError prop reference
changes.

161-167: LGTM on callback invocations, but verify necessity of onError in dependency array.

The onLoad?.() and onError?.(error) calls are correctly placed. However, the dependency array at line 167 includes both onError and onLoad, which is correct since they are used in the effect body.

Note: Line 193 also includes onError in its dependency array, but onError is not called within that effect. Consider removing onError from line 193's dependencies to avoid unnecessary effect re-runs when the callback reference changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/elements/content-sharing/ContentSharingV2.tsx` around lines 161 - 167,
The effect at ContentSharingV2.tsx that includes onError in its dependency array
but does not call onError should have onError removed from that effect's
dependency list; locate the useEffect (the second effect around the later block
referenced in the review) and remove onError from its dependencies (verify that
onError is not referenced in that effect's body such as in any callbacks or
nested functions), then run the linter/tests to ensure no missing dependency
warnings and confirm behavior is unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx`:
- Around line 281-289: The test "should call onError and not onLoad when item
data fails to load" calls renderComponent with { api: errorApi, onError } but
never provides onLoad, so the negative assertion on onLoad is invalid; update
the test to pass both callbacks (provide the mocked onLoad alongside onError)
when calling renderComponent (the symbol to change is the renderComponent
invocation in this test) so the component's error path is verified to call
onError(error) and not invoke onLoad.
- Around line 271-279: The test "should call onLoad and not onError when item
data loads successfully" currently asserts onError wasn't called but never
passes onError into renderComponent; update the test to pass both mocks into
renderComponent (e.g., call renderComponent({ onLoad, onError })) so the
component receives the onError prop, then keep the existing assertions; locate
the test function and the renderComponent helper and ensure both onLoad and
onError mocks are provided when rendering.

---

Nitpick comments:
In `@src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx`:
- Around line 257-290: Add a test for the new onClose prop on ContentSharingV2
by rendering the component with a jest.fn() passed as onClose via
renderComponent({ onClose }), then simulate the user closing the modal (e.g.,
click the modal close button or backdrop using the same query used elsewhere in
the suite) and await a waitFor(() => expect(onClose).toHaveBeenCalled()) to
assert it was invoked; ensure the test isolates onClose (use fresh jest.fn())
and does not rely on other callbacks.

In `@src/elements/content-sharing/ContentSharingV2.tsx`:
- Line 193: The useEffect in ContentSharingV2.tsx that fetches the current user
includes onError in its dependency array but never uses it; remove onError from
the dependency array of that useEffect so the dependencies are [api,
currentUser, item, itemId, itemType, sharedLink, getError] (leave the effect
body and getError usage unchanged) to prevent unnecessary re-renders when the
onError prop reference changes.
- Around line 161-167: The effect at ContentSharingV2.tsx that includes onError
in its dependency array but does not call onError should have onError removed
from that effect's dependency list; locate the useEffect (the second effect
around the later block referenced in the review) and remove onError from its
dependencies (verify that onError is not referenced in that effect's body such
as in any callbacks or nested functions), then run the linter/tests to ensure no
missing dependency warnings and confirm behavior is unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9537cb82-73aa-4836-ab3d-16a8a1e7778b

📥 Commits

Reviewing files that changed from the base of the PR and between 10c815c and 4cda830.

📒 Files selected for processing (2)
  • src/elements/content-sharing/ContentSharingV2.tsx
  • src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx

Comment on lines +271 to +279
test('should call onLoad and not onError when item data loads successfully', async () => {
renderComponent({ onLoad });

await waitFor(() => {
expect(onLoad).toHaveBeenCalled();
});

expect(onError).not.toHaveBeenCalled();
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Test assertion doesn't validate component behavior.

Line 278 asserts expect(onError).not.toHaveBeenCalled(), but onError was never passed to the component in this test. This assertion will always pass regardless of component behavior—it only confirms an unpassed mock wasn't called.

To properly test that the component doesn't call onError on success, pass both callbacks:

Proposed fix
         test('should call onLoad and not onError when item data loads successfully', async () => {
-            renderComponent({ onLoad });
+            renderComponent({ onLoad, onError });

             await waitFor(() => {
                 expect(onLoad).toHaveBeenCalled();
             });

             expect(onError).not.toHaveBeenCalled();
         });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('should call onLoad and not onError when item data loads successfully', async () => {
renderComponent({ onLoad });
await waitFor(() => {
expect(onLoad).toHaveBeenCalled();
});
expect(onError).not.toHaveBeenCalled();
});
test('should call onLoad and not onError when item data loads successfully', async () => {
renderComponent({ onLoad, onError });
await waitFor(() => {
expect(onLoad).toHaveBeenCalled();
});
expect(onError).not.toHaveBeenCalled();
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx` around
lines 271 - 279, The test "should call onLoad and not onError when item data
loads successfully" currently asserts onError wasn't called but never passes
onError into renderComponent; update the test to pass both mocks into
renderComponent (e.g., call renderComponent({ onLoad, onError })) so the
component receives the onError prop, then keep the existing assertions; locate
the test function and the renderComponent helper and ensure both onLoad and
onError mocks are provided when rendering.

Comment on lines +281 to +289
test('should call onError and not onLoad when item data fails to load', async () => {
renderComponent({ api: errorApi, onError });

await waitFor(() => {
expect(onError).toHaveBeenCalledWith(error);
});

expect(onLoad).not.toHaveBeenCalled();
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Same issue: pass both callbacks to validate mutual exclusivity.

Line 288 asserts expect(onLoad).not.toHaveBeenCalled(), but onLoad was never passed. Pass both callbacks to properly verify the component's error path doesn't invoke onLoad.

Proposed fix
         test('should call onError and not onLoad when item data fails to load', async () => {
-            renderComponent({ api: errorApi, onError });
+            renderComponent({ api: errorApi, onLoad, onError });

             await waitFor(() => {
                 expect(onError).toHaveBeenCalledWith(error);
             });

             expect(onLoad).not.toHaveBeenCalled();
         });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('should call onError and not onLoad when item data fails to load', async () => {
renderComponent({ api: errorApi, onError });
await waitFor(() => {
expect(onError).toHaveBeenCalledWith(error);
});
expect(onLoad).not.toHaveBeenCalled();
});
test('should call onError and not onLoad when item data fails to load', async () => {
renderComponent({ api: errorApi, onLoad, onError });
await waitFor(() => {
expect(onError).toHaveBeenCalledWith(error);
});
expect(onLoad).not.toHaveBeenCalled();
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/elements/content-sharing/__tests__/ContentSharingV2.test.tsx` around
lines 281 - 289, The test "should call onError and not onLoad when item data
fails to load" calls renderComponent with { api: errorApi, onError } but never
provides onLoad, so the negative assertion on onLoad is invalid; update the test
to pass both callbacks (provide the mocked onLoad alongside onError) when
calling renderComponent (the symbol to change is the renderComponent invocation
in this test) so the component's error path is verified to call onError(error)
and not invoke onLoad.

onClose?: () => void;
/** onError - Callback when item data fails to load, preventing USM from opening */
onError?: (error: Error) => void;
/** onLoad - Callback when item data loads successfully, use to hide loading indicator */
Copy link
Contributor

Choose a reason for hiding this comment

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

there is currently no loading indicator used in content sharing

});
});

describe('callback props', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

should we add a test for onClose?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants