Add aria-labels
[ccsdk/features.git] / sdnr / wt / odlux / apps / inventoryApp / src / views / treeview.tsx
1 /**
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt odlux
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18 import * as React from "react";
19 import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
20
21 import { renderObject } from '../../../../framework/src/components/objectDump';
22 import { Connect, connect, IDispatcher } from '../../../../framework/src/flux/connect';
23 import { TreeView, TreeViewCtorType, SearchMode } from '../../../../framework/src/components/material-ui/treeView';
24
25 import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
26
27 import { updateInventoryTreeAsyncAction, selectInventoryNodeAsyncAction, UpdateSelectedNodeAction, UpdateExpandedNodesAction, setSearchTermAction} from "../actions/inventoryTreeActions";
28 import { TreeDemoItem } from "../models/inventory";
29
30 import { RouteComponentProps } from "react-router-dom";
31
32 const styles = (theme: Theme) => createStyles({
33   root: {
34     flex: "1 0 0%",
35     display: "flex",
36     flexDirection: "row",
37   },
38   tree: {
39     flex: "1 0 0%",
40     minWidth: "250px",
41     padding: `0px ${theme.spacing(1)}px`
42   },
43   details: {
44     flex: "5 0 0%",
45     padding: `0px ${theme.spacing(1)}px`
46   }
47 });
48
49 const mapProps = (state: IApplicationStoreState) => ({
50   isBusy: state.inventory.inventoryTree.isBusy,
51   rootNodes: state.inventory.inventoryTree.rootNodes,
52   searchTerm: state.inventory.inventoryTree.searchTerm,
53   selectedNode: state.inventory.inventoryTree.selectedNode,
54   expendedItems: state.inventory.inventoryTree.expandedItems,
55 });
56
57 const mapDispatch = (dispatcher: IDispatcher) => ({
58   updateExpendedNodes: (expendedNodes: TreeDemoItem[]) => dispatcher.dispatch(new UpdateExpandedNodesAction(expendedNodes)),
59   updateInventoryTree: (mountId: string, seatchTerm?: string) => dispatcher.dispatch(updateInventoryTreeAsyncAction(mountId, seatchTerm)),
60   selectTreeNode: (nodeId?: string) => nodeId ? dispatcher.dispatch(selectInventoryNodeAsyncAction(nodeId)) : dispatcher.dispatch(new UpdateSelectedNodeAction(undefined)),
61   setSearchTerm: (searchTerm: string) => dispatcher.dispatch(setSearchTermAction(searchTerm)),
62 });
63
64 const propsChache = Symbol("PropsCache");
65 const InventoryTree = TreeView as any as TreeViewCtorType<string>;
66
67
68
69 type TreeviewComponentProps = RouteComponentProps<{ mountId: string}> & WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>
70
71 type TreeviewComponentState = {
72   [propsChache]: {
73     rootNodes?: TreeDemoItem[];
74   };
75   rootNodes: TreeDemoItem[];
76 }
77
78
79 class DashboardComponent extends React.Component<TreeviewComponentProps, TreeviewComponentState> {
80
81   constructor (props: TreeviewComponentProps) {
82     super(props);
83
84     this.state = {
85       [propsChache]: {},
86       rootNodes: [],
87     };
88   }
89
90   static getDerivedStateFromProps(props: TreeviewComponentProps, state: TreeviewComponentState) {
91     if (state[propsChache].rootNodes != props.rootNodes) {
92       state = { ...state, rootNodes: props.rootNodes}
93     }
94     return state;
95   }
96
97   render() {
98     const { classes, updateInventoryTree, updateExpendedNodes, expendedItems, selectedNode, selectTreeNode, searchTerm, match: { params: { mountId }} } = this.props;
99     return (
100       <div className={classes.root}>
101         <InventoryTree className={classes.tree} items={this.state.rootNodes} enableSearchBar initialSearchTerm={searchTerm} searchMode={SearchMode.OnEnter} searchTerm={searchTerm}
102           onSearch={(searchTerm) => updateInventoryTree(mountId, searchTerm)} expandedItems={expendedItems} onFolderClick={(item) => {
103             const indexOfItemToToggle = expendedItems.indexOf(item);
104             if (indexOfItemToToggle === -1) {
105               updateExpendedNodes([...expendedItems, item]);
106             } else {
107               updateExpendedNodes([
108                 ...expendedItems.slice(0, indexOfItemToToggle),
109                 ...expendedItems.slice(indexOfItemToToggle + 1),
110               ]);
111             }
112           }}
113           onItemClick={(elm) => selectTreeNode(elm.value)} />
114         <div className={classes.details}>{
115           selectedNode && renderObject(selectedNode, "tree-view") || null
116         }</div>
117       </div>
118     );
119   }
120
121   componentDidMount() {
122     const { updateInventoryTree, searchTerm, match: { params: { mountId } }} = this.props;
123     updateInventoryTree(mountId, searchTerm);
124   }
125
126   componentWillUnmount(){
127     this.props.setSearchTerm("");
128   }
129 }
130
131 export const InventoryTreeView = connect(mapProps, mapDispatch)(withStyles(styles)(DashboardComponent));
132 export default InventoryTreeView;