Jelajahi Sumber

adding build settings to form

Feroze Mohideen 3 tahun lalu
induk
melakukan
4e902d845b

+ 36 - 30
dashboard/package-lock.json

@@ -5,6 +5,7 @@
   "requires": true,
   "packages": {
     "": {
+      "name": "dashboard",
       "version": "0.1.0",
       "dependencies": {
         "@ironplans/react": "^0.4.0",
@@ -50,6 +51,7 @@
         "random-word-slugs": "^0.1.6",
         "react": "^18.0.0",
         "react-ace": "^8.0.0",
+        "react-animate-height": "^3.1.1",
         "react-color": "^2.19.3",
         "react-datepicker": "^4.8.0",
         "react-dom": "^18.0.0",
@@ -3029,7 +3031,7 @@
       "version": "18.0.28",
       "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
       "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==",
-      "devOptional": true,
+      "dev": true,
       "dependencies": {
         "@types/prop-types": "*",
         "@types/scheduler": "*",
@@ -3142,7 +3144,7 @@
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
       "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==",
-      "devOptional": true
+      "dev": true
     },
     "node_modules/@types/reactcss": {
       "version": "1.2.6",
@@ -10599,6 +10601,18 @@
         "react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0"
       }
     },
+    "node_modules/react-animate-height": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/react-animate-height/-/react-animate-height-3.1.1.tgz",
+      "integrity": "sha512-UkC6+V3ZlCneBRaSM7aUctDJ+PRP6ztcGtxvU7MTeoMMWPhz8BQNaX7QWaZrkzp1ih1G8uZZ+DI9nfLvtD6OdQ==",
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8.0",
+        "react-dom": ">=16.8.0"
+      }
+    },
     "node_modules/react-color": {
       "version": "2.19.3",
       "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz",
@@ -16047,8 +16061,7 @@
     "@icons/material": {
       "version": "0.2.4",
       "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
-      "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==",
-      "requires": {}
+      "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw=="
     },
     "@ironplans/api": {
       "version": "0.4.1",
@@ -16214,8 +16227,7 @@
     "@material-ui/types": {
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
-      "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==",
-      "requires": {}
+      "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A=="
     },
     "@material-ui/utils": {
       "version": "4.11.3",
@@ -16530,8 +16542,7 @@
       "version": "7.2.1",
       "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-7.2.1.tgz",
       "integrity": "sha512-oZ0Ib5I4Z2pUEcoo95cT1cr6slco9WY7yiPpG+RGNkj8YcYgJnM7pXmYmorNOReh8MIGcKSqXyeGjxnr8YiZbA==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "@types/body-parser": {
       "version": "1.19.2",
@@ -16839,7 +16850,7 @@
       "version": "18.0.28",
       "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
       "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==",
-      "devOptional": true,
+      "dev": true,
       "requires": {
         "@types/prop-types": "*",
         "@types/scheduler": "*",
@@ -16850,7 +16861,7 @@
           "version": "3.1.1",
           "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
           "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==",
-          "devOptional": true
+          "dev": true
         }
       }
     },
@@ -17806,15 +17817,13 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
       "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "ajv-keywords": {
       "version": "3.5.2",
       "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
       "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "anser": {
       "version": "2.1.1",
@@ -20639,8 +20648,7 @@
     "goober": {
       "version": "2.1.12",
       "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.12.tgz",
-      "integrity": "sha512-yXHAvO08FU1JgTXX6Zn6sYCUFfB/OJSX8HHjDSgerZHZmFKAb08cykp5LBw5QnmyMcZyPRMqkdyHUSSzge788Q==",
-      "requires": {}
+      "integrity": "sha512-yXHAvO08FU1JgTXX6Zn6sYCUFfB/OJSX8HHjDSgerZHZmFKAb08cykp5LBw5QnmyMcZyPRMqkdyHUSSzge788Q=="
     },
     "good-listener": {
       "version": "1.2.2",
@@ -21026,8 +21034,7 @@
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
       "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "ieee754": {
       "version": "1.2.1",
@@ -21863,8 +21870,7 @@
     "markdown-to-jsx": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.2.0.tgz",
-      "integrity": "sha512-3l4/Bigjm4bEqjCR6Xr+d4DtM1X6vvtGsMGSjJYyep8RjjIvcWtrXBS8Wbfe1/P+atKNMccpsraESIaWVplzVg==",
-      "requires": {}
+      "integrity": "sha512-3l4/Bigjm4bEqjCR6Xr+d4DtM1X6vvtGsMGSjJYyep8RjjIvcWtrXBS8Wbfe1/P+atKNMccpsraESIaWVplzVg=="
     },
     "material-colors": {
       "version": "1.2.6",
@@ -22755,8 +22761,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
       "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "postcss-modules-local-by-default": {
       "version": "4.0.0",
@@ -23045,6 +23050,11 @@
         "prop-types": "^15.7.2"
       }
     },
+    "react-animate-height": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/react-animate-height/-/react-animate-height-3.1.1.tgz",
+      "integrity": "sha512-UkC6+V3ZlCneBRaSM7aUctDJ+PRP6ztcGtxvU7MTeoMMWPhz8BQNaX7QWaZrkzp1ih1G8uZZ+DI9nfLvtD6OdQ=="
+    },
     "react-color": {
       "version": "2.19.3",
       "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz",
@@ -23134,8 +23144,7 @@
     "react-onclickoutside": {
       "version": "6.12.2",
       "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.12.2.tgz",
-      "integrity": "sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA==",
-      "requires": {}
+      "integrity": "sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA=="
     },
     "react-popper": {
       "version": "2.3.0",
@@ -23185,8 +23194,7 @@
     "react-table": {
       "version": "7.8.0",
       "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz",
-      "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==",
-      "requires": {}
+      "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA=="
     },
     "react-transition-group": {
       "version": "4.4.5",
@@ -24966,8 +24974,7 @@
     "use-sync-external-store": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
-      "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
-      "requires": {}
+      "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA=="
     },
     "util": {
       "version": "0.11.1",
@@ -26262,8 +26269,7 @@
       "version": "7.5.9",
       "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
       "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "xtend": {
       "version": "4.0.2",

+ 1 - 0
dashboard/package.json

@@ -46,6 +46,7 @@
     "random-word-slugs": "^0.1.6",
     "react": "^18.0.0",
     "react-ace": "^8.0.0",
+    "react-animate-height": "^3.1.1",
     "react-color": "^2.19.3",
     "react-datepicker": "^4.8.0",
     "react-dom": "^18.0.0",

+ 9 - 4
dashboard/src/components/porter/Toggle.tsx

@@ -5,19 +5,24 @@ type Props = {
   items: any[];
   active: string;
   setActive: (active: string) => void;
+  highlightColor?: string;
 };
 
 const Toggle: React.FC<Props> = ({
   items,
   active,
   setActive,
+  highlightColor,
 }) => {
   return (
     <StyledToggle>
       {items.map((item, index) => (
-        <Item 
+        <Item
           active={item.value === active}
-          onClick={() => setActive(item.value)}
+          onClick={() => {
+            setActive(item.value)
+          }}
+          highlightColor={highlightColor}
         >
           {item.label}
         </Item>
@@ -37,12 +42,12 @@ const StyledToggle = styled.div`
   align-items: center;
 `;
 
-const Item = styled.div<{ active: boolean }>`
+const Item = styled.div<{ active: boolean, highlightColor?: string }>`
   display: flex;
   align-items: center;
   height: 100%;
   cursor: pointer;
   justify-content: center;
   padding: 10px;
-  background: ${props => props.active ? "#ffffff11" : "transparent"};
+  background: ${props => props.active ? props.highlightColor ?? "#ffffff11" : "transparent"};
 `;

+ 191 - 47
dashboard/src/main/home/app-dashboard/new-app-flow/AdvancedBuildSettings.tsx

@@ -4,86 +4,174 @@ 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 { DeviconsNameList } from "assets/devicons-name-list";
 
 interface AdvancedBuildSettingsProps {
 
 }
 
+type Buildpack = {
+    name: string;
+    buildpack: string;
+    config?: {
+        [key: string]: string;
+    };
+};
+
 
 const AdvancedBuildSettings: React.FC<AdvancedBuildSettingsProps> = ({
 }) => {
-    const [showSettings, setShowSettings] = useState(false)
+    const [showSettings, setShowSettings] = useState<boolean>(false)
     const [buildView, setBuildView] = useState<string>('docker')
 
     const createDockerView = () => {
         return (
             <>
-                <Text size={16}>Build settings</Text>
+                <Text size={16}>Build with a Dockerfile</Text>
                 <Spacer y={0.5} />
                 <Text color="helper">
-                    Select your Github repository.
+                    Specify your Dockerfile path.
                 </Text>
-                <Spacer height="20px" />
+                <Spacer y={0.5} />
                 <Input
-                    placeholder="ex: academic-sophon"
+                    placeholder="ex: ./Dockerfile"
                     value=""
                     width="300px"
                     setValue={(e) => { }}
                 />
                 <Spacer y={0.5} />
                 <Text color="helper">
-                    Select your branch.
+                    Specify your Docker build context.
                 </Text>
                 <Spacer y={0.5} />
                 <Input
                     placeholder="ex: academic-sophon"
-                    value=""
+                    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">
-                    Specify your application root path.
+                    Select a builder.
                 </Text>
                 <Spacer y={0.5} />
                 <Input
-                    placeholder="ex: academic-sophon"
-                    value="./"
+                    placeholder="ex: heroku/buildpacks:20"
+                    value=""
                     width="300px"
                     setValue={(e) => { }}
                 />
-                <Spacer y={1} />
+                <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>
+            );
+        }));
+    };
+
     return (
         <>
-            <StyledAdvancedBuildSettings showSettings={showSettings} isCurrent={true} onClick={() => setShowSettings(!showSettings)} >
+            <StyledAdvancedBuildSettings
+                showSettings={showSettings}
+                isCurrent={true}
+                onClick={() => {
+                    setShowSettings(!showSettings)
+                }
+                } >
                 <AdvancedBuildTitle>
-                    <i className="material-icons">arrow_drop_down</i>
-                    Advanced build settings (optional)
+                    <i className="material-icons dropdown">arrow_drop_down</i>
+                    Configure advanced build settings (optional)
                 </AdvancedBuildTitle>
-                <div>
-                    <DetectedBuildMessage>
-                        <i className="material-icons">check</i>
-                        Detected Dockerfile
-                    </DetectedBuildMessage>
-                </div>
             </StyledAdvancedBuildSettings>
-            {showSettings &&
+
+            <AnimateHeight
+                height={showSettings ? 'auto' : 0}
+                duration={1000}
+            >
                 <StyledSourceBox>
                     <ToggleWrapper>
-                        <Toggle items={[
-                            { label: 'Docker', value: "docker" },
-                            { label: 'Buildpacks', value: "buildpacks" },
-                        ]}
+                        <Toggle
+                            items={[
+                                { label: 'Docker', value: "docker" },
+                                { label: 'Buildpacks', value: "buildpacks" },
+                            ]}
                             active={buildView}
                             setActive={setBuildView}
+                            highlightColor="#8590ff"
                         />
                     </ToggleWrapper>
-                    {buildView === 'docker' && createDockerView()}
+                    <Spacer y={0.5} />
+                    {buildView === 'docker' ? createDockerView() : createBuildpackView()}
                 </StyledSourceBox>
-            }
+            </AnimateHeight>
+
         </>
     );
 }
@@ -108,7 +196,7 @@ const StyledAdvancedBuildSettings = styled.div`
   border-bottom-left-radius: ${({ showSettings }) => showSettings && "0px"};
   border-bottom-right-radius: ${({ showSettings }) => showSettings && "0px"};
 
-  > div > i {
+  .dropdown {
     margin-right: 8px;
     font-size: 20px;
     cursor: pointer;
@@ -123,39 +211,95 @@ const AdvancedBuildTitle = styled.div`
   align-items: center;
 `;
 
-const DetectedBuildMessage = styled.div`
-  color: #0f872b;
-  display: flex;
-  align-items: center;
-  padding: 4px 10px;
-  border-radius: 5px;
-  margin-right: 10px;
-
-  > i {
-    margin-right: 6px;
-    font-size: 20px;
-    cursor: pointer;
-    border-radius: 20px;
-    transform: none;
-  }
-`;
-
 const StyledSourceBox = styled.div`
   width: 100%;
   color: #ffffff;
   padding: 14px 35px 20px;
   position: relative;
   font-size: 13px;
-  margin-bottom: 25px;
   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;
+
 `;
 
 const ToggleWrapper = styled.div`
   display: flex;
   justify-content: center;
-`
+`
+
+const StyledCard = styled.div`
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  border: 1px solid #ffffff00;
+  background: #ffffff08;
+  margin-bottom: 5px;
+  border-radius: 8px;
+  padding: 14px;
+  overflow: hidden;
+  height: 60px;
+  font-size: 13px;
+`;
+
+const ContentContainer = styled.div`
+  display: flex;
+  height: 100%;
+  width: 100%;
+  align-items: center;
+`;
+const Icon = styled.span<{ disableMarginRight: boolean }>`
+  font-size: 20px;
+  margin-left: 10px;
+  ${(props) => {
+        if (!props.disableMarginRight) {
+            return "margin-right: 20px";
+        }
+    }}
+`;
+
+const EventInformation = styled.div`
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  height: 100%;
+`;
+
+const EventName = styled.div`
+  font-family: "Work Sans", sans-serif;
+  font-weight: 500;
+  color: #ffffff;
+`;
+
+const ActionContainer = styled.div`
+  display: flex;
+  align-items: center;
+  white-space: nowrap;
+  height: 100%;
+`;
+
+const ActionButton = styled.button`
+  position: relative;
+  border: none;
+  background: none;
+  color: white;
+  padding: 5px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-radius: 50%;
+  cursor: pointer;
+  color: #aaaabb;
+
+  :hover {
+    background: #ffffff11;
+    border: 1px solid #ffffff44;
+  }
+
+  > span {
+    font-size: 20px;
+  }
+`;

+ 14 - 64
dashboard/src/main/home/app-dashboard/new-app-flow/NewAppFlow.tsx

@@ -22,7 +22,7 @@ import { generateSlug } from "random-word-slugs";
 import { RouteComponentProps, withRouter } from "react-router";
 import Error from "components/porter/Error";
 import SourceSelector from "./SourceSelector";
-import AdvancedBuildSettings from "./AdvancedBuildSettings"
+import SourceSettings from "./SourceSettings"
 
 type Props = RouteComponentProps & {
 };
@@ -56,6 +56,7 @@ const NewAppFlow: React.FC<Props> = ({
   const [currentStep, setCurrentStep] = useState<number>(0);
   const [formState, setFormState] = useState<FormState>(INITIAL_STATE);
 
+
   return (
     <StyledConfigureTemplate>
       <Back to="/apps" />
@@ -114,73 +115,22 @@ const NewAppFlow: React.FC<Props> = ({
                 }
               }}
             />
-            {formState.selectedSourceType === "github" ? (
-              <>
-                <Text size={16}>Build settings</Text>
-                <Spacer y={0.5} />
-                <Text color="helper">
-                  Select your Github repository.
-                </Text>
-                <Spacer height="20px" />
-                <Input
-                  placeholder="ex: academic-sophon"
-                  value=""
-                  width="300px"
-                  setValue={(e) => { }}
-                />
-                <Spacer y={0.5} />
-                <Text color="helper">
-                  Select your branch.
-                </Text>
-                <Spacer y={0.5} />
-                <Input
-                  placeholder="ex: academic-sophon"
-                  value=""
-                  width="300px"
-                  setValue={(e) => { }}
-                />
-                <Spacer y={0.5} />
-                <Text color="helper">
-                  Specify your application root path.
-                </Text>
-                <Spacer y={0.5} />
-                <Input
-                  placeholder="ex: academic-sophon"
-                  value="./"
-                  width="300px"
-                  setValue={(e) => { }}
-                />
-                <Spacer y={1} />
-                <AdvancedBuildSettings />
-              </>
-            ) :
-              formState.selectedSourceType === 'docker-registry' ? (
-                <>
-                  <Text size={16}>Registry settings</Text>
-                  <Spacer y={0.5} />
-                  <Text color="helper">
-                    Select your Github repository.
-                  </Text>
-                  <Spacer height="20px" />
-                  <Input
-                    placeholder="ex: academic-sophon"
-                    value=""
-                    width="300px"
-                    setValue={(e) => { }}
-                  />
-                  <Spacer y={0.5} />
-                  <Text color="helper">
-                    Select your branch.
-                  </Text>
-                </>
-              ) : undefined
-            }
+            <SourceSettings source={formState.selectedSourceType} />
+          </>,
+          <>
+            <Text size={16}>Services</Text>
+            <Spacer y={0.5} />
+            <Text color="helper">
+              Add services to this application.
+            </Text>
+            <Spacer y={1} />
+            SOME MORE STUFF HERE
           </>,
           <>
-            <Text size={16}>More configuration</Text>
+            <Text size={16}>Services</Text>
             <Spacer y={0.5} />
             <Text color="helper">
-              Configure settings for this add-on.
+              Add services to this application.
             </Text>
             <Spacer y={1} />
             SOME MORE STUFF HERE

+ 125 - 0
dashboard/src/main/home/app-dashboard/new-app-flow/SourceSettings.tsx

@@ -0,0 +1,125 @@
+import AnimateHeight from "react-animate-height";
+import { SourceType } from "./NewAppFlow";
+import React from "react";
+import Text from "components/porter/Text";
+import Spacer from "components/porter/Spacer";
+import Input from "components/porter/Input";
+import AdvancedBuildSettings from "./AdvancedBuildSettings";
+import styled from "styled-components";
+
+interface SourceSettingsProps {
+    source: SourceType | undefined;
+}
+
+const SourceSettings: React.FC<SourceSettingsProps> = ({
+    source
+}) => {
+    const renderGithubSettings = () => {
+        return (
+            <>
+                <Text size={16}>Build settings</Text>
+                <Spacer y={0.5} />
+                <Text color="helper">
+                    Select your Github repository.
+                </Text>
+                <Spacer y={0.5} />
+                <Input
+                    placeholder="ex: academic-sophon"
+                    value=""
+                    width="300px"
+                    setValue={(e) => { }}
+                />
+                <Spacer y={0.5} />
+                <Text color="helper">
+                    Select your branch.
+                </Text>
+                <Spacer y={0.5} />
+                <Input
+                    placeholder="ex: academic-sophon"
+                    value=""
+                    width="300px"
+                    setValue={(e) => { }}
+                />
+                <Spacer y={0.5} />
+                <Text color="helper">
+                    Specify your application root path.
+                </Text>
+                <Spacer y={0.5} />
+                <Input
+                    placeholder="ex: ./"
+                    value=""
+                    width="300px"
+                    setValue={(e) => { }}
+                />
+                <Spacer y={0.5} />
+                <Text color="helper">
+                    Specify your porter.yaml path. <a>&nbsp;What is this?</a>
+                </Text>
+                <Spacer y={0.5} />
+                <Input
+                    placeholder="ex: ./porter.yaml"
+                    value=""
+                    width="300px"
+                    setValue={(e) => { }}
+                />
+                <Spacer y={1} />
+                <DetectedBuildMessage>
+                    <i className="material-icons">check</i>
+                    Detected Dockerfile at ./Dockerfile
+                </DetectedBuildMessage>
+                <Spacer y={1} />
+                <AdvancedBuildSettings />
+            </>
+        )
+    }
+
+    const renderDockerSettings = () => {
+        return (
+            <>
+                <Text size={16}>Registry settings</Text>
+                <Spacer y={0.5} />
+                <Text color="helper">
+                    Select your Github repository.
+                </Text>
+                <Spacer height="20px" />
+                <Input
+                    placeholder="ex: academic-sophon"
+                    value=""
+                    width="300px"
+                    setValue={(e) => { }}
+                />
+                <Spacer y={0.5} />
+                <Text color="helper">
+                    Select your branch.
+                </Text>
+            </>
+        )
+    }
+
+    return (
+        <AnimateHeight
+            height={source ? 'auto' : 0}
+        >
+            <div >
+                {source === "github" ? renderGithubSettings() : renderDockerSettings()}
+            </div>
+        </AnimateHeight >
+    )
+}
+
+export default SourceSettings;
+
+const DetectedBuildMessage = styled.div`
+  color: #0f872b;
+  display: flex;
+  align-items: center;
+  border-radius: 5px;
+  margin-right: 10px;
+
+  > i {
+    margin-right: 6px;
+    font-size: 20px;
+    border-radius: 20px;
+    transform: none;
+  }
+`;