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

redirect to cluster settings on initial create

Justin Rhee 3 лет назад
Родитель
Сommit
7e4f41519b

+ 41 - 13
dashboard/src/components/ProvisionerSettings.tsx

@@ -1,15 +1,17 @@
 import React, { useEffect, useState, useContext } from "react";
 import styled from "styled-components";
+import { RouteComponentProps, withRouter } from "react-router";
 
 import api from "shared/api";
-
 import { Context } from "shared/Context";
+import { pushFiltered } from "shared/routing";
 
 import SelectRow from "components/form-components/SelectRow";
 import Heading from "components/form-components/Heading";
 import InputRow from "./form-components/InputRow";
 import SaveButton from "./SaveButton";
 import { Contract, EnumKubernetesKind, EnumCloudProvider, NodeGroupType, EKSNodeGroup, EKS, Cluster } from "@porter-dev/api-contracts";
+import { ClusterType } from "shared/types";
 
 const regionOptions = [
   { value: "us-east-1", label: "US East (N. Virginia) us-east-1" },
@@ -40,16 +42,19 @@ const machineTypeOptions = [
   { value: "t3.2xlarge", label: "t3.2xlarge" },
 ];
 
-type Props = {
+type Props = RouteComponentProps & {
   credentialId: string;
   clusterId?: number;
 };
 
-const ProvisionerForm: React.FC<Props> = ({
-  credentialId,
-  clusterId,
-}) => {
-  const { currentProject, currentCluster } = useContext(Context);
+const ProvisionerSettings: React.FC<Props> = props => {
+  const {
+    currentProject,
+    currentCluster,
+    setCurrentCluster,
+    setShouldRefreshClusters,
+    setHasFinishedOnboarding,
+  } = useContext(Context);
   const [createStatus, setCreateStatus] = useState("");
   const [clusterName, setClusterName] = useState("");
   const [awsRegion, setAwsRegion] = useState("us-east-1");
@@ -66,7 +71,7 @@ const ProvisionerForm: React.FC<Props> = ({
         projectId: currentProject.id,
         kind: EnumKubernetesKind.EKS,
         cloudProvider: EnumCloudProvider.AWS,
-        cloudProviderCredentialsId: String(credentialId),
+        cloudProviderCredentialsId: String(props.credentialId),
         kindValues: {
           case: "eksKind",
           value: new EKS({
@@ -102,8 +107,8 @@ const ProvisionerForm: React.FC<Props> = ({
       })
     });
 
-    if (clusterId) {
-      data["cluster"]["clusterId"] = clusterId;
+    if (props.clusterId) {
+      data["cluster"]["clusterId"] = props.clusterId;
     }
 
     try {
@@ -112,7 +117,30 @@ const ProvisionerForm: React.FC<Props> = ({
         data,
         { project_id: currentProject.id }
       );
-      console.log(res.data);
+
+      // Only refresh and set clusters on initial create
+      if (!props.clusterId) {
+        setShouldRefreshClusters(true);
+        api.getClusters(
+          "<token>",
+          {},
+          { id: currentProject.id },
+        )
+          .then(({ data }) => {
+            data.forEach((cluster: ClusterType) => {
+              if (cluster.id === res.data.cluster_id) {
+                setHasFinishedOnboarding(true);
+                setCurrentCluster(cluster);
+                pushFiltered(props, "/cluster-dashboard", ["project_id"], {
+                  cluster: cluster.name,
+                });
+              }
+            });
+          })
+          .catch((err) => {
+            console.error(err);
+          });
+      }
     } catch (err) {
       console.log(err);
     }
@@ -120,7 +148,7 @@ const ProvisionerForm: React.FC<Props> = ({
 
   useEffect(() => {
     setIsReadOnly(
-      clusterId && (
+      props.clusterId && (
         currentCluster.status === "UPDATING" ||
         currentCluster.status === "UPDATING_UNAVAILABLE"
       )
@@ -217,7 +245,7 @@ const ProvisionerForm: React.FC<Props> = ({
   );
 };
 
-export default ProvisionerForm;
+export default withRouter(ProvisionerSettings);
 
 const ExpandHeader = styled.div<{ isExpanded: boolean }>`
   display: flex;

+ 10 - 0
dashboard/src/main/home/Home.tsx

@@ -61,6 +61,7 @@ const Home: React.FC<Props> = props => {
     currentModal,
     currentOverlay,
     hasFinishedOnboarding,
+    shouldRefreshClusters,
     setProjects,
     setCurrentProject,
     setCapabilities,
@@ -70,6 +71,7 @@ const Home: React.FC<Props> = props => {
     setCurrentModal,
     setHasBillingEnabled,
     setUsage,
+    setShouldRefreshClusters,
   } = useContext(Context);
 
   const [showWelcome, setShowWelcome] = useState(false);
@@ -215,6 +217,14 @@ const Home: React.FC<Props> = props => {
     }
   }, []);
 
+  // Hacky legacy shim for remote cluster refresh until Context is properly split
+  useEffect(() => {
+    if (shouldRefreshClusters) {
+      setForceRefreshClusters(true);
+      setShouldRefreshClusters(false);
+    }
+  }, [shouldRefreshClusters]);
+
   const checkIfProjectHasBilling = async (projectId: number) => {
     if (!projectId) {
       return false;

+ 56 - 34
dashboard/src/main/home/dashboard/ClusterList.tsx

@@ -8,6 +8,8 @@ import loading from "assets/loading.gif";
 import Loading from "components/Loading";
 
 import { Context } from "shared/Context";
+import Heading from "components/form-components/Heading";
+import Helper from "components/form-components/Helper";
 
 type Props = {};
 
@@ -101,41 +103,53 @@ const ClusterList: React.FC<Props> = ({}) => {
         isLoading ? (
           <LoadingWrapper><Loading /></LoadingWrapper>
         ) : (
-          <StyledClusterList>
-            {clusters.map((cluster: any) => {
-              return (
-                <ClusterRow
-                  key={cluster.id}
-                  onClick={() => {
-                    setCurrentCluster(cluster);
-                    pushFiltered({ location, history }, "/applications", ["project_id"], {
-                      cluster: cluster.name,
-                    });
-                  }}
-                >
-                  {renderIcon()}
-                  {cluster.name}
-                  {
-                    (
-                      cluster.status === "UPDATING" || cluster.status === "UPDATING_UNAVAILABLE"
-                    ) && (
-                      <Status
-                        onClick={(e) => {
-                          e.stopPropagation();
-                          setCurrentCluster(cluster);
-                          pushFiltered({ location, history }, "/cluster-dashboard", ["project_id"], {
-                            cluster: cluster.name,
-                          });
-                        }}
-                      >
-                        <Img src={loading} /> Updating
-                      </Status>
-                    )
-                  }
-                </ClusterRow>
+          <>
+            {
+              clusters.length === 0 && (
+                <Placeholder>
+                  <Heading isAtTop>No clusters found</Heading>
+                  <Helper>
+                    Create a cluster to deploy new applications.
+                  </Helper>
+                </Placeholder>
               )
-            })}
-          </StyledClusterList>
+            }
+            <StyledClusterList>
+              {clusters.map((cluster: any) => {
+                return (
+                  <ClusterRow
+                    key={cluster.id}
+                    onClick={() => {
+                      setCurrentCluster(cluster);
+                      pushFiltered({ location, history }, "/applications", ["project_id"], {
+                        cluster: cluster.name,
+                      });
+                    }}
+                  >
+                    {renderIcon()}
+                    {cluster.name}
+                    {
+                      (
+                        cluster.status === "UPDATING" || cluster.status === "UPDATING_UNAVAILABLE"
+                      ) && (
+                        <Status
+                          onClick={(e) => {
+                            e.stopPropagation();
+                            setCurrentCluster(cluster);
+                            pushFiltered({ location, history }, "/cluster-dashboard", ["project_id"], {
+                              cluster: cluster.name,
+                            });
+                          }}
+                        >
+                          <Img src={loading} /> Updating
+                        </Status>
+                      )
+                    }
+                  </ClusterRow>
+                )
+              })}
+            </StyledClusterList>
+          </>
         )
       }
     </>
@@ -144,6 +158,14 @@ const ClusterList: React.FC<Props> = ({}) => {
 
 export default ClusterList;
 
+const Placeholder = styled.div`
+  padding: 25px;
+  border-radius: 5px;
+  background: #26292e;
+  border: 1px solid #494b4f;
+  padding-bottom: 10px;
+`;
+
 const Img = styled.img`
   height: 15px;
   margin-right: 7px;

+ 3 - 1
dashboard/src/main/home/launch/Launch.tsx

@@ -99,7 +99,9 @@ class Templates extends Component<PropsType, StateType> {
           }
         });
 
-        if (numUnavailable === data.length) {
+        if (data.length === 0) {
+          this.setState({ readyClusterStatus: "onboarding" });
+        } else if (numUnavailable === data.length) {
           this.setState({ readyClusterStatus: "none-ready" });
         } else {
           this.setState({ readyClusterStatus: "has-ready" });

+ 6 - 0
dashboard/src/shared/Context.tsx

@@ -64,6 +64,8 @@ export interface GlobalContextType {
   setCanCreateProject: (canCreateProject: boolean) => void;
   enableGitlab: boolean;
   setEnableGitlab: (enableGitlab: boolean) => void;
+  shouldRefreshClusters: boolean;
+  setShouldRefreshClusters: (shouldRefreshClusters: boolean) => void;
 }
 
 /**
@@ -196,6 +198,10 @@ class ContextProvider extends Component<PropsType, StateType> {
     setEnableGitlab: (enableGitlab) => {
       this.setState({ enableGitlab });
     },
+    shouldRefreshClusters: false,
+    setShouldRefreshClusters: (shouldRefreshClusters) => {
+      this.setState({ shouldRefreshClusters });
+    },
   };
 
   render() {

+ 2 - 0
dashboard/src/shared/types.tsx

@@ -373,6 +373,8 @@ export interface ContextProps {
   setCanCreateProject: (canCreateProject: boolean) => void;
   enableGitlab: boolean;
   setEnableGitlab: (enableGitlab: boolean) => void;
+  shouldRefreshClusters: boolean;
+  setShouldRefreshClusters: (shouldRefreshClusters: boolean) => void;
 }
 
 export enum JobStatusType {