From 256e22f9d35f5c28f4560da76c12108351ea6cde Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Thu, 20 May 2021 02:26:18 +0200 Subject: [PATCH 1/3] show list of managed ICs on manager IC page #306 --- src/ic/ic-pages/default-manager-page.js | 187 ++++++++++++++++++++++++ src/ic/ic.js | 28 +++- src/ic/ics.js | 1 - 3 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 src/ic/ic-pages/default-manager-page.js diff --git a/src/ic/ic-pages/default-manager-page.js b/src/ic/ic-pages/default-manager-page.js new file mode 100644 index 0000000..d8065fb --- /dev/null +++ b/src/ic/ic-pages/default-manager-page.js @@ -0,0 +1,187 @@ +/** + * 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 React from 'react'; +import {Col, Container, Row} from "react-bootstrap"; +import IconButton from "../../common/icon-button"; +import Table from '../../common/table'; +import TableColumn from '../../common/table-column'; + +class DefaultManagerPage extends React.Component { + + constructor() { + super(); + + this.state = { + managedICs: [], + } + } + + componentDidMount() { + let sortedICs = this.props.ics.filter(ic => ic.category !== "manager" && parseInt(ic.manager,10) === parseInt(this.props.ic.uuid,10)); + + this.setState({managedICs: sortedICs}); + } + + static calculateState(prevState, props) { + + let sortedICs = props.ics.filter(ic => ic.category !== "manager" && parseInt(ic.manager,10) === parseInt(props.ic.uuid,10)); + return { + managedICs: sortedICs + } + } + + stateLabelStyle(state, component){ + var style = [ 'badge' ]; + + switch (state) { + case 'error': + style.push('badge-danger'); + break; + case 'idle': + style.push('badge-primary'); + break; + case 'starting': + style.push('badge-info'); + break; + case 'running': + style.push('badge-success'); + break; + case 'pausing': + style.push('badge-info'); + break; + case 'paused': + style.push('badge-info'); + break; + case 'resuming': + style.push('badge-warning'); + break; + case 'stopping': + style.push('badge-warning'); + break; + case 'resetting': + style.push('badge-warning'); + break; + case 'shuttingdown': + style.push('badge-warning'); + break; + case 'shutdown': + style.push('badge-warning'); + break; + + default: + style.push('badge-default'); + + /* Possible states of ICs + * 'error': ['resetting', 'error'], + * 'idle': ['resetting', 'error', 'idle', 'starting', 'shuttingdown'], + * 'starting': ['resetting', 'error', 'running'], + * 'running': ['resetting', 'error', 'pausing', 'stopping'], + * 'pausing': ['resetting', 'error', 'paused'], + * 'paused': ['resetting', 'error', 'resuming', 'stopping'], + * 'resuming': ['resetting', 'error', 'running'], + * 'stopping': ['resetting', 'error', 'idle'], + * 'resetting': ['resetting', 'error', 'idle'], + * 'shuttingdown': ['shutdown', 'error'], + * 'shutdown': ['starting', 'error'] + */ + } + + return style.join(' ') + } + + stateUpdateModifier(updatedAt, component) { + let dateFormat = 'ddd, DD MMM YYYY HH:mm:ss ZZ'; + let dateTime = moment(updatedAt, dateFormat); + return dateTime.fromNow() + } + + modifyUptimeColumn(uptime, component){ + if(uptime >= 0){ + let momentDurationFormatSetup = require("moment-duration-format"); + momentDurationFormatSetup(moment) + + let timeString = moment.duration(uptime, "seconds").humanize(); + return {timeString} + } + else{ + return Unknown + } + } + + render() { + + return (
+ + +

{this.props.ic.name} + + + this.props.refresh(this.props.ic, this.props.sessionToken)} + icon='sync-alt' + buttonStyle={this.props.buttonStyle} + iconStyle={this.props.iconStyle} + /> + +

+ + + + + {this.props.ICParamsTable(this.props.ic)} + + +

Managed ICs:

+ + {this.props.currentUser.role === "Admin" ? + + : <> + } + + this.stateLabelStyle(state, component)} + /> + +
+ +
+
+
+ ) + + } + +} + +export default DefaultManagerPage; diff --git a/src/ic/ic.js b/src/ic/ic.js index 444d825..d591b54 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -26,6 +26,7 @@ import ReactJson from 'react-json-view'; import GatewayVillasNode from './ic-pages/gateway-villas-node' import ManagerVillasRelay from './ic-pages/manager-villas-relay' import DefaultICPage from './ic-pages/default-page' +import DefaultManagerPage from './ic-pages/default-manager-page'; class InfrastructureComponent extends React.Component { constructor(props) { @@ -43,6 +44,7 @@ class InfrastructureComponent extends React.Component { static calculateState(prevState, props) { return { + ics: ICstore.getState(), ic: ICstore.getState().find(ic => ic.id === parseInt(props.match.params.ic, 10)) } } @@ -57,6 +59,16 @@ class InfrastructureComponent extends React.Component { }); } + componentDidUpdate(prevProps: Readonly

, prevState: Readonly, snapshot: SS){ + + let icID = parseInt(this.props.match.params.ic, 10); + + if(typeof prevState !== "undefined" && typeof prevState.ic !== "undefined" && parseInt(prevState.ic.id, 10) !== icID){ + this.setState({ ic: ICstore.getState().find(ic => ic.id === icID)}); + } + + } + static refresh(ic, token) { // get status of VILLASnode and VILLASrelay ICs if (ic.apiurl !== '' && ic.apiurl !== undefined && ic.apiurl !== null && !ic.managedexternally) { @@ -146,7 +158,6 @@ class InfrastructureComponent extends React.Component { height: '25px', width: '25px' } - let page = <>IC page not defined if (this.state.ic.category ==="gateway" && this.state.ic.type === "villas-node") { page = InfrastructureComponent.ICParamsTable(ic)} @@ -170,7 +182,19 @@ class InfrastructureComponent extends React.Component { buttonStyle = {buttonStyle} iconStyle = {iconStyle} /> - } else { + }else if (this.state.ic.category ==="manager") { + page = InfrastructureComponent.ICParamsTable(ic)} + rawDataTable = {(rawData) => InfrastructureComponent.rawDataTable(rawData)} + refresh = {(ic, token) => InfrastructureComponent.refresh(ic, token)} + buttonStyle = {buttonStyle} + iconStyle = {iconStyle} + /> + }else { page = InfrastructureComponent.ICParamsTable(ic)} diff --git a/src/ic/ics.js b/src/ic/ics.js index 7452fa8..f78b568 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -26,7 +26,6 @@ import moment from 'moment' import AppDispatcher from '../common/app-dispatcher'; import InfrastructureComponentStore from './ic-store'; -import Icon from '../common/icon'; import Table from '../common/table'; import TableColumn from '../common/table-column'; import NewICDialog from './new-ic'; From 909a6aee17a840aefea151828967e82877bae184 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 26 May 2021 16:01:12 +0200 Subject: [PATCH 2/3] decrease code redundancy, use exported static functions --- src/ic/ic-pages/default-manager-page.js | 94 ++----------------------- src/ic/ic-pages/default-page.js | 18 ++++- src/ic/ic-pages/gateway-villas-node.js | 11 +-- src/ic/ic-pages/manager-villas-relay.js | 7 +- src/ic/ic.js | 15 ++-- src/ic/ics.js | 23 +++--- 6 files changed, 49 insertions(+), 119 deletions(-) diff --git a/src/ic/ic-pages/default-manager-page.js b/src/ic/ic-pages/default-manager-page.js index d8065fb..cfdbb04 100644 --- a/src/ic/ic-pages/default-manager-page.js +++ b/src/ic/ic-pages/default-manager-page.js @@ -20,6 +20,8 @@ import {Col, Container, Row} from "react-bootstrap"; import IconButton from "../../common/icon-button"; import Table from '../../common/table'; import TableColumn from '../../common/table-column'; +import { stateLabelStyle } from "../ics"; +import { refresh, ICParamsTable } from "../ic" class DefaultManagerPage extends React.Component { @@ -31,98 +33,14 @@ class DefaultManagerPage extends React.Component { } } - componentDidMount() { - let sortedICs = this.props.ics.filter(ic => ic.category !== "manager" && parseInt(ic.manager,10) === parseInt(this.props.ic.uuid,10)); - - this.setState({managedICs: sortedICs}); - } - static calculateState(prevState, props) { - + let sortedICs = props.ics.filter(ic => ic.category !== "manager" && parseInt(ic.manager,10) === parseInt(props.ic.uuid,10)); return { managedICs: sortedICs } } - stateLabelStyle(state, component){ - var style = [ 'badge' ]; - - switch (state) { - case 'error': - style.push('badge-danger'); - break; - case 'idle': - style.push('badge-primary'); - break; - case 'starting': - style.push('badge-info'); - break; - case 'running': - style.push('badge-success'); - break; - case 'pausing': - style.push('badge-info'); - break; - case 'paused': - style.push('badge-info'); - break; - case 'resuming': - style.push('badge-warning'); - break; - case 'stopping': - style.push('badge-warning'); - break; - case 'resetting': - style.push('badge-warning'); - break; - case 'shuttingdown': - style.push('badge-warning'); - break; - case 'shutdown': - style.push('badge-warning'); - break; - - default: - style.push('badge-default'); - - /* Possible states of ICs - * 'error': ['resetting', 'error'], - * 'idle': ['resetting', 'error', 'idle', 'starting', 'shuttingdown'], - * 'starting': ['resetting', 'error', 'running'], - * 'running': ['resetting', 'error', 'pausing', 'stopping'], - * 'pausing': ['resetting', 'error', 'paused'], - * 'paused': ['resetting', 'error', 'resuming', 'stopping'], - * 'resuming': ['resetting', 'error', 'running'], - * 'stopping': ['resetting', 'error', 'idle'], - * 'resetting': ['resetting', 'error', 'idle'], - * 'shuttingdown': ['shutdown', 'error'], - * 'shutdown': ['starting', 'error'] - */ - } - - return style.join(' ') - } - - stateUpdateModifier(updatedAt, component) { - let dateFormat = 'ddd, DD MMM YYYY HH:mm:ss ZZ'; - let dateTime = moment(updatedAt, dateFormat); - return dateTime.fromNow() - } - - modifyUptimeColumn(uptime, component){ - if(uptime >= 0){ - let momentDurationFormatSetup = require("moment-duration-format"); - momentDurationFormatSetup(moment) - - let timeString = moment.duration(uptime, "seconds").humanize(); - return {timeString} - } - else{ - return Unknown - } - } - render() { return (

@@ -134,7 +52,7 @@ class DefaultManagerPage extends React.Component { this.props.refresh(this.props.ic, this.props.sessionToken)} + onClick={() => refresh(this.props.ic, this.props.sessionToken)} icon='sync-alt' buttonStyle={this.props.buttonStyle} iconStyle={this.props.iconStyle} @@ -145,7 +63,7 @@ class DefaultManagerPage extends React.Component { - {this.props.ICParamsTable(this.props.ic)} + {ICParamsTable(this.props.ic)}

Managed ICs:

@@ -167,7 +85,7 @@ class DefaultManagerPage extends React.Component { title='State' labelKey='state' tooltipKey='error' - labelStyle={(state, component) => this.stateLabelStyle(state, component)} + labelStyle={(state, component) => stateLabelStyle(state, component)} /> -

{this.props.ic.name}

+

{this.props.ic.name} + + + refresh(this.props.ic, this.props.sessionToken)} + icon='sync-alt' + buttonStyle={this.props.buttonStyle} + iconStyle={this.props.iconStyle} + /> + +

- {this.props.ICParamsTable(this.props.ic)} + {ICParamsTable(this.props.ic)} diff --git a/src/ic/ic-pages/gateway-villas-node.js b/src/ic/ic-pages/gateway-villas-node.js index 65baadb..0369d17 100644 --- a/src/ic/ic-pages/gateway-villas-node.js +++ b/src/ic/ic-pages/gateway-villas-node.js @@ -21,6 +21,7 @@ import IconButton from "../../common/icon-button"; import ConfirmCommand from "../confirm-command"; import FileSaver from 'file-saver'; import AppDispatcher from "../../common/app-dispatcher"; +import { refresh, ICParamsTable, rawDataTable } from "../ic" class GatewayVillasNode extends React.Component { @@ -78,7 +79,7 @@ class GatewayVillasNode extends React.Component { this.props.refresh(this.props.ic, this.props.sessionToken)} + onClick={() => refresh(this.props.ic, this.props.sessionToken)} icon='sync-alt' buttonStyle={this.props.buttonStyle} iconStyle={this.props.iconStyle} @@ -89,7 +90,7 @@ class GatewayVillasNode extends React.Component { - {this.props.ICParamsTable(this.props.ic)} + {ICParamsTable(this.props.ic)}
@@ -142,15 +143,15 @@ class GatewayVillasNode extends React.Component { Raw Status - {this.props.rawDataTable(this.props.ic.statusupdateraw)} + {rawDataTable(this.props.ic.statusupdateraw)} Raw Config - {this.props.rawDataTable(this.props.ic.statusupdateraw != null ? this.props.ic.statusupdateraw.config : null )} + {rawDataTable(this.props.ic.statusupdateraw != null ? this.props.ic.statusupdateraw.config : null )} Raw Statistics - {this.props.rawDataTable(this.props.ic.statusupdateraw != null ? this.props.ic.statusupdateraw.statistics : null)} + {rawDataTable(this.props.ic.statusupdateraw != null ? this.props.ic.statusupdateraw.statistics : null)} diff --git a/src/ic/ic-pages/manager-villas-relay.js b/src/ic/ic-pages/manager-villas-relay.js index 04987ee..6e879a7 100644 --- a/src/ic/ic-pages/manager-villas-relay.js +++ b/src/ic/ic-pages/manager-villas-relay.js @@ -18,6 +18,7 @@ import React from 'react'; import IconButton from "../../common/icon-button"; import {Col, Container, Row} from "react-bootstrap"; +import { refresh, ICParamsTable, rawDataTable } from "../ic" class ManagerVillasRelay extends React.Component { @@ -34,7 +35,7 @@ class ManagerVillasRelay extends React.Component { this.props.refresh(this.props.ic, this.props.sessionToken)} + onClick={() => refresh(this.props.ic, this.props.sessionToken)} icon='sync-alt' buttonStyle={this.props.buttonStyle} iconStyle={this.props.iconStyle} @@ -45,11 +46,11 @@ class ManagerVillasRelay extends React.Component { - {this.props.ICParamsTable(this.props.ic)} + {ICParamsTable(this.props.ic)} Raw Status - {this.props.rawDataTable(this.props.ic.statusupdateraw)} + {rawDataTable(this.props.ic.statusupdateraw)} diff --git a/src/ic/ic.js b/src/ic/ic.js index d591b54..87bd869 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -164,9 +164,6 @@ class InfrastructureComponent extends React.Component { ic = {this.state.ic} currentUser = {this.state.currentUser} sessionToken = {this.state.sessionToken} - ICParamsTable = {(ic) => InfrastructureComponent.ICParamsTable(ic)} - rawDataTable = {(rawData) => InfrastructureComponent.rawDataTable(rawData)} - refresh = {(ic, token) => InfrastructureComponent.refresh(ic, token)} buttonStyle = {buttonStyle} iconStyle = {iconStyle} /> @@ -176,9 +173,6 @@ class InfrastructureComponent extends React.Component { ics = {this.state.ics} currentUser = {this.state.currentUser} sessionToken = {this.state.sessionToken} - ICParamsTable = {(ic) => InfrastructureComponent.ICParamsTable(ic)} - rawDataTable = {(rawData) => InfrastructureComponent.rawDataTable(rawData)} - refresh = {(ic, token) => InfrastructureComponent.refresh(ic, token)} buttonStyle = {buttonStyle} iconStyle = {iconStyle} /> @@ -188,16 +182,14 @@ class InfrastructureComponent extends React.Component { ics = {this.state.ics} currentUser = {this.state.currentUser} sessionToken = {this.state.sessionToken} - ICParamsTable = {(ic) => InfrastructureComponent.ICParamsTable(ic)} - rawDataTable = {(rawData) => InfrastructureComponent.rawDataTable(rawData)} - refresh = {(ic, token) => InfrastructureComponent.refresh(ic, token)} buttonStyle = {buttonStyle} iconStyle = {iconStyle} /> }else { page = InfrastructureComponent.ICParamsTable(ic)} + buttonStyle = {buttonStyle} + iconStyle = {iconStyle} /> } return page @@ -206,3 +198,6 @@ class InfrastructureComponent extends React.Component { let fluxContainerConverter = require('../common/FluxContainerConverter'); export default FluxContainer.create(fluxContainerConverter.convert(InfrastructureComponent), { withProps: true }); +export const refresh = InfrastructureComponent.refresh; +export const ICParamsTable = InfrastructureComponent.ICParamsTable; +export const rawDataTable = InfrastructureComponent.rawDataTable; diff --git a/src/ic/ics.js b/src/ic/ics.js index 0a5b7bc..dd07e37 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -270,8 +270,8 @@ class InfrastructureComponents extends Component { return Date.now() - new Date(component.stateUpdateAt) > fiveMinutes; } - stateLabelStyle(state, component){ - var style = [ 'badge' ]; + static stateLabelStyle(state, component){ + let style = [ 'badge' ]; if (InfrastructureComponents.isICOutdated(component) && state !== 'shutdown') { style.push('badge-outdated'); @@ -333,13 +333,13 @@ class InfrastructureComponents extends Component { return style.join(' ') } - stateUpdateModifier(updatedAt, component) { + static stateUpdateModifier(updatedAt, component) { let dateFormat = 'ddd, DD MMM YYYY HH:mm:ss ZZ'; let dateTime = moment(updatedAt, dateFormat); return dateTime.fromNow() } - modifyUptimeColumn(uptime, component){ + static modifyUptimeColumn(uptime, component){ if(uptime >= 0){ let momentDurationFormatSetup = require("moment-duration-format"); momentDurationFormatSetup(moment) @@ -352,7 +352,7 @@ class InfrastructureComponents extends Component { } } - isLocalIC(index, ics){ + static isLocalIC(index, ics){ let ic = ics[index] return !ic.managedexternally } @@ -364,7 +364,7 @@ class InfrastructureComponents extends Component { this.isLocalIC(index, ics) === true} + checkboxDisabled={(index) => InfrastructureComponents.isLocalIC(index, ics) === true} onChecked={(ic, event) => this.onICChecked(ic, event)} width='30' /> @@ -385,7 +385,7 @@ class InfrastructureComponents extends Component { title='State' labelKey='state' tooltipKey='error' - labelStyle={(state, component) => this.stateLabelStyle(state, component)} + labelStyle={(state, component) => InfrastructureComponents.stateLabelStyle(state, component)} /> this.modifyUptimeColumn(uptime, component)} + modifier={(uptime, component) => InfrastructureComponents.modifyUptimeColumn(uptime, component)} /> this.stateUpdateModifier(stateUpdateAt, component)} + modifier={(stateUpdateAt, component) => InfrastructureComponents.stateUpdateModifier(stateUpdateAt, component)} /> {this.state.currentUser.role === "Admin" ? @@ -407,10 +407,10 @@ class InfrastructureComponents extends Component { width='150' align='right' editButton - showEditButton ={(index) => this.isLocalIC(index, ics)} + showEditButton ={(index) => InfrastructureComponents.isLocalIC(index, ics)} exportButton deleteButton - showDeleteButton = {(index) => this.isLocalIC(index, ics)} + showDeleteButton = {(index) => InfrastructureComponents.isLocalIC(index, ics)} onEdit={index => this.setState({editModal: true, modalIC: ics[index], modalIndex: index})} onExport={index => this.exportIC(index)} onDelete={index => this.setState({deleteModal: true, modalIC: ics[index], modalIndex: index})} @@ -508,3 +508,4 @@ class InfrastructureComponents extends Component { let fluxContainerConverter = require('../common/FluxContainerConverter'); export default Container.create(fluxContainerConverter.convert(InfrastructureComponents)); +export const stateLabelStyle = InfrastructureComponents.stateLabelStyle; From 68363735dc3cb4e696fd6d1ba4b8be0b4f11de12 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 26 May 2021 16:05:36 +0200 Subject: [PATCH 3/3] add missing token to default IC page --- src/ic/ic.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ic/ic.js b/src/ic/ic.js index d7e33f7..af2fe67 100644 --- a/src/ic/ic.js +++ b/src/ic/ic.js @@ -184,6 +184,7 @@ class InfrastructureComponent extends React.Component { }else { page =