From 928e2ccc98844ea3aabd414fbdda1aabf582b8cd Mon Sep 17 00:00:00 2001
From: tjuanitas <7311041+tjuanitas@users.noreply.github.com>
Date: Tue, 3 Sep 2024 12:42:51 -0700
Subject: [PATCH 1/3] fix: resolve ItemAction issues
---
i18n/en-US.properties | 8 +-
src/elements/common/messages.js | 5 ++
.../content-uploader/IconInProgress.js | 18 -----
.../content-uploader/IconInProgress.tsx | 19 +++++
src/elements/content-uploader/ItemAction.scss | 23 +++---
src/elements/content-uploader/ItemAction.tsx | 74 +++++++++----------
src/elements/content-uploader/ItemList.tsx | 7 +-
src/elements/content-uploader/ItemProgress.js | 21 ------
.../content-uploader/ItemProgress.scss | 4 +-
.../content-uploader/ItemProgress.tsx | 16 ++++
src/elements/content-uploader/ItemRemove.tsx | 16 ++--
src/elements/content-uploader/ProgressBar.tsx | 8 +-
.../content-uploader/UploadsManager.scss | 4 +-
13 files changed, 103 insertions(+), 120 deletions(-)
delete mode 100644 src/elements/content-uploader/IconInProgress.js
create mode 100644 src/elements/content-uploader/IconInProgress.tsx
delete mode 100644 src/elements/content-uploader/ItemProgress.js
create mode 100644 src/elements/content-uploader/ItemProgress.tsx
diff --git a/i18n/en-US.properties b/i18n/en-US.properties
index a7fad33ac9..17284b7bce 100644
--- a/i18n/en-US.properties
+++ b/i18n/en-US.properties
@@ -34,12 +34,6 @@ be.activitySidebarFilter.status.tasks = Tasks
be.add = Add
# Text to display when app is disabled by applied access policy
be.additionalTab.blockedByShieldAccessPolicy = Use of this app is blocked due to a security policy.
-# Error message when an annotation deletion fails
-be.annotationThread.errorDeleteAnnotation = There was an error deleting this item.
-# Error message when an annotation update fails
-be.annotationThread.errorEditAnnotation = This annotation could not be modified.
-# Error message when an annotation fetch fails
-be.annotattionThread.errorFetchAnnotation = The annotation could not be fetched.
# Error message when an app activity deletion fails
be.api.appActivityDeleteErrorMessage = There was an error deleting this item.
# Error message when a comment creation fails due to a conflict
@@ -92,6 +86,8 @@ be.close = Close
be.collaboratedFolder = Collaborated Folder
# Message to the user to collapse the Transcript entries
be.collapse = Collapse
+# Label for complete state.
+be.complete = Complete
# Text shown to users when opening the content insights flyout and there is an error
be.contentInsights.contentAnalyticsErrorText = There was a problem loading content insights. Please try again.
# Message shown when the user does not have access to view content insights anymore
diff --git a/src/elements/common/messages.js b/src/elements/common/messages.js
index 0a3821b351..1da503ab4b 100644
--- a/src/elements/common/messages.js
+++ b/src/elements/common/messages.js
@@ -52,6 +52,11 @@ const messages = defineMessages({
description: 'Message when new preview is available.',
defaultMessage: 'A new version of this file is available.',
},
+ complete: {
+ id: 'be.complete',
+ description: 'Label for complete state.',
+ defaultMessage: 'Complete',
+ },
loading: {
id: 'be.loading',
description: 'Label for loading state.',
diff --git a/src/elements/content-uploader/IconInProgress.js b/src/elements/content-uploader/IconInProgress.js
deleted file mode 100644
index a10a69a0e6..0000000000
--- a/src/elements/content-uploader/IconInProgress.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * @flow
- * @file Icon
- * @author Box
- */
-
-import * as React from 'react';
-import LoadingIndicator from '../../components/loading-indicator/LoadingIndicator';
-import IconClose from '../../icons/general/IconClose';
-
-const IconInProgress = () => (
-
-
-
-
-);
-
-export default IconInProgress;
diff --git a/src/elements/content-uploader/IconInProgress.tsx b/src/elements/content-uploader/IconInProgress.tsx
new file mode 100644
index 0000000000..82df749b8e
--- /dev/null
+++ b/src/elements/content-uploader/IconInProgress.tsx
@@ -0,0 +1,19 @@
+import * as React from 'react';
+import { useIntl } from 'react-intl';
+import { LoadingIndicator } from '@box/blueprint-web';
+import { IconCtaIconHover, Size5 } from '@box/blueprint-web-assets/tokens/tokens';
+import { XMark } from '@box/blueprint-web-assets/icons/Fill';
+import messages from '../common/messages';
+
+const IconInProgress = () => {
+ const { formatMessage } = useIntl();
+
+ return (
+
+
+
+
+ );
+};
+
+export default IconInProgress;
diff --git a/src/elements/content-uploader/ItemAction.scss b/src/elements/content-uploader/ItemAction.scss
index c8a9ffc9aa..d538776327 100644
--- a/src/elements/content-uploader/ItemAction.scss
+++ b/src/elements/content-uploader/ItemAction.scss
@@ -1,23 +1,20 @@
.bcu-item-action {
- .crawler {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .bcu-ItemAction-loading,
+ .bcu-IconInProgress-loading {
+ position: relative; // Override default Blueprint position: `absolute`
}
button {
- display: flex;
-
// Vertically center icon
svg {
display: block;
}
- .be-icon-in-progress {
- width: 24px;
- height: 24px;
-
+ .bcu-IconInProgress {
// Hide cross icon without hover
svg {
display: none;
@@ -25,12 +22,12 @@
}
// Display cross icon on hover and hide loading indicator
- &:hover .be-icon-in-progress {
+ &:hover .bcu-IconInProgress {
svg {
display: block;
}
- .crawler {
+ .bcu-IconInProgress-loading {
display: none;
}
}
diff --git a/src/elements/content-uploader/ItemAction.tsx b/src/elements/content-uploader/ItemAction.tsx
index 1479867984..40537cc85a 100644
--- a/src/elements/content-uploader/ItemAction.tsx
+++ b/src/elements/content-uploader/ItemAction.tsx
@@ -2,17 +2,17 @@ import * as React from 'react';
import { useIntl } from 'react-intl';
import { AxiosError } from 'axios';
import { Button, IconButton, LoadingIndicator, Tooltip } from '@box/blueprint-web';
-import { ArrowCurveForward, Checkmark } from '@box/blueprint-web-assets/icons/Line';
-import { EllipsisBadge, XMark } from '@box/blueprint-web-assets/icons/Fill';
+import { ArrowCurveForward, Checkmark, XMark } from '@box/blueprint-web-assets/icons/Fill';
import { Size5, SurfaceStatusSurfaceSuccess } from '@box/blueprint-web-assets/tokens/tokens';
+import IconInProgress from './IconInProgress';
import {
ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED,
- STATUS_PENDING,
- STATUS_IN_PROGRESS,
- STATUS_STAGED,
STATUS_COMPLETE,
STATUS_ERROR,
+ STATUS_IN_PROGRESS,
+ STATUS_PENDING,
+ STATUS_STAGED,
} from '../../constants';
import messages from '../common/messages';
@@ -30,29 +30,6 @@ export interface ItemActionProps {
status: UploadStatus;
}
-const getIconWithTooltip = (
- icon: React.ReactNode,
- isDisabled: boolean,
- isLoading: boolean,
- onClick: React.MouseEventHandler,
- tooltip: boolean,
- tooltipText: string,
-) => {
- if (isLoading) {
- return ;
- }
-
- if (tooltip) {
- return (
-
- icon} />
-
- );
- }
-
- return <>{icon}>;
-};
-
const ItemAction = ({
error,
isFolder = false,
@@ -61,12 +38,11 @@ const ItemAction = ({
onUpgradeCTAClick,
status,
}: ItemActionProps) => {
- const intl = useIntl();
- let icon: React.ReactNode = ;
- let tooltip;
- let isLoading = false;
+ const { formatMessage } = useIntl();
const { code } = error || {};
- const { formatMessage } = intl;
+
+ let Icon = XMark;
+ let tooltip;
if (isFolder && status !== STATUS_PENDING) {
return null;
@@ -74,28 +50,39 @@ const ItemAction = ({
switch (status) {
case STATUS_COMPLETE:
- icon = ;
+ Icon = () => (
+
+ );
if (!isResumableUploadsEnabled) {
tooltip = messages.remove;
}
break;
case STATUS_ERROR:
- icon = ;
+ Icon = ArrowCurveForward;
tooltip = isResumableUploadsEnabled ? messages.resume : messages.retry;
break;
case STATUS_IN_PROGRESS:
case STATUS_STAGED:
if (isResumableUploadsEnabled) {
- isLoading = true;
+ Icon = () => (
+
+ );
} else {
- icon = ;
+ Icon = IconInProgress;
tooltip = messages.uploadsCancelButtonTooltip;
}
break;
case STATUS_PENDING:
default:
if (isResumableUploadsEnabled) {
- isLoading = true;
+ Icon = () => (
+
+ );
} else {
tooltip = messages.uploadsCancelButtonTooltip;
}
@@ -109,16 +96,23 @@ const ItemAction = ({
data-resin-target="large_version_error_inline_upgrade_cta"
variant="primary"
>
- {intl.formatMessage(messages.uploadsFileSizeLimitExceededUpgradeMessageForUpgradeCta)}
+ {formatMessage(messages.uploadsFileSizeLimitExceededUpgradeMessageForUpgradeCta)}
);
}
+
const isDisabled = status === STATUS_STAGED;
const tooltipText = tooltip && formatMessage(tooltip);
return (
- {getIconWithTooltip(icon, isDisabled, isLoading, onClick, tooltip, tooltipText)}
+ {tooltip ? (
+
+
+
+ ) : (
+
+ )}
);
};
diff --git a/src/elements/content-uploader/ItemList.tsx b/src/elements/content-uploader/ItemList.tsx
index b81c0a0a36..f6d9eb7191 100644
--- a/src/elements/content-uploader/ItemList.tsx
+++ b/src/elements/content-uploader/ItemList.tsx
@@ -13,6 +13,8 @@ import type { UploadItem } from '../../common/types/upload';
import '@box/react-virtualized/styles.css';
import './ItemList.scss';
+const ACTION_CELL_WIDTH = 32;
+
export interface ItemListProps {
isResumableUploadsEnabled?: boolean;
items: UploadItem[];
@@ -38,7 +40,6 @@ const ItemList = ({
const progressCell = progressCellRenderer(!!onUpgradeCTAClick);
const actionCell = actionCellRenderer(isResumableUploadsEnabled, onClick, onUpgradeCTAClick);
const removeCell = removeCellRenderer(onRemoveClick);
- const baseIconWidth = 32;
return (
{isResumableUploadsEnabled && (
)}
diff --git a/src/elements/content-uploader/ItemProgress.js b/src/elements/content-uploader/ItemProgress.js
deleted file mode 100644
index e070def5c5..0000000000
--- a/src/elements/content-uploader/ItemProgress.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * @flow
- * @file Upload item progress component
- */
-
-import * as React from 'react';
-import ProgressBar from './ProgressBar';
-import './ItemProgress.scss';
-
-type Props = {
- progress: number,
-};
-
-const ItemProgress = ({ progress }: Props) => (
-
-);
-
-export default ItemProgress;
diff --git a/src/elements/content-uploader/ItemProgress.scss b/src/elements/content-uploader/ItemProgress.scss
index 6b22b04bc4..da3f4cff5f 100644
--- a/src/elements/content-uploader/ItemProgress.scss
+++ b/src/elements/content-uploader/ItemProgress.scss
@@ -1,8 +1,8 @@
-.bcu-item-progress {
+.bcu-ItemProgress {
display: flex;
align-items: center;
}
-.bcu-progress-label {
+.bcu-ItemProgress-label {
min-width: 35px; // 100% takes up 34.27px
}
diff --git a/src/elements/content-uploader/ItemProgress.tsx b/src/elements/content-uploader/ItemProgress.tsx
new file mode 100644
index 0000000000..d22f6ebaba
--- /dev/null
+++ b/src/elements/content-uploader/ItemProgress.tsx
@@ -0,0 +1,16 @@
+import * as React from 'react';
+import ProgressBar from './ProgressBar';
+import './ItemProgress.scss';
+
+export interface ItemProgressProps {
+ progress: number;
+}
+
+const ItemProgress = ({ progress }: ItemProgressProps) => (
+
+);
+
+export default ItemProgress;
diff --git a/src/elements/content-uploader/ItemRemove.tsx b/src/elements/content-uploader/ItemRemove.tsx
index 42264aa75f..65e235f68f 100644
--- a/src/elements/content-uploader/ItemRemove.tsx
+++ b/src/elements/content-uploader/ItemRemove.tsx
@@ -1,7 +1,6 @@
import * as React from 'react';
import { useIntl } from 'react-intl';
import { IconButton, Tooltip } from '@box/blueprint-web';
-import { GrayBlack, Size5 } from '@box/blueprint-web-assets/tokens/tokens';
import { XMark } from '@box/blueprint-web-assets/icons/Fill';
import type { UploadItem, UploadStatus } from '../../common/types/upload';
@@ -16,6 +15,8 @@ export interface ItemRemoveProps {
}
const ItemRemove = ({ onClick, status }: ItemRemoveProps) => {
+ const { formatMessage } = useIntl();
+
const resin: Record = {};
let target = null;
@@ -29,20 +30,13 @@ const ItemRemove = ({ onClick, status }: ItemRemoveProps) => {
resin['data-resin-target'] = target;
}
- const intl = useIntl();
const isDisabled = status === STATUS_STAGED;
- const tooltipText = intl.formatMessage(messages.remove);
+ const tooltipText = formatMessage(messages.remove);
return (
-
- }
- {...resin}
- />
+
+
);
diff --git a/src/elements/content-uploader/ProgressBar.tsx b/src/elements/content-uploader/ProgressBar.tsx
index 58b20aa049..ac3d333009 100644
--- a/src/elements/content-uploader/ProgressBar.tsx
+++ b/src/elements/content-uploader/ProgressBar.tsx
@@ -1,12 +1,12 @@
import * as React from 'react';
import './ProgressBar.scss';
-type Props = {
+export interface ProgressBarProps {
percent?: number;
-};
+}
-const ProgressBar = ({ percent }: Props) => {
- const clampedPercentage = Math.max(0, Math.min(100, percent || 0));
+const ProgressBar = ({ percent = 0 }: ProgressBarProps) => {
+ const clampedPercentage = Math.max(0, Math.min(100, percent));
const containerStyle = {
transitionDelay: clampedPercentage > 0 && clampedPercentage < 100 ? '0' : '0.4s',
diff --git a/src/elements/content-uploader/UploadsManager.scss b/src/elements/content-uploader/UploadsManager.scss
index e02b3c0d98..962a82e055 100644
--- a/src/elements/content-uploader/UploadsManager.scss
+++ b/src/elements/content-uploader/UploadsManager.scss
@@ -11,12 +11,12 @@
margin-right: 0;
}
- .bcu-item-progress {
+ .bcu-ItemProgress {
.bcu-progress-container {
display: none;
}
- .bcu-progress-label {
+ .bcu-ItemProgress-label {
margin-left: auto;
}
}
From 3868277ad8799409fcc85acdaae56ffb46df4caa Mon Sep 17 00:00:00 2001
From: tjuanitas <7311041+tjuanitas@users.noreply.github.com>
Date: Wed, 4 Sep 2024 11:58:21 -0700
Subject: [PATCH 2/3] fix: unit tests
---
i18n/en-US.properties | 6 +
src/elements/content-uploader/ItemAction.tsx | 2 +-
.../__tests__/ItemAction.test.tsx | 132 +++++++-----------
.../__tests__/ItemList.test.js | 58 --------
4 files changed, 55 insertions(+), 143 deletions(-)
delete mode 100644 src/elements/content-uploader/__tests__/ItemList.test.js
diff --git a/i18n/en-US.properties b/i18n/en-US.properties
index 17284b7bce..368753a74f 100644
--- a/i18n/en-US.properties
+++ b/i18n/en-US.properties
@@ -34,6 +34,12 @@ be.activitySidebarFilter.status.tasks = Tasks
be.add = Add
# Text to display when app is disabled by applied access policy
be.additionalTab.blockedByShieldAccessPolicy = Use of this app is blocked due to a security policy.
+# Error message when an annotation deletion fails
+be.annotationThread.errorDeleteAnnotation = There was an error deleting this item.
+# Error message when an annotation update fails
+be.annotationThread.errorEditAnnotation = This annotation could not be modified.
+# Error message when an annotation fetch fails
+be.annotattionThread.errorFetchAnnotation = The annotation could not be fetched.
# Error message when an app activity deletion fails
be.api.appActivityDeleteErrorMessage = There was an error deleting this item.
# Error message when a comment creation fails due to a conflict
diff --git a/src/elements/content-uploader/ItemAction.tsx b/src/elements/content-uploader/ItemAction.tsx
index 40537cc85a..d89f3a307e 100644
--- a/src/elements/content-uploader/ItemAction.tsx
+++ b/src/elements/content-uploader/ItemAction.tsx
@@ -22,7 +22,7 @@ import type { UploadStatus } from '../../common/types/upload';
import './ItemAction.scss';
export interface ItemActionProps {
- error?: AxiosError;
+ error?: Partial;
isFolder?: boolean;
isResumableUploadsEnabled: boolean;
onClick: React.MouseEventHandler;
diff --git a/src/elements/content-uploader/__tests__/ItemAction.test.tsx b/src/elements/content-uploader/__tests__/ItemAction.test.tsx
index 92a5812355..1661f1a145 100644
--- a/src/elements/content-uploader/__tests__/ItemAction.test.tsx
+++ b/src/elements/content-uploader/__tests__/ItemAction.test.tsx
@@ -1,106 +1,70 @@
import * as React from 'react';
-import { AxiosError } from 'axios';
import { render, screen } from '../../../test-utils/testing-library';
-import ItemAction, { ItemActionProps } from '../ItemAction';
-import {
- ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED,
- STATUS_PENDING,
- STATUS_IN_PROGRESS,
- STATUS_COMPLETE,
- STATUS_STAGED,
- STATUS_ERROR,
-} from '../../../constants';
+import ItemAction from '../ItemAction';
describe('elements/content-uploader/ItemAction', () => {
- const defaultError: AxiosError = {
- code: '',
- config: undefined,
- isAxiosError: false,
- toJSON: jest.fn(),
- name: '',
- message: '',
+ const renderComponent = (props = {}) => {
+ const defaultProps = {
+ isResumableUploadsEnabled: false,
+ onClick: jest.fn(),
+ status: 'pending',
+ };
+ return render();
};
- const defaultProps: ItemActionProps = {
- isResumableUploadsEnabled: false,
- onClick: jest.fn(),
- status: STATUS_PENDING,
- error: defaultError,
- isFolder: false,
- onUpgradeCTAClick: jest.fn(),
- };
-
- const renderComponent = (props: Partial) => render();
-
test.each`
- status
- ${STATUS_COMPLETE}
- ${STATUS_IN_PROGRESS}
- ${STATUS_STAGED}
- ${STATUS_ERROR}
- ${STATUS_PENDING}
- `('should render correctly with $status', ({ status }: Pick) => {
- renderComponent({ status });
- expect(screen.getByRole('button')).toBeInTheDocument();
+ status | label
+ ${'complete'} | ${'Remove'}
+ ${'error'} | ${'Retry'}
+ ${'inprogress'} | ${'Cancel this upload'}
+ ${'pending'} | ${'Cancel this upload'}
+ ${'staged'} | ${'Cancel this upload'}
+ ${'unknown'} | ${'Cancel this upload'}
+ `('renders icon button when status is `$status` and resumable uploads is disabled', ({ label, status }) => {
+ renderComponent({ isResumableUploadsEnabled: false, status });
+ expect(screen.getByRole('button', { name: label })).toBeInTheDocument();
});
- test.each`
- status | label
- ${STATUS_COMPLETE} | ${'complete'}
- ${STATUS_ERROR} | ${'error'}
- `(
- 'should render correctly with $status and resumable uploads enabled',
- ({ status, label }: Pick & { label: string }) => {
- renderComponent({ status, isResumableUploadsEnabled: true });
- expect(screen.getByRole('img', { name: label })).toBeInTheDocument();
+ test.each(['inprogress', 'pending', 'staged', 'unknown'])(
+ 'renders loading indicator when status is `%s` and resumable uploads is enabled',
+ status => {
+ renderComponent({ isResumableUploadsEnabled: true, status });
+ expect(screen.queryByRole('button')).not.toBeInTheDocument();
+ expect(screen.getByRole('status', { name: 'Loading' })).toBeInTheDocument();
},
);
- test.each`
- status
- ${STATUS_IN_PROGRESS}
- ${STATUS_PENDING}
- ${STATUS_STAGED}
- `(
- 'should render correctly with $status and resumable uploads enabled',
- ({ status }: Pick) => {
- renderComponent({ status, isResumableUploadsEnabled: true });
- expect(screen.getByRole('status', { name: 'loading' })).toBeInTheDocument();
- },
- );
+ test('renders correctly when status is `complete` and resumable uploads is enabled', () => {
+ renderComponent({ isResumableUploadsEnabled: true, status: 'complete' });
+ expect(screen.queryByRole('button')).not.toBeInTheDocument();
+ expect(screen.getByRole('img', { name: 'Complete' })).toBeInTheDocument();
+ });
- test.each`
- status | label
- ${STATUS_IN_PROGRESS} | ${'staged'}
- ${STATUS_STAGED} | ${'staged'}
- `(
- 'should render correctly with $status and resumable uploads disabled',
- ({ status, label }: Pick & { label: string }) => {
- renderComponent({ status, isResumableUploadsEnabled: false });
- expect(screen.getByRole('img', { name: label })).toBeInTheDocument();
+ test('renders correctly when status is `error` and resumable uploads is enabled', () => {
+ renderComponent({ isResumableUploadsEnabled: true, status: 'error' });
+ expect(screen.getByRole('button', { name: 'Resume' })).toBeInTheDocument();
+ });
+
+ test.each(['complete', 'error', 'inprogress', 'staged', 'unknown'])(
+ 'renders an empty component when item is folder and status is `%s`',
+ status => {
+ const { container } = renderComponent({ isFolder: true, status });
+ expect(container).toBeEmptyDOMElement();
},
);
- test('should render correctly with STATUS_PENDING and resumable uploads disabled', () => {
- renderComponent({ status: STATUS_PENDING, isResumableUploadsEnabled: false });
- expect(screen.getByRole('button', { name: 'Cancel this upload' })).toBeInTheDocument();
+ test('does not render an empty component when item is folder and status is `pending`', () => {
+ const { container } = renderComponent({ isFolder: true, status: 'pending' });
+ expect(container).not.toBeEmptyDOMElement();
});
- test('should render correctly with STATUS_ERROR and item is folder', () => {
- renderComponent({ status: STATUS_ERROR, isFolder: true });
- expect(screen.queryByRole('button')).not.toBeInTheDocument();
+ test('renders CTA button when status is `error` and code is `file_size_limit_exceeded`', () => {
+ renderComponent({ error: { code: 'file_size_limit_exceeded' }, onUpgradeCTAClick: jest.fn(), status: 'error' });
+ expect(screen.getByRole('button', { name: 'Upgrade' })).toBeInTheDocument();
});
- test('should render CTA button to upgrade when upload file size exceeded error is received', () => {
- renderComponent({
- status: STATUS_ERROR,
- error: { ...defaultError, code: ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED },
- onUpgradeCTAClick: jest.fn(),
- });
- expect(
- screen.getByRole('button', {
- name: 'Upgrade',
- }),
- ).toBeInTheDocument();
+ test('does not render CTA button when status is `error` and code is not `file_size_limit_exceeded`', () => {
+ renderComponent({ error: { code: 'unknown' }, onUpgradeCTAClick: jest.fn(), status: 'error' });
+ expect(screen.queryByRole('button', { name: 'Upgrade' })).not.toBeInTheDocument();
});
});
diff --git a/src/elements/content-uploader/__tests__/ItemList.test.js b/src/elements/content-uploader/__tests__/ItemList.test.js
deleted file mode 100644
index 67a39b8ebf..0000000000
--- a/src/elements/content-uploader/__tests__/ItemList.test.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import * as React from 'react';
-import { mount } from 'enzyme';
-// TODO Providers can be removed when converted to RTL - providers are included in the testing utility library
-import { IntlProvider } from 'react-intl';
-import { TooltipProvider } from '@box/blueprint-web';
-
-import ItemList from '../ItemList';
-import { ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED, STATUS_COMPLETE, STATUS_ERROR } from '../../../constants';
-
-jest.unmock('react-intl'); // TODO can be removed when converted to RTL
-jest.mock(
- '@box/react-virtualized/dist/es/AutoSizer',
- () =>
- ({ children }) =>
- children({ height: 600, width: 600 }),
-);
-
-describe('elements/content-uploader/ItemList', () => {
- const renderComponent = props =>
- mount(
-
-
- {}} {...props} />
-
- ,
- );
-
- describe('render()', () => {
- test('should render default component', () => {
- const wrapper = renderComponent();
-
- expect(wrapper.find('Table').length).toBe(1);
- expect(wrapper.find('Table.bcu-item-list').length).toBe(1);
- });
-
- test('should render component with correct number of items', () => {
- const items = [
- { id: '1', name: 'item1', status: STATUS_COMPLETE },
- { id: '2', name: 'item2', status: STATUS_COMPLETE },
- { id: '3', name: 'item3', status: STATUS_COMPLETE },
- ];
- const wrapper = renderComponent({ items });
- expect(wrapper.find('div.bcu-item-row').length).toBe(3);
- const actionColumnStyle = wrapper.find('.bcu-item-list-action-column').first().prop('style');
- expect(actionColumnStyle.flex).toEqual('0 0 32px');
- });
-
- test('should render action column with correct width for upgrade cta', () => {
- const items = [
- { id: '1', name: 'item1', status: STATUS_ERROR, code: ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED },
- ];
- const wrapper = renderComponent({ items, onUpgradeCTAClick: () => {} });
- expect(wrapper.find('div.bcu-item-row').length).toBe(1);
- const actionColumnStyle = wrapper.find('.bcu-item-list-action-column').prop('style');
- expect(actionColumnStyle.flex).toEqual('0 0 100px');
- });
- });
-});
From 9369d134e2df637640f2f6a32143ee70ae26b337 Mon Sep 17 00:00:00 2001
From: tjuanitas <7311041+tjuanitas@users.noreply.github.com>
Date: Wed, 4 Sep 2024 14:10:37 -0700
Subject: [PATCH 3/3] fix: simplify loading indicator
---
src/elements/content-uploader/ItemAction.tsx | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/elements/content-uploader/ItemAction.tsx b/src/elements/content-uploader/ItemAction.tsx
index d89f3a307e..8e61e14ce7 100644
--- a/src/elements/content-uploader/ItemAction.tsx
+++ b/src/elements/content-uploader/ItemAction.tsx
@@ -41,6 +41,10 @@ const ItemAction = ({
const { formatMessage } = useIntl();
const { code } = error || {};
+ const LoadingIndicatorIcon = () => (
+
+ );
+
let Icon = XMark;
let tooltip;
@@ -69,9 +73,7 @@ const ItemAction = ({
case STATUS_IN_PROGRESS:
case STATUS_STAGED:
if (isResumableUploadsEnabled) {
- Icon = () => (
-
- );
+ Icon = LoadingIndicatorIcon;
} else {
Icon = IconInProgress;
tooltip = messages.uploadsCancelButtonTooltip;
@@ -80,9 +82,7 @@ const ItemAction = ({
case STATUS_PENDING:
default:
if (isResumableUploadsEnabled) {
- Icon = () => (
-
- );
+ Icon = LoadingIndicatorIcon;
} else {
tooltip = messages.uploadsCancelButtonTooltip;
}