igor-starostenko/report_factory-web

View on GitHub
src/containers/project_rspec_reports.jsx

Summary

Maintainability
C
1 day
Test Coverage
import React, { Fragment, useEffect } from 'react';
import { PropTypes } from 'prop-types';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import SearchReports from './search_reports';
import {
  Loading,
  RspecReportsBar,
  RspecReportsList,
  ReportsSuccessChart,
  PaginationConnection,
  PerPageFilter,
} from '../components';
import {
  queryProjectRspecReports,
  setProjectRspecReportsQuery,
  resetProjectRspecReports,
} from '../actions/project_reports_actions';
import { prepareVariables } from '../helpers/search_helpers';
import styles from './styles/ProjectRspecReports.css';

function ProjectRspecReports(props) {
  const { edges, pageInfo, projectName, query, totalCount, xApiKey } = props;

  function fetchProjectRspecReports(options) {
    if (query.page !== options.page) {
      const opts = { query, pageInfo, totalCount, ...options };
      const variables = prepareVariables(opts);
      props.setProjectRspecReportsQuery(variables);
      props.queryProjectRspecReports(xApiKey, { ...variables, projectName });
    }
  }

  function resetSearchTags(tags) {
    props.setProjectRspecReportsQuery({ page: 1, perPage: 10, tags });
  }

  useEffect(() => {
    if (!edges) {
      fetchProjectRspecReports({ perPage: query.perPage, tags: query.tags });
    }
    return () => props.resetProjectRspecReports();
  }, []);

  if (!edges) {
    return <Loading page />;
  }

  const projectUrl = `/projects/${projectName}`;

  return (
    <Fragment>
      <Link to={projectUrl}>Back to project</Link>
      <div className={styles.projectReportsContainer}>
        <div className={styles.projectReportsHeader}>
          <h1 className={styles.projectReportsName}>{projectName}</h1>
        </div>
        <div className={styles.projectReportsSearch}>
          <SearchReports
            action={fetchProjectRspecReports}
            setSearch={resetSearchTags}
            initialValues={{ tags: query.tags }}
            {...props}
          />
        </div>
        <div className={styles.projectReportsTotal}>
          Reports submitted: {totalCount}
        </div>
        <div className={styles.projectReportsChart}>
          <RspecReportsBar edges={edges} displayCount={query.perPage} />
        </div>
        <div className={styles.projectReportsSuccessChart}>
          <ReportsSuccessChart edges={edges} />
        </div>
        <div className={styles.projectReportsList}>
          <RspecReportsList edges={edges} />
        </div>
        <div className={styles.projectReportsListButtons}>
          <PaginationConnection
            className={styles.projectReportsPagination}
            page={query.page}
            perPage={query.perPage}
            totalCount={totalCount}
            setPage={fetchProjectRspecReports}
          />
          <PerPageFilter
            totalCount={totalCount}
            buttons={[30, 10]}
            perPage={query.perPage}
            setPerPage={fetchProjectRspecReports}
          />
        </div>
      </div>
    </Fragment>
  );
}

ProjectRspecReports.propTypes = {
  edges: PropTypes.arrayOf(
    PropTypes.shape({
      node: PropTypes.object,
    }),
  ),
  pageInfo: PropTypes.shape({
    startCursor: PropTypes.string,
    endCursor: PropTypes.string,
    hasNextPage: PropTypes.bool.isRequired,
    hasPreviousPage: PropTypes.bool.isRequired,
  }),
  projectName: PropTypes.string.isRequired,
  query: PropTypes.shape({
    page: PropTypes.number.isRequired,
    perPage: PropTypes.number.isRequired,
    query: PropTypes.arrayOf(PropTypes.string),
  }).isRequired,
  totalCount: PropTypes.number,
  xApiKey: PropTypes.string.isRequired,
  queryProjectRspecReports: PropTypes.func.isRequired,
  setProjectRspecReportsQuery: PropTypes.func.isRequired,
  resetProjectRspecReports: PropTypes.func.isRequired,
};

ProjectRspecReports.defaultProps = {
  edges: null,
  totalCount: 0,
  pageInfo: {
    startCursor: null,
    endCursor: null,
    hasNextPage: false,
    hasPreviousPage: false,
  },
};

const mapDispatchToProps = {
  queryProjectRspecReports,
  resetProjectRspecReports,
  setProjectRspecReportsQuery,
};

const mapStateToProps = (state, ownProps) => ({
  projectName: ownProps.match.params.name,
  edges: state.projectReports.rspecReportsConnection.edges,
  pageInfo: state.projectReports.rspecReportsConnection.pageInfo,
  totalCount: state.projectReports.rspecReportsConnection.totalCount,
  query: state.projectReports.rspecReportsConnection.query,
  xApiKey: state.users.currentUser.xApiKey,
});

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(ProjectRspecReports);