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];
2017-04-07 18:41:33 +09:00
// if there is a value for parentRouteName you are adding this route as new child
if (parentRouteName) {
2017-04-07 18:41:33 +09:00
addAsChildRoute(parentRouteName, addedRoutes);
2017-04-07 18:41:33 +09:00
} 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) => {
2017-04-07 18:41:33 +09:00
// if the parentRouteName does not exist, error
if (!RoutesTable[parentRouteName]) {
2017-04-07 18:41:33 +09:00
throw new Error(`Route ${parentRouteName} doesn't exist`)
}
// modify the routes table with the new routes
addedRoutes.map(({name, path, ...properties}) => {
2017-04-07 18:41:33 +09:00
// 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];
}
2017-04-07 18:41:33 +09:00
// append to the child routes the new route
childRoutes.push({
name,
path,
...properties
});
2017-04-07 18:41:33 +09:00
// 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);
});
}