diff options
author | Aijana Schumann <aijana.schumann@highstreet-technologies.com> | 2021-07-28 11:19:09 +0200 |
---|---|---|
committer | Aijana Schumann <aijana.schumann@highstreet-technologies.com> | 2021-07-28 11:19:09 +0200 |
commit | d70d7624795a9305eef1f0a6d3842d47ecd27160 (patch) | |
tree | 5324c4484be5a94d2a8f2cebb8035792a6073d7b /sdnr/wt/odlux/apps/connectApp/src/components | |
parent | 2aa3a5dd6c190bf0a6c398bf7bf69e359eff2f9d (diff) |
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
Diffstat (limited to 'sdnr/wt/odlux/apps/connectApp/src/components')
-rw-r--r-- | sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx | 281 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx | 14 |
2 files changed, 151 insertions, 144 deletions
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 diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx index 84a22a99a..73706f678 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx @@ -36,12 +36,12 @@ import { NavigateToApplication } from '../../../../framework/src/actions/navigat import { createNetworkElementsActions, createNetworkElementsProperties } from '../handlers/networkElementsHandler'; import { NetworkElementConnection } from '../models/networkElementConnection'; -import { TopologyNode } from '../models/topologyNetconf'; +import { ModuleSet, TopologyNode } from '../models/topologyNetconf'; import EditNetworkElementDialog, { EditNetworkElementDialogMode } from './editNetworkElementDialog'; import RefreshNetworkElementsDialog, { RefreshNetworkElementsDialogMode } from './refreshNetworkElementsDialog'; import InfoNetworkElementDialog, { InfoNetworkElementDialogMode } from './infoNetworkElementDialog'; -import { loadAllInfoElementAsync } from '../actions/infoNetworkElementActions'; +import { loadAllInfoElementAsync, loadAllInfoElementFeaturesAsync } from '../actions/infoNetworkElementActions'; import { connectService } from '../services/connectService'; import { getAccessPolicyByUrl } from '../../../../framework/src/services/restService'; @@ -92,6 +92,7 @@ const mapDispatch = (dispatcher: IDispatcher) => ({ networkElementsActions: createNetworkElementsActions(dispatcher.dispatch), navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)), networkElementInfo: async (nodeId: string) => await dispatcher.dispatch(loadAllInfoElementAsync(nodeId)), + networkElementFeaturesInfo: async (nodeId: string) => await dispatcher.dispatch(loadAllInfoElementFeaturesAsync(nodeId)) }); type NetworkElementsListComponentProps = WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>; @@ -100,7 +101,8 @@ type NetworkElementsListComponentState = { networkElementEditorMode: EditNetworkElementDialogMode, refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode, infoNetworkElementEditorMode: InfoNetworkElementDialogMode, - elementInfo: TopologyNode | null + elementInfo: TopologyNode | null, + elementInfoFeature: ModuleSet | null } const emptyRequireNetworkElement: NetworkElementConnection = { id: "", nodeId: "", host: "", port: 0, status: "Disconnected", isRequired: false }; @@ -117,6 +119,7 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement networkElementEditorMode: EditNetworkElementDialogMode.None, refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.None, elementInfo: null, + elementInfoFeature:null, infoNetworkElementEditorMode: InfoNetworkElementDialogMode.None }; } @@ -164,7 +167,7 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement const canAdd = true; const addRequireNetworkElementAction = { - icon: AddIcon, tooltip: 'Add', onClick: () => { + icon: AddIcon, tooltip: 'Add', ariaLabel:"add-element", onClick: () => { this.setState({ networkElementEditorMode: EditNetworkElementDialogMode.AddNewNetworkElement, networkElementToEdit: emptyRequireNetworkElement, @@ -173,7 +176,7 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement }; const refreshNetworkElementsAction = { - icon: Refresh, tooltip: 'Refresh Network Elements table', onClick: () => { + icon: Refresh, tooltip: 'Refresh Network Elements table', ariaLabel:'refresh', onClick: () => { this.setState({ refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.RefreshNetworkElementsTable }); @@ -266,6 +269,7 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement private onOpenInfoNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => { this.props.networkElementInfo(element.nodeId); + this.props.networkElementFeaturesInfo(element.nodeId); this.setState({ networkElementToEdit: element, infoNetworkElementEditorMode: InfoNetworkElementDialogMode.InfoNetworkElement, |