Vulcan/packages/vulcan-lib/lib/modules/routes.js

128 lines
3.5 KiB
JavaScript
Raw Normal View History

import {Components, getComponent} from './components';
2017-03-23 16:27:59 +09:00
export const Routes = {}; // will be populated on startup (see vulcan:routing)
export const RoutesTable = {}; // storage for infos about routes themselves
/*
A route is defined in the list like:
RoutesTable.foobar = {
name: 'foobar',
path: '/xyz',
component: getComponent('FooBar')
componentName: 'FooBar' // optional
}
if there there is value for parentRouteName it will look for the route and add the new route as a child of it
*/
export const addRoute = (routeOrRouteArray, parentRouteName) => {
// be sure to have an array of routes to manipulate
const addedRoutes = Array.isArray(routeOrRouteArray) ? routeOrRouteArray : [routeOrRouteArray];
//if there is a value for parentRouteName you are adding this route as new child
if (parentRouteName) {
addAsChildRoute(parentRouteName, addedRoutes);
}
else {
// modify the routes table with the new routes
addedRoutes.map(({name, path, ...properties}) => {
// check if there is already a route registered to this path
// note: destructure in order to get the first item of the array, as _.filter returns an array
const [routeWithSamePath] = _.filter(RoutesTable, route => route.path === path);
if (routeWithSamePath) {
// delete the route registered with same path
delete RoutesTable[routeWithSamePath.name];
}
// register the new route
RoutesTable[name] = {
name,
path,
...properties
};
});
}
};
/**
A route is defined in the list like: (same as above)
RoutesTable.foobar = {
name: 'foobar',
path: '/xyz',
component: getComponent('FooBar')
componentName: 'FooBar' // optional
}
NOTE: This is implemented on single level deep ONLY for now
**/
const addAsChildRoute = (parentRouteName, addedRoutes) => {
//if the parentRouteName does not exist just ignore this, silently?
if (!RoutesTable.hasOwnProperty(parentRouteName))
return;
// modify the routes table with the new routes
addedRoutes.map(({name, path, ...properties}) => {
//get the current child routes for this Route
const childRoutes = RoutesTable[parentRouteName]['childRoutes'] || [];
// check if there is already a route registered to this path
const [routeWithSamePath] = _.filter(childRoutes, route => route.path === path);
if (routeWithSamePath) {
// delete the route registered with same path
delete childRoutes[routeWithSamePath.name];
}
//append to the child routes the new route
childRoutes.push({
name,
path,
...properties
});
//register the new child route (overwriting the current which is fine)
RoutesTable[parentRouteName]['childRoutes'] = childRoutes;
});
};
export const getRoute = name => {
const routeDef = RoutesTable[name];
// components should be loaded by now (populateComponentsApp function), we can grab the component in the lookup table and assign it to the route
if (!routeDef.component && routeDef.componentName) {
routeDef.component = getComponent(routeDef.componentName);
}
return routeDef;
}
/**
* Populate the lookup table for routes to be callable
* Called once on app startup
**/
export const populateRoutesApp = () => {
// loop over each component in the list
Object.keys(RoutesTable).map(name => {
// populate an entry in the lookup table
Routes[name] = getRoute(name);
// uncomment for debug
// console.log('init route:', name);
});
}