1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/web/ synced 2025-03-23 00:00:02 +01:00
VILLASweb/src/signal/edit-signal-mapping.js
2021-03-09 00:25:17 +01:00

339 lines
10 KiB
JavaScript

/**
* 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 <http://www.gnu.org/licenses/>.
******************************************************************************/
import React from 'react';
import PropTypes from 'prop-types';
import { Button, Form, OverlayTrigger, Tooltip } 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";
import Icon from "../common/icon";
import AppDispatcher from "../common/app-dispatcher";
class EditSignalMappingDialog extends React.Component {
constructor(props) {
super(props);
let dir = "";
if ( this.props.direction === "Output") {
dir = "out";
} else if ( this.props.direction === "Input" ) {
dir = "in";
}
this.state = {
dir,
signals: [],
modifiedSignalIDs : [],
openCollapse: false
};
}
static getDerivedStateFromProps(props, state) {
// 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 = signals.concat(temp);
}
}
signals.forEach(signal => {
if (signal.checked === undefined) {
signal.checked = false;
}
});
return {
signals: signals,
};
}
onClose(canceled) {
for (let signalID of this.state.modifiedSignalIDs) {
let sig = this.state.signals.find(s => s.id === signalID);
//dispatch changes to signal
AppDispatcher.dispatch({
type: 'signals/start-edit',
data: sig,
token: this.props.sessionToken,
});
}
this.props.onCloseEdit(this.state.dir)
}
handleMappingChange = (event, row, column) => {
let signals = this.state.signals;
let modifiedSignals = this.state.modifiedSignalIDs;
console.log("HandleMappingChange", row, column)
if (column === 2) { // Name change
signals[row].name = event.target.value;
if (modifiedSignals.find(id => id === signals[row].id) === undefined) {
modifiedSignals.push(signals[row].id);
}
} else if (column === 3) { // unit change
signals[row].unit = event.target.value;
if (modifiedSignals.find(id => id === signals[row].id) === undefined) {
modifiedSignals.push(signals[row].id);
}
} else if (column === 4) { // scaling factor change
signals[row].scalingFactor = parseFloat(event.target.value);
if (modifiedSignals.find(id => id === signals[row].id) === undefined) {
modifiedSignals.push(signals[row].id);
}
} else if (column === 1) { //index change
console.log("Index change")
signals[row].index =parseInt(event.target.value, 10);
if (modifiedSignals.find(id => id === signals[row].id) === undefined) {
modifiedSignals.push(signals[row].id);
}
}
this.setState({
signals: signals,
modifiedSignalIDs: modifiedSignals
})
};
handleDelete = (index) => {
let data = this.state.signals[index]
AppDispatcher.dispatch({
type: 'signals/start-remove',
data: data,
token: this.props.sessionToken
});
};
handleRemove = () => {
let checkedSignals = this.state.signals.filter(signal => signal.checked === true);
checkedSignals.forEach(signal => {
AppDispatcher.dispatch({
type: 'signals/start-remove',
data: signal,
token: this.props.sessionToken
});
})
}
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: configID,
direction: this.state.dir,
name: "PlaceholderName",
unit: "PlaceholderUnit",
index: 999,
scalingFactor: 1.0
};
AppDispatcher.dispatch({
type: 'signals/start-add',
data: newSignal,
token: this.props.sessionToken
});
this.setState({openCollapse: false});
};
resetState() {
let signals = this.props.signals.filter((sig) => {
return (sig.configID === this.props.configID) && (sig.direction === this.state.dir);
});
this.setState({signals: signals})
}
onSignalChecked(signal) {
let tempSignals = this.state.signals;
const index = tempSignals.indexOf(signal);
tempSignals[index].checked = !tempSignals[index].checked;
this.setState({signals: tempSignals});
}
checkAll() {
let tempSignals = this.state.signals;
let allChecked = true;
tempSignals.forEach(signal => {
if (signal.checked === false) {
signal.checked = true;
allChecked = false;
}
});
if (allChecked) {
tempSignals.forEach(signal => signal.checked = false);
}
this.setState({signals: tempSignals});
}
render() {
const buttonStyle = {
marginLeft: '10px',
};
return <Dialog
show={this.props.show}
title="Edit Signal Mapping"
buttonTitle="Save"
blendOutCancel = {false}
onClose={(c) => this.onClose(c)}
onReset={() => this.resetState()}
valid={true}
>
<Form.Group>
<Form.Label>{this.props.direction} Mapping</Form.Label>
<Form.Text>Click <i>Index</i>, <i>Name</i> or <i>Unit</i> cell to edit</Form.Text>
<Table checkbox onChecked={(signal) => this.onSignalChecked(signal)} data={this.state.signals}>
<TableColumn
checkbox
onChecked={(index, event) => this.onSignalChecked(index, event)}
checkboxKey='checked'
width='30'
/>
<TableColumn
title='Index'
dataKey='index'
inlineEditable
inputType='number'
onInlineChange={(e, row, column) => this.handleMappingChange(e, row, column)}
/>
<TableColumn
title='Name'
dataKey='name'
inlineEditable
inputType='text'
onInlineChange={(e, row, column) => this.handleMappingChange(e, row, column)}
/>
<TableColumn
title='Unit'
dataKey='unit'
inlineEditable
inputType='text'
onInlineChange={(e, row, column) => this.handleMappingChange(e, row, column)}
/>
<TableColumn
title='Scaling Factor'
dataKey='scalingFactor'
inlineEditable
inputType='number'
onInlineChange={(e, row, column) => this.handleMappingChange(e, row, column)}
/>
<TableColumn
title='Remove'
deleteButton
onDelete={(index) => this.handleDelete(index)}
/>
</Table>
<div className='solid-button' style={{ float: 'right' }}>
<OverlayTrigger
key={0}
placement='left'
overlay={<Tooltip id={`tooltip-${"check"}`}> Check/Uncheck All </Tooltip>}
>
<Button
variant='secondary'
key={50}
onClick={() => this.checkAll()}
style={buttonStyle}
>
<Icon icon="check" />
</Button>
</OverlayTrigger>
<Button
variant='secondary'
key={51}
onClick={() => this.handleRemove()} style={buttonStyle}>
<Icon icon="minus" /> Remove
</Button>
<Button
variant='secondary'
key={52}
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 className='solid-button'>
{typeof this.props.configs !== "undefined" && this.props.configs.map(config => (
<Button
variant='secondary'
key={config.id}
onClick={() => this.handleAdd(config.id)}
style={buttonStyle}
>
{config.name}
</Button>
))}
</div>
</Collapse>
</div>
</Form.Group>
</Dialog>;
}
}
EditSignalMappingDialog.propTypes = {
name: PropTypes.string,
length: PropTypes.number,
signals: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
unit: PropTypes.string.isRequired,
direction: PropTypes.string.isRequired,
configID: PropTypes.number.isRequired,
index: PropTypes.number.isRequired
})
),
onChange: PropTypes.func
};
export default EditSignalMappingDialog;