Update ODLUX
[ccsdk/features.git] / sdnr / wt / odlux / apps / inventoryApp / src / views / dashboard.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
19 import * as React from 'react';
20 import { RouteComponentProps, withRouter } from 'react-router-dom';
21
22 import connect, { IDispatcher, Connect } from "../../../../framework/src/flux/connect";
23 import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
24 import { MaterialTable, MaterialTableCtorType, ColumnType } from "../../../../framework/src/components/material-table";
25 import { AppBar, Tabs, Tab, MenuItem, Typography } from "@mui/material";
26 import Refresh from '@mui/icons-material/Refresh';
27 import { PanelId } from "../models/panelId";
28 import { setPanelAction } from "../actions/panelActions";
29
30
31 import { createConnectedNetworkElementsProperties, createConnectedNetworkElementsActions } from "../handlers/connectedNetworkElementsHandler";
32
33 import { NetworkElementConnection } from "../models/networkElementConnection";
34
35 import { InventoryType } from '../models/inventory';
36
37 import { createInventoryElementsProperties, createInventoryElementsActions } from "../handlers/inventoryElementsHandler";
38 import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
39 import { updateInventoryTreeAsyncAction } from '../actions/inventoryTreeActions';
40 import RefreshInventoryDialog, { RefreshInventoryDialogMode } from '../components/refreshInventoryDialog';
41
42 const InventoryTable = MaterialTable as MaterialTableCtorType<InventoryType & { _id: string }>;
43
44 const mapProps = (state: IApplicationStoreState) => ({
45   connectedNetworkElementsProperties: createConnectedNetworkElementsProperties(state),
46   panelId: state.inventory.currentOpenPanel,
47   inventoryElementsProperties: createInventoryElementsProperties(state),
48   inventoryElements: state.inventory.inventoryElements
49 });
50
51 const mapDispatch = (dispatcher: IDispatcher) => ({
52   connectedNetworkElementsActions: createConnectedNetworkElementsActions(dispatcher.dispatch),
53   switchActivePanel: (panelId: PanelId) => {
54     dispatcher.dispatch(setPanelAction(panelId));
55   },
56   inventoryElementsActions: createInventoryElementsActions(dispatcher.dispatch),
57   navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)),
58   updateInventoryTree: (mountId: string, searchTerm?: string) => dispatcher.dispatch(updateInventoryTreeAsyncAction(mountId, searchTerm)),
59 });
60
61 let treeViewInitialSorted = false;
62 let inventoryInitialSorted = false;
63
64 const ConnectedElementTable = MaterialTable as MaterialTableCtorType<NetworkElementConnection>;
65
66 type DashboardComponentProps = RouteComponentProps & Connect<typeof mapProps, typeof mapDispatch>;
67 type DashboardComponentState = {
68   refreshInventoryEditorMode: RefreshInventoryDialogMode
69 }
70
71 class DashboardSelectorComponent extends React.Component<DashboardComponentProps, DashboardComponentState> {
72   constructor(props: DashboardComponentProps) {
73     super(props);
74
75     this.state = {
76       refreshInventoryEditorMode: RefreshInventoryDialogMode.None
77     };
78   }
79
80   private onHandleTabChange = (event: React.SyntheticEvent, newValue: PanelId) => {
81     this.onTogglePanel(newValue);
82   }
83
84   private onTogglePanel = (panelId: PanelId) => {
85     const nextActivePanel = panelId;
86     this.props.switchActivePanel(nextActivePanel);
87
88     switch (nextActivePanel) {
89       case 'InventoryElementsTable':
90
91         if (!inventoryInitialSorted) {
92           this.props.inventoryElementsActions.onHandleExplicitRequestSort("nodeId", "asc");
93           inventoryInitialSorted = true;
94         } else {
95           this.props.inventoryElementsActions.onRefresh();
96
97         }
98         break;
99       case 'TreeviewTable':
100         if (!treeViewInitialSorted) {
101           this.props.connectedNetworkElementsActions.onHandleExplicitRequestSort("nodeId", "asc");
102           treeViewInitialSorted = true;
103         } else {
104           this.props.connectedNetworkElementsActions.onRefresh();
105         }
106         break;
107       case null:
108         // do nothing if all panels are closed
109         break;
110       default:
111         console.warn("Unknown nextActivePanel [" + nextActivePanel + "] in connectView");
112         break;
113     }
114
115   };
116
117   getContextMenu = (rowData: InventoryType) => {
118     return [
119       <MenuItem aria-label={"inventory-button"} onClick={event => { this.props.updateInventoryTree(rowData.nodeId, rowData.uuid); this.props.navigateToApplication("inventory", rowData.nodeId) }}><Typography>View in Treeview</Typography></MenuItem>,
120     ];
121
122   }
123
124   render() {
125
126     const refreshInventoryAction = {
127       icon: Refresh, tooltip: 'Refresh Inventory', ariaLabel: 'refresh', onClick: () => {
128         this.setState({
129           refreshInventoryEditorMode: RefreshInventoryDialogMode.RefreshInventoryTable
130         });
131       }
132     };
133     const { panelId: activePanelId } = this.props;
134     return (
135       <>
136         <AppBar enableColorOnDark position="static">
137           <Tabs indicatorColor="secondary" textColor="inherit" value={activePanelId} onChange={this.onHandleTabChange} aria-label="inventory-app-tabs">
138             <Tab label="Table View" value="InventoryElementsTable" aria-label="table-tab" />
139             <Tab label="Tree view" value="TreeviewTable" aria-label="treeview-tab" />
140           </Tabs>
141         </AppBar>
142
143         {
144
145           activePanelId === "InventoryElementsTable" &&
146           <>
147             <InventoryTable stickyHeader title="Inventory" idProperty="_id" tableId="inventory-table" customActionButtons={[refreshInventoryAction]} columns={[
148               { property: "nodeId", title: "Node Name" },
149               { property: "manufacturerIdentifier", title: "Manufacturer" },
150               { property: "parentUuid", title: "Parent" },
151               { property: "uuid", title: "Name" },
152               { property: "serial", title: "Serial" },
153               { property: "version", title: "Version" },
154               { property: "date", title: "Date" },
155               { property: "description", title: "Description" },
156               { property: "partTypeId", title: "Part Type Id" },
157               { property: "modelIdentifier", title: "Model Identifier" },
158               { property: "typeName", title: "Type" },
159               { property: "treeLevel", title: "Containment Level" },
160             ]}  {...this.props.inventoryElementsActions} {...this.props.inventoryElementsProperties}
161               createContextMenu={rowData => {
162
163                 return this.getContextMenu(rowData);
164               }} >
165             </InventoryTable>
166             <RefreshInventoryDialog
167               mode={this.state.refreshInventoryEditorMode}
168               onClose={this.onCloseRefreshInventoryDialog}
169             />
170           </>
171
172         }
173         {
174           activePanelId === "TreeviewTable" &&
175
176           <ConnectedElementTable stickyHeader tableId="treeview-networkelement-selection-table"
177             onHandleClick={(e, row) => {
178               this.props.navigateToApplication("inventory", row.nodeId);
179               this.props.updateInventoryTree(row.nodeId, '*');
180             }}
181             columns={[
182               { property: "nodeId", title: "Node Name", type: ColumnType.text },
183               { property: "isRequired", title: "Required", type: ColumnType.boolean },
184               { property: "host", title: "Host", type: ColumnType.text },
185               { property: "port", title: "Port", type: ColumnType.numeric },
186               { property: "coreModelCapability", title: "Core Model", type: ColumnType.text },
187               { property: "deviceType", title: "Type", type: ColumnType.text },
188             ]} idProperty="id" {...this.props.connectedNetworkElementsActions} {...this.props.connectedNetworkElementsProperties} asynchronus >
189           </ConnectedElementTable>
190         }
191       </>
192     );
193   }
194
195   private onCloseRefreshInventoryDialog = () => {
196     this.setState({
197       refreshInventoryEditorMode: RefreshInventoryDialogMode.None
198     });
199   }
200   componentDidMount() {
201
202     if (this.props.panelId === null) { //set default tab if none is set
203       this.onTogglePanel("InventoryElementsTable");
204     }
205
206   }
207 }
208
209 export const Dashboard = withRouter(connect(mapProps, mapDispatch)(DashboardSelectorComponent));
210 export default Dashboard;
211