update odlux and featureaggregator
[ccsdk/features.git] / sdnr / wt / odlux / apps / connectApp / src / components / networkElements.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 { Theme, createStyles, withStyles, WithStyles } from '@material-ui/core/styles';
20
21 import AddIcon from '@material-ui/icons/Add';
22 import LinkIcon from '@material-ui/icons/Link';
23 import LinkOffIcon from '@material-ui/icons/LinkOff';
24 import RemoveIcon from '@material-ui/icons/RemoveCircleOutline';
25 import EditIcon from '@material-ui/icons/Edit';
26 import Info from '@material-ui/icons/Info';
27 import ComputerIcon from '@material-ui/icons/Computer';
28
29 import Button from '@material-ui/core/Button';
30 import IconButton from '@material-ui/core/IconButton';
31 import Tooltip from '@material-ui/core/Tooltip';
32
33 import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
34 import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
35 import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect';
36 import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
37
38 import { createNetworkElementsActions, createNetworkElementsProperties } from '../handlers/networkElementsHandler';
39
40 import { NetworkElementConnection } from '../models/networkElementConnection';
41 import EditNetworkElementDialog, { EditNetworkElementDialogMode } from './editNetworkElementDialog';
42
43 import InfoNetworkElementDialog, { InfoNetworkElementDialogMode } from './infoNetworkElementDialog';
44 import { loadAllInfoElementAsync } from '../actions/infoNetworkElementActions';
45 import { TopologyNode } from '../models/topologyNetconf';
46
47 const styles = (theme: Theme) => createStyles({
48   connectionStatusConnected: {
49     color: 'darkgreen',
50   },
51   connectionStatusConnecting: {
52     color: 'blue',
53   },
54   connectionStatusDisconnected: {
55     color: 'red',
56   },
57   button: {
58     margin: 0,
59     padding: "6px 6px",
60     minWidth: 'unset'
61   },
62   spacer: {
63     marginLeft: theme.spacing(1),
64     marginRight: theme.spacing(1),
65     display: "inline"
66   }
67 });
68
69 const mapProps = (state: IApplicationStoreState) => ({
70   networkElementsProperties: createNetworkElementsProperties(state),
71 });
72
73 const mapDispatch = (dispatcher: IDispatcher) => ({
74   networkElementsActions: createNetworkElementsActions(dispatcher.dispatch),
75   navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)),
76   networkElementInfo: async (nodeId: string) => await dispatcher.dispatch(loadAllInfoElementAsync(nodeId)),
77 });
78
79 type NetworkElementsListComponentProps = WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>;
80 type NetworkElementsListComponentState = {
81   networkElementToEdit: NetworkElementConnection,
82   networkElementEditorMode: EditNetworkElementDialogMode,
83   infoNetworkElementEditorMode: InfoNetworkElementDialogMode,
84   elementInfo: TopologyNode | null
85 }
86
87 const emptyRequireNetworkElement: NetworkElementConnection = { id: "", nodeId: "", host: "", port: 0, status: "Disconnected", isRequired: false };
88
89 const NetworkElementTable = MaterialTable as MaterialTableCtorType<NetworkElementConnection>;
90
91 export class NetworkElementsListComponent extends React.Component<NetworkElementsListComponentProps, NetworkElementsListComponentState> {
92
93   constructor(props: NetworkElementsListComponentProps) {
94     super(props);
95
96     this.state = {
97       networkElementToEdit: emptyRequireNetworkElement,
98       networkElementEditorMode: EditNetworkElementDialogMode.None,
99       elementInfo: null,
100       infoNetworkElementEditorMode: InfoNetworkElementDialogMode.None
101     };
102   }
103
104   //  private navigationCreator
105
106   render(): JSX.Element {
107     const { classes } = this.props;
108     const { networkElementToEdit } = this.state;
109     const addRequireNetworkElementAction = {
110       icon: AddIcon, tooltip: 'Add', onClick: () => {
111         this.setState({
112           networkElementEditorMode: EditNetworkElementDialogMode.AddNewNetworkElement,
113           networkElementToEdit: emptyRequireNetworkElement,
114         });
115       }
116     };
117     let counter = 0;
118     return (
119       <>
120         <NetworkElementTable tableId="network-element-table" customActionButtons={[addRequireNetworkElementAction]} columns={[
121           { property: "nodeId", title: "Node Name", type: ColumnType.text },
122           { property: "isRequired", title: "Required", type: ColumnType.boolean },
123           { property: "status", title: "Connection Status", type: ColumnType.text },
124           { property: "host", title: "Host", type: ColumnType.text },
125           { property: "port", title: "Port", type: ColumnType.numeric },
126           { property: "coreModelCapability", title: "Core Model", type: ColumnType.text },
127           { property: "deviceType", title: "Type", type: ColumnType.text },
128           {
129             property: "actions", title: "Actions", type: ColumnType.custom, customControl: ({ rowData }) => {
130               counter++;
131               return (
132                 <>
133                   <div className={classes.spacer}>
134                     {
135                       rowData.webUri && <Tooltip title={"Web Client"} ><IconButton aria-label={"web-client-button-" + counter} className={classes.button} onClick={event => { console.log(rowData); window.open(rowData.webUri, "_blank") }}><ComputerIcon /></IconButton></Tooltip>
136                     }
137                     <Tooltip title={"Mount"} >
138                       <IconButton aria-label={"mount-button-" + counter} className={classes.button} onClick={event => this.onOpenMountdNetworkElementsDialog(event, rowData)} >
139                         <LinkIcon /></IconButton>
140                     </Tooltip>
141                     <Tooltip title={"Unmount"} >
142                       <IconButton aria-label={"unmount-button-" + counter} className={classes.button} onClick={event => this.onOpenUnmountdNetworkElementsDialog(event, rowData)} >
143                         <LinkOffIcon /></IconButton>
144                     </Tooltip>
145                     <Tooltip title={"Info"} ><IconButton aria-label={"info-button-" + counter} className={classes.button} onClick={event => this.onOpenInfoNetworkElementDialog(event, rowData)} disabled={rowData.status === "Connecting" || rowData.status === "Disconnected"} >
146                       <Info /></IconButton>
147                     </Tooltip>
148                     <Tooltip title={"Edit"} ><IconButton aria-label={"edit-button-" + counter} className={classes.button} onClick={event => this.onOpenEditNetworkElementDialog(event, rowData)} ><EditIcon /></IconButton></Tooltip>
149                     <Tooltip title={"Remove"} ><IconButton aria-label={"remove-button-" + counter} className={classes.button} onClick={event => this.onOpenRemoveNetworkElementDialog(event, rowData)} ><RemoveIcon /></IconButton></Tooltip>
150                   </div>
151                   <div className={classes.spacer}>
152                     <Tooltip title={"Inventory"} ><Button aria-label={"inventory-button-" + counter} className={classes.button} onClick={this.navigateToApplicationHandlerCreator("inventory", rowData)} >I</Button></Tooltip>
153                   </div>
154                   <div className={classes.spacer}>
155                     <Tooltip title={"Fault"} ><Button aria-label={"fault-button-" + counter} className={classes.button} onClick={this.navigateToApplicationHandlerCreator("fault", rowData)} >F</Button></Tooltip>
156                     <Tooltip title={"Configure"} ><Button aria-label={"configure-button-" + counter} className={classes.button} onClick={this.navigateToApplicationHandlerCreator("configuration", rowData)} >C</Button></Tooltip>
157                     <Tooltip title={"Accounting "} ><Button className={classes.button} onClick={this.navigateToApplicationHandlerCreator("accounting", rowData)} disabled={true} >A</Button></Tooltip>
158                     <Tooltip title={"Performance"} ><Button aria-label={"performance-button-" + counter} className={classes.button} onClick={this.navigateToApplicationHandlerCreator("performanceHistory", rowData)}>P</Button></Tooltip>
159                     <Tooltip title={"Security"} ><Button className={classes.button} onClick={this.navigateToApplicationHandlerCreator("security", rowData)} disabled={true} >S</Button></Tooltip>
160                   </div>
161                 </>
162               )
163             }
164           },
165         ]} idProperty="id" {...this.props.networkElementsActions} {...this.props.networkElementsProperties} asynchronus >
166         </NetworkElementTable>
167         <EditNetworkElementDialog
168           initialNetworkElement={networkElementToEdit}
169           mode={this.state.networkElementEditorMode}
170           onClose={this.onCloseEditNetworkElementDialog}
171         />
172         <InfoNetworkElementDialog
173           initialNetworkElement={networkElementToEdit}
174           mode={this.state.infoNetworkElementEditorMode}
175           onClose={this.onCloseInfoNetworkElementDialog}
176         />
177       </>
178     );
179   };
180
181   public componentDidMount() {
182     this.props.networkElementsActions.onRefresh();
183   }
184
185   private onOpenRemoveNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
186     this.setState({
187       networkElementToEdit: element,
188       networkElementEditorMode: EditNetworkElementDialogMode.RemoveNetworkElement
189     });
190     event.preventDefault();
191     event.stopPropagation();
192   }
193
194   private onOpenEditNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
195     this.setState({
196       networkElementToEdit: {
197         nodeId: element.nodeId,
198         isRequired: element.isRequired,
199         host: element.host,
200         port: element.port,
201         username: element.username,
202         password: element.password,
203       },
204       networkElementEditorMode: EditNetworkElementDialogMode.EditNetworkElement
205     });
206     event.preventDefault();
207     event.stopPropagation();
208   }
209
210   private onOpenUnmountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
211     this.setState({
212       networkElementToEdit: element,
213       networkElementEditorMode: EditNetworkElementDialogMode.UnmountNetworkElement
214     });
215     event.preventDefault();
216     event.stopPropagation();
217   }
218
219   private onOpenMountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
220     this.setState({
221       networkElementToEdit: element,
222       networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElement
223     });
224     event.preventDefault();
225     event.stopPropagation();
226   }
227
228   private onOpenInfoNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
229     this.props.networkElementInfo(element.nodeId);
230     this.setState({
231       networkElementToEdit: element,
232       infoNetworkElementEditorMode: InfoNetworkElementDialogMode.InfoNetworkElement,
233     });
234     event.preventDefault();
235     event.stopPropagation();
236   }
237
238   private onCloseEditNetworkElementDialog = () => {
239     this.setState({
240       networkElementEditorMode: EditNetworkElementDialogMode.None,
241       networkElementToEdit: emptyRequireNetworkElement,
242     });
243   }
244   private onCloseInfoNetworkElementDialog = () => {
245     this.setState({
246       infoNetworkElementEditorMode: InfoNetworkElementDialogMode.None,
247       networkElementToEdit: emptyRequireNetworkElement,
248     });
249   }
250
251   private navigateToApplicationHandlerCreator = (applicationName: string, element: NetworkElementConnection) => (event: React.MouseEvent<HTMLElement>) => {
252     this.props.navigateToApplication(applicationName, element.nodeId);
253     event.preventDefault();
254     event.stopPropagation();
255   }
256 }
257
258 export const NetworkElementsList = withStyles(styles)(connect(mapProps, mapDispatch)(NetworkElementsListComponent));
259 export default NetworkElementsList;