Преглед изворни кода

lots of cleanup, fixes drilldown table issue

Signed-off-by: Thomas Evans <tevans3@icloud.com>
jjarrett21 пре 2 година
родитељ
комит
13197ed21c

+ 62 - 70
ui/src/CloudCost/CloudCost.js

@@ -1,5 +1,5 @@
 import React from "react";
-import { get, round } from "lodash";
+import { get } from "lodash";
 import { makeStyles } from "@material-ui/styles";
 import {
   Typography,
@@ -15,11 +15,11 @@ import {
 
 import { toCurrency } from "../util";
 import CloudCostChart from "./CloudCostChart";
-import { primary } from "../constants/colors";
+import { CloudCostRow } from "./CloudCostRow";
 
 const CloudCost = ({
   cumulativeData = [],
-  totalData = {},
+  totalData: totalsRow = {},
   graphData = [],
   currency = "USD",
   drilldown,
@@ -60,19 +60,31 @@ const CloudCost = ({
   }
 
   const headCells = [
-    { id: "name", numeric: false, label: "Name", width: "auto" },
     {
-      id: "kubernetesPercent",
-      numeric: true,
-      label: "K8's Utilization",
-      width: 200,
+      id: "name",
+      numeric: false,
+      label: "Name",
+      width: "auto",
     },
     {
-      id: "cost",
+      id: "kubernetesPercent",
       numeric: true,
-      label: "Sum of Sample Data",
-      width: 200,
+      label: "K8s Utilization",
+      width: 160,
     },
+    sampleData
+      ? {
+          id: "cost",
+          numeric: true,
+          label: "Sum of Sample Data",
+          width: 200,
+        }
+      : {
+          id: "cost",
+          numeric: true,
+          label: "Total cost",
+          width: 155,
+        },
   ];
 
   const [order, setOrder] = React.useState("desc");
@@ -117,6 +129,25 @@ const CloudCost = ({
     );
   }
 
+  function dataToCloudCostRow(row) {
+    const suffix =
+      { hourly: "/hr", monthly: "/mo", daily: "/day" }["cumulative"] || "";
+    return (
+      <CloudCostRow
+        costSuffix={suffix}
+        cost={row.cost}
+        drilldown={drilldown}
+        key={row.name}
+        kubernetesPercent={row.kubernetesPercent}
+        name={
+          sampleData && row.labelName ? row.labelName ?? "" : row.name ?? ""
+        }
+        row={row}
+        sampleData={sampleData}
+      />
+    );
+  }
+
   return (
     <div id="cloud-cost">
       <div id="cloud-graph-">
@@ -143,7 +174,11 @@ const CloudCost = ({
                     <TableSortLabel
                       active={orderBy === cell.id}
                       direction={orderBy === cell.id ? order : "asc"}
-                      onClick={createSortHandler(cell.id)}
+                      onClick={() => {
+                        const isDesc = orderBy === cell.id && order === "desc";
+                        setOrder(isDesc ? "asc" : "desc");
+                        setOrderBy(cell.id);
+                      }}
                     >
                       {cell.label}
                     </TableSortLabel>
@@ -153,65 +188,22 @@ const CloudCost = ({
             </TableHead>
             <TableBody>
               <TableRow>
-                {headCells.map((cell) => {
-                  let tableCell = (
-                    <TableCell
-                      key={cell.id}
-                      colSpan={cell.colspan}
-                      align={cell.numeric ? "right" : "left"}
-                      style={{ fontWeight: 500 }}
-                    >
-                      {cell.id === "kubernetesPercent"
-                        ? round(totalData[cell.id] * 100, 2) + "%"
-                        : isNaN(totalData[cell.id])
-                        ? "Totals"
-                        : toCurrency(round(totalData[cell.id]), currency)}
-                    </TableCell>
-                  );
-                  if (sampleData && cell.label === "Sum of Sample Data") {
-                    tableCell = (
-                      <TableCell
-                        align={cell.numeric ? "right" : "left"}
-                        key={cell.id}
-                        style={{
-                          width: cell.width,
-                          paddingRight: cell.id === "totalCost" ? "2em" : "",
-                        }}
-                      >
-                        <TableSortLabel
-                          active={orderBy === cell.id}
-                          direction={orderBy === cell.id ? order : "asc"}
-                          onClick={createSortHandler(cell.id)}
-                        >
-                          {cell.label}
-                        </TableSortLabel>
-                      </TableCell>
-                    );
-
-                    return tableCell;
-                  }
-                  return <>{tableCell}</>;
-                })}
+                <TableCell align={"left"} style={{ fontWeight: 500 }}>
+                  {totalsRow?.name || "Totals"}
+                </TableCell>
+
+                <TableCell align={"right"} style={{ fontWeight: 500 }}>
+                  {Math.round(totalsRow?.kubernetesPercent * 100)}%
+                </TableCell>
+
+                <TableCell
+                  align={"right"}
+                  style={{ fontWeight: 500, paddingRight: "2em" }}
+                >
+                  {toCurrency(totalsRow?.cost || 0, currency)}
+                </TableCell>
               </TableRow>
-              {pageRows.map((row, key) => {
-                return (
-                  <TableRow
-                    key={key}
-                    onClick={() => drilldown(row)}
-                    style={{ cursor: "pointer" }}
-                  >
-                    <TableCell align="left" style={{ color: "#346ef2" }}>
-                      {row.name}
-                    </TableCell>
-                    <TableCell align="right">
-                      {round(row.kubernetesPercent * 100) + "%"}
-                    </TableCell>
-                    <TableCell align="right">
-                      {toCurrency(row.cost, currency)}
-                    </TableCell>
-                  </TableRow>
-                );
-              })}
+              {pageRows.map(dataToCloudCostRow)}
             </TableBody>
           </Table>
         </TableContainer>

+ 54 - 0
ui/src/CloudCost/CloudCostRow.js

@@ -0,0 +1,54 @@
+import React from "react";
+
+import { TableCell, TableRow } from "@material-ui/core";
+
+import { toCurrency } from "../util";
+import { primary } from "../constants/colors";
+
+const displayCurrencyAsLessThanPenny = (amount, currency) =>
+  amount > 0 && amount < 0.01
+    ? `<${toCurrency(0.01, currency)}`
+    : toCurrency(amount, currency);
+
+const CloudCostRow = ({
+  cost,
+  costSuffix,
+  currency,
+  drilldown,
+  kubernetesPercent,
+  name,
+  row,
+  sampleData,
+}) => {
+  function calculatePercent() {
+    const totalPercent = (kubernetesPercent * 100).toFixed();
+    return `${totalPercent}%`;
+  }
+
+  // const canShowMore = sampleData && !!row.providerID;
+  const whichPercent = sampleData
+    ? `${(kubernetesPercent * 100).toFixed(1)}%`
+    : calculatePercent();
+  return (
+    <TableRow onClick={() => drilldown(row)}>
+      <TableCell
+        align={"left"}
+        // style={
+        //   canShowMore
+        //     ? { cursor: "pointer", color: "#346ef2", padding: "1rem" }
+        //     : { pointerEvents: "none", padding: "1rem" }
+        // }
+        style={{ cursor: "pointer", color: "#346ef2", padding: "1rem" }}
+      >
+        {name}
+      </TableCell>
+      <TableCell align={"right"}>{whichPercent}</TableCell>
+      {/* total cost */}
+      <TableCell align={"right"} style={{ paddingRight: "2em" }}>
+        {`${displayCurrencyAsLessThanPenny(cost, currency)}${costSuffix}`}
+      </TableCell>
+    </TableRow>
+  );
+};
+
+export { CloudCostRow };

+ 2 - 1
ui/src/components/Subtitle.js

@@ -17,7 +17,7 @@ const useStyles = makeStyles({
   },
 });
 
-const Subtitle = ({ report }) => {
+const Subtitle = ({ report, onClick }) => {
   const classes = useStyles();
 
   const { aggregateBy, window } = report;
@@ -27,6 +27,7 @@ const Subtitle = ({ report }) => {
       <Breadcrumbs
         separator={<NavigateNextIcon fontSize="small" />}
         aria-label="breadcrumb"
+        onClick={onClick}
       >
         {aggregateBy && aggregateBy.length > 0 ? (
           <Typography>

+ 0 - 25
ui/src/services/cloudCost.js

@@ -1,25 +0,0 @@
-import axios from "axios";
-
-class CloudCostService {
-  BASE_URL = process.env.BASE_URL || "{PLACEHOLDER_BASE_URL}";
-
-  async fetchCloudCostData(window, aggregate, costMetric) {
-    if (this.BASE_URL.includes("PLACEHOLDER_BASE_URL")) {
-      this.BASE_URL = `http://localhost:9090/model`;
-    }
-
-    const params = {
-      window,
-      aggregate,
-      costMetric,
-      accumulate: false,
-    };
-
-    const result = await axios.get(`${this.BASE_URL}/model/cloudCost/view`, {
-      params,
-    });
-    return result.data;
-  }
-}
-
-export default new CloudCostService();

+ 1 - 1
ui/src/services/cloudCostDayTotals.js

@@ -26,7 +26,7 @@ class CloudCostDayTotalsService {
       const resp = await axios.get(
         `${
           this.BASE_URL
-        }/model/cloudCost/top?window=${window}&costMetric=${costMetric}${getCloudFilters(
+        }/cloudCost/top?window=${window}&costMetric=${costMetric}${getCloudFilters(
           filters
         )}`
       );

+ 2 - 2
ui/src/services/cloudCostTop.js

@@ -20,7 +20,7 @@ class CloudCostTopService {
       const resp = await axios.get(
         `${
           this.BASE_URL
-        }/model/cloudCost/top?window=${window}&costMetric=${costMetric}${getCloudFilters(
+        }/cloudCost/top?window=${window}&costMetric=${costMetric}${getCloudFilters(
           filters
         )}`
       );
@@ -29,7 +29,7 @@ class CloudCostTopService {
       return { data: formatSampleItemsForGraph(result_2, costMetric) };
     }
 
-    const result = await axios.get(`${this.BASE_URL}/model/cloudCost/view`, {
+    const result = await axios.get(`${this.BASE_URL}/cloudCost/view`, {
       params,
     });
     return result.data;