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

Implemented connect to source screen

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

+ 198 - 0
dashboard/src/main/home/onboarding/ConnectSource.tsx

@@ -0,0 +1,198 @@
+import Helper from "components/form-components/Helper";
+import SaveButton from "components/SaveButton";
+import TitleSection from "components/TitleSection";
+import React, { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
+import api from "shared/api";
+import { useRouting } from "shared/routing";
+import styled from "styled-components";
+
+interface GithubAppAccessData {
+  username?: string;
+  accounts?: string[];
+}
+
+/**
+ * First step of the flow showing simple Connect to github button, this should
+ * redirect to the github flow
+ *
+ * That way we can be sure that the we have full credentials to launch apps from the user repos.
+ *
+ * The other option would be skip integration, that will skip the whole github connection flow.
+ */
+const ConnectSource = () => {
+  const [accountData, setAccountData] = useState<GithubAppAccessData>(null);
+  const [isLoading, setIsLoading] = useState(true);
+  const { pushFiltered } = useRouting();
+
+  const getAccounts = async () => {
+    setIsLoading(true);
+    try {
+      const res = await api.getGithubAccounts("<token>", {}, {});
+      if (res.status !== 200) {
+        throw new Error("Not authorized");
+      }
+      return res.data;
+    } catch (error) {
+      console.log(error);
+    } finally {
+      setIsLoading(false);
+    }
+  };
+
+  useEffect(() => {
+    let isSubscribed = true;
+    getAccounts().then((accountsData) => {
+      if (isSubscribed) {
+        if (!accountsData) {
+          setAccountData(null);
+        } else {
+          setAccountData(accountsData);
+        }
+      }
+    });
+    return () => {
+      isSubscribed = false;
+    };
+  }, []);
+
+  const nextStep = () => {
+    pushFiltered("/onboarding/provision", []);
+  };
+
+  return (
+    <>
+      <TitleSection>Getting Started</TitleSection>
+      <Subtitle>Step 1 of 2</Subtitle>
+      <Helper>
+        To deploy applications from your repo, you need to connect a Github
+        account
+      </Helper>
+      {!isLoading && (!accountData || !accountData?.accounts?.length) && (
+        <>
+          <ConnectToGithubButton href="/api/integrations/github-app/oauth">
+            Connect to github
+          </ConnectToGithubButton>
+          <Helper>
+            No thanks, I want to deploy from a{" "}
+            <A onClick={nextStep}>Docker registry</A>
+          </Helper>
+        </>
+      )}
+      {!isLoading && accountData?.accounts.length && (
+        <>
+          <List>
+            {accountData?.accounts.map((name, i) => {
+              return (
+                <Row key={i} isLastItem={i === accountData.accounts.length - 1}>
+                  <i className="material-icons">bookmark</i>
+                  {name}
+                </Row>
+              );
+            })}
+          </List>
+          <br />
+          Don't see the right repos?{" "}
+          <A href={"/api/integrations/github-app/install"}>
+            Install Porter in more repositories
+          </A>
+          <NextStep
+            text="Continue"
+            disabled={false}
+            onClick={nextStep}
+            status={""}
+            makeFlush={true}
+            clearPosition={true}
+            statusPosition="right"
+            saveText=""
+            successText="Project created successfully!"
+          />
+        </>
+      )}
+    </>
+  );
+};
+
+export default ConnectSource;
+
+const NextStep = styled(SaveButton)`
+  margin-top: 24px;
+`;
+
+const A = styled.a`
+  color: #8590ff;
+  text-decoration: underline;
+  margin-left: 5px;
+  cursor: pointer;
+`;
+
+const List = styled.div`
+  width: 100%;
+  background: #ffffff11;
+  border-radius: 5px;
+  margin-top: 20px;
+  border: 1px solid #ffffff44;
+  max-height: 200px;
+  overflow-y: auto;
+`;
+
+const Row = styled.div<{ isLastItem?: boolean }>`
+  width: 100%;
+  height: 35px;
+  color: #ffffff55;
+  display: flex;
+  align-items: center;
+  border-bottom: ${(props) => (props.isLastItem ? "" : "1px solid #ffffff44")};
+  > i {
+    font-size: 17px;
+    margin-left: 10px;
+    margin-right: 12px;
+    color: #ffffff44;
+  }
+`;
+
+const Subtitle = styled(TitleSection)`
+  font-size: 16px;
+  margin-top: 16px;
+`;
+
+const ConnectToGithubButton = styled.a`
+  width: 150px;
+  justify-content: center;
+  border-radius: 5px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  font-size: 13px;
+  cursor: pointer;
+  font-family: "Work Sans", sans-serif;
+  color: white;
+  font-weight: 500;
+  padding: 10px;
+  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" : "#616FEEcc"};
+  :hover {
+    background: ${(props: { disabled?: boolean }) =>
+      props.disabled ? "" : "#505edddd"};
+  }
+
+  > 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;
+  }
+`;

+ 1 - 3
dashboard/src/main/home/onboarding/NewProject.tsx

@@ -78,8 +78,6 @@ export const NewProjectFC = () => {
         .createProject("<token>", { name: projectName }, {})
         .then((res) => res.data);
 
-      // Need to set project list for dropdown
-      // TODO: consolidate into ProjectSection (case on exists in list on set)
       const projectList = await api
         .getProjects(
           "<token>",
@@ -92,7 +90,7 @@ export const NewProjectFC = () => {
       setProjects(projectList);
       setCurrentProject(project);
 
-      pushFiltered("/onboarding/provision", []);
+      pushFiltered("/onboarding/integrations", []);
       setButtonStatus("success");
     } catch (error) {
       setButtonStatus("Couldn't create project, try again.");

+ 7 - 0
dashboard/src/main/home/onboarding/ProvisionerForms.tsx

@@ -1,6 +1,7 @@
 import Helper from "components/form-components/Helper";
 import TitleSection from "components/TitleSection";
 import React from "react";
+import styled from "styled-components";
 import { useSnapshot } from "valtio";
 import ProvisionerSettings from "../provisioner/ProvisionerSettings";
 import { OnboardingState } from "./OnboardingState";
@@ -10,6 +11,7 @@ const ProvisionerForms = () => {
   return (
     <>
       <TitleSection>Getting Started</TitleSection>
+      <Subtitle>Step 2 of 2</Subtitle>
       <Helper>Provision a new cluster through us or link one later!</Helper>
       <ProvisionerSettings
         isInNewProject={true}
@@ -21,3 +23,8 @@ const ProvisionerForms = () => {
 };
 
 export default ProvisionerForms;
+
+const Subtitle = styled(TitleSection)`
+  font-size: 16px;
+  margin-top: 16px;
+`;

+ 3 - 3
dashboard/src/main/home/onboarding/Routes.tsx

@@ -1,6 +1,6 @@
 import React from "react";
 import { Route, Switch } from "react-router";
-import ConnectGithub from "./github-connection/ConnectGithub";
+import ConnectSource from "./ConnectSource";
 import { NewProjectFC } from "./NewProject";
 import ProvisionerForms from "./ProvisionerForms";
 
@@ -11,8 +11,8 @@ export const Routes = () => {
         <Route path={`/onboarding/new-project`}>
           <NewProjectFC />
         </Route>
-        <Route path={`/onboarding/integrations/step_1`}>
-          <ConnectGithub />
+        <Route path={`/onboarding/integrations`}>
+          <ConnectSource />
         </Route>
         <Route path={`/onboarding/provision`}>
           <ProvisionerForms />

+ 0 - 85
dashboard/src/main/home/onboarding/github-connection/ConnectGithub.tsx

@@ -1,85 +0,0 @@
-import Button from "components/Button";
-import Helper from "components/form-components/Helper";
-import TitleSection from "components/TitleSection";
-import React from "react";
-import { Link } from "react-router-dom";
-import styled from "styled-components";
-
-/**
- * First step of the flow showing simple Connect to github button, this should
- * redirect to the github flow in this order
- * Has registered through github? Yes -> /api/integrations/github-app/install
- * Hasn't registered through github? -> /api/integrations/github-app/oauth -> /api/integrations/github-app/install
- *
- * That way we can be sure that the we have full credentials to launch apps from the user repos.
- *
- * The other option would be skip integration, that will skip the whole github connection flow.
- */
-const ConnectGithub = () => {
-  return (
-    <>
-      <TitleSection>Getting Started</TitleSection>
-      <Subtitle>Step 1 of 3</Subtitle>
-      <Helper>
-        To deploy applications from your repo, you need to connect a Github
-        account
-      </Helper>
-      {/* Pending: Check with alex where to change the redirect URL and if that can be dynamic (in order to not break other app stuff) */}
-      <ConnectToGithubButton href="/api/integrations/github-app/oauth">
-        Connect to github
-      </ConnectToGithubButton>
-      <Helper>
-        No thanks, I want to deploy from a{" "}
-        <Link to={"/onboarding/provision"}>Docker registry</Link>
-      </Helper>
-    </>
-  );
-};
-
-export default ConnectGithub;
-
-const Subtitle = styled(TitleSection)`
-  font-size: 16px;
-  margin-top: 16px;
-`;
-
-const ConnectToGithubButton = styled.a`
-  width: 150px;
-  justify-content: center;
-  border-radius: 5px;
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-  font-size: 13px;
-  cursor: pointer;
-  font-family: "Work Sans", sans-serif;
-  color: white;
-  font-weight: 500;
-  padding: 10px;
-  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" : "#616FEEcc"};
-  :hover {
-    background: ${(props: { disabled?: boolean }) =>
-      props.disabled ? "" : "#505edddd"};
-  }
-
-  > 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;
-  }
-`;