Skip to content
Snippets Groups Projects
Commit e64e8902 authored by Sandro Weber's avatar Sandro Weber
Browse files

simulation view can start/pause simulation

parent 6dfd4e20
No related branches found
No related tags found
No related merge requests found
...@@ -15,7 +15,7 @@ class App extends React.Component { ...@@ -15,7 +15,7 @@ class App extends React.Component {
<HashRouter> <HashRouter>
<Switch> <Switch>
<Route path='/experiments-overview' component={ExperimentOverview} /> <Route path='/experiments-overview' component={ExperimentOverview} />
<Route path='/simulation-view/:simID' component={SimulationView} /> <Route path='/simulation-view/:serverIP/:simulationID' component={SimulationView} />
<Route path='/' component={EntryPage} /> <Route path='/' component={EntryPage} />
</Switch> </Switch>
</HashRouter> </HashRouter>
......
...@@ -55,6 +55,13 @@ class SimulationDetails extends React.Component { ...@@ -55,6 +55,13 @@ class SimulationDetails extends React.Component {
}); });
} }
joinSimulation(simulationInfo) {
console.info(simulationInfo);
this.props.history.push({
pathname: '/simulation-view/' + simulationInfo.server + '/' + simulationInfo.runningSimulation.simulationID
});
}
render() { render() {
return ( return (
<div className='simulations-details-wrapper'> <div className='simulations-details-wrapper'>
...@@ -81,10 +88,7 @@ class SimulationDetails extends React.Component { ...@@ -81,10 +88,7 @@ class SimulationDetails extends React.Component {
type="button" className='nrp-btn btn-default' type="button" className='nrp-btn btn-default'
disabled={this.isJoinDisabled(simulation)} disabled={this.isJoinDisabled(simulation)}
onClick={() => { onClick={() => {
console.info(simulation); this.joinSimulation(simulation);
this.props.history.push({
pathname: '/simulation-view/' + simulation.runningSimulation.simulationID
});
}}> }}>
<ImEnter className='icon' />Join <ImEnter className='icon' />Join
</button> </button>
......
.simulation-view-wrapper { .simulation-view-wrapper {
display: grid; display: grid;
grid-template-rows: 63px auto; grid-template-rows: auto auto;
grid-template-columns: 100px auto; grid-template-columns: 66px auto;
grid-template-areas: grid-template-areas:
"simulation-view-header simulation-view-header" "simulation-view-header simulation-view-header"
"simulation-view-sidebar simulation-view-mainview"; "simulation-view-sidebar simulation-view-mainview";
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
background-color: red; background-color: red;
} }
.simulation-view-flexlayout { .flexlayout__layout {
position: relative; position: relative;
height: calc(100vh - 63px); height: calc(100vh - 63px);
} }
...@@ -69,7 +69,9 @@ ...@@ -69,7 +69,9 @@
margin: 2px; margin: 2px;
padding: 2px; padding: 2px;
font-size: 0.7em; font-size: 0.7em;
color: black;
font-weight: bold; font-weight: bold;
background-color: lightgray;
} }
iframe { iframe {
......
import React from 'react'; import React from 'react';
import FlexLayout from 'flexlayout-react'; import FlexLayout from 'flexlayout-react';
import { OverlayTrigger, Tooltip, Button } from 'react-bootstrap'; import { OverlayTrigger, Tooltip, Button } from 'react-bootstrap';
import { RiPlayFill, RiLayout6Line } from 'react-icons/ri'; import { RiPlayFill, RiPauseFill, RiLayout6Line } from 'react-icons/ri';
import { GiExitDoor } from 'react-icons/gi'; import { GiExitDoor } from 'react-icons/gi';
import { TiMediaRecord } from 'react-icons/ti'; import { TiMediaRecord } from 'react-icons/ti';
import { VscDebugRestart } from 'react-icons/vsc'; import { VscDebugRestart } from 'react-icons/vsc';
import SimulationToolsService from './simulation-tools-service'; import SimulationToolsService from './simulation-tools-service';
import RunningSimulationService from '../../services/experiments/execution/running-simulation-service';
import { EXPERIMENT_STATE } from '../../services/experiments/experiment-constants';
import '../../../node_modules/flexlayout-react/style/light.css'; import '../../../node_modules/flexlayout-react/style/light.css';
import './simulation-view.css'; import './simulation-view.css';
...@@ -34,29 +36,34 @@ const jsonBaseLayout = { ...@@ -34,29 +36,34 @@ const jsonBaseLayout = {
} }
}; };
const classNameMapper = (className) => {
if (className === 'flexlayout__layout') {
return 'simulation-view-flexlayout';
}
else {
return className;
}
};
export default class SimulationView extends React.Component { export default class SimulationView extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
console.info(this.state);
console.info(this.props); const {serverIP, simulationID} = props.match.params;
//console.info('SimulationView ' + serverIP + ' ' + simulationID);
this.serverIP = serverIP;
this.simulationID = simulationID;
this.serverURL = 'http://' + this.serverIP + ':8080';
this.state = {model: FlexLayout.Model.fromJson(jsonBaseLayout)}; this.state = {model: FlexLayout.Model.fromJson(jsonBaseLayout)};
console.info(this.state); this.updateSimulationInfo();
this.refLayout = React.createRef(); this.refLayout = React.createRef();
} }
factory = (node) => { async updateSimulationInfo() {
return SimulationToolsService.instance.flexlayoutNodeFactory(node); let simInfo = await RunningSimulationService.instance.getInfo(this.serverURL, this.simulationID);
this.setState({simulationInfo: simInfo});
}
async onButtonStartPause() {
let newState = this.state.simulationInfo.state === EXPERIMENT_STATE.PAUSED
? EXPERIMENT_STATE.STARTED
: EXPERIMENT_STATE.PAUSED;
await RunningSimulationService.instance.updateState(this.serverURL, this.simulationID, newState);
this.updateSimulationInfo();
} }
render() { render() {
...@@ -67,7 +74,13 @@ export default class SimulationView extends React.Component { ...@@ -67,7 +74,13 @@ export default class SimulationView extends React.Component {
<div className='simulation-view-control-buttons'> <div className='simulation-view-control-buttons'>
<button className='nrp-btn btn-default'><GiExitDoor className='icon' /></button> <button className='nrp-btn btn-default'><GiExitDoor className='icon' /></button>
<button className='nrp-btn btn-default'><VscDebugRestart className='icon' /></button> <button className='nrp-btn btn-default'><VscDebugRestart className='icon' /></button>
<button className='nrp-btn btn-default'><RiPlayFill className='icon' /></button> <button className='nrp-btn btn-default' onClick={() => {
this.onButtonStartPause();
}}>
{this.state.simulationInfo && this.state.simulationInfo.state === EXPERIMENT_STATE.PAUSED
? <RiPlayFill className='icon' />
: <RiPauseFill className='icon' />}
</button>
<button className='nrp-btn btn-default'><TiMediaRecord className='icon' /></button> <button className='nrp-btn btn-default'><TiMediaRecord className='icon' /></button>
</div> </div>
...@@ -108,8 +121,10 @@ export default class SimulationView extends React.Component { ...@@ -108,8 +121,10 @@ export default class SimulationView extends React.Component {
})} })}
</div> </div>
<div className='simulation-view-mainview'> <div className='simulation-view-mainview'>
<FlexLayout.Layout ref={this.refLayout} model={this.state.model} factory={this.factory} <FlexLayout.Layout ref={this.refLayout} model={this.state.model}
classNameMapper={classNameMapper}/> factory={(node) => {
return SimulationToolsService.instance.flexlayoutNodeFactory(node);
}} />
</div> </div>
</div> </div>
); );
......
...@@ -200,7 +200,7 @@ class ExperimentExecutionService extends HttpService { ...@@ -200,7 +200,7 @@ class ExperimentExecutionService extends HttpService {
return SimulationService.instance.updateState( return SimulationService.instance.updateState(
serverURL, serverURL,
simulationID, simulationID,
{ state: state } state
); );
} }
......
...@@ -164,13 +164,30 @@ class SimulationService extends HttpService { ...@@ -164,13 +164,30 @@ class SimulationService extends HttpService {
async updateState(serverURL, simulationID, state) { async updateState(serverURL, simulationID, state) {
let url = serverURL + '/simulation/' + simulationID + '/state'; let url = serverURL + '/simulation/' + simulationID + '/state';
try { try {
let response = await this.httpRequestPUT(url, JSON.stringify(state)); let response = await this.httpRequestPUT(url, JSON.stringify({ state: state }));
return response; return response;
} }
catch (error) { catch (error) {
ErrorHandlerService.instance.updateSimulationError(error); ErrorHandlerService.instance.updateSimulationError(error);
} }
} }
/**
* Get simulation information.
* @param {string} serverURL The full URL of the server the simulation is running on
* @param {string} simulationID The simulation ID
* @returns The simulation information
*/
async getInfo(serverURL, simulationID) {
let url = serverURL + '/simulation/' + simulationID;
try {
let response = await (await this.httpRequestGET(url)).json();
return response;
}
catch (error) {
ErrorHandlerService.instance.networkError(error);
}
}
} }
export default SimulationService; export default SimulationService;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment