UNPKG

webgme-dss

Version:

Design Studio for Dynamic Systems with Modelica as backend

380 lines (337 loc) 14 kB
/* eslint-env browser */ /* globals window */ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import superagent from 'superagent'; import classNames from 'classnames'; import Drawer from '@material-ui/core/Drawer'; import Divider from '@material-ui/core/Divider'; import IconButton from '@material-ui/core/IconButton'; import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; import PlayCircleOutline from '@material-ui/icons/PlayCircleOutline'; import CheckCircle from '@material-ui/icons/CheckCircle'; import AddCircle from '@material-ui/icons/AddCircle'; import Timeline from '@material-ui/icons/Timeline'; import History from '@material-ui/icons/History'; import {withStyles} from '@material-ui/core/styles'; import green from '@material-ui/core/colors/green'; import PartBrowser from 'webgme-react-components/src/components/PartBrowser'; import SystemSimulatorMetadata from '../../plugins/SystemSimulator/metadata.json'; import ModelCheckMetadata from '../../plugins/ModelCheck/metadata.json'; import ModelCheckPlugin from '../../plugins/ModelCheck/ModelCheck'; import getMetaNodeByName from '../gme/utils/getMetaNodeByName'; import {downloadBlobArtifact} from '../gme/utils/saveUrlToDisk'; import {removePlotVariable, toggleLeftDrawer, toggleModelingView, setResultNode, toggleRightDrawer} from '../actions'; import ResultList from './ResultList'; import PluginConfigDialog from '../Dialogs/PluginConfigDialog'; import DomainSelector from '../Dialogs/DomainSelector'; import NotifyDialog from '../Dialogs/NotifyDialog'; import PluginResultDialog from '../Dialogs/PluginResultDialog'; import ProjectHistory from '../containers/Dialogs/ProjectHistory'; import colorHash from '../gme/utils/colorHash'; import {sideDrawer as styles} from '../classes'; const mapStateToProps = state => ({ open: state.leftDrawer, activeNode: state.activeNode, modelingView: state.modelingView, variables: state.plotData.variables, scale: state.scale, }); const mapDispatchToProps = dispatch => ({ hide: () => { dispatch(toggleLeftDrawer(false)); }, show: () => { dispatch(toggleLeftDrawer(true)); }, removePlotVariable: (varName) => { dispatch(removePlotVariable(varName)); }, toggleModelingView: (modelView) => { dispatch(toggleModelingView(modelView)); }, setResultNode: (resultNode) => { dispatch(setResultNode(resultNode)); }, toggleRightDrawer: (show) => { dispatch(toggleRightDrawer(show)); }, }); class LeftDrawer extends Component { static propTypes = { gmeClient: PropTypes.object.isRequired, open: PropTypes.bool.isRequired, classes: PropTypes.object.isRequired, activeNode: PropTypes.string.isRequired, scale: PropTypes.number.isRequired, modelingView: PropTypes.bool.isRequired, variables: PropTypes.arrayOf(PropTypes.string).isRequired, removePlotVariable: PropTypes.func.isRequired, toggleModelingView: PropTypes.func.isRequired, // setResultNode: PropTypes.func.isRequired, toggleRightDrawer: PropTypes.func.isRequired, show: PropTypes.func.isRequired, hide: PropTypes.func.isRequired, }; constructor(props) { super(props); const {gmeConfig} = this.props.gmeClient; this.SystemSimulatorMetadata = JSON.parse(JSON.stringify(SystemSimulatorMetadata)); this.SystemSimulatorMetadata.configStructure.forEach((configDesc) => { if (gmeConfig.plugin.SystemSimulator && gmeConfig.plugin.SystemSimulator[configDesc.name] !== undefined) { configDesc.value = gmeConfig.plugin.SystemSimulator[configDesc.name]; configDesc.readOnly = true; } }); } state = { showSimulator: false, showChecker: false, showDomainSelector: false, showHistory: false, checkResult: null, }; onUpdateDomains = (data) => { const {gmeClient} = this.props; this.setState({showDomainSelector: false}); if (!data) { // Cancelled return; } const path = [ window.location.origin + gmeClient.mountedPath, gmeClient.gmeConfig.rest.components.DomainManager.mount, 'updateProject', ].join('/'); superagent.post(path) .send({ projectId: gmeClient.getActiveProjectId(), domains: data.domains, }) .end((err, result) => { if (err) { // TODO: we need to show these errors console.error(err); } else { console.log(result.body); // const [owner, name] = result.body.projectId.split('+'); // this.props.history.push(`/p/${owner}/${name}`); } }); }; getCheckResultContent = () => { const {checkResult} = this.state; if (checkResult.success === true) { return (<NotifyDialog title="Model check success" text="The model has no issues and can be simulated as such." onOK={ () => { this.setState({checkResult: null}); }} />); } return (<PluginResultDialog onOK={ () => { this.setState({checkResult: null}); } } result={checkResult} title="Model check findings" />); }; runModelCheck = (config) => { const {gmeClient, activeNode} = this.props; console.log(ModelCheckPlugin); this.setState({showChecker: false}); if (!config) { // Cancelled return; } const pluginId = ModelCheckMetadata.id; const context = gmeClient.getCurrentPluginContext(pluginId, activeNode); // TODO: Remove when engine is bumped context.managerConfig.activeNode = activeNode; gmeClient.runBrowserPlugin(ModelCheckPlugin, context, (err, result) => { if (err) { console.error(err); } else { console.log('model check finished'); this.setState({checkResult: result}); } }); }; runSimulator = (config) => { const {gmeClient, activeNode} = this.props; const pluginId = this.SystemSimulatorMetadata.id; this.setState({showSimulator: false}); if (!config) { // Cancelled return; } if (config.simulationTool === 'Only Code Generation') { const context = gmeClient.getCurrentPluginContext(pluginId, activeNode); context.pluginConfig = config; gmeClient.runServerPlugin(pluginId, context, (err, result) => { if (err) { console.error(err); } else if (result.success) { downloadBlobArtifact(result.artifacts[0]); } else { console.error(result); } }); } else { const simResContainer = getMetaNodeByName(gmeClient, 'SimulationResults'); const simResMeta = getMetaNodeByName(gmeClient, 'SimulationResult'); if (!simResContainer || !simResMeta) { console.error(new Error('Could not find SimulationResults or SimulationResult in meta...')); return; } gmeClient.startTransaction(); // Create a Simulation Result.. const resId = gmeClient.createNode({ parentId: simResContainer.getId(), baseId: simResMeta.getId(), }, { attributes: { name: config.executionName, timeStamp: Date.now(), }, }); // .. copy over the canvas model const modelId = gmeClient.copyNode(activeNode, resId); const uiId = gmeClient.addUI(null, () => { }); gmeClient.updateTerritory(uiId, {[modelId]: {children: 0}}); gmeClient.completeTransaction('Created simulation results', (err) => { if (err) { console.error(err); return; } const context = gmeClient.getCurrentPluginContext(pluginId, modelId); context.pluginConfig = config; gmeClient.removeUI(uiId); this.props.toggleModelingView(false); this.props.show(); this.props.toggleRightDrawer(false); gmeClient.runServerPlugin(pluginId, context, (err2, result) => { if (err2) { console.error(err2); } else if (result.success) { // downloadBlobArtifact(result.artifacts[0]); } else { console.error(result); } }); }); } }; render() { const { classes, gmeClient, open, modelingView, variables, activeNode, scale, } = this.props; let actionButtons; if (modelingView) { actionButtons = [ { id: 'showChecker', iconClass: <CheckCircle style={{color: green[500]}}/>, onClick: () => { this.setState({showChecker: true}); }, }, { id: 'showSimulator', iconClass: <PlayCircleOutline color="primary"/>, onClick: () => { this.setState({showSimulator: true}); }, }, { id: 'showDomainSelector', iconClass: <AddCircle color="secondary"/>, onClick: () => { this.setState({showDomainSelector: true}); }, }, { id: 'showHistory', iconClass: <History color="primary"/>, onClick: () => { this.setState({showHistory: true}); }, }, ]; } else if (!open) { actionButtons = variables.map(variable => ({ id: variable, iconClass: <Timeline style={{color: colorHash(variable).rgb}}/>, color: colorHash(variable).rgb, onClick: () => { this.props.removePlotVariable(variable); }, })); } else { actionButtons = []; } return ( <div> <Drawer variant="permanent" anchor="left" open={open} classes={{paper: classNames(classes.drawerPaper, !open && classes.drawerPaperClose)}} > <span> <IconButton onClick={open ? this.props.hide : this.props.show}> {open ? <ChevronLeftIcon/> : <ChevronRightIcon/>} </IconButton> {actionButtons.map(desc => ( <IconButton key={desc.id} onClick={desc.onClick} > {desc.iconClass} </IconButton> ))} </span> <Divider/> {modelingView ? <PartBrowser gmeClient={gmeClient} activeNode={activeNode} minimized={!open} scale={scale}/> : <ResultList gmeClient={gmeClient} minimized={!open}/>} </Drawer> {this.state.showSimulator ? <PluginConfigDialog metadata={this.SystemSimulatorMetadata} onOK={this.runSimulator} /> : null} {this.state.showChecker ? <PluginConfigDialog metadata={ModelCheckMetadata} onOK={this.runModelCheck} fastForward /> : null} {this.state.showDomainSelector ? <DomainSelector domains={(gmeClient.getProjectInfo().info.kind || '').split(':').slice(1)} showDomainSelection title="Update Domains" onOK={this.onUpdateDomains} onCancel={this.onUpdateDomains} /> : null} {this.state.checkResult ? this.getCheckResultContent() : null} {this.state.showHistory ? <ProjectHistory gmeClient={gmeClient} onOK={() => { this.setState({showHistory: false}); }} /> : null} </div> ); } } export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(LeftDrawer));