Jelajahi Sumber

test-changes

Soham Dessai 3 tahun lalu
induk
melakukan
cf51d1c8f3

+ 1 - 0
api/server/handlers/stacks/create_porter_app.go

@@ -43,6 +43,7 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		ClusterID: cluster.ID,
 		ProjectID: project.ID,
 		RepoName:  request.RepoName,
+		GitRepoID: request.GitRepoID,
 		GitBranch: request.GitBranch,
 
 		BuildContext: request.BuildContext,

+ 1 - 0
api/types/porter_app.go

@@ -28,6 +28,7 @@ type CreatePorterAppRequest struct {
 	ProjectID    uint   `json:"project_id"`
 	RepoName     string `json:"repo_name"`
 	GitBranch    string `json:"git_branch"`
+	GitRepoID    uint   `json:"git_repo_id"`
 	BuildContext string `json:"build_context"`
 	Builder      string `json:"builder"`
 	Buildpacks   string `json:"buildpacks"`

+ 1 - 1
dashboard/src/components/TitleSectionStacks.tsx

@@ -32,7 +32,7 @@ const TitleSectionStacks: React.FC<Props> = ({
         </BackButton>
       )}
 
-      {icon && <Icon disableMarginRight={true} className={icon} />}
+      {icon}
 
       <StyledTitle capitalize={capitalize} onClick={onClick}>
         {children}

+ 7 - 3
dashboard/src/components/porter/Modal.tsx

@@ -5,11 +5,13 @@ import { createPortal } from "react-dom";
 type Props = {
   closeModal?: () => void;
   children: React.ReactNode;
+  width?: string;
 };
 
 const Modal: React.FC<Props> = ({
   closeModal,
   children,
+  width,
 }) => {
   return (
     <>
@@ -17,7 +19,7 @@ const Modal: React.FC<Props> = ({
         createPortal(
           <ModalWrapper>
             <ModalBg onClick={closeModal} />
-            <StyledModal> 
+            <StyledModal width={width}> 
               {closeModal && (
                 <CloseButton onClick={closeModal}>
                   <i className="material-icons">close</i>
@@ -92,14 +94,16 @@ const ModalBg = styled.div`
   }
 `;
 
-const StyledModal = styled.div`
+const StyledModal = styled.div<{
+  width?: string;
+}>`
   position: relative;
   padding: 25px;
   padding-bottom: 35px;
   border-radius: 10px;
   border: 1px solid #494b4f;
   font-size: 13px;
-  width: 600px;
+  width: ${props => props.width || "600px"};
   background: #42444933;
   backdrop-filter: saturate(150%) blur(8px);
 

+ 12 - 2
dashboard/src/components/repo-selector/BuildpackSelection.tsx

@@ -43,12 +43,22 @@ export const BuildpackSelection: React.FC<{
   folderPath: string;
   branch: string;
   hide: boolean;
+  defaultBuildConfig?: BuildConfig;
   onChange: (config: BuildConfig) => void;
-}> = ({ actionConfig, folderPath, branch, hide, onChange }) => {
+}> = ({
+  actionConfig,
+  folderPath,
+  branch,
+  hide,
+  onChange,
+  defaultBuildConfig,
+}) => {
   const { currentProject } = useContext(Context);
 
   const [builders, setBuilders] = useState<DetectedBuildpack[]>(null);
-  const [selectedBuilder, setSelectedBuilder] = useState<string>(null);
+  const [selectedBuilder, setSelectedBuilder] = useState<string>(
+    defaultBuildConfig ? defaultBuildConfig.builder : null
+  );
 
   const [stacks, setStacks] = useState<string[]>(null);
   const [selectedStack, setSelectedStack] = useState<string>(null);

+ 1 - 13
dashboard/src/components/repo-selector/BuildpackStack.tsx

@@ -48,15 +48,7 @@ export const BuildpackStack: React.FC<{
   branch: string;
   hide: boolean;
   onChange: (config: BuildConfig) => void;
-  defaultBuildConfig: BuildConfig;
-}> = ({
-  actionConfig,
-  folderPath,
-  branch,
-  hide,
-  onChange,
-  defaultBuildConfig,
-}) => {
+}> = ({ actionConfig, folderPath, branch, hide, onChange }) => {
   const { currentProject } = useContext(Context);
 
   const [builders, setBuilders] = useState<DetectedBuildpack[]>(null);
@@ -115,10 +107,6 @@ export const BuildpackStack: React.FC<{
   };
   useEffect(() => {
     let buildConfig: BuildConfig = {} as BuildConfig;
-    if (defaultBuildConfig) {
-      buildConfig = defaultBuildConfig;
-    }
-
     buildConfig.builder = selectedStack;
     console.log(buildConfig);
     buildConfig.buildpacks = selectedBuildpacks?.map((buildpack) => {

+ 1 - 3
dashboard/src/main/home/app-dashboard/AppDashboard.tsx

@@ -112,7 +112,7 @@ const AppDashboard: React.FC<Props> = ({
       apps.forEach((app: any, i: number) => {
         app["last_deployed"] = readableDate(timeRes[i].data[0]?.info?.last_deployed);
       });
-      setApps(apps);
+      setApps(apps.reverse());
       setIsLoading(false);
     }
     catch (err) {
@@ -149,7 +149,6 @@ const AppDashboard: React.FC<Props> = ({
     var src = box;
     if (b) {
       const bp = b.split(",")[0]?.split("/")[1];
-      console.log(b)
       switch (bp) {
         case "ruby":
           src = icons[0];
@@ -214,7 +213,6 @@ const AppDashboard: React.FC<Props> = ({
         <GridList>
          {(filteredApps ?? []).map((app: any, i: number) => {
            if (!namespaceBlacklist.includes(app.name)) {
-            console.log(app)
              return (
               <Link to={`/apps/${app.name}`} key={i}>
                 <Block>

+ 154 - 21
dashboard/src/main/home/app-dashboard/expanded-app/BuildSettingsTabStack.tsx

@@ -1,5 +1,5 @@
 import AnimateHeight from "react-animate-height";
-import React, { Component, Dispatch, useState } from "react";
+import React, { Component, Dispatch, useMemo, useRef, useState } from "react";
 import Text from "components/porter/Text";
 import Spacer from "components/porter/Spacer";
 import Input from "components/porter/Input";
@@ -10,6 +10,7 @@ import ActionConfEditorStack from "components/repo-selector/ActionConfEditorStac
 import {
   ActionConfigType,
   BuildConfig,
+  FullActionConfigType,
   GithubActionConfigType,
 } from "shared/types";
 import { RouteComponentProps } from "react-router";
@@ -20,6 +21,9 @@ import { pushFiltered } from "shared/routing";
 import ImageSelector from "components/image-selector/ImageSelector";
 import SharedBuildSettings from "./SharedBuildSettings";
 import Loading from "components/Loading";
+import { BuildpackSelection } from "components/repo-selector/BuildpackSelection";
+import BuildpackConfigSection from "main/home/cluster-dashboard/expanded-chart/build-settings/_BuildpackConfigSection";
+import { BuildpackStack } from "components/repo-selector/BuildpackStack";
 type Props = {
   appData: any;
   setAppData: Dispatch<any>;
@@ -28,9 +32,14 @@ type Props = {
 const BuildSettingsTabStack: React.FC<Props> = ({ appData, setAppData }) => {
   const [updated, setUpdated] = useState(null);
   const [branch, setBranch] = useState(appData.app.git_branch);
-  const defaultActionConfig: GithubActionConfigType = {
+  const [showSettings, setShowSettings] = useState(false);
+  const [dockerfilePath, setDockerfilePath] = useState(
+    appData.app.dockerfilePath
+  );
+  const [folderPath, setFolderPath] = useState("./");
+  const defaultActionConfig: ActionConfigType = {
     git_repo: appData.app.repo_name,
-    image_repo_uri: appData.chart.image_uri,
+    image_repo_uri: appData.chart.image_repo_uri,
     git_branch: appData.app.git_branch,
     git_repo_id: appData.app.repo_id,
     kind: "github",
@@ -38,32 +47,108 @@ const BuildSettingsTabStack: React.FC<Props> = ({ appData, setAppData }) => {
   const defaultBuildConfig: BuildConfig = {
     builder: appData.app.builder,
     buildpacks: appData.app.build_packs?.split(","),
-    config: {},
+    config: appData.chart.config,
   };
   const [buildConfig, setBuildConfig] = useState<BuildConfig>({
     ...defaultBuildConfig,
   });
-  const [actionConfig, setActionConfig] = useState<GithubActionConfigType>({
+  const [actionConfig, setActionConfig] = useState<ActionConfigType>({
     ...defaultActionConfig,
   });
 
+  const [imageUrl, setImageUrl] = useState(appData.chart.image_uri);
+
+  const buildpackConfigRef = useRef<{
+    isLoading: boolean;
+    getBuildConfig: () => BuildConfig;
+  }>(null);
+
+  const currentActionConfig = useMemo(() => {
+    console.log(appData.chart.config);
+    console.log(appData);
+    const actionConf = appData.chart.config;
+
+    return {
+      kind: "github",
+      ...actionConf,
+    } as FullActionConfigType;
+  }, [appData.chart]);
+
   return (
-    <SharedBuildSettings
-      actionConfig={actionConfig}
-      branch={branch}
-      dockerfilePath={"./"}
-      folderPath={"./"}
-      setActionConfig={setActionConfig}
-      setDockerfilePath={() => {}}
-      setFolderPath={() => {}}
-      setBuildConfig={setBuildConfig}
-      buildConfig={buildConfig}
-      porterYaml={""}
-      setPorterYaml={() => {}}
-      setBranch={setBranch}
-      imageUrl={""}
-      setImageUrl={() => {}}
-    />
+    <>
+      <Text size={16}>Build settings</Text>
+      <ActionConfEditorStack
+        actionConfig={actionConfig}
+        setActionConfig={(actionConfig: ActionConfigType) => {
+          setActionConfig((currentActionConfig: ActionConfigType) => ({
+            ...currentActionConfig,
+            ...actionConfig,
+          }));
+          setImageUrl(actionConfig.image_repo_uri);
+        }}
+        setBranch={setBranch}
+        setDockerfilePath={setDockerfilePath}
+        setFolderPath={setFolderPath}
+      />
+      <DarkMatter antiHeight="-4px" />
+      <br />
+      {actionConfig.git_repo && (
+        <>
+          <ActionConfBranchSelector
+            actionConfig={actionConfig}
+            branch={branch}
+            setActionConfig={(actionConfig: ActionConfigType) => {
+              setActionConfig((currentActionConfig: ActionConfigType) => ({
+                ...currentActionConfig,
+                ...actionConfig,
+              }));
+              setImageUrl(actionConfig.image_repo_uri);
+            }}
+            setBranch={setBranch}
+            setDockerfilePath={setDockerfilePath}
+            setFolderPath={setFolderPath}
+          />
+        </>
+      )}
+      <Spacer y={1} />
+      <Text color="helper">Specify your application root path.</Text>
+      <Spacer y={0.5} />
+      <Input
+        disabled={!branch ? true : false}
+        placeholder="ex: ./"
+        value={folderPath}
+        width="100%"
+        setValue={setFolderPath}
+      />
+      <StyledAdvancedBuildSettings
+        showSettings={showSettings}
+        isCurrent={true}
+        onClick={() => {
+          setShowSettings(!showSettings);
+        }}
+      >
+        <AdvancedBuildTitle>
+          <i className="material-icons dropdown">arrow_drop_down</i>
+          Configure Build Pack Settings
+        </AdvancedBuildTitle>
+      </StyledAdvancedBuildSettings>
+      <AnimateHeight height={showSettings ? "auto" : 0} duration={1000}>
+        <StyledSourceBox>
+          {actionConfig && (
+            <BuildpackStack
+              actionConfig={actionConfig}
+              branch={branch}
+              folderPath={folderPath}
+              onChange={(config) => {
+                setBuildConfig(config);
+                setDockerfilePath("");
+              }}
+              hide={!showSettings}
+            />
+          )}
+        </StyledSourceBox>
+      </AnimateHeight>
+    </>
   );
 };
 
@@ -89,3 +174,51 @@ const Required = styled.div`
   color: #fc4976;
   display: inline-block;
 `;
+const AdvancedBuildTitle = styled.div`
+  display: flex;
+  align-items: center;
+`;
+
+const StyledAdvancedBuildSettings = styled.div`
+  color: ${({ showSettings }) => (showSettings ? "white" : "#aaaabb")};
+  background: #26292e;
+  border: 1px solid #494b4f;
+  :hover {
+    border: 1px solid #7a7b80;
+    color: white;
+  }
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: 15px;
+  border-radius: 5px;
+  height: 40px;
+  font-size: 13px;
+  width: 100%;
+  padding-left: 10px;
+  cursor: pointer;
+  border-bottom-left-radius: ${({ showSettings }) => showSettings && "0px"};
+  border-bottom-right-radius: ${({ showSettings }) => showSettings && "0px"};
+
+  .dropdown {
+    margin-right: 8px;
+    font-size: 20px;
+    cursor: pointer;
+    border-radius: 20px;
+    transform: ${(props: { showSettings: boolean; isCurrent: boolean }) =>
+      props.showSettings ? "" : "rotate(-90deg)"};
+  }
+`;
+const StyledSourceBox = styled.div`
+  width: 100%;
+  color: #ffffff;
+  padding: 14px 35px 20px;
+  position: relative;
+  font-size: 13px;
+  border-radius: 5px;
+  background: ${(props) => props.theme.fg};
+  border: 1px solid #494b4f;
+  border-top: 0px;
+  border-top-left-radius: 0px;
+  border-top-right-radius: 0px;
+`;

+ 167 - 76
dashboard/src/main/home/app-dashboard/expanded-app/ExpandedApp.tsx

@@ -1,27 +1,25 @@
 import React, { useEffect, useState, useContext, useCallback } from "react";
 import { RouteComponentProps, withRouter } from "react-router";
 import styled from "styled-components";
-import { DeviconsNameList } from "assets/devicons-name-list";
-import useAuth from "shared/auth/useAuth";
 import yaml from "js-yaml";
-import api from "shared/api";
-import { Context } from "shared/Context";
 
 import notFound from "assets/not-found.png";
+import web from "assets/web.png";
+import box from "assets/box.png";
+import github from "assets/github.png";
+import pr_icon from "assets/pull_request_icon.svg";
+
+import api from "shared/api";
+import { Context } from "shared/Context";
+import useAuth from "shared/auth/useAuth";
 
-import Fieldset from "components/porter/Fieldset";
 import Loading from "components/Loading";
 import Text from "components/porter/Text";
 import Container from "components/porter/Container";
 import Spacer from "components/porter/Spacer";
 import Link from "components/porter/Link";
-import DashboardHeader from "main/home/cluster-dashboard/DashboardHeader";
 import Back from "components/porter/Back";
 import TabSelector from "components/TabSelector";
-import TitleSectionStacks from "components/TitleSectionStacks";
-import DeploymentTypeStacks from "main/home/cluster-dashboard/expanded-chart/DeploymentTypeStacks";
-import DeployStatusSection from "main/home/cluster-dashboard/expanded-chart/deploy-status-section/DeployStatusSection";
-import { integrationList } from "shared/common";
 import { ChartType, ResourceType } from "shared/types";
 import RevisionSection from "main/home/cluster-dashboard/expanded-chart/RevisionSection";
 import BuildSettingsTabStack from "./BuildSettingsTabStack";
@@ -29,6 +27,14 @@ import Button from "components/porter/Button";
 
 type Props = RouteComponentProps & {};
 
+const icons = [
+  "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/ruby/ruby-plain.svg",
+  "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nodejs/nodejs-plain.svg",
+  "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/python/python-plain.svg",
+  "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/go/go-original-wordmark.svg",
+  web,
+];
+
 const ExpandedApp: React.FC<Props> = ({ ...props }) => {
   const {
     currentCluster,
@@ -92,23 +98,32 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
     }
   };
 
-  const renderIcon = (str: string) => {
-    let value = str.split(",");
-    let buildpack = value[0];
-    // console.log(value);
-    // value.forEach((buildpack) => {
-    //   console.log(buildpack);
-    const [languageName] = buildpack.split("/").reverse();
-    const devicon = DeviconsNameList.find(
-      (devicon) => languageName.toLowerCase() === devicon.name
-    );
-    if (devicon) {
-      const icon = `devicon-${devicon?.name}-plain colored`;
-      return icon;
+  const renderIcon = (b: string, size?: string) => {
+    var src = box;
+    if (b) {
+      const bp = b.split(",")[0]?.split("/")[1];
+      switch (bp) {
+        case "ruby":
+          src = icons[0];
+          break;
+        case "nodejs":
+          src = icons[1];
+          break;
+        case "python":
+          src = icons[2];
+          break;
+        case "go":
+          src = icons[3];
+          break;
+        default:
+          break;
+      }
     }
-    // });
-    return "";
+    return (
+      <Icon src={src} />
+    );
   };
+
   const updateComponents = async (currentChart: ChartType) => {
     setLoading(true);
     try {
@@ -257,14 +272,30 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
           <BuildSettingsTabStack appData={appData} setAppData={setAppData} />
         );
       case "settings":
-        return <div>TODO: stack deletion</div>;
+        return (
+          <>
+            <Text size={16}>
+              Delete app "{appData.app.name}"
+            </Text>
+            <Spacer y={1} />
+            <Text color="helper">
+              Delete this application and all of its resources.
+            </Text>
+            <Spacer y={1} />
+            <Button onClick={() => {
+              // set delete overlay
+            }} color="#b91133">
+              Delete {appData.app.name}
+            </Button>
+          </>
+        );
       default:
         return <div>dream on</div>;
     }
   };
 
   return (
-    <StyledExpandedApp>
+    <>
       {isLoading && <Loading />}
       {!appData && !isLoading && (
         <Placeholder>
@@ -280,55 +311,51 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
         </Placeholder>
       )}
       {appData && (
-        <>
-          {/* <Container row>
-            <Icon src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nodejs/nodejs-plain.svg" />
-            <Text size={21}>{appData.name}</Text>
-            <Spacer inline x={1} />
-            <Text size={13}>repo: porter-dev/porter</Text>
-            <Spacer inline x={1} />
-            <Text size={13}>branch: main</Text>
-          </Container> */}
+        <StyledExpandedApp>
           <Back to="/apps" />
-          <HeaderWrapper>
-            <TitleSectionStacks
-              icon={
-                appData.app?.build_packs &&
-                renderIcon(appData.app?.build_packs) != ""
-                  ? renderIcon(appData.app?.build_packs)
-                  : integrationList.registry.icon
-              }
-              iconWidth="33px"
-            >
-              {appData.chart.canonical_name === ""
-                ? appData.chart.name
-                : appData.chart.canonical_name}
-              <DeploymentTypeStacks appData={appData} />
-            </TitleSectionStacks>
-
-            {/* {currentChart.chart.metadata.name != "worker" &&
-              currentChart.chart.metadata.name != "job" &&
-              renderUrl()} */}
-
-            {/* //{currentChart.canonical_name !== "" && renderHelmReleaseName()} */}
-            <InfoWrapper>
-              {/*
-                  <StatusIndicator
-                    controllers={controllers}
-                    status={currentChart.info.status}
-                    margin_left={"0px"}
+          <Container row>
+            {renderIcon(appData.app.build_packs)}
+            <Text size={21}>{appData.app.name}</Text>
+            {appData.app.repo_name && (
+              <>
+                <Spacer inline x={1} />
+                <Text size={13} color="helper">
+                  <SmallIcon src={github} />
+                  {appData.app.repo_name}
+                </Text>
+              </>
+            )}
+            {appData.app.git_branch && (
+              <>
+                <Spacer inline x={1} />
+                <TagWrapper>
+                  Branch
+                  <BranchTag>
+                    <BranchIcon src={pr_icon} />
+                    {appData.app.git_branch}
+                  </BranchTag>
+                </TagWrapper>
+              </>
+            )}
+            {!appData.app.repo_name && appData.app.image_repo_uri && (
+              <>
+                <Spacer inline x={1} />
+                <Text size={13} color="helper">
+                  <SmallIcon
+                    height="19px"
+                    src="https://cdn4.iconfinder.com/data/icons/logos-and-brands/512/97_Docker_logo_logos-512.png"
                   />
-                  */}
-              {/* <DeployStatusSection
-                chart={appData.chart}
-                setLogData={test}//renderLogsAtTimestamp}
-              /> */}
-              <LastDeployed>
-                <Dot>•</Dot>Last deployed
-                {" " + getReadableDate(appData.chart.info.last_deployed)}
-              </LastDeployed>
-            </InfoWrapper>
-          </HeaderWrapper>
+                  {appData.app.image_repo_uri}
+                </Text>
+              </>
+            )}
+          </Container>
+          <Spacer y={1} />
+          <Text color="#aaaabb66">
+            Last deployed {getReadableDate(appData.chart.info.last_deployed)}
+          </Text>
+          <Spacer y={1} />
+          <DarkMatter />
           <RevisionSection
             showRevisions={showRevisions}
             toggleShowRevisions={() => {
@@ -347,6 +374,7 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
             latestVersion={appData.chart.latest_version}
             upgradeVersion={appUpgradeVersion}
           />
+          <DarkMatter antiHeight="-18px" />
           <Spacer y={1} />
           <TabSelector
             options={[
@@ -362,14 +390,67 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
           />
           <Spacer y={1} />
           {renderTabContents()}
-        </>
+        </StyledExpandedApp>
       )}
-    </StyledExpandedApp>
+    </>
   );
 };
 
 export default withRouter(ExpandedApp);
 
+const DarkMatter = styled.div<{ antiHeight?: string }>`
+  width: 100%;
+  margin-top: ${props => props.antiHeight || "-20px"};
+`;
+
+const TagWrapper = styled.div`
+  height: 20px;
+  font-size: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #ffffff44;
+  border: 1px solid #ffffff44;
+  border-radius: 3px;
+  padding-left: 6px;
+`;
+
+const BranchTag = styled.div`
+  height: 20px;
+  margin-left: 6px;
+  color: #aaaabb;
+  background: #ffffff22;
+  border-radius: 3px;
+  font-size: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 0px 6px;
+  padding-left: 7px;
+  border-top-left-radius: 0px;
+  border-bottom-left-radius: 0px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+`;
+
+const BranchSection = styled.div`
+  background: ${props => props.theme.fg};
+  border: 1px solid #494b4f;
+`;
+
+const SmallIcon = styled.img<{ opacity?: string, height?: string }>`
+  height: ${props => props.height || "15px"};
+  opacity: ${props => props.opacity || 1};
+  margin-right: 10px;
+`;
+
+const BranchIcon = styled.img`
+  height: 14px;
+  opacity: 0.65;
+  margin-right: 5px;
+`;
+
 const Icon = styled.img`
   height: 24px;
   margin-right: 15px;
@@ -394,6 +475,16 @@ const Placeholder = styled.div`
 const StyledExpandedApp = styled.div`
   width: 100%;
   height: 100%;
+
+  animation: fadeIn 0.5s 0s;
+  @keyframes fadeIn {
+    from {
+      opacity: 0;
+    }
+    to {
+      opacity: 1;
+    }
+  }
 `;
 
 const HeaderWrapper = styled.div`

+ 1 - 1
dashboard/src/main/home/app-dashboard/expanded-app/SharedBuildSettings.tsx

@@ -101,7 +101,7 @@ const SharedBuildSettings: React.FC<Props> = ({
         width="100%"
         setValue={setFolderPath}
       />
-      {actionConfig.git_repo && branch && buildConfig.builder != "" && (
+      {actionConfig.git_repo && branch && buildConfig.builder == "" && (
         <DetectContentsList
           actionConfig={actionConfig}
           branch={branch}

+ 10 - 7
dashboard/src/main/home/app-dashboard/new-app-flow/GithubActionModal.tsx

@@ -1,21 +1,22 @@
+import { RouteComponentProps, withRouter } from "react-router";
+import styled from "styled-components";
+import React from "react";
+
 import Modal from "components/porter/Modal";
-import React, { useContext } from "react";
 import Text from "components/porter/Text";
 import Spacer from "components/porter/Spacer";
 import ExpandableSection from "components/porter/ExpandableSection";
 import Fieldset from "components/porter/Fieldset";
-import styled from "styled-components";
 import Button from "components/porter/Button";
 import Select from "components/porter/Select";
 import api from "shared/api";
-import { CopyBlock } from "react-code-blocks";
 import { getGithubAction } from "./utils";
 import AceEditor from "react-ace";
 import YamlEditor from "components/YamlEditor";
 import Error from "components/porter/Error";
 
 
-interface GithubActionModalProps {
+type Props = RouteComponentProps & {
   closeModal: () => void;
   githubAppInstallationID?: number;
   githubRepoOwner?: string;
@@ -30,7 +31,7 @@ interface GithubActionModalProps {
 
 type Choice = "open_pr" | "copy";
 
-const GithubActionModal: React.FC<GithubActionModalProps> = ({
+const GithubActionModal: React.FC<Props> = ({
   closeModal,
   githubAppInstallationID,
   githubRepoOwner,
@@ -41,6 +42,7 @@ const GithubActionModal: React.FC<GithubActionModalProps> = ({
   clusterId,
   deployPorterApp,
   deploymentError,
+  ...props
 }) => {
   const [choice, setChoice] = React.useState<Choice>("open_pr");
   const [loading, setLoading] = React.useState<boolean>(false);
@@ -71,7 +73,8 @@ const GithubActionModal: React.FC<GithubActionModalProps> = ({
             }
           );
           if (res?.data?.url) {
-            window.open(res.data.url, "_blank", "noreferrer")
+            window.open(res.data.url, "_blank", "noreferrer");
+            props.history.push(`/apps/${stackName}`);
           }
         }
       } catch (error) {
@@ -140,7 +143,7 @@ const GithubActionModal: React.FC<GithubActionModalProps> = ({
   )
 }
 
-export default GithubActionModal;
+export default withRouter(GithubActionModal);
 
 const Tab = styled.span`
   margin-left: 20px;

+ 7 - 5
dashboard/src/main/home/app-dashboard/new-app-flow/NewAppFlow.tsx

@@ -1,5 +1,6 @@
 import React, { useEffect, useState, useContext, useMemo } from "react";
 import styled from "styled-components";
+import { RouteComponentProps, withRouter } from "react-router";
 import _ from "lodash";
 import yaml from "js-yaml";
 
@@ -19,8 +20,6 @@ import VerticalSteps from "components/porter/VerticalSteps";
 import PorterFormWrapper from "components/porter-form/PorterFormWrapper";
 import Placeholder from "components/Placeholder";
 import Button from "components/porter/Button";
-import { generateSlug } from "random-word-slugs";
-import { RouteComponentProps, withRouter } from "react-router";
 import SourceSelector, { SourceType } from "./SourceSelector";
 import SourceSettings from "./SourceSettings";
 import Services from "./Services";
@@ -219,15 +218,17 @@ const NewAppFlow: React.FC<Props> = ({ ...props }) => {
         : {};
 
       // write to the db
+      console.log("what is it", actionConfig.git_repo_id)
       await api.createPorterApp(
         "<token>",
         {
           name: formState.applicationName,
           repo_name: actionConfig.git_repo,
           git_branch: branch,
+          git_repo_id: actionConfig?.git_repo_id,
           build_context: folderPath,
           builder: (buildConfig as any)?.builder,
-          buildpacks: (buildConfig as any)?.buildpacks.join(",") ?? "",
+          buildpacks: (buildConfig as any)?.buildpacks?.join(",") ?? "",
           dockerfile: dockerfilePath,
           image_repo_uri: imageUrl,
         },
@@ -237,7 +238,6 @@ const NewAppFlow: React.FC<Props> = ({ ...props }) => {
         }
       );
 
-      // deploy dummy chart
       await api.updatePorterStack(
         "<token>",
         {
@@ -250,7 +250,9 @@ const NewAppFlow: React.FC<Props> = ({ ...props }) => {
           project_id: currentProject.id,
         }
       )
-
+      if (!actionConfig?.git_repo) {
+        props.history.push(`/apps/${formState.applicationName}`);
+      }
       return true;
     } catch (err) {
       // TODO: better error handling

+ 8 - 4
dashboard/src/main/home/app-dashboard/new-app-flow/Services.tsx

@@ -60,12 +60,15 @@ const Services: React.FC<ServicesProps> = ({ services, setServices }) => {
           <Spacer y={0.5} />
         </>
       )}
-      <AddServiceButton onClick={() => setShowAddServiceModal(true)}>
+      <AddServiceButton onClick={() => {
+        setShowAddServiceModal(true);
+        setServiceType("web");
+      }}>
         <i className="material-icons add-icon">add_icon</i>
         Add a new service
       </AddServiceButton>
       {showAddServiceModal && (
-        <Modal closeModal={() => setShowAddServiceModal(false)}>
+        <Modal closeModal={() => setShowAddServiceModal(false)} width="500px">
           <Text size={16}>Add a new service</Text>
           <Spacer y={1} />
           <Text color="helper">Select a service type:</Text>
@@ -78,7 +81,7 @@ const Services: React.FC<ServicesProps> = ({ services, setServices }) => {
             </ServiceIcon>
             <Select
               value={serviceType}
-              // this is ugly
+              width="100%"
               setValue={(value: string) => setServiceType(value as ServiceType)}
               options={[
                 { label: "Web", value: "web" },
@@ -92,7 +95,7 @@ const Services: React.FC<ServicesProps> = ({ services, setServices }) => {
           <Spacer y={0.5} />
           <Input
             placeholder="ex: my-service"
-            width="300px"
+            width="100%"
             value={serviceName}
             error={
               (serviceName != "" &&
@@ -136,6 +139,7 @@ const ServiceIcon = styled.div`
   justify-content: center;
   height: 35px;
   width: 35px;
+  min-width: 35px;
   margin-right: 10px;
   overflow: hidden;
   border-radius: 5px;

+ 1 - 0
dashboard/src/shared/api.tsx

@@ -192,6 +192,7 @@ const createPorterApp = baseApi<
     name: string;
     repo_name: string;
     git_branch: string;
+    git_repo_id: number;
     build_context: string;
     builder: string;
     buildpacks: string;