diff options
author | sai-neetha <sai-neetha.phulmali@highstreet-technologies.com> | 2023-03-20 08:05:47 +0100 |
---|---|---|
committer | highstreetherbert <herbert.eiselt@highstreet-technologies.com> | 2023-03-29 19:06:25 +0200 |
commit | 15e2d3a29b0d1a304965e34f114a911e5a7abdb3 (patch) | |
tree | 711ef5616aceb115a1081cccd152eeae0e87bc79 /sdnr/wt/odlux/apps/connectApp/src | |
parent | ac5e2dc8f1ee4d5549f7260374e8164d52b07f55 (diff) |
Odlux Update
Add eslint and custom icons update
Issue-ID: CCSDK-3871
Signed-off-by: sai-neetha <sai-neetha.phulmali@highstreet-technologies.com>
Change-Id: If6b676128cc9cff0437a5dc54f85eaafd3b8c586
Signed-off-by: highstreetherbert <herbert.eiselt@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wt/odlux/apps/connectApp/src')
28 files changed, 792 insertions, 790 deletions
diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts index 26aa8d2d7..948f2aada 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts @@ -1,5 +1,3 @@ -// update action erstellen, die unterscheiden kann, ob die eine oder die andere Ansicht gerade aktive ist und diese katualisiert. -// Diese action wird dann bei jeder aktualisierung in den anderen Actions und bei eintreffen von notifikationen verwendet. /** * ============LICENSE_START======================================================================== @@ -19,16 +17,22 @@ * ============LICENSE_END========================================================================== */ +/** + * Create an update action that can distinguish whether one or the other view is currently active and update it. + * This action is then used for each update in the other actions and when notifications arrive. + * create an update action that can distinguish whether one or the other view is currently active and update it. + * This action is then used for each update in the other actions and when notifications arrive. + */ + import { Action } from '../../../../framework/src/flux/action'; import { Dispatch } from '../../../../framework/src/flux/store'; import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; -import { networkElementsReloadAction } from '../handlers/networkElementsHandler'; import { connectionStatusLogReloadAction } from '../handlers/connectionStatusLogHandler'; - -import { PanelId } from '../models/panelId'; +import { networkElementsReloadAction } from '../handlers/networkElementsHandler'; import { guiCutThrough } from '../models/guiCutTrough'; -import { connectService} from '../services/connectService'; +import { PanelId } from '../models/panelId'; +import { connectService } from '../services/connectService'; export class SetPanelAction extends Action { @@ -51,7 +55,7 @@ export class RemoveWebUri extends Action { export const removeWebUriAction = (nodeId: string) => { return new RemoveWebUri(nodeId); -} +}; export class SetWeburiSearchBusy extends Action { constructor(public isbusy: boolean) { @@ -68,7 +72,7 @@ export const findWebUrisForGuiCutThroughAsyncAction = (networkElementIds: string return; isBusy = true; - const { connect: { guiCutThrough, networkElements } } = getState(); + const { connect: { guiCutThrough: guiCutThrough2, networkElements } } = getState(); let notConnectedElements: string[] = []; let elementsToSearch: string[] = []; @@ -78,16 +82,16 @@ export const findWebUrisForGuiCutThroughAsyncAction = (networkElementIds: string networkElementIds.forEach(id => { const item = networkElements.rows.find((ne) => ne.id === id); if (item) { - if (item.status === "Connected") { + if (item.status === 'Connected') { // if (item.coreModelCapability !== "Unsupported") { // element is connected and is added to search list, if it doesn't exist already - const exists = guiCutThrough.searchedElements.filter(element => element.id === id).length > 0; + const exists = guiCutThrough2.searchedElements.filter(element => element.id === id).length > 0; if (!exists) { elementsToSearch.push(id); //element was found previously, but wasn't connected - if (guiCutThrough.notSearchedElements.length > 0 && guiCutThrough.notSearchedElements.includes(id)) { + if (guiCutThrough2.notSearchedElements.length > 0 && guiCutThrough2.notSearchedElements.includes(id)) { prevFoundElements.push(id); } } @@ -104,10 +108,9 @@ export const findWebUrisForGuiCutThroughAsyncAction = (networkElementIds: string // } // } // } - } - else { + } else { // element isn't connected and cannot be searched for a weburi - if (!guiCutThrough.notSearchedElements.includes(id)) { + if (!guiCutThrough2.notSearchedElements.includes(id)) { notConnectedElements.push(item.id as string); } } @@ -121,18 +124,17 @@ export const findWebUrisForGuiCutThroughAsyncAction = (networkElementIds: string } isBusy = false; -} +}; export const setPanelAction = (panelId: PanelId) => { return new SetPanelAction(panelId); -} +}; export const updateCurrentViewAsyncAction = () => (dispatch: Dispatch, getState: () => IApplicationStoreState) => { const { connect: { currentOpenPanel } } = getState(); - if (currentOpenPanel === "NetworkElements") { + if (currentOpenPanel === 'NetworkElements') { return dispatch(networkElementsReloadAction); - } - else { + } else { return dispatch(connectionStatusLogReloadAction); } }; diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/infoNetworkElementActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/infoNetworkElementActions.ts index bb744e236..120f9916f 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/actions/infoNetworkElementActions.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/actions/infoNetworkElementActions.ts @@ -15,68 +15,68 @@ * the License. * ============LICENSE_END========================================================================== */ - import { Action } from '../../../../framework/src/flux/action'; - import { Dispatch } from '../../../../framework/src/flux/store'; +import { Action } from '../../../../framework/src/flux/action'; +import { Dispatch } from '../../../../framework/src/flux/store'; - import { Module, TopologyNode } from '../models/topologyNetconf'; - import { connectService } from '../services/connectService'; +import { Module, TopologyNode } from '../models/topologyNetconf'; +import { connectService } from '../services/connectService'; - /** +/** * Represents the base action. */ - export class BaseAction extends Action { } +export class BaseAction extends Action { } - /** +/** * Represents an action causing the store to load all element Yang capabilities. */ - export class LoadAllElementInfoAction extends BaseAction { } +export class LoadAllElementInfoAction extends BaseAction { } - /** +/** * Represents an action causing the store to update element Yang capabilities. */ - export class AllElementInfoLoadedAction extends BaseAction { - /** +export class AllElementInfoLoadedAction extends BaseAction { + /** * Initialize this instance. * @param elementInfo The information of the element which is returned. */ - constructor(public elementInfo: TopologyNode | null, public error?: string) { - super(); - } - } + constructor(public elementInfo: TopologyNode | null, public error?: string) { + super(); + } +} - /** +/** * Represents an action causing the store to update element Yang capabilities Module Features. */ - export class AllElementInfoFeatureLoadedAction extends BaseAction { - /** +export class AllElementInfoFeatureLoadedAction extends BaseAction { + /** * Initialize this instance. * @param elementFeatureInfo The information of the element which is returned. */ - constructor(public elementFeatureInfo: Module[] | null | undefined, public error?: string) { - super(); - } - } + constructor(public elementFeatureInfo: Module[] | null | undefined, public error?: string) { + super(); + } +} - /** +/** * Represents an asynchronous thunk action to load all yang capabilities. */ - export const loadAllInfoElementAsync = (nodeId: string) => (dispatch: Dispatch) => { - dispatch(new LoadAllElementInfoAction()); - connectService.infoNetworkElement(nodeId).then(info => { - dispatch(new AllElementInfoLoadedAction(info)); - }, error => { - dispatch(new AllElementInfoLoadedAction(null, error)); - }); - } +export const loadAllInfoElementAsync = (nodeId: string) => (dispatch: Dispatch) => { + dispatch(new LoadAllElementInfoAction()); + connectService.infoNetworkElement(nodeId).then(info => { + dispatch(new AllElementInfoLoadedAction(info)); + }, error => { + dispatch(new AllElementInfoLoadedAction(null, error)); + }); +}; - /** +/** * Represents an asynchronous thunk action to load all yang features. */ - export const loadAllInfoElementFeaturesAsync = (nodeId: string) => (dispatch: Dispatch) => { - dispatch(new LoadAllElementInfoAction()); - connectService.infoNetworkElementFeatures(nodeId).then(infoFeatures => { - dispatch(new AllElementInfoFeatureLoadedAction(infoFeatures)); - }, error => { - dispatch(new AllElementInfoFeatureLoadedAction(null, error)); - }); - }
\ No newline at end of file +export const loadAllInfoElementFeaturesAsync = (nodeId: string) => (dispatch: Dispatch) => { + dispatch(new LoadAllElementInfoAction()); + connectService.infoNetworkElementFeatures(nodeId).then(infoFeatures => { + dispatch(new AllElementInfoFeatureLoadedAction(infoFeatures)); + }, error => { + dispatch(new AllElementInfoFeatureLoadedAction(null, error)); + }); +};
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts index 26ee7674f..11bac10e4 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts @@ -32,7 +32,7 @@ export const mountNetworkElementAsyncActionCreator = (networkElement: NetworkEle return connectService.mountNetworkElement(networkElement).then((success) => { if (success) { dispatch(updateCurrentViewAsyncAction()); - dispatch(new AddSnackbarNotification({ message: `Requesting mount [${networkElement.nodeId}]`, options: { variant: 'info' } })) + dispatch(new AddSnackbarNotification({ message: `Requesting mount [${networkElement.nodeId}]`, options: { variant: 'info' } })); } else { dispatch(new AddSnackbarNotification({ message: `Failed to mount [${networkElement.nodeId}]`, options: { variant: 'warning' } })); } diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts index 57f036e56..d22a6c645 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts @@ -30,7 +30,7 @@ export class BaseAction extends Action { } /** Represents an async thunk action creator to add an element to the network elements/nodes. */ export const addNewNetworkElementAsyncActionCreator = (element: NetworkElementConnection) => async (dispatch: Dispatch) => { - const res = await connectService.createNetworkElement({ ...element }); + await connectService.createNetworkElement({ ...element }); dispatch(updateCurrentViewAsyncAction()); dispatch(new AddSnackbarNotification({ message: `Successfully added [${element.nodeId}]`, options: { variant: 'success' } })); }; @@ -39,11 +39,10 @@ export const addNewNetworkElementAsyncActionCreator = (element: NetworkElementCo export const editNetworkElementAsyncActionCreator = (element: UpdateNetworkElement) => async (dispatch: Dispatch) => { const connectionStatus: ConnectionStatus[] = (await connectService.getNetworkElementConnectionStatus(element.id).then(ne => (ne))) || []; const currentConnectionStatus = connectionStatus[0].status; - if (currentConnectionStatus === "Disconnected") { - const res = await connectService.deleteNetworkElement(element); - } - else { - const res = await connectService.updateNetworkElement(element); + if (currentConnectionStatus === 'Disconnected') { + await connectService.deleteNetworkElement(element); + } else { + await connectService.updateNetworkElement(element); } dispatch(updateCurrentViewAsyncAction()); dispatch(new AddSnackbarNotification({ message: `Successfully modified [${element.id}]`, options: { variant: 'success' } })); @@ -52,7 +51,7 @@ export const editNetworkElementAsyncActionCreator = (element: UpdateNetworkEleme /** Represents an async thunk action creator to delete an element from network elements/nodes. */ export const removeNetworkElementAsyncActionCreator = (element: UpdateNetworkElement) => async (dispatch: Dispatch) => { - const res = await connectService.deleteNetworkElement(element); + await connectService.deleteNetworkElement(element); await dispatch(unmountNetworkElementAsyncActionCreator(element && element.id)); await dispatch(updateCurrentViewAsyncAction()); }; diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/tlsKeyActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/tlsKeyActions.ts index 1da16d9ad..65d23c439 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/actions/tlsKeyActions.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/actions/tlsKeyActions.ts @@ -17,7 +17,6 @@ */ import { Action } from '../../../../framework/src/flux/action'; import { Dispatch } from '../../../../framework/src/flux/store'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; import { TlsKeys } from '../models/networkElementConnection'; import { connectService } from '../services/connectService'; @@ -36,14 +35,14 @@ export class LoadAllTlsKeyListAction extends BaseAction { } * Represents an action causing the store to get all TLS Keys. */ export class AllTlsKeyListLoadedAction extends BaseAction { - /** + /** * Initialize this instance. * * @param gets all the tlsKey list from the database. */ - constructor(public tlsList: TlsKeys[] | null, public error?: string) { - super(); - } + constructor(public tlsList: TlsKeys[] | null, public error?: string) { + super(); + } } /** @@ -51,10 +50,10 @@ export class AllTlsKeyListLoadedAction extends BaseAction { */ export const loadAllTlsKeyListAsync = () => async (dispatch: Dispatch) => { - dispatch(new LoadAllTlsKeyListAction()); - connectService.getTlsKeys().then(TlsKeyList => { - dispatch(new AllTlsKeyListLoadedAction(TlsKeyList)); - }).catch(error => { - dispatch(new AllTlsKeyListLoadedAction(null, error)); - }); + dispatch(new LoadAllTlsKeyListAction()); + connectService.getTlsKeys().then(TlsKeyList => { + dispatch(new AllTlsKeyListLoadedAction(TlsKeyList)); + }).catch(error => { + dispatch(new AllTlsKeyListLoadedAction(null, error)); + }); }; diff --git a/sdnr/wt/odlux/apps/connectApp/src/assets/icons/connectAppIcon.svg b/sdnr/wt/odlux/apps/connectApp/src/assets/icons/connectAppIcon.svg new file mode 100644 index 000000000..5aca4fae7 --- /dev/null +++ b/sdnr/wt/odlux/apps/connectApp/src/assets/icons/connectAppIcon.svg @@ -0,0 +1,22 @@ +<!-- highstreet technologies GmbH colour scheme + Grey #565656 + LBlue #36A9E1 + DBlue #246DA2 + Green #003F2C / #006C4B + Yellw #C8D400 + Red #D81036 +--> + +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 650 650"> + +<g transform="translate(20,0) scale(1,1)"> + +<path fill="#C8D400" d="M 121.5 10 c -11.5 4.1 -19.6 12.1 -23.6 23.5 c -1.8 5 -1.9 9.2 -1.9 73.9 l 0 48.5 l 37.5 0 l 37.5 0 l 0 -45.9 c 0 -40.3 -0.4 -67.9 -1 -71.2 c -2.3 -11.9 -10.6 -22.5 -21.6 -27.6 c -7.9 -3.6 -18.8 -4.1 -26.9 -1.2 z"/> + +<path fill="#C8D400" d="M 347.9 10 c -11.5 4.1 -19.6 12.1 -23.6 23.5 c -1.8 5 -1.9 9.2 -1.9 73.9 l 0 48.5 l 37.5 0 l 37.5 0 l 0 -45.9 c 0 -40.3 -0.4 -67.9 -1 -71.2 c -2.3 -11.9 -10.6 -22.5 -21.6 -27.6 c -7.9 -3.6 -18.8 -4.1 -26.9 -1.2 z"/> + +<path fill="#565656" d="m 32.5 190 c -4.9 2.2 -9.1 6.9 -10.5 11.9 c -0.7 2.4 -1 11.9 -0.8 26.3 l 0.3 22.6 l 2.9 4.1 c 4.5 6.5 9.1 8.2 22.4 8.2 l 11.2 0 l 0 17.7 c 0 35.3 3.1 59 10.5 80.3 c 21.5 61.6 70.5 105.9 135.3 122 l 4.2 1.1 l 0 57.9 c 1 27.9 4 72.9 75 75 c 177 -5.1 344 -100.1 345 -204.1 l 1 -75 c -49 124 -165 214 -337 217.1 c -5 -0.1 -7 -3.1 -7 -7.1 l 0 -63.8 l 4.2 -1.1 c 17.1 -4.4 26.1 -7.6 39.6 -14 c 51.7 -24.6 90.3 -74.2 101.7 -130.5 c 3 -14.6 4.5 -33.9 4.5 -57.7 l 0 -17.6 l 12.3 -0.4 c 11.1 -0.3 12.7 -0.5 15.9 -2.7 c 1.9 -1.3 4.6 -4 5.9 -5.9 c 2.3 -3.5 2.4 -4.2 2.7 -26.1 c 0.2 -14.4 -0.1 -23.9 -0.8 -26.3 c -1.4 -5 -5.6 -9.7 -10.5 -11.9 c -3.8 -1.8 -12.4 -1.9 -213 -1.9 c -200.6 0 -209.2 0.1 -213 1.9 z"/> + + +</g> +</svg> diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx index b240b2419..6a8c92438 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx @@ -15,11 +15,13 @@ * the License. * ============LICENSE_END========================================================================== */ -import * as React from 'react'; -import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect'; +import React from 'react'; + +import Refresh from '@mui/icons-material/Refresh'; + +import { ColumnType, MaterialTable, MaterialTableCtorType } from '../../../../framework/src/components/material-table'; +import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect'; import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; -import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table'; -import Refresh from '@mui/icons-material/Refresh'; import { createConnectionStatusLogActions, createConnectionStatusLogProperties } from '../handlers/connectionStatusLogHandler'; import { NetworkElementConnectionLog } from '../models/networkElementConnectionLog'; @@ -37,36 +39,36 @@ const ConnectionStatusTable = MaterialTable as MaterialTableCtorType<NetworkElem type ConnectionStatusLogComponentProps = Connect<typeof mapProps, typeof mapDispatch>; type ConnectionStatusLogComponentState = { - refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode -} + refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode; +}; let initialSorted = false; -class ConnectionStatusLogComponent extends React.Component<ConnectionStatusLogComponentProps,ConnectionStatusLogComponentState > { +class ConnectionStatusLogComponent extends React.Component<ConnectionStatusLogComponentProps, ConnectionStatusLogComponentState > { constructor(props: ConnectionStatusLogComponentProps) { super(props); this.state = { - refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode.None + refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode.None, }; } render(): JSX.Element { const refreshConnectionStatusLogAction = { - icon: Refresh, tooltip: 'Refresh Connection Status Log Table',ariaLabel:'refresh', onClick: () => { + icon: Refresh, tooltip: 'Refresh Connection Status Log Table', ariaLabel:'refresh', onClick: () => { this.setState({ - refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode.RefreshConnectionStatusLogTable + refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode.RefreshConnectionStatusLogTable, }); - } + }, }; return ( <> <ConnectionStatusTable stickyHeader tableId="connection-status-table" customActionButtons={[refreshConnectionStatusLogAction]} columns={[ - { property: "timestamp", title: "Timestamp", type: ColumnType.text }, - { property: "nodeId", title: "Node ID", type: ColumnType.text }, - { property: "status", title: "Connection Status", type: ColumnType.text }, + { property: 'timestamp', title: 'Timestamp', type: ColumnType.text }, + { property: 'nodeId', title: 'Node ID', type: ColumnType.text }, + { property: 'status', title: 'Connection Status', type: ColumnType.text }, ]} idProperty="id" {...this.props.connectionStatusLogActions} {...this.props.connectionStatusLogProperties} > </ConnectionStatusTable> <RefreshConnectionStatusLogDialog @@ -75,17 +77,18 @@ class ConnectionStatusLogComponent extends React.Component<ConnectionStatusLogCo /> </> ); - }; + } private onCloseRefreshConnectionStatusLogDialog = () => { this.setState({ - refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode.None + refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode.None, }); - } + }; + componentDidMount() { if (!initialSorted) { initialSorted = true; - this.props.connectionStatusLogActions.onHandleExplicitRequestSort("timestamp", "desc"); + this.props.connectionStatusLogActions.onHandleExplicitRequestSort('timestamp', 'desc'); } else { this.props.connectionStatusLogActions.onRefresh(); } diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx index 5740ebda0..b0db63476 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx @@ -15,42 +15,43 @@ * the License. * ============LICENSE_END========================================================================== */ -import * as React from 'react'; +import React from 'react'; import Button from '@mui/material/Button'; -import TextField from '@mui/material/TextField'; import Dialog from '@mui/material/Dialog'; import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogTitle from '@mui/material/DialogTitle'; -import { FormControl, InputLabel, Select, MenuItem, Typography, Radio, RadioGroup, Options, FormLabel, FormControlLabel } from '@mui/material'; -import { loadAllTlsKeyListAsync } from '../actions/tlsKeyActions'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; +import FormControl from '@mui/material/FormControl'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import InputLabel from '@mui/material/InputLabel'; +import MenuItem from '@mui/material/MenuItem'; +import Radio from '@mui/material/Radio'; +import RadioGroup from '@mui/material/RadioGroup'; +import Select from '@mui/material/Select'; +import TextField from '@mui/material/TextField'; +import Typography from '@mui/material/Typography'; -import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect'; +import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect'; +import { removeWebUriAction } from '../actions/commonNetworkElementsActions'; +import { mountNetworkElementAsyncActionCreator, unmountNetworkElementAsyncActionCreator } from '../actions/mountedNetworkElementsActions'; import { - editNetworkElementAsyncActionCreator, - addNewNetworkElementAsyncActionCreator, - removeNetworkElementAsyncActionCreator + addNewNetworkElementAsyncActionCreator, editNetworkElementAsyncActionCreator, removeNetworkElementAsyncActionCreator, } from '../actions/networkElementsActions'; - -import { unmountNetworkElementAsyncActionCreator, mountNetworkElementAsyncActionCreator } from '../actions/mountedNetworkElementsActions'; -import { NetworkElementConnection, UpdateNetworkElement, propertyOf } from '../models/networkElementConnection'; -import { removeWebUriAction } from '../actions/commonNetworkElementsActions'; +import { loadAllTlsKeyListAsync } from '../actions/tlsKeyActions'; +import { NetworkElementConnection, propertyOf, UpdateNetworkElement } from '../models/networkElementConnection'; export enum EditNetworkElementDialogMode { - None = "none", - EditNetworkElement = "editNetworkElement", - RemoveNetworkElement = "removeNetworkElement", - AddNewNetworkElement = "addNewNetworkElement", - MountNetworkElement = "mountNetworkElement", - UnmountNetworkElement = "unmountNetworkElement", + None = 'none', + EditNetworkElement = 'editNetworkElement', + RemoveNetworkElement = 'removeNetworkElement', + AddNewNetworkElement = 'addNewNetworkElement', + MountNetworkElement = 'mountNetworkElement', + UnmountNetworkElement = 'unmountNetworkElement', } - - const mapDispatch = (dispatcher: IDispatcher) => ({ addNewNetworkElement: async (element: NetworkElementConnection) => { await dispatcher.dispatch(addNewNetworkElementAsyncActionCreator(element)); @@ -63,12 +64,12 @@ const mapDispatch = (dispatcher: IDispatcher) => ({ editNetworkElement: async (element: UpdateNetworkElement, mountElement: NetworkElementConnection) => { const values = Object.keys(element); - console.log("edit element"); + console.log('edit element'); console.log(values); //make sure properties are there in case they get renamed - const idProperty = propertyOf<UpdateNetworkElement>("id"); - const isRequiredProperty = propertyOf<UpdateNetworkElement>("isRequired"); + const idProperty = propertyOf<UpdateNetworkElement>('id'); + const isRequiredProperty = propertyOf<UpdateNetworkElement>('isRequired'); if (values.length === 2 && values.includes(idProperty as string) && values.includes(isRequiredProperty as string)) { @@ -84,92 +85,92 @@ const mapDispatch = (dispatcher: IDispatcher) => ({ await dispatcher.dispatch(removeNetworkElementAsyncActionCreator(element)); dispatcher.dispatch(removeWebUriAction(element.id)); }, - getAvailableTlsKeys: async () => await dispatcher.dispatch(loadAllTlsKeyListAsync()), + getAvailableTlsKeys: async () => dispatcher.dispatch(loadAllTlsKeyListAsync()), }); type DialogSettings = { - dialogTitle: string, - dialogDescription: string, - applyButtonText: string, - cancelButtonText: string, - enableMountIdEditor: boolean, - enableUsernameEditor: boolean, - enableExtendedEditor: boolean, -} + dialogTitle: string; + dialogDescription: string; + applyButtonText: string; + cancelButtonText: string; + enableMountIdEditor: boolean; + enableUsernameEditor: boolean; + enableExtendedEditor: boolean; +}; const settings: { [key: string]: DialogSettings } = { [EditNetworkElementDialogMode.None]: { - dialogTitle: "", - dialogDescription: "", - applyButtonText: "", - cancelButtonText: "", + dialogTitle: '', + dialogDescription: '', + applyButtonText: '', + cancelButtonText: '', enableMountIdEditor: false, enableUsernameEditor: false, enableExtendedEditor: false, }, [EditNetworkElementDialogMode.AddNewNetworkElement]: { - dialogTitle: "Add New Node", - dialogDescription: "Add this new node:", - applyButtonText: "Add node", - cancelButtonText: "Cancel", + dialogTitle: 'Add New Node', + dialogDescription: 'Add this new node:', + applyButtonText: 'Add node', + cancelButtonText: 'Cancel', enableMountIdEditor: true, enableUsernameEditor: true, enableExtendedEditor: true, }, [EditNetworkElementDialogMode.MountNetworkElement]: { - dialogTitle: "Mount Node", - dialogDescription: "Mount this node:", - applyButtonText: "Mount node", - cancelButtonText: "Cancel", + dialogTitle: 'Mount Node', + dialogDescription: 'Mount this node:', + applyButtonText: 'Mount node', + cancelButtonText: 'Cancel', enableMountIdEditor: false, enableUsernameEditor: false, enableExtendedEditor: false, }, [EditNetworkElementDialogMode.UnmountNetworkElement]: { - dialogTitle: "Unmount Node", - dialogDescription: "Unmount this node:", - applyButtonText: "Unmount node", - cancelButtonText: "Cancel", + dialogTitle: 'Unmount Node', + dialogDescription: 'Unmount this node:', + applyButtonText: 'Unmount node', + cancelButtonText: 'Cancel', enableMountIdEditor: false, enableUsernameEditor: false, enableExtendedEditor: false, }, [EditNetworkElementDialogMode.EditNetworkElement]: { - dialogTitle: "Modify Node", - dialogDescription: "Modify this node", - applyButtonText: "Modify", - cancelButtonText: "Cancel", + dialogTitle: 'Modify Node', + dialogDescription: 'Modify this node', + applyButtonText: 'Modify', + cancelButtonText: 'Cancel', enableMountIdEditor: false, enableUsernameEditor: true, enableExtendedEditor: false, }, [EditNetworkElementDialogMode.RemoveNetworkElement]: { - dialogTitle: "Remove Node", - dialogDescription: "Do you really want to remove this node?", - applyButtonText: "Remove node", - cancelButtonText: "Cancel", + dialogTitle: 'Remove Node', + dialogDescription: 'Do you really want to remove this node?', + applyButtonText: 'Remove node', + cancelButtonText: 'Cancel', enableMountIdEditor: false, enableUsernameEditor: false, enableExtendedEditor: false, - } -} + }, +}; type EditNetworkElementDialogComponentProps = Connect<undefined, typeof mapDispatch> & { mode: EditNetworkElementDialogMode; initialNetworkElement: NetworkElementConnection; onClose: () => void; - radioChecked: string + radioChecked: string; }; type EditNetworkElementDialogComponentState = NetworkElementConnection & { - isNameValid: boolean, - isHostSet: boolean, - isPasswordSelected: boolean, - isTlsSelected: boolean, - radioSelected: string, - showPasswordTextField: boolean, - showTlsDropdown: boolean + isNameValid: boolean; + isHostSet: boolean; + isPasswordSelected: boolean; + isTlsSelected: boolean; + radioSelected: string; + showPasswordTextField: boolean; + showTlsDropdown: boolean; }; class EditNetworkElementDialogComponent extends React.Component<EditNetworkElementDialogComponentProps, EditNetworkElementDialogComponentState> { @@ -189,16 +190,17 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme isTlsSelected: false, radioSelected: '', showPasswordTextField: true, - showTlsDropdown: false + showTlsDropdown: false, }; } + public handleRadioChange = (event: any) => { this.setState({ radioSelected: event.target.value, showPasswordTextField: event.target.value === 'password', - showTlsDropdown: event.target.value === 'tlsKey' + showTlsDropdown: event.target.value === 'tlsKey', }); - } + }; render(): JSX.Element { const setting = settings[this.props.mode]; @@ -215,22 +217,27 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme showTlsDropdown = true; } - let tlsKeysList = this.props.state.connect.availableTlsKeys ? this.props.state.connect.availableTlsKeys.tlsKeysList ? this.props.state.connect.availableTlsKeys.tlsKeysList : [] : [] + let tlsKeysList = this.props.state.connect.availableTlsKeys ? this.props.state.connect.availableTlsKeys.tlsKeysList ? this.props.state.connect.availableTlsKeys.tlsKeysList : [] : []; return ( <Dialog open={this.props.mode !== EditNetworkElementDialogMode.None}> - <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle> + <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, '-').toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle> <DialogContent> <DialogContentText> {setting.dialogDescription} </DialogContentText> - <TextField variant="standard" disabled={!setting.enableMountIdEditor} spellCheck={false} autoFocus margin="dense" id="name" label="Node ID" aria-label="name" type="text" fullWidth value={this.state.nodeId} onChange={(event) => { this.setState({ nodeId: event.target.value }); }} /> + <TextField variant="standard" disabled={!setting.enableMountIdEditor} spellCheck={false} autoFocus margin="dense" + id="name" label="Node ID" aria-label="name" type="text" fullWidth value={this.state.nodeId} onChange={(event) => { this.setState({ nodeId: event.target.value }); }} /> {!this.state.isNameValid && <Typography variant="body1" color="error">Node ID cannot be empty.</Typography>} - <TextField variant="standard" disabled={!setting.enableMountIdEditor} spellCheck={false} margin="dense" id="ipaddress" label="Host/IP address" aria-label="ip adress" type="text" fullWidth value={this.state.host} onChange={(event) => { this.setState({ host: event.target.value }); }} /> + <TextField variant="standard" disabled={!setting.enableMountIdEditor} spellCheck={false} margin="dense" + id="ipaddress" label="Host/IP address" aria-label="ip adress" type="text" fullWidth value={this.state.host} onChange={(event) => { this.setState({ host: event.target.value }); }} /> {!this.state.isHostSet && <Typography variant="body1" color="error">Host/IP address cannot be empty.</Typography>} - <TextField variant="standard" disabled={!setting.enableMountIdEditor} spellCheck={false} margin="dense" id="netconfport" label="NETCONF port" aria-label="netconf port" type="number" fullWidth value={this.state.port.toString()} onChange={(event) => { this.setState({ port: +event.target.value }); }} /> - {setting.enableUsernameEditor && <TextField variant="standard" disabled={!setting.enableUsernameEditor} spellCheck={false} margin="dense" id="username" label="Username" aria-label="username" type="text" fullWidth value={this.state.username} onChange={(event) => { this.setState({ username: event.target.value }); }} /> || null} + <TextField variant="standard" disabled={!setting.enableMountIdEditor} spellCheck={false} margin="dense" + id="netconfport" label="NETCONF port" aria-label="netconf port" type="number" fullWidth value={this.state.port.toString()} + onChange={(event) => { this.setState({ port: +event.target.value }); }} /> + {setting.enableUsernameEditor && <TextField variant="standard" disabled={!setting.enableUsernameEditor} spellCheck={false} margin="dense" + id="username" label="Username" aria-label="username" type="text" fullWidth value={this.state.username} onChange={(event) => { this.setState({ username: event.target.value }); }} /> || null} {setting.enableUsernameEditor && <RadioGroup row aria-label="password-tls-key" name="password-tls-key" value={radioSelected} @@ -253,7 +260,7 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme id="tlsKey" aria-label="tlsKey" value={this.state.tlsKey} fullWidth // displayEmpty onChange={(event) => { this.setState({ tlsKey: event.target.value as any }); }} inputProps={{ name: 'tlsKey', id: 'tlsKey' }} > - <MenuItem value={""} disabled >--Select tls-key--</MenuItem> + <MenuItem value={''} disabled >--Select tls-key--</MenuItem> {tlsKeysList.map(tlsKey => (<MenuItem value={tlsKey.key} key={tlsKey.key} aria-label={tlsKey.key} >{tlsKey.key}</MenuItem>))} </Select> @@ -283,7 +290,7 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme port: this.state.port, username: this.state.username, password: this.state.password, - tlsKey: this.state.tlsKey + tlsKey: this.state.tlsKey, }); } event.preventDefault(); @@ -305,7 +312,7 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme } catch (err) { console.log(err); } - } + }; public componentDidMount() { this.renderTlsKeys(); @@ -313,37 +320,36 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme public onRadioSelect = (e: any) => { if (e.target.value == 'password') { - this.setState({ isPasswordSelected: true, isTlsSelected: false }) + this.setState({ isPasswordSelected: true, isTlsSelected: false }); } else if (e.target.value == 'tlsKey') { - this.setState({ isPasswordSelected: false, isTlsSelected: true }) + this.setState({ isPasswordSelected: false, isTlsSelected: true }); } }; private onApply = (element: NetworkElementConnection) => { - this.props.onClose && this.props.onClose(); + if (this.props.onClose) this.props.onClose(); let updateElement: UpdateNetworkElement = { - id: this.state.nodeId - } + id: this.state.nodeId, + }; if (this.state.isPasswordSelected) { - element.tlsKey = '' - } - else if (this.state.isTlsSelected) { //check here - element.password = '' + element.tlsKey = ''; + } else if (this.state.isTlsSelected) { //check here + element.password = ''; } switch (this.props.mode) { case EditNetworkElementDialogMode.AddNewNetworkElement: - element && this.props.addNewNetworkElement(element); + if (element) this.props.addNewNetworkElement(element); this.setState({ radioSelected: '', isPasswordSelected: true, }); break; case EditNetworkElementDialogMode.MountNetworkElement: - element && this.props.mountNetworkElement(element); + if (element) this.props.mountNetworkElement(element); break; case EditNetworkElementDialogMode.UnmountNetworkElement: - element && this.props.unmountNetworkElement(element); + if (element) this.props.unmountNetworkElement(element); break; case EditNetworkElementDialogMode.EditNetworkElement: if (this.props.initialNetworkElement.isRequired !== this.state.isRequired) @@ -358,13 +364,13 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme updateElement.tlsKey = this.state.tlsKey; updateElement.password = ''; } - element && this.props.editNetworkElement(updateElement, element); + if (element) this.props.editNetworkElement(updateElement, element); this.setState({ - radioSelected: '' + radioSelected: '', }); break; case EditNetworkElementDialogMode.RemoveNetworkElement: - element && this.props.removeNetworkElement(updateElement); + if (element) this.props.removeNetworkElement(updateElement); break; } @@ -373,10 +379,10 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme }; private onCancel = () => { - this.props.onClose && this.props.onClose(); + if (this.props.onClose) this.props.onClose(); this.setState({ password: '', username: '', tlsKey: '', radioSelected: '' }); this.resetRequieredFields(); - } + }; private resetRequieredFields() { this.setState({ isNameValid: true, isHostSet: true }); @@ -402,15 +408,16 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme return areFieldsValid; } - static getDerivedStateFromProps(props: EditNetworkElementDialogComponentProps, state: EditNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection }): EditNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection } { - if (props.initialNetworkElement !== state._initialNetworkElement) { - state = { + static getDerivedStateFromProps(props: EditNetworkElementDialogComponentProps, state: EditNetworkElementDialogComponentState & { initialNetworkElement: NetworkElementConnection }): EditNetworkElementDialogComponentState & { initialNetworkElement: NetworkElementConnection } { + let returnState = state; + if (props.initialNetworkElement !== state.initialNetworkElement) { + returnState = { ...state, ...props.initialNetworkElement, - _initialNetworkElement: props.initialNetworkElement, + initialNetworkElement: props.initialNetworkElement, }; } - return state; + return returnState; } } diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx index b0c7840be..4841b9389 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx @@ -15,145 +15,146 @@ * the License. * ============LICENSE_END========================================================================== */ - import * as React from 'react'; - - import Button from '@mui/material/Button'; - import Dialog from '@mui/material/Dialog'; - import DialogActions from '@mui/material/DialogActions'; - import DialogTitle from '@mui/material/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 Node", - 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.substring(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.substring(indexRevision + 9, indexRevision + 19), - 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 isPopup tableId="info-element-table" asynchronus columns={[ - { property: "module", title: "YANG Capability", 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 +import * as React from 'react'; + +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogTitle from '@mui/material/DialogTitle'; + +import { ColumnType, MaterialTable, MaterialTableCtorType } from '../../../../framework/src/components/material-table'; +import { 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 = () => ({ +}); + +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 Node', + 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.substring(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.substring(indexRevision + 9, indexRevision + 19), + 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 isPopup tableId="info-element-table" asynchronus columns={[ + { property: 'module', title: 'YANG Capability', 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 } { + let returnState = state; + if (props.initialNetworkElement !== state.initialNetworkElement) { + returnState = { + ...state, + ...props.initialNetworkElement, + initialNetworkElement: props.initialNetworkElement, + }; + } + return returnState; + } +} + +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 67fdef69d..1ce8f0c3b 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx @@ -15,39 +15,37 @@ * the License. * ============LICENSE_END========================================================================== */ -import * as React from 'react'; -import { Theme } from '@mui/material/styles'; - -import { WithStyles } from '@mui/styles'; -import createStyles from '@mui/styles/createStyles'; -import withStyles from '@mui/styles/withStyles'; +import React from 'react'; import AddIcon from '@mui/icons-material/Add'; -import Refresh from '@mui/icons-material/Refresh'; +import ComputerIcon from '@mui/icons-material/Computer'; +import EditIcon from '@mui/icons-material/Edit'; +import Info from '@mui/icons-material/Info'; import LinkIcon from '@mui/icons-material/Link'; import LinkOffIcon from '@mui/icons-material/LinkOff'; +import Refresh from '@mui/icons-material/Refresh'; import RemoveIcon from '@mui/icons-material/RemoveCircleOutline'; -import EditIcon from '@mui/icons-material/Edit'; -import Info from '@mui/icons-material/Info'; -import ComputerIcon from '@mui/icons-material/Computer'; -import { MenuItem, Divider, Typography } from '@mui/material'; +import { Divider, MenuItem, Typography } from '@mui/material'; +import { Theme } from '@mui/material/styles'; +import { WithStyles } from '@mui/styles'; +import createStyles from '@mui/styles/createStyles'; +import withStyles from '@mui/styles/withStyles'; -import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; -import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect'; import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions'; +import { ColumnType, MaterialTable, MaterialTableCtorType } from '../../../../framework/src/components/material-table'; +import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect'; +import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; +import { getAccessPolicyByUrl } from '../../../../framework/src/services/restService'; +import { loadAllInfoElementAsync, loadAllInfoElementFeaturesAsync } from '../actions/infoNetworkElementActions'; import { createNetworkElementsActions, createNetworkElementsProperties } from '../handlers/networkElementsHandler'; - import { NetworkElementConnection } from '../models/networkElementConnection'; import { ModuleSet, TopologyNode } from '../models/topologyNetconf'; -import EditNetworkElementDialog, { EditNetworkElementDialogMode } from './editNetworkElementDialog'; -import RefreshNetworkElementsDialog, { RefreshNetworkElementsDialogMode } from './refreshNetworkElementsDialog'; +import { connectService } from '../services/connectService'; +import EditNetworkElementDialog, { EditNetworkElementDialogMode } from './editNetworkElementDialog'; import InfoNetworkElementDialog, { InfoNetworkElementDialogMode } from './infoNetworkElementDialog'; -import { loadAllInfoElementAsync, loadAllInfoElementFeaturesAsync } from '../actions/infoNetworkElementActions'; -import { connectService } from '../services/connectService'; -import { getAccessPolicyByUrl } from '../../../../framework/src/services/restService'; +import RefreshNetworkElementsDialog, { RefreshNetworkElementsDialogMode } from './refreshNetworkElementsDialog'; const styles = (theme: Theme) => createStyles({ connectionStatusConnected: { @@ -61,17 +59,17 @@ const styles = (theme: Theme) => createStyles({ }, button: { margin: 0, - padding: "6px 6px", - minWidth: 'unset' + padding: '6px 6px', + minWidth: 'unset', }, spacer: { marginLeft: theme.spacing(1), marginRight: theme.spacing(1), - display: "inline" - } + display: 'inline', + }, }); -type GetStatelessComponentProps<T> = T extends (props: infer P & { children?: React.ReactNode }) => any ? P : any +type GetStatelessComponentProps<T> = T extends (props: infer P & { children?: React.ReactNode }) => any ? P : any; const MenuItemExt: React.FC<GetStatelessComponentProps<typeof MenuItem>> = (props) => { const [disabled, setDisabled] = React.useState(true); const onMouseDown = (ev: React.MouseEvent<HTMLElement>) => { @@ -95,21 +93,21 @@ const mapProps = (state: IApplicationStoreState) => ({ 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)) + networkElementInfo: async (nodeId: string) => dispatcher.dispatch(loadAllInfoElementAsync(nodeId)), + networkElementFeaturesInfo: async (nodeId: string) => dispatcher.dispatch(loadAllInfoElementFeaturesAsync(nodeId)), }); type NetworkElementsListComponentProps = WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>; type NetworkElementsListComponentState = { - networkElementToEdit: NetworkElementConnection, - networkElementEditorMode: EditNetworkElementDialogMode, - refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode, - infoNetworkElementEditorMode: InfoNetworkElementDialogMode, - elementInfo: TopologyNode | null, - elementInfoFeature: ModuleSet | null -} + networkElementToEdit: NetworkElementConnection; + networkElementEditorMode: EditNetworkElementDialogMode; + refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode; + infoNetworkElementEditorMode: InfoNetworkElementDialogMode; + elementInfo: TopologyNode | null; + elementInfoFeature: ModuleSet | null; +}; -const emptyRequireNetworkElement: NetworkElementConnection = { id: "", nodeId: "", host: "", port: 830, status: "Disconnected", isRequired: true }; +const emptyRequireNetworkElement: NetworkElementConnection = { id: '', nodeId: '', host: '', port: 830, status: 'Disconnected', isRequired: true }; let initialSorted = false; const NetworkElementTable = MaterialTable as MaterialTableCtorType<NetworkElementConnection>; @@ -124,7 +122,7 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.None, elementInfo: null, elementInfoFeature: null, - infoNetworkElementEditorMode: InfoNetworkElementDialogMode.None + infoNetworkElementEditorMode: InfoNetworkElementDialogMode.None, }; } @@ -135,25 +133,25 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement const { configuration } = this.props.applicationState as any; const buttonArray = [ - <MenuItemExt aria-label={"mount-button"} onClick={event => this.onOpenMountdNetworkElementsDialog(event, rowData)} disabled={!canMount} ><LinkIcon /><Typography>Mount</Typography></MenuItemExt>, - <MenuItemExt aria-label={"unmount-button"} onClick={event => this.onOpenUnmountdNetworkElementsDialog(event, rowData)} disabled={!canMount} ><LinkOffIcon /><Typography>Unmount</Typography></MenuItemExt>, + <MenuItemExt aria-label={'mount-button'} onClick={event => this.onOpenMountdNetworkElementsDialog(event, rowData)} disabled={!canMount} ><LinkIcon /><Typography>Mount</Typography></MenuItemExt>, + <MenuItemExt aria-label={'unmount-button'} onClick={event => this.onOpenUnmountdNetworkElementsDialog(event, rowData)} disabled={!canMount} ><LinkOffIcon /><Typography>Unmount</Typography></MenuItemExt>, <Divider />, - <MenuItem aria-label={"info-button"} onClick={event => this.onOpenInfoNetworkElementDialog(event, rowData)} disabled={rowData.status !== "Connected"} ><Info /><Typography>Info</Typography></MenuItem>, - <MenuItem aria-label={"edit-button"} onClick={event => this.onOpenEditNetworkElementDialog(event, rowData)}><EditIcon /><Typography>Edit</Typography></MenuItem>, - <MenuItem aria-label={"remove-button"} onClick={event => this.onOpenRemoveNetworkElementDialog(event, rowData)} ><RemoveIcon /><Typography>Remove</Typography></MenuItem>, + <MenuItem aria-label={'info-button'} onClick={event => this.onOpenInfoNetworkElementDialog(event, rowData)} disabled={rowData.status !== 'Connected'} ><Info /><Typography>Info</Typography></MenuItem>, + <MenuItem aria-label={'edit-button'} onClick={event => this.onOpenEditNetworkElementDialog(event, rowData)}><EditIcon /><Typography>Edit</Typography></MenuItem>, + <MenuItem aria-label={'remove-button'} onClick={event => this.onOpenRemoveNetworkElementDialog(event, rowData)} ><RemoveIcon /><Typography>Remove</Typography></MenuItem>, <Divider />, - <MenuItem aria-label={"inventory-button"} onClick={event => this.props.navigateToApplication("inventory", rowData.nodeId)}><Typography>Inventory</Typography></MenuItem>, + <MenuItem aria-label={'inventory-button'} onClick={() => this.props.navigateToApplication('inventory', rowData.nodeId)}><Typography>Inventory</Typography></MenuItem>, <Divider />, - <MenuItem aria-label={"fault-button"} onClick={event => this.props.navigateToApplication("fault", rowData.nodeId)} ><Typography>Fault</Typography></MenuItem>, - <MenuItem aria-label={"configure-button"} onClick={event => this.props.navigateToApplication("configuration", rowData.nodeId)} disabled={rowData.status === "Connecting" || rowData.status === "Disconnected" || !configuration}><Typography>Configure</Typography></MenuItem>, - <MenuItem onClick={event => this.props.navigateToApplication("accounting", rowData.nodeId)} disabled={true}><Typography>Accounting</Typography></MenuItem>, - <MenuItem aria-label={"performance-button"} onClick={event => this.props.navigateToApplication("performanceHistory", rowData.nodeId)}><Typography>Performance</Typography></MenuItem>, - <MenuItem onClick={event => this.props.navigateToApplication("security", rowData.nodeId)} disabled={true} ><Typography>Security</Typography></MenuItem>, + <MenuItem aria-label={'fault-button'} onClick={() => this.props.navigateToApplication('fault', rowData.nodeId)} ><Typography>Fault</Typography></MenuItem>, + <MenuItem aria-label={'configure-button'} onClick={() => this.props.navigateToApplication('configuration', rowData.nodeId)} disabled={rowData.status === 'Connecting' || rowData.status === 'Disconnected' || !configuration}><Typography>Configure</Typography></MenuItem>, + <MenuItem onClick={() => this.props.navigateToApplication('accounting', rowData.nodeId)} disabled={true}><Typography>Accounting</Typography></MenuItem>, + <MenuItem aria-label={'performance-button'} onClick={() => this.props.navigateToApplication('performanceHistory', rowData.nodeId)}><Typography>Performance</Typography></MenuItem>, + <MenuItem onClick={() => this.props.navigateToApplication('security', rowData.nodeId)} disabled={true} ><Typography>Security</Typography></MenuItem>, ]; if (rowData.weburi) { // add an icon for gui cuttrough, if weburi is available - return [<MenuItem aria-label={"web-client-button"} onClick={event => window.open(rowData.weburi, "_blank")} ><ComputerIcon /><Typography>Web Client</Typography></MenuItem>].concat(buttonArray) + return [<MenuItem aria-label={'web-client-button'} onClick={() => window.open(rowData.weburi, '_blank')} ><ComputerIcon /><Typography>Web Client</Typography></MenuItem>].concat(buttonArray); } else { return buttonArray; } @@ -162,13 +160,13 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement // private navigationCreator render(): JSX.Element { - const { classes } = this.props; + //const { classes } = this.props; const { networkElementToEdit } = this.state; - let savedRadio = "password"; + let savedRadio = 'password'; if (this.state.networkElementToEdit.password && this.state.networkElementToEdit.password.length > 0) { - savedRadio = 'password' + savedRadio = 'password'; } else if (this.state.networkElementToEdit.tlsKey && this.state.networkElementToEdit.tlsKey.length > 0) { - savedRadio = 'tlsKey' + savedRadio = 'tlsKey'; } // const mountUri = rowData.id && connectService.getNetworkElementUri(rowData.id); @@ -177,32 +175,32 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement const canAdd = true; const addRequireNetworkElementAction = { - icon: AddIcon, tooltip: 'Add node', ariaLabel: "add-element", onClick: () => { + icon: AddIcon, tooltip: 'Add node', ariaLabel: 'add-element', onClick: () => { this.setState({ networkElementEditorMode: EditNetworkElementDialogMode.AddNewNetworkElement, networkElementToEdit: emptyRequireNetworkElement, }); - } + }, }; const refreshNetworkElementsAction = { icon: Refresh, tooltip: 'Refresh table', ariaLabel: 'refresh', onClick: () => { this.setState({ - refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.RefreshNetworkElementsTable + refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.RefreshNetworkElementsTable, }); - } + }, }; return <> <NetworkElementTable stickyHeader tableId="network-element-table" customActionButtons={[refreshNetworkElementsAction, ...(canAdd ? [addRequireNetworkElementAction] : [])]} columns={[ - { property: "nodeId", title: "Node ID", type: ColumnType.text }, - { property: "status", title: "Connection Status", type: ColumnType.text, width:'15%' }, - { property: "host", title: "Host", type: ColumnType.text }, - { property: "port", title: "Port", type: ColumnType.numeric }, - { property: "isRequired", title: "Required", type: ColumnType.boolean }, - { property: "deviceType", title: "Type", type: ColumnType.text }, - // { property: "coreModelCapability", title: "Core Model", type: ColumnType.text }, - { property: "deviceFunction", title: "Function", type: ColumnType.text, width: '25%' } + { property: 'nodeId', title: 'Node ID', type: ColumnType.text }, + { property: 'status', title: 'Connection Status', type: ColumnType.text, width:'15%' }, + { property: 'host', title: 'Host', type: ColumnType.text }, + { property: 'port', title: 'Port', type: ColumnType.numeric }, + { property: 'isRequired', title: 'Required', type: ColumnType.boolean }, + { property: 'deviceType', title: 'Type', type: ColumnType.text }, + // { property: "coreModelCapability", title: "Core Model", type: ColumnType.text }, + { property: 'deviceFunction', title: 'Function', type: ColumnType.text, width: '25%' }, ]} idProperty="id" {...this.props.networkElementsActions} {...this.props.networkElementsProperties} asynchronus createContextMenu={rowData => { return this.getContextMenu(rowData); @@ -224,12 +222,12 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement onClose={this.onCloseInfoNetworkElementDialog} /> </>; - }; + } public componentDidMount() { if (!initialSorted) { initialSorted = true; - this.props.networkElementsActions.onHandleRequestSort("node-id"); + this.props.networkElementsActions.onHandleRequestSort('node-id'); } else { this.props.networkElementsActions.onRefresh(); } @@ -238,23 +236,23 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement private onOpenAddNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => { this.setState({ networkElementToEdit: element, - networkElementEditorMode: EditNetworkElementDialogMode.AddNewNetworkElement + networkElementEditorMode: EditNetworkElementDialogMode.AddNewNetworkElement, }); - } + }; private onOpenRemoveNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => { this.setState({ networkElementToEdit: element, - networkElementEditorMode: EditNetworkElementDialogMode.RemoveNetworkElement + networkElementEditorMode: EditNetworkElementDialogMode.RemoveNetworkElement, }); - } + }; private onOpenEditNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => { - let radioSaved; - if (element.password && element.password.length > 0) - radioSaved = 'password' - else if (element.tlsKey && element.tlsKey.length > 0) - radioSaved = 'tlsKey' + //let radioSaved; + //if (element.password && element.password.length > 0) + // radioSaved = 'password'; + //else if (element.tlsKey && element.tlsKey.length > 0) + // radioSaved = 'tlsKey'; this.setState({ networkElementToEdit: { nodeId: element.nodeId, @@ -263,25 +261,25 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement port: element.port, username: element.username, password: element.password, - tlsKey: element.tlsKey + tlsKey: element.tlsKey, }, - networkElementEditorMode: EditNetworkElementDialogMode.EditNetworkElement + networkElementEditorMode: EditNetworkElementDialogMode.EditNetworkElement, }); - } + }; private onOpenUnmountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => { this.setState({ networkElementToEdit: element, - networkElementEditorMode: EditNetworkElementDialogMode.UnmountNetworkElement + networkElementEditorMode: EditNetworkElementDialogMode.UnmountNetworkElement, }); - } + }; private onOpenMountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => { this.setState({ networkElementToEdit: element, - networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElement + networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElement, }); - } + }; private onOpenInfoNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => { this.props.networkElementInfo(element.nodeId); @@ -290,25 +288,27 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement networkElementToEdit: element, infoNetworkElementEditorMode: InfoNetworkElementDialogMode.InfoNetworkElement, }); - } + }; private onCloseEditNetworkElementDialog = () => { this.setState({ networkElementEditorMode: EditNetworkElementDialogMode.None, networkElementToEdit: emptyRequireNetworkElement, }); - } + }; + private onCloseInfoNetworkElementDialog = () => { this.setState({ infoNetworkElementEditorMode: InfoNetworkElementDialogMode.None, networkElementToEdit: emptyRequireNetworkElement, }); - } + }; + private onCloseRefreshNetworkElementsDialog = () => { this.setState({ - refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.None + refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.None, }); - } + }; } export const NetworkElementsList = withStyles(styles)(connect(mapProps, mapDispatch)(NetworkElementsListComponent)); diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/refreshConnectionStatusLogDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/refreshConnectionStatusLogDialog.tsx index c09f59b40..a4aea7f82 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/refreshConnectionStatusLogDialog.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/refreshConnectionStatusLogDialog.tsx @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -import * as React from 'react'; +import React from 'react'; import Button from '@mui/material/Button'; import Dialog from '@mui/material/Dialog'; @@ -24,78 +24,75 @@ import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogTitle from '@mui/material/DialogTitle'; -import { connectionStatusLogReloadAction } from '../handlers/connectionStatusLogHandler'; -import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect'; +import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect'; +import { connectionStatusLogReloadAction } from '../handlers/connectionStatusLogHandler'; import { ConnectionStatusLogType } from '../models/connectionStatusLog'; export enum RefreshConnectionStatusLogDialogMode { - None = "none", - RefreshConnectionStatusLogTable = "RefreshConnectionStatusLogTable", + None = 'none', + RefreshConnectionStatusLogTable = 'RefreshConnectionStatusLogTable', } const mapDispatch = (dispatcher: IDispatcher) => ({ - refreshConnectionStatusLog: () => dispatcher.dispatch(connectionStatusLogReloadAction) + refreshConnectionStatusLog: () => dispatcher.dispatch(connectionStatusLogReloadAction), }); type DialogSettings = { - dialogTitle: string, - dialogDescription: string, - applyButtonText: string, - cancelButtonText: string, - enableMountIdEditor: boolean, - enableUsernameEditor: boolean, - enableExtendedEditor: boolean, -} + dialogTitle: string; + dialogDescription: string; + applyButtonText: string; + cancelButtonText: string; + enableMountIdEditor: boolean; + enableUsernameEditor: boolean; + enableExtendedEditor: boolean; +}; const settings: { [key: string]: DialogSettings } = { [RefreshConnectionStatusLogDialogMode.None]: { - dialogTitle: "", - dialogDescription: "", - applyButtonText: "", - cancelButtonText: "", + dialogTitle: '', + dialogDescription: '', + applyButtonText: '', + cancelButtonText: '', enableMountIdEditor: false, enableUsernameEditor: false, enableExtendedEditor: false, }, [RefreshConnectionStatusLogDialogMode.RefreshConnectionStatusLogTable]: { - dialogTitle: "Do you want to refresh the Connection Status Log table?", - dialogDescription: "", - applyButtonText: "Yes", - cancelButtonText: "Cancel", + dialogTitle: 'Do you want to refresh the Connection Status Log table?', + dialogDescription: '', + applyButtonText: 'Yes', + cancelButtonText: 'Cancel', enableMountIdEditor: true, enableUsernameEditor: true, enableExtendedEditor: true, - } -} + }, +}; type RefreshConnectionStatusLogDialogComponentProps = Connect<undefined, typeof mapDispatch> & { mode: RefreshConnectionStatusLogDialogMode; onClose: () => void; }; -type RefreshConnectionStatusLogDialogComponentState = ConnectionStatusLogType & { isNameValid: boolean, isHostSet: boolean }; +type RefreshConnectionStatusLogDialogComponentState = ConnectionStatusLogType & { isNameValid: boolean; isHostSet: boolean }; class RefreshConnectionStatusLogDialogComponent extends React.Component<RefreshConnectionStatusLogDialogComponentProps, RefreshConnectionStatusLogDialogComponentState> { - constructor(props: RefreshConnectionStatusLogDialogComponentProps) { - super(props); - } render(): JSX.Element { const setting = settings[this.props.mode]; return ( <Dialog open={this.props.mode !== RefreshConnectionStatusLogDialogMode.None}> - <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle> + <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, '-').toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle> <DialogContent> <DialogContentText> {setting.dialogDescription} </DialogContentText> </DialogContent> <DialogActions> - <Button aria-label="dialog-confirm-button" onClick={(event) => { + <Button aria-label="dialog-confirm-button" onClick={() => { this.onRefresh(); }} color="inherit" > {setting.applyButtonText} </Button> - <Button aria-label="dialog-cancel-button" onClick={(event) => { + <Button aria-label="dialog-cancel-button" onClick={() => { this.onCancel(); }} color="secondary"> {setting.cancelButtonText} </Button> </DialogActions> @@ -110,7 +107,7 @@ class RefreshConnectionStatusLogDialogComponent extends React.Component<RefreshC private onCancel = () => { this.props.onClose(); - } + }; } export const RefreshConnectionStatusLogDialog = connect(undefined, mapDispatch)(RefreshConnectionStatusLogDialogComponent); diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/refreshNetworkElementsDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/refreshNetworkElementsDialog.tsx index abf593882..e41fd27aa 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/refreshNetworkElementsDialog.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/refreshNetworkElementsDialog.tsx @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -import * as React from 'react'; +import React from 'react'; import Button from '@mui/material/Button'; import Dialog from '@mui/material/Dialog'; @@ -24,78 +24,75 @@ import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogTitle from '@mui/material/DialogTitle'; -import { networkElementsReloadAction } from '../handlers/networkElementsHandler'; -import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect'; +import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect'; +import { networkElementsReloadAction } from '../handlers/networkElementsHandler'; import { NetworkElementConnection } from '../models/networkElementConnection'; export enum RefreshNetworkElementsDialogMode { - None = "none", - RefreshNetworkElementsTable = "RefreshNetworkElementsTable", + None = 'none', + RefreshNetworkElementsTable = 'RefreshNetworkElementsTable', } const mapDispatch = (dispatcher: IDispatcher) => ({ - refreshNetworkElement: () => dispatcher.dispatch(networkElementsReloadAction) + refreshNetworkElement: () => dispatcher.dispatch(networkElementsReloadAction), }); type DialogSettings = { - dialogTitle: string, - dialogDescription: string, - applyButtonText: string, - cancelButtonText: string, - enableMountIdEditor: boolean, - enableUsernameEditor: boolean, - enableExtendedEditor: boolean, -} + dialogTitle: string; + dialogDescription: string; + applyButtonText: string; + cancelButtonText: string; + enableMountIdEditor: boolean; + enableUsernameEditor: boolean; + enableExtendedEditor: boolean; +}; const settings: { [key: string]: DialogSettings } = { [RefreshNetworkElementsDialogMode.None]: { - dialogTitle: "", - dialogDescription: "", - applyButtonText: "", - cancelButtonText: "", + dialogTitle: '', + dialogDescription: '', + applyButtonText: '', + cancelButtonText: '', enableMountIdEditor: false, enableUsernameEditor: false, enableExtendedEditor: false, }, [RefreshNetworkElementsDialogMode.RefreshNetworkElementsTable]: { - dialogTitle: "Do you want to refresh the nodes table?", - dialogDescription: "", - applyButtonText: "Yes", - cancelButtonText: "Cancel", + dialogTitle: 'Do you want to refresh the nodes table?', + dialogDescription: '', + applyButtonText: 'Yes', + cancelButtonText: 'Cancel', enableMountIdEditor: true, enableUsernameEditor: true, enableExtendedEditor: true, - } -} + }, +}; type RefreshNetworkElementsDialogComponentProps = Connect<undefined, typeof mapDispatch> & { mode: RefreshNetworkElementsDialogMode; onClose: () => void; }; -type RefreshNetworkElementsDialogComponentState = NetworkElementConnection & { isNameValid: boolean, isHostSet: boolean }; +type RefreshNetworkElementsDialogComponentState = NetworkElementConnection & { isNameValid: boolean; isHostSet: boolean }; class RefreshNetworkElementsDialogComponent extends React.Component<RefreshNetworkElementsDialogComponentProps, RefreshNetworkElementsDialogComponentState> { - constructor(props: RefreshNetworkElementsDialogComponentProps) { - super(props); - } render(): JSX.Element { const setting = settings[this.props.mode]; return ( <Dialog open={this.props.mode !== RefreshNetworkElementsDialogMode.None}> - <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle> + <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, '-').toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle> <DialogContent> <DialogContentText> {setting.dialogDescription} </DialogContentText> </DialogContent> <DialogActions> - <Button aria-label="dialog-confirm-button" onClick={(event) => { + <Button aria-label="dialog-confirm-button" onClick={() => { this.onRefresh(); }} color="inherit" > {setting.applyButtonText} </Button> - <Button aria-label="dialog-cancel-button" onClick={(event) => { + <Button aria-label="dialog-cancel-button" onClick={() => { this.onCancel(); }} color="secondary"> {setting.cancelButtonText} </Button> </DialogActions> @@ -110,7 +107,7 @@ class RefreshNetworkElementsDialogComponent extends React.Component<RefreshNetwo private onCancel = () => { this.props.onClose(); - } + }; } export const RefreshNetworkElementsDialog = connect(undefined, mapDispatch)(RefreshNetworkElementsDialogComponent); diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts index 6a1825224..b386dcdef 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts @@ -18,12 +18,13 @@ import { IActionHandler } from '../../../../framework/src/flux/action'; import { combineActionHandler } from '../../../../framework/src/flux/middleware'; -import { INetworkElementsState, networkElementsActionHandler } from './networkElementsHandler'; -import { IConnectionStatusLogState, connectionStatusLogActionHandler } from './connectionStatusLogHandler'; -import { IInfoNetworkElementsState, infoNetworkElementsActionHandler, IInfoNetworkElementFeaturesState, infoNetworkElementFeaturesActionHandler } from './infoNetworkElementHandler'; -import { SetPanelAction, AddWebUriList, RemoveWebUri, SetWeburiSearchBusy } from '../actions/commonNetworkElementsActions'; -import { PanelId } from '../models/panelId'; + +import { AddWebUriList, RemoveWebUri, SetPanelAction } from '../actions/commonNetworkElementsActions'; import { guiCutThrough } from '../models/guiCutTrough'; +import { PanelId } from '../models/panelId'; +import { connectionStatusLogActionHandler, IConnectionStatusLogState } from './connectionStatusLogHandler'; +import { IInfoNetworkElementFeaturesState, IInfoNetworkElementsState, infoNetworkElementFeaturesActionHandler, infoNetworkElementsActionHandler } from './infoNetworkElementHandler'; +import { INetworkElementsState, networkElementsActionHandler } from './networkElementsHandler'; import { availableTlsKeysActionHandler, IAvailableTlsKeysState } from './tlsKeyHandler'; export interface IConnectAppStoreState { @@ -33,7 +34,7 @@ export interface IConnectAppStoreState { elementInfo: IInfoNetworkElementsState; elementFeatureInfo: IInfoNetworkElementFeaturesState; guiCutThrough: guiCutThroughState; - availableTlsKeys: IAvailableTlsKeysState + availableTlsKeys: IAvailableTlsKeysState; } const currentOpenPanelHandler: IActionHandler<PanelId> = (state = null, action) => { @@ -41,7 +42,7 @@ const currentOpenPanelHandler: IActionHandler<PanelId> = (state = null, action) state = action.panelId; } return state; -} +}; interface guiCutThroughState { searchedElements: guiCutThrough[]; @@ -62,12 +63,12 @@ const guiCutThroughHandler: IActionHandler<guiCutThroughState> = (state = { sear if (action.newlySearchedElements) { action.newlySearchedElements.forEach(item => { notSearchedElements = notSearchedElements.filter(id => id !== item); - }) + }); } searchedElements = state.searchedElements.concat(action.searchedElements); - state = { searchedElements: searchedElements, notSearchedElements: notSearchedElements, unsupportedElements: unsupportedElements } + state = { searchedElements: searchedElements, notSearchedElements: notSearchedElements, unsupportedElements: unsupportedElements }; } else if (action instanceof RemoveWebUri) { const nodeId = action.element; @@ -77,11 +78,11 @@ const guiCutThroughHandler: IActionHandler<guiCutThroughState> = (state = { sear state = { notSearchedElements: knownElements, searchedElements: webUris, unsupportedElements: unsupportedElement }; } return state; -} +}; declare module '../../../../framework/src/store/applicationStore' { interface IApplicationStoreState { - connect: IConnectAppStoreState + connect: IConnectAppStoreState; } } @@ -92,7 +93,7 @@ const actionHandlers = { elementInfo: infoNetworkElementsActionHandler, elementFeatureInfo: infoNetworkElementFeaturesActionHandler, guiCutThrough: guiCutThroughHandler, - availableTlsKeys: availableTlsKeysActionHandler + availableTlsKeys: availableTlsKeysActionHandler, }; export const connectAppRootHandler = combineActionHandler<IConnectAppStoreState>(actionHandlers); diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.ts index 6863ec33b..264b6c198 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.ts @@ -15,10 +15,11 @@ * the License. * ============LICENSE_END========================================================================== */ -import { createExternal,IExternalTableState } from '../../../../framework/src/components/material-table/utilities'; +import { createExternal, IExternalTableState } from '../../../../framework/src/components/material-table/utilities'; import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch'; import { NetworkElementConnectionLog } from '../models/networkElementConnectionLog'; + export interface IConnectionStatusLogState extends IExternalTableState<NetworkElementConnectionLog> { } // create eleactic search material data fetch handler diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/infoNetworkElementHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/infoNetworkElementHandler.ts index 3e2d1cec1..692e63a5c 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/handlers/infoNetworkElementHandler.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/infoNetworkElementHandler.ts @@ -15,79 +15,78 @@ * the License. * ============LICENSE_END========================================================================== */ - import { IActionHandler } from '../../../../framework/src/flux/action'; +import { IActionHandler } from '../../../../framework/src/flux/action'; - import { AllElementInfoLoadedAction, AllElementInfoFeatureLoadedAction, LoadAllElementInfoAction } from '../actions/infoNetworkElementActions'; +import { AllElementInfoFeatureLoadedAction, AllElementInfoLoadedAction, LoadAllElementInfoAction } from '../actions/infoNetworkElementActions'; +import { Module, TopologyNode } from '../models/topologyNetconf'; - import { Module, TopologyNode } from '../models/topologyNetconf'; +export interface IInfoNetworkElementsState { + elementInfo: TopologyNode; + busy: boolean; +} - export interface IInfoNetworkElementsState { - elementInfo: TopologyNode; - busy: boolean; - } +export interface IInfoNetworkElementFeaturesState { + elementFeatureInfo: Module[]; + busy: boolean; +} - export interface IInfoNetworkElementFeaturesState { - elementFeatureInfo: Module[]; - busy: boolean; - } +const infoNetworkElementsStateInit: IInfoNetworkElementsState = { + elementInfo: { + 'node-id': '', + 'netconf-node-topology:available-capabilities': { + 'available-capability': [], + }, + }, + busy: false, +}; - const infoNetworkElementsStateInit: IInfoNetworkElementsState = { - elementInfo: { - "node-id": "", - "netconf-node-topology:available-capabilities": { - "available-capability": [] - } - }, - busy: false - }; +const infoNetworkElementFeaturesStateInit: IInfoNetworkElementFeaturesState = { + elementFeatureInfo: [], + busy: false, +}; - const infoNetworkElementFeaturesStateInit: IInfoNetworkElementFeaturesState = { - elementFeatureInfo: [], - busy: false - }; +export const infoNetworkElementsActionHandler: IActionHandler<IInfoNetworkElementsState> = (state = infoNetworkElementsStateInit, action) => { + if (action instanceof LoadAllElementInfoAction) { + state = { + ...state, + busy: true, + }; + } else if (action instanceof AllElementInfoLoadedAction) { + if (!action.error && action.elementInfo) { + state = { + ...state, + elementInfo: action.elementInfo, + busy: false, + }; + } else { + state = { + ...state, + busy: false, + }; + } + } + return state; +}; - export const infoNetworkElementsActionHandler: IActionHandler<IInfoNetworkElementsState> = (state = infoNetworkElementsStateInit, action) => { - if (action instanceof LoadAllElementInfoAction) { - state = { - ...state, - busy: true - }; - } else if (action instanceof AllElementInfoLoadedAction) { - if (!action.error && action.elementInfo) { - state = { - ...state, - elementInfo: action.elementInfo, - busy: false - }; - } else { - state = { - ...state, - busy: false - }; - } - } - return state; - }; - - export const infoNetworkElementFeaturesActionHandler: IActionHandler<IInfoNetworkElementFeaturesState> = (state = infoNetworkElementFeaturesStateInit, action) => { - if (action instanceof LoadAllElementInfoAction) { - state = { - ...state, - busy: true - }; - } else if (action instanceof AllElementInfoFeatureLoadedAction) { - if (!action.error && action.elementFeatureInfo) { - state = { - ...state, - elementFeatureInfo: action.elementFeatureInfo, - busy: false - }; - } else { - state = { - ...state, - busy: false - }; - } - } - return state; - };
\ No newline at end of file +export const infoNetworkElementFeaturesActionHandler: IActionHandler<IInfoNetworkElementFeaturesState> = (state = infoNetworkElementFeaturesStateInit, action) => { + if (action instanceof LoadAllElementInfoAction) { + state = { + ...state, + busy: true, + }; + } else if (action instanceof AllElementInfoFeatureLoadedAction) { + if (!action.error && action.elementFeatureInfo) { + state = { + ...state, + elementFeatureInfo: action.elementFeatureInfo, + busy: false, + }; + } else { + state = { + ...state, + busy: false, + }; + } + } + return state; +};
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts index b74a39427..42d2824b9 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts @@ -16,8 +16,8 @@ * ============LICENSE_END========================================================================== */ import { createExternal, IExternalTableState } from '../../../../framework/src/components/material-table/utilities'; -import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch'; import { getAccessPolicyByUrl } from '../../../../framework/src/services/restService'; +import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch'; import { NetworkElementConnection } from '../models/networkElementConnection'; import { connectService } from '../services/connectService'; @@ -32,7 +32,7 @@ export const { createActions: createNetworkElementsActions, createProperties: createNetworkElementsProperties, reloadAction: networkElementsReloadAction, - + // set value action, to change a value } = createExternal<NetworkElementConnection>(networkElementsSearchHandler, appState => { @@ -42,20 +42,19 @@ export const { appState.connect.networkElements.rows.forEach(element => { - if (element.status === "Connected") { + if (element.status === 'Connected') { const webUri = webUris.find(item => item.id === element.id as string); if (webUri) { element.weburi = webUri.weburi; element.isWebUriUnreachable = false; - } - else { - element.isWebUriUnreachable = true + } else { + element.isWebUriUnreachable = true; } } }); } - return appState.connect.networkElements + return appState.connect.networkElements; }, (ne) => { if (!ne || !ne.id) return true; const neUrl = connectService.getNetworkElementUri(ne.id); diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/tlsKeyHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/tlsKeyHandler.ts index 326b3cc8e..20badcba0 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/handlers/tlsKeyHandler.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/tlsKeyHandler.ts @@ -34,7 +34,7 @@ export const availableTlsKeysActionHandler: IActionHandler<IAvailableTlsKeysStat if (action instanceof LoadAllTlsKeyListAction) { state = { ...state, - busy: true + busy: true, }; } else if (action instanceof AllTlsKeyListLoadedAction) { @@ -47,7 +47,7 @@ export const availableTlsKeysActionHandler: IActionHandler<IAvailableTlsKeysStat } else { state = { ...state, - busy: false + busy: false, }; } } diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/connectionStatusLog.ts b/sdnr/wt/odlux/apps/connectApp/src/models/connectionStatusLog.ts index df43c217a..82b49a081 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/models/connectionStatusLog.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/models/connectionStatusLog.ts @@ -23,5 +23,5 @@ export type ConnectionStatusLogType = { objectId: string; type: string; newValue: string; -} +}; diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts b/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts index b9f515dc8..0fd46a82d 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts @@ -17,6 +17,6 @@ */ export type guiCutThrough = { - id: string, - weburi?: string -}
\ No newline at end of file + id: string; + weburi?: string; +};
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/networkElementBase.ts b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementBase.ts index 39278a8e1..a46a30e2b 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/models/networkElementBase.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementBase.ts @@ -16,7 +16,7 @@ * ============LICENSE_END========================================================================== */ export type NetworkElementBaseType = { - mountId: string, - host: string, - port: number, -}
\ No newline at end of file + mountId: string; + host: string; + port: number; +};
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts index bc15afb31..bb076c720 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts @@ -27,7 +27,7 @@ export type NetworkElementConnection = { tlsKey?: string; weburi?: string; isWebUriUnreachable?: boolean; - status?: "Connected" | "mounted" | "unmounted" | "Connecting" | "Disconnected" | "idle"; + status?: 'Connected' | 'mounted' | 'unmounted' | 'Connecting' | 'Disconnected' | 'idle'; coreModelCapability?: string; deviceType?: string; deviceFunction?: string; @@ -40,8 +40,8 @@ export type NetworkElementConnection = { failureReason: string; capability: string; }[]; - } -} + }; +}; export type UpdateNetworkElement = { @@ -50,15 +50,15 @@ export type UpdateNetworkElement = { username?: string; password?: string; tlsKey?: string; -} +}; export type ConnectionStatus = { - status: string -} + status: string; +}; export type TlsKeys = { - key: string -} + key: string; +}; /** diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnectionLog.ts b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnectionLog.ts index a1535cbe5..4b4e28325 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnectionLog.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnectionLog.ts @@ -19,7 +19,7 @@ export type NetworkElementConnectionLog = { id: string; nodeId: string; - status: "connected" | "mounted" | "unmounted" | "connecting" | "disconnected" | "idle"; + status: 'connected' | 'mounted' | 'unmounted' | 'connecting' | 'disconnected' | 'idle'; timestamp: string; -} +}; diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/panelId.ts b/sdnr/wt/odlux/apps/connectApp/src/models/panelId.ts index 2000d9407..2861f107f 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/models/panelId.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/models/panelId.ts @@ -16,4 +16,4 @@ * ============LICENSE_END========================================================================== */ -export type PanelId = null | "NetworkElements" | "ConnectionStatusLog";
\ No newline at end of file +export type PanelId = null | 'NetworkElements' | 'ConnectionStatusLog';
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/topologyNetconf.ts b/sdnr/wt/odlux/apps/connectApp/src/models/topologyNetconf.ts index 936e20bc2..85a1a71fd 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/models/topologyNetconf.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/models/topologyNetconf.ts @@ -16,23 +16,23 @@ * ============LICENSE_END========================================================================== */ - export interface AvailableCapability { - "capability-origin": string; +export interface AvailableCapability { + 'capability-origin': string; capability: string; } export interface NetconfNodeTopologyAvailableCapabilities { - "available-capability": AvailableCapability[]; + 'available-capability': AvailableCapability[]; } export interface TopologyNode { - "node-id": string; - "netconf-node-topology:available-capabilities": NetconfNodeTopologyAvailableCapabilities; + 'node-id': string; + 'netconf-node-topology:available-capabilities': NetconfNodeTopologyAvailableCapabilities; } export interface Topology { - "topology-id": string; - "network-topology:node": TopologyNode[]; + 'topology-id': string; + 'network-topology:node': TopologyNode[]; } /** @@ -47,13 +47,13 @@ export interface Module { } export interface ModuleFeatures { - module: Module[]; + module: Module[]; } export interface ModuleSet { - "module-set": ModuleFeatures[]; + 'module-set': ModuleFeatures[]; } export interface FeatureTopology { - "ietf-yang-library:yang-library" : ModuleSet + 'ietf-yang-library:yang-library' : ModuleSet; } diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/yangCapabilitiesType.ts b/sdnr/wt/odlux/apps/connectApp/src/models/yangCapabilitiesType.ts index c8cf7049c..b69993f7d 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/models/yangCapabilitiesType.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/models/yangCapabilitiesType.ts @@ -16,9 +16,9 @@ * ============LICENSE_END========================================================================== */ - export type AvailableCapabilities = { - id?: string, - module: string, - revision: string, - features: string -}
\ No newline at end of file +export type AvailableCapabilities = { + id?: string; + module: string; + revision: string; + features: string; +};
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx b/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx index 2a9a46d2b..c2907166c 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx @@ -16,27 +16,25 @@ * ============LICENSE_END========================================================================== */ -import * as React from "react"; -import { withRouter, RouteComponentProps, Route, Switch, Redirect } from 'react-router-dom'; -import { faPlug } from '@fortawesome/free-solid-svg-icons'; +import React from 'react'; +import { Redirect, Route, RouteComponentProps, Switch, withRouter } from 'react-router-dom'; -import applicationManager from '../../../framework/src/services/applicationManager'; -import { subscribe, IFormatedMessage } from '../../../framework/src/services/notificationService'; import { AddSnackbarNotification } from '../../../framework/src/actions/snackbarActions'; -import { IApplicationStoreState } from "../../../framework/src/store/applicationStore"; -import connect, { Connect, IDispatcher } from '../../../framework/src/flux/connect'; +import { connect, Connect, IDispatcher } from '../../../framework/src/flux/connect'; +import applicationManager from '../../../framework/src/services/applicationManager'; +import { IFormatedMessage, subscribe } from '../../../framework/src/services/notificationService'; +import { IApplicationStoreState } from '../../../framework/src/store/applicationStore'; -import { findWebUrisForGuiCutThroughAsyncAction, updateCurrentViewAsyncAction, SetPanelAction } from './actions/commonNetworkElementsActions'; -import { createNetworkElementsActions, createNetworkElementsProperties, networkElementsReloadAction } from './handlers/networkElementsHandler'; +import { findWebUrisForGuiCutThroughAsyncAction, SetPanelAction, updateCurrentViewAsyncAction } from './actions/commonNetworkElementsActions'; +import { NetworkElementsList } from './components/networkElements'; import connectAppRootHandler from './handlers/connectAppRootHandler'; +import { createNetworkElementsActions, createNetworkElementsProperties, networkElementsReloadAction } from './handlers/networkElementsHandler'; +import { PanelId } from './models/panelId'; import ConnectApplication from './views/connectView'; -import { PanelId } from "./models/panelId"; -import { NetworkElementsList } from './components/networkElements'; +const appIcon = require('./assets/icons/connectAppIcon.svg'); // select app icon let currentStatus: string | undefined = undefined; -let refreshInterval: ReturnType<typeof window.setInterval> | null = null; - const mapProps = (state: IApplicationStoreState) => ({ networkElementDashboardProperties: createNetworkElementsProperties(state), @@ -48,24 +46,25 @@ const mapDisp = (dispatcher: IDispatcher) => ({ }); const ConnectApplicationRouteAdapter = connect(mapProps, mapDisp)((props: RouteComponentProps<{ status?: string }> & Connect<typeof mapProps, typeof mapDisp>) => { + + // TODO: move into useEffect! if (currentStatus !== props.match.params.status) { currentStatus = props.match.params.status || undefined; window.setTimeout(() => { if (currentStatus) { - props.setCurrentPanel("NetworkElements"); - props.networkElementsDashboardActions.onFilterChanged("status", currentStatus); + props.setCurrentPanel('NetworkElements'); + props.networkElementsDashboardActions.onFilterChanged('status', currentStatus); if (!props.networkElementDashboardProperties.showFilter) { props.networkElementsDashboardActions.onToggleFilter(false); props.networkElementsDashboardActions.onRefresh(); - } - else + } else props.networkElementsDashboardActions.onRefresh(); } }); } return ( <NetworkElementsList /> - ) + ); }); @@ -79,19 +78,19 @@ const App = withRouter((props: RouteComponentProps) => ( export function register() { const applicationApi = applicationManager.registerApplication({ - name: "connect", - icon: faPlug, + name: 'connect', + icon: appIcon, rootComponent: App, rootActionHandler: connectAppRootHandler, - menuEntry: "Connect" + menuEntry: 'Connect', }); // subscribe to the websocket notifications - subscribe<IFormatedMessage>(["object-creation-notification", "object-deletion-notification", "attribute-value-changed-notification"], (msg => { + subscribe<IFormatedMessage>(['object-creation-notification', 'object-deletion-notification', 'attribute-value-changed-notification'], (msg => { const store = applicationApi.applicationStore; - if (msg && msg.type.type === "object-creation-notification" && store) { + if (msg && msg.type.type === 'object-creation-notification' && store) { store.dispatch(new AddSnackbarNotification({ message: `Adding node [${msg.data['object-id-ref']}]`, options: { variant: 'info' } })); - } else if (msg && (msg.type.type === "object-deletion-notification" || msg.type.type === "attribute-value-changed-notification") && store) { + } else if (msg && (msg.type.type === 'object-deletion-notification' || msg.type.type === 'attribute-value-changed-notification') && store) { store.dispatch(new AddSnackbarNotification({ message: `Updating node [${msg.data['object-id-ref']}]`, options: { variant: 'info' } })); } if (store) { diff --git a/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts b/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts index 08cc58056..1d74f859a 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts @@ -18,7 +18,7 @@ import { requestRest } from '../../../../framework/src/services/restService'; import { NetworkElementConnection, ConnectionStatus, UpdateNetworkElement } from '../models/networkElementConnection'; -import { TlsKeys } from '../models/networkElementConnection' +import { TlsKeys } from '../models/networkElementConnection'; import { convertPropertyNames, replaceUpperCase } from '../../../../framework/src/utilities/yangHelper'; import { Result } from '../../../../framework/src/models/elasticSearch'; @@ -30,17 +30,20 @@ import { guiCutThrough } from '../models/guiCutTrough'; */ class ConnectService { public getNetworkElementUri = (nodeId: string) => '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId; - public getNetworkElementConnectDataProviderUri = (operation: "create" | "update" | "delete") => `/rests/operations/data-provider:${operation}-network-element-connection`; + + public getNetworkElementConnectDataProviderUri = (operation: 'create' | 'update' | 'delete') => `/rests/operations/data-provider:${operation}-network-element-connection`; + public getAllWebUriExtensionsForNetworkElementListUri = (nodeId: string) => this.getNetworkElementUri(nodeId) + '/yang-ext:mount/core-model:network-element'; - public getNetworkElementYangLibraryFeature = (nodeId: string) => '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId + '/yang-ext:mount/ietf-yang-library:yang-library?content=nonconfig' + + public getNetworkElementYangLibraryFeature = (nodeId: string) => '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId + '/yang-ext:mount/ietf-yang-library:yang-library?content=nonconfig'; /** * Inserts a network element/node. */ public async createNetworkElement(element: NetworkElementConnection): Promise<NetworkElementConnection | null> { - const path = this.getNetworkElementConnectDataProviderUri("create"); + const path = this.getNetworkElementConnectDataProviderUri('create'); const result = await requestRest<NetworkElementConnection>(path, { - method: "POST", body: JSON.stringify(convertPropertyNames({ "data-provider:input": element }, replaceUpperCase)) + method: 'POST', body: JSON.stringify(convertPropertyNames({ 'data-provider:input': element }, replaceUpperCase)), }); return result || null; } @@ -49,9 +52,9 @@ class ConnectService { * Updates a network element/node. */ public async updateNetworkElement(element: UpdateNetworkElement): Promise<NetworkElementConnection | null> { - const path = this.getNetworkElementConnectDataProviderUri("update"); + const path = this.getNetworkElementConnectDataProviderUri('update'); const result = await requestRest<NetworkElementConnection>(path, { - method: "POST", body: JSON.stringify(convertPropertyNames({ "data-provider:input": element }, replaceUpperCase)) + method: 'POST', body: JSON.stringify(convertPropertyNames({ 'data-provider:input': element }, replaceUpperCase)), }); return result || null; } @@ -61,11 +64,11 @@ class ConnectService { */ public async deleteNetworkElement(element: UpdateNetworkElement): Promise<NetworkElementConnection | null> { const query = { - "id": element.id + 'id': element.id, }; - const path = this.getNetworkElementConnectDataProviderUri("delete"); + const path = this.getNetworkElementConnectDataProviderUri('delete'); const result = await requestRest<NetworkElementConnection>(path, { - method: "POST", body: JSON.stringify(convertPropertyNames({ "data-provider:input": query }, replaceUpperCase)) + method: 'POST', body: JSON.stringify(convertPropertyNames({ 'data-provider:input': query }, replaceUpperCase)), }); return result || null; } @@ -107,13 +110,12 @@ class ConnectService { '<name xmlns="urn:opendaylight:netconf-node-topology">TLS</name>', ' </protocol>', '<max-connection-attempts xmlns="urn:opendaylight:netconf-node-topology">2</max-connection-attempts>', - '</node>'].join('') + '</node>'].join(''); let bodyXml; if (networkElement.password) { - bodyXml = mountXml - } - else { - bodyXml = tlsXml + bodyXml = mountXml; + } else { + bodyXml = tlsXml; } try { @@ -121,16 +123,16 @@ class ConnectService { method: 'PUT', headers: { 'Content-Type': 'application/xml', - 'Accept': 'application/xml' + 'Accept': 'application/xml', }, - body: bodyXml + body: bodyXml, }); // expect an empty answer return result !== null; } catch { return false; } - }; + } /** Unmounts a network element by its id. */ public async unmountNetworkElement(nodeId: string): Promise<boolean> { @@ -141,7 +143,7 @@ class ConnectService { method: 'DELETE', headers: { 'Content-Type': 'application/xml', - 'Accept': 'application/xml' + 'Accept': 'application/xml', }, }); // expect an empty answer @@ -150,15 +152,15 @@ class ConnectService { } catch { return false; } - }; + } /** Yang capabilities of the selected network element/node */ public async infoNetworkElement(nodeId: string): Promise<TopologyNode | null> { const path = this.getNetworkElementUri(nodeId); - const topologyRequestPomise = requestRest<Topology>(path, { method: "GET" }); + const topologyRequestPomise = requestRest<Topology>(path, { method: 'GET' }); return topologyRequestPomise && topologyRequestPomise.then(result => { - return result && result["network-topology:node"] && result["network-topology:node"][0] || null; + return result && result['network-topology:node'] && result['network-topology:node'][0] || null; }); } @@ -166,13 +168,13 @@ class ConnectService { /** Yang features of the selected network element/node module */ public async infoNetworkElementFeatures(nodeId: string): Promise<Module[] | null | undefined> { const path = this.getNetworkElementYangLibraryFeature(nodeId); - const topologyRequestPomise = requestRest<FeatureTopology>(path, { method: "GET" }); + const topologyRequestPomise = requestRest<FeatureTopology>(path, { method: 'GET' }); return topologyRequestPomise && topologyRequestPomise.then(result => { const resultFinal = result && result['ietf-yang-library:yang-library'] - && result["ietf-yang-library:yang-library"]["module-set"] && - result["ietf-yang-library:yang-library"]["module-set"][0] && - result["ietf-yang-library:yang-library"]["module-set"][0]['module'] || null; + && result['ietf-yang-library:yang-library']['module-set'] && + result['ietf-yang-library:yang-library']['module-set'][0] && + result['ietf-yang-library:yang-library']['module-set'][0].module || null; return resultFinal; }); } @@ -183,22 +185,22 @@ class ConnectService { * Get the connection state of the network element/ node */ public async getNetworkElementConnectionStatus(element: string): Promise<(ConnectionStatus)[] | null> { - const path = `/rests/operations/data-provider:read-network-element-connection-list`; + const path = '/rests/operations/data-provider:read-network-element-connection-list'; const query = { - "data-provider:input": { - "filter": [{ - "property": "node-id", - "filtervalue": element + 'data-provider:input': { + 'filter': [{ + 'property': 'node-id', + 'filtervalue': element, }], - "pagination": { - "size": 20, - "page": 1 - } - } - } - const result = await requestRest<Result<ConnectionStatus>>(path, { method: "POST", body: JSON.stringify(query) }); - return result && result["data-provider:output"] && result["data-provider:output"].data && result["data-provider:output"].data.map(ne => ({ - status: ne.status + 'pagination': { + 'size': 20, + 'page': 1, + }, + }, + }; + const result = await requestRest<Result<ConnectionStatus>>(path, { method: 'POST', body: JSON.stringify(query) }); + return result && result['data-provider:output'] && result['data-provider:output'].data && result['data-provider:output'].data.map(ne => ({ + status: ne.status, })) || null; } @@ -209,44 +211,43 @@ class ConnectService { public async getTlsKeys(): Promise<(TlsKeys)[] | null> { const path = '/rests/operations/data-provider:read-tls-key-entry'; const query = { - "data-provider:input": { - "filter": [], - "sortorder": [], - "pagination": { - "size": 20, - "page": 1 - } - } + 'data-provider:input': { + 'filter': [], + 'sortorder': [], + 'pagination': { + 'size': 20, + 'page': 1, + }, + }, }; - const result = await requestRest<Result<string>>(path, { method: "POST", body: JSON.stringify(query) }); - return result && result["data-provider:output"] && result["data-provider:output"].data && result["data-provider:output"].data.map(ne => ({ - key: ne + const result = await requestRest<Result<string>>(path, { method: 'POST', body: JSON.stringify(query) }); + return result && result['data-provider:output'] && result['data-provider:output'].data && result['data-provider:output'].data.map(ne => ({ + key: ne, })) || null; } public async getAllWebUriExtensionsForNetworkElementListAsync(neList: string[]): Promise<(guiCutThrough)[]> { - const path = `/rests/operations/data-provider:read-gui-cut-through-entry`; - let webUriList: guiCutThrough[] = [] + const path = '/rests/operations/data-provider:read-gui-cut-through-entry'; + let webUriList: guiCutThrough[] = []; const query = { - "data-provider:input": { - "filter": [{ - "property": "id", - "filtervalues": neList + 'data-provider:input': { + 'filter': [{ + 'property': 'id', + 'filtervalues': neList, }], - "pagination": { - "size": 20, - "page": 1 - } - } - } + 'pagination': { + 'size': 20, + 'page': 1, + }, + }, + }; - const result = await requestRest<Result<guiCutThrough>>(path, { method: "POST", body: JSON.stringify(query) }); - const resultData = result && result["data-provider:output"] && result["data-provider:output"].data; + const result = await requestRest<Result<guiCutThrough>>(path, { method: 'POST', body: JSON.stringify(query) }); + const resultData = result && result['data-provider:output'] && result['data-provider:output'].data; neList.forEach(nodeId => { let entryNotFound = true; if (resultData) { - const BreakException = {}; try { resultData.forEach(entry => { if (entry.id == nodeId) { @@ -256,7 +257,7 @@ class ConnectService { } else { webUriList.push({ id: nodeId, weburi: undefined }); } - throw BreakException; + throw new Error(); } }); } catch (e) { } diff --git a/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx b/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx index 082839718..a6fcb7c32 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx @@ -15,113 +15,88 @@ * the License. * ============LICENSE_END========================================================================== */ -import * as React from 'react'; +import React from 'react'; -import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; -import { Panel } from '../../../../framework/src/components/material-ui'; -import { networkElementsReloadAction, createNetworkElementsActions } from '../handlers/networkElementsHandler'; -import { connectionStatusLogReloadAction, createConnectionStatusLogActions } from '../handlers/connectionStatusLogHandler'; +import { AppBar, Tab, Tabs } from '@mui/material'; -import { NetworkElementsList } from '../components/networkElements'; +import { useApplicationDispatch, useSelectApplicationState } from '../../../../framework/src/flux/connect'; + +import { findWebUrisForGuiCutThroughAsyncAction, setPanelAction } from '../actions/commonNetworkElementsActions'; import { ConnectionStatusLog } from '../components/connectionStatusLog'; -import { setPanelAction, findWebUrisForGuiCutThroughAsyncAction, SetWeburiSearchBusy } from '../actions/commonNetworkElementsActions'; +import { NetworkElementsList } from '../components/networkElements'; +import { connectionStatusLogReloadAction } from '../handlers/connectionStatusLogHandler'; +import { networkElementsReloadAction } from '../handlers/networkElementsHandler'; +import { NetworkElementConnection } from '../models/networkElementConnection'; import { PanelId } from '../models/panelId'; -import { NetworkElementConnection } from 'models/networkElementConnection'; -import { AppBar, Tabs, Tab } from '@mui/material'; - -const mapProps = (state: IApplicationStoreState) => ({ - panelId: state.connect.currentOpenPanel, - user: state.framework.authenticationState.user, - netWorkElements: state.connect.networkElements, - availableGuiCutroughs: state.connect.guiCutThrough -}); - -const mapDispatcher = (dispatcher: IDispatcher) => ({ - networkElementsActions: createNetworkElementsActions(dispatcher.dispatch), - connectionStatusLogActions: createConnectionStatusLogActions(dispatcher.dispatch), - onLoadNetworkElements: () => dispatcher.dispatch(networkElementsReloadAction), - loadWebUris: (networkElements: NetworkElementConnection[]) => - dispatcher.dispatch(findWebUrisForGuiCutThroughAsyncAction(networkElements.map((ne) => ne.id!))), - isBusy: (busy: boolean) => dispatcher.dispatch(new SetWeburiSearchBusy(busy)), - onLoadConnectionStatusLog: () => { - dispatcher.dispatch(connectionStatusLogReloadAction); - }, - switchActivePanel: (panelId: PanelId) => { - dispatcher.dispatch(setPanelAction(panelId)); - } -}); -type ConnectApplicationComponentProps = Connect<typeof mapProps, typeof mapDispatcher>; +const ConnectApplicationComponent: React.FC<{}> = () => { -class ConnectApplicationComponent extends React.Component<ConnectApplicationComponentProps>{ + const panelId = useSelectApplicationState(state => state.connect.currentOpenPanel); + const netWorkElements = useSelectApplicationState(state => state.connect.networkElements); - public componentDidMount() { - if (this.props.panelId === null) { //don't change tabs, if one is selected already - this.onTogglePanel("NetworkElements"); - } - //this.props.networkElementsActions.onToggleFilter(); - //this.props.connectionStatusLogActions.onToggleFilter(); - } - - public componentDidUpdate = () => { - - const networkElements = this.props.netWorkElements; - - if (networkElements.rows.length > 0) { - // Update all netWorkElements for propper WebUriClient settings in case of table data changes. - // e.G: Pagination of the table data (there is no event) - this.props.loadWebUris(networkElements.rows); - } - } + const dispatch = useApplicationDispatch(); + const onLoadNetworkElements = () => dispatch(networkElementsReloadAction); + const loadWebUris = (networkElements: NetworkElementConnection[]) => dispatch(findWebUrisForGuiCutThroughAsyncAction(networkElements.map((ne) => ne.id!))); + const onLoadConnectionStatusLog = () => dispatch(connectionStatusLogReloadAction); + const switchActivePanel = (panelId2: PanelId) => dispatch(setPanelAction(panelId2)); - private onTogglePanel = (panelId: PanelId) => { - const nextActivePanel = panelId; - this.props.switchActivePanel(nextActivePanel); + const onTogglePanel = (panelId2: PanelId) => { + const nextActivePanel = panelId2; + switchActivePanel(nextActivePanel); switch (nextActivePanel) { case 'NetworkElements': - this.props.onLoadNetworkElements(); + onLoadNetworkElements(); break; case 'ConnectionStatusLog': - this.props.onLoadConnectionStatusLog(); + onLoadConnectionStatusLog(); break; case null: // do nothing if all panels are closed break; default: - console.warn("Unknown nextActivePanel [" + nextActivePanel + "] in connectView"); + console.warn('Unknown nextActivePanel [' + nextActivePanel + '] in connectView'); break; } - }; - private onHandleTabChange = (event: React.SyntheticEvent, newValue: PanelId) => { - this.props.switchActivePanel(newValue); - } - - render(): JSX.Element { - const { panelId: activePanelId } = this.props; - - return ( - <> - <AppBar enableColorOnDark position="static"> - <Tabs indicatorColor="secondary" textColor="inherit" value={activePanelId} onChange={this.onHandleTabChange} aria-label="connect-app-tabs"> - <Tab aria-label="network-elements-list-tab" label="NODES" value="NetworkElements" /> - <Tab aria-label="connection-status-log-tab" label="Connection Status Log" value="ConnectionStatusLog" /> - </Tabs> - </AppBar> - {activePanelId === 'NetworkElements' - ? <NetworkElementsList /> - : activePanelId === 'ConnectionStatusLog' - ? <ConnectionStatusLog /> - : null} - </> - ); + const onHandleTabChange = (event: React.SyntheticEvent, newValue: PanelId) => { + switchActivePanel(newValue); }; + React.useEffect(()=>{ + if (panelId === null) { //don't change tabs, if one is selected already + onTogglePanel('NetworkElements'); + } + }, []); -} + React.useEffect(()=>{ + const networkElements = netWorkElements; -export const ConnectApplication = (connect(mapProps, mapDispatcher)(ConnectApplicationComponent)); + if (networkElements.rows.length > 0) { + // Search for weburi client for all netWorkElements in case of table data changes. + // e.G: Pagination of the table data (there is no event) + loadWebUris(networkElements.rows); + } + }, [netWorkElements]); + + return ( + <> + <AppBar enableColorOnDark position="static"> + <Tabs indicatorColor="secondary" textColor="inherit" value={panelId} onChange={onHandleTabChange} aria-label="connect-app-tabs"> + <Tab aria-label="network-elements-list-tab" label="NODES" value="NetworkElements" /> + <Tab aria-label="connection-status-log-tab" label="Connection Status Log" value="ConnectionStatusLog" /> + </Tabs> + </AppBar> + {panelId === 'NetworkElements' + ? <NetworkElementsList /> + : panelId === 'ConnectionStatusLog' + ? <ConnectionStatusLog /> + : null + } + </> + ); +}; + +export const ConnectApplication = ConnectApplicationComponent; export default ConnectApplication;
\ No newline at end of file |