From c20f783689803b74248c284a4d30ccd5f360bd5b Mon Sep 17 00:00:00 2001 From: irismarie Date: Fri, 9 Apr 2021 19:22:12 +0200 Subject: [PATCH 01/13] lock scenarios as admin user, see #309 --- src/common/icon-button.js | 1 + src/common/table-column.js | 2 + src/common/table.js | 10 +- src/componentconfig/config-table.js | 5 + src/dashboard/dashboard-button-group.js | 5 +- src/dashboard/dashboard-table.js | 3 + src/dashboard/dashboard.js | 19 +++- src/file/edit-files.js | 13 ++- src/result/result-table.js | 2 + src/scenario/scenario-users-table.js | 2 + src/scenario/scenario.js | 9 +- src/scenario/scenarios.js | 123 ++++++++++++++---------- 12 files changed, 130 insertions(+), 64 deletions(-) diff --git a/src/common/icon-button.js b/src/common/icon-button.js index a905dd1..1f9ed33 100644 --- a/src/common/icon-button.js +++ b/src/common/icon-button.js @@ -42,6 +42,7 @@ class IconButton extends React.Component { variant='light' onClick={this.props.onClick} style={altButtonStyle} + disabled={this.props.disabled} > child.props.onEdit(index)} - disabled={child.props.onEdit == null} > + disabled={child.props.onEdit == null || isLocked} > @@ -190,7 +192,7 @@ class CustomTable extends Component { @@ -206,7 +208,7 @@ class CustomTable extends Component { @@ -242,7 +244,7 @@ class CustomTable extends Component { diff --git a/src/componentconfig/config-table.js b/src/componentconfig/config-table.js index f18fb6d..476f680 100644 --- a/src/componentconfig/config-table.js +++ b/src/componentconfig/config-table.js @@ -308,12 +308,14 @@ class ConfigTable extends Component { tooltip='Add Component Configuration' onClick={() => this.addConfig()} icon='plus' + disabled={this.props.locked} /> this.setState({ importConfigModal: true })} icon='upload' + disabled={this.props.locked} /> @@ -343,6 +345,7 @@ class ConfigTable extends Component { editButton onEdit={index => this.setState({ editOutputSignalsModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })} width={150} + locked={this.props.locked} /> this.setState({ editInputSignalsModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })} width={150} + locked={this.props.locked} /> this.setState({ deleteConfigModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })} onExport={index => this.exportConfig(index)} onDuplicate={index => this.duplicateConfig(index)} + locked={this.props.locked} /> diff --git a/src/dashboard/dashboard-button-group.js b/src/dashboard/dashboard-button-group.js index be73aad..a2b7b5f 100644 --- a/src/dashboard/dashboard-button-group.js +++ b/src/dashboard/dashboard-button-group.js @@ -91,9 +91,10 @@ class DashboardButtonGroup extends React.Component { } if (this.props.fullscreen !== true) { + let filesTooltip = this.props.locked ? "View files of scenario" : "Add, edit or delete files of scenario"; buttons.push( Add, edit or delete files of scenario }> + overlay={{filesTooltip}}> @@ -120,7 +121,7 @@ class DashboardButtonGroup extends React.Component { buttons.push( Add widgets and edit layout }> - diff --git a/src/dashboard/dashboard-table.js b/src/dashboard/dashboard-table.js index cb96fdb..7728d78 100644 --- a/src/dashboard/dashboard-table.js +++ b/src/dashboard/dashboard-table.js @@ -148,12 +148,14 @@ class DashboardTable extends Component { tooltip='Add Dashboard' onClick={() => this.setState({newDashboardModal: true})} icon='plus' + disabled={this.props.locked} /> this.setState({importDashboardModal: true})} icon='upload' + disabled={this.props.locked} /> @@ -198,6 +200,7 @@ class DashboardTable extends Component { })} onExport={index => this.exportDashboard(index)} onDuplicate={index => this.duplicateDashboard(index)} + locked={this.props.locked} /> diff --git a/src/dashboard/dashboard.js b/src/dashboard/dashboard.js index 8ed06ac..a68363a 100644 --- a/src/dashboard/dashboard.js +++ b/src/dashboard/dashboard.js @@ -35,6 +35,8 @@ import WidgetStore from '../widget/widget-store'; import ICStore from '../ic/ic-store' import ConfigStore from '../componentconfig/config-store' import AppDispatcher from '../common/app-dispatcher'; +import ScenarioStore from '../scenario/scenario-store'; + import 'react-contexify/dist/ReactContexify.min.css'; import WidgetContainer from '../widget/widget-container'; @@ -45,7 +47,7 @@ class Dashboard extends Component { static lastWidgetKey = 0; static webSocketsOpened = false; static getStores() { - return [DashboardStore, FileStore, WidgetStore, SignalStore, ConfigStore, ICStore]; + return [DashboardStore, FileStore, WidgetStore, SignalStore, ConfigStore, ICStore, ScenarioStore]; } static calculateState(prevState, props) { @@ -80,9 +82,14 @@ class Dashboard extends Component { // filter component configurations to the ones that belong to this scenario let configs = []; let files = []; + let locked = false; if (dashboard !== undefined) { configs = ConfigStore.getState().filter(config => config.scenarioID === dashboard.scenarioID); files = FileStore.getState().filter(file => file.scenarioID === dashboard.scenarioID); + let scenario = ScenarioStore.getState().find(s => s.id === dashboard.scenarioID); + if (scenario) { + locked = scenario.isLocked; + } if (dashboard.height === 0) { dashboard.height = 400; } @@ -144,6 +151,7 @@ class Dashboard extends Component { widgetOrigIDs: prevState.widgetOrigIDs || [], maxWidgetHeight: maxHeight || null, + locked, }; } @@ -205,6 +213,13 @@ class Dashboard extends Component { param: '?scenarioID=' + this.state.dashboard.scenarioID, token: this.state.sessionToken }); + + // load scenario for 'isLocked' value + AppDispatcher.dispatch({ + type: 'scenarios/start-load', + data: this.state.dashboard.scenarioID, + token: this.state.sessionToken + }); } } @@ -482,6 +497,7 @@ class Dashboard extends Component { this.onClose()} blendOutCancel = {true} @@ -139,6 +141,7 @@ class EditFilesDialog extends React.Component { onDelete={(index) => this.deleteFile(index)} editButton onEdit={index => this.setState({ editModal: true, modalFile: this.props.files[index] })} + locked={this.props.locked} /> @@ -146,13 +149,17 @@ class EditFilesDialog extends React.Component {
Add file
- this.selectUploadFile(event)} /> + this.selectUploadFile(event)} + disabled={this.props.locked} + /> diff --git a/src/result/result-table.js b/src/result/result-table.js index 92b8b62..4b81427 100644 --- a/src/result/result-table.js +++ b/src/result/result-table.js @@ -165,6 +165,7 @@ class ResultTable extends Component { tooltip='Add Result' onClick={() => this.setState({ newResultModal: true })} icon='plus' + disabled={this.props.locked} /> @@ -208,6 +209,7 @@ class ResultTable extends Component { onEdit={index => this.setState({ editResultsModal: true, modalResultsIndex: index })} onDownloadAll={(index) => this.downloadResultData(this.props.results[index])} onDelete={(index) => this.setState({ deleteResultsModal: true, modalResultsData: this.props.results[index], modalResultsIndex: index })} + locked={this.props.locked} /> diff --git a/src/scenario/scenario-users-table.js b/src/scenario/scenario-users-table.js index c93b356..f6e7b7a 100644 --- a/src/scenario/scenario-users-table.js +++ b/src/scenario/scenario-users-table.js @@ -124,6 +124,7 @@ class ScenarioUsersTable extends Component { deleteUserName: this.props.scenario.users[index].username, modalUserIndex: index })} + locked={this.props.locked} /> @@ -145,6 +146,7 @@ class ScenarioUsersTable extends Component { variant='light' type="submit" style={altButtonStyle} + disabled={this.props.locked} onClick={() => this.addUser()}> diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 1e1033c..066f24f 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -126,11 +126,13 @@ class Scenario extends React.Component { return

Loading Scenario...

; } + let tooltip = this.state.scenario.isLocked ? "View files of scenario" : "Add, edit or delete files of scenario"; + return
@@ -144,6 +146,7 @@ class Scenario extends React.Component { signals={this.state.signals} files={this.state.files} scenarioID={this.state.scenario.id} + locked={this.state.scenario.isLocked} />
diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index 9d81a74..1e9df38 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -73,7 +73,7 @@ class Scenarios extends Component { } closeNewModal(data) { - if(data) { + if (data) { AppDispatcher.dispatch({ type: 'scenarios/start-add', data: data, @@ -218,7 +218,7 @@ class Scenarios extends Component { jsonObj["configs"] = this.getConfigs(scenario.id); jsonObj["dashboards"] = this.getDashboards(scenario.id); - if(jsonObj) { + if (jsonObj) { AppDispatcher.dispatch({ type: 'scenarios/start-add', data: jsonObj, @@ -227,68 +227,85 @@ class Scenarios extends Component { } } - modifyRunningColumn(running){ - return + isLocked(index) { + return this.state.scenarios[index].isLocked; + } + + onLock(scenario) { + let data = {}; + data.id = scenario.id; + data.isLocked = !scenario.isLocked; + + AppDispatcher.dispatch({ + type: 'scenarios/start-edit', + data, + token: this.state.sessionToken + }); } render() { return
-

Scenarios +

Scenarios - this.setState({ newModal: true })} - icon='plus' - /> - this.setState({ importModal: true })} - icon='upload' - /> - -

- - - {this.state.currentUser.role === "Admin" ? - - : <> - } - this.setState({ newModal: true })} + icon='plus' /> - this.modifyRunningColumn(running)} + this.setState({ importModal: true })} + icon='upload' /> + + + +
+ {this.state.currentUser.role === "Admin" ? this.setState({ editModal: true, modalScenario: this.state.scenarios[index] })} - onDelete={index => this.setState({ deleteModal: true, modalScenario: this.state.scenarios[index] })} - onExport={index => this.exportScenario(index)} - onDuplicate={index => this.duplicateScenario(index)} + title='ID' + dataKey='id' /> -
+ : <> + } + + {this.state.currentUser.role === "Admin" ? + this.onLock(index)} + /> + : <> + } + this.setState({ editModal: true, modalScenario: this.state.scenarios[index] })} + onDelete={index => this.setState({ deleteModal: true, modalScenario: this.state.scenarios[index] })} + onExport={index => this.exportScenario(index)} + onDuplicate={index => this.duplicateScenario(index)} + isLocked={index => this.isLocked(index)} + /> + - this.closeNewModal(data)} /> - this.closeEditModal(data)} scenario={this.state.modalScenario} /> - this.closeImportModal(data)} nodes={this.state.nodes} /> + this.closeNewModal(data)} /> + this.closeEditModal(data)} scenario={this.state.modalScenario} /> + this.closeImportModal(data)} nodes={this.state.nodes} /> - this.closeDeleteModal(e)} /> -
; + this.closeDeleteModal(e)} /> +
; } } From 662e3949adafffc1a246dcc514f5cd148751968b Mon Sep 17 00:00:00 2001 From: irismarie Date: Tue, 13 Apr 2021 15:22:19 +0200 Subject: [PATCH 02/13] changed button for signal autoconf, see #250 --- src/common/table-column.js | 1 + src/common/table.js | 17 +++++++++++++++++ src/componentconfig/config-table.js | 8 ++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/common/table-column.js b/src/common/table-column.js index 887d70b..042010b 100644 --- a/src/common/table-column.js +++ b/src/common/table-column.js @@ -27,6 +27,7 @@ class TableColumn extends Component { deleteButton: false, showDeleteButton: null, exportButton: false, + signalButton: false, duplicateButton: false, isLocked: null, locked: false, diff --git a/src/common/table.js b/src/common/table.js index 7ea7d1f..09a9b4a 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -183,6 +183,23 @@ class CustomTable extends Component { ); } + if (child.props.signalButton) { + cell.push( + Autoconfigure Signals } + > + + + ); + } + if (child.props.duplicateButton) { cell.push( this.signalsAutoConf(index)} - width={150} + title='Autoconfigure Signals' + signalButton + onAutoConf={(index) => this.signalsAutoConf(index)} + width={170} /> Date: Tue, 13 Apr 2021 17:54:50 +0200 Subject: [PATCH 03/13] disable signal buttons, #309 --- src/dashboard/dashboard-button-group.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dashboard/dashboard-button-group.js b/src/dashboard/dashboard-button-group.js index a2b7b5f..ba63cfe 100644 --- a/src/dashboard/dashboard-button-group.js +++ b/src/dashboard/dashboard-button-group.js @@ -103,7 +103,7 @@ class DashboardButtonGroup extends React.Component { buttons.push( Add, edit or delete input signals }> - @@ -112,7 +112,7 @@ class DashboardButtonGroup extends React.Component { buttons.push( Add, edit or delete output signals }> - From bddbadf9aca529ce11bff775cbf63bbc99d75159 Mon Sep 17 00:00:00 2001 From: irismarie Date: Wed, 14 Apr 2021 13:16:13 +0200 Subject: [PATCH 04/13] show/change locked status of scenario --- package.json | 5 ++- src/common/icon-toggle-button.js | 76 ++++++++++++++++++++++++++++++++ src/scenario/scenario.js | 42 +++++++++++++++--- 3 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 src/common/icon-toggle-button.js diff --git a/package.json b/package.json index 6954861..f7ba094 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@fortawesome/fontawesome-svg-core": "^1.2.34", "@fortawesome/free-solid-svg-icons": "^5.15.2", "@fortawesome/react-fontawesome": "^0.1.14", + "@rjsf/core": "^2.5.1", "babel-runtime": "^6.26.0", "bootstrap": "^4.6.0", "classnames": "^2.2.6", @@ -23,8 +24,8 @@ "gaugeJS": "^1.3.7", "handlebars": "^4.7.7", "jquery": "^3.6.0", - "jszip": "^3.6.0", "jsonwebtoken": "^8.5.1", + "jszip": "^3.6.0", "libcimsvg": "git+https://git.rwth-aachen.de/acs/public/cim/pintura-npm-package.git", "lodash": "^4.17.21", "moment": "^2.29.1", @@ -61,7 +62,7 @@ "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }, - "proxy": "https://villas.k8s.eonerc.rwth-aachen.de", + "proxy": "http://localhost:4000", "browserslist": { "production": [ ">0.2%", diff --git a/src/common/icon-toggle-button.js b/src/common/icon-toggle-button.js new file mode 100644 index 0000000..44613f6 --- /dev/null +++ b/src/common/icon-toggle-button.js @@ -0,0 +1,76 @@ +/** + * 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 { ToggleButton, ButtonGroup, Tooltip, OverlayTrigger } from 'react-bootstrap'; + +import Icon from './icon'; + + +class IconToggleButton extends React.Component { + + render() { + const altButtonStyle = { + marginLeft: '20px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } + + return + {this.props.checked ? + this.props.tooltipChecked + : + this.props.tooltipUnchecked + } + } > + + + {this.props.checked ? + + : + + } + + + + } +} + +export default IconToggleButton; diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 066f24f..d9d76d7 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -20,6 +20,7 @@ import { Container } from 'flux/utils'; import AppDispatcher from '../common/app-dispatcher'; import IconButton from '../common/icon-button'; +import IconToggleButton from '../common/icon-toggle-button'; import ScenarioStore from './scenario-store'; import ICStore from '../ic/ic-store'; @@ -52,6 +53,7 @@ class Scenario extends React.Component { let scenarioID = parseInt(props.match.params.scenario, 10) return{ + sessionToken: localStorage.getItem("token"), scenario: ScenarioStore.getState().find(s => s.id === scenarioID), results: ResultStore.getState().filter(result => result.scenarioID === scenarioID), sessionToken: localStorage.getItem("token"), @@ -70,26 +72,24 @@ class Scenario extends React.Component { } componentDidMount() { - - let token = localStorage.getItem("token") let scenarioID = parseInt(this.props.match.params.scenario, 10) //load selected scenario AppDispatcher.dispatch({ type: 'scenarios/start-load', data: scenarioID, - token: token + token: this.state.sessionToken }); AppDispatcher.dispatch({ type: 'scenarios/start-load-users', data: scenarioID, - token: token + token: this.state.sessionToken }); // load ICs to enable that component configs and dashboards work with them AppDispatcher.dispatch({ type: 'ics/start-load', - token: token + token: this.state.sessionToken }); } @@ -112,6 +112,22 @@ class Scenario extends React.Component { this.setState({ filesEditModal: false }); } + /* ############################################## + * Change locked state of scenario + ############################################## */ + + onChangeLock() { + let data = {}; + data.id = this.state.scenario.id; + data.isLocked = !this.state.scenario.isLocked; + + AppDispatcher.dispatch({ + type: 'scenarios/start-edit', + data, + token: this.state.sessionToken + }); + } + /* ############################################## * Render method ############################################## */ @@ -137,7 +153,21 @@ class Scenario extends React.Component { icon="file" /> -

{this.state.scenario.name}

+

+ {this.state.scenario.name} + + this.onChangeLock()} + checked={this.state.scenario.isLocked} + checkedIcon='lock' + uncheckedIcon='lock-open' + tooltipChecked='Scenario is locked, cannot be edited' + tooltipUnchecked='Scenario is unlocked, can be edited' + disabled={this.state.currentUser.role !== "Admin"} + /> + +

Date: Thu, 15 Apr 2021 11:23:10 +0200 Subject: [PATCH 05/13] add locking button in scenarios table --- src/common/icon-toggle-button.js | 9 +-------- src/common/table.js | 25 ++++++++++++++++++++---- src/scenario/scenario-users-table.js | 29 ++++++++++------------------ src/scenario/scenarios.js | 11 ++++++----- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/common/icon-toggle-button.js b/src/common/icon-toggle-button.js index 44613f6..cd421e0 100644 --- a/src/common/icon-toggle-button.js +++ b/src/common/icon-toggle-button.js @@ -26,12 +26,7 @@ class IconToggleButton extends React.Component { render() { const altButtonStyle = { - marginLeft: '20px', - } - - const iconStyle = { - height: '30px', - width: '30px' + marginLeft: '10px', } return : } diff --git a/src/common/table.js b/src/common/table.js index 09a9b4a..6d36367 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -20,6 +20,8 @@ import _ from 'lodash'; import { Table, Button, Form, Tooltip, OverlayTrigger } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import Icon from './icon'; +import IconToggleButton from './icon-toggle-button'; + class CustomTable extends Component { constructor(props) { @@ -128,7 +130,7 @@ class CustomTable extends Component { let isLocked = child.props.locked || (child.props.isLocked != null && child.props.isLocked(index)); // add buttons - let showEditButton = child.props.showEditButton !== null && child.props.showEditButton !== undefined + let showEditButton = child.props.showEditButton !== null && child.props.showEditButton !== undefined ? child.props.showEditButton(index) : true; @@ -166,6 +168,21 @@ class CustomTable extends Component { ); } + if (child.props.lockButton) { + cell.push( + child.props.onChangeLock(index)} + checked={isLocked} + checkedIcon='lock' + uncheckedIcon='lock-open' + tooltipChecked='Scenario is locked, cannot be edited' + tooltipUnchecked='Scenario is unlocked, can be edited' + disabled={false} + /> + ); + } + if (child.props.exportButton) { cell.push( children[cellIndex].props.onInlineChange(event, rowIndex, cellIndex)} ref={ref => { this.activeInput = ref; }} /> - : + : { cell.map((element, elementIndex) => {element} ) } - } + } }) } diff --git a/src/scenario/scenario-users-table.js b/src/scenario/scenario-users-table.js index f6e7b7a..26eb06f 100644 --- a/src/scenario/scenario-users-table.js +++ b/src/scenario/scenario-users-table.js @@ -16,11 +16,11 @@ ******************************************************************************/ import React, {Component} from "react"; -import {Button, Form, InputGroup} from "react-bootstrap"; +import { Form, InputGroup} from "react-bootstrap"; import {Redirect} from "react-router-dom"; import Table from "../common/table"; import TableColumn from "../common/table-column"; -import Icon from "../common/icon"; +import IconButton from "../common/icon-button"; import DeleteDialog from "../common/dialogs/delete-dialog"; import AppDispatcher from "../common/app-dispatcher"; @@ -82,15 +82,6 @@ class ScenarioUsersTable extends Component { return (); } - const altButtonStyle = { - marginLeft: '10px', - } - - const iconStyle = { - height: '30px', - width: '30px' - } - return (
{/*Scenario Users table*/} @@ -142,14 +133,14 @@ class ScenarioUsersTable extends Component { /> - + this.addUser()} + icon='plus' + disabled={this.props.locked} + hidetooltip={this.props.locked} + /> diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index 1e9df38..7f9c45b 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -231,10 +231,10 @@ class Scenarios extends Component { return this.state.scenarios[index].isLocked; } - onLock(scenario) { + onLock(index) { let data = {}; - data.id = scenario.id; - data.isLocked = !scenario.isLocked; + data.id = this.state.scenarios[index].id; + data.isLocked = !this.state.scenarios[index].isLocked; AppDispatcher.dispatch({ type: 'scenarios/start-edit', @@ -279,9 +279,10 @@ class Scenarios extends Component { {this.state.currentUser.role === "Admin" ? this.onLock(index)} + onChangeLock={(index, event) => this.onLock(index)} + isLocked={index => this.isLocked(index)} /> : <> } From 1b2e5d0bdd5a752acdf2276fadf3a1d507157165 Mon Sep 17 00:00:00 2001 From: irismarie Date: Fri, 16 Apr 2021 14:08:52 +0200 Subject: [PATCH 06/13] show locked state on Dashboard page --- src/dashboard/dashboard.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/dashboard/dashboard.js b/src/dashboard/dashboard.js index a68363a..9462bad 100644 --- a/src/dashboard/dashboard.js +++ b/src/dashboard/dashboard.js @@ -27,6 +27,7 @@ import WidgetContextMenu from '../widget/widget-context-menu'; import WidgetToolbox from '../widget/widget-toolbox'; import WidgetArea from '../widget/widget-area'; import DashboardButtonGroup from './dashboard-button-group'; +import IconToggleButton from '../common/icon-toggle-button'; import DashboardStore from './dashboard-store'; import SignalStore from '../signal/signal-store' @@ -493,7 +494,20 @@ class Dashboard extends Component { return (
-

{this.state.dashboard.name}

+

+ {this.state.dashboard.name} + + + +

Date: Fri, 16 Apr 2021 17:40:15 +0200 Subject: [PATCH 07/13] use IconButton in DashboardButtonGroup --- src/common/icon-button.js | 43 ++++--- src/dashboard/dashboard-button-group.js | 144 +++++++++--------------- 2 files changed, 79 insertions(+), 108 deletions(-) diff --git a/src/common/icon-button.js b/src/common/icon-button.js index 1f9ed33..e4876c9 100644 --- a/src/common/icon-button.js +++ b/src/common/icon-button.js @@ -34,23 +34,32 @@ class IconButton extends React.Component { width: '30px' } - return {this.props.tooltip}} > - - + let btn = + + let button; + if (!this.props.tooltip || this.props.hidetooltip) { + button = btn; + } else { + button = {this.props.tooltip}} > + {btn} + + } + + return button; } } diff --git a/src/dashboard/dashboard-button-group.js b/src/dashboard/dashboard-button-group.js index ba63cfe..6f9843a 100644 --- a/src/dashboard/dashboard-button-group.js +++ b/src/dashboard/dashboard-button-group.js @@ -17,115 +17,77 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Button,OverlayTrigger, Tooltip } from 'react-bootstrap'; -import Icon from "../common/icon"; +import IconButton from '../common/icon-button'; + +const buttonStyle = { + marginLeft: '12px', + height: '44px', + width: '35px', +}; + +const iconStyle = { + height: '25px', + width: '25px' +} + +let buttonkey = 0; class DashboardButtonGroup extends React.Component { - render() { - const buttonStyle = { - marginLeft: '12px', - height: '44px', - width : '35px', - }; - const iconStyle = { - height: '25px', - width : '25px' + getBtn(icon, tooltip, clickFn, locked = false) { + if (locked) { + return + } else { + return } + } + render() { const buttons = []; - let key = 0; - - /*if (this.props.fullscreen) { - return null; - }*/ + key = 0; if (this.props.editing) { - buttons.push( - Save changes } > - - , - Discard changes } > - - - ); + buttons.push(this.getBtn("save", "Save changes", this.props.onSave)); + buttons.push(this.getBtn("times", "Discard changes", this.props.onCancel)); } else { if (this.props.fullscreen !== true) { - buttons.push( - Change to fullscreen view } > - - - ); + buttons.push(this.getBtn("expand", "Change to fullscreen view", this.props.onFullscreen)); } else { - buttons.push( - Back to normal view } > - - - ); + buttons.push(this.getBtn("compress", "Back to normal view", this.props.onFullscreen)); } if (this.props.paused) { - buttons.push( - Continue simulation } > - - - ); + buttons.push(this.getBtn("play", "Continue simulation", this.props.onUnpause)); } else { - buttons.push( - Pause simulation } > - - - ); + buttons.push(this.getBtn("pause", "Pause simulation", this.props.onPause)); } if (this.props.fullscreen !== true) { - let filesTooltip = this.props.locked ? "View files of scenario" : "Add, edit or delete files of scenario"; - buttons.push( - {filesTooltip}}> - - - ); - - buttons.push( - Add, edit or delete input signals }> - - - ); - - buttons.push( - Add, edit or delete output signals }> - - - ); - - buttons.push( - Add widgets and edit layout }> - - - ); + let tooltip = this.props.locked ? "View files of scenario" : "Add, edit or delete files of scenario"; + buttons.push(this.getBtn("file", tooltip, this.props.onEditFiles)); + buttons.push(this.getBtn("sign-in-alt", "Add, edit or delete input signals", this.props.onEditInputSignals, this.props.locked)); + buttons.push(this.getBtn("sign-out-alt", "Add, edit or delete output signals", this.props.onEditOutputSignals, this.props.locked)); + buttons.push(this.getBtn("pen", "Add widgets and edit layout", this.props.onEdit, this.props.locked)); } } From 1a118de0a52636fc98073f85cc4900a0899d004a Mon Sep 17 00:00:00 2001 From: irismarie Date: Fri, 16 Apr 2021 17:42:58 +0200 Subject: [PATCH 08/13] hide tooltips for locked buttons --- src/componentconfig/config-table.js | 2 ++ src/dashboard/dashboard-table.js | 2 ++ src/result/result-table.js | 3 +-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/componentconfig/config-table.js b/src/componentconfig/config-table.js index a43f811..b711ab5 100644 --- a/src/componentconfig/config-table.js +++ b/src/componentconfig/config-table.js @@ -309,6 +309,7 @@ class ConfigTable extends Component { onClick={() => this.addConfig()} icon='plus' disabled={this.props.locked} + hidetooltip={this.props.locked} /> this.setState({ importConfigModal: true })} icon='upload' disabled={this.props.locked} + hidetooltip={this.props.locked} /> diff --git a/src/dashboard/dashboard-table.js b/src/dashboard/dashboard-table.js index 7728d78..9c76270 100644 --- a/src/dashboard/dashboard-table.js +++ b/src/dashboard/dashboard-table.js @@ -149,6 +149,7 @@ class DashboardTable extends Component { onClick={() => this.setState({newDashboardModal: true})} icon='plus' disabled={this.props.locked} + hidetooltip={this.props.locked} /> this.setState({importDashboardModal: true})} icon='upload' disabled={this.props.locked} + hidetooltip={this.props.locked} /> diff --git a/src/result/result-table.js b/src/result/result-table.js index 4b81427..d8aba2e 100644 --- a/src/result/result-table.js +++ b/src/result/result-table.js @@ -159,15 +159,14 @@ class ResultTable extends Component {
{/*Result table*/}

Results - this.setState({ newResultModal: true })} icon='plus' disabled={this.props.locked} + hidetooltip={this.props.locked} /> -

From 18af356dd5f1bafa64ff2600ebb0811b8f1c7c96 Mon Sep 17 00:00:00 2001 From: irismarie Date: Fri, 16 Apr 2021 17:46:28 +0200 Subject: [PATCH 09/13] visualize hover over button --- src/result/result-table.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/result/result-table.js b/src/result/result-table.js index d8aba2e..9001b59 100644 --- a/src/result/result-table.js +++ b/src/result/result-table.js @@ -159,6 +159,7 @@ class ResultTable extends Component {
{/*Result table*/}

Results + +

From d07b5c68c8d0ca809dd458d1d66ae4a1a7f46d2d Mon Sep 17 00:00:00 2001 From: irismarie Date: Fri, 16 Apr 2021 19:37:47 +0200 Subject: [PATCH 10/13] use IconButton in Table, remove tooltips for locked buttons --- src/common/icon-button.js | 15 +-- src/common/icon-toggle-button.js | 17 +-- src/common/table.js | 167 +++++++++++------------- src/componentconfig/config-table.js | 13 ++ src/dashboard/dashboard-button-group.js | 2 +- src/dashboard/dashboard-table.js | 12 ++ src/dashboard/dashboard.js | 11 ++ src/result/result-table.js | 10 ++ src/scenario/scenario.js | 12 ++ src/scenario/scenarios.js | 13 ++ 10 files changed, 158 insertions(+), 114 deletions(-) diff --git a/src/common/icon-button.js b/src/common/icon-button.js index e4876c9..2a65b95 100644 --- a/src/common/icon-button.js +++ b/src/common/icon-button.js @@ -25,25 +25,16 @@ import Icon from '../common/icon'; class IconButton extends React.Component { render() { - const altButtonStyle = { - marginLeft: '10px', - } - - const iconStyle = { - height: '30px', - width: '30px' - } - let btn = diff --git a/src/common/icon-toggle-button.js b/src/common/icon-toggle-button.js index cd421e0..e4f23d2 100644 --- a/src/common/icon-toggle-button.js +++ b/src/common/icon-toggle-button.js @@ -25,27 +25,18 @@ import Icon from './icon'; class IconToggleButton extends React.Component { render() { - const altButtonStyle = { - marginLeft: '10px', - } + let tooltip = this.props.checked ? this.props.tooltipChecked : this.props.tooltipUnchecked; return - {this.props.checked ? - this.props.tooltipChecked - : - this.props.tooltipUnchecked - } - } > + overlay={{tooltip}} > @@ -53,11 +44,13 @@ class IconToggleButton extends React.Component { : } diff --git a/src/common/table.js b/src/common/table.js index 6d36367..ea6494d 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -21,6 +21,7 @@ import { Table, Button, Form, Tooltip, OverlayTrigger } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import Icon from './icon'; import IconToggleButton from './icon-toggle-button'; +import IconButton from '../common/icon-button'; class CustomTable extends Component { @@ -47,6 +48,7 @@ class CustomTable extends Component { static addCell(data, index, child) { // add data to cell let content = null; + let childkey = 0; if ('dataKeys' in child.props) { for (let key of child.props.dataKeys) { @@ -92,7 +94,7 @@ class CustomTable extends Component { onClick={() => child.props.onDownload(contentkey)} disabled={child.props.onDownload == null}> {contentkey + ' '} - + ); }); @@ -136,19 +138,17 @@ class CustomTable extends Component { if (child.props.editButton && showEditButton) { cell.push( - Edit } - > - - - ); + child.props.onEdit(index)} + variant={'table-control-button'} + />) } if (child.props.checkbox) { @@ -171,7 +171,7 @@ class CustomTable extends Component { if (child.props.lockButton) { cell.push( child.props.onChangeLock(index)} checked={isLocked} checkedIcon='lock' @@ -185,84 +185,74 @@ class CustomTable extends Component { if (child.props.exportButton) { cell.push( - Export } - > - - - ); + child.props.onExport(index)} + variant={'table-control-button'} + />); } if (child.props.signalButton) { cell.push( - Autoconfigure Signals } - > - - - ); + child.props.onAutoConf(index)} + variant={'table-control-button'} + />); } if (child.props.duplicateButton) { cell.push( - Duplicate } > - - - ); + child.props.onDuplicate(index)} + variant={'table-control-button'} + />); } if (child.props.addRemoveFilesButton) { cell.push( - Add/remove File(s)} > - - - ); + child.props.onAddRemove(index)} + variant={'table-control-button'} + />); } if (child.props.downloadAllButton) { cell.push( - Download All Files} > - - - ); + child.props.onDownloadAll(index)} + variant={'table-control-button'} + />); } let showDeleteButton = child.props.showDeleteButton !== null && child.props.showDeleteButton !== undefined @@ -271,18 +261,17 @@ class CustomTable extends Component { if (child.props.deleteButton && showDeleteButton) { cell.push( - Delete } > - - - ); + child.props.onDelete(index)} + variant={'table-control-button'} + />); } return cell; diff --git a/src/componentconfig/config-table.js b/src/componentconfig/config-table.js index b711ab5..d5e1b8f 100644 --- a/src/componentconfig/config-table.js +++ b/src/componentconfig/config-table.js @@ -298,6 +298,15 @@ class ConfigTable extends Component { } render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } + return (
{/*Component Configurations table*/} @@ -310,6 +319,8 @@ class ConfigTable extends Component { icon='plus' disabled={this.props.locked} hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> diff --git a/src/dashboard/dashboard-button-group.js b/src/dashboard/dashboard-button-group.js index 6f9843a..ddacfa0 100644 --- a/src/dashboard/dashboard-button-group.js +++ b/src/dashboard/dashboard-button-group.js @@ -64,7 +64,7 @@ class DashboardButtonGroup extends React.Component { render() { const buttons = []; - key = 0; + buttonkey = 0; if (this.props.editing) { buttons.push(this.getBtn("save", "Save changes", this.props.onSave)); diff --git a/src/dashboard/dashboard-table.js b/src/dashboard/dashboard-table.js index 9c76270..589366b 100644 --- a/src/dashboard/dashboard-table.js +++ b/src/dashboard/dashboard-table.js @@ -137,6 +137,14 @@ class DashboardTable extends Component { } render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } return (
@@ -150,6 +158,8 @@ class DashboardTable extends Component { icon='plus' disabled={this.props.locked} hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> diff --git a/src/dashboard/dashboard.js b/src/dashboard/dashboard.js index 9462bad..2d1aa75 100644 --- a/src/dashboard/dashboard.js +++ b/src/dashboard/dashboard.js @@ -487,6 +487,15 @@ class Dashboard extends Component { return
{"Loading Dashboard..."}
} + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '25px', + width: '25px' + } + const grid = this.state.dashboard.grid; const boxClasses = classNames('section', 'box', { 'fullscreen-padding': this.props.isFullscreen }); let draggable = this.state.editing; @@ -505,6 +514,8 @@ class Dashboard extends Component { tooltipChecked='Dashboard is locked, cannot be edited' tooltipUnchecked='Dashboard is unlocked, can be edited' disabled={true} + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> diff --git a/src/result/result-table.js b/src/result/result-table.js index 9001b59..a38d160 100644 --- a/src/result/result-table.js +++ b/src/result/result-table.js @@ -154,6 +154,14 @@ class ResultTable extends Component { } render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } return (
@@ -167,6 +175,8 @@ class ResultTable extends Component { icon='plus' disabled={this.props.locked} hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index d9d76d7..f19a01b 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -133,6 +133,14 @@ class Scenario extends React.Component { ############################################## */ render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } const tableHeadingStyle = { paddingTop: '30px' @@ -151,6 +159,8 @@ class Scenario extends React.Component { tooltip={tooltip} onClick={this.onEditFiles.bind(this)} icon="file" + buttonStyle={buttonStyle} + iconStyle={iconStyle} />

@@ -165,6 +175,8 @@ class Scenario extends React.Component { tooltipChecked='Scenario is locked, cannot be edited' tooltipUnchecked='Scenario is unlocked, can be edited' disabled={this.state.currentUser.role !== "Admin"} + buttonStyle={buttonStyle} + iconStyle={iconStyle} />

diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index 7f9c45b..89b52d9 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -244,6 +244,15 @@ class Scenarios extends Component { } render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } + return

Scenarios @@ -252,12 +261,16 @@ class Scenarios extends Component { tooltip='Add Scenario' onClick={() => this.setState({ newModal: true })} icon='plus' + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> this.setState({ importModal: true })} icon='upload' + buttonStyle={buttonStyle} + iconStyle={iconStyle} />

From d5b338c4612ba07f77641370cc03fed57a30a999 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Mon, 19 Apr 2021 17:05:47 +0200 Subject: [PATCH 11/13] package updates --- package-lock.json | 212 ++++++++++++++++++++++++---------------------- package.json | 24 +++--- 2 files changed, 122 insertions(+), 114 deletions(-) diff --git a/package-lock.json b/package-lock.json index fca3d27..932eb71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1245,31 +1245,24 @@ } }, "@fortawesome/fontawesome-common-types": { - "version": "0.2.34", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.34.tgz", - "integrity": "sha512-XcIn3iYbTEzGIxD0/dY5+4f019jIcEIWBiHc3KrmK/ROahwxmZ/s+tdj97p/5K0klz4zZUiMfUlYP0ajhSJjmA==" + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz", + "integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw==" }, "@fortawesome/fontawesome-svg-core": { - "version": "1.2.34", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.34.tgz", - "integrity": "sha512-0KNN0nc5eIzaJxlv43QcDmTkDY1CqeN6J7OCGSs+fwGPdtv0yOQqRjieopBCmw+yd7uD3N2HeNL3Zm5isDleLg==", + "version": "1.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz", + "integrity": "sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg==", "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.34" - }, - "dependencies": { - "@fortawesome/fontawesome-common-types": { - "version": "0.2.34", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.34.tgz", - "integrity": "sha512-XcIn3iYbTEzGIxD0/dY5+4f019jIcEIWBiHc3KrmK/ROahwxmZ/s+tdj97p/5K0klz4zZUiMfUlYP0ajhSJjmA==" - } + "@fortawesome/fontawesome-common-types": "^0.2.35" } }, "@fortawesome/free-solid-svg-icons": { - "version": "5.15.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.2.tgz", - "integrity": "sha512-ZfCU+QjaFsdNZmOGmfqEWhzI3JOe37x5dF4kz9GeXvKn/sTxhqMtZ7mh3lBf76SvcYY5/GKFuyG7p1r4iWMQqw==", + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz", + "integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==", "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.34" + "@fortawesome/fontawesome-common-types": "^0.2.35" } }, "@fortawesome/react-fontawesome": { @@ -4205,9 +4198,9 @@ } }, "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" }, "clean-css": { "version": "4.2.3", @@ -4975,9 +4968,9 @@ } }, "d3": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-6.6.0.tgz", - "integrity": "sha512-fWyMfZDSOLksXeYuiHM/uHap7pKgypUnOGY8jiTfmmAWH1HM6ErPtnHiKEdqs7DtZqbombUgaKwq3B5Pjm7GOQ==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-6.7.0.tgz", + "integrity": "sha512-hNHRhe+yCDLUG6Q2LwvR/WdNFPOJQ5VWqsJcwIYVeI401+d2/rrCjxSXkiAdIlpx7/73eApFB4Olsmh3YN7a6g==", "requires": { "d3-array": "2", "d3-axis": "2", @@ -5025,16 +5018,19 @@ } }, "d3-time": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.0.0.tgz", - "integrity": "sha512-2mvhstTFcMvwStWd9Tj3e6CEqtOivtD8AUiHT8ido/xmzrI9ijrUUihZ6nHuf/vsScRBonagOdj0Vv+SEL5G3Q==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "requires": { + "d3-array": "2" + } } } }, "d3-array": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.0.tgz", - "integrity": "sha512-T6H/qNldyD/1OlRkJbonb3u3MPhNwju8OPxYv0YSjDb/B2RUeeBEHzIpNrYiinwpmz8+am+puMrpcrDWgY9wRg==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", "requires": { "internmap": "^1.0.0" } @@ -5186,15 +5182,25 @@ "integrity": "sha512-0D9P8TRj6qDAtHhRQn6EfdOtHMfsUWanl3yb/84C4DqpZ+VsgfI5iTVRNRbELCfNvRfpMr8OrqqUTQ6ANGCijw==" }, "d3-scale": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.3.tgz", - "integrity": "sha512-8E37oWEmEzj57bHcnjPVOBS3n4jqakOeuv1EDdQSiSrYnMCBdMd3nc4HtKk7uia8DUHcY/CGuJ42xxgtEYrX0g==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", "requires": { "d3-array": "^2.3.0", "d3-format": "1 - 2", "d3-interpolate": "1.2.0 - 2", - "d3-time": "1 - 2", + "d3-time": "^2.1.1", "d3-time-format": "2 - 3" + }, + "dependencies": { + "d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "requires": { + "d3-array": "2" + } + } } }, "d3-scale-chromatic": { @@ -7765,9 +7771,9 @@ "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, "highlight.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.6.0.tgz", - "integrity": "sha512-8mlRcn5vk/r4+QcqerapwBYTe+iPL5ih6xrNylxrnBdHQiijDETfXX7VIxC3UiCRiINBJfANBAsPzAvRQj8RpQ==" + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", + "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==" }, "history": { "version": "4.10.1", @@ -10901,12 +10907,12 @@ } }, "lowlight": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.19.0.tgz", - "integrity": "sha512-NIskvQ1d1ovKyUytkMpT8+8Bhq3Ub54os1Xp4RAC9uNbXH1YVRf5NERq7JNzapEe5BzUc1Cj4F0I+eLBBFj6hA==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", "requires": { "fault": "^1.0.0", - "highlight.js": "~10.6.0" + "highlight.js": "~10.7.0" } }, "lru-cache": { @@ -13456,9 +13462,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13481,9 +13487,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13496,9 +13502,9 @@ } }, "rc-slider": { - "version": "9.7.1", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.1.tgz", - "integrity": "sha512-r9r0dpFA3PEvxBhIfVi1lVzxuSogWxeY+tGvi2AqMM1rPgaOXQ7WbtT+9kVFkJ9K8TntA/vYPgiCCKfN29KTkw==", + "version": "9.7.2", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.2.tgz", + "integrity": "sha512-mVaLRpDo6otasBs6yVnG02ykI3K6hIrLTNfT5eyaqduFv95UODI9PDS6fWuVVehVpdS4ENgOSwsTjrPVun+k9g==", "requires": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", @@ -13508,9 +13514,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13523,18 +13529,18 @@ } }, "rc-tooltip": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.0.1.tgz", - "integrity": "sha512-3AnxhUS0j74xAV3khrKw8o6rg+Ima3nw09DJBezMPnX3ImQUAnayWsPSlN1mEnihjA43rcFkGM1emiKE+CXyMQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.0.tgz", + "integrity": "sha512-pFqD1JZwNIpbdcefB7k5xREoHAWM/k3yQwYF0iminbmDXERgq4rvBfUwIvlCqqZSM7HDr9hYeYr6ZsVNaKtvCQ==", "requires": { "@babel/runtime": "^7.11.2", "rc-trigger": "^5.0.0" }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13547,9 +13553,9 @@ } }, "rc-trigger": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.0.tgz", - "integrity": "sha512-fpC1ZkM/IgIIDfF6XHx3Hb2zXy9wvdI5eMh+6DdLygk6Z3HGmkri6ZCXg9a0wfF9AFuzlYTeBLS1uRASZRsnMQ==", + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.5.tgz", + "integrity": "sha512-RlF5RpWqK+JeiFeQVOzwjLFzpNe2FowoXc/42azz+20wr/bYF1Q/MwprUK+3+vs/oFhLC0ht3/NlrslAo/OoWA==", "requires": { "@babel/runtime": "^7.11.2", "classnames": "^2.2.6", @@ -13559,9 +13565,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13574,9 +13580,9 @@ } }, "rc-util": { - "version": "5.6.6", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.6.6.tgz", - "integrity": "sha512-GLAqlODTuVu4V5dZpcDhM7i1pM0BCck2i5u1tW7PO0ZlmX385BhCJOWKqpJXvv4oh3rR5iC2zsJgb1B8hU5FJw==", + "version": "5.9.8", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.9.8.tgz", + "integrity": "sha512-typLSHYGf5irvGLYQshs0Ra3aze086h0FhzsAkyirMunYZ7b3Te8gKa5PVaanoHaZa9sS6qx98BxgysoRP+6Tw==", "requires": { "@babel/runtime": "^7.12.5", "react-is": "^16.12.0", @@ -13584,9 +13590,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13612,9 +13618,9 @@ } }, "react": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", - "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -13905,13 +13911,13 @@ } }, "react-dom": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", - "integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "scheduler": "^0.20.1" + "scheduler": "^0.20.2" } }, "react-draggable": { @@ -15148,9 +15154,9 @@ } }, "scheduler": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.1.tgz", - "integrity": "sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -16178,9 +16184,9 @@ } }, "swagger-client": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.13.1.tgz", - "integrity": "sha512-Hmy4+wVVa3kveWzC7PIeUwiAY5qcYbm4XlC4uZ7e5kAePfB2cprXImiqrZHIzL+ndU0YTN7I+9w/ZayTisn3Jg==", + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.13.2.tgz", + "integrity": "sha512-kamtyXtmbZiA2C5YTVqJYgoPJgzqtM5RbeP23Rt/YPYjMArTKZ2fjx1UTsI0aSbws0GluU5pVHiGp8YMciSUfw==", "requires": { "@babel/runtime-corejs3": "^7.11.2", "btoa": "^1.2.1", @@ -16213,26 +16219,29 @@ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==" + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "requires": { + "side-channel": "^1.0.4" + } } } }, "swagger-ui-react": { - "version": "3.45.0", - "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-3.45.0.tgz", - "integrity": "sha512-wCoZEWfhg6/6u0sY2Kks1zDua2aMQnSMnS10/N/40G4h2SGr6Qfqex5ca5uaJvprpLLIPUv4BcRHs++ZTxjK4A==", + "version": "3.47.1", + "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-3.47.1.tgz", + "integrity": "sha512-KPfhRE3kJnN9/yKrPIvKNrZYzGxSLQOEc0gVUlYXrMh6iQ5rR/fW8s9xXCV0ivOOvhvr09LQ5H3ZjwAIbvUHoA==", "requires": { - "@babel/runtime-corejs3": "^7.13.9", + "@babel/runtime-corejs3": "^7.13.10", "@braintree/sanitize-url": "^5.0.0", "@kyleshockey/object-assign-deep": "^0.4.2", "@kyleshockey/xml": "^1.0.2", "base64-js": "^1.5.1", - "classnames": "^2.2.6", + "classnames": "^2.3.1", "css.escape": "1.5.1", "deep-extend": "0.6.0", - "dompurify": "^2.2.6", + "dompurify": "^2.2.7", "ieee754": "^1.2.1", "immutable": "^3.x.x", "js-file-download": "^0.4.12", @@ -16255,7 +16264,7 @@ "reselect": "^4.0.0", "serialize-error": "^2.1.0", "sha.js": "^2.4.11", - "swagger-client": "^3.13.1", + "swagger-client": "^3.13.2", "url-parse": "^1.5.1", "xml-but-prettier": "^1.0.1", "zenscroll": "^4.0.2" @@ -16794,9 +16803,9 @@ } }, "typescript": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", - "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==" + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==" }, "ua-parser-js": { "version": "0.7.24", @@ -17653,8 +17662,7 @@ }, "ssri": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "resolved": "", "requires": { "figgy-pudding": "^3.5.1" } @@ -18442,9 +18450,9 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" }, "yallist": { "version": "4.0.0", diff --git a/package.json b/package.json index 6954861..4cff9a1 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,16 @@ "version": "0.1.0", "private": true, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^1.2.34", - "@fortawesome/free-solid-svg-icons": "^5.15.2", + "@fortawesome/fontawesome-svg-core": "^1.2.35", + "@fortawesome/free-solid-svg-icons": "^5.15.3", "@fortawesome/react-fontawesome": "^0.1.14", "babel-runtime": "^6.26.0", "bootstrap": "^4.6.0", - "classnames": "^2.2.6", - "d3": "^6.6.0", - "d3-array": "^2.12.0", + "classnames": "^2.3.1", + "d3": "^6.7.0", + "d3-array": "^2.12.1", "d3-axis": "^2.1.0", - "d3-scale": "^3.2.3", + "d3-scale": "^3.3.0", "d3-scale-chromatic": "^2.0.0", "d3-selection": "^2.0.0", "d3-shape": "^2.1.0", @@ -23,8 +23,8 @@ "gaugeJS": "^1.3.7", "handlebars": "^4.7.7", "jquery": "^3.6.0", - "jszip": "^3.6.0", "jsonwebtoken": "^8.5.1", + "jszip": "^3.6.0", "libcimsvg": "git+https://git.rwth-aachen.de/acs/public/cim/pintura-npm-package.git", "lodash": "^4.17.21", "moment": "^2.29.1", @@ -32,15 +32,15 @@ "multiselect-react-dropdown": "^1.6.11", "popper.js": "^1.16.1", "prop-types": "^15.7.2", - "rc-slider": "^9.7.1", - "react": "^17.0.1", + "rc-slider": "^9.7.2", + "react": "^17.0.2", "react-bootstrap": "^1.5.2", "react-collapse": "^5.1.0", "react-color": "^2.19.3", "react-contexify": "^5.0.0", "react-dnd": "^13.1.1", "react-dnd-html5-backend": "^12.1.1", - "react-dom": "^17.0.1", + "react-dom": "^17.0.2", "react-fullscreenable": "^2.5.1-0", "react-grid-system": "^7.1.2", "react-json-view": "^1.21.3", @@ -51,8 +51,8 @@ "react-svg-pan-zoom": "^3.10.0", "react-trafficlight": "^5.2.1", "superagent": "^6.1.0", - "swagger-ui-react": "^3.45.0", - "typescript": "^4.2.3" + "swagger-ui-react": "^3.47.1", + "typescript": "^4.2.4" }, "devDependencies": {}, "scripts": { From c64d7d891778dd8c7f48016879d512c345d57c6b Mon Sep 17 00:00:00 2001 From: irismarie Date: Tue, 20 Apr 2021 12:58:58 +0200 Subject: [PATCH 12/13] #309, allow duplication of locked scenario --- src/common/icon-toggle-button.js | 2 +- src/common/table.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/icon-toggle-button.js b/src/common/icon-toggle-button.js index e4f23d2..e9adc8a 100644 --- a/src/common/icon-toggle-button.js +++ b/src/common/icon-toggle-button.js @@ -33,7 +33,7 @@ class IconToggleButton extends React.Component { overlay={{tooltip}} > ); } @@ -217,7 +218,7 @@ class CustomTable extends Component { key={childkey++} ikey={childkey++} icon={'copy'} - disabled={child.props.onDuplicate == null || isLocked} + disabled={child.props.onDuplicate == null || child.props.locked} hidetooltip={isLocked} tooltip={"Duplicate"} tipPlacement={'bottom'} From c1c8ea2ed81a709424a7bcea568f8d6ce9c8647b Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Tue, 20 Apr 2021 16:42:43 +0200 Subject: [PATCH 13/13] disable signal autoconf button for locked scenarios #309 --- src/common/table.js | 3 ++- src/componentconfig/config-table.js | 1 + src/scenario/scenario.js | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/table.js b/src/common/table.js index c3daff5..8ea1579 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -204,7 +204,8 @@ class CustomTable extends Component { key={childkey++} ikey={childkey++} icon={'wave-square'} - disabled={child.props.onAutoConf == null} + disabled={child.props.onAutoConf == null || child.props.locked } + hidetooltip={isLocked} tooltip={"Autoconfigure Signals"} tipPlacement={'bottom'} onClick={() => child.props.onAutoConf(index)} diff --git a/src/componentconfig/config-table.js b/src/componentconfig/config-table.js index d5e1b8f..665850e 100644 --- a/src/componentconfig/config-table.js +++ b/src/componentconfig/config-table.js @@ -375,6 +375,7 @@ class ConfigTable extends Component { signalButton onAutoConf={(index) => this.signalsAutoConf(index)} width={170} + locked={this.props.locked} /> s.id === scenarioID), results: ResultStore.getState().filter(result => result.scenarioID === scenarioID), sessionToken: localStorage.getItem("token"),