From a2b6dd34d73bf432846dc59c6f57dd59a03aff9b Mon Sep 17 00:00:00 2001 From: Michael Dürre Date: Thu, 8 Sep 2022 09:45:06 +0200 Subject: update odlux sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update basic odlux functionality for kohn Issue-ID: CCSDK-3765 Signed-off-by: Michael Dürre Change-Id: I3723c9c2f35b9012ba537920b294a54bb556cbc6 Signed-off-by: Michael Dürre --- .../configurationApp/src/actions/deviceActions.ts | 50 +- .../handlers/connectedNetworkElementsHandler.ts | 2 +- .../configurationApp/src/services/yangService.ts | 4 +- .../src/views/configurationApplication.tsx | 4 +- .../src/views/networkElementSelector.tsx | 2 +- .../apps/configurationApp/src/yang/yangParser.ts | 7 +- .../odlux/apps/configurationApp/webpack.config.js | 22 +- sdnr/wt/odlux/apps/connectApp/package.json | 6 +- .../src/actions/connectionStatusCountActions.ts | 55 - .../src/actions/mountedNetworkElementsActions.ts | 4 +- .../src/actions/networkElementsActions.ts | 6 +- .../src/components/connectionStatusLog.tsx | 2 +- .../connectApp/src/components/dashboardHome.tsx | 425 ----- .../src/components/editNetworkElementDialog.tsx | 46 +- .../src/components/infoNetworkElementDialog.tsx | 12 +- .../connectApp/src/components/networkElements.tsx | 20 +- .../components/refreshNetworkElementsDialog.tsx | 2 +- .../src/handlers/connectAppRootHandler.ts | 3 - .../src/handlers/connectionStatusCountHandler.ts | 61 - .../connectApp/src/models/connectionStatusCount.ts | 43 - .../wt/odlux/apps/connectApp/src/pluginConnect.tsx | 33 +- .../apps/connectApp/src/services/connectService.ts | 16 +- .../src/services/connectionStatusCountService.ts | 54 - .../apps/connectApp/src/views/connectView.tsx | 2 +- sdnr/wt/odlux/apps/connectApp/webpack.config.js | 8 + .../faultApp/src/actions/partialUpdatesAction.ts | 25 - .../apps/faultApp/src/actions/statusActions.ts | 20 +- .../apps/faultApp/src/components/dashboardHome.tsx | 476 ++++++ .../faultApp/src/handlers/faultStatusHandler.ts | 33 +- sdnr/wt/odlux/apps/faultApp/src/models/fault.ts | 23 +- sdnr/wt/odlux/apps/faultApp/src/pluginFault.tsx | 7 +- .../faultApp/src/services/faultStatusService.ts | 20 +- .../apps/faultApp/src/views/faultApplication.tsx | 12 +- .../wt/odlux/apps/helpApp/src/views/helpTocApp.tsx | 2 +- sdnr/wt/odlux/apps/helpApp/webpack.config.js | 19 +- .../handlers/connectedNetworkElementsHandler.ts | 2 +- sdnr/wt/odlux/apps/mediatorApp/pom.xml | 2 +- .../mediatorApp/src/views/mediatorApplication.tsx | 4 +- .../src/views/mediatorServerSelection.tsx | 2 +- .../src/handlers/adaptiveModulationHandler.ts | 2 +- .../handlers/crossPolarDiscriminationHandler.ts | 2 +- .../src/handlers/performanceDataHandler.ts | 2 +- .../src/handlers/receiveLevelHandler.ts | 2 +- .../src/handlers/signalToInterferenceHandler.ts | 2 +- .../src/handlers/temperatureHandler.ts | 2 +- .../src/handlers/transmissionPowerHandler.ts | 2 +- .../features/sdnr/wt/odlux/ResFilesServlet.java | 20 +- sdnr/wt/odlux/framework/pom.xml | 8 - .../odlux/framework/src/actions/authentication.ts | 38 +- .../odlux/framework/src/actions/settingsAction.ts | 86 +- sdnr/wt/odlux/framework/src/assets/images/home.svg | 20 + .../framework/src/assets/images/home.svg.d.ts | 20 + .../src/components/material-table/columnModel.ts | 1 + .../src/components/material-table/index.tsx | 51 +- .../components/material-table/showColumnDialog.tsx | 188 ++ .../src/components/material-table/tableFilter.tsx | 7 +- .../src/components/material-table/tableHead.tsx | 14 +- .../src/components/material-table/tableToolbar.tsx | 36 +- .../src/components/material-table/utilities.ts | 40 +- .../framework/src/components/navigationMenu.tsx | 11 +- .../wt/odlux/framework/src/components/titleBar.tsx | 8 +- .../src/handlers/applicationStateHandler.ts | 29 +- .../src/handlers/authenticationHandler.ts | 4 - sdnr/wt/odlux/framework/src/index.dev.html | 2 +- sdnr/wt/odlux/framework/src/index.html | 2 +- .../wt/odlux/framework/src/models/elasticSearch.ts | 11 + .../odlux/framework/src/models/iconDefinition.ts | 2 +- sdnr/wt/odlux/framework/src/models/settings.ts | 24 + .../src/services/authenticationService.ts | 8 +- .../framework/src/services/broadcastService.ts | 2 +- .../framework/src/services/forceLogoutService.ts | 57 - .../wt/odlux/framework/src/services/restService.ts | 15 +- .../framework/src/services/userSessionService.ts | 2 +- .../odlux/framework/src/utilities/elasticSearch.ts | 94 +- sdnr/wt/odlux/framework/src/views/about.tsx | 6 +- sdnr/wt/odlux/framework/src/views/frame.tsx | 3 +- sdnr/wt/odlux/framework/src/views/login.tsx | 28 +- sdnr/wt/odlux/framework/src/views/test.tsx | 2 +- .../framework/src2/main/resources/version.json | 2 - sdnr/wt/odlux/framework/webpack.vendor.js | 5 +- sdnr/wt/odlux/lerna.json | 8 +- sdnr/wt/odlux/odlux.properties | 17 +- sdnr/wt/odlux/yarn.lock | 1791 +++++++++++++++----- 83 files changed, 2738 insertions(+), 1474 deletions(-) delete mode 100644 sdnr/wt/odlux/apps/connectApp/src/actions/connectionStatusCountActions.ts delete mode 100644 sdnr/wt/odlux/apps/connectApp/src/components/dashboardHome.tsx delete mode 100644 sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusCountHandler.ts delete mode 100644 sdnr/wt/odlux/apps/connectApp/src/models/connectionStatusCount.ts delete mode 100644 sdnr/wt/odlux/apps/connectApp/src/services/connectionStatusCountService.ts delete mode 100644 sdnr/wt/odlux/apps/faultApp/src/actions/partialUpdatesAction.ts create mode 100644 sdnr/wt/odlux/apps/faultApp/src/components/dashboardHome.tsx create mode 100644 sdnr/wt/odlux/framework/src/assets/images/home.svg create mode 100644 sdnr/wt/odlux/framework/src/assets/images/home.svg.d.ts create mode 100644 sdnr/wt/odlux/framework/src/components/material-table/showColumnDialog.tsx delete mode 100644 sdnr/wt/odlux/framework/src/services/forceLogoutService.ts (limited to 'sdnr/wt/odlux') diff --git a/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts b/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts index 0dd42e3b7..2846dba06 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts +++ b/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts @@ -1,21 +1,3 @@ -/** - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt odlux - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ - import { Action } from '../../../../framework/src/flux/action'; import { Dispatch } from '../../../../framework/src/flux/store'; import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore"; @@ -65,6 +47,22 @@ export class UpdatOutputData extends Action { } } +type HttpResult = { + status: number; + message?: string | undefined; + data: { + [key: string]: any; + } | null | undefined; +}; + +const checkResponseCode = (restResult: HttpResult) =>{ + + //403 gets handled by the framework from now on + + return restResult.status !== 403 && ( restResult.status < 200 || restResult.status > 299); + +} + export const updateNodeIdAsyncActionCreator = (nodeId: string) => async (dispatch: Dispatch, getState: () => IApplicationStoreState ) => { dispatch(new UpdateDeviceDescription("", {}, [])); @@ -81,8 +79,8 @@ export const updateNodeIdAsyncActionCreator = (nodeId: string) => async (dispatc })); throw new Error(`NetworkElement : [${nodeId}] has no capabilities.`); } - - const parser = new YangParser(unavailableCapabilities || undefined, importOnlyModules || undefined); + + const parser = new YangParser(unavailableCapabilities || undefined, importOnlyModules || undefined, nodeId); for (let i = 0; i < availableCapabilities.length; ++i){ const capRaw = availableCapabilities[i]; @@ -146,7 +144,7 @@ const getReferencedDataList = async (refPath: string, dataPath: string, modules: for (let j = 0; j < dataUrls.length; ++j) { const dataUrl = dataUrls[j]; const restResult = (await restService.getConfigData(dataUrl)); - if (restResult.data == null || restResult.status < 200 || restResult.status > 299) { + if (restResult.data == null || checkResponseCode(restResult)) { const message = restResult.data && restResult.data.errors && restResult.data.errors.error && restResult.data.errors.error[0] && restResult.data.errors.error[0]["error-message"] || ""; throw new Error(`Server Error. Status: [${restResult.status}]\n${message || restResult.message || ''}`); } @@ -178,7 +176,7 @@ const getReferencedDataList = async (refPath: string, dataPath: string, modules: for (let j = 0; j < dataUrls.length; ++j) { const dataUrl = dataUrls[j]; const restResult = (await restService.getConfigData(dataUrl)); - if (restResult.data == null || restResult.status < 200 || restResult.status > 299) { + if (restResult.data == null || checkResponseCode(restResult)) { const message = restResult.data && restResult.data.errors && restResult.data.errors.error && restResult.data.errors.error[0] && restResult.data.errors.error[0]["error-message"] || ""; throw new Error(`Server Error. Status: [${restResult.status}]\n${message || restResult.message || ''}`); } @@ -426,7 +424,7 @@ export const updateViewActionAsyncCreator = (vPath: string) => async (dispatch: return dispatch(new UpdatViewDescription(vPath, [], ds)); } throw new Error(`Did not get response from Server. Status: [${restResult.status}]`); - } else if (restResult.status < 200 || restResult.status > 299) { + } else if (checkResponseCode(restResult)) { const message = restResult.data.errors && restResult.data.errors.error && restResult.data.errors.error[0] && restResult.data.errors.error[0]["error-message"] || ""; throw new Error(`Server Error. Status: [${restResult.status}]\n${message}`); } else { @@ -581,7 +579,7 @@ export const updateDataActionAsyncCreator = (vPath: string, data: any) => async // do not extract root member (0) if (viewSpecification && viewSpecification.id !== "0") { const updateResult = await restService.setConfigData(dataPath, { [`${currentNS}:${dataMember!}`]: data }); // addDataMember using currentNS - if (updateResult.status < 200 || updateResult.status > 299) { + if (checkResponseCode(updateResult)) { const message = updateResult.data && updateResult.data.errors && updateResult.data.errors.error && updateResult.data.errors.error[0] && updateResult.data.errors.error[0]["error-message"] || ""; throw new Error(`Server Error. Status: [${updateResult.status}]\n${message || updateResult.message || ''}`); } @@ -653,7 +651,7 @@ export const removeElementActionAsyncCreator = (vPath: string) => async (dispatc } const updateResult = await restService.removeConfigElement(dataPath); - if (updateResult.status < 200 || updateResult.status > 299) { + if (checkResponseCode(updateResult)) { const message = updateResult.data && updateResult.data.errors && updateResult.data.errors.error && updateResult.data.errors.error[0] && updateResult.data.errors.error[0]["error-message"] || ""; throw new Error(`Server Error. Status: [${updateResult.status}]\n${message || updateResult.message || ''}`); } @@ -747,7 +745,7 @@ export const executeRpcActionAsyncCreator = (vPath: string, data: any) => async // do not post root member (0) if ((viewSpecification && viewSpecification.id !== "0") || (dataMember! && !data)) { const updateResult = await restService.executeRpc(dataPath, { [`${defaultNS}:input`]: data || {} }); - if (updateResult.status < 200 || updateResult.status > 299) { + if (checkResponseCode(updateResult)) { const message = updateResult.data && updateResult.data.errors && updateResult.data.errors.error && updateResult.data.errors.error[0] && updateResult.data.errors.error[0]["error-message"] || ""; throw new Error(`Server Error. Status: [${updateResult.status}]\n${message || updateResult.message || ''}`); } diff --git a/sdnr/wt/odlux/apps/configurationApp/src/handlers/connectedNetworkElementsHandler.ts b/sdnr/wt/odlux/apps/configurationApp/src/handlers/connectedNetworkElementsHandler.ts index 02f2929cd..8ca8fdf27 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/handlers/connectedNetworkElementsHandler.ts +++ b/sdnr/wt/odlux/apps/configurationApp/src/handlers/connectedNetworkElementsHandler.ts @@ -26,7 +26,7 @@ import { restService } from '../services/restServices'; export interface IConnectedNetworkElementsState extends IExternalTableState { } // create eleactic search material data fetch handler -const connectedNetworkElementsSearchHandler = createSearchDataHandler('network-element-connection', { status: "Connected" }); +const connectedNetworkElementsSearchHandler = createSearchDataHandler('network-element-connection', false, { status: "Connected" }); export const { actionHandler: connectedNetworkElementsActionHandler, diff --git a/sdnr/wt/odlux/apps/configurationApp/src/services/yangService.ts b/sdnr/wt/odlux/apps/configurationApp/src/services/yangService.ts index cf4677bc9..b81a92c14 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/services/yangService.ts +++ b/sdnr/wt/odlux/apps/configurationApp/src/services/yangService.ts @@ -24,8 +24,8 @@ const cache: { [path: string]: string } = { class YangService { - public async getCapability(capability: string, version?: string) { - const url = `/yang-schema/${capability}${version ? `/${version}` : ""}`; + public async getCapability(capability: string, nodeId: string, version?: string) { + const url = `/yang-schema/${capability}${version ? `/${version}` : ""}?node=${nodeId}`; const cacheHit = cache[url]; if (cacheHit) return cacheHit; diff --git a/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx b/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx index 2879899a5..12815a517 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx +++ b/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx @@ -639,7 +639,7 @@ class ConfigurationApplicationComponent extends React.Component[]>((acc, cur) => { const elm = listElements[cur]; if (elm.uiType !== "object" && listData.every(entry => entry[elm.label] != null)) { @@ -822,7 +822,7 @@ class ConfigurationApplicationComponent extends React.Component - []>((acc, cur) => { const elm = listSpecification.elements[cur]; if (elm.uiType !== "object" && listData.every(entry => entry[elm.label] != null)) { diff --git a/sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx b/sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx index 5cac22eba..1a1008dad 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx +++ b/sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx @@ -54,7 +54,7 @@ class NetworkElementSelectorComponent extends React.Component { this.props.history.push(`${this.props.match.path}/${row.nodeId}`) }} columns={[ + { this.props.history.push(`${this.props.match.path}/${row.nodeId}`) }} columns={[ { property: "nodeId", title: "Node Name", type: ColumnType.text }, { property: "isRequired", title: "Required", type: ColumnType.boolean }, { property: "host", title: "Host", type: ColumnType.text }, diff --git a/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts b/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts index c80bd4c84..965935a5c 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts +++ b/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts @@ -286,7 +286,7 @@ export class YangParser { public static ResolveStack = Symbol("ResolveStack"); - constructor(private _unavailableCapabilities: { failureReason: string; capability: string; }[] = [], private _importOnlyModules: { name: string; revision: string; }[] = []) { + constructor(private _unavailableCapabilities: { failureReason: string; capability: string; }[] = [], private _importOnlyModules: { name: string; revision: string; }[] = [], private nodeId: string) { } @@ -310,8 +310,7 @@ export class YangParser { // // console.warn(`Skipped capability: ${capability} since it is marked as unavailable.` ); // return; // } - - const data = await yangService.getCapability(capability, version); + const data = await yangService.getCapability(capability, this.nodeId, version); if (!data) { throw new Error(`Could not load yang file for ${capability}.`); } @@ -409,6 +408,8 @@ export class YangParser { // import all required files and set module state if (imports) for (let ind = 0; ind < imports.length; ++ind) { const moduleName = imports[ind].arg!; + + //TODO: Fix imports getting loaded without revision await this.addCapability(moduleName, undefined, module.state === ModuleState.importOnly); const importedModule = this._modules[imports[ind].arg!]; if (importedModule && importedModule.state > ModuleState.stable) { diff --git a/sdnr/wt/odlux/apps/configurationApp/webpack.config.js b/sdnr/wt/odlux/apps/configurationApp/webpack.config.js index 5461c14f2..57caf079f 100644 --- a/sdnr/wt/odlux/apps/configurationApp/webpack.config.js +++ b/sdnr/wt/odlux/apps/configurationApp/webpack.config.js @@ -135,49 +135,49 @@ module.exports = (env) => { }, proxy: { "/about": { - target: "http://localhost:18181", + target: "http://sdnr:8181", secure: false }, "/yang-schema/": { - target: "http://localhost:18181", + target: "http://sdnr:8181", secure: false }, "/oauth/": { - target: "http://localhost:18181", + target: "http://sdnr:8181", secure: false }, "/database/": { - target: "http://localhost:18181", + target: "http://sdnr:8181", secure: false }, "/restconf/": { - target: "http://localhost:18181", + target: "http://sdnr:8181", secure: false }, "/rests/": { - target: "http://localhost:18181", + target: "http://sdnr:8181", secure: false }, "/help/": { - target: "http://localhost:18181", + target: "http://sdnr:8181", secure: false }, "/about/": { - target: "http://localhost:18181", + target: "http://sdnr:8181", secure: false }, "/tree/": { - target: "http://localhost:18181", + target: "http://sdnr:8181", secure: false }, "/websocket": { - target: "http://localhost:18181", + target: "http://sdnr:8181", ws: true, changeOrigin: true, secure: false }, "/apidoc": { - target: "http://localhost:18181", + target: "http://sdnr:8181", ws: true, changeOrigin: true, secure: false diff --git a/sdnr/wt/odlux/apps/connectApp/package.json b/sdnr/wt/odlux/apps/connectApp/package.json index 9ecdaf853..a31824ae2 100644 --- a/sdnr/wt/odlux/apps/connectApp/package.json +++ b/sdnr/wt/odlux/apps/connectApp/package.json @@ -1,7 +1,7 @@ { "name": "@odlux/connect-app", "version": "0.1.1", - "description": "A react based modular UI to display network connect data from a database.", + "description": "A react based modular UI to display network element/node connect data from a database.", "main": "index.js", "scripts": { "start": "webpack-dev-server --env debug", @@ -26,9 +26,7 @@ "@mui/icons-material": "^5.2.0", "@mui/material": "^5.2.2", "@mui/styles": "^5.2.2", - "@odlux/framework": "*", - "react-chartjs-2": "2.7.6", - "chart.js": "2.8.0" + "@odlux/framework": "*" }, "peerDependencies": { "@types/classnames": "2.2.6", diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/connectionStatusCountActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/connectionStatusCountActions.ts deleted file mode 100644 index 43bae720c..000000000 --- a/sdnr/wt/odlux/apps/connectApp/src/actions/connectionStatusCountActions.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt odlux - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -import { getConnectionStatusCountStateFromDatabase } from '../services/connectionStatusCountService'; -import { Dispatch } from '../../../../framework/src/flux/store'; - -import { Action } from '../../../../framework/src/flux/action'; - - -export class ConnectionStatusCountBaseAction extends Action { } - - -export class SetConnectionStatusCountAction extends ConnectionStatusCountBaseAction { - constructor(public ConnectedCount: number, public ConnectingCount: number, public DisconnectedCount: number, - public MountedCount: number, public UnableToConnectCount: number, public UndefinedCount: number, public UnmountedCount: number, public totalCount: number, public isLoadingConnectionStatusChart: boolean) { - super(); - } -} - - -export const refreshConnectionStatusCountAsyncAction = async (dispatch: Dispatch) => { - dispatch(new SetConnectionStatusCountAction(0, 0, 0, 0, 0, 0, 0, 0, true)); - const result = await getConnectionStatusCountStateFromDatabase().catch(_ => null); - if (result) { - const statusAction = new SetConnectionStatusCountAction( - result["Connected"] || 0, - result["Connecting"] || 0, - result["Disconnected"] || 0, - result["Mounted"] || 0, - result["UnableToConnect"] || 0, - result["Undefined"] || 0, - result["Unmounted"] || 0, - result["total"] || 0, - false - ); - dispatch(statusAction); - return; - } else { - dispatch(new SetConnectionStatusCountAction(0, 0, 0, 0, 0, 0, 0, 0, false)); - } -} diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts index 84e73ae5a..26ee7674f 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts @@ -27,7 +27,7 @@ import { updateCurrentViewAsyncAction } from './commonNetworkElementsActions'; /** Represents the base action. */ export class BaseAction extends Action { } -/** Represents an action crator for a async thunk action to mount a network element. */ +/** Represents an action creator for a async thunk action to mount a network element/node. */ export const mountNetworkElementAsyncActionCreator = (networkElement: NetworkElementConnection) => (dispatch: Dispatch) => { return connectService.mountNetworkElement(networkElement).then((success) => { if (success) { @@ -42,7 +42,7 @@ export const mountNetworkElementAsyncActionCreator = (networkElement: NetworkEle }); }; -/** Represents an action crator for a async thunk action to unmount a network element. */ +/** Represents an action creator for a async thunk action to unmount a network element/node. */ export const unmountNetworkElementAsyncActionCreator = (nodeId: string) => (dispatch: Dispatch) => { return connectService.unmountNetworkElement(nodeId).then((success) => { if (success) { diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts index 041cff9da..57f036e56 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts @@ -28,14 +28,14 @@ import { unmountNetworkElementAsyncActionCreator } from './mountedNetworkElement /** Represents the base action. */ export class BaseAction extends Action { } -/** Represents an async thunk action creator to add an element to the network elements. */ +/** 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 }); dispatch(updateCurrentViewAsyncAction()); dispatch(new AddSnackbarNotification({ message: `Successfully added [${element.nodeId}]`, options: { variant: 'success' } })); }; -/** Represents an async thunk action creator to edit network element. */ +/** Represents an async thunk action creator to edit network element/node. */ export const editNetworkElementAsyncActionCreator = (element: UpdateNetworkElement) => async (dispatch: Dispatch) => { const connectionStatus: ConnectionStatus[] = (await connectService.getNetworkElementConnectionStatus(element.id).then(ne => (ne))) || []; const currentConnectionStatus = connectionStatus[0].status; @@ -50,7 +50,7 @@ export const editNetworkElementAsyncActionCreator = (element: UpdateNetworkEleme }; -/** Represents an async thunk action creator to delete an element from network elements. */ +/** 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 dispatch(unmountNetworkElementAsyncActionCreator(element && element.id)); diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx index a7d96d072..b240b2419 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx @@ -65,7 +65,7 @@ class ConnectionStatusLogComponent extends React.Component diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/dashboardHome.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/dashboardHome.tsx deleted file mode 100644 index 683c59623..000000000 --- a/sdnr/wt/odlux/apps/connectApp/src/components/dashboardHome.tsx +++ /dev/null @@ -1,425 +0,0 @@ -/** - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt odlux - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -import * as React from 'react'; - -import { withRouter, RouteComponentProps } from 'react-router-dom'; -import connect, { Connect, IDispatcher } from '../../../../framework/src/flux/connect';; -import { Theme } from '@mui/material'; -import { WithStyles } from '@mui/styles'; -import createStyles from '@mui/styles/createStyles'; -import withStyles from '@mui/styles/withStyles'; -import { Doughnut } from 'react-chartjs-2'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; -import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions'; - -const styles = (theme: Theme) => createStyles({ - pageWidthSettings: { - width: '50%', - float: 'left' - }, -}) - -const scrollbar = { overflow: "auto", paddingRight: "20px" } - -let connectionStatusinitialLoad = true; -let connectionStatusinitialStateChanged = false; -let connectionStatusDataLoad: number[] = [0, 0, 0, 0]; -let connectionTotalCount = 0; - -let alarmStatusinitialLoad = true; -let alarmStatusinitialStateChanged = false; -let alarmStatusDataLoad: number[] = [0, 0, 0, 0]; -let alarmTotalCount = 0; - -const mapProps = (state: IApplicationStoreState) => ({ - connectionStatusCount: state.connect.connectionStatusCount, - alarmStatus: state.fault.faultStatus -}); - -const mapDispatch = (dispatcher: IDispatcher) => ({ - navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)), -}); - -type HomeComponentProps = RouteComponentProps & Connect & WithStyles; - -class DashboardHome extends React.Component { - constructor(props: HomeComponentProps) { - super(props); - this.state = { - } - } - - render(): JSX.Element { - const { classes } = this.props; - - if (!this.props.connectionStatusCount.isLoadingConnectionStatusChart) { - connectionStatusDataLoad = [ - this.props.connectionStatusCount.Connected, - this.props.connectionStatusCount.Connecting, - this.props.connectionStatusCount.Disconnected, - this.props.connectionStatusCount.UnableToConnect - ]; - connectionTotalCount = this.props.connectionStatusCount.Connected + this.props.connectionStatusCount.Connecting - + this.props.connectionStatusCount.Disconnected + this.props.connectionStatusCount.UnableToConnect; - - } - - if (!this.props.alarmStatus.isLoadingAlarmStatusChart) { - alarmStatusDataLoad = [ - this.props.alarmStatus.critical, - this.props.alarmStatus.major, - this.props.alarmStatus.minor, - this.props.alarmStatus.warning - ]; - alarmTotalCount = this.props.alarmStatus.critical + this.props.alarmStatus.major - + this.props.alarmStatus.minor + this.props.alarmStatus.warning; - } - - /** Available Network Connection Status chart data */ - const connectionStatusData = { - labels: ['Connected', 'Connecting', 'Disconnected', 'UnableToConnect'], - datasets: [{ - data: connectionStatusDataLoad, - backgroundColor: [ - 'rgb(0, 153, 51)', - 'rgb(255, 102, 0)', - 'rgb(191, 191, 191)', - 'rgb(191, 191, 191)' - ] - }] - }; - - - /** No Devices available */ - const connectionStatusUnavailableData = { - labels: ['No Devices available'], - datasets: [{ - data: [1], - backgroundColor: [ - 'rgb(255, 255, 255)' - ] - }] - }; - - /** Loading Connection Status chart */ - const connectionStatusisLoading = { - labels: ['Loading chart...'], - datasets: [{ - data: [1], - backgroundColor: [ - 'rgb(255, 255, 255)' - ] - }] - }; - - /** Loading Alarm Status chart */ - const alarmStatusisLoading = { - labels: ['Loading chart...'], - datasets: [{ - data: [1], - backgroundColor: [ - 'rgb(255, 255, 255)' - ] - }] - }; - - /** Connection status options */ - let labels: String[] = ['Connected', 'Connecting', 'Disconnected', 'UnableToConnect']; - const connectionStatusOptions = { - responsive: true, - maintainAspectRatio: false, - animation: { - duration: 0 - }, - plugins: { - legend: { - display: true, - position: 'top' - } - }, - onClick: (event: MouseEvent, item: any) => { - if (item[0]) { - let connectionStatus = labels[item[0]._index] + ''; - this.props.navigateToApplication("connect", '/connectionStatus/' + connectionStatus); - } - } - } - - /** Connection status unavailable options */ - const connectionStatusUnavailableOptions = { - responsive: true, - maintainAspectRatio: false, - animation: { - duration: 0 - }, - plugins: { - legend: { - display: true, - position: 'top' - }, - tooltip: { - enabled: false - } - } - } - - /** Add text inside the doughnut chart for Connection Status */ - const connectionStatusPlugins = [{ - beforeDraw: function (chart: any) { - var width = chart.width, - height = chart.height, - ctx = chart.ctx; - ctx.restore(); - var fontSize = (height / 480).toFixed(2); - ctx.font = fontSize + "em sans-serif"; - ctx.textBaseline = "top"; - var text = "Network Connection Status", - textX = Math.round((width - ctx.measureText(text).width) / 2), - textY = height / 2; - ctx.fillText(text, textX, textY); - ctx.save(); - } - }] - - /** Alarm status Data */ - const alarmStatusData = { - labels: [ - 'Critical', - 'Major', - 'Minor', - 'Warning' - ], - datasets: [{ - data: alarmStatusDataLoad, - backgroundColor: [ - 'rgb(240, 25, 10)', - 'rgb(240, 133, 10)', - 'rgb(240, 240, 10)', - 'rgb(46, 115, 176)' - ], - }] - } - - /** No Alarm status available */ - const alarmStatusUnavailableData = { - labels: ['No Alarms available'], - datasets: [{ - data: [1], - backgroundColor: [ - 'rgb(0, 153, 51)' - ] - }] - }; - - /** Alarm status Options */ - let alarmLabels: String[] = ['Critical', 'Major', 'Minor', 'Warning']; - const alarmStatusOptions = { - responsive: true, - maintainAspectRatio: false, - animation: { - duration: 0 - }, - plugins: { - legend: { - display: true, - position: 'top' - } - }, - onClick: (event: MouseEvent, item: any) => { - if (item[0]) { - let severity = alarmLabels[item[0].index] + ''; - this.props.navigateToApplication("fault", '/alarmStatus/' + severity); - } - }, - }; - - /** Alarm status unavailable options */ - const alarmStatusUnavailableOptions = { - responsive: true, - maintainAspectRatio: false, - animation: { - duration: 0 - }, - plugins: { - legend: { - display: true, - position: 'top' - }, - tooltip: { - enabled: false - } - } - } - /** Add text inside the doughnut chart for Alarm Status */ - const alarmStatusPlugins = [{ - beforeDraw: function (chart: any) { - var width = chart.width, - height = chart.height, - ctx = chart.ctx; - ctx.restore(); - var fontSize = (height / 480).toFixed(2); - ctx.font = fontSize + "em sans-serif"; - ctx.textBaseline = "top"; - var text = "Network Alarm Status", - textX = Math.round((width - ctx.measureText(text).width) / 2), - textY = height / 2; - ctx.fillText(text, textX, textY); - ctx.save(); - } - }] - - return ( - <> -
-

Welcome to ODLUX

-
- {this.checkElementsAreLoaded() ? - this.checkConnectionStatus() && connectionTotalCount != 0 ? - - : - : - } -
-
- {this.checkAlarmsAreLoaded() ? - this.checkAlarmStatus() && alarmTotalCount != 0 ? - - : - : - } -
-
- - ) - } - - /** Check if connection status data available */ - public checkConnectionStatus = () => { - let statusCount = this.props.connectionStatusCount; - if (statusCount.isLoadingConnectionStatusChart) { - return true; - } - if (statusCount.Connected == 0 && statusCount.Connecting == 0 && statusCount.Disconnected == 0 - && statusCount.UnableToConnect == 0) { - return false; - } else { - return true; - } - } - - /** Check if connection status chart data is loaded */ - public checkElementsAreLoaded = () => { - let isLoadingCheck = this.props.connectionStatusCount; - if (connectionStatusinitialLoad && !isLoadingCheck.isLoadingConnectionStatusChart) { - if (this.checkConnectionStatus()) { - connectionStatusinitialLoad = false; - return true; - } - return false; - } else if (connectionStatusinitialLoad && isLoadingCheck.isLoadingConnectionStatusChart) { - connectionStatusinitialLoad = false; - connectionStatusinitialStateChanged = true; - return !isLoadingCheck.isLoadingConnectionStatusChart; - } else if (connectionStatusinitialStateChanged) { - if (!isLoadingCheck.isLoadingConnectionStatusChart) { - connectionStatusinitialStateChanged = false; - } - return !isLoadingCheck.isLoadingConnectionStatusChart; - } - return true; - } - - /** Check if alarms data available */ - public checkAlarmStatus = () => { - let alarmCount = this.props.alarmStatus; - if (alarmCount.isLoadingAlarmStatusChart) { - return true; - } - if (alarmCount.critical == 0 && alarmCount.major == 0 && alarmCount.minor == 0 && alarmCount.warning == 0) { - return false; - } - else { - return true; - } - } - - /** Check if alarm status chart data is loaded */ - public checkAlarmsAreLoaded = () => { - let isLoadingCheck = this.props.alarmStatus; - if (alarmStatusinitialLoad && !isLoadingCheck.isLoadingAlarmStatusChart) { - if (this.checkAlarmStatus()) { - alarmStatusinitialLoad = false; - return true; - } - return false; - } else if (alarmStatusinitialLoad && isLoadingCheck.isLoadingAlarmStatusChart) { - alarmStatusinitialLoad = false; - alarmStatusinitialStateChanged = true; - return !isLoadingCheck.isLoadingAlarmStatusChart; - } else if (alarmStatusinitialStateChanged) { - if (!isLoadingCheck.isLoadingAlarmStatusChart) { - alarmStatusinitialStateChanged = false; - } - return !isLoadingCheck.isLoadingAlarmStatusChart; - } - return true; - } -} - -export default (withRouter(connect(mapProps, mapDispatch)(DashboardHome))); \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx index 7324ffab8..5740ebda0 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx @@ -72,10 +72,10 @@ const mapDispatch = (dispatcher: IDispatcher) => ({ if (values.length === 2 && values.includes(idProperty as string) && values.includes(isRequiredProperty as string)) { - // do not mount network element, if only isRequired is changed + // do not mount network element/node, if only isRequired is changed await dispatcher.dispatch(editNetworkElementAsyncActionCreator(element)); - } else if (!(values.length === 1 && values.includes(idProperty as string))) { //do not edit or mount element, if only id was saved into object (no changes made!) + } else if (!(values.length === 1 && values.includes(idProperty as string))) { //do not edit or mount network element/node , if only id was saved into object (no changes made!) await dispatcher.dispatch(editNetworkElementAsyncActionCreator(element)); await dispatcher.dispatch(mountNetworkElementAsyncActionCreator(mountElement)); } @@ -109,35 +109,35 @@ const settings: { [key: string]: DialogSettings } = { }, [EditNetworkElementDialogMode.AddNewNetworkElement]: { - dialogTitle: "Add new network element", - dialogDescription: "Add this new network element:", - applyButtonText: "Add network element", + dialogTitle: "Add New Node", + dialogDescription: "Add this new node:", + applyButtonText: "Add node", cancelButtonText: "Cancel", enableMountIdEditor: true, enableUsernameEditor: true, enableExtendedEditor: true, }, [EditNetworkElementDialogMode.MountNetworkElement]: { - dialogTitle: "Mount network element", - dialogDescription: "mount this network element:", - applyButtonText: "mount network element", + dialogTitle: "Mount Node", + dialogDescription: "Mount this node:", + applyButtonText: "Mount node", cancelButtonText: "Cancel", enableMountIdEditor: false, enableUsernameEditor: false, enableExtendedEditor: false, }, [EditNetworkElementDialogMode.UnmountNetworkElement]: { - dialogTitle: "Unmount network element", - dialogDescription: "unmount this network element:", - applyButtonText: "Unmount network element", + dialogTitle: "Unmount Node", + dialogDescription: "Unmount this node:", + applyButtonText: "Unmount node", cancelButtonText: "Cancel", enableMountIdEditor: false, enableUsernameEditor: false, enableExtendedEditor: false, }, [EditNetworkElementDialogMode.EditNetworkElement]: { - dialogTitle: "Modify the network elements", - dialogDescription: "Modify this network element", + dialogTitle: "Modify Node", + dialogDescription: "Modify this node", applyButtonText: "Modify", cancelButtonText: "Cancel", enableMountIdEditor: false, @@ -145,9 +145,9 @@ const settings: { [key: string]: DialogSettings } = { enableExtendedEditor: false, }, [EditNetworkElementDialogMode.RemoveNetworkElement]: { - dialogTitle: "Remove network element", - dialogDescription: "Do you really want to remove this network element:", - applyButtonText: "Remove network element", + dialogTitle: "Remove Node", + dialogDescription: "Do you really want to remove this node?", + applyButtonText: "Remove node", cancelButtonText: "Cancel", enableMountIdEditor: false, enableUsernameEditor: false, @@ -176,9 +176,11 @@ class EditNetworkElementDialogComponent extends React.Component {setting.dialogDescription} - { this.setState({ nodeId: event.target.value }); }} /> - {!this.state.isNameValid && Name cannot be empty.} - { this.setState({ host: event.target.value }); }} /> - {!this.state.isHostSet && IP Adress cannot be empty.} + { this.setState({ nodeId: event.target.value }); }} /> + {!this.state.isNameValid && Node ID cannot be empty.} + { this.setState({ host: event.target.value }); }} /> + {!this.state.isHostSet && Host/IP address cannot be empty.} - { this.setState({ port: +event.target.value }); }} /> + { this.setState({ port: +event.target.value }); }} /> {setting.enableUsernameEditor && { this.setState({ username: event.target.value }); }} /> || null} {setting.enableUsernameEditor && diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx index 5514fa5f8..b0c7840be 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx @@ -51,7 +51,7 @@ cancelButtonText: "", }, [InfoNetworkElementDialogMode.InfoNetworkElement]: { - dialogTitle: "Yang capabilities of the network element", + dialogTitle: "YANG Capabilities of the Node", dialogDescription: "", cancelButtonText: "OK", } @@ -88,7 +88,7 @@ const indexRevision = capabilty.indexOf("revision="); const indexModule = capabilty.indexOf(")", indexRevision); if (indexRevision > 0 && indexModule > 0) { - let moduleName = capabilty.substr(indexModule + 1); + let moduleName = capabilty.substring(indexModule + 1); let ModuleFeaturesList; for(let index = 0; index < yangFeatures.length; index++) { if(yangFeatures[index].name == moduleName) { @@ -101,7 +101,7 @@ yangCapabilities.push({ module: moduleName, - revision: capabilty.substr(indexRevision + 9, 10), + revision: capabilty.substring(indexRevision + 9, indexRevision + 19), features: featuresList }); } @@ -112,14 +112,14 @@ return ( <> - {setting.dialogTitle + ' - ' + this.state.nodeId} + {`${setting.dialogTitle}: "${this.state.nodeId}"`} { return ( ) } diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx index a17a247d2..67fdef69d 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx @@ -109,7 +109,7 @@ type NetworkElementsListComponentState = { elementInfoFeature: ModuleSet | null } -const emptyRequireNetworkElement: NetworkElementConnection = { id: "", nodeId: "", host: "", port: 0, status: "Disconnected", isRequired: false }; +const emptyRequireNetworkElement: NetworkElementConnection = { id: "", nodeId: "", host: "", port: 830, status: "Disconnected", isRequired: true }; let initialSorted = false; const NetworkElementTable = MaterialTable as MaterialTableCtorType; @@ -138,7 +138,7 @@ export class NetworkElementsListComponent extends React.Component this.onOpenMountdNetworkElementsDialog(event, rowData)} disabled={!canMount} >Mount, this.onOpenUnmountdNetworkElementsDialog(event, rowData)} disabled={!canMount} >Unmount, , - this.onOpenInfoNetworkElementDialog(event, rowData)} disabled={rowData.status === "Connecting" || rowData.status === "Disconnected"} >Info, + this.onOpenInfoNetworkElementDialog(event, rowData)} disabled={rowData.status !== "Connected"} >Info, this.onOpenEditNetworkElementDialog(event, rowData)}>Edit, this.onOpenRemoveNetworkElementDialog(event, rowData)} >Remove, , @@ -177,7 +177,7 @@ export class NetworkElementsListComponent extends React.Component { + icon: AddIcon, tooltip: 'Add node', ariaLabel: "add-element", onClick: () => { this.setState({ networkElementEditorMode: EditNetworkElementDialogMode.AddNewNetworkElement, networkElementToEdit: emptyRequireNetworkElement, @@ -186,7 +186,7 @@ export class NetworkElementsListComponent extends React.Component { + icon: Refresh, tooltip: 'Refresh table', ariaLabel: 'refresh', onClick: () => { this.setState({ refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.RefreshNetworkElementsTable }); @@ -195,20 +195,20 @@ export class NetworkElementsListComponent extends React.Component { return this.getContextMenu(rowData); }} > - = (state = connectionStatusCountInit, action) => { - if (action instanceof SetConnectionStatusCountAction) { - state = { - Connected: action.ConnectedCount, - Connecting: action.ConnectingCount, - Disconnected: action.DisconnectedCount, - Mounted: action.MountedCount, - UnableToConnect: action.UnableToConnectCount, - Undefined: action.UndefinedCount, - Unmounted: action.UnmountedCount, - total: action.totalCount, - isLoadingConnectionStatusChart: action.isLoadingConnectionStatusChart - } - } - - return state; -} \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/connectionStatusCount.ts b/sdnr/wt/odlux/apps/connectApp/src/models/connectionStatusCount.ts deleted file mode 100644 index 125a6e369..000000000 --- a/sdnr/wt/odlux/apps/connectApp/src/models/connectionStatusCount.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt odlux - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.number (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.number - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ - -export type ConnectionStatusCountReturnType = { - Connected: number, - Connecting: number, - Disconnected: number, - Mounted: number, - UnableToConnect: number, - Undefined: number, - Unmounted: number, - total: number -}; - -export type ConnectionStatusCountType = { - Connected: number, - Connecting: number, - Disconnected: number, - Mounted: number, - UnableToConnect: number, - Undefined: number, - Unmounted: number, - total: number -}; - -export type ConnectionStatusCount = { - 'network-element-connections': ConnectionStatusCountReturnType -}; diff --git a/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx b/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx index 83763485b..2a9a46d2b 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx @@ -27,13 +27,12 @@ import { IApplicationStoreState } from "../../../framework/src/store/application import connect, { Connect, IDispatcher } from '../../../framework/src/flux/connect'; import { findWebUrisForGuiCutThroughAsyncAction, updateCurrentViewAsyncAction, SetPanelAction } from './actions/commonNetworkElementsActions'; -import { refreshConnectionStatusCountAsyncAction } from './actions/connectionStatusCountActions'; import { createNetworkElementsActions, createNetworkElementsProperties, networkElementsReloadAction } from './handlers/networkElementsHandler'; import connectAppRootHandler from './handlers/connectAppRootHandler'; import ConnectApplication from './views/connectView'; import { PanelId } from "./models/panelId"; import { NetworkElementsList } from './components/networkElements'; -import DashboardHome from "./components/dashboardHome"; + let currentStatus: string | undefined = undefined; let refreshInterval: ReturnType | null = null; @@ -84,7 +83,6 @@ export function register() { icon: faPlug, rootComponent: App, rootActionHandler: connectAppRootHandler, - dashbaordElement: DashboardHome, menuEntry: "Connect" }); @@ -92,9 +90,9 @@ export function register() { 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) { - store.dispatch(new AddSnackbarNotification({ message: `Adding network element [${msg.data['object-id-ref']}]`, options: { variant: 'info' } })); + 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) { - store.dispatch(new AddSnackbarNotification({ message: `Updating network element [${msg.data['object-id-ref']}]`, options: { variant: 'info' } })); + store.dispatch(new AddSnackbarNotification({ message: `Updating node [${msg.data['object-id-ref']}]`, options: { variant: 'info' } })); } if (store) { store.dispatch(updateCurrentViewAsyncAction() as any).then(() => { @@ -109,29 +107,4 @@ export function register() { store.dispatch(networkElementsReloadAction); }); - applicationApi.applicationStoreInitialized.then(store => { - store.dispatch(refreshConnectionStatusCountAsyncAction); - }); - - - applicationApi.loginEvent.addHandler(e=>{ - refreshInterval = startRefreshInterval() as any; - }) - - applicationApi.logoutEvent.addHandler(e=>{ - - applicationApi.applicationStoreInitialized.then(store => { - clearInterval(refreshInterval!); - }); - }) - - const startRefreshInterval =() =>{ - const refresh = window.setInterval(() => { - applicationApi.applicationStoreInitialized.then(store => { - store.dispatch(refreshConnectionStatusCountAsyncAction); - }); - }, 15000); - - return refresh; - } } \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts b/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts index 427acd3ec..08cc58056 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts +++ b/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts @@ -26,7 +26,7 @@ import { FeatureTopology, Topology, TopologyNode, Module } from '../models/topol import { guiCutThrough } from '../models/guiCutTrough'; /** -* Represents a web api accessor service for all Network Elements actions. +* Represents a web api accessor service for all network element/node actions. */ class ConnectService { public getNetworkElementUri = (nodeId: string) => '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId; @@ -35,7 +35,7 @@ class ConnectService { 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 elements. + * Inserts a network element/node. */ public async createNetworkElement(element: NetworkElementConnection): Promise { const path = this.getNetworkElementConnectDataProviderUri("create"); @@ -46,7 +46,7 @@ class ConnectService { } /** - * Updates a network element. + * Updates a network element/node. */ public async updateNetworkElement(element: UpdateNetworkElement): Promise { const path = this.getNetworkElementConnectDataProviderUri("update"); @@ -57,7 +57,7 @@ class ConnectService { } /** - * Deletes a network element. + * Deletes a network element/node. */ public async deleteNetworkElement(element: UpdateNetworkElement): Promise { const query = { @@ -70,7 +70,7 @@ class ConnectService { return result || null; } - /** Mounts network element. */ + /** Mounts network element/node */ public async mountNetworkElement(networkElement: NetworkElementConnection): Promise { const path = this.getNetworkElementUri(networkElement.nodeId); const mountXml = [ @@ -152,7 +152,7 @@ class ConnectService { } }; - /** Yang capabilities of the selected network elements. */ + /** 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" }); @@ -163,7 +163,7 @@ class ConnectService { } - /** Yang features of the selected network element module. */ + /** 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" }); @@ -180,7 +180,7 @@ class ConnectService { /** - * Get the connection state of the network element. + * 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`; diff --git a/sdnr/wt/odlux/apps/connectApp/src/services/connectionStatusCountService.ts b/sdnr/wt/odlux/apps/connectApp/src/services/connectionStatusCountService.ts deleted file mode 100644 index 519c965c4..000000000 --- a/sdnr/wt/odlux/apps/connectApp/src/services/connectionStatusCountService.ts +++ /dev/null @@ -1,54 +0,0 @@ -/** - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt odlux - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ - -import { requestRest } from "../../../../framework/src/services/restService"; -import { Result } from "../../../../framework/src/models/elasticSearch"; -import { ConnectionStatusCountType, ConnectionStatusCount } from "../models/connectionStatusCount"; - - - -export const getConnectionStatusCountStateFromDatabase = async (): Promise => { - const path = 'rests/operations/data-provider:read-status'; - const result = await requestRest>(path, { method: "POST" }); - let connectionStatusCountType: ConnectionStatusCountType = { - Connected: 0, - Connecting: 0, - Disconnected: 0, - Mounted: 0, - UnableToConnect: 0, - Undefined: 0, - Unmounted: 0, - total: 0 - } - let connectionStatusCount: ConnectionStatusCount[] | null = null; - - if (result && result["data-provider:output"] && result["data-provider:output"].data) { - connectionStatusCount = result["data-provider:output"].data; - connectionStatusCountType = { - Connected: connectionStatusCount[0]["network-element-connections"].Connected, - Connecting: connectionStatusCount[0]["network-element-connections"].Connecting, - Disconnected: connectionStatusCount[0]["network-element-connections"].Disconnected, - Mounted: connectionStatusCount[0]["network-element-connections"].Mounted, - UnableToConnect: connectionStatusCount[0]["network-element-connections"].UnableToConnect, - Undefined: connectionStatusCount[0]["network-element-connections"].Undefined, - Unmounted: connectionStatusCount[0]["network-element-connections"].Unmounted, - total: connectionStatusCount[0]["network-element-connections"].total, - } - } - return connectionStatusCountType; -} diff --git a/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx b/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx index e99b6af8e..082839718 100644 --- a/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx +++ b/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx @@ -107,7 +107,7 @@ class ConnectApplicationComponent extends React.Component - + diff --git a/sdnr/wt/odlux/apps/connectApp/webpack.config.js b/sdnr/wt/odlux/apps/connectApp/webpack.config.js index b283e426c..ff76904c5 100644 --- a/sdnr/wt/odlux/apps/connectApp/webpack.config.js +++ b/sdnr/wt/odlux/apps/connectApp/webpack.config.js @@ -154,6 +154,14 @@ module.exports = (env) => { target: "http://sdnr:8181", secure: false }, + "/userdata": { + target: "http://sdnr:8181", + secure: false + }, + "/userdata/": { + target: "http://sdnr:8181", + secure: false + }, "/help/": { target: "http://sdnr:8181", secure: false diff --git a/sdnr/wt/odlux/apps/faultApp/src/actions/partialUpdatesAction.ts b/sdnr/wt/odlux/apps/faultApp/src/actions/partialUpdatesAction.ts deleted file mode 100644 index 198976796..000000000 --- a/sdnr/wt/odlux/apps/faultApp/src/actions/partialUpdatesAction.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt odlux - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ - -import { Action } from "../../../../framework/src/flux/action"; - -export class SetPartialUpdatesAction extends Action { - constructor(public isActive: boolean) { - super(); - } -} \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/faultApp/src/actions/statusActions.ts b/sdnr/wt/odlux/apps/faultApp/src/actions/statusActions.ts index c50c08ef2..54fea6a5f 100644 --- a/sdnr/wt/odlux/apps/faultApp/src/actions/statusActions.ts +++ b/sdnr/wt/odlux/apps/faultApp/src/actions/statusActions.ts @@ -21,15 +21,18 @@ import { Dispatch } from '../../../../framework/src/flux/store'; export class SetFaultStatusAction extends FaultApplicationBaseAction { - constructor (public criticalFaults: number, public majorFaults: number, public minorFaults: number, public warnings: number, public isLoadingAlarmStatusChart: boolean) { + constructor(public criticalFaults: number, public majorFaults: number, public minorFaults: number, public warnings: number, + public isLoadingAlarmStatusChart: boolean, public ConnectedCount: number, public ConnectingCount: number, public DisconnectedCount: number, + public MountedCount: number, public UnableToConnectCount: number, public UndefinedCount: number, public UnmountedCount: number, + public totalCount: number, public isLoadingConnectionStatusChart: boolean) { super(); } } export const refreshFaultStatusAsyncAction = async (dispatch: Dispatch) => { - - dispatch(new SetFaultStatusAction(0, 0, 0, 0, true)); + + dispatch(new SetFaultStatusAction(0, 0, 0, 0, true, 0, 0, 0, 0, 0, 0, 0, 0, true)); const result = await getFaultStateFromDatabase().catch(_ => null); if (result) { const statusAction = new SetFaultStatusAction( @@ -37,12 +40,21 @@ export const refreshFaultStatusAsyncAction = async (dispatch: Dispatch) => { result["Major"] || 0, result["Minor"] || 0, result["Warning"] || 0, + false, + result["Connected"] || 0, + result["Connecting"] || 0, + result["Disconnected"] || 0, + result["Mounted"] || 0, + result["UnableToConnect"] || 0, + result["Undefined"] || 0, + result["Unmounted"] || 0, + result["total"] || 0, false ); dispatch(statusAction); return; } else { - dispatch(new SetFaultStatusAction(0, 0, 0, 0, false)); + dispatch(new SetFaultStatusAction(0, 0, 0, 0, false, 0, 0, 0, 0, 0, 0, 0, 0, false)); } } diff --git a/sdnr/wt/odlux/apps/faultApp/src/components/dashboardHome.tsx b/sdnr/wt/odlux/apps/faultApp/src/components/dashboardHome.tsx new file mode 100644 index 000000000..a81705965 --- /dev/null +++ b/sdnr/wt/odlux/apps/faultApp/src/components/dashboardHome.tsx @@ -0,0 +1,476 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +import * as React from 'react'; + +import { withRouter, RouteComponentProps } from 'react-router-dom'; +import connect, { Connect, IDispatcher } from '../../../../framework/src/flux/connect';; +import { Theme } from '@mui/material'; +import { WithStyles } from '@mui/styles'; +import createStyles from '@mui/styles/createStyles'; +import withStyles from '@mui/styles/withStyles'; +import { Doughnut } from 'react-chartjs-2'; +import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; +import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions'; + +const styles = (theme: Theme) => createStyles({ + pageWidthSettings: { + width: '50%', + float: 'left' + }, +}) + +const scrollbar = { overflow: "auto", paddingRight: "20px" } + +let connectionStatusinitialLoad = true; +let connectionStatusinitialStateChanged = false; +let connectionStatusDataLoad: number[] = [0, 0, 0, 0]; +let connectionTotalCount = 0; + +let alarmStatusinitialLoad = true; +let alarmStatusinitialStateChanged = false; +let alarmStatusDataLoad: number[] = [0, 0, 0, 0]; +let alarmTotalCount = 0; + +const mapProps = (state: IApplicationStoreState) => ({ + alarmStatus: state.fault.faultStatus +}); + +const mapDispatch = (dispatcher: IDispatcher) => ({ + navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)), +}); + +type HomeComponentProps = RouteComponentProps & Connect & WithStyles; + +class DashboardHome extends React.Component { + constructor(props: HomeComponentProps) { + super(props); + this.state = { + } + } + + render(): JSX.Element { + const { classes } = this.props; + + if (!this.props.alarmStatus.isLoadingConnectionStatusChart) { + connectionStatusDataLoad = [ + this.props.alarmStatus.Connected, + this.props.alarmStatus.Connecting, + this.props.alarmStatus.Disconnected, + this.props.alarmStatus.UnableToConnect, + this.props.alarmStatus.Undefined + ]; + connectionTotalCount = this.props.alarmStatus.Connected + this.props.alarmStatus.Connecting + + this.props.alarmStatus.Disconnected + this.props.alarmStatus.UnableToConnect + this.props.alarmStatus.Undefined; + + } + + if (!this.props.alarmStatus.isLoadingAlarmStatusChart) { + alarmStatusDataLoad = [ + this.props.alarmStatus.critical, + this.props.alarmStatus.major, + this.props.alarmStatus.minor, + this.props.alarmStatus.warning + ]; + alarmTotalCount = this.props.alarmStatus.critical + this.props.alarmStatus.major + + this.props.alarmStatus.minor + this.props.alarmStatus.warning; + } + + /** Available Network Connection Status chart data */ + const connectionStatusData = { + labels: [ + 'Connected: ' + this.props.alarmStatus.Connected, + 'Connecting: ' + this.props.alarmStatus.Connecting, + 'Disconnected: ' + this.props.alarmStatus.Disconnected, + 'UnableToConnect: ' + this.props.alarmStatus.UnableToConnect, + 'Undefined: ' + this.props.alarmStatus.Undefined + ], + datasets: [{ + labels: ['Connected', 'Connecting', 'Disconnected', 'UnableToConnect', 'Undefined'], + data: connectionStatusDataLoad, + backgroundColor: [ + 'rgb(0, 153, 51)', + 'rgb(255, 102, 0)', + 'rgb(191, 191, 191)', + 'rgb(191, 191, 191)', + 'rgb(242, 240, 240)' + ] + }] + }; + + + /** No Devices available */ + const connectionStatusUnavailableData = { + labels: ['No Devices available'], + datasets: [{ + data: [1], + backgroundColor: [ + 'rgb(255, 255, 255)' + ] + }] + }; + + /** Loading Connection Status chart */ + const connectionStatusisLoading = { + labels: ['Loading chart...'], + datasets: [{ + data: [1], + backgroundColor: [ + 'rgb(255, 255, 255)' + ] + }] + }; + + /** Loading Alarm Status chart */ + const alarmStatusisLoading = { + labels: ['Loading chart...'], + datasets: [{ + data: [1], + backgroundColor: [ + 'rgb(255, 255, 255)' + ] + }] + }; + + /** Connection status options */ + let labels: String[] = ['Connected', 'Connecting', 'Disconnected', 'UnableToConnect', 'Undefined']; + const connectionStatusOptions = { + tooltips: { + callbacks: { + label: (tooltipItem: any, data: any) => { + let label = + (data.datasets[tooltipItem.datasetIndex].labels && + data.datasets[tooltipItem.datasetIndex].labels[ + tooltipItem.index + ]) || + data.labels[tooltipItem.index] || + ""; + if (label) { + label += ": "; + } + label += + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index] + + (data.datasets[tooltipItem.datasetIndex].labelSuffix || ""); + + return label; + } + } + }, + responsive: true, + maintainAspectRatio: false, + animation: { + duration: 0 + }, + plugins: { + legend: { + display: true, + position: 'top' + } + }, + onClick: (event: MouseEvent, item: any) => { + if (item[0]) { + let connectionStatus = labels[item[0]._index] + ''; + this.props.navigateToApplication("connect", '/connectionStatus/' + connectionStatus); + } + } + } + + /** Connection status unavailable options */ + const connectionStatusUnavailableOptions = { + responsive: true, + maintainAspectRatio: false, + animation: { + duration: 0 + }, + plugins: { + legend: { + display: true, + position: 'top' + }, + tooltip: { + enabled: false + } + } + } + + /** Add text inside the doughnut chart for Connection Status */ + const connectionStatusPlugins = [{ + beforeDraw: function (chart: any) { + var width = chart.width, + height = chart.height, + ctx = chart.ctx; + ctx.restore(); + var fontSize = (height / 480).toFixed(2); + ctx.font = fontSize + "em sans-serif"; + ctx.textBaseline = "top"; + var text = "Network Connection Status", + textX = Math.round((width - ctx.measureText(text).width) / 2), + textY = height / 2; + ctx.fillText(text, textX, textY); + ctx.save(); + } + }] + + /** Alarm status Data */ + const alarmStatusData = { + labels: [ + 'Critical : ' + this.props.alarmStatus.critical, + 'Major : ' + this.props.alarmStatus.major, + 'Minor : ' + this.props.alarmStatus.minor, + 'Warning : ' + this.props.alarmStatus.warning + ], + datasets: [{ + labels: ['Critical', 'Major', 'Minor', 'Warning'], + data: alarmStatusDataLoad, + backgroundColor: [ + 'rgb(240, 25, 10)', + 'rgb(240, 133, 10)', + 'rgb(240, 240, 10)', + 'rgb(46, 115, 176)' + ], + }] + } + + /** No Alarm status available */ + const alarmStatusUnavailableData = { + labels: ['No Alarms available'], + datasets: [{ + data: [1], + backgroundColor: [ + 'rgb(0, 153, 51)' + ] + }] + }; + + /** Alarm status Options */ + let alarmLabels: String[] = ['Critical', 'Major', 'Minor', 'Warning']; + const alarmStatusOptions = { + tooltips: { + callbacks: { + label: (tooltipItem: any, data: any) => { + let label = + (data.datasets[tooltipItem.datasetIndex].labels && + data.datasets[tooltipItem.datasetIndex].labels[ + tooltipItem.index + ]) || + data.labels[tooltipItem.index] || + ""; + if (label) { + label += ": "; + } + label += + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index] + + (data.datasets[tooltipItem.datasetIndex].labelSuffix || ""); + + return label; + } + } + }, + responsive: true, + maintainAspectRatio: false, + animation: { + duration: 0 + }, + plugins: { + legend: { + display: true, + position: 'top' + } + }, + onClick: (event: MouseEvent, item: any) => { + if (item[0]) { + let severity = alarmLabels[item[0]._index] + ''; + this.props.navigateToApplication("fault", '/alarmStatus/' + severity); + } + }, + }; + + /** Alarm status unavailable options */ + const alarmStatusUnavailableOptions = { + responsive: true, + maintainAspectRatio: false, + animation: { + duration: 0 + }, + plugins: { + legend: { + display: true, + position: 'top' + }, + tooltip: { + enabled: false + } + } + } + /** Add text inside the doughnut chart for Alarm Status */ + const alarmStatusPlugins = [{ + beforeDraw: function (chart: any) { + var width = chart.width, + height = chart.height, + ctx = chart.ctx; + ctx.restore(); + var fontSize = (height / 480).toFixed(2); + ctx.font = fontSize + "em sans-serif"; + ctx.textBaseline = "top"; + var text = "Network Alarm Status", + textX = Math.round((width - ctx.measureText(text).width) / 2), + textY = height / 2; + ctx.fillText(text, textX, textY); + ctx.save(); + } + }] + + return ( + <> +
+

Welcome to ODLUX

+
+ {this.checkElementsAreLoaded() ? + this.checkConnectionStatus() && connectionTotalCount != 0 ? + + : + : + } +
+
+ {this.checkAlarmsAreLoaded() ? + this.checkAlarmStatus() && alarmTotalCount != 0 ? + + : + : + } +
+
+ + ) + } + + /** Check if connection status data available */ + public checkConnectionStatus = () => { + let statusCount = this.props.alarmStatus; + if (statusCount.isLoadingConnectionStatusChart) { + return true; + } + if (statusCount.Connected == 0 && statusCount.Connecting == 0 && statusCount.Disconnected == 0 + && statusCount.UnableToConnect == 0 && statusCount.Undefined == 0) { + return false; + } else { + return true; + } + } + + /** Check if connection status chart data is loaded */ + public checkElementsAreLoaded = () => { + let isLoadingCheck = this.props.alarmStatus; + if (connectionStatusinitialLoad && !isLoadingCheck.isLoadingConnectionStatusChart) { + if (this.checkConnectionStatus()) { + connectionStatusinitialLoad = false; + return true; + } + return false; + } else if (connectionStatusinitialLoad && isLoadingCheck.isLoadingConnectionStatusChart) { + connectionStatusinitialLoad = false; + connectionStatusinitialStateChanged = true; + return !isLoadingCheck.isLoadingConnectionStatusChart; + } else if (connectionStatusinitialStateChanged) { + if (!isLoadingCheck.isLoadingConnectionStatusChart) { + connectionStatusinitialStateChanged = false; + } + return !isLoadingCheck.isLoadingConnectionStatusChart; + } + return true; + } + + /** Check if alarms data available */ + public checkAlarmStatus = () => { + let alarmCount = this.props.alarmStatus; + if (alarmCount.isLoadingAlarmStatusChart) { + return true; + } + if (alarmCount.critical == 0 && alarmCount.major == 0 && alarmCount.minor == 0 && alarmCount.warning == 0) { + return false; + } + else { + return true; + } + } + + /** Check if alarm status chart data is loaded */ + public checkAlarmsAreLoaded = () => { + let isLoadingCheck = this.props.alarmStatus; + if (alarmStatusinitialLoad && !isLoadingCheck.isLoadingAlarmStatusChart) { + if (this.checkAlarmStatus()) { + alarmStatusinitialLoad = false; + return true; + } + return false; + } else if (alarmStatusinitialLoad && isLoadingCheck.isLoadingAlarmStatusChart) { + alarmStatusinitialLoad = false; + alarmStatusinitialStateChanged = true; + return !isLoadingCheck.isLoadingAlarmStatusChart; + } else if (alarmStatusinitialStateChanged) { + if (!isLoadingCheck.isLoadingAlarmStatusChart) { + alarmStatusinitialStateChanged = false; + } + return !isLoadingCheck.isLoadingAlarmStatusChart; + } + return true; + } +} + +export default (withRouter(connect(mapProps, mapDispatch)(DashboardHome))); \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/faultApp/src/handlers/faultStatusHandler.ts b/sdnr/wt/odlux/apps/faultApp/src/handlers/faultStatusHandler.ts index e1fceb4be..6fa95b685 100644 --- a/sdnr/wt/odlux/apps/faultApp/src/handlers/faultStatusHandler.ts +++ b/sdnr/wt/odlux/apps/faultApp/src/handlers/faultStatusHandler.ts @@ -23,7 +23,16 @@ export interface IFaultStatus { major: number, minor: number, warning: number, - isLoadingAlarmStatusChart: boolean + isLoadingAlarmStatusChart: boolean, + Connected: number, + Connecting: number, + Disconnected: number, + Mounted: number, + UnableToConnect: number, + Undefined: number, + Unmounted: number, + total: number, + isLoadingConnectionStatusChart: boolean } const faultStatusInit: IFaultStatus = { @@ -31,7 +40,16 @@ const faultStatusInit: IFaultStatus = { major: 0, minor: 0, warning: 0, - isLoadingAlarmStatusChart: false + isLoadingAlarmStatusChart: false, + Connected: 0, + Connecting: 0, + Disconnected: 0, + Mounted: 0, + UnableToConnect: 0, + Undefined: 0, + Unmounted: 0, + total: 0, + isLoadingConnectionStatusChart: false }; export const faultStatusHandler: IActionHandler = (state = faultStatusInit, action) => { @@ -41,7 +59,16 @@ export const faultStatusHandler: IActionHandler = (state = faultSt major: action.majorFaults, minor: action.minorFaults, warning: action.warnings, - isLoadingAlarmStatusChart: action.isLoadingAlarmStatusChart + isLoadingAlarmStatusChart: action.isLoadingAlarmStatusChart, + Connected: action.ConnectedCount, + Connecting: action.ConnectingCount, + Disconnected: action.DisconnectedCount, + Mounted: action.MountedCount, + UnableToConnect: action.UnableToConnectCount, + Undefined: action.UndefinedCount, + Unmounted: action.UnmountedCount, + total: action.totalCount, + isLoadingConnectionStatusChart: action.isLoadingConnectionStatusChart } } diff --git a/sdnr/wt/odlux/apps/faultApp/src/models/fault.ts b/sdnr/wt/odlux/apps/faultApp/src/models/fault.ts index 2ba8da01d..5f38e5fe9 100644 --- a/sdnr/wt/odlux/apps/faultApp/src/models/fault.ts +++ b/sdnr/wt/odlux/apps/faultApp/src/models/fault.ts @@ -61,18 +61,35 @@ export type FaultsReturnType = { criticals: number, majors: number, minors: number, - warnings: number + warnings: number, + Connected: number, + Connecting: number, + Disconnected: number, + Mounted: number, + UnableToConnect: number, + Undefined: number, + Unmounted: number, + total: number }; export type FaultType = { Critical: number, Major: number, Minor: number, - Warning: number + Warning: number, + Connected: number, + Connecting: number, + Disconnected: number, + Mounted: number, + UnableToConnect: number, + Undefined: number, + Unmounted: number, + total: number }; export type Faults = { - faults: FaultsReturnType + faults: FaultsReturnType, + 'network-element-connections': FaultsReturnType }; export type DeletedStuckAlarms = { diff --git a/sdnr/wt/odlux/apps/faultApp/src/pluginFault.tsx b/sdnr/wt/odlux/apps/faultApp/src/pluginFault.tsx index 0c5fdde27..ff901b097 100644 --- a/sdnr/wt/odlux/apps/faultApp/src/pluginFault.tsx +++ b/sdnr/wt/odlux/apps/faultApp/src/pluginFault.tsx @@ -41,6 +41,8 @@ import { createCurrentProblemsProperties, createCurrentProblemsActions, currentP import { FaultStatus } from "./components/faultStatus"; import { refreshFaultStatusAsyncAction, SetFaultStatusAction } from "./actions/statusActions"; +import DashboardHome from "./components/dashboardHome"; + let currentMountId: string | undefined = undefined; let currentSeverity: string | undefined = undefined; let refreshInterval: ReturnType | null = null; @@ -113,6 +115,7 @@ export function register() { rootComponent: App, rootActionHandler: faultAppRootHandler, statusBarElement: FaultStatus, + dashbaordElement: DashboardHome, menuEntry: "Fault" }); @@ -149,14 +152,14 @@ export function register() { applicationApi.logoutEvent.addHandler(e=>{ applicationApi.applicationStoreInitialized.then(store => { - store.dispatch(new SetFaultStatusAction(0, 0, 0, 0, false)); + store.dispatch(new SetFaultStatusAction(0, 0, 0, 0, false, 0, 0, 0, 0, 0, 0, 0, 0, false)); clearInterval(refreshInterval!); }); }) - function startRefreshInterval(){ + function startRefreshInterval() { const refreshFaultStatus = window.setInterval(() => { applicationApi.applicationStoreInitialized.then(store => { diff --git a/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts b/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts index 663def086..880ed7715 100644 --- a/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts +++ b/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts @@ -28,7 +28,15 @@ export const getFaultStateFromDatabase = async (): Promise => Critical: 0, Major: 0, Minor: 0, - Warning: 0 + Warning: 0, + Connected: 0, + Connecting: 0, + Disconnected: 0, + Mounted: 0, + UnableToConnect: 0, + Undefined: 0, + Unmounted: 0, + total: 0 } let faults: Faults[] | null = null; @@ -38,7 +46,15 @@ export const getFaultStateFromDatabase = async (): Promise => Critical: faults[0].faults.criticals, Major: faults[0].faults.majors, Minor: faults[0].faults.minors, - Warning: faults[0].faults.warnings + Warning: faults[0].faults.warnings, + Connected: faults[0]["network-element-connections"].Connected, + Connecting: faults[0]["network-element-connections"].Connecting, + Disconnected: faults[0]["network-element-connections"].Disconnected, + Mounted: faults[0]["network-element-connections"].Mounted, + UnableToConnect: faults[0]["network-element-connections"].UnableToConnect, + Undefined: faults[0]["network-element-connections"].Undefined, + Unmounted: faults[0]["network-element-connections"].Unmounted, + total: faults[0]["network-element-connections"].total, } } diff --git a/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx b/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx index 456e05e84..b9cd5e4da 100644 --- a/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx +++ b/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx @@ -173,13 +173,13 @@ class FaultApplicationComponent extends React.Component } @@ -204,13 +204,13 @@ class FaultApplicationComponent extends React.Component - + Help & FAQ diff --git a/sdnr/wt/odlux/apps/helpApp/webpack.config.js b/sdnr/wt/odlux/apps/helpApp/webpack.config.js index 963a99ef3..b069c2a31 100644 --- a/sdnr/wt/odlux/apps/helpApp/webpack.config.js +++ b/sdnr/wt/odlux/apps/helpApp/webpack.config.js @@ -143,23 +143,32 @@ module.exports = (env) => { }, proxy: { "/oauth2/": { - target: "http://10.20.6.29:48181", + //target: "http://10.20.6.29:48181", + target: "http://sdnr:8181", secure: false }, "/database/": { - target: "http://10.20.6.29:48181", + //target: "http://10.20.6.29:48181", + target: "http://sdnr:8181", secure: false }, "/restconf/": { - target: "http://10.20.6.29:48181", + //target: "http://10.20.6.29:48181", + target: "http://sdnr:8181", + secure: false + }, + "/rests/": { + target: "http://sdnr:8181", secure: false }, "/help/": { - target: "http://10.20.6.29:48181", + //target: "http://10.20.6.29:48181", + target: "http://sdnr:8181", secure: false }, "/websocket/": { - target: "http://10.20.6.29:48181", + //target: "http://10.20.6.29:48181", + target: "http://sdnr:8181", ws: true, changeOrigin: true, secure: false diff --git a/sdnr/wt/odlux/apps/inventoryApp/src/handlers/connectedNetworkElementsHandler.ts b/sdnr/wt/odlux/apps/inventoryApp/src/handlers/connectedNetworkElementsHandler.ts index 79c12d619..e6138cc38 100644 --- a/sdnr/wt/odlux/apps/inventoryApp/src/handlers/connectedNetworkElementsHandler.ts +++ b/sdnr/wt/odlux/apps/inventoryApp/src/handlers/connectedNetworkElementsHandler.ts @@ -24,7 +24,7 @@ import { NetworkElementConnection } from '../models/networkElementConnection'; export interface IConnectedNetworkElementsState extends IExternalTableState { } // create eleactic search material data fetch handler -const connectedNetworkElementsSearchHandler = createSearchDataHandler('network-element-connection', { status: "Connected" }); +const connectedNetworkElementsSearchHandler = createSearchDataHandler('network-element-connection', false, { status: "Connected" }); export const { actionHandler: connectedNetworkElementsActionHandler, diff --git a/sdnr/wt/odlux/apps/mediatorApp/pom.xml b/sdnr/wt/odlux/apps/mediatorApp/pom.xml index 604ba8632..e0f7cc44b 100644 --- a/sdnr/wt/odlux/apps/mediatorApp/pom.xml +++ b/sdnr/wt/odlux/apps/mediatorApp/pom.xml @@ -31,7 +31,7 @@ org.onap.ccsdk.features.sdnr.wt sdnr-wt-odlux-app-mediatorApp - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT bundle ccsdk-features :: ${project.artifactId} diff --git a/sdnr/wt/odlux/apps/mediatorApp/src/views/mediatorApplication.tsx b/sdnr/wt/odlux/apps/mediatorApp/src/views/mediatorApplication.tsx index da0ffa048..55d9b400e 100644 --- a/sdnr/wt/odlux/apps/mediatorApp/src/views/mediatorApplication.tsx +++ b/sdnr/wt/odlux/apps/mediatorApp/src/views/mediatorApplication.tsx @@ -176,7 +176,7 @@ class MediatorApplicationComponent extends React.Component rowData.pid ? (Running) : (Stopped) }, { property: "DeviceIp", title: "IP Adress", type: ColumnType.text }, @@ -191,7 +191,7 @@ class MediatorApplicationComponent extends React.Component renderActions(rowData) }, ]} /> : - - (getFilter, null) +const adaptiveModulationSearchHandler = createSearchDataHandler(getFilter, false, null) export const { actionHandler: adaptiveModulationActionHandler, createActions: createAdaptiveModulationActions, diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/crossPolarDiscriminationHandler.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/crossPolarDiscriminationHandler.ts index 1e6c6d0a6..5008dd56d 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/crossPolarDiscriminationHandler.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/crossPolarDiscriminationHandler.ts @@ -26,7 +26,7 @@ export interface ICrossPolarDiscriminationState extends IExternalTableState(getFilter, null) +const crossPolarDiscriminationSearchHandler = createSearchDataHandler(getFilter, false, null) export const { actionHandler: crossPolarDiscriminationActionHandler, diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/performanceDataHandler.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/performanceDataHandler.ts index 131566367..a7b63a324 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/performanceDataHandler.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/performanceDataHandler.ts @@ -28,7 +28,7 @@ export interface IPerformanceDataState extends IExternalTableState(getFilter, null); +const performanceDataSearchHandler = createSearchDataHandler(getFilter, false, null); export const { actionHandler: performanceDataActionHandler, diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/receiveLevelHandler.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/receiveLevelHandler.ts index 91595cc58..34fd3ebce 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/receiveLevelHandler.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/receiveLevelHandler.ts @@ -26,7 +26,7 @@ export interface IReceiveLevelState extends IExternalTableState(getFilter, null); +const receiveLevelSearchHandler = createSearchDataHandler(getFilter, false, null); export const { actionHandler: receiveLevelActionHandler, diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/signalToInterferenceHandler.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/signalToInterferenceHandler.ts index e0f804086..5fd5c0cde 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/signalToInterferenceHandler.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/signalToInterferenceHandler.ts @@ -26,7 +26,7 @@ export interface ISignalToInterferenceState extends IExternalTableState(getFilter, null); +const signalToInterferenceSearchHandler = createSearchDataHandler(getFilter, false, null); export const { actionHandler: signalToInterferenceActionHandler, diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/temperatureHandler.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/temperatureHandler.ts index 0a6c73a1c..130b81801 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/temperatureHandler.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/temperatureHandler.ts @@ -26,7 +26,7 @@ export interface ITemperatureState extends IExternalTableState(getFilter, null); +const temperatureSearchHandler = createSearchDataHandler< TemperatureDataType>(getFilter, false, null); export const { actionHandler: temperatureActionHandler, diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/transmissionPowerHandler.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/transmissionPowerHandler.ts index 32bef817d..2a09e58f3 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/transmissionPowerHandler.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/transmissionPowerHandler.ts @@ -26,7 +26,7 @@ export interface ITransmissionPowerState extends IExternalTableState(getFilter, null) +const transmissionPowerSearchHandler = createSearchDataHandler(getFilter, false, null) export const { actionHandler: transmissionPowerActionHandler, diff --git a/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/ResFilesServlet.java b/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/ResFilesServlet.java index a3f8dd7f6..c9d8a2d20 100644 --- a/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/ResFilesServlet.java +++ b/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/ResFilesServlet.java @@ -55,7 +55,12 @@ public class ResFilesServlet extends HttpServlet { if(f.exists()) { resp.setStatus(HttpURLConnection.HTTP_OK); resp.setContentType("image/gif"); - Files.copy(f, resp.getOutputStream()); + try { + Files.copy(f, resp.getOutputStream()); + } catch (IOException e) { + LOG.warn("Can not copy data", e); + resp.setStatus(500); + } return; } } @@ -73,16 +78,19 @@ public class ResFilesServlet extends HttpServlet { resp.setContentType(mimeType); resp.setContentLength(length); resp.setStatus(HttpURLConnection.HTTP_OK); - OutputStream os = resp.getOutputStream(); - os.write(byteContent); - os.flush(); - os.close(); + try (OutputStream os = resp.getOutputStream()) { + os.write(byteContent); + os.flush(); + } catch (IOException e) { + LOG.warn("Can not write data", e); + resp.setStatus(500); + } } else { LOG.debug("File {} not found in res.", fn); resp.setStatus(HttpURLConnection.HTTP_NOT_FOUND); } } else { - LOG.debug("BundleLoaderInstance to found.", fn); + LOG.debug("BundleLoaderInstance not found. {}", fn); resp.setStatus(HttpURLConnection.HTTP_NOT_FOUND); } } diff --git a/sdnr/wt/odlux/framework/pom.xml b/sdnr/wt/odlux/framework/pom.xml index 48b0d95d1..6f0285a56 100644 --- a/sdnr/wt/odlux/framework/pom.xml +++ b/sdnr/wt/odlux/framework/pom.xml @@ -236,10 +236,6 @@ ##odlux.apps.inventoryApp.buildno## ${odlux.apps.inventoryApp.buildno} - - ##odlux.apps.linkCalculationApp.buildno## - ${odlux.apps.linkCalculationApp.buildno} - ##odlux.apps.maintenanceApp.buildno## ${odlux.apps.maintenanceApp.buildno} @@ -248,10 +244,6 @@ ##odlux.apps.mediatorApp.buildno## ${odlux.apps.mediatorApp.buildno} - - ##odlux.apps.networkMapApp.buildno## - ${odlux.apps.networkMapApp.buildno} - ##odlux.apps.permanceHistoryApp.buildno## ${odlux.apps.permanceHistoryApp.buildno} diff --git a/sdnr/wt/odlux/framework/src/actions/authentication.ts b/sdnr/wt/odlux/framework/src/actions/authentication.ts index 20a248dc1..f1d11de37 100644 --- a/sdnr/wt/odlux/framework/src/actions/authentication.ts +++ b/sdnr/wt/odlux/framework/src/actions/authentication.ts @@ -18,9 +18,11 @@ import { Dispatch } from '../flux/store'; import { Action } from '../flux/action'; import { AuthPolicy, User } from '../models/authentication'; -import { GeneralSettings } from '../models/settings'; -import { SetGeneralSettingsAction, setGeneralSettingsAction } from './settingsAction'; +import { GeneralSettings, Settings } from '../models/settings'; +import { saveInitialSettings, SetGeneralSettingsAction, setGeneralSettingsAction } from './settingsAction'; import { endWebsocketSession } from '../services/notificationService'; +import { endUserSession, startUserSession } from '../services/userSessionService'; +import { IApplicationStoreState } from '../store/applicationStore'; export class UpdateUser extends Action { @@ -40,16 +42,30 @@ export class UpdatePolicies extends Action { export const loginUserAction = (user?: User) => (dispatcher: Dispatch) =>{ dispatcher(new UpdateUser(user)); - loadUserSettings(user, dispatcher); - - + if(user){ + startUserSession(user); + loadUserSettings(user, dispatcher); + localStorage.setItem("userToken", user.toString()); + } } -export const logoutUser = () => (dispatcher: Dispatch) =>{ +export const logoutUser = () => (dispatcher: Dispatch, getState: () => IApplicationStoreState) =>{ + + const {framework:{applicationState:{ authentication }, authenticationState: {user}}} = getState(); dispatcher(new UpdateUser(undefined)); dispatcher(new SetGeneralSettingsAction(null)); endWebsocketSession(); + endUserSession(); + localStorage.removeItem("userToken"); + + + //only call if a user is currently logged in + if (authentication === "oauth" && user) { + + const url = window.location.origin; + window.location.href=`${url}/oauth/logout`; + } } const loadUserSettings = (user: User | undefined, dispatcher: Dispatch) =>{ @@ -74,14 +90,8 @@ const loadUserSettings = (user: User | undefined, dispatcher: Dispatch) =>{ }else{ return null; } - }).then((result:GeneralSettings)=>{ - if(result?.general){ - //will start websocket session if applicable - dispatcher(setGeneralSettingsAction(result.general.areNotificationsEnabled!)); - - }else{ - dispatcher(setGeneralSettingsAction(false)); - } + }).then((result:Settings)=>{ + dispatcher(saveInitialSettings(result)); }) } } \ No newline at end of file diff --git a/sdnr/wt/odlux/framework/src/actions/settingsAction.ts b/sdnr/wt/odlux/framework/src/actions/settingsAction.ts index ffcdfc26a..1c18ddc8e 100644 --- a/sdnr/wt/odlux/framework/src/actions/settingsAction.ts +++ b/sdnr/wt/odlux/framework/src/actions/settingsAction.ts @@ -18,47 +18,113 @@ import { Dispatch } from "../flux/store"; import { Action } from "../flux/action"; -import { GeneralSettings } from "../models/settings"; +import { GeneralSettings, Settings, TableSettings, TableSettingsColumn } from "../models/settings"; import { getSettings, putSettings } from "../services/settingsService"; import { startWebsocketSession, suspendWebsocketSession } from "../services/notificationService"; +import { IApplicationStoreState } from "../store/applicationStore"; -export class SetGeneralSettingsAction extends Action{ +export class SetGeneralSettingsAction extends Action { /** * */ - constructor(public areNoticationsActive: boolean|null) { + constructor(public areNoticationsActive: boolean | null) { super(); - } } -export const setGeneralSettingsAction = (value: boolean) => (dispatcher: Dispatch) =>{ +export class SetTableSettings extends Action { + + constructor(public tableName: string, public updatedColumns: TableSettingsColumn[]) { + super(); + } +} + +export class LoadSettingsAction extends Action { + + constructor(public settings: Settings & { isInitialLoadDone: true }) { + super(); + } + +} + +export class SettingsDoneLoadingAction extends Action { + +} + +export const setGeneralSettingsAction = (value: boolean) => (dispatcher: Dispatch) => { dispatcher(new SetGeneralSettingsAction(value)); - if(value){ + if (value) { startWebsocketSession(); - }else{ + } else { suspendWebsocketSession(); } } -export const updateGeneralSettingsAction = (activateNotifications: boolean) => async (dispatcher: Dispatch) =>{ +export const updateGeneralSettingsAction = (activateNotifications: boolean) => async (dispatcher: Dispatch) => { - const value: GeneralSettings = {general:{areNotificationsEnabled: activateNotifications}}; + const value: GeneralSettings = { general: { areNotificationsEnabled: activateNotifications } }; const result = await putSettings("/general", JSON.stringify(value.general)); dispatcher(setGeneralSettingsAction(activateNotifications)); } +export const updateTableSettings = (tableName: string, columns: TableSettingsColumn[]) => async (dispatcher: Dispatch, getState: () => IApplicationStoreState) => { + + + //TODO: ask micha how to handle object with variable properties! + //fix for now: just safe everything! + + let {framework:{applicationState:{settings:{tables}}}} = getState(); + + tables[tableName] = { columns: columns }; + const json=JSON.stringify(tables); + + // would only save latest entry + //const json = JSON.stringify({ [tableName]: { columns: columns } }); + + const result = await putSettings("/tables", json); + + dispatcher(new SetTableSettings(tableName, columns)); +} + export const getGeneralSettingsAction = () => async (dispatcher: Dispatch) => { const result = await getSettings(); - if(result && result.general){ + if (result && result.general) { dispatcher(new SetGeneralSettingsAction(result.general.areNotificationsEnabled!)) } +} + +export const saveInitialSettings = (settings: any) => async (dispatcher: Dispatch) => { + + const defaultSettings = {general:{ areNotificationsEnabled: false }, tables:{}}; + + const initialSettings = {...defaultSettings, ...settings}; + + if (initialSettings) { + if (initialSettings.general) { + const settingsActive = initialSettings.general.areNotificationsEnabled; + + if (settingsActive) { + startWebsocketSession(); + } else { + suspendWebsocketSession(); + } + } + + dispatcher(new LoadSettingsAction(initialSettings)); + } + else { + dispatcher(new SettingsDoneLoadingAction()); + + } + + + } \ No newline at end of file diff --git a/sdnr/wt/odlux/framework/src/assets/images/home.svg b/sdnr/wt/odlux/framework/src/assets/images/home.svg new file mode 100644 index 000000000..080d0502e --- /dev/null +++ b/sdnr/wt/odlux/framework/src/assets/images/home.svg @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/sdnr/wt/odlux/framework/src/assets/images/home.svg.d.ts b/sdnr/wt/odlux/framework/src/assets/images/home.svg.d.ts new file mode 100644 index 000000000..7098d79a2 --- /dev/null +++ b/sdnr/wt/odlux/framework/src/assets/images/home.svg.d.ts @@ -0,0 +1,20 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + + declare const home: string; + export default home; \ No newline at end of file diff --git a/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts b/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts index ce5b2cd1e..3ed313497 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts +++ b/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts @@ -37,6 +37,7 @@ export type ColumnModel = { disablePadding?: boolean; width?: string | number ; className?: string; + hide?: boolean; style?: React.CSSProperties; align?: 'inherit' | 'left' | 'center' | 'right' | 'justify'; disableSorting?: boolean; diff --git a/sdnr/wt/odlux/framework/src/components/material-table/index.tsx b/sdnr/wt/odlux/framework/src/components/material-table/index.tsx index aac2a1252..8541cfe56 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/index.tsx +++ b/sdnr/wt/odlux/framework/src/components/material-table/index.tsx @@ -36,7 +36,7 @@ import { EnhancedTableHead } from './tableHead'; import { EnhancedTableFilter } from './tableFilter'; import { ColumnModel, ColumnType } from './columnModel'; -import { Menu } from '@mui/material'; +import { Menu, Typography } from '@mui/material'; import { DistributiveOmit } from '@mui/types'; import makeStyles from '@mui/styles/makeStyles'; @@ -151,19 +151,23 @@ export type MaterialTableComponentState = { rowsPerPage: number; loading: boolean; showFilter: boolean; + hiddenColumns: string[]; filter: { [property: string]: string }; }; export type TableApi = { forceRefresh?: () => Promise }; -type MaterialTableComponentBaseProps = WithStyles & { +type MaterialTableComponentBaseProps = WithStyles & { className?: string; columns: ColumnModel[]; idProperty: keyof TData | ((data: TData) => React.Key); - tableId?: string; + + //Note: used to save settings as well. Must be unique across apps. Null tableIds will not get saved to the settings + tableId: string | null; isPopup?: boolean; title?: string; stickyHeader?: boolean; + allowHtmlHeader?: boolean; defaultSortOrder?: 'asc' | 'desc'; defaultSortColumn?: keyof TData; enableSelection?: boolean; @@ -182,6 +186,8 @@ type MaterialTableComponentPropsWithExternalState = MaterialTableCom onHandleChangePage: (page: number) => void; onHandleChangeRowsPerPage: (rowsPerPage: number | null) => void; onHandleRequestSort: (property: string) => void; + onHideColumns : (columnNames: string[]) => void + onShowColumns: (columnNames: string[]) => void }; type MaterialTableComponentProps = @@ -203,13 +209,18 @@ function isMaterialTableComponentPropsWithRowsAndRequestData(props: MaterialTabl propsWithExternalState.onHandleChangePage instanceof Function || propsWithExternalState.onHandleChangeRowsPerPage instanceof Function || propsWithExternalState.onToggleFilter instanceof Function || + propsWithExternalState.onHideColumns instanceof Function || propsWithExternalState.onHandleRequestSort instanceof Function } +// get settings in here! + + class MaterialTableComponent extends React.Component { constructor(props: MaterialTableComponentProps) { super(props); + const page = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.page : 0; const rowsPerPage = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.rowsPerPage || 10 : 10; @@ -224,6 +235,7 @@ class MaterialTableComponent extends React.Component extends React.Component ((data as { [key: string]: any })[this.props.idProperty as any as string] as string | number) : this.props.idProperty; const toggleFilter = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.onToggleFilter : () => { !this.props.disableFilter && this.setState({ showFilter: !showFilter }, this.update) } + + const hideColumns = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.onHideColumns : (data: string[]) => { const newArray = [...new Set([...this.state.hiddenColumns, ...data])]; this.setState({hiddenColumns:newArray}); } + const showColumns = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.onShowColumns : (data: string[]) => { const newArray = this.state.hiddenColumns.filter(el=> !data.includes(el)); this.setState({hiddenColumns:newArray}); } + + const allColumnsHidden = this.props.columns.length === this.state.hiddenColumns.length; return ( + onToggleFilter={toggleFilter} + columns={columns} + onHideColumns={hideColumns} + onShowColumns={showColumns} /> extends React.Component - {showFilter && || null} - {rows // may need ordering here + {showFilter && || null} + + {allColumnsHidden ? All columns of this table are hidden. : + + rows // may need ordering here .map((entry: TData & { [RowDisabled]?: boolean, [kex: string]: any }, index) => { const entryId = getId(entry); const contextMenu = (this.props.createContextMenu && this.state.contextMenuInfo.index === index && this.props.createContextMenu(entry)) || null; @@ -295,15 +320,17 @@ class MaterialTableComponent extends React.Component {this.props.enableSelection ? - + : null } { + this.props.columns.map( col => { const style = col.width ? { width: col.width } : {}; - return ( + const tableCell = ( + {col.type === ColumnType.custom && col.customControl ? @@ -313,6 +340,10 @@ class MaterialTableComponent extends React.Component ); + + //show column if... + const showColumn = !this.state.hiddenColumns.includes(col.property); + return showColumn && tableCell } ) } @@ -352,6 +383,7 @@ class MaterialTableComponent extends React.Component extends React.Component ({ + settings: state.framework.applicationState.settings, + settingsDoneLoading: state.framework.applicationState.settings.isInitialLoadDone +}); + +const mapDispatchToProps = (dispatcher: IDispatcher) => ({ + saveToSettings: (tableName: string, columns: TableSettingsColumn[]) => dispatcher.dispatch(updateTableSettings(tableName, columns)) +}) + +type DialogProps = { + columns: ColumnModel<{}>[], + settingsName: string | null, + anchorEl: HTMLElement | null; + hideColumns: (columnNames: string[]) => void + showColumns: (columnNames: string[]) => void + onClose(): void + +} & Connect; + + //TODO: figure out why everything gets triggered twice... + +const ShowColumnsDialog: React.FunctionComponent = (props) => { + + const savedSettings = props.settingsName && props.settings.tables[props.settingsName]; + + const [checkedColumns, setCheckedColumns] = React.useState<{ property: string, display: boolean, title: string | undefined }[]>([]); + + const open = Boolean(props.anchorEl); + const allColumnNames = props.columns.map(e => e.property); + + React.useEffect(() => { + + createHideShowSelection(); + + }, []); + + React.useEffect(() => { + + createHideShowSelection(); + + }, [props.settings.isInitialLoadDone]); + + + const createHideShowSelection = () => { + let columns = props.columns.map(e => { return { property: e.property, display: !Boolean(e.hide), title: e.title } }); + + + if (savedSettings) { + + if (columns.length !== savedSettings.columns.length) { + console.error("saved column length does not match current column length. Maybe a settings entry got wrongly overridden?") + } + + //overwrite column data with settings + savedSettings?.columns.forEach(el => { + let foundIndex = columns.findIndex(e => e.property == el.property); + if (columns[foundIndex] !== undefined) + columns[foundIndex].display = el.displayed; + }); + + } else { + console.warn("No settingsName set, changes will not be saved.") + } + + setCheckedColumns(columns); + + const hideColumns = columns.filter(el => !el.display).map(e => e.property); + props.hideColumns(hideColumns); + } + + + const handleChange = (propertyName: string, checked: boolean) => { + if (!checked) { + props.hideColumns([propertyName]); + } else { + props.showColumns([propertyName]) + + } + + let updatedList = checkedColumns.map(item => { + if (item.property == propertyName) { + return { ...item, display: checked }; + } + return item; + }); + + setCheckedColumns(updatedList); + }; + + const onHideAll = () => { + + switchCheckedColumns(false); + props.hideColumns(allColumnNames); + } + + const onShowAll = () => { + + switchCheckedColumns(true); + props.showColumns(allColumnNames); + } + + const onClose = () => { + + const tableColumns: TableSettingsColumn[] = checkedColumns.map(el => { + return { + property: el.property, + displayed: el.display + } + }); + + if (props.settingsName) { + props.saveToSettings(props.settingsName, tableColumns); + } + props.onClose(); + + } + + const switchCheckedColumns = (changeToValue: boolean) => { + let updatedList = checkedColumns.map(item => { + return { ...item, display: changeToValue }; + }); + + setCheckedColumns(updatedList); + + } + + return ( +
+ Hide / Show Columns +
+
+ { + checkedColumns?.map((el, i) => { + + return <> + + handleChange(el.property, e.target.checked)} />} + label={el.title || el.property} + labelPlacement="end" + /> + + }) + } +
+ + +
+
+
) +} + +export default connect(mapStateToProps, mapDispatchToProps)(ShowColumnsDialog); diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx index a46dd18d8..1b9136844 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx +++ b/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx @@ -50,6 +50,7 @@ interface IEnhancedTableFilterComponentProps extends WithStyles { onFilterChanged: (property: string, filterTerm: string) => void; filter: { [property: string]: string }; columns: ColumnModel<{}>[]; + hiddenColumns: string[]; enableSelection?: boolean; } @@ -73,7 +74,7 @@ class EnhancedTableFilterComponent extends React.Component { const style = col.width ? { width: col.width } : {}; - return ( + const tableCell = ( } ); + + const showColumn = !this.props.hiddenColumns.includes(col.property); + + return showColumn && tableCell; }, this)} ); diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx index c500f44ce..d6f7b7def 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx +++ b/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx @@ -50,7 +50,9 @@ interface IEnhancedTableHeadComponentProps extends styles_header { orderBy: string | null; rowCount: number; columns: ColumnModel<{}>[]; + hiddenColumns: string[]; enableSelection?: boolean; + allowHtmlHeader?: boolean; } class EnhancedTableHeadComponent extends React.Component { @@ -77,7 +79,7 @@ class EnhancedTableHeadComponent extends React.Component { const style = col.width ? { width: col.width } : {}; - return ( + const tableCell = ( - { col.title || col.property } + { + this.props.allowHtmlHeader ?
+ : (col.title || col.property ) + } }
); + + //show column if... + const showColumn = !this.props.hiddenColumns.includes(col.property); + + return showColumn && tableCell; }, this) } diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx index 426436d44..143b802a4 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx +++ b/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx @@ -33,6 +33,8 @@ import MenuItem from '@mui/material/MenuItem'; import Menu from '@mui/material/Menu'; import { SvgIconProps } from '@mui/material/SvgIcon'; import { Button } from '@mui/material'; +import { ColumnModel } from './columnModel'; +import ShowColumnsDialog from './showColumnDialog' const styles = (theme: Theme) => createStyles({ root: { @@ -69,18 +71,24 @@ const styles = (theme: Theme) => createStyles({ interface ITableToolbarComponentProps extends WithStyles { numSelected: number | null; title?: string; - tableId?: string; + tableId: string | null; customActionButtons?: { icon: React.ComponentType, tooltip?: string, ariaLabel: string, onClick: () => void, disabled?: boolean }[]; + columns: ColumnModel<{}>[]; + onHideColumns: (columnNames: string[]) => void + onShowColumns: (columnNames: string[]) => void onToggleFilter: () => void; onExportToCsv: () => void; } -class TableToolbarComponent extends React.Component { +class TableToolbarComponent extends React.Component { + + constructor(props: ITableToolbarComponentProps) { super(props); this.state = { - anchorEl: null + anchorEl: null, + anchorElDialog: null }; } @@ -91,11 +99,22 @@ class TableToolbarComponent extends React.Component { this.setState({ anchorEl: null }); }; + + private showColumnsDialog = (event: React.MouseEvent) =>{ + this.setState({ anchorElDialog: this.state.anchorEl }); + } + + private onCloseDialog = () =>{ + this.setState({ anchorElDialog: null }); + + } + render() { const { numSelected, classes } = this.props; const open = !!this.state.anchorEl; - const buttonPrefix = this.props.tableId !== undefined ? this.props.tableId : 'table'; + const buttonPrefix = this.props.tableId !== null ? this.props.tableId : 'table'; return ( + <> 0 ? classes.highlight : ''} `} >
{numSelected && numSelected > 0 ? ( @@ -153,9 +172,18 @@ class TableToolbarComponent extends React.Component { this.props.onExportToCsv(); this.handleClose()}}>Export as CSV + { this.showColumnsDialog(e); this.handleClose()}}>Hide/show columns
+ + ); } } diff --git a/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts b/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts index 544e14e01..f9015493f 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts +++ b/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts @@ -28,6 +28,7 @@ export interface IExternalTableState { order: 'asc' | 'desc'; orderBy: string | null; selected: any[] | null; + hiddenColumns: string[] rows: (TData & { [RowDisabled]?: boolean })[]; total: number; page: number; @@ -48,7 +49,9 @@ export type ExternalMethodes = { onFilterChanged: (property: string, filterTerm: string) => void; onHandleChangePage: (page: number) => void; onHandleChangeRowsPerPage: (rowsPerPage: number | null) => void; - }; + onHideColumns: (columnName: string[]) => void; + onShowColumns: (columnName: string[]) => void; + }, createPreActions: (dispatch: Dispatch, skipRefresh?: boolean) => { onPreFilterChanged: (preFilter: { [key: string]: string; @@ -128,6 +131,18 @@ export function createExternal(callback: DataCallback, selectState } } + class HideColumnsAction extends TableAction{ + constructor(public property: string[]){ + super(); + } + } + + class ShowColumnsAction extends TableAction{ + constructor(public property: string[]){ + super(); + } + } + // #endregion //#region Action Handler @@ -135,6 +150,7 @@ export function createExternal(callback: DataCallback, selectState order: 'asc', orderBy: null, selected: null, + hiddenColumns:[], rows: [], total: 0, page: 0, @@ -208,6 +224,18 @@ export function createExternal(callback: DataCallback, selectState rowsPerPage: action.rowsPerPage } } + else if (action instanceof HideColumnsAction){ + + //merge arrays, remove duplicates + const newArray = [...new Set([...state.hiddenColumns, ...action.property])] + state = {...state, hiddenColumns: newArray}; + } + else if(action instanceof ShowColumnsAction){ + + const newArray = state.hiddenColumns.filter(el=> !action.property.includes(el)); + state = {...state, hiddenColumns: newArray}; + } + return state; } @@ -290,6 +318,16 @@ export function createExternal(callback: DataCallback, selectState dispatch(new SetRowsPerPageAction(rowsPerPage || 10)); (!skipRefresh) && dispatch(reloadAction); }); + }, + onHideColumns: (columnName: string[]) =>{ + dispatch((dispatch: Dispatch) => { + dispatch(new HideColumnsAction(columnName)); + }) + }, + onShowColumns: (columnName: string[]) =>{ + dispatch((dispatch: Dispatch) => { + dispatch(new ShowColumnsAction(columnName)); + }) } // selected: }; diff --git a/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx b/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx index 1134e230b..195706d28 100644 --- a/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx +++ b/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx @@ -64,9 +64,9 @@ const styles = (theme: Theme) => createStyles({ duration: theme.transitions.duration.leavingScreen, }), overflowX: 'hidden', - width: theme.spacing(7) + 1, + width: theme.spacing(7), [theme.breakpoints.up('sm')]: { - width: theme.spacing(9) + 1, + width: theme.spacing(9), }, }, drawer: { @@ -101,7 +101,7 @@ export const NavigationMenu = withStyles(styles)(connect()(({ classes, state, di //collapse menu on mount if necessary React.useEffect(()=>{ - if(isOpen && window.innerWidth < tabletWidthBreakpoint){ + if(isOpen && window.innerWidth <= tabletWidthBreakpoint){ setResponsive(true); dispatch(new MenuAction(false)); @@ -116,14 +116,12 @@ export const NavigationMenu = withStyles(styles)(connect()(({ classes, state, di if (window.innerWidth < tabletWidthBreakpoint && !responsive) { setResponsive(true); if (!closedByUser) { - console.log("responsive menu collapsed") dispatch(new MenuAction(false)); } } else if (window.innerWidth > tabletWidthBreakpoint && responsive) { setResponsive(false); if (!closedByUser) { - console.log("responsive menu restored") dispatch(new MenuAction(true)); } @@ -145,13 +143,14 @@ export const NavigationMenu = withStyles(styles)(connect()(({ classes, state, di let menuItems = state.framework.applicationRegistraion && Object.keys(state.framework.applicationRegistraion).map(key => { const reg = state.framework.applicationRegistraion[key]; + const icon = !reg.icon ? null :( typeof reg.icon === 'string' ? : ) return reg && ( || null} /> + icon={icon} /> ) || null; }) || null; diff --git a/sdnr/wt/odlux/framework/src/components/titleBar.tsx b/sdnr/wt/odlux/framework/src/components/titleBar.tsx index 7872e51da..19d3bdf74 100644 --- a/sdnr/wt/odlux/framework/src/components/titleBar.tsx +++ b/sdnr/wt/odlux/framework/src/components/titleBar.tsx @@ -131,6 +131,10 @@ class TitleBarComponent extends React.Component : ) + + return ( @@ -144,9 +148,7 @@ class TitleBarComponent extends React.Component - {state.framework.applicationState.icon - ? () - : null} + {icon} {state.framework.applicationState.title}
diff --git a/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts b/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts index 16c6ed5d3..d0a07248d 100644 --- a/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts +++ b/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts @@ -31,8 +31,8 @@ import { ExternalLoginProvider } from '../models/externalLoginProvider'; import { ApplicationConfig } from '../models/applicationConfig'; import { IConnectAppStoreState } from '../../../apps/connectApp/src/handlers/connectAppRootHandler'; import { IFaultAppStoreState } from '../../../apps/faultApp/src/handlers/faultAppRootHandler'; -import { GeneralSettings } from '../models/settings'; -import { SetGeneralSettingsAction } from '../actions/settingsAction'; +import { GeneralSettings, Settings } from '../models/settings'; +import { LoadSettingsAction, SetGeneralSettingsAction, SetTableSettings, SettingsDoneLoadingAction } from '../actions/settingsAction'; import { startWebsocketSession, suspendWebsocketSession } from '../services/notificationService'; @@ -55,7 +55,7 @@ export interface IApplicationState { authentication: "basic"|"oauth", // basic enablePolicy: boolean, // false transportpceUrl : string, - settings: GeneralSettings + settings: Settings & { isInitialLoadDone: boolean } } const applicationStateInit: IApplicationState = { @@ -69,7 +69,11 @@ const applicationStateInit: IApplicationState = { authentication: "basic", enablePolicy: false, transportpceUrl: "", - settings:{ general: { areNotificationsEnabled: null }} + settings:{ + general: { areNotificationsEnabled: null }, + tables: {}, + isInitialLoadDone: false + } }; export const configureApplication = (config: ApplicationConfig) => { @@ -150,8 +154,23 @@ export const applicationStateHandler: IActionHandler = (state state = { ...state, - settings:{general:{areNotificationsEnabled: action.areNoticationsActive}} + settings:{tables: state.settings.tables, isInitialLoadDone:state.settings.isInitialLoadDone, general:{areNotificationsEnabled: action.areNoticationsActive}} } } + else if(action instanceof SetTableSettings){ + + let tableUpdate = state.settings.tables; + tableUpdate[action.tableName] = {columns: action.updatedColumns}; + + state = {...state, settings:{general: state.settings.general, isInitialLoadDone:state.settings.isInitialLoadDone, tables: tableUpdate}} + + }else if(action instanceof LoadSettingsAction){ + + state = {...state, settings:action.settings} + } + else if(action instanceof SettingsDoneLoadingAction){ + state= {...state, settings: {...state.settings, isInitialLoadDone: true}} + } + return state; }; diff --git a/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts b/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts index 1bcb43528..f98d77487 100644 --- a/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts +++ b/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts @@ -39,12 +39,8 @@ export const authenticationStateHandler: IActionHandler = const {user} = action; if (user) { - localStorage.setItem("userToken", user.toString()); - startUserSession(user); onLogin(); } else { - localStorage.removeItem("userToken"); - endUserSession(); onLogout(); } diff --git a/sdnr/wt/odlux/framework/src/index.dev.html b/sdnr/wt/odlux/framework/src/index.dev.html index 4dc353c44..69c5f0607 100644 --- a/sdnr/wt/odlux/framework/src/index.dev.html +++ b/sdnr/wt/odlux/framework/src/index.dev.html @@ -26,7 +26,7 @@ faultApp.register(); // inventoryApp.register(); // helpApp.register(); - app("./app.tsx").configureApplication({ authentication:"oauth", enablePolicy: false, transportpceUrl:"http://test.de"}); + app("./app.tsx").configureApplication({ authentication:"basic", enablePolicy: false, transportpceUrl:"http://test.de"}); app("./app.tsx").runApplication(); }); diff --git a/sdnr/wt/odlux/framework/src/index.html b/sdnr/wt/odlux/framework/src/index.html index 5cd2805c1..7196b5cfe 100644 --- a/sdnr/wt/odlux/framework/src/index.html +++ b/sdnr/wt/odlux/framework/src/index.html @@ -16,7 +16,7 @@