From d70d7624795a9305eef1f0a6d3842d47ecd27160 Mon Sep 17 00:00:00 2001
From: Aijana Schumann <aijana.schumann@highstreet-technologies.com>
Date: Wed, 28 Jul 2021 11:19:09 +0200
Subject: ODLUX Connect App Info enhancement

Present yang capabilities in a table view instead of list

Issue-ID: SDNC-1121
Signed-off-by: Aijana Schumann <aijana.schumann@highstreet-technologies.com>
Change-Id: I4904fb132351199b57a851faf07d371fa5e575ab
---
 .../src/components/infoNetworkElementDialog.tsx    | 281 +++++++++++----------
 1 file changed, 142 insertions(+), 139 deletions(-)

(limited to 'sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx')

diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx
index df8515e58..9b71eb354 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx
@@ -15,142 +15,145 @@
  * the License.
  * ============LICENSE_END==========================================================================
  */
-import * as React from 'react';
-
-import Button from '@material-ui/core/Button';
-import Dialog from '@material-ui/core/Dialog';
-import DialogActions from '@material-ui/core/DialogActions';
-import DialogContent from '@material-ui/core/DialogContent';
-import DialogContentText from '@material-ui/core/DialogContentText';
-import DialogTitle from '@material-ui/core/DialogTitle';
-import Table from '@material-ui/core/Table';
-import TableBody from '@material-ui/core/TableBody';
-import TableCell from '@material-ui/core/TableCell';
-import TableHead from '@material-ui/core/TableHead';
-import TableRow from '@material-ui/core/TableRow';
-import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
-
-import { NetworkElementConnection } from '../models/networkElementConnection';
-import { AvailableCapabilities } from '../models/yangCapabilitiesType'
-
-export enum InfoNetworkElementDialogMode {
-  None = "none",
-  InfoNetworkElement = "infoNetworkElement"
-}
-
-const mapDispatch = (dispatcher: IDispatcher) => ({
-});
-
-type DialogSettings = {
-  dialogTitle: string,
-  dialogDescription: string,
-  cancelButtonText: string,
-}
-
-const settings: { [key: string]: DialogSettings } = {
-  [InfoNetworkElementDialogMode.None]: {
-    dialogTitle: "",
-    dialogDescription: "",
-    cancelButtonText: "",
-  },
-  [InfoNetworkElementDialogMode.InfoNetworkElement]: {
-    dialogTitle: "Yang capabilities of the network element",
-    dialogDescription: "Available capabilities of the network element",
-    cancelButtonText: "OK",
-  }
-}
-
-type InfoNetworkElementDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
-  mode: InfoNetworkElementDialogMode;
-  initialNetworkElement: NetworkElementConnection;
-  onClose: () => void;
-};
-
-type InfoNetworkElementDialogComponentState = NetworkElementConnection;
-
-class InfoNetworkElementDialogComponent extends React.Component<InfoNetworkElementDialogComponentProps, InfoNetworkElementDialogComponentState> {
-  constructor(props: InfoNetworkElementDialogComponentProps) {
-    super(props);
-
-    this.state = {
-      nodeId: this.props.initialNetworkElement.nodeId,
-      isRequired: false,
-      host: this.props.initialNetworkElement.host,
-      port: this.props.initialNetworkElement.port,
-    };
-  }
-
-  render(): JSX.Element {
-    const setting = settings[this.props.mode];
-    const availableCapabilities = this.props.state.connect.elementInfo.elementInfo["netconf-node-topology:available-capabilities"]["available-capability"];
-    let yangCapabilities: AvailableCapabilities[] = [];
-    
-    availableCapabilities.forEach(value => {
-      const capabilty = value.capability;
-      const indexRevision = capabilty.indexOf("revision=");
-      const indexModule = capabilty.indexOf(")", indexRevision);
-      if (indexRevision > 0 && indexModule > 0) {
-        yangCapabilities.push({
-          module: capabilty.substr(indexModule + 1),
-          revision: capabilty.substr(indexRevision + 9, 10)
-        });
-      }
-    });
-
-    yangCapabilities = yangCapabilities.sort((a,b) => a.module === b.module ? 0 : a.module > b.module ? 1 : -1);
-
-    return (
-      <Dialog open={this.props.mode !== InfoNetworkElementDialogMode.None}>
-        <DialogTitle id="form-dialog-title">{setting.dialogTitle}</DialogTitle>
-        <DialogContent>
-          <DialogContentText>
-            {setting.dialogDescription + " " + this.state.nodeId}
-          </DialogContentText>
-          <Table aria-label="yang-capabilities-table">
-            <TableHead>
-              <TableRow>
-                <TableCell align="right">S.No</TableCell>
-                <TableCell >Module</TableCell>
-                <TableCell >Revision</TableCell>
-              </TableRow>
-            </TableHead>
-            <TableBody>
-              {yangCapabilities.map((yang, index) => (
-                <TableRow aria-label="yang-capabilities-row">
-                  <TableCell>{index + 1}</TableCell>
-                  <TableCell aria-label="yang-module"><a href={`/yang-schema/${yang.module}`} target={"_blank"}> {yang.module} </a></TableCell>
-                  <TableCell aria-label="yang-revision">{yang.revision}</TableCell>
-                </TableRow>
-              ))}
-            </TableBody>
-          </Table>
-        </DialogContent>
-        <DialogActions>
-          <Button aria-label="ok-button" onClick={(event) => {
-            this.onCancel();
-            event.preventDefault();
-            event.stopPropagation();
-          }} color="secondary"> {setting.cancelButtonText} </Button>
-        </DialogActions>
-      </Dialog>
-    )
-  }
-
-  private onCancel = () => {
-    this.props.onClose();
-  }
-
-  static getDerivedStateFromProps(props: InfoNetworkElementDialogComponentProps, state: InfoNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection }): InfoNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection } {
-    if (props.initialNetworkElement !== state._initialNetworkElement) {
-      state = {
-        ...state,
-        ...props.initialNetworkElement,
-        _initialNetworkElement: props.initialNetworkElement,
-      };
-    }
-    return state;
-  }
-}
-
-export const InfoNetworkElementDialog = connect(undefined, mapDispatch)(InfoNetworkElementDialogComponent);
-export default InfoNetworkElementDialog;
\ No newline at end of file
+ import * as React from 'react';
+
+ import Button from '@material-ui/core/Button';
+ import Dialog from '@material-ui/core/Dialog';
+ import DialogActions from '@material-ui/core/DialogActions';
+ import DialogTitle from '@material-ui/core/DialogTitle';
+ import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
+ import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+ 
+ import { NetworkElementConnection } from '../models/networkElementConnection';
+ import { AvailableCapabilities } from '../models/yangCapabilitiesType'
+ 
+ export enum InfoNetworkElementDialogMode {
+   None = "none",
+   InfoNetworkElement = "infoNetworkElement"
+ }
+ 
+ const mapDispatch = (dispatcher: IDispatcher) => ({
+ });
+ 
+ 
+ const InfoElementTable = MaterialTable as MaterialTableCtorType<AvailableCapabilities>;
+ 
+ type DialogSettings = {
+   dialogTitle: string,
+   dialogDescription: string,
+   cancelButtonText: string,
+ }
+ 
+ const settings: { [key: string]: DialogSettings } = {
+   [InfoNetworkElementDialogMode.None]: {
+     dialogTitle: "",
+     dialogDescription: "",
+     cancelButtonText: "",
+   },
+   [InfoNetworkElementDialogMode.InfoNetworkElement]: {
+     dialogTitle: "Yang capabilities of the network element",
+     dialogDescription: "",
+     cancelButtonText: "OK",
+   }
+ }
+ 
+ type InfoNetworkElementDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+   mode: InfoNetworkElementDialogMode;
+   initialNetworkElement: NetworkElementConnection;
+   onClose: () => void;
+ };
+ 
+ type InfoNetworkElementDialogComponentState = NetworkElementConnection;
+ 
+ class InfoNetworkElementDialogComponent extends React.Component<InfoNetworkElementDialogComponentProps, InfoNetworkElementDialogComponentState> {
+   constructor(props: InfoNetworkElementDialogComponentProps) {
+     super(props);
+ 
+     this.state = {
+       nodeId: this.props.initialNetworkElement.nodeId,
+       isRequired: false,
+       host: this.props.initialNetworkElement.host,
+       port: this.props.initialNetworkElement.port,
+     };
+   }
+ 
+   render(): JSX.Element {
+     const setting = settings[this.props.mode];
+     const availableCapabilities = this.props.state.connect.elementInfo.elementInfo["netconf-node-topology:available-capabilities"]["available-capability"];
+     let yangFeatures = this.props.state.connect.elementFeatureInfo.elementFeatureInfo;
+     let yangCapabilities: AvailableCapabilities[] = [];
+     
+     availableCapabilities.forEach(value => {
+       const capabilty = value.capability;
+       const indexRevision = capabilty.indexOf("revision=");
+       const indexModule = capabilty.indexOf(")", indexRevision);
+       if (indexRevision > 0 && indexModule > 0) {
+         let moduleName = capabilty.substr(indexModule + 1);
+         let ModuleFeaturesList;
+         for(let index = 0; index < yangFeatures.length; index++) {
+           if(yangFeatures[index].name == moduleName) {
+             ModuleFeaturesList = yangFeatures[index].feature? yangFeatures[index].feature : null;
+             break;
+           }
+         }
+         const featuresListCommaSeparated= ModuleFeaturesList? ModuleFeaturesList.toString() : ""
+         let featuresList = featuresListCommaSeparated.replace(',',', ');
+ 
+         yangCapabilities.push({
+           module: moduleName,
+           revision: capabilty.substr(indexRevision + 9, 10),
+           features: featuresList 
+          });
+       }
+     });
+ 
+     yangCapabilities = yangCapabilities.sort((a,b) => a.module === b.module ? 0 : a.module > b.module ? 1 : -1);
+ 
+     return (
+       <>
+         <Dialog open={this.props.mode !== InfoNetworkElementDialogMode.None}  >
+           <DialogTitle id="form-dialog-title">{setting.dialogTitle + ' - ' + this.state.nodeId}</DialogTitle>
+           <InfoElementTable stickyHeader tableId="info-element-table" asynchronus columns={[
+             { property: "module", title: "Module", type: ColumnType.text, width:900 },
+             {
+               property: "revision", title: "Revision", type: ColumnType.custom, customControl: ({ rowData }) => {
+                 return (
+                   <div>
+                     <a href={'/yang-schema/' + rowData.module + '/' + rowData.revision} target="_blank"  > {rowData.revision} </a>
+                   </div>
+                 )
+               }
+             },
+             { property: "features", title: "Features", type: ColumnType.text, width:500 },
+           ]} idProperty="id" rows={yangCapabilities}  >
+           </InfoElementTable>
+           <DialogActions>
+             <Button aria-label="ok-button" onClick={(event) => {
+               this.onCancel();
+               event.preventDefault();
+               event.stopPropagation();
+             }} color="secondary"> {setting.cancelButtonText} </Button>
+           </DialogActions>
+         </Dialog>
+       </>
+     )
+   }
+ 
+   private onCancel = () => {
+     this.props.onClose();
+   }
+ 
+   static getDerivedStateFromProps(props: InfoNetworkElementDialogComponentProps, state: InfoNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection }): InfoNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection } {
+     if (props.initialNetworkElement !== state._initialNetworkElement) {
+       state = {
+         ...state,
+         ...props.initialNetworkElement,
+         _initialNetworkElement: props.initialNetworkElement,
+       };
+     }
+     return state;
+   }
+ }
+ 
+ export const InfoNetworkElementDialog = connect(undefined, mapDispatch)(InfoNetworkElementDialogComponent);
+ export default InfoNetworkElementDialog;
\ No newline at end of file
-- 
cgit 1.2.3-korg

