diff --git a/package.json b/package.json index 8977188..aa1e73c 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "rc-slider": "^7.0.1" }, "devDependencies": { + "chai": "^3.5.0", "react-scripts": "0.9.3" }, "scripts": { diff --git a/src/__tests__/components/dialog/edit-widget-control-creator.js b/src/__tests__/components/dialog/edit-widget-control-creator.js new file mode 100644 index 0000000..fea0b2a --- /dev/null +++ b/src/__tests__/components/dialog/edit-widget-control-creator.js @@ -0,0 +1,42 @@ + +import { expect } from 'chai'; + +import createControls from '../../../components/dialog/edit-widget-control-creator'; +import EditWidgetTextControl from '../../../components/dialog/edit-widget-text-control'; +import EditWidgetColorControl from '../../../components/dialog/edit-widget-color-control'; +import EditWidgetTimeControl from '../../../components/dialog/edit-widget-time-control'; +import EditImageWidgetControl from '../../../components/dialog/edit-widget-image-control'; +import EditWidgetSimulatorControl from '../../../components/dialog/edit-widget-simulator-control'; +import EditWidgetSignalControl from '../../../components/dialog/edit-widget-signal-control'; +import EditWidgetSignalsControl from '../../../components/dialog/edit-widget-signals-control'; +import EditWidgetOrientation from '../../../components/dialog/edit-widget-orientation'; + +describe('edit widget control creator', () => { + it('should not return null', () => { + let controls = createControls('Value', null, null, null, null, null, null); + expect(controls).to.be.defined; + }); + + var runs = [ + { args: { widgetType: 'Value' }, result: { controlNumber: 2, controlTypes: [EditWidgetSimulatorControl, EditWidgetSignalControl] } }, + { args: { widgetType: 'Plot' }, result: { controlNumber: 4, controlTypes: [EditWidgetTimeControl, EditWidgetSimulatorControl, EditWidgetSignalsControl, EditWidgetTextControl] } }, + { args: { widgetType: 'Table' }, result: { controlNumber: 1, controlTypes: [EditWidgetSimulatorControl] } }, + { args: { widgetType: 'Image' }, result: { controlNumber: 1, controlTypes: [EditImageWidgetControl] } }, + { args: { widgetType: 'Gauge' }, result: { controlNumber: 2, controlTypes: [EditWidgetSimulatorControl, EditWidgetSignalControl] } }, + { args: { widgetType: 'PlotTable' }, result: { controlNumber: 3, controlTypes: [EditWidgetSimulatorControl, EditWidgetSignalsControl, EditWidgetTextControl] } }, + { args: { widgetType: 'Slider' }, result: { controlNumber: 1, controlTypes: [EditWidgetOrientation] } }, + { args: { widgetType: 'Button' }, result: { controlNumber: 2, controlTypes: [EditWidgetColorControl] } }, + { args: { widgetType: 'Box' }, result: { controlNumber: 1, controlTypes: [EditWidgetColorControl] } }, + ]; + + runs.forEach( (run) => { + let itMsg = run.args.widgetType + ' widget edit model should have correct controls'; + it(itMsg, () => { + let controls = createControls(run.args.widgetType, null, null, null, null, null, null); + + expect(controls).to.have.lengthOf(run.result.controlNumber); + + controls.forEach( (control) => expect(control.type).to.be.oneOf(run.result.controlTypes)) + }); + }); +}); \ No newline at end of file diff --git a/src/components/dialog/edit-widget-control-creator.js b/src/components/dialog/edit-widget-control-creator.js new file mode 100644 index 0000000..455ca2f --- /dev/null +++ b/src/components/dialog/edit-widget-control-creator.js @@ -0,0 +1,109 @@ +/** + * File: edit-widget-control-creator.js + * Author: Ricardo Hernandez-Montoya + * Date: 23.05.2017 + * + * 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 EditWidgetTextControl from './edit-widget-text-control'; +import EditWidgetColorControl from './edit-widget-color-control'; +import EditWidgetTimeControl from './edit-widget-time-control'; +import EditImageWidgetControl from './edit-widget-image-control'; +import EditWidgetSimulatorControl from './edit-widget-simulator-control'; +import EditWidgetSignalControl from './edit-widget-signal-control'; +import EditWidgetSignalsControl from './edit-widget-signals-control'; +import EditWidgetOrientation from './edit-widget-orientation'; + +export default function createControls(widgetType = null, widget = null, sessionToken = null, files = null, validateForm, simulation, handleChange) { + // Use a list to concatenate the controls according to the widget type + var dialogControls = []; + + switch(widgetType) { + case 'Value': { + let valueBoundOnChange = (e) => { + handleChange([e, {target: {id: 'signal', value: 0}}]); + } + dialogControls.push( + validateForm(id)} simulation={simulation} handleChange={(e) => valueBoundOnChange(e)} />, + validateForm(id)} simulation={simulation} handleChange={(e) => handleChange(e)} /> + ) + } + break; + case 'Plot': { + let plotBoundOnChange = (e) => { + handleChange([e, {target: {id: 'signals', value: []}}]); + } + dialogControls.push( + validateForm(id)} simulation={simulation} handleChange={(e) => handleChange(e)} />, + validateForm(id)} simulation={simulation} handleChange={(e) => plotBoundOnChange(e)} />, + validateForm(id)} simulation={simulation} handleChange={(e) => handleChange(e)} />, + handleChange(e)} />) + } + break; + case 'Table': { + dialogControls.push( + validateForm(id)} simulation={simulation} handleChange={(e) => handleChange(e)} />) + } + break; + case 'Image': { + dialogControls.push( + validateForm(id)} simulation={simulation} handleChange={(e) => handleChange(e)} />) + } + break; + case 'Gauge': { + let gaugeBoundOnChange = (e) => { + handleChange([e, {target: {id: 'signal', value: ''}}]); + } + dialogControls.push( + validateForm(id)} simulation={simulation} handleChange={(e) => gaugeBoundOnChange(e) } />, + validateForm(id)} simulation={simulation} handleChange={(e) => handleChange(e)} />) + } + break; + case 'PlotTable': { + let plotTableBoundOnChange = (e) => { + handleChange([e, {target: {id: 'preselectedSignals', value: []}}]); + } + dialogControls.push( + validateForm(id)} simulation={simulation} handleChange={(e) => plotTableBoundOnChange(e)} />, + validateForm(id)} simulation={simulation} handleChange={(e) => handleChange(e)} />, + handleChange(e)} />) + } + break; + case 'Slider': { + dialogControls.push( + validateForm(id)} simulation={simulation} handleChange={(e) => handleChange(e)} />) + } + break; + case 'Button': { + dialogControls.push( + validateForm(id)} handleChange={(e) => handleChange(e)} />, + validateForm(id)} handleChange={(e) => handleChange(e)} />) + } + break; + case 'Box': { + dialogControls.push( + validateForm(id)} handleChange={(e) => handleChange(e)} />) + } + break; + default: + console.log('Non-valid widget type'); + } + + return dialogControls; +} \ No newline at end of file diff --git a/src/components/dialog/edit-widget-orientation.js b/src/components/dialog/edit-widget-orientation.js index 76aa874..9f3e67f 100644 --- a/src/components/dialog/edit-widget-orientation.js +++ b/src/components/dialog/edit-widget-orientation.js @@ -2,9 +2,21 @@ * File: edit-widget-orientation.js * Author: Ricardo Hernandez-Montoya * Date: 10.04.2017 - * Copyright: 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. + * + * 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, { Component } from 'react'; diff --git a/src/components/dialog/edit-widget-signal-control.js b/src/components/dialog/edit-widget-signal-control.js index 879052b..623b416 100644 --- a/src/components/dialog/edit-widget-signal-control.js +++ b/src/components/dialog/edit-widget-signal-control.js @@ -2,9 +2,21 @@ * File: edit-widget-signal-control.js * Author: Ricardo Hernandez-Montoya * Date: 03.04.2017 - * Copyright: 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. + * + * 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, { Component } from 'react'; @@ -31,7 +43,7 @@ class EditWidgetSignalControl extends Component { if (this.props.simulation) { // get selected simulation model - const simulationModel = this.props.simulation.models.find( model => model.simulation === this.state.widget.simulation ); + const simulationModel = this.props.simulation.models.find( model => model.simulator === this.state.widget.simulator ); // If simulation model update the signals to render signalsToRender = simulationModel? simulationModel.mapping : []; diff --git a/src/components/dialog/edit-widget-signal-type-control.js b/src/components/dialog/edit-widget-signal-type-control.js deleted file mode 100644 index 8978186..0000000 --- a/src/components/dialog/edit-widget-signal-type-control.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * File: edit-widget-signal-type-control.js - * Author: Ricardo Hernandez-Montoya - * Date: 03.04.2017 - * Copyright: 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ - -import React, { Component } from 'react'; -import { FormGroup, FormControl, ControlLabel } from 'react-bootstrap'; - -class EditWidgetSignalTypeControl extends Component { - constructor(props) { - super(props); - - this.state = { - widget: {} - }; - } - - componentWillReceiveProps(nextProps) { - // Update state's widget with props - this.setState({ widget: nextProps.widget }); - } - - render() { - // get selected simulation model - var simulationModel = {}; - - if (this.props.simulation) { - this.props.simulation.models.forEach((model) => { - if (model.simulation === this.state.widget.simulation) { - simulationModel = model; - } - }); - } - - // Obtain unique signal types with the help of dictionary keys - var signalTypes = Object.keys(simulationModel.mapping.reduce( (collection, signal) => { - var lower = signal.type.toLowerCase(); - collection[lower] = ''; - return collection; - }, {})); - - var capitalize = (str) => { return str.charAt(0).toUpperCase() + str.slice(1); } - - var selectedValue = signalTypes.includes(this.state.widget.signalType) ? this.state.widget.signalType : ''; - - return ( - - Signal type - this.props.handleChange(e)}> - - {signalTypes.map((type, index) => ( - - ))} - - - ); - } -} - -export default EditWidgetSignalTypeControl; \ No newline at end of file diff --git a/src/components/dialog/edit-widget-signals-control.js b/src/components/dialog/edit-widget-signals-control.js index b84d930..76b832b 100644 --- a/src/components/dialog/edit-widget-signals-control.js +++ b/src/components/dialog/edit-widget-signals-control.js @@ -2,9 +2,21 @@ * File: edit-widget-signals-control.js * Author: Ricardo Hernandez-Montoya * Date: 03.04.2017 - * Copyright: 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. + * + * 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, { Component } from 'react'; @@ -46,7 +58,7 @@ class EditWidgetSignalsControl extends Component { if (this.props.simulation) { // get selected simulation model - const simulationModel = this.props.simulation.models.find( model => model.simulation === this.state.widget.simulation ); + const simulationModel = this.props.simulation.models.find( model => model.simulator === this.state.widget.simulator ); // If simulation model update the signals to render signalsToRender = simulationModel? simulationModel.mapping : []; diff --git a/src/components/dialog/edit-widget-simulator-control.js b/src/components/dialog/edit-widget-simulator-control.js index 23de386..48186ef 100644 --- a/src/components/dialog/edit-widget-simulator-control.js +++ b/src/components/dialog/edit-widget-simulator-control.js @@ -2,9 +2,21 @@ * File: edit-widget-simulator-control.js * Author: Ricardo Hernandez-Montoya * Date: 03.04.2017 - * Copyright: 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. + * + * 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, { Component } from 'react'; diff --git a/src/components/dialog/edit-widget-text-control.js b/src/components/dialog/edit-widget-text-control.js index d4196b4..b9eef66 100644 --- a/src/components/dialog/edit-widget-text-control.js +++ b/src/components/dialog/edit-widget-text-control.js @@ -2,9 +2,21 @@ * File: edit-widget-text-control.js * Author: Ricardo Hernandez-Montoya * Date: 21.04.2017 - * Copyright: 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. + * + * 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, { Component } from 'react'; diff --git a/src/components/dialog/edit-widget-time-control.js b/src/components/dialog/edit-widget-time-control.js index 5b8e234..8f6434d 100644 --- a/src/components/dialog/edit-widget-time-control.js +++ b/src/components/dialog/edit-widget-time-control.js @@ -2,9 +2,21 @@ * File: edit-widget-time-control.js * Author: Ricardo Hernandez-Montoya * Date: 13.04.2017 - * Copyright: 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. + * + * 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, { Component } from 'react'; diff --git a/src/components/dialog/edit-widget.js b/src/components/dialog/edit-widget.js index eeabba3..8c2277f 100644 --- a/src/components/dialog/edit-widget.js +++ b/src/components/dialog/edit-widget.js @@ -24,14 +24,7 @@ import { FormGroup, FormControl, ControlLabel } from 'react-bootstrap'; import Dialog from './dialog'; -import EditWidgetTextControl from './edit-widget-text-control'; -import EditWidgetColorControl from './edit-widget-color-control'; -import EditWidgetTimeControl from './edit-widget-time-control'; -import EditImageWidgetControl from './edit-widget-image-control'; -import EditWidgetSimulatorControl from './edit-widget-simulator-control'; -import EditWidgetSignalControl from './edit-widget-signal-control'; -import EditWidgetSignalsControl from './edit-widget-signals-control'; -import EditWidgetOrientation from './edit-widget-orientation'; +import createControls from './edit-widget-control-creator'; class EditWidgetDialog extends Component { static propTypes = { @@ -62,10 +55,16 @@ class EditWidgetDialog extends Component { } } - handleChange(e, index) { - var update = this.state.temporal; - update[e.target.id] = e.target.value; - this.setState({ temporal: update }); + handleChange(e) { + if (e.constructor === Array) { + // Every property in the array will be updated + let changes = e.reduce( (changesObject, event) => { changesObject[event.target.id] = event.target.value; return changesObject }, {}); + this.setState({ temporal: Object.assign({}, this.state.temporal, changes ) }); + } else { + let changeObject = {}; + changeObject[e.target.id] = e.target.value; + this.setState({ temporal: Object.assign({}, this.state.temporal, changeObject ) }); + } } resetState() { @@ -88,55 +87,17 @@ class EditWidgetDialog extends Component { } render() { - // Use a list to concatenate the controls according to the widget type - var dialogControls = []; - + + let controls = null; if (this.props.widget) { - if (this.props.widget.type === 'Value') { - dialogControls.push( - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} />, - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} /> - ) - } else if (this.props.widget.type === 'Plot') { - dialogControls.push( - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e, index) => this.handleChange(e, index)} />, - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} />, - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} />, - this.handleChange(e)} /> - ) - } else if (this.props.widget.type === 'Table') { - dialogControls.push( - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} /> - ) - } else if (this.props.widget.type === 'Image') { - dialogControls.push( - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e, index) => this.handleChange(e, index)} /> - ) - } else if (this.props.widget.type === 'Gauge') { - dialogControls.push( - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} />, - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} /> - ) - } else if (this.props.widget.type === 'PlotTable') { - dialogControls.push( - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} />, - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} />, - this.handleChange(e)} /> - ) - } else if (this.props.widget.type === 'Slider') { - dialogControls.push( - this.validateForm(id)} simulation={this.props.simulation} handleChange={(e) => this.handleChange(e)} />, - ) - } else if (this.props.widget.type === 'Button') { - dialogControls.push( - this.validateForm(id)} handleChange={(e, index) => this.handleChange(e, index)} />, - this.validateForm(id)} handleChange={(e, index) => this.handleChange(e, index)} /> - ) - } else if (this.props.widget.type === 'Box') { - dialogControls.push( - this.validateForm(id)} handleChange={(e, index) => this.handleChange(e, index)} /> - ) - } + controls = createControls( + this.props.widget.type, + this.state.temporal, + this.props.sessionToken, + this.props.files, + (id) => this.validateForm(id), + this.props.simulation, + (e) => this.handleChange(e)); } return ( @@ -147,7 +108,7 @@ class EditWidgetDialog extends Component { this.handleChange(e)} /> - { dialogControls } + { controls || '' } );