1
0
Fork 0
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:
Sonja Happ 2021-05-26 14:35:40 +00:00
commit b56c94f286
6 changed files with 172 additions and 31 deletions

View 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;

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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;

View file

@ -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;