2
0
jnfrati 4 жил өмнө
parent
commit
da34553146

+ 1 - 0
dashboard/src/components/OptionsDropdown.tsx

@@ -9,6 +9,7 @@ export const OptionsDropdown: React.FC<{
 
   const handleClick = (e: any) => {
     e.stopPropagation();
+    e.preventDefault();
     setIsOpen(!isOpen);
   };
 

+ 7 - 5
dashboard/src/main/CurrentError.tsx

@@ -5,7 +5,7 @@ import close from "assets/close.png";
 import { Context } from "shared/Context";
 
 type PropsType = {
-  currentError: string;
+  currentError: any;
 };
 
 type StateType = {};
@@ -26,11 +26,13 @@ export default class CurrentError extends Component<PropsType, StateType> {
   }
 
   render() {
-    let currentError = this.props.currentError;
-    if (!React.isValidElement(this.props.currentError)) {
-      currentError = String(this.props.currentError);
+    // Check if it's an error from the API then retrieve the error message that we get from the API
+    let currentError =
+      this.props.currentError?.response?.data?.error || this.props.currentError;
+    if (!React.isValidElement(currentError)) {
+      currentError = String(currentError);
     }
-    if (this.props.currentError) {
+    if (currentError) {
       if (!this.state.expanded) {
         return (
           <StyledCurrentError>

+ 41 - 59
dashboard/src/main/home/cluster-dashboard/preview-environments/PreviewEnvironmentsHome.tsx

@@ -1,5 +1,5 @@
 import Loading from "components/Loading";
-import React, { useContext, useEffect, useState } from "react";
+import React, { useCallback, useContext, useEffect, useState } from "react";
 import { useHistory, useLocation } from "react-router";
 import api from "shared/api";
 import { Context } from "shared/Context";
@@ -12,21 +12,16 @@ import DeploymentList from "./deployments/DeploymentList";
 import EnvironmentsList from "./environments/EnvironmentsList";
 import { environments } from "./mocks";
 
-const AvailableTabs = ["repositories", "pull_requests"];
-
-type TabEnum = typeof AvailableTabs[number];
-
 const PreviewEnvironmentsHome = () => {
   const { currentCluster, currentProject } = useContext(Context);
 
   const [hasGHAccountsLinked, setHasGHAccountsLinked] = useState(false);
   const [hasEnvironments, setHasEnvironments] = useState(false);
   const [isLoading, setIsLoading] = useState(true);
-  const [hasError, setHasError] = useState(false);
   const [environments, setEnvironments] = useState([]);
   const [selectedRepo, setSelectedRepo] = useState("");
 
-  const { getQueryParam, pushQueryParams } = useRouting();
+  const { getQueryParam } = useRouting();
   const location = useLocation();
   const history = useHistory();
 
@@ -107,21 +102,29 @@ const PreviewEnvironmentsHome = () => {
     setSelectedRepo(current_repo);
   }, [location.search, history]);
 
-  const renderMain = () => {
-    if (isLoading) {
-      return (
+  const renderHeader = useCallback(() => {
+    <DashboardHeader
+      image={PullRequestIcon}
+      title="Preview Environments"
+      description="Create full-stack preview environments for your pull requests."
+    />;
+  }, []);
+
+  if (isLoading) {
+    return (
+      <>
+        {renderHeader()}
         <Placeholder>
           <Loading />
         </Placeholder>
-      );
-    }
-  
-    if (hasError) {
-      return <Placeholder>Something went wrong, please try again</Placeholder>;
-    }
-  
-    if (!hasGHAccountsLinked) {
-      return (
+      </>
+    );
+  }
+
+  if (!hasGHAccountsLinked) {
+    return (
+      <>
+        {renderHeader()}
         <Placeholder>
           <Title>There are no repositories linked</Title>
           <Subtitle>
@@ -130,11 +133,15 @@ const PreviewEnvironmentsHome = () => {
           </Subtitle>
           <ButtonEnablePREnvironments />
         </Placeholder>
-      );
-    }
-  
-    if (!hasEnvironments) {
-      return (
+      </>
+    );
+  }
+
+  if (!hasEnvironments) {
+    return (
+      <>
+        {renderHeader()}
+
         <Placeholder>
           <Title>Preview environments are not enabled on this cluster</Title>
           <Subtitle>
@@ -143,57 +150,32 @@ const PreviewEnvironmentsHome = () => {
           </Subtitle>
           <ButtonEnablePREnvironments />
         </Placeholder>
-      );
-    }
+      </>
+    );
+  }
 
-    if (!selectedRepo) {
-      return (
+  if (!selectedRepo) {
+    return (
+      <>
+        {renderHeader()}
         <EnvironmentsList
           environments={environments}
           setEnvironments={setEnvironments}
         />
-      );
-    }
-
-    return (
-      <DeploymentList
-        // selectedRepo={selectedRepo}
-        environments={environments}
-      />
+      </>
     );
   }
 
   return (
     <>
-      <DashboardHeader
-        image={PullRequestIcon}
-        title="Preview Environments"
-        description="Create full-stack preview environments for your pull requests."
-      />
-      {renderMain()}
+      {renderHeader()}
+      <DeploymentList />
     </>
   );
 };
 
-/*
-<DeploymentList environments={environments} />
-*/
 export default PreviewEnvironmentsHome;
 
-const mockRequest = () =>
-  new Promise((res) => {
-    setTimeout(() => {
-      res({ data: environments });
-    }, 1000);
-  });
-
-const LineBreak = styled.div`
-  width: calc(100% - 0px);
-  height: 2px;
-  background: #ffffff20;
-  margin: 10px 0px 35px;
-`;
-
 const Placeholder = styled.div`
   padding: 30px;
   margin-top: 35px;

+ 37 - 74
dashboard/src/main/home/cluster-dashboard/preview-environments/deployments/DeploymentList.tsx

@@ -10,7 +10,7 @@ import _ from "lodash";
 import DeploymentCard from "./DeploymentCard";
 import { Environment, PRDeployment, PullRequest } from "../types";
 import { useRouting } from "shared/routing";
-import { useHistory, useLocation } from "react-router";
+import { useHistory, useLocation, useParams } from "react-router";
 import { deployments, pull_requests } from "../mocks";
 import PullRequestCard from "./PullRequestCard";
 
@@ -25,7 +25,7 @@ const AvailableStatusFilters = [
 
 type AvailableStatusFiltersType = typeof AvailableStatusFilters[number];
 
-const DeploymentList = ({ environments }: { environments: Environment[] }) => {
+const DeploymentList = () => {
   const [isLoading, setIsLoading] = useState(true);
   const [hasError, setHasError] = useState(false);
   const [deploymentList, setDeploymentList] = useState<PRDeployment[]>([]);
@@ -35,17 +35,25 @@ const DeploymentList = ({ environments }: { environments: Environment[] }) => {
     statusSelectorVal,
     setStatusSelectorVal,
   ] = useState<AvailableStatusFiltersType>("active");
-  const [selectedRepo, setSelectedRepo] = useState("");
 
   const { currentProject, currentCluster } = useContext(Context);
   const { getQueryParam, pushQueryParams } = useRouting();
   const location = useLocation();
   const history = useHistory();
+  const { environment_id, repo_name, repo_owner } = useParams<{
+    environment_id: string;
+    repo_name: string;
+    repo_owner: string;
+  }>();
+
+  const selectedRepo = `${repo_owner}/${repo_name}`;
 
   const getPRDeploymentList = () => {
     return api.getPRDeploymentList(
       "<token>",
-      {},
+      {
+        environment_id: Number(environment_id),
+      },
       {
         project_id: currentProject.id,
         cluster_id: currentCluster.id,
@@ -54,18 +62,6 @@ const DeploymentList = ({ environments }: { environments: Environment[] }) => {
     // return mockRequest();
   };
 
-  useEffect(() => {
-    const selected_repo = getQueryParam("repository");
-
-    const repo = environments.find(
-      (env) => `${env.git_repo_owner}/${env.git_repo_name}` === selected_repo
-    );
-
-    if (repo && true) {
-      setSelectedRepo(`${repo.git_repo_owner}/${repo.git_repo_name}`);
-    }
-  }, [location.search, history]);
-
   useEffect(() => {
     const status_filter = getQueryParam("status_filter");
 
@@ -105,20 +101,20 @@ const DeploymentList = ({ environments }: { environments: Environment[] }) => {
     return () => {
       isSubscribed = false;
     };
-  }, [currentCluster, currentProject, statusSelectorVal]);
+  }, [currentCluster, currentProject]);
 
-  const handleRefresh = () => {
+  const handleRefresh = async () => {
     setIsLoading(true);
-    getPRDeploymentList()
-      .then(({ data }) => {
-        setDeploymentList(data.deployments || []);
-        setPullRequests(data.pull_requests || []);
-      })
-      .catch((err) => {
-        setHasError(true);
-        console.error(err);
-      })
-      .finally(() => setIsLoading(false));
+    try {
+      const { data } = await getPRDeploymentList();
+      setDeploymentList(data.deployments || []);
+      setPullRequests(data.pull_requests || []);
+    } catch (error) {
+      setHasError(true);
+      console.error(error);
+    } finally {
+      setIsLoading(false);
+    }
   };
 
   const handlePreviewEnvironmentManualCreation = (pullRequest: PullRequest) => {
@@ -135,55 +131,29 @@ const DeploymentList = ({ environments }: { environments: Environment[] }) => {
   };
 
   const filteredDeployments = useMemo(() => {
-    if (statusSelectorVal === "not_deployed") {
-      return [];
-    }
-
-    if (statusSelectorVal === "all" && selectedRepo === "all") {
-      return deploymentList;
-    }
-
-    let tmpDeploymentList = [...deploymentList];
-
-    if (selectedRepo !== "all") {
-      tmpDeploymentList = tmpDeploymentList.filter((deployment) => {
-        return (
-          `${deployment.gh_repo_owner}/${deployment.gh_repo_name}` ===
-          selectedRepo
-        );
-      });
-    }
-
     // Only filter out inactive when status filter is "active"
     if (statusSelectorVal === "active") {
-      tmpDeploymentList = tmpDeploymentList.filter((d) => {
+      return deploymentList.filter((d) => {
         return d.status !== "inactive";
       });
-    } else if (statusSelectorVal === "inactive") {
-      tmpDeploymentList = tmpDeploymentList.filter((d) => {
+    }
+
+    if (statusSelectorVal === "inactive") {
+      return deploymentList.filter((d) => {
         return d.status === "inactive";
       });
     }
 
-    return tmpDeploymentList;
-  }, [selectedRepo, statusSelectorVal, deploymentList]);
+    return deploymentList;
+  }, [statusSelectorVal, deploymentList]);
 
   const filteredPullRequests = useMemo(() => {
-    if (
-      statusSelectorVal !== "not_deployed" &&
-      statusSelectorVal !== "inactive"
-    ) {
+    if (statusSelectorVal !== "inactive") {
       return [];
     }
 
-    if (selectedRepo === "inactive") {
-      return pullRequests;
-    }
-
-    return pullRequests.filter((pr) => {
-      return `${pr.repo_owner}/${pr.repo_name}` === selectedRepo;
-    });
-  }, [selectedRepo, pullRequests]);
+    return pullRequests;
+  }, [pullRequests, statusSelectorVal]);
 
   const renderDeploymentList = () => {
     if (isLoading) {
@@ -237,19 +207,10 @@ const DeploymentList = ({ environments }: { environments: Environment[] }) => {
   };
 
   const handleStatusFilterChange = (value: string) => {
-    setIsLoading(true);
     pushQueryParams({ status_filter: value });
     setStatusSelectorVal(value);
   };
 
-  const renderMain = () => {
-    return (
-      <Container>
-        <EventsGrid>{renderDeploymentList()}</EventsGrid>
-      </Container>
-    );
-  };
-
   return (
     <>
       <Flex>
@@ -291,7 +252,9 @@ const DeploymentList = ({ environments }: { environments: Environment[] }) => {
           </StyledStatusSelector>
         </ActionsWrapper>
       </Flex>
-      {renderMain()}
+      <Container>
+        <EventsGrid>{renderDeploymentList()}</EventsGrid>
+      </Container>
     </>
   );
 };

+ 6 - 16
dashboard/src/main/home/cluster-dashboard/preview-environments/environments/EnvironmentCard.tsx

@@ -1,14 +1,8 @@
-import React, {
-  FormEvent,
-  FormEventHandler,
-  useContext,
-  useState,
-} from "react";
+import React, { useContext, useState } from "react";
 import { capitalize } from "shared/string_utils";
 import styled from "styled-components";
 import { Environment } from "../types";
 import Options from "components/OptionsDropdown";
-import { useRouting } from "shared/routing";
 import api from "shared/api";
 import { Context } from "shared/Context";
 import Modal from "main/home/modals/Modal";
@@ -25,7 +19,6 @@ const EnvironmentCard = ({ environment, onDelete }: Props) => {
   const { currentCluster, currentProject, setCurrentError } = useContext(
     Context
   );
-  const { pushFiltered } = useRouting();
 
   const [showDeleteModal, setShowDeleteModal] = useState(false);
   const [deleteConfirmationRepoName, setDeleteConfirmationRepoName] = useState(
@@ -42,12 +35,6 @@ const EnvironmentCard = ({ environment, onDelete }: Props) => {
     last_deployment_status,
   } = environment;
 
-  const showOpenPrs = () => {
-    pushFiltered("/preview-environments", [], {
-      repository: `${git_repo_owner}/${git_repo_name}`,
-    });
-  };
-
   const handleDelete = () => {
     if (!canDelete()) {
       return;
@@ -116,7 +103,9 @@ const EnvironmentCard = ({ environment, onDelete }: Props) => {
           </ActionWrapper>
         </Modal>
       ) : null}
-      <EnvironmentCardWrapper onClick={showOpenPrs}>
+      <EnvironmentCardWrapper
+        to={`/environment/${id}/${git_repo_owner}/${git_repo_name}`}
+      >
         <DataContainer>
           <RepoName>
             <Icon
@@ -176,8 +165,9 @@ const OptionWrapper = styled.div`
   justify-content: center;
 `;
 
-const EnvironmentCardWrapper = styled.div`
+const EnvironmentCardWrapper = styled(DynamicLink)`
   display: flex;
+  color: #ffffff;
   background: #2b2e3699;
   justify-content: space-between;
   border-radius: 5px;

+ 7 - 1
dashboard/src/main/home/cluster-dashboard/preview-environments/routes.tsx

@@ -3,6 +3,7 @@ import { Redirect, Route, Switch, useRouteMatch } from "react-router";
 import { Context } from "shared/Context";
 import ConnectNewRepo from "./ConnectNewRepo";
 import DeploymentDetail from "./deployments/DeploymentDetail";
+import DeploymentList from "./deployments/DeploymentList";
 import PreviewEnvironmentsHome from "./PreviewEnvironmentsHome";
 
 export const Routes = () => {
@@ -22,7 +23,12 @@ export const Routes = () => {
         <Route path={`${url}/details/:namespace?`}>
           <DeploymentDetail />
         </Route>
-        <Route path={`${url}/:selected_tab?`}>
+        <Route
+          path={`${url}/environment/:environment_id/:repo_owner/:repo_name`}
+        >
+          <DeploymentList />
+        </Route>
+        <Route path={`${url}/`}>
           <PreviewEnvironmentsHome />
         </Route>
       </Switch>

+ 9 - 2
dashboard/src/shared/api.tsx

@@ -313,7 +313,7 @@ const updateNotificationConfig = baseApi<
 
 const getPRDeploymentList = baseApi<
   {
-    status?: string[];
+    environment_id?: number;
   },
   {
     cluster_id: number;
@@ -373,7 +373,14 @@ const deletePRDeployment = baseApi<
     pr_number: number;
   }
 >("DELETE", (pathParams) => {
-  const { cluster_id, project_id, environment_id, repo_owner, repo_name, pr_number } = pathParams;
+  const {
+    cluster_id,
+    project_id,
+    environment_id,
+    repo_owner,
+    repo_name,
+    pr_number,
+  } = pathParams;
   return `/api/projects/${project_id}/clusters/${cluster_id}/deployments/${environment_id}/${repo_owner}/${repo_name}/${pr_number}`;
 });