diff --git a/static_src/components/not_found.jsx b/static_src/components/not_found.jsx
index a769b29f..eb4797e1 100644
--- a/static_src/components/not_found.jsx
+++ b/static_src/components/not_found.jsx
@@ -1,6 +1,6 @@
import React from 'react';
const NotFound = () =>
-
Not Found
+ Not Found
;
export default NotFound;
diff --git a/static_src/components/router/route_provider.jsx b/static_src/components/router/route_provider.jsx
new file mode 100644
index 00000000..bde91c04
--- /dev/null
+++ b/static_src/components/router/route_provider.jsx
@@ -0,0 +1,36 @@
+import React from 'react';
+import RouterStore from '../../stores/router_store.js';
+import Loading from '../loading.jsx';
+
+class RouteProvider extends React.Component {
+ constructor() {
+ super();
+
+ this.state = RouterStore.component;
+
+ this.onChange = this.onChange.bind(this);
+ }
+
+ componentDidMount() {
+ RouterStore.addChangeListener(this.onChange);
+ }
+
+ shouldComponentUpdate(nextProps, nextState) {
+ return this.state === nextState || true;
+ }
+
+ componentWillUnmount() {
+ RouterStore.removeChangeListener(this.onChange);
+ }
+
+ onChange() {
+ this.setState({ ...RouterStore.component });
+ }
+
+ render() {
+ const { component: Component, props } = this.state;
+ return Component ? : ;
+ }
+}
+
+export default RouteProvider;
diff --git a/static_src/main.js b/static_src/main.js
index d07c7e22..10605793 100644
--- a/static_src/main.js
+++ b/static_src/main.js
@@ -4,61 +4,27 @@ import './css/main.css';
import './img/dashboard-uaa-icon.jpg';
import 'cloudgov-style/img/favicon.ico';
+import React from 'react';
+import ReactDOM from 'react-dom';
+
import axios from 'axios';
import { Router } from 'director';
import { trackPageView } from './util/analytics.js';
import routes, { checkAuth, clearErrors, notFound } from './routes';
-import RouterStore from './stores/router_store.js';
import MainContainer from './components/main_container.jsx';
-import Loading from './components/loading.jsx';
-
-const meta = document.querySelector('meta[name="gorilla.csrf.Token"]');
-
-if (meta) {
- axios.defaults.headers.common['X-CSRF-Token'] = meta.content;
-}
-
-import React from 'react';
-import ReactDOM from 'react-dom';
-
-class RouteHandler extends React.Component {
- constructor() {
- super();
-
- this.state = {
- component: null
- };
-
- this.onChange = this.onChange.bind(this);
- }
-
- componentDidMount() {
- RouterStore.addChangeListener(this.onChange);
- }
+import RouteProvider from './components/router/route_provider.jsx';
- shouldComponentUpdate(nextProps, nextState) {
- return this.state === nextState ? false : true;
+const initCSRFHeader = metaTag => {
+ if (metaTag) {
+ axios.defaults.headers.common['X-CSRF-Token'] = metaTag.content;
}
-
- componentWillUnmount() {
- RouterStore.removeChangeListener(this.onChange);
- }
-
- onChange() {
- this.setState({ ...RouterStore.component });
- }
-
- render() {
- const { component: Component, props } = this.state;
- return Component ? : ;
- }
-}
+};
const cRouter = {
- run(routes, renderEl) {
- const router = new Router(routes);
+ run(routeConfig, renderEl) {
+ const router = new Router(routeConfig);
router.configure({
async: true,
before: [clearErrors, checkAuth],
@@ -67,13 +33,15 @@ const cRouter = {
trackPageView(window.location.hash);
}
});
+
ReactDOM.render(
-
+
, renderEl);
router.init('/');
}
};
+initCSRFHeader(document.querySelector('meta[name="gorilla.csrf.Token"]'));
cRouter.run(routes, document.querySelector('.js-app'));
diff --git a/static_src/routes.js b/static_src/routes.js
index 2c623b1e..83eab517 100644
--- a/static_src/routes.js
+++ b/static_src/routes.js
@@ -1,6 +1,3 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-
import activityActions from './actions/activity_actions.js';
import AppContainer from './components/app_container.jsx';
import appActions from './actions/app_actions.js';
@@ -10,7 +7,6 @@ import Loading from './components/loading.jsx';
import Login from './components/login.jsx';
import loginActions from './actions/login_actions';
import LoginStore from './stores/login_store';
-import MainContainer from './components/main_container.jsx';
import NotFound from './components/not_found.jsx';
import orgActions from './actions/org_actions.js';
import Overview from './components/overview_container.jsx';
@@ -27,14 +23,11 @@ import windowUtil from './util/window';
import userActions from './actions/user_actions.js';
import routerActions from './actions/router_actions.js';
-// TODO this is hard to stub since we query it at module load time. It should
-// be passed in or something.
-const mainEl = document.querySelector('.js-app');
-
const MAX_OVERVIEW_SPACES = 10;
export function login(next) {
routerActions.navigate(Login);
+ next();
}
export function overview(next) {
@@ -44,7 +37,7 @@ export function overview(next) {
orgActions.changeCurrentOrg();
spaceActions.changeCurrentSpace();
appActions.changeCurrentApp();
-
+ routerActions.navigate(Overview);
spaceActions.fetchAll()
.then(spaces => {
let i = 0;
@@ -56,8 +49,9 @@ export function overview(next) {
return Promise.all(fetches);
})
- .then(pageActions.loadSuccess, pageActions.loadError)
- .then(() => routerActions.navigate(Overview));
+ .then(pageActions.loadSuccess, pageActions.loadError);
+
+ next();
}
export function org(orgGuid, next) {
@@ -72,6 +66,7 @@ export function org(orgGuid, next) {
userActions.fetchOrgUsers(orgGuid);
userActions.fetchOrgUserRoles(orgGuid);
routerActions.navigate(OrgContainer);
+ next();
}
export function space(orgGuid, spaceGuid, next) {
@@ -89,6 +84,7 @@ export function space(orgGuid, spaceGuid, next) {
orgActions.fetch(orgGuid);
serviceActions.fetchAllServices(orgGuid);
routerActions.navigate(SpaceContainer, { currentPage: 'apps' });
+ next();
}
export function app(orgGuid, spaceGuid, appGuid, next) {
@@ -111,6 +107,7 @@ export function app(orgGuid, spaceGuid, appGuid, next) {
serviceActions.fetchAllInstances(spaceGuid);
serviceActions.fetchServiceBindings();
routerActions.navigate(AppContainer);
+ next();
}
export function checkAuth(...args) {
@@ -149,9 +146,6 @@ export function checkAuth(...args) {
// Just in case something goes wrong, don't leave the user hanging. Show
// a delayed loading indicator to give them a hint. Hopefully the
// redirect is quick and they never see the loader.
- // ReactDOM.render(
- //
- // , mainEl);
routerActions.navigate(Loading, {
text: 'Redirecting to login',
loadingDelayMS: 3000,
@@ -185,6 +179,7 @@ export function notFound(next) {
spaceActions.changeCurrentSpace();
appActions.changeCurrentApp();
routerActions.navigate(NotFound);
+ next();
}
const routes = {
diff --git a/static_src/stores/router_store.js b/static_src/stores/router_store.js
index 00338896..7dd58fae 100644
--- a/static_src/stores/router_store.js
+++ b/static_src/stores/router_store.js
@@ -12,17 +12,19 @@ class RouterStore extends BaseStore {
registerToActions(action) {
const { type, data } = action;
- switch(type) {
+ switch (type) {
case routerActionTypes.NAVIGATE:
this.routeComponent = Object.assign({}, { ...data });
this.emitChange();
break;
+ default:
+ break;
}
}
get component() {
return this.routeComponent;
}
-};
+}
export default new RouterStore();
diff --git a/static_src/test/unit/routes.spec.js b/static_src/test/unit/routes.spec.js
index 4cdb6486..0dc1148e 100644
--- a/static_src/test/unit/routes.spec.js
+++ b/static_src/test/unit/routes.spec.js
@@ -1,6 +1,6 @@
import '../global_setup.js';
-import ReactDOM from 'react-dom';
+import routerActions from '../../actions/router_actions';
import errorActions from '../../actions/error_actions';
import loginActions from '../../actions/login_actions';
import LoginStore from '../../stores/login_store';
@@ -126,7 +126,7 @@ describe('routes', function () {
beforeEach(function (done) {
next = sandbox.spy(done);
- sandbox.stub(ReactDOM, 'render');
+ sandbox.stub(routerActions, 'navigate');
sandbox.stub(windowUtil, 'redirect');
loginActions.fetchStatus.returns(Promise.resolve({ status: 'unauthorized' }));
@@ -142,7 +142,7 @@ describe('routes', function () {
});
it('renders a loader', function () {
- expect(ReactDOM.render).toHaveBeenCalledOnce();
+ expect(routerActions.navigate).toHaveBeenCalledOnce();
});
it('does not fetch page data', function () {