Skip to content

Commit b444bab

Browse files
authored
Merge pull request #785 from MetaCell/feature/188-range-fields-fix
Feature/188 range fields fix
2 parents f899b70 + 55e4da2 commit b444bab

2 files changed

Lines changed: 112 additions & 55 deletions

File tree

webapp/components/general/AdapterComponent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export default class AdapterComponent extends Component {
5151

5252
// Call to conversion function
5353
const newValue = this.props.convertToPython(this.state);
54-
if (newValue != undefined && this.state.value != newValue) {
54+
if (newValue != undefined && this.state.value != newValue && this.props.onChange) {
5555
this.props.onChange(null, null, newValue);
5656
}
5757
}

webapp/components/general/NetPyNECoordsRange.js

Lines changed: 111 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,29 @@ import Utils from '../../Utils';
99
export default class NetPyNECoordsRange extends Component {
1010
constructor (props) {
1111
super(props);
12-
this.state = { rangeType: undefined };
12+
this.state = { rangeType: undefined, rangeValue: [undefined, undefined] };
1313

1414
this._isMounted = false;
1515
}
1616

17-
triggerUpdate (updateMethod) {
18-
// common strategy when triggering processing of a value change, delay it, every time there is a change we reset
19-
if (this.updateTimer != undefined) {
20-
clearTimeout(this.updateTimer);
21-
}
22-
this.updateTimer = setTimeout(updateMethod, 1000);
23-
}
24-
2517
componentDidMount () {
2618
this._isMounted = true;
2719
this.updateLayout();
2820
}
2921

3022
componentDidUpdate (prevProps, prevState) {
3123
if (this.props.name != prevProps.name) {
32-
this.triggerUpdate(() => {
33-
const message = `netpyne_geppetto.${this.props.model}['${this.props.name}']${(this.props.conds != undefined) ? `['${this.props.conds}']` : ''}`;
34-
Utils
35-
.evalPythonMessage(`[key in ${message} for key in ['${this.props.items[0].value}', '${this.props.items[1].value}']]`)
36-
.then((response) => {
37-
if (response[0] && this._isMounted === true) {
38-
this.setState({ rangeType: this.props.items[0].value });
39-
} else if (response[1] && this._isMounted === true) {
40-
this.setState({ rangeType: this.props.items[1].value });
41-
} else if (this._isMounted === true) {
42-
this.setState({ rangeType: undefined });
43-
}
44-
});
24+
const message = `netpyne_geppetto.${this.props.model}['${this.props.name}']${(this.props.conds != undefined) ? `['${this.props.conds}']` : ''}`;
25+
Utils
26+
.evalPythonMessage(`[key in ${message} for key in ['${this.props.items[0].value}', '${this.props.items[1].value}']]`)
27+
.then((response) => {
28+
if (response[0] && this._isMounted === true) {
29+
this.setState({ rangeType: this.props.items[0].value });
30+
} else if (response[1] && this._isMounted === true) {
31+
this.setState({ rangeType: this.props.items[1].value });
32+
} else if (this._isMounted === true) {
33+
this.setState({ rangeType: undefined });
34+
}
4535
});
4636
} else if (this.props.conds != prevProps.conds) {
4737
this.updateLayout();
@@ -58,17 +48,34 @@ export default class NetPyNECoordsRange extends Component {
5848

5949
const message = `netpyne_geppetto.${model}['${name}']${(conds !== undefined)
6050
? `['${conds}']` : ''}`;
51+
const evalMessage = `[key in ${message} for key in ['${items[0].value}', '${items[1].value}']]` ;
52+
6153
Utils
62-
.evalPythonMessage(`[key in ${message} for key in ['${items[0].value}', '${items[1].value}']]`)
63-
.then((response) => {
64-
if (response[0] && this._isMounted === true) {
65-
this.setState({ rangeType: items[0].value });
66-
} else if (response[1] && this._isMounted === true) {
67-
this.setState({ rangeType: items[1].value });
68-
} else if (this._isMounted === true) {
69-
this.setState({ rangeType: undefined });
70-
}
71-
});
54+
.evalPythonMessage(evalMessage)
55+
.then((response) => {
56+
57+
let rangeType = undefined ;
58+
59+
if (response[0] && this._isMounted === true) {
60+
rangeType = items[0].value ;
61+
} else if (response[1] && this._isMounted === true) {
62+
rangeType = items[1].value ;
63+
}
64+
65+
this.setState({ rangeType });
66+
67+
if (rangeType)
68+
{
69+
const pythonMessage = `netpyne_geppetto.${model}['${name}']['${conds}']['${this.state.rangeType}']` ;
70+
71+
Utils
72+
.evalPythonMessage(pythonMessage)
73+
.then((response) => {
74+
if (response && response.length > 0 ) {
75+
this.setState({ rangeValue: response });
76+
}});
77+
}
78+
});
7279
}
7380

7481
createMenuItems = () => this.props.items.map((obj) => (
@@ -85,6 +92,71 @@ export default class NetPyNECoordsRange extends Component {
8592
this._isMounted = false;
8693
}
8794

95+
handleRangeTypeChange(event) {
96+
const {
97+
model,
98+
conds,
99+
name,
100+
} = this.props;
101+
102+
const rangeType = event.target.value ;
103+
104+
const pythonMessageDelAll = `netpyne_geppetto.${model}['${name}']['${conds}'] = {}`;
105+
Utils.execPythonMessage(
106+
pythonMessageDelAll
107+
);
108+
109+
const rangeValue = this.state.rangeValue ;
110+
111+
if (!rangeValue.some(e => e === undefined))
112+
{
113+
const pythonMessage = `netpyne_geppetto.${model}['${name}']['${conds}']['${rangeType}'] = [${rangeValue}]` ;
114+
Utils.execPythonMessage(
115+
pythonMessage
116+
);
117+
}
118+
119+
this.setState({ rangeType})
120+
}
121+
122+
//preConds: pop, cellType, cellModel, x, y, z, xnorm, ynorm, znorm
123+
handleCoordParamChange(index, newValue) {
124+
const {
125+
model,
126+
conds,
127+
name,
128+
} = this.props;
129+
130+
function getOppositeObject(list, givenValue) {
131+
const index = list.findIndex(obj => obj.value === givenValue);
132+
133+
if (index === -1 || list.length !== 2) {
134+
return null;
135+
}
136+
return list[1 - index];
137+
}
138+
139+
if (newValue === '' || (/^\d+$/.test(newValue))) {
140+
const opossiteRangeType = getOppositeObject(this.props.items, this.state.rangeType) ;
141+
142+
if (opossiteRangeType)
143+
{
144+
const pythonMessageDelOpposite = `netpyne_geppetto.${model}['${name}']['${conds}'].pop('${opossiteRangeType.value}', None)`;
145+
Utils.execPythonMessage(
146+
pythonMessageDelOpposite
147+
);
148+
}
149+
150+
const rangeValue = this.state.rangeValue ;
151+
rangeValue[index] = newValue ;
152+
const pythonMessage = `netpyne_geppetto.${model}['${name}']['${conds}']['${this.state.rangeType}'] = [${rangeValue}]` ;
153+
Utils.execPythonMessage(
154+
pythonMessage
155+
);
156+
this.setState({ rangeValue })
157+
}
158+
}
159+
88160
render () {
89161
if (this.props.conds != undefined) {
90162
var meta = `${this.props.model}.${this.props.conds}.${this.props.items[0].value}`;
@@ -95,42 +167,27 @@ export default class NetPyNECoordsRange extends Component {
95167
}
96168
const min = `${this.props.id}MinRange`;
97169
const max = `${this.props.id}MaxRange`;
170+
171+
const minVal = this.state.rangeValue[0];
172+
const maxVal = this.state.rangeValue[1];
173+
98174
return (
99175
<div>
100176
<NetPyNEField id={meta}>
101177
<SelectField
102178
id={`${this.props.id}Select`}
103179
label="Range type"
104180
value={this.state.rangeType || ''}
105-
onChange={(event) => this.setState({ rangeType: event.target.value })}
181+
onChange={(event) => { this.handleRangeTypeChange(event); }}
106182
>
107183
{this.createMenuItems()}
108184
</SelectField>
109185
</NetPyNEField>
110186
{(this.state.rangeType != undefined)
111187
? (
112188
<Box width="100%" p={1}>
113-
<AdapterComponent
114-
model={path}
115-
convertToPython={(state) => {
116-
if (!state[state.lastUpdated].toString()
117-
.endsWith('.')
118-
&& ((!isNaN(parseFloat(state[min]))) && (!isNaN(parseFloat(state[max]))))) {
119-
return [parseFloat(state[min]), parseFloat(state[max])];
120-
}
121-
}}
122-
convertFromPython={(prevProps, prevState, value) => {
123-
if (value != undefined && prevProps.value != value && value != '') {
124-
const output = {};
125-
output[min] = value[0];
126-
output[max] = value[1];
127-
return output;
128-
}
129-
}}
130-
>
131-
<TextField label="Minimum" id={min} variant="filled" fullWidth />
132-
<TextField label="Maximum" id={max} variant="filled" fullWidth />
133-
</AdapterComponent>
189+
<TextField label="Minimum" id={min} variant="filled" value={minVal} fullWidth onChange={ (e) => { this.handleCoordParamChange(0, parseInt(e.target.value)) } } />
190+
<TextField label="Maximum" id={max} variant="filled" value={maxVal} fullWidth onChange={ (e) => { this.handleCoordParamChange(1, parseInt(e.target.value)) } } />
134191
</Box>
135192
)
136193
: null}

0 commit comments

Comments
 (0)