Skip to content

Commit

Permalink
feat(content-explorer-modal-container): add optional info notice
Browse files Browse the repository at this point in the history
  • Loading branch information
psatala-box committed Sep 5, 2024
1 parent 42cc092 commit 8399665
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ class ContentExplorerModalContainer extends Component {
searchInputProps: PropTypes.object,
/** Custom text for the choose button */
chooseButtonText: PropTypes.node,
/** Whether the informational notice is visible */
isInfoNoticeVisible: PropTypes.bool,
/** Text for the informational notice */
infoNoticeText: PropTypes.string,
};

static defaultProps = {
Expand Down Expand Up @@ -207,6 +211,8 @@ class ContentExplorerModalContainer extends Component {
createFolderError,
initialFoldersPath,
shouldNotUsePortal,
isInfoNoticeVisible = false,
infoNoticeText,
...rest
} = this.props;
const { foldersPath, isNewFolderModalOpen } = this.state;
Expand All @@ -223,6 +229,8 @@ class ContentExplorerModalContainer extends Component {
onEnterFolder={this.handleEnterFolder}
onCreateNewFolderButtonClick={this.handleCreateNewFolderButtonClick}
shouldNotUsePortal={shouldNotUsePortal}
isInfoNoticeVisible={isInfoNoticeVisible}
infoNoticeText={infoNoticeText}
{...rest}
/>
{isNewFolderModalOpen && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ContentExplorerModalContainer from '../ContentExplorerModalContainer';

describe('features/content-explorer/content-explorer-modal-container/ContentExplorerModalContainer', () => {
const sandbox = sinon.sandbox.create();
const initialSelectedItems = { '123': { id: '123', name: 'folder123' } };
const initialSelectedItems = { 123: { id: '123', name: 'folder123' } };
const renderComponent = (props, renderer = shallow) =>
renderer(
<ContentExplorerModalContainer
Expand Down Expand Up @@ -97,6 +97,14 @@ describe('features/content-explorer/content-explorer-modal-container/ContentExpl

expect(wrapper.find('Portal').length).toBe(0);
});

test('should pass isInfoNoticeVisible and infoNoticeText to ContentExplorerModal', () => {
const isInfoNoticeVisible = true;
const infoNoticeText = 'info notice text';
const wrapper = renderComponent({ isInfoNoticeVisible, infoNoticeText });
expect(wrapper.find('ContentExplorerModal').prop('isInfoNoticeVisible')).toEqual(isInfoNoticeVisible);
expect(wrapper.find('ContentExplorerModal').prop('infoNoticeText')).toEqual(infoNoticeText);
});
});

describe('onNewFolderModalShown', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type Props = {
onViewSelectedClick?: Function,
shouldNotUsePortal?: boolean,
title?: string,
isInfoNoticeVisible?: boolean,
infoNoticeText?: string,
};

const ContentExplorerModal = ({
Expand All @@ -49,6 +51,8 @@ const ContentExplorerModal = ({
onSelectedClick,
onSelectItem,
shouldNotUsePortal = false,
isInfoNoticeVisible = false,
infoNoticeText = '',
...rest
}: Props) => (
<Modal
Expand All @@ -70,6 +74,8 @@ const ContentExplorerModal = ({
onSelectItem={onSelectItem}
listWidth={560}
listHeight={285}
isInfoNoticeVisible={isInfoNoticeVisible}
infoNoticeText={infoNoticeText}
{...rest}
/>
</Modal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,13 @@ describe('features/content-explorer/content-explorer-modal/ContentExplorerModal'
expect(wrapper.find('ContentExplorer').prop('onSelectedClick')).toEqual(onSelectedClick);
expect(wrapper.find('ContentExplorer').prop('onSelectItem')).toEqual(onSelectItem);
});

test('should pass isInfoNoticeVisible and infoNoticeText to ContentExplorer', () => {
const isInfoNoticeVisible = true;
const infoNoticeText = 'info notice text';
const wrapper = renderComponent({ isInfoNoticeVisible, infoNoticeText });
expect(wrapper.find('ContentExplorer').prop('isInfoNoticeVisible')).toEqual(isInfoNoticeVisible);
expect(wrapper.find('ContentExplorer').prop('infoNoticeText')).toEqual(infoNoticeText);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ exports[`features/content-explorer/content-explorer-modal/ContentExplorerModal r
contentExplorerMode="selectFile"
customInput={[Function]}
formatMessage={[Function]}
infoNoticeText=""
initialFoldersPath={[]}
isInfoNoticeVisible={false}
isResponsive={false}
items={[]}
listHeight={285}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ContentExplorerEmptyState from './ContentExplorerEmptyState';
import ContentExplorerActionButtons from './ContentExplorerActionButtons';
import ContentExplorerSelectAll from './ContentExplorerSelectAll';
import ContentExplorerIncludeSubfolders from './ContentExplorerIncludeSubfolders';
import ContentExplorerInfoNotice from './ContentExplorerInfoNotice';

import ItemList from '../item-list';
import { ContentExplorerModePropType, FoldersPathPropType, ItemsPropType } from '../prop-types';
Expand Down Expand Up @@ -158,6 +159,10 @@ class ContentExplorer extends Component {
listHeight: PropTypes.number.isRequired,
/** Props for the search input */
searchInputProps: PropTypes.object,
/** Whether the informational notice is visible */
isInfoNoticeVisible: PropTypes.bool,
/** Text for the informational notice */
infoNoticeText: PropTypes.string,
};

static defaultProps = {
Expand Down Expand Up @@ -496,6 +501,8 @@ class ContentExplorer extends Component {
listWidth,
listHeight,
searchInputProps,
isInfoNoticeVisible = false,
infoNoticeText,
...rest
} = this.props;
const { isInSearchMode, foldersPath, isSelectAllChecked } = this.state;
Expand Down Expand Up @@ -552,6 +559,7 @@ class ContentExplorer extends Component {
}}
{...contentExplorerProps}
>
{isInfoNoticeVisible && <ContentExplorerInfoNotice infoNoticeText={infoNoticeText} />}
<ContentExplorerHeaderActions
breadcrumbProps={breadcrumbProps}
contentExplorerMode={contentExplorerMode}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
@import '../../../styles/variables';

.content-explorer {
.content-explorer-info-notice {
border: none;

.content-explorer-info-notice-flex-container {
display: flex;

.content-explorer-info-notice-icon {
flex-shrink: 0;
width: 17.5px;
height: 17.5px;
margin: 1.25px;
}

p {
margin-bottom: 0;
margin-left: 10px;
font-size: 14px;
}
}
}

.content-explorer-search-new-folder-container {
display: flex;
align-items: center;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from 'react';
import PropTypes from 'prop-types';

import { InfoBadge } from '@box/blueprint-web-assets/icons/Line';

import InlineNotice from '../../../components/inline-notice';

const ContentExplorerInfoNotice = ({ infoNoticeText }) => (
<InlineNotice type="info" className="content-explorer-info-notice">
<div className="content-explorer-info-notice-flex-container">
<InfoBadge className="content-explorer-info-notice-icon" />
<p>{infoNoticeText}</p>
</div>
</InlineNotice>
);

ContentExplorerInfoNotice.propTypes = {
infoNoticeText: PropTypes.string.isRequired,
};

export default ContentExplorerInfoNotice;
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {

wrapper.setState({
selectedItems: {
'1': {
1: {
id: '1',
isActionDisabled: true,
name: 'name',
Expand Down Expand Up @@ -216,7 +216,7 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
{ id: '3', name: 'item3' },
];

const selectedItems = { '1': items[0] };
const selectedItems = { 1: items[0] };
const wrapper = renderComponent({
contentExplorerMode,
items,
Expand Down Expand Up @@ -271,13 +271,31 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {

test('should render all items from both selectedItems state and controlledSelectedItems prop', () => {
const wrapper = renderComponent({
controlledSelectedItems: { '2': { id: '2', name: 'item2' } },
controlledSelectedItems: { 2: { id: '2', name: 'item2' } },
});
const selectedItems = { '1': { id: '1', name: 'item1' } };
const selectedItems = { 1: { id: '1', name: 'item1' } };
wrapper.setState({ selectedItems });
expect(Object.keys(wrapper.find('ItemList').prop('selectedItems')).length).toBe(2);
expect(Object.keys(wrapper.find('ContentExplorerActionButtons').prop('selectedItems')).length).toBe(2);
});

test('should not render ContentExplorerInfoNotice by default', () => {
const wrapper = renderComponent();

expect(wrapper.exists('ContentExplorerInfoNotice')).toBe(false);
});

test('should render ContentExplorerInfoNotice when flag is not set', () => {
const wrapper = renderComponent({ isInfoNoticeVisible: false });

expect(wrapper.exists('ContentExplorerInfoNotice')).toBe(false);
});

test('should render ContentExplorerInfoNotice when flag is set', () => {
const wrapper = renderComponent({ isInfoNoticeVisible: true });

expect(wrapper.exists('ContentExplorerInfoNotice')).toBe(true);
});
});

describe('onEnterFolder', () => {
Expand Down Expand Up @@ -312,10 +330,7 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
const clickedFolder = items[clickedFolderIndex];
const newFoldersPath = initialFoldersPath.concat([clickedFolder]);

wrapper
.find('.item-list-name')
.first()
.simulate('click');
wrapper.find('.item-list-name').first().simulate('click');

expect(onEnterFolderSpy.withArgs(clickedFolder, newFoldersPath).calledOnce).toBe(true);
});
Expand All @@ -325,10 +340,7 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
const clickedFolder = items[clickedFolderIndex];
const newFoldersPath = initialFoldersPath.concat([clickedFolder]);

wrapper
.find('.item-list-name')
.first()
.simulate('doubleClick');
wrapper.find('.item-list-name').first().simulate('doubleClick');

expect(onEnterFolderSpy.withArgs(clickedFolder, newFoldersPath).calledOnce).toBe(true);
});
Expand All @@ -348,10 +360,7 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
const clickedFolder = items[clickedFolderIndex];
const newFoldersPath = initialFoldersPath.concat([clickedFolder]);

wrapper
.find('.item-list-name')
.first()
.simulate('click');
wrapper.find('.item-list-name').first().simulate('click');

expect(onEnterFolderSpy.withArgs(clickedFolder, newFoldersPath).calledOnce).toBe(false);
});
Expand All @@ -373,10 +382,7 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
];
const wrapper = renderComponent({ items, onSelectItem: onSelectItemSpy }, true);

wrapper
.find('.table-row')
.at(clickedItemIndex)
.simulate('click');
wrapper.find('.table-row').at(clickedItemIndex).simulate('click');

expect(onSelectItemSpy.withArgs(items[clickedItemIndex], clickedItemIndex).calledOnce).toBe(true);
});
Expand All @@ -391,15 +397,9 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
];
const wrapper = renderComponent({ items, onSelectItem: onSelectItemSpy }, true);

wrapper
.find('.table-row')
.at(clickedItemIndex)
.simulate('click');
wrapper.find('.table-row').at(clickedItemIndex).simulate('click');

wrapper
.find('.table-row')
.at(clickedItemIndex2)
.simulate('click');
wrapper.find('.table-row').at(clickedItemIndex2).simulate('click');

expect(onSelectItemSpy.withArgs(items[clickedItemIndex], clickedItemIndex).calledOnce).toBe(true);

Expand All @@ -426,15 +426,9 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
true,
);

wrapper
.find('.table-row')
.at(clickedItemIndex)
.simulate('click');
wrapper.find('.table-row').at(clickedItemIndex).simulate('click');

wrapper
.find('.table-row')
.at(clickedItemIndex2)
.simulate('click');
wrapper.find('.table-row').at(clickedItemIndex2).simulate('click');

expect(onSelectItemSpy.withArgs(items[clickedItemIndex], clickedItemIndex).calledOnce).toBe(true);

Expand Down Expand Up @@ -483,20 +477,11 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
true,
);

wrapper
.find('.table-row')
.at(clickedItemIndex)
.simulate('click');
wrapper.find('.table-row').at(clickedItemIndex).simulate('click');

wrapper
.find('.table-row')
.at(clickedItemIndex2)
.simulate('click');
wrapper.find('.table-row').at(clickedItemIndex2).simulate('click');

wrapper
.find('.table-row')
.at(clickedItemIndex3)
.simulate('click');
wrapper.find('.table-row').at(clickedItemIndex3).simulate('click');

expect(Object.keys(wrapper.state('selectedItems')).length).toBe(3);
expect(wrapper.state('isSelectAllChecked')).toBe(true);
Expand All @@ -509,7 +494,7 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
{ id: '1', name: 'item1' },
{ id: '2', name: 'item2' },
];
const selectedItems = { '1': items[clickedItemIndex], '2': items[clickedItemIndex2] };
const selectedItems = { 1: items[clickedItemIndex], 2: items[clickedItemIndex2] };
const wrapper = renderComponent(
{
items,
Expand All @@ -521,10 +506,7 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {
);
wrapper.setState({ selectedItems, isSelectAllChecked: true });

wrapper
.find('.table-row')
.at(clickedItemIndex)
.simulate('click');
wrapper.find('.table-row').at(clickedItemIndex).simulate('click');

expect(Object.keys(wrapper.state('selectedItems')).length).toBe(1);
expect(wrapper.state('isSelectAllChecked')).toBe(false);
Expand All @@ -540,7 +522,7 @@ describe('features/content-explorer/content-explorer/ContentExplorer', () => {

test('should call onChooseItems with the clicked file when double clicking a file', () => {
const items = [{ id: '1', name: 'item1', type: 'file' }];
const selectedItems = { '1': items[0] };
const selectedItems = { 1: items[0] };
const wrapper = renderComponent({ items, onChooseItems: onChooseItemsSpy }, true);

// Need to make the item selected first because simulating a double click doesn't actually click anything
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';

import ContentExplorerInfoNotice from '../ContentExplorerInfoNotice';

describe('features/content-explorer/content-explorer/ContentExplorerInfoNotice', () => {
const renderComponent = infoNoticeText => shallow(<ContentExplorerInfoNotice infoNoticeText={infoNoticeText} />);

test('should render correctly', () => {
const wrapper = renderComponent('This is an info notice');
expect(wrapper).toMatchSnapshot();
});
});
Loading

0 comments on commit 8399665

Please sign in to comment.