box-ui-elements 23.4.0-beta.22 → 23.4.0-beta.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/explorer.js +1 -1
- package/dist/openwith.js +1 -1
- package/dist/picker.js +1 -1
- package/dist/preview.js +1 -1
- package/dist/sharing.js +1 -1
- package/dist/sidebar.js +1 -1
- package/dist/uploader.js +1 -1
- package/es/api/uploads/BaseUpload.js +4 -0
- package/es/api/uploads/BaseUpload.js.flow +5 -1
- package/es/api/uploads/BaseUpload.js.map +1 -1
- package/es/api/uploads/MultiputUpload.js +7 -0
- package/es/api/uploads/MultiputUpload.js.flow +11 -6
- package/es/api/uploads/MultiputUpload.js.map +1 -1
- package/es/api/uploads/PlainUpload.js +2 -1
- package/es/api/uploads/PlainUpload.js.flow +3 -2
- package/es/api/uploads/PlainUpload.js.map +1 -1
- package/es/components/flyout/OverlayHeader.js +6 -3
- package/es/components/flyout/OverlayHeader.js.map +1 -1
- package/es/elements/common/nav-router/NavRouter.js +7 -3
- package/es/elements/common/nav-router/NavRouter.js.flow +10 -1
- package/es/elements/common/nav-router/NavRouter.js.map +1 -1
- package/es/elements/common/nav-router/types.js.map +1 -1
- package/es/elements/common/nav-router/withNavRouter.js +10 -1
- package/es/elements/common/nav-router/withNavRouter.js.flow +5 -0
- package/es/elements/common/nav-router/withNavRouter.js.map +1 -1
- package/es/elements/common/routing/withRouterAndRef.js +17 -3
- package/es/elements/common/routing/withRouterAndRef.js.flow +11 -3
- package/es/elements/common/routing/withRouterAndRef.js.map +1 -1
- package/es/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.js +22 -13
- package/es/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.js.flow +30 -17
- package/es/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.js.map +1 -1
- package/es/elements/content-sidebar/ContentSidebar.js +3 -1
- package/es/elements/content-sidebar/ContentSidebar.js.flow +2 -1
- package/es/elements/content-sidebar/ContentSidebar.js.map +1 -1
- package/es/elements/content-sidebar/SidebarToggle.js +27 -9
- package/es/elements/content-sidebar/SidebarToggle.js.flow +29 -6
- package/es/elements/content-sidebar/SidebarToggle.js.map +1 -1
- package/es/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.js +12 -1
- package/es/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.js.map +1 -1
- package/es/elements/content-uploader/ContentUploader.js +7 -3
- package/es/elements/content-uploader/ContentUploader.js.map +1 -1
- package/es/elements/content-uploader/ItemAction.js +8 -3
- package/es/elements/content-uploader/ItemAction.js.map +1 -1
- package/es/features/header-flyout/HeaderFlyout.js +6 -3
- package/es/features/header-flyout/HeaderFlyout.js.flow +15 -2
- package/es/features/header-flyout/HeaderFlyout.js.map +1 -1
- package/es/src/components/flyout/OverlayHeader.d.ts +3 -1
- package/es/src/elements/common/nav-router/NavRouter.d.ts +3 -1
- package/es/src/elements/common/nav-router/types.d.ts +2 -0
- package/es/src/elements/content-uploader/ContentUploader.d.ts +1 -1
- package/package.json +1 -1
- package/src/api/uploads/BaseUpload.js +5 -1
- package/src/api/uploads/MultiputUpload.js +11 -6
- package/src/api/uploads/PlainUpload.js +3 -2
- package/src/api/uploads/__tests__/BaseUpload.test.js +14 -0
- package/src/components/flyout/OverlayHeader.tsx +7 -3
- package/src/components/flyout/__tests__/OverlayHeader.test.js +25 -0
- package/src/elements/common/nav-router/NavRouter.js.flow +10 -1
- package/src/elements/common/nav-router/NavRouter.tsx +9 -3
- package/src/elements/common/nav-router/__tests__/withNavRouter.test.tsx +34 -20
- package/src/elements/common/nav-router/types.ts +2 -0
- package/src/elements/common/nav-router/withNavRouter.js.flow +5 -0
- package/src/elements/common/nav-router/withNavRouter.tsx +9 -1
- package/src/elements/common/routing/__tests__/withRouterAndRef.test.js +64 -12
- package/src/elements/common/routing/withRouterAndRef.js +11 -3
- package/src/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.js +30 -17
- package/src/elements/content-sidebar/ContentSidebar.js +2 -1
- package/src/elements/content-sidebar/SidebarToggle.js +29 -6
- package/src/elements/content-sidebar/__tests__/SidebarToggle.test.js +74 -10
- package/src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.tsx +14 -1
- package/src/elements/content-uploader/ContentUploader.tsx +7 -3
- package/src/elements/content-uploader/ItemAction.tsx +8 -2
- package/src/features/header-flyout/HeaderFlyout.js +15 -2
- package/src/features/header-flyout/__tests__/__snapshots__/HeaderFlyout.test.js.snap +9 -3
- package/src/elements/content-sidebar/__tests__/__snapshots__/SidebarToggle.test.js.snap +0 -19
|
@@ -1,23 +1,87 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { render, screen, userEvent } from '../../../test-utils/testing-library';
|
|
3
3
|
import { SidebarToggleComponent as SidebarToggle } from '../SidebarToggle';
|
|
4
4
|
|
|
5
5
|
describe('elements/content-sidebar/SidebarToggle', () => {
|
|
6
6
|
const historyMock = { replace: jest.fn() };
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
jest.clearAllMocks();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const renderSidebarToggle = (props = {}) => {
|
|
13
|
+
return render(<SidebarToggle history={historyMock} {...props} />);
|
|
14
|
+
};
|
|
8
15
|
|
|
9
16
|
test.each`
|
|
10
|
-
isOpen |
|
|
17
|
+
isOpen | expectedState
|
|
11
18
|
${true} | ${{ state: { open: false } }}
|
|
12
19
|
${false} | ${{ state: { open: true } }}
|
|
13
|
-
`('should render and handle clicks correctly when isOpen is $isOpen', ({ isOpen,
|
|
14
|
-
const
|
|
15
|
-
|
|
20
|
+
`('should render and handle clicks correctly when isOpen is $isOpen', async ({ isOpen, expectedState }) => {
|
|
21
|
+
const user = userEvent();
|
|
22
|
+
renderSidebarToggle({ isOpen });
|
|
23
|
+
|
|
24
|
+
const toggleButton = screen.getByTestId('sidebartoggle');
|
|
25
|
+
expect(toggleButton).toBeInTheDocument();
|
|
26
|
+
|
|
27
|
+
await user.click(toggleButton);
|
|
28
|
+
|
|
29
|
+
expect(historyMock.replace).toHaveBeenCalledWith(expectedState);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
16
32
|
|
|
17
|
-
|
|
33
|
+
describe('elements/content-sidebar/SidebarToggle - Router Disabled', () => {
|
|
34
|
+
const mockInternalSidebarNavigationHandler = jest.fn();
|
|
35
|
+
const defaultProps = {
|
|
36
|
+
routerDisabled: true,
|
|
37
|
+
internalSidebarNavigation: { sidebar: 'activity' },
|
|
38
|
+
internalSidebarNavigationHandler: mockInternalSidebarNavigationHandler,
|
|
39
|
+
};
|
|
18
40
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
expect(wrapper).toMatchSnapshot();
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
jest.clearAllMocks();
|
|
22
43
|
});
|
|
44
|
+
|
|
45
|
+
const renderSidebarToggle = (props = {}) => {
|
|
46
|
+
return render(<SidebarToggle {...defaultProps} {...props} />);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
test.each`
|
|
50
|
+
isOpen | expectedNavigation
|
|
51
|
+
${true} | ${{ sidebar: 'activity', open: false }}
|
|
52
|
+
${false} | ${{ sidebar: 'activity', open: true }}
|
|
53
|
+
`('should handle toggle clicks correctly when isOpen is $isOpen', async ({ isOpen, expectedNavigation }) => {
|
|
54
|
+
const user = userEvent();
|
|
55
|
+
renderSidebarToggle({ isOpen });
|
|
56
|
+
|
|
57
|
+
const toggleButton = screen.getByTestId('sidebartoggle');
|
|
58
|
+
expect(toggleButton).toBeInTheDocument();
|
|
59
|
+
await user.click(toggleButton);
|
|
60
|
+
|
|
61
|
+
expect(mockInternalSidebarNavigationHandler).toHaveBeenCalledWith(expectedNavigation, true);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('should handle complex navigation state correctly', async () => {
|
|
65
|
+
const user = userEvent();
|
|
66
|
+
const complexNavigation = {
|
|
67
|
+
sidebar: 'activity',
|
|
68
|
+
versionId: '123',
|
|
69
|
+
activeFeedEntryType: 'comments',
|
|
70
|
+
activeFeedEntryId: '456',
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
renderSidebarToggle({
|
|
74
|
+
isOpen: true,
|
|
75
|
+
internalSidebarNavigation: complexNavigation,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const toggleButton = screen.getByTestId('sidebartoggle');
|
|
79
|
+
await user.click(toggleButton);
|
|
80
|
+
|
|
81
|
+
expect(mockInternalSidebarNavigationHandler).toHaveBeenCalledWith({
|
|
82
|
+
...complexNavigation,
|
|
83
|
+
open: false,
|
|
84
|
+
}, true);
|
|
85
|
+
});
|
|
86
|
+
|
|
23
87
|
});
|
package/src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.tsx
CHANGED
|
@@ -344,6 +344,19 @@ export const SwitchEditingTemplateInstances: StoryObj<typeof MetadataSidebarRede
|
|
|
344
344
|
fileId: '416047501580',
|
|
345
345
|
metadataSidebarProps: defaultMetadataSidebarProps,
|
|
346
346
|
},
|
|
347
|
+
parameters: {
|
|
348
|
+
msw: {
|
|
349
|
+
handlers: [
|
|
350
|
+
...defaultMockHandlers,
|
|
351
|
+
http.get(`/2.0/files/416047501580`, () => {
|
|
352
|
+
return HttpResponse.json(mockFileRequest.response);
|
|
353
|
+
}),
|
|
354
|
+
http.get(`/2.0/files/416047501580/metadata`, () => {
|
|
355
|
+
return HttpResponse.json(mockMetadataInstances.response);
|
|
356
|
+
}),
|
|
357
|
+
],
|
|
358
|
+
},
|
|
359
|
+
},
|
|
347
360
|
play: async ({ canvasElement }) => {
|
|
348
361
|
const canvas = within(canvasElement);
|
|
349
362
|
// open and edit a new template
|
|
@@ -543,7 +556,7 @@ export const SuggestionForNewlyCreatedTemplateInstance: StoryObj<typeof Metadata
|
|
|
543
556
|
const autofillButton = await canvas.findByRole('button', { name: 'Autofill' });
|
|
544
557
|
userEvent.click(autofillButton);
|
|
545
558
|
|
|
546
|
-
const suggestion = await canvas.findByText('4/1/2024');
|
|
559
|
+
const suggestion = await canvas.findByText('4/1/2024', {}, { timeout: 5000 });
|
|
547
560
|
expect(suggestion).toBeInTheDocument();
|
|
548
561
|
},
|
|
549
562
|
};
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
CLIENT_NAME_CONTENT_UPLOADER,
|
|
35
35
|
DEFAULT_HOSTNAME_API,
|
|
36
36
|
DEFAULT_HOSTNAME_UPLOAD,
|
|
37
|
+
ERROR_CODE_ITEM_NAME_IN_USE,
|
|
37
38
|
ERROR_CODE_UPLOAD_FILE_LIMIT,
|
|
38
39
|
STATUS_COMPLETE,
|
|
39
40
|
STATUS_ERROR,
|
|
@@ -90,7 +91,7 @@ export interface ContentUploaderProps {
|
|
|
90
91
|
onResume: (item: UploadItem) => void;
|
|
91
92
|
onUpgradeCTAClick?: () => void;
|
|
92
93
|
onUpload: (item?: UploadItem | BoxItem) => void;
|
|
93
|
-
overwrite: boolean;
|
|
94
|
+
overwrite: boolean | 'error';
|
|
94
95
|
requestInterceptor?: (response: AxiosResponse) => void;
|
|
95
96
|
responseInterceptor?: (config: AxiosRequestConfig) => void;
|
|
96
97
|
rootFolderId: string;
|
|
@@ -1083,7 +1084,7 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
|
|
|
1083
1084
|
*/
|
|
1084
1085
|
onClick = (item: UploadItem) => {
|
|
1085
1086
|
const { chunked, isResumableUploadsEnabled, onClickCancel, onClickResume, onClickRetry } = this.props;
|
|
1086
|
-
const { file, status } = item;
|
|
1087
|
+
const { file, status, error } = item;
|
|
1087
1088
|
const isChunkedUpload =
|
|
1088
1089
|
chunked && !item.isFolder && file.size > CHUNKED_UPLOAD_MIN_SIZE_BYTES && isMultiputSupported();
|
|
1089
1090
|
const isResumable = isResumableUploadsEnabled && isChunkedUpload && item.api.sessionId;
|
|
@@ -1097,7 +1098,10 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
|
|
|
1097
1098
|
onClickCancel(item);
|
|
1098
1099
|
break;
|
|
1099
1100
|
case STATUS_ERROR:
|
|
1100
|
-
if (
|
|
1101
|
+
if (error?.code === ERROR_CODE_ITEM_NAME_IN_USE) {
|
|
1102
|
+
this.removeFileFromUploadQueue(item);
|
|
1103
|
+
onClickCancel(item);
|
|
1104
|
+
} else if (isResumable) {
|
|
1101
1105
|
item.bytesUploadedOnLastResume = item.api.totalUploadedBytes;
|
|
1102
1106
|
this.resumeFile(item);
|
|
1103
1107
|
onClickResume(item);
|
|
@@ -8,6 +8,7 @@ import { Size5, SurfaceStatusSurfaceSuccess } from '@box/blueprint-web-assets/to
|
|
|
8
8
|
import IconInProgress from './IconInProgress';
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
+
ERROR_CODE_ITEM_NAME_IN_USE,
|
|
11
12
|
ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED,
|
|
12
13
|
STATUS_COMPLETE,
|
|
13
14
|
STATUS_ERROR,
|
|
@@ -70,8 +71,13 @@ const ItemAction = ({
|
|
|
70
71
|
}
|
|
71
72
|
break;
|
|
72
73
|
case STATUS_ERROR:
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
if (code === ERROR_CODE_ITEM_NAME_IN_USE) {
|
|
75
|
+
Icon = XMark;
|
|
76
|
+
tooltip = messages.uploadsCancelButtonTooltip;
|
|
77
|
+
} else {
|
|
78
|
+
Icon = ArrowCurveForward;
|
|
79
|
+
tooltip = isResumableUploadsEnabled ? messages.resume : messages.retry;
|
|
80
|
+
}
|
|
75
81
|
break;
|
|
76
82
|
case STATUS_IN_PROGRESS:
|
|
77
83
|
case STATUS_STAGED:
|
|
@@ -20,6 +20,8 @@ type Props = FlyoutProps & {
|
|
|
20
20
|
header?: React.Element<any>,
|
|
21
21
|
/** Optional function to get the scrollRef in parent components */
|
|
22
22
|
scrollRefFn?: any => any,
|
|
23
|
+
/** Are OverlayHeader actions enabled */
|
|
24
|
+
isOverlayHeaderActionEnabled?: boolean,
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
class HeaderFlyout extends React.Component<Props> {
|
|
@@ -30,7 +32,16 @@ class HeaderFlyout extends React.Component<Props> {
|
|
|
30
32
|
};
|
|
31
33
|
|
|
32
34
|
render() {
|
|
33
|
-
const {
|
|
35
|
+
const {
|
|
36
|
+
header,
|
|
37
|
+
footer,
|
|
38
|
+
flyoutButton,
|
|
39
|
+
children,
|
|
40
|
+
scrollRefFn,
|
|
41
|
+
className,
|
|
42
|
+
isOverlayHeaderActionEnabled = false,
|
|
43
|
+
...rest
|
|
44
|
+
} = this.props;
|
|
34
45
|
|
|
35
46
|
return (
|
|
36
47
|
<Flyout
|
|
@@ -42,7 +53,9 @@ class HeaderFlyout extends React.Component<Props> {
|
|
|
42
53
|
>
|
|
43
54
|
{flyoutButton}
|
|
44
55
|
<Overlay className="header-flyout-overlay">
|
|
45
|
-
<OverlayHeader
|
|
56
|
+
<OverlayHeader isOverlayHeaderActionEnabled={isOverlayHeaderActionEnabled}>
|
|
57
|
+
{header && <h4 className="header-flyout-title">{header}</h4>}
|
|
58
|
+
</OverlayHeader>
|
|
46
59
|
<div className="header-flyout-list-container">
|
|
47
60
|
<div
|
|
48
61
|
className={classNames('flyout-list-container-body', {
|
|
@@ -21,7 +21,9 @@ exports[`components/core/header/components/HeaderFlyout render() should include
|
|
|
21
21
|
<Overlay
|
|
22
22
|
className="header-flyout-overlay"
|
|
23
23
|
>
|
|
24
|
-
<OverlayHeader
|
|
24
|
+
<OverlayHeader
|
|
25
|
+
isOverlayHeaderActionEnabled={false}
|
|
26
|
+
>
|
|
25
27
|
<h4
|
|
26
28
|
className="header-flyout-title"
|
|
27
29
|
>
|
|
@@ -78,7 +80,9 @@ exports[`components/core/header/components/HeaderFlyout render() should render d
|
|
|
78
80
|
<Overlay
|
|
79
81
|
className="header-flyout-overlay"
|
|
80
82
|
>
|
|
81
|
-
<OverlayHeader
|
|
83
|
+
<OverlayHeader
|
|
84
|
+
isOverlayHeaderActionEnabled={false}
|
|
85
|
+
/>
|
|
82
86
|
<div
|
|
83
87
|
className="header-flyout-list-container"
|
|
84
88
|
>
|
|
@@ -123,7 +127,9 @@ exports[`components/core/header/components/HeaderFlyout render() should render t
|
|
|
123
127
|
<Overlay
|
|
124
128
|
className="header-flyout-overlay"
|
|
125
129
|
>
|
|
126
|
-
<OverlayHeader
|
|
130
|
+
<OverlayHeader
|
|
131
|
+
isOverlayHeaderActionEnabled={false}
|
|
132
|
+
/>
|
|
127
133
|
<div
|
|
128
134
|
className="header-flyout-list-container"
|
|
129
135
|
>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`elements/content-sidebar/SidebarToggle should render and handle clicks correctly when isOpen is false 1`] = `
|
|
4
|
-
<SidebarToggleButton
|
|
5
|
-
data-resin-target="sidebartoggle"
|
|
6
|
-
data-testid="sidebartoggle"
|
|
7
|
-
isOpen={false}
|
|
8
|
-
onClick={[Function]}
|
|
9
|
-
/>
|
|
10
|
-
`;
|
|
11
|
-
|
|
12
|
-
exports[`elements/content-sidebar/SidebarToggle should render and handle clicks correctly when isOpen is true 1`] = `
|
|
13
|
-
<SidebarToggleButton
|
|
14
|
-
data-resin-target="sidebartoggle"
|
|
15
|
-
data-testid="sidebartoggle"
|
|
16
|
-
isOpen={true}
|
|
17
|
-
onClick={[Function]}
|
|
18
|
-
/>
|
|
19
|
-
`;
|