Commit 6a54e1ac authored by Kevin Di Lallo's avatar Kevin Di Lallo
Browse files

replay status update + dashboard & replay event pane fixes

parent 6dade5d1
Loading
Loading
Loading
Loading
+18 −44
Original line number Diff line number Diff line
@@ -29,14 +29,11 @@ import Iframe from 'react-iframe';

import { getScenarioNodeChildren, isApp } from '../../util/scenario-utils';

import {
  execChangeSourceNodeSelected,
  execChangeDestNodeSelected
} from '../../state/exec';

import {
  uiExecChangeDashboardView1,
  uiExecChangeDashboardView2
  uiExecChangeDashboardView2,
  uiExecChangeSourceNodeSelected,
  uiExecChangeDestNodeSelected
} from '../../state/ui';

import {
@@ -89,9 +86,7 @@ const ConfigurationView = props => {
            onChange={e => {
              props.changeSourceNodeSelected(e.target.value);
            }}
            value={
              props.sourceNodeSelected ? props.sourceNodeSelected.data.id : ''
            }
            value={props.sourceNodeSelected}
          />
        </GridCell>
        <GridCell span={2}>
@@ -102,9 +97,7 @@ const ConfigurationView = props => {
            onChange={e => {
              props.changeDestNodeSelected(e.target.value);
            }}
            value={
              props.destNodeSelected ? props.destNodeSelected.data.id : ''
            }
            value={props.destNodeSelected}
          />
        </GridCell>
        <GridCell span={2}>
@@ -285,38 +278,19 @@ class DashboardContainer extends Component {
    this.keyForSvg++;
    const root = this.getRoot();
    const nodes = root.descendants();

    const apps = nodes.filter(isApp);
    const appIds = apps.map(a => a.data.id);
    const appMap = apps.reduce((acc, app) => {
      acc[app.data.id] = app;
      return acc;
    }, {});

    const selectedSource = this.props.sourceNodeSelected
      ? this.props.sourceNodeSelected.data.id
      : null;
    appIds.unshift('None');

    const selectedDest = this.props.destNodeSelected
      ? this.props.destNodeSelected.data.id
      : null;

    // For view 1
    const selectedSource = appIds.includes(this.props.sourceNodeSelected) ? this.props.sourceNodeSelected : 'None';
    const selectedDest = appIds.includes(this.props.destNodeSelected) ? this.props.destNodeSelected : 'None';
    const view1Name = this.props.view1Name;

    // For view2
    const view2Name = this.props.view2Name;

    // const height = 600;

    let span1 = 12;
    let span2 = 12;
    // let width1 = 700;
    // let width2 = 700;

    const view1Present = this.props.view1Name !== VIEW_NAME_NONE;
    const view2Present = this.props.view2Name !== VIEW_NAME_NONE;

    let span1 = 12;
    let span2 = 12;
    if (view1Present && view2Present) {
      span1 = 6;
      span2 = 6;
@@ -361,13 +335,13 @@ class DashboardContainer extends Component {
          nodeIds={appIds}
          view1Name={view1Name}
          view2Name={view2Name}
          sourceNodeSelected={this.props.sourceNodeSelected}
          destNodeSelected={this.props.destNodeSelected}
          sourceNodeSelected={selectedSource}
          destNodeSelected={selectedDest}
          changeSourceNodeSelected={nodeId =>
            this.props.changeSourceNodeSelected(appMap[nodeId])
            this.props.changeSourceNodeSelected(nodeId)
          }
          changeDestNodeSelected={nodeId =>
            this.props.changeDestNodeSelected(appMap[nodeId])
            this.props.changeDestNodeSelected(nodeId)
          }
          dashboardViewsList={dashboardViewsList}
          changeView1={viewName => this.props.changeView1(viewName)}
@@ -413,8 +387,8 @@ class DashboardContainer extends Component {
const mapStateToProps = state => {
  return {
    displayedScenario: state.exec.displayedScenario,
    sourceNodeSelected: state.exec.metrics.sourceNodeSelected,
    destNodeSelected: state.exec.metrics.destNodeSelected,
    sourceNodeSelected: state.ui.sourceNodeSelected,
    destNodeSelected: state.ui.destNodeSelected,
    eventCreationMode: state.exec.eventCreationMode,
    scenarioState: state.exec.state.scenario,
    view1Name: state.ui.dashboardView1,
@@ -425,8 +399,8 @@ const mapStateToProps = state => {

const mapDispatchToProps = dispatch => {
  return {
    changeSourceNodeSelected: src => dispatch(execChangeSourceNodeSelected(src)),
    changeDestNodeSelected: dest => dispatch(execChangeDestNodeSelected(dest)),
    changeSourceNodeSelected: src => dispatch(uiExecChangeSourceNodeSelected(src)),
    changeDestNodeSelected: dest => dispatch(uiExecChangeDestNodeSelected(dest)),
    changeView1: name => dispatch(uiExecChangeDashboardView1(name)),
    changeView2: name => dispatch(uiExecChangeDashboardView2(name))
  };
+55 −63
Original line number Diff line number Diff line
@@ -39,26 +39,25 @@ const styles = {
};

const StatusTable = props => {
  return (
  var timeToNextEvent = props.timeToNextEvent ? props.timeToNextEvent / 1000 : 0;
  var timeRemaining = props.timeRemaining ? props.timeRemaining / 1000 : 0;

    <Grid>
      <GridCell span={4}>
        <Typography use="subtitle2">REPLAY FILE</Typography>
      </GridCell>
      <GridCell span={4}>
        <Typography use="subtitle2">EVENT COUNT</Typography>
      </GridCell>
      <GridCell span={4}>
        <Typography use="subtitle2">REMAINING TIME (MS)</Typography>
  return (
    <Grid style={{border: '1px solid #e4e4e4'}}>
      <GridCell span={2}>
        <Typography use="headline6" style={{ marginLeft: 10 }}>Status:</Typography>
      </GridCell>
      <GridCell span={4}>
      <GridCell align={'middle'} span={3}>
        <Typography use="subtitle2" style={{ marginRight: 10 }}>REPLAY FILE:</Typography>
        <Typography use="body2">{props.name}</Typography>
      </GridCell>
      <GridCell span={4}>
      <GridCell align={'middle'} span={3}>
        <Typography use="subtitle2" style={{ marginRight: 10 }}>EVENT COUNT:</Typography>
        <Typography use="body2">{props.index} / {props.maxIndex}</Typography>
      </GridCell>
      <GridCell span={4}>
        <Typography use="body2">{props.timeToNextEvent} / {props.timeRemaining}</Typography>
      <GridCell align={'middle'} span={4}>
        <Typography use="subtitle2" style={{ marginRight: 10 }}>NEXT/LAST EVENT (S):</Typography>
        <Typography use="body2">{timeToNextEvent.toFixed(2)} / {timeRemaining.toFixed(2)}</Typography>
      </GridCell>
    </Grid>
  );
@@ -91,8 +90,11 @@ class EventContainer extends Component {

  // SHOW REPLAY EVENT PANE
  onReplayEvent() {
    this.props.changeEventReplayMode(true);
    this.props.changeEventCreationMode(false);
    this.props.changeEventReplayMode(true);

    // Refresh 
    this.props.onShowReplay();
  }

  render() {
@@ -109,7 +111,7 @@ class EventContainer extends Component {
          className="component-style"
          style={{ padding: 10, marginBottom: 10 }}
        >
          <Grid>
          <Grid style={{ marginBottom: 10 }}>
            <GridCell span={6}>
              <div style={{ marginBottom: 10 }}>
                <span className="mdc-typography--headline6">
@@ -119,19 +121,6 @@ class EventContainer extends Component {
            </GridCell>
            <GridCell span={6}>
              <div align={'right'}>
                <Button
                  outlined
                  style={styles.button}
                  onClick={this.props.onCloseEventCfg}
                >
                  Close
                </Button>
              </div>
            </GridCell>
          </Grid>

          <Grid style={{ marginBottom: 10 }}>
            <GridCell span={5}>
                <Button
                  outlined
                  style={styles.button}
@@ -156,15 +145,20 @@ class EventContainer extends Component {
                >
                  SAVE EVENTS
                </Button>
                <Button
                  outlined
                  style={styles.button}
                  onClick={this.props.onCloseEventCfg}
                >
                  Close
                </Button>
              </div>
            </GridCell>
          </Grid>

            <GridCell span={6}>
              <Elevation
                z={2}
                className="component-style"
                style={{ padding: 15 }}
              >
                {replayStatus ?
          <Grid>
            <GridCell span={12}>
              {replayStatus &&
                <StatusTable
                  name={replayStatus.replayFileRunning}
                  index={replayStatus.index}
@@ -172,10 +166,8 @@ class EventContainer extends Component {
                  loopMode={replayStatus.loopMode}
                  timeRemaining={replayStatus.timeRemaining}
                  timeToNextEvent={replayStatus.timeToNextEvent}
                  /> :
                  <Typography use="subtitle2">Ready to run REPLAY file</Typography>
                />
              }
              </Elevation>
            </GridCell>
          </Grid>
        </Elevation>
@@ -188,7 +180,7 @@ const mapStateToProps = state => {
  return {
    eventCreationMode: state.exec.eventCreationMode,
    eventReplayMode: state.exec.eventReplayMode,
    replayStatus: state.ui.replayStatus
    replayStatus: state.exec.state.replayStatus
  };
};

+35 −67
Original line number Diff line number Diff line
@@ -22,7 +22,11 @@ import { Select } from '@rmwc/select';
import { Grid, GridInner, GridCell } from '@rmwc/grid';
import { Typography } from '@rmwc/typography';

import { uiExecChangeReplayFileSelected } from '../../state/ui';
import {
  uiExecChangeReplayFileSelected,
  uiExecChangeReplayFileDesc,
  uiExecChangeReplayLoop
} from '../../state/ui';

import {
  EXEC_EVT_REPLAY_FILES,
@@ -30,32 +34,8 @@ import {
  EXEC_BTN_REPLAY_STOP
} from '../../meep-constants';

import {
  execChangeReplayFilesList
} from '../../state/exec';

import { 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);
@@ -91,25 +71,6 @@ class EventReplayPane extends Component {
    }
  }

  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
@@ -121,14 +82,7 @@ class EventReplayPane extends Component {
      // 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);
    });
    this.props.changeReplayFileDesc(data.description);
  }

  getDescription(name) {
@@ -151,23 +105,32 @@ class EventReplayPane extends Component {
        <div style={styles.block}>
          <Typography use="headline6">Replay Events</Typography>
        </div>
        <ReplayFileSelect
          replayFiles={this.props.replayFiles}
          replayFileSelected={this.props.replayFileSelected}
          onClick={() => this.updateReplayFileList()}
        <Grid style={styles.field}>
          <GridCell span={12}>
            <Select
              style={styles.select}
              label="Replay file"
              fullwidth="true"
              outlined
              options={this.props.replayFiles}
              onChange={event => {
                this.props.changeReplayFileSelected(event.target.value);
                this.getDescription(event.target.value);
              }}
              value={this.props.replayFileSelected}
              data-cy={EXEC_EVT_REPLAY_FILES}
            />
        <div style={styles.block}>
          <Typography use="subtitle2">{this.state.description}</Typography>
        </div>
          </GridCell>
          <GridCell span={12}>
            <Typography use="subtitle2">{this.props.replayFileDesc}</Typography>
          </GridCell>
        </Grid>

        <Grid style={{ marginBottom: 10 }}>
          <GridCell span={2}>
            <Checkbox
              checked={this.props.replayLoop}
              onChange={e => this.changeLoop(e.target.checked)}
              onChange={e => this.props.changeReplayLoop(e.target.checked)}
            >
              Loop
            </Checkbox>
@@ -227,14 +190,19 @@ const styles = {
const mapStateToProps = state => {
  return {
    page: state.ui.page,
    replayStatus: state.ui.replayStatus
    replayStatus: state.exec.state.replayStatus,
    replayFiles: state.ui.replayFiles,
    replayFileSelected: state.ui.replayFileSelected,
    replayFileDesc: state.ui.replayFileDesc,
    replayLoop: state.ui.eventReplayLoop
  };
};

const mapDispatchToProps = dispatch => {
  return {
    changeReplayFileSelected: name => dispatch(uiExecChangeReplayFileSelected(name)),
    changeReplayFilesList: list => dispatch(execChangeReplayFilesList(list))
    changeReplayFileDesc: name => dispatch(uiExecChangeReplayFileDesc(name)),
    changeReplayLoop: val => dispatch(uiExecChangeReplayLoop(val))
  };
};

+46 −32
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ import {
  uiExecChangeEventCfgMode,
  uiExecChangeCurrentEvent,
  uiExecChangeShowApps,
  uiExecChangeReplayLoop
  uiExecChangeReplayFilesList
} from '../../state/ui';

import {
@@ -121,6 +121,36 @@ class ExecPageContainer extends Component {
    this.props.execChangeOkToTerminate(false);
  }

  /**
   * Callback function to receive the result of the createScenario operation.
   * @callback module:api/ScenarioConfigurationApi~createScenarioCallback
   * @param {String} error Error message, if any.
   * @param data This operation does not return a value.
   * @param {String} response The complete HTTP response.
   */
  createScenarioCb(/*error, data, response*/) {
    // if (error == null) {
    //   console.log('Scenario successfully created');
    // } else {
    //   console.log('Failed to create scenario');
    // }
    // TODO: consider showing an alert/toast
  }

  /**
   * 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);
  }

  saveScenario(scenarioName) {
    const scenario = this.props.scenario;

@@ -134,9 +164,14 @@ class ExecPageContainer extends Component {
    );
  }

  updateReplayFileList() {
    this.props.replayApi.getReplayFileList((error, data, response) => {
      this.getReplayFileListCb(error, data, response);
    });
  }
  
  saveReplay(state) {
    const scenarioName = this.props.scenario.name;

    var replayInfo = {
      scenarioName: '',
      description: ''
@@ -151,22 +186,9 @@ class ExecPageContainer extends Component {
        // console.log(error);
      }
    });
  }

  /**
   * Callback function to receive the result of the createScenario operation.
   * @callback module:api/ScenarioConfigurationApi~createScenarioCallback
   * @param {String} error Error message, if any.
   * @param data This operation does not return a value.
   * @param {String} response The complete HTTP response.
   */
  createScenarioCb(/*error, data, response*/) {
    // if (error == null) {
    //   console.log('Scenario successfully created');
    // } else {
    //   console.log('Failed to create scenario');
    // }
    // TODO: consider showing an alert/toast
    // Refresh file list
    this.updateReplayFileList();
  }

  // CLOSE DIALOG
@@ -193,11 +215,15 @@ class ExecPageContainer extends Component {
    this.props.changeCurrentDialog(IDC_DIALOG_TERMINATE_SCENARIO);
  }

  // SAVE SCENARIO
  // SAVE REPLAY FILE
  onSaveReplay() {
    this.props.changeCurrentDialog(IDC_DIALOG_SAVE_REPLAY);
  }

  // SHOW REPLAY PANE
  onShowReplay() {
    this.updateReplayFileList();
  }

  // CLOSE CREATE EVENT PANE
  onQuitEventCreationMode() {
@@ -243,10 +269,6 @@ class ExecPageContainer extends Component {
    });
  }

  changeReplayLoop(val) {
    this.props.changeReplayLoop(val);
  }

  renderDialogs() {
    return (
      <>
@@ -359,11 +381,10 @@ class ExecPageContainer extends Component {
                <div>
                  <EventContainer
                    scenarioName={this.props.execScenarioName}
                    onReplayLoopChanged={val => this.changeReplayLoop(val)}
                    replayLoop={this.props.replayLoop}
                    eventCfgMode={this.props.eventCfgMode}
                    onCloseEventCfg={() => this.onCloseEventCfg()}
                    onSaveReplay={() => this.onSaveReplay()}
                    onShowReplay={() => this.onShowReplay()}
                    api={this.props.replayApi}
                  />

@@ -383,10 +404,6 @@ class ExecPageContainer extends Component {
              >
                <Elevation className="component-style" z={2}>
                  <EventReplayPane
                    replayFiles={this.props.replayFiles}
                    replayFileSelected={this.props.replayFileSelected}
                    onReplayLoopChanged={val => this.changeReplayLoop(val)}
                    replayLoop={this.props.replayLoop}
                    api={this.props.replayApi}
                    hide={!this.props.eventReplayMode}
                    onClose={() => this.onQuitEventReplayMode()}
@@ -430,7 +447,6 @@ const mapStateToProps = state => {
  return {
    exec: state.exec,
    showApps: state.ui.execShowApps,
    replayLoop: state.ui.eventReplayLoop,
    execVis: state.exec.vis,
    configuredElement: state.cfg.elementConfiguration.configuredElement,
    table: state.exec.table,
@@ -439,8 +455,6 @@ const mapStateToProps = state => {
    scenarios: state.exec.apiResults.scenarios,
    eventCreationMode: state.ui.eventCreationMode,
    eventReplayMode: state.ui.eventReplayMode,
    replayFiles: state.exec.apiResults.replayFiles,
    replayFileSelected: state.ui.execReplayFileSelected,
    dashCfgMode: state.ui.dashCfgMode,
    eventCfgMode: state.ui.eventCfgMode,
    page: state.ui.page,
@@ -464,7 +478,7 @@ const mapDispatchToProps = dispatch => {
    changeCurrentEvent: e => dispatch(uiExecChangeCurrentEvent(e)),
    execChangeOkToTerminate: ok => dispatch(execChangeOkToTerminate(ok)),
    changeShowApps: show => dispatch(uiExecChangeShowApps(show)),
    changeReplayLoop: val => dispatch(uiExecChangeReplayLoop(val))
    changeReplayFilesList: list => dispatch(uiExecChangeReplayFilesList(list))
  };
};

+3 −5
Original line number Diff line number Diff line
@@ -55,7 +55,6 @@ import {
  uiChangeCurrentPage,
  uiExecChangeEventCreationMode,
  uiExecChangeEventReplayMode,
  uiExecChangeReplayStatus,
  uiToggleMainDrawer
} from '../state/ui';

@@ -70,7 +69,8 @@ import {
  execChangeOkToTerminate,
  corePodsRunning,
  corePodsErrors,
  execVisFilteredData
  execVisFilteredData,
  execChangeReplayStatus
} from '../state/exec';

import {
@@ -102,8 +102,6 @@ class MeepContainer extends Component {

  componentDidMount() {
    document.title = 'AdvantEDGE';
    this.props.changeEventCreationMode(false);
    this.props.changeEventReplayMode(false);
    this.refreshScenario();
    this.startTimers();
    this.monitorTabFocus();
@@ -536,7 +534,7 @@ const mapDispatchToProps = dispatch => {
    changeCurrentPage: page => dispatch(uiChangeCurrentPage(page)),
    changeEventCreationMode: mode => dispatch(uiExecChangeEventCreationMode(mode)),
    changeEventReplayMode: mode => dispatch(uiExecChangeEventReplayMode(mode)),
    changeReplayStatus: status => dispatch(uiExecChangeReplayStatus(status)),
    changeReplayStatus: status => dispatch(execChangeReplayStatus(status)),
    cfgChangeScenario: scenario => dispatch(cfgChangeScenario(scenario)),
    execChangeScenario: scenario => dispatch(execChangeScenario(scenario)),
    execChangeScenarioState: s => dispatch(execChangeScenarioState(s)),
Loading