mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
merged with develop branch
This commit is contained in:
commit
8e54d6f1ed
10 changed files with 6836 additions and 3363 deletions
10011
package-lock.json
generated
10011
package-lock.json
generated
File diff suppressed because it is too large
Load diff
50
package.json
50
package.json
|
@ -3,19 +3,19 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.30",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.14.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.32",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.1",
|
||||
"@fortawesome/react-fontawesome": "^0.1.11",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"bootstrap": "^4.5.2",
|
||||
"bootstrap": "^4.5.3",
|
||||
"classnames": "^2.2.6",
|
||||
"d3-array": "^2.6.0",
|
||||
"d3-axis": "^1.0.12",
|
||||
"d3-scale": "^3.2.2",
|
||||
"d3-scale-chromatic": "^1.5.0",
|
||||
"d3-selection": "^1.4.2",
|
||||
"d3-shape": "^1.3.7",
|
||||
"d3-time-format": "^2.3.0",
|
||||
"d3-array": "^2.8.0",
|
||||
"d3-axis": "^2.0.0",
|
||||
"d3-scale": "^3.2.3",
|
||||
"d3-scale-chromatic": "^2.0.0",
|
||||
"d3-selection": "^2.0.0",
|
||||
"d3-shape": "^2.0.0",
|
||||
"d3-time-format": "^3.0.0",
|
||||
"es6-promise": "^4.2.8",
|
||||
"file-saver": "^2.0.2",
|
||||
"flux": "^3.1.3",
|
||||
|
@ -25,14 +25,14 @@
|
|||
"jszip": "^3.5.0",
|
||||
"libcimsvg": "git+https://git.rwth-aachen.de/acs/public/cim/pintura-npm-package.git",
|
||||
"lodash": "^4.17.20",
|
||||
"moment": "^2.27.0",
|
||||
"multiselect-react-dropdown": "^1.5.7",
|
||||
"moment": "^2.29.1",
|
||||
"multiselect-react-dropdown": "^1.6.1",
|
||||
"node-sass": "^4.14.1",
|
||||
"popper.js": "^1.16.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"rc-slider": "^9.3.1",
|
||||
"react": "^16.13.1",
|
||||
"react-bootstrap": "^1.3.0",
|
||||
"rc-slider": "^9.5.4",
|
||||
"react": "^16.14.0",
|
||||
"react-bootstrap": "^1.4.0",
|
||||
"react-bootstrap-time-picker": "^2.0.1",
|
||||
"react-collapse": "^5.0.1",
|
||||
"react-color": "^2.18.1",
|
||||
|
@ -40,20 +40,20 @@
|
|||
"react-d3": "^0.4.0",
|
||||
"react-dnd": "^10.0.2",
|
||||
"react-dnd-html5-backend": "^10.0.2",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-dom": "^16.14.0",
|
||||
"react-fullscreenable": "^2.5.1-0",
|
||||
"react-grid-system": "^6.4.2",
|
||||
"react-grid-system": "^7.1.1",
|
||||
"react-json-view": "^1.19.1",
|
||||
"react-notification-system": "^0.3.0",
|
||||
"react-rnd": "^10.2.2",
|
||||
"react-notification-system": "^0.4.0",
|
||||
"react-rnd": "^10.2.3",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "^3.4.3",
|
||||
"react-svg-pan-zoom": "^3.8.0",
|
||||
"sass": "^1.26.10",
|
||||
"superagent": "^5.3.1",
|
||||
"typescript": "^3.9.7",
|
||||
"validator": "^12.2.0"
|
||||
"react-scripts": "^4.0.0",
|
||||
"react-svg-pan-zoom": "^3.8.1",
|
||||
"sass": "^1.27.0",
|
||||
"superagent": "^6.1.0",
|
||||
"typescript": "^4.0.3",
|
||||
"validator": "^13.1.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0"
|
||||
|
|
|
@ -92,7 +92,7 @@ class App extends React.Component {
|
|||
{/*
|
||||
<Col style={{ width: this.state.showSidebarMenu ? '280px' : '0px' }} smHidden mdHidden lgHidden className="sidenav">
|
||||
*/}
|
||||
<Hidden sm md lg xl>
|
||||
<Hidden sm md lg xl xxl>
|
||||
<Col style={{ width: this.state.showSidebarMenu ? '280px' : '0px' }} className="sidenav">
|
||||
<HeaderMenu onClose={this.hideSidebarMenu} currentRole={currentUser.role} />
|
||||
</Col>
|
||||
|
|
|
@ -38,7 +38,7 @@ function isNetworkError(err) {
|
|||
let result = false;
|
||||
|
||||
// If not status nor response fields, it is a network error. TODO: Handle timeouts
|
||||
if (err.status == null || err.response == null) {
|
||||
if (err.status == null || err.status === 500 || err.response == null) {
|
||||
result = true;
|
||||
|
||||
let notification = err.timeout? REQUEST_TIMEOUT_NOTIFICATION : SERVER_NOT_REACHABLE_NOTIFICATION;
|
||||
|
@ -47,6 +47,8 @@ function isNetworkError(err) {
|
|||
return result;
|
||||
}
|
||||
|
||||
let prevURL = null;
|
||||
|
||||
class RestAPI {
|
||||
get(url, token) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
@ -58,6 +60,8 @@ class RestAPI {
|
|||
|
||||
req.end(function (error, res) {
|
||||
if (res == null || res.status !== 200) {
|
||||
if (req.url !== prevURL) error.handled = isNetworkError(error);
|
||||
prevURL = req.url;
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(JSON.parse(res.text));
|
||||
|
@ -97,6 +101,7 @@ class RestAPI {
|
|||
|
||||
req.end(function (error, res) {
|
||||
if (res == null || res.status !== 200) {
|
||||
error.handled = isNetworkError(error);
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(JSON.parse(res.text));
|
||||
|
@ -115,6 +120,7 @@ class RestAPI {
|
|||
|
||||
req.end(function (error, res) {
|
||||
if (res == null || res.status !== 200) {
|
||||
error.handled = isNetworkError(error);
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(JSON.parse(res.text));
|
||||
|
@ -133,6 +139,7 @@ class RestAPI {
|
|||
|
||||
req.end(function (error, res) {
|
||||
if (res == null || res.status !== 200) {
|
||||
error.handled = isNetworkError(error);
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(JSON.parse(res.text));
|
||||
|
@ -152,6 +159,7 @@ class RestAPI {
|
|||
|
||||
req.end(function (error, res) {
|
||||
if (error !== null || res.status !== 200) {
|
||||
error.handled = isNetworkError(error);
|
||||
reject(error);
|
||||
} else {
|
||||
// file data is contained in res.body (because of blob response type)
|
||||
|
|
|
@ -58,7 +58,7 @@ class Home extends React.Component {
|
|||
|
||||
return (
|
||||
<div className="home-container">
|
||||
<img style={{height: 120, float: 'right'}} src={require('../img/villas_web.svg')} alt="Logo VILLASweb" />
|
||||
<img style={{height: 120, float: 'right'}} src={require('../img/villas_web.svg').default} alt="Logo VILLASweb" />
|
||||
<h1>Home</h1>
|
||||
<p>
|
||||
Welcome to <b>{config.instance}</b> hosted by <a href={"mailto:" + config.admin.mail}>{config.admin.name}</a>!<br />
|
||||
|
@ -73,7 +73,7 @@ class Home extends React.Component {
|
|||
|
||||
|
||||
<h3>Data Model</h3>
|
||||
<img height={400} src={require('../img/datamodel.png')} alt="Datamodel VILLASweb" />
|
||||
<img height={400} src={require('../img/datamodel.png').default} alt="Datamodel VILLASweb" />
|
||||
|
||||
<h3>Terminology </h3>
|
||||
|
||||
|
@ -124,13 +124,13 @@ class Home extends React.Component {
|
|||
<li><a href="http://www.re-serve.eu">RESERVE</a> a European Union’s Horizon 2020 research and innovation programme under grant agreement No 727481</li>
|
||||
<li><a href="http://www.jara.org/en/research/energy">JARA-ENERGY</a>. Jülich-Aachen Research Alliance (JARA) is an initiative of RWTH Aachen University and Forschungszentrum Jülich.</li>
|
||||
</ul>
|
||||
<img height={100} src={require('../img/european_commission.svg')} alt="Logo EU" />
|
||||
<img height={70} src={require('../img/reserve.svg')} alt="Logo EU" />
|
||||
<img height={70} src={require('../img/uel_efre.jpeg')} alt="Logo UEL OP EFRE NRW" />
|
||||
<img height={70} src={require('../img/uel.png')} alt="Logo UEL" />
|
||||
<img height={60} src={require('../img/eonerc_rwth.svg')} alt="Logo ACS" />
|
||||
<img height={100} src={require('../img/european_commission.svg').default} alt="Logo EU" />
|
||||
<img height={70} src={require('../img/reserve.svg').default} alt="Logo EU" />
|
||||
<img height={70} src={require('../img/uel_efre.jpeg').default} alt="Logo UEL OP EFRE NRW" />
|
||||
<img height={70} src={require('../img/uel.png').default} alt="Logo UEL" />
|
||||
<img height={60} src={require('../img/eonerc_rwth.svg').default} alt="Logo ACS" />
|
||||
{
|
||||
//<img height={70} src={require('../img/jara.svg')} alt="Logo JARA" />
|
||||
//<img height={70} src={require('../img/jara.svg').default} alt="Logo JARA" />
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -92,7 +92,7 @@ class DashboardButtonGroup extends React.Component {
|
|||
);
|
||||
|
||||
buttons.push(
|
||||
<OverlayTrigger key={key++} placement={'bottom'} overlay={<Tooltip id={`tooltip-${"file"}`}> Add, edit or delete input signal </Tooltip>} >
|
||||
<OverlayTrigger key={key++} placement={'bottom'} overlay={<Tooltip id={`tooltip-${"file"}`}> Add, edit or delete input signals </Tooltip>} >
|
||||
<Button key={key} variant= 'light' size="lg" onClick={this.props.onEditInputSignals} style={buttonStyle}>
|
||||
<Icon icon="sign-in-alt" style={iconStyle}/>
|
||||
</Button>
|
||||
|
|
|
@ -91,7 +91,7 @@ class Dashboard extends Component {
|
|||
dashboard.height = maxHeight + 80;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// filter signals to the ones belonging to the scenario at hand
|
||||
let signals = []
|
||||
let allSignals = SignalStore.getState();
|
||||
|
@ -119,6 +119,9 @@ class Dashboard extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
let editOutputSignalsModal = prevState.editOutputSignalsModal;
|
||||
let editInputSignalsModal = prevState.editInputSignalsModal;
|
||||
|
||||
return {
|
||||
dashboard,
|
||||
widgets,
|
||||
|
@ -131,9 +134,9 @@ class Dashboard extends Component {
|
|||
editing: prevState.editing || false,
|
||||
paused: prevState.paused || false,
|
||||
|
||||
editModal: prevState.editModal || false,
|
||||
editOutputSignalsModal: prevState.editOutputSignals || false,
|
||||
editInputSignalsModal: prevState.editInputSignals || false,
|
||||
editModal: prevState.editModal || false,
|
||||
editOutputSignalsModal: editOutputSignalsModal,
|
||||
editInputSignalsModal: editInputSignalsModal,
|
||||
filesEditModal: prevState.filesEditModal || false,
|
||||
filesEditSaveState: prevState.filesEditSaveState || [],
|
||||
modalData: null,
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {Button, FormGroup, FormLabel, FormText} from 'react-bootstrap';
|
||||
import {Collapse} from 'react-collapse';
|
||||
import Table from '../common/table';
|
||||
import TableColumn from '../common/table-column';
|
||||
import Dialog from "../common/dialogs/dialog";
|
||||
|
@ -40,7 +41,8 @@ class EditSignalMapping extends React.Component {
|
|||
this.state = {
|
||||
dir,
|
||||
signals: [],
|
||||
modifiedSignalIDs : []
|
||||
modifiedSignalIDs : [],
|
||||
openCollapse: false
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -49,15 +51,15 @@ class EditSignalMapping extends React.Component {
|
|||
// filter all signals by configID and direction
|
||||
let signals = [];
|
||||
if(props.signalID != null || typeof props.configs === "undefined"){
|
||||
signals = props.signals.filter((sig) => {
|
||||
return (sig.configID === props.configID) && (sig.direction === state.dir);
|
||||
});
|
||||
}
|
||||
else{
|
||||
for(let i = 0; i < props.configs.length; i++){
|
||||
let temp = props.signals.filter((sig) => {
|
||||
return (sig.configID === props.configs[i].id) && (sig.direction === state.dir);
|
||||
})
|
||||
signals = props.signals.filter((sig) => {
|
||||
return (sig.configID === props.configID) && (sig.direction === state.dir);
|
||||
});
|
||||
}
|
||||
else{
|
||||
for(let i = 0; i < props.configs.length; i++){
|
||||
let temp = props.signals.filter((sig) => {
|
||||
return (sig.configID === props.configs[i].id) && (sig.direction === state.dir);
|
||||
})
|
||||
signals = signals.concat(temp);
|
||||
}
|
||||
}
|
||||
|
@ -132,10 +134,20 @@ class EditSignalMapping extends React.Component {
|
|||
|
||||
};
|
||||
|
||||
handleAdd = () => {
|
||||
handleAdd = (configID = null) => {
|
||||
|
||||
if(typeof this.props.configs !== "undefined"){
|
||||
|
||||
if(configID === null){
|
||||
this.setState({openCollapse: true});
|
||||
return
|
||||
}
|
||||
}
|
||||
else{
|
||||
configID = this.props.configID;
|
||||
}
|
||||
let newSignal = {
|
||||
configID: this.props.configID,
|
||||
configID: configID,
|
||||
direction: this.state.dir,
|
||||
name: "PlaceholderName",
|
||||
unit: "PlaceholderUnit",
|
||||
|
@ -149,6 +161,7 @@ class EditSignalMapping extends React.Component {
|
|||
token: this.props.sessionToken
|
||||
});
|
||||
|
||||
this.setState({openCollapse: false});
|
||||
};
|
||||
|
||||
resetState() {
|
||||
|
@ -190,7 +203,19 @@ class EditSignalMapping extends React.Component {
|
|||
</Table>
|
||||
|
||||
<div style={{ float: 'right' }}>
|
||||
<Button onClick={() => this.handleAdd()} style={buttonStyle}><Icon icon="plus" /> Signal</Button>
|
||||
<Button key={50} onClick={() => this.handleAdd()} style={buttonStyle}><Icon icon="plus" /> Signal</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Collapse isOpened={this.state.openCollapse}>
|
||||
<h6>Choose a Component Configuration to add the signal to: </h6>
|
||||
<div>
|
||||
{typeof this.props.configs !== "undefined" && this.props.configs.map(config => (
|
||||
|
||||
<Button key ={config.id} onClick={() => this.handleAdd(config.id)} style={buttonStyle}>{config.name}</Button>
|
||||
|
||||
))}
|
||||
</div>
|
||||
</Collapse>
|
||||
</div>
|
||||
</FormGroup>
|
||||
</Dialog>
|
||||
|
|
|
@ -27,7 +27,7 @@ class EditWidgetDialog extends React.Component {
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
temporal: {},
|
||||
temporal: props.widget,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -38,12 +38,9 @@ class EditWidgetDialog extends React.Component {
|
|||
}
|
||||
|
||||
|
||||
|
||||
onClose(canceled) {
|
||||
if (canceled === false) {
|
||||
if (this.validChanges()) {
|
||||
this.props.onClose(this.state.temporal);
|
||||
}
|
||||
this.props.onClose(this.state.temporal);
|
||||
} else {
|
||||
this.props.onClose();
|
||||
}
|
||||
|
@ -117,23 +114,26 @@ class EditWidgetDialog extends React.Component {
|
|||
changeObject = this.assignAspectRatio(changeObject, this.state.temporal.customProperties.file);
|
||||
}
|
||||
} else if (e.target.id.includes('file')) {
|
||||
|
||||
customProperty ? changeObject[parts[0]][parts[1]] = e.target.value : changeObject[e.target.id] = e.target.value;
|
||||
if (e.target.value === "Select file")
|
||||
{
|
||||
customProperty ? changeObject[parts[0]][parts[1]] = -1 : changeObject[e.target.id] = -1;
|
||||
} else {
|
||||
customProperty ? changeObject[parts[0]][parts[1]] = e.target.value : changeObject[e.target.id] = e.target.value;
|
||||
}
|
||||
|
||||
// get file and update size (if it's an image)
|
||||
if ((changeObject.customProperties.file !== -1)&&('lockAspect' in this.state.temporal && this.state.temporal.lockAspect)) {
|
||||
/*if ((changeObject.customProperties.file !== -1)&&('lockAspect' in this.state.temporal && this.state.temporal.lockAspect)) {
|
||||
// TODO this if condition requires changes to work!!!
|
||||
changeObject = this.assignAspectRatio(changeObject, e.target.value);
|
||||
}
|
||||
}else if (parts[1] === 'textSize'){
|
||||
}*/
|
||||
} else if (parts[1] === 'textSize'){
|
||||
changeObject[parts[0]][parts[1]] = Number(e.target.value);
|
||||
changeObject = this.setMaxWidth(changeObject);
|
||||
|
||||
}else if(parts[1] === 'orientation'){
|
||||
} else if(parts[1] === 'orientation'){
|
||||
customProperty ? changeObject[parts[0]][parts[1]] = e.target.value : changeObject[e.target.id] = e.target.value ;
|
||||
changeObject = this.setNewLockRestrictions(changeObject);
|
||||
}
|
||||
else if (e.target.type === 'number') {
|
||||
} else if (e.target.type === 'number') {
|
||||
customProperty ? changeObject[parts[0]][parts[1]] = Number(e.target.value) : changeObject[e.target.id] = Number(e.target.value);
|
||||
} else if(e.target.id === 'name'){
|
||||
if(customProperty ? (changeObject[parts[0]][parts[1]] != null) : (changeObject[e.target.id] != null)){
|
||||
|
@ -145,7 +145,7 @@ class EditWidgetDialog extends React.Component {
|
|||
} else {
|
||||
customProperty ? changeObject[parts[0]][parts[1]] = e.target.value : changeObject[e.target.id] = e.target.value ;
|
||||
}
|
||||
this.validChanges();
|
||||
|
||||
this.setState({ temporal: changeObject});
|
||||
|
||||
}
|
||||
|
@ -155,18 +155,6 @@ class EditWidgetDialog extends React.Component {
|
|||
this.setState({ temporal: widget_data });
|
||||
}
|
||||
|
||||
validChanges() {
|
||||
// check that widget has a name
|
||||
var name = true;
|
||||
|
||||
if (this.state.temporal[name] === '') {
|
||||
name = false;
|
||||
}
|
||||
|
||||
this.valid = name;
|
||||
return name;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
let controls = null;
|
||||
|
|
|
@ -44,6 +44,7 @@ class WidgetImage extends React.Component {
|
|||
|
||||
componentDidUpdate(prevProps: Readonly<P>, prevState: Readonly<S>, snapshot: SS) {
|
||||
|
||||
|
||||
let file = this.props.files.find(file => file.id === parseInt(this.props.widget.customProperties.file, 10));
|
||||
|
||||
|
||||
|
@ -55,9 +56,12 @@ class WidgetImage extends React.Component {
|
|||
data: file.id,
|
||||
token: this.props.token
|
||||
});
|
||||
|
||||
|
||||
this.setState({ file: file, fileDate: file.date });
|
||||
}
|
||||
} else if (this.setState.file !== undefined) {
|
||||
console.log("file undefined", file)
|
||||
this.setState({file:undefined})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue