From 15e2d3a29b0d1a304965e34f114a911e5a7abdb3 Mon Sep 17 00:00:00 2001 From: sai-neetha Date: Mon, 20 Mar 2023 08:05:47 +0100 Subject: Odlux Update Add eslint and custom icons update Issue-ID: CCSDK-3871 Signed-off-by: sai-neetha Change-Id: If6b676128cc9cff0437a5dc54f85eaafd3b8c586 Signed-off-by: highstreetherbert --- .../src/actions/commonNetworkElementsActions.ts | 40 +-- .../src/actions/infoNetworkElementActions.ts | 80 +++--- .../src/actions/mountedNetworkElementsActions.ts | 2 +- .../src/actions/networkElementsActions.ts | 13 +- .../apps/connectApp/src/actions/tlsKeyActions.ts | 21 +- .../connectApp/src/assets/icons/connectAppIcon.svg | 22 ++ .../src/components/connectionStatusLog.tsx | 39 +-- .../src/components/editNetworkElementDialog.tsx | 209 +++++++-------- .../src/components/infoNetworkElementDialog.tsx | 285 +++++++++++---------- .../connectApp/src/components/networkElements.tsx | 174 ++++++------- .../refreshConnectionStatusLogDialog.tsx | 61 +++-- .../components/refreshNetworkElementsDialog.tsx | 61 +++-- .../src/handlers/connectAppRootHandler.ts | 25 +- .../src/handlers/connectionStatusLogHandler.ts | 3 +- .../src/handlers/infoNetworkElementHandler.ts | 137 +++++----- .../src/handlers/networkElementsHandler.ts | 13 +- .../apps/connectApp/src/handlers/tlsKeyHandler.ts | 4 +- .../connectApp/src/models/connectionStatusLog.ts | 2 +- .../apps/connectApp/src/models/guiCutTrough.ts | 6 +- .../connectApp/src/models/networkElementBase.ts | 8 +- .../src/models/networkElementConnection.ts | 16 +- .../src/models/networkElementConnectionLog.ts | 4 +- .../wt/odlux/apps/connectApp/src/models/panelId.ts | 2 +- .../apps/connectApp/src/models/topologyNetconf.ts | 20 +- .../connectApp/src/models/yangCapabilitiesType.ts | 12 +- .../wt/odlux/apps/connectApp/src/pluginConnect.tsx | 47 ++-- .../apps/connectApp/src/services/connectService.ts | 135 +++++----- .../apps/connectApp/src/views/connectView.tsx | 141 +++++----- 28 files changed, 792 insertions(+), 790 deletions(-) create mode 100644 sdnr/wt/odlux/apps/connectApp/src/assets/icons/connectAppIcon.svg (limited to 'sdnr/wt/odlux/apps/connectApp/src') 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 @@ + + + + + + + + + + + + + + + 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; type ConnectionStatusLogComponentState = { - refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode -} + refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode; +}; let initialSorted = false; -class ConnectionStatusLogComponent extends React.Component { +class ConnectionStatusLogComponent extends React.Component { 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 ( <> ); - }; + } 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("id"); - const isRequiredProperty = propertyOf("isRequired"); + const idProperty = propertyOf('id'); + const isRequiredProperty = propertyOf('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 & { 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 { @@ -189,16 +190,17 @@ class EditNetworkElementDialogComponent extends React.Component { 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 - {setting.dialogTitle} + {setting.dialogTitle} {setting.dialogDescription} - { this.setState({ nodeId: event.target.value }); }} /> + { this.setState({ nodeId: event.target.value }); }} /> {!this.state.isNameValid && Node ID cannot be empty.} - { this.setState({ host: event.target.value }); }} /> + { this.setState({ host: event.target.value }); }} /> {!this.state.isHostSet && Host/IP address cannot be empty.} - { this.setState({ port: +event.target.value }); }} /> - {setting.enableUsernameEditor && { this.setState({ username: event.target.value }); }} /> || null} + { this.setState({ port: +event.target.value }); }} /> + {setting.enableUsernameEditor && { this.setState({ username: event.target.value }); }} /> || null} {setting.enableUsernameEditor && { this.setState({ tlsKey: event.target.value as any }); }} inputProps={{ name: 'tlsKey', id: 'tlsKey' }} > - --Select tls-key-- + --Select tls-key-- {tlsKeysList.map(tlsKey => ({tlsKey.key}))} @@ -283,7 +290,7 @@ class EditNetworkElementDialogComponent extends React.Component { 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 { - 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 ({ - }); - - - const InfoElementTable = MaterialTable as MaterialTableCtorType; - - 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 & { - mode: InfoNetworkElementDialogMode; - initialNetworkElement: NetworkElementConnection; - onClose: () => void; - }; - - type InfoNetworkElementDialogComponentState = NetworkElementConnection; - - class InfoNetworkElementDialogComponent extends React.Component { - 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 ( - <> - - {`${setting.dialogTitle}: "${this.state.nodeId}"`} - { - return ( - - ) - } - }, - { property: "features", title: "Features", type: ColumnType.text, width:500 }, - ]} idProperty="id" rows={yangCapabilities} > - - - - - - - ) - } - - 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; + +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 & { + mode: InfoNetworkElementDialogMode; + initialNetworkElement: NetworkElementConnection; + onClose: () => void; +}; + +type InfoNetworkElementDialogComponentState = NetworkElementConnection; + +class InfoNetworkElementDialogComponent extends React.Component { + 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 ( + <> + + {`${setting.dialogTitle}: "${this.state.nodeId}"`} + { + return ( + + ); + }, + }, + { property: 'features', title: 'Features', type: ColumnType.text, width: 500 }, + ]} idProperty="id" rows={yangCapabilities} > + + + + + + + ); + } + + 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 extends (props: infer P & { children?: React.ReactNode }) => any ? P : any +type GetStatelessComponentProps = T extends (props: infer P & { children?: React.ReactNode }) => any ? P : any; const MenuItemExt: React.FC> = (props) => { const [disabled, setDisabled] = React.useState(true); const onMouseDown = (ev: React.MouseEvent) => { @@ -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 & Connect; 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; @@ -124,7 +122,7 @@ export class NetworkElementsListComponent extends React.Component this.onOpenMountdNetworkElementsDialog(event, rowData)} disabled={!canMount} >Mount, - this.onOpenUnmountdNetworkElementsDialog(event, rowData)} disabled={!canMount} >Unmount, + this.onOpenMountdNetworkElementsDialog(event, rowData)} disabled={!canMount} >Mount, + this.onOpenUnmountdNetworkElementsDialog(event, rowData)} disabled={!canMount} >Unmount, , - this.onOpenInfoNetworkElementDialog(event, rowData)} disabled={rowData.status !== "Connected"} >Info, - this.onOpenEditNetworkElementDialog(event, rowData)}>Edit, - this.onOpenRemoveNetworkElementDialog(event, rowData)} >Remove, + this.onOpenInfoNetworkElementDialog(event, rowData)} disabled={rowData.status !== 'Connected'} >Info, + this.onOpenEditNetworkElementDialog(event, rowData)}>Edit, + this.onOpenRemoveNetworkElementDialog(event, rowData)} >Remove, , - this.props.navigateToApplication("inventory", rowData.nodeId)}>Inventory, + this.props.navigateToApplication('inventory', rowData.nodeId)}>Inventory, , - this.props.navigateToApplication("fault", rowData.nodeId)} >Fault, - this.props.navigateToApplication("configuration", rowData.nodeId)} disabled={rowData.status === "Connecting" || rowData.status === "Disconnected" || !configuration}>Configure, - this.props.navigateToApplication("accounting", rowData.nodeId)} disabled={true}>Accounting, - this.props.navigateToApplication("performanceHistory", rowData.nodeId)}>Performance, - this.props.navigateToApplication("security", rowData.nodeId)} disabled={true} >Security, + this.props.navigateToApplication('fault', rowData.nodeId)} >Fault, + this.props.navigateToApplication('configuration', rowData.nodeId)} disabled={rowData.status === 'Connecting' || rowData.status === 'Disconnected' || !configuration}>Configure, + this.props.navigateToApplication('accounting', rowData.nodeId)} disabled={true}>Accounting, + this.props.navigateToApplication('performanceHistory', rowData.nodeId)}>Performance, + this.props.navigateToApplication('security', rowData.nodeId)} disabled={true} >Security, ]; if (rowData.weburi) { // add an icon for gui cuttrough, if weburi is available - return [ window.open(rowData.weburi, "_blank")} >Web Client].concat(buttonArray) + return [ window.open(rowData.weburi, '_blank')} >Web Client].concat(buttonArray); } else { return buttonArray; } @@ -162,13 +160,13 @@ export class NetworkElementsListComponent extends React.Component 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 { + 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 <> { return this.getContextMenu(rowData); @@ -224,12 +222,12 @@ export class NetworkElementsListComponent extends React.Component ; - }; + } 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, element: NetworkElementConnection) => { this.setState({ networkElementToEdit: element, - networkElementEditorMode: EditNetworkElementDialogMode.AddNewNetworkElement + networkElementEditorMode: EditNetworkElementDialogMode.AddNewNetworkElement, }); - } + }; private onOpenRemoveNetworkElementDialog = (event: React.MouseEvent, element: NetworkElementConnection) => { this.setState({ networkElementToEdit: element, - networkElementEditorMode: EditNetworkElementDialogMode.RemoveNetworkElement + networkElementEditorMode: EditNetworkElementDialogMode.RemoveNetworkElement, }); - } + }; private onOpenEditNetworkElementDialog = (event: React.MouseEvent, 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, element: NetworkElementConnection) => { this.setState({ networkElementToEdit: element, - networkElementEditorMode: EditNetworkElementDialogMode.UnmountNetworkElement + networkElementEditorMode: EditNetworkElementDialogMode.UnmountNetworkElement, }); - } + }; private onOpenMountdNetworkElementsDialog = (event: React.MouseEvent, element: NetworkElementConnection) => { this.setState({ networkElementToEdit: element, - networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElement + networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElement, }); - } + }; private onOpenInfoNetworkElementDialog = (event: React.MouseEvent, element: NetworkElementConnection) => { this.props.networkElementInfo(element.nodeId); @@ -290,25 +288,27 @@ export class NetworkElementsListComponent extends React.Component { 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 & { mode: RefreshConnectionStatusLogDialogMode; onClose: () => void; }; -type RefreshConnectionStatusLogDialogComponentState = ConnectionStatusLogType & { isNameValid: boolean, isHostSet: boolean }; +type RefreshConnectionStatusLogDialogComponentState = ConnectionStatusLogType & { isNameValid: boolean; isHostSet: boolean }; class RefreshConnectionStatusLogDialogComponent extends React.Component { - constructor(props: RefreshConnectionStatusLogDialogComponentProps) { - super(props); - } render(): JSX.Element { const setting = settings[this.props.mode]; return ( - {setting.dialogTitle} + {setting.dialogTitle} {setting.dialogDescription} - - @@ -110,7 +107,7 @@ class RefreshConnectionStatusLogDialogComponent extends React.Component { 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 & { mode: RefreshNetworkElementsDialogMode; onClose: () => void; }; -type RefreshNetworkElementsDialogComponentState = NetworkElementConnection & { isNameValid: boolean, isHostSet: boolean }; +type RefreshNetworkElementsDialogComponentState = NetworkElementConnection & { isNameValid: boolean; isHostSet: boolean }; class RefreshNetworkElementsDialogComponent extends React.Component { - constructor(props: RefreshNetworkElementsDialogComponentProps) { - super(props); - } render(): JSX.Element { const setting = settings[this.props.mode]; return ( - {setting.dialogTitle} + {setting.dialogTitle} {setting.dialogDescription} - - @@ -110,7 +107,7 @@ class RefreshNetworkElementsDialogComponent extends React.Component { 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 = (state = null, action) => { @@ -41,7 +42,7 @@ const currentOpenPanelHandler: IActionHandler = (state = null, action) state = action.panelId; } return state; -} +}; interface guiCutThroughState { searchedElements: guiCutThrough[]; @@ -62,12 +63,12 @@ const guiCutThroughHandler: IActionHandler = (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 = (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(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 { } // 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 = (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 = (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 = (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 = (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(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 | 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) => { + + // 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 ( - ) + ); }); @@ -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(["object-creation-notification", "object-deletion-notification", "attribute-value-changed-notification"], (msg => { + subscribe(['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 { - const path = this.getNetworkElementConnectDataProviderUri("create"); + const path = this.getNetworkElementConnectDataProviderUri('create'); const result = await requestRest(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 { - const path = this.getNetworkElementConnectDataProviderUri("update"); + const path = this.getNetworkElementConnectDataProviderUri('update'); const result = await requestRest(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 { const query = { - "id": element.id + 'id': element.id, }; - const path = this.getNetworkElementConnectDataProviderUri("delete"); + const path = this.getNetworkElementConnectDataProviderUri('delete'); const result = await requestRest(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 { 'TLS', ' ', '2', - ''].join('') + ''].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 { @@ -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 { const path = this.getNetworkElementUri(nodeId); - const topologyRequestPomise = requestRest(path, { method: "GET" }); + const topologyRequestPomise = requestRest(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 { const path = this.getNetworkElementYangLibraryFeature(nodeId); - const topologyRequestPomise = requestRest(path, { method: "GET" }); + const topologyRequestPomise = requestRest(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>(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>(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>(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>(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>(path, { method: "POST", body: JSON.stringify(query) }); - const resultData = result && result["data-provider:output"] && result["data-provider:output"].data; + const result = await requestRest>(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; +const ConnectApplicationComponent: React.FC<{}> = () => { -class ConnectApplicationComponent extends React.Component{ + 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 ( - <> - - - - - - - {activePanelId === 'NetworkElements' - ? - : activePanelId === '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 ( + <> + + + + + + + {panelId === 'NetworkElements' + ? + : panelId === 'ConnectionStatusLog' + ? + : null + } + + ); +}; + +export const ConnectApplication = ConnectApplicationComponent; export default ConnectApplication; \ No newline at end of file -- cgit 1.2.3-korg