From feae879988486af994343e82b6fc798848194335 Mon Sep 17 00:00:00 2001 From: Hleb Kryshyn Date: Wed, 20 May 2026 11:17:42 +0200 Subject: [PATCH 1/4] feat(uploads-manager): add enableModernizedUploads feature flag to ContentUploader --- .../content-uploader/ContentUploader.tsx | 9 +++++- .../__tests__/ContentUploader.test.js | 30 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/elements/content-uploader/ContentUploader.tsx b/src/elements/content-uploader/ContentUploader.tsx index f177e7cd81..8afe7f9e12 100644 --- a/src/elements/content-uploader/ContentUploader.tsx +++ b/src/elements/content-uploader/ContentUploader.tsx @@ -104,6 +104,7 @@ export interface ContentUploaderProps { token?: Token; uploadHost: string; useUploadsManager?: boolean; + enableModernizedUploads?: boolean; } type State = { @@ -169,6 +170,7 @@ class ContentUploader extends Component { rootFolderId: DEFAULT_ROOT, uploadHost: DEFAULT_HOSTNAME_UPLOAD, useUploadsManager: false, + enableModernizedUploads: false, }; /** @@ -1268,6 +1270,7 @@ class ContentUploader extends Component { render() { const { className, + enableModernizedUploads, fileLimit, isDraggingItemsToUploadsManager = false, isFolderUploadEnabled, @@ -1297,7 +1300,11 @@ class ContentUploader extends Component { return ( - {useUploadsManager ? ( + {enableModernizedUploads ? ( +
+ +
+ ) : useUploadsManager ? (
{ expect(instance.addToQueue.mock.calls[0][0].length).toBe(mockFoldersList.length); }); }); + + describe('render()', () => { + describe('enableModernizedUploads', () => { + test('should render legacy UploadsManager when enableModernizedUploads is false and useUploadsManager is true', () => { + const wrapper = getWrapper({ enableModernizedUploads: false, useUploadsManager: true }); + expect(wrapper.find(UploadsManager)).toHaveLength(1); + expect(wrapper.find(DroppableContent)).toHaveLength(0); + }); + + test('should render DroppableContent when enableModernizedUploads is false and useUploadsManager is false', () => { + const wrapper = getWrapper({ enableModernizedUploads: false, useUploadsManager: false }); + expect(wrapper.find(DroppableContent)).toHaveLength(1); + expect(wrapper.find(UploadsManager)).toHaveLength(0); + }); + + test('should render modernized uploads placeholder when enableModernizedUploads is true', () => { + const wrapper = getWrapper({ enableModernizedUploads: true }); + expect(wrapper.find(UploadsManager)).toHaveLength(0); + expect(wrapper.find(DroppableContent)).toHaveLength(0); + }); + + test('should render modernized uploads placeholder even when useUploadsManager is true', () => { + const wrapper = getWrapper({ enableModernizedUploads: true, useUploadsManager: true }); + expect(wrapper.find(UploadsManager)).toHaveLength(0); + expect(wrapper.find(DroppableContent)).toHaveLength(0); + }); + }); + }); }); From a2770d31fae30e6d7e30facd41e10faf905fd28f Mon Sep 17 00:00:00 2001 From: Hleb Kryshyn Date: Wed, 20 May 2026 11:17:42 +0200 Subject: [PATCH 2/4] feat(uploads-manager): add enableModernizedUploads feature flag to ContentUploader --- i18n/en-US.properties | 10 ++ scripts/jest/jest.config.js | 2 +- .../content-uploader/ContentUploader.tsx | 106 ++++++++++-------- .../stories/ContentUploader.stories.js | 6 + 4 files changed, 77 insertions(+), 47 deletions(-) diff --git a/i18n/en-US.properties b/i18n/en-US.properties index d4c6296ce7..7e265bf90c 100644 --- a/i18n/en-US.properties +++ b/i18n/en-US.properties @@ -386,6 +386,16 @@ be.contentSidebar.editTask.general.title = Modify General Task be.contentSidebar.mentionUserSelectorLoading = Loading users # Accessibility role description for the mention user selector input be.contentSidebar.mentionUserSelectorRoleDescription = Mention a user +# Aria label for the close button on the cancel all uploads modal +be.contentUploader.cancelAllUploadsCloseLabel = Close cancel uploads dialog +# Confirm button for the cancel all uploads modal +be.contentUploader.cancelAllUploadsConfirmButton = Cancel All +# Dismiss button for the cancel all uploads modal +be.contentUploader.cancelAllUploadsKeepButton = Keep Uploading +# Body content for the cancel all uploads confirmation modal +be.contentUploader.cancelAllUploadsModalContent = Files that are still uploading will be canceled. Completed uploads will not be affected. +# Heading for the cancel all uploads confirmation modal +be.contentUploader.cancelAllUploadsModalHeading = Cancel all uploads? # Label for copy action. be.copy = Copy # Label for create action. diff --git a/scripts/jest/jest.config.js b/scripts/jest/jest.config.js index ad447fdb77..4a7f6bb249 100644 --- a/scripts/jest/jest.config.js +++ b/scripts/jest/jest.config.js @@ -28,6 +28,6 @@ module.exports = { testMatch: ['**/__tests__/**/*.test.+(js|jsx|ts|tsx)'], testPathIgnorePatterns: ['stories.test.js$', 'stories.test.tsx$', 'stories.test.d.ts'], transformIgnorePatterns: [ - 'node_modules/(?!(@box/activity-feed|@box/collaboration-popover|@box/react-virtualized/dist/es|@box/cldr-data|@box/blueprint-web|@box/blueprint-web-assets|@box/metadata-editor|@box/box-ai-content-answers|@box/box-ai-agent-selector|@box/item-icon|@box/combobox-with-api|@box/tree|@box/metadata-filter|@box/metadata-view|@box/content-field|@box/types|@box/box-item-type-selector|@box/unified-share-modal|@box/user-selector|@box/copy-input|@box/readable-time|@box/threaded-annotations)/)', + 'node_modules/(?!(@box/activity-feed|@box/collaboration-popover|@box/react-virtualized/dist/es|@box/cldr-data|@box/blueprint-web|@box/blueprint-web-assets|@box/metadata-editor|@box/box-ai-content-answers|@box/box-ai-agent-selector|@box/item-icon|@box/combobox-with-api|@box/tree|@box/metadata-filter|@box/metadata-view|@box/content-field|@box/types|@box/box-item-type-selector|@box/unified-share-modal|@box/user-selector|@box/copy-input|@box/readable-time|@box/threaded-annotations|@box/uploads-manager)/)', ], }; diff --git a/src/elements/content-uploader/ContentUploader.tsx b/src/elements/content-uploader/ContentUploader.tsx index 8afe7f9e12..9923bf3ced 100644 --- a/src/elements/content-uploader/ContentUploader.tsx +++ b/src/elements/content-uploader/ContentUploader.tsx @@ -6,6 +6,7 @@ import flow from 'lodash/flow'; import getProp from 'lodash/get'; import noop from 'lodash/noop'; import uniqueid from 'lodash/uniqueId'; +import { UploadsManager as UploadsManagerBP } from '@box/uploads-manager'; import { TooltipProvider } from '@box/blueprint-web'; import { AxiosRequestConfig, AxiosResponse } from 'axios'; import DroppableContent from './DroppableContent'; @@ -1297,55 +1298,68 @@ class ContentUploader extends Component { be: !useUploadsManager, }); + const renderUploader = () => { + if (enableModernizedUploads) { + return ( +
+ + +
+ ); + } + + if (useUploadsManager) { + return ( +
+ + +
+ ) + } + + return ( +
+ + +
+
+ ) + } + return ( - {enableModernizedUploads ? ( -
- -
- ) : useUploadsManager ? ( -
- - -
- ) : ( -
- - -
-
- )} + {renderUploader()}
); diff --git a/src/elements/content-uploader/stories/ContentUploader.stories.js b/src/elements/content-uploader/stories/ContentUploader.stories.js index 6ddd6f8591..693d44d0a0 100644 --- a/src/elements/content-uploader/stories/ContentUploader.stories.js +++ b/src/elements/content-uploader/stories/ContentUploader.stories.js @@ -10,6 +10,12 @@ export const withTheming = { }, }; +export const withModernizedUploads = { + args: { + enableModernizedUploads: true, + }, +}; + export default { title: 'Elements/ContentUploader', component: ContentUploader, From 9e8170b5f89410deaae28cf1d2eff64b49ab66b7 Mon Sep 17 00:00:00 2001 From: Hleb Kryshyn Date: Thu, 21 May 2026 13:41:57 +0200 Subject: [PATCH 3/4] feat(uploads-manager): add UploadManagerBP for tests --- .../content-uploader/__tests__/ContentUploader.test.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/elements/content-uploader/__tests__/ContentUploader.test.js b/src/elements/content-uploader/__tests__/ContentUploader.test.js index 579b9a9f97..10b0afefcc 100644 --- a/src/elements/content-uploader/__tests__/ContentUploader.test.js +++ b/src/elements/content-uploader/__tests__/ContentUploader.test.js @@ -1,5 +1,6 @@ import * as React from 'react'; import { shallow } from 'enzyme'; +import { UploadsManager as UploadsManagerBP } from '@box/uploads-manager'; import * as UploaderUtils from '../../../utils/uploads'; import Browser from '../../../utils/Browser'; import { ContentUploaderComponent, CHUNKED_UPLOAD_MIN_SIZE_BYTES } from '../ContentUploader'; @@ -763,6 +764,7 @@ describe('elements/content-uploader/ContentUploader', () => { test('should render legacy UploadsManager when enableModernizedUploads is false and useUploadsManager is true', () => { const wrapper = getWrapper({ enableModernizedUploads: false, useUploadsManager: true }); expect(wrapper.find(UploadsManager)).toHaveLength(1); + expect(wrapper.find(UploadsManagerBP)).toHaveLength(0); expect(wrapper.find(DroppableContent)).toHaveLength(0); }); @@ -770,16 +772,19 @@ describe('elements/content-uploader/ContentUploader', () => { const wrapper = getWrapper({ enableModernizedUploads: false, useUploadsManager: false }); expect(wrapper.find(DroppableContent)).toHaveLength(1); expect(wrapper.find(UploadsManager)).toHaveLength(0); + expect(wrapper.find(UploadsManagerBP)).toHaveLength(0); }); - test('should render modernized uploads placeholder when enableModernizedUploads is true', () => { + test('should render modernized UploadsManager when enableModernizedUploads is true', () => { const wrapper = getWrapper({ enableModernizedUploads: true }); + expect(wrapper.find(UploadsManagerBP)).toHaveLength(1); expect(wrapper.find(UploadsManager)).toHaveLength(0); expect(wrapper.find(DroppableContent)).toHaveLength(0); }); - test('should render modernized uploads placeholder even when useUploadsManager is true', () => { + test('should render modernized UploadsManager when enableModernizedUploads is true and useUploadsManager is true', () => { const wrapper = getWrapper({ enableModernizedUploads: true, useUploadsManager: true }); + expect(wrapper.find(UploadsManagerBP)).toHaveLength(1); expect(wrapper.find(UploadsManager)).toHaveLength(0); expect(wrapper.find(DroppableContent)).toHaveLength(0); }); From 55f3e27000517727c13a8f33ac2c2324c0423a1c Mon Sep 17 00:00:00 2001 From: Hleb Kryshyn Date: Thu, 21 May 2026 14:04:58 +0200 Subject: [PATCH 4/4] fix(i18n): drop en-us auto generated --- i18n/en-US.properties | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/i18n/en-US.properties b/i18n/en-US.properties index 7e265bf90c..d4c6296ce7 100644 --- a/i18n/en-US.properties +++ b/i18n/en-US.properties @@ -386,16 +386,6 @@ be.contentSidebar.editTask.general.title = Modify General Task be.contentSidebar.mentionUserSelectorLoading = Loading users # Accessibility role description for the mention user selector input be.contentSidebar.mentionUserSelectorRoleDescription = Mention a user -# Aria label for the close button on the cancel all uploads modal -be.contentUploader.cancelAllUploadsCloseLabel = Close cancel uploads dialog -# Confirm button for the cancel all uploads modal -be.contentUploader.cancelAllUploadsConfirmButton = Cancel All -# Dismiss button for the cancel all uploads modal -be.contentUploader.cancelAllUploadsKeepButton = Keep Uploading -# Body content for the cancel all uploads confirmation modal -be.contentUploader.cancelAllUploadsModalContent = Files that are still uploading will be canceled. Completed uploads will not be affected. -# Heading for the cancel all uploads confirmation modal -be.contentUploader.cancelAllUploadsModalHeading = Cancel all uploads? # Label for copy action. be.copy = Copy # Label for create action.