Przeglądaj źródła

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

Router fixes
sunguroku 5 lat temu
rodzic
commit
b3eac3cfa4

+ 91 - 79
dashboard/src/main/Main.tsx

@@ -1,59 +1,57 @@
-import React, { Component } from 'react';
-import styled, { createGlobalStyle } from 'styled-components';
-import { BrowserRouter, Route, Redirect, Switch } from 'react-router-dom';
-import close from 'assets/close.png';
-
-import api from 'shared/api';
-import { Context } from 'shared/Context';
-
-import Login from './Login';
-import Register from './Register';
-import CurrentError from './CurrentError';
-import Home from './home/Home';
-import Loading from 'components/Loading';
-import PorterUrls from 'shared/urls';
-
-type PropsType = {
-};
+import React, { Component } from "react";
+import styled, { createGlobalStyle } from "styled-components";
+import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
+import close from "assets/close.png";
+
+import api from "shared/api";
+import { Context } from "shared/Context";
+
+import Login from "./Login";
+import Register from "./Register";
+import CurrentError from "./CurrentError";
+import Home from "./home/Home";
+import Loading from "components/Loading";
+import { PorterUrls } from "shared/urls";
+
+type PropsType = {};
 
 type StateType = {
-  loading: boolean,
-  isLoggedIn: boolean,
-  initialized: boolean,
+  loading: boolean;
+  isLoggedIn: boolean;
+  initialized: boolean;
 };
 
 export default class Main extends Component<PropsType, StateType> {
-  
   state = {
     loading: true,
-    isLoggedIn : false,
-    initialized: localStorage.getItem("init") === 'true'
-  }
+    isLoggedIn: false,
+    initialized: localStorage.getItem("init") === "true",
+  };
 
   componentDidMount() {
     let { setUser } = this.context;
-    api.checkAuth('', {}, {}, (err: any, res: any) => {    
+    api.checkAuth("", {}, {}, (err: any, res: any) => {
       if (err && err.response?.status == 403) {
-        this.setState({ isLoggedIn: false, loading: false })
+        this.setState({ isLoggedIn: false, loading: false });
       }
 
       if (res && res.data) {
         setUser(res?.data?.id, res?.data?.email);
         this.setState({ isLoggedIn: true, initialized: true, loading: false });
       } else {
-        this.setState({ isLoggedIn: false, loading: false })
+        this.setState({ isLoggedIn: false, loading: false });
       }
     });
   }
 
   initialize = () => {
-    this.setState({isLoggedIn: true, initialized: true});
-    localStorage.setItem('init', 'true');
-  }
-  
+    this.setState({ isLoggedIn: true, initialized: true });
+    localStorage.setItem("init", "true");
+  };
+
   authenticate = () => {
     this.setState({ isLoggedIn: true, initialized: true });
-  }
+  };
 
   handleLogOut = () => {
     // Clears local storage for proper rendering of clusters
@@ -61,75 +59,89 @@ export default class Main extends Component<PropsType, StateType> {
 
     this.context.clearContext();
     this.setState({ isLoggedIn: false, initialized: true });
-  }
+  };
 
   renderMain = () => {
     if (this.state.loading) {
-      return <Loading />
+      return <Loading />;
     }
 
     const authedUrls: PorterUrls[] = [
-      "dashboard", "templates", "integrations", "new-project",
-      "cluster-dashboard", "provisioner", "project-settings"
+      "dashboard",
+      "templates",
+      "integrations",
+      "new-project",
+      "cluster-dashboard",
+      "provisioner",
+      "project-settings",
     ];
 
     return (
       <Switch>
-        <Route path='/login' render={() => {
-          if (!this.state.isLoggedIn) {
-            return <Login authenticate={this.authenticate} />
-          } else {
-            return <Redirect to='/' />
-          }
-        }} />
-
-        <Route path='/register' render={() => {
-          if (!this.state.isLoggedIn) {
-            return <Register authenticate={this.initialize} />
-          } else {
-            return <Redirect to='/' />
-          }
-        }} />
-
-        // TODO: Possible template this into a map from url to routed home
-        {...authedUrls.map(route =>
-            <Route path={`/${route}`} render={() => {
-            if (this.state.isLoggedIn && this.state.initialized) {
+        <Route
+          path="/login"
+          render={() => {
+            if (!this.state.isLoggedIn) {
+              return <Login authenticate={this.authenticate} />;
+            } else {
+              return <Redirect to="/" />;
+            }
+          }}
+        />
+        <Route
+          path="/register"
+          render={() => {
+            if (!this.state.isLoggedIn) {
+              return <Register authenticate={this.initialize} />;
+            } else {
+              return <Redirect to="/" />;
+            }
+          }}
+        />
+        <Route
+          path={`/:subroute`}
+          render={(routeProps) => {
+            const urlRoute = routeProps.location.pathname.slice(1);
+            if (
+              this.state.isLoggedIn &&
+              this.state.initialized &&
+              PorterUrls.includes(urlRoute)
+            ) {
               return (
-                <Home 
+                <Home
+                  key="home"
                   currentProject={this.context.currentProject}
-                  currentCluster={this.context.currentCluster} 
-                  currentRoute={route}
-                  logOut={this.handleLogOut} 
+                  currentCluster={this.context.currentCluster}
+                  currentRoute={urlRoute as PorterUrls}
+                  logOut={this.handleLogOut}
                 />
               );
             } else {
-              return <Redirect to='/' />
+              return <Redirect to="/" />;
+            }
+          }}
+        />
+        <Route
+          path="/"
+          render={() => {
+            if (this.state.isLoggedIn) {
+              return <Redirect to="/dashboard" />;
+            } else if (this.state.initialized) {
+              return <Redirect to="/login" />;
+            } else {
+              return <Redirect to="/register" />;
             }
-          }}/>
-        )}
-        
-
-        <Route path='/' render={() => {
-          if (this.state.isLoggedIn) {
-            return <Redirect to='/dashboard'/>
-          } else if (this.state.initialized) {
-            return <Redirect to='/login'/>
-          } else {
-            return <Redirect to='/register' />
-          }
-        }}/>
+          }}
+        />
       </Switch>
     );
-  }
+  };
 
   render() {
     return (
       <StyledMain>
         <GlobalStyle />
-        <BrowserRouter>
-          {this.renderMain()}
-        </BrowserRouter>
+        <BrowserRouter>{this.renderMain()}</BrowserRouter>
         <CurrentError currentError={this.context.currentError} />
       </StyledMain>
     );
@@ -167,4 +179,4 @@ const StyledMain = styled.div`
   left: 0;
   background: #202227;
   color: white;
-`;
+`;

+ 6 - 5
dashboard/src/main/home/Home.tsx

@@ -25,7 +25,7 @@ import ConfirmOverlay from 'components/ConfirmOverlay';
 import Modal from './modals/Modal';
 import * as FullStory from '@fullstory/browser';
 import { Redirect, RouteComponentProps, withRouter } from 'react-router';
-import PorterUrls from 'shared/urls';
+import {PorterUrls} from 'shared/urls';
 
 type PropsType = RouteComponentProps & {
   logOut: () => void,
@@ -79,7 +79,8 @@ class Home extends Component<PropsType, StateType> {
         this.props.history.push("integrations");
         this.setState({ sidebarReady: true, ghRedirect: false });
       } else {
-        this.props.history.push("dashboard");
+        // TODO: figure out when exactly in flow we need to send user to dashboard
+        // this.props.history.push("dashboard");
         this.setState({ sidebarReady: true });
       }
     });
@@ -215,7 +216,7 @@ class Home extends Component<PropsType, StateType> {
     this.setState({ ghRedirect: urlParams.get('gh_oauth') !== null });
     urlParams.delete('gh_oauth');
     
-    window.location.href.indexOf('127.0.0.1') === -1 && posthog.init(process.env.POSTHOG_API_KEY || 'placeholder', {
+    window.location.href.indexOf('localhost') === -1 && posthog.init(process.env.POSTHOG_API_KEY || 'placeholder', {
       api_host: process.env.POSTHOG_HOST || 'placeholder',
       loaded: function(posthog: any) { 
         posthog.identify(user.userId) 
@@ -277,7 +278,6 @@ class Home extends Component<PropsType, StateType> {
   }
 
   renderContents = () => {
-    // let { handleDO } = this.state;
     let currentView = this.props.currentRoute;
     if (this.context.currentProject && currentView !== 'new-project') {
       if (currentView === 'cluster-dashboard') {
@@ -321,6 +321,7 @@ class Home extends Component<PropsType, StateType> {
       } else {
         return (
           <Sidebar
+            key="sidebar"
             forceSidebar={this.state.forceSidebar}
             setWelcome={(x: boolean) => this.setState({ showWelcome: x })}
             currentView={this.props.currentRoute}
@@ -417,7 +418,7 @@ class Home extends Component<PropsType, StateType> {
         }
       }
     });
-    setCurrentModal(null, null)
+    setCurrentModal(null, null);
     this.props.history.push("dashboard");
   }
 

+ 1 - 1
dashboard/src/main/home/dashboard/Dashboard.tsx

@@ -98,7 +98,7 @@ class Dashboard extends Component<PropsType, StateType> {
                 <>
                   <Banner>
                     <i className="material-icons">error_outline</i>
-                    This project currently has no clusters conncted.
+                    This project currently has no clusters connected.
                     </Banner>
                   <ProvisionerSettings 
                     infras={infras}

+ 13 - 3
dashboard/src/main/home/modals/UpdateClusterModal.tsx

@@ -9,8 +9,9 @@ import { Context } from 'shared/Context';
 import SaveButton from 'components/SaveButton';
 import InputRow from 'components/values-form/InputRow';
 import ConfirmOverlay from 'components/ConfirmOverlay';
+import { RouteComponentProps, withRouter } from 'react-router';
 
-type PropsType = {
+type PropsType = RouteComponentProps & {
   setRefreshClusters: (x: boolean) => void,
 };
 
@@ -20,7 +21,7 @@ type StateType = {
   showDeleteOverlay: boolean
 };
 
-export default class UpdateClusterModal extends Component<PropsType, StateType> {
+class UpdateClusterModal extends Component<PropsType, StateType> {
   state = {
     clusterName: this.context.currentCluster.name,
     status: null as string | null,
@@ -42,7 +43,14 @@ export default class UpdateClusterModal extends Component<PropsType, StateType>
         return;
       }
 
-      if (!currentCluster?.infra_id) return;
+      if (!currentCluster?.infra_id) {
+        // TODO: make this more declarative from the Home component
+        this.props.setRefreshClusters(true);
+        this.setState({ status: 'successful', showDeleteOverlay: false });
+        this.context.setCurrentModal(null, null);
+        this.props.history.push("dashboard");
+        return;
+      }
 
       // Handle destroying infra we've provisioned
       switch (currentCluster.service) {
@@ -169,6 +177,8 @@ export default class UpdateClusterModal extends Component<PropsType, StateType>
 
 UpdateClusterModal.contextType = Context;
 
+export default withRouter(UpdateClusterModal);
+
 const Help = styled.a`
   position: absolute;
   left: 31px;

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

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

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

@@ -1,11 +1,11 @@
-type PorterUrls =
-  | "dashboard"
-  | "templates"
-  | "integrations"
-  | "new-project"
-  | "cluster-dashboard"
-  | "provisioner"
-  | "project-settings";
+export const PorterUrls = [
+  "dashboard",
+  "templates",
+  "integrations",
+  "new-project",
+  "cluster-dashboard",
+  "provisioner",
+  "project-settings",
+];
 
-
-export default PorterUrls;
+export type PorterUrls = typeof PorterUrls[number];