Explorar o código

BuildPackSettings

Soham Dessai %!s(int64=3) %!d(string=hai) anos
pai
achega
1c2117edba

+ 309 - 336
dashboard/src/components/repo-selector/DetectContentsList.tsx

@@ -1,4 +1,4 @@
-import React, { Component } from "react";
+import React, { useState, useEffect, useContext } from "react";
 import styled from "styled-components";
 import file from "assets/file.svg";
 import folder from "assets/folder.svg";
@@ -12,6 +12,8 @@ import { ActionConfigType, FileType } from "../../shared/types";
 import Loading from "../Loading";
 import Spacer from "components/porter/Spacer";
 import AdvancedBuildSettings from "main/home/app-dashboard/new-app-flow/AdvancedBuildSettings";
+import { render } from "react-dom";
+import BuildpackConfigSection from "main/home/cluster-dashboard/expanded-chart/build-settings/_BuildpackConfigSection";
 
 interface AutoBuildpack {
   name?: string;
@@ -29,53 +31,84 @@ type PropsType = {
   setDockerfilePath: (x: string) => void;
   setProcfilePath: (x: string) => void;
   setFolderPath: (x: string) => void;
+  setBuildConfig: (x: any) => void;
 };
 
-type StateType = {
-  loading: boolean;
-  error: boolean;
-  contents: FileType[];
-  currentDir: string;
-  dockerfiles: string[];
-  processes: Record<string, string>;
-  autoBuildpack: AutoBuildpack;
-  showingBuildContextPrompt: boolean;
-};
+const DetectContentsList: React.FC<PropsType> = (props) => {
+  const [loading, setLoading] = useState(true);
+  const [error, setError] = useState(false);
+  const [contents, setContents] = useState<FileType[]>([]);
+  const [currentDir, setCurrentDir] = useState("");
+  const [autoBuildpack, setAutoBuildpack] = useState<AutoBuildpack>({
+    valid: false,
+    name: "",
+  });
+  const [showingBuildContextPrompt, setShowingBuildContextPrompt] = useState(
+    "buildpacks"
+  );
+
+  const context = useContext(Context);
+
+  useEffect(() => {
+    updateContents();
+  }, []);
+
+  useEffect(() => {
+    const dockerFileItem = contents.find((item: FileType) =>
+      item.path.includes("Dockerfile")
+    );
 
-export default class DetectContentsList extends Component<
-  PropsType,
-  StateType
-> {
-  state = {
-    loading: true,
-    error: false,
-    contents: [] as FileType[],
-    currentDir: "",
-    dockerfiles: [] as string[],
-    processes: null as Record<string, string>,
-    autoBuildpack: {
-      valid: false,
-      name: "",
-    },
-    showingBuildContextPrompt: true,
-  };
+    if (dockerFileItem) {
+      props.setDockerfilePath(dockerFileItem.path);
+      setShowingBuildContextPrompt("docker");
+    }
+  }, [contents]);
+
+  useEffect(() => {
+    detectBuildpacks().then(({ data }) => {
+      setAutoBuildpack(data);
+    });
+  }, [contents]);
+
+  const renderContentList = () => {
+    if (loading) {
+      return (
+        <LoadingWrapper>
+          <Loading />
+        </LoadingWrapper>
+      );
+    } else if (error || !contents) {
+      return <LoadingWrapper>Error loading repo contents.</LoadingWrapper>;
+    }
 
-  setSubdirectory = (x: string) => {
-    this.setState({ currentDir: x }, () => this.updateContents());
+    return contents.map((item: FileType, i: number) => {
+      let splits = item.path.split("/");
+      let fileName = splits[splits.length - 1];
+      if (fileName.includes("Dockerfile")) {
+        return (
+          <AdvancedBuildSettings
+            setBuildConfig={props.setBuildConfig}
+            autoBuildPack={autoBuildpack}
+            showSettings={false}
+            buildView={"docker"}
+            actionConfig={props.actionConfig}
+            branch={props.branch}
+            folderPath={props.folderPath}
+          />
+        );
+      }
+    });
   };
 
-  componentDidMount() {
-    this.updateContents();
-  }
-  fetchContents = () => {
-    let { currentProject } = this.context;
-    const { actionConfig, branch } = this.props;
+  const fetchContents = () => {
+    let { currentProject } = context;
+    const { actionConfig, branch } = props;
 
     if (actionConfig.kind === "gitlab") {
       return api
         .getGitlabFolderContent(
           "<token>",
-          { dir: this.state.currentDir || "./" },
+          { dir: currentDir || "./" },
           {
             project_id: currentProject.id,
             integration_id: actionConfig.gitlab_integration_id,
@@ -97,7 +130,7 @@ export default class DetectContentsList extends Component<
     }
     return api.getBranchContents(
       "<token>",
-      { dir: this.state.currentDir || "./" },
+      { dir: currentDir || "./" },
       {
         project_id: currentProject.id,
         git_repo_id: actionConfig.git_repo_id,
@@ -109,15 +142,15 @@ export default class DetectContentsList extends Component<
     );
   };
 
-  detectBuildpacks = () => {
-    let { currentProject } = this.context;
-    let { actionConfig, branch } = this.props;
+  const detectBuildpacks = () => {
+    let { currentProject } = context;
+    let { actionConfig, branch } = props;
 
     if (actionConfig.kind === "github") {
       return api.detectBuildpack(
         "<token>",
         {
-          dir: this.state.currentDir || ".",
+          dir: currentDir || ".",
         },
         {
           project_id: currentProject.id,
@@ -132,7 +165,7 @@ export default class DetectContentsList extends Component<
 
     return api.detectGitlabBuildpack(
       "<token>",
-      { dir: this.state.currentDir || "." },
+      { dir: currentDir || "." },
       {
         project_id: currentProject.id,
         integration_id: actionConfig.gitlab_integration_id,
@@ -144,308 +177,248 @@ export default class DetectContentsList extends Component<
     );
   };
 
-  updateContents = () => {
-    // Get branch contents
-    this.fetchContents()
-      .then((res) => {
-        let files = [] as FileType[];
-        let folders = [] as FileType[];
-        res.data.map((x: FileType, i: number) => {
-          x.type === "dir" ? folders.push(x) : files.push(x);
-        });
-
-        folders.sort((a: FileType, b: FileType) => {
-          return a.path < b.path ? 1 : 0;
-        });
-        files.sort((a: FileType, b: FileType) => {
-          return a.path < b.path ? 1 : 0;
-        });
-        let contents = folders.concat(files);
-
-        this.setState({ contents, loading: false, error: false });
-      })
-      .catch((err) => {
-        console.log(err);
-
-        this.setState({ loading: false, error: true });
+  const updateContents = async () => {
+    try {
+      const res = await fetchContents();
+      let files = [] as FileType[];
+      let folders = [] as FileType[];
+      res.data.map((x: FileType, i: number) => {
+        x.type === "dir" ? folders.push(x) : files.push(x);
       });
 
-    this.detectBuildpacks()
-      .then(({ data }) => {
-        this.setState({
-          autoBuildpack: data,
-        });
-      })
-      .catch((err) => {
-        console.log(err);
-        this.setState({
-          autoBuildpack: {
-            valid: false,
-          },
-        });
+      folders.sort((a: FileType, b: FileType) => {
+        return a.path < b.path ? 1 : 0;
       });
-  };
-
-  renderContentList = () => {
-    let { contents, loading, error } = this.state;
-    if (loading) {
-      return (
-        <LoadingWrapper>
-          <Loading />
-        </LoadingWrapper>
-      );
-    } else if (error || !contents) {
-      return <LoadingWrapper>Error loading repo contents.</LoadingWrapper>;
-    }
-    let contentsMap = contents.map((item: FileType, i: number) => {
-      let splits = item.path.split("/");
-      let fileName = splits[splits.length - 1];
-      if (fileName.includes("Dockerfile")) {
-        this.props.setDockerfilePath(item.path);
-        return (
-          <DetectedBuildMessage>
-            <i className="material-icons">check</i>
-            Detected Dockerfile at ./{item.path}
-          </DetectedBuildMessage>
-        );
-      }
-    });
-
-    if (this.props.dockerfilePath) {
-      return contentsMap;
-    } else {
-      this.detectBuildpacks()
-        .then(({ data }) => {
-          this.setState({
-            autoBuildpack: data,
-          });
-        })
-        .catch((err) => {
-          console.log(err);
-          this.setState({
-            autoBuildpack: {
-              valid: false,
-            },
-          });
-        });
-      return contentsMap;
-    }
-  };
-
-  renderJumpToParent = () => {
-    if (this.state.currentDir !== "") {
-      let splits = this.state.currentDir.split("/");
-      let subdir = "";
-      if (splits.length !== 1) {
-        subdir = this.state.currentDir.replace(splits[splits.length - 1], "");
-        if (subdir.charAt(subdir.length - 1) === "/") {
-          subdir = subdir.slice(0, subdir.length - 1);
-        }
-      }
-
-      return (
-        <Item lastItem={false} onClick={() => this.setSubdirectory(subdir)}>
-          <BackLabel>..</BackLabel>
-        </Item>
-      );
+      files.sort((a: FileType, b: FileType) => {
+        return a.path < b.path ? 1 : 0;
+      });
+      let contents = folders.concat(files);
+
+      setContents(contents);
+      setLoading(false);
+      setError(false);
+    } catch (err) {
+      console.log(err);
+      setLoading(false);
+      setError(true);
     }
 
-    return (
-      <FileItem lastItem={false}>
-        <img src={info} />
-        Select{" "}
-        {this.props.dockerfilePath
-          ? "Docker Build Context"
-          : "Application Folder"}
-      </FileItem>
-    );
-  };
-
-  renderOverlay = () => {
-    if (this.props.procfilePath) {
-      let processes = this.state.processes
-        ? Object.keys(this.state.processes)
-        : [];
-      if (this.state.processes == null) {
-        return (
-          <Overlay>
-            <BgOverlay>
-              <LoadingWrapper>
-                <Loading />
-              </LoadingWrapper>
-            </BgOverlay>
-          </Overlay>
-        );
-      }
-
-      if (processes.length == 0) {
-        this.props.setProcfilePath("");
-      }
-
-      return (
-        <Overlay>
-          <BgOverlay
-            onClick={() =>
-              this.setState({ dockerfiles: [] }, () => {
-                this.props.setFolderPath("");
-                this.props.setProcfilePath("");
-              })
-            }
-          />
-          <CloseButton
-            onClick={() =>
-              this.setState({ dockerfiles: [] }, () => {
-                this.props.setProcfilePath("");
-              })
-            }
-          >
-            <CloseButtonImg src={close} />
-          </CloseButton>
-          <Label>
-            Porter has detected a Procfile in this folder. Which process would
-            you like to run?
-          </Label>
-          <DockerfileList>
-            {processes.map((process: string, i: number) => {
-              return (
-                <Row
-                  key={i}
-                  onClick={() => {
-                    if (
-                      !this.props.folderPath ||
-                      this.props.folderPath === ""
-                    ) {
-                      this.props.setFolderPath("./");
-                    }
-                    this.props.setProcfileProcess(process);
-                  }}
-                  isLast={processes.length - 1 === i}
-                >
-                  <Indicator selected={false} />
-                  {process}
-                </Row>
-              );
-            })}
-          </DockerfileList>
-        </Overlay>
-      );
-    }
-    if (this.state.dockerfiles.length > 0 && !this.props.dockerfilePath) {
-      return (
-        <Overlay>
-          <BgOverlay onClick={() => this.setState({ dockerfiles: [] })} />
-          <CloseButton onClick={() => this.setState({ dockerfiles: [] })}>
-            <CloseButtonImg src={close} />
-          </CloseButton>
-          <Label>
-            Porter has detected at least one Dockerfile in this folder. Would
-            you like to use an existing Dockerfile?
-          </Label>
-          <DockerfileList>
-            {this.state.dockerfiles.map((dockerfile: string, i: number) => {
-              return (
-                <Row
-                  key={i}
-                  onClick={() =>
-                    this.props.setDockerfilePath(
-                      `${this.state.currentDir || "."}/${dockerfile}`
-                    )
-                  }
-                  isLast={this.state.dockerfiles.length - 1 === i}
-                >
-                  <Indicator selected={false}></Indicator>
-                  {dockerfile}
-                </Row>
-              );
-            })}
-          </DockerfileList>
-          <ConfirmButton
-            onClick={() => {
-              this.props.setFolderPath(this.state.currentDir || "./");
-              if (
-                this.state.processes &&
-                Object.keys(this.state.processes).length > 0
-              ) {
-                this.props.setProcfilePath("./Procfile");
-              }
-            }}
-          >
-            No, I don't want to use a Dockerfile
-          </ConfirmButton>
-        </Overlay>
-      );
-    }
-    if (
-      this.props.dockerfilePath &&
-      !this.props.folderPath &&
-      this.state.showingBuildContextPrompt
-    ) {
-      return (
-        <Overlay>
-          <BgOverlay onClick={() => this.props.setDockerfilePath("")} />
-          <CloseButton
-            onClick={() =>
-              this.props.setFolderPath(this.state.currentDir || "./")
-            }
-          >
-            <CloseButtonImg src={close} />
-          </CloseButton>
-          <Label>
-            Would you like to set the Docker build context to a different
-            directory?
-          </Label>
-          <MultiSelectRow>
-            <ConfirmButton
-              onClick={() => {
-                this.setState({ showingBuildContextPrompt: false });
-                this.setSubdirectory("");
-              }}
-            >
-              Yes
-            </ConfirmButton>
-            <ConfirmButton
-              onClick={() =>
-                this.props.setFolderPath(this.state.currentDir || "./")
-              }
-            >
-              No
-            </ConfirmButton>
-          </MultiSelectRow>
-        </Overlay>
-      );
+    try {
+      const { data } = await detectBuildpacks();
+      setAutoBuildpack(data);
+    } catch (err) {
+      console.log(err);
+      setAutoBuildpack({
+        valid: false,
+      });
     }
   };
 
-  render() {
-    return (
-      <>
-        {this.renderContentList()}
-        {this.state.autoBuildpack ? (
-          <Banner>
-            <i className="material-icons">info</i>{" "}
-            <p>
-              <b>{this.state.autoBuildpack.name}</b> buildpack was{" "}
-              <a
-                href="https://docs.porter.run/deploying-applications/deploying-from-github/selecting-application-and-build-method#customizing-buildpacks"
-                target="_blank"
-              >
-                detected automatically
-              </a>
-              . Alternatively, select an application folder below:
-            </p>
-          </Banner>
-        ) : (
-          <>
-            <Spacer y={1} />
-            <AdvancedBuildSettings />
-          </>
-        )}
-      </>
-    );
-  }
-}
+  // const renderJumpToParent = () => {
+  //   if (this.state.currentDir !== "") {
+  //     let splits = this.state.currentDir.split("/");
+  //     let subdir = "";
+  //     if (splits.length !== 1) {
+  //       subdir = this.state.currentDir.replace(splits[splits.length - 1], "");
+  //       if (subdir.charAt(subdir.length - 1) === "/") {
+  //         subdir = subdir.slice(0, subdir.length - 1);
+  //       }
+  //     }
+
+  //     return (
+  //       <Item lastItem={false} onClick={() => this.setSubdirectory(subdir)}>
+  //         <BackLabel>..</BackLabel>
+  //       </Item>
+  //     );
+  //   }
+
+  //   return (
+  //     <FileItem lastItem={false}>
+  //       <img src={info} />
+  //       Select{" "}
+  //       {this.props.dockerfilePath
+  //         ? "Docker Build Context"
+  //         : "Application Folder"}
+  //     </FileItem>
+  //   );
+  // };
+
+  // const renderOverlay = () => {
+  //   if (this.props.procfilePath) {
+  //     let processes = this.state.processes
+  //       ? Object.keys(this.state.processes)
+  //       : [];
+  //     if (this.state.processes == null) {
+  //       return (
+  //         <Overlay>
+  //           <BgOverlay>
+  //             <LoadingWrapper>
+  //               <Loading />
+  //             </LoadingWrapper>
+  //           </BgOverlay>
+  //         </Overlay>
+  //       );
+  //     }
+
+  //     if (processes.length == 0) {
+  //       this.props.setProcfilePath("");
+  //     }
+
+  //     return (
+  //       <Overlay>
+  //         <BgOverlay
+  //           onClick={() =>
+  //             this.setState({ dockerfiles: [] }, () => {
+  //               this.props.setFolderPath("");
+  //               this.props.setProcfilePath("");
+  //             })
+  //           }
+  //         />
+  //         <CloseButton
+  //           onClick={() =>
+  //             this.setState({ dockerfiles: [] }, () => {
+  //               this.props.setProcfilePath("");
+  //             })
+  //           }
+  //         >
+  //           <CloseButtonImg src={close} />
+  //         </CloseButton>
+  //         <Label>
+  //           Porter has detected a Procfile in this folder. Which process would
+  //           you like to run?
+  //         </Label>
+  //         <DockerfileList>
+  //           {processes.map((process: string, i: number) => {
+  //             return (
+  //               <Row
+  //                 key={i}
+  //                 onClick={() => {
+  //                   if (
+  //                     !this.props.folderPath ||
+  //                     this.props.folderPath === ""
+  //                   ) {
+  //                     this.props.setFolderPath("./");
+  //                   }
+  //                   this.props.setProcfileProcess(process);
+  //                 }}
+  //                 isLast={processes.length - 1 === i}
+  //               >
+  //                 <Indicator selected={false} />
+  //                 {process}
+  //               </Row>
+  //             );
+  //           })}
+  //         </DockerfileList>
+  //       </Overlay>
+  //     );
+  //   }
+  //   if (this.state.dockerfiles.length > 0 && !this.props.dockerfilePath) {
+  //     return (
+  //       <Overlay>
+  //         <BgOverlay onClick={() => this.setState({ dockerfiles: [] })} />
+  //         <CloseButton onClick={() => this.setState({ dockerfiles: [] })}>
+  //           <CloseButtonImg src={close} />
+  //         </CloseButton>
+  //         <Label>
+  //           Porter has detected at least one Dockerfile in this folder. Would
+  //           you like to use an existing Dockerfile?
+  //         </Label>
+  //         <DockerfileList>
+  //           {this.state.dockerfiles.map((dockerfile: string, i: number) => {
+  //             return (
+  //               <Row
+  //                 key={i}
+  //                 onClick={() =>
+  //                   this.props.setDockerfilePath(
+  //                     `${this.state.currentDir || "."}/${dockerfile}`
+  //                   )
+  //                 }
+  //                 isLast={this.state.dockerfiles.length - 1 === i}
+  //               >
+  //                 <Indicator selected={false}></Indicator>
+  //                 {dockerfile}
+  //               </Row>
+  //             );
+  //           })}
+  //         </DockerfileList>
+  //         <ConfirmButton
+  //           onClick={() => {
+  //             this.props.setFolderPath(this.state.currentDir || "./");
+  //             if (
+  //               this.state.processes &&
+  //               Object.keys(this.state.processes).length > 0
+  //             ) {
+  //               this.props.setProcfilePath("./Procfile");
+  //             }
+  //           }}
+  //         >
+  //           No, I don't want to use a Dockerfile
+  //         </ConfirmButton>
+  //       </Overlay>
+  //     );
+  //   }
+  //   if (
+  //     this.props.dockerfilePath &&
+  //     !this.props.folderPath &&
+  //     this.state.showingBuildContextPrompt
+  //   ) {
+  //     return (
+  //       <Overlay>
+  //         <BgOverlay onClick={() => this.props.setDockerfilePath("")} />
+  //         <CloseButton
+  //           onClick={() =>
+  //             this.props.setFolderPath(this.state.currentDir || "./")
+  //           }
+  //         >
+  //           <CloseButtonImg src={close} />
+  //         </CloseButton>
+  //         <Label>
+  //           Would you like to set the Docker build context to a different
+  //           directory?
+  //         </Label>
+  //         <MultiSelectRow>
+  //           <ConfirmButton
+  //             onClick={() => {
+  //               this.setState({ showingBuildContextPrompt: false });
+  //               this.setSubdirectory("");
+  //             }}
+  //           >
+  //             Yes
+  //           </ConfirmButton>
+  //           <ConfirmButton
+  //             onClick={() =>
+  //               this.props.setFolderPath(this.state.currentDir || "./")
+  //             }
+  //           >
+  //             No
+  //           </ConfirmButton>
+  //         </MultiSelectRow>
+  //       </Overlay>
+  //     );
+  //   }
+  // };
+
+  return (
+    <>
+      {renderContentList()}
+      {props.dockerfilePath == null || props.dockerfilePath == "" ? (
+        <AdvancedBuildSettings
+          setBuildConfig={props.setBuildConfig}
+          autoBuildPack={autoBuildpack}
+          showSettings={false}
+          buildView={"buildpacks"}
+          actionConfig={props.actionConfig}
+          branch={props.branch}
+          folderPath={props.folderPath}
+        />
+      ) : (
+        <></>
+      )}
+    </>
+  );
+};
 
-DetectContentsList.contextType = Context;
+export default DetectContentsList;
 
 const FlexWrapper = styled.div`
   position: absolute;

+ 116 - 171
dashboard/src/main/home/app-dashboard/new-app-flow/AdvancedBuildSettings.tsx

@@ -4,187 +4,133 @@ import Text from "components/porter/Text";
 import Spacer from "components/porter/Spacer";
 import Input from "components/porter/Input";
 import Toggle from "components/porter/Toggle";
-import AnimateHeight from 'react-animate-height';
+import AnimateHeight from "react-animate-height";
 import { DeviconsNameList } from "assets/devicons-name-list";
+import { BuildpackStack } from "components/repo-selector/BuildpackStack";
+import { ActionConfigType } from "shared/types";
 
-interface AdvancedBuildSettingsProps {
+interface AutoBuildpack {
+  name?: string;
+  valid: boolean;
+}
 
+interface AdvancedBuildSettingsProps {
+  autoBuildPack?: AutoBuildpack;
+  buildView: string;
+  showSettings: boolean;
+  actionConfig: ActionConfigType | null;
+  branch: string;
+  folderPath: string;
+  setBuildConfig: (x: any) => void;
 }
 
 type Buildpack = {
-    name: string;
-    buildpack: string;
-    config?: {
-        [key: string]: string;
-    };
+  name: string;
+  buildpack: string;
+  config?: {
+    [key: string]: string;
+  };
 };
 
+const AdvancedBuildSettings: React.FC<AdvancedBuildSettingsProps> = (props) => {
+  const [showSettings, setShowSettings] = useState<boolean>(props.showSettings);
+  const [buildView, setBuildView] = useState<string>(props.buildView);
 
-const AdvancedBuildSettings: React.FC<AdvancedBuildSettingsProps> = ({
-}) => {
-    const [showSettings, setShowSettings] = useState<boolean>(false)
-    const [buildView, setBuildView] = useState<string>('docker')
-
-    const createDockerView = () => {
-        return (
-            <>
-                <Text size={16}>Build with a Dockerfile</Text>
-                <Spacer y={0.5} />
-                <Text color="helper">
-                    Specify your Dockerfile path.
-                </Text>
-                <Spacer y={0.5} />
-                <Input
-                    placeholder="ex: ./Dockerfile"
-                    value=""
-                    width="300px"
-                    setValue={(e) => { }}
-                />
-                <Spacer y={0.5} />
-                <Text color="helper">
-                    Specify your Docker build context.
-                </Text>
-                <Spacer y={0.5} />
-                <Input
-                    placeholder="ex: academic-sophon"
-                    value="./"
-                    width="300px"
-                    setValue={(e) => { }}
-                />
-                <Spacer y={0.5} />
-            </>
-        )
-    }
-
-    const createBuildpackView = () => {
-        return (
-            <>
-                <Text size={16}>Build with buildpacks</Text>
-                <Spacer y={0.5} />
-                <Text color="helper">
-                    Select a builder.
-                </Text>
-                <Spacer y={0.5} />
-                <Input
-                    placeholder="ex: heroku/buildpacks:20"
-                    value=""
-                    width="300px"
-                    setValue={(e) => { }}
-                />
-                <Spacer y={0.5} />
-                <Text color="helper">
-                    The following buildpacks were automatically detected. You can also
-                    manually add/remove buildpacks.
-                </Text>
-                <Spacer y={0.5} />
-                {renderBuildpacksList([{
-                    name: 'Python',
-                    buildpack: 'heroku/python'
-                }], "remove")}
-                <Text color="helper">
-                    Available buildpacks:
-                </Text>
-                <Spacer y={0.5} />
-                {renderBuildpacksList([{
-                    name: 'Ruby',
-                    buildpack: 'heroku/ruby'
-                }], "add")}
-            </>
-        )
-    }
-
-    const renderBuildpacksList = (
-        buildpacks: Buildpack[],
-        action: "remove" | "add"
-    ) => {
-        return (buildpacks?.map((buildpack) => {
-            const [languageName] = buildpack.name?.split("/").reverse();
-
-            const devicon = DeviconsNameList.find(
-                (devicon) => languageName.toLowerCase() === devicon.name
-            );
-
-            const icon = `devicon-${devicon?.name}-plain colored`;
-
-            let disableIcon = false;
-            if (!devicon) {
-                disableIcon = true;
-            }
-
-            return (
-                <StyledCard key={buildpack.name}>
-                    <ContentContainer>
-                        <Icon disableMarginRight={disableIcon} className={icon} />
-                        <EventInformation>
-                            <EventName>{buildpack?.name}</EventName>
-                        </EventInformation>
-                    </ContentContainer>
-                    <ActionContainer>
-                        {action === "add" && (
-                            <ActionButton>
-                                <span className="material-icons-outlined">add</span>
-                            </ActionButton>
-                        )}
-                        {action === "remove" && (
-                            <ActionButton>
-                                <span className="material-icons">delete</span>
-                            </ActionButton>
-                        )}
-                    </ActionContainer>
-                </StyledCard>
-            );
-        }));
-    };
-
+  const createDockerView = () => {
     return (
-        <>
-            <StyledAdvancedBuildSettings
-                showSettings={showSettings}
-                isCurrent={true}
-                onClick={() => {
-                    setShowSettings(!showSettings)
-                }
-                } >
-                <AdvancedBuildTitle>
-                    <i className="material-icons dropdown">arrow_drop_down</i>
-                    Configure advanced build settings (optional)
-                </AdvancedBuildTitle>
-            </StyledAdvancedBuildSettings>
-
-            <AnimateHeight
-                height={showSettings ? 'auto' : 0}
-                duration={1000}
-            >
-                <StyledSourceBox>
-                    <ToggleWrapper>
-                        <Toggle
-                            items={[
-                                { label: 'Docker', value: "docker" },
-                                { label: 'Buildpacks', value: "buildpacks" },
-                            ]}
-                            active={buildView}
-                            setActive={setBuildView}
-                            highlightColor="#8590ff"
-                        />
-                    </ToggleWrapper>
-                    <Spacer y={0.5} />
-                    {buildView === 'docker' ? createDockerView() : createBuildpackView()}
-                </StyledSourceBox>
-            </AnimateHeight>
+      <>
+        <Text size={16}>Build with a Dockerfile</Text>
+        <Spacer y={0.5} />
+        <Text color="helper">Specify your Dockerfile path.</Text>
+        <Spacer y={0.5} />
+        <Input
+          placeholder="ex: ./Dockerfile"
+          value=""
+          width="300px"
+          setValue={(e) => {}}
+        />
+        <Spacer y={0.5} />
+        <Text color="helper">Specify your Docker build context.</Text>
+        <Spacer y={0.5} />
+        <Input
+          placeholder="ex: academic-sophon"
+          value="./"
+          width="300px"
+          setValue={(e) => {}}
+        />
+        <Spacer y={0.5} />
+      </>
+    );
+  };
 
-        </>
+  const createBuildpackView = () => {
+    return (
+      <>
+        <BuildpackStack
+          actionConfig={props.actionConfig}
+          branch={props.branch}
+          folderPath={props.folderPath}
+          onChange={(config) => {
+            props.setBuildConfig(config);
+          }}
+          hide={false}
+        />
+      </>
     );
-}
+  };
+
+  return (
+    <>
+      <StyledAdvancedBuildSettings
+        showSettings={showSettings}
+        isCurrent={true}
+        onClick={() => {
+          setShowSettings(!showSettings);
+        }}
+      >
+        {buildView == "docker" ? (
+          <AdvancedBuildTitle>
+            <i className="material-icons dropdown">arrow_drop_down</i>
+            Dockerfile Detected (configure Dockerfile Settings)
+          </AdvancedBuildTitle>
+        ) : (
+          <AdvancedBuildTitle>
+            <i className="material-icons dropdown">arrow_drop_down</i>
+            Configure Build Pack Settings
+          </AdvancedBuildTitle>
+        )}
+      </StyledAdvancedBuildSettings>
+
+      <AnimateHeight height={showSettings ? "auto" : 0} duration={1000}>
+        <StyledSourceBox>
+          <ToggleWrapper>
+            <Toggle
+              items={[
+                { label: "Docker", value: "docker" },
+                { label: "Buildpacks", value: "buildpacks" },
+              ]}
+              active={buildView}
+              setActive={setBuildView}
+              highlightColor="#8590ff"
+            />
+          </ToggleWrapper>
+          <Spacer y={0.5} />
+          {buildView === "docker" ? createDockerView() : createBuildpackView()}
+        </StyledSourceBox>
+      </AnimateHeight>
+    </>
+  );
+};
 
-export default AdvancedBuildSettings
+export default AdvancedBuildSettings;
 
 const StyledAdvancedBuildSettings = styled.div`
-  color: ${({ showSettings }) => showSettings ? "white" : "#aaaabb"};
+  color: ${({ showSettings }) => (showSettings ? "white" : "#aaaabb")};
   background: #26292e;
   border: 1px solid #494b4f;
   :hover {
     border: 1px solid #7a7b80;
-    color:  white;
+    color: white;
   }
   display: flex;
   justify-content: space-between;
@@ -204,7 +150,7 @@ const StyledAdvancedBuildSettings = styled.div`
     cursor: pointer;
     border-radius: 20px;
     transform: ${(props: { showSettings: boolean; isCurrent: boolean }) =>
-        props.showSettings ? "" : "rotate(-90deg)"};
+      props.showSettings ? "" : "rotate(-90deg)"};
   }
 `;
 
@@ -220,18 +166,17 @@ const StyledSourceBox = styled.div`
   position: relative;
   font-size: 13px;
   border-radius: 5px;
-  background: ${props => props.theme.fg};
+  background: ${(props) => props.theme.fg};
   border: 1px solid #494b4f;
   border-top: 0px;
   border-top-left-radius: 0px;
   border-top-right-radius: 0px;
-
 `;
 
 const ToggleWrapper = styled.div`
   display: flex;
   justify-content: center;
-`
+`;
 
 const StyledCard = styled.div`
   display: flex;
@@ -257,10 +202,10 @@ const Icon = styled.span<{ disableMarginRight: boolean }>`
   font-size: 20px;
   margin-left: 10px;
   ${(props) => {
-        if (!props.disableMarginRight) {
-            return "margin-right: 20px";
-        }
-    }}
+    if (!props.disableMarginRight) {
+      return "margin-right: 20px";
+    }
+  }}
 `;
 
 const EventInformation = styled.div`
@@ -304,4 +249,4 @@ const ActionButton = styled.button`
   > span {
     font-size: 20px;
   }
-`;
+`;

+ 23 - 28
dashboard/src/main/home/app-dashboard/new-app-flow/SourceSettings.tsx

@@ -75,6 +75,7 @@ const SourceSettings: React.FC<Props> = ({
   setProcfilePath,
   folderPath,
   setFolderPath,
+  setBuildConfig,
 }) => {
   const renderGithubSettings = () => {
     return (
@@ -89,12 +90,10 @@ const SourceSettings: React.FC<Props> = ({
           <ActionConfEditorStack
             actionConfig={actionConfig}
             setActionConfig={(actionConfig: ActionConfigType) => {
-              setActionConfig(
-                (currentActionConfig: ActionConfigType) => ({
-                  ...currentActionConfig,
-                  ...actionConfig,
-                })
-              );
+              setActionConfig((currentActionConfig: ActionConfigType) => ({
+                ...currentActionConfig,
+                ...actionConfig,
+              }));
               setImageUrl(actionConfig.image_repo_uri);
             }}
             setBranch={setBranch}
@@ -112,12 +111,10 @@ const SourceSettings: React.FC<Props> = ({
               actionConfig={actionConfig}
               branch={branch}
               setActionConfig={(actionConfig: ActionConfigType) => {
-                setActionConfig(
-                  (currentActionConfig: ActionConfigType) => ({
-                    ...currentActionConfig,
-                    ...actionConfig,
-                  })
-                );
+                setActionConfig((currentActionConfig: ActionConfigType) => ({
+                  ...currentActionConfig,
+                  ...actionConfig,
+                }));
                 setImageUrl(actionConfig.image_repo_uri);
               }}
               setBranch={setBranch}
@@ -148,6 +145,7 @@ const SourceSettings: React.FC<Props> = ({
             setProcfilePath={setProcfilePath}
             setProcfileProcess={setProcfileProcess}
             setFolderPath={setFolderPath}
+            setBuildConfig={setBuildConfig}
           />
         )}
       </>
@@ -174,25 +172,22 @@ const SourceSettings: React.FC<Props> = ({
   };
 
   return (
-      <SourceSettingsContainer>
-        {source && <Spacer y={1} />}
-        <AnimateHeight height={source ? "auto" : 0}>
-          <div>
-            {source === "github" ? (
-              renderGithubSettings()
-            ) : (
-              renderDockerSettings()
-            )}
-          </div>
-        </AnimateHeight>
-      </SourceSettingsContainer>
-  )
+    <SourceSettingsContainer>
+      {source && <Spacer y={1} />}
+      <AnimateHeight height={source ? "auto" : 0}>
+        <div>
+          {source === "github"
+            ? renderGithubSettings()
+            : renderDockerSettings()}
+        </div>
+      </AnimateHeight>
+    </SourceSettingsContainer>
+  );
 };
 
 export default SourceSettings;
 
-const SourceSettingsContainer = styled.div`
-`;
+const SourceSettingsContainer = styled.div``;
 
 const DarkMatter = styled.div<{ antiHeight?: string }>`
   width: 100%;
@@ -211,4 +206,4 @@ const Required = styled.div`
   margin-left: 8px;
   color: #fc4976;
   display: inline-block;
-`;
+`;