aed81993be9af2621a0794bb987bad077edfb009
[ccsdk/features.git] / sdnr / wt / odlux / apps / connectApp / src / components / requiredNetworkElements.tsx
1 import * as React from 'react';
2 import { Theme, createStyles, withStyles, WithStyles } from '@material-ui/core/styles';
3
4 import AddIcon from '@material-ui/icons/Add';
5 import LinkIcon from '@material-ui/icons/Link';
6 import LinkOffIcon from '@material-ui/icons/LinkOff';
7 import RemoveIcon from '@material-ui/icons/RemoveCircleOutline';
8
9 import Button from '@material-ui/core/Button';
10 import IconButton from '@material-ui/core/IconButton';
11
12 import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
13 import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
14 import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect';
15 import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
16
17 import { RequiredNetworkElementType } from '../models/requiredNetworkElements';
18 import { createRequiredNetworkElementsActions, createRequiredNetworkElementsProperties } from '../handlers/requiredNetworkElementsHandler';
19
20 import EditNetworkElementDialog, { EditNetworkElementDialogMode } from './editNetworkElementDialog';
21 import { Tooltip } from '@material-ui/core';
22 import { NetworkElementBaseType } from 'models/networkElementBase';
23
24 const styles = (theme: Theme) => createStyles({
25   connectionStatusConnected: {
26     color: 'darkgreen',
27   },
28   connectionStatusConnecting: {
29     color: 'blue',
30   },
31   connectionStatusDisconnected: {
32     color: 'red',
33   },
34   button: {
35     margin: 0,
36     padding: "6px 6px",
37     minWidth: 'unset'
38   },
39   spacer: {
40     marginLeft: theme.spacing.unit,
41     marginRight: theme.spacing.unit,
42     display: "inline"
43   }
44 });
45
46 const mapProps = (state: IApplicationStoreState) => ({
47   requiredNetworkElementsProperties: createRequiredNetworkElementsProperties(state),
48   mountedNetworkElements: state.connect.mountedNetworkElements
49 });
50
51 const mapDispatch = (dispatcher: IDispatcher) => ({
52   requiredNetworkElementsActions: createRequiredNetworkElementsActions(dispatcher.dispatch),
53   navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)),
54 });
55
56 type RequiredNetworkElementsListComponentProps = WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>;
57 type RequiredNetworkElementsListComponentState = {
58   networkElementToEdit: RequiredNetworkElementType,
59   networkElementEditorMode: EditNetworkElementDialogMode
60 }
61
62 const emptyRequireNetworkElement = { mountId: '', host: '', port: 0 };
63
64 const RequiredNetworkElementTable = MaterialTable as MaterialTableCtorType<RequiredNetworkElementType>;
65
66 export class RequiredNetworkElementsListComponent extends React.Component<RequiredNetworkElementsListComponentProps, RequiredNetworkElementsListComponentState> {
67
68   constructor(props: RequiredNetworkElementsListComponentProps) {
69     super(props);
70
71     this.state = {
72       networkElementToEdit: emptyRequireNetworkElement,
73       networkElementEditorMode: EditNetworkElementDialogMode.None
74     };
75   }
76
77   //  private navigationCreator
78
79   render(): JSX.Element {
80     const { classes } = this.props;
81     const { networkElementToEdit } = this.state;
82     const addRequireNetworkElementAction = {
83       icon: AddIcon, tooltip: 'Add', onClick: () => {
84         this.setState({
85           networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElementToRequiredNetworkElements,
86           networkElementToEdit: emptyRequireNetworkElement,
87         });
88       }
89     };
90     return (
91       <>
92         <RequiredNetworkElementTable customActionButtons={ [addRequireNetworkElementAction] } columns={ [
93           { property: "mountId", title: "Name", type: ColumnType.text },
94           {
95             property: "connectionStatus", title: "Connection Status", type: ColumnType.custom, disableFilter: true, disableSorting: true, customControl: ({ rowData }) => {
96               const unknownNetworkElement = this.props.mountedNetworkElements.elements.find(el => el.mountId === rowData.mountId);
97               const connectionStatus = unknownNetworkElement && unknownNetworkElement.connectionStatus || 'disconnected';
98               const cssClasses = connectionStatus === "connected"
99                 ? classes.connectionStatusConnected
100                 : connectionStatus === "disconnected"
101                   ? classes.connectionStatusDisconnected
102                   : classes.connectionStatusConnecting
103               return <div className={ cssClasses } >{ connectionStatus } </div>
104
105             }
106           },
107           { property: "host", title: "Host", type: ColumnType.text },
108           { property: "port", title: "Port", type: ColumnType.text },
109           // { property: "username", title: "Username", type: ColumnType.text },
110           // { property: "password", title: "Password", type: ColumnType.text },
111           {
112             property: "actions", title: "Actions", type: ColumnType.custom, customControl: ({ rowData }) => {
113               const unknownNetworkElement = this.props.mountedNetworkElements.elements.find(el => el.mountId === rowData.mountId);
114               const connectionStatus = unknownNetworkElement && unknownNetworkElement.connectionStatus || 'disconnected';
115               return (
116                 <>
117                   <div className={ classes.spacer }>
118                     <Tooltip title={ "Mount" } ><IconButton className={ classes.button } onClick={ event => this.onOpenMountdNetworkElementsDialog(event, rowData) }><LinkIcon /></IconButton></Tooltip>
119                     <Tooltip title={ "Unmount" } ><IconButton className={ classes.button } onClick={ event => this.onOpenUnmountdNetworkElementsDialog(event, rowData) }><LinkOffIcon /></IconButton></Tooltip>
120                     <Tooltip title={ "Remove" } ><IconButton className={ classes.button } onClick={ event => this.onOpenRemoveRequiredNetworkElementDialog(event, rowData) } ><RemoveIcon /></IconButton></Tooltip>
121                   </div>
122                   <div className={ classes.spacer }>
123                     <Tooltip title={ "Info" } ><Button className={ classes.button } >I</Button></Tooltip>
124                   </div>
125                   <div className={ classes.spacer }>
126                     <Tooltip title={ "Fault" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("fault", rowData) } >F</Button></Tooltip>
127                     <Tooltip title={ "Configure" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("configure", rowData)} >C</Button></Tooltip>
128                     <Tooltip title={ "Accounting " } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("accounting", rowData) }>A</Button></Tooltip>
129                     <Tooltip title={ "Performance" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("performance", rowData) }>P</Button></Tooltip>
130                     <Tooltip title={ "Security" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("security", rowData) }>S</Button></Tooltip>
131                   </div>
132                 </>
133               )
134             }
135           },
136         ] } idProperty="mountId" { ...this.props.requiredNetworkElementsActions } { ...this.props.requiredNetworkElementsProperties } asynchronus >
137         </RequiredNetworkElementTable>
138         <EditNetworkElementDialog
139           initialNetworkElement={ networkElementToEdit }
140           mode={ this.state.networkElementEditorMode }
141           onClose={ this.onCloseEditNetworkElementDialog }
142         />
143       </>
144     );
145   };
146
147   public componentDidMount() {
148     this.props.requiredNetworkElementsActions.onRefresh();
149   }
150
151   private onOpenRemoveRequiredNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: RequiredNetworkElementType) => {
152     this.setState({
153       networkElementToEdit: element,
154       networkElementEditorMode: EditNetworkElementDialogMode.RequiredNetworkElementToUnknownNetworkElements
155     });
156     event.preventDefault();
157     event.stopPropagation();
158   }
159
160   private onOpenUnmountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: RequiredNetworkElementType) => {
161     this.setState({
162       networkElementToEdit: element,
163       networkElementEditorMode: EditNetworkElementDialogMode.UnmountNetworkElement
164     });
165     event.preventDefault();
166     event.stopPropagation();
167   }
168
169   private onOpenMountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: RequiredNetworkElementType) => {
170     this.setState({
171       networkElementToEdit: element,
172       networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElement
173     });
174     event.preventDefault();
175     event.stopPropagation();
176   }
177
178   private onCloseEditNetworkElementDialog = () => {
179     this.setState({
180       networkElementEditorMode: EditNetworkElementDialogMode.None,
181       networkElementToEdit: emptyRequireNetworkElement,
182     });
183   }
184
185   private navigateToApplicationHandlerCreator = (applicationName: string, element: NetworkElementBaseType) => (event: React.MouseEvent<HTMLElement>) => {
186     this.props.navigateToApplication(applicationName, element.mountId);
187     event.preventDefault();
188     event.stopPropagation();
189   }
190 }
191
192 export const RequiredNetworkElementsList = withStyles(styles)(connect(mapProps, mapDispatch)(RequiredNetworkElementsListComponent));
193 export default RequiredNetworkElementsList;