Просмотр исходного кода

Added cluster Dashboard and Node list components

jnfrati 5 лет назад
Родитель
Сommit
2834e9a3bc

+ 127 - 0
dashboard/src/main/home/cluster-dashboard/dashboard/Dashboard.tsx

@@ -0,0 +1,127 @@
+import React, { useContext, useState } from "react";
+import styled from "styled-components";
+
+import { Context } from "shared/Context";
+import TabSelector from "components/TabSelector";
+
+import NodeList from "./NodeList";
+
+
+type TabEnum = "nodes";
+
+const tabOptions: {
+  label: string;
+  value: TabEnum
+}[] = [
+  { label: "Nodes", value: "nodes" },
+];
+
+export const Dashboard: React.FC = ({ children }) => {
+  const [currentTab, setCurrentTab] = useState<TabEnum>("nodes");
+  const context = useContext(Context);
+  const renderTab = (cluster: any) => {
+    switch (currentTab) {
+      case "nodes":
+      default:
+        return <NodeList />;
+    }
+  };
+
+  return (
+    
+    <>
+      <TitleSection>
+        <i className="material-icons">device_hub</i>
+        <Title>{context.currentCluster.name}</Title>
+      </TitleSection>
+
+      <InfoSection>
+        <TopRow>
+          <InfoLabel>
+            <i className="material-icons">info</i> Info
+          </InfoLabel>
+        </TopRow>
+        <Description>Some text</Description>
+      </InfoSection>
+
+      <TabSelector
+        options={tabOptions}
+        currentTab={currentTab}
+        setCurrentTab={(value: TabEnum) =>
+          setCurrentTab(value)
+        }
+      />
+
+      {renderTab(context.currentCluster)}
+    </>
+  );
+};
+
+
+const TopRow = styled.div`
+  display: flex;
+  align-items: center;
+`;
+
+const Description = styled.div`
+  color: #aaaabb;
+  margin-top: 13px;
+  margin-left: 2px;
+  font-size: 13px;
+`;
+
+const InfoLabel = styled.div`
+  width: 72px;
+  height: 20px;
+  display: flex;
+  align-items: center;
+  color: #7a838f;
+  font-size: 13px;
+  > i {
+    color: #8b949f;
+    font-size: 18px;
+    margin-right: 5px;
+  }
+`;
+
+const InfoSection = styled.div`
+  margin-top: 20px;
+  font-family: "Work Sans", sans-serif;
+  margin-left: 0px;
+  margin-bottom: 35px;
+`;
+
+const Title = styled.div`
+  font-size: 20px;
+  font-weight: 500;
+  font-family: "Work Sans", sans-serif;
+  margin-left: 18px;
+  color: #ffffff;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  text-transform: capitalize;
+`;
+
+const TitleSection = styled.div`
+  height: 80px;
+  margin-top: 10px;
+  margin-bottom: 10px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding-left: 0px;
+
+  > i {
+    margin-left: 10px;
+    cursor: pointer;
+    font-size 18px;
+    color: #858FAAaa;
+    padding: 5px;
+    border-radius: 100px;
+    :hover {
+      background: #ffffff11;
+    }
+    margin-bottom: -3px;
+  }
+`;

+ 71 - 0
dashboard/src/main/home/cluster-dashboard/dashboard/NodeList.tsx

@@ -0,0 +1,71 @@
+import React, { useContext, useEffect, useMemo, useState } from "react";
+
+import Table from "components/Table";
+import { Column } from "react-table";
+import styled from "styled-components";
+import api from "shared/api";
+import { Context } from "shared/Context";
+
+const NodeList: React.FC = () => {
+  const context = useContext(Context);
+  const [nodeList, setNodeList] = useState([]);
+
+  const columns = useMemo<Column<any>[]>(
+    () => [
+      {
+        Header: "Node name",
+        accessor: "name",
+      },
+      {
+        Header: "CPU Usage",
+        accessor: "cpu_usage",
+      },
+      {
+        Header: "RAM Usage",
+        accessor: "ram_usage",
+      },
+    ],
+    []
+  );
+
+  const data = useMemo(() => {
+    const percentFormatter = (number: number) => `${Number(number).toFixed(2)}%`
+    
+    return nodeList.map( node => {
+      return {
+        name: node.name,
+        cpu_usage: percentFormatter(node.cpu_reqs),
+        ram_usage: percentFormatter(node.memory_reqs)
+      }
+    })
+  }, [nodeList]);
+
+  useEffect(() => {
+    let { currentCluster, currentProject } = context;
+    api
+      .getClusterNodes(
+        "<token>",
+        {},
+        {
+          cluster_id: currentCluster.id,
+          project_id: currentProject.id,
+        }
+      )
+      .then(({ data }) => {
+        if (data) {
+          setNodeList(data);
+        }
+      })
+      .catch(() => {
+        console.log({ error: true });
+      });
+  }, [context, setNodeList]);
+
+  return (
+    <>
+      <Table columns={columns} data={data} />
+    </>
+  );
+};
+
+export default NodeList;

+ 11 - 0
dashboard/src/shared/api.tsx

@@ -399,6 +399,16 @@ const getCluster = baseApi<
   return `/api/projects/${pathParams.project_id}/clusters/${pathParams.cluster_id}`;
 });
 
+const getClusterNodes = baseApi<
+  {},
+  {
+    project_id: number;
+    cluster_id: number;
+  }
+>("GET", (pathParams) => {
+  return `/api/projects/${pathParams.project_id}/clusters/${pathParams.cluster_id}/nodes`
+})
+
 const getGitRepoList = baseApi<
   {},
   {
@@ -880,6 +890,7 @@ export default {
   getClusterIntegrations,
   getClusters,
   getCluster,
+  getClusterNodes,
   getConfigMap,
   getGitRepoList,
   getGitRepos,