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

Merge pull request #686 from porter-dev/0.3.0-launch-flow-revamp

error message on launch flow hotfix
jusrhee 5 лет назад
Родитель
Сommit
6b198b418e

+ 7 - 3
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedJobChart.tsx

@@ -93,15 +93,19 @@ export default class ExpandedJobChart extends Component<PropsType, StateType> {
               currentChart: res.data,
               loading: false,
               imageIsPlaceholder: true,
+              newestImage: image,
             },
             () => {
               this.updateTabs();
             }
           );
         } else {
-          this.setState({ currentChart: res.data, loading: false }, () => {
-            this.updateTabs();
-          });
+          this.setState(
+            { currentChart: res.data, loading: false, newestImage: image },
+            () => {
+              this.updateTabs();
+            }
+          );
         }
       })
       .catch(console.log);

+ 3 - 4
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/Logs.tsx

@@ -103,7 +103,7 @@ export default class Logs extends Component<PropsType, StateType> {
     }
 
     if (status?.phase === "Succeeded") {
-      return "succeeded"
+      return "succeeded";
     }
 
     if (status?.phase === "Failed") {
@@ -168,7 +168,7 @@ export default class Logs extends Component<PropsType, StateType> {
   componentDidMount() {
     let { selectedPod } = this.props;
     let status = this.getPodStatus(selectedPod?.status);
-    console.log("STATUS", selectedPod?.status, status)
+    console.log("STATUS", selectedPod?.status, status);
     if (status == "running" || status == "succeeded") {
       this.setupWebsocket();
       this.scrollToBottom(false);
@@ -193,8 +193,7 @@ export default class Logs extends Component<PropsType, StateType> {
         // logs.push(Anser.ansiToJson("\u001b[33;5;196mEvent Type\u001b[0m \t || \t \u001b[43m\u001b[34m\tReason\t\u001b[0m \t ||\tMessage"))
 
         res.data.items.forEach((evt: any) => {
-          let ansiEvtType =
-            evt.type == "Warning" ? "\u001b[31m" : "\u001b[32m";
+          let ansiEvtType = evt.type == "Warning" ? "\u001b[31m" : "\u001b[32m";
           let ansiLog = Anser.ansiToJson(
             `${ansiEvtType}${evt.type}\u001b[0m \t \u001b[43m\u001b[34m\t${evt.reason} \u001b[0m \t ${evt.message}`
           );

+ 52 - 53
dashboard/src/main/home/launch/Launch.tsx

@@ -156,24 +156,22 @@ export default class Templates extends Component<PropsType, StateType> {
 
     return (
       <TemplateList>
-        {templates.map(
-          (template: PorterTemplate, i: number) => {
-            let { name, icon, description } = template;
-            if (hardcodedNames[name]) {
-              name = hardcodedNames[name];
-            }
-            return (
-              <TemplateBlock
-                key={name}
-                onClick={() => this.setState({ currentTemplate: template })}
-              >
-                {this.renderIcon(icon)}
-                <TemplateTitle>{name}</TemplateTitle>
-                <TemplateDescription>{description}</TemplateDescription>
-              </TemplateBlock>
-            );
+        {templates.map((template: PorterTemplate, i: number) => {
+          let { name, icon, description } = template;
+          if (hardcodedNames[name]) {
+            name = hardcodedNames[name];
           }
-        )}
+          return (
+            <TemplateBlock
+              key={name}
+              onClick={() => this.setState({ currentTemplate: template })}
+            >
+              {this.renderIcon(icon)}
+              <TemplateTitle>{name}</TemplateTitle>
+              <TemplateDescription>{description}</TemplateDescription>
+            </TemplateBlock>
+          );
+        })}
       </TemplateList>
     );
   };
@@ -197,7 +195,7 @@ export default class Templates extends Component<PropsType, StateType> {
     } else {
       return this.renderTemplateList(this.state.addonTemplates);
     }
-  }
+  };
 
   render() {
     if (!this.state.isOnLaunchFlow || !this.state.currentTemplate) {
@@ -212,40 +210,41 @@ export default class Templates extends Component<PropsType, StateType> {
               <i className="material-icons">help_outline</i>
             </a>
           </TitleSection>
-          {
-            this.context.currentCluster ? (
-              <>
-                <TabSelector
-                  options={tabOptions}
-                  currentTab={this.state.currentTab}
-                  setCurrentTab={(value: string) =>
-                    this.setState({
-                      currentTab: value,
-                      currentTemplate: null,
-                    })
-                  }
-                />
-                {this.renderTabContents()}
-              </>
-            ) : (
-              <>
-                <Banner>
-                  <i className="material-icons">error_outline</i>
-                  No cluster connected to this project.
-                </Banner>
-                <StyledStatusPlaceholder>
-                  You need to connect a cluster to use Porter.
-                  <Highlight
-                    onClick={() => {
-                      this.context.setCurrentModal("ClusterInstructionsModal", {});
-                    }}
-                  >
-                    + Connect an existing cluster
-                  </Highlight>
-                </StyledStatusPlaceholder>
-              </>
-            )
-          }
+          {this.context.currentCluster ? (
+            <>
+              <TabSelector
+                options={tabOptions}
+                currentTab={this.state.currentTab}
+                setCurrentTab={(value: string) =>
+                  this.setState({
+                    currentTab: value,
+                    currentTemplate: null,
+                  })
+                }
+              />
+              {this.renderTabContents()}
+            </>
+          ) : (
+            <>
+              <Banner>
+                <i className="material-icons">error_outline</i>
+                No cluster connected to this project.
+              </Banner>
+              <StyledStatusPlaceholder>
+                You need to connect a cluster to use Porter.
+                <Highlight
+                  onClick={() => {
+                    this.context.setCurrentModal(
+                      "ClusterInstructionsModal",
+                      {}
+                    );
+                  }}
+                >
+                  + Connect an existing cluster
+                </Highlight>
+              </StyledStatusPlaceholder>
+            </>
+          )}
         </TemplatesWrapper>
       );
     } else {
@@ -253,7 +252,7 @@ export default class Templates extends Component<PropsType, StateType> {
         <LaunchFlow
           form={this.state.form}
           currentTab={this.state.currentTab}
-          currentTemplate={this.state.currentTemplate} 
+          currentTemplate={this.state.currentTemplate}
           hideLaunchFlow={() => this.setState({ isOnLaunchFlow: false })}
         />
       );

+ 57 - 31
dashboard/src/main/home/launch/launch-flow/LaunchFlow.tsx

@@ -79,7 +79,7 @@ class LaunchFlow extends Component<PropsType, StateType> {
 
   createGHAction = (chartName: string, chartNamespace: string, env?: any) => {
     let { currentProject, currentCluster } = this.context;
-    let { 
+    let {
       actionConfig,
       branch,
       selectedRegistry,
@@ -114,15 +114,20 @@ class LaunchFlow extends Component<PropsType, StateType> {
         }
       )
       .then((res) => console.log(""))
-      .catch((err) => this.setState({
-        saveValuesStatus: `Could not create GitHub Action: ${err}`,
-      }));
+      .catch((err) => {
+        let parsedErr =
+          err?.response?.data?.errors && err.response.data.errors[0];
+        if (parsedErr) {
+          err = parsedErr;
+        }
+        this.setState({
+          saveValuesStatus: `Could not create GitHub Action: ${err}`,
+        });
+      });
   };
 
   onSubmitAddon = (wildcard?: any) => {
-    let {
-      selectedNamespace
-    } = this.state;
+    let { selectedNamespace } = this.state;
     let { currentCluster, currentProject, setCurrentError } = this.context;
     let name =
       this.state.templateName || randomWords({ exactly: 3, join: "-" });
@@ -168,7 +173,14 @@ class LaunchFlow extends Component<PropsType, StateType> {
         });
       })
       .catch((err) => {
-        this.setState({ saveValuesStatus: `Could not deploy template: ${err}` });
+        let parsedErr =
+          err?.response?.data?.errors && err.response.data.errors[0];
+        if (parsedErr) {
+          err = parsedErr;
+        }
+        this.setState({
+          saveValuesStatus: `Could not deploy template: ${err}`,
+        });
         setCurrentError(err.response.data.errors[0]);
         window.analytics.track("Failed to Deploy Add-on", {
           name: this.props.currentTemplate.name,
@@ -181,12 +193,12 @@ class LaunchFlow extends Component<PropsType, StateType> {
 
   onSubmit = async (rawValues: any) => {
     let { currentCluster, currentProject } = this.context;
-    let { 
-      selectedNamespace, 
+    let {
+      selectedNamespace,
       templateName,
-      imageUrl, 
+      imageUrl,
       imageTag,
-      sourceType
+      sourceType,
     } = this.state;
     let name = templateName || randomWords({ exactly: 3, join: "-" });
     this.setState({ saveValuesStatus: "loading" });
@@ -258,7 +270,14 @@ class LaunchFlow extends Component<PropsType, StateType> {
               resolve(res.data?.external_url);
             })
             .catch((err) => {
-              this.setState({ saveValuesStatus: `Could not create subdomain: ${err}` });
+              let parsedErr =
+                err?.response?.data?.errors && err.response.data.errors[0];
+              if (parsedErr) {
+                err = parsedErr;
+              }
+              this.setState({
+                saveValuesStatus: `Could not create subdomain: ${err}`,
+              });
             });
         });
 
@@ -285,7 +304,7 @@ class LaunchFlow extends Component<PropsType, StateType> {
           repo_url: process.env.APPLICATION_CHART_REPO_URL,
         }
       )
-      .then((_: any) => {
+      .then((res: any) => {
         if (sourceType === "repo") {
           let env = rawValues["container.env.normal"];
           console.log(env);
@@ -304,14 +323,22 @@ class LaunchFlow extends Component<PropsType, StateType> {
         });
       })
       .catch((err: any) => {
-        this.setState({ saveValuesStatus: `Could not deploy template: ${err}` });
+        let parsedErr =
+          err?.response?.data?.errors && err.response.data.errors[0];
+        console.log(parsedErr);
+        if (parsedErr) {
+          err = parsedErr;
+        }
+        this.setState({
+          saveValuesStatus: `Could not deploy template: ${err}`,
+        });
       });
   };
 
   renderCurrentPage = () => {
     let { form, currentTab } = this.props;
-    let { 
-      currentPage, 
+    let {
+      currentPage,
       valuesToOverride,
       templateName,
       imageUrl,
@@ -339,29 +366,27 @@ class LaunchFlow extends Component<PropsType, StateType> {
             this.setState({ currentPage: x });
           }}
           setTemplateName={(x: string) => this.setState({ templateName: x })}
-          setValuesToOverride={(x: any) => 
+          setValuesToOverride={(x: any) =>
             this.setState({ valuesToOverride: x })
           }
-
           imageUrl={imageUrl}
           setImageUrl={(x: string) => this.setState({ imageUrl: x })}
           imageTag={imageTag}
           setImageTag={(x: string) => this.setState({ imageTag: x })}
-
           actionConfig={actionConfig}
-          setActionConfig={(x: ActionConfigType) => 
+          setActionConfig={(x: ActionConfigType) =>
             this.setState({ actionConfig: x })
           }
           branch={branch}
           setBranch={(x: string) => this.setState({ branch: x })}
           procfileProcess={procfileProcess}
-          setProcfileProcess={(x: string) => 
+          setProcfileProcess={(x: string) =>
             this.setState({ procfileProcess: x })
           }
           repoType={repoType}
           setRepoType={(x: string) => this.setState({ repoType: x })}
           dockerfilePath={dockerfilePath}
-          setDockerfilePath={(x: string) => 
+          setDockerfilePath={(x: string) =>
             this.setState({ dockerfilePath: x })
           }
           folderPath={folderPath}
@@ -369,7 +394,7 @@ class LaunchFlow extends Component<PropsType, StateType> {
           procfilePath={procfilePath}
           setProcfilePath={(x: string) => this.setState({ procfilePath: x })}
           selectedRegistry={selectedRegistry}
-          setSelectedRegistry={(x: string) => 
+          setSelectedRegistry={(x: string) =>
             this.setState({ selectedRegistry: x })
           }
         />
@@ -382,7 +407,9 @@ class LaunchFlow extends Component<PropsType, StateType> {
         onSubmit={currentTab === "porter" ? this.onSubmit : this.onSubmitAddon}
         saveValuesStatus={saveValuesStatus}
         selectedNamespace={selectedNamespace}
-        setSelectedNamespace={(x: string) => this.setState({ selectedNamespace: x })}
+        setSelectedNamespace={(x: string) =>
+          this.setState({ selectedNamespace: x })
+        }
         templateName={templateName}
         setTemplateName={(x: string) => this.setState({ templateName: x })}
         hasSource={currentTab === "porter"}
@@ -392,7 +419,7 @@ class LaunchFlow extends Component<PropsType, StateType> {
         clearValuesToOverride={() => this.setState({ valuesToOverride: null })}
       />
     );
-  }
+  };
 
   renderIcon = () => {
     let icon = this.props.currentTemplate?.icon;
@@ -417,14 +444,13 @@ class LaunchFlow extends Component<PropsType, StateType> {
     return (
       <StyledLaunchFlow>
         <TitleSection>
-          <i
-            className="material-icons"
-            onClick={this.props.hideLaunchFlow}
-          >
+          <i className="material-icons" onClick={this.props.hideLaunchFlow}>
             keyboard_backspace
           </i>
           {this.renderIcon()}
-          <Title>New {name} {currentTab === "porter" ? null : "Instance"}</Title>
+          <Title>
+            New {name} {currentTab === "porter" ? null : "Instance"}
+          </Title>
         </TitleSection>
         {this.renderCurrentPage()}
         <Br />

+ 13 - 22
dashboard/src/main/home/launch/launch-flow/SettingsPage.tsx

@@ -115,14 +115,14 @@ export default class SettingsPage extends Component<PropsType, StateType> {
   };
 
   renderSettingsRegion = () => {
-    let {
-      saveValuesStatus,
-      selectedNamespace,
-      onSubmit,
-    } = this.props;
+    let { saveValuesStatus, selectedNamespace, onSubmit } = this.props;
 
     if (this.state.currentTab === "") {
-      return <LoadingWrapper><Loading /></LoadingWrapper>;
+      return (
+        <LoadingWrapper>
+          <Loading />
+        </LoadingWrapper>
+      );
     }
     if (this.state.tabOptions.length > 0) {
       let {
@@ -176,12 +176,8 @@ export default class SettingsPage extends Component<PropsType, StateType> {
   };
 
   renderHeaderSection = () => {
-    let {
-      hasSource,
-      templateName,
-      setTemplateName
-    } = this.props;
-    
+    let { hasSource, templateName, setTemplateName } = this.props;
+
     if (hasSource) {
       return (
         <BackButton
@@ -193,7 +189,7 @@ export default class SettingsPage extends Component<PropsType, StateType> {
           <i className="material-icons">first_page</i>
           Source Settings
         </BackButton>
-      )
+      );
     }
 
     return (
@@ -218,17 +214,12 @@ export default class SettingsPage extends Component<PropsType, StateType> {
         </InputWrapper>
       </>
     );
-  }
+  };
 
   render() {
-    let {
-      selectedCluster,
-    } = this.state;
+    let { selectedCluster } = this.state;
 
-    let {
-      selectedNamespace,
-      setSelectedNamespace,
-    } = this.props;
+    let { selectedNamespace, setSelectedNamespace } = this.props;
 
     return (
       <PaddingWrapper>
@@ -413,4 +404,4 @@ const Subtitle = styled.div`
   line-height: 1.6em;
   display: flex;
   align-items: center;
-`;
+`;

+ 19 - 35
dashboard/src/main/home/launch/launch-flow/SourcePage.tsx

@@ -44,8 +44,7 @@ type PropsType = RouteComponentProps & {
   setSelectedRegistry: (x: string) => void;
 };
 
-type StateType = {
-};
+type StateType = {};
 
 const defaultActionConfig: ActionConfigType = {
   git_repo: "",
@@ -80,16 +79,11 @@ class SourcePage extends Component<PropsType, StateType> {
           </Block>
         </BlockList>
       );
-    } 
-    
+    }
+
     // Display image selector
     if (sourceType === "registry") {
-      let { 
-        imageUrl,
-        setImageUrl,
-        imageTag,
-        setImageTag,
-      } = this.props;
+      let { imageUrl, setImageUrl, imageTag, setImageTag } = this.props;
       return (
         <StyledSourceBox>
           <CloseButton
@@ -125,7 +119,7 @@ class SourcePage extends Component<PropsType, StateType> {
     }
 
     // Display repo selector
-    let { 
+    let {
       history,
       setValuesToOverride,
       setImageUrl,
@@ -151,9 +145,7 @@ class SourcePage extends Component<PropsType, StateType> {
         </CloseButton>
         <Subtitle>
           Provide a repo folder to use as source.
-          <Highlight
-            onClick={() => history.push("integrations/repo")}
-          >
+          <Highlight onClick={() => history.push("integrations/repo")}>
             Manage Git repos
           </Highlight>
           <Required>*</Required>
@@ -205,39 +197,28 @@ class SourcePage extends Component<PropsType, StateType> {
   };
 
   checkSourceSelected = () => {
-    let {
-      imageUrl,
-      selectedRegistry,
-    } = this.props;
+    let { imageUrl, selectedRegistry } = this.props;
     return imageUrl || selectedRegistry;
-  }
+  };
 
   // TODO: consolidate status w/ helper at button-level
   getButtonStatus = () => {
-    let {
-      imageUrl,
-      selectedRegistry,
-      imageTag,
-      templateName,
-    } = this.props;
+    let { imageUrl, selectedRegistry, imageTag, templateName } = this.props;
     if (!isAlphanumeric(templateName) && templateName !== "") {
-      return "Name contains illegal characters"
+      return "Name contains illegal characters";
     }
     if (imageUrl || selectedRegistry) {
       return "";
     }
-    return "No source selected"
-  }
+    return "No source selected";
+  };
 
   getButtonHelper = () => {
-    let {
-      imageUrl,
-      imageTag,
-    } = this.props;
+    let { imageUrl, imageTag } = this.props;
     if (imageUrl && !imageTag) {
       return 'Tag "latest" will be used by default';
     }
-  }
+  };
 
   render() {
     let { templateName, setTemplateName, setPage } = this.props;
@@ -271,7 +252,10 @@ class SourcePage extends Component<PropsType, StateType> {
         {this.renderSourceSelector()}
         <Helper>
           Learn more about
-          <Highlight>
+          <Highlight
+            href="https://docs.getporter.dev/docs/add-ons"
+            target="_blank"
+          >
             deploying services to Porter
           </Highlight>
         </Helper>
@@ -448,7 +432,7 @@ const Warning = styled.span`
     props.makeFlush ? "" : "5px"};
 `;
 
-const Highlight = styled.div`
+const Highlight = styled.a`
   color: #8590ff;
   text-decoration: none;
   margin-left: 5px;