summaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/apps/faultApp
diff options
context:
space:
mode:
Diffstat (limited to 'sdnr/wt/odlux/apps/faultApp')
-rw-r--r--sdnr/wt/odlux/apps/faultApp/package.json18
-rw-r--r--sdnr/wt/odlux/apps/faultApp/pom.xml55
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/actions/clearStuckAlarmsAction.ts36
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/actions/notificationActions.ts4
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/components/clearStuckAlarmsDialog.tsx136
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/components/faultStatus.tsx2
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/handlers/alarmLogEntriesHandler.ts11
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/handlers/clearStuckAlarmsHandler.ts36
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/handlers/currentProblemsHandler.ts11
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/handlers/faultAppRootHandler.ts6
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/handlers/notificationsHandler.ts4
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/index.html6
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/models/fault.ts48
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/pluginFault.tsx (renamed from sdnr/wt/odlux/apps/faultApp/src/plugin.tsx)8
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts48
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx89
-rw-r--r--sdnr/wt/odlux/apps/faultApp/webpack.config.js12
17 files changed, 405 insertions, 125 deletions
diff --git a/sdnr/wt/odlux/apps/faultApp/package.json b/sdnr/wt/odlux/apps/faultApp/package.json
index be7bf6d02..909626303 100644
--- a/sdnr/wt/odlux/apps/faultApp/package.json
+++ b/sdnr/wt/odlux/apps/faultApp/package.json
@@ -20,21 +20,21 @@
],
"author": "Matthias Fischer",
"license": "Apache-2.0",
- "dependencies": {
- "@odlux/framework": "*"
- },
+ "dependencies": {
+ "@odlux/framework": "*"
+ },
"peerDependencies": {
- "@types/react": "16.4.14",
- "@types/react-dom": "16.0.8",
+ "@types/react": "16.9.11",
+ "@types/react-dom": "16.9.4",
"@types/react-router-dom": "4.3.1",
- "@material-ui/core": "3.8.3",
- "@material-ui/icons": "3.0.2",
+ "@material-ui/core": "4.6.1",
+ "@material-ui/icons": "4.5.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.5.2",
- "react-dom": "16.5.2",
+ "react": "16.11.0",
+ "react-dom": "16.11.0",
"react-router-dom": "4.3.1"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/faultApp/pom.xml b/sdnr/wt/odlux/apps/faultApp/pom.xml
index b748b7d19..1c616a40b 100644
--- a/sdnr/wt/odlux/apps/faultApp/pom.xml
+++ b/sdnr/wt/odlux/apps/faultApp/pom.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onap.ccsdk.parent</groupId>
@@ -8,18 +9,19 @@
<relativePath/>
</parent>
- <modelVersion>4.0.0</modelVersion>
<groupId>org.onap.ccsdk.features.sdnr.wt</groupId>
<artifactId>sdnr-wt-odlux-app-faultApp</artifactId>
<version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
- <name>sdnr-wt-odlux-app-faultApp</name>
+
+ <name>ccsdk-features :: ${project.artifactId}</name>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
+
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
@@ -38,8 +40,21 @@
<scope>test</scope>
</dependency>
</dependencies>
+
<build>
<sourceDirectory>src2/main/java</sourceDirectory>
+ <resources>
+ <resource>
+ <directory>dist</directory>
+ <targetPath>odlux</targetPath>
+ </resource>
+ <resource>
+ <directory>src2/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>src2/test/resources</directory>
+ </resource>
+ </resources>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
@@ -62,10 +77,10 @@
<followSymlinks>false</followSymlinks>
</fileset>
<!-- eclipse bug build bin folder in basedir -->
- <fileset>
- <directory>bin</directory>
- <followSymlinks>false</followSymlinks>
- </fileset>
+ <fileset>
+ <directory>bin</directory>
+ <followSymlinks>false</followSymlinks>
+ </fileset>
</filesets>
</configuration>
</plugin>
@@ -88,7 +103,7 @@
</executions>
</plugin>
<plugin>
- <groupId>de.jacksitlab</groupId>
+ <groupId>de.jacks-it-lab</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.7.1</version>
<executions>
@@ -100,8 +115,8 @@
<!-- optional: default phase is "generate-resources" -->
<phase>initialize</phase>
<configuration>
- <nodeVersion>v8.10.0</nodeVersion>
- <yarnVersion>v1.12.3</yarnVersion>
+ <nodeVersion>v10.16.3</nodeVersion>
+ <yarnVersion>v1.19.0</yarnVersion>
</configuration>
</execution>
<execution>
@@ -131,27 +146,5 @@
</configuration>
</plugin>
</plugins>
- <resources>
- <resource>
- <directory>dist</directory>
- <targetPath>odlux</targetPath>
- </resource>
- <resource>
- <directory>src2/main/resources</directory>
- </resource>
- <resource>
- <directory>src2/test/resources</directory>
- </resource>
- </resources>
</build>
- <pluginRepositories>
- <pluginRepository>
- <id>highstreet repo</id>
- <url>https://cloud-highstreet-technologies.com/mvn/</url>
- <snapshots>
- <enabled>true</enabled>
- <updatePolicy>always</updatePolicy>
- </snapshots>
- </pluginRepository>
- </pluginRepositories>
</project>
diff --git a/sdnr/wt/odlux/apps/faultApp/src/actions/clearStuckAlarmsAction.ts b/sdnr/wt/odlux/apps/faultApp/src/actions/clearStuckAlarmsAction.ts
new file mode 100644
index 000000000..ba1a24822
--- /dev/null
+++ b/sdnr/wt/odlux/apps/faultApp/src/actions/clearStuckAlarmsAction.ts
@@ -0,0 +1,36 @@
+/**
+ * ============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 { clearStuckAlarms } from "../services/faultStatusService"
+import { Dispatch } from "../../../../framework/src/flux/store";
+import { FaultApplicationBaseAction } from "./notificationActions";
+
+export class AreStuckAlarmsCleared extends FaultApplicationBaseAction {
+ constructor(public isBusy: boolean) {
+ super();
+ }
+}
+
+
+export const clearStuckAlarmAsyncAction = (dispatcher: Dispatch) => async (nodeNames: string[]) => {
+ dispatcher(new AreStuckAlarmsCleared(true))
+ const result = await clearStuckAlarms(nodeNames).catch(error => { console.error(error); return undefined });
+ dispatcher(new AreStuckAlarmsCleared(false))
+ return result;
+} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/faultApp/src/actions/notificationActions.ts b/sdnr/wt/odlux/apps/faultApp/src/actions/notificationActions.ts
index b990536e4..584e7cd8b 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/actions/notificationActions.ts
+++ b/sdnr/wt/odlux/apps/faultApp/src/actions/notificationActions.ts
@@ -17,13 +17,13 @@
*/
import { Action } from '../../../../framework/src/flux/action';
-import { Fault } from '../models/fault';
+import { FaultAlarmNotification } from '../models/fault';
export class FaultApplicationBaseAction extends Action { }
export class AddFaultNotificationAction extends FaultApplicationBaseAction {
- constructor(public fault:Fault) {
+ constructor(public fault:FaultAlarmNotification) {
super();
}
}
diff --git a/sdnr/wt/odlux/apps/faultApp/src/components/clearStuckAlarmsDialog.tsx b/sdnr/wt/odlux/apps/faultApp/src/components/clearStuckAlarmsDialog.tsx
new file mode 100644
index 000000000..3b8b9b684
--- /dev/null
+++ b/sdnr/wt/odlux/apps/faultApp/src/components/clearStuckAlarmsDialog.tsx
@@ -0,0 +1,136 @@
+/**
+ * ============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 { DialogContent, DialogActions, Button, Dialog, DialogTitle, DialogContentText } from '@material-ui/core';
+import { currentProblemsReloadAction } from '../handlers/currentProblemsHandler';
+import { clearStuckAlarmAsyncAction } from '../actions/clearStuckAlarmsAction';
+import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect';
+
+export enum ClearStuckAlarmsDialogMode {
+ None = "none",
+ Show = "show"
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ clearStuckAlarmsAsync: clearStuckAlarmAsyncAction(dispatcher.dispatch),
+ reloadCurrentProblemsAction: () => dispatcher.dispatch(currentProblemsReloadAction)
+})
+
+type clearStuckAlarmsProps = Connect<typeof undefined, typeof mapDispatch> & {
+ numberDevices: Number,
+ mode: ClearStuckAlarmsDialogMode,
+ stuckAlarms: string[]
+ onClose: () => void
+}
+
+type ClearStuckAlarmsState = {
+ clearAlarmsSuccessful: boolean,
+ errormessage: string,
+ unclearedAlarms: string[]
+}
+
+class ClearStuckAlarmsDialogComponent extends React.Component<clearStuckAlarmsProps, ClearStuckAlarmsState>{
+ constructor(props: clearStuckAlarmsProps) {
+ super(props);
+ this.state = { clearAlarmsSuccessful: true, errormessage: '', unclearedAlarms: [] }
+ }
+
+ onClose = (event: React.MouseEvent) => {
+ event.stopPropagation();
+ event.preventDefault();
+ this.props.onClose();
+ }
+
+ onRefresh = async (event: React.MouseEvent) => {
+ event.stopPropagation();
+ event.preventDefault();
+ const result = await this.props.clearStuckAlarmsAsync(this.props.stuckAlarms);
+
+ if (result) {
+ if (result.output.nodenames) {
+ if (result.output.nodenames.length !== this.props.stuckAlarms.length) { //show errormessage if not all devices were cleared
+ const undeletedAlarm = this.props.stuckAlarms.filter(item => !result.output.nodenames.includes(item))
+ const error = "The alarms of the following devices couldn't be refreshed: ";
+ this.setState({ clearAlarmsSuccessful: false, errormessage: error, unclearedAlarms: undeletedAlarm })
+ return;
+ }
+ }
+ }
+ else { //show errormessage if no devices were cleared
+ this.setState({ clearAlarmsSuccessful: false, errormessage: "Alarms couldn't be refreshed.", unclearedAlarms: [] })
+ return;
+ }
+
+ this.props.reloadCurrentProblemsAction();
+ this.props.onClose();
+ }
+
+ onOk = (event: React.MouseEvent) => {
+
+ event.stopPropagation();
+ event.preventDefault();
+ if (this.state.unclearedAlarms.length > 0)
+ this.props.reloadCurrentProblemsAction();
+ this.props.onClose();
+ }
+
+ render() {
+ console.log(this.props.stuckAlarms);
+ const device = this.props.numberDevices > 1 ? 'devices' : 'device'
+ const defaultMessage = "Are you sure you want to refresh all alarms for " + this.props.numberDevices + " " + device + "?"
+ const message = this.state.clearAlarmsSuccessful ? defaultMessage : this.state.errormessage;
+
+ const defaultTitle = "Refresh Confirmation"
+ const title = this.state.clearAlarmsSuccessful ? defaultTitle : 'Refresh Result';
+
+ return (
+ <Dialog open={this.props.mode !== ClearStuckAlarmsDialogMode.None}>
+ <DialogTitle>{title}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {message}
+ </DialogContentText>
+ {
+ this.state.unclearedAlarms.map(item =>
+ <DialogContentText>
+ {item}
+ </DialogContentText>
+ )
+ }
+ </DialogContent>
+ <DialogActions>
+ {
+ this.state.clearAlarmsSuccessful &&
+ <>
+ <Button onClick={this.onRefresh}>Yes</Button>
+ <Button onClick={this.onClose}>No</Button>
+ </>
+ }
+
+ {
+ !this.state.clearAlarmsSuccessful && <Button onClick={this.onOk}>Ok</Button>
+ }
+ </DialogActions>
+ </Dialog>
+ )
+ }
+}
+
+const ClearStuckAlarmsDialog = connect(undefined, mapDispatch)(ClearStuckAlarmsDialogComponent)
+export default ClearStuckAlarmsDialog;
diff --git a/sdnr/wt/odlux/apps/faultApp/src/components/faultStatus.tsx b/sdnr/wt/odlux/apps/faultApp/src/components/faultStatus.tsx
index 780e61d7a..1ec463f47 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/components/faultStatus.tsx
+++ b/sdnr/wt/odlux/apps/faultApp/src/components/faultStatus.tsx
@@ -58,7 +58,7 @@ class FaultStatusComponent extends React.Component<FaultStatusComponentProps> {
return (
<Typography variant="body1" color="inherit" >
- Alarm status: <FontAwesomeIcon className={`${classes.icon} ${classes.critical}`} icon={faExclamationTriangle} /> { faultStatus.critical } |
+ Alarm Status: <FontAwesomeIcon className={`${classes.icon} ${classes.critical}`} icon={faExclamationTriangle} /> { faultStatus.critical } |
<FontAwesomeIcon className={`${classes.icon} ${classes.major}`} icon={faExclamationTriangle} /> { faultStatus.major } |
<FontAwesomeIcon className={`${classes.icon} ${classes.minor}`} icon={faExclamationTriangle} /> { faultStatus.minor } |
<FontAwesomeIcon className={`${classes.icon} ${classes.warning}`} icon={faExclamationTriangle} /> { faultStatus.warning } |
diff --git a/sdnr/wt/odlux/apps/faultApp/src/handlers/alarmLogEntriesHandler.ts b/sdnr/wt/odlux/apps/faultApp/src/handlers/alarmLogEntriesHandler.ts
index be41a51b2..31b8259b2 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/handlers/alarmLogEntriesHandler.ts
+++ b/sdnr/wt/odlux/apps/faultApp/src/handlers/alarmLogEntriesHandler.ts
@@ -18,17 +18,12 @@
import { createExternal,IExternalTableState } from '../../../../framework/src/components/material-table/utilities';
import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch';
-import { Fault, FaultLog } from '../models/fault';
+import { Fault } from '../models/fault';
export interface IAlarmLogEntriesState extends IExternalTableState<Fault> { }
-// create eleactic search material data fetch handler
-const alarmLogEntriesSearchHandler = createSearchDataHandler<FaultLog, Fault>(
- 'sdnevents/faultlog',
- null,
- (hit) => ({ _id: hit._id, ...hit._source.fault }),
- (name) => `fault.${ name }`
-);
+// create eleactic search data fetch handler
+const alarmLogEntriesSearchHandler = createSearchDataHandler< Fault>('faultlog');
export const {
actionHandler: alarmLogEntriesActionHandler,
diff --git a/sdnr/wt/odlux/apps/faultApp/src/handlers/clearStuckAlarmsHandler.ts b/sdnr/wt/odlux/apps/faultApp/src/handlers/clearStuckAlarmsHandler.ts
new file mode 100644
index 000000000..14634b4c4
--- /dev/null
+++ b/sdnr/wt/odlux/apps/faultApp/src/handlers/clearStuckAlarmsHandler.ts
@@ -0,0 +1,36 @@
+/**
+ * ============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 { IActionHandler } from "../../../../framework/src/flux/action"
+import { AreStuckAlarmsCleared } from "../actions/clearStuckAlarmsAction";
+
+export interface IStuckAlarms {
+ areAlarmsCleared: boolean
+}
+
+const initialState: IStuckAlarms = {
+ areAlarmsCleared: false
+}
+
+export const stuckAlarmHandler: IActionHandler<IStuckAlarms> = (state = initialState, action) => {
+ if (action instanceof AreStuckAlarmsCleared) {
+ state = { ...state, areAlarmsCleared: action.isBusy }
+ }
+
+ return state;
+} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/faultApp/src/handlers/currentProblemsHandler.ts b/sdnr/wt/odlux/apps/faultApp/src/handlers/currentProblemsHandler.ts
index 760dbeadc..3698a2798 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/handlers/currentProblemsHandler.ts
+++ b/sdnr/wt/odlux/apps/faultApp/src/handlers/currentProblemsHandler.ts
@@ -18,17 +18,12 @@
import { createExternal,IExternalTableState } from '../../../../framework/src/components/material-table/utilities';
import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch';
-import { FaultResult, Fault } from '../models/fault';
+import { Fault } from '../models/fault';
export interface ICurrentProblemsState extends IExternalTableState<Fault> { }
-// create eleactic search material data fetch handler
-const currentProblemsSearchHandler = createSearchDataHandler<FaultResult, Fault>(
- 'sdnevents/faultcurrent',
- null,
- (hit) => ({ _id: hit._id, ...hit._source.faultCurrent }),
- (name) => `faultCurrent.${name}`
- );
+// create eleactic search data fetch handler
+const currentProblemsSearchHandler = createSearchDataHandler<Fault>('faultcurrent');
export const {
actionHandler: currentProblemsActionHandler,
diff --git a/sdnr/wt/odlux/apps/faultApp/src/handlers/faultAppRootHandler.ts b/sdnr/wt/odlux/apps/faultApp/src/handlers/faultAppRootHandler.ts
index 22a9a58a2..dddb4a247 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/handlers/faultAppRootHandler.ts
+++ b/sdnr/wt/odlux/apps/faultApp/src/handlers/faultAppRootHandler.ts
@@ -28,12 +28,13 @@ import { ICurrentProblemsState, currentProblemsActionHandler } from './currentPr
import { IAlarmLogEntriesState, alarmLogEntriesActionHandler } from './alarmLogEntriesHandler';
import { SetPanelAction } from '../actions/panelChangeActions';
import { IFaultStatus, faultStatusHandler } from './faultStatusHandler';
+import { stuckAlarmHandler } from './clearStuckAlarmsHandler';
export interface IFaultAppStoreState {
currentProblems: ICurrentProblemsState;
faultNotifications: IFaultNotifications;
alarmLogEntries: IAlarmLogEntriesState;
- currentOpenPanel: string|null;
+ currentOpenPanel: string | null;
faultStatus: IFaultStatus;
}
@@ -55,7 +56,8 @@ const actionHandlers = {
faultNotifications: faultNotificationsHandler,
alarmLogEntries: alarmLogEntriesActionHandler,
currentOpenPanel: currentOpenPanelHandler,
- faultStatus: faultStatusHandler
+ faultStatus: faultStatusHandler,
+ stuckAlarms: stuckAlarmHandler
};
export const faultAppRootHandler = combineActionHandler<IFaultAppStoreState>(actionHandlers);
diff --git a/sdnr/wt/odlux/apps/faultApp/src/handlers/notificationsHandler.ts b/sdnr/wt/odlux/apps/faultApp/src/handlers/notificationsHandler.ts
index 4377a1b0a..aa92d2a1c 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/handlers/notificationsHandler.ts
+++ b/sdnr/wt/odlux/apps/faultApp/src/handlers/notificationsHandler.ts
@@ -17,10 +17,10 @@
*/
import { IActionHandler } from '../../../../framework/src/flux/action';
import { AddFaultNotificationAction, ResetFaultNotificationsAction } from '../actions/notificationActions';
-import { Fault } from '../models/fault';
+import { FaultAlarmNotification } from '../models/fault';
export interface IFaultNotifications {
- faults: Fault[];
+ faults: FaultAlarmNotification[];
since: Date;
}
diff --git a/sdnr/wt/odlux/apps/faultApp/src/index.html b/sdnr/wt/odlux/apps/faultApp/src/index.html
index a2a0830b3..cd315f0b7 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/index.html
+++ b/sdnr/wt/odlux/apps/faultApp/src/index.html
@@ -15,12 +15,8 @@
<script type="text/javascript" src="./config.js"></script>
<script>
// run the application
- require(["app", "connectApp", "faultApp", "maintenanceApp", "configurationApp", "helpApp"], function (app, connectApp, faultApp, maintenanceApp, configurationApp, helpApp) {
- connectApp.register();
+ require(["app", "faultApp" ], function (app, faultApp) {
faultApp.register();
- configurationApp.register();
- maintenanceApp.register();
- helpApp.register();
app("./app.tsx").runApplication();
});
</script>
diff --git a/sdnr/wt/odlux/apps/faultApp/src/models/fault.ts b/sdnr/wt/odlux/apps/faultApp/src/models/fault.ts
index 153e8def3..c65734437 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/models/fault.ts
+++ b/sdnr/wt/odlux/apps/faultApp/src/models/fault.ts
@@ -15,17 +15,53 @@
* the License.
* ============LICENSE_END==========================================================================
*/
-export type FaultType = {
+export type Fault = {
+ id: string;
+ nodeId: string;
+ counter: number;
+ timestamp: string;
+ objectId: string;
+ problem: string;
+ severity: null | 'Warning' | 'Minor' | 'Major' | 'Critical';
+ type: string;
+ sourceType: string;
+}
+
+export type FaultAlarmNotification = {
+ id: string;
nodeName: string;
- counter: string;
+ counter: number;
timeStamp: string;
objectId: string;
problem: string;
- severity: null | 'Warning' | 'Minor' | 'Major' | 'Critical' ;
+ severity: null | 'Warning' | 'Minor' | 'Major' | 'Critical';
type: string;
+ sourceType: string;
}
-export type FaultResult = { faultCurrent: FaultType };
-export type FaultLog = { fault: FaultType };
+/**
+ * Fault status return type
+ */
+export type FaultsReturnType = {
+ criticals: number,
+ majors: number,
+ minors: number,
+ warnings: number
+};
+
+export type FaultType = {
+ Critical: number,
+ Major: number,
+ Minor: number,
+ Warning: number
+};
+
+export type Faults = {
+ faults: FaultsReturnType
+};
-export type Fault = FaultType & { _id: string };
+export type DeletedStuckAlarms = {
+ output: {
+ nodenames: string[]
+ }
+} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/faultApp/src/plugin.tsx b/sdnr/wt/odlux/apps/faultApp/src/pluginFault.tsx
index eec8c0821..02dde90f7 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/plugin.tsx
+++ b/sdnr/wt/odlux/apps/faultApp/src/pluginFault.tsx
@@ -31,7 +31,7 @@ import { IApplicationStoreState } from "../../../framework/src/store/application
import { faultAppRootHandler } from './handlers/faultAppRootHandler';
import { FaultApplication } from "./views/faultApplication";
-import { Fault } from "./models/fault";
+import { FaultAlarmNotification } from "./models/fault";
import { PanelId } from "./models/panelId";
import { SetPanelAction } from "./actions/panelChangeActions";
@@ -60,8 +60,8 @@ const FaultApplicationRouteAdapter = connect(mapProps, mapDisp)((props: RouteCom
window.setTimeout(() => {
if (currentMountId) {
props.setCurrentPanel("CurrentProblem");
- props.currentProblemsActions.onFilterChanged("objectId", currentMountId);
- props.currentProblemsProperties.showFilter || (props.currentProblemsActions.onToggleFilter());
+ props.currentProblemsActions.onFilterChanged("nodeId", currentMountId);
+ props.currentProblemsProperties.showFilter; // || (props.currentProblemsActions.onToggleFilter());
props.currentProblemsActions.onRefresh();
}
});
@@ -89,7 +89,7 @@ export function register() {
});
// subscribe to the websocket notifications
- subscribe<Fault & IFormatedMessage>("ProblemNotification", (fault => {
+ subscribe<FaultAlarmNotification & IFormatedMessage>("ProblemNotification", (fault => {
const store = applicationApi && applicationApi.applicationStore;
if (fault && store) {
store.dispatch(new AddFaultNotificationAction(fault));
diff --git a/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts b/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts
index ed1f3f919..d3409e095 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts
+++ b/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts
@@ -16,24 +16,38 @@
* ============LICENSE_END==========================================================================
*/
import { requestRest } from "../../../../framework/src/services/restService";
-import { Result } from "../../../../framework/src/models/elasticSearch";
+import { Result, PostResponse } from "../../../../framework/src/models/elasticSearch";
+import { FaultType, Faults, DeletedStuckAlarms } from "../models/fault";
-export const getFaultStateFromDatabase = async (): Promise < { [key: string]: number } | null > => {
- const path = 'database/sdnevents/faultcurrent/_search';
- const query = {
- "size": 0,
- "aggregations": {
- "severity": {
- "terms": {
- "field": "faultCurrent.severity"
- }
- }
+
+export const getFaultStateFromDatabase = async (): Promise<FaultType | null> => {
+ const path = 'restconf/operations/data-provider:read-status';
+ const result = await requestRest<Result<Faults>>(path, { method: "POST" });
+
+ let faultType: FaultType = {
+ Critical: 0,
+ Major: 0,
+ Minor: 0,
+ Warning: 0
+ }
+ let faults: Faults[] | null = null;
+
+ if (result && result.output && result.output.data) {
+ faults = result.output.data;
+ faultType = {
+ Critical: faults[0].faults.criticals,
+ Major: faults[0].faults.majors,
+ Minor: faults[0].faults.minors,
+ Warning: faults[0].faults.warnings
}
- };
+ }
+
+ return faultType;
+}
+
+export const clearStuckAlarms = async (nodeNames: string[]) => {
+ const path = 'restconf/operations/devicemanager:clear-current-fault-by-nodename'
+ const result = await requestRest<DeletedStuckAlarms>(path, { method: 'Post', body: JSON.stringify({ input: { nodenames: nodeNames } }) })
+ return result;
- const result = await requestRest<Result<{ severity: { buckets: { key: string, doc_count: number }[] } }>>(path, { method: "POST", body: JSON.stringify(query) });
- return result && result.aggregations && result.aggregations["severity"].buckets.reduce<{ [key: string]: number }>((acc, cur) => {
- acc[cur.key] = cur.doc_count;
- return acc;
- }, {}) || null;
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx b/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx
index 9faa3566b..fd1c48ac5 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx
+++ b/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx
@@ -28,12 +28,15 @@ import { Panel } from '../../../../framework/src/components/material-ui';
import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
import connect, { Connect, IDispatcher } from '../../../../framework/src/flux/connect';
-import { Fault } from '../models/fault';
+import { Fault, FaultAlarmNotification } from '../models/fault';
import { PanelId } from '../models/panelId';
import { createCurrentProblemsProperties, createCurrentProblemsActions, currentProblemsReloadAction } from '../handlers/currentProblemsHandler';
import { createAlarmLogEntriesProperties, createAlarmLogEntriesActions, alarmLogEntriesReloadAction } from '../handlers/alarmLogEntriesHandler';
import { SetPanelAction } from '../actions/panelChangeActions';
+import { Tooltip, IconButton } from '@material-ui/core';
+import RefreshIcon from '@material-ui/icons/Refresh';
+import ClearStuckAlarmsDialog, { ClearStuckAlarmsDialogMode } from '../components/clearStuckAlarmsDialog';
const mapProps = (state: IApplicationStoreState) => ({
activePanel: state.fault.currentOpenPanel,
@@ -47,18 +50,50 @@ const mapDisp = (dispatcher: IDispatcher) => ({
alarmLogEntriesActions: createAlarmLogEntriesActions(dispatcher.dispatch),
reloadCurrentProblems: () => dispatcher.dispatch(currentProblemsReloadAction),
reloadAlarmLogEntries: () => dispatcher.dispatch(alarmLogEntriesReloadAction),
- setCurrentPanel: (panelId: PanelId) => dispatcher.dispatch(new SetPanelAction(panelId))
+ setCurrentPanel: (panelId: PanelId) => dispatcher.dispatch(new SetPanelAction(panelId)),
});
type FaultApplicationComponentProps = RouteComponentProps & Connect<typeof mapProps, typeof mapDisp>;
+type FaultApplicationState = {
+ clearAlarmDialogMode: ClearStuckAlarmsDialogMode,
+ stuckAlarms: string[]
+}
+
const FaultTable = MaterialTable as MaterialTableCtorType<Fault>;
+const FaultAlarmNotificationTable = MaterialTable as MaterialTableCtorType<FaultAlarmNotification>;
+
+
+class FaultApplicationComponent extends React.Component<FaultApplicationComponentProps, FaultApplicationState>{
+
+ /**
+ *
+ */
+ constructor(props: FaultApplicationComponentProps) {
+ super(props);
+ this.state = { clearAlarmDialogMode: ClearStuckAlarmsDialogMode.None, stuckAlarms: [] }
+ }
+
+ onDialogClose = () => {
+ this.setState({ clearAlarmDialogMode: ClearStuckAlarmsDialogMode.None, stuckAlarms: [] })
+ }
+
+ onDialogOpen = () => {
+ const stuckAlarms = [...new Set(this.props.currentProblemsProperties.rows.map(item => item.nodeId))];
+ this.setState({ clearAlarmDialogMode: ClearStuckAlarmsDialogMode.Show, stuckAlarms: stuckAlarms })
+ }
+
-class FaultApplicationComponent extends React.Component<FaultApplicationComponentProps>{
render(): JSX.Element {
+ const refreshButton = {
+ icon: RefreshIcon, tooltip: 'Clear stuck alarms', onClick: this.onDialogOpen
+ };
+ const areFaultsAvailable = this.props.currentProblemsProperties.rows && this.props.currentProblemsProperties.rows.length > 0
+ const customAction = areFaultsAvailable ? [refreshButton] : [];
+
const { activePanel } = this.props;
const onTogglePanel = (panelId: PanelId) => {
@@ -82,19 +117,19 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
return (
<>
- <Panel activePanel={ activePanel } panelId={ 'CurrentProblem' } onToggle={ onTogglePanel } title={ 'Current Problem List' }>
- <FaultTable idProperty={ '_id' } columns={ [
- { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
- { property: "timeStamp", type: ColumnType.text, title: "Time Stamp" },
- { property: "nodeName", title: "Node Name", type: ColumnType.text },
- { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
- { property: "objectId", title: "Object Id", type: ColumnType.text } ,
- { property: "problem", title: "Alarm Type", type: ColumnType.text },
- { property: "severity", title: "Severity", type: ColumnType.text, width: "140px" },
- ] } { ...this.props.currentProblemsProperties } { ...this.props.currentProblemsActions } />
+ <Panel activePanel={activePanel} panelId={'CurrentProblem'} onToggle={onTogglePanel} title={'Current Problem List'}>
+ <FaultTable idProperty={'id'} customActionButtons={customAction} columns={[
+ { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
+ { property: "timestamp", type: ColumnType.text, title: "Time Stamp" },
+ { property: "nodeId", title: "Node Name", type: ColumnType.text },
+ { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
+ { property: "objectId", title: "Object Id", type: ColumnType.text },
+ { property: "problem", title: "Alarm Type", type: ColumnType.text },
+ { property: "severity", title: "Severity", type: ColumnType.text, width: "140px" },
+ ]} {...this.props.currentProblemsProperties} {...this.props.currentProblemsActions} />
</Panel>
- <Panel activePanel={ activePanel } panelId={ 'AlarmNotifications' } onToggle={ onTogglePanel } title={ `Alarm Notifications ${this.props.faultNotifications.faults.length} since ${this.props.faultNotifications.since}` }>
- <FaultTable rows={ this.props.faultNotifications.faults } asynchronus columns={ [
+ <Panel activePanel={activePanel} panelId={'AlarmNotifications'} onToggle={onTogglePanel} title={`Alarm Notifications ${this.props.faultNotifications.faults.length} since ${this.props.faultNotifications.since}`}>
+ <FaultAlarmNotificationTable rows={this.props.faultNotifications.faults} asynchronus columns={[
{ property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
{ property: "timeStamp", title: "Time Stamp" },
{ property: "nodeName", title: "Node Name" },
@@ -102,19 +137,25 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
{ property: "objectId", title: "Object Id" },
{ property: "problem", title: "Alarm Type" },
{ property: "severity", title: "Severity", width: "140px" },
- ] } idProperty={ '_id' } />
+ ]} idProperty={'id'} />
</Panel>
- <Panel activePanel={ activePanel } panelId={ 'AlarmLog' } onToggle={ onTogglePanel } title={ 'Alarm Log' }>
- <FaultTable idProperty={ '_id' } columns={ [
+ <Panel activePanel={activePanel} panelId={'AlarmLog'} onToggle={onTogglePanel} title={'Alarm Log'}>
+ <FaultTable idProperty={'id'} columns={[
{ property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
- { property: "timeStamp", title: "Time Stamp" },
- { property: "nodeName", title: "Node Name" },
+ { property: "timestamp", title: "Time Stamp" },
+ { property: "nodeId", title: "Node Name" },
{ property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
{ property: "objectId", title: "Object Id" },
{ property: "problem", title: "Alarm Type" },
{ property: "severity", title: "Severity", width: "140px" },
- ] } { ...this.props.alarmLogEntriesProperties } { ...this.props.alarmLogEntriesActions }/>
- </Panel>
+ { property: "sourceType", title: "Source", width: "140px" },
+ ]} {...this.props.alarmLogEntriesProperties} {...this.props.alarmLogEntriesActions} />
+ </Panel>
+ {
+ this.state.clearAlarmDialogMode !== ClearStuckAlarmsDialogMode.None && <ClearStuckAlarmsDialog mode={this.state.clearAlarmDialogMode} numberDevices={this.state.stuckAlarms.length} stuckAlarms={this.state.stuckAlarms} onClose={this.onDialogClose} />
+
+ }
+
</>
);
};
@@ -123,9 +164,9 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
this.props.alarmLogEntriesActions.onToggleFilter();
this.props.currentProblemsActions.onToggleFilter();
}
- private renderIcon = (props: { rowData: Fault }) => {
+ private renderIcon = (props: { rowData: Fault | FaultAlarmNotification }) => {
return (
- <FontAwesomeIcon icon={ faExclamationTriangle } />
+ <FontAwesomeIcon icon={faExclamationTriangle} />
);
};
diff --git a/sdnr/wt/odlux/apps/faultApp/webpack.config.js b/sdnr/wt/odlux/apps/faultApp/webpack.config.js
index bbf33ea2f..66926edfb 100644
--- a/sdnr/wt/odlux/apps/faultApp/webpack.config.js
+++ b/sdnr/wt/odlux/apps/faultApp/webpack.config.js
@@ -26,7 +26,7 @@ module.exports = (env) => {
context: path.resolve(__dirname, "src"),
entry: {
- faultApp: ["./plugin.tsx"]
+ faultApp: ["./pluginFault.tsx"]
},
devtool: env === "release" ? false : "source-map",
@@ -125,23 +125,23 @@ module.exports = (env) => {
},
proxy: {
"/oauth2/": {
- target: "http://localhost:3000",
+ target: "http://10.20.6.29:28181/",
secure: false
},
"/database/": {
- target: "http://localhost:3000",
+ target: "http://10.20.6.29:28181/",
secure: false
},
"/restconf/": {
- target: "http://localhost:3000",
+ target: "http://10.20.6.29:28181/",
secure: false
},
"/help/": {
- target: "http://localhost:3000",
+ target: "http://10.20.6.29:28181/",
secure: false
},
"/websocket/": {
- target: "http://localhost:3000",
+ target: "http://10.20.6.29:28181/",
ws: true,
changeOrigin: true,
secure: false