From 0fde0d95813e494287559143cecaedd669e9b39d Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Tue, 13 Apr 2021 19:55:48 +0200 Subject: [PATCH 01/12] ICs clean up: delete unnecessary code --- src/ic/ics.js | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/ic/ics.js b/src/ic/ics.js index 7698317..fe202e6 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -201,9 +201,6 @@ class InfrastructureComponents extends Component { } } - closeICModal(data){ - this.setState({ icModal : false }); - } closeDeleteModal(confirmDelete){ this.setState({ deleteModal: false }); @@ -345,14 +342,6 @@ class InfrastructureComponents extends Component { return dateTime.fromNow() } - modifyManagedExternallyColumn(managedExternally, component){ - if(managedExternally){ - return - } else { - return "" - } - } - modifyUptimeColumn(uptime, component){ if(uptime >= 0){ let momentDurationFormatSetup = require("moment-duration-format"); @@ -366,11 +355,6 @@ class InfrastructureComponents extends Component { } } - openICStatus(ic){ - let index = this.state.ics.indexOf(ic); - this.setState({ icModal: true, modalIC: ic, modalIndex: index }) - } - isLocalIC(index, ics){ let ic = ics[index] return !ic.managedexternally @@ -451,14 +435,6 @@ class InfrastructureComponents extends Component { render() { - const buttonStyle = { - marginLeft: '10px' - }; - - const iconStyle = { - height: '30px', - width: '30px' - } let managerTable = this.getICCategoryTable(this.state.managers, false, "IC Managers") let simulatorTable = this.getICCategoryTable(this.state.simulators, true, "Simulators") From fb6f4f2b973f193aec9c97f49450be37c639eab0 Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Wed, 21 Apr 2021 21:20:22 +0200 Subject: [PATCH 02/12] WIP: IC dialog customization for VILLASnode #303 --- src/ic/ic-store.js | 21 +++++++++++++++++++-- src/ic/ics-data-manager.js | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/ic/ic-store.js b/src/ic/ic-store.js index bc9aa18..f3532e0 100644 --- a/src/ic/ic-store.js +++ b/src/ic/ic-store.js @@ -112,9 +112,18 @@ class InfrastructureComponentStore extends ArrayStore { ICsDataManager.getStatus(action.url, action.token, action.ic); return super.reduce(state, action); + case 'ics/get-config': + ICsDataManager.getConfig(action.url, action.token, action.ic); + return super.reduce(state, action); + + case 'ics/get-statistics': + ICsDataManager.getStatistics(action.url, action.token, action.ic); + return super.reduce(state, action); + + case 'ics/status-received': let tempIC = action.ic; - if(!tempIC.managedexternally){ + if (!tempIC.managedexternally) { tempIC.state = action.data.state; tempIC.uptime = action.data.time_now - action.data.time_started; tempIC.statusupdateraw = action.data @@ -130,9 +139,17 @@ class InfrastructureComponentStore extends ArrayStore { console.log("status error:", action.error); return super.reduce(state, action); + case 'ics/config-error': + console.log("config error:", action.error); + return super.reduce(state, action); + + case 'ics/statistics-error': + console.log("statistics error:", action.error); + return super.reduce(state, action); + case 'ics/nodestats-received': let tempIC2 = action.ic; - if(!tempIC2.managedexternally){ + if (!tempIC2.managedexternally) { if (tempIC2.statusupdateraw === null || tempIC2.statusupdateraw === undefined) { tempIC2.statusupdateraw = {}; } diff --git a/src/ic/ics-data-manager.js b/src/ic/ics-data-manager.js index 74b4080..43dc045 100644 --- a/src/ic/ics-data-manager.js +++ b/src/ic/ics-data-manager.js @@ -117,7 +117,8 @@ class IcsDataManager extends RestDataManager { }) // get name of websocket - /*let ws_api = ic.websocketurl.split("/") + /* + let ws_api = ic.websocketurl.split("/") let ws_name = ws_api[ws_api.length-1] // websocket name is the last element in the websocket url RestAPI.get(url + "/node/" + ws_name + "/stats", null).then(response => { @@ -136,6 +137,38 @@ class IcsDataManager extends RestDataManager { } + getConfig(url,token,ic){ + RestAPI.get(url + "node/" + ic.uuid, null).then(response => { + AppDispatcher.dispatch({ + type: 'ics/config-received', + data: response, + token: token, + ic: ic + }); + }).catch(error => { + AppDispatcher.dispatch({ + type: 'ics/config-error', + error: error + }) + }) + } + + getStatistics(url,token,ic){ + RestAPI.get(url + "/node/" +ic.uuid + "/stats", null).then(response => { + AppDispatcher.dispatch({ + type: 'ics/statistics-received', + data: response, + token: token, + ic: ic + }); + }).catch(error => { + AppDispatcher.dispatch({ + type: 'ics/statistics-error', + error: error + }) + }) + } + restart(url,token){ RestAPI.post(url, null).then(response => { AppDispatcher.dispatch({ From acde44528fad360e516bccd36ba65b99fb8b54f2 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 28 Apr 2021 11:47:31 +0200 Subject: [PATCH 03/12] cascade requests of status, config and statistics of VILLASnode so that IC raw status does not get overwritten; handle bad request response of statistics request separately --- package-lock.json | 3 ++- src/ic/ic-store.js | 49 +++++++++++++++++++++++++------------- src/ic/ics-data-manager.js | 43 +++++++++++++++------------------ 3 files changed, 54 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index c9207a8..8d7c22d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17825,7 +17825,8 @@ }, "ssri": { "version": "6.0.1", - "resolved": "", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "requires": { "figgy-pudding": "^3.5.1" } diff --git a/src/ic/ic-store.js b/src/ic/ic-store.js index f3532e0..385af58 100644 --- a/src/ic/ic-store.js +++ b/src/ic/ic-store.js @@ -112,15 +112,6 @@ class InfrastructureComponentStore extends ArrayStore { ICsDataManager.getStatus(action.url, action.token, action.ic); return super.reduce(state, action); - case 'ics/get-config': - ICsDataManager.getConfig(action.url, action.token, action.ic); - return super.reduce(state, action); - - case 'ics/get-statistics': - ICsDataManager.getStatistics(action.url, action.token, action.ic); - return super.reduce(state, action); - - case 'ics/status-received': let tempIC = action.ic; if (!tempIC.managedexternally) { @@ -132,6 +123,8 @@ class InfrastructureComponentStore extends ArrayStore { data: tempIC, token: action.token, }); + + ICsDataManager.getConfig(action.url, action.token, tempIC); } return super.reduce(state, action); @@ -143,11 +136,39 @@ class InfrastructureComponentStore extends ArrayStore { console.log("config error:", action.error); return super.reduce(state, action); - case 'ics/statistics-error': - console.log("statistics error:", action.error); + case 'ics/config-received': + let temp = action.ic; + if (!temp.managedexternally) { + if (temp.statusupdateraw === null || temp.statusupdateraw === undefined) { + temp.statusupdateraw = {}; + } + temp.statusupdateraw["config"] = action.data; + AppDispatcher.dispatch({ + type: 'ics/start-edit', + data: temp, + token: action.token, + }); + ICsDataManager.getStatistics(action.url, action.token, temp); + + } return super.reduce(state, action); - case 'ics/nodestats-received': + case 'ics/statistics-error': + if (action.error.status === 400){ + // in case of bad request add the error message to the raw status + // most likely the statistics collection is disabled for this node + AppDispatcher.dispatch({ + type: 'ics/statistics-received', + data: action.error.response.text, + token: action.token, + ic: action.ic + }); + } else { + console.log("statistics error:", action.error); + } + return super.reduce(state, action); + + case 'ics/statistics-received': let tempIC2 = action.ic; if (!tempIC2.managedexternally) { if (tempIC2.statusupdateraw === null || tempIC2.statusupdateraw === undefined) { @@ -162,10 +183,6 @@ class InfrastructureComponentStore extends ArrayStore { } return super.reduce(state, action); - case 'ics/nodestats-error': - console.log("nodestats error:", action.error); - return super.reduce(state, action); - case 'ics/restart': ICsDataManager.restart(action.url, action.token); return super.reduce(state, action); diff --git a/src/ic/ics-data-manager.js b/src/ic/ics-data-manager.js index 43dc045..44c85c3 100644 --- a/src/ic/ics-data-manager.js +++ b/src/ic/ics-data-manager.js @@ -107,7 +107,8 @@ class IcsDataManager extends RestDataManager { type: 'ics/status-received', data: response, token: token, - ic: ic + ic: ic, + url: url }); }).catch(error => { AppDispatcher.dispatch({ @@ -116,34 +117,21 @@ class IcsDataManager extends RestDataManager { }) }) - // get name of websocket - /* - let ws_api = ic.websocketurl.split("/") - let ws_name = ws_api[ws_api.length-1] // websocket name is the last element in the websocket url - - RestAPI.get(url + "/node/" + ws_name + "/stats", null).then(response => { - AppDispatcher.dispatch({ - type: 'ics/nodestats-received', - data: response, - token: token, - ic: ic - }); - }).catch(error => { - AppDispatcher.dispatch({ - type: 'ics/nodestats-error', - error: error - }) - })*/ - } getConfig(url,token,ic){ - RestAPI.get(url + "node/" + ic.uuid, null).then(response => { + + // get the name of the node + let ws_api = ic.websocketurl.split("/") + let ws_name = ws_api[ws_api.length-1] // name is the last element in the websocket url + + RestAPI.get(url + "/node/" + ws_name, null).then(response => { AppDispatcher.dispatch({ type: 'ics/config-received', data: response, token: token, - ic: ic + ic: ic, + url: url }); }).catch(error => { AppDispatcher.dispatch({ @@ -154,7 +142,12 @@ class IcsDataManager extends RestDataManager { } getStatistics(url,token,ic){ - RestAPI.get(url + "/node/" +ic.uuid + "/stats", null).then(response => { + + // get the name of the node + let ws_api = ic.websocketurl.split("/") + let ws_name = ws_api[ws_api.length-1] // name is the last element in the websocket url + + RestAPI.get(url + "/node/" +ws_name + "/stats", null).then(response => { AppDispatcher.dispatch({ type: 'ics/statistics-received', data: response, @@ -164,7 +157,9 @@ class IcsDataManager extends RestDataManager { }).catch(error => { AppDispatcher.dispatch({ type: 'ics/statistics-error', - error: error + error: error, + token: token, + ic: ic }) }) } From 7935e8ff6a4b43f6923e4265c67690ab6570d24e Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 28 Apr 2021 11:58:51 +0200 Subject: [PATCH 04/12] add refresh of IC and status query to IC page; improve error handling for start parameter schema JSON view --- src/ic/ic.js | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/ic/ic.js b/src/ic/ic.js index 9bb730f..b9f9575 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -61,6 +61,31 @@ class InfrastructureComponent extends React.Component { data: icID, token: this.state.sessionToken, }); + + // Start timer for periodic refresh + this.timer = window.setInterval(() => this.refresh(), 10000); + } + + refresh() { + + let icID = parseInt(this.props.match.params.ic, 10); + AppDispatcher.dispatch({ + type: 'ics/start-load', + token: this.state.sessionToken, + data: icID + }); + + // get status of VILLASnode and VILLASrelay ICs + if ((this.state.ic.type === "villas-node" || this.state.ic.type === "villas-relay") + && this.state.ic.apiurl !== '' && this.state.ic.apiurl !== undefined && this.state.ic.apiurl !== null && !this.state.ic.managedexternally) { + AppDispatcher.dispatch({ + type: 'ics/get-status', + url: this.state.ic.apiurl, + token: this.state.sessionToken, + ic: this.state.ic + }); + } + } isJSON(data) { @@ -102,12 +127,12 @@ class InfrastructureComponent extends React.Component { if(!canceled){ this.sendControlCommand(); } - + this.setState({confirmCommand: false, command: ''}); } - + async downloadGraph(url) { - + let blob = await fetch(url).then(r => r.blob()) FileSaver.saveAs(blob, this.props.ic.name + ".svg"); } @@ -172,14 +197,15 @@ class InfrastructureComponent extends React.Component { Start parameter schema - + /> :
No Start parameter schema JSON available.
} @@ -237,4 +263,4 @@ class InfrastructureComponent extends React.Component { } let fluxContainerConverter = require('../common/FluxContainerConverter'); -export default FluxContainer.create(fluxContainerConverter.convert(InfrastructureComponent), { withProps: true }); \ No newline at end of file +export default FluxContainer.create(fluxContainerConverter.convert(InfrastructureComponent), { withProps: true }); From ea0ec52902d94b1ec85448b295258ddac275397c Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Wed, 28 Apr 2021 14:04:49 +0200 Subject: [PATCH 05/12] WIP: IC page customization for VILLASnode #303 --- src/ic/ic.js | 21 +++++++++++++++++++++ src/ic/ics-data-manager.js | 8 ++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/ic/ic.js b/src/ic/ic.js index b9f9575..f61bd3d 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -222,6 +222,27 @@ class InfrastructureComponent extends React.Component { collapsed={0} /> :
No valid JSON raw data available.
} + Raw Config + {this.isJSON(this.state.ic.statusupdateraw["config"]) ? + :
No valid config JSON raw data available.
} + Raw Statistics + {this.isJSON(this.state.ic.statusupdateraw["statistics"]) ? + :
No valid statistics JSON raw data available.
} + {this.state.ic.type === "villas-node" ? <>
diff --git a/src/ic/ics-data-manager.js b/src/ic/ics-data-manager.js index 44c85c3..fcfd5db 100644 --- a/src/ic/ics-data-manager.js +++ b/src/ic/ics-data-manager.js @@ -102,7 +102,11 @@ class IcsDataManager extends RestDataManager { } getStatus(url,token,ic){ - RestAPI.get(url + "/status", null).then(response => { + let requestURL = url; + if(ic.type === "villas-node"){ + requestURL += "/status"; + } + RestAPI.get(requestURL, null).then(response => { AppDispatcher.dispatch({ type: 'ics/status-received', data: response, @@ -147,7 +151,7 @@ class IcsDataManager extends RestDataManager { let ws_api = ic.websocketurl.split("/") let ws_name = ws_api[ws_api.length-1] // name is the last element in the websocket url - RestAPI.get(url + "/node/" +ws_name + "/stats", null).then(response => { + RestAPI.get(url + "/node/" + ws_name + "/stats", null).then(response => { AppDispatcher.dispatch({ type: 'ics/statistics-received', data: response, From 81209d4ef0bee67f1eb0c85d1c5e06bdf46833f1 Mon Sep 17 00:00:00 2001 From: irismarie Date: Fri, 30 Apr 2021 16:53:35 +0200 Subject: [PATCH 06/12] small fixes --- src/ic/ic.js | 4 ++-- src/ic/ics.js | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ic/ic.js b/src/ic/ic.js index f61bd3d..0d2abfe 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -223,7 +223,7 @@ class InfrastructureComponent extends React.Component { /> :
No valid JSON raw data available.
} Raw Config - {this.isJSON(this.state.ic.statusupdateraw["config"]) ? + {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["config"]) ? :
No valid config JSON raw data available.
} Raw Statistics - {this.isJSON(this.state.ic.statusupdateraw["statistics"]) ? + {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["statistics"]) ? Date: Wed, 5 May 2021 16:03:27 +0200 Subject: [PATCH 07/12] IC page: show only villas-relay status --- src/ic/ic.js | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/ic/ic.js b/src/ic/ic.js index 0d2abfe..a62eaa2 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -211,8 +211,11 @@ class InfrastructureComponent extends React.Component { - Raw Status - {this.isJSON(this.state.ic.statusupdateraw) ? + + {this.state.ic.type === "villas-node" ? + <> + Raw Status + {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? :
No valid statistics JSON raw data available.
} - {this.state.ic.type === "villas-node" ? - <>
@@ -275,6 +276,22 @@ class InfrastructureComponent extends React.Component { :
} + {this.state.ic.type === "villas-relay" ? + <> + Raw Status + {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? + :
No valid JSON raw data available.
} + + : +
} + From dd453f668e369386db44fe7db35e457680074e50 Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Thu, 6 May 2021 01:01:15 +0200 Subject: [PATCH 08/12] IC page customization for VILLASnode and VILLASrelay #303 #304 #305 --- src/ic/ic.js | 109 +++++++++++++++++++++++++++++++++----------------- src/ic/ics.js | 13 ------ 2 files changed, 72 insertions(+), 50 deletions(-) diff --git a/src/ic/ic.js b/src/ic/ic.js index a62eaa2..1d9a38c 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -62,9 +62,23 @@ class InfrastructureComponent extends React.Component { token: this.state.sessionToken, }); - // Start timer for periodic refresh - this.timer = window.setInterval(() => this.refresh(), 10000); + // get status of VILLASnode and VILLASrelay ICs + if(this.state.ic != undefined){ + if ((this.state.ic.type === "villas-node" || this.state.ic.type === "villas-relay") + && this.state.ic.apiurl !== '' && this.state.ic.apiurl !== undefined && this.state.ic.apiurl !== null && !this.state.ic.managedexternally) { + AppDispatcher.dispatch({ + type: 'ics/get-status', + url: this.state.ic.apiurl, + token: this.state.sessionToken, + ic: this.state.ic + }); + } } + else{ + this.timer = window.setInterval(() => this.refresh(), 10000); + } + } + refresh() { @@ -86,6 +100,10 @@ class InfrastructureComponent extends React.Component { }); } + if(this.timer){ + window.clearInterval(this.timer); + } + } isJSON(data) { @@ -212,40 +230,8 @@ class InfrastructureComponent extends React.Component { - {this.state.ic.type === "villas-node" ? + {this.state.ic.type === "villas-node" ? <> - Raw Status - {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? - :
No valid JSON raw data available.
} - - Raw Config - {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["config"]) ? - :
No valid config JSON raw data available.
} - Raw Statistics - {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["statistics"]) ? - :
No valid statistics JSON raw data available.
} -
@@ -278,6 +264,10 @@ class InfrastructureComponent extends React.Component { {this.state.ic.type === "villas-relay" ? <> +
+ +
Raw Status {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? :
No valid JSON raw data available.
} :
} - + + {this.state.ic.type === "villas-node" ? + <> + + Raw Status + {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? + :
No valid JSON raw data available.
} + + + Raw Config + {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["config"]) ? + :
No valid config JSON raw data available.
} + + +
+ +
+ Raw Statistics + {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["statistics"]) ? + :
No valid statistics JSON raw data available.
} + + + :
} +
; } diff --git a/src/ic/ics.js b/src/ic/ics.js index 01e9c0b..f64c47e 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -133,19 +133,6 @@ class InfrastructureComponents extends Component { token: this.state.sessionToken, }); - // get status of VILLASnode and VILLASrelay ICs - this.state.ics.forEach(ic => { - if ((ic.type === "villas-node" || ic.type === "villas-relay") - && ic.apiurl !== '' && ic.apiurl !== undefined && ic.apiurl !== null && !ic.managedexternally) { - AppDispatcher.dispatch({ - type: 'ics/get-status', - url: ic.apiurl, - token: this.state.sessionToken, - ic: ic - }); - } - }) - } } From 1c14087822243c22e66bd7f9824eefe2bea43d9b Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Thu, 6 May 2021 01:34:51 +0200 Subject: [PATCH 09/12] Replace IC page buttons with IconButtons --- src/ic/ic.js | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/src/ic/ic.js b/src/ic/ic.js index 1d9a38c..5752f3e 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -23,7 +23,7 @@ import { Container, Col, Row, Table, Button } from 'react-bootstrap'; import moment from 'moment'; import ReactJson from 'react-json-view'; import ConfirmCommand from './confirm-command'; -import Icon from "../common/icon"; +import IconButton from '../common/icon-button'; @@ -165,6 +165,15 @@ class InfrastructureComponent extends React.Component { graphURL = this.state.ic.apiurl + "/graph.svg" } + const buttonStyle = { + marginLeft: '5px', + } + + const iconStyle = { + height: '25px', + width: '25px' + } + return

{this.state.ic.name}

@@ -233,8 +242,14 @@ class InfrastructureComponent extends React.Component { {this.state.ic.type === "villas-node" ? <>
- + this.downloadGraph(graphURL)} + icon='download' + buttonStyle={buttonStyle} + iconStyle={iconStyle} + />

Graph: @@ -265,9 +280,15 @@ class InfrastructureComponent extends React.Component { {this.state.ic.type === "villas-relay" ? <>
- -
+ this.refresh()} + icon='sync-alt' + buttonStyle={buttonStyle} + iconStyle={iconStyle} + /> +
Raw Status {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? }
+
+ this.refresh()} + icon='sync-alt' + buttonStyle={buttonStyle} + iconStyle={iconStyle} + /> +
{this.state.ic.type === "villas-node" ? <> @@ -310,11 +341,7 @@ class InfrastructureComponent extends React.Component { collapsed={1} /> :
No valid config JSON raw data available.
} - -
- -
+ Raw Statistics {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["statistics"]) ? Date: Thu, 6 May 2021 16:09:20 +0200 Subject: [PATCH 10/12] reinsert IC status refresh on ICs page --- src/ic/ics.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/ic/ics.js b/src/ic/ics.js index f64c47e..f0d7a8d 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -134,6 +134,20 @@ class InfrastructureComponents extends Component { }); } + + // get status of VILLASnode and VILLASrelay ICs + this.state.ics.forEach(ic => { + if ((ic.type === "villas-node" || ic.type === "villas-relay") + && ic.apiurl !== '' && ic.apiurl !== undefined && ic.apiurl !== null && !ic.managedexternally) { + AppDispatcher.dispatch({ + type: 'ics/get-status', + url: ic.apiurl, + token: this.state.sessionToken, + ic: ic + }); + } + }) + } closeNewModal(data) { From 57e6a6c3d064e8ebb4202c5afbeb61e4b0855bce Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Thu, 6 May 2021 16:35:10 +0200 Subject: [PATCH 11/12] minor fixes in IC pages for VILLASnode and VILLASrelay #304 #303 - fix indentation - fix loading of IC and refresh of status - add missing IC data store - show refresh button only for villas-node and villas-relay - remove duplicated function --- src/ic/ic.js | 607 ++++++++++++++++++++++++--------------------------- 1 file changed, 287 insertions(+), 320 deletions(-) diff --git a/src/ic/ic.js b/src/ic/ic.js index 5752f3e..ed5c8ef 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -16,7 +16,8 @@ ******************************************************************************/ import React from 'react'; -import InfrastructureComponentStore from './ic-store'; +import ICstore from './ic-store'; +import ICdataStore from './ic-data-store' import { Container as FluxContainer } from 'flux/utils'; import AppDispatcher from '../common/app-dispatcher'; import { Container, Col, Row, Table, Button } from 'react-bootstrap'; @@ -28,338 +29,304 @@ import IconButton from '../common/icon-button'; class InfrastructureComponent extends React.Component { - constructor(props) { - super(props); + constructor(props) { + super(props); - this.state = { - confirmCommand: false, - command: '', - }; + this.state = { + confirmCommand: false, + command: '', + sessionToken: localStorage.getItem("token"), + currentUser: JSON.parse(localStorage.getItem("currentUser")), + }; + } + + static getStores() { + return [ICstore, ICdataStore]; + } + + static calculateState(prevState, props) { + return { + ic: ICstore.getState().find(ic => ic.id === parseInt(props.match.params.ic, 10)) + } + } + + componentDidMount() { + let icID = parseInt(this.props.match.params.ic, 10); + + AppDispatcher.dispatch({ + type: 'ics/start-load', + data: icID, + token: this.state.sessionToken, + }); + } + + + refresh() { + // get status of VILLASnode and VILLASrelay ICs + if ((this.state.ic.type === "villas-node" || this.state.ic.type === "villas-relay") + && this.state.ic.apiurl !== '' && this.state.ic.apiurl !== undefined && this.state.ic.apiurl !== null && !this.state.ic.managedexternally) { + AppDispatcher.dispatch({ + type: 'ics/get-status', + url: this.state.ic.apiurl, + token: this.state.sessionToken, + ic: this.state.ic + }); + } + } + + isJSON(data) { + if (data === undefined || data === null) { + return false; + } + let str = JSON.stringify(data); + try { + JSON.parse(str) + } + catch (ex) { + return false + } + return true + } + + async downloadGraph(url) { + let blob = await fetch(url).then(r => r.blob()) + FileSaver.saveAs(blob, this.state.ic.name + ".svg"); + } + + sendControlCommand() { + if (this.state.command === "restart") { + AppDispatcher.dispatch({ + type: 'ics/restart', + url: this.state.ic.apiurl + "/restart", + token: this.state.sessionToken, + }); + } else if (this.state.command === "shutdown") { + AppDispatcher.dispatch({ + type: 'ics/shutdown', + url: this.state.ic.apiurl + "/shutdown", + token: this.state.sessionToken, + }); + } + } + + confirmCommand(canceled){ + if(!canceled){ + this.sendControlCommand(); } - static getStores() { - return [InfrastructureComponentStore]; + this.setState({confirmCommand: false, command: ''}); + } + + + render() { + if (this.state.ic === undefined) { + return

Loading Infrastructure Component...

; } - static calculateState(prevState, props) { - if (prevState == null) { - prevState = {}; - } - - return { - sessionToken: localStorage.getItem("token"), - currentUser: JSON.parse(localStorage.getItem("currentUser")), - ic: InfrastructureComponentStore.getState().find(ic => ic.id === parseInt(props.match.params.ic, 10)) - } + let graphURL = "" + if (this.state.ic.apiurl !== "") { + graphURL = this.state.ic.apiurl + "/graph.svg" } - componentDidMount() { - let icID = parseInt(this.props.match.params.ic, 10); - - AppDispatcher.dispatch({ - type: 'ics/start-load', - data: icID, - token: this.state.sessionToken, - }); - - // get status of VILLASnode and VILLASrelay ICs - if(this.state.ic != undefined){ - if ((this.state.ic.type === "villas-node" || this.state.ic.type === "villas-relay") - && this.state.ic.apiurl !== '' && this.state.ic.apiurl !== undefined && this.state.ic.apiurl !== null && !this.state.ic.managedexternally) { - AppDispatcher.dispatch({ - type: 'ics/get-status', - url: this.state.ic.apiurl, - token: this.state.sessionToken, - ic: this.state.ic - }); - } - } - else{ - this.timer = window.setInterval(() => this.refresh(), 10000); - } + const buttonStyle = { + marginLeft: '5px', } - - refresh() { - - let icID = parseInt(this.props.match.params.ic, 10); - AppDispatcher.dispatch({ - type: 'ics/start-load', - token: this.state.sessionToken, - data: icID - }); - - // get status of VILLASnode and VILLASrelay ICs - if ((this.state.ic.type === "villas-node" || this.state.ic.type === "villas-relay") - && this.state.ic.apiurl !== '' && this.state.ic.apiurl !== undefined && this.state.ic.apiurl !== null && !this.state.ic.managedexternally) { - AppDispatcher.dispatch({ - type: 'ics/get-status', - url: this.state.ic.apiurl, - token: this.state.sessionToken, - ic: this.state.ic - }); - } - - if(this.timer){ - window.clearInterval(this.timer); - } - + const iconStyle = { + height: '25px', + width: '25px' } - isJSON(data) { - if (data === undefined || data === null) { - return false; - } - let str = JSON.stringify(data); - try { - JSON.parse(str) - } - catch (ex) { - return false - } - return true - } - - async downloadGraph(url) { - let blob = await fetch(url).then(r => r.blob()) - FileSaver.saveAs(blob, this.state.ic.name + ".svg"); - } - - sendControlCommand() { - if (this.state.command === "restart") { - AppDispatcher.dispatch({ - type: 'ics/restart', - url: this.state.ic.apiurl + "/restart", - token: this.state.sessionToken, - }); - } else if (this.state.command === "shutdown") { - AppDispatcher.dispatch({ - type: 'ics/shutdown', - url: this.state.ic.apiurl + "/shutdown", - token: this.state.sessionToken, - }); - } - } - - confirmCommand(canceled){ - if(!canceled){ - this.sendControlCommand(); - } - - this.setState({confirmCommand: false, command: ''}); - } - - async downloadGraph(url) { - - let blob = await fetch(url).then(r => r.blob()) - FileSaver.saveAs(blob, this.props.ic.name + ".svg"); - } - - render() { - if (this.state.ic === undefined) { - return

Loading Infrastructure Component...

; - } - - let graphURL = "" - if (this.state.ic.apiurl !== "") { - graphURL = this.state.ic.apiurl + "/graph.svg" - } - - const buttonStyle = { - marginLeft: '5px', - } - - const iconStyle = { - height: '25px', - width: '25px' - } - - return
-

{this.state.ic.name}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name{this.state.ic.name}
Description{this.state.ic.description}
UUID{this.state.ic.uuid}
State{this.state.ic.state}
Category{this.state.ic.category}
Type{this.state.ic.type}
Uptime{moment.duration(this.state.ic.uptime, "seconds").humanize()}
Location{this.state.ic.location}
Websocket URL{this.state.ic.websocketurl}
API URL{this.state.ic.apiurl}
Start parameter schema - {this.isJSON(this.state.ic.startparameterschema) ? - :
No Start parameter schema JSON available.
} -
- - - {this.state.ic.type === "villas-node" ? - <> -
- this.downloadGraph(graphURL)} - icon='download' - buttonStyle={buttonStyle} - iconStyle={iconStyle} - /> -
-
- Graph: -
- {"Graph -
- - {this.state.currentUser.role === "Admin" ? -
-
- Controls: -
- - -
-
- :
- } - this.confirmCommand(c)} /> - - :
} - - {this.state.ic.type === "villas-relay" ? - <> -
- this.refresh()} - icon='sync-alt' - buttonStyle={buttonStyle} - iconStyle={iconStyle} - /> -
- Raw Status - {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? - :
No valid JSON raw data available.
} - - : -
} - - + return
+

{this.state.ic.name}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name{this.state.ic.name}
Description{this.state.ic.description}
UUID{this.state.ic.uuid}
State{this.state.ic.state}
Category{this.state.ic.category}
Type{this.state.ic.type}
Uptime{moment.duration(this.state.ic.uptime, "seconds").humanize()}
Location{this.state.ic.location}
Websocket URL{this.state.ic.websocketurl}
API URL{this.state.ic.apiurl}
Start parameter schema + {this.isJSON(this.state.ic.startparameterschema) ? + :
No Start parameter schema JSON available.
} +
+ + + {this.state.ic.type === "villas-node" ? + <>
- this.refresh()} - icon='sync-alt' - buttonStyle={buttonStyle} - iconStyle={iconStyle} - /> -
- - {this.state.ic.type === "villas-node" ? - <> - - Raw Status - {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? - :
No valid JSON raw data available.
} - - - Raw Config - {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["config"]) ? - :
No valid config JSON raw data available.
} - - - Raw Statistics - {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["statistics"]) ? - :
No valid statistics JSON raw data available.
} - - - :
} - - -
; - } + this.downloadGraph(graphURL)} + icon='download' + buttonStyle={buttonStyle} + iconStyle={iconStyle} + /> +
+
+ Graph: +
+ {"Graph +
+ {this.state.currentUser.role === "Admin" ? +
+
+ Controls: +
+ + +
+
+ :
+ } + this.confirmCommand(c)} + /> + + :
} + + {this.state.ic.type === "villas-relay" ? + <> +
+ this.refresh()} + icon='sync-alt' + buttonStyle={buttonStyle} + iconStyle={iconStyle} + /> +
+ Raw Status + {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? + :
No valid JSON raw data available.
} + + : +
} + + + {this.state.ic.type === "villas-node" ? + <> +
+ this.refresh()} + icon='sync-alt' + buttonStyle={buttonStyle} + iconStyle={iconStyle} + /> +
+ + + + Raw Status + {this.state.ic.statusupdateraw !== null && this.isJSON(this.state.ic.statusupdateraw) ? + :
No valid JSON raw data available.
} + + + Raw Config + {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["config"]) ? + :
No valid config JSON raw data available.
} + + + Raw Statistics + {this.state.ic.statusupdateraw && this.isJSON(this.state.ic.statusupdateraw["statistics"]) ? + :
No valid statistics JSON raw data available.
} + + +
+ :
} + +
; + } } let fluxContainerConverter = require('../common/FluxContainerConverter'); From 9a82072b36d8523e9052beae4deee0570757b6be Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Thu, 6 May 2021 16:35:49 +0200 Subject: [PATCH 12/12] add missing stores in scenario and scenarios component --- src/scenario/scenario.js | 3 ++- src/scenario/scenarios.js | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index d9e9d4c..57e7a15 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -30,6 +30,7 @@ import SignalStore from '../signal/signal-store' import FileStore from "../file/file-store" import WidgetStore from "../widget/widget-store"; import ResultStore from "../result/result-store" +import UsersStore from "../user/users-store" import DashboardTable from '../dashboard/dashboard-table' import ResultTable from "../result/result-table"; @@ -67,7 +68,7 @@ class Scenario extends React.Component { } static getStores() { - return [ScenarioStore, ConfigStore, DashboardStore, ICStore, SignalStore, FileStore, WidgetStore, ResultStore]; + return [ScenarioStore, ConfigStore, DashboardStore, ICStore, SignalStore, FileStore, WidgetStore, ResultStore, UsersStore]; } componentDidMount() { diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index 51f8d3e..4a3ecbb 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -18,21 +18,19 @@ import React, { Component } from 'react'; import { Container } from 'flux/utils'; import FileSaver from 'file-saver'; - import AppDispatcher from '../common/app-dispatcher'; import ScenarioStore from './scenario-store'; import DashboardStore from '../dashboard/dashboard-store'; import WidgetStore from "../widget/widget-store"; import ConfigStore from '../componentconfig/config-store'; import SignalStore from '../signal/signal-store' - -import Icon from '../common/icon'; +import ResultStore from '../result/result-store' +import FileStore from '../file/file-store' import Table from '../common/table'; import TableColumn from '../common/table-column'; import NewScenarioDialog from './new-scenario'; import EditScenarioDialog from './edit-scenario'; import ImportScenarioDialog from './import-scenario'; - import DeleteDialog from '../common/dialogs/delete-dialog'; import IconButton from '../common/icon-button'; @@ -40,7 +38,7 @@ import IconButton from '../common/icon-button'; class Scenarios extends Component { static getStores() { - return [ScenarioStore, DashboardStore, WidgetStore, ConfigStore, SignalStore]; + return [ScenarioStore, DashboardStore, WidgetStore, ConfigStore, SignalStore, ResultStore, FileStore]; } static calculateState(prevState, props) {