Bladeren bron

forgot Environment tab raw boolean value case

jusrhee 5 jaren geleden
bovenliggende
commit
a5ac910b29

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

@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import styled from "styled-components";
 import styled from "styled-components";
 import AceEditor from "react-ace";
 import AceEditor from "react-ace";
 
 
-import "shared/ace-porter-theme"
+import "shared/ace-porter-theme";
 import "ace-builds/src-noconflict/mode-yaml";
 import "ace-builds/src-noconflict/mode-yaml";
 
 
 type PropsType = {
 type PropsType = {

+ 5 - 3
dashboard/src/components/repo-selector/ContentsList.tsx

@@ -213,9 +213,11 @@ export default class ContentsList extends Component<PropsType, StateType> {
   };
   };
 
 
   renderOverlay = () => {
   renderOverlay = () => {
-    console.log(this.props.procfilePath)
+    console.log(this.props.procfilePath);
     if (this.props.procfilePath) {
     if (this.props.procfilePath) {
-      let processes = this.state.processes ? Object.keys(this.state.processes) : [];
+      let processes = this.state.processes
+        ? Object.keys(this.state.processes)
+        : [];
       return (
       return (
         <Overlay>
         <Overlay>
           <BgOverlay
           <BgOverlay
@@ -294,7 +296,7 @@ export default class ContentsList extends Component<PropsType, StateType> {
                 this.state.processes &&
                 this.state.processes &&
                 Object.keys(this.state.processes).length > 0
                 Object.keys(this.state.processes).length > 0
               ) {
               ) {
-                console.log('setting procfile')
+                console.log("setting procfile");
                 this.props.setProcfilePath("./Procfile");
                 this.props.setProcfilePath("./Procfile");
               }
               }
             }}
             }}

+ 52 - 49
dashboard/src/components/values-form/KeyValueArray.tsx

@@ -95,12 +95,11 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
     return (
     return (
       <>
       <>
         {this.state.values.map((entry: any, i: number) => {
         {this.state.values.map((entry: any, i: number) => {
-
           // Preprocess non-string env values set via raw Helm values
           // Preprocess non-string env values set via raw Helm values
           let { value } = entry;
           let { value } = entry;
           if (typeof value === "object") {
           if (typeof value === "object") {
             value = JSON.stringify(value);
             value = JSON.stringify(value);
-          } else if (typeof value === "number") {
+          } else if (typeof value === "number" || typeof value === "boolean") {
             value = value.toString();
             value = value.toString();
           }
           }
 
 
@@ -117,7 +116,7 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
                   let obj = this.valuesToObject();
                   let obj = this.valuesToObject();
                   this.props.setValues(obj);
                   this.props.setValues(obj);
                 }}
                 }}
-                disabled={this.props.disabled || value.includes("PORTERSECRET") }
+                disabled={this.props.disabled || value.includes("PORTERSECRET")}
               />
               />
               <Spacer />
               <Spacer />
               <Input
               <Input
@@ -131,7 +130,7 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
                   let obj = this.valuesToObject();
                   let obj = this.valuesToObject();
                   this.props.setValues(obj);
                   this.props.setValues(obj);
                 }}
                 }}
-                disabled={this.props.disabled || value.includes("PORTERSECRET") }
+                disabled={this.props.disabled || value.includes("PORTERSECRET")}
                 type={value.includes("PORTERSECRET") ? "password" : "text"}
                 type={value.includes("PORTERSECRET") ? "password" : "text"}
               />
               />
               {this.renderDeleteButton(i)}
               {this.renderDeleteButton(i)}
@@ -182,59 +181,64 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
     }
     }
   };
   };
 
 
-    // Parses src into an Object
+  // Parses src into an Object
   parseEnv = (src: any, options: any) => {
   parseEnv = (src: any, options: any) => {
-    const debug = Boolean(options && options.debug)
-    const obj = {} as Record<string, string>
-    const NEWLINE = '\n'
-    const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/
-    const RE_NEWLINES = /\\n/g
-    const NEWLINES_MATCH = /\n|\r|\r\n/
+    const debug = Boolean(options && options.debug);
+    const obj = {} as Record<string, string>;
+    const NEWLINE = "\n";
+    const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/;
+    const RE_NEWLINES = /\\n/g;
+    const NEWLINES_MATCH = /\n|\r|\r\n/;
 
 
     // convert Buffers before splitting into lines and processing
     // convert Buffers before splitting into lines and processing
-    src.toString().split(NEWLINES_MATCH).forEach(function (line: any, idx: any) {
-      // matching "KEY' and 'VAL' in 'KEY=VAL'
-      const keyValueArr = line.match(RE_INI_KEY_VAL)
-      // matched?
-      if (keyValueArr != null) {
-        const key = keyValueArr[1]
-        // default undefined or missing values to empty string
-        let val = (keyValueArr[2] || '')
-        const end = val.length - 1
-        const isDoubleQuoted = val[0] === '"' && val[end] === '"'
-        const isSingleQuoted = val[0] === "'" && val[end] === "'"
-
-        // if single or double quoted, remove quotes
-        if (isSingleQuoted || isDoubleQuoted) {
-          val = val.substring(1, end)
-
-          // if double quoted, expand newlines
-          if (isDoubleQuoted) {
-            val = val.replace(RE_NEWLINES, NEWLINE)
+    src
+      .toString()
+      .split(NEWLINES_MATCH)
+      .forEach(function (line: any, idx: any) {
+        // matching "KEY' and 'VAL' in 'KEY=VAL'
+        const keyValueArr = line.match(RE_INI_KEY_VAL);
+        // matched?
+        if (keyValueArr != null) {
+          const key = keyValueArr[1];
+          // default undefined or missing values to empty string
+          let val = keyValueArr[2] || "";
+          const end = val.length - 1;
+          const isDoubleQuoted = val[0] === '"' && val[end] === '"';
+          const isSingleQuoted = val[0] === "'" && val[end] === "'";
+
+          // if single or double quoted, remove quotes
+          if (isSingleQuoted || isDoubleQuoted) {
+            val = val.substring(1, end);
+
+            // if double quoted, expand newlines
+            if (isDoubleQuoted) {
+              val = val.replace(RE_NEWLINES, NEWLINE);
+            }
+          } else {
+            // remove surrounding whitespace
+            val = val.trim();
           }
           }
-        } else {
-          // remove surrounding whitespace
-          val = val.trim()
-        }
 
 
-        obj[key] = val
-      } else if (debug) {
-        console.log(`did not match key and value when parsing line ${idx + 1}: ${line}`)
-      }
-    })
+          obj[key] = val;
+        } else if (debug) {
+          console.log(
+            `did not match key and value when parsing line ${idx + 1}: ${line}`
+          );
+        }
+      });
 
 
-    return obj
-  }
+    return obj;
+  };
 
 
   readFile = (env: string) => {
   readFile = (env: string) => {
-    let envObj = this.parseEnv(env, null)
+    let envObj = this.parseEnv(env, null);
     let push = true;
     let push = true;
 
 
     for (let key in envObj) {
     for (let key in envObj) {
       for (var i = 0; i < this.state.values.length; i++) {
       for (var i = 0; i < this.state.values.length; i++) {
-        let existingKey = this.state.values[i]["key"]
+        let existingKey = this.state.values[i]["key"];
         if (key === existingKey) {
         if (key === existingKey) {
-          this.state.values[i]["value"] = envObj[key]
+          this.state.values[i]["value"] = envObj[key];
           push = false;
           push = false;
         }
         }
       }
       }
@@ -242,14 +246,13 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
       if (push) {
       if (push) {
         this.state.values.push({ key, value: envObj[key] });
         this.state.values.push({ key, value: envObj[key] });
       }
       }
-
     }
     }
 
 
     this.setState({ values: this.state.values }, () => {
     this.setState({ values: this.state.values }, () => {
       let obj = this.valuesToObject();
       let obj = this.valuesToObject();
       this.props.setValues(obj);
       this.props.setValues(obj);
     });
     });
-  }
+  };
 
 
   render() {
   render() {
     return (
     return (
@@ -281,7 +284,7 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
               )}
               )}
               {this.props.fileUpload && (
               {this.props.fileUpload && (
                 <UploadButton
                 <UploadButton
-                  onClick={()=>{
+                  onClick={() => {
                     this.setState({ showEditorModal: true });
                     this.setState({ showEditorModal: true });
                   }}
                   }}
                 >
                 >
@@ -398,7 +401,7 @@ const HideButton = styled(DeleteButton)`
       color: #ffffff44;
       color: #ffffff44;
     }
     }
   }
   }
-`
+`;
 
 
 const InputWrapper = styled.div`
 const InputWrapper = styled.div`
   display: flex;
   display: flex;
@@ -430,4 +433,4 @@ const Label = styled.div`
 const StyledInputArray = styled.div`
 const StyledInputArray = styled.div`
   margin-bottom: 15px;
   margin-bottom: 15px;
   margin-top: 22px;
   margin-top: 22px;
-`;
+`;

+ 50 - 37
dashboard/src/components/values-form/UploadArea.tsx

@@ -12,60 +12,74 @@ type PropsType = {
 };
 };
 
 
 type StateType = {
 type StateType = {
-    fileName: string;
+  fileName: string;
 };
 };
 
 
 export default class UploadArea extends Component<PropsType, StateType> {
 export default class UploadArea extends Component<PropsType, StateType> {
-    state = {
-        fileName: null as string,
-    }
-    handleChange = (e: any) => {
+  state = {
+    fileName: null as string,
+  };
+  handleChange = (e: any) => {
     this.props.setValue(e.target.value);
     this.props.setValue(e.target.value);
   };
   };
 
 
   readFile = (file: any) => {
   readFile = (file: any) => {
-    const reader = new FileReader()
+    const reader = new FileReader();
     reader.onload = async (e) => {
     reader.onload = async (e) => {
-      let text = (e.target.result)
+      let text = e.target.result;
       this.props.setValue(text);
       this.props.setValue(text);
-    }
-    reader.readAsText(file, 'UTF-8')
+    };
+    reader.readAsText(file, "UTF-8");
     this.setState({ fileName: file.name });
     this.setState({ fileName: file.name });
-  }
+  };
 
 
   render() {
   render() {
     let { label, placeholder } = this.props;
     let { label, placeholder } = this.props;
-    console.log(this.state.fileName)
+    console.log(this.state.fileName);
     if (this.state.fileName) {
     if (this.state.fileName) {
-        placeholder = `Uploaded ${this.state.fileName}`
+      placeholder = `Uploaded ${this.state.fileName}`;
     }
     }
 
 
     return (
     return (
       <StyledUploadArea>
       <StyledUploadArea>
         <Label>
         <Label>
-            {label}
-            <Required>{this.props.isRequired ? " *" : null}</Required>
-        </Label> 
-        <DNDArea 
-        onDragOver={(e: any) => {e.preventDefault()}}
-        onDragEnter={(e: any) => {e.preventDefault()}}
-        onDragLeave={(e: any) => {e.preventDefault()}}
-        onDrop={(e: any) => {
+          {label}
+          <Required>{this.props.isRequired ? " *" : null}</Required>
+        </Label>
+        <DNDArea
+          onDragOver={(e: any) => {
+            e.preventDefault();
+          }}
+          onDragEnter={(e: any) => {
+            e.preventDefault();
+          }}
+          onDragLeave={(e: any) => {
+            e.preventDefault();
+          }}
+          onDrop={(e: any) => {
             e.preventDefault();
             e.preventDefault();
             const files = e.dataTransfer.files;
             const files = e.dataTransfer.files;
-            this.readFile(files[0])
-        }}
-        onClick={() => {
+            this.readFile(files[0]);
+          }}
+          onClick={() => {
             document.getElementById("file").click();
             document.getElementById("file").click();
-        }}>
-        <input id='file' hidden type="file" accept=".json" onChange={(event) => {
-            event.preventDefault();
-            this.readFile(event.target.files[0]);
-            event.currentTarget.value = null
-        }}/>
-        <Message>
-            <img src={upload} style={{ marginRight: "6px", height: "16px"}} /> {placeholder}
-        </Message>
+          }}
+        >
+          <input
+            id="file"
+            hidden
+            type="file"
+            accept=".json"
+            onChange={(event) => {
+              event.preventDefault();
+              this.readFile(event.target.files[0]);
+              event.currentTarget.value = null;
+            }}
+          />
+          <Message>
+            <img src={upload} style={{ marginRight: "6px", height: "16px" }} />{" "}
+            {placeholder}
+          </Message>
         </DNDArea>
         </DNDArea>
       </StyledUploadArea>
       </StyledUploadArea>
     );
     );
@@ -73,10 +87,10 @@ export default class UploadArea extends Component<PropsType, StateType> {
 }
 }
 
 
 const Message = styled.div`
 const Message = styled.div`
-    display: flex;
-    align-items: center;
-    vertical-align: middle;
-`
+  display: flex;
+  align-items: center;
+  vertical-align: middle;
+`;
 
 
 const Required = styled.div`
 const Required = styled.div`
   margin-left: 8px;
   margin-left: 8px;
@@ -112,7 +126,6 @@ const Label = styled.div`
   font-family: "Work Sans", sans-serif;
   font-family: "Work Sans", sans-serif;
 `;
 `;
 
 
-
 const StyledUploadArea = styled.div`
 const StyledUploadArea = styled.div`
   margin-top: 20px;
   margin-top: 20px;
 `;
 `;

+ 5 - 5
dashboard/src/main/home/cluster-dashboard/env-groups/CreateEnvGroup.tsx

@@ -53,16 +53,16 @@ export default class CreateEnvGroup extends Component<PropsType, StateType> {
   onSubmit = () => {
   onSubmit = () => {
     this.setState({ submitStatus: "loading" });
     this.setState({ submitStatus: "loading" });
 
 
-    let apiEnvVariables : Record<string, string> = {}
-    let secretEnvVariables : Record<string, string> = {}
+    let apiEnvVariables: Record<string, string> = {};
+    let secretEnvVariables: Record<string, string> = {};
 
 
     this.state.envVariables.forEach((envVar: KeyValueType) => {
     this.state.envVariables.forEach((envVar: KeyValueType) => {
       if (envVar.hidden) {
       if (envVar.hidden) {
-        secretEnvVariables[envVar.key] = envVar.value
+        secretEnvVariables[envVar.key] = envVar.value;
       } else {
       } else {
-        apiEnvVariables[envVar.key] = envVar.value
+        apiEnvVariables[envVar.key] = envVar.value;
       }
       }
-    })
+    });
 
 
     api
     api
       .createConfigMap(
       .createConfigMap(

+ 162 - 144
dashboard/src/main/home/cluster-dashboard/env-groups/EnvGroupArray.tsx

@@ -8,12 +8,12 @@ import upload from "assets/upload.svg";
 import { keysIn } from "lodash";
 import { keysIn } from "lodash";
 
 
 export type KeyValueType = {
 export type KeyValueType = {
-    key: string;
-    value: string;
-    hidden: boolean;
-    locked: boolean;
-    deleted: boolean;
-}
+  key: string;
+  value: string;
+  hidden: boolean;
+  locked: boolean;
+  deleted: boolean;
+};
 
 
 type PropsType = {
 type PropsType = {
   label?: string;
   label?: string;
@@ -40,10 +40,10 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
   };
   };
 
 
   componentDidMount() {
   componentDidMount() {
-      if (!this.props.values) {
-          let _values = [] as KeyValueType[];
-          this.props.setValues(_values)
-      }
+    if (!this.props.values) {
+      let _values = [] as KeyValueType[];
+      this.props.setValues(_values);
+    }
   }
   }
 
 
   renderDeleteButton = (i: number) => {
   renderDeleteButton = (i: number) => {
@@ -51,8 +51,8 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
       return (
       return (
         <DeleteButton
         <DeleteButton
           onClick={() => {
           onClick={() => {
-            let _values = this.props.values
-            _values[i].deleted = true
+            let _values = this.props.values;
+            _values[i].deleted = true;
             this.props.setValues(_values);
             this.props.setValues(_values);
           }}
           }}
         >
         >
@@ -64,20 +64,20 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
 
 
   renderHiddenOption = (hidden: boolean, locked: boolean, i: number) => {
   renderHiddenOption = (hidden: boolean, locked: boolean, i: number) => {
     if (this.props.secretOption) {
     if (this.props.secretOption) {
-      let icon = <i className="material-icons">lock_open</i>
+      let icon = <i className="material-icons">lock_open</i>;
 
 
       if (hidden) {
       if (hidden) {
-        icon = <i className="material-icons">lock</i>
+        icon = <i className="material-icons">lock</i>;
       }
       }
 
 
       return (
       return (
         <HideButton
         <HideButton
           onClick={() => {
           onClick={() => {
-              if (!locked) {
-                let  _values = this.props.values
-                _values[i].hidden = !_values[i].hidden;
-                this.props.setValues(_values)
-              }
+            if (!locked) {
+              let _values = this.props.values;
+              _values[i].hidden = !_values[i].hidden;
+              this.props.setValues(_values);
+            }
           }}
           }}
           disabled={locked}
           disabled={locked}
         >
         >
@@ -91,38 +91,38 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
     return (
     return (
       <>
       <>
         {this.props.values.map((entry: KeyValueType, i: number) => {
         {this.props.values.map((entry: KeyValueType, i: number) => {
-            if (!entry.deleted) {
-                return (
-                    <InputWrapper key={i}>
-                      <Input
-                        placeholder="ex: key"
-                        width="270px"
-                        value={entry.key}
-                        onChange={(e: any) => {
-                          let _values = this.props.values
-                          _values[i].key = e.target.value;
-                          this.props.setValues(_values);
-                        }}
-                        disabled={this.props.disabled || entry.locked}
-                      />
-                      <Spacer />
-                      <Input
-                        placeholder="ex: value"
-                        width="270px"
-                        value={entry.value}
-                        onChange={(e: any) => {
-                          let _values = this.props.values
-                          _values[i].value = e.target.value;
-                          this.props.setValues(_values);
-                        }}
-                        disabled={this.props.disabled || entry.locked}
-                        type={entry.hidden ? "password" : "text"}
-                      />
-                      {this.renderHiddenOption(entry.hidden, entry.locked, i)}
-                      {this.renderDeleteButton(i)}
-                    </InputWrapper>
-                  );
-            }
+          if (!entry.deleted) {
+            return (
+              <InputWrapper key={i}>
+                <Input
+                  placeholder="ex: key"
+                  width="270px"
+                  value={entry.key}
+                  onChange={(e: any) => {
+                    let _values = this.props.values;
+                    _values[i].key = e.target.value;
+                    this.props.setValues(_values);
+                  }}
+                  disabled={this.props.disabled || entry.locked}
+                />
+                <Spacer />
+                <Input
+                  placeholder="ex: value"
+                  width="270px"
+                  value={entry.value}
+                  onChange={(e: any) => {
+                    let _values = this.props.values;
+                    _values[i].value = e.target.value;
+                    this.props.setValues(_values);
+                  }}
+                  disabled={this.props.disabled || entry.locked}
+                  type={entry.hidden ? "password" : "text"}
+                />
+                {this.renderHiddenOption(entry.hidden, entry.locked, i)}
+                {this.renderDeleteButton(i)}
+              </InputWrapper>
+            );
+          }
         })}
         })}
       </>
       </>
     );
     );
@@ -145,121 +145,137 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
     }
     }
   };
   };
 
 
-    // Parses src into an Object
+  // Parses src into an Object
   parseEnv = (src: any, options: any) => {
   parseEnv = (src: any, options: any) => {
-    const debug = Boolean(options && options.debug)
-    const obj = {} as Record<string, string>
-    const NEWLINE = '\n'
-    const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/
-    const RE_NEWLINES = /\\n/g
-    const NEWLINES_MATCH = /\n|\r|\r\n/
+    const debug = Boolean(options && options.debug);
+    const obj = {} as Record<string, string>;
+    const NEWLINE = "\n";
+    const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/;
+    const RE_NEWLINES = /\\n/g;
+    const NEWLINES_MATCH = /\n|\r|\r\n/;
 
 
     // convert Buffers before splitting into lines and processing
     // convert Buffers before splitting into lines and processing
-    src.toString().split(NEWLINES_MATCH).forEach(function (line: any, idx: any) {
-      // matching "KEY' and 'VAL' in 'KEY=VAL'
-      const keyValueArr = line.match(RE_INI_KEY_VAL)
-      // matched?
-      if (keyValueArr != null) {
-        const key = keyValueArr[1]
-        // default undefined or missing values to empty string
-        let val = (keyValueArr[2] || '')
-        const end = val.length - 1
-        const isDoubleQuoted = val[0] === '"' && val[end] === '"'
-        const isSingleQuoted = val[0] === "'" && val[end] === "'"
-
-        // if single or double quoted, remove quotes
-        if (isSingleQuoted || isDoubleQuoted) {
-          val = val.substring(1, end)
-
-          // if double quoted, expand newlines
-          if (isDoubleQuoted) {
-            val = val.replace(RE_NEWLINES, NEWLINE)
+    src
+      .toString()
+      .split(NEWLINES_MATCH)
+      .forEach(function (line: any, idx: any) {
+        // matching "KEY' and 'VAL' in 'KEY=VAL'
+        const keyValueArr = line.match(RE_INI_KEY_VAL);
+        // matched?
+        if (keyValueArr != null) {
+          const key = keyValueArr[1];
+          // default undefined or missing values to empty string
+          let val = keyValueArr[2] || "";
+          const end = val.length - 1;
+          const isDoubleQuoted = val[0] === '"' && val[end] === '"';
+          const isSingleQuoted = val[0] === "'" && val[end] === "'";
+
+          // if single or double quoted, remove quotes
+          if (isSingleQuoted || isDoubleQuoted) {
+            val = val.substring(1, end);
+
+            // if double quoted, expand newlines
+            if (isDoubleQuoted) {
+              val = val.replace(RE_NEWLINES, NEWLINE);
+            }
+          } else {
+            // remove surrounding whitespace
+            val = val.trim();
           }
           }
-        } else {
-          // remove surrounding whitespace
-          val = val.trim()
-        }
 
 
-        obj[key] = val
-      } else if (debug) {
-        console.log(`did not match key and value when parsing line ${idx + 1}: ${line}`)
-      }
-    })
+          obj[key] = val;
+        } else if (debug) {
+          console.log(
+            `did not match key and value when parsing line ${idx + 1}: ${line}`
+          );
+        }
+      });
 
 
-    return obj
-  }
+    return obj;
+  };
 
 
   readFile = (env: string) => {
   readFile = (env: string) => {
-    let envObj = this.parseEnv(env, null)
+    let envObj = this.parseEnv(env, null);
     let push = true;
     let push = true;
-    let _values = this.props.values
+    let _values = this.props.values;
 
 
     for (let key in envObj) {
     for (let key in envObj) {
       for (var i = 0; i < this.props.values.length; i++) {
       for (var i = 0; i < this.props.values.length; i++) {
-        let existingKey = this.props.values[i]["key"]
+        let existingKey = this.props.values[i]["key"];
         if (key === existingKey) {
         if (key === existingKey) {
-            _values[i]["value"] = envObj[key]
+          _values[i]["value"] = envObj[key];
           push = false;
           push = false;
         }
         }
       }
       }
 
 
       if (push) {
       if (push) {
-        _values.push({ key, value: envObj[key], hidden: false, locked: false, deleted: false });
+        _values.push({
+          key,
+          value: envObj[key],
+          hidden: false,
+          locked: false,
+          deleted: false,
+        });
       }
       }
-
     }
     }
 
 
     this.props.setValues(_values);
     this.props.setValues(_values);
-  }
+  };
 
 
   render() {
   render() {
-      if (this.props.values) {
-        return (
-            <>
-              <StyledInputArray>
-                <Label>{this.props.label}</Label>
-                {this.props.values.length === 0 ? <></> : this.renderInputList()}
-                {this.props.disabled ? (
-                  <></>
-                ) : (
-                  <InputWrapper>
-                    <AddRowButton
-                      onClick={() => {
-                        let _values = this.props.values
-                        _values.push({ key: "", value: "", hidden: false, locked: false, deleted: false });
-                        this.props.setValues(_values)
-                      }}
-                    >
-                      <i className="material-icons">add</i> Add Row
-                    </AddRowButton>
-                    <Spacer />
-                    {this.props.namespace && this.props.envLoader && (
-                      <LoadButton
-                        onClick={() =>
-                          this.setState({ showEnvModal: !this.state.showEnvModal })
-                        }
-                      >
-                        <img src={sliders} /> Load from Env Group
-                      </LoadButton>
-                    )}
-                    {this.props.fileUpload && (
-                      <UploadButton
-                        onClick={()=>{
-                          this.setState({ showEditorModal: true });
-                        }}
-                      >
-                        <img src={upload} /> Copy from File
-                      </UploadButton>
-                    )}
-                  </InputWrapper>
+    if (this.props.values) {
+      return (
+        <>
+          <StyledInputArray>
+            <Label>{this.props.label}</Label>
+            {this.props.values.length === 0 ? <></> : this.renderInputList()}
+            {this.props.disabled ? (
+              <></>
+            ) : (
+              <InputWrapper>
+                <AddRowButton
+                  onClick={() => {
+                    let _values = this.props.values;
+                    _values.push({
+                      key: "",
+                      value: "",
+                      hidden: false,
+                      locked: false,
+                      deleted: false,
+                    });
+                    this.props.setValues(_values);
+                  }}
+                >
+                  <i className="material-icons">add</i> Add Row
+                </AddRowButton>
+                <Spacer />
+                {this.props.namespace && this.props.envLoader && (
+                  <LoadButton
+                    onClick={() =>
+                      this.setState({ showEnvModal: !this.state.showEnvModal })
+                    }
+                  >
+                    <img src={sliders} /> Load from Env Group
+                  </LoadButton>
                 )}
                 )}
-              </StyledInputArray>
-              {this.renderEditorModal()}
-            </>
-          );
-      }
+                {this.props.fileUpload && (
+                  <UploadButton
+                    onClick={() => {
+                      this.setState({ showEditorModal: true });
+                    }}
+                  >
+                    <img src={upload} /> Copy from File
+                  </UploadButton>
+                )}
+              </InputWrapper>
+            )}
+          </StyledInputArray>
+          {this.renderEditorModal()}
+        </>
+      );
+    }
 
 
-      return null
+    return null;
   }
   }
 }
 }
 
 
@@ -358,12 +374,14 @@ const HideButton = styled(DeleteButton)`
   margin-top: -5px;
   margin-top: -5px;
   > i {
   > i {
     font-size: 19px;
     font-size: 19px;
-    cursor: ${(props : {disabled: boolean}) => props.disabled ? "default" : "pointer"};
+    cursor: ${(props: { disabled: boolean }) =>
+      props.disabled ? "default" : "pointer"};
     :hover {
     :hover {
-        color: ${(props : {disabled: boolean}) => props.disabled ? "#ffffff44" : "#ffffff88"};
-      }
+      color: ${(props: { disabled: boolean }) =>
+        props.disabled ? "#ffffff44" : "#ffffff88"};
+    }
   }
   }
-`
+`;
 
 
 const InputWrapper = styled.div`
 const InputWrapper = styled.div`
   display: flex;
   display: flex;

+ 11 - 11
dashboard/src/main/home/cluster-dashboard/env-groups/ExpandedEnvGroup.tsx

@@ -50,8 +50,8 @@ export default class ExpandedEnvGroup extends Component<PropsType, StateType> {
 
 
   componentDidMount() {
   componentDidMount() {
     // parse env group props into values type
     // parse env group props into values type
-    let envVariables = [] as KeyValueType[]
-    let envGroupData = this.props.envGroup.data
+    let envVariables = [] as KeyValueType[];
+    let envGroupData = this.props.envGroup.data;
 
 
     for (const key in envGroupData) {
     for (const key in envGroupData) {
       envVariables.push({
       envVariables.push({
@@ -60,10 +60,10 @@ export default class ExpandedEnvGroup extends Component<PropsType, StateType> {
         hidden: envGroupData[key].includes("PORTERSECRET"),
         hidden: envGroupData[key].includes("PORTERSECRET"),
         locked: envGroupData[key].includes("PORTERSECRET"),
         locked: envGroupData[key].includes("PORTERSECRET"),
         deleted: false,
         deleted: false,
-      })
+      });
     }
     }
 
 
-    this.setState({ envVariables })
+    this.setState({ envVariables });
   }
   }
 
 
   handleUpdateValues = () => {
   handleUpdateValues = () => {
@@ -71,24 +71,24 @@ export default class ExpandedEnvGroup extends Component<PropsType, StateType> {
     let name = envGroup.metadata.name;
     let name = envGroup.metadata.name;
     let namespace = envGroup.metadata.namespace;
     let namespace = envGroup.metadata.namespace;
 
 
-    let apiEnvVariables : Record<string, string> = {}
-    let secretEnvVariables : Record<string, string> = {}
+    let apiEnvVariables: Record<string, string> = {};
+    let secretEnvVariables: Record<string, string> = {};
 
 
     this.state.envVariables.forEach((envVar: KeyValueType) => {
     this.state.envVariables.forEach((envVar: KeyValueType) => {
       if (envVar.hidden) {
       if (envVar.hidden) {
         if (envVar.deleted) {
         if (envVar.deleted) {
-          secretEnvVariables[envVar.key] = null
+          secretEnvVariables[envVar.key] = null;
         } else if (envVar.value.includes("PORTERSECRET")) {
         } else if (envVar.value.includes("PORTERSECRET")) {
-          secretEnvVariables[envVar.key] = envVar.value
+          secretEnvVariables[envVar.key] = envVar.value;
         }
         }
       } else {
       } else {
         if (envVar.deleted) {
         if (envVar.deleted) {
-          apiEnvVariables[envVar.key] = null
+          apiEnvVariables[envVar.key] = null;
         } else {
         } else {
-          apiEnvVariables[envVar.key] = envVar.value
+          apiEnvVariables[envVar.key] = envVar.value;
         }
         }
       }
       }
-    })
+    });
 
 
     this.setState({ saveValuesStatus: "loading" });
     this.setState({ saveValuesStatus: "loading" });
     api
     api

+ 10 - 7
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChart.tsx

@@ -98,7 +98,10 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
         }
         }
       )
       )
       .then((res) => {
       .then((res) => {
-        this.updateComponents({ currentChart: res.data, loading: false }, res.data);
+        this.updateComponents(
+          { currentChart: res.data, loading: false },
+          res.data
+        );
         // // if the current tab is manifests or chart overview, update components as well
         // // if the current tab is manifests or chart overview, update components as well
         // if (this.state.currentTab == "graph" || this.state.currentTab == "list") {
         // if (this.state.currentTab == "graph" || this.state.currentTab == "list") {
         //   this.updateComponents({ currentChart: res.data, loading: false }, currentChart);
         //   this.updateComponents({ currentChart: res.data, loading: false }, currentChart);
@@ -203,7 +206,7 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
     this.setState({ websockets });
     this.setState({ websockets });
   };
   };
 
 
-  updateComponents = (state : any, currentChart : ChartType) => {
+  updateComponents = (state: any, currentChart: ChartType) => {
     let { currentCluster, currentProject } = this.context;
     let { currentCluster, currentProject } = this.context;
 
 
     api
     api
@@ -221,10 +224,10 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
         }
         }
       )
       )
       .then((res) => {
       .then((res) => {
-        let newState = state || {}
+        let newState = state || {};
 
 
-        newState.components = res.data.Objects
-        newState.podSelectors = res.data.PodSelectors
+        newState.components = res.data.Objects;
+        newState.podSelectors = res.data.PodSelectors;
 
 
         this.setState(newState);
         this.setState(newState);
         this.updateTabs();
         this.updateTabs();
@@ -255,7 +258,7 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
 
 
     this.setState({ saveValuesStatus: "loading" });
     this.setState({ saveValuesStatus: "loading" });
     this.refreshChart();
     this.refreshChart();
-    
+
     api
     api
       .upgradeChartValues(
       .upgradeChartValues(
         "<token>",
         "<token>",
@@ -282,7 +285,7 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
         });
         });
       })
       })
       .catch((err) => {
       .catch((err) => {
-        console.log(err)
+        console.log(err);
         this.setState({ saveValuesStatus: "error" });
         this.setState({ saveValuesStatus: "error" });
         window.analytics.track("Failed to Upgrade Chart", {
         window.analytics.track("Failed to Upgrade Chart", {
           chart: this.state.currentChart.name,
           chart: this.state.currentChart.name,

+ 3 - 4
dashboard/src/main/home/cluster-dashboard/expanded-chart/graph/GraphDisplay.tsx

@@ -101,7 +101,7 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
     let graph = localStorage.getItem(
     let graph = localStorage.getItem(
       `charts.${currentChart.name}-${currentChart.version}`
       `charts.${currentChart.name}-${currentChart.version}`
     );
     );
-    
+
     let nodes = [] as NodeType[];
     let nodes = [] as NodeType[];
     let edges = [] as EdgeType[];
     let edges = [] as EdgeType[];
 
 
@@ -146,7 +146,7 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
 
 
   // Live update on rollback/upgrade
   // Live update on rollback/upgrade
   componentDidUpdate(prevProps: PropsType) {
   componentDidUpdate(prevProps: PropsType) {
-    if (!(_.isEqual(prevProps.currentChart, this.props.currentChart))) {
+    if (!_.isEqual(prevProps.currentChart, this.props.currentChart)) {
       this.storeChartGraph(prevProps);
       this.storeChartGraph(prevProps);
       this.getChartGraph();
       this.getChartGraph();
     }
     }
@@ -246,7 +246,6 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
   };
   };
 
 
   storeChartGraph = (props?: PropsType) => {
   storeChartGraph = (props?: PropsType) => {
-
     let useProps = props || this.props;
     let useProps = props || this.props;
 
 
     let { currentChart } = useProps;
     let { currentChart } = useProps;
@@ -565,7 +564,7 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
           isOpen={node === this.state.openedNode}
           isOpen={node === this.state.openedNode}
           // Parameterized to allow setting to null
           // Parameterized to allow setting to null
           setCurrentNode={(node: NodeType) => {
           setCurrentNode={(node: NodeType) => {
-            this.setState({ currentNode: node })
+            this.setState({ currentNode: node });
           }}
           }}
         />
         />
       );
       );

+ 26 - 19
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/Logs.tsx

@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import React, { Component } from "react";
 import styled from "styled-components";
 import styled from "styled-components";
 import { Context } from "shared/Context";
 import { Context } from "shared/Context";
-import * as Anser from 'anser';
+import * as Anser from "anser";
 
 
 type PropsType = {
 type PropsType = {
   selectedPod: any;
   selectedPod: any;
@@ -61,17 +61,21 @@ export default class Logs extends Component<PropsType, StateType> {
     }
     }
 
 
     return this.state.logs.map((log, i) => {
     return this.state.logs.map((log, i) => {
-      return <Log key={i}>
-        {this.state.logs[i].map((ansi, j) => {
-          if (ansi.clearLine) {
-            return null
-          }
-
-          return <LogSpan key={i + "." + j} ansi={ansi}>
-            {ansi.content.replace(/ /g, '\u00a0')}
-          </LogSpan>
-        })}
-      </Log>;
+      return (
+        <Log key={i}>
+          {this.state.logs[i].map((ansi, j) => {
+            if (ansi.clearLine) {
+              return null;
+            }
+
+            return (
+              <LogSpan key={i + "." + j} ansi={ansi}>
+                {ansi.content.replace(/ /g, "\u00a0")}
+              </LogSpan>
+            );
+          })}
+        </Log>
+      );
     });
     });
   };
   };
 
 
@@ -87,10 +91,10 @@ export default class Logs extends Component<PropsType, StateType> {
     this.ws.onopen = () => {};
     this.ws.onopen = () => {};
 
 
     this.ws.onmessage = (evt: MessageEvent) => {
     this.ws.onmessage = (evt: MessageEvent) => {
-      let ansiLog = Anser.ansiToJson(evt.data)
+      let ansiLog = Anser.ansiToJson(evt.data);
 
 
-      let logs = this.state.logs
-      logs.push(ansiLog)
+      let logs = this.state.logs;
+      logs.push(ansiLog);
 
 
       this.setState({ logs: logs }, () => {
       this.setState({ logs: logs }, () => {
         if (this.state.scroll) {
         if (this.state.scroll) {
@@ -262,7 +266,10 @@ const Log = styled.div`
 const LogSpan = styled.span`
 const LogSpan = styled.span`
   font-family: monospace, sans-serif;
   font-family: monospace, sans-serif;
   font-size: 12px;
   font-size: 12px;
-  font-weight: ${(props: { ansi: Anser.AnserJsonEntry }) => props.ansi?.decoration && props.ansi?.decoration == "bold" ? "700" : "400"};
-  color: ${(props: { ansi: Anser.AnserJsonEntry }) => props.ansi?.fg ? `rgb(${props.ansi?.fg})` : "white"};
-  background-color: ${(props: { ansi: Anser.AnserJsonEntry }) => props.ansi?.bg ? `rgb(${props.ansi?.bg})` : "transparent"};
-`
+  font-weight: ${(props: { ansi: Anser.AnserJsonEntry }) =>
+    props.ansi?.decoration && props.ansi?.decoration == "bold" ? "700" : "400"};
+  color: ${(props: { ansi: Anser.AnserJsonEntry }) =>
+    props.ansi?.fg ? `rgb(${props.ansi?.fg})` : "white"};
+  background-color: ${(props: { ansi: Anser.AnserJsonEntry }) =>
+    props.ansi?.bg ? `rgb(${props.ansi?.bg})` : "transparent"};
+`;

+ 13 - 15
dashboard/src/main/home/integrations/create-integration/GCRForm.tsx

@@ -32,14 +32,8 @@ export default class GCRForm extends Component<PropsType, StateType> {
   };
   };
 
 
   isDisabled = (): boolean => {
   isDisabled = (): boolean => {
-    let {
-      serviceAccountKey,
-      credentialsName
-    } = this.state;
-    if (
-      serviceAccountKey === "" ||
-      credentialsName === ""
-    ) {
+    let { serviceAccountKey, credentialsName } = this.state;
+    if (serviceAccountKey === "" || credentialsName === "") {
       return true;
       return true;
     }
     }
     return false;
     return false;
@@ -110,7 +104,11 @@ export default class GCRForm extends Component<PropsType, StateType> {
             height="100%"
             height="100%"
             isRequired={true}
             isRequired={true}
           />
           />
-          <Helper>GCR URI, in the form <CodeBlock>[gcr_domain]/[gcp_project_id]</CodeBlock>. For example, <CodeBlock>gcr.io/skynet-dev-172969</CodeBlock>.</Helper>
+          <Helper>
+            GCR URI, in the form{" "}
+            <CodeBlock>[gcr_domain]/[gcp_project_id]</CodeBlock>. For example,{" "}
+            <CodeBlock>gcr.io/skynet-dev-172969</CodeBlock>.
+          </Helper>
           <InputRow
           <InputRow
             type="text"
             type="text"
             value={this.state.url}
             value={this.state.url}
@@ -146,12 +144,12 @@ const StyledForm = styled.div`
 `;
 `;
 
 
 const CodeBlock = styled.span`
 const CodeBlock = styled.span`
-  display: inline-block; 
+  display: inline-block;
   background-color: #1b1d26;
   background-color: #1b1d26;
-  color: white; 
-  border-radius: 5px; 
+  color: white;
+  border-radius: 5px;
   font-family: monospace;
   font-family: monospace;
-  padding: 2px 3px; 
-  margin-top: -2px; 
+  padding: 2px 3px;
+  margin-top: -2px;
   user-select: text;
   user-select: text;
-`
+`;

+ 1 - 2
dashboard/src/main/home/integrations/create-integration/GKEForm.tsx

@@ -121,7 +121,7 @@ export default class GKEForm extends Component<PropsType, StateType> {
           onClick={this.isDisabled() ? null : this.handleSubmit}
           onClick={this.isDisabled() ? null : this.handleSubmit}
         />
         />
 
 
-              {/* <UploadButton
+        {/* <UploadButton
       onClick={()=>{
       onClick={()=>{
         // document.getElementById("file").click();
         // document.getElementById("file").click();
         this.setState({ showEditorModal: true });
         this.setState({ showEditorModal: true });
@@ -133,7 +133,6 @@ export default class GKEForm extends Component<PropsType, StateType> {
         event.currentTarget.value = null
         event.currentTarget.value = null
       }}/>}
       }}/>}
     </UploadButton> */}
     </UploadButton> */}
-      
       </StyledForm>
       </StyledForm>
     );
     );
   }
   }

+ 1 - 1
dashboard/src/main/home/launch/expanded-template/LaunchTemplate.tsx

@@ -434,7 +434,7 @@ class LaunchTemplate extends Component<PropsType, StateType> {
 
 
           // handle when procfileProcess is already specified
           // handle when procfileProcess is already specified
           if (this.state.procfileProcess) {
           if (this.state.procfileProcess) {
-            metaState["container.command"] = this.state.procfileProcess
+            metaState["container.command"] = this.state.procfileProcess;
           }
           }
 
 
           return this.props.form?.tabs.map((tab: any, i: number) => {
           return this.props.form?.tabs.map((tab: any, i: number) => {

+ 15 - 12
dashboard/src/main/home/modals/EnvEditorModal.tsx

@@ -3,7 +3,7 @@ import styled from "styled-components";
 import close from "assets/close.png";
 import close from "assets/close.png";
 import AceEditor from "react-ace";
 import AceEditor from "react-ace";
 
 
-import "shared/ace-porter-theme"
+import "shared/ace-porter-theme";
 import "ace-builds/src-noconflict/mode-text";
 import "ace-builds/src-noconflict/mode-text";
 
 
 import { Context } from "shared/Context";
 import { Context } from "shared/Context";
@@ -22,7 +22,7 @@ type StateType = {
 };
 };
 
 
 export default class EnvEditorModal extends Component<PropsType, StateType> {
 export default class EnvEditorModal extends Component<PropsType, StateType> {
-    state = {
+  state = {
     error: false,
     error: false,
     buttonStatus: "",
     buttonStatus: "",
     envFile: "",
     envFile: "",
@@ -31,13 +31,13 @@ export default class EnvEditorModal extends Component<PropsType, StateType> {
   aceEditorRef = React.createRef<AceEditor>();
   aceEditorRef = React.createRef<AceEditor>();
 
 
   onSubmit = () => {
   onSubmit = () => {
-    this.props.setEnvVariables(this.state.envFile)
+    this.props.setEnvVariables(this.state.envFile);
     this.props.closeModal();
     this.props.closeModal();
   };
   };
 
 
-  onChange = (e: string) => { 
-    this.setState({envFile: e})
-  }
+  onChange = (e: string) => {
+    this.setState({ envFile: e });
+  };
 
 
   componentDidMount() {}
   componentDidMount() {}
 
 
@@ -49,11 +49,14 @@ export default class EnvEditorModal extends Component<PropsType, StateType> {
         </CloseButton>
         </CloseButton>
 
 
         <ModalTitle>Load from Environment Group</ModalTitle>
         <ModalTitle>Load from Environment Group</ModalTitle>
-        <Subtitle>
-          Copy paste your environment file in .env format:
-        </Subtitle>
-
-        <Editor onSubmit={(e: any) => {e.preventDefault()}} border={true}>
+        <Subtitle>Copy paste your environment file in .env format:</Subtitle>
+
+        <Editor
+          onSubmit={(e: any) => {
+            e.preventDefault();
+          }}
+          border={true}
+        >
           <AceEditor
           <AceEditor
             ref={this.aceEditorRef}
             ref={this.aceEditorRef}
             mode="text"
             mode="text"
@@ -163,4 +166,4 @@ const StyledLoadEnvGroupModal = styled.div`
   overflow: hidden;
   overflow: hidden;
   border-radius: 6px;
   border-radius: 6px;
   background: #202227;
   background: #202227;
-`;
+`;

+ 1 - 1
dashboard/src/main/home/provisioner/GCPFormSection.tsx

@@ -319,7 +319,7 @@ class GCPFormSection extends Component<PropsType, StateType> {
   render() {
   render() {
     let { setSelectedProvisioner } = this.props;
     let { setSelectedProvisioner } = this.props;
     let { gcpRegion, gcpProjectId, gcpKeyData, selectedInfras } = this.state;
     let { gcpRegion, gcpProjectId, gcpKeyData, selectedInfras } = this.state;
-    console.log('gcpkeydata', gcpKeyData)
+    console.log("gcpkeydata", gcpKeyData);
     return (
     return (
       <StyledGCPFormSection>
       <StyledGCPFormSection>
         <FormSection>
         <FormSection>

+ 8 - 4
dashboard/src/shared/ace-porter-theme.js

@@ -1,6 +1,9 @@
-import ace from 'brace';
+import ace from "brace";
 
 
-ace['define']('ace/theme/porter', ['require', 'exports', 'module', 'ace/lib/dom'], (acequire, exports) => {
+ace["define"](
+  "ace/theme/porter",
+  ["require", "exports", "module", "ace/lib/dom"],
+  (acequire, exports) => {
     exports.isDark = true;
     exports.isDark = true;
     exports.cssClass = "ace-porter";
     exports.cssClass = "ace-porter";
     exports.cssText = `.ace-porter, div.ace_content, div.ace_line, div.ace_gutter-cell {\
     exports.cssText = `.ace-porter, div.ace_content, div.ace_line, div.ace_gutter-cell {\
@@ -105,7 +108,8 @@ ace['define']('ace/theme/porter', ['require', 'exports', 'module', 'ace/lib/dom'
     .ace-porter .ace_indent-guide {
     .ace-porter .ace_indent-guide {
     background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLBWV/8PAAK4AYnhiq+xAAAAAElFTkSuQmCC) right repeat-y;
     background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLBWV/8PAAK4AYnhiq+xAAAAAElFTkSuQmCC) right repeat-y;
     }`;
     }`;
-    
+
     var dom = acequire("../lib/dom");
     var dom = acequire("../lib/dom");
     dom.importCssString(exports.cssText, exports.cssClass);
     dom.importCssString(exports.cssText, exports.cssClass);
-});
+  }
+);