Commit 366df81b authored by Sonja Happ's avatar Sonja Happ

progress with signal editing: correct signals are shown per simulation model...

progress with signal editing: correct signals are shown per simulation model (input and output), next step: make them editable
parent 73d2bd4b
......@@ -92,7 +92,8 @@ class RestDataManager {
AppDispatcher.dispatch({
type: this.type + 's/loaded',
data: data
data: data,
token: token
});
if (this.onLoad != null) {
......@@ -113,7 +114,8 @@ class RestDataManager {
AppDispatcher.dispatch({
type: this.type + 's/loaded',
data: data
data: data,
token: token,
});
if (this.onLoad != null) {
......
......@@ -30,6 +30,7 @@ import SimulatorStore from '../simulator/simulator-store';
import DashboardStore from '../dashboard/dashboard-store';
import SimulationModelStore from '../simulationmodel/simulation-model-store';
import LoginStore from '../user/login-store';
import SignalStore from '../signal/signal-store'
import AppDispatcher from '../common/app-dispatcher';
import Icon from '../common/icon';
......@@ -42,10 +43,11 @@ import NewDashboardDialog from "../dashboard/new-dashboard";
import SimulatorAction from '../simulator/simulator-action';
import DeleteDialog from '../common/dialogs/delete-dialog';
import EditSimulationModelDialog from "../simulationmodel/edit-simulation-model";
import EditSignalMapping from "../signal/edit-signal-mapping";
class Scenario extends React.Component {
static getStores() {
return [ ScenarioStore, SimulationModelStore, DashboardStore, SimulatorStore, LoginStore];
return [ ScenarioStore, SimulationModelStore, DashboardStore, SimulatorStore, LoginStore, SignalStore];
}
static calculateState(prevState, props) {
......@@ -65,13 +67,17 @@ class Scenario extends React.Component {
let dashboards = DashboardStore.getState().filter(dashb => dashb.scenarioID === parseInt(props.match.params.scenario, 10));
// obtain all simulation models of a scenario
let simulationmodels = SimulationModelStore.getState().filter(simmodel => simmodel.scenarioID === parseInt(props.match.params.scenario, 10));
let simulationModels = SimulationModelStore.getState().filter(simmodel => simmodel.scenarioID === parseInt(props.match.params.scenario, 10));
let signals = SignalStore.getState();
return {
scenario,
sessionToken,
simulationModels: simulationmodels,
dashboards: dashboards,
simulationModels,
dashboards,
signals,
simulators: SimulatorStore.getState(),
deleteSimulationModelModal: false,
......@@ -79,6 +85,10 @@ class Scenario extends React.Component {
editSimulationModelModal: false,
modalSimulationModelData: {},
selectedSimulationModels: [],
modalSimulationModelIndex: 0,
editInputSignalsModal: false,
editOutputSignalsModal: false,
newDashboardModal: false,
deleteDashboardModal: false,
......@@ -115,6 +125,8 @@ class Scenario extends React.Component {
type: 'simulators/start-load',
token: this.state.sessionToken,
});
}
addSimulationModel(){
......@@ -151,6 +163,27 @@ class Scenario extends React.Component {
}
}
closeEditOutputSignalsModal(data){
this.setState({ editOutputSignalsModal : false });
//data is an array of signals
if (data){
//TODO: dispatch changes to signals
//TODO: Check if new signal is added
}
}
closeEditInputSignalsModal(data){
this.setState({ editInputSignalsModal : false });
//data is an array of signals
if(data){
//TODO: dispatch changes to signals
//TODO: Check if new signal is added
}
}
closeDeleteSimulationModelModal(confirmDelete) {
this.setState({ deleteSimulationModelModal: false });
......@@ -316,6 +349,9 @@ class Scenario extends React.Component {
marginLeft: '10px'
};
console.log("simulationmodel modal data: ", this.state.modalSimulationModelData)
console.log("simulation models: ", this.state.simulationModels)
return <div className='section'>
<h1>{this.state.scenario.name}</h1>
......@@ -328,13 +364,13 @@ class Scenario extends React.Component {
title='# Outputs'
dataKey='outputLength'
editButton
onEdit={index => this.setState({ editSimulationModelModal: true, modalSimulationModelData: this.state.simulationModels[index], modalIndex: index })}
onEdit={index => this.setState({ editOutputSignalsModal: true, modalSimulationModelData: this.state.simulationModels[index], modalSimulationModelIndex: index })}
/>
<TableColumn
title='# Inputs'
dataKey='inputLength'
editButton
onEdit={index => this.setState({ editSimulationModelModal: true, modalSimulationModelData: this.state.simulationModels[index], modalIndex: index })}
onEdit={index => this.setState({ editInputSignalsModal: true, modalSimulationModelData: this.state.simulationModels[index], modalSimulationModelIndex: index })}
/>
<TableColumn title='Simulator' dataKey='simulatorID' modifier={(simulatorID) => this.getSimulatorName(simulatorID)} />
<TableColumn
......@@ -343,7 +379,7 @@ class Scenario extends React.Component {
editButton
deleteButton
exportButton
onEdit={index => this.setState({ editSimulationModelModal: true, modalSimulationModelData: this.state.simulationModels[index], modalIndex: index })}
onEdit={index => this.setState({ editSimulationModelModal: true, modalSimulationModelData: this.state.simulationModels[index], modalSimulationModelIndex: index })}
onDelete={(index) => this.setState({ deleteSimulationModelModal: true, modalSimulationModelData: this.state.simulationModels[index], modalSimulationModelIndex: index })}
onExport={index => this.exportModel(index)}
/>
......@@ -372,6 +408,9 @@ class Scenario extends React.Component {
<ImportSimulationModelDialog show={this.state.importSimulationModelModal} onClose={data => this.importSimulationModel(data)} simulators={this.state.simulators} />
<DeleteDialog title="simulation model" name={this.state.modalSimulationModelData.name} show={this.state.deleteSimulationModelModal} onClose={(c) => this.closeDeleteSimulationModelModal(c)} />
<EditSignalMapping show={this.state.editOutputSignalsModal} onClose={data => this.closeEditOutputSignalsModal(data)} direction="Output" signals={this.state.signals} simulationModelID={this.state.modalSimulationModelData.id} />
<EditSignalMapping show={this.state.editInputSignalsModal} onClose={data => this.closeEditInputSignalsModal(data)} direction="Input" signals={this.state.signals} simulationModelID={this.state.modalSimulationModelData.id}/>
{/*Dashboard table*/}
<h2>Dashboards</h2>
<Table data={this.state.dashboards}>
......
......@@ -18,102 +18,114 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormGroup, FormControl, FormLabel, FormText } from 'react-bootstrap';
import validator from 'validator';
import { FormGroup, FormLabel, FormText } from 'react-bootstrap';
import Table from '../common/table';
import TableColumn from '../common/table-column';
import Dialog from "../common/dialogs/dialog";
import SignalStore from "./signal-store"
import LoginStore from "../user/login-store";
class EditSignalMapping extends React.Component {
constructor(props) {
super(props);
var length = props.length;
if (length === undefined)
length = 1;
static getStores() {
return [ SignalStore, LoginStore];
}
this.state = {
length: length,
signals: props.signals
};
}
constructor(props) {
super(props);
static getDerivedStateFromProps(props, state){
if (props.length === state.length && props.signals === state.signals) {
return null
let dir = "";
if ( this.props.direction === "Output"){
dir = "out";
} else if ( this.props.direction === "Input" ){
dir = "in";
}
return{
length: props.length,
signals: props.signals
this.state = {
sessionToken: LoginStore.getState().token,
dir
};
}
}
componentDidMount(): void {
}
validateLength(){
const valid = validator.isInt(this.state.length + '', { min: 1, max: 100 });
onClose(canceled) {
if (canceled === false) {
if (this.valid) {
// TODO
let data = null;
return valid ? 'success' : 'error';
//forward modified simulation model to callback function
this.props.onClose(data)
}
} else {
this.props.onClose();
}
}
handleLengthChange = event => {
const length = event.target.value;
// update signals to represent length
const signals = this.state.signals;
handleMappingChange = (event, row, column) => {
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);
}
//const length = this.state.length;
// save updated state
this.setState({ length, signals });
if (column === 1) { // Name change
signals[row].name = event.target.value;
} else if (column === 2) { // unit change
signals[row].unit = event.target.value;
} else if (column === 0) { //index change
signals[row].index = event.target.value;
}
if (this.props.onChange != null) {
this.props.onChange(length, signals);
}
}
//this.setState({ length, signals });
//TODO dispatch changes by calling API
handleMappingChange = (event, row, column) => {
const signals = this.state.signals;
/*if (this.props.onChange != null) {
this.props.onChange(this.state.length, signals);
}
*/
}
const length = this.state.length;
resetState() {
//this.setState({});
}
if (column === 1) {
signals[row].name = event.target.value;
} else if (column === 2) {
signals[row].type = event.target.value;
}
render() {
this.setState({ length, signals });
// filter all signals by Simulation Model ID and direction
let signals = this.props.signals.filter((sig) => {
return (sig.simulationModelID === this.props.simulationModelID) && (sig.direction === this.state.dir);
});
if (this.props.onChange != null) {
this.props.onChange(this.state.length, signals);
}
}
return(
render() {
return <div>
<FormGroup validated={this.validateLength()}>
<FormLabel>{this.props.name} Length</FormLabel>
<FormControl name='length' type='number' placeholder='Enter length' defaultValue={this.state.length} min='1' onBlur={this.handleLengthChange} />
<FormControl.Feedback />
</FormGroup>
<Dialog show={this.props.show} title="Edit Signal Mapping" buttonTitle="Save" onClose={(c) => this.onClose(c)} onReset={() => this.resetState()} valid={this.valid}>
<FormGroup>
<FormLabel>{this.props.name} Mapping</FormLabel>
<FormText>Click <i>name</i> or <i>type</i> cell to edit</FormText>
<Table data={this.props.signals}>
<TableColumn title='ID' width='60' dataIndex />
<TableColumn title='Name' dataKey='name' inlineEditable onInlineChange={this.handleMappingChange} />
<TableColumn title='Unit' dataKey='unit' inlineEditable onInlineChange={this.handleMappingChange} />
</Table>
{/*
<FormGroup validated={this.validateLength()}>
<FormLabel>{this.props.name} Length</FormLabel>
<FormControl name='length' type='number' placeholder='Enter length' defaultValue={this.state.length}
min='1' onBlur={this.handleLengthChange}/>
<FormControl.Feedback/>
</FormGroup>
</div>;
}
*/}
<FormGroup>
<FormLabel>{this.props.direction} Mapping</FormLabel>
<FormText>Click <i>name</i> or <i>type</i> cell to edit</FormText>
<Table data={signals}>
<TableColumn title='Index' dataKey='index' inlineEditable onInlineChange={this.handleMappingChange()} />
<TableColumn title='Name' dataKey='name' inlineEditable onInlineChange={this.handleMappingChange} />
<TableColumn title='Unit' dataKey='unit' inlineEditable onInlineChange={this.handleMappingChange} />
</Table>
</FormGroup>
</Dialog>
);
}
}
EditSignalMapping.propTypes = {
......@@ -122,7 +134,11 @@ EditSignalMapping.propTypes = {
signals: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
type: PropTypes.string.isRequired
unit: PropTypes.string.isRequired,
direction: PropTypes.string.isRequired,
simulationModelID: PropTypes.number.isRequired,
index: PropTypes.number.isRequired
})
),
onChange: PropTypes.func
......
......@@ -22,4 +22,25 @@
import ArrayStore from '../common/array-store';
import SimulationModelsDataManager from './simulation-models-data-manager';
export default new ArrayStore('simulationModels', SimulationModelsDataManager);
class SimulationModelStore extends ArrayStore {
constructor() {
super('simulationModels', SimulationModelsDataManager);
}
reduce(state, action) {
switch (action.type) {
case 'simulationModels/loaded':
SimulationModelsDataManager.loadSignals(action.token, action.data);
return super.reduce(state, action);
default:
return super.reduce(state, action);
}
}
}
export default new SimulationModelStore();
......@@ -70,6 +70,7 @@ class SimulationModel extends React.Component {
outputSignals,
files,
sessionToken,
signals: SignalStore.getState(),
simulators: SimulatorStore.getState(),
selectedFile: null,
......@@ -85,25 +86,25 @@ class SimulationModel extends React.Component {
});
// load input signals for selected simulation model
AppDispatcher.dispatch({
type: 'signals/start-load',
token: this.state.sessionToken,
param: '?direction=in&modelID=' + this.state.simulationModel.id,
});
// load output signals for selected simulation model
AppDispatcher.dispatch({
type: 'signals/start-load',
token: this.state.sessionToken,
param: '?direction=out&modelID=' + this.state.simulationModel.id,
});
// AppDispatcher.dispatch({
// type: 'signals/start-load',
// token: this.state.sessionToken,
// param: '?direction=in&modelID=' + this.state.simulationModel.id,
// });
//
// // load output signals for selected simulation model
// AppDispatcher.dispatch({
// type: 'signals/start-load',
// token: this.state.sessionToken,
// param: '?direction=out&modelID=' + this.state.simulationModel.id,
// });
// load files for selected simulation model
AppDispatcher.dispatch({
type: 'files/start-load',
token: this.state.sessionToken,
param: '?objectType=model&objectID=' + this.state.simulationModel.id,
});
// AppDispatcher.dispatch({
// type: 'files/start-load',
// token: this.state.sessionToken,
// param: '?objectType=model&objectID=' + this.state.simulationModel.id,
// });
// load simulators
AppDispatcher.dispatch({
......@@ -197,6 +198,7 @@ class SimulationModel extends React.Component {
console.log("InputSignals Array", inputSignals);
}
console.log("All SIGNALS: ", this.state.signals);
return <div className='section'>
<EditableHeader title={this.state.simulationModel.name} onChange={this.handleTitleChange} />
......@@ -221,11 +223,11 @@ class SimulationModel extends React.Component {
</FormGroup>
<Col xs={12} sm={6}>
<EditSignalMapping name='Output' length={this.state.simulationModel.outputLength} signals={outputSignals} onChange={this.handleOutputMappingChange} />
<EditSignalMapping name='Output' length={this.state.simulationModel.outputLength} signals={this.state.outputSignals} onChange={this.handleOutputMappingChange} />
</Col>
<Col xs={12} sm={6}>
<EditSignalMapping name='Input' length={this.state.simulationModel.inputLength} signals={inputSignals} onChange={this.handleInputMappingChange} />
<EditSignalMapping name='Input' length={this.state.simulationModel.inputLength} signals={this.state.inputSignals} onChange={this.handleInputMappingChange} />
</Col>
<div style={{ clear: 'both' }}></div>
......
......@@ -21,6 +21,7 @@
import RestDataManager from '../common/data-managers/rest-data-manager';
import AppDispatcher from '../common/app-dispatcher';
import RestAPI from "../common/api/rest-api";
class SimulationModelDataManager extends RestDataManager {
constructor() {
......@@ -45,6 +46,28 @@ class SimulationModelDataManager extends RestDataManager {
id: model.simulator
});
}
loadSignals(token, models){
for (let model of models) {
// request in signals
RestAPI.get(this.makeURL('/signals?direction=in&modelID=' + model.id), token).then(response => {
AppDispatcher.dispatch({
type: 'signals/loaded',
data: response.signals
});
});
// request out signals
RestAPI.get(this.makeURL('/signals?direction=out&modelID=' + model.id), token).then(response => {
AppDispatcher.dispatch({
type: 'signals/loaded',
data: response.signals
});
});
}
}
}
export default new SimulationModelDataManager();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment