Skip to content

feat(content-uploader): add drop support for modernized uploads manager#4674

Open
bkepka-box wants to merge 4 commits into
box:masterfrom
bkepka-box:drop-support
Open

feat(content-uploader): add drop support for modernized uploads manager#4674
bkepka-box wants to merge 4 commits into
box:masterfrom
bkepka-box:drop-support

Conversation

@bkepka-box

@bkepka-box bkepka-box commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Adds drag-and-drop support to the modernized Content Uploader uploads manager panel.

This wraps the modernized uploads manager in a droppable panel so files dropped onto it are queued instead of triggering browser navigation. It also ensures raw file uploads through the modernized uploads manager include the current rootFolderId in upload options, while preserving existing behavior outside that flow.

Summary by CodeRabbit

  • New Features

    • Added a modernized upload drop zone for dragging files into the uploads manager.
    • Introduced a new option to control whether dropping is enabled on the uploads manager panel.
  • Bug Fixes

    • Uploads now correctly include the destination folder when using the modernized uploads flow.
    • Improved drag-and-drop handling so dropped files are queued only when allowed.

@bkepka-box bkepka-box requested review from a team as code owners July 2, 2026 09:19
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7370b073-33e4-45c0-b4df-caa9862c3508

📥 Commits

Reviewing files that changed from the base of the PR and between f8fb79c and 7245efa.

📒 Files selected for processing (1)
  • src/elements/content-uploader/__tests__/ContentUploader.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/elements/content-uploader/tests/ContentUploader.test.js

Walkthrough

Adds a canDropOnUploadsManager prop to ContentUploader and renders a new ModernizedUploadsManagerDropZone component that validates drop types and forwards dropped items to the upload queue. Upload options conditionally include folderId for modernized uploads-manager configurations. Test coverage is expanded accordingly.

Changes

Modernized Uploads Manager Drop Zone Tests

Layer / File(s) Summary
Drop zone and folderId behavior tests
src/elements/content-uploader/__tests__/ContentUploader.test.js
Adds tests validating that rootFolderId is set on upload options only when modernized uploads manager is enabled, verifying drag/drop handling in ModernizedUploadsManagerDropZone (preventDefault, queueing when enabled, no queueing when disabled, prop hygiene), and updating render assertions to expect the new drop zone component.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • box/box-ui-elements#4276: The new drop zone is implemented via makeDroppable on a forwardRef div, depending on ref-based makeDroppable behavior introduced there.
  • box/box-ui-elements#4571: Both PRs modify ContentUploader.tsx's modernized uploads rendering path gated by enableModernizedUploads/useUploadsManager.
  • box/box-ui-elements#4573: Both PRs modify how folder uploads' per-item options (including folderId) are attached in the modernized uploads-manager path.

Suggested reviewers: dealwith, jpan-box, jfox-box

Poem

A rabbit hops with paws so light,
Dragging files into the drop zone bright,
With folderId tucked safe inside,
Tests confirm the queue's applied,
Hop, hop, hooray — the uploads glide! 🐇📦

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description summarizes the code change but omits the repository template's merge-queue and ready-to-merge guidance. Add the template's merge-queue checklist, ready-to-merge label guidance, and any required approval/reviewer details.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding drag-and-drop support to the modernized uploads manager.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.44.0)
src/elements/content-uploader/__tests__/ContentUploader.test.js

ast-grep timed out on this file


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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-uploader/ContentUploader.tsx (1)

658-687: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Snapshot rootFolderId for the modernized flow src/elements/content-uploader/ContentUploader.tsx:658-687 The modernized drop zone is active whenever enableModernizedUploads is true, even if useUploadsManager is false, so this guard should match that path. Otherwise dropped items skip the folder snapshot and can upload into a later rootFolderId.

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

In `@src/elements/content-uploader/ContentUploader.tsx` around lines 658 - 687,
The modernized upload path in ContentUploader.tsx does not snapshot rootFolderId
for all modernized drops because shouldAddRootFolderIdToUploadOptions is gated
by useUploadsManager too narrowly. Update the upload-item creation flow in the
newItems map so the folderId snapshot is applied whenever
enableModernizedUploads is enabled for the modernized drop zone, using
rootFolderId and getUploadAPI/getFileAPIOptions logic in ContentUploader to
ensure dropped files keep the original folder context.
🧹 Nitpick comments (1)
src/elements/content-uploader/ModernizedUploadsManagerDropZone.tsx (1)

14-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared drop-type check ModernizedUploadsManagerDropZone and DroppableContent now keep the same Array/DOMStringList intersection logic in two places; pull that into a shared helper and keep only the canDrop gate here.

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

In `@src/elements/content-uploader/ModernizedUploadsManagerDropZone.tsx` around
lines 14 - 40, The Array/DOMStringList intersection logic in
ModernizedUploadsManagerDropZone is duplicated with DroppableContent, so extract
that shared drop-type check into a common helper and reuse it here. Keep
dropDefinition.dropValidator focused on the canDrop gate plus a call to the
shared helper, and preserve the existing allowedTypes/types behavior in
ModernizedUploadsManagerDropZone and the shared utility used by
DroppableContent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/elements/content-uploader/ContentUploader.tsx`:
- Around line 658-687: The modernized upload path in ContentUploader.tsx does
not snapshot rootFolderId for all modernized drops because
shouldAddRootFolderIdToUploadOptions is gated by useUploadsManager too narrowly.
Update the upload-item creation flow in the newItems map so the folderId
snapshot is applied whenever enableModernizedUploads is enabled for the
modernized drop zone, using rootFolderId and getUploadAPI/getFileAPIOptions
logic in ContentUploader to ensure dropped files keep the original folder
context.

---

Nitpick comments:
In `@src/elements/content-uploader/ModernizedUploadsManagerDropZone.tsx`:
- Around line 14-40: The Array/DOMStringList intersection logic in
ModernizedUploadsManagerDropZone is duplicated with DroppableContent, so extract
that shared drop-type check into a common helper and reuse it here. Keep
dropDefinition.dropValidator focused on the canDrop gate plus a call to the
shared helper, and preserve the existing allowedTypes/types behavior in
ModernizedUploadsManagerDropZone and the shared utility used by
DroppableContent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d3f5c79c-f9d9-4e63-a3ac-918b663d4236

📥 Commits

Reviewing files that changed from the base of the PR and between f13b0a9 and 73bb86a.

📒 Files selected for processing (3)
  • src/elements/content-uploader/ContentUploader.tsx
  • src/elements/content-uploader/ModernizedUploadsManagerDropZone.tsx
  • src/elements/content-uploader/__tests__/ContentUploader.test.js


const dropDefinition = {
dropValidator: (
{ allowedTypes, isDropEnabled = true }: ModernizedUploadsManagerDropZoneProps,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It should be false at the ContentUploader level by default because use should not be able to drop files when canDropOnUploadsManager is ommited. The DropZone component defaults to true only when used directly.

@@ -678,7 +682,9 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
};

if (uploadAPIOptions) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i know this isn't a part of your pr but one thing i've been looking for in recent PRs are unnecessary guards. is uploadAPIOptions ever falsy for a file? i see it's defined a few lines above

https://github.com/box/box-ui-elements/pull/4674/changes#diff-71da4c8322f44025d67f136a0fd91e42a42d269dfc74654fa335bc7d24cc5c88R664

and i see that function always returns something ie it should be truthy

function getFileAPIOptions(file: UploadFile | UploadFileWithAPIOptions): UploadItemAPIOptions {
if (doesFileContainAPIOptions(file)) {
return ((file: any): UploadFileWithAPIOptions).options || DEFAULT_API_OPTIONS;
}

in other repos i know we have quality gates for cognitive load (ie extra or unused if conditions), but not so much in this one, however it might still be good to clean this up while you're in here. up to you though on how much creep you're ok with in this pr

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I would like to avoid changing it as part of this PR because I do not have enough context why this guard is there. If something breaks it could force us to revert the whole drop support as well, so I’d rather keep this PR scoped to the related changes.

try {
renderModernizedUploadsManagerDropZone();

fireEvent.dragEnter(screen.getByTestId('bcu-modernized-panel'), { dataTransfer });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i know this test id was already in here but i have to ask, is it totally necessary to use it here? we always prefer to use the role based lookups

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

EUA’s dropzone component also use data-testid for testing these wrapper-only drop targets. Since this element doesn’t currently expose a meaningful role/name I would like to keep the data-testid approach.

Comment thread src/elements/content-uploader/__tests__/ContentUploader.test.js Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants