feat(uploads-manager): integrate shared feature into ContentUploader#4573
feat(uploads-manager): integrate shared feature into ContentUploader#4573dealwith wants to merge 6 commits into
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughContentUploader maps legacy upload items to UploadsManager item objects, exposes rootFolderId to the mapper, renders UploadsManagerBP when enabled, and bridges UploadsManagerBP actions (cancel/retry/remove) back to legacy handlers; folder uploads now include uploadInitTimestamp in options. ChangesContentUploader Modernized Uploads Integration
Sequence Diagram(s)sequenceDiagram
participant LegacyState as ContentUploader (state.items)
participant Mapper as mapToModernizedUploadItems
participant UploadsManagerBP as UploadsManagerBP
participant Bridging as Bridging Handlers (findItemByModernizedId)
participant LegacyHandlers as Legacy Handlers (onClick, removeFileFromUploadQueue)
LegacyState->>Mapper: state.items + rootFolderId
Mapper->>UploadsManagerBP: ModernizedUploadItem[]
UploadsManagerBP->>Bridging: onItemCancel(modernizedId)
Bridging->>Bridging: findItemByModernizedId(modernizedId)
Bridging->>LegacyHandlers: onClick(legacyItem)
UploadsManagerBP->>Bridging: onItemRemove(modernizedId)
Bridging->>LegacyHandlers: removeFileFromUploadQueue(legacyItem)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
62792f4 to
55f3e27
Compare
Wire @box/uploads-manager UploadsManager into ContentUploader behind the enableModernizedUploads flag. Maps legacy upload state to the shared feature's item shape and delegates per-item cancel/retry/remove actions to existing handlers.
b7bf9cc to
4acdc6a
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
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/__tests__/ContentUploader.test.js (1)
3-3:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winRemove duplicate
UploadsManagerBPimport (build-blocking parse error).
UploadsManagerBPis declared twice, which triggers the exact parser/lint failures shown in CI. Keep only one import.Also applies to: 10-10
🤖 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/__tests__/ContentUploader.test.js` at line 3, There are duplicate imports of UploadsManagerBP causing a parse error; locate both import statements that declare UploadsManagerBP (the import from '`@box/uploads-manager`') and remove the redundant one so UploadsManagerBP is imported only once; ensure any usages rely on the remaining import and that no other alias or name change is introduced.
🧹 Nitpick comments (1)
src/elements/content-uploader/utils/__tests__/mapToModernizedUploadItem.test.ts (1)
10-19: ⚡ Quick winAdd a regression test for folder items without
file.Current fixtures always include
file, so the folder path is untested. Add a case with{ isFolder: true, file: undefined }to ensure mapping (includingid) is safe.Also applies to: 69-79
🤖 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/utils/__tests__/mapToModernizedUploadItem.test.ts` around lines 10 - 19, Add a regression test in mapToModernizedUploadItem.test.ts that constructs a legacy item with isFolder: true and file: undefined (use the existing buildLegacyItem helper) to cover the folder path; call the mapping function under test (mapToModernizedUploadItem or whichever test subject is imported) with that item and assert it returns a valid modernized upload item without throwing and includes a safe id (e.g., non-null/defined) and expected folder-specific fields. Ensure the new test mirrors other fixtures but overrides file: undefined and isFolder: true so the mapping logic that reads file properties is exercised safely.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/elements/content-uploader/ContentUploader.tsx`:
- Around line 1226-1229: findItemByModernizedId currently recomputes IDs from
item.file (using getFileId) which fails for folder entries that lack a file;
update findItemByModernizedId to use the same ID derivation contract used when
mapping this.state.items (i.e., reuse the precomputed modernized ID stored on
each UploadItem or the helper that produced it) and explicitly handle folder
items by deriving their ID from the folder-specific fields instead of item.file
so cancel/retry/remove operations find the correct item whether it's a file or
folder.
In `@src/elements/content-uploader/utils/mapToModernizedUploadItem.ts`:
- Around line 31-36: mapToModernizedUploadItem currently calls
getFileId(item.file, rootFolderId) unconditionally which breaks for folder items
that lack item.file; change the id assignment in mapToModernizedUploadItem so it
uses getFileId(item.file, rootFolderId) only when item.file exists and otherwise
returns the same folder-safe fallback used by
ContentUploader.findItemByModernizedId (use the exact same fallback value/logic
from that method to keep lookups consistent). Ensure you reference getFileId,
mapToModernizedUploadItem, and ContentUploader.findItemByModernizedId while
making this conditional fix.
---
Outside diff comments:
In `@src/elements/content-uploader/__tests__/ContentUploader.test.js`:
- Line 3: There are duplicate imports of UploadsManagerBP causing a parse error;
locate both import statements that declare UploadsManagerBP (the import from
'`@box/uploads-manager`') and remove the redundant one so UploadsManagerBP is
imported only once; ensure any usages rely on the remaining import and that no
other alias or name change is introduced.
---
Nitpick comments:
In
`@src/elements/content-uploader/utils/__tests__/mapToModernizedUploadItem.test.ts`:
- Around line 10-19: Add a regression test in mapToModernizedUploadItem.test.ts
that constructs a legacy item with isFolder: true and file: undefined (use the
existing buildLegacyItem helper) to cover the folder path; call the mapping
function under test (mapToModernizedUploadItem or whichever test subject is
imported) with that item and assert it returns a valid modernized upload item
without throwing and includes a safe id (e.g., non-null/defined) and expected
folder-specific fields. Ensure the new test mirrors other fixtures but overrides
file: undefined and isFolder: true so the mapping logic that reads file
properties is exercised safely.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5c857d9c-d038-41d0-af47-52ee7be0952e
📒 Files selected for processing (4)
src/elements/content-uploader/ContentUploader.tsxsrc/elements/content-uploader/__tests__/ContentUploader.test.jssrc/elements/content-uploader/utils/__tests__/mapToModernizedUploadItem.test.tssrc/elements/content-uploader/utils/mapToModernizedUploadItem.ts
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
@Mergifyio queue |
Merge Queue Status
Waiting for any of
All conditions
|
|
|
||
| handleModernizedItemAction = (id: string) => { | ||
| const item = this.findItemByModernizedId(id); | ||
| if (item) { |
There was a problem hiding this comment.
if findItemByModernizedId doesn't find a match, this just proceeds without issue. we should catch any unhandled scenarios here with an else.
There was a problem hiding this comment.
Do you have any suggestion about it?
We can do something like this, but not really sure about it, what's your thoughts?
handleMissingModernizedUploadItem = (key: string, action: 'action' | 'remove') => {
const error = new Error(`ContentUploader: no upload item found for key "${key}" on ${action}.`);
this.props.onError({ error });
};
handleModernizedItemAction = (key: string) => {
const item = this.findItemByUploadKey(key);
if (item) {
this.onClick(item);
} else {
this.handleMissingModernizedUploadItem(key, 'action');
}
};There was a problem hiding this comment.
the easiest thing in my mind is a console.error, i see that's done elsewhere in buie. however, i know everybody has their own opinions on console.errors in production code.
the other option is if this is an error that should be surfaced or handled in some way to the user.
also, i wonder if there's any action we need to take on our side, ie what happens if this else case is triggered? would the rest of the manager (the toast?) be functional, or not so much? or, what can we do to help ourselves debug in the future if a bug shows up somewhere and this case is triggered? ie if a customer raises an issue and it ends up in our queues.
if the answer is not much then so be it, but this feels like the right time to set ourselves up for success in the future.
There was a problem hiding this comment.
For now added the the console.error, because it feels like this error shouldn't popup to the user
| <ThemingStyles selector={`#${this.id}`} theme={theme} /> | ||
| <UploadsManagerBP items={[]} /> | ||
| <UploadsManagerBP | ||
| items={mapToModernizedUploadItems(items, rootFolderId)} |
There was a problem hiding this comment.
mapToModernizedUploadItems runs on every render without memoization, which means we're re-mapping all items in the queue even when nothing changed. I believe our consuming app sets fileLimit to 100,000 - so this could get expensive. if you can think of a way to optimize this or get ahead of the performance issues that would be great.
There was a problem hiding this comment.
thanks @jpan-box I have a follow up to overall remove mapToModernizedUploadItems, so if I will see that we won't be making follow up about getting rid of mapToModernizedUploadItems — I will create an additional PR for optimization of the mapToModernizedUploadItems
There was a problem hiding this comment.
ok - this is a case i expect to see very very quickly as many customers will drag and drop large volumes of content via the web app despite our best encouragement to not do that.
There was a problem hiding this comment.
no worries about it, I will keep it under control
jpan-box
left a comment
There was a problem hiding this comment.
requesting some changes. some lower priority, some that i think should be changed.
|
looks like a lint error to take care of |
There was a problem hiding this comment.
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-uploader/ContentUploader.tsx (1)
1333-1344:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift
enableModernizedUploadsonly switches the render path.This branch renders
UploadsManagerBPwhenever the flag is on, but the rest of the uploader still keys manager behavior offuseUploadsManager. With the defaultuseUploadsManager={false}, prop-driven uploads never enter the queue incomponentDidUpdate, toggle/auto-expand stay disabled, and success/complete still follow the legacy callback flow. Please drive all uploads-manager codepaths from one shared boolean instead of gating only the JSX.🤖 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 1333 - 1344, The render branch currently gates only the JSX on enableModernizedUploads while lifecycle and behavior still read useUploadsManager; change to a single shared boolean (e.g., isUsingUploadsManager = enableModernizedUploads || useUploadsManager) and use that everywhere: render UploadsManagerBP, componentDidUpdate enqueue logic, toggleUploadsManager/auto-expand logic, and success/complete flows so prop-driven uploads go through the manager. Update references in render (UploadsManagerBP, mapToModernizedUploadItems), lifecycle (componentDidUpdate), and handlers (toggleUploadsManager, handleModernizedItemAction, handleModernizedItemRemove) to read the new shared boolean.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/elements/content-uploader/ContentUploader.tsx`:
- Around line 1234-1235: Canceling/removing folder uploads leaves dedupe keys in
itemIdsRef because removeFileFromUploadQueue only clears when item.file exists;
update the cleanup to also remove keys for folder-type items (and wherever
onClick triggers removal for folders) by computing the same dedupe key used when
the folder was enqueued and deleting it from itemIdsRef (e.g., check/remove by
item.id or folder identifier and the same key-generation logic used when adding
to itemIdsRef in addFileToUploadQueue). Ensure both removeFileFromUploadQueue
and the onClick removal path handle items without item.file so folder cancels
fully free the dedupe entry.
---
Outside diff comments:
In `@src/elements/content-uploader/ContentUploader.tsx`:
- Around line 1333-1344: The render branch currently gates only the JSX on
enableModernizedUploads while lifecycle and behavior still read
useUploadsManager; change to a single shared boolean (e.g.,
isUsingUploadsManager = enableModernizedUploads || useUploadsManager) and use
that everywhere: render UploadsManagerBP, componentDidUpdate enqueue logic,
toggleUploadsManager/auto-expand logic, and success/complete flows so
prop-driven uploads go through the manager. Update references in render
(UploadsManagerBP, mapToModernizedUploadItems), lifecycle (componentDidUpdate),
and handlers (toggleUploadsManager, handleModernizedItemAction,
handleModernizedItemRemove) to read the new shared boolean.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6ba16534-4a8f-48bb-817d-637c97d5fa11
📒 Files selected for processing (1)
src/elements/content-uploader/ContentUploader.tsx
Wire
@box/uploads-managerUploadsManager component intoContentUploaderbehind theenableModernizedUploadsflag. Maps legacy upload state to the shared feature's item shape and delegates per-item cancel/retry/remove actions to existing handlers.1/5 pr in the queue
Summary by CodeRabbit
Refactor
Tests