diff --git a/src/js/App.jsx b/src/js/App.jsx index fb264da..1230732 100644 --- a/src/js/App.jsx +++ b/src/js/App.jsx @@ -27,6 +27,42 @@ let routes = { let blank = false; +// Build a link to a page. +let find = ({ to, params, query }) => { + let $url; + let re = /:[^\/]+/g; + + // Skip empty objects. + [ params, query ] = [_.isObject(params) ? params : {}, query ].map(o => _.pick(o, _.identity)); + + // Find among the routes. + _.find(routes, (name, url) => { + if (name != to) return; + let matches = url.match(re); + + // Do not match on the number of params. + if (_.keys(params).length != (matches || []).length) return; + + // Do not match on the name of params. + if (!_.every(matches, m => m.slice(1) in params)) return; + + // Fill in the params. + $url = url.replace(re, m => params[m.slice(1)]); + + // Found it. + return true; + }); + + if (!$url) throw new Error(`path ${to} ${JSON.stringify(params)} is not recognized`); + + // Append querystring. + if (_.keys(query).length) { + $url += "?" + _.map(query, (v, k) => `${k}=${v}`).join("&"); + } + + return $url; +}; + export default React.createClass({ displayName: 'App.jsx', @@ -37,44 +73,14 @@ export default React.createClass({ statics: { // Build a link to a page. - link(to, params, query) { - let $url; - let re = /:[^\/]+/g; - - // Skip empty objects. - [ params, query ] = [_.isObject(params) ? params : {}, query ].map(o => _.pick(o, _.identity)); - - // Find among the routes. - _.find(routes, (name, url) => { - if (name != to) return; - let matches = url.match(re); - - // Do not match on the number of params. - if (_.keys(params).length != (matches || []).length) return; - - // Do not match on the name of params. - if (!_.every(matches, m => m.slice(1) in params)) return; - - // Fill in the params. - $url = url.replace(re, m => params[m.slice(1)]); - - // Found it. - return true; - }); - - if (!$url) console.log(`path ${to} ${JSON.stringify(params)} is not recognized`); - - // Append querystring. - if (_.keys(query).length) { - $url += "?" + _.map(query, (v, k) => `${k}=${v}`).join("&"); - } - - return $url; + link: (route) => { + return find(route); }, - // Route to a link. - // TODO: make this a named route. - navigate: navigate + navigate: (route) => { + let fn = _.isString(route) ? _.identity : find; + navigate(fn(route)); + } }, // Show projects. diff --git a/src/js/components/AddProjectForm.jsx b/src/js/components/AddProjectForm.jsx index c319a09..3920edb 100644 --- a/src/js/components/AddProjectForm.jsx +++ b/src/js/components/AddProjectForm.jsx @@ -30,7 +30,7 @@ export default React.createClass({ let [ owner, name ] = this.state.val.split('/'); actions.emit('projects.add', { owner, name }); // Redirect to the dashboard. - App.navigate('/'); + App.navigate({ 'to': 'projects' }); }, getInitialState() { diff --git a/src/js/components/Link.jsx b/src/js/components/Link.jsx index c075be0..2fb35e5 100644 --- a/src/js/components/Link.jsx +++ b/src/js/components/Link.jsx @@ -6,20 +6,20 @@ export default React.createClass({ displayName: 'Link.jsx', - _route(link, evt) { + _navigate(link, evt) { App.navigate(link); evt.preventDefault(); }, render() { let route = this.props.route; - let link = App.link(route.to, route.params, route.query); + let link = App.link(route); return ( {this.props.children}