Loading js-apps/meep-frontend/package.json +1 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ "test:verbose": "jest --verbose true", "test:coverage": "jest --verbose true --coverage --colors", "build": "webpack", "build:dev": "webpack-serve --port 8091 --host 10.3.16.105" "build:dev": "webpack-serve --port 8091 --host 10.3.16.150" }, "author": "", "license": "ISC", Loading js-apps/meep-frontend/src/js/components/dialogs/id-save-replay-dialog.js 0 → 100644 +123 −0 Original line number Diff line number Diff line /* * Copyright (c) 2019 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import React, { Component } from 'react'; import { TextField, TextFieldHelperText } from '@rmwc/textfield'; import IDDialog from './id-dialog'; import { MEEP_DLG_SAVE_REPLAY } from '../../meep-constants'; class IDSaveReplayDialog extends Component { constructor(props) { super(props); this.state = { err: null, replayName: null, description: null }; } changeReplayName(name) { var err = null; if (name) { if (name.length > 20) { err = 'Maximum 20 characters'; } else if (!name.match(/^(([a-z0-9][-a-z0-9.]*)?[a-z0-9])+$/)) { err = 'Lowercase alphanumeric or \'-\''; } } else { err = 'Please enter a replay file name'; } this.setState({ replayName: name, err: err }); } changeDescription(desc) { var err = null; if (desc) { if (desc.length > 30) { err = 'Maximum 30 characters'; } } this.setState({ description: desc, err: err }); } saveReplay() { this.props.saveReplay(this.state); } render() { return ( <IDDialog title={this.props.title} open={this.props.open} onClose={this.props.onClose} onSubmit={() => this.saveReplay()} okDisabled={ (!this.state.replayName && this.props.replayNameRequired) || this.state.err } cydata={MEEP_DLG_SAVE_REPLAY} > <span style={styles.text}> { 'Store the events as a replay file in the MEEP Controller for current deployed scenario (overwrites any existing replay file with the same name)' } </span> <TextField outlined style={{ width: '100%' }} label={'Replay Name'} invalid={ this.state.err || (!this.state.replayName && this.props.replayNameRequired) } onChange={e => this.changeReplayName(e.target.value)} value={this.replayName} /> <TextField outlined style={{ width: '100%' }} label={'Replay Description'} invalid={ this.state.err } onChange={e => this.changeDescription(e.target.value)} value={this.description} /> <TextFieldHelperText validationMsg={true}> <span>{this.state.err}</span> </TextFieldHelperText> </IDDialog> ); } } const styles = { text: { color: 'gray' } }; export default IDSaveReplayDialog; js-apps/meep-frontend/src/js/containers/exec/event-container.js 0 → 100644 +210 −0 Original line number Diff line number Diff line /* * Copyright (c) 2019 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { connect } from 'react-redux'; import React, { Component } from 'react'; import { Grid, GridCell } from '@rmwc/grid'; import { Elevation } from '@rmwc/elevation'; import { Button } from '@rmwc/button'; import { Checkbox } from '@rmwc/checkbox'; import { uiExecChangeEventCreationMode, uiExecChangeEventReplayMode } from '../../state/ui'; import { EXEC_BTN_MANUAL_REPLAY, EXEC_BTN_AUTO_REPLAY, EXEC_BTN_SAVE_REPLAY } from '../../meep-constants'; const greyColor = 'grey'; const styles = { button: { marginRight: 0 }, slider: { container: { marginTop: 10, marginBottom: 10, color: greyColor }, boundaryValues: { marginTop: 15 }, title: { marginBottom: 0 } }, section1: { color: 'white', marginRight: 5 }, section2: { color: 'white', marginRight: 5, marginLeft: 10 } }; const ConfigurationView = props => { return ( <> <Grid style={{ marginBottom: 10 }}> <GridCell span={6}> <Button raised style={styles.section1} onClick={props.onCreateEvent} data-cy={EXEC_BTN_MANUAL_REPLAY} > MANUAL </Button> <Button raised style={styles.section1} onClick={props.onReplayEvent} data-cy={EXEC_BTN_AUTO_REPLAY} > AUTO-REPLAY </Button> <Button raised style={styles.section1} onClick={props.onSaveReplay} data-cy={EXEC_BTN_SAVE_REPLAY} > SAVE EVENTS AS ... </Button> </GridCell> </Grid> </> ); }; const EventConfiguration = props => { if (!props.eventCfgMode) { return null; } let configurationView = null; configurationView = ( <ConfigurationView onCreateEvent={props.onCreateEvent} onReplayEvent={props.onReplayEvent} onSaveReplay={props.onSaveReplay} /> ); return ( <Elevation z={2} className="component-style" style={{ padding: 10, marginBottom: 10 }} > <Grid> <GridCell span={11}> <div style={{ marginBottom: 10 }}> <span className="mdc-typography--headline6"> Event Configuration </span> </div> </GridCell> <GridCell span={1}> <Button outlined style={styles.button} onClick={() => props.onCloseEventCfg()} > Close </Button> </GridCell> </Grid> {configurationView} </Elevation> ); }; class EventContainer extends Component { constructor(props) { super(props); this.state = { sourceNodeId: '' }; } componentDidMount() { } componentWillUnmount() { clearInterval(this.dataTimer); } changeReplayLoop(checked) { this.props.onReplayLoopChanged(checked); } // CREATE EVENT PANE onCreateEvent() { this.props.changeEventCreationMode(true); this.props.changeEventReplayMode(false); } // SHOW REPLAY EVENT PANE onReplayEvent() { this.props.changeEventReplayMode(true); this.props.changeEventCreationMode(false); } render() { return ( <> <EventConfiguration eventCfgMode={this.props.eventCfgMode} onCloseEventCfg={this.props.onCloseEventCfg} onCreateEvent={() => this.onCreateEvent()} onReplayEvent={() => this.onReplayEvent()} onSaveReplay={this.props.onSaveReplay} changeReplayLoop={checked => this.changeReplayLoop(checked)} replayLoop={this.props.replayLoop} /> </> ); } } const mapStateToProps = state => { return { eventCreationMode: state.exec.eventCreationMode, eventReplayMode: state.exec.eventReplayMode }; }; const mapDispatchToProps = dispatch => { return { changeEventCreationMode: mode => dispatch(uiExecChangeEventCreationMode(mode)), changeEventReplayMode: mode => dispatch(uiExecChangeEventReplayMode(mode)) }; }; const ConnectedEventContainer = connect( mapStateToProps, mapDispatchToProps )(EventContainer); export default ConnectedEventContainer; js-apps/meep-frontend/src/js/containers/exec/event-creation-pane.js +1 −1 Original line number Diff line number Diff line Loading @@ -114,7 +114,7 @@ class EventCreationPane extends Component { } render() { if (this.props.page !== PAGE_EXECUTE) { if (this.props.page !== PAGE_EXECUTE || this.props.hide) { return null; } Loading js-apps/meep-frontend/src/js/containers/exec/event-replay-pane.js 0 → 100644 +243 −0 Original line number Diff line number Diff line /* * Copyright (c) 2019 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { connect } from 'react-redux'; import React, { Component } from 'react'; import { Button } from '@rmwc/button'; import { Checkbox } from '@rmwc/checkbox'; import { Select } from '@rmwc/select'; import { Grid, GridInner, GridCell } from '@rmwc/grid'; import { Typography } from '@rmwc/typography'; import { updateObject } from '../../util/object-util'; import { uiExecChangeReplayFileSelected } from '../../state/ui'; import { EXEC_EVT_REPLAY_FILES, EXEC_BTN_REPLAY_START, EXEC_BTN_REPLAY_STOP } from '../../meep-constants'; import { execChangeReplayFilesList } from '../../state/exec'; import { EXEC_EVT_TYPE, PAGE_EXECUTE } from '../../meep-constants'; const ReplayFileSelect = props => { return ( <Grid style={styles.field}> <GridCell span={12}> <Select style={styles.select} label="Replay file" fullwidth="true" outlined options={props.replayFiles} onChange={props.onChange} onClick={props.onClick} value={props.replayFileSelected} data-cy={EXEC_EVT_REPLAY_FILES} /> </GridCell> </Grid> ); }; class EventReplayPane extends Component { constructor(props) { super(props); this.state = { description: null }; } triggerReplay(play) { if (play) { if (this.props.replayLoop) { this.props.api.loopReplay(this.props.replayFileSelected, (error, data, response) => { if (error) { console.log(error) } }); } else { this.props.api.playReplayFile(this.props.replayFileSelected, (error, data, response) => { if (error) { console.log(error) } }); } } else { //stop this.props.api.stopReplayFile(this.props.replayFileSelected, (error, data, response) => { if (error) { console.log(error) } }); } } changeLoop(checked) { this.props.onReplayLoopChanged(checked); } /** * Callback function to receive the result of the getReplayList operation. * @callback module:api/EventReplayApi~getReplayFileListCallback * @param {String} error Error message, if any. * @param {module:model/ReplayFileList} data The data returned by the service call. */ getReplayFileListCb(error, data) { if (error !== null) { // TODO: consider showing an alert/toast return; } this.props.changeReplayFilesList(data.replayFiles); } /** * Callback function to receive the result of the getReplayFile operation. * @callback module:api/EventReplayApi~getReplayFileCallback * @param {String} error Error message, if any. * @param {module:model/Replay} data The data returned by the service call. */ getReplayFileCb(error, data) { if (error !== null) { // TODO: consider showing an alert/toast return; } this.state.description = data.description; } updateReplayFileList() { this.props.api.getReplayFileList((error, data, response) => { this.getReplayFileListCb(error, data, response); }); } getDescription(name) { this.props.api.getReplayFile(name, (error, data, response) => { this.getReplayFileCb(error, data, response); }); } render() { if (this.props.page !== PAGE_EXECUTE || this.props.hide) { return null; } return ( <div style={{ padding: 10 }}> <div style={styles.block}> <Typography use="headline6">Replay Events</Typography> </div> <ReplayFileSelect replayFiles={this.props.replayFiles} replayFileSelected={this.props.replayFileSelected} onClick={() => this.updateReplayFileList()} onChange={event => { this.props.changeReplayFileSelected(event.target.value); this.getDescription(event.target.value); }} /> <div style={styles.block}> <Typography use="subtitle2">{this.state.description}</Typography> </div> <Grid style={{ marginBottom: 10 }}> <GridCell span={2}> <Checkbox checked={this.props.replayLoop} onChange={e => this.changeLoop(e.target.checked)} > Loop </Checkbox> </GridCell> </Grid> <Grid style={{ marginTop: 10 }}> <GridInner align={'right'}> <GridCell span={12}> <Button raised style={styles.section1} onClick={() => this.triggerReplay(true)} data-cy={EXEC_BTN_REPLAY_START} > START </Button> <Button raised style={styles.section1} onClick={() => this.triggerReplay(false)} data-cy={EXEC_BTN_REPLAY_STOP} > STOP </Button> <Button outlined style={styles.button} onClick={this.props.onClose} > Close </Button> </GridCell> </GridInner> </Grid> </div> ); } } const styles = { button: { marginRight: 0 }, block: { marginBottom: 20 }, field: { marginBottom: 10 }, section1: { color: 'white', marginRight: 5 }, select: { width: '100%' } }; const mapStateToProps = state => { return { page: state.ui.page }; }; const mapDispatchToProps = dispatch => { return { changeReplayFileSelected: name => dispatch(uiExecChangeReplayFileSelected(name)), changeReplayFilesList: list => dispatch(execChangeReplayFilesList(list)) }; }; const ConnectedEventReplayPane = connect( mapStateToProps, mapDispatchToProps )(EventReplayPane); export default ConnectedEventReplayPane; Loading
js-apps/meep-frontend/package.json +1 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ "test:verbose": "jest --verbose true", "test:coverage": "jest --verbose true --coverage --colors", "build": "webpack", "build:dev": "webpack-serve --port 8091 --host 10.3.16.105" "build:dev": "webpack-serve --port 8091 --host 10.3.16.150" }, "author": "", "license": "ISC", Loading
js-apps/meep-frontend/src/js/components/dialogs/id-save-replay-dialog.js 0 → 100644 +123 −0 Original line number Diff line number Diff line /* * Copyright (c) 2019 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import React, { Component } from 'react'; import { TextField, TextFieldHelperText } from '@rmwc/textfield'; import IDDialog from './id-dialog'; import { MEEP_DLG_SAVE_REPLAY } from '../../meep-constants'; class IDSaveReplayDialog extends Component { constructor(props) { super(props); this.state = { err: null, replayName: null, description: null }; } changeReplayName(name) { var err = null; if (name) { if (name.length > 20) { err = 'Maximum 20 characters'; } else if (!name.match(/^(([a-z0-9][-a-z0-9.]*)?[a-z0-9])+$/)) { err = 'Lowercase alphanumeric or \'-\''; } } else { err = 'Please enter a replay file name'; } this.setState({ replayName: name, err: err }); } changeDescription(desc) { var err = null; if (desc) { if (desc.length > 30) { err = 'Maximum 30 characters'; } } this.setState({ description: desc, err: err }); } saveReplay() { this.props.saveReplay(this.state); } render() { return ( <IDDialog title={this.props.title} open={this.props.open} onClose={this.props.onClose} onSubmit={() => this.saveReplay()} okDisabled={ (!this.state.replayName && this.props.replayNameRequired) || this.state.err } cydata={MEEP_DLG_SAVE_REPLAY} > <span style={styles.text}> { 'Store the events as a replay file in the MEEP Controller for current deployed scenario (overwrites any existing replay file with the same name)' } </span> <TextField outlined style={{ width: '100%' }} label={'Replay Name'} invalid={ this.state.err || (!this.state.replayName && this.props.replayNameRequired) } onChange={e => this.changeReplayName(e.target.value)} value={this.replayName} /> <TextField outlined style={{ width: '100%' }} label={'Replay Description'} invalid={ this.state.err } onChange={e => this.changeDescription(e.target.value)} value={this.description} /> <TextFieldHelperText validationMsg={true}> <span>{this.state.err}</span> </TextFieldHelperText> </IDDialog> ); } } const styles = { text: { color: 'gray' } }; export default IDSaveReplayDialog;
js-apps/meep-frontend/src/js/containers/exec/event-container.js 0 → 100644 +210 −0 Original line number Diff line number Diff line /* * Copyright (c) 2019 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { connect } from 'react-redux'; import React, { Component } from 'react'; import { Grid, GridCell } from '@rmwc/grid'; import { Elevation } from '@rmwc/elevation'; import { Button } from '@rmwc/button'; import { Checkbox } from '@rmwc/checkbox'; import { uiExecChangeEventCreationMode, uiExecChangeEventReplayMode } from '../../state/ui'; import { EXEC_BTN_MANUAL_REPLAY, EXEC_BTN_AUTO_REPLAY, EXEC_BTN_SAVE_REPLAY } from '../../meep-constants'; const greyColor = 'grey'; const styles = { button: { marginRight: 0 }, slider: { container: { marginTop: 10, marginBottom: 10, color: greyColor }, boundaryValues: { marginTop: 15 }, title: { marginBottom: 0 } }, section1: { color: 'white', marginRight: 5 }, section2: { color: 'white', marginRight: 5, marginLeft: 10 } }; const ConfigurationView = props => { return ( <> <Grid style={{ marginBottom: 10 }}> <GridCell span={6}> <Button raised style={styles.section1} onClick={props.onCreateEvent} data-cy={EXEC_BTN_MANUAL_REPLAY} > MANUAL </Button> <Button raised style={styles.section1} onClick={props.onReplayEvent} data-cy={EXEC_BTN_AUTO_REPLAY} > AUTO-REPLAY </Button> <Button raised style={styles.section1} onClick={props.onSaveReplay} data-cy={EXEC_BTN_SAVE_REPLAY} > SAVE EVENTS AS ... </Button> </GridCell> </Grid> </> ); }; const EventConfiguration = props => { if (!props.eventCfgMode) { return null; } let configurationView = null; configurationView = ( <ConfigurationView onCreateEvent={props.onCreateEvent} onReplayEvent={props.onReplayEvent} onSaveReplay={props.onSaveReplay} /> ); return ( <Elevation z={2} className="component-style" style={{ padding: 10, marginBottom: 10 }} > <Grid> <GridCell span={11}> <div style={{ marginBottom: 10 }}> <span className="mdc-typography--headline6"> Event Configuration </span> </div> </GridCell> <GridCell span={1}> <Button outlined style={styles.button} onClick={() => props.onCloseEventCfg()} > Close </Button> </GridCell> </Grid> {configurationView} </Elevation> ); }; class EventContainer extends Component { constructor(props) { super(props); this.state = { sourceNodeId: '' }; } componentDidMount() { } componentWillUnmount() { clearInterval(this.dataTimer); } changeReplayLoop(checked) { this.props.onReplayLoopChanged(checked); } // CREATE EVENT PANE onCreateEvent() { this.props.changeEventCreationMode(true); this.props.changeEventReplayMode(false); } // SHOW REPLAY EVENT PANE onReplayEvent() { this.props.changeEventReplayMode(true); this.props.changeEventCreationMode(false); } render() { return ( <> <EventConfiguration eventCfgMode={this.props.eventCfgMode} onCloseEventCfg={this.props.onCloseEventCfg} onCreateEvent={() => this.onCreateEvent()} onReplayEvent={() => this.onReplayEvent()} onSaveReplay={this.props.onSaveReplay} changeReplayLoop={checked => this.changeReplayLoop(checked)} replayLoop={this.props.replayLoop} /> </> ); } } const mapStateToProps = state => { return { eventCreationMode: state.exec.eventCreationMode, eventReplayMode: state.exec.eventReplayMode }; }; const mapDispatchToProps = dispatch => { return { changeEventCreationMode: mode => dispatch(uiExecChangeEventCreationMode(mode)), changeEventReplayMode: mode => dispatch(uiExecChangeEventReplayMode(mode)) }; }; const ConnectedEventContainer = connect( mapStateToProps, mapDispatchToProps )(EventContainer); export default ConnectedEventContainer;
js-apps/meep-frontend/src/js/containers/exec/event-creation-pane.js +1 −1 Original line number Diff line number Diff line Loading @@ -114,7 +114,7 @@ class EventCreationPane extends Component { } render() { if (this.props.page !== PAGE_EXECUTE) { if (this.props.page !== PAGE_EXECUTE || this.props.hide) { return null; } Loading
js-apps/meep-frontend/src/js/containers/exec/event-replay-pane.js 0 → 100644 +243 −0 Original line number Diff line number Diff line /* * Copyright (c) 2019 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { connect } from 'react-redux'; import React, { Component } from 'react'; import { Button } from '@rmwc/button'; import { Checkbox } from '@rmwc/checkbox'; import { Select } from '@rmwc/select'; import { Grid, GridInner, GridCell } from '@rmwc/grid'; import { Typography } from '@rmwc/typography'; import { updateObject } from '../../util/object-util'; import { uiExecChangeReplayFileSelected } from '../../state/ui'; import { EXEC_EVT_REPLAY_FILES, EXEC_BTN_REPLAY_START, EXEC_BTN_REPLAY_STOP } from '../../meep-constants'; import { execChangeReplayFilesList } from '../../state/exec'; import { EXEC_EVT_TYPE, PAGE_EXECUTE } from '../../meep-constants'; const ReplayFileSelect = props => { return ( <Grid style={styles.field}> <GridCell span={12}> <Select style={styles.select} label="Replay file" fullwidth="true" outlined options={props.replayFiles} onChange={props.onChange} onClick={props.onClick} value={props.replayFileSelected} data-cy={EXEC_EVT_REPLAY_FILES} /> </GridCell> </Grid> ); }; class EventReplayPane extends Component { constructor(props) { super(props); this.state = { description: null }; } triggerReplay(play) { if (play) { if (this.props.replayLoop) { this.props.api.loopReplay(this.props.replayFileSelected, (error, data, response) => { if (error) { console.log(error) } }); } else { this.props.api.playReplayFile(this.props.replayFileSelected, (error, data, response) => { if (error) { console.log(error) } }); } } else { //stop this.props.api.stopReplayFile(this.props.replayFileSelected, (error, data, response) => { if (error) { console.log(error) } }); } } changeLoop(checked) { this.props.onReplayLoopChanged(checked); } /** * Callback function to receive the result of the getReplayList operation. * @callback module:api/EventReplayApi~getReplayFileListCallback * @param {String} error Error message, if any. * @param {module:model/ReplayFileList} data The data returned by the service call. */ getReplayFileListCb(error, data) { if (error !== null) { // TODO: consider showing an alert/toast return; } this.props.changeReplayFilesList(data.replayFiles); } /** * Callback function to receive the result of the getReplayFile operation. * @callback module:api/EventReplayApi~getReplayFileCallback * @param {String} error Error message, if any. * @param {module:model/Replay} data The data returned by the service call. */ getReplayFileCb(error, data) { if (error !== null) { // TODO: consider showing an alert/toast return; } this.state.description = data.description; } updateReplayFileList() { this.props.api.getReplayFileList((error, data, response) => { this.getReplayFileListCb(error, data, response); }); } getDescription(name) { this.props.api.getReplayFile(name, (error, data, response) => { this.getReplayFileCb(error, data, response); }); } render() { if (this.props.page !== PAGE_EXECUTE || this.props.hide) { return null; } return ( <div style={{ padding: 10 }}> <div style={styles.block}> <Typography use="headline6">Replay Events</Typography> </div> <ReplayFileSelect replayFiles={this.props.replayFiles} replayFileSelected={this.props.replayFileSelected} onClick={() => this.updateReplayFileList()} onChange={event => { this.props.changeReplayFileSelected(event.target.value); this.getDescription(event.target.value); }} /> <div style={styles.block}> <Typography use="subtitle2">{this.state.description}</Typography> </div> <Grid style={{ marginBottom: 10 }}> <GridCell span={2}> <Checkbox checked={this.props.replayLoop} onChange={e => this.changeLoop(e.target.checked)} > Loop </Checkbox> </GridCell> </Grid> <Grid style={{ marginTop: 10 }}> <GridInner align={'right'}> <GridCell span={12}> <Button raised style={styles.section1} onClick={() => this.triggerReplay(true)} data-cy={EXEC_BTN_REPLAY_START} > START </Button> <Button raised style={styles.section1} onClick={() => this.triggerReplay(false)} data-cy={EXEC_BTN_REPLAY_STOP} > STOP </Button> <Button outlined style={styles.button} onClick={this.props.onClose} > Close </Button> </GridCell> </GridInner> </Grid> </div> ); } } const styles = { button: { marginRight: 0 }, block: { marginBottom: 20 }, field: { marginBottom: 10 }, section1: { color: 'white', marginRight: 5 }, select: { width: '100%' } }; const mapStateToProps = state => { return { page: state.ui.page }; }; const mapDispatchToProps = dispatch => { return { changeReplayFileSelected: name => dispatch(uiExecChangeReplayFileSelected(name)), changeReplayFilesList: list => dispatch(execChangeReplayFilesList(list)) }; }; const ConnectedEventReplayPane = connect( mapStateToProps, mapDispatchToProps )(EventReplayPane); export default ConnectedEventReplayPane;