mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
Merge branch 'ic-page-customization' into 'master'
Add IC page customization for Manager ICs (duplicate) See merge request acs/public/villas/web!86
This commit is contained in:
commit
b56c94f286
6 changed files with 172 additions and 31 deletions
105
src/ic/ic-pages/default-manager-page.js
Normal file
105
src/ic/ic-pages/default-manager-page.js
Normal file
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
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';
|
||||
import { stateLabelStyle } from "../ics";
|
||||
import { refresh, ICParamsTable } from "../ic"
|
||||
|
||||
class DefaultManagerPage extends React.Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
managedICs: [],
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (<div className='section'>
|
||||
|
||||
|
||||
<h1>{this.props.ic.name}
|
||||
<span className='icon-button'>
|
||||
|
||||
<IconButton
|
||||
childKey={2}
|
||||
tooltip='Refresh'
|
||||
onClick={() => refresh(this.props.ic, this.props.sessionToken)}
|
||||
icon='sync-alt'
|
||||
buttonStyle={this.props.buttonStyle}
|
||||
iconStyle={this.props.iconStyle}
|
||||
/>
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
{ICParamsTable(this.props.ic)}
|
||||
</Col>
|
||||
<Col>
|
||||
<h3>Managed ICs:</h3>
|
||||
<Table data={this.state.managedICs}>
|
||||
{this.props.currentUser.role === "Admin" ?
|
||||
<TableColumn
|
||||
title='ID'
|
||||
dataKey='id'
|
||||
/>
|
||||
: <></>
|
||||
}
|
||||
<TableColumn
|
||||
title='Name'
|
||||
dataKeys={['name']}
|
||||
link='/infrastructure/'
|
||||
linkKey='id'
|
||||
/>
|
||||
<TableColumn
|
||||
title='State'
|
||||
labelKey='state'
|
||||
tooltipKey='error'
|
||||
labelStyle={(state, component) => stateLabelStyle(state, component)}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Type'
|
||||
dataKeys={['type']}
|
||||
/>
|
||||
</Table>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default DefaultManagerPage;
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
import React from 'react';
|
||||
import {Col, Container, Row} from "react-bootstrap";
|
||||
import IconButton from "../../common/icon-button";
|
||||
import {refresh, ICParamsTable } from "../ic"
|
||||
|
||||
class DefaultICPage extends React.Component {
|
||||
|
||||
|
@ -26,11 +28,23 @@ class DefaultICPage extends React.Component {
|
|||
|
||||
render() {
|
||||
return (<div className='section'>
|
||||
<h1>{this.props.ic.name} </h1>
|
||||
<h1>{this.props.ic.name}
|
||||
<span className='icon-button'>
|
||||
|
||||
<IconButton
|
||||
childKey={1}
|
||||
tooltip='Refresh'
|
||||
onClick={() => refresh(this.props.ic, this.props.sessionToken)}
|
||||
icon='sync-alt'
|
||||
buttonStyle={this.props.buttonStyle}
|
||||
iconStyle={this.props.iconStyle}
|
||||
/>
|
||||
</span>
|
||||
</h1>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
{this.props.ICParamsTable(this.props.ic)}
|
||||
{ICParamsTable(this.props.ic)}
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
|
|
|
@ -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 {
|
|||
<IconButton
|
||||
childKey={2}
|
||||
tooltip='Refresh'
|
||||
onClick={() => 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 {
|
|||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
{this.props.ICParamsTable(this.props.ic)}
|
||||
{ICParamsTable(this.props.ic)}
|
||||
</Col>
|
||||
<Col>
|
||||
<div className='section-buttons-group-right'>
|
||||
|
@ -142,15 +143,15 @@ class GatewayVillasNode extends React.Component {
|
|||
<Row>
|
||||
<Col>
|
||||
<b>Raw Status</b>
|
||||
{this.props.rawDataTable(this.props.ic.statusupdateraw)}
|
||||
{rawDataTable(this.props.ic.statusupdateraw)}
|
||||
</Col>
|
||||
<Col>
|
||||
<b>Raw Config</b>
|
||||
{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 )}
|
||||
</Col>
|
||||
<Col>
|
||||
<b>Raw Statistics</b>
|
||||
{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)}
|
||||
</Col>
|
||||
<Col>
|
||||
|
||||
|
|
|
@ -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 {
|
|||
<IconButton
|
||||
childKey={2}
|
||||
tooltip='Refresh'
|
||||
onClick={() => 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 {
|
|||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
{this.props.ICParamsTable(this.props.ic)}
|
||||
{ICParamsTable(this.props.ic)}
|
||||
</Col>
|
||||
<Col>
|
||||
<b>Raw Status</b>
|
||||
{this.props.rawDataTable(this.props.ic.statusupdateraw)}
|
||||
{rawDataTable(this.props.ic.statusupdateraw)}
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
|
|
38
src/ic/ic.js
38
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<P>, prevState: Readonly<S>, 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) {
|
||||
AppDispatcher.dispatch({
|
||||
type: 'ics/start-load',
|
||||
|
@ -142,34 +154,39 @@ 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 = <GatewayVillasNode
|
||||
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}
|
||||
/>
|
||||
} else if (this.state.ic.category ==="manager" && this.state.ic.type === "villas-relay") {
|
||||
page = <ManagerVillasRelay
|
||||
ic = {this.state.ic}
|
||||
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 {
|
||||
}else if (this.state.ic.category ==="manager") {
|
||||
page = <DefaultManagerPage
|
||||
ic = {this.state.ic}
|
||||
ics = {this.state.ics}
|
||||
currentUser = {this.state.currentUser}
|
||||
sessionToken = {this.state.sessionToken}
|
||||
buttonStyle = {buttonStyle}
|
||||
iconStyle = {iconStyle}
|
||||
/>
|
||||
}else {
|
||||
page = <DefaultICPage
|
||||
ic = {this.state.ic}
|
||||
ICParamsTable = {(ic) => InfrastructureComponent.ICParamsTable(ic)}
|
||||
sessionToken = {this.state.sessionToken}
|
||||
buttonStyle = {buttonStyle}
|
||||
iconStyle = {iconStyle}
|
||||
/>
|
||||
}
|
||||
return page
|
||||
|
@ -178,3 +195,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;
|
||||
|
|
|
@ -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';
|
||||
|
@ -257,8 +256,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');
|
||||
|
@ -320,13 +319,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)
|
||||
|
@ -339,7 +338,7 @@ class InfrastructureComponents extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
isLocalIC(index, ics){
|
||||
static isLocalIC(index, ics){
|
||||
let ic = ics[index]
|
||||
return !ic.managedexternally
|
||||
}
|
||||
|
@ -351,7 +350,7 @@ class InfrastructureComponents extends Component {
|
|||
<Table data={ics}>
|
||||
<TableColumn
|
||||
checkbox
|
||||
checkboxDisabled={(index) => this.isLocalIC(index, ics) === true}
|
||||
checkboxDisabled={(index) => InfrastructureComponents.isLocalIC(index, ics) === true}
|
||||
onChecked={(ic, event) => this.onICChecked(ic, event)}
|
||||
width='30'
|
||||
/>
|
||||
|
@ -372,7 +371,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)}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Type'
|
||||
|
@ -381,12 +380,12 @@ class InfrastructureComponents extends Component {
|
|||
<TableColumn
|
||||
title='Uptime'
|
||||
dataKey='uptime'
|
||||
modifier={(uptime, component) => this.modifyUptimeColumn(uptime, component)}
|
||||
modifier={(uptime, component) => InfrastructureComponents.modifyUptimeColumn(uptime, component)}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Last Update'
|
||||
dataKey='stateUpdateAt'
|
||||
modifier={(stateUpdateAt, component) => this.stateUpdateModifier(stateUpdateAt, component)}
|
||||
modifier={(stateUpdateAt, component) => InfrastructureComponents.stateUpdateModifier(stateUpdateAt, component)}
|
||||
/>
|
||||
|
||||
{this.state.currentUser.role === "Admin" ?
|
||||
|
@ -394,10 +393,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})}
|
||||
|
@ -495,3 +494,4 @@ class InfrastructureComponents extends Component {
|
|||
|
||||
let fluxContainerConverter = require('../common/FluxContainerConverter');
|
||||
export default Container.create(fluxContainerConverter.convert(InfrastructureComponents));
|
||||
export const stateLabelStyle = InfrastructureComponents.stateLabelStyle;
|
||||
|
|
Loading…
Add table
Reference in a new issue