mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
Merge branch 'master' of git.rwth-aachen.de:acs/public/villas/web
This commit is contained in:
commit
ab0ed00231
9 changed files with 261 additions and 23518 deletions
23362
package-lock.json
generated
23362
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -37,7 +37,7 @@ class DeleteDialog extends React.Component {
|
|||
<Modal.Body>
|
||||
Are you sure you want to delete the {this.props.title} <strong>'{this.props.name}'</strong>?
|
||||
<Collapse isOpened={this.props.managedexternally} >
|
||||
<FormLabel size="sm">The IC will be deleted if the respective VILLAScontroller sends "gone" state and no component config is using the IC anymore</FormLabel>
|
||||
<FormLabel size="sm">The IC will be deleted if the respective manager sends "gone" state and no component config is using the IC anymore</FormLabel>
|
||||
</Collapse>
|
||||
</Modal.Body>
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ class CustomTable extends Component {
|
|||
inline
|
||||
disabled = {isDisabled}
|
||||
checked={checkboxKey ? data[checkboxKey] : null}
|
||||
onChange={e => child.props.onChecked(index, e)}
|
||||
onChange={e => child.props.onChecked(data, e)}
|
||||
/>);
|
||||
}
|
||||
|
||||
|
|
|
@ -122,8 +122,8 @@ class EditICDialog extends React.Component {
|
|||
case "simulator":
|
||||
typeOptions = ["dummy","generic","dpsim","rtlab","rscad", "opalrt"];
|
||||
break;
|
||||
case "controller":
|
||||
typeOptions = ["kubernetes","villas-controller"];
|
||||
case "manager":
|
||||
typeOptions = ["villas-node","villas-relay","generic"];
|
||||
break;
|
||||
case "gateway":
|
||||
typeOptions = ["villas-node","villas-relay"];
|
||||
|
@ -158,10 +158,10 @@ class EditICDialog extends React.Component {
|
|||
<FormLabel column={false}>Category</FormLabel>
|
||||
<FormControl as="select" value={this.state.category} onChange={(e) => this.handleChange(e)}>
|
||||
<option>simulator</option>
|
||||
<option>controller</option>
|
||||
<option>service</option>
|
||||
<option>gateway</option>
|
||||
<option>equipment</option>
|
||||
<option>manager</option>
|
||||
</FormControl>
|
||||
</FormGroup>
|
||||
<FormGroup controlId="type">
|
||||
|
|
|
@ -16,75 +16,93 @@
|
|||
******************************************************************************/
|
||||
|
||||
import React from 'react';
|
||||
import { Button, ButtonToolbar, DropdownButton, Dropdown } from 'react-bootstrap';
|
||||
import TimePicker from 'react-bootstrap-time-picker'
|
||||
import { Button, ButtonToolbar, DropdownButton, Dropdown, InputGroup, FormControl } from 'react-bootstrap';
|
||||
|
||||
class ICAction extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
selectedAction: null,
|
||||
selectedDelay: 0
|
||||
};
|
||||
let t = new Date()
|
||||
|
||||
Number.prototype.pad = function(size) {
|
||||
var s = String(this);
|
||||
while (s.length < (size || 2)) {s = "0" + s;}
|
||||
return s;
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(props, state){
|
||||
if (state.selectedAction == null) {
|
||||
if (props.actions != null && props.actions.length > 0) {
|
||||
return{
|
||||
selectedAction: props.actions[0]
|
||||
};
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
let time = new Date();
|
||||
time.setMinutes(5 * Math.round(time.getMinutes() / 5 + 1))
|
||||
|
||||
setAction = id => {
|
||||
// search action
|
||||
for (let action of this.props.actions) {
|
||||
if (action.id === id) {
|
||||
this.setState({ selectedAction: action });
|
||||
}
|
||||
}
|
||||
this.state = {
|
||||
selectedAction: null,
|
||||
time: time
|
||||
};
|
||||
}
|
||||
|
||||
setDelayForAction = time => {
|
||||
// time in int format: (hours * 3600 + minutes * 60 + seconds)
|
||||
this.setState({selectedDelay: time})
|
||||
static getDerivedStateFromProps(props, state) {
|
||||
if (state.selectedAction == null) {
|
||||
if (props.actions != null && props.actions.length > 0) {
|
||||
return {
|
||||
selectedAction: props.actions[0]
|
||||
};
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
let sendCommandDisabled = this.props.runDisabled || this.state.selectedAction == null || this.state.selectedAction.id === "-1"
|
||||
|
||||
const actionList = this.props.actions.map(action => (
|
||||
<Dropdown.Item key={action.id} eventKey={action.id} active={this.state.selectedAction === action.id}>
|
||||
{action.title}
|
||||
</Dropdown.Item>
|
||||
));
|
||||
|
||||
return <div>
|
||||
{"Select delay for command execution (Format hh:mm, max 1h):"}
|
||||
<TimePicker
|
||||
format={24}
|
||||
initialValue={this.state.selectedDelay}
|
||||
value={this.state.selectedDelay}
|
||||
start={"00:00"}
|
||||
end={"01:00"}
|
||||
step={1}
|
||||
onChange={this.setDelayForAction}
|
||||
/>
|
||||
<ButtonToolbar>
|
||||
<DropdownButton title={this.state.selectedAction != null ? this.state.selectedAction.title : ''} id="action-dropdown" onSelect={this.setAction}>
|
||||
{actionList}
|
||||
</DropdownButton>
|
||||
|
||||
<Button style={{ marginLeft: '5px' }} disabled={sendCommandDisabled} onClick={() => this.props.runAction(this.state.selectedAction, this.state.selectedDelay)}>Send command</Button>
|
||||
|
||||
</ButtonToolbar>
|
||||
</div>;
|
||||
setAction = id => {
|
||||
// search action
|
||||
for (let action of this.props.actions) {
|
||||
if (action.id === id) {
|
||||
this.setState({ selectedAction: action });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setTimeForAction = (time) => {
|
||||
this.setState({ time: new Date(time) })
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
let sendCommandDisabled = this.props.runDisabled || this.state.selectedAction == null || this.state.selectedAction.id === "-1"
|
||||
|
||||
let time = this.state.time.getFullYear().pad(4) + '-' +
|
||||
this.state.time.getMonth().pad(2) + '-' +
|
||||
this.state.time.getDay().pad(2) + 'T' +
|
||||
this.state.time.getHours().pad(2) + ':' +
|
||||
this.state.time.getMinutes().pad(2);
|
||||
|
||||
const actionList = this.props.actions.map(action => (
|
||||
<Dropdown.Item key={action.id} eventKey={action.id} active={this.state.selectedAction === action.id}>
|
||||
{action.title}
|
||||
</Dropdown.Item>
|
||||
));
|
||||
|
||||
return <div>
|
||||
<InputGroup>
|
||||
<InputGroup.Prepend>
|
||||
<DropdownButton
|
||||
variant="outline-secondary"
|
||||
title={this.state.selectedAction != null ? this.state.selectedAction.title : ''}
|
||||
id="action-dropdown"
|
||||
onSelect={this.setAction}>
|
||||
{actionList}
|
||||
</DropdownButton>
|
||||
<FormControl
|
||||
type="datetime-local"
|
||||
variant="outline-secondary"
|
||||
value={time}
|
||||
onChange={this.setTimeForAction} />
|
||||
</InputGroup.Prepend>
|
||||
<Button
|
||||
variant="outline-secondary"
|
||||
disabled={sendCommandDisabled}
|
||||
onClick={() => this.props.runAction(this.state.selectedAction, this.state.time)}>Run</Button>
|
||||
</InputGroup>
|
||||
<small className="text-muted">Select time for synced command execution</small>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
export default ICAction;
|
||||
|
|
|
@ -24,8 +24,14 @@ class IcsDataManager extends RestDataManager {
|
|||
super('ic', '/ic');
|
||||
}
|
||||
|
||||
doActions(ic, action, token = null) {
|
||||
RestAPI.post(this.makeURL(this.url + '/' + ic.id + '/action'), action, token).then(response => {
|
||||
doActions(ic, actions, token = null) {
|
||||
for (let action of actions) {
|
||||
if (action.when)
|
||||
// Send timestamp as Unix Timestamp
|
||||
action.when = Math.round(action.when.getTime() / 1000);
|
||||
}
|
||||
|
||||
RestAPI.post(this.makeURL(this.url + '/' + ic.id + '/action'), actions, token).then(response => {
|
||||
AppDispatcher.dispatch({
|
||||
type: 'ics/action-started',
|
||||
data: response
|
||||
|
|
173
src/ic/ics.js
173
src/ic/ics.js
|
@ -75,17 +75,26 @@ class InfrastructureComponents extends Component {
|
|||
}
|
||||
});
|
||||
|
||||
let externalICs = ics.find(ic => ic.managedexternally === true)
|
||||
// collect number of external ICs
|
||||
let externalICs = ics.filter(ic => ic.managedexternally === true)
|
||||
let numberOfExternalICs = externalICs.length;
|
||||
|
||||
// collect all IC categories
|
||||
let managers = ics.filter(ic => ic.category === "manager")
|
||||
let gateways = ics.filter(ic => ic.category === "gateway")
|
||||
let simulators = ics.filter(ic => ic.category === "simulator")
|
||||
let services = ics.filter(ic => ic.category === "service")
|
||||
let equipment = ics.filter(ic => ic.category === "equipment")
|
||||
|
||||
let numberOfExternalICs = 0
|
||||
if (externalICs !== undefined && !Array.isArray(externalICs)) {
|
||||
externalICs = [externalICs];
|
||||
numberOfExternalICs = externalICs.length;
|
||||
}
|
||||
|
||||
return {
|
||||
sessionToken: localStorage.getItem("token"),
|
||||
ics: ics,
|
||||
managers: managers,
|
||||
gateways: gateways,
|
||||
simulators: simulators,
|
||||
services: services,
|
||||
equipment: equipment,
|
||||
numberOfExternalICs,
|
||||
modalIC: {},
|
||||
deleteModal: false,
|
||||
|
@ -136,7 +145,6 @@ class InfrastructureComponents extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
closeNewModal(data) {
|
||||
this.setState({ newModal : false });
|
||||
|
||||
|
@ -205,7 +213,9 @@ class InfrastructureComponents extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
onICChecked(index, event) {
|
||||
onICChecked(ic, event) {
|
||||
|
||||
let index = this.state.ics.indexOf(ic);
|
||||
const selectedICs = Object.assign([], this.state.selectedICs);
|
||||
for (let key in selectedICs) {
|
||||
if (selectedICs[key] === index) {
|
||||
|
@ -230,8 +240,10 @@ class InfrastructureComponents extends Component {
|
|||
this.setState({ selectedICs: selectedICs });
|
||||
}
|
||||
|
||||
runAction(action) {
|
||||
runAction(action, when) {
|
||||
for (let index of this.state.selectedICs) {
|
||||
action.when = when;
|
||||
|
||||
AppDispatcher.dispatch({
|
||||
type: 'ics/start-action',
|
||||
ic: this.state.ics[index],
|
||||
|
@ -251,7 +263,6 @@ class InfrastructureComponents extends Component {
|
|||
}
|
||||
|
||||
stateLabelStyle(state, component){
|
||||
|
||||
var style = [ 'badge' ];
|
||||
|
||||
if (InfrastructureComponents.isICOutdated(component) && state !== 'shutdown') {
|
||||
|
@ -296,7 +307,6 @@ class InfrastructureComponents extends Component {
|
|||
default:
|
||||
style.push('badge-default');
|
||||
|
||||
|
||||
/* Possible states of ICs
|
||||
* 'error': ['resetting', 'error'],
|
||||
'idle': ['resetting', 'error', 'idle', 'starting', 'shuttingdown'],
|
||||
|
@ -322,13 +332,11 @@ class InfrastructureComponents extends Component {
|
|||
}
|
||||
|
||||
modifyManagedExternallyColumn(managedExternally, component){
|
||||
|
||||
if(managedExternally){
|
||||
return <Icon icon='check' />
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
modifyUptimeColumn(uptime, component){
|
||||
|
@ -336,7 +344,7 @@ class InfrastructureComponents extends Component {
|
|||
let momentDurationFormatSetup = require("moment-duration-format");
|
||||
momentDurationFormatSetup(moment)
|
||||
|
||||
let timeString = moment.duration(uptime, "seconds").format();
|
||||
let timeString = moment.duration(uptime, "seconds").humanize();
|
||||
return <span>{timeString}</span>
|
||||
}
|
||||
else{
|
||||
|
@ -355,7 +363,6 @@ class InfrastructureComponents extends Component {
|
|||
}
|
||||
|
||||
sendControlCommand(command,ic){
|
||||
|
||||
if(command === "restart"){
|
||||
AppDispatcher.dispatch({
|
||||
type: 'ics/restart',
|
||||
|
@ -369,7 +376,6 @@ class InfrastructureComponents extends Component {
|
|||
token: this.state.sessionToken,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
isExternalIC(index){
|
||||
|
@ -377,12 +383,80 @@ class InfrastructureComponents extends Component {
|
|||
return ic.managedexternally
|
||||
}
|
||||
|
||||
getICCategoryTable(ics, editable, title){
|
||||
if (ics && ics.length > 0) {
|
||||
return (<div>
|
||||
<h2>{title}</h2>
|
||||
<Table data={ics}>
|
||||
<TableColumn
|
||||
checkbox
|
||||
checkboxDisabled={(index) => this.isExternalIC(index)}
|
||||
onChecked={(ic, event) => this.onICChecked(ic, event)}
|
||||
width='30'
|
||||
/>
|
||||
<TableColumn
|
||||
title='Name'
|
||||
dataKeys={['name']}
|
||||
modifier={(name, component) => this.modifyNameColumn(name, component)}
|
||||
/>
|
||||
<TableColumn
|
||||
title='State'
|
||||
labelKey='state'
|
||||
tooltipKey='error'
|
||||
labelStyle={(state, component) => this.stateLabelStyle(state, component)}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Type'
|
||||
dataKeys={['type']}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Uptime'
|
||||
dataKey='uptime'
|
||||
modifier={(uptime, component) => this.modifyUptimeColumn(uptime, component)}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Last Update'
|
||||
dataKey='stateUpdateAt'
|
||||
modifier={(stateUpdateAt, component) => this.stateUpdateModifier(stateUpdateAt, component)}
|
||||
/>
|
||||
|
||||
{this.state.currentUser.role === "Admin" && editable ?
|
||||
<TableColumn
|
||||
width='200'
|
||||
editButton
|
||||
exportButton
|
||||
deleteButton
|
||||
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})}
|
||||
/>
|
||||
:
|
||||
<TableColumn
|
||||
width='100'
|
||||
exportButton
|
||||
onExport={index => this.exportIC(index)}
|
||||
/>
|
||||
}
|
||||
</Table>
|
||||
</div>);
|
||||
} else {
|
||||
return <div/>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const buttonStyle = {
|
||||
marginLeft: '10px'
|
||||
};
|
||||
|
||||
let managerTable = this.getICCategoryTable(this.state.managers, false, "IC Managers")
|
||||
let simulatorTable = this.getICCategoryTable(this.state.simulators, true, "Simulators")
|
||||
let gatewayTable = this.getICCategoryTable(this.state.gateways, true, "Gateways")
|
||||
let serviceTable = this.getICCategoryTable(this.state.services, true, "Services")
|
||||
let equipmentTable = this.getICCategoryTable(this.state.equipment, true, "Equipment")
|
||||
|
||||
return (
|
||||
<div className='section'>
|
||||
<h1>Infrastructure Components
|
||||
|
@ -407,69 +481,20 @@ class InfrastructureComponents extends Component {
|
|||
(<span> </span>)
|
||||
}
|
||||
</h1>
|
||||
<Table data={this.state.ics}>
|
||||
<TableColumn
|
||||
checkbox
|
||||
checkboxDisabled={(index) => this.isExternalIC(index)}
|
||||
onChecked={(index, event) => this.onICChecked(index, event)}
|
||||
width='30'
|
||||
/>
|
||||
<TableColumn
|
||||
title='Name'
|
||||
dataKeys={['name']}
|
||||
modifier={(name, component) => this.modifyNameColumn(name, component)}
|
||||
/>
|
||||
<TableColumn
|
||||
title='State'
|
||||
labelKey='state'
|
||||
tooltipKey='error'
|
||||
labelStyle={(state, component) => this.stateLabelStyle(state, component)}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Category'
|
||||
dataKeys={['category']}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Type'
|
||||
dataKeys={['type']}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Uptime'
|
||||
dataKey='uptime'
|
||||
modifier={(uptime, component) => this.modifyUptimeColumn(uptime, component)}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Last Update'
|
||||
dataKey='stateUpdateAt'
|
||||
modifier={(stateUpdateAt, component) => this.stateUpdateModifier(stateUpdateAt, component)}
|
||||
/>
|
||||
|
||||
{this.state.currentUser.role === "Admin" ?
|
||||
<TableColumn
|
||||
width='200'
|
||||
editButton
|
||||
exportButton
|
||||
deleteButton
|
||||
onEdit={index => this.setState({editModal: true, modalIC: this.state.ics[index], modalIndex: index})}
|
||||
onExport={index => this.exportIC(index)}
|
||||
onDelete={index => this.setState({deleteModal: true, modalIC: this.state.ics[index], modalIndex: index})}
|
||||
/>
|
||||
:
|
||||
<TableColumn
|
||||
width='100'
|
||||
exportButton
|
||||
onExport={index => this.exportIC(index)}
|
||||
/>
|
||||
}
|
||||
</Table>
|
||||
{managerTable}
|
||||
{simulatorTable}
|
||||
{gatewayTable}
|
||||
{serviceTable}
|
||||
{equipmentTable}
|
||||
|
||||
{this.state.currentUser.role === "Admin" && this.state.numberOfExternalICs > 0 ?
|
||||
<div style={{float: 'left'}}>
|
||||
<ICAction
|
||||
runDisabled={this.state.selectedICs.length === 0}
|
||||
runAction={action => this.runAction(action)}
|
||||
runAction={(action, when) => this.runAction(action, when)}
|
||||
actions={[
|
||||
{id: '-1', title: 'Select command', data: {action: 'none'}},
|
||||
{id: '-1', title: 'Action', data: {action: 'none'}},
|
||||
{id: '0', title: 'Reset', data: {action: 'reset'}},
|
||||
{id: '1', title: 'Shutdown', data: {action: 'shutdown'}},
|
||||
]}
|
||||
|
@ -481,9 +506,10 @@ class InfrastructureComponents extends Component {
|
|||
|
||||
<div style={{ clear: 'both' }} />
|
||||
|
||||
<NewICDialog show={this.state.newModal} onClose={data => this.closeNewModal(data)} />
|
||||
<NewICDialog show={this.state.newModal} onClose={data => this.closeNewModal(data)} managers={this.state.managers} />
|
||||
<EditICDialog show={this.state.editModal} onClose={data => this.closeEditModal(data)} ic={this.state.modalIC} />
|
||||
<ImportICDialog show={this.state.importModal} onClose={data => this.closeImportModal(data)} />
|
||||
<DeleteDialog title="infrastructure-component" name={this.state.modalIC.name || 'Unknown'} show={this.state.deleteModal} onClose={(e) => this.closeDeleteModal(e)} />
|
||||
<ICDialog
|
||||
show={this.state.icModal}
|
||||
onClose={data => this.closeICModal(data)}
|
||||
|
@ -492,7 +518,6 @@ class InfrastructureComponents extends Component {
|
|||
userRole={this.state.currentUser.role}
|
||||
sendControlCommand={(command, ic) => this.sendControlCommand(command, ic)}/>
|
||||
|
||||
<DeleteDialog title="infrastructure-component" name={this.state.modalIC.name || 'Unknown'} show={this.state.deleteModal} onClose={(e) => this.closeDeleteModal(e)} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@ class NewICDialog extends React.Component {
|
|||
category: '',
|
||||
managedexternally: false,
|
||||
description: '',
|
||||
location: ''
|
||||
location: '',
|
||||
manager: ''
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -48,7 +49,8 @@ class NewICDialog extends React.Component {
|
|||
uuid: this.state.uuid,
|
||||
managedexternally: this.state.managedexternally,
|
||||
location: this.state.location,
|
||||
description: this.state.description
|
||||
description: this.state.description,
|
||||
manager: this.state.manager
|
||||
};
|
||||
|
||||
if (this.state.websocketurl != null && this.state.websocketurl !== "" && this.state.websocketurl !== 'http://') {
|
||||
|
@ -88,6 +90,7 @@ class NewICDialog extends React.Component {
|
|||
let websocketurl = true;
|
||||
let type = true;
|
||||
let category = true;
|
||||
let manager = true;
|
||||
|
||||
if (this.state.name === '') {
|
||||
name = false;
|
||||
|
@ -97,6 +100,10 @@ class NewICDialog extends React.Component {
|
|||
uuid = false;
|
||||
}
|
||||
|
||||
if(this.state.managedexternally && manager === ''){
|
||||
manager = false;
|
||||
}
|
||||
|
||||
if (this.state.type === '') {
|
||||
type = false;
|
||||
}
|
||||
|
@ -105,7 +112,7 @@ class NewICDialog extends React.Component {
|
|||
category = false;
|
||||
}
|
||||
|
||||
this.valid = name && uuid && websocketurl && type && category;
|
||||
this.valid = name && uuid && websocketurl && type && category && manager;
|
||||
|
||||
// return state to control
|
||||
if (target === 'name') return name ? "success" : "error";
|
||||
|
@ -113,6 +120,7 @@ class NewICDialog extends React.Component {
|
|||
if (target === 'websocketurl') return websocketurl ? "success" : "error";
|
||||
if (target === 'type') return type ? "success" : "error";
|
||||
if (target === 'category') return category ? "success" : "error";
|
||||
if (target === 'manager') return manager ? "success" : "error";
|
||||
|
||||
return this.valid;
|
||||
}
|
||||
|
@ -131,8 +139,8 @@ class NewICDialog extends React.Component {
|
|||
case "simulator":
|
||||
typeOptions = ["dummy","generic","dpsim","rtlab","rscad","opalrt"];
|
||||
break;
|
||||
case "controller":
|
||||
typeOptions = ["kubernetes","villas-controller"];
|
||||
case "manager":
|
||||
typeOptions = ["villas-node","villas-relay","generic"];
|
||||
break;
|
||||
case "gateway":
|
||||
typeOptions = ["villas-node","villas-relay"];
|
||||
|
@ -146,33 +154,60 @@ class NewICDialog extends React.Component {
|
|||
default:
|
||||
typeOptions =[];
|
||||
}
|
||||
|
||||
let managerOptions = [];
|
||||
managerOptions.push(<option default>Select manager</option>);
|
||||
for (let m of this.props.managers) {
|
||||
managerOptions.push (
|
||||
<option key={m.id} value={m.uuid}>{m.name}</option>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<Dialog show={this.props.show} title="New Infrastructure Component" buttonTitle="Add" onClose={(c) => this.onClose(c)} onReset={() => this.resetState()} valid={this.validateForm()}>
|
||||
<form>
|
||||
<FormGroup controlId="managedexternally">
|
||||
<OverlayTrigger key="3" placement={'left'} overlay={<Tooltip id={`tooltip-${"me"}`}>An externally managed component will show up in the list only after a VILLAScontroller for the component type has created the component and cannot be edited by users</Tooltip>} >
|
||||
<FormCheck type={"checkbox"} label={"Managed externally"} defaultChecked={this.state.managedexternally} onChange={e => this.handleChange(e)}>
|
||||
</FormCheck>
|
||||
</OverlayTrigger>
|
||||
</FormGroup>
|
||||
{this.props.managers.length > 0 ?
|
||||
<>
|
||||
<FormGroup controlId="managedexternally">
|
||||
<OverlayTrigger key="3" placement={'left'} overlay={<Tooltip id={`tooltip-${"me"}`}>An externally managed component is created and managed by an IC manager via AMQP</Tooltip>} >
|
||||
<FormCheck type={"checkbox"} label={"Managed externally"} defaultChecked={this.state.managedexternally} onChange={e => this.handleChange(e)}>
|
||||
</FormCheck>
|
||||
</OverlayTrigger>
|
||||
</FormGroup>
|
||||
{this.state.managedexternally === true ?
|
||||
<FormGroup controlId="manager" valid={this.validateForm('manager')}>
|
||||
<OverlayTrigger key="0" placement={'right'} overlay={<Tooltip id={`tooltip-${"required"}`}> Required field </Tooltip>} >
|
||||
<FormLabel>Manager to create new IC *</FormLabel>
|
||||
</OverlayTrigger>
|
||||
<FormControl as="select" value={this.state.manager} onChange={(e) => this.handleChange(e)}>
|
||||
{managerOptions}
|
||||
</FormControl>
|
||||
</FormGroup>
|
||||
: <div/>
|
||||
|
||||
}
|
||||
</>
|
||||
: <div/>
|
||||
}
|
||||
<FormGroup controlId="name" valid={this.validateForm('name')}>
|
||||
<OverlayTrigger key="0" placement={'right'} overlay={<Tooltip id={`tooltip-${"required"}`}> Required field </Tooltip>} >
|
||||
<OverlayTrigger key="1" placement={'right'} overlay={<Tooltip id={`tooltip-${"required"}`}> Required field </Tooltip>} >
|
||||
<FormLabel>Name *</FormLabel>
|
||||
</OverlayTrigger>
|
||||
<FormControl type="text" placeholder="Enter name" value={this.state.name} onChange={(e) => this.handleChange(e)} />
|
||||
<FormControl.Feedback />
|
||||
</FormGroup>
|
||||
<FormGroup controlId="category" valid={this.validateForm('category')}>
|
||||
<OverlayTrigger key="1" placement={'right'} overlay={<Tooltip id={`tooltip-${"required"}`}> Required field </Tooltip>} >
|
||||
<OverlayTrigger key="2" placement={'right'} overlay={<Tooltip id={`tooltip-${"required"}`}> Required field </Tooltip>} >
|
||||
<FormLabel>Category of component *</FormLabel>
|
||||
</OverlayTrigger>
|
||||
<FormControl as="select" value={this.state.category} onChange={(e) => this.handleChange(e)}>
|
||||
<option default>Select category</option>
|
||||
<option>simulator</option>
|
||||
<option>controller</option>
|
||||
<option>service</option>
|
||||
<option>gateway</option>
|
||||
<option>equipment</option>
|
||||
<option>manager</option>
|
||||
</FormControl>
|
||||
</FormGroup>
|
||||
<FormGroup controlId="type" valid={this.validateForm('type')}>
|
||||
|
@ -206,11 +241,15 @@ class NewICDialog extends React.Component {
|
|||
<FormControl type="text" placeholder="Enter Description" value={this.state.description} onChange={(e) => this.handleChange(e)} />
|
||||
<FormControl.Feedback />
|
||||
</FormGroup>
|
||||
<FormGroup controlId="uuid" valid={this.validateForm('uuid')}>
|
||||
<FormLabel>UUID</FormLabel>
|
||||
<FormControl type="text" placeholder="Enter uuid" value={this.state.uuid} onChange={(e) => this.handleChange(e)} />
|
||||
<FormControl.Feedback />
|
||||
</FormGroup>
|
||||
{this.state.managedexternally === false ?
|
||||
<FormGroup controlId="uuid" valid={this.validateForm('uuid')}>
|
||||
<FormLabel>UUID</FormLabel>
|
||||
<FormControl type="text" placeholder="Enter uuid" value={this.state.uuid}
|
||||
onChange={(e) => this.handleChange(e)}/>
|
||||
<FormControl.Feedback/>
|
||||
</FormGroup>
|
||||
: <div/>
|
||||
}
|
||||
</form>
|
||||
</Dialog>
|
||||
);
|
||||
|
|
|
@ -390,9 +390,7 @@ class Scenario extends React.Component {
|
|||
|
||||
}
|
||||
|
||||
runAction(action, delay) {
|
||||
// delay in seconds
|
||||
|
||||
runAction(action, when) {
|
||||
if (action.data.action === 'none') {
|
||||
console.warn("No command selected. Nothing was sent.");
|
||||
return;
|
||||
|
@ -415,8 +413,7 @@ class Scenario extends React.Component {
|
|||
action.data.parameters = this.state.configs[index].startParameters;
|
||||
}
|
||||
|
||||
// Unix time stamp + delay
|
||||
action.data.when = Math.round(Date.now() / 1000.0 + delay)
|
||||
action.data.when = when;
|
||||
|
||||
console.log("Sending action: ", action.data)
|
||||
|
||||
|
@ -798,8 +795,6 @@ class Scenario extends React.Component {
|
|||
scenarioID={this.state.scenario.id}
|
||||
/>
|
||||
|
||||
|
||||
|
||||
{/*Component Configurations table*/}
|
||||
<h2 style={tableHeadingStyle}>Component Configurations
|
||||
<OverlayTrigger
|
||||
|
@ -866,9 +861,9 @@ class Scenario extends React.Component {
|
|||
<div style={{float: 'left'}}>
|
||||
<ICAction
|
||||
runDisabled={this.state.selectedConfigs.length === 0}
|
||||
runAction={(action, delay) => this.runAction(action, delay)}
|
||||
runAction={(action, when) => this.runAction(action, when)}
|
||||
actions={[
|
||||
{id: '-1', title: 'Select command', data: {action: 'none'}},
|
||||
{id: '-1', title: 'Action', data: {action: 'none'}},
|
||||
{id: '0', title: 'Start', data: {action: 'start'}},
|
||||
{id: '1', title: 'Stop', data: {action: 'stop'}},
|
||||
{id: '2', title: 'Pause', data: {action: 'pause'}},
|
||||
|
|
Loading…
Add table
Reference in a new issue