Added child routes, and config defined routes

Change-Id: I61c5a49a330a63737312d1eb6077aab02236a44f
diff --git a/src/app/core/services/helpers/config.helpers.spec.ts b/src/app/core/services/helpers/config.helpers.spec.ts
index 44260d8..af424e4 100644
--- a/src/app/core/services/helpers/config.helpers.spec.ts
+++ b/src/app/core/services/helpers/config.helpers.spec.ts
@@ -50,13 +50,13 @@
     it('should format an array of strings', () => {
       let strings: string[] = ['camelCase', 'snake_case', 'kebab-case'];
       let labels = ['Camel case', 'Snake case', 'Kebab case'];
-      expect(service.toLabel(strings)).toEqual(labels);
+      expect(service.toLabels(strings)).toEqual(labels);
     });
 
     it('should set plural on an array of strings', () => {
       let strings: string[] = ['camelCase', 'snake_case', 'kebab-case'];
       let labels = ['Camel cases', 'Snake cases', 'Kebab cases'];
-      expect(service.toLabel(strings, true)).toEqual(labels);
+      expect(service.toLabels(strings, true)).toEqual(labels);
     });
   });
 
diff --git a/src/app/core/services/helpers/config.helpers.ts b/src/app/core/services/helpers/config.helpers.ts
index 44d3cdc..3e0af96 100644
--- a/src/app/core/services/helpers/config.helpers.ts
+++ b/src/app/core/services/helpers/config.helpers.ts
@@ -11,6 +11,7 @@
   modeldefToTableCfg(fields: IXosModelDefsField[]): any[]; // TODO use a proper interface
   pluralize(string: string, quantity?: number, count?: boolean): string;
   toLabel(string: string, pluralize?: boolean): string;
+  toLabels(string: string[], pluralize?: boolean): string[];
 }
 
 export class ConfigHelpers {
@@ -24,13 +25,15 @@
     return pluralize(string, quantity, count);
   }
 
-  toLabel(string: string, pluralize?: boolean): string {
-
-    if (angular.isArray(string)) {
-      return _.map(string, s => {
+  toLabels(strings: string[], pluralize?: boolean): string[] {
+    if (angular.isArray(strings)) {
+      return _.map(strings, s => {
         return this.toLabel(s, pluralize);
       });
     }
+  }
+
+  toLabel(string: string, pluralize?: boolean): string {
 
     if (pluralize) {
       string = this.pluralize(string);
diff --git a/src/app/core/services/navigation.spec.ts b/src/app/core/services/navigation.spec.ts
index 1096ec7..c5fb85d 100644
--- a/src/app/core/services/navigation.spec.ts
+++ b/src/app/core/services/navigation.spec.ts
@@ -6,9 +6,7 @@
 
 let service: IXosNavigationService;
 
-const defaultRoutes: IXosNavigationRoute[] = [
-  {label: 'Home', state: 'xos.dashboard'}
-];
+let defaultRoutes: IXosNavigationRoute[];
 
 describe('The Navigation service', () => {
 
@@ -18,6 +16,7 @@
     NavigationService: IXosNavigationService,
   ) => {
     service = NavigationService;
+    defaultRoutes = angular.copy(service.query());
   }));
 
   it('should return navigation routes', () => {
@@ -31,7 +30,17 @@
     ];
     service.add(testRoutes[0]);
     service.add(testRoutes[1]);
-    expect(service.query()).toEqual(defaultRoutes.concat(testRoutes));
+    const serviceRoutes = service.query();
+    expect(serviceRoutes).toEqual(defaultRoutes.concat(testRoutes));
+  });
+
+  it('should add a child route', () => {
+    const testRoute: IXosNavigationRoute = {
+      label: 'TestState', state: 'xos.test', parent: 'xos.core'
+    };
+    service.add(testRoute);
+    defaultRoutes[1].children = [testRoute];
+    expect(service.query()).toEqual(defaultRoutes);
   });
 
   it('should not add route that have both url and state', () => {
diff --git a/src/app/core/services/navigation.ts b/src/app/core/services/navigation.ts
index 04eb575..c840878 100644
--- a/src/app/core/services/navigation.ts
+++ b/src/app/core/services/navigation.ts
@@ -1,7 +1,15 @@
+/// <reference path="../../../../typings/index.d.ts" />
+
+import * as _ from 'lodash';
+import {StyleConfig} from '../../config/style.config';
+
 export interface IXosNavigationRoute {
   label: string;
   state?: string;
   url?: string;
+  parent?: string;
+  children?: [IXosNavigationRoute];
+  opened?: boolean;
 }
 
 export interface IXosNavigationService {
@@ -13,12 +21,18 @@
   private routes: IXosNavigationRoute[];
 
   constructor() {
-    this.routes = [
+    const defaultRoutes = [
+      {
+        label: 'Core',
+        state: 'xos.core'
+      },
       {
         label: 'Home',
         state: 'xos.dashboard'
       }
     ];
+    // adding configuration defined routes
+    this.routes = StyleConfig.routes.concat(defaultRoutes).reverse();
   }
 
   query() {
@@ -29,6 +43,21 @@
     if (angular.isDefined(route.state) && angular.isDefined(route.url)) {
       throw new Error('[XosNavigation] You can\'t provide both state and url');
     }
-    this.routes.push(route);
+
+
+    if (angular.isDefined(route.parent)) {
+      // route parent should be a state for now
+      const parentRoute = _.find(this.routes, {state: route.parent});
+
+      if (angular.isArray(parentRoute.children)) {
+        parentRoute.children.push(route);
+      }
+      else {
+        parentRoute.children = [route];
+      }
+    }
+    else {
+      this.routes.push(route);
+    }
   }
 }
diff --git a/src/app/core/services/runtime-states.ts b/src/app/core/services/runtime-states.ts
index 401075a..bc99a8e 100644
--- a/src/app/core/services/runtime-states.ts
+++ b/src/app/core/services/runtime-states.ts
@@ -1,10 +1,10 @@
 import {IXosState} from '../../../index';
 export interface IRuntimeStatesService {
-  addState(name: string, state: angular.ui.IState): void;
+  addState(name: string, state: ng.ui.IState): void;
 }
 
-export function RuntimeStates($stateProvider: angular.ui.IStateProvider): angular.IServiceProvider {
-  this.$get = function($state: angular.ui.IStateService) { // for example
+export function RuntimeStates($stateProvider: ng.ui.IStateProvider): ng.IServiceProvider {
+  this.$get = function($state: ng.ui.IStateService) {
     return {
       addState: function(name: string, state: IXosState) {
         $stateProvider.state(name, state);