Added child routes, and config defined routes

Change-Id: I61c5a49a330a63737312d1eb6077aab02236a44f
diff --git a/src/app/core/nav/nav.html b/src/app/core/nav/nav.html
index 2bcdadd..a1292b8 100644
--- a/src/app/core/nav/nav.html
+++ b/src/app/core/nav/nav.html
@@ -1,8 +1,23 @@
 <div class="nav">
   <ul>
-    <li ng-repeat="route in vm.routes" ui-sref-active="active" ng-class="vm.isRouteActive(route)">
-      <a ng-if="route.state" ui-sref="{{route.state}}">{{route.label}}</a>
-      <a ng-if="route.url" href="#/{{route.url}}">{{route.label}}</a>
+    <li
+      ng-repeat="route in vm.routes track by $index"
+      ui-sref-active="active"
+      ng-class="vm.isRouteActive(route)">
+      <a ng-if="route.state" ui-sref="{{route.state}}" ng-click="vm.activateRoute(route)">
+        <i ng-if="route.children" class="fa fa-chevron-right"></i>
+        {{route.label}}
+      </a>
+      <a ng-if="route.url" href="#/{{route.url}}" ng-click="vm.activateRoute(route)">
+        <i ng-if="route.children" class="fa fa-chevron-right"></i>
+        {{route.label}}
+      </a>
+      <ul class="child-routes" ng-if="route.children" ng-class="{opened: route.opened}">
+        <li ng-repeat="childRoute in route.children" ui-sref-active="active">
+          <a ng-if="childRoute.state" ui-sref="{{childRoute.state}}">{{childRoute.label}}</a>
+          <a ng-if="childRoute.url" href="#/{{childRoute.url}}">{{childRoute.label}}</a>
+        </li>
+      </ul>
     </li>
   </ul>
 </div>
diff --git a/src/app/core/nav/nav.scss b/src/app/core/nav/nav.scss
index 5c2c85c..dbe60d7 100644
--- a/src/app/core/nav/nav.scss
+++ b/src/app/core/nav/nav.scss
@@ -15,7 +15,6 @@
     > li {
       display: flex;
       flex-direction: column;
-      padding: 10px 20px;
       border-bottom: 1px solid darken(grey, 20);
 
       &.active {
@@ -31,8 +30,29 @@
       }
 
       > a {
+        padding: 10px 20px;
         cursor: pointer;
       }
+
+      // child router
+      > ul {
+        height: 0;
+        overflow: hidden;
+        transition: .5s all;
+
+        > li {
+          padding-left: 20px;
+          background: darken(grey, 15);
+
+          &:hover, &.active {
+            background: darken(grey, 20);
+          }
+        }
+      }
+
+      > ul.opened {
+        height: auto;
+      }
     }
   }
 }
diff --git a/src/app/core/nav/nav.spec.ts b/src/app/core/nav/nav.spec.ts
new file mode 100644
index 0000000..fbed8ea
--- /dev/null
+++ b/src/app/core/nav/nav.spec.ts
@@ -0,0 +1,57 @@
+/// <reference path="../../../../typings/index.d.ts" />
+
+import * as $ from 'jquery';
+import 'jasmine-jquery';
+import * as angular from 'angular';
+import 'angular-mocks';
+import {IXosNavigationRoute} from '../services/navigation';
+import {xosNav} from './nav';
+
+let element, scope: angular.IRootScopeService, compile: ng.ICompileService, isolatedScope;
+
+let baseRoutes: IXosNavigationRoute[] = [
+  {label: 'Home', state: 'xos'},
+  {label: 'Core', state: 'xos.core'}
+];
+
+const NavigationService = function(){
+  this.query = () => baseRoutes;
+};
+
+describe('Nav component', () => {
+  beforeEach(() => {
+    angular
+      .module('xosNav', ['app/core/nav/nav.html', 'ui.router'])
+      .component('xosNav', xosNav)
+      .service('NavigationService', NavigationService);
+    angular.mock.module('xosNav');
+  });
+
+  beforeEach(angular.mock.inject(($rootScope: ng.IRootScopeService, $compile: ng.ICompileService) => {
+    scope = $rootScope;
+    compile = $compile;
+    element = $compile('<xos-nav></xos-nav>')($rootScope);
+    $rootScope.$digest();
+    isolatedScope = element.isolateScope();
+
+    // clear routes
+    isolatedScope.routes = [];
+  }));
+
+  it('should render a list of routes', () => {
+    const routes = $('.nav ul li', element);
+    expect(routes.length).toBe(2);
+  });
+
+  it('should render child routes', () => {
+    baseRoutes = [
+      {label: 'Home', state: 'xos'},
+      {label: 'Core', state: 'xos.core', children: [
+        {label: 'Slices', state: 'xos.core.slices', parent: 'xos.core'}
+      ]}
+    ];
+    scope.$apply();
+    const childRouteContainer = $('.child-routes', element);
+    expect(childRouteContainer.length).toBe(1);
+  });
+});
diff --git a/src/app/core/nav/nav.ts b/src/app/core/nav/nav.ts
index d978ef0..cd249b9 100644
--- a/src/app/core/nav/nav.ts
+++ b/src/app/core/nav/nav.ts
@@ -2,10 +2,11 @@
 import {IXosNavigationService, IXosNavigationRoute} from '../services/navigation';
 
 class NavCtrl {
-  static $inject = ['$state', 'NavigationService'];
+  static $inject = ['$scope', '$state', 'NavigationService'];
   public routes: IXosNavigationRoute[];
 
   constructor(
+    private $scope: ng.IScope,
     private $state: angular.ui.IStateService,
     private navigationService: IXosNavigationService
   ) {
@@ -13,12 +14,19 @@
     // - Base routes (defined from configuration based on BRAND)
     // - Autogenerated routes (nested somewhere)
     // - Service Routes (dynamically added)
-    this.routes = this.navigationService.query();
+
+    this.$scope.$watch(() => this.navigationService.query(), (routes) => {
+      this.routes = routes;
+    });
   }
 
   isRouteActive(route: IXosNavigationRoute) {
     return this.$state.current.url === route.url ? 'active' : '';
   }
+
+  activateRoute(route: IXosNavigationRoute) {
+    route.opened = !route.opened;
+  }
 }
 
 export const xosNav: angular.IComponentOptions = {