Skip to content
This repository has been archived by the owner on May 27, 2021. It is now read-only.

Commit

Permalink
Merge pull request #37 from andymikulski/normandy-remove-lilrouter
Browse files Browse the repository at this point in the history
#31: Use react-router in Normandy
  • Loading branch information
rehandalal committed Apr 3, 2018
2 parents 826ed8d + fc895b0 commit 8104fae
Show file tree
Hide file tree
Showing 38 changed files with 623 additions and 513 deletions.
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
"dependencies": {
"antd": "^3.2.1",
"autobind-decorator": "^2.1.0",
"enzyme-adapter-react-16": "^1.1.1",
"es6-promise": "^4.2.4",
"immutable": "^3.8.2",
"isomorphic-fetch": "^2.2.1",
"js-cookie": "^2.2.0",
"localforage": "^1.5.6",
"lodash.get": "^4.4.2",
"photon-ant": "^0.1.4",
"react": "^16.2.0",
Expand All @@ -18,7 +20,6 @@
"react-router-dom": "^4.2.2",
"react-scripts": "1.1.1",
"redux": "^3.7.2",
"redux-little-router": "14.0.0-0",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.2.0",
"underscore": "^1.8.3"
Expand All @@ -38,6 +39,7 @@
"devDependencies": {
"babel-plugin-import": "^1.6.5",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"enzyme": "^3.3.0",
"flow-bin": "^0.66.0",
"prettier": "^1.11.1",
"react-app-rewire-less": "^2.1.0",
Expand Down
85 changes: 50 additions & 35 deletions src/console/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'console/App.less';
import LoginPage from './LoginPage';
import Normandy from 'normandy/App';
import { BrowserRouter, NavLink, Link } from 'react-router-dom';
import { Route, Redirect } from 'react-router';
import { Route, Redirect, Switch } from 'react-router';

import { Alert, Layout } from 'antd';
const { Header, Content } = Layout;
Expand All @@ -17,7 +17,7 @@ const Homepage = props => (
<h3>Welcome {props.authToken ? 'back' : 'home'}!</h3>
{props.authToken ? (
<p>
Go to the <Link to="/normandy">Normandy page</Link>.
Go to the <Link to="/shield">SHIELD control panel</Link>.
</p>
) : (
<p>
Expand Down Expand Up @@ -57,9 +57,7 @@ class App extends Component<AppProps, AppState> {
Home
</NavLink>
<NavLink to="/login">Login</NavLink>
<NavLink exact to="/normandy">
Normandy
</NavLink>
<NavLink to="/shield">SHIELD</NavLink>

{this.state.username && (
<Alert
Expand All @@ -71,38 +69,55 @@ class App extends Component<AppProps, AppState> {
)}
</Header>
<Content className="app-content">
{/* Homepage */}
<Route
exact
path="/"
component={() => <Homepage authToken={this.state.authToken} />}
/>
<Switch>
{/* Homepage */}
<Route
exact
path="/"
component={() => <Homepage authToken={this.state.authToken} />}
/>

{/* Login */}
<Route
exact
path="/login/"
component={() =>
this.state.username ? (
<Redirect to="/" />
) : (
<LoginPage onAuth={this.onUserLogin} />
)
}
/>

{/* Login */}
<Route
exact
path="/login/"
component={() =>
this.state.username ? (
<Redirect to="/" />
) : (
<LoginPage onAuth={this.onUserLogin} />
)
}
/>
{/* Normandy App */}
<Route
path="/shield"
component={props =>
this.state.username ? (
<Normandy
authToken={this.state.authToken}
urlPrefix="/shield"
{...props}
/>
) : (
<Redirect to="/login/?next=/shield" />
)
}
/>

{/* Normandy App */}
<Route
exact
path="/normandy/"
component={() =>
this.state.username ? (
<Normandy authToken={this.state.authToken} />
) : (
<Redirect to="/login/?next=/normandy/" />
)
}
/>
<Route
component={({ location }) => (
<div>
<h2>404 - Page Not Found</h2>
<p>
No delivery-console match for{' '}
<code>{location.pathname}</code>
</p>
</div>
)}
/>
</Switch>
</Content>
</Layout>
</BrowserRouter>
Expand Down
10 changes: 6 additions & 4 deletions src/console/App.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { shallow } from 'enzyme';

it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
describe('delivery-console', () => {
it('renders without crashing', () => {
const wrapper = () => shallow(<App />);
expect(wrapper).not.toThrow();
});
});
36 changes: 19 additions & 17 deletions src/normandy/App.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
import React from 'react';
import { Provider } from 'react-redux';
import { applyMiddleware, compose, createStore } from 'redux';
import { initializeCurrentLocation } from 'redux-little-router';
import thunk from 'redux-thunk';

import App from 'normandy/components/App';
import NormandyRouter, { NormandyLink } from './Router';

import './less/main.less';

import Router, {
enhancer as routerEnhancer,
middleware as routerMiddleware,
} from 'normandy/routes';
import reducers from 'normandy/state';

const middleware = [routerMiddleware, thunk];
const middleware = [thunk];

const store = createStore(
reducers,
reducers(undefined, { type: 'initial' }),
compose(applyMiddleware(...middleware), routerEnhancer),
compose(applyMiddleware(...middleware)),
);

const initialLocation = store.getState().router;
if (initialLocation) {
store.dispatch(initializeCurrentLocation(initialLocation));
}
export default class Root extends React.Component {
componentWillMount() {
// `NormandyLinks` are wrapped Links which append a prefix for nested apps.
// At this point we know the prefix, so we can update all instances of the
// Link here via the static PREFIX property.
NormandyLink.PREFIX = this.props.urlPrefix || '';
}

export default class Root extends React.PureComponent {
render() {
const urlPrefix = this.props.urlPrefix;

return (
<div id="normandy-app">
<Provider store={store}>
<Router />
</Provider>
</div>
<Provider store={store}>
<App>
<NormandyRouter urlPrefix={urlPrefix} />
</App>
</Provider>
);
}
}
21 changes: 17 additions & 4 deletions src/normandy/App.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { shallow } from 'enzyme';

it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
describe('normandy', () => {
beforeAll(() => {
const fakeStorage = {
store: {},
getItem: key => fakeStorage.store[key] || null,
setItem: (key, value) => (fakeStorage.store[key] = value),
};
Object.defineProperty(window, 'localStorage', {
value: fakeStorage,
});
});

it('renders without crashing', () => {
const wrapper = () => shallow(<App />);
expect(wrapper).not.toThrow();
});
});
99 changes: 99 additions & 0 deletions src/normandy/Router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from 'react-router';

import CreateExtensionPage from 'normandy/components/extensions/CreateExtensionPage';
import EditExtensionPage from 'normandy/components/extensions/EditExtensionPage';
import ApprovalHistoryPage from 'normandy/components/recipes/ApprovalHistoryPage';
import CreateRecipePage from 'normandy/components/recipes/CreateRecipePage';
import CloneRecipePage from 'normandy/components/recipes/CloneRecipePage';
import EditRecipePage from 'normandy/components/recipes/EditRecipePage';
import ExtensionListing from 'normandy/components/extensions/ExtensionListing';
import Gateway from 'normandy/components/pages/Gateway';
import RecipeListing from 'normandy/components/recipes/RecipeListing';
import RecipeDetailPage from 'normandy/components/recipes/RecipeDetailPage';

import { NavLink } from 'react-router-dom';

export default class NormandyRouter extends React.Component {
static ROUTES = {
'/': {
component: Gateway,
},
// Recipes ---
'/recipe': {
component: RecipeListing,
},
'/recipe/new': {
component: CreateRecipePage,
},
'/recipe/:recipeId': {
component: RecipeDetailPage,
},
'/recipe/:recipeId/edit': {
component: EditRecipePage,
},
'/recipe/:recipeId/approval_history': {
component: ApprovalHistoryPage,
},
'/recipe/:recipeId/clone': {
component: CloneRecipePage,
},
// Recipe Revisions ---
'/recipe/:recipeId/rev/:revisionId': {
component: RecipeDetailPage,
},
'/recipe/:recipeId/rev/:revisionId/clone': {
component: CloneRecipePage,
},
// Extensions ---
'/extension': {
component: ExtensionListing,
},
'/extension/new': {
component: CreateExtensionPage,
},
'/extension/:extensionId': {
component: EditExtensionPage,
},
};

render() {
const urlPrefix = this.props.urlPrefix || '';

return (
<Switch>
{Object.keys(NormandyRouter.ROUTES).map(route => {
return (
<Route
key={route}
exact
path={`${urlPrefix}${route}`}
{...NormandyRouter.ROUTES[route]}
/>
);
})}

<Route
component={({ location }) => (
<div>
<h2>404 - Page Not Found</h2>
<p>
No normandy match for <code>{location.pathname}</code>
</p>
</div>
)}
/>
</Switch>
);
}
}

export class NormandyLink extends React.Component {
static PREFIX = '';
render() {
const { to, ...rest } = this.props;

return <NavLink to={`${NormandyLink.PREFIX}${to}`} {...rest} />;
}
}
8 changes: 3 additions & 5 deletions src/normandy/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { Layout, LocaleProvider } from 'antd';
import enUS from 'antd/lib/locale-provider/en_US';
import PropTypes from 'prop-types';
import React from 'react';
import { Link } from 'redux-little-router';
import { NormandyLink as Link } from 'normandy/Router';

import CurrentUserDetails from 'normandy/components/common/CurrentUserDetails';
import NavigationCrumbs from 'normandy/components/common/NavigationCrumbs';
import NavigationMenu from 'normandy/components/common/NavigationMenu';
import EnvAlert from 'normandy/components/common/EnvAlert';
Expand All @@ -27,7 +26,7 @@ export default class App extends React.PureComponent {

return (
<LocaleProvider locale={enUS}>
<Layout>
<Layout id="normandy-app">
<EnvAlert />

{/*
Expand All @@ -38,9 +37,8 @@ export default class App extends React.PureComponent {
<QueryServiceInfo />

<Header>
<CurrentUserDetails />
<div className="logo">
<Link href="/">SHIELD Control Panel</Link>
<Link to="/">SHIELD Control Panel</Link>
</div>
</Header>

Expand Down

0 comments on commit 8104fae

Please sign in to comment.