From b79de99e9aa8ab2af5cbe731100552ba28ad4ab1 Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Sun, 22 Nov 2020 22:06:01 +0100 Subject: [PATCH] WIP: Show status of VILLASnode ICs #265 --- src/ic/ic-api-store.js | 49 ++++++++++++++++++++++++++++++++ src/ic/ic-data-data-manager.js | 18 ++++++++++++ src/ic/ic-dialog.js | 51 ++++++++++++++++++++++++++++++++-- src/ic/ics.js | 36 ++++++++++++++++++++---- 4 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 src/ic/ic-api-store.js diff --git a/src/ic/ic-api-store.js b/src/ic/ic-api-store.js new file mode 100644 index 0000000..d02d644 --- /dev/null +++ b/src/ic/ic-api-store.js @@ -0,0 +1,49 @@ +/** + * This file is part of VILLASweb. + * + * VILLASweb is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * VILLASweb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with VILLASweb. If not, see . + ******************************************************************************/ + +import ArrayStore from '../common/array-store'; +import ICDataDataManager from './ic-data-data-manager'; + +class ICAPIStore extends ArrayStore { + constructor() { + super('ic-api', ICDataDataManager); + } + + + reduce(state, action) { + switch(action.type) { + + case 'ic-api/get-status': + ICDataDataManager.getStatus(action.url, action.socketname, action.token,action.icid); + return super.reduce(state, action); + + case 'ic-api/status-received': + let tempData = action.data; + tempData.icId = action.icid; + return this.updateElements(state, [tempData]); + + case 'ic-api/status-error': + console.log("status error"); + return super.reduce(state, action); + + default: + return super.reduce(state, action); + } + } +} + +export default new ICAPIStore(); diff --git a/src/ic/ic-data-data-manager.js b/src/ic/ic-data-data-manager.js index 0dcc853..5e10007 100644 --- a/src/ic/ic-data-data-manager.js +++ b/src/ic/ic-data-data-manager.js @@ -17,6 +17,7 @@ import WebsocketAPI from '../common/api/websocket-api'; import AppDispatcher from '../common/app-dispatcher'; +import RestAPI from "../common/api/rest-api"; const OFFSET_TYPE = 2; const OFFSET_VERSION = 4; @@ -43,6 +44,23 @@ class IcDataDataManager { } } + getStatus(url,socketname,token,icid){ + RestAPI.get(url, null).then(response => { + AppDispatcher.dispatch({ + type: 'ic-api/status-received', + data: response, + token: token, + socketname: socketname, + icid: icid, + }); + }).catch(error => { + AppDispatcher.dispatch({ + type: 'ic-api/status-error', + error: error + }) + }) + } + closeAll() { // close every open socket for (var identifier in this._sockets) { diff --git a/src/ic/ic-dialog.js b/src/ic/ic-dialog.js index b134f95..0a1a411 100644 --- a/src/ic/ic-dialog.js +++ b/src/ic/ic-dialog.js @@ -1,6 +1,9 @@ import React from 'react'; -import {FormLabel} from 'react-bootstrap'; +import {FormLabel, Button} from 'react-bootstrap'; import Dialog from '../common/dialogs/dialog'; +import {Collapse} from 'react-collapse'; +import Icon from "../common/icon"; + class ICDialog extends React.Component { @@ -10,10 +13,20 @@ class ICDialog extends React.Component { super(props); this.state = { - ic: props.ic + timezone: false, + kernel: false, + system: false, }; } +/* static getDerivedStateFromProps(props, state){ + let icStatus = props.icStatus; + return { + icStatus: icStatus, + ic: props.ic, + }; + }*/ + onClose(canceled) { this.props.onClose(); } @@ -22,6 +35,19 @@ class ICDialog extends React.Component { } + showFurtherInfo(key){ + switch(key){ + case 'timezone': + this.setState({timezone: !this.state.timezone}); + return; + case 'kernel': + this.setState({kernel: !this.state.kernel}); + return; + case 'system': + this.setState({system: !this.state.system}); + return; + } + } render() { @@ -35,7 +61,26 @@ class ICDialog extends React.Component { size='lg' >
- Infos and Controls + Status + { + typeof this.props.icStatus !== "undefined" && Object.keys(this.props.icStatus).map(statusKey => ( + typeof this.props.icStatus[statusKey] === 'object' ? + (
+ + + { + Object.keys(this.props.icStatus[statusKey]).map(key => ( +
{key + ": " + this.props.icStatus[statusKey][key]}
+ )) + } +
+ +
) + : + (
{statusKey + ": " + this.props.icStatus[statusKey]}
) + )) + }
); diff --git a/src/ic/ics.js b/src/ic/ics.js index 138852f..2789b1e 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -24,6 +24,7 @@ import moment from 'moment' import AppDispatcher from '../common/app-dispatcher'; import InfrastructureComponentStore from './ic-store'; +import ICAPIStore from './ic-api-store'; import Icon from '../common/icon'; import Table from '../common/table'; @@ -38,7 +39,7 @@ import DeleteDialog from '../common/dialogs/delete-dialog'; class InfrastructureComponents extends Component { static getStores() { - return [ InfrastructureComponentStore ]; + return [ InfrastructureComponentStore, ICAPIStore ]; } static statePrio(state) { @@ -73,11 +74,15 @@ class InfrastructureComponents extends Component { return a.stateUpdatedAt < b.stateUpdatedAt; } }); + + const icInfo = ICAPIStore.getState(); return { sessionToken: localStorage.getItem("token"), ics: ics, + icInfo: icInfo, modalIC: {}, + modalICStatus: {}, deleteModal: false, icModal: false, selectedICs: [], @@ -90,11 +95,11 @@ class InfrastructureComponents extends Component { type: 'ics/start-load', token: this.state.sessionToken, }); - - // Start timer for periodic refresh + + // Start timer for periodic refresh this.timer = window.setInterval(() => this.refresh(), 10000); } - + componentWillUnmount() { window.clearInterval(this.timer); } @@ -109,6 +114,19 @@ class InfrastructureComponents extends Component { type: 'ics/start-load', token: this.state.sessionToken, }); + + this.state.ics.forEach(ic => { + if (ic.type === "villas-node" || ic.type === "villas-relay") { + let splitWebsocketURL = ic.websocketurl.split("/"); + AppDispatcher.dispatch({ + type: 'ic-api/get-status', + url: ic.apiurl + "/status", + socketname: splitWebsocketURL[splitWebsocketURL.length - 1], + token: this.state.sessionToken, + icid: ic.id, + }); + } + }) } } @@ -320,12 +338,18 @@ class InfrastructureComponents extends Component { let ic = this.state.ics.find(ic => ic.name === name); let index = this.state.ics.indexOf(ic); if(ic.type === "villas-node" || ic.type === "villas-relay"){ - return } + return } else{ return {name} } } + openICStatus(ic){ + let index = this.state.ics.indexOf(ic); + let icStatus = this.state.icInfo.find(info => info.icID === ic.id); + this.setState({ icModal: true, modalIC: ic, modalICStatus: icStatus, modalIndex: index }) + } + render() { const buttonStyle = { marginLeft: '10px' @@ -396,7 +420,7 @@ class InfrastructureComponents extends Component { this.closeNewModal(data)} /> this.closeEditModal(data)} ic={this.state.modalIC} /> this.closeImportModal(data)} /> - this.closeICModal(data)} ic={this.state.modalIC} token={this.state.sessionToken} /> + this.closeICModal(data)} ic={this.state.modalIC} token={this.state.sessionToken} icStatus={this.state.modalICStatus} /> this.closeDeleteModal(e)} />