import React from 'react';
import { useIntl } from 'react-intl';
import noop from 'lodash/noop';
import { ActionCell, Cell, DropdownMenu, GridList, IconButton } from '@box/blueprint-web';
import { Ellipsis } from '@box/blueprint-web-assets/icons/Fill';
import type { IconButtonProps } from '@box/blueprint-web';
import Browser from '../../../utils/Browser';
import {
PERMISSION_CAN_DELETE,
PERMISSION_CAN_DOWNLOAD,
PERMISSION_CAN_PREVIEW,
PERMISSION_CAN_RENAME,
PERMISSION_CAN_SHARE,
TYPE_FILE,
TYPE_WEBLINK,
VIEW_MODE_GRID,
VIEW_MODE_LIST,
} from '../../../constants';
import messages from '../messages';
import type { BoxItem } from '../../../common/types/core';
import type { ItemAction, ItemEventHandlers, ItemEventPermissions } from './types';
export interface ItemOptionsProps extends ItemEventHandlers, ItemEventPermissions {
item: BoxItem;
itemActions?: ItemAction[];
portalElement?: HTMLElement;
viewMode?: VIEW_MODE_GRID | VIEW_MODE_LIST;
}
const ItemOptions = ({
canDelete = false,
canDownload = false,
canPreview = false,
canRename = false,
canShare = false,
item,
itemActions = [],
onItemDelete = noop,
onItemDownload = noop,
onItemPreview = noop,
onItemRename = noop,
onItemShare = noop,
portalElement,
viewMode,
}: ItemOptionsProps) => {
const { permissions, type: itemType } = item;
const { formatMessage } = useIntl();
const isListView = viewMode === VIEW_MODE_LIST;
const isGridView = viewMode === VIEW_MODE_GRID;
if (!permissions) {
return isListView ? | : null;
}
const isDeleteEnabled = canDelete && permissions[PERMISSION_CAN_DELETE];
const isDownloadEnabled =
itemType === TYPE_FILE && canDownload && permissions[PERMISSION_CAN_DOWNLOAD] && Browser.canDownload();
const isOpenEnabled = itemType === TYPE_WEBLINK;
const isPreviewEnabled = itemType === TYPE_FILE && canPreview && permissions[PERMISSION_CAN_PREVIEW];
const isRenameEnabled = canRename && permissions[PERMISSION_CAN_RENAME];
const isShareEnabled = canShare && permissions[PERMISSION_CAN_SHARE];
const actions = itemActions.reduce((validActions, action) => {
const { filter: actionFilter, label: actionLabel, onAction, type: actionType } = action;
if (actionType && actionType !== itemType) {
return validActions;
}
if (actionFilter && !actionFilter(item)) {
return validActions;
}
return [
...validActions,
onAction(item)}>
{actionLabel}
,
];
}, []);
const hasActions = !!actions.length;
const hasOptions =
isDeleteEnabled || isDownloadEnabled || isOpenEnabled || isPreviewEnabled || isRenameEnabled || isShareEnabled;
if (!hasActions && !hasOptions) {
return isListView ? | : null;
}
const iconButtonProps = {
onPointerDown: event => {
event.stopPropagation();
},
size: 'large',
};
const OptionsGroup = isGridView ? GridList.Actions : ActionCell;
const OptionsTrigger = isGridView ? GridList.ActionIconButton : IconButton;
const optionsTriggerProps = isGridView ? {} : iconButtonProps;
const OptionsDropdownMenu = ({ onOpenChange = noop }) => (
{isPreviewEnabled && (
onItemPreview(item)}>
{formatMessage(messages.preview)}
)}
{isOpenEnabled && (
onItemPreview(item)}>
{formatMessage(messages.open)}
)}
{isDeleteEnabled && (
onItemDelete(item)}>
{formatMessage(messages.delete)}
)}
{isDownloadEnabled && (
onItemDownload(item)}>
{formatMessage(messages.download)}
)}
{isRenameEnabled && (
onItemRename(item)}>
{formatMessage(messages.rename)}
)}
{isShareEnabled && (
onItemShare(item)}>
{formatMessage(messages.share)}
)}
{hasActions && hasOptions && }
{hasActions && actions}
);
// TODO: Update to one `return` statement after ContentPicker has been migrated to Blueprint
if (viewMode) {
return {onOpenChange => };
}
return ;
};
export default ItemOptions;