Skip to content
This repository has been archived by the owner on May 24, 2024. It is now read-only.

[terra-navigation-side-menu] Drill-in Custom status display, isLoading #2170

Merged
merged 8 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/terra-framework-docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Unreleased

* Changed
* Updated
* Updated example for drill-in view under `terra-navigation-side-menu`.

## 1.89.1 - (May 20, 2024)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ class DrillInDefault extends React.Component {
key: 'submenu3', text: 'Hospital Accommodations', isDisabled: true,
},
{ key: 'submenu4', text: 'Hospital Careers' },
{ key: 'submenu5', text: 'Hospital Info', childKeys: [] },
{
key: 'submenu5',
text: 'Hospital Info',
childKeys: [],
customStatusDisplay: <span>No results for Hospital Info</span>,
},
{
key: 'subsubmenu1', text: 'Imaging', id: 'test-item-2',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,40 @@ import styles from './NavigationSideMenuDocCommon.module.scss';

const cx = classNames.bind(styles);

const data = [
{
key: 'menu', text: 'Hospital Details', childKeys: ['submenu1', 'submenu2', 'submenu3', 'submenu4', 'submenu5'],
},
{
key: 'submenu1',
text: 'Hospital services',
childKeys: ['subsubmenu1', 'subsubmenu2', 'subsubmenu3'],
id: 'test-item-1',
},
{ key: 'submenu2', text: 'Hospital events' },
{
key: 'submenu3', text: 'Hospital Accommodations',
},
{ key: 'submenu4', text: 'Hospital Careers' },
{
key: 'submenu5',
text: 'Hospital Info',
childKeys: [],
customStatusDisplay: <span>No results for Hospital Info</span>,
},
{
key: 'subsubmenu1', text: 'Imaging', id: 'test-item-2',
},
{ key: 'subsubmenu2', text: 'Laboratory' },
{
key: 'subsubmenu3', text: 'Rehabilitation services', childKeys: ['rehab1', 'rehab2', 'rehab3'], icon: <IconHospital />,
},
{ key: 'rehab1', text: 'Rehabilitation services 1' },
{
key: 'rehab2', text: 'Rehabilitation services 2', childKeys: [], isLoading: true, customStatusDisplay: <span>Loading...</span>,
},
{ key: 'rehab3', text: 'Rehabilitation services 3', childKeys: [] },
];
class DrillInExample extends React.Component {
constructor(props) {
super(props);
Expand All @@ -14,19 +48,31 @@ class DrillInExample extends React.Component {
this.resetMenuState = this.resetMenuState.bind(this);
this.fakeRoutingBack = this.fakeRoutingBack.bind(this);

this.state = { selectedMenuKey: 'menu', selectedChildKey: undefined };
this.state = { selectedMenuKey: 'menu', selectedChildKey: undefined, data };
}

handleOnChange(event, changeData) {
if (changeData.selectedMenuKey === 'rehab2') {
this.setState({ selectedMenuKey: changeData.selectedMenuKey });
setTimeout(() => {
const modifiedData = [
{
key: 'rehab2', text: 'Rehabilitation services 2', childKeys: ['rehab1sub'], isLoading: false,
},
{ key: 'rehab1sub', text: 'Rehabilitation services submenu', childKeys: [] },
];
this.setState({ data: modifiedData, selectedMenuKey: 'rehab2' });
}, 1000);
}
this.setState({ selectedMenuKey: changeData.selectedMenuKey, selectedChildKey: changeData.selectedChildKey });
}

resetMenuState() {
this.setState({ selectedMenuKey: 'menu', selectedChildKey: undefined });
this.setState({ selectedMenuKey: 'menu', selectedChildKey: undefined, data });
}

fakeRoutingBack() {
this.setState({ selectedMenuKey: 'fake-parent', selectedChildKey: undefined });
this.setState({ selectedMenuKey: 'fake-parent', selectedChildKey: undefined, data });
}

render() {
Expand All @@ -44,33 +90,7 @@ class DrillInExample extends React.Component {
content = (
<NavigationSideMenu
id="test-menu"
menuItems={[
{
key: 'menu', text: 'Hospital Details', childKeys: ['submenu1', 'submenu2', 'submenu3', 'submenu4', 'submenu5'],
},
{
key: 'submenu1',
text: 'Hospital services',
childKeys: ['subsubmenu1', 'subsubmenu2', 'subsubmenu3'],
id: 'test-item-1',
},
{ key: 'submenu2', text: 'Hospital events' },
{
key: 'submenu3', text: 'Hospital Accommodations',
},
{ key: 'submenu4', text: 'Hospital Careers' },
{ key: 'submenu5', text: 'Hospital Info', childKeys: [] },
{
key: 'subsubmenu1', text: 'Imaging', id: 'test-item-2',
},
{ key: 'subsubmenu2', text: 'Laboratory' },
{
key: 'subsubmenu3', text: 'Rehabilitation services', childKeys: ['rehab1', 'rehab2', 'rehab3'], icon: <IconHospital />,
},
{ key: 'rehab1', text: 'Rehabilitation services 1' },
{ key: 'rehab2', text: 'Rehabilitation services 2' },
{ key: 'rehab3', text: 'Rehabilitation services 3', childKeys: [] },
]}
menuItems={this.state.data}
onChange={this.handleOnChange}
routingStackBack={this.fakeRoutingBack}
selectedMenuKey={this.state.selectedMenuKey}
Expand Down
2 changes: 2 additions & 0 deletions packages/terra-navigation-side-menu/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## Unreleased

* Added
* Added custom status display for Drill-in content.
* Added isLoading prop for Drill-in item.
* Added headerLevel prop for the title of the menu.
* Added missing A11y attributes.

Expand Down
23 changes: 18 additions & 5 deletions packages/terra-navigation-side-menu/src/NavigationSideMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ const propTypes = {
* The icon to display to the left for the menu item when variant is 'drill-in'
*/
icon: PropTypes.element,
/**
* A custom status display for menu item with no children. Component will fallback to status-view with no results.
*/
customStatusDisplay: PropTypes.node,
/**
* Indicates if items are loaded.
*/
isLoading: PropTypes.bool,
})),
/**
* Callback function when a menu endpoint is reached.
Expand Down Expand Up @@ -120,6 +128,8 @@ const processMenuItems = (menuItems, variant) => {
isRootMenu: item.isRootMenu,
icon: item.icon,
isDisabled: item.isDisabled,
customStatusDisplay: item.customStatusDisplay,
isLoading: item.isLoading,
};
if (item.childKeys) {
item.childKeys.forEach((key) => {
Expand Down Expand Up @@ -337,15 +347,18 @@ class NavigationSideMenu extends Component {
}
};

buildListItem(key, keys) {
buildListItem(key, currentItem) {
const item = this.state.items[key];
const tabIndex = Array.from(keys).indexOf(key);
const tabIndex = Array.from(currentItem.childKeys).indexOf(key);
const onKeyDown = (event) => {
this.handleEvents(event, item, key);
};

if (key === 'empty-child-key') {
return this.props.variant === VARIANTS.DRILL_IN ? <StatusView variant="no-data" /> : null;
// Render Custom status / Spinner / No results
if (key === 'empty-child-key' || currentItem.isLoading) {
return this.props.variant === VARIANTS.DRILL_IN
? (currentItem.customStatusDisplay || <StatusView variant="no-data" />)
: null;
}

return (
Expand All @@ -368,7 +381,7 @@ class NavigationSideMenu extends Component {

buildListContent(currentItem) {
if (currentItem && currentItem.childKeys && currentItem.childKeys.length) {
return currentItem.childKeys.map(key => this.buildListItem(key, currentItem.childKeys));
return currentItem.childKeys.map(key => this.buildListItem(key, currentItem));
}
return null;
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,29 @@ Terra.describeViewports('DrillIn View', ['medium'], () => {
browser.keys(['ArrowDown']);
Terra.validates.element('second drill-in item focused', { selector: '#root' });
});
});

describe('DrillIn status display for folder with no items', () => {
it('Navigates into folder with no items', () => {
browser.url('/#/raw/tests/cerner-terra-framework-docs/navigation-side-menu/drill-in');
browser.keys(['Tab', 'ArrowDown', 'ArrowRight', 'ArrowDown', 'ArrowDown', 'ArrowDown', 'ArrowRight',
'ArrowDown', 'ArrowDown', 'ArrowDown', 'ArrowRight']);
Terra.validates.element('displays no results status-view', { selector: '#root' });
});

it('Navigate into folder with no items', () => {
browser.keys(['ArrowDown', 'ArrowDown', 'ArrowDown', 'ArrowRight']);
Terra.validates.element('displays no results status', { selector: '#root' });
it('Should display custom status for folder with no items', () => {
browser.url('/#/raw/tests/cerner-terra-framework-docs/navigation-side-menu/drill-in');
browser.keys(['Tab', 'ArrowDown', 'ArrowDown', 'ArrowDown', 'ArrowDown', 'ArrowDown', 'ArrowRight']);
Terra.validates.element('displays no results custom status', { selector: '#root' });
});

it('Should display custom status when Loading is true and data when loading is false', () => {
browser.url('/#/raw/tests/cerner-terra-framework-docs/navigation-side-menu/drill-in');
browser.keys(['Tab', 'ArrowDown', 'ArrowRight', 'ArrowDown', 'ArrowDown', 'ArrowDown']);
browser.keys(['ArrowRight', 'ArrowDown', 'ArrowDown', 'ArrowRight']);
Terra.validates.element('displays loading status', { selector: '#root' });
browser.pause(1000);
Terra.validates.element('displays data after loading', { selector: '#root' });
});
});
});
Expand Down
Loading