Skip to content

Commit 5225d8a

Browse files
authored
Merge pull request #677 from MetaCell/feature/netpyne-99
Feature/netpyne 99
2 parents fe6a399 + 468d740 commit 5225d8a

5 files changed

Lines changed: 87 additions & 47 deletions

File tree

webapp/components/NetPyNE.js

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,119 @@
1-
import React from 'react';
1+
import React from 'react'
22

3-
import { Box, Grid } from '@material-ui/core';
4-
import { withStyles } from '@material-ui/core/styles';
3+
import { Box, Grid } from '@material-ui/core'
4+
import { withStyles } from '@material-ui/core/styles'
55
import {
66
ErrorDialog,
77
Topbar,
88
LayoutManager,
99
Drawer,
1010
Dialog,
1111
ConfirmationDialog,
12-
LaunchDialog,
13-
} from 'netpyne/components';
14-
12+
LaunchDialog
13+
} from 'netpyne/components'
14+
import { loadModel } from '../redux/actions/general'
1515

1616
const styles = ({ zIndex }) => ({
1717
root: {
1818
height: '100%',
1919
overflow: 'hidden',
2020
display: 'flex',
21-
flex: 1,
21+
flex: 1
2222
},
2323
container: {
2424
display: 'flex',
2525
flex: 1,
2626
alignItems: 'stretch',
27-
flexDirection: 'column',
27+
flexDirection: 'column'
2828
},
2929
topbar: {
3030
position: 'relative',
31-
zIndex: zIndex.drawer,
31+
zIndex: zIndex.drawer
3232
},
3333
content: {
3434
flexGrow: 1,
3535
display: 'flex',
3636
flexDirection: 'row',
37-
position: 'relative',
37+
position: 'relative'
3838
},
39-
noGrow: { flexGrow: 0 },
40-
});
41-
42-
39+
noGrow: { flexGrow: 0 }
40+
})
4341

4442
class NetPyNE extends React.Component {
4543
constructor (props) {
46-
super(props);
47-
this.openPythonCallDialog = this.openPythonCallDialog.bind(this);
44+
super(props)
45+
this.openPythonCallDialog = this.openPythonCallDialog.bind(this)
46+
this.loaded = false
4847
}
4948

5049
componentDidMount () {
51-
GEPPETTO.on(GEPPETTO.Events.Error_while_exec_python_command, this.openPythonCallDialog, this);
50+
GEPPETTO.on(GEPPETTO.Events.Error_while_exec_python_command, this.openPythonCallDialog, this)
5251

5352
const {
54-
setDefaultWidgets,
55-
} = this.props;
53+
setDefaultWidgets
54+
} = this.props
5655

57-
setDefaultWidgets();
56+
setDefaultWidgets()
57+
58+
// Listen messages
59+
const loadFromEvent = event => {
60+
console.log('Parent frame message received:', event)
61+
62+
// Here we would expect some cross-origin check, but we don't do anything more than load a model here
63+
switch (event.data.type) {
64+
case 'INIT_INSTANCE':
65+
if (this.loaded) {
66+
return
67+
}
68+
this.loaded = true
69+
console.log('Netpyne is ready')
70+
if (window !== window.parent) {
71+
window.parent.postMessage({
72+
type: 'APP_READY'
73+
}, '*')
74+
}
75+
break
76+
case 'LOAD_RESOURCE': {
77+
const resource = event.data.payload
78+
this.props.dispatchAction(loadModel(resource))
79+
}
80+
}
81+
}
82+
// A message from the parent frame can specify the file to load
83+
window.addEventListener('message', loadFromEvent)
84+
// window.load = loadFromEvent
5885
}
5986

6087
componentWillUnmount () {
61-
GEPPETTO.off(GEPPETTO.Events.Error_while_exec_python_command, this.openPythonCallDialog, this);
88+
GEPPETTO.off(GEPPETTO.Events.Error_while_exec_python_command, this.openPythonCallDialog, this)
6289
}
6390

6491
openPythonCallDialog (event) {
6592
if (event?.evalue && event?.traceback) {
6693
this.props.pythonCallErrorDialogBox({
6794
errorMessage: event.evalue,
68-
errorDetails: event.traceback.join('\n'),
69-
});
95+
errorDetails: event.traceback.join('\n')
96+
})
7097
} else {
7198
this.props.pythonCallErrorDialogBox({
7299
errorMessage: event.data.response.evalue,
73-
errorDetails: event.data.response.traceback.join('\n'),
74-
});
100+
errorDetails: event.data.response.traceback.join('\n')
101+
})
75102
}
76103
}
77104

78-
79-
80105
render () {
81-
const { classes } = this.props;
106+
const { classes } = this.props
82107

83-
const Layout = LayoutManager();
108+
const Layout = LayoutManager()
84109
return (
85110
<div className={classes.root}>
86111
<div className={classes.container}>
87112
<div className={classes.topbar}>
88113
<Topbar />
89114
</div>
90-
<Box p={1} flex={1} display="flex" alignItems="stretch">
91-
<Grid container spacing={1} className={classes.content} alignItems="stretch">
115+
<Box p={1} flex={1} display='flex' alignItems='stretch'>
116+
<Grid container spacing={1} className={classes.content} alignItems='stretch'>
92117
<Grid item className={classes.noGrow}>
93118
<Drawer />
94119
</Grid>
@@ -103,8 +128,8 @@ class NetPyNE extends React.Component {
103128
<ErrorDialog />
104129
<LaunchDialog />
105130
</div>
106-
);
131+
)
107132
}
108133
}
109134

110-
export default withStyles(styles)(NetPyNE);
135+
export default withStyles(styles)(NetPyNE)

webapp/components/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ export const Dimensions = connect(
176176
export const NetPyNE = connect(
177177
null,
178178
(dispatch) => ({
179+
dispatchAction: (action) => dispatch(action),
179180
pythonCallErrorDialogBox: (payload) => dispatch(openBackendErrorDialog(payload)),
180181
setWidgets: (payload) => dispatch(setWidgets(payload)),
181182
setDefaultWidgets: () => dispatch(setDefaultWidgets),

webapp/components/topbar/Topbar.js

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import ImportCellParamsDialog from './dialogs/ImportCellParams';
2424
import UploadDownloadFilesDialog from './dialogs/UploadDownloadFiles';
2525

2626
import { TOPBAR_CONSTANTS, MODEL_STATE, DEFAULT_CONFIRMATION_DIALOG_MESSAGE, NETPYNE_COMMANDS } from '../../constants';
27-
import { LOAD_TUTORIAL, registerModelPath } from '../../redux/actions/general';
27+
import { LOAD_TUTORIAL, registerModelPath, loadModel } from '../../redux/actions/general';
2828
import OverwriteModel from './dialogs/OverwriteModel';
2929

3030
const styles = () => ({
@@ -36,6 +36,7 @@ const styles = () => ({
3636
},
3737
});
3838

39+
3940
class Topbar extends Component {
4041
snackBarMessage = '';
4142

@@ -47,18 +48,8 @@ class Topbar extends Component {
4748

4849
closeExplorerDialog (fieldValue) {
4950
if (fieldValue) {
50-
Utils.evalPythonMessage('netpyne_geppetto.loadFromIndexFile', [fieldValue.path])
51-
.then(() => {
52-
// const fileName = fieldValue.path.replace(/^.*[\\/]/, '');
53-
// const path = fieldValue.path
54-
// .split(fileName)
55-
// .slice(0, -1)
56-
// .join('');
57-
// const action = registerModelPath(path);
58-
// this.props.dispatchAction(action);
59-
const action = registerModelPath(fieldValue.path);
60-
this.props.dispatchAction(action);
61-
});
51+
const path = fieldValue.path
52+
this.props.dispatchAction(loadModel(path));
6253
}
6354
this.handleClose();
6455
}

webapp/redux/actions/general.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const SHOW_NETWORK = 'SHOW_NETWORK';
77
export const CREATE_NETWORK = 'CREATE_NETWORK';
88
export const CREATE_SIMULATE_NETWORK = 'CREATE_SIMULATE_NETWORK';
99
export const REGISTER_MODEL_PATH = 'REGISTER_MODEL_PATH';
10+
export const LOAD_MODEL = 'LOAD_MODEL';
1011
export const SIMULATE_NETWORK = 'SIMULATE_NETWORK';
1112
export const EDIT_MODEL = 'EDIT_MODEL';
1213
export const RESET_MODEL = 'RESET_MODEL';
@@ -46,6 +47,11 @@ export const registerModelPath = (path) => ({
4647
payload: path
4748
});
4849

50+
export const loadModel = (path) => ({
51+
type: LOAD_MODEL,
52+
payload: path
53+
})
54+
4955
export const resetModel = { type: RESET_MODEL };
5056

5157
export const pythonCall = (cmd, args) => ({

webapp/redux/middleware/middleware.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import {
2525
RESET_MODEL,
2626
showNetwork,
2727
addInstancesToCanvas,
28-
openConfirmationDialog
28+
openConfirmationDialog,
29+
registerModelPath,
30+
LOAD_MODEL
2931
} from '../actions/general';
3032
import { OPEN_BACKEND_ERROR_DIALOG, CLOSE_BACKEND_ERROR_DIALOG, openBackendErrorDialog } from '../actions/errors';
3133
import { closeDrawerDialogBox } from '../actions/drawer';
@@ -506,6 +508,21 @@ export default (store) => (next) => (action) => {
506508
next(action);
507509
break;
508510
}
511+
case LOAD_MODEL: {
512+
const path = action.payload;
513+
Utils.evalPythonMessage('netpyne_geppetto.loadFromIndexFile', [path])
514+
.then(() => {
515+
// const fileName = fieldValue.path.replace(/^.*[\\/]/, '');
516+
// const path = fieldValue.path
517+
// .split(fileName)
518+
// .slice(0, -1)
519+
// .join('');
520+
// const action = registerModelPath(path);
521+
// this.props.dispatchAction(action);
522+
store.dispatch(registerModelPath(path));
523+
});
524+
break;
525+
}
509526
default: {
510527
next(action);
511528
}

0 commit comments

Comments
 (0)