github.com/replicatedhq/ship@v0.55.0/web/init/src/components/shared/RouteDecider.jsx (about) 1 import React from "react"; 2 import PropTypes from "prop-types"; 3 import { Router, Route, Switch } from "react-router-dom"; 4 import isEmpty from "lodash/isEmpty"; 5 import NavBar from "../../containers/Navbar"; 6 7 import Loader from "./Loader"; 8 import StepNumbers from "./StepNumbers"; 9 import DetermineComponentForRoute from "../../containers/DetermineComponentForRoute"; 10 import StepDone from "./StepDone"; 11 12 const isRootPath = (basePath) => { 13 const formattedBasePath = basePath === "" ? "/" : basePath.replace(/\/$/, ""); 14 return window.location.pathname === formattedBasePath 15 } 16 17 const ShipRoutesWrapper = ({ routes, headerEnabled, stepsEnabled, basePath, onCompletion }) => ( 18 <div className="flex-column flex1"> 19 <div className="flex-column flex1 u-overflow--hidden u-position--relative"> 20 {!routes ? 21 <div className="flex1 flex-column justifyContent--center alignItems--center"> 22 <Loader size="60" /> 23 </div> 24 : 25 <div className="u-minHeight--full u-minWidth--full flex-column flex1"> 26 {headerEnabled && <NavBar hideLinks={true} hideSteps={stepsEnabled} routes={routes} basePath={basePath} />} 27 {stepsEnabled && <StepNumbers basePath={basePath} steps={routes} />} 28 <div className="flex-1-auto flex-column u-overflow--auto"> 29 <Switch> 30 {routes && routes.map((route) => ( 31 <Route 32 exact 33 key={route.id} 34 path={`${basePath}/${route.id}`} 35 render={() => <DetermineComponentForRoute 36 onCompletion={onCompletion} 37 basePath={basePath} 38 routes={routes} 39 currentRoute={route} 40 />} 41 /> 42 ))} 43 <Route exact path={`${basePath}/`} component={() => <div className="flex1 flex-column justifyContent--center alignItems--center"><Loader size="60" /></div> } /> 44 <Route exact path={`${basePath}/done`} component={() => <StepDone />} /> 45 </Switch> 46 </div> 47 </div> 48 } 49 </div> 50 </div> 51 ) 52 53 export default class RouteDecider extends React.Component { 54 static propTypes = { 55 isDone: PropTypes.bool.isRequired, 56 routes: PropTypes.arrayOf( 57 PropTypes.shape({ 58 id: PropTypes.string, 59 description: PropTypes.string, 60 phase: PropTypes.string, 61 }) 62 ), 63 basePath: PropTypes.string.isRequired, 64 headerEnabled: PropTypes.bool.isRequired, 65 stepsEnabled: PropTypes.bool.isRequired, 66 history: PropTypes.object.isRequired, 67 /** Callback function to be invoked at the finalization of the Ship Init flow */ 68 onCompletion: PropTypes.func, 69 } 70 71 componentDidUpdate(lastProps) { 72 const { 73 routes, 74 basePath 75 } = this.props 76 if (routes !== lastProps.routes && routes.length) { 77 if (isRootPath(basePath)) { 78 const defaultRoute = `${basePath}/${routes[0].id}`; 79 this.props.history.push(defaultRoute); 80 } 81 } 82 } 83 84 componentDidMount() { 85 const { 86 routes, 87 getRoutes, 88 getMetadata, 89 } = this.props; 90 if (isEmpty(routes)) { 91 getRoutes(); 92 } 93 getMetadata(); 94 } 95 96 render() { 97 const { 98 routes, 99 basePath, 100 history, 101 headerEnabled, 102 stepsEnabled, 103 onCompletion, 104 } = this.props; 105 const routeProps = { 106 routes, 107 basePath, 108 headerEnabled, 109 stepsEnabled, 110 onCompletion, 111 } 112 return ( 113 <div className="u-minHeight--full u-minWidth--full flex-column flex1"> 114 <Router history={history}> 115 <ShipRoutesWrapper 116 {...routeProps} 117 /> 118 </Router> 119 </div> 120 ); 121 } 122 }