瀏覽代碼

Merge pull request #263 from porter-dev/beta.3.fe-refactor

Fixed routing param updating
sunguroku 5 年之前
父節點
當前提交
5617719e1c

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

@@ -20,8 +20,8 @@ jobs:
     - name: Write Dashboard Environment Variables
     - name: Write Dashboard Environment Variables
       run: |
       run: |
         cat >./dashboard/.env <<EOL
         cat >./dashboard/.env <<EOL
-        NODE_ENV=development
-        API_SERVER=localhost:8080
+        NODE_ENV=production
+        API_SERVER=dashboard.staging.getporter.dev
         FULLSTORY_ORG_ID=${{secrets.FULLSTORY_ORG_ID}}
         FULLSTORY_ORG_ID=${{secrets.FULLSTORY_ORG_ID}}
         DISCORD_KEY=${{secrets.DISCORD_KEY}}
         DISCORD_KEY=${{secrets.DISCORD_KEY}}
         DISCORD_CID=${{secrets.DISCORD_CID}}
         DISCORD_CID=${{secrets.DISCORD_CID}}

+ 7 - 10
dashboard/src/components/TabRegion.tsx

@@ -17,21 +17,18 @@ type StateType = {};
 
 
 // Manages a tab selector and renders the associated view
 // Manages a tab selector and renders the associated view
 export default class TabRegion extends Component<PropsType, StateType> {
 export default class TabRegion extends Component<PropsType, StateType> {
-  setDefaultTab = () => {
-    if (!this.props.defaultTab && this.props.options[0]) {
-      this.props.setCurrentTab(this.props.options[0].value);
-    }
-  };
-
-  componentDidMount() {
-    this.setDefaultTab();
-  }
+  defaultTab = () =>
+    this.props.defaultTab
+      ? this.props.defaultTab
+      : this.props.options[0]
+      ? this.props.options[0].value
+      : "";
 
 
   componentDidUpdate(prevProps: PropsType) {
   componentDidUpdate(prevProps: PropsType) {
     let { options, currentTab } = this.props;
     let { options, currentTab } = this.props;
     if (prevProps.options !== options) {
     if (prevProps.options !== options) {
       if (options.filter((x) => x.value === currentTab).length === 0) {
       if (options.filter((x) => x.value === currentTab).length === 0) {
-        this.setDefaultTab();
+        this.props.setCurrentTab(this.defaultTab());
       }
       }
     }
     }
   }
   }

+ 1 - 1
dashboard/src/main/Main.tsx

@@ -10,7 +10,7 @@ import Register from "./Register";
 import CurrentError from "./CurrentError";
 import CurrentError from "./CurrentError";
 import Home from "./home/Home";
 import Home from "./home/Home";
 import Loading from "components/Loading";
 import Loading from "components/Loading";
-import { PorterUrls } from "shared/urls";
+import { PorterUrls } from "shared/routing";
 
 
 type PropsType = {};
 type PropsType = {};
 
 

+ 23 - 20
dashboard/src/main/home/Home.tsx

@@ -23,7 +23,7 @@ import ConfirmOverlay from "components/ConfirmOverlay";
 import Modal from "./modals/Modal";
 import Modal from "./modals/Modal";
 import * as FullStory from "@fullstory/browser";
 import * as FullStory from "@fullstory/browser";
 import { Redirect, RouteComponentProps, withRouter } from "react-router";
 import { Redirect, RouteComponentProps, withRouter } from "react-router";
-import { PorterUrls } from "shared/urls";
+import { PorterUrls } from "shared/routing";
 
 
 type PropsType = RouteComponentProps & {
 type PropsType = RouteComponentProps & {
   logOut: () => void;
   logOut: () => void;
@@ -61,26 +61,30 @@ class Home extends Component<PropsType, StateType> {
 
 
     if (!currentProject) return;
     if (!currentProject) return;
 
 
-    api.getInfra('<token>', {}, { 
-      project_id: currentProject.id 
-    }, (err: any, res: any) => {
-      if (err) return;
-      
-      let creating = false;
+    api.getInfra(
+      "<token>",
+      {},
+      {
+        project_id: currentProject.id,
+      },
+      (err: any, res: any) => {
+        if (err) return;
+        let creating = false;
 
 
-      for (var i = 0; i < res.data.length; i++) {
-        creating = res.data[i].status === "creating"
-      }
+        for (var i = 0; i < res.data.length; i++) {
+          creating = res.data[i].status === "creating";
+        }
 
 
-      if (creating) {
-        this.props.history.push("dashboard?tab=provisioner");
-      } else if (this.state.ghRedirect) {
-        this.props.history.push("integrations");
-        this.setState({ ghRedirect: false });
-      } else if (this.props.currentRoute !== "dashboard") {
-          this.props.history.push("dashboard");
+        if (creating) {
+          this.props.history.push("dashboard?tab=provisioner");
+        } else if (this.state.ghRedirect) {
+          this.props.history.push("integrations");
+          this.setState({ ghRedirect: false });
+        } else if (this.props.currentRoute !== "dashboard") {
+          this.props.history.push("dashboard?tab=overview");
+        }
       }
       }
-    });
+    );
   };
   };
 
 
   getProjects = (id?: number) => {
   getProjects = (id?: number) => {
@@ -108,7 +112,6 @@ class Home extends Component<PropsType, StateType> {
               });
               });
               this.context.setCurrentProject(foundProject);
               this.context.setCurrentProject(foundProject);
             }
             }
-
             if (!foundProject) {
             if (!foundProject) {
               res.data.forEach((project: ProjectType, i: number) => {
               res.data.forEach((project: ProjectType, i: number) => {
                 if (
                 if (
@@ -473,7 +476,7 @@ class Home extends Component<PropsType, StateType> {
       }
       }
     );
     );
     setCurrentModal(null, null);
     setCurrentModal(null, null);
-    this.props.history.push("dashboard");
+    this.props.history.push("dashboard?tab=overview");
   };
   };
 
 
   render() {
   render() {

+ 18 - 19
dashboard/src/main/home/dashboard/Dashboard.tsx

@@ -1,4 +1,3 @@
-import { render } from "@testing-library/react";
 import React, { Component } from "react";
 import React, { Component } from "react";
 import styled from "styled-components";
 import styled from "styled-components";
 
 
@@ -9,10 +8,12 @@ import api from "shared/api";
 
 
 import ProvisionerSettings from "../provisioner/ProvisionerSettings";
 import ProvisionerSettings from "../provisioner/ProvisionerSettings";
 import ClusterPlaceholderContainer from "./ClusterPlaceholderContainer";
 import ClusterPlaceholderContainer from "./ClusterPlaceholderContainer";
-import { Redirect, RouteComponentProps, withRouter } from "react-router";
+import { RouteComponentProps, withRouter } from "react-router";
 import TabRegion from "components/TabRegion";
 import TabRegion from "components/TabRegion";
 import Provisioner from "../provisioner/Provisioner";
 import Provisioner from "../provisioner/Provisioner";
 
 
+import { setSearchParam } from "shared/routing";
+
 type PropsType = RouteComponentProps & {
 type PropsType = RouteComponentProps & {
   projectId: number | null;
   projectId: number | null;
 };
 };
@@ -21,19 +22,16 @@ const tabOptions = [
   { label: "Project Overview", value: "overview" },
   { label: "Project Overview", value: "overview" },
   { label: "Provisioner Status", value: "provisioner" },
   { label: "Provisioner Status", value: "provisioner" },
 ];
 ];
-// TODO: rethink this typing, should be coupled with tabOptions
-type TabType = "overview" | "provisioner"
+// TODO: rethink this list, should be coupled with tabOptions
+const tabOptionStrings = ["overview", "provisioner"];
 
 
 type StateType = {
 type StateType = {
   infras: InfraType[];
   infras: InfraType[];
-  currentTab: TabType;
 };
 };
 
 
-
 class Dashboard extends Component<PropsType, StateType> {
 class Dashboard extends Component<PropsType, StateType> {
   state = {
   state = {
     infras: [] as InfraType[],
     infras: [] as InfraType[],
-    currentTab: "overview" as TabType,
   };
   };
 
 
   refreshInfras = () => {
   refreshInfras = () => {
@@ -63,21 +61,20 @@ class Dashboard extends Component<PropsType, StateType> {
     if (this.props.projectId && prevProps.projectId !== this.props.projectId) {
     if (this.props.projectId && prevProps.projectId !== this.props.projectId) {
       this.refreshInfras();
       this.refreshInfras();
     }
     }
+
+    if (!tabOptionStrings.includes(this.currentTab())) {
+      this.setCurrentTab("overview");
+    }
   }
   }
 
 
   onShowProjectSettings = () => {
   onShowProjectSettings = () => {
     this.props.history.push("project-settings");
     this.props.history.push("project-settings");
   };
   };
 
 
-  renderTabContents = () => {
-    const currentTab = new URLSearchParams(this.props.location.search).get("tab")
-    if (
-      currentTab && currentTab !== this.state.currentTab
-    ) {
-      this.setState({ currentTab: currentTab as TabType });
-    }
+  currentTab = () => new URLSearchParams(this.props.location.search).get("tab");
 
 
-    if (this.state.currentTab === "provisioner") {
+  renderTabContents = () => {
+    if (this.currentTab() === "provisioner") {
       return <Provisioner />;
       return <Provisioner />;
     } else {
     } else {
       return (
       return (
@@ -98,9 +95,11 @@ class Dashboard extends Component<PropsType, StateType> {
     }
     }
   };
   };
 
 
+  setCurrentTab = (x: string) =>
+    this.props.history.push(setSearchParam(this.props.location, "tab", x));
+
   render() {
   render() {
-    let { currentProject, currentCluster } = this.context;
-    let { infras } = this.state;
+    let { currentProject } = this.context;
     let { onShowProjectSettings } = this;
     let { onShowProjectSettings } = this;
     return (
     return (
       <>
       <>
@@ -135,8 +134,8 @@ class Dashboard extends Component<PropsType, StateType> {
             </InfoSection>
             </InfoSection>
 
 
             <TabRegion
             <TabRegion
-              currentTab={this.state.currentTab}
-              setCurrentTab={(x: TabType) => this.props.history.push(`dashboard?tab=${x}`)}
+              currentTab={this.currentTab()}
+              setCurrentTab={this.setCurrentTab}
               options={tabOptions}
               options={tabOptions}
             >
             >
               {this.renderTabContents()}
               {this.renderTabContents()}

+ 1 - 1
dashboard/src/main/home/modals/UpdateClusterModal.tsx

@@ -51,7 +51,7 @@ class UpdateClusterModal extends Component<PropsType, StateType> {
           this.props.setRefreshClusters(true);
           this.props.setRefreshClusters(true);
           this.setState({ status: "successful", showDeleteOverlay: false });
           this.setState({ status: "successful", showDeleteOverlay: false });
           this.context.setCurrentModal(null, null);
           this.context.setCurrentModal(null, null);
-          this.props.history.push("dashboard");
+          this.props.history.push("dashboard?tab=overview");
           return;
           return;
         }
         }
 
 

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

@@ -52,7 +52,7 @@ class ExistingClusterSection extends Component<PropsType, StateType> {
                   });
                   });
                   setCurrentProject(proj);
                   setCurrentProject(proj);
 
 
-                  this.props.history.push("dashboard");
+                  this.props.history.push("dashboard?tab=overview");
                 }
                 }
               }
               }
             }
             }

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

@@ -39,7 +39,7 @@ class NewProject extends Component<PropsType, StateType> {
     setCurrentError(
     setCurrentError(
       "Provisioning failed. Check your credentials and try again."
       "Provisioning failed. Check your credentials and try again."
     );
     );
-    this.props.history.push("dashboard");
+    this.props.history.push("dashboard?tab=overview");
   };
   };
 
 
   renderSelectedProvider = () => {
   renderSelectedProvider = () => {

+ 1 - 1
dashboard/src/main/home/sidebar/ClusterSection.tsx

@@ -81,7 +81,7 @@ class ClusterSection extends Component<PropsType, StateType> {
             ) {
             ) {
               this.setState({ clusters: [] });
               this.setState({ clusters: [] });
               setCurrentCluster(null);
               setCurrentCluster(null);
-              // this.props.history.push("dashboard");
+              // this.props.history.push("dashboard?tab=overview");
             }
             }
           }
           }
         }
         }

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

@@ -7,10 +7,10 @@ import settings from "assets/settings.svg";
 
 
 import { Context } from "shared/Context";
 import { Context } from "shared/Context";
 
 
-import ClusterSection from './ClusterSection';
-import ProjectSectionContainer from './ProjectSectionContainer';
-import loading from 'assets/loading.gif';
-import { RouteComponentProps, withRouter } from 'react-router';
+import ClusterSection from "./ClusterSection";
+import ProjectSectionContainer from "./ProjectSectionContainer";
+import loading from "assets/loading.gif";
+import { RouteComponentProps, withRouter } from "react-router";
 
 
 type PropsType = RouteComponentProps & {
 type PropsType = RouteComponentProps & {
   forceSidebar: boolean;
   forceSidebar: boolean;
@@ -102,7 +102,7 @@ class Sidebar extends Component<PropsType, StateType> {
           <NavButton
           <NavButton
             onClick={() =>
             onClick={() =>
               currentView !== "provisioner" &&
               currentView !== "provisioner" &&
-              this.props.history.push("dashboard")
+              this.props.history.push("dashboard?tab=overview")
             }
             }
             selected={
             selected={
               currentView === "dashboard" || currentView === "provisioner"
               currentView === "dashboard" || currentView === "provisioner"
@@ -119,7 +119,7 @@ class Sidebar extends Component<PropsType, StateType> {
             Templates
             Templates
           </NavButton>
           </NavButton>
           <NavButton
           <NavButton
-            selected={currentView === 'integrations'}
+            selected={currentView === "integrations"}
             /* 
             /* 
             onClick={() => {
             onClick={() => {
               setCurrentView('integrations')
               setCurrentView('integrations')

+ 25 - 0
dashboard/src/shared/routing.tsx

@@ -0,0 +1,25 @@
+import { Location } from "history";
+
+export const PorterUrls = [
+  "dashboard",
+  "templates",
+  "integrations",
+  "new-project",
+  "cluster-dashboard",
+  "project-settings",
+];
+
+export const setSearchParam = (
+  location: Location<any>,
+  key: string,
+  value: string
+) => {
+  const urlParams = new URLSearchParams(location.search);
+  urlParams.set(key, value);
+  return {
+    pathname: location.pathname,
+    search: urlParams.toString(),
+  };
+};
+
+export type PorterUrls = typeof PorterUrls[number];

+ 0 - 10
dashboard/src/shared/urls.tsx

@@ -1,10 +0,0 @@
-export const PorterUrls = [
-  "dashboard",
-  "templates",
-  "integrations",
-  "new-project",
-  "cluster-dashboard",
-  "project-settings",
-];
-
-export type PorterUrls = typeof PorterUrls[number];