text: import React, { Component } from "react";
  import {
    Breadcrumb,
    Card,
    CardBody,
    CardHeader,
    Col,
    Row,
    Table,
    Spinner
  } from "reactstrap";
  import _ from "lodash";
  import { connect } from "react-redux";
  import { Pie } from 'react-chartjs-2';
  import ComponentServices from "../../services/ComponentServices";
  import TestRow from "../../components/TestRow/TestRow";
  import { setCurrentComponent } from '../../store/actions/actions';
  import '../../scss/style.scss'
  import history from "../../components/History/History";
  
  const DATE_REGEX = /^\d{4}([./-])\d{2}\1\d{2}$/;
  
  class Execution extends Component {
    constructor(props) {
      super(props);
  
      this.loadingTests = false;
  
      this.state = {
        dropdownOpen: false,
        radioSelected: 2,
        totalTests: [],
        isLoading: false,
        executionsCount: [],
        execDate: null,
        successCount: 0,
        failureCount: 0,
        skippedCount: 0,
        loadingExecutions: false
       };
    }
  
    componentDidMount() {
      if (!this.props.currentComponent) {
        let componentId = this.props.match.params.id;
        ComponentServices.getComponentById(componentId)
        .then(response => {
          this.props.onSetCurrentComponent({id: componentId, name: response.data[0].name, component: response.data[0].component});
        })
        .catch(err => {
          history.push('/dashboard')
        })
      }
  
      this.getExecutionByDate();
      this.setState({loadingExecutions: true});
  
    }
  
    shouldComponentUpdate(nextProps, nextState) {
      return (
        !_.isEqual(nextProps, this.props) || !_.isEqual(nextState, this.state)
      );
    }
  
    getExecutionByDate(shouldLoad = true) {
      let executionDate = this.props.match.params.date;
      let componentId = this.props.match.params.id;
  
      this.setState({ isLoading: shouldLoad, execDate: executionDate }, () => {
        this.loadingTests = true;
        ComponentServices.getTestsByExecutionDate(
          this.props.currentComponent.id || componentId,
          executionDate
        )
          .then(response => {
            this.cancelLoading();
            this.loadingTests = false;
            this.setState({
              loadingExecutions: false
            })
            let executions = [];
            let executionsCountForTest = [];
  
            for (var i = 0; i < Object.keys(response.data.tests).length; i++) {
              let key = Object.keys(response.data.tests)[i];
              let execution = response.data.tests[key];
              execution.id = key;
              executions = [...executions, execution];
  
              for (var j = 0; j < Object.keys(execution.executions).length; j++) {
                let executionKey = Object.keys(execution.executions)[j];
                let execId = execution.executions[executionKey];
                execId.id = executionKey;
                let testId = execution.id;
                execId.testId = testId;
                executionsCountForTest = [...executionsCountForTest, execId];
              }
            }
  
            if (executions && executions.length > 0) {
              this.setState({
                totalTests: executions
              });
            }
  
            if (executionsCountForTest && executionsCountForTest.length > 0) {
              this.setState({
                executionsCount: executionsCountForTest
              });
            }
          })
          .catch(err => {
            this.cancelLoading();
            this.loadingTests = false;
            console.log(err);
  
          });
      });
    }
  
    componentDidUpdate() {
      if (!this.loadingTests) {
        this.getExecutionByDate();
      }
  
      this.getCountPerTypes();
    }
  
    cancelLoading = () => {
      this.setState({ isLoading: false });
    };
  
    getCountPerTypes = () => {
      const { totalTests } = this.state;
      let success = 0;
      let failed = 0;
      let skipped = 0;
      totalTests.forEach((test) => {
        if (!isNaN(test.lastExecution.SUCCESS)) success += test.lastExecution.SUCCESS;
        if (!isNaN(test.lastExecution.FAILURE)) failed += test.lastExecution.FAILURE;
        if (!isNaN(test.lastExecution.SKIP)) skipped += test.lastExecution.SKIP;
      });
  
      this.setState({
        successCount: success,
        failureCount: failed,
        skippedCount: skipped
      });
    };
  
    renderPieChart() {
      const { successCount, failureCount, skippedCount } = this.state;
      const data = {
        labels: ["FAILED", "PASSED", "SKIPPED"],
        datasets: [
          {
            data: [failureCount, successCount, skippedCount],
            backgroundColor: ["#F85151", "#32C463", "#FFCE56"],
            hoverBackgroundColor: ["#FF6384", "#008f39", "#FFCE56"]
          }
        ]
      }
  
      return (
        <Pie
          circleTitle="Total Executions"
          data={data}
        />
      );
    }
  
    renderDate = () => {
      let { execDate } = this.state;
      if (!execDate) return;
  
      execDate = execDate.replaceAll('-', '/');
  
      if (this.isDateValid(execDate)) {
        const date = new Date(execDate);
        return date.toLocaleDateString('en-US', {day: 'numeric', month: 'long', year: 'numeric'});
      }
  
      return 'Invalid Date';
    }
  
    isDateValid(dateStr) {
      let dateReg = new RegExp(DATE_REGEX);
  
      let dateObj = new Date(dateStr);
      return dateReg.exec(dateStr) && !isNaN(dateObj.getTime());
    }
  
    checkExecutionStatus = () => {
      this.getExecutionByDate(false)
    }
  
    render() {
      const componentId = this.props.match.params.id;
      const { successCount, skippedCount, failureCount } = this.state;
      const { loadingExecutions } = this.state;
  
      return (
        <React.Fragment>
        {
          loadingExecutions &&
          <div className="loading-overlay">
            <Spinner color="primary"/>
          </div>
        }
        <div className="animated fadeIn">
          <Row>
            <Col xs="12">
              <Card>
                <CardHeader>
                  <i className="fa fa-align-justify"></i>
                  <strong>{this.props.currentComponent.name}</strong>
  
                  <div className="card-header-actions">
                    <a
                      href="#"
                      rel="noreferrer noopener"
                      target="_blank"
                      className="card-header-action"
                    >
                      <small className="text-muted"> </small>
                    </a>
                  </div>
                </CardHeader>
                <CardBody>
                  <Breadcrumb>
                  <div className="tableContainer">
                    <div className="tableRow">
                      <div className="tableCol">Date</div>
                      <div className="tableCol">{  this.renderDate() }</div>
                    </div>
                    <div className="tableRow">
                    <div className="tableCol">Total Tests</div>
                      <div className="tableCol">{ successCount + failureCount + skippedCount }</div>
                    </div>
                    <div className="tableRow">
                    <div className="tableCol">Total Passed</div>
                      <div className="tableCol">{ successCount }</div>
                    </div>
                    <div className="tableRow">
                    <div className="tableCol">Total Failed</div>
                      <div className="tableCol">{ failureCount }</div>
                    </div>
                    <div className="tableRow">
                    <div className="tableCol">Total Skipped</div>
                      <div className="tableCol">{ skippedCount }</div>
                    </div>
                  </div>
                  <div className="tableContainer">
                    { this.renderPieChart() }
                  </div>
                  </Breadcrumb>
                </CardBody>
              </Card>
            </Col>
          </Row>
  
          <Row>
            <Col xs="12">
              <Card>
                <CardHeader>
                  <i className="fa fa-align-justify"></i>
                  <strong>{`${this.props.currentComponent.name} - Tests`}</strong>
                </CardHeader>
                <CardBody>
                  {this.state.isLoading ? (
                    <div
                      className="flex-xl-row"
                      style={{
                        textAlign: "center",
                        fontWeight: "3" + "px",
                        position: "static",
                        display: "block"
                      }}
                    >
                      <Spinner color="primary" />
                      <span
                        className="flex-xl-row"
                        style={{
                          position: "relative",
                          marginLeft: "10px",
                          display: "block"
                        }}
                      >
                        Loading...
                      </span>
                    </div>
                  ) : (
                    <Table responsive hover>
                      <thead>
                        <tr>
                          <th scope="col">Test Name</th>
                          <th scope="col">Executions</th>
                          <th scope="col">Last Execution Status</th>
                          <th scope="col">Success</th>
                          <th scope="col">Failed</th>
                          <th scope="col">Skipped</th>
                          <th scope="col">In Progress</th>
                          <th scope="col">Execute</th>
                        </tr>
                      </thead>
                      <tbody>
                        {this.state.totalTests &&
                          this.state.totalTests.map(item => {
                            return <TestRow componentId={componentId} date={this.state.execDate} key={item.id} item={item} checkStatus={ this.checkExecutionStatus } />;
                          })}
  
                        {
  
                          <tr>
                            <td style={{textTransform: "uppercase", fontWeight: "bold"}}>Totals</td>
                            <td></td>
                            <td></td>
                            <td className="totalTable">{ successCount }</td>
                            <td className="totalTable">{ failureCount }</td>
                            <td className="totalTable">{ skippedCount }</td>
                            <td></td>
                            <td></td>
                          </tr>
                        }
                      </tbody>
                    </Table>
                  )}
                </CardBody>
              </Card>
            </Col>
          </Row>
        </div>
        </React.Fragment>
      );
    }
  }
  
  const mapStateToProps = state => {
    return {
      componentList: state.reducer.componentList,
      currentComponent: state.reducer.currentComponent
    };
  };
  
  const mapDispatchToProps = dispatch => {
    return {
      onSetCurrentComponent: (data) => dispatch(setCurrentComponent(data))
    }
  }
  
  export default connect(mapStateToProps, mapDispatchToProps)(Execution);
  