sunguroku 5 роки тому
батько
коміт
4369eef02d
25 змінених файлів з 445 додано та 363 видалено
  1. 39 39
      .github/workflows/dev.yaml
  2. 39 39
      .github/workflows/production.yaml
  3. 39 39
      .github/workflows/staging.yaml
  4. 2 0
      .prettierignore
  5. 1 1
      dashboard/src/App.tsx
  6. 1 1
      dashboard/src/components/SaveButton.tsx
  7. 1 1
      dashboard/src/components/image-selector/ImageList.tsx
  8. 1 1
      dashboard/src/components/image-selector/ImageSelector.tsx
  9. 1 1
      dashboard/src/components/repo-selector/ContentsList.tsx
  10. 13 13
      dashboard/src/components/repo-selector/RepoList.tsx
  11. 63 6
      dashboard/src/index.html
  12. 3 1
      dashboard/src/index.tsx
  13. 3 3
      dashboard/src/main/home/cluster-dashboard/chart/Chart.tsx
  14. 4 4
      dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChart.tsx
  15. 3 3
      dashboard/src/main/home/cluster-dashboard/expanded-chart/SettingsSection.tsx
  16. 9 8
      dashboard/src/main/home/integrations/IntegrationCategories.tsx
  17. 41 39
      dashboard/src/main/home/integrations/IntegrationList.tsx
  18. 74 77
      dashboard/src/main/home/integrations/IntegrationRow.tsx
  19. 70 58
      dashboard/src/main/home/integrations/Integrations.tsx
  20. 5 2
      dashboard/src/main/home/integrations/create-integration/CreateIntegrationForm.tsx
  21. 5 2
      dashboard/src/main/home/integrations/edit-integration/EditIntegrationForm.tsx
  22. 14 11
      dashboard/src/main/home/launch/expanded-template/LaunchTemplate.tsx
  23. 2 2
      dashboard/src/main/home/provisioner/ProvisionerLogs.tsx
  24. 11 11
      dashboard/src/main/home/sidebar/Sidebar.tsx
  25. 1 1
      dashboard/webpack.config.js

+ 39 - 39
.github/workflows/dev.yaml

@@ -1,46 +1,46 @@
 name: Deploy to production
 on:
   push:
-    branches: 
-    - dev
+    branches:
+      - dev
 jobs:
   deploy:
     runs-on: ubuntu-latest
     steps:
-    - name: Set up Cloud SDK
-      uses: google-github-actions/setup-gcloud@master
-      with:
-        project_id: ${{ secrets.GCP_PROJECT_ID }}
-        service_account_key: ${{ secrets.GCP_SA_KEY }}
-        export_default_credentials: true
-    - name: Install kubectl
-      run: |
-        sudo apt-get install kubectl
-    - name: Log in to gcloud CLI
-      run: gcloud auth configure-docker
-    - name: Checkout
-      uses: actions/checkout@v2.3.4
-    - name: Write Dashboard Environment Variables
-      run: |
-        cat >./dashboard/.env <<EOL
-        NODE_ENV=production
-        API_SERVER=dashboard.dev.getporter.dev
-        FULLSTORY_ORG_ID=${{secrets.FULLSTORY_ORG_ID}}
-        DISCORD_KEY=${{secrets.DISCORD_KEY}}
-        DISCORD_CID=${{secrets.DISCORD_CID}}
-        FEEDBACK_ENDPOINT=${{secrets.FEEDBACK_ENDPOINT}}
-        POSTHOG_API_KEY=${{secrets.POSTHOG_API_KEY}}
-        POSTHOG_HOST=${{secrets.POSTHOG_HOST}}
-        EOL
-    - name: Build
-      run: |
-        DOCKER_BUILDKIT=1 docker build . -t gcr.io/porter-dev-273614/porter:dev -f ./docker/Dockerfile
-    - name: Push
-      run: |
-        docker push gcr.io/porter-dev-273614/porter:dev
-    - name: Deploy to cluster
-      run: |
-        gcloud container clusters get-credentials \
-          dev --region us-central1 --project ${{ secrets.GCP_PROJECT_ID }}
-          
-        kubectl rollout restart deployment/porter
+      - name: Set up Cloud SDK
+        uses: google-github-actions/setup-gcloud@master
+        with:
+          project_id: ${{ secrets.GCP_PROJECT_ID }}
+          service_account_key: ${{ secrets.GCP_SA_KEY }}
+          export_default_credentials: true
+      - name: Install kubectl
+        run: |
+          sudo apt-get install kubectl
+      - name: Log in to gcloud CLI
+        run: gcloud auth configure-docker
+      - name: Checkout
+        uses: actions/checkout@v2.3.4
+      - name: Write Dashboard Environment Variables
+        run: |
+          cat >./dashboard/.env <<EOL
+          NODE_ENV=production
+          API_SERVER=dashboard.dev.getporter.dev
+          FULLSTORY_ORG_ID=${{secrets.FULLSTORY_ORG_ID}}
+          DISCORD_KEY=${{secrets.DISCORD_KEY}}
+          DISCORD_CID=${{secrets.DISCORD_CID}}
+          FEEDBACK_ENDPOINT=${{secrets.FEEDBACK_ENDPOINT}}
+          POSTHOG_API_KEY=${{secrets.POSTHOG_API_KEY}}
+          POSTHOG_HOST=${{secrets.POSTHOG_HOST}}
+          EOL
+      - name: Build
+        run: |
+          DOCKER_BUILDKIT=1 docker build . -t gcr.io/porter-dev-273614/porter:dev -f ./docker/Dockerfile
+      - name: Push
+        run: |
+          docker push gcr.io/porter-dev-273614/porter:dev
+      - name: Deploy to cluster
+        run: |
+          gcloud container clusters get-credentials \
+            dev --region us-central1 --project ${{ secrets.GCP_PROJECT_ID }}
+            
+          kubectl rollout restart deployment/porter

+ 39 - 39
.github/workflows/production.yaml

@@ -1,46 +1,46 @@
 name: Deploy to production
 on:
   push:
-    branches: 
-    - production
+    branches:
+      - production
 jobs:
   deploy:
     runs-on: ubuntu-latest
     steps:
-    - name: Set up Cloud SDK
-      uses: google-github-actions/setup-gcloud@master
-      with:
-        project_id: ${{ secrets.GCP_PROJECT_ID }}
-        service_account_key: ${{ secrets.GCP_SA_KEY }}
-        export_default_credentials: true
-    - name: Install kubectl
-      run: |
-        sudo apt-get install kubectl
-    - name: Log in to gcloud CLI
-      run: gcloud auth configure-docker
-    - name: Checkout
-      uses: actions/checkout@v2.3.4
-    - name: Write Dashboard Environment Variables
-      run: |
-        cat >./dashboard/.env <<EOL
-        NODE_ENV=production
-        API_SERVER=dashboard.getporter.dev
-        FULLSTORY_ORG_ID=${{secrets.FULLSTORY_ORG_ID}}
-        DISCORD_KEY=${{secrets.DISCORD_KEY}}
-        DISCORD_CID=${{secrets.DISCORD_CID}}
-        FEEDBACK_ENDPOINT=${{secrets.FEEDBACK_ENDPOINT}}
-        POSTHOG_API_KEY=${{secrets.POSTHOG_API_KEY}}
-        POSTHOG_HOST=${{secrets.POSTHOG_HOST}}
-        EOL
-    - name: Build
-      run: |
-        DOCKER_BUILDKIT=1 docker build . -t gcr.io/porter-dev-273614/porter:latest -f ./docker/Dockerfile
-    - name: Push
-      run: |
-        docker push gcr.io/porter-dev-273614/porter:latest
-    - name: Deploy to cluster
-      run: |
-        gcloud container clusters get-credentials \
-          production-2 --region us-central1 --project ${{ secrets.GCP_PROJECT_ID }}
-          
-        kubectl rollout restart deployment/porter
+      - name: Set up Cloud SDK
+        uses: google-github-actions/setup-gcloud@master
+        with:
+          project_id: ${{ secrets.GCP_PROJECT_ID }}
+          service_account_key: ${{ secrets.GCP_SA_KEY }}
+          export_default_credentials: true
+      - name: Install kubectl
+        run: |
+          sudo apt-get install kubectl
+      - name: Log in to gcloud CLI
+        run: gcloud auth configure-docker
+      - name: Checkout
+        uses: actions/checkout@v2.3.4
+      - name: Write Dashboard Environment Variables
+        run: |
+          cat >./dashboard/.env <<EOL
+          NODE_ENV=production
+          API_SERVER=dashboard.getporter.dev
+          FULLSTORY_ORG_ID=${{secrets.FULLSTORY_ORG_ID}}
+          DISCORD_KEY=${{secrets.DISCORD_KEY}}
+          DISCORD_CID=${{secrets.DISCORD_CID}}
+          FEEDBACK_ENDPOINT=${{secrets.FEEDBACK_ENDPOINT}}
+          POSTHOG_API_KEY=${{secrets.POSTHOG_API_KEY}}
+          POSTHOG_HOST=${{secrets.POSTHOG_HOST}}
+          EOL
+      - name: Build
+        run: |
+          DOCKER_BUILDKIT=1 docker build . -t gcr.io/porter-dev-273614/porter:latest -f ./docker/Dockerfile
+      - name: Push
+        run: |
+          docker push gcr.io/porter-dev-273614/porter:latest
+      - name: Deploy to cluster
+        run: |
+          gcloud container clusters get-credentials \
+            production-2 --region us-central1 --project ${{ secrets.GCP_PROJECT_ID }}
+            
+          kubectl rollout restart deployment/porter

+ 39 - 39
.github/workflows/staging.yaml

@@ -1,46 +1,46 @@
 name: Build, Push to GCR.
 on:
   push:
-    branches: 
-    - staging
+    branches:
+      - staging
 jobs:
   login-build-push:
     runs-on: ubuntu-latest
     steps:
-    - name: Set up Cloud SDK
-      uses: google-github-actions/setup-gcloud@master
-      with:
-        project_id: ${{ secrets.GCP_PROJECT_ID }}
-        service_account_key: ${{ secrets.GCP_SA_KEY }}
-        export_default_credentials: true
-    - name: Install kubectl
-      run: |
-        sudo apt-get install kubectl
-    - name: Log in to gcloud CLI
-      run: gcloud auth configure-docker
-    - name: Checkout
-      uses: actions/checkout@v2.3.4
-    - name: Write Dashboard Environment Variables
-      run: |
-        cat >./dashboard/.env <<EOL
-        NODE_ENV=production
-        API_SERVER=dashboard.staging.getporter.dev
-        FULLSTORY_ORG_ID=${{secrets.FULLSTORY_ORG_ID}}
-        DISCORD_KEY=${{secrets.DISCORD_KEY}}
-        DISCORD_CID=${{secrets.DISCORD_CID}}
-        FEEDBACK_ENDPOINT=${{secrets.FEEDBACK_ENDPOINT}}
-        POSTHOG_API_KEY=${{secrets.POSTHOG_API_KEY}}
-        POSTHOG_HOST=${{secrets.POSTHOG_HOST}}
-        EOL
-    - name: Build
-      run: |
-        DOCKER_BUILDKIT=1 docker build . -t gcr.io/porter-dev-273614/porter:staging -f ./docker/Dockerfile
-    - name: Push
-      run: |
-        docker push gcr.io/porter-dev-273614/porter:staging
-    - name: Deploy to cluster
-      run: |
-        gcloud container clusters get-credentials \
-          staging --region us-central1 --project ${{ secrets.GCP_PROJECT_ID }}
-          
-        kubectl rollout restart deployment/porter
+      - name: Set up Cloud SDK
+        uses: google-github-actions/setup-gcloud@master
+        with:
+          project_id: ${{ secrets.GCP_PROJECT_ID }}
+          service_account_key: ${{ secrets.GCP_SA_KEY }}
+          export_default_credentials: true
+      - name: Install kubectl
+        run: |
+          sudo apt-get install kubectl
+      - name: Log in to gcloud CLI
+        run: gcloud auth configure-docker
+      - name: Checkout
+        uses: actions/checkout@v2.3.4
+      - name: Write Dashboard Environment Variables
+        run: |
+          cat >./dashboard/.env <<EOL
+          NODE_ENV=production
+          API_SERVER=dashboard.staging.getporter.dev
+          FULLSTORY_ORG_ID=${{secrets.FULLSTORY_ORG_ID}}
+          DISCORD_KEY=${{secrets.DISCORD_KEY}}
+          DISCORD_CID=${{secrets.DISCORD_CID}}
+          FEEDBACK_ENDPOINT=${{secrets.FEEDBACK_ENDPOINT}}
+          POSTHOG_API_KEY=${{secrets.POSTHOG_API_KEY}}
+          POSTHOG_HOST=${{secrets.POSTHOG_HOST}}
+          EOL
+      - name: Build
+        run: |
+          DOCKER_BUILDKIT=1 docker build . -t gcr.io/porter-dev-273614/porter:staging -f ./docker/Dockerfile
+      - name: Push
+        run: |
+          docker push gcr.io/porter-dev-273614/porter:staging
+      - name: Deploy to cluster
+        run: |
+          gcloud container clusters get-credentials \
+            staging --region us-central1 --project ${{ secrets.GCP_PROJECT_ID }}
+            
+          kubectl rollout restart deployment/porter

+ 2 - 0
.prettierignore

@@ -0,0 +1,2 @@
+build
+node_modules

+ 1 - 1
dashboard/src/App.tsx

@@ -7,7 +7,7 @@ type PropsType = {};
 
 type StateType = {};
 
-export default class App extends Component<PropsType, StateType> {  
+export default class App extends Component<PropsType, StateType> {
   render() {
     return (
       <ContextProvider>

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

@@ -86,7 +86,7 @@ const StatusWrapper = styled.div`
     font-size: 18px;
     margin-right: 10px;
     color: ${(props: { successful: boolean }) =>
-    props.successful ? "#4797ff" : "#fcba03"};
+      props.successful ? "#4797ff" : "#fcba03"};
   }
 
   animation: statusFloatIn 0.5s;

+ 1 - 1
dashboard/src/components/image-selector/ImageList.tsx

@@ -288,7 +288,7 @@ const ImageItem = styled.div`
   font-size: 13px;
   border-bottom: 1px solid
     ${(props: { lastItem: boolean; isSelected: boolean }) =>
-    props.lastItem ? "#00000000" : "#606166"};
+      props.lastItem ? "#00000000" : "#606166"};
   color: #ffffff;
   user-select: none;
   align-items: center;

+ 1 - 1
dashboard/src/components/image-selector/ImageSelector.tsx

@@ -298,7 +298,7 @@ const ImageItem = styled.div`
   font-size: 13px;
   border-bottom: 1px solid
     ${(props: { lastItem: boolean; isSelected: boolean }) =>
-    props.lastItem ? "#00000000" : "#606166"};
+      props.lastItem ? "#00000000" : "#606166"};
   color: #ffffff;
   user-select: none;
   align-items: center;

+ 1 - 1
dashboard/src/components/repo-selector/ContentsList.tsx

@@ -34,7 +34,7 @@ export default class ContentsList extends Component<PropsType, StateType> {
     let { actionConfig, setActionConfig } = this.props;
     let updatedConfig = actionConfig;
     let path = x;
-    console.log(fileName)
+    console.log(fileName);
     updatedConfig.dockerfile_path = path;
     setActionConfig(updatedConfig);
     this.updateContents();

+ 13 - 13
dashboard/src/components/repo-selector/RepoList.tsx

@@ -159,26 +159,26 @@ const RepoName = styled.div`
   font-size: 13px;
   border-bottom: 1px solid
     ${(props: { lastItem: boolean; isSelected: boolean; readOnly: boolean }) =>
-    props.lastItem ? "#00000000" : "#606166"};
+      props.lastItem ? "#00000000" : "#606166"};
   color: #ffffff;
   user-select: none;
   align-items: center;
   padding: 10px 0px;
   cursor: ${(props: {
-      lastItem: boolean;
-      isSelected: boolean;
-      readOnly: boolean;
-    }) => (props.readOnly ? "default" : "pointer")};
+    lastItem: boolean;
+    isSelected: boolean;
+    readOnly: boolean;
+  }) => (props.readOnly ? "default" : "pointer")};
   pointer-events: ${(props: {
-      lastItem: boolean;
-      isSelected: boolean;
-      readOnly: boolean;
-    }) => (props.readOnly ? "none" : "auto")};
+    lastItem: boolean;
+    isSelected: boolean;
+    readOnly: boolean;
+  }) => (props.readOnly ? "none" : "auto")};
   background: ${(props: {
-      lastItem: boolean;
-      isSelected: boolean;
-      readOnly: boolean;
-    }) => (props.isSelected ? "#ffffff22" : "#ffffff11")};
+    lastItem: boolean;
+    isSelected: boolean;
+    readOnly: boolean;
+  }) => (props.isSelected ? "#ffffff22" : "#ffffff11")};
   :hover {
     background: #ffffff22;
 

+ 63 - 6
dashboard/src/index.html

@@ -2,14 +2,71 @@
 <html lang="en">
   <head>
     <title>Porter | Dashboard</title>
-    
+
     <script>
-      !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.src="https://cdn.segment.com/analytics.js/v1/" + key + "/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);analytics._loadOptions=e};analytics._writeKey="ZKKaKBrAw9BGE8aF8XDoupd7Fi6ZyN5b";analytics.SNIPPET_VERSION="4.13.2";
-      analytics.load("<%= htmlWebpackPlugin.options.segmentKey %>");
-      analytics.page();
-      }}();
+      !(function () {
+        var analytics = (window.analytics = window.analytics || []);
+        if (!analytics.initialize)
+          if (analytics.invoked)
+            window.console &&
+              console.error &&
+              console.error("Segment snippet included twice.");
+          else {
+            analytics.invoked = !0;
+            analytics.methods = [
+              "trackSubmit",
+              "trackClick",
+              "trackLink",
+              "trackForm",
+              "pageview",
+              "identify",
+              "reset",
+              "group",
+              "track",
+              "ready",
+              "alias",
+              "debug",
+              "page",
+              "once",
+              "off",
+              "on",
+              "addSourceMiddleware",
+              "addIntegrationMiddleware",
+              "setAnonymousId",
+              "addDestinationMiddleware",
+            ];
+            analytics.factory = function (e) {
+              return function () {
+                var t = Array.prototype.slice.call(arguments);
+                t.unshift(e);
+                analytics.push(t);
+                return analytics;
+              };
+            };
+            for (var e = 0; e < analytics.methods.length; e++) {
+              var key = analytics.methods[e];
+              analytics[key] = analytics.factory(key);
+            }
+            analytics.load = function (key, e) {
+              var t = document.createElement("script");
+              t.type = "text/javascript";
+              t.async = !0;
+              t.src =
+                "https://cdn.segment.com/analytics.js/v1/" +
+                key +
+                "/analytics.min.js";
+              var n = document.getElementsByTagName("script")[0];
+              n.parentNode.insertBefore(t, n);
+              analytics._loadOptions = e;
+            };
+            analytics._writeKey = "ZKKaKBrAw9BGE8aF8XDoupd7Fi6ZyN5b";
+            analytics.SNIPPET_VERSION = "4.13.2";
+            analytics.load("<%= htmlWebpackPlugin.options.segmentKey %>");
+            analytics.page();
+          }
+      })();
     </script>
-    
+
     <link rel="icon" href="https://i.ibb.co/Xy0QK6P/dsquare.png" />
     <meta
       name="description"

+ 3 - 1
dashboard/src/index.tsx

@@ -3,7 +3,9 @@ import * as ReactDOM from "react-dom";
 import App from "./App";
 
 declare global {
-  interface Window { analytics: any; }
+  interface Window {
+    analytics: any;
+  }
 }
 
 ReactDOM.render(<App />, document.getElementById("output"));

+ 3 - 3
dashboard/src/main/home/cluster-dashboard/chart/Chart.tsx

@@ -43,9 +43,9 @@ export default class Chart extends Component<PropsType, StateType> {
   };
 
   componentDidMount() {
-    window.analytics.track('Opened Chart', {
-      chart: this.props.chart.chart.metadata.name
-    })
+    window.analytics.track("Opened Chart", {
+      chart: this.props.chart.chart.metadata.name,
+    });
   }
 
   render() {

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

@@ -256,18 +256,18 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
           forceRefreshRevisions: true,
         });
 
-        window.analytics.track('Chart Upgraded', {
+        window.analytics.track("Chart Upgraded", {
           chart: this.props.currentChart.name,
           values: valuesYaml,
-        })
+        });
       })
       .catch((err) => {
         this.setState({ saveValuesStatus: "error" });
-        window.analytics.track('Failed to Upgrade Chart', {
+        window.analytics.track("Failed to Upgrade Chart", {
           chart: this.props.currentChart.name,
           values: valuesYaml,
           error: err,
-        })
+        });
       });
   };
 

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

@@ -113,9 +113,9 @@ export default class SettingsSection extends Component<PropsType, StateType> {
     };
 
     let values = {};
-    let rawValues = this.props.currentChart.config
+    let rawValues = this.props.currentChart.config;
     for (let key in rawValues) {
-      _.set(values, key, rawValues[key])
+      _.set(values, key, rawValues[key]);
     }
 
     // Weave in preexisting values and convert to yaml
@@ -130,7 +130,7 @@ export default class SettingsSection extends Component<PropsType, StateType> {
         {
           namespace: this.props.currentChart.namespace,
           storage: StorageType.Secret,
-          values: valuesYaml
+          values: valuesYaml,
         },
         {
           id: currentProject.id,

+ 9 - 8
dashboard/src/main/home/integrations/IntegrationCategories.tsx

@@ -8,7 +8,6 @@ import { RouteComponentProps, withRouter } from "react-router";
 import IntegrationList from "./IntegrationList";
 import api from "shared/api";
 
-
 type PropsType = RouteComponentProps & {
   category: string;
 };
@@ -39,7 +38,6 @@ class IntegrationCategories extends Component<PropsType, StateType> {
     }
   }
 
-
   getIntegrationsForCategory = (categoryType: string) => {
     const { currentProject } = this.context;
     this.setState({
@@ -117,8 +115,7 @@ class IntegrationCategories extends Component<PropsType, StateType> {
   render = () => {
     const { category: currentCategory } = this.props;
     let icon =
-      integrationList[currentCategory] &&
-      integrationList[currentCategory].icon;
+      integrationList[currentCategory] && integrationList[currentCategory].icon;
     let label =
       integrationList[currentCategory] &&
       integrationList[currentCategory].label;
@@ -144,7 +141,9 @@ class IntegrationCategories extends Component<PropsType, StateType> {
                 this.context.setCurrentModal("IntegrationsModal", {
                   category: currentCategory,
                   setCurrentIntegration: (x: string) =>
-                    this.props.history.push(`/integrations/${this.props.category}/create/${x}`),
+                    this.props.history.push(
+                      `/integrations/${this.props.category}/create/${x}`
+                    ),
                 })
               }
             >
@@ -179,7 +178,9 @@ class IntegrationCategories extends Component<PropsType, StateType> {
             </Flex>
             <Button
               onClick={() =>
-                window.open(`/api/oauth/projects/${this.context.currentProject.id}/github`)
+                window.open(
+                  `/api/oauth/projects/${this.context.currentProject.id}/github`
+                )
               }
             >
               <GHIcon />
@@ -195,10 +196,10 @@ class IntegrationCategories extends Component<PropsType, StateType> {
             titles={this.state.currentTitles}
             itemIdentifier={this.state.currentIds}
           />
-        </div >
+        </div>
       );
     }
-  }
+  };
 }
 
 IntegrationCategories.contextType = Context;

+ 41 - 39
dashboard/src/main/home/integrations/IntegrationList.tsx

@@ -24,7 +24,7 @@ export default class IntegrationList extends Component<PropsType, StateType> {
   };
 
   allCollapsed = () =>
-    this.state.displayExpanded.reduce((prev, cur) => prev && !cur, true)
+    this.state.displayExpanded.reduce((prev, cur) => prev && !cur, true);
 
   componentDidUpdate(prevProps: PropsType) {
     if (prevProps.integrations !== this.props.integrations) {
@@ -33,7 +33,9 @@ export default class IntegrationList extends Component<PropsType, StateType> {
   }
 
   collapseAll = () => {
-    this.setState({ displayExpanded: this.props.integrations.map(() => false) });
+    this.setState({
+      displayExpanded: this.props.integrations.map(() => false),
+    });
   };
 
   expandAll = () => {
@@ -52,26 +54,22 @@ export default class IntegrationList extends Component<PropsType, StateType> {
   handleParent = (event: any, integration: string) =>
     this.props.setCurrent && this.props.setCurrent(integration);
 
-
   renderContents = () => {
-    let {
-      integrations,
-      titles,
-      setCurrent,
-      isCategory,
-    } = this.props;
+    let { integrations, titles, setCurrent, isCategory } = this.props;
     if (titles && titles.length > 0) {
       return integrations.map((integration: string, i: number) => {
         let label = titles[i];
-        return <IntegrationRow
-          category={this.props.currentCategory}
-          integration={integration}
-          expanded={this.state.displayExpanded[i]}
-          key={i}
-          itemId={this.props.itemIdentifier[i]}
-          label={label}
-          toggleCollapse={(e: MouseEvent) => this.toggleDisplay(e, i)}
-        ></IntegrationRow>;
+        return (
+          <IntegrationRow
+            category={this.props.currentCategory}
+            integration={integration}
+            expanded={this.state.displayExpanded[i]}
+            key={i}
+            itemId={this.props.itemIdentifier[i]}
+            label={label}
+            toggleCollapse={(e: MouseEvent) => this.toggleDisplay(e, i)}
+          ></IntegrationRow>
+        );
       });
     } else if (integrations && integrations.length > 0) {
       return integrations.map((integration: string, i: number) => {
@@ -83,7 +81,9 @@ export default class IntegrationList extends Component<PropsType, StateType> {
         return (
           <Integration
             key={i}
-            onClick={() => (disabled ? null : (setCurrent && setCurrent(integration)))}
+            onClick={() =>
+              disabled ? null : setCurrent && setCurrent(integration)
+            }
             disabled={disabled}
           >
             <MainRow disabled={disabled}>
@@ -102,27 +102,29 @@ export default class IntegrationList extends Component<PropsType, StateType> {
     return <Placeholder>No integrations set up yet.</Placeholder>;
   };
 
-  collapseAllButton = () => <Button
-    onClick={() => this.allCollapsed() ? this.expandAll() : this.collapseAll()}
-  >
-    {this.allCollapsed() ? (
-      <>
-        <i className="material-icons">expand_more</i> Expand All
-    </>
-    ) : (
-      <>
-        <i className="material-icons">expand_less</i> Collapse All
-    </>
-    )}
-  </Button>;
+  collapseAllButton = () => (
+    <Button
+      onClick={() =>
+        this.allCollapsed() ? this.expandAll() : this.collapseAll()
+      }
+    >
+      {this.allCollapsed() ? (
+        <>
+          <i className="material-icons">expand_more</i> Expand All
+        </>
+      ) : (
+        <>
+          <i className="material-icons">expand_less</i> Collapse All
+        </>
+      )}
+    </Button>
+  );
 
   render() {
     return (
       <StyledIntegrationList>
         {this.props.titles && this.props.titles.length > 0 && (
-          <ControlRow>
-            {this.collapseAllButton()}
-          </ControlRow>
+          <ControlRow>{this.collapseAllButton()}</ControlRow>
         )}
         {this.renderContents()}
       </StyledIntegrationList>
@@ -148,10 +150,10 @@ const MainRow = styled.div`
   border-radius: 5px;
   :hover {
     background: ${(props: { disabled: boolean }) =>
-    props.disabled ? "" : "#ffffff11"};
+      props.disabled ? "" : "#ffffff11"};
     > i {
       background: ${(props: { disabled: boolean }) =>
-    props.disabled ? "" : "#ffffff11"};
+        props.disabled ? "" : "#ffffff11"};
     }
   }
 
@@ -163,7 +165,7 @@ const MainRow = styled.div`
     margin-right: -7px;
     :hover {
       background: ${(props: { disabled: boolean }) =>
-    props.disabled ? "" : "#ffffff11"};
+        props.disabled ? "" : "#ffffff11"};
     }
   }
 `;
@@ -250,7 +252,7 @@ const Button = styled.div`
     props.disabled ? "#aaaabbee" : "#616FEEcc"};
   :hover {
     background: ${(props: { disabled?: boolean }) =>
-    props.disabled ? "" : "#505edddd"};
+      props.disabled ? "" : "#505edddd"};
   }
 
   > i {

+ 74 - 77
dashboard/src/main/home/integrations/IntegrationRow.tsx

@@ -23,99 +23,97 @@ type StateType = {
 
 export default class IntegrationRow extends Component<PropsType, StateType> {
   state = {
-    editMode: false
+    editMode: false,
   };
 
   editButtonOnClick = (e: MouseEvent) => {
     e.stopPropagation();
     if (!this.props.expanded) {
       this.setState({
-        editMode: true
+        editMode: true,
       });
       this.props.toggleCollapse(null);
-    }
-    else {
+    } else {
       this.setState({
-        editMode: !this.state.editMode
+        editMode: !this.state.editMode,
       });
       if (this.state.editMode) {
         this.props.toggleCollapse(null);
       }
     }
-  }
+  };
 
   render = () => {
     const icon =
-      integrationList[this.props.integration] && integrationList[this.props.integration].icon;
+      integrationList[this.props.integration] &&
+      integrationList[this.props.integration].icon;
     const subtitle =
-      integrationList[this.props.integration] && integrationList[this.props.integration].label;
-    return <Integration disabled={false}>
-      <MainRow
-        onClick={this.props.toggleCollapse}
-        disabled={false}
-      >
-        <Flex>
-          <Icon src={icon && icon} />
-          <Description>
-            <Label>{this.props.label}</Label>
-            <Subtitle>{subtitle}</Subtitle>
-          </Description>
-        </Flex>
-        <MaterialIconTray disabled={false}>
-          {/* <i className="material-icons"
+      integrationList[this.props.integration] &&
+      integrationList[this.props.integration].label;
+    return (
+      <Integration disabled={false}>
+        <MainRow onClick={this.props.toggleCollapse} disabled={false}>
+          <Flex>
+            <Icon src={icon && icon} />
+            <Description>
+              <Label>{this.props.label}</Label>
+              <Subtitle>{subtitle}</Subtitle>
+            </Description>
+          </Flex>
+          <MaterialIconTray disabled={false}>
+            {/* <i className="material-icons"
             onClick={this.editButtonOnClick}>mode_edit</i> */}
-          <I
-            className="material-icons"
-            showList={this.props.expanded}
-            onClick={this.props.toggleCollapse}
-          >
-            expand_more
-          </I>
-        </MaterialIconTray>
-      </MainRow>
-      {this.props.expanded && !this.state.editMode && (
-        <ImageHodler adjustMargin={this.props.category !== "repo"}>
-          {this.props.category !== "repo" ? (
-            <ImageList
-              selectedImageUrl={null}
-              selectedTag={null}
-              clickedImage={null}
-              registry={this.props.itemId}
-              setSelectedImageUrl={() => { }}
-              setSelectedTag={() => { }}
-              setClickedImage={() => { }}
-            />
-          ) : (
-            <RepoList
-              actionConfig={
-                {
-                  git_repo: "",
-                  image_repo_uri: "",
-                  git_repo_id: 0,
-                  dockerfile_path: "",
-                } as ActionConfigType
-              }
-              setActionConfig={() => { }}
-              readOnly={true}
-              userId={this.props.itemId}
-            />
-          )}
-        </ImageHodler>
-      )}
-      {
-        this.props.expanded && this.state.editMode && <CreateIntegrationForm
-          integrationName={this.props.integration}
-          closeForm={() => {
-            this.setState({ editMode: false });
-          }}
-        />
-      }
-    </Integration>
-  }
-
+            <I
+              className="material-icons"
+              showList={this.props.expanded}
+              onClick={this.props.toggleCollapse}
+            >
+              expand_more
+            </I>
+          </MaterialIconTray>
+        </MainRow>
+        {this.props.expanded && !this.state.editMode && (
+          <ImageHodler adjustMargin={this.props.category !== "repo"}>
+            {this.props.category !== "repo" ? (
+              <ImageList
+                selectedImageUrl={null}
+                selectedTag={null}
+                clickedImage={null}
+                registry={this.props.itemId}
+                setSelectedImageUrl={() => {}}
+                setSelectedTag={() => {}}
+                setClickedImage={() => {}}
+              />
+            ) : (
+              <RepoList
+                actionConfig={
+                  {
+                    git_repo: "",
+                    image_repo_uri: "",
+                    git_repo_id: 0,
+                    dockerfile_path: "",
+                  } as ActionConfigType
+                }
+                setActionConfig={() => {}}
+                readOnly={true}
+                userId={this.props.itemId}
+              />
+            )}
+          </ImageHodler>
+        )}
+        {this.props.expanded && this.state.editMode && (
+          <CreateIntegrationForm
+            integrationName={this.props.integration}
+            closeForm={() => {
+              this.setState({ editMode: false });
+            }}
+          />
+        )}
+      </Integration>
+    );
+  };
 }
 
-
 const Flex = styled.div`
   display: flex;
   align-items: center;
@@ -149,10 +147,10 @@ const MainRow = styled.div`
   border-radius: 5px;
   :hover {
     background: ${(props: { disabled: boolean }) =>
-    props.disabled ? "" : "#ffffff11"};
+      props.disabled ? "" : "#ffffff11"};
     > i {
       background: ${(props: { disabled: boolean }) =>
-    props.disabled ? "" : "#ffffff11"};
+        props.disabled ? "" : "#ffffff11"};
     }
   }
 
@@ -164,7 +162,7 @@ const MainRow = styled.div`
     margin-right: -7px;
     :hover {
       background: ${(props: { disabled: boolean }) =>
-    props.disabled ? "" : "#ffffff11"};
+        props.disabled ? "" : "#ffffff11"};
     }
   }
 `;
@@ -183,7 +181,7 @@ const MaterialIconTray = styled.div`
     color: #ffffff44;
     :hover {
       background: ${(props: { disabled: boolean }) =>
-    props.disabled ? "" : "#ffffff11"};
+        props.disabled ? "" : "#ffffff11"};
     }
   }
 `;
@@ -209,7 +207,6 @@ const Subtitle = styled.div`
   padding-top: 5px;
 `;
 
-
 const I = styled.i`
   transform: ${(props: { showList: boolean }) =>
     props.showList ? "rotate(180deg)" : ""};

+ 70 - 58
dashboard/src/main/home/integrations/Integrations.tsx

@@ -14,71 +14,83 @@ type StateType = {
   currentIntegrationData: any[];
 };
 
-const IntegrationCategoryStrings = ["registry", "repo"] /*"kubernetes",*/
+const IntegrationCategoryStrings = ["registry", "repo"]; /*"kubernetes",*/
 
 class Integrations extends Component<PropsType, StateType> {
   state = {
     currentIntegrationData: [] as any[],
   };
 
-  render = () => <StyledIntegrations><Switch>
-    <Route path="/integrations/:category/create/:integration" render={(rp) => {
-      const { integration, category } = rp.match.params;
-      if (!IntegrationCategoryStrings.includes(category)) {
-        this.props.history.push("/integrations");
-      }
-      let icon =
-        integrationList[integration] &&
-        integrationList[integration].icon;
-      return (
-        <div>
-          <TitleSectionAlt>
-            <Flex>
-              <i
-                className="material-icons"
-                onClick={() => this.props.history.push(`/integrations/${category}`)}
-              >
-                keyboard_backspace
-                </i>
-              <Icon src={icon && icon} />
-              <Title>{integrationList[integration].label}</Title>
-            </Flex>
-          </TitleSectionAlt>
-          <CreateIntegrationForm
-            integrationName={integration}
-            closeForm={() => {
-              this.props.history.push(`/integrations/${category}`)
-            }}
-          />
-          <Br />
-        </div>
-      );
-
-    }} />
-    <Route path="/integrations/:category" render={(rp) => {
-      const currentCategory = rp.match.params.category;
-      if (!IntegrationCategoryStrings.includes(currentCategory)) {
-        this.props.history.push("/integrations");
-      }
-      return <IntegrationCategories
-        category={currentCategory}
-      ></IntegrationCategories>
-    }} />
-    <Route>
-      <div>
-        <TitleSection>
-          <Title>Integrations</Title>
-        </TitleSection>
-
-        <IntegrationList
-          currentCategory={""}
-          integrations={["kubernetes", "registry", "repo"]}
-          setCurrent={(x) => this.props.history.push(`/integrations/${x}`)}
-          isCategory={true}
+  render = () => (
+    <StyledIntegrations>
+      <Switch>
+        <Route
+          path="/integrations/:category/create/:integration"
+          render={(rp) => {
+            const { integration, category } = rp.match.params;
+            if (!IntegrationCategoryStrings.includes(category)) {
+              this.props.history.push("/integrations");
+            }
+            let icon =
+              integrationList[integration] && integrationList[integration].icon;
+            return (
+              <div>
+                <TitleSectionAlt>
+                  <Flex>
+                    <i
+                      className="material-icons"
+                      onClick={() =>
+                        this.props.history.push(`/integrations/${category}`)
+                      }
+                    >
+                      keyboard_backspace
+                    </i>
+                    <Icon src={icon && icon} />
+                    <Title>{integrationList[integration].label}</Title>
+                  </Flex>
+                </TitleSectionAlt>
+                <CreateIntegrationForm
+                  integrationName={integration}
+                  closeForm={() => {
+                    this.props.history.push(`/integrations/${category}`);
+                  }}
+                />
+                <Br />
+              </div>
+            );
+          }}
         />
-      </div>
-    </Route>
-  </Switch></StyledIntegrations>;
+        <Route
+          path="/integrations/:category"
+          render={(rp) => {
+            const currentCategory = rp.match.params.category;
+            if (!IntegrationCategoryStrings.includes(currentCategory)) {
+              this.props.history.push("/integrations");
+            }
+            return (
+              <IntegrationCategories
+                category={currentCategory}
+              ></IntegrationCategories>
+            );
+          }}
+        />
+        <Route>
+          <div>
+            <TitleSection>
+              <Title>Integrations</Title>
+            </TitleSection>
+
+            <IntegrationList
+              currentCategory={""}
+              integrations={["kubernetes", "registry", "repo"]}
+              setCurrent={(x) => this.props.history.push(`/integrations/${x}`)}
+              isCategory={true}
+            />
+          </div>
+        </Route>
+      </Switch>
+    </StyledIntegrations>
+  );
 }
 
 export default withRouter(Integrations);

+ 5 - 2
dashboard/src/main/home/integrations/create-integration/CreateIntegrationForm.tsx

@@ -13,7 +13,10 @@ type PropsType = {
 
 type StateType = {};
 
-export default class CreateIntegrationForm extends Component<PropsType, StateType> {
+export default class CreateIntegrationForm extends Component<
+  PropsType,
+  StateType
+> {
   state = {};
 
   render = () => {
@@ -31,5 +34,5 @@ export default class CreateIntegrationForm extends Component<PropsType, StateTyp
       default:
         return null;
     }
-  }
+  };
 }

+ 5 - 2
dashboard/src/main/home/integrations/edit-integration/EditIntegrationForm.tsx

@@ -13,7 +13,10 @@ type PropsType = {
 
 type StateType = {};
 
-export default class CreateIntegrationForm extends Component<PropsType, StateType> {
+export default class CreateIntegrationForm extends Component<
+  PropsType,
+  StateType
+> {
   state = {};
 
   render = () => {
@@ -31,5 +34,5 @@ export default class CreateIntegrationForm extends Component<PropsType, StateTyp
       default:
         return null;
     }
-  }
+  };
 }

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

@@ -22,7 +22,6 @@ import ValuesWrapper from "components/values-form/ValuesWrapper";
 import ValuesForm from "components/values-form/ValuesForm";
 import { isAlphanumeric } from "shared/common";
 
-
 type PropsType = RouteComponentProps & {
   currentTemplate: any;
   hideLaunch: () => void;
@@ -137,23 +136,25 @@ class LaunchTemplate extends Component<PropsType, StateType> {
 
         this.setState({ saveValuesStatus: "successful" }, () => {
           // redirect to dashboard
-          setTimeout(() => { this.props.history.push("cluster-dashboard")}, 500);
-          window.analytics.track('Deployed Add-on', {
+          setTimeout(() => {
+            this.props.history.push("cluster-dashboard");
+          }, 500);
+          window.analytics.track("Deployed Add-on", {
             name: this.props.currentTemplate.name,
             namespace: this.state.selectedNamespace,
             values: values,
-          })
+          });
         });
       })
       .catch((err) => {
         this.setState({ saveValuesStatus: "error" });
         setCurrentError(err.response.data.errors[0]);
-        window.analytics.track('Failed to Deploy Add-on', {
+        window.analytics.track("Failed to Deploy Add-on", {
           name: this.props.currentTemplate.name,
           namespace: this.state.selectedNamespace,
           values: values,
           error: err,
-        })
+        });
       });
   };
 
@@ -243,15 +244,17 @@ class LaunchTemplate extends Component<PropsType, StateType> {
         // this.props.setCurrentView('cluster-dashboard');
         this.setState({ saveValuesStatus: "successful" }, () => {
           // redirect to dashboard with namespace
-          setTimeout(() => { this.props.history.push("cluster-dashboard")}, 1000);
+          setTimeout(() => {
+            this.props.history.push("cluster-dashboard");
+          }, 1000);
         });
         try {
-          window.analytics.track('Deployed Application', {
+          window.analytics.track("Deployed Application", {
             name: this.props.currentTemplate.name,
             namespace: this.state.selectedNamespace,
             sourceType: this.state.sourceType,
             values: values,
-          })
+          });
         } catch (error) {
           console.log(error);
         }
@@ -260,13 +263,13 @@ class LaunchTemplate extends Component<PropsType, StateType> {
         this.setState({ saveValuesStatus: "error" });
 
         try {
-          window.analytics.track('Failed to Deploy Application', {
+          window.analytics.track("Failed to Deploy Application", {
             name: this.props.currentTemplate.name,
             namespace: this.state.selectedNamespace,
             sourceType: this.state.sourceType,
             values: values,
             error: err,
-          })
+          });
         } catch (error) {
           console.log(error);
         }

+ 2 - 2
dashboard/src/main/home/provisioner/ProvisionerLogs.tsx

@@ -137,9 +137,9 @@ class ProvisionerLogs extends Component<PropsType, StateType> {
       }
 
       if (err) {
-        window.analytics.track('Provisioning Error', {
+        window.analytics.track("Provisioning Error", {
           error: err,
-        })
+        });
         let e = ansiparse(err).map((el: any) => {
           return el.text;
         });

+ 11 - 11
dashboard/src/main/home/sidebar/Sidebar.tsx

@@ -124,9 +124,9 @@ class Sidebar extends Component<PropsType, StateType> {
             onClick={() => {
               this.props.history.push("/integrations");
             }}
-          // onClick={() => {
-          //   setCurrentModal("IntegrationsInstructionsModal", {});
-          // }}
+            // onClick={() => {
+            //   setCurrentModal("IntegrationsInstructionsModal", {});
+            // }}
           >
             <Img src={integrations} />
             Integrations
@@ -134,14 +134,14 @@ class Sidebar extends Component<PropsType, StateType> {
           {this.context.currentProject.roles.filter((obj: any) => {
             return obj.user_id === this.context.user.userId;
           })[0].kind === "admin" && (
-              <NavButton
-                onClick={() => this.props.history.push("/project-settings")}
-                selected={this.props.currentView === "project-settings"}
-              >
-                <Img enlarge={true} src={settings} />
+            <NavButton
+              onClick={() => this.props.history.push("/project-settings")}
+              selected={this.props.currentView === "project-settings"}
+            >
+              <Img enlarge={true} src={settings} />
               Settings
-              </NavButton>
-            )}
+            </NavButton>
+          )}
 
           <br />
 
@@ -249,7 +249,7 @@ const NavButton = styled.div`
 
   :hover {
     background: ${(props: { disabled?: boolean; selected?: boolean }) =>
-    props.selected ? "" : "#ffffff08"};
+      props.selected ? "" : "#ffffff08"};
   }
 
   > i {

+ 1 - 1
dashboard/webpack.config.js

@@ -59,7 +59,7 @@ module.exports = () => {
     plugins: [
       new HtmlWebpackPlugin({
         template: path.resolve(__dirname, "src", "index.html"),
-        segmentKey: `${process.env.SEGMENT_PUBLIC_KEY}`
+        segmentKey: `${process.env.SEGMENT_PUBLIC_KEY}`,
       }),
       new webpack.DefinePlugin(envKeys),
     ],