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

Implemented own component for environment card and fixed reactivity issue when changing clusters

jnfrati 4 лет назад
Родитель
Сommit
922c1b062d

+ 6 - 235
dashboard/src/main/home/cluster-dashboard/dashboard/preview-environments/EnvironmentList.tsx

@@ -5,12 +5,13 @@ import api from "shared/api";
 import { useHistory, useLocation, useRouteMatch } from "react-router";
 import { getQueryParam } from "shared/routing";
 import styled from "styled-components";
-import { integrationList } from "shared/common";
+
 import ButtonEnablePREnvironments from "./components/ButtonEnablePREnvironments";
 import ConnectNewRepo from "./components/ConnectNewRepo";
 import Loading from "components/Loading";
-import pr_icon from "assets/pull_request_icon.svg";
+
 import _ from "lodash";
+import EnvironmentCard from "./components/EnvironmentCard";
 
 export type PRDeployment = {
   id: number;
@@ -35,16 +36,12 @@ export type Environment = {
   git_repo_name: string;
 };
 
-export const capitalize = (s: string) => {
-  return s.charAt(0).toUpperCase() + s.substring(1).toLowerCase();
-};
-
 const EnvironmentList = () => {
   const [isLoading, setIsLoading] = useState(true);
   const [hasError, setHasError] = useState(false);
   const [environmentList, setEnvironmentList] = useState<Environment[]>([]);
   const [deploymentList, setDeploymentList] = useState<PRDeployment[]>([]);
-  const [showRepoTooltip, setShowRepoTooltip] = useState(false);
+
   const [showConnectRepoFlow, setShowConnectRepoFlow] = useState(false);
   const { currentProject, currentCluster, setCurrentModal } = useContext(
     Context
@@ -121,7 +118,7 @@ const EnvironmentList = () => {
     return () => {
       isSubscribed = false;
     };
-  }, []);
+  }, [currentCluster, currentProject]);
 
   useEffect(() => {
     const action = getQueryParam({ location }, "action");
@@ -171,53 +168,7 @@ const EnvironmentList = () => {
     }
 
     return deploymentList.map((d) => {
-      let repository = `${d.gh_repo_owner}/${d.gh_repo_name}`;
-      return (
-        <EnvironmentCard key={d.id}>
-          <DataContainer>
-            <PRName>
-              <PRIcon src={pr_icon} alt="pull request icon" />
-              {d.gh_pr_name}
-            </PRName>
-
-            <Flex>
-              <StatusContainer>
-                <Status>
-                  <StatusDot status={d.status} />
-                  {capitalize(d.status)}
-                </Status>
-              </StatusContainer>
-              <DeploymentImageContainer>
-                <DeploymentTypeIcon src={integrationList.repo.icon} />
-                <RepositoryName
-                  onMouseOver={() => {
-                    setShowRepoTooltip(true);
-                  }}
-                  onMouseOut={() => {
-                    setShowRepoTooltip(false);
-                  }}
-                >
-                  {repository}
-                </RepositoryName>
-                {showRepoTooltip && <Tooltip>{repository}</Tooltip>}
-              </DeploymentImageContainer>
-            </Flex>
-          </DataContainer>
-          <Flex>
-            <RowButton
-              to={`${currentUrl}/pr-env-detail/${d.namespace}?environment_id=${d.environment_id}`}
-              key={d.id}
-            >
-              <i className="material-icons-outlined">info</i>
-              Details
-            </RowButton>
-            <RowButton to={d.subdomain} key={d.subdomain} target="_blank">
-              <i className="material-icons">open_in_new</i>
-              View Live
-            </RowButton>
-          </Flex>
-        </EnvironmentCard>
-      );
+      return <EnvironmentCard deployment={d} />;
     });
   };
 
@@ -294,26 +245,6 @@ const Placeholder = styled.div`
   }
 `;
 
-const Flex = styled.div`
-  display: flex;
-  align-items: center;
-`;
-
-const Helper = styled.span`
-  text-transform: capitalize;
-  color: #ffffff44;
-  margin-right: 5px;
-`;
-
-const PRName = styled.div`
-  font-family: "Work Sans", sans-serif;
-  font-weight: 500;
-  color: #ffffff;
-  display: flex;
-  align-items: center;
-  margin-bottom: 10px;
-`;
-
 const Container = styled.div`
   margin-top: 33px;
   padding-bottom: 120px;
@@ -372,168 +303,8 @@ const Button = styled(DynamicLink)`
   }
 `;
 
-const SortFilterWrapper = styled.div`
-  display: flex;
-  justify-content: space-between;
-  > div:not(:first-child) {
-    margin-left: 30px;
-  }
-`;
-
-const EnvironmentCard = styled.div`
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  border: 1px solid #ffffff44;
-  background: #ffffff08;
-  margin-bottom: 5px;
-  border-radius: 10px;
-  padding: 14px;
-  overflow: hidden;
-  height: 80px;
-  font-size: 13px;
-  animation: fadeIn 0.5s;
-  @keyframes fadeIn {
-    from {
-      opacity: 0;
-    }
-    to {
-      opacity: 1;
-    }
-  }
-`;
-
 const EventsGrid = styled.div`
   display: grid;
   grid-row-gap: 20px;
   grid-template-columns: 1;
 `;
-
-const DataContainer = styled.div`
-  display: flex;
-  flex-direction: column;
-  justify-content: space-between;
-`;
-
-const StatusContainer = styled.div`
-  display: flex;
-  flex-direction: column;
-  justify-content: flex-start;
-  height: 100%;
-`;
-
-const DataPRUrl = styled.span`
-  font-size: 16px;
-  display: flex;
-  align-items: center;
-`;
-
-const PRIcon = styled.img`
-  font-size: 20px;
-  height: 17px;
-  margin-right: 10px;
-  color: #aaaabb;
-  opacity: 50%;
-`;
-
-const RowButton = styled(DynamicLink)`
-  font-size: 12px;
-  padding: 8px 10px;
-  margin-left: 10px;
-  border-radius: 5px;
-  color: #ffffff;
-  border: 1px solid #aaaabb;
-  display: flex;
-  align-items: center;
-  background: #ffffff08;
-  cursor: pointer;
-  :hover {
-    background: #ffffff22;
-  }
-
-  > i {
-    font-size: 14px;
-    margin-right: 8px;
-  }
-`;
-
-const Status = styled.span`
-  font-size: 13px;
-  display: flex;
-  align-items: center;
-  min-height: 17px;
-  color: #a7a6bb;
-`;
-
-const StatusDot = styled.div`
-  width: 8px;
-  height: 8px;
-  margin-right: 15px;
-  background: ${(props: { status: string }) =>
-    props.status === "created"
-      ? "#4797ff"
-      : props.status === "failed"
-      ? "#ed5f85"
-      : props.status === "completed"
-      ? "#00d12a"
-      : "#f5cb42"};
-  border-radius: 20px;
-  margin-left: 3px;
-`;
-
-const DeploymentImageContainer = styled.div`
-  height: 20px;
-  font-size: 13px;
-  position: relative;
-  display: flex;
-  margin-left: 15px;
-  align-items: center;
-  font-weight: 400;
-  justify-content: center;
-  color: #ffffff66;
-  padding-left: 5px;
-`;
-
-const Icon = styled.img`
-  width: 100%;
-`;
-
-const DeploymentTypeIcon = styled(Icon)`
-  width: 20px;
-  margin-right: 10px;
-`;
-
-const RepositoryName = styled.div`
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  max-width: 390px;
-  position: relative;
-  margin-right: 3px;
-`;
-
-const Tooltip = styled.div`
-  position: absolute;
-  left: -20px;
-  top: 10px;
-  min-height: 18px;
-  max-width: calc(700px);
-  padding: 5px 7px;
-  background: #272731;
-  z-index: 999;
-  color: white;
-  font-size: 12px;
-  font-family: "Work Sans", sans-serif;
-  outline: 1px solid #ffffff55;
-  opacity: 0;
-  animation: faded-in 0.2s 0.15s;
-  animation-fill-mode: forwards;
-  @keyframes faded-in {
-    from {
-      opacity: 0;
-    }
-    to {
-      opacity: 1;
-    }
-  }
-`;

+ 232 - 0
dashboard/src/main/home/cluster-dashboard/dashboard/preview-environments/components/EnvironmentCard.tsx

@@ -0,0 +1,232 @@
+import React, { useState } from "react";
+import styled from "styled-components";
+import { PRDeployment } from "../EnvironmentList";
+import pr_icon from "assets/pull_request_icon.svg";
+import { integrationList } from "shared/common";
+import { useRouteMatch } from "react-router";
+import DynamicLink from "components/DynamicLink";
+
+export const capitalize = (s: string) => {
+  return s.charAt(0).toUpperCase() + s.substring(1).toLowerCase();
+};
+
+const EnvironmentCard: React.FC<{ deployment: PRDeployment }> = ({
+  deployment,
+}) => {
+  const [showRepoTooltip, setShowRepoTooltip] = useState(false);
+  const { url: currentUrl } = useRouteMatch();
+
+  let repository = `${deployment.gh_repo_owner}/${deployment.gh_repo_name}`;
+
+  return (
+    <EnvironmentCardWrapper key={deployment.id}>
+      <DataContainer>
+        <PRName>
+          <PRIcon src={pr_icon} alt="pull request icon" />
+          {deployment.gh_pr_name}
+        </PRName>
+
+        <Flex>
+          <StatusContainer>
+            <Status>
+              <StatusDot status={deployment.status} />
+              {capitalize(deployment.status)}
+            </Status>
+          </StatusContainer>
+          <DeploymentImageContainer>
+            <DeploymentTypeIcon src={integrationList.repo.icon} />
+            <RepositoryName
+              onMouseOver={() => {
+                setShowRepoTooltip(true);
+              }}
+              onMouseOut={() => {
+                setShowRepoTooltip(false);
+              }}
+            >
+              {repository}
+            </RepositoryName>
+            {showRepoTooltip && <Tooltip>{repository}</Tooltip>}
+          </DeploymentImageContainer>
+        </Flex>
+      </DataContainer>
+      <Flex>
+        <RowButton
+          to={`${currentUrl}/pr-env-detail/${deployment.namespace}?environment_id=${deployment.environment_id}`}
+          key={deployment.id}
+        >
+          <i className="material-icons-outlined">info</i>
+          Details
+        </RowButton>
+        <RowButton
+          to={deployment.subdomain}
+          key={deployment.subdomain}
+          target="_blank"
+        >
+          <i className="material-icons">open_in_new</i>
+          View Live
+        </RowButton>
+      </Flex>
+    </EnvironmentCardWrapper>
+  );
+};
+
+export default EnvironmentCard;
+const Flex = styled.div`
+  display: flex;
+  align-items: center;
+`;
+
+const PRName = styled.div`
+  font-family: "Work Sans", sans-serif;
+  font-weight: 500;
+  color: #ffffff;
+  display: flex;
+  align-items: center;
+  margin-bottom: 10px;
+`;
+
+const EnvironmentCardWrapper = styled.div`
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  border: 1px solid #ffffff44;
+  background: #ffffff08;
+  margin-bottom: 5px;
+  border-radius: 10px;
+  padding: 14px;
+  overflow: hidden;
+  height: 80px;
+  font-size: 13px;
+  animation: fadeIn 0.5s;
+  @keyframes fadeIn {
+    from {
+      opacity: 0;
+    }
+    to {
+      opacity: 1;
+    }
+  }
+`;
+
+const DataContainer = styled.div`
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+`;
+
+const StatusContainer = styled.div`
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  height: 100%;
+`;
+
+const PRIcon = styled.img`
+  font-size: 20px;
+  height: 17px;
+  margin-right: 10px;
+  color: #aaaabb;
+  opacity: 50%;
+`;
+
+const RowButton = styled(DynamicLink)`
+  font-size: 12px;
+  padding: 8px 10px;
+  margin-left: 10px;
+  border-radius: 5px;
+  color: #ffffff;
+  border: 1px solid #aaaabb;
+  display: flex;
+  align-items: center;
+  background: #ffffff08;
+  cursor: pointer;
+  :hover {
+    background: #ffffff22;
+  }
+
+  > i {
+    font-size: 14px;
+    margin-right: 8px;
+  }
+`;
+
+const Status = styled.span`
+  font-size: 13px;
+  display: flex;
+  align-items: center;
+  min-height: 17px;
+  color: #a7a6bb;
+`;
+
+const StatusDot = styled.div`
+  width: 8px;
+  height: 8px;
+  margin-right: 15px;
+  background: ${(props: { status: string }) =>
+    props.status === "created"
+      ? "#4797ff"
+      : props.status === "failed"
+      ? "#ed5f85"
+      : props.status === "completed"
+      ? "#00d12a"
+      : "#f5cb42"};
+  border-radius: 20px;
+  margin-left: 3px;
+`;
+
+const DeploymentImageContainer = styled.div`
+  height: 20px;
+  font-size: 13px;
+  position: relative;
+  display: flex;
+  margin-left: 15px;
+  align-items: center;
+  font-weight: 400;
+  justify-content: center;
+  color: #ffffff66;
+  padding-left: 5px;
+`;
+
+const Icon = styled.img`
+  width: 100%;
+`;
+
+const DeploymentTypeIcon = styled(Icon)`
+  width: 20px;
+  margin-right: 10px;
+`;
+
+const RepositoryName = styled.div`
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  max-width: 390px;
+  position: relative;
+  margin-right: 3px;
+`;
+
+const Tooltip = styled.div`
+  position: absolute;
+  left: -20px;
+  top: 10px;
+  min-height: 18px;
+  max-width: calc(700px);
+  padding: 5px 7px;
+  background: #272731;
+  z-index: 999;
+  color: white;
+  font-size: 12px;
+  font-family: "Work Sans", sans-serif;
+  outline: 1px solid #ffffff55;
+  opacity: 0;
+  animation: faded-in 0.2s 0.15s;
+  animation-fill-mode: forwards;
+  @keyframes faded-in {
+    from {
+      opacity: 0;
+    }
+    to {
+      opacity: 1;
+    }
+  }
+`;