Procházet zdrojové kódy

Fixed logs query and implemented incidents tab on expanded chart

jnfrati před 4 roky
rodič
revize
8c760e1e40

+ 4 - 3
dashboard/src/main/home/cluster-dashboard/dashboard/incidents/EventDrawer.tsx

@@ -1,5 +1,5 @@
 import Loading from "components/Loading";
-import { isEmpty, isObjectLike } from "lodash";
+import { isEmpty } from "lodash";
 import React, { useContext, useEffect, useMemo, useState } from "react";
 import api from "shared/api";
 import { Context } from "shared/Context";
@@ -36,13 +36,14 @@ const EventDrawer: React.FC<{ event: IncidentEvent }> = ({ event }) => {
       return api
         .getIncidentLogsByLogId<{ contents: string }>(
           "<token>",
-          {},
+          {
+            log_id: container.log_id,
+          },
           {
             project_id: currentProject.id,
             cluster_id: currentCluster.id,
             namespace: event.namespace,
             release_name: event.release_name,
-            log_id: container.log_id,
           }
         )
         .then((res) => ({

+ 2 - 2
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChart.tsx

@@ -29,7 +29,7 @@ import useAuth from "shared/auth/useAuth";
 import TitleSection from "components/TitleSection";
 import DeploymentType from "./DeploymentType";
 import { onlyInLeft } from "shared/array_utils";
-import IncidentsTable from "./incidents/IncidentsTable";
+import IncidentsTab from "./incidents/IncidentsTab";
 
 type Props = {
   namespace: string;
@@ -427,7 +427,7 @@ const ExpandedChart: React.FC<Props> = (props) => {
         return <MetricsSection currentChart={chart} />;
       case "incidents":
         return (
-          <IncidentsTable
+          <IncidentsTab
             releaseName={chart?.name}
             namespace={chart?.namespace}
           />

+ 194 - 0
dashboard/src/main/home/cluster-dashboard/expanded-chart/incidents/IncidentsTab.tsx

@@ -0,0 +1,194 @@
+import Loading from "components/Loading";
+import React, { useContext, useEffect, useState } from "react";
+import api from "shared/api";
+import { Context } from "shared/Context";
+import styled from "styled-components";
+import IncidentsTable from "./IncidentsTable";
+
+export type DetectAgentResponse = {
+  version: string;
+};
+
+const IncidentsTab = (props: {
+  releaseName: string;
+  namespace: string;
+}): JSX.Element => {
+  const { currentProject, currentCluster } = useContext(Context);
+  const [isAgentInstalled, setIsAgentInstalled] = useState(false);
+  const [isAgentOutdated, setIsAgentOutdated] = useState(false);
+  const [isLoading, setIsLoading] = useState(true);
+
+  useEffect(() => {
+    api
+      .detectPorterAgent<DetectAgentResponse>(
+        "<token>",
+        {},
+        {
+          project_id: currentProject.id,
+          cluster_id: currentCluster.id,
+        }
+      )
+      .then((res) => res.data)
+      .then((data) => {
+        if (data.version === "v1") {
+          setIsAgentInstalled(true);
+          setIsAgentOutdated(true);
+        } else {
+          setIsAgentInstalled(true);
+          setIsAgentOutdated(false);
+        }
+      })
+      .catch(() => {
+        setIsAgentInstalled(false);
+      })
+      .finally(() => {
+        setIsLoading(false);
+      });
+  }, []);
+
+  const upgradeAgent = async () => {
+    const project_id = currentProject?.id;
+    const cluster_id = currentCluster?.id;
+    try {
+      await api.upgradePorterAgent(
+        "<token>",
+        {},
+        {
+          project_id,
+          cluster_id,
+        }
+      );
+      setIsAgentOutdated(false);
+    } catch (err) {
+      setIsAgentOutdated(true);
+    }
+  };
+
+  const installAgent = async () => {
+    const project_id = currentProject?.id;
+    const cluster_id = currentCluster?.id;
+
+    api
+      .installPorterAgent("<token>", {}, { project_id, cluster_id })
+      .then(() => {
+        setIsAgentInstalled(true);
+      })
+      .catch(() => {
+        setIsAgentInstalled(false);
+      });
+  };
+
+  const triggerInstall = () => {
+    if (isAgentOutdated) {
+      upgradeAgent();
+      return;
+    }
+
+    installAgent();
+  };
+
+  if (isLoading) {
+    return (
+      <StyledCard>
+        <Loading height="200px" />
+      </StyledCard>
+    );
+  }
+
+  if (!isAgentInstalled || isAgentOutdated) {
+    return (
+      <StyledCard>
+        <Placeholder>
+          <InstallPorterAgentButton onClick={() => triggerInstall()}>
+            <i className="material-icons">add</i> Enable incidents detection
+          </InstallPorterAgentButton>
+        </Placeholder>
+      </StyledCard>
+    );
+  }
+
+  return (
+    <StyledCard>
+      <IncidentsTable {...props} />
+    </StyledCard>
+  );
+};
+
+export default IncidentsTab;
+
+const StyledCard = styled.div`
+  margin-top: 35px;
+  background: #26282f;
+  padding: 14px;
+  border-radius: 8px;
+  box-shadow: 0 4px 15px 0px #00000055;
+  position: relative;
+  border: 2px solid #9eb4ff00;
+  width: 100%;
+  :not(:last-child) {
+    margin-bottom: 25px;
+  }
+`;
+
+const InstallPorterAgentButton = styled.button`
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 13px;
+  cursor: pointer;
+  font-family: "Work Sans", sans-serif;
+  border: none;
+  border-radius: 5px;
+  color: white;
+  height: 35px;
+  padding: 0px 8px;
+  padding-bottom: 1px;
+  margin-top: 20px;
+  font-weight: 500;
+  padding-right: 15px;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  box-shadow: 0 5px 8px 0px #00000010;
+  cursor: ${(props: { disabled?: boolean }) =>
+    props.disabled ? "not-allowed" : "pointer"};
+  background: ${(props: { disabled?: boolean }) =>
+    props.disabled ? "#aaaabbee" : "#5561C0"};
+  :hover {
+    filter: ${(props) => (!props.disabled ? "brightness(120%)" : "")};
+  }
+  > i {
+    color: white;
+    width: 18px;
+    height: 18px;
+    font-weight: 600;
+    font-size: 12px;
+    border-radius: 20px;
+    display: flex;
+    align-items: center;
+    margin-right: 5px;
+    justify-content: center;
+  }
+`;
+
+const Placeholder = styled.div`
+  padding: 30px;
+  margin-top: 35px;
+  padding-bottom: 40px;
+  font-size: 13px;
+  color: #ffffff44;
+  min-height: 400px;
+  height: 50vh;
+  background: #26282f;
+  border-radius: 8px;
+  width: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+  > i {
+    font-size: 18px;
+    margin-right: 8px;
+  }
+`;

+ 5 - 4
dashboard/src/shared/api.tsx

@@ -1629,18 +1629,19 @@ const getIncidentById = baseApi<
 );
 
 const getIncidentLogsByLogId = baseApi<
-  {},
+  {
+    log_id: string;
+  },
   {
     project_id: number;
     cluster_id: number;
     namespace: string;
     release_name: string;
-    log_id: string;
   }
 >(
   "GET",
-  ({ project_id, cluster_id, namespace, release_name: name, log_id }) =>
-    `/api/projects/${project_id}/clusters/${cluster_id}/namespaces/${namespace}/releases/${name}/incidents/logs/${log_id}`
+  ({ project_id, cluster_id, namespace, release_name: name }) =>
+    `/api/projects/${project_id}/clusters/${cluster_id}/namespaces/${namespace}/releases/${name}/incidents/logs`
 );
 
 const upgradePorterAgent = baseApi<