Skip to content

Commit

Permalink
chore(content-uploader): Migrated ItemAction
Browse files Browse the repository at this point in the history
  • Loading branch information
greg-in-a-box committed Aug 2, 2024
1 parent 219300f commit 34feaea
Show file tree
Hide file tree
Showing 8 changed files with 297 additions and 393 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
/**
* @flow
* @file Item action component displayed on the upload toast, e.g. cancel/resume
*/

import * as React from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
import { injectIntl } from 'react-intl';
import type { IntlShape } from 'react-intl';
import IconCheck from '../../icons/general/IconCheck';
import IconClose from '../../icons/general/IconClose';
import IconInProgress from './IconInProgress';
import IconRetry from '../../icons/general/IconRetry';
import LoadingIndicator from '../../components/loading-indicator';
import PlainButton from '../../components/plain-button/PlainButton';
import PrimaryButton from '../../components/primary-button/PrimaryButton';
import Tooltip from '../../components/tooltip';
import messages from '../common/messages';
import { Button, IconButton, LoadingIndicator } 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 Tooltip, { TooltipPosition } from '../../components/tooltip';
import {
ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED,
STATUS_PENDING,
Expand All @@ -23,34 +14,60 @@ import {
STATUS_COMPLETE,
STATUS_ERROR,
} from '../../constants';

import messages from '../common/messages';

import type { UploadStatus } from '../../common/types/upload';

import './ItemAction.scss';
import { Size5, SurfaceStatusSurfaceSuccess } from '@box/blueprint-web-assets/tokens/tokens';

const ICON_CHECK_COLOR = '#26C281';

type Props = {
error?: Object,
type ItemActionProps = {
error?: any,
intl: IntlShape,
isFolder?: boolean,
isResumableUploadsEnabled: boolean,
onClick: Function,
onUpgradeCTAClick?: Function,
onClick: any,
onUpgradeCTAClick?: any,
status: UploadStatus,
};

const getIconWithTooltip = (
icon: React.ReactNode,
isDisabled: boolean,
isLoading: boolean,
onClick: any,
tooltip: boolean,
tooltipText: string,
) => {
if (isLoading) {
return <LoadingIndicator aria-label="loading" />;
}

if (tooltip) {
return (
<Tooltip position={TooltipPosition.TOP_LEFT} text={tooltipText}>
<IconButton aria-label={tooltipText} disabled={isDisabled} onClick={onClick} icon={() => icon} />
</Tooltip>
);
}

return <>{icon}</>;
};

const ItemAction = ({
error = {},
error,
intl,
isFolder = false,
isResumableUploadsEnabled,
onClick,
onUpgradeCTAClick,
status,
}: Props) => {
let icon = <IconClose />;
}: ItemActionProps) => {
let icon: React.ReactNode = <XMark color="black" height={Size5} width={Size5} />;
let tooltip;
const { code } = error;
let isLoading = false;
const { code } = error || {};
const { formatMessage } = intl;

if (isFolder && status !== STATUS_PENDING) {
Expand All @@ -59,28 +76,28 @@ const ItemAction = ({

switch (status) {
case STATUS_COMPLETE:
icon = <IconCheck color={ICON_CHECK_COLOR} />;
icon = <Checkmark aria-label="complete" color={SurfaceStatusSurfaceSuccess} height={Size5} width={Size5} />;
if (!isResumableUploadsEnabled) {
tooltip = messages.remove;
}
break;
case STATUS_ERROR:
icon = <IconRetry height={24} width={24} />;
icon = <ArrowCurveForward aria-label="error" color="black" height={Size5} width={Size5} />;
tooltip = isResumableUploadsEnabled ? messages.resume : messages.retry;
break;
case STATUS_IN_PROGRESS:
case STATUS_STAGED:
if (isResumableUploadsEnabled) {
icon = <LoadingIndicator />;
isLoading = true;
} else {
icon = <IconInProgress />;
icon = <EllipsisBadge aria-label="staged" color="black" height={Size5} width={Size5} />;
tooltip = messages.uploadsCancelButtonTooltip;
}
break;
case STATUS_PENDING:
default:
if (isResumableUploadsEnabled) {
icon = <LoadingIndicator />;
isLoading = true;
} else {
tooltip = messages.uploadsCancelButtonTooltip;
}
Expand All @@ -89,32 +106,23 @@ const ItemAction = ({

if (status === STATUS_ERROR && code === ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED && !!onUpgradeCTAClick) {
return (
<PrimaryButton
<Button
onClick={onUpgradeCTAClick}
data-resin-target="large_version_error_inline_upgrade_cta"
type="button"
variant="primary"
>
<FormattedMessage {...messages.uploadsFileSizeLimitExceededUpgradeMessageForUpgradeCta} />
</PrimaryButton>
{intl.formatMessage(messages.uploadsFileSizeLimitExceededUpgradeMessageForUpgradeCta)}
</Button>
);
}
const isDisabled = status === STATUS_STAGED;
const tooltipText = tooltip && formatMessage(tooltip);

return (
<div className="bcu-item-action">
{tooltip ? (
<Tooltip position="top-left" text={tooltipText}>
<PlainButton aria-label={tooltipText} isDisabled={isDisabled} onClick={onClick} type="button">
{icon}
</PlainButton>
</Tooltip>
) : (
icon
)}
{getIconWithTooltip(icon, isDisabled, isLoading, onClick, tooltip, tooltipText)}
</div>
);
};

export { ItemAction as ItemActionForTesting };
export default injectIntl(ItemAction);
3 changes: 0 additions & 3 deletions src/elements/content-uploader/ItemAction.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
.bcu-item-action {
width: 24px;
height: 24px;

.crawler {
display: flex;
align-items: center;
Expand Down
129 changes: 129 additions & 0 deletions src/elements/content-uploader/ItemAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import * as React from 'react';
import { injectIntl } from 'react-intl';
import type { IntlShape } from 'react-intl';
import { Button, IconButton, LoadingIndicator } 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 { AxiosError } from 'axios';
import { Size5, SurfaceStatusSurfaceSuccess } from '@box/blueprint-web-assets/tokens/tokens';
import Tooltip, { TooltipPosition } from '../../components/tooltip';
import {
ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED,
STATUS_PENDING,
STATUS_IN_PROGRESS,
STATUS_STAGED,
STATUS_COMPLETE,
STATUS_ERROR,
} from '../../constants';

import messages from '../common/messages';

import type { UploadStatus } from '../../common/types/upload';

import './ItemAction.scss';

export interface ItemActionProps {
error?: AxiosError;
intl: IntlShape;
isFolder?: boolean;
isResumableUploadsEnabled: boolean;
onClick: React.MouseEventHandler<HTMLButtonElement>;
onUpgradeCTAClick?: () => void;
status: UploadStatus;
}

const getIconWithTooltip = (
icon: React.ReactNode,
isDisabled: boolean,
isLoading: boolean,
onClick: React.MouseEventHandler<HTMLButtonElement>,
tooltip: boolean,
tooltipText: string,
) => {
if (isLoading) {
return <LoadingIndicator aria-label="loading" />;
}

if (tooltip) {
return (
<Tooltip position={TooltipPosition.TOP_LEFT} text={tooltipText}>
<IconButton aria-label={tooltipText} disabled={isDisabled} onClick={onClick} icon={() => icon} />
</Tooltip>
);
}

return <>{icon}</>;
};

const ItemAction = ({
error,
intl,
isFolder = false,
isResumableUploadsEnabled,
onClick,
onUpgradeCTAClick,
status,
}: ItemActionProps) => {
let icon: React.ReactNode = <XMark color="black" height={Size5} width={Size5} />;
let tooltip;
let isLoading = false;
const { code } = error || {};
const { formatMessage } = intl;

if (isFolder && status !== STATUS_PENDING) {
return null;
}

switch (status) {
case STATUS_COMPLETE:
icon = <Checkmark aria-label="complete" color={SurfaceStatusSurfaceSuccess} height={Size5} width={Size5} />;
if (!isResumableUploadsEnabled) {
tooltip = messages.remove;
}
break;
case STATUS_ERROR:
icon = <ArrowCurveForward aria-label="error" color="black" height={Size5} width={Size5} />;
tooltip = isResumableUploadsEnabled ? messages.resume : messages.retry;
break;
case STATUS_IN_PROGRESS:
case STATUS_STAGED:
if (isResumableUploadsEnabled) {
isLoading = true;
} else {
icon = <EllipsisBadge aria-label="staged" color="black" height={Size5} width={Size5} />;
tooltip = messages.uploadsCancelButtonTooltip;
}
break;
case STATUS_PENDING:
default:
if (isResumableUploadsEnabled) {
isLoading = true;
} else {
tooltip = messages.uploadsCancelButtonTooltip;
}
break;
}

if (status === STATUS_ERROR && code === ERROR_CODE_UPLOAD_FILE_SIZE_LIMIT_EXCEEDED && !!onUpgradeCTAClick) {
return (
<Button
onClick={onUpgradeCTAClick}
data-resin-target="large_version_error_inline_upgrade_cta"
variant="primary"
>
{intl.formatMessage(messages.uploadsFileSizeLimitExceededUpgradeMessageForUpgradeCta)}
</Button>
);
}
const isDisabled = status === STATUS_STAGED;
const tooltipText = tooltip && formatMessage(tooltip);

return (
<div className="bcu-item-action">
{getIconWithTooltip(icon, isDisabled, isLoading, onClick, tooltip, tooltipText)}
</div>
);
};

export default injectIntl(ItemAction);
4 changes: 2 additions & 2 deletions src/elements/content-uploader/ItemList.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ const ItemList = ({
cellRenderer={actionCell}
dataKey="status"
flexShrink={0}
width={onUpgradeCTAClick ? 100 : 25}
width={onUpgradeCTAClick ? 100 : 32}
/>
{isResumableUploadsEnabled && (
<Column
className="bcu-item-list-action-column"
cellRenderer={removeCell}
dataKey="remove"
flexShrink={0}
width={25}
width={32}
/>
)}
</Table>
Expand Down
Loading

0 comments on commit 34feaea

Please sign in to comment.