crane-cloud/frontend

View on GitHub
src/pages/ProjectCPUPage/index.jsx

Summary

Maintainability
A
1 hr
Test Coverage
F
34%
import React from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import Spinner from "../../components/Spinner";
import "./ProjectCPUPage.css";
import getProjectCPU, { clearProjectCPU } from "../../redux/actions/projectCPU";
import MetricsCard from "../../components/MetricsCard";
import PeriodSelector from "../../components/Period";
import LineChartComponent from "../../components/LineChart";
import {
  formatCPUMetrics,
  getCurrentTimeStamp,
  subtractTime,
} from "../../helpers/formatMetrics";
import { getProjectName } from "../../helpers/projectName";
import DashboardLayout from "../../components/Layouts/DashboardLayout";
class ProjectCPUPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      time: {
        start: 0,
        end: getCurrentTimeStamp(),
        step: "",
      },
      period: "1d",
      showErrorMessage: false,
      dateError: "",
    };
    this.handlePeriodChange = this.handlePeriodChange.bind(this);
    this.fetchCPU = this.fetchCPU.bind(this);
    this.getDateCreated = this.getDateCreated.bind(this);
  }

  /*componentDidMount() {
    const {
      match: { params },
      getProjectCPU,
      clearProjectCPU,
    } = this.props;
    const { projectID } = params;
    clearProjectCPU();
    getProjectCPU(projectID, { step: "2h" });
  }*/
  componentDidMount() {
    const {
      match: { params },
      getProjectCPU,
      clearProjectCPU,
    } = this.props;
    const { projectID } = params;
    clearProjectCPU();
  
    const endTimeStamp = getCurrentTimeStamp(); // Set the end date to the current timestamp
  
    this.setState({
      time: {
        start: 0,
        end: endTimeStamp,
        step: "2h", // You can adjust the default step value here if needed
      },
    });
  
    getProjectCPU(projectID, { step: "2h" });
  }
  

  getDateCreated() {
    const {
      match: { params },
      projects,
    } = this.props;
    const { projectID } = params;
    return projects.find((project) => project.id === projectID).date_created;
  }

  async handlePeriodChange(period, customTime = null) {
    
let days;
    let step;
    let startTimeStamp;
    let endTimeStamp;
  
    if (period === "1d") {
      days = 1;
      step = "2h";
    } else if (period === "7d") {
      days = 7;
      step = "1d";
    } else if (period === "1m") {
      days = 30;
      step = "1d";
    } else if (period === "3m") {
      days = 90;
      step = "7d";
    } else if (period === "1y") {
      days = 365;
      step = "1m";
    } else if (period === "custom") {
      step = "1d";
    }
  
    this.setState({ period });
  
    if (period === "all") {
      startTimeStamp = await Date.parse(this.getDateCreated());
      endTimeStamp = getCurrentTimeStamp();
    } else if (period === "custom" && customTime !== null) {
      startTimeStamp = customTime.start;
      endTimeStamp = customTime.end;
      const { start, end } = customTime;
      if (end <= start) {
        this.setState({
          showErrorMessage: true,
          dateError: "End date must be greater than start date.",
        });
        return; // Exit the function early to prevent further processing
      } else {
        this.setState({
          showErrorMessage: false,
          dateError: "",
        });
      }
    } else {
      startTimeStamp = await subtractTime(getCurrentTimeStamp(), days);
      endTimeStamp = getCurrentTimeStamp();
    }
  
    this.setState((prevState) => ({
      time: {
        ...prevState.time,
        start: startTimeStamp,
        end: endTimeStamp,
        step,
      },
    }));
  
    if (endTimeStamp > startTimeStamp) {
      this.fetchCPU();
    }
  }
  

  fetchCPU() {
    const { time } = this.state;
    const {
      match: { params },
      getProjectCPU,
      clearProjectCPU,
    } = this.props;
    const { projectID } = params;

    clearProjectCPU();
    getProjectCPU(projectID, time);
  }

  render() {
    const {
      match: { params },
      isFetchingCPU,
      cpuMetrics,
      projects,
    } = this.props;
    const { projectID } = params;
    const { period } = this.state;
    const formattedMetrics = formatCPUMetrics(projectID, cpuMetrics, period);

    return (
      <DashboardLayout
        name={getProjectName(projects, projectID)}
        header="Project CPU"
      >
        <MetricsCard
          className="MetricsCardGraph"
          title={
            <div className="PeriodContainer">
               <div className="SelectedContainer"> 
                <PeriodSelector onChange={this.handlePeriodChange} />
                {this.state.period === 'custom' && (
                  <>
                    <div className="SelectedDates">
                      {new Date(this.state.time.start).toLocaleString()} - {new Date(this.state.time.end).toLocaleString()}
                    </div>
                  </>
                )}
               </div> 
              {this.state.showErrorMessage && (
                <div className="ErrorMessage"> {this.state.dateError}</div>
              )}
            </div>
          }
        >
          {isFetchingCPU ? (
            <div className="ContentSectionSpinner">
              <Spinner />
            </div>
          ) : (
            <LineChartComponent
              yLabel="CPU(cores)"
              xLabel="Time"
              xDataKey="time"
              lineDataKey="cpu"
              data={formattedMetrics}
            />
          )}
        </MetricsCard>
      </DashboardLayout>
    );
  }
}
ProjectCPUPage.propTypes = {
  match: PropTypes.shape({
    params: PropTypes.shape({
      projectID: PropTypes.string.isRequired,
    }).isRequired,
  }).isRequired,
  isFetchingCPU: PropTypes.bool.isRequired,
  cpuMetrics: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
  getProjectCPU: PropTypes.func.isRequired,
  clearProjectCPU: PropTypes.func.isRequired,
  projects: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
};
export const mapStateToProps = (state) => {
  const { isFetchingCPU, cpuMetrics, cpuMessage } = state.projectCPUReducer;
  const { projects } = state.userProjectsReducer;
  return {
    projects,
    isFetchingCPU,
    cpuMetrics,
    cpuMessage,
  };
};

const mapDispatchToProps = {
  getProjectCPU,
  clearProjectCPU,
};
export default connect(mapStateToProps, mapDispatchToProps)(ProjectCPUPage);