Skip to content

Commit

Permalink
Update routing, implement Flux architecture. Closes #14
Browse files Browse the repository at this point in the history
  • Loading branch information
koistya committed Sep 30, 2014
1 parent aabbd38 commit 7580590
Show file tree
Hide file tree
Showing 15 changed files with 221 additions and 100 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@
├── /docs/ # Documentation files
├── /node_modules/ # Node.js-based dev tools and utilities
├── /src/ # The source code of the application
│ ├── /actions/ # Action methods that allow to trigger a dispatch to stores
│ ├── /assets/ # Static files which don't require pre-processing
│ ├── /data/ # Data access layer and models
│ ├── /common/ # Utility classes etc.
│ ├── /constants/ # Enumerations used in action methods and stores
│ ├── /components/ # React components. E.g. Navbar.jsx
│ ├── /images/ # Graphics (.png, .jpg, .svg etc.)
│ ├── /layouts/ # Layouts for web pages
│ ├── /pages/ # Web pages. E.g. Profile.jsx (or .html, .jade etc.)
│ ├── /services/ # Services and business logic
│ ├── /stores/ # Stores contain the application state and logic
│ ├── /styles/ # LESS style sheets (or SASS/SCSS, Stylus etc.)
│ └── /app.jsx # Entry point of your web application
│ ├── /App.jsx # Entry point of your web application
│ └── /AppDispatcher.js # The central hub that manages all data flow
├── /test/ # Unit, integration and load tests
│ ├── /e2e/ # End-to-end tests
│ └── /unit/ # Unit tests
Expand Down
2 changes: 1 addition & 1 deletion config/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ module.exports = function (release) {
loader: 'url-loader?limit=10000&mimetype=image/png'
},
{
test: /\.jsx$/,
test: /\.(js|jsx)$/,
loader: 'jsx-loader?harmony'
}
]
Expand Down
4 changes: 2 additions & 2 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ gulp.task('images', function () {
src.images = 'src/images/**';
return gulp.src(src.images)
.pipe($.changed(DEST + '/images'))
.pipe($.cache($.imagemin({
.pipe($.imagemin({
progressive: true,
interlaced: true
})))
}))
.pipe(gulp.dest(DEST + '/images'))
.pipe($.size({title: 'images'}));
});
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
"license": "MIT",
"dependencies": {
"bootstrap": "^3.2.0",
"react": "^0.11.2",
"react-router": "^0.7.0"
"director": "^1.2.3",
"flux": "^2.0.1",
"react": "^0.11.2"
},
"devDependencies": {
"browser-sync": "^1.5.1",
Expand Down
40 changes: 26 additions & 14 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
/**
* @jsx React.DOM
*/

'use strict';

var React = require('react');
var {Routes, Route} = require('react-router');
var {Router} = require('director');
var AppDispatcher = require('./AppDispatcher');
var ActionTypes = require('./constants/ActionTypes');

// Export React so the dev tools can find it
(window !== window.top ? window.top : window).React = React;

React.renderComponent(
<Routes location="history">
<Route name="app" path="/" handler={require('./layouts/Default.jsx')}>
<Route name="home" path="/" handler={require('./pages/Home.jsx')} />
<Route name="privacy" handler={require('./pages/Privacy.jsx')} />
</Route>
</Routes>,
document.body
);
function render(component) {
React.renderComponent(component(), document.body);
}

var routes = {
'/': () => render(require('./pages/Home.jsx')),
'/privacy': () => render(require('./pages/Privacy.jsx'))
};

var router = new Router(routes).configure({html5history: true}).init();

AppDispatcher.register(function(payload) {

var action = payload.action;

switch (action.actionType) {
case ActionTypes.SET_CURRENT_ROUTE:
router.setRoute(action.route);
break;
}

return true; // No errors. Needed by promise in Dispatcher.
});
39 changes: 39 additions & 0 deletions src/AppDispatcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* A singleton that operates as the central hub for application updates.
*/

'use strict';

var {Dispatcher} = require('flux');
var PayloadSources = require('./constants/PayloadSources');
var copyProperties = require('react/lib/copyProperties');

var AppDispatcher = copyProperties(new Dispatcher(), {

/**
* @param {object} action The details of the action, including the action's
* type and additional data coming from the server.
*/
handleServerAction: function(action) {
var payload = {
source: PayloadSources.SERVER_ACTION,
action: action
};
this.dispatch(payload);
},

/**
* @param {object} action The details of the action, including the action's
* type and additional data coming from the view.
*/
handleViewAction: function(action) {
var payload = {
source: PayloadSources.VIEW_ACTION,
action: action
};
this.dispatch(payload);
}

});

module.exports = AppDispatcher;
21 changes: 21 additions & 0 deletions src/actions/RouteActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

var AppDispatcher = require('../AppDispatcher');
var ActionTypes = require('../constants/ActionTypes');

var AppActions = {

/**
* Set the current route.
* @param {string} route Supply a route value, such as `todos/completed`.
*/
setRoute: function(route) {
AppDispatcher.handleViewAction({
actionType: ActionTypes.SET_CURRENT_ROUTE,
route: route
});
}

};

module.exports = AppActions;
30 changes: 30 additions & 0 deletions src/components/Link.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @jsx React.DOM
*/

'use strict';

var React = require('react');
var RouteActions = require('../actions/RouteActions');

var Link = React.createClass({
propTypes: {
to: React.PropTypes.string.isRequired,
children: React.PropTypes.component.isRequired
},
render() {
this.props.href =
this.props.to && this.props.to.lastIndexOf('/', 0) === 0 ?
this.props.to : '/' + this.props.to;

return this.transferPropsTo(
<a onClick={this.handleClick}>{this.props.children}</a>
);
},
handleClick(e) {
e.preventDefault();
RouteActions.setRoute(this.props.to);
}
});

module.exports = Link;
4 changes: 2 additions & 2 deletions src/components/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
'use strict';

var React = require('react');
var {Link} = require('react-router');
var Link = require('./Link.jsx');

var Navbar = React.createClass({
render() {
return (
<div className="navbar-top">
<div className="container">
<Link className="navbar-brand row" to="home">
<Link className="navbar-brand row" to="/">
<img src="/images/logo-small.png" width="38" height="38" alt="React" />
{' Facebook React Starter Kit'}
</Link>
Expand Down
2 changes: 1 addition & 1 deletion src/components/NavbarSpec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe('Navbar', () => {

beforeEach(() => {
Navbar = require('./Navbar.jsx');
component = new Navbar();
component = Navbar();
});

it('should create a new instance of Navbar', () => {
Expand Down
6 changes: 6 additions & 0 deletions src/constants/ActionTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {

// Route action types
SET_CURRENT_ROUTE: 'SET_CURRENT_ROUTE'

};
4 changes: 4 additions & 0 deletions src/constants/PayloadSources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
VIEW_ACTION: 'VIEW_ACTION',
SERVER_ACTION: 'SERVER_ACTION'
};
8 changes: 4 additions & 4 deletions src/layouts/Default.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
'use strict';

var React = require('react');
var {Link} = require('react-router');
var Link = require('../components/Link.jsx');
var Navbar = require('../components/Navbar.jsx');

var DefaultLayout = React.createClass({
Expand All @@ -19,13 +19,13 @@ var DefaultLayout = React.createClass({
<p>Complex web apps made easy</p>
</div>
</div>
<this.props.activeRouteHandler />
{this.props.children}
<div className="navbar-footer">
<div className="container">
<p className="text-muted">
{' © KriaSoft • '}
<Link to="home">Home</Link> {' • '}
<Link to="privacy">Privacy</Link>
<Link to="/">Home</Link>{' • '}
<Link to="/privacy">Privacy</Link>
</p>
</div>
</div>
Expand Down
59 changes: 31 additions & 28 deletions src/pages/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,43 @@
'use strict';

var React = require('react');
var Layout = require('../layouts/Default.jsx');

var HomePage = React.createClass({
render() {
return (
<div className="container">
<div className="row">
<div className="col-sm-4">
<h3>Runtime Components</h3>
<dl>
<dt><a href="https://facebook.github.io/react/">React</a></dt>
<dd>A JavaScript library for building user interfaces, developed by Facebook</dd>
<dt><a href="https://github.com/rackt/react-router">React-Router</a></dt>
<dd>A complete routing library for React</dd>
<dt><a href="http://getbootstrap.com/">Bootstrap</a></dt>
<dd>CSS framework for developing responsive, mobile first interfaces</dd>
</dl>
</div>
<div className="col-sm-4">
<h3>Development Tools</h3>
<dl>
<dt><a href="http://gulpjs.com">Gulp</a></dt>
<dd>JavaScript streaming build system and task automation</dd>
<dt><a href="http://webpack.github.io/">Webpack</a></dt>
<dd>Compiles front-end source code into modules / bundles</dd>
<dt><a href="http://www.browsersync.io/">BrowserSync</a></dt>
<dd>A lightweight HTTP server for development</dd>
</dl>
</div>
<div className="col-sm-4">
<h3>Fork me on GitHub</h3>
<p><a href="https://github.com/kriasoft/react-starter-kit">github.com/kriasoft/react-starter-kit</a></p>
<Layout>
<div className="container">
<div className="row">
<div className="col-sm-4">
<h3>Runtime Components</h3>
<dl>
<dt><a href="https://facebook.github.io/react/">React</a></dt>
<dd>A JavaScript library for building user interfaces, developed by Facebook</dd>
<dt><a href="https://github.com/rackt/react-router">React-Router</a></dt>
<dd>A complete routing library for React</dd>
<dt><a href="http://getbootstrap.com/">Bootstrap</a></dt>
<dd>CSS framework for developing responsive, mobile first interfaces</dd>
</dl>
</div>
<div className="col-sm-4">
<h3>Development Tools</h3>
<dl>
<dt><a href="http://gulpjs.com">Gulp</a></dt>
<dd>JavaScript streaming build system and task automation</dd>
<dt><a href="http://webpack.github.io/">Webpack</a></dt>
<dd>Compiles front-end source code into modules / bundles</dd>
<dt><a href="http://www.browsersync.io/">BrowserSync</a></dt>
<dd>A lightweight HTTP server for development</dd>
</dl>
</div>
<div className="col-sm-4">
<h3>Fork me on GitHub</h3>
<p><a href="https://github.com/kriasoft/react-starter-kit">github.com/kriasoft/react-starter-kit</a></p>
</div>
</div>
</div>
</div>
</Layout>
);
}
});
Expand Down
Loading

0 comments on commit 7580590

Please sign in to comment.