Преглед изворни кода

Merge pull request #1962 from porter-dev/nico/build-settings-stabilization

[POR-443] [POR-444] Build settings stabilization
Nicolas Frati пре 4 година
родитељ
комит
43e39ba6c5
1 измењених фајлова са 112 додато и 66 уклоњено
  1. 112 66
      dashboard/src/main/home/cluster-dashboard/expanded-chart/BuildSettingsTab.tsx

+ 112 - 66
dashboard/src/main/home/cluster-dashboard/expanded-chart/BuildSettingsTab.tsx

@@ -4,8 +4,8 @@ import KeyValueArray from "components/form-components/KeyValueArray";
 import SelectRow from "components/form-components/SelectRow";
 import SelectRow from "components/form-components/SelectRow";
 import Loading from "components/Loading";
 import Loading from "components/Loading";
 import MultiSaveButton from "components/MultiSaveButton";
 import MultiSaveButton from "components/MultiSaveButton";
-import _, { unionBy } from "lodash";
-import React, { useContext, useEffect, useMemo, useState } from "react";
+import _, { differenceBy, unionBy } from "lodash";
+import React, { useContext, useEffect, useMemo, useRef, useState } from "react";
 import api from "shared/api";
 import api from "shared/api";
 import { Context } from "shared/Context";
 import { Context } from "shared/Context";
 import {
 import {
@@ -81,10 +81,6 @@ const BuildSettingsTab: React.FC<Props> = ({ chart, isPreviousVersion }) => {
       return;
       return;
     }
     }
 
 
-    if (!config.builder.length || !config.buildpacks.length) {
-      throw new Error("You have to select at least one buildpack");
-    }
-
     try {
     try {
       await api.updateBuildConfig<UpdateBuildconfigResponse>(
       await api.updateBuildConfig<UpdateBuildconfigResponse>(
         "<token>",
         "<token>",
@@ -349,6 +345,47 @@ const BuildpackConfigSection: React.FC<{
     []
     []
   );
   );
 
 
+  const state = useRef<null | {
+    [builder: string]: {
+      stack: string;
+      selectedBuildpacks: Buildpack[];
+      availableBuildpacks: Buildpack[];
+    };
+  }>(null);
+
+  const populateState = (
+    builder: string,
+    stack: string,
+    availableBuildpacks: Buildpack[] = [],
+    selectedBuildpacks: Buildpack[] = []
+  ) => {
+    state.current = {
+      ...state.current,
+      [builder]: {
+        stack: stack,
+        availableBuildpacks: availableBuildpacks,
+        selectedBuildpacks: selectedBuildpacks,
+      },
+    };
+  };
+
+  const populateBuildpacks = (
+    userBuildpacks: string[],
+    detectedBuildpacks: Buildpack[]
+  ) => {
+    const customBuildpackFactory = (name: string): Buildpack => ({
+      name: name,
+      buildpack: name,
+      config: null,
+    });
+
+    return userBuildpacks.map(
+      (ub) =>
+        detectedBuildpacks.find((db) => db.buildpack === ub) ||
+        customBuildpackFactory(ub)
+    );
+  };
+
   useEffect(() => {
   useEffect(() => {
     const currentBuildConfig = currentChart?.build_config;
     const currentBuildConfig = currentChart?.build_config;
 
 
@@ -378,38 +415,26 @@ const BuildpackConfigSection: React.FC<{
           builder.builders.find((stack) => stack === currentBuildConfig.builder)
           builder.builders.find((stack) => stack === currentBuildConfig.builder)
         );
         );
 
 
-        const availableBuildpacks = defaultBuilder.others?.filter(
-          (buildpack) => {
-            if (!currentBuildConfig.buildpacks.includes(buildpack.buildpack)) {
-              return true;
-            }
-            return false;
-          }
-        );
-
-        const userAddedBuildpacks = defaultBuilder.others?.filter(
-          (buildpack) => {
-            if (currentBuildConfig.buildpacks.includes(buildpack.buildpack)) {
-              return true;
-            }
-            return false;
-          }
+        const nonSelectedBuilder = builders.find(
+          (builder) =>
+            !builder.builders.find(
+              (stack) => stack === currentBuildConfig.builder
+            )
         );
         );
 
 
-        const customBuildpacks: any = currentBuildConfig.buildpacks
-          .filter(
-            (buildpack) =>
-              URLRegex.test(buildpack) &&
-              !buildpack.includes("gcr.io/paketo-buildpacks")
-          )
-          .map((b) => ({ buildpack: b, name: b }));
+        const fullDetectedBuildpacks = [
+          ...defaultBuilder.detected,
+          ...defaultBuilder.others,
+        ];
 
 
-        console.log(customBuildpacks);
-        console.log(userAddedBuildpacks);
+        const userSelectedBuildpacks = populateBuildpacks(
+          currentBuildConfig.buildpacks,
+          fullDetectedBuildpacks
+        ).filter((b) => b.buildpack);
 
 
-        const detectedBuildpacks = unionBy(
-          [...userAddedBuildpacks, ...customBuildpacks],
-          defaultBuilder.detected,
+        const availableBuildpacks = differenceBy(
+          fullDetectedBuildpacks,
+          userSelectedBuildpacks,
           "buildpack"
           "buildpack"
         );
         );
 
 
@@ -417,15 +442,29 @@ const BuildpackConfigSection: React.FC<{
           return stack === currentBuildConfig.builder;
           return stack === currentBuildConfig.builder;
         });
         });
 
 
+        populateState(
+          defaultBuilder.name.toLowerCase(),
+          defaultStack,
+          userSelectedBuildpacks,
+          availableBuildpacks
+        );
+
+        populateState(
+          nonSelectedBuilder.name.toLowerCase(),
+          nonSelectedBuilder.builders[0],
+          nonSelectedBuilder.others,
+          nonSelectedBuilder.detected
+        );
+
         setBuilders(builders);
         setBuilders(builders);
         setSelectedBuilder(defaultBuilder.name.toLowerCase());
         setSelectedBuilder(defaultBuilder.name.toLowerCase());
 
 
         setStacks(defaultBuilder.builders);
         setStacks(defaultBuilder.builders);
         setSelectedStack(defaultStack);
         setSelectedStack(defaultStack);
-        if (!Array.isArray(detectedBuildpacks)) {
+        if (!Array.isArray(userSelectedBuildpacks)) {
           setSelectedBuildpacks([]);
           setSelectedBuildpacks([]);
         } else {
         } else {
-          setSelectedBuildpacks(detectedBuildpacks);
+          setSelectedBuildpacks(userSelectedBuildpacks);
         }
         }
         if (!Array.isArray(availableBuildpacks)) {
         if (!Array.isArray(availableBuildpacks)) {
           setAvailableBuildpacks([]);
           setAvailableBuildpacks([]);
@@ -449,6 +488,15 @@ const BuildpackConfigSection: React.FC<{
     onChange(buildConfig);
     onChange(buildConfig);
   }, [selectedBuilder, selectedBuildpacks, selectedStack]);
   }, [selectedBuilder, selectedBuildpacks, selectedStack]);
 
 
+  useEffect(() => {
+    populateState(
+      selectedBuilder,
+      selectedStack,
+      availableBuildpacks,
+      selectedBuildpacks
+    );
+  }, [selectedBuilder, selectedBuildpacks, selectedStack, availableBuildpacks]);
+
   const builderOptions = useMemo(() => {
   const builderOptions = useMemo(() => {
     if (!Array.isArray(builders)) {
     if (!Array.isArray(builders)) {
       return;
       return;
@@ -482,27 +530,18 @@ const BuildpackConfigSection: React.FC<{
     const builder = builders.find(
     const builder = builders.find(
       (b) => b.name.toLowerCase() === builderName.toLowerCase()
       (b) => b.name.toLowerCase() === builderName.toLowerCase()
     );
     );
-    const detectedBuildpacks = builder.detected;
-    const availableBuildpacks = builder.others;
-    const defaultStack = builder.builders.find((stack) => {
-      return stack === DEFAULT_HEROKU_STACK || stack === DEFAULT_PAKETO_STACK;
-    });
-    setSelectedBuilder(builderName);
-    setBuilders(builders);
-    setSelectedBuilder(builderName.toLowerCase());
 
 
+    setBuilders(builders);
     setStacks(builder.builders);
     setStacks(builder.builders);
-    setSelectedStack(defaultStack);
 
 
-    if (!Array.isArray(detectedBuildpacks)) {
-      setSelectedBuildpacks([]);
-    } else {
-      setSelectedBuildpacks(detectedBuildpacks);
-    }
-    if (!Array.isArray(availableBuildpacks)) {
-      setAvailableBuildpacks([]);
-    } else {
-      setAvailableBuildpacks(availableBuildpacks);
+    const currState = state.current;
+    if (currState[builderName]) {
+      const stateBuilder = currState[builderName];
+      setSelectedBuilder(builderName);
+      setSelectedStack(stateBuilder.stack);
+      setAvailableBuildpacks(stateBuilder.availableBuildpacks);
+      setSelectedBuildpacks(stateBuilder.selectedBuildpacks);
+      return;
     }
     }
   };
   };
 
 
@@ -510,7 +549,22 @@ const BuildpackConfigSection: React.FC<{
     buildpacks: Buildpack[],
     buildpacks: Buildpack[],
     action: "remove" | "add"
     action: "remove" | "add"
   ) => {
   ) => {
-    return buildpacks?.map((buildpack) => {
+    if (!buildpacks.length && action === "remove") {
+      return (
+        <StyledCard>Buildpacks will be automatically detected.</StyledCard>
+      );
+    }
+
+    if (!buildpacks.length && action === "add") {
+      return (
+        <StyledCard>
+          No additional buildpacks are available. You can add a custom buildpack
+          below.
+        </StyledCard>
+      );
+    }
+
+    return buildpacks?.map((buildpack, i) => {
       const icon = `devicon-${buildpack?.name?.toLowerCase()}-plain colored`;
       const icon = `devicon-${buildpack?.name?.toLowerCase()}-plain colored`;
 
 
       let disableIcon = false;
       let disableIcon = false;
@@ -522,7 +576,7 @@ const BuildpackConfigSection: React.FC<{
       }
       }
 
 
       return (
       return (
-        <StyledCard>
+        <StyledCard key={i}>
           <ContentContainer>
           <ContentContainer>
             <Icon disableMarginRight={disableIcon} className={icon} />
             <Icon disableMarginRight={disableIcon} className={icon} />
             <EventInformation>
             <EventInformation>
@@ -602,7 +656,6 @@ const BuildpackConfigSection: React.FC<{
           setActiveValue={(option) => handleSelectBuilder(option)}
           setActiveValue={(option) => handleSelectBuilder(option)}
           label="Select a builder"
           label="Select a builder"
         />
         />
-
         <SelectRow
         <SelectRow
           value={selectedStack}
           value={selectedStack}
           width="100%"
           width="100%"
@@ -614,20 +667,13 @@ const BuildpackConfigSection: React.FC<{
           The following buildpacks were automatically detected. You can also
           The following buildpacks were automatically detected. You can also
           manually add/remove buildpacks.
           manually add/remove buildpacks.
         </Helper>
         </Helper>
-
-        {!!selectedBuildpacks?.length &&
-          renderBuildpacksList(selectedBuildpacks, "remove")}
-
+        <>{renderBuildpacksList(selectedBuildpacks, "remove")}</>
         <Helper>Available buildpacks:</Helper>
         <Helper>Available buildpacks:</Helper>
-        {!!availableBuildpacks?.length && (
-          <>{renderBuildpacksList(availableBuildpacks, "add")}</>
-        )}
-
+        <>{renderBuildpacksList(availableBuildpacks, "add")}</>
         <Helper>
         <Helper>
           You may also add buildpacks by directly providing their GitHub links
           You may also add buildpacks by directly providing their GitHub links
           or links to ZIP files that contain the buildpack source code.
           or links to ZIP files that contain the buildpack source code.
         </Helper>
         </Helper>
-
         <AddCustomBuildpackForm onAdd={handleAddCustomBuildpack} />
         <AddCustomBuildpackForm onAdd={handleAddCustomBuildpack} />
       </>
       </>
     </BuildpackConfigurationContainer>
     </BuildpackConfigurationContainer>