Răsfoiți Sursa

Implemented conditions table and basic node usage information

jnfrati 5 ani în urmă
părinte
comite
91796a4a44

+ 1 - 1
dashboard/src/main/home/cluster-dashboard/dashboard/Routes.tsx

@@ -1,7 +1,7 @@
 import React from "react";
 import { Route, Switch, useRouteMatch } from "react-router";
 import { Dashboard } from "./Dashboard";
-import ExpandedNodeView from "./ExpandedNodeView";
+import ExpandedNodeView from "./node-view/ExpandedNodeView";
 
 export const Routes = () => {
   const { url } = useRouteMatch();

+ 71 - 0
dashboard/src/main/home/cluster-dashboard/dashboard/node-view/ConditionsTable.tsx

@@ -0,0 +1,71 @@
+import React, { useMemo } from "react";
+import Table from "components/Table";
+import { Column } from "react-table";
+import styled from "styled-components";
+
+type NodeStatusModalProps = {
+  node: any;
+};
+
+export const ConditionsTable: React.FunctionComponent<NodeStatusModalProps> = ({
+  node,
+}) => {
+  const columns = useMemo<Column<any>[]>(
+    () => [
+      {
+        Header: "Type",
+        accessor: "type",
+      },
+      {
+        Header: "Status",
+        accessor: "status",
+      },
+      {
+        Header: "Reason",
+        accessor: "reason",
+      },
+      {
+        Header: "Message",
+        accessor: "message",
+      },
+      {
+        Header: "Last Heartbeat",
+        accessor: "lastHeartbeatTime",
+        Cell: ({ row }) => {
+          const date = new Date(row.values.lastHeartbeatTime);
+          return <>{date.toLocaleDateString("en-EU")}</>;
+        },
+      },
+      {
+        Header: "Last Transition",
+        accessor: "lastTransitionTime",
+        Cell: ({ row }) => {
+          const date = new Date(row.values.lastHeartbeatTime);
+          return <>{date.toLocaleString("en-EU")}</>;
+        },
+      },
+    ],
+    []
+  );
+
+  const data = useMemo<Array<any>>(() => {
+    return node?.node_conditions || [];
+  }, [node]);
+
+  return (
+    <div>
+      <TableWrapper>
+        <Table
+          columns={columns}
+          data={data}
+          isLoading={!data.length}
+          disableGlobalFilter={true}
+        />
+      </TableWrapper>
+    </div>
+  );
+};
+
+const TableWrapper = styled.div`
+  margin-top: 14px;
+`;

+ 57 - 6
dashboard/src/main/home/cluster-dashboard/dashboard/ExpandedNodeView.tsx → dashboard/src/main/home/cluster-dashboard/dashboard/node-view/ExpandedNodeView.tsx

@@ -1,21 +1,37 @@
-import React, { useContext, useEffect } from "react";
-import { useParams } from "react-router";
+import React, { useContext, useEffect, useState } from "react";
+import { useHistory, useLocation, useParams } from "react-router";
 import styled from "styled-components";
 import closeImg from "assets/close.png";
 import api from "shared/api";
 import { Context } from "shared/Context";
 
 import nodePng from "assets/node.png";
+import TabSelector from "components/TabSelector";
+import { pushFiltered } from "shared/routing";
+import NodeUsage from "./NodeUsage";
+import { ConditionsTable } from "./ConditionsTable";
 
 type ExpandedNodeViewParams = {
   nodeId: string;
 };
 
+type TabEnum = "conditions";
+
+const tabOptions: {
+  label: string;
+  value: TabEnum;
+}[] = [{ label: "Conditions", value: "conditions" }];
+
 export const ExpandedNodeView = () => {
   const { nodeId } = useParams<ExpandedNodeViewParams>();
+  const history = useHistory();
+  const location = useLocation();
   const { currentCluster, currentProject } = useContext(Context);
+  const [node, setNode] = useState(undefined);
+  const [currentTab, setCurrentTab] = useState("conditions");
 
   useEffect(() => {
+    let isSubscribed = true;
     api
       .getClusterNode(
         "<token>",
@@ -27,14 +43,21 @@ export const ExpandedNodeView = () => {
         }
       )
       .then((res) => {
-        console.log(res);
+        if (isSubscribed) {
+          setNode(res.data);
+        }
       });
-  }, []);
 
-  const closeNodeView = () => {};
+    return () => (isSubscribed = false);
+  }, [nodeId, currentCluster.id, currentProject.id]);
+
+  const closeNodeView = () => {
+    pushFiltered({ history, location }, "/cluster-dashboard", []);
+  };
 
   return (
     <>
+      <CloseOverlay onClick={closeNodeView} />
       <StyledExpandedChart>
         <HeaderWrapper>
           <TitleSection>
@@ -50,7 +73,15 @@ export const ExpandedNodeView = () => {
             <CloseButtonImg src={closeImg} />
           </CloseButton>
         </HeaderWrapper>
-        <BodyWrapper>{nodeId}</BodyWrapper>
+        <BodyWrapper>
+          <NodeUsage node={node} />
+          <TabSelector
+            options={tabOptions}
+            currentTab={currentTab}
+            setCurrentTab={(value: TabEnum) => setCurrentTab(value)}
+          />
+          <ConditionsTable node={node} />
+        </BodyWrapper>
       </StyledExpandedChart>
     </>
   );
@@ -66,6 +97,26 @@ const BodyWrapper = styled.div`
 
 const HeaderWrapper = styled.div``;
 
+const CloseOverlay = styled.div`
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: #202227;
+  animation: fadeIn 0.2s 0s;
+  opacity: 0;
+  animation-fill-mode: forwards;
+  @keyframes fadeIn {
+    from {
+      opacity: 0;
+    }
+    to {
+      opacity: 1;
+    }
+  }
+`;
+
 const IconWrapper = styled.div`
   color: #efefef;
   font-size: 16px;

+ 35 - 0
dashboard/src/main/home/cluster-dashboard/dashboard/node-view/NodeUsage.tsx

@@ -0,0 +1,35 @@
+import React from "react";
+import styled from "styled-components";
+
+type NodeUsageProps = {
+  node: any;
+};
+
+const NodeUsage: React.FunctionComponent<NodeUsageProps> = ({ node }) => {
+  return (
+    <Wrapper>
+      <span>
+        <Bolded>Cpu Usage:</Bolded> {node?.cpu_reqs || "Loading..."}
+      </span>
+      <span>
+        <Bolded>Memory Usage:</Bolded> {node?.memory_reqs || "Loading..."}
+      </span>
+    </Wrapper>
+  );
+};
+
+const Wrapper = styled.div`
+  display: flex;
+  margin: 16px 0px;
+  font-size: 14px;
+  flex-direction: column;
+  line-height: 24px;
+`;
+
+const Bolded = styled.span`
+  font-weight: 500;
+  color: #ffffff44;
+  margin-right: 6px;
+`;
+
+export default NodeUsage;