diff --git a/package-lock.json b/package-lock.json index 5ce72e9..b8e396b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8322,11 +8322,29 @@ } }, "prop-types": { - "version": "https://registry.npmjs.org/prop-types/-/prop-types-15.5.10.tgz", - "integrity": "sha512-vCFzoUFaZkVNeFkhK1KbSq4cn97GDrpfBt9K2qLkGnPAEFhEv3M61Lk5t+B7c0QfMLWo0fPkowk/4SuXerh26Q==", + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz", + "integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==", "requires": { - "fbjs": "^0.8.9", - "loose-envify": "^1.3.1" + "fbjs": "^0.8.16", + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + }, + "dependencies": { + "fbjs": { + "version": "0.8.16", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", + "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", + "requires": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.9" + } + } } }, "proxy-addr": { @@ -12309,6 +12327,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "validator": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.2.0.tgz", + "integrity": "sha512-gz/uknWtNfZTj1BLUzYHDxOoiQ7A4wZ6xPuuE6RpxswR4cNyT4I5kN9jmU0AQr7IBEap9vfYChI2TpssTN6Itg==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index f09ae20..f54e1a9 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "gaugeJS": "^1.3.2", "immutable": "^3.8.1", "lodash": "^4.17.5", + "prop-types": "^15.6.1", "rc-slider": "^8.3.0", "react": "^15.4.2", "react-bootstrap": "^0.31.1", @@ -34,7 +35,8 @@ "react-scripts": "1.0.10", "react-sortable-tree": "^0.1.19", "react-svg-pan-zoom": "^2.14.1", - "superagent": "^3.5.0" + "superagent": "^3.5.0", + "validator": "^10.2.0" }, "devDependencies": { "chai": "^4.1.0" diff --git a/src/components/signal-mapping.js b/src/components/signal-mapping.js new file mode 100644 index 0000000..3c975b8 --- /dev/null +++ b/src/components/signal-mapping.js @@ -0,0 +1,125 @@ +/** + * File: signalMapping.js + * Author: Markus Grigull + * Date: 10.08.2018 + * + * 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 PropTypes from 'prop-types'; +import { FormGroup, FormControl, ControlLabel, HelpBlock } from 'react-bootstrap'; +import validator from 'validator'; + +import Table from './table'; +import TableColumn from './table-column'; + +class SignalMapping extends React.Component { + constructor(props) { + super(props); + + this.state = { + length: props.length, + signals: props.signals + }; + } + + componentWillReceiveProps(nextProps) { + if (nextProps.length === this.state.length && nextProps.signals === this.state.signals) { + return; + } + + this.setState({ length: nextProps.length, signals: nextProps.signals }); + } + + validateLength(){ + const valid = validator.isInt(this.state.length + '', { min: 1, max: 100 }); + + return valid ? 'success' : 'error'; + } + + handleLengthChange = event => { + const length = event.target.value; + + // update signals to represent length + const signals = this.state.signals; + + if (this.state.length < length) { + while (signals.length < length) { + signals.push({ name: 'Signal', type: 'Type' }); + } + } else { + signals.splice(length, signals.length - length); + } + + // save updated state + this.setState({ length, signals }); + + if (this.props.onChange != null) { + this.props.onChange(length, signals); + } + } + + handleMappingChange = (event, row, column) => { + const signals = this.state.signals; + + if (column === 1) { + signals[row].name = event.target.value; + } else if (column === 2) { + signals[row].type = event.target.value; + } + + this.setState({ signals }); + + if (this.props.onChange != null) { + this.props.onChange(this.state.length, signals); + } + } + + render() { + return
+ + {this.props.name} Length + + + + + + {this.props.name} Mapping + Click name or type cell to edit + + + + +
+
+
; + } +} + +SignalMapping.propTypes = { + name: PropTypes.string, + length: PropTypes.number, + signals: PropTypes.arrayOf( + PropTypes.shape({ + name: PropTypes.string.isRequired, + type: PropTypes.string.isRequired + }) + ), + onChange: PropTypes.func +}; + +export default SignalMapping; diff --git a/src/containers/app.js b/src/containers/app.js index 420442f..4199935 100644 --- a/src/containers/app.js +++ b/src/containers/app.js @@ -45,7 +45,7 @@ import Simulators from './simulators'; import Visualization from './visualization'; import Simulations from './simulations'; import Simulation from './simulation'; -import SimulationModel from './simulationModel'; +import SimulationModel from './simulation-model'; import Users from './users'; import '../styles/app.css'; diff --git a/src/containers/selectFile.js b/src/containers/select-file.js similarity index 100% rename from src/containers/selectFile.js rename to src/containers/select-file.js diff --git a/src/containers/selectSimulator.js b/src/containers/select-simulator.js similarity index 100% rename from src/containers/selectSimulator.js rename to src/containers/select-simulator.js diff --git a/src/containers/simulationModel.js b/src/containers/simulation-model.js similarity index 71% rename from src/containers/simulationModel.js rename to src/containers/simulation-model.js index db68ae3..f2558db 100644 --- a/src/containers/simulationModel.js +++ b/src/containers/simulation-model.js @@ -27,8 +27,9 @@ import SimulationModelStore from '../stores/simulation-model-store'; import UserStore from '../stores/user-store'; import AppDispatcher from '../app-dispatcher'; -import SelectSimulator from './selectSimulator'; -import SelectFile from './selectFile'; +import SelectSimulator from './select-simulator'; +import SelectFile from './select-file'; +import SignalMapping from '../components/signal-mapping'; class SimulationModel extends React.Component { static getStores() { @@ -72,16 +73,27 @@ class SimulationModel extends React.Component { console.log(file); } + handleOutputMappingChange = (length, signals) => { + console.log(length); + console.log(signals); + } + render() { return

{this.state.simulationModel.name}

- +
+ - + - + +
+ +
+ +