blob: 02552fcb7e3c1099950f08044e909a6371bc3e40 [file] [log] [blame]
AviZi280f8012017-06-09 02:39:56 +03001/*!
2 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13 * or implied. See the License for the specific language governing
14 * permissions and limitations under the License.
15 */
Michael Landoefa037d2017-02-19 12:57:33 +020016import React from 'react';
talig8e9c0652017-12-20 14:30:43 +020017import PropTypes from 'prop-types';
Michael Landoefa037d2017-02-19 12:57:33 +020018import classnames from 'classnames';
19import Collapse from 'react-bootstrap/lib/Collapse.js';
20
21class NavigationSideBar extends React.Component {
Michael Landoefa037d2017-02-19 12:57:33 +020022 static PropTypes = {
talig8e9c0652017-12-20 14:30:43 +020023 activeItemId: PropTypes.string.isRequired,
24 onSelect: PropTypes.func,
25 onToggle: PropTypes.func,
26 groups: PropTypes.array
Michael Landoefa037d2017-02-19 12:57:33 +020027 };
28
AviZi280f8012017-06-09 02:39:56 +030029 constructor(props) {
30 super(props);
31 this.state = {
32 activeItemId: null
33 };
34 this.handleItemClicked = this.handleItemClicked.bind(this);
35 }
36
Michael Landoefa037d2017-02-19 12:57:33 +020037 render() {
38 let {groups, activeItemId} = this.props;
39
40 return (
41 <div className='navigation-side-content'>
42 {groups.map(group => (
AviZi280f8012017-06-09 02:39:56 +030043 <NavigationMenu menu={group} activeItemId={activeItemId} onNavigationItemClick={this.handleItemClicked} key={'menu_' + group.id} />
Michael Landoefa037d2017-02-19 12:57:33 +020044 ))}
45 </div>
46 );
47 }
48
Michael Landoefa037d2017-02-19 12:57:33 +020049 handleItemClicked(event, item) {
50 event.stopPropagation();
51 if(this.props.onToggle) {
52 this.props.onToggle(this.props.groups, item.id);
53 }
54 if(item.onSelect) {
55 item.onSelect();
56 }
57 if(this.props.onSelect) {
58 this.props.onSelect(item);
59 }
60 }
61}
62
AviZi280f8012017-06-09 02:39:56 +030063class NavigationMenu extends React.Component {
64 static PropTypes = {
talig8e9c0652017-12-20 14:30:43 +020065 activeItemId: PropTypes.string.isRequired,
66 onNavigationItemClick: PropTypes.func,
67 menu: PropTypes.array
AviZi280f8012017-06-09 02:39:56 +030068 };
69
70 render() {
71 const {menu, activeItemId, onNavigationItemClick} = this.props;
72 return (
73 <div className='navigation-group' key={menu.id}>
74 <NavigationMenuHeader title={menu.name} />
75 <NavigationMenuItems items={menu.items} activeItemId={activeItemId} onNavigationItemClick={onNavigationItemClick} />
76 </div>);
77 }
78}
79
80function NavigationMenuHeader(props) {
81 return <div className='group-name' data-test-id='navbar-group-name'>{props.title}</div>;
82}
83
talig8e9c0652017-12-20 14:30:43 +020084function getItemDataTestId(itemId) {
85 return itemId.split('|')[0];
86}
AviZi280f8012017-06-09 02:39:56 +030087function NavigationMenuItems(props) {
88 const {items, activeItemId, onNavigationItemClick} = props;
89 return (
90 <div className='navigation-group-items'>
91 {
92 items && items.map(item => (<NavigationMenuItem key={'menuItem_' + item.id} item={item} activeItemId={activeItemId} onNavigationItemClick={onNavigationItemClick} />))
93 }
94 </div>
95 );
96}
97
98function NavigationMenuItem(props) {
99 const {onNavigationItemClick, item, activeItemId} = props;
100 const isGroup = item.items && item.items.length > 0;
101 return (
102 <div className={classnames('navigation-group-item', {'selected-item': item.id === activeItemId})} key={'item_' + item.id}>
103 <NavigationLink item={item} activeItemId={activeItemId} onClick={onNavigationItemClick} />
talig8e9c0652017-12-20 14:30:43 +0200104 {isGroup && <Collapse in={item.expanded} data-test-id={'navigation-group-' + getItemDataTestId(item.id)}>
AviZi280f8012017-06-09 02:39:56 +0300105 <div>
106 {item.items.map(subItem => (<NavigationMenuItem key={'menuItem_' + subItem.id} item={subItem} onNavigationItemClick={onNavigationItemClick} activeItemId={activeItemId} />)) }
107 </div>
108 </Collapse>
109 }
110 </div>
111 );
112}
113
114function NavigationLink(props) {
115 const {item, activeItemId, onClick} = props;
az2497644017c2017-08-10 17:49:40 +0300116 // todo should this be button
AviZi280f8012017-06-09 02:39:56 +0300117 return (
118 <div
119 key={'navAction_' + item.id}
120 className={classnames('navigation-group-item-name', {
121 'selected': item.id === activeItemId,
122 'disabled': item.disabled,
123 'bold-name': item.expanded,
124 'hidden': item.hidden
125 })}
126 onClick={(event) => onClick(event, item)}
talig8e9c0652017-12-20 14:30:43 +0200127 data-test-id={'navbar-group-item-' + getItemDataTestId(item.id)}>
AviZi280f8012017-06-09 02:39:56 +0300128 {item.name}
129 </div>
130 );
131}
132
Michael Landoefa037d2017-02-19 12:57:33 +0200133export default NavigationSideBar;