From 4adc277eb319e52cae790628462cb2cd800560b1 Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Mon, 28 Dec 2020 14:27:34 +0100 Subject: [PATCH 01/25] WIP: change button color scheme #276 --- src/common/dialogs/dialog.js | 10 ++++-- src/dashboard/dashboard-button-group.js | 6 ++-- src/dashboard/dashboard.js | 2 +- src/ic/ic-action.js | 2 +- src/ic/ics.js | 4 ++- src/scenario/scenario.js | 15 +++++++-- src/scenario/scenarios.js | 4 ++- src/user/login-form.js | 2 +- src/user/user.js | 45 +++++++++++++------------ src/user/users.js | 2 +- src/widget/toolbox-item.js | 2 +- src/widget/widget-toolbox.js | 32 +++++++++++++----- 12 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/common/dialogs/dialog.js b/src/common/dialogs/dialog.js index 4cc15af..741ecaf 100644 --- a/src/common/dialogs/dialog.js +++ b/src/common/dialogs/dialog.js @@ -45,6 +45,12 @@ class Dialog extends React.Component { } render() { + const buttonStyle = { + backgroundColor: '#527984', + borderColor: '#527984' + }; + + return ( @@ -56,8 +62,8 @@ class Dialog extends React.Component { - {this.props.blendOutCancel?
: } - + {this.props.blendOutCancel?
: } +
); diff --git a/src/dashboard/dashboard-button-group.js b/src/dashboard/dashboard-button-group.js index 7f49292..9f3e1a0 100644 --- a/src/dashboard/dashboard-button-group.js +++ b/src/dashboard/dashboard-button-group.js @@ -25,11 +25,13 @@ class DashboardButtonGroup extends React.Component { const buttonStyle = { marginLeft: '12px', height: '44px', - width : '35px' + width : '35px', + borderColor: '#ffffff', + backgroundColor: '#ffffff' }; const iconStyle = { - color: '#007bff', + color: '#527984', height: '25px', width : '25px' } diff --git a/src/dashboard/dashboard.js b/src/dashboard/dashboard.js index 19bfd36..9f94192 100644 --- a/src/dashboard/dashboard.js +++ b/src/dashboard/dashboard.js @@ -478,7 +478,7 @@ class Dashboard extends Component { return
- {this.state.dashboard.name} +

{this.state.dashboard.name}

- +
; diff --git a/src/ic/ics.js b/src/ic/ics.js index 0d43077..2bf666f 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -328,7 +328,9 @@ class InfrastructureComponents extends Component { render() { const buttonStyle = { - marginLeft: '10px' + marginLeft: '10px', + backgroundColor: '#527984', + borderColor: '#527984' }; return ( diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index c19cfaa..3e6bf83 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -596,15 +596,23 @@ class Scenario extends React.Component { } const buttonStyle = { - marginLeft: '10px' + marginLeft: '10px', + backgroundColor: '#527984', + borderColor: '#527984' }; + const altButtonStyle = { + marginLeft: '10px', + backgroundColor: '#ffffff', + borderColor: 'ffffff' + } + const tableHeadingStyle = { paddingTop: '30px' } const iconStyle = { - color: '#007bff', + color: '#527984', height: '25px', width: '25px' } @@ -616,7 +624,7 @@ class Scenario extends React.Component { return
Add, edit or delete files of scenario } > - @@ -785,6 +793,7 @@ class Scenario extends React.Component { diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index d176d0f..64ad762 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -236,7 +236,9 @@ class Scenarios extends Component { render() { const buttonStyle = { - marginLeft: '10px' + marginLeft: '10px', + backgroundColor: '#527984', + borderColor: '#527984' }; return ( diff --git a/src/user/login-form.js b/src/user/login-form.js index 1c2fc5e..a270977 100644 --- a/src/user/login-form.js +++ b/src/user/login-form.js @@ -91,7 +91,7 @@ class LoginForm extends Component { - + diff --git a/src/user/user.js b/src/user/user.js index 850b663..974f7f2 100644 --- a/src/user/user.js +++ b/src/user/user.js @@ -17,7 +17,7 @@ import React, { Component } from 'react'; import { Container } from 'flux/utils'; -import {Button, Col, Row} from 'react-bootstrap'; +import {Button, Col, Row, FormGroup, FormLabel} from 'react-bootstrap'; import AppDispatcher from '../common/app-dispatcher'; import UsersStore from './users-store'; @@ -121,6 +121,16 @@ class User extends Component { render() { + const iconStyle = { + color: '#527984', + } + + const buttonStyle = { + margin: '10px', + borderColor: '#ffffff', + backgroundColor: '#ffffff' + } + return (

Your User Account

@@ -128,27 +138,23 @@ class User extends Component { {this.state.currentUser !== undefined && this.state.currentUser !== null ?
+ - Username: - {this.state.currentUser.username} + +
Username:
+
E-mail:
+
Role:
+
+ +
{this.state.currentUser.username}
+
{this.state.currentUser.mail}
+
{this.state.currentUser.role}
+ +
- - - E-mail: - {this.state.currentUser.mail} - - - - Role: - {this.state.currentUser.role} - - - - - this.closeEditModal(data)} - user={this.state.currentUser}/> + user={this.state.currentUser} /> : "Loading user data..." } @@ -157,8 +163,5 @@ class User extends Component { } } - - - let fluxContainerConverter = require('../common/FluxContainerConverter'); export default Container.create(fluxContainerConverter.convert(User)); diff --git a/src/user/users.js b/src/user/users.js index f6f03df..acde3bf 100644 --- a/src/user/users.js +++ b/src/user/users.js @@ -146,7 +146,7 @@ class Users extends Component { this.setState({ editModal: true, modalData: this.state.users[index] })} onDelete={index => this.setState({ deleteModal: true, modalData: this.state.users[index] })} /> - + this.closeNewModal(data)} /> this.closeEditModal(data)} user={this.state.modalData} /> diff --git a/src/widget/toolbox-item.js b/src/widget/toolbox-item.js index f1ebb93..e2aa402 100644 --- a/src/widget/toolbox-item.js +++ b/src/widget/toolbox-item.js @@ -51,7 +51,7 @@ class ToolboxItem extends React.Component { if (this.props.disabled === false) { return this.props.connectDragSource(
- + {this.props.icon && } {this.props.name} diff --git a/src/widget/widget-toolbox.js b/src/widget/widget-toolbox.js index 9b057ec..a2d231a 100644 --- a/src/widget/widget-toolbox.js +++ b/src/widget/widget-toolbox.js @@ -96,11 +96,25 @@ class WidgetToolbox extends React.Component { const disableDecrease = this.disableDecrease(); // Only one topology widget at the time is supported const iconStyle = { - color: '#007bff', + color: '#527984', height: '25px', width : '25px' } + const buttonStyle = { + marginRight: '3px', + height: '40px', + borderColor: '#527984', + backgroundColor: '#527984' + } + + const altButtonStyle = { + marginRight: '3px', + height: '40px', + borderColor: '#ffffff', + backgroundColor: '#ffffff' + } + const thereIsTopologyWidget = this.props.widgets != null && Object.values(this.props.widgets).filter(w => w.type === 'Topology').length > 0; const topologyItemMsg = thereIsTopologyWidget? 'Currently only one is supported' : ''; @@ -110,16 +124,16 @@ class WidgetToolbox extends React.Component {
Show/ hide available Cosmetic Widgets } > - + Show/ hide available Displaying Widgets } > - + Show/ hide available Manipulation Widgets } > - +
@@ -128,12 +142,12 @@ class WidgetToolbox extends React.Component { Grid: { this.props.grid > 1 ? this.props.grid : 'Disabled' } Increase dashboard height } > - Decrease dashboard height } > - From a6d9edde593a24d722d7dfd92f6e91879ff1b19a Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Mon, 28 Dec 2020 14:48:33 +0100 Subject: [PATCH 02/25] WIP: change DropdownButton color --- src/ic/ic-action.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ic/ic-action.js b/src/ic/ic-action.js index 82dea64..3647662 100644 --- a/src/ic/ic-action.js +++ b/src/ic/ic-action.js @@ -76,7 +76,7 @@ class ICAction extends React.Component { onChange={this.setDelayForAction} /> - + {actionList} From aef3694d1d1e8ee096fc3c3d9ca8c7f7e081f81c Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Wed, 30 Dec 2020 17:30:50 +0100 Subject: [PATCH 03/25] change link color scheme, resolve warnings, change account site layout #276 --- src/common/dialogs/delete-dialog.js | 2 +- src/dashboard/edit-dashboard.js | 2 +- src/dashboard/new-dashboard.js | 2 +- src/ic/ics.js | 2 +- src/ic/import-ic.js | 4 ++-- src/scenario/scenario.js | 2 +- src/styles/app.css | 4 ++++ src/user/user.js | 4 ++-- 8 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/common/dialogs/delete-dialog.js b/src/common/dialogs/delete-dialog.js index 8d114f4..179b3cd 100644 --- a/src/common/dialogs/delete-dialog.js +++ b/src/common/dialogs/delete-dialog.js @@ -42,7 +42,7 @@ class DeleteDialog extends React.Component { - + ; diff --git a/src/dashboard/edit-dashboard.js b/src/dashboard/edit-dashboard.js index cb062ce..2df61bf 100644 --- a/src/dashboard/edit-dashboard.js +++ b/src/dashboard/edit-dashboard.js @@ -73,7 +73,7 @@ class EditDashboardDialog extends React.Component { return ( this.onClose(c)} onReset={() => this.resetState()} valid={this.valid}>
- + Name this.handleChange(e)} /> diff --git a/src/dashboard/new-dashboard.js b/src/dashboard/new-dashboard.js index 6f4b9da..a023ba4 100644 --- a/src/dashboard/new-dashboard.js +++ b/src/dashboard/new-dashboard.js @@ -69,7 +69,7 @@ class NewDashboardDialog extends React.Component { return ( this.onClose(c)} onReset={() => this.resetState()} valid={this.valid}> - + Name this.handleChange(e)} /> diff --git a/src/ic/ics.js b/src/ic/ics.js index 2bf666f..2074f5d 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -320,7 +320,7 @@ class InfrastructureComponents extends Component { let ic = this.state.ics.find(ic => ic.name === name); let index = this.state.ics.indexOf(ic); if(ic.type === "villas-node" || ic.type === "villas-relay"){ - return } + return } else{ return {name} } diff --git a/src/ic/import-ic.js b/src/ic/import-ic.js index bde1d9a..a165af6 100644 --- a/src/ic/import-ic.js +++ b/src/ic/import-ic.js @@ -118,7 +118,7 @@ class ImportICDialog extends React.Component { this.loadFile(e.target.files)} /> - + Name this.handleChange(e)} /> @@ -128,7 +128,7 @@ class ImportICDialog extends React.Component { this.handleChange(e)} /> - + UUID this.handleChange(e)} /> diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 3e6bf83..185590a 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -604,7 +604,7 @@ class Scenario extends React.Component { const altButtonStyle = { marginLeft: '10px', backgroundColor: '#ffffff', - borderColor: 'ffffff' + borderColor: '#ffffff' } const tableHeadingStyle = { diff --git a/src/styles/app.css b/src/styles/app.css index a2d887d..c607fb0 100644 --- a/src/styles/app.css +++ b/src/styles/app.css @@ -388,3 +388,7 @@ body { .badge-outdated { opacity: 0.4; } + +a:link, a:active, a:visited , a:hover { + color: #047cab ; +} diff --git a/src/user/user.js b/src/user/user.js index 974f7f2..72428ba 100644 --- a/src/user/user.js +++ b/src/user/user.js @@ -140,12 +140,12 @@ class User extends Component { - +
Username:
E-mail:
Role:
- +
{this.state.currentUser.username}
{this.state.currentUser.mail}
{this.state.currentUser.role}
From e45de4fc643981342ee5594a502f9973919412f2 Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Sun, 3 Jan 2021 18:54:28 +0100 Subject: [PATCH 04/25] Change link and button color scheme #276 --- src/file/edit-files.js | 1 + src/ic/ic-action.js | 13 ++++++++----- src/signal/edit-signal-mapping.js | 4 +++- src/user/login-form.js | 2 +- .../edit-widget-color-zones-control.js | 16 ++++++++++++++-- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/file/edit-files.js b/src/file/edit-files.js index 8cc3421..585db3e 100644 --- a/src/file/edit-files.js +++ b/src/file/edit-files.js @@ -145,6 +145,7 @@ class EditFilesDialog extends React.Component { @@ -87,4 +90,4 @@ class ICAction extends React.Component { } } -export default ICAction; +export default ICAction; \ No newline at end of file diff --git a/src/signal/edit-signal-mapping.js b/src/signal/edit-signal-mapping.js index 82a8442..10980ae 100644 --- a/src/signal/edit-signal-mapping.js +++ b/src/signal/edit-signal-mapping.js @@ -176,7 +176,9 @@ class EditSignalMapping extends React.Component { render() { const buttonStyle = { - marginLeft: '10px' + marginLeft: '10px', + backgroundColor: '#527984', + borderColor: '#527984' }; return( diff --git a/src/user/login-form.js b/src/user/login-form.js index a270977..e828de3 100644 --- a/src/user/login-form.js +++ b/src/user/login-form.js @@ -92,7 +92,7 @@ class LoginForm extends Component { - + diff --git a/src/widget/edit-widget/edit-widget-color-zones-control.js b/src/widget/edit-widget/edit-widget-color-zones-control.js index 4ade39f..1fca8d3 100644 --- a/src/widget/edit-widget/edit-widget-color-zones-control.js +++ b/src/widget/edit-widget/edit-widget-color-zones-control.js @@ -175,6 +175,18 @@ class EditWidgetColorZonesControl extends React.Component { render() { + const buttonStyle = { + marginBottom: '10px', + marginLeft: '120px', + borderColor: '#ffffff', + backgroundColor: '#ffffff' + }; + + const iconStyle = { + color: '#527984', + height: '25px', + width : '25px' + } let tempColor = 'FFFFFF'; let collapse = false; @@ -192,7 +204,7 @@ class EditWidgetColorZonesControl extends React.Component { return Color zones - +
{ @@ -245,7 +257,7 @@ class EditWidgetColorZonesControl extends React.Component { - + this.closeEditModal(data)} widget={this.state.widget} zoneIndex={this.state.selectedIndex} controlId={'strokeStyle'} /> From 8eefcc31e7d139395f7b1d341bc174dae1ecec28 Mon Sep 17 00:00:00 2001 From: irismarie Date: Wed, 13 Jan 2021 09:55:38 +0100 Subject: [PATCH 05/25] WIP --- package-lock.json | 13 +++++++++++++ package.json | 1 + src/common/table.js | 3 ++- src/signal/edit-signal-mapping.js | 18 ++++++++++++++---- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 10f2405..0d23ec6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1184,6 +1184,14 @@ "minimist": "^1.2.0" } }, + "@createnl/grouped-checkboxes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@createnl/grouped-checkboxes/-/grouped-checkboxes-1.1.2.tgz", + "integrity": "sha512-F4SoFF7UwktrpVeJPs/cQFP5Nn+1wpUm5v1/vzUcgseDGxvjXjLrs+F99ivH/TA3VDJbeFdBPi7gymmw2cessQ==", + "requires": { + "lodash.debounce": "^4.0.8" + } + }, "@csstools/convert-colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", @@ -10897,6 +10905,11 @@ "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", "integrity": "sha1-JI42By7ekGUB11lmIAqG2riyMXA=" }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + }, "lodash.flow": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", diff --git a/package.json b/package.json index 219d249..bb16f31 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@fortawesome/fontawesome-svg-core": "^1.2.32", "@fortawesome/free-solid-svg-icons": "^5.15.1", "@fortawesome/react-fontawesome": "^0.1.12", + "@createnl/grouped-checkboxes": "^1.1.2", "babel-runtime": "^6.26.0", "bootstrap": "^4.5.3", "bufferutil": "^4.0.1", diff --git a/src/common/table.js b/src/common/table.js index 12d0ebf..a44be38 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -34,7 +34,8 @@ class CustomTable extends Component { } static defaultProps = { - width: null + width: null, + checked: true }; onClick(event, row, column) { diff --git a/src/signal/edit-signal-mapping.js b/src/signal/edit-signal-mapping.js index 82a8442..e977854 100644 --- a/src/signal/edit-signal-mapping.js +++ b/src/signal/edit-signal-mapping.js @@ -134,6 +134,10 @@ class EditSignalMapping extends React.Component { }; + handleRemove = () => { + + } + handleAdd = (configID = null) => { if(typeof this.props.configs !== "undefined"){ @@ -173,6 +177,10 @@ class EditSignalMapping extends React.Component { this.setState({signals: signals}) } + onSignalChecked(index, signal) { + console.log(index); + } + render() { const buttonStyle = { @@ -185,7 +193,7 @@ class EditSignalMapping extends React.Component { show={this.props.show} title="Edit Signal Mapping" buttonTitle="Save" - blendOutCancel = {true} + blendOutCancel = {false} onClose={(c) => this.onClose(c)} onReset={() => this.resetState()} valid={true} @@ -194,7 +202,8 @@ class EditSignalMapping extends React.Component { {this.props.direction} Mapping Click Index, Name or Unit cell to edit - +
this.onSignalChecked(index, event)} data={this.state.signals}> + this.onSignalChecked(index, event)} width='30' /> this.handleMappingChange(e, row, column)} /> this.handleMappingChange(e, row, column)} /> this.handleMappingChange(e, row, column)} /> @@ -202,8 +211,9 @@ class EditSignalMapping extends React.Component { this.handleDelete(index)} />
-
- +
+ +
From cec5acb6eb4786939eed28dc263d916589206137 Mon Sep 17 00:00:00 2001 From: irismarie Date: Fri, 12 Feb 2021 17:48:46 +0100 Subject: [PATCH 06/25] create result with start cmd, show configSnapshots --- src/result/result-configs-dialog.js | 64 +++++++++++++ src/scenario/scenario.js | 139 +++++++++++++++++++--------- 2 files changed, 158 insertions(+), 45 deletions(-) create mode 100644 src/result/result-configs-dialog.js diff --git a/src/result/result-configs-dialog.js b/src/result/result-configs-dialog.js new file mode 100644 index 0000000..8dfc220 --- /dev/null +++ b/src/result/result-configs-dialog.js @@ -0,0 +1,64 @@ +/** + * 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 Dialog from '../common/dialogs/dialog'; +import ReactJson from 'react-json-view'; + + +class ResultConfigDialog extends React.Component { + valid = true; + + constructor(props) { + super(props); + + this.state = { + confirmCommand: false, + command: '', + }; + } + + onClose(canceled) { + this.props.onClose(); + } + + render() { + return ( + this.onClose(c)} + valid={true} + size="lg" + blendOutCancel={true} + > + + + + + ); + } +} + +export default ResultConfigDialog; diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 7bf2de9..1f7d127 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -37,7 +37,8 @@ import NewDashboardDialog from "../dashboard/new-dashboard"; import EditDashboardDialog from '../dashboard/edit-dashboard'; import EditFiles from '../file/edit-files' import NewResultDialog from '../result/new-result'; -import EditResultDialog from '../result/edit-result' +import EditResultDialog from '../result/edit-result'; +import ResultConfigDialog from '../result/result-configs-dialog'; import ICAction from '../ic/ic-action'; @@ -119,6 +120,9 @@ class Scenario extends React.Component { filesToDownload: prevState.filesToDownload, zipfiles: prevState.zipfiles || false, resultNodl: prevState.resultNodl, + resultConfigsModal: false, + modalResultConfigs: {}, + modalResultConfigsIndex: 0, editOutputSignalsModal: prevState.editOutputSignalsModal || false, editInputSignalsModal: prevState.editInputSignalsModal || false, @@ -161,12 +165,12 @@ class Scenario extends React.Component { componentDidUpdate(prevProps, prevState) { // check whether file data has been loaded - if (this.state.filesToDownload && this.state.filesToDownload.length > 0 ) { + if (this.state.filesToDownload && this.state.filesToDownload.length > 0) { if (this.state.files != prevState.files) { if (!this.state.zipfiles) { let fileToDownload = FileStore.getState().filter(file => file.id === this.state.filesToDownload[0]) if (fileToDownload.length === 1 && fileToDownload[0].data) { - const blob = new Blob([fileToDownload[0].data], {type: fileToDownload[0].type}); + const blob = new Blob([fileToDownload[0].data], { type: fileToDownload[0].type }); FileSaver.saveAs(blob, fileToDownload[0].name); this.setState({ filesToDownload: [] }); } @@ -178,7 +182,7 @@ class Scenario extends React.Component { zip.file(file.name, file.data); }); let zipname = "result_" + this.state.resultNodl + "_" + Date.now(); - zip.generateAsync({type: "blob"}).then(function(content) { + zip.generateAsync({ type: "blob" }).then(function (content) { saveAs(content, zipname); }); this.setState({ filesToDownload: [] }); @@ -367,7 +371,7 @@ class Scenario extends React.Component { this.setState({ selectedConfigs: selectedConfigs }); } - usesExternalIC(index){ + usesExternalIC(index) { let icID = this.state.configs[index].icID; let ic = null; @@ -381,8 +385,8 @@ class Scenario extends React.Component { return false; } - if (ic.managedexternally === true){ - this.setState({ExternalICInUse: true}) + if (ic.managedexternally === true) { + this.setState({ ExternalICInUse: true }) return true } @@ -396,6 +400,7 @@ class Scenario extends React.Component { return; } + let configs = []; for (let index of this.state.selectedConfigs) { // get IC for component config let ic = null; @@ -410,6 +415,7 @@ class Scenario extends React.Component { } if (action.data.action === 'start') { + configs.push(this.copyConfig(index)); action.data.parameters = this.state.configs[index].startParameters; } @@ -424,6 +430,22 @@ class Scenario extends React.Component { token: this.state.sessionToken }); } + + if (configs != 0) { //create result (only if command was 'start') + let componentConfigs = {}; + componentConfigs["configs"] = configs; + let data = {}; + data["Description"] = "created by start cmd"; + data["ResultFileIDs"] = []; + data["scenarioID"] = this.state.scenario.id; + data["ConfigSnapshots"] = JSON.stringify(componentConfigs, null, 2); + AppDispatcher.dispatch({ + type: 'results/start-add', + data, + token: this.state.sessionToken, + }) + } + }; getICName(icID) { @@ -645,13 +667,13 @@ class Scenario extends React.Component { let toDownload = []; let zip = false; - if (typeof(param) === 'object') { // download all files + if (typeof (param) === 'object') { // download all files toDownload = param.resultFileIDs; zip = true; this.setState({ filesToDownload: toDownload, zipfiles: zip, resultNodl: param.id }); } else { // download one file toDownload.push(param); - this.setState({ filesToDownload: toDownload, zipfiles: zip}); + this.setState({ filesToDownload: toDownload, zipfiles: zip }); } toDownload.forEach(fileid => { @@ -677,6 +699,22 @@ class Scenario extends React.Component { }); } + openResultConfigSnaphots(result) { + this.setState({ + modalResultConfigs: JSON.parse(result.configSnapshots), + modalResultConfigsIndex: result.id, + resultConfigsModal: true + }); + } + + closeResultConfigSnapshots() { + this.setState({ resultConfigsModal: false }); + } + + modifyResultNoColumn(id, result) { + return + } + startPintura(configIndex) { let config = this.state.configs[configIndex]; @@ -740,40 +778,50 @@ class Scenario extends React.Component { let resulttable; if (this.state.results && this.state.results.length > 0) { resulttable =
- - - - - - this.downloadResultData(index)} - /> - this.setState({ editResultsModal: true, modalResultsIndex: index })} - onDownloadAll={(index) => this.downloadResultData(this.state.results[index])} - onDelete={(index) => this.setState({ deleteResultsModal: true, modalResultsData: this.state.results[index], modalResultsIndex: index })} - /> -
+ + this.modifyResultNoColumn(id, result)} + /> + + + + this.downloadResultData(index)} + /> + this.setState({ editResultsModal: true, modalResultsIndex: index })} + onDownloadAll={(index) => this.downloadResultData(this.state.results[index])} + onDelete={(index) => this.setState({ deleteResultsModal: true, modalResultsData: this.state.results[index], modalResultsIndex: index })} + /> +
- - this.closeDeleteResultsModal(e)} /> -
+ + this.closeDeleteResultsModal(e)} /> + +
} return
@@ -858,7 +906,7 @@ class Scenario extends React.Component { { this.state.ExternalICInUse ? ( -
+
this.runAction(action, when)} @@ -870,9 +918,10 @@ class Scenario extends React.Component { {id: '3', title: 'Resume', data: {action: 'resume'}} ]}/>
- ) : (
) + ) : (
) } -
+ + < div style={{ clear: 'both' }} /> Date: Tue, 16 Feb 2021 18:00:44 +0100 Subject: [PATCH 07/25] Delete (all) signal(s) with checkbox-button combination #269 --- src/signal/edit-signal-mapping.js | 57 +++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/src/signal/edit-signal-mapping.js b/src/signal/edit-signal-mapping.js index e977854..7dec36a 100644 --- a/src/signal/edit-signal-mapping.js +++ b/src/signal/edit-signal-mapping.js @@ -17,7 +17,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {Button, FormGroup, FormLabel, FormText} from 'react-bootstrap'; +import {Button, FormGroup, FormLabel, FormText, OverlayTrigger, Tooltip} from 'react-bootstrap'; import {Collapse} from 'react-collapse'; import Table from '../common/table'; import TableColumn from '../common/table-column'; @@ -64,6 +64,11 @@ class EditSignalMapping extends React.Component { } } + signals.forEach(signal => { + if(signal.checked == undefined) signal.checked = false + }); + + return { signals: signals, }; @@ -136,6 +141,17 @@ class EditSignalMapping extends React.Component { handleRemove = () => { + let checkedSignals = this.state.signals.filter(signal => signal.checked === true); + + checkedSignals.forEach(signal => { + AppDispatcher.dispatch({ + type: 'signals/start-remove', + data: signal, + token: this.props.sessionToken + }); + + }) + } handleAdd = (configID = null) => { @@ -177,8 +193,32 @@ class EditSignalMapping extends React.Component { this.setState({signals: signals}) } - onSignalChecked(index, signal) { - console.log(index); + onSignalChecked(signal) { + let tempSignals = this.state.signals; + const index = tempSignals.indexOf(signal); + + tempSignals[index].checked = !tempSignals[index].checked; + + this.setState({signals: tempSignals}); + + } + + checkAll(){ + let tempSignals = this.state.signals; + let allChecked = true; + + tempSignals.forEach(signal => + { + if(signal.checked === false){ + signal.checked = true; + allChecked = false; + } + }); + + if(allChecked){ + tempSignals.forEach(signal => signal.checked = false); + } + this.setState({signals: tempSignals}); } render() { @@ -202,8 +242,8 @@ class EditSignalMapping extends React.Component { {this.props.direction} Mapping Click Index, Name or Unit cell to edit - this.onSignalChecked(index, event)} data={this.state.signals}> - this.onSignalChecked(index, event)} width='30' /> +
this.onSignalChecked(signal)} data={this.state.signals}> + this.onSignalChecked(index, event)} checkboxKey='checked' width='30' /> this.handleMappingChange(e, row, column)} /> this.handleMappingChange(e, row, column)} /> this.handleMappingChange(e, row, column)} /> @@ -212,8 +252,11 @@ class EditSignalMapping extends React.Component {
- - + Check/Uncheck All } > + + + +
From b0e9ba4d1c15925f59c63ad75b8c88d0d55039e1 Mon Sep 17 00:00:00 2001 From: irismarie Date: Tue, 16 Feb 2021 19:41:32 +0100 Subject: [PATCH 08/25] bugfix: configSnapshots empty or null --- src/scenario/scenario.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 15ab264..65799ff 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -700,11 +700,19 @@ class Scenario extends React.Component { } openResultConfigSnaphots(result) { - this.setState({ - modalResultConfigs: JSON.parse(result.configSnapshots), - modalResultConfigsIndex: result.id, - resultConfigsModal: true - }); + if (!result.configSnapshots || result.configSnapshots == "") { + this.setState({ + modalResultConfigs: {"configs": []}, + modalResultConfigsIndex: result.id, + resultConfigsModal: true + }); + } else { + this.setState({ + modalResultConfigs: JSON.parse(result.configSnapshots), + modalResultConfigsIndex: result.id, + resultConfigsModal: true + }); + } } closeResultConfigSnapshots() { From 51c02c1d1d079d894e906ba7562f473874b5e3e4 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 17 Feb 2021 11:10:16 +0100 Subject: [PATCH 09/25] revise home page, add more funding info --- src/common/home.js | 51 +++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/common/home.js b/src/common/home.js index 0fc874d..5932022 100644 --- a/src/common/home.js +++ b/src/common/home.js @@ -43,17 +43,15 @@ class Home extends React.Component { Logo VILLASweb

Home

- Welcome to {config.instance} hosted by {config.admin.name}!
+ {/*Welcome to {config.instance} hosted by {config.admin.name}!
*/} + Welcome to {config.instance}!

You are logged in as user {currentUser.username} with ID {currentUser.id} and role {currentUser.role}.

-

- An interactive documentation of the VILLASweb API is available here. -

-

Data Model

+ {/*

Data Model

Datamodel VILLASweb

Terminology

@@ -82,32 +80,47 @@ class Home extends React.Component {
  • A collection of component configurations and dashboards for a specific experiment
  • Users can have access to multiple scenarios
  • -
+ */}

Credits

-

VILLASweb is developed by the Institute for Automation of Complex Power Systems at the RWTH Aachen University.

+

VILLASweb is an open source project developed by the Institute for Automation of Complex Power Systems at RWTH Aachen University.

+ Logo ACS

Links

Funding

-

The development of VILLASframework projects have received funding from

+

The development of VILLASframework projects has received funding from

    -
  • Urban Energy Lab 4.0 a project funded by OP EFRE NRW (European Regional Development Fund) for the setup of a novel energy research infrastructure.
  • -
  • RESERVE a European Union’s Horizon 2020 research and innovation programme under grant agreement No 727481
  • -
  • JARA-ENERGY. Jülich-Aachen Research Alliance (JARA) is an initiative of RWTH Aachen University and Forschungszentrum Jülich.
  • +

    SLEW: Second Life for Energiewende, an Exploratory Teaching Space project funded by RWTH Aachen University

    +

    ERIgrid 2.0: An EU Horizon 2020 research and innovation action project for connecting European Smart Grid Infrastructures (grant agreement No 870620)

    +

    + Logo EU + Logo ERIgrid 2.0 +

    +

    Urban Energy Lab 4.0: A project funded by EFRE.NRW (European Regional Development Fund) for the setup of a novel energy research infrastructure.

    +

    + Logo UEL OP EFRE NRW + Logo UEL +

    +

    RESERVE: An EU Horizon 2020 research and innovation project (grant agreement No 727481)

    +

    + Logo EU + Logo RESERVE +

    +

    JARA-ENERGY: Jülich-Aachen Research Alliance (JARA) is an initiative of RWTH Aachen University and Forschungszentrum Jülich.

- Logo EU - Logo EU - Logo UEL OP EFRE NRW - Logo UEL - Logo ACS + + + { //Logo JARA } From f29ee56d5162c204dd0329e4035418a9132727b8 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 17 Feb 2021 11:13:23 +0100 Subject: [PATCH 10/25] add missing logo --- src/img/erigrid2.png | Bin 0 -> 18902 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/img/erigrid2.png diff --git a/src/img/erigrid2.png b/src/img/erigrid2.png new file mode 100644 index 0000000000000000000000000000000000000000..0c19b4c536db15b9388ccf74796c10fca7a4a165 GIT binary patch literal 18902 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 z*8ML}e~}FU000000000000000000000000000000000000000000000000000001h a|BQdX-1u9=T(gM)0000 Date: Thu, 18 Feb 2021 16:14:29 +0100 Subject: [PATCH 11/25] improve reloading of config after signal removal --- src/scenario/scenario.js | 10 ++++++++++ src/signal/signal-store.js | 7 ++----- src/signal/signals-data-manager.js | 4 ++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 698f1d6..a1e550a 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -539,11 +539,21 @@ class Scenario extends React.Component { ############################################## */ closeEditSignalsModal(direction) { + + // reload the config + AppDispatcher.dispatch({ + type: 'configs/start-load', + data: this.state.modalConfigData.id, + token: this.state.sessionToken + }); + if (direction === "in") { this.setState({ editInputSignalsModal: false }); } else if (direction === "out") { this.setState({ editOutputSignalsModal: false }); } + + } onEditFiles() { diff --git a/src/signal/signal-store.js b/src/signal/signal-store.js index 175467c..40eae35 100644 --- a/src/signal/signal-store.js +++ b/src/signal/signal-store.js @@ -27,11 +27,9 @@ class SignalStore extends ArrayStore{ reduce(state, action) { switch (action.type) { + case 'signals/added': - this.dataManager.reloadConfig(action.token, action.data); - return super.reduce(state, action); - case 'signals/removed': - this.dataManager.reloadConfig(action.token, action.data); + this.dataManager.reloadConfig(action.token, action.data.configID); return super.reduce(state, action); case 'signals/start-autoconfig': @@ -41,7 +39,6 @@ class SignalStore extends ArrayStore{ case 'signals/autoconfig-loaded': console.log("AutoConfig Loaded: ", action.data) this.dataManager.saveSignals(action.data, action.token, action.configID, action.socketname); - return super.reduce(state, action); case 'signals/autoconfig-error': diff --git a/src/signal/signals-data-manager.js b/src/signal/signals-data-manager.js index 3cc6493..1a5ee0c 100644 --- a/src/signal/signals-data-manager.js +++ b/src/signal/signals-data-manager.js @@ -27,9 +27,9 @@ class SignalsDataManager extends RestDataManager{ super('signal', '/signals'); } - reloadConfig(token, data){ + reloadConfig(token, id){ // request in signals - RestAPI.get(this.makeURL('/configs/' + data.configID), token).then(response => { + RestAPI.get(this.makeURL('/configs/' + id), token).then(response => { AppDispatcher.dispatch({ type: 'configs/edited', data: response.config From 77c08fc5af2e4eacc876565240031cb77e455e24 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Fri, 19 Feb 2021 10:58:15 +0100 Subject: [PATCH 12/25] fix array length check and change default description of result --- src/scenario/scenario.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 65799ff..454f78e 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -431,11 +431,11 @@ class Scenario extends React.Component { }); } - if (configs != 0) { //create result (only if command was 'start') + if (configs.length !== 0) { //create result (only if command was 'start') let componentConfigs = {}; componentConfigs["configs"] = configs; let data = {}; - data["Description"] = "created by start cmd"; + data["Description"] = "Run " + this.state.scenario.name; // default description, to be change by user later data["ResultFileIDs"] = []; data["scenarioID"] = this.state.scenario.id; data["ConfigSnapshots"] = JSON.stringify(componentConfigs, null, 2); From 1804648d6abd35920a7c50bd0c47260bd5256ae9 Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Mon, 22 Feb 2021 03:13:50 +0100 Subject: [PATCH 13/25] implement new button colors with css #276 --- src/common/dialogs/delete-dialog.js | 4 +- src/common/dialogs/dialog.js | 11 ++-- src/common/icon.js | 2 +- src/dashboard/dashboard-button-group.js | 27 ++++---- src/file/edit-files.js | 4 +- src/ic/ic-action.js | 8 +-- src/ic/ic-dialog.js | 6 +- src/ic/ics.js | 11 ++-- src/scenario/scenario.js | 34 +++++----- src/scenario/scenarios.js | 9 ++- src/signal/edit-signal-mapping.js | 10 ++- src/styles/app.css | 66 +++++++++++++++++-- src/user/login-form.js | 6 +- src/user/user.js | 13 +--- src/user/users.js | 7 +- .../edit-widget-color-zones-control.js | 12 ++-- src/widget/toolbox-item.js | 2 +- src/widget/widget-toolbox.js | 26 +++----- 18 files changed, 146 insertions(+), 112 deletions(-) diff --git a/src/common/dialogs/delete-dialog.js b/src/common/dialogs/delete-dialog.js index 179b3cd..b99f2af 100644 --- a/src/common/dialogs/delete-dialog.js +++ b/src/common/dialogs/delete-dialog.js @@ -42,7 +42,9 @@ class DeleteDialog extends React.Component { - + + + ; diff --git a/src/common/dialogs/dialog.js b/src/common/dialogs/dialog.js index 741ecaf..071a58e 100644 --- a/src/common/dialogs/dialog.js +++ b/src/common/dialogs/dialog.js @@ -45,11 +45,6 @@ class Dialog extends React.Component { } render() { - const buttonStyle = { - backgroundColor: '#527984', - borderColor: '#527984' - }; - return ( @@ -62,8 +57,10 @@ class Dialog extends React.Component { - {this.props.blendOutCancel?
: } - + + {this.props.blendOutCancel?
: } + +
); diff --git a/src/common/icon.js b/src/common/icon.js index 1ad1701..25155b4 100644 --- a/src/common/icon.js +++ b/src/common/icon.js @@ -28,7 +28,7 @@ library.add(fas); class Icon extends React.Component { render() { - return + return } } diff --git a/src/dashboard/dashboard-button-group.js b/src/dashboard/dashboard-button-group.js index 9d171c6..20a8994 100644 --- a/src/dashboard/dashboard-button-group.js +++ b/src/dashboard/dashboard-button-group.js @@ -26,12 +26,9 @@ class DashboardButtonGroup extends React.Component { marginLeft: '12px', height: '44px', width : '35px', - borderColor: '#ffffff', - backgroundColor: '#ffffff' }; const iconStyle = { - color: '#527984', height: '25px', width : '25px' } @@ -47,21 +44,22 @@ class DashboardButtonGroup extends React.Component { buttons.push( Save changes } > , Discard changes } > ); } else { if (this.props.fullscreen !== true) { buttons.push( + Change to fullscreen view } > ); @@ -69,7 +67,7 @@ class DashboardButtonGroup extends React.Component { buttons.push( Back to normal view } > ); @@ -79,7 +77,7 @@ class DashboardButtonGroup extends React.Component { buttons.push( Continue simulation } > ); @@ -87,7 +85,7 @@ class DashboardButtonGroup extends React.Component { buttons.push( Pause simulation } > ); @@ -98,16 +96,15 @@ class DashboardButtonGroup extends React.Component { Add, edit or delete files of scenario }> ); buttons.push( - Add, edit or delete input signals }> + Add, edit or delete input signals }> ); @@ -116,7 +113,7 @@ class DashboardButtonGroup extends React.Component { Add, edit or delete output signals }> ); @@ -125,7 +122,7 @@ class DashboardButtonGroup extends React.Component { Add widgets and edit layout }> ); diff --git a/src/file/edit-files.js b/src/file/edit-files.js index 97ae6e3..d15102b 100644 --- a/src/file/edit-files.js +++ b/src/file/edit-files.js @@ -149,12 +149,14 @@ class EditFilesDialog extends React.Component { + + diff --git a/src/ic/ic-action.js b/src/ic/ic-action.js index e18ba54..e968c17 100644 --- a/src/ic/ic-action.js +++ b/src/ic/ic-action.js @@ -75,17 +75,17 @@ class ICAction extends React.Component { step={1} onChange={this.setDelayForAction} /> +
- {this.state.selectedAction != null ? this.state.selectedAction.title : ''} + {this.state.selectedAction != null ? this.state.selectedAction.title : ''} {actionList} - - - + +
; } } diff --git a/src/ic/ic-dialog.js b/src/ic/ic-dialog.js index 6e79fac..a919f3f 100644 --- a/src/ic/ic-dialog.js +++ b/src/ic/ic-dialog.js @@ -95,10 +95,10 @@ class ICDialog extends React.Component { {this.props.userRole === "Admin" ? (
Controls:
-
- - diff --git a/src/ic/ics.js b/src/ic/ics.js index dc013c6..e3405f2 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -334,7 +334,7 @@ class InfrastructureComponents extends Component { let ic = this.state.ics.find(ic => ic.name === name); let index = this.state.ics.indexOf(ic); if(ic.type === "villas-node" || ic.type === "villas-relay"){ - return } + return } else{ return {name} } @@ -369,12 +369,9 @@ class InfrastructureComponents extends Component { const buttonStyle = { marginLeft: '10px', - backgroundColor: '#ffffff', - borderColor: '#ffffff' } const iconStyle = { - color: '#527984', height: '30px', width: '30px' } @@ -384,9 +381,9 @@ class InfrastructureComponents extends Component {

Infrastructure Components {this.state.currentUser.role === "Admin" ? - - - + + + : diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 6802d15..7353ce2 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -697,16 +697,8 @@ class Scenario extends React.Component { return (); } - const buttonStyle = { - marginLeft: '10px', - backgroundColor: '#527984', - borderColor: '#527984' - }; - const altButtonStyle = { marginLeft: '10px', - backgroundColor: '#ffffff', - borderColor: '#ffffff' } const tableHeadingStyle = { @@ -714,7 +706,6 @@ class Scenario extends React.Component { } const iconStyle = { - color: '#527984', height: '30px', width: '30px' } @@ -764,8 +755,8 @@ class Scenario extends React.Component { return
Add, edit or delete files of scenario } > -
@@ -784,8 +775,10 @@ class Scenario extends React.Component { {/*Component Configurations table*/}

Component Configurations - - + + + +

this.onConfigChecked(index, event)} width='30' /> @@ -876,8 +869,10 @@ class Scenario extends React.Component { {/*Dashboard table*/}

Dashboards - - + + + +

@@ -904,7 +899,9 @@ class Scenario extends React.Component { {/*Result table*/}

Results - + + +

{resulttable} this.closeNewResultModal(data)} /> @@ -931,12 +928,15 @@ class Scenario extends React.Component { type="text" /> + +

diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index 00477d3..5c8ca13 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -237,12 +237,9 @@ class Scenarios extends Component { render() { const buttonStyle = { marginLeft: '10px', - backgroundColor: '#ffffff', - borderColor: '#ffffff' }; const iconStyle = { - color: '#527984', height: '30px', width: '30px' } @@ -250,8 +247,10 @@ class Scenarios extends Component { return (

Scenarios - - + + + +

diff --git a/src/signal/edit-signal-mapping.js b/src/signal/edit-signal-mapping.js index 10980ae..e882cb2 100644 --- a/src/signal/edit-signal-mapping.js +++ b/src/signal/edit-signal-mapping.js @@ -177,8 +177,6 @@ class EditSignalMapping extends React.Component { const buttonStyle = { marginLeft: '10px', - backgroundColor: '#527984', - borderColor: '#527984' }; return( @@ -204,16 +202,16 @@ class EditSignalMapping extends React.Component { this.handleDelete(index)} />
-
- +
+
Choose a Component Configuration to add the signal to:
-
+
{typeof this.props.configs !== "undefined" && this.props.configs.map(config => ( - + ))}
diff --git a/src/styles/app.css b/src/styles/app.css index cc09d33..7640536 100644 --- a/src/styles/app.css +++ b/src/styles/app.css @@ -369,6 +369,18 @@ body { height: auto !important; padding: 5px; float: right; + border-color: #ffffff; + background-color: #ffffff; +} + +.section-buttons-group-right .btn{ + border-color: #ffffff; + background-color: #ffffff; +} + +.section-buttons-group-right .btn:hover{ + border-color: #e3e3e3; + background-color: #e3e3e3; } .section-buttons-group-left { @@ -377,10 +389,60 @@ body { float: left; } +.section-buttons-group-left .btn{ + background-color: #527984; + border-color: #527984; +} + +.section-buttons-group-left .btn:hover{ + background-color: #31484f; + border-color: #31484f; +} + +.drag-and-drop .btn{ + color: #527984; + border-color: #527984; +} + +.drag-and-drop .btn:hover{ + color: #527984; + border-color: #527984; +} + + .section-buttons-group-right .rc-slider { margin-left: 12px; } +.solid-button .btn{ + background-color: #527984; + border-color: #527984; +} + +.solid-button .btn:hover{ + background-color: #31484f; + border-color: #31484f; +} + +.solid-button .btn:disabled{ + background-color: #527984; + border-color: #527984; +} + +.icon-button .btn{ + border-color: #ffffff; + background-color: #ffffff; +} + +.icon-button .btn:hover{ + border-color: #e3e3e3; + background-color: #e3e3e3; +} + +.icon-color { + color: #527984; +} + .form-horizontal .form-group { margin-left: 0 !important; margin-right: 0 !important; @@ -389,7 +451,3 @@ body { .badge-outdated { opacity: 0.4; } - -a:link, a:active, a:visited , a:hover { - color: #047cab ; -} diff --git a/src/user/login-form.js b/src/user/login-form.js index e828de3..08c09df 100644 --- a/src/user/login-form.js +++ b/src/user/login-form.js @@ -91,8 +91,10 @@ class LoginForm extends Component { - - + + + + diff --git a/src/user/user.js b/src/user/user.js index fc82d49..007602c 100644 --- a/src/user/user.js +++ b/src/user/user.js @@ -112,15 +112,6 @@ class User extends Component { render() { - const iconStyle = { - color: '#527984', - } - - const buttonStyle = { - margin: '10px', - borderColor: '#ffffff', - backgroundColor: '#ffffff' - } return (
@@ -140,7 +131,9 @@ class User extends Component {
{this.state.currentUser.username}
{this.state.currentUser.mail}
{this.state.currentUser.role}
- + + + diff --git a/src/user/users.js b/src/user/users.js index 807bed4..a9b84dc 100644 --- a/src/user/users.js +++ b/src/user/users.js @@ -132,12 +132,9 @@ class Users extends Component { const buttonStyle = { marginLeft: '10px', - backgroundColor: '#ffffff', - borderColor: '#ffffff' } const iconStyle = { - color: '#527984', height: '30px', width: '30px' } @@ -145,7 +142,9 @@ class Users extends Component { return (

Users - + + +

diff --git a/src/widget/edit-widget/edit-widget-color-zones-control.js b/src/widget/edit-widget/edit-widget-color-zones-control.js index 93653fb..6ef3fcd 100644 --- a/src/widget/edit-widget/edit-widget-color-zones-control.js +++ b/src/widget/edit-widget/edit-widget-color-zones-control.js @@ -178,12 +178,9 @@ class EditWidgetColorZonesControl extends React.Component { const buttonStyle = { marginBottom: '10px', marginLeft: '120px', - borderColor: '#ffffff', - backgroundColor: '#ffffff' }; const iconStyle = { - color: '#527984', height: '25px', width : '25px' } @@ -204,8 +201,9 @@ class EditWidgetColorZonesControl extends React.Component { return Color zones - - + + +
{ this.state.widget.customProperties.zones.map((zone, idx) => { @@ -255,7 +253,9 @@ class EditWidgetColorZonesControl extends React.Component {
- + + + this.closeEditModal(data)} widget={this.state.widget} zoneIndex={this.state.selectedIndex} controlId={'strokeStyle'} /> diff --git a/src/widget/toolbox-item.js b/src/widget/toolbox-item.js index e2aa402..4c268c5 100644 --- a/src/widget/toolbox-item.js +++ b/src/widget/toolbox-item.js @@ -51,7 +51,7 @@ class ToolboxItem extends React.Component { if (this.props.disabled === false) { return this.props.connectDragSource(
- + {this.props.icon && } {this.props.name} diff --git a/src/widget/widget-toolbox.js b/src/widget/widget-toolbox.js index 4483f1b..ee48d37 100644 --- a/src/widget/widget-toolbox.js +++ b/src/widget/widget-toolbox.js @@ -96,7 +96,6 @@ class WidgetToolbox extends React.Component { const disableDecrease = this.disableDecrease(); // Only one topology widget at the time is supported const iconStyle = { - color: '#527984', height: '25px', width : '25px' } @@ -104,15 +103,6 @@ class WidgetToolbox extends React.Component { const buttonStyle = { marginRight: '3px', height: '40px', - borderColor: '#527984', - backgroundColor: '#527984' - } - - const altButtonStyle = { - marginRight: '3px', - height: '40px', - borderColor: '#ffffff', - backgroundColor: '#ffffff' } const thereIsTopologyWidget = this.props.widgets != null && Object.values(this.props.widgets).filter(w => w.type === 'Topology').length > 0; @@ -124,15 +114,15 @@ class WidgetToolbox extends React.Component {
Show/ hide available Cosmetic Widgets } > - Show/ hide available Displaying Widgets } > - Show/ hide available Manipulation Widgets } > -
@@ -142,13 +132,13 @@ class WidgetToolbox extends React.Component { Grid: { this.props.grid > 1 ? this.props.grid : 'Disabled' } Increase dashboard height } > - Decrease dashboard height } > - @@ -157,7 +147,7 @@ class WidgetToolbox extends React.Component {





-
+
From 04916aa9d6fb96dea1ea9dfbf47e7b9151a286c6 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Mon, 22 Feb 2021 17:41:28 +0100 Subject: [PATCH 14/25] WIP: rework AMQP commands --- src/ic/ic-action.js | 180 ++++++++++++++++++++++++++++++++++++- src/ic/ic-store.js | 31 ++++++- src/ic/ics-data-manager.js | 69 ++++++++++++-- src/ic/ics.js | 28 +++--- src/scenario/scenario.js | 74 +++------------ 5 files changed, 291 insertions(+), 91 deletions(-) diff --git a/src/ic/ic-action.js b/src/ic/ic-action.js index b0333b8..b187c5e 100644 --- a/src/ic/ic-action.js +++ b/src/ic/ic-action.js @@ -17,6 +17,7 @@ import React from 'react'; import { Button, DropdownButton, Dropdown, InputGroup, FormControl } from 'react-bootstrap'; +import AppDispatcher from "../common/app-dispatcher"; class ICAction extends React.Component { constructor(props) { @@ -47,9 +48,178 @@ class ICAction extends React.Component { }; } } + return null } + runAction(action, when) { + + console.log("configs", this.props.configs) + console.log("selectedConfigs", this.props.selectedConfigs) + console.log("ics", this.props.ics) + console.log("selectedICs", this.props.selectedICs) + console.log("action", action) + console.log("when", when) + + if (action.data.action === 'none') { + console.warn("No command selected. Nothing was sent."); + return; + } + + if (!this.props.hasConfigs){ + let newAction = {}; + newAction["action"] = action.data.action + newAction["when"] = when + + for (let index of this.props.selectedICs) { + let ic = this.props.ics[index]; + let icID = ic.id; + + /* VILLAScontroller protocol + see: https://villas.fein-aachen.org/doc/controller-protocol.html + + RESET SHUTDOWN + { + "action": "reset/shutdown/stop/pause/resume" + "when": "1234567" + } + + DELETE + { + "action": "delete" + "parameters":{ + "uuid": "uuid-of-the-manager-for-this-IC" + } + "when": "1234567" + } + + CREATE is not possible within ICAction (see add IC) + */ + + if (newAction.action === "delete"){ + // prepare parameters for delete incl. correct IC id + newAction["parameters"] = {}; + newAction.parameters["uuid"] = ic.id; + icID = ic.manager; // send delete action to manager of IC + } + + AppDispatcher.dispatch({ + type: 'ics/start-action', + icid: ic.id, + action: newAction, + result: null, + token: this.props.token + }); + + } // end for loop over selected ICs + } else { + + /*VILLAScontoller protocol + see: https://villas.fein-aachen.org/doc/controller-protocol.html + * + * STOP PAUSE RESUME + { + "action": "reset/shutdown/stop/pause/resume" + "when": "1234567" + } + * + * START + { + "action": "start" + "when": 1234567 + "parameters": { + Start parameters for this IC as configured in the component config + } + "model": { + "type": "url" + "url": "https://villas.k8s.eonerc.rwth-aachen.de/api/v2/files/{fileID}" where fileID is the model file configured in the component config + "token": "asessiontoken" + } + "results":{ + "type": "url" + "url" : "https://villas.k8s.eonerc.rwth-aachen.de/api/v2/results/{resultID}/file" where resultID is the ID of the result created for this run + "token": "asessiontoken" + } + } + * + * + * */ + + + let newActions = []; + for (let config of this.props.selectedConfigs) { + let newAction = {} + newAction["action"] = action.data.action + newAction["when"] = when + + // get IC for component config + let ic = null; + for (let component of this.props.ics) { + if (component.id === config.icID) { + ic = component; + } + } + + if (ic == null) { + continue; + } + + // the following is not required by the protocol; it is an internal help + newAction["icid"] = ic.id + + if (newAction.action === 'start') { + newAction["parameters"] = config.startParameters; + newAction["model"] = {} + + if (config.fileIDs.length > 0){ + newAction.model["type"] = "url" + newAction.model["token"] = this.props.token + // TODO do not default to the first file of the config + newAction.model["url"] = "/files/" + config.fileIDs[0].toString() + } + + newAction["results"] = {} + newAction.results["type"] = "url" + newAction.results["token"] = this.props.token + newAction.results["url"] = "/results/RESULTID/file" // RESULTID serves as placeholder and is replaced later + + } + + // add the new action + newActions.push(newAction); + console.log("New actions in loop", newAction, newActions) + + } // end for loop over selected configs + + + let newResult = {} + newResult["result"] = {} + if (action.data.action === 'start') { + + let configSnapshots = []; + // create config snapshots in case action is start + for (let config of this.props.selectedConfigs) { + let index = this.props.configs.indexOf(config) + configSnapshots.push(this.props.snapshotConfig(index)); + } + + // create new result for new run + newResult.result["description"] = "Placeholder for description" + newResult.result["scenarioID"] = this.props.selectedConfigs[0].scenarioID + newResult.result["configSnapshots"] = configSnapshots + } + + + console.log("Dispatching actions for configs", newActions, newResult) + AppDispatcher.dispatch({ + type: 'ics/start-action', + action: newActions, + result: newResult, + token: this.props.token + }); + } + } + setAction = id => { // search action for (let action of this.props.actions) { @@ -65,7 +235,13 @@ class ICAction extends React.Component { render() { - let sendCommandDisabled = this.props.runDisabled || this.state.selectedAction == null || this.state.selectedAction.id === "-1" + let sendCommandDisabled = false; + if (!this.props.hasConfigs && this.props.selectedICs.length === 0 || this.state.selectedAction == null || this.state.selectedAction.id === "-1"){ + sendCommandDisabled = true; + } + if (this.props.hasConfigs && this.props.selectedConfigs.length === 0|| this.state.selectedAction == null || this.state.selectedAction.id === "-1"){ + sendCommandDisabled = true; + } let time = this.state.time.getFullYear().pad(4) + '-' + this.state.time.getMonth().pad(2) + '-' + @@ -98,7 +274,7 @@ class ICAction extends React.Component { + onClick={() => this.runAction(this.state.selectedAction, this.state.time)}>Run Select time for synced command execution
; diff --git a/src/ic/ic-store.js b/src/ic/ic-store.js index 7cf314a..c6d0810 100644 --- a/src/ic/ic-store.js +++ b/src/ic/ic-store.js @@ -66,16 +66,41 @@ class InfrastructureComponentStore extends ArrayStore { return state; case 'ics/start-action': - if (!Array.isArray(action.data)) - action.data = [ action.data ] + if (!Array.isArray(action.action)) + action.action = [ action.action ] - ICsDataManager.doActions(action.ic, action.data, action.token); + ICsDataManager.doActions(action.icid, action.action, action.token, action.result); return state; case 'ics/action-error': console.log(action.error); return state; + case 'ics/action-result-added': + + for (let a of action.actions){ + let icid = Object.assign({}, a.icid) + + if (a.results !== undefined && a.results != null){ + // adapt URL for newly created result ID + a.results.url = a.results.url.replace("RESULTID", action.data.result.id); + a.results.url = ICsDataManager.makeURL(a.results.url); + a.results.url = window.location.host + a.results.url; + } + if (a.model !== undefined && a.model != null) { + // adapt URL for model file + a.model.url = ICsDataManager.makeURL(a.model.url); + a.model.url = window.location.host + a.model.url; + } + delete a.icid + ICsDataManager.doActions(icid, [a], action.token) + } + return state; + + case 'ics/action-result-add-error': + console.log(action.error); + return state + case 'ics/get-status': ICsDataManager.getStatus(action.url, action.token, action.ic); return super.reduce(state, action); diff --git a/src/ic/ics-data-manager.js b/src/ic/ics-data-manager.js index 02d480f..a6a625d 100644 --- a/src/ic/ics-data-manager.js +++ b/src/ic/ics-data-manager.js @@ -24,24 +24,79 @@ class IcsDataManager extends RestDataManager { super('ic', '/ic'); } - doActions(ic, actions, token = null) { + doActions(icid, actions, token = null, result=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 => { + if (icid !== undefined && icid != null) { + + console.log("doActions, icid:", icid) + // sending action to a specific IC via IC list + + RestAPI.post(this.makeURL(this.url + '/' + icid + '/action'), actions, token).then(response => { AppDispatcher.dispatch({ - type: 'ics/action-started', - data: response + type: 'ics/action-started', + data: response }); - }).catch(error => { + }).catch(error => { AppDispatcher.dispatch({ - type: 'ics/action-error', + type: 'ics/action-error', + error + }); + }); + } else { + // sending the same action to multiple ICs via scenario controls + + // distinguish between "start" action and any other + + if (actions[0].action !== "start"){ + for (let a of actions){ + console.log("doActions, a.icid:", a.icid) + icid = JSON.parse(JSON.stringify(a.icid)) + delete a.icid + console.log("doActions, icid:", icid) + // sending action to a specific IC via IC list + + RestAPI.post(this.makeURL(this.url + '/' + icid + '/action'), [a], token).then(response => { + AppDispatcher.dispatch({ + type: 'ics/action-started', + data: response + }); + }).catch(error => { + AppDispatcher.dispatch({ + type: 'ics/action-error', + error + }); + }); + + } + } else{ + // for start actions procedure is different + // first a result needs to be created, then the start actions can be sent + + RestAPI.post(this.makeURL( '/results'), result, token).then(response => { + AppDispatcher.dispatch({ + type: 'ics/action-result-added', + data: response, + actions: actions, + token: token, + }); + }).catch(error => { + AppDispatcher.dispatch({ + type: 'ics/action-result-add-error', error + }); }); - }); + + + } + + + + } } getStatus(url,token,ic){ diff --git a/src/ic/ics.js b/src/ic/ics.js index de10aaa..9c1f2db 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -240,18 +240,7 @@ class InfrastructureComponents extends Component { this.setState({ selectedICs: selectedICs }); } - runAction(action, when) { - for (let index of this.state.selectedICs) { - action.when = when; - AppDispatcher.dispatch({ - type: 'ics/start-action', - ic: this.state.ics[index], - data: action.data, - token: this.state.sessionToken, - }); - } - } static isICOutdated(component) { if (!component.stateUpdateAt) @@ -420,19 +409,19 @@ class InfrastructureComponents extends Component { modifier={(stateUpdateAt, component) => this.stateUpdateModifier(stateUpdateAt, component)} /> - {this.state.currentUser.role === "Admin" && editable ? + {this.state.currentUser.role === "Admin" ? !this.isExternalIC(index)} exportButton - deleteButton + deleteButton = {(index) => !this.isExternalIC(index)} 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})} /> : this.exportIC(index)} /> @@ -496,12 +485,15 @@ class InfrastructureComponents extends Component { {this.state.currentUser.role === "Admin" && this.state.numberOfExternalICs > 0 ?
this.runAction(action, when)} + hasConfigs = {false} + ics={this.state.ics} + selectedICs={this.state.selectedICs} + token={this.state.sessionToken} actions={[ {id: '-1', title: 'Action', data: {action: 'none'}}, {id: '0', title: 'Reset', data: {action: 'reset'}}, {id: '1', title: 'Shutdown', data: {action: 'shutdown'}}, + {id: '2', title: 'Delete', data: {action: 'delete'}} ]} />
diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 791e79f..cacb2db 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -302,6 +302,7 @@ class Scenario extends React.Component { } copyConfig(index) { + console.log("index", index, "copyConfig: ", this.state.configs[index]) let config = JSON.parse(JSON.stringify(this.state.configs[index])); let signals = JSON.parse(JSON.stringify(SignalStore.getState().filter(s => s.configID === parseInt(config.id, 10)))); @@ -394,60 +395,6 @@ class Scenario extends React.Component { } - runAction(action, when) { - if (action.data.action === 'none') { - console.warn("No command selected. Nothing was sent."); - return; - } - - let configs = []; - for (let index of this.state.selectedConfigs) { - // get IC for component config - let ic = null; - for (let component of this.state.ics) { - if (component.id === this.state.configs[index].icID) { - ic = component; - } - } - - if (ic == null) { - continue; - } - - if (action.data.action === 'start') { - configs.push(this.copyConfig(index)); - action.data.parameters = this.state.configs[index].startParameters; - } - - action.data.when = when; - - console.log("Sending action: ", action.data) - - AppDispatcher.dispatch({ - type: 'ics/start-action', - ic: ic, - data: action.data, - token: this.state.sessionToken - }); - } - - if (configs.length !== 0) { //create result (only if command was 'start') - let componentConfigs = {}; - componentConfigs["configs"] = configs; - let data = {}; - data["Description"] = "Run " + this.state.scenario.name; // default description, to be change by user later - data["ResultFileIDs"] = []; - data["scenarioID"] = this.state.scenario.id; - data["ConfigSnapshots"] = JSON.stringify(componentConfigs, null, 2); - AppDispatcher.dispatch({ - type: 'results/start-add', - data, - token: this.state.sessionToken, - }) - } - - }; - getICName(icID) { for (let ic of this.state.ics) { if (ic.id === icID) { @@ -710,7 +657,7 @@ class Scenario extends React.Component { } openResultConfigSnaphots(result) { - if (!result.configSnapshots || result.configSnapshots == "") { + if (result.configSnapshots === null || result.configSnapshots === undefined) { this.setState({ modalResultConfigs: {"configs": []}, modalResultConfigsIndex: result.id, @@ -881,7 +828,8 @@ class Scenario extends React.Component { this.usesExternalIC(index)} + // checkboxDisabled={(index) => this.usesExternalIC(index)} + checkboxDistabled={false} onChecked={(index, event) => this.onConfigChecked(index, event)} width='30' /> @@ -925,11 +873,15 @@ class Scenario extends React.Component { />
- {this.state.ExternalICInUse ? ( + {/*{this.state.ExternalICInUse ? (*/}
this.runAction(action, when)} + hasConfigs={true} + ics={this.state.ics} + configs={this.state.configs} + selectedConfigs = {this.state.selectedConfigs} + snapshotConfig = {(index) => this.copyConfig(index)} + token = {this.state.sessionToken} actions={[ { id: '-1', title: 'Action', data: { action: 'none' } }, { id: '0', title: 'Start', data: { action: 'start' } }, @@ -938,8 +890,8 @@ class Scenario extends React.Component { { id: '3', title: 'Resume', data: { action: 'resume' } } ]} />
- ) : (
) - } + {/*) : (
)*/} + {/*}*/} < div style={{ clear: 'both' }} /> From 035e1defc78f04a9d44ee054f95022c06abfaa52 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Tue, 23 Feb 2021 11:38:15 +0100 Subject: [PATCH 15/25] IC actions start, stop, pause, resume working with correct params - start parameters of component config added to start action #285 - auto-creation of result and url for start action working #286 - model defaults to first file of component config for now #286 --- src/ic/ic-action.js | 13 +++---------- src/ic/ic-store.js | 6 ++---- src/ic/ics-data-manager.js | 33 ++++++++++++++++++++------------- src/scenario/scenario.js | 9 ++++----- 4 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/ic/ic-action.js b/src/ic/ic-action.js index b187c5e..33fe9a8 100644 --- a/src/ic/ic-action.js +++ b/src/ic/ic-action.js @@ -54,13 +54,6 @@ class ICAction extends React.Component { runAction(action, when) { - console.log("configs", this.props.configs) - console.log("selectedConfigs", this.props.selectedConfigs) - console.log("ics", this.props.ics) - console.log("selectedICs", this.props.selectedICs) - console.log("action", action) - console.log("when", when) - if (action.data.action === 'none') { console.warn("No command selected. Nothing was sent."); return; @@ -169,9 +162,10 @@ class ICAction extends React.Component { if (newAction.action === 'start') { newAction["parameters"] = config.startParameters; - newAction["model"] = {} + if (config.fileIDs.length > 0){ + newAction["model"] = {} newAction.model["type"] = "url" newAction.model["token"] = this.props.token // TODO do not default to the first file of the config @@ -187,7 +181,6 @@ class ICAction extends React.Component { // add the new action newActions.push(newAction); - console.log("New actions in loop", newAction, newActions) } // end for loop over selected configs @@ -204,7 +197,7 @@ class ICAction extends React.Component { } // create new result for new run - newResult.result["description"] = "Placeholder for description" + newResult.result["description"] = "Start at " + when; newResult.result["scenarioID"] = this.props.selectedConfigs[0].scenarioID newResult.result["configSnapshots"] = configSnapshots } diff --git a/src/ic/ic-store.js b/src/ic/ic-store.js index c6d0810..d2e00de 100644 --- a/src/ic/ic-store.js +++ b/src/ic/ic-store.js @@ -79,7 +79,6 @@ class InfrastructureComponentStore extends ArrayStore { case 'ics/action-result-added': for (let a of action.actions){ - let icid = Object.assign({}, a.icid) if (a.results !== undefined && a.results != null){ // adapt URL for newly created result ID @@ -87,13 +86,12 @@ class InfrastructureComponentStore extends ArrayStore { a.results.url = ICsDataManager.makeURL(a.results.url); a.results.url = window.location.host + a.results.url; } - if (a.model !== undefined && a.model != null) { + if (a.model !== undefined && a.model != null && JSON.stringify(a.model) !== JSON.stringify({})) { // adapt URL for model file a.model.url = ICsDataManager.makeURL(a.model.url); a.model.url = window.location.host + a.model.url; } - delete a.icid - ICsDataManager.doActions(icid, [a], action.token) + ICsDataManager.doActions(a.icid, [a], action.token) } return state; diff --git a/src/ic/ics-data-manager.js b/src/ic/ics-data-manager.js index a6a625d..a2382fc 100644 --- a/src/ic/ics-data-manager.js +++ b/src/ic/ics-data-manager.js @@ -25,15 +25,16 @@ class IcsDataManager extends RestDataManager { } doActions(icid, actions, token = null, result=null) { - for (let action of actions) { - if (action.when) - // Send timestamp as Unix Timestamp - action.when = Math.round(action.when.getTime() / 1000); - } - if (icid !== undefined && icid != null) { - console.log("doActions, icid:", icid) + if (icid !== undefined && icid != null && JSON.stringify(icid) !== JSON.stringify({})) { + + for (let action of actions) { + if (action.when) { + // Send timestamp as Unix Timestamp + action.when = Math.round(action.when.getTime() / 1000); + } + } // sending action to a specific IC via IC list RestAPI.post(this.makeURL(this.url + '/' + icid + '/action'), actions, token).then(response => { @@ -54,13 +55,14 @@ class IcsDataManager extends RestDataManager { if (actions[0].action !== "start"){ for (let a of actions){ - console.log("doActions, a.icid:", a.icid) - icid = JSON.parse(JSON.stringify(a.icid)) - delete a.icid - console.log("doActions, icid:", icid) - // sending action to a specific IC via IC list - RestAPI.post(this.makeURL(this.url + '/' + icid + '/action'), [a], token).then(response => { + // sending action to a specific IC via IC list + if (a.when) { + // Send timestamp as Unix Timestamp + a.when = Math.round(a.when.getTime() / 1000); + } + + RestAPI.post(this.makeURL(this.url + '/' + a.icid + '/action'), [a], token).then(response => { AppDispatcher.dispatch({ type: 'ics/action-started', data: response @@ -84,6 +86,11 @@ class IcsDataManager extends RestDataManager { actions: actions, token: token, }); + + AppDispatcher.dispatch({ + type: "results/added", + data: response.result, + }); }).catch(error => { AppDispatcher.dispatch({ type: 'ics/action-result-add-error', diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index cacb2db..ab65b82 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -302,7 +302,6 @@ class Scenario extends React.Component { } copyConfig(index) { - console.log("index", index, "copyConfig: ", this.state.configs[index]) let config = JSON.parse(JSON.stringify(this.state.configs[index])); let signals = JSON.parse(JSON.stringify(SignalStore.getState().filter(s => s.configID === parseInt(config.id, 10)))); @@ -665,7 +664,7 @@ class Scenario extends React.Component { }); } else { this.setState({ - modalResultConfigs: JSON.parse(result.configSnapshots), + modalResultConfigs: result.configSnapshots, modalResultConfigsIndex: result.id, resultConfigsModal: true }); @@ -873,7 +872,7 @@ class Scenario extends React.Component { /> - {/*{this.state.ExternalICInUse ? (*/} + {this.state.ExternalICInUse ? (
- {/*) : (
)*/} - {/*}*/} + ) : (
) + } < div style={{ clear: 'both' }} /> From e4b77b38c1d6826c0ce02637813c077ba8117630 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Tue, 23 Feb 2021 11:41:37 +0100 Subject: [PATCH 16/25] re-enable checkbox deactivation if IC is not managed externally (was turned off for testing) --- src/scenario/scenario.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index ab65b82..1f8dee2 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -827,8 +827,7 @@ class Scenario extends React.Component { this.usesExternalIC(index)} - checkboxDistabled={false} + checkboxDisabled={(index) => this.usesExternalIC(index)} onChecked={(index, event) => this.onConfigChecked(index, event)} width='30' /> From ac944a5beda0529b81745189074a72d52e93851c Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Tue, 23 Feb 2021 13:35:24 +0100 Subject: [PATCH 17/25] IC actions for delete, shutdown, reset are working; add notification for actions --- .../data-managers/notifications-factory.js | 8 +++++++ src/ic/ic-action.js | 21 ++++++++++++++++--- src/ic/ic-store.js | 4 ++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/common/data-managers/notifications-factory.js b/src/common/data-managers/notifications-factory.js index ece1e8b..a032db0 100644 --- a/src/common/data-managers/notifications-factory.js +++ b/src/common/data-managers/notifications-factory.js @@ -138,6 +138,14 @@ class NotificationsFactory { }; } + static ACTION_INFO() { + return { + title: 'Action successfully requested', + level: 'info' + }; + } + + } export default NotificationsFactory; diff --git a/src/ic/ic-action.js b/src/ic/ic-action.js index 33fe9a8..c2e4455 100644 --- a/src/ic/ic-action.js +++ b/src/ic/ic-action.js @@ -18,6 +18,8 @@ import React from 'react'; import { Button, DropdownButton, Dropdown, InputGroup, FormControl } from 'react-bootstrap'; import AppDispatcher from "../common/app-dispatcher"; +import NotificationsFactory from "../common/data-managers/notifications-factory"; +import NotificationsDataManager from "../common/data-managers/notifications-data-manager"; class ICAction extends React.Component { constructor(props) { @@ -92,13 +94,26 @@ class ICAction extends React.Component { if (newAction.action === "delete"){ // prepare parameters for delete incl. correct IC id newAction["parameters"] = {}; - newAction.parameters["uuid"] = ic.id; - icID = ic.manager; // send delete action to manager of IC + newAction.parameters["uuid"] = ic.uuid; + // get the ID of the manager IC + let managerIC = null; + for (let i of this.props.ics){ + if (i.uuid === ic.manager){ + managerIC = i; + } + } + if (managerIC == null){ + console.log("DELETE action", newAction); + NotificationsDataManager.addNotification(NotificationsFactory.DELETE_ERROR("Could not find manager IC with UUID " + ic.manager)); + continue; + } + + icID = managerIC.id; // send delete action to manager of IC } AppDispatcher.dispatch({ type: 'ics/start-action', - icid: ic.id, + icid: icID, action: newAction, result: null, token: this.props.token diff --git a/src/ic/ic-store.js b/src/ic/ic-store.js index d2e00de..39b1c8c 100644 --- a/src/ic/ic-store.js +++ b/src/ic/ic-store.js @@ -72,6 +72,10 @@ class InfrastructureComponentStore extends ArrayStore { ICsDataManager.doActions(action.icid, action.action, action.token, action.result); return state; + case 'ics/action-started': + NotificationsDataManager.addNotification(NotificationsFactory.ACTION_INFO()); + return state; + case 'ics/action-error': console.log(action.error); return state; From 939a168ce3e0a72ff50b340746efad3a8682eb25 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Tue, 23 Feb 2021 15:57:50 +0100 Subject: [PATCH 18/25] enable create action via add IC button for new externally managed IC --- src/ic/ic-action.js | 1 - src/ic/ics.js | 36 +++++++++++++++++++++++++++++++----- src/ic/new-ic.js | 2 +- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/ic/ic-action.js b/src/ic/ic-action.js index c2e4455..02d3a63 100644 --- a/src/ic/ic-action.js +++ b/src/ic/ic-action.js @@ -103,7 +103,6 @@ class ICAction extends React.Component { } } if (managerIC == null){ - console.log("DELETE action", newAction); NotificationsDataManager.addNotification(NotificationsFactory.DELETE_ERROR("Could not find manager IC with UUID " + ic.manager)); continue; } diff --git a/src/ic/ics.js b/src/ic/ics.js index 9c1f2db..95d224f 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -36,6 +36,8 @@ import ICDialog from './ic-dialog'; import ICAction from './ic-action'; import DeleteDialog from '../common/dialogs/delete-dialog'; +import NotificationsDataManager from "../common/data-managers/notifications-data-manager"; +import NotificationsFactory from "../common/data-managers/notifications-factory"; class InfrastructureComponents extends Component { static getStores() { @@ -149,11 +151,35 @@ class InfrastructureComponents extends Component { this.setState({ newModal : false }); if (data) { - AppDispatcher.dispatch({ - type: 'ics/start-add', - data, - token: this.state.sessionToken, - }); + if (!data.managedexternally) { + AppDispatcher.dispatch({ + type: 'ics/start-add', + data, + token: this.state.sessionToken, + }); + } else { + // externally managed IC: dispatch create action to selected manager + let newAction = {}; + newAction["action"] = "create"; + newAction["parameters"] = data; + newAction["when"] = new Date() + + // find the manager IC + let managerIC = this.state.ics.find(ic => ic.uuid === data.manager) + if (managerIC === null || managerIC === undefined){ + NotificationsDataManager.addNotification(NotificationsFactory.ADD_ERROR("Could not find manager IC with UUID " + data.manager)); + return; + } + + AppDispatcher.dispatch({ + type: 'ics/start-action', + icid: managerIC.id, + action: newAction, + result: null, + token: this.state.sessionToken + }); + + } } } diff --git a/src/ic/new-ic.js b/src/ic/new-ic.js index 2e81887..39aeebd 100644 --- a/src/ic/new-ic.js +++ b/src/ic/new-ic.js @@ -170,7 +170,7 @@ class NewICDialog extends React.Component { {this.props.managers.length > 0 ? <> - An externally managed component is created and managed by an IC manager via AMQP} > + An externally managed component is created and managed by an IC manager via AMQP} > this.handleChange(e)}> From e22c0ca6592dedd44bdabfd6f1328bbacc852351 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Tue, 23 Feb 2021 17:19:43 +0100 Subject: [PATCH 19/25] clean up and improve code structure of table --- src/common/table.js | 115 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 97 insertions(+), 18 deletions(-) diff --git a/src/common/table.js b/src/common/table.js index 8774d10..5471244 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -79,9 +79,19 @@ class CustomTable extends Component { cell.push(); } else if (linkKey === 'filebuttons') { content.forEach((contentvalue, contentkey) => { - cell.push(Download {contentvalue}} > - ); + cell.push( + Download {contentvalue}} > + + ); }); } else { cell.push(content); @@ -115,9 +125,18 @@ class CustomTable extends Component { // add buttons if (child.props.editButton) { - let disable = (typeof data.managedexternally !== "undefined" && data.managedexternally); - cell.push({disable ? "Externally managed ICs cannot be edited" : "edit"} } > - ); + cell.push( + Edit }> + + ); } if (child.props.checkbox) { @@ -137,28 +156,78 @@ class CustomTable extends Component { } if (child.props.exportButton) { - cell.push( Export } > - ); + cell.push( + Export } > + + ); } if (child.props.duplicateButton) { - cell.push( Duplicate } > - ); + cell.push( + Duplicate } > + + ); } if (child.props.addRemoveFilesButton) { - cell.push(Add/remove File(s)} > - ); + cell.push( + Add/remove File(s)} > + + ); } if (child.props.downloadAllButton) { - cell.push(Download All Files} > - ); + cell.push( + Download All Files} > + + ); } if (child.props.deleteButton) { - cell.push( Delete } > - ); + cell.push( + Delete } > + + ); } return cell; @@ -244,9 +313,19 @@ class CustomTable extends Component { onCellBlur: () => { } }; - return (
+ return ( {(this.state.editCell[0] === cellIndex && this.state.editCell[1] === rowIndex) ? ( - children[cellIndex].props.onInlineChange(event, rowIndex, cellIndex)} ref={ref => { this.activeInput = ref; }} /> + children[cellIndex].props.onInlineChange(event, rowIndex, cellIndex)} + ref={ref => { this.activeInput = ref; }} /> ) : ( {cell.map((element, elementIndex) => ( From 64e504b939862ebcacf3522bc66fc06591eacf2d Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Tue, 23 Feb 2021 17:25:22 +0100 Subject: [PATCH 20/25] fix determination of external IC in IC table --- src/ic/ics.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ic/ics.js b/src/ic/ics.js index 95d224f..6024e10 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -393,8 +393,8 @@ class InfrastructureComponents extends Component { } } - isExternalIC(index){ - let ic = this.state.ics[index] + isExternalIC(index, ics){ + let ic = ics[index] return ic.managedexternally } @@ -405,7 +405,7 @@ class InfrastructureComponents extends Component { this.isExternalIC(index)} + checkboxDisabled={(index) => this.isExternalIC(index, ics)} onChecked={(ic, event) => this.onICChecked(ic, event)} width='30' /> @@ -438,9 +438,9 @@ class InfrastructureComponents extends Component { {this.state.currentUser.role === "Admin" ? !this.isExternalIC(index)} + editButton = {(index) => !this.isExternalIC(index, ics)} exportButton - deleteButton = {(index) => !this.isExternalIC(index)} + deleteButton = {(index) => !this.isExternalIC(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})} From a4223aa6d0f24d2295d6cfc6cc42edc6ca15b729 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 24 Feb 2021 11:28:46 +0100 Subject: [PATCH 21/25] another fix for determination of external IC in IC table, edit and delete buttons should not show in case of external ic --- src/ic/ics.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ic/ics.js b/src/ic/ics.js index 6024e10..026695b 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -405,7 +405,7 @@ class InfrastructureComponents extends Component {
this.isExternalIC(index, ics)} + checkboxDisabled={(index) => this.isExternalIC(index, ics) === true} onChecked={(ic, event) => this.onICChecked(ic, event)} width='30' /> @@ -438,9 +438,9 @@ class InfrastructureComponents extends Component { {this.state.currentUser.role === "Admin" ? !this.isExternalIC(index, ics)} + editButton = {(index) => this.isExternalIC(index, ics) !== true} exportButton - deleteButton = {(index) => !this.isExternalIC(index, ics)} + deleteButton = {(index) => this.isExternalIC(index, ics) !== true} 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})} From d4b9acd08d4a6e0352e0a3a7ebacfb1d981161f6 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 24 Feb 2021 12:32:07 +0100 Subject: [PATCH 22/25] check if true for editButton and deleteButton --- src/common/table.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/table.js b/src/common/table.js index 5471244..d5c750c 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -124,7 +124,7 @@ class CustomTable extends Component { } // add buttons - if (child.props.editButton) { + if (child.props.editButton === true) { cell.push( ); } - if (child.props.deleteButton) { + if (child.props.deleteButton === true) { cell.push( Date: Wed, 24 Feb 2021 12:40:12 +0100 Subject: [PATCH 23/25] START command: Use a list of urls for all associated files instead of just one file --- src/ic/ic-action.js | 8 ++++++-- src/ic/ic-store.js | 11 ++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/ic/ic-action.js b/src/ic/ic-action.js index 02d3a63..2d08af4 100644 --- a/src/ic/ic-action.js +++ b/src/ic/ic-action.js @@ -182,8 +182,12 @@ class ICAction extends React.Component { newAction["model"] = {} newAction.model["type"] = "url" newAction.model["token"] = this.props.token - // TODO do not default to the first file of the config - newAction.model["url"] = "/files/" + config.fileIDs[0].toString() + + let fileURLs = [] + for (let fileID of config.fileIDs){ + fileURLs.push("/files/" + fileID.toString()) + } + newAction.model["url"] = fileURLs } newAction["results"] = {} diff --git a/src/ic/ic-store.js b/src/ic/ic-store.js index 39b1c8c..36abb91 100644 --- a/src/ic/ic-store.js +++ b/src/ic/ic-store.js @@ -91,9 +91,14 @@ class InfrastructureComponentStore extends ArrayStore { a.results.url = window.location.host + a.results.url; } if (a.model !== undefined && a.model != null && JSON.stringify(a.model) !== JSON.stringify({})) { - // adapt URL for model file - a.model.url = ICsDataManager.makeURL(a.model.url); - a.model.url = window.location.host + a.model.url; + // adapt URL(s) for model file + let modelURLs = [] + for (let url of a.model.url){ + let modifiedURL = ICsDataManager.makeURL(url); + modifiedURL = window.location.host + modifiedURL; + modelURLs.push(modifiedURL) + } + a.model.url = modelURLs } ICsDataManager.doActions(a.icid, [a], action.token) } From 27c3b2dffad085dff813e2feea803f89c985d5e7 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 24 Feb 2021 13:41:07 +0100 Subject: [PATCH 24/25] fixed column indexes of edit signal mapping dialog (shifted because of additional checkbox column) --- src/signal/edit-signal-mapping.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/signal/edit-signal-mapping.js b/src/signal/edit-signal-mapping.js index b1df22c..3b75386 100644 --- a/src/signal/edit-signal-mapping.js +++ b/src/signal/edit-signal-mapping.js @@ -97,23 +97,24 @@ class EditSignalMapping extends React.Component { let signals = this.state.signals; let modifiedSignals = this.state.modifiedSignalIDs; - - if (column === 1) { // Name change + console.log("HandleMappingChange", row, column) + if (column === 2) { // Name change signals[row].name = event.target.value; if (modifiedSignals.find(id => id === signals[row].id) === undefined){ modifiedSignals.push(signals[row].id); } - } else if (column === 2) { // unit change + } else if (column === 3) { // unit change signals[row].unit = event.target.value; if (modifiedSignals.find(id => id === signals[row].id) === undefined){ modifiedSignals.push(signals[row].id); } - } else if (column === 3) { // scaling factor change + } else if (column === 4) { // scaling factor change signals[row].scalingFactor = parseFloat(event.target.value); if (modifiedSignals.find(id => id === signals[row].id) === undefined){ modifiedSignals.push(signals[row].id); } - } else if (column === 0) { //index change + } else if (column === 1) { //index change + console.log("Index change") signals[row].index =parseInt(event.target.value, 10); if (modifiedSignals.find(id => id === signals[row].id) === undefined){ modifiedSignals.push(signals[row].id); From 1c0a2403d294b219cac065ef04f019f55e8eaac2 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Thu, 25 Feb 2021 10:31:11 +0100 Subject: [PATCH 25/25] disable showing of edit and delete button through additional table column parameter --- src/common/table-column.js | 2 ++ src/common/table.js | 71 +++++++++++++++++++++++--------------- src/ic/ics.js | 12 ++++--- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/common/table-column.js b/src/common/table-column.js index 9d77606..460eb4b 100644 --- a/src/common/table-column.js +++ b/src/common/table-column.js @@ -23,7 +23,9 @@ class TableColumn extends Component { modifier: null, width: null, editButton: false, + showEditButton: null, deleteButton: false, + showDeleteButton: null, exportButton: false, duplicateButton: false, link: '/', diff --git a/src/common/table.js b/src/common/table.js index d5c750c..f54335e 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -124,26 +124,34 @@ class CustomTable extends Component { } // add buttons - if (child.props.editButton === true) { - cell.push( - Edit }> - - ); + let showEditButton = true + if (child.props.showEditButton !== null) + { + showEditButton = child.props.showEditButton(index) } + if(showEditButton){ + if (child.props.editButton) { + cell.push( + Edit }> + + ); + } + } + if (child.props.checkbox) { const checkboxKey = child.props.checkboxKey; let isDisabled = false; if (child.props.checkboxDisabled != null){ - isDisabled = !child.props.checkboxDisabled(index) + isDisabled = child.props.checkboxDisabled(index) } cell.push( ); } - if (child.props.deleteButton === true) { - cell.push( - Delete } > - - ); + let showDeleteButton = true; + if (child.props.showDeleteButton !== null){ + showDeleteButton = child.props.showDeleteButton(index) } + if (showDeleteButton){ + if (child.props.deleteButton) { + cell.push( + Delete } > + + ); + } + } + + + return cell; } // addCell diff --git a/src/ic/ics.js b/src/ic/ics.js index 026695b..bb97ef1 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -393,9 +393,9 @@ class InfrastructureComponents extends Component { } } - isExternalIC(index, ics){ + isLocalIC(index, ics){ let ic = ics[index] - return ic.managedexternally + return !ic.managedexternally } getICCategoryTable(ics, editable, title){ @@ -405,7 +405,7 @@ class InfrastructureComponents extends Component {
this.isExternalIC(index, ics) === true} + checkboxDisabled={(index) => this.isLocalIC(index, ics) === true} onChecked={(ic, event) => this.onICChecked(ic, event)} width='30' /> @@ -438,9 +438,11 @@ class InfrastructureComponents extends Component { {this.state.currentUser.role === "Admin" ? this.isExternalIC(index, ics) !== true} + editButton + showEditButton ={(index) => this.isLocalIC(index, ics)} exportButton - deleteButton = {(index) => this.isExternalIC(index, ics) !== true} + deleteButton + showDeleteButton = {(index) => this.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})}