blob: 2eda7e69bf14d124edade33d699bde112ccc8aaa [file] [log] [blame]
AviZi280f8012017-06-09 02:39:56 +03001/*!
svishnevf6784902018-02-12 09:10:35 +02002 * Copyright © 2016-2018 European Support Limited
AviZi280f8012017-06-09 02:39:56 +03003 *
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,
svishnevf6784902018-02-12 09:10:35 +020026 groups: PropTypes.array,
27 disabled: PropTypes.bool
Michael Landoefa037d2017-02-19 12:57:33 +020028 };
29
AviZi280f8012017-06-09 02:39:56 +030030 constructor(props) {
31 super(props);
32 this.state = {
33 activeItemId: null
34 };
35 this.handleItemClicked = this.handleItemClicked.bind(this);
36 }
37
Michael Landoefa037d2017-02-19 12:57:33 +020038 render() {
svishnevf6784902018-02-12 09:10:35 +020039 let {groups, activeItemId, disabled = false} = this.props;
Michael Landoefa037d2017-02-19 12:57:33 +020040
41 return (
svishnevf6784902018-02-12 09:10:35 +020042 <div className={`navigation-side-content ${disabled ? 'disabled' : ''}`}>
Michael Landoefa037d2017-02-19 12:57:33 +020043 {groups.map(group => (
AviZi280f8012017-06-09 02:39:56 +030044 <NavigationMenu menu={group} activeItemId={activeItemId} onNavigationItemClick={this.handleItemClicked} key={'menu_' + group.id} />
Michael Landoefa037d2017-02-19 12:57:33 +020045 ))}
46 </div>
47 );
48 }
49
Michael Landoefa037d2017-02-19 12:57:33 +020050 handleItemClicked(event, item) {
51 event.stopPropagation();
52 if(this.props.onToggle) {
53 this.props.onToggle(this.props.groups, item.id);
54 }
55 if(item.onSelect) {
56 item.onSelect();
57 }
58 if(this.props.onSelect) {
59 this.props.onSelect(item);
60 }
61 }
62}
63
AviZi280f8012017-06-09 02:39:56 +030064class NavigationMenu extends React.Component {
65 static PropTypes = {
talig8e9c0652017-12-20 14:30:43 +020066 activeItemId: PropTypes.string.isRequired,
67 onNavigationItemClick: PropTypes.func,
68 menu: PropTypes.array
AviZi280f8012017-06-09 02:39:56 +030069 };
70
71 render() {
72 const {menu, activeItemId, onNavigationItemClick} = this.props;
73 return (
74 <div className='navigation-group' key={menu.id}>
75 <NavigationMenuHeader title={menu.name} />
76 <NavigationMenuItems items={menu.items} activeItemId={activeItemId} onNavigationItemClick={onNavigationItemClick} />
77 </div>);
78 }
79}
80
81function NavigationMenuHeader(props) {
82 return <div className='group-name' data-test-id='navbar-group-name'>{props.title}</div>;
83}
84
talig8e9c0652017-12-20 14:30:43 +020085function getItemDataTestId(itemId) {
86 return itemId.split('|')[0];
87}
AviZi280f8012017-06-09 02:39:56 +030088function NavigationMenuItems(props) {
89 const {items, activeItemId, onNavigationItemClick} = props;
90 return (
91 <div className='navigation-group-items'>
92 {
93 items && items.map(item => (<NavigationMenuItem key={'menuItem_' + item.id} item={item} activeItemId={activeItemId} onNavigationItemClick={onNavigationItemClick} />))
94 }
95 </div>
96 );
97}
98
99function NavigationMenuItem(props) {
100 const {onNavigationItemClick, item, activeItemId} = props;
101 const isGroup = item.items && item.items.length > 0;
102 return (
103 <div className={classnames('navigation-group-item', {'selected-item': item.id === activeItemId})} key={'item_' + item.id}>
104 <NavigationLink item={item} activeItemId={activeItemId} onClick={onNavigationItemClick} />
talig8e9c0652017-12-20 14:30:43 +0200105 {isGroup && <Collapse in={item.expanded} data-test-id={'navigation-group-' + getItemDataTestId(item.id)}>
AviZi280f8012017-06-09 02:39:56 +0300106 <div>
107 {item.items.map(subItem => (<NavigationMenuItem key={'menuItem_' + subItem.id} item={subItem} onNavigationItemClick={onNavigationItemClick} activeItemId={activeItemId} />)) }
108 </div>
109 </Collapse>
110 }
111 </div>
112 );
113}
114
115function NavigationLink(props) {
116 const {item, activeItemId, onClick} = props;
az2497644017c2017-08-10 17:49:40 +0300117 // todo should this be button
AviZi280f8012017-06-09 02:39:56 +0300118 return (
119 <div
120 key={'navAction_' + item.id}
121 className={classnames('navigation-group-item-name', {
122 'selected': item.id === activeItemId,
123 'disabled': item.disabled,
124 'bold-name': item.expanded,
125 'hidden': item.hidden
126 })}
127 onClick={(event) => onClick(event, item)}
talig8e9c0652017-12-20 14:30:43 +0200128 data-test-id={'navbar-group-item-' + getItemDataTestId(item.id)}>
AviZi280f8012017-06-09 02:39:56 +0300129 {item.name}
130 </div>
131 );
132}
133
Michael Landoefa037d2017-02-19 12:57:33 +0200134export default NavigationSideBar;