diff --git a/src/app.js b/src/app.js index cf4ce3b..b077ea9 100644 --- a/src/app.js +++ b/src/app.js @@ -31,6 +31,7 @@ import Footer from './common/footer'; import Menu from './common/menu'; import InfrastructureComponents from './ic/ics'; +import InfrastructureComponent from './ic/ic'; import Dashboard from './dashboard/dashboard'; import Scenarios from './scenario/scenarios'; import Scenario from './scenario/scenario'; @@ -117,7 +118,8 @@ class App extends React.Component { - + + diff --git a/src/common/table.js b/src/common/table.js index c5edd2e..dfba04f 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -291,7 +291,7 @@ class CustomTable extends Component { for (let child of props.children) { // check whether empty <> object has been given - if (Object.keys(child.props).length != 0) { + if (Object.keys(child.props).length !== 0) { row.push(CustomTable.addCell(data, index, child)); } } diff --git a/src/ic/ic-dialog.js b/src/ic/ic-dialog.js deleted file mode 100644 index 25fe61a..0000000 --- a/src/ic/ic-dialog.js +++ /dev/null @@ -1,195 +0,0 @@ -import React from 'react'; -import { Button, Row, Col } from 'react-bootstrap'; -import Dialog from '../common/dialogs/dialog'; -import Icon from "../common/icon"; -import ConfirmCommand from './confirm-command'; -import ReactJson from 'react-json-view'; -import FileSaver from 'file-saver'; -import moment from 'moment'; - -class ICDialog extends React.Component { - valid = true; - - constructor(props) { - super(props); - - this.state = { - confirmCommand: false, - command: '', - }; - } - - onClose(canceled) { - this.props.onClose(); - } - - handleChange(e) { - - } - - showFurtherInfo(key){ - if(typeof this.state[key] === 'undefined') this.setState({[key]: false}); - this.setState({[key]: !this.state[key]}); - } - - closeConfirmModal(canceled){ - if(!canceled){ - this.props.sendControlCommand(this.state.command,this.props.ic); - } - - 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"); - } - - isJSON(data){ - if (data === undefined || data === null){ - return false; - } - let str = JSON.stringify(data); - try - { - JSON.parse(str) - } - catch(ex){ - return false - } - - return true - } - - - render() { - - let graphURL = "" - if (this.props.ic.apiurl !== ""){ - graphURL = this.props.ic.apiurl + "/graph.svg" - } - - return ( - this.onClose(c)} - valid={true} - size='xl' - blendOutCancel={true} - > -
- - - - Name - {this.props.ic.name} - - - UUID - {this.props.ic.uuid} - - - State - {this.props.ic.state} - - - Category - {this.props.ic.category} - - - Type - {this.props.ic.type} - - - Uptime - {moment.duration(this.props.ic.uptime, "seconds").humanize()} - - - Location - {this.props.ic.location} - - - Description - {this.props.ic.description} - - - Websocket URL - {this.props.ic.websocketurl} - - - API URL - {this.props.ic.apiurl} - - - Start parameter schema - - - - - - - -
Raw Status:
- {this.isJSON(this.props.ic.statusupdateraw) ? - - : -
No valid JSON raw data available.
- } - - - {this.props.ic.type === "villas-node" ? - <> -
- -
-
Graph:
-
- {"Graph -
- - {this.props.user.role === "Admin" ? -
-
Controls:
-
- - -
-
- :
- } - this.closeConfirmModal(c)}/> - - :
- } - - - -
- ); - } -} - -export default ICDialog; diff --git a/src/ic/ic.js b/src/ic/ic.js new file mode 100644 index 0000000..9bb730f --- /dev/null +++ b/src/ic/ic.js @@ -0,0 +1,240 @@ +/** + * 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 InfrastructureComponentStore from './ic-store'; +import { Container as FluxContainer } from 'flux/utils'; +import AppDispatcher from '../common/app-dispatcher'; +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"; + + + +class InfrastructureComponent extends React.Component { + constructor(props) { + super(props); + + this.state = { + confirmCommand: false, + command: '', + }; + } + + static getStores() { + return [InfrastructureComponentStore]; + } + + 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)) + } + } + + componentDidMount() { + let icID = parseInt(this.props.match.params.ic, 10); + + AppDispatcher.dispatch({ + type: 'ics/start-load', + data: icID, + token: this.state.sessionToken, + }); + } + + 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" + } + + 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 + +
+ + Raw Status + {this.isJSON(this.state.ic.statusupdateraw) ? + :
No valid JSON raw data available.
} + + {this.state.ic.type === "villas-node" ? + <> +
+ +
+
+ Graph: +
+ {"Graph +
+ + {this.state.currentUser.role === "Admin" ? +
+
+ Controls: +
+ + +
+
+ :
+ } + this.confirmCommand(c)} /> + + :
} + + + + +
; + } + +} + +let fluxContainerConverter = require('../common/FluxContainerConverter'); +export default FluxContainer.create(fluxContainerConverter.convert(InfrastructureComponent), { withProps: true }); \ No newline at end of file diff --git a/src/ic/ics.js b/src/ic/ics.js index b0a5016..6ef3562 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -367,32 +367,11 @@ class InfrastructureComponents extends Component { } } - modifyNameColumn(name, component){ - let index = this.state.ics.indexOf(component); - return - } - openICStatus(ic){ let index = this.state.ics.indexOf(ic); this.setState({ icModal: true, modalIC: ic, modalIndex: index }) } - sendControlCommand(command,ic){ - if(command === "restart"){ - AppDispatcher.dispatch({ - type: 'ics/restart', - url: ic.apiurl + "/restart", - token: this.state.sessionToken, - }); - }else if(command === "shutdown"){ - AppDispatcher.dispatch({ - type: 'ics/shutdown', - url: ic.apiurl + "/shutdown", - token: this.state.sessionToken, - }); - } - } - isLocalIC(index, ics){ let ic = ics[index] return !ic.managedexternally @@ -419,7 +398,8 @@ class InfrastructureComponents extends Component { this.modifyNameColumn(name, component)} + link='/infrastructure/' + linkKey='id' /> +