You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2018/12/14 02:09:32 UTC

[servicecomb-pack] branch master updated: [SCB-935] Saga transaction management console UI initial commit (#317)

This is an automated email from the ASF dual-hosted git repository.

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-pack.git


The following commit(s) were added to refs/heads/master by this push:
     new 96b1514  [SCB-935] Saga transaction management console UI initial commit (#317)
96b1514 is described below

commit 96b15140f63a57ee8161bbfb024210188831db8d
Author: Anvith KS <an...@huawei.com>
AuthorDate: Fri Dec 14 07:39:28 2018 +0530

    [SCB-935] Saga transaction management console UI initial commit (#317)
    
    * Saga transaction management console UI initial commit
    
    * Removed unnecessary files and updated the icons.
    
    * Updated dashboard as per new ALpha API's.
    
    * Fixed some UI style issues.
    
    * Fixed spelling error.
    
    * Updated ASF headers. removed commented code.
    
    * Docker image reference changed.
    
    * Updated the Readme file.
    
    * Added missing license information
    
    * Added license copies. Added usage information and version number.
    
    * Updated license information in the scss files.
---
 .../saga-servicecomb-demo/docker-compose.yaml      |   2 +
 saga-distribution/src/release/LICENSE              |   7 +-
 saga-distribution/src/release/NOTICE               |   6 +-
 .../src/release/licenses/LICENSE-ngxadmin          |  21 ++
 .../src/main/resources/saga-frontend/README.md     |  32 +++
 .../src/main/resources/saga-frontend/angular.json  |  89 ++++++
 .../src/main/resources/saga-frontend/package.json  |  77 +++++
 .../saga-frontend/src/app/@core/core.module.ts     |  80 ++++++
 .../src/app/@core/data/data.module.ts              |  34 +++
 .../src/app/@core/data/saga-events.service.ts      |  71 +++++
 .../src/app/@core/data/state.service.ts            |  97 +++++++
 .../src/app/@core/module-import-guard.ts           |  21 ++
 .../src/app/@core/utils/analytics.service.ts       |  37 +++
 .../src/app/@core/utils/util.service.ts            | 127 +++++++++
 .../@theme/components/footer/footer.component.scss |  53 ++++
 .../@theme/components/footer/footer.component.ts   |  32 +++
 .../@theme/components/header/header.component.html |  35 +++
 .../@theme/components/header/header.component.scss | 235 ++++++++++++++++
 .../@theme/components/header/header.component.ts   |  53 ++++
 .../src/app/@theme/components/index.ts             |  11 +
 .../components/switcher/switcher.component.scss    | 135 +++++++++
 .../components/switcher/switcher.component.ts      |  65 +++++
 .../theme-settings/theme-settings.component.scss   |  94 +++++++
 .../theme-settings/theme-settings.component.ts     |  63 +++++
 .../theme-switcher/theme-switcher.component.html   |  21 ++
 .../theme-switcher/theme-switcher.component.scss   |  73 +++++
 .../theme-switcher/theme-switcher.component.ts     |  24 ++
 .../theme-switcher-list.component.scss             |  99 +++++++
 .../themes-switcher-list.component.ts              |  56 ++++
 .../app/@theme/layouts/default/default.layout.scss | 187 ++++++++++++
 .../app/@theme/layouts/default/default.layout.ts   | 119 ++++++++
 .../saga-frontend/src/app/@theme/layouts/index.ts  |   7 +
 .../layouts/one-column/one-column.layout.scss      | 180 ++++++++++++
 .../@theme/layouts/one-column/one-column.layout.ts |  56 ++++
 .../src/app/@theme/pipes/capitalize.pipe.ts        |  16 ++
 .../saga-frontend/src/app/@theme/pipes/index.ts    |  11 +
 .../src/app/@theme/pipes/no-sanitize.pipe.ts       |  28 ++
 .../app/@theme/pipes/number-with-commas.pipe.ts    |  14 +
 .../src/app/@theme/pipes/plural.pipe.ts            |  19 ++
 .../src/app/@theme/pipes/round.pipe.ts             |  14 +
 .../src/app/@theme/pipes/timing.pipe.ts            |  23 ++
 .../src/app/@theme/styles/bootstrap-rtl.scss       | 216 ++++++++++++++
 .../src/app/@theme/styles/font-size.scss           |  26 ++
 .../src/app/@theme/styles/pace.theme.scss          |  40 +++
 .../src/app/@theme/styles/styles.scss              |  54 ++++
 .../src/app/@theme/styles/theme.corporate.ts       | 309 ++++++++++++++++++++
 .../src/app/@theme/styles/theme.cosmic.ts          | 309 ++++++++++++++++++++
 .../src/app/@theme/styles/theme.default.ts         | 312 +++++++++++++++++++++
 .../src/app/@theme/styles/themes.scss              | 120 ++++++++
 .../saga-frontend/src/app/@theme/theme.module.ts   | 124 ++++++++
 .../saga-frontend/src/app/app-routing.module.ts    |  43 +++
 .../saga-frontend/src/app/app.component.ts         |  22 ++
 .../resources/saga-frontend/src/app/app.module.ts  |  38 +++
 .../count-cards/count-cards.component.html         |  23 ++
 .../count-cards/count-cards.component.scss         |  37 +++
 .../dashboard/count-cards/count-cards.component.ts |  38 +++
 .../app/pages/dashboard/dashboard.component.html   |  64 +++++
 .../app/pages/dashboard/dashboard.component.scss   |  44 +++
 .../src/app/pages/dashboard/dashboard.component.ts | 196 +++++++++++++
 .../src/app/pages/dashboard/dashboard.module.ts    |  39 +++
 .../recent-table/recent-table.component.html       |  60 ++++
 .../recent-table/recent-table.component.scss       |  19 ++
 .../recent-table/recent-table.component.ts         |  72 +++++
 .../miscellaneous/miscellaneous-routing.module.ts  |  30 ++
 .../pages/miscellaneous/miscellaneous.component.ts |  15 +
 .../pages/miscellaneous/miscellaneous.module.ts    |  19 ++
 .../not-found/not-found.component.html             |  29 ++
 .../not-found/not-found.component.scss             |  43 +++
 .../miscellaneous/not-found/not-found.component.ts |  22 ++
 .../saga-frontend/src/app/pages/pages-menu.ts      |  63 +++++
 .../src/app/pages/pages-routing.module.ts          |  70 +++++
 .../saga-frontend/src/app/pages/pages.component.ts |  33 +++
 .../saga-frontend/src/app/pages/pages.module.ts    |  44 +++
 .../pages/transactions/customRender.component.ts   |  47 ++++
 .../transactions/findTransaction.component.html    |  48 ++++
 .../transactions/findTransaction.component.ts      |  79 ++++++
 .../pages/transactions/transactions.component.html |  15 +
 .../pages/transactions/transactions.component.ts   |  53 ++++
 .../app/pages/transactions/transactions.module.ts  |  36 +++
 .../transactions/transactionsTable.component.html  |  34 +++
 .../transactions/transactionsTable.component.scss  |  20 ++
 .../transactions/transactionsTable.component.ts    | 135 +++++++++
 .../src/assets/images/square_pattern.svg           |   1 +
 .../src/assets/images/square_pattern_cosmic.svg    |   1 +
 .../src/environments/environment.prod.ts           |   9 +
 .../saga-frontend/src/environments/environment.ts  |  15 +
 .../main/resources/saga-frontend/src/favicon.ico   | Bin 0 -> 798 bytes
 .../main/resources/saga-frontend/src/favicon.png   | Bin 0 -> 29126 bytes
 .../main/resources/saga-frontend/src/index.html    |  48 ++++
 .../src/main/resources/saga-frontend/src/main.ts   |  17 ++
 .../main/resources/saga-frontend/src/polyfills.ts  |  76 +++++
 .../resources/saga-frontend/src/tsconfig.app.json  |  27 ++
 .../main/resources/saga-frontend/src/typings.d.ts  |  15 +
 .../src/main/resources/saga-frontend/tsconfig.json |  22 ++
 94 files changed, 5693 insertions(+), 2 deletions(-)

diff --git a/saga-demo/saga-servicecomb-demo/docker-compose.yaml b/saga-demo/saga-servicecomb-demo/docker-compose.yaml
index 036a206..88b4e24 100644
--- a/saga-demo/saga-servicecomb-demo/docker-compose.yaml
+++ b/saga-demo/saga-servicecomb-demo/docker-compose.yaml
@@ -36,6 +36,8 @@ services:
     hostname: alpha-server
     links:
       - "database:postgresql.servicecomb.io"
+    ports:
+      - "8090:8090"
     environment:
       - JAVA_OPTS=-Dspring.profiles.active=prd
     healthcheck:
diff --git a/saga-distribution/src/release/LICENSE b/saga-distribution/src/release/LICENSE
index 1c06754..a440d44 100644
--- a/saga-distribution/src/release/LICENSE
+++ b/saga-distribution/src/release/LICENSE
@@ -262,7 +262,12 @@ org.slf4j:log4j-over-slf4j:jar:1.7.25
 This product bundles slf4j libraries which is licensed under the
 MIT license.
 For details, see http://www.slf4j.org
-You can find a copy of the License at licenses/LICENSE-slf4j
+You can find a copy of the License at licenses/LICENSE-slf4j  
+===========================================================================
+This product bundles ngx-admin libraries which is licensed under the
+MIT license.
+For details, see https://github.com/akveo/ngx-admin
+You can find a copy of the License at licenses/LICENSE-ngxadmin
 
 ===========================================================================
 For com.google.protobuf:protobuf-java:bundle:3.5.1
diff --git a/saga-distribution/src/release/NOTICE b/saga-distribution/src/release/NOTICE
index 5a61c81..19bc823 100644
--- a/saga-distribution/src/release/NOTICE
+++ b/saga-distribution/src/release/NOTICE
@@ -50,4 +50,8 @@ See licenses/NOTICE-tomcat
 ================================================================
 Notice for Netty tcnative
 
-See licenses/NOTICE-netty-tcnative
+See licenses/NOTICE-netty-tcnative  
+================================================================
+Notice for akveo ngx-admin
+
+See licenses/LICENSE-ngxadmin
\ No newline at end of file
diff --git a/saga-distribution/src/release/licenses/LICENSE-ngxadmin b/saga-distribution/src/release/licenses/LICENSE-ngxadmin
new file mode 100644
index 0000000..93092fd
--- /dev/null
+++ b/saga-distribution/src/release/licenses/LICENSE-ngxadmin
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/saga-web/src/main/resources/saga-frontend/README.md b/saga-web/src/main/resources/saga-frontend/README.md
new file mode 100644
index 0000000..ee62a37
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/README.md
@@ -0,0 +1,32 @@
+# Saga Web UI -  A Transaction viewer dashboard
+This project is using [ngx-admin](https://github.com/akveo/ngx-admin), [here you can find documentation and other useful articles](https://akveo.github.io/nebular/docs/getting-started/what-is-nebular).
+
+### How to run the UI
+To install saga-frontend on your machine you need to have the following tools installed:
+
+- Git - https://git-scm.com
+- Node.js - https://nodejs.org. Please note the version should be >=8
+- Npm - Node.js package manager, comes with Node.js. Please make sure npm version is >=5
+- You might also need some specific native packages depending on your operating system like build-essential on Ubuntu
+- Clone the repository
+
+```
+git clone https://github.com/apache/servicecomb-pack
+```  
+
+- Navigate to the frontend folder  
+
+```
+cd servicecomb-pack/saga-web/src/main/resources/saga-frontend && npm i
+```  
+- To run a local copy
+```
+npm start  
+```  
+Go to http://0.0.0.0:4200 or http://localhost:4200 in your browser.  
+- To create a bundle in production mode
+```
+npm run build:prod
+```  
+This will clear up your **dist** folder (where release files are located) and generate a release build. Now you can copy the sources from the **dist** folder and simply put it under the **static** folder or under a web server.
+
diff --git a/saga-web/src/main/resources/saga-frontend/angular.json b/saga-web/src/main/resources/saga-frontend/angular.json
new file mode 100644
index 0000000..df102a8
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/angular.json
@@ -0,0 +1,89 @@
+{
+  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+  "version": 1,
+  "newProjectRoot": "projects",
+  "projects": {
+    "saga-frontend": {
+      "root": "",
+      "sourceRoot": "src",
+      "projectType": "application",
+      "architect": {
+        "build": {
+          "builder": "@angular-devkit/build-angular:browser",
+          "options": {
+            "preserveSymlinks": true,
+            "outputPath": "dist",
+            "index": "src/index.html",
+            "main": "src/main.ts",
+            "tsConfig": "src/tsconfig.app.json",
+            "polyfills": "src/polyfills.ts",
+            "assets": [
+              "src/assets",
+              "src/favicon.ico",
+              "src/favicon.png"
+            ],
+            "styles": [
+              "node_modules/bootstrap/dist/css/bootstrap.css",
+              "node_modules/typeface-exo/index.css",
+              "node_modules/roboto-fontface/css/roboto/roboto-fontface.css",
+              "node_modules/ionicons/scss/ionicons.scss",
+              "node_modules/@fortawesome/fontawesome-free/css/all.css",
+              "node_modules/socicon/css/socicon.css",
+              "node_modules/nebular-icons/scss/nebular-icons.scss",
+              "node_modules/pace-js/templates/pace-theme-flash.tmpl.css",
+              "src/app/@theme/styles/styles.scss"
+            ],
+            "scripts": [
+              "node_modules/pace-js/pace.min.js"            ]
+          },
+          "configurations": {
+            "production": {
+              "optimization": true,
+              "outputHashing": "all",
+              "sourceMap": false,
+              "extractCss": true,
+              "namedChunks": false,
+              "aot": true,
+              "extractLicenses": true,
+              "vendorChunk": false,
+              "buildOptimizer": true,
+              "fileReplacements": [
+                {
+                  "replace": "src/environments/environment.ts",
+                  "with": "src/environments/environment.prod.ts"
+                }
+              ]
+            }
+          }
+        },
+        "serve": {
+          "builder": "@angular-devkit/build-angular:dev-server",
+          "options": {
+            "browserTarget": "saga-frontend:build"
+          },
+          "configurations": {
+            "production": {
+              "browserTarget": "saga-frontend:build:production"
+            }
+          }
+        },
+        "extract-i18n": {
+          "builder": "@angular-devkit/build-angular:extract-i18n",
+          "options": {
+            "browserTarget": "saga-frontend:build"
+          }
+        }
+      }
+    }
+  },
+  "defaultProject": "saga-frontend",
+  "schematics": {
+    "@schematics/angular:component": {
+      "prefix": "ngx",
+      "styleext": "scss"
+    },
+    "@schematics/angular:directive": {
+      "prefix": "ngx"
+    }
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/package.json b/saga-web/src/main/resources/saga-frontend/package.json
new file mode 100644
index 0000000..c8c9d92
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/package.json
@@ -0,0 +1,77 @@
+{
+  "name": "saga-frontend",
+  "version": "0.2.0",
+  "license": "Apache 2.0",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/apache/incubator-servicecomb-saga.git"
+  },
+  "bugs": {
+    "url": "https://github.com/apache/incubator-servicecomb-saga/issues"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "IE 11"
+  ],
+  "scripts": {
+    "ng": "ng",
+    "conventional-changelog": "conventional-changelog",
+    "start": "ng serve --port 5200",
+    "build": "ng build",
+    "build:prod": "npm run build -- --prod --aot",
+    "prepush": "npm run lint:ci",
+    "release:changelog": "npm run conventional-changelog -- -p angular -i CHANGELOG.md -s"
+  },
+  "dependencies": {
+    "@angular/animations": "6.0.0",
+    "@angular/common": "6.0.0",
+    "@angular/compiler": "6.0.0",
+    "@angular/core": "6.0.0",
+    "@angular/forms": "6.0.0",
+    "@angular/http": "6.0.0",
+    "@angular/platform-browser": "6.0.0",
+    "@angular/platform-browser-dynamic": "6.0.0",
+    "@angular/router": "6.0.0",
+    "@nebular/auth": "2.0.0-rc.10",
+    "@nebular/security": "2.0.0-rc.10",
+    "@nebular/theme": "2.0.0-rc.10",
+    "@ng-bootstrap/ng-bootstrap": "1.0.0",
+    "angular2-toaster": "6.0.0",
+    "bootstrap": "4.0.0",
+    "classlist.js": "1.1.20150312",
+    "core-js": "2.5.1",
+    "intl": "1.2.5",
+    "ionicons": "2.0.1",
+    "nebular-icons": "1.0.9",
+    "ng2-completer": "2.0.8",
+    "ng2-smart-table": "1.3.5",
+    "normalize.css": "6.0.0",
+    "pace-js": "1.0.2",
+    "roboto-fontface": "0.8.0",
+    "rxjs": "^6.1.0",
+    "rxjs-compat": "^6.1.0",
+    "socicon": "3.0.5",
+    "typeface-exo": "0.0.22",
+    "underscore": "^1.9.1",
+    "web-animations-js": "2.2.5",
+    "zone.js": "^0.8.26"
+  },
+  "devDependencies": {
+    "@angular/cli": "6.0.0",
+    "@angular/compiler-cli": "6.0.0",
+    "@angular/language-service": "6.0.0",
+    "@compodoc/compodoc": "1.0.1",
+    "@fortawesome/fontawesome-free": "^5.2.0",
+    "@types/d3-color": "1.0.5",
+    "@types/node": "6.0.90",
+    "codelyzer": "4.0.2",
+    "conventional-changelog-cli": "1.3.4",
+    "husky": "0.13.3",
+    "npm-run-all": "4.0.2",
+    "rimraf": "2.6.1",
+    "ts-node": "3.2.2",
+    "typescript": "2.7.2",
+    "@angular-devkit/build-angular": "~0.6.0"
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@core/core.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/@core/core.module.ts
new file mode 100644
index 0000000..011ea3c
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@core/core.module.ts
@@ -0,0 +1,80 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { NbAuthModule, NbDummyAuthStrategy } from '@nebular/auth';
+import { NbSecurityModule, NbRoleProvider } from '@nebular/security';
+import { of as observableOf } from 'rxjs';
+
+import { throwIfAlreadyLoaded } from './module-import-guard';
+import { DataModule } from './data/data.module';
+import { AnalyticsService } from './utils/analytics.service';
+import { UtilService } from './utils/util.service';
+
+
+export class NbSimpleRoleProvider extends NbRoleProvider {
+  getRole() {
+    // here you could provide any role based on any auth flow
+    return observableOf('guest');
+  }
+}
+
+export const NB_CORE_PROVIDERS = [
+  ...DataModule.forRoot().providers,
+  ...NbAuthModule.forRoot({
+
+    strategies: [
+      NbDummyAuthStrategy.setup({
+        name: 'email',
+        delay: 3000,
+      }),
+    ],
+  }).providers,
+
+  NbSecurityModule.forRoot({
+    accessControl: {
+      guest: {
+        view: '*',
+      },
+      user: {
+        parent: 'guest',
+        create: '*',
+        edit: '*',
+        remove: '*',
+      },
+    },
+  }).providers,
+
+  {
+    provide: NbRoleProvider, useClass: NbSimpleRoleProvider,
+  },
+  AnalyticsService,
+  UtilService,
+];
+
+@NgModule({
+  imports: [
+    CommonModule,
+  ],
+  exports: [
+    NbAuthModule,
+  ],
+  declarations: [],
+})
+export class CoreModule {
+  constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
+    throwIfAlreadyLoaded(parentModule, 'CoreModule');
+  }
+
+  static forRoot(): ModuleWithProviders {
+    return <ModuleWithProviders>{
+      ngModule: CoreModule,
+      providers: [
+        ...NB_CORE_PROVIDERS,
+      ],
+    };
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@core/data/data.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/@core/data/data.module.ts
new file mode 100644
index 0000000..221e392
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@core/data/data.module.ts
@@ -0,0 +1,34 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { NgModule, ModuleWithProviders } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { SagaeventsService } from './saga-events.service';
+import { StateService } from './state.service';
+
+const SERVICES = [
+  SagaeventsService,
+  StateService,
+];
+
+@NgModule({
+  imports: [
+    CommonModule,
+  ],
+  providers: [
+    ...SERVICES,
+  ],
+})
+export class DataModule {
+  static forRoot(): ModuleWithProviders {
+    return <ModuleWithProviders>{
+      ngModule: DataModule,
+      providers: [
+        ...SERVICES,
+      ],
+    };
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@core/data/saga-events.service.ts b/saga-web/src/main/resources/saga-frontend/src/app/@core/data/saga-events.service.ts
new file mode 100644
index 0000000..3517d70
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@core/data/saga-events.service.ts
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable } from 'rxjs/Observable';
+
+
+import { environment } from '../../../environments/environment';
+
+const API_URL = environment.apiUrl;
+
+@Injectable()
+export class SagaeventsService {
+
+  private events;
+
+  constructor(private http: HttpClient) {
+    
+  }
+
+  public getRecentTransactions(status: any, count?: number): Observable<any> {
+    let url;
+    if(status && status.length){
+      if(count){
+        url = API_URL + '/saga/recent?status=' + status + '&count=' + count; 
+      } else{
+        url = API_URL + '/saga/recent?status=' + status + '&count=5';
+      }
+    }
+    return this.http.get(url, {observe: 'response'});
+  }
+
+  public findTransaction(gid?: any, name?: string): Observable<any> {
+    let url;
+      if(gid){
+        url = API_URL + '/saga/findTransactions?globalTxID=' + gid ; 
+      } else if(name){
+        url = API_URL + '/saga/findTransactions?microServiceName=' + name ;
+      } else {
+        url = API_URL + '/saga/findTransactions';
+      }
+    return this.http.get(url, {observe: 'response'});
+  }
+
+  public getTransactions(status: any): Observable<any> {
+    let url;
+    if(status && status.length){
+      url = API_URL + '/saga/transactions?status=' + status;
+    }
+    return this.http.get(url, {observe: 'response'});
+  }
+
+  public getAllStats(): Observable<any> {
+    return this.http.get(API_URL + '/saga/stats', {observe: 'response'});
+  }
+
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@core/data/state.service.ts b/saga-web/src/main/resources/saga-frontend/src/app/@core/data/state.service.ts
new file mode 100644
index 0000000..2bb676b
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@core/data/state.service.ts
@@ -0,0 +1,97 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Injectable, OnDestroy } from '@angular/core';
+import { of as observableOf,  Observable,  BehaviorSubject } from 'rxjs';
+import { takeWhile } from 'rxjs/operators';
+
+import { NbLayoutDirectionService, NbLayoutDirection } from '@nebular/theme';
+
+@Injectable()
+export class StateService implements OnDestroy {
+
+  protected layouts: any = [
+    {
+      name: 'One Column',
+      icon: 'nb-layout-default',
+      id: 'one-column',
+      selected: true,
+    },
+    {
+      name: 'Two Column',
+      icon: 'nb-layout-two-column',
+      id: 'two-column',
+    },
+    {
+      name: 'Center Column',
+      icon: 'nb-layout-centre',
+      id: 'center-column',
+    },
+  ];
+
+  protected sidebars: any = [
+    {
+      name: 'Sidebar at layout start',
+      icon: 'nb-layout-sidebar-left',
+      id: 'start',
+      selected: true,
+    },
+    {
+      name: 'Sidebar at layout end',
+      icon: 'nb-layout-sidebar-right',
+      id: 'end',
+    },
+  ];
+
+  protected layoutState$ = new BehaviorSubject(this.layouts[0]);
+  protected sidebarState$ = new BehaviorSubject(this.sidebars[0]);
+
+  alive = true;
+
+  constructor(directionService: NbLayoutDirectionService) {
+    directionService.onDirectionChange()
+      .pipe(takeWhile(() => this.alive))
+      .subscribe(direction => this.updateSidebarIcons(direction));
+
+    this.updateSidebarIcons(directionService.getDirection());
+  }
+
+  ngOnDestroy() {
+    this.alive = false;
+  }
+
+  private updateSidebarIcons(direction: NbLayoutDirection) {
+    const [ startSidebar, endSidebar ] = this.sidebars;
+    const isLtr = direction === NbLayoutDirection.LTR;
+    const startIconClass = isLtr ? 'nb-layout-sidebar-left' : 'nb-layout-sidebar-right';
+    const endIconClass = isLtr ? 'nb-layout-sidebar-right' : 'nb-layout-sidebar-left';
+    startSidebar.icon = startIconClass;
+    endSidebar.icon = endIconClass;
+  }
+
+  setLayoutState(state: any): any {
+    this.layoutState$.next(state);
+  }
+
+  getLayoutStates(): Observable<any[]> {
+    return observableOf(this.layouts);
+  }
+
+  onLayoutState(): Observable<any> {
+    return this.layoutState$.asObservable();
+  }
+
+  setSidebarState(state: any): any {
+    this.sidebarState$.next(state);
+  }
+
+  getSidebarStates(): Observable<any[]> {
+    return observableOf(this.sidebars);
+  }
+
+  onSidebarState(): Observable<any> {
+    return this.sidebarState$.asObservable();
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@core/module-import-guard.ts b/saga-web/src/main/resources/saga-frontend/src/app/@core/module-import-guard.ts
new file mode 100644
index 0000000..932555e
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@core/module-import-guard.ts
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export function throwIfAlreadyLoaded(parentModule: any, moduleName: string) {
+  if (parentModule) {
+    throw new Error(`${moduleName} has already been loaded. Import Core modules in the AppModule only.`);
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@core/utils/analytics.service.ts b/saga-web/src/main/resources/saga-frontend/src/app/@core/utils/analytics.service.ts
new file mode 100644
index 0000000..592947f
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@core/utils/analytics.service.ts
@@ -0,0 +1,37 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Injectable } from '@angular/core';
+import { NavigationEnd, Router } from '@angular/router';
+import { Location } from '@angular/common';
+import { filter } from 'rxjs/operators';
+
+declare const ga: any;
+
+@Injectable()
+export class AnalyticsService {
+  private enabled: boolean;
+
+  constructor(private location: Location, private router: Router) {
+    this.enabled = false;
+  }
+
+  trackPageViews() {
+    if (this.enabled) {
+      this.router.events.pipe(
+        filter((event) => event instanceof NavigationEnd),
+      )
+        .subscribe(() => {
+          ga('send', {hitType: 'pageview', page: this.location.path()});
+        });
+    }
+  }
+
+  trackEvent(eventName: string) {
+    if (this.enabled) {
+      ga('send', 'event', eventName);
+    }
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@core/utils/util.service.ts b/saga-web/src/main/resources/saga-frontend/src/app/@core/utils/util.service.ts
new file mode 100644
index 0000000..ed75fd1
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@core/utils/util.service.ts
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Injectable } from '@angular/core';
+import { ToasterService, ToasterConfig, Toast, BodyOutputType } from 'angular2-toaster';
+import 'style-loader!angular2-toaster/toaster.css';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class UtilService {
+
+  constructor(private toasterService: ToasterService) { }
+
+  config: ToasterConfig;
+
+  positions = 'toast-bottom-right';
+  animationType = 'fade';
+  timeout = 5000;
+  toastsLimit = 5;
+
+  isNewestOnTop = true;
+  isHideOnClick = true;
+  isDuplicatesPrevented = false;
+  isCloseButton = true;
+
+  success (title: string, body: string, params?: any) {
+    this.config = new ToasterConfig({
+      positionClass: params && params.position?params.position:this.positions,
+      timeout:  params && params.timeout?params.timeout:this.timeout,
+      newestOnTop:  params && params.isNewestOnTop?params.isNewestOnTop:this.isNewestOnTop,
+      tapToDismiss:  params && params.isHideOnClick?params.isHideOnClick:this.isHideOnClick,
+      preventDuplicates:  params && params.isDuplicatesPrevented?params.isDuplicatesPrevented:this.isDuplicatesPrevented,
+      animation:  params && params.animationType?params.animationType:this.animationType,
+      limit:   params && params.toastsLimit?params.toastsLimit:this.toastsLimit,
+    });
+    const toast: Toast = {
+      type: 'success',
+      title: title,
+      body: body,
+      timeout:  params && params.timeout?params.timeout:this.timeout,
+      showCloseButton:  params && params.isCloseButton?params.isCloseButton:this.isCloseButton,
+      bodyOutputType: BodyOutputType.TrustedHtml,
+    };
+    this.toasterService.popAsync(toast);
+  }
+
+  error (title: string, body: string, params?: any) {
+    this.config = new ToasterConfig({
+      positionClass: params && params.position?params.position:this.positions,
+      timeout:  params && params.timeout?params.timeout:this.timeout,
+      newestOnTop:  params && params.isNewestOnTop?params.isNewestOnTop:this.isNewestOnTop,
+      tapToDismiss:  params && params.isHideOnClick?params.isHideOnClick:this.isHideOnClick,
+      preventDuplicates:  params && params.isDuplicatesPrevented?params.isDuplicatesPrevented:this.isDuplicatesPrevented,
+      animation:  params && params.animationType?params.animationType:this.animationType,
+      limit:   params && params.toastsLimit?params.toastsLimit:this.toastsLimit,
+    });
+    const toast: Toast = {
+      type: 'error',
+      title: title,
+      body: body,
+      timeout:  params && params.timeout?params.timeout:this.timeout,
+      showCloseButton:  params && params.isCloseButton?params.isCloseButton:this.isCloseButton,
+      bodyOutputType: BodyOutputType.TrustedHtml,
+    };
+    this.toasterService.popAsync(toast);
+  }
+
+  warning (title: string, body: string, params?: any) {
+    this.config = new ToasterConfig({
+      positionClass: params && params.position?params.position:this.positions,
+      timeout:  params && params.timeout?params.timeout:this.timeout,
+      newestOnTop:  params && params.isNewestOnTop?params.isNewestOnTop:this.isNewestOnTop,
+      tapToDismiss:  params && params.isHideOnClick?params.isHideOnClick:this.isHideOnClick,
+      preventDuplicates:  params && params.isDuplicatesPrevented?params.isDuplicatesPrevented:this.isDuplicatesPrevented,
+      animation:  params && params.animationType?params.animationType:this.animationType,
+      limit:   params && params.toastsLimit?params.toastsLimit:this.toastsLimit,
+    });
+    const toast: Toast = {
+      type: 'warning',
+      title: title,
+      body: body,
+      timeout:  params && params.timeout?params.timeout:this.timeout,
+      showCloseButton:  params && params.isCloseButton?params.isCloseButton:this.isCloseButton,
+      bodyOutputType: BodyOutputType.TrustedHtml,
+    };
+    this.toasterService.popAsync(toast);
+  }
+
+  info (title: string, body: string, params?: any) {
+    this.config = new ToasterConfig({
+      positionClass: params && params.position?params.position:this.positions,
+      timeout:  params && params.timeout?params.timeout:this.timeout,
+      newestOnTop:  params && params.isNewestOnTop?params.isNewestOnTop:this.isNewestOnTop,
+      tapToDismiss:  params && params.isHideOnClick?params.isHideOnClick:this.isHideOnClick,
+      preventDuplicates:  params && params.isDuplicatesPrevented?params.isDuplicatesPrevented:this.isDuplicatesPrevented,
+      animation:  params && params.animationType?params.animationType:this.animationType,
+      limit:   params && params.toastsLimit?params.toastsLimit:this.toastsLimit,
+    });
+    const toast: Toast = {
+      type: 'info',
+      title: title,
+      body: body,
+      timeout:  params && params.timeout?params.timeout:this.timeout,
+      showCloseButton:  params && params.isCloseButton?params.isCloseButton:this.isCloseButton,
+      bodyOutputType: BodyOutputType.TrustedHtml,
+    };
+    this.toasterService.popAsync(toast);
+  }
+
+  clearToasts() {
+    this.toasterService.clear();
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/footer/footer.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/footer/footer.component.scss
new file mode 100644
index 0000000..a7a85b4
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/footer/footer.component.scss
@@ -0,0 +1,53 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+@import '../../styles/themes';
+@import '~@nebular/theme/styles/global/bootstrap/breakpoints';
+@import '~bootstrap/scss/mixins/breakpoints';
+
+@include nb-install-component() {
+  width: 100%;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+
+  .socials {
+    font-size: 2rem;
+
+    a {
+      padding: 0.4rem;
+      color: nb-theme(color-fg);
+      transition: color ease-out 0.1s;
+
+      &:hover {
+        color: nb-theme(color-fg-heading);
+      }
+    }
+  }
+
+  @include media-breakpoint-down(is) {
+    .socials {
+      font-size: 1.5rem;
+    }
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/footer/footer.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/footer/footer.component.ts
new file mode 100644
index 0000000..68ab67c
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/footer/footer.component.ts
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'ngx-footer',
+  styleUrls: ['./footer.component.scss'],
+  template: `
+    <span class="created-by">&copy; 2018 <b><a href="http://servicecomb.apache.org/" target="_blank">ServiceComb</a></b></span>
+    <div class="socials">
+      <a title="GitHub" href="https://github.com/apache?q=ServiceComb" target="_blank" class="ion ion-social-github"></a>
+      <a title="Twitter" href="https://twitter.com/servicecomb" target="_blank" class="ion ion-social-twitter"></a>
+      <a title="Gitter" href="https://gitter.im/ServiceCombUsers/Saga" target="_blank" class="fab fa-gitter"></a>
+    </div>
+  `,
+})
+export class FooterComponent {
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/header/header.component.html b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/header/header.component.html
new file mode 100644
index 0000000..5def2e4
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/header/header.component.html
@@ -0,0 +1,35 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<div class="header-container"
+     [class.left]="position === 'normal'"
+     [class.right]="position === 'inverse'">
+  <div class="logo-containter mr-5">
+    <a (click)="toggleSidebar()" href="#" class="navigation"><i class="nb-menu"></i></a>
+    <div class="logo" (click)="goToHome()">ServiceComb<span> Saga</span></div>
+    
+  </div>
+  <small class="ml-5">
+         A transaction management system for servicecomb
+  </small>
+</div>
+
+<div class="header-container">
+  <ngx-theme-switcher></ngx-theme-switcher>
+  <nb-actions
+    size="medium"
+    [class.right]="position === 'normal'"
+    [class.left]="position === 'inverse'">
+  </nb-actions>
+</div>
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/header/header.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/header/header.component.scss
new file mode 100644
index 0000000..3300a90
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/header/header.component.scss
@@ -0,0 +1,235 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+@import '../../styles/themes';
+@import '~bootstrap/scss/mixins/breakpoints';
+@import '~@nebular/theme/styles/global/bootstrap/breakpoints';
+
+@include nb-install-component() {
+  display: flex;
+  justify-content: space-between;
+  width: 100%;
+
+  .left {
+    display: flex;
+    width: 100%;
+    order: 0;
+    flex-direction: row;
+  }
+  .right {
+    order: 1;
+    flex-direction: row-reverse;
+  }
+
+  .logo-containter {
+    display: flex;
+    align-items: center;
+    width: calc(#{nb-theme(sidebar-width)} - #{nb-theme(header-padding)});
+  }
+
+  .control-item {
+    display: block;
+  }
+
+  .header-container {
+    display: flex;
+    align-items: center;
+    width: auto;
+
+    .navigation {
+      @include nb-ltr(padding-right, nb-theme(padding));
+      @include nb-rtl(padding-left, nb-theme(padding));
+      font-size: 2.5rem;
+      text-decoration: none;
+
+      i {
+        display: block;
+      }
+
+    }
+
+    .logo {
+      padding: 0 nb-theme(padding);
+      font-size: 1.75rem;
+      font-weight: nb-theme(font-weight-bolder);
+      @include nb-ltr(border-left, 1px solid nb-theme(separator));
+      @include nb-rtl(border-right, 1px solid nb-theme(separator));
+      white-space: nowrap;
+
+      span {
+        font-weight: nb-theme(font-weight-normal);
+      }
+    }
+  }
+
+  @include nb-for-theme(corporate) {
+    $menu-action-separator-color: #3f4550;
+
+    nb-action {
+      @include nb-ltr(border-left-color, $menu-action-separator-color);
+      @include nb-rtl(border-right-color, $menu-action-separator-color);
+    }
+
+    .header-container .logo {
+      @include nb-ltr(border, none);
+      @include nb-rtl(border, none);
+    }
+
+    .header-container /deep/ ngx-theme-switcher .dropdown-toggle {
+      color: nb-theme(color-white);
+      background: transparent;
+    }
+  }
+
+  ngx-layout-direction-switcher {
+    margin: 0 1.5rem;
+  }
+
+  ngx-theme-switcher {
+    margin: nb-theme(layout-padding);
+    margin-top: 0;
+    margin-bottom: 0;
+  }
+
+  @include media-breakpoint-down(xl) {
+    ngx-layout-direction-switcher {
+      display: none;
+    }
+  }
+
+  .toggle-layout /deep/ a {
+    display: block;
+    text-decoration: none;
+    line-height: 1;
+
+    i {
+      color: nb-theme(color-fg-highlight);
+      font-size: 2.25rem;
+      border-radius: 50%;
+      position: relative;
+      animation-name: pulse-light;
+
+      &::after {
+        content: ' ';
+        // hack to be able to set border-radius
+        background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
+        border-radius: 50%;
+        pointer-events: none;
+
+        position: absolute;
+        top: 52.3%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        width: 13%;
+        height: 13%;
+
+        animation: 3s linear infinite pulse;
+
+        @include nb-for-theme(default) {
+          animation-name: pulse-light;
+        }
+      }
+    }
+  }
+
+  @include keyframes(pulse) {
+    0% {
+      box-shadow: 0 0 1px 0 rgba(nb-theme(color-fg-highlight), 0);
+    }
+    20% {
+      box-shadow: 0 0 3px 10px rgba(nb-theme(color-fg-highlight), 0.4);
+    }
+    100% {
+      box-shadow: 0 0 5px 20px rgba(nb-theme(color-fg-highlight), 0);
+    }
+  }
+
+  @include keyframes(pulse-light) {
+    0% {
+      box-shadow: 0 0 1px 0 rgba(115, 255, 208, 0);
+    }
+    20% {
+      box-shadow: 0 0 3px 10px rgba(115, 255, 208, 0.4);
+    }
+    100% {
+      box-shadow: 0 0 5px 20px rgba(115, 255, 208, 0);
+    }
+  }
+
+  @include media-breakpoint-down(md) {
+
+    nb-action:not(.toggle-layout) {
+      border: none;
+    }
+
+    .control-item {
+      display: none;
+    }
+
+    .toggle-layout {
+      padding: 0;
+    }
+
+    ngx-layout-direction-switcher {
+      display: none;
+    }
+
+    ngx-theme-switcher {
+      margin: 0 0.5rem;
+    }
+  }
+
+  @include media-breakpoint-down(sm) {
+
+    nb-user /deep/ .user-name {
+      display: none;
+    }
+  }
+
+  @include media-breakpoint-down(is) {
+
+    .header-container {
+      .logo {
+        font-size: 1.25rem;
+      }
+    }
+
+    .toggle-layout {
+      display: none;
+    }
+
+    ngx-theme-switcher {
+      display: none;
+    }
+
+    nb-action:not(.toggle-layout) {
+      padding: 0;
+    }
+  }
+
+  @include media-breakpoint-down(xs) {
+    .right /deep/ {
+      display: none;
+    }
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/header/header.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/header/header.component.ts
new file mode 100644
index 0000000..1aab1d4
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/header/header.component.ts
@@ -0,0 +1,53 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Component, Input, OnInit } from '@angular/core';
+
+import { NbMenuService, NbSidebarService } from '@nebular/theme';
+import { AnalyticsService } from '../../../@core/utils/analytics.service';
+
+@Component({
+  selector: 'ngx-header',
+  styleUrls: ['./header.component.scss'],
+  templateUrl: './header.component.html',
+})
+export class HeaderComponent implements OnInit {
+
+  @Input() position = 'normal';
+
+  user: any;
+
+  userMenu = [{ title: 'Profile' }, { title: 'Log out' }];
+
+  constructor(private sidebarService: NbSidebarService,
+              private menuService: NbMenuService,
+              private analyticsService: AnalyticsService,
+              ) {
+  }
+
+  ngOnInit() {
+    
+  }
+
+  toggleSidebar(): boolean {
+    this.sidebarService.toggle(true, 'menu-sidebar');
+
+    return false;
+  }
+
+  toggleSettings(): boolean {
+    this.sidebarService.toggle(false, 'settings-sidebar');
+
+    return false;
+  }
+
+  goToHome() {
+    this.menuService.navigateHome();
+  }
+
+  startSearch() {
+    this.analyticsService.trackEvent('startSearch');
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/index.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/index.ts
new file mode 100644
index 0000000..5446283
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/index.ts
@@ -0,0 +1,11 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+export * from './header/header.component';
+export * from './footer/footer.component';
+export * from './theme-settings/theme-settings.component';
+export * from './theme-switcher/theme-switcher.component';
+export * from './switcher/switcher.component';
+export * from './theme-switcher/themes-switcher-list/themes-switcher-list.component';
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/switcher/switcher.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/switcher/switcher.component.scss
new file mode 100644
index 0000000..ec95d29
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/switcher/switcher.component.scss
@@ -0,0 +1,135 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+@import '../../styles/themes';
+@import '~@nebular/theme/styles/global/bootstrap/hero-buttons';
+@import '~bootstrap/scss/mixins/breakpoints';
+@import '~@nebular/theme/styles/global/bootstrap/breakpoints';
+
+@include nb-install-component() {
+  .switch-label {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    cursor: pointer;
+    margin: 0;
+
+    &.vertical {
+      flex-direction: column;
+      align-items: flex-start;
+
+      .first,
+      .second {
+        padding: 0;
+      }
+
+      .switch {
+        margin-top: 0.5em;
+      }
+    }
+
+    & > span {
+      font-size: 1.125rem;
+      font-weight: nb-theme(font-weight-bold);
+      transition: opacity 0.3s ease;
+      color: nb-theme(color-fg);
+
+      &.first {
+        @include nb-ltr(padding-right, 10px);
+        @include nb-rtl(padding-left, 10px);
+      }
+
+      &.second {
+        @include nb-ltr(padding-left, 10px);
+        @include nb-rtl(padding-right, 10px);
+      }
+
+      &.active {
+        color: nb-theme(color-fg-text);
+      }
+
+      @include nb-for-theme(cosmic) {
+        color: nb-theme(color-fg);
+
+        &.active {
+          color: nb-theme(color-white);
+        }
+      }
+
+      &:active {
+        opacity: 0.78;
+      }
+    }
+  }
+
+  .switch {
+    position: relative;
+    display: inline-block;
+    width: 3rem;
+    height: 1.5rem;
+    margin: 0;
+
+    input {
+      display: none;
+
+      &:checked + .slider::before {
+        @include nb-ltr(transform, translateX(1.5rem));
+        @include nb-rtl(transform, translateX(-1.5rem));
+      }
+    }
+
+    .slider {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      border-radius: 1.75rem;
+      background-color: nb-theme(layout-bg);
+    }
+
+    .slider::before {
+      position: absolute;
+      content: '';
+      height: 1.5rem;
+      width: 1.5rem;
+      border-radius: 50%;
+      background-color: nb-theme(color-success);
+      transition: 0.2s;
+
+      box-shadow: 0 0 0.25rem 0 rgba(nb-theme(color-fg), 0.4);
+
+      @include nb-for-theme(cosmic) {
+        @include btn-hero-primary-gradient();
+      }
+
+      @include nb-for-theme(corporate) {
+        background-color: nb-theme(color-primary);
+      }
+    }
+  }
+
+  @include media-breakpoint-down(xs) {
+    align-items: flex-end;
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/switcher/switcher.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/switcher/switcher.component.ts
new file mode 100644
index 0000000..377d639
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/switcher/switcher.component.ts
@@ -0,0 +1,65 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Component, Input, Output, EventEmitter } from '@angular/core';
+
+@Component({
+  selector: 'ngx-switcher',
+  styleUrls: ['./switcher.component.scss'],
+  template: `
+    <label class="switch-label" [class.vertical]="vertical">
+      <span class="first" [class.active]="vertical || isFirstValue()">
+        {{vertical ? currentValueLabel() : firstValueLabel}}
+      </span>
+
+      <div class="switch">
+        <input type="checkbox" [checked]="isSecondValue()" (change)="changeValue()">
+        <span class="slider"></span>
+      </div>
+
+      <span
+        *ngIf="!vertical"
+        class="second"
+        [class.active]="isSecondValue()"
+      >
+          {{secondValueLabel}}
+      </span>
+    </label>
+  `,
+})
+export class SwitcherComponent {
+  @Input() firstValue: any;
+  @Input() secondValue: any;
+
+  @Input() firstValueLabel: string;
+  @Input() secondValueLabel: string;
+
+  @Input() vertical: boolean;
+
+  @Input() value: any;
+  @Output() valueChange = new EventEmitter<any>();
+
+  isFirstValue() {
+    return this.value === this.firstValue;
+  }
+
+  isSecondValue() {
+    return this.value === this.secondValue;
+  }
+
+  currentValueLabel() {
+    return this.isFirstValue()
+      ? this.firstValueLabel
+      : this.secondValueLabel;
+  }
+
+  changeValue() {
+    this.value = this.isFirstValue()
+      ? this.secondValue
+      : this.firstValue;
+
+    this.valueChange.emit(this.value);
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-settings/theme-settings.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-settings/theme-settings.component.scss
new file mode 100644
index 0000000..054a3cf
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-settings/theme-settings.component.scss
@@ -0,0 +1,94 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+@import '../../styles/themes';
+
+@include nb-install-component() {
+  h6 {
+    margin-bottom: 0.5rem;
+  }
+
+  .settings-row {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    flex-wrap: wrap;
+
+    width: 90%;
+    margin: 0 0 1rem;
+
+    a {
+      text-decoration: none;
+      font-size: 2.25rem;
+
+      color: nb-theme(color-fg);
+
+      &.selected {
+        color: nb-theme(color-success);
+      }
+
+      @include nb-for-theme(cosmic) {
+        &.selected {
+          color: nb-theme(link-color);
+        }
+      }
+    }
+  }
+
+  .settings {
+    margin-bottom: 1em;
+  }
+
+  .switcher {
+    margin-bottom: 1rem;
+
+    /deep/ ngx-switcher {
+      .switch-label span {
+        font-size: 1em;
+        font-weight: normal;
+      }
+
+      .switch {
+        height: 1.5em;
+        width: 3em;
+
+        .slider::before {
+          height: 1.5em;
+          width: 1.5em;
+        }
+
+        input:checked + .slider::before {
+          @include nb-ltr(transform, translateX(1.5rem)!important);
+          @include nb-rtl(transform, translateX(-1.5rem)!important);
+        }
+      }
+
+      @include nb-for-theme(cosmic) {
+        .switch .slider {
+          background-color: nb-theme(color-bg);
+        }
+      }
+    }
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-settings/theme-settings.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-settings/theme-settings.component.ts
new file mode 100644
index 0000000..edd7092
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-settings/theme-settings.component.ts
@@ -0,0 +1,63 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Component } from '@angular/core';
+
+import { StateService } from '../../../@core/data/state.service';
+
+@Component({
+  selector: 'ngx-theme-settings',
+  styleUrls: ['./theme-settings.component.scss'],
+  template: `
+    <h6>SIDEBAR</h6>
+    <div class="settings-row">
+      <a *ngFor="let sidebar of sidebars"
+         href="#"
+         [class.selected]="sidebar.selected"
+         [attr.title]="sidebar.name"
+         (click)="sidebarSelect(sidebar)">
+        <i [attr.class]="sidebar.icon"></i>
+      </a>
+    </div>
+    <!-- <div class="switcher">
+      <ngx-layout-direction-switcher [vertical]="true"></ngx-layout-direction-switcher>
+    </div> -->
+  `,
+})
+export class ThemeSettingsComponent {
+
+  layouts = [];
+  sidebars = [];
+
+  constructor(protected stateService: StateService) {
+    this.stateService.getLayoutStates()
+      .subscribe((layouts: any[]) => this.layouts = layouts);
+
+    this.stateService.getSidebarStates()
+      .subscribe((sidebars: any[]) => this.sidebars = sidebars);
+  }
+
+  layoutSelect(layout: any): boolean {
+    this.layouts = this.layouts.map((l: any) => {
+      l.selected = false;
+      return l;
+    });
+
+    layout.selected = true;
+    this.stateService.setLayoutState(layout);
+    return false;
+  }
+
+  sidebarSelect(sidebars: any): boolean {
+    this.sidebars = this.sidebars.map((s: any) => {
+      s.selected = false;
+      return s;
+    });
+
+    sidebars.selected = true;
+    this.stateService.setSidebarState(sidebars);
+    return false;
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/theme-switcher.component.html b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/theme-switcher.component.html
new file mode 100644
index 0000000..355b1e6
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/theme-switcher.component.html
@@ -0,0 +1,21 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<div class="themes-switcher"
+     [nbPopover]="switcherListComponent"
+     nbPopoverPlacement="bottom"
+     [nbPopoverContext]="{popover: popover}">
+  <i class="nb-drops"></i>
+  <span *ngIf="showTitle">Themes</span>
+</div>
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/theme-switcher.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/theme-switcher.component.scss
new file mode 100644
index 0000000..93222db
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/theme-switcher.component.scss
@@ -0,0 +1,73 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+@import '../../styles/themes';
+@import '~@nebular/theme/styles/core/mixins';
+@import '~@nebular/theme/styles/core/functions';
+
+@include nb-install-component() {
+  .themes-switcher {
+    display: flex;
+    font-size: 1.25rem;
+    padding: 0.8rem 1.25rem;
+    align-items: center;
+    cursor: pointer;
+    background-color: nb-theme(switcher-background);
+    border-radius: nb-theme(radius);
+
+    &:hover {
+      $color: nb-theme(switcher-background);
+      $percentage: nb-theme(switcher-background-percentage);
+
+      background-color: tint($color, $percentage);
+    }
+
+    span {
+      margin: 0 1.2rem;
+    }
+
+    i {
+      color: nb-theme(color-primary);
+      font-size: 1.8rem;
+      border-radius: 50%;
+      position: relative;
+
+      @include nb-for-theme(default) {
+        color: nb-theme(color-success);
+      }
+
+      @include nb-for-theme(corporate) {
+        color: nb-theme(color-fg-highlight);
+      }
+
+      &::before {
+        // Hack for IE11, IE11 should not set background
+        background: nb-theme(drops-icon-line-gadient);
+        -webkit-background-clip: text;
+        -webkit-text-fill-color: transparent;
+      }
+    }
+  }
+}
+
+
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/theme-switcher.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/theme-switcher.component.ts
new file mode 100644
index 0000000..7680a1b
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/theme-switcher.component.ts
@@ -0,0 +1,24 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Component, Input, ViewChild } from '@angular/core';
+import { NbPopoverDirective } from '@nebular/theme';
+import { NbJSThemeOptions } from '@nebular/theme/services/js-themes/theme.options';
+
+import { ThemeSwitcherListComponent } from './themes-switcher-list/themes-switcher-list.component';
+
+@Component({
+  selector: 'ngx-theme-switcher',
+  templateUrl: './theme-switcher.component.html',
+  styleUrls: ['./theme-switcher.component.scss'],
+})
+export class ThemeSwitcherComponent {
+  @ViewChild(NbPopoverDirective) popover: NbPopoverDirective;
+
+  @Input() showTitle: boolean = true;
+
+  switcherListComponent = ThemeSwitcherListComponent;
+  theme: NbJSThemeOptions;
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/themes-switcher-list/theme-switcher-list.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/themes-switcher-list/theme-switcher-list.component.scss
new file mode 100644
index 0000000..b63f1b1
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/themes-switcher-list/theme-switcher-list.component.scss
@@ -0,0 +1,99 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+@import '../../../styles/themes';
+@import '~@nebular/theme/styles/core/mixins';
+@import '~bootstrap/scss/mixins/breakpoints';
+@import '~@nebular/theme/styles/global/bootstrap/breakpoints';
+
+$icon-color-default: #0bbb79;
+$icon-color-cosmic: #7958fa;
+$icon-color-corporate: #a7a2be;
+
+$icon-top-color-default: #01dbb5;
+$icon-top-color-cosmic: #a258fe;
+$icon-top-color-corporate: #e9e8eb;
+
+@include nb-install-component() {
+  /deep/ .themes-switcher-list {
+    padding: 1rem 2rem 1.25rem 0.5rem;
+    margin: 0;
+
+    @include nb-ltr(text-align, start);
+    @include nb-rtl(text-align, end);
+
+    .themes-switcher-item {
+      list-style: none;
+      cursor: pointer;
+
+      &:hover span {
+        opacity: 0.5;
+      }
+
+      i {
+        font-size: 2rem;
+
+        &.drop-icon-default {
+          color: $icon-color-default;
+
+          // Hack for IE11, IE11 should not set background
+          background: -webkit-linear-gradient($icon-top-color-default, $icon-color-default);
+        }
+
+        &.drop-icon-cosmic {
+          color: $icon-color-cosmic;
+
+          // Hack for IE11, IE11 should not set background
+          background: -webkit-linear-gradient($icon-top-color-cosmic, $icon-color-cosmic);
+        }
+
+        &.drop-icon-corporate {
+          color: $icon-color-corporate;
+
+          // Hack for IE11, IE11 should not set background
+          background: -webkit-linear-gradient($icon-top-color-corporate, $icon-color-corporate);
+        }
+
+        &.drop-icon-default,
+        &.drop-icon-cosmic,
+        &.drop-icon-corporate {
+          -webkit-background-clip: text;
+          -webkit-text-fill-color: transparent;
+        }
+      }
+
+      span {
+        font-weight: 300;
+        vertical-align: super;
+        padding-left: 1rem;
+        color: nb-theme(color-fg-heading);
+      }
+    }
+  }
+
+  @include media-breakpoint-down(is) {
+    /deep/ .themes-switcher-list {
+      display: none;
+    }
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/themes-switcher-list/themes-switcher-list.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/themes-switcher-list/themes-switcher-list.component.ts
new file mode 100644
index 0000000..3b410ea
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/components/theme-switcher/themes-switcher-list/themes-switcher-list.component.ts
@@ -0,0 +1,56 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import {Component, Input} from '@angular/core';
+import { NbThemeService, NbPopoverDirective } from '@nebular/theme';
+import { AnalyticsService } from '../../../../@core/utils/analytics.service';
+import { NbJSThemeOptions } from '@nebular/theme/services/js-themes/theme.options';
+
+@Component({
+  selector: 'ngx-theme-switcher-list',
+  template: `
+    <ul class="themes-switcher-list">
+      <li class="themes-switcher-item"
+          *ngFor="let theme of themes"
+          (click)="onToggleTheme(theme.key)">
+        <i class="nb-drop" [ngClass]="'drop-icon-' + theme.key"></i>
+        <span>{{ theme.title }}</span>
+      </li>
+    </ul>
+  `,
+  styleUrls: ['./theme-switcher-list.component.scss'],
+})
+export class ThemeSwitcherListComponent {
+
+  @Input() popover: NbPopoverDirective;
+
+  theme: NbJSThemeOptions;
+
+  themes = [
+    {
+      title: 'Light',
+      key: 'default',
+    },
+    {
+      title: 'Cosmic',
+      key: 'cosmic',
+    },
+    {
+      title: 'Corporate',
+      key: 'corporate',
+    },
+  ];
+
+  constructor(
+    private themeService: NbThemeService,
+    private analyticsService: AnalyticsService,
+  ) {}
+
+  onToggleTheme(themeKey: string) {
+    this.themeService.changeTheme(themeKey);
+    this.analyticsService.trackEvent('switchTheme');
+    this.popover.hide();
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/default/default.layout.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/default/default.layout.scss
new file mode 100644
index 0000000..45e0401
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/default/default.layout.scss
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@import '../../styles/themes';
+@import '~bootstrap/scss/mixins/breakpoints';
+@import '~@nebular/theme/styles/global/bootstrap/breakpoints';
+
+@include nb-install-component() {
+  nb-layout-column.small {
+    flex: 0.15 !important;
+  }
+
+  nb-sidebar.settings-sidebar {
+    $sidebar-width: 7.5rem;
+
+    transition: width 0.3s ease;
+    width: $sidebar-width;
+    overflow: hidden;
+
+    &.collapsed {
+      width: 0;
+
+      /deep/ .main-container {
+        width: 0;
+
+        .scrollable {
+          width: $sidebar-width;
+          padding: 1.25rem;
+        }
+      }
+    }
+
+    /deep/ .main-container {
+      width: $sidebar-width;
+      background: nb-theme(color-bg);
+      transition: width 0.3s ease;
+      overflow: hidden;
+
+      .scrollable {
+        width: $sidebar-width;
+      }
+
+      @include nb-for-theme(cosmic) {
+        background: nb-theme(layout-bg);
+      }
+    }
+  }
+
+  nb-sidebar.menu-sidebar {
+
+    margin-top: nb-theme(sidebar-header-gap);
+
+    @include nb-for-theme(corporate) {
+      margin-top: 0;
+    }
+
+    /deep/ .main-container {
+      height:
+        calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important;
+      @include nb-ltr(border-top-right-radius, nb-theme(radius));
+      @include nb-rtl(border-top-left-radius, nb-theme(radius));
+
+      @include nb-for-theme(corporate) {
+        border: 1px solid nb-theme(separator);
+        height:
+          calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important;
+      }
+    }
+
+    /deep/ .scrollable {
+      @include nb-for-theme(corporate) {
+        padding-top: 0;
+
+        .menu-item:first-child {
+          border-top: none;
+        }
+      }
+    }
+
+    /deep/ nb-sidebar-header {
+      padding-bottom: 0.5rem;
+      text-align: center;
+    }
+
+    background: transparent;
+
+    .main-btn {
+      padding: 0.75rem 2.5rem;
+      margin-top: -2rem;
+      font-weight: bold;
+      transition: padding 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.48);
+
+      @include nb-for-theme(corporate) {
+        border-radius: nb-theme(radius);
+      }
+
+      i {
+        font-size: 2rem;
+        text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+      }
+      span {
+        @include nb-ltr(padding-left, 0.25rem);
+        @include nb-rtl(padding-right, 0.25rem);
+      }
+
+      i, span {
+        vertical-align: middle;
+      }
+    }
+
+    /deep/ nb-menu {
+      & > .menu-items {
+        & > .menu-item:first-child {
+          .menu-title {
+           
+          }
+        }
+      }
+
+      .nb-e-commerce {
+        font-size: 2rem;
+      }
+    }
+
+    &.compacted {
+
+      /deep/ nb-sidebar-header {
+        padding-left: 0;
+        padding-right: 0;
+      }
+
+      .main-btn {
+        width: 46px;
+        height: 44px;
+        padding: 0.375rem;
+        border-radius: 5px;
+        transition: none;
+
+        span {
+          display: none;
+        }
+      }
+    }
+  }
+
+  @include media-breakpoint-down(xs) {
+    .main-content {
+      padding: 0.75rem !important;
+
+    }
+  }
+
+  @include media-breakpoint-down(sm) {
+
+    nb-sidebar.menu-sidebar {
+
+      margin-top: 0;
+
+      /deep/ .main-container {
+        height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important;
+        @include nb-ltr(border-top-right-radius, 0);
+        @include nb-rtl(border-top-left-radius, 0);
+
+        .scrollable {
+          padding-top: 0;
+        }
+      }
+    }
+
+    .main-btn {
+      display: none;
+    }
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/default/default.layout.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/default/default.layout.ts
new file mode 100644
index 0000000..3d6f308
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/default/default.layout.ts
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Component, OnDestroy } from '@angular/core';
+import { delay, withLatestFrom, takeWhile } from 'rxjs/operators';
+import {
+  NbMediaBreakpoint,
+  NbMediaBreakpointsService,
+  NbMenuItem,
+  NbMenuService,
+  NbSidebarService,
+  NbThemeService,
+} from '@nebular/theme';
+
+import { StateService } from '../../../@core/data/state.service';
+
+// TODO: move layouts into the framework
+@Component({
+  selector: 'ngx-default-layout',
+  styleUrls: ['./default.layout.scss'],
+  template: `
+    <nb-layout [center]="layout.id === 'center-column'" windowMode>
+      <nb-layout-header fixed>
+        <ngx-header [position]="sidebar.id === 'start' ? 'normal': 'inverse'"></ngx-header>
+      </nb-layout-header>
+
+      <nb-sidebar class="menu-sidebar"
+                   tag="menu-sidebar"
+                   responsive
+                   [end]="sidebar.id === 'end'">
+        <nb-sidebar-header *ngIf="currentTheme !== 'corporate'">
+          <a href="https://gitter.im/ServiceCombUsers/Saga" target='_blank' class="btn btn-hero-success main-btn">
+            <i class="fab fa-gitter"></i> <span>Talk to Us</span>
+          </a>
+        </nb-sidebar-header>
+        <ng-content select="nb-menu"></ng-content>
+      </nb-sidebar>
+
+      <nb-layout-column class="main-content">
+        <ng-content select="router-outlet"></ng-content>
+      </nb-layout-column>
+
+      <nb-layout-footer fixed>
+        <ngx-footer></ngx-footer>
+      </nb-layout-footer>
+
+      <nb-sidebar class="settings-sidebar"
+                   tag="settings-sidebar"
+                   state="collapsed"
+                   fixed
+                   [end]="sidebar.id !== 'end'">
+        <ngx-theme-settings></ngx-theme-settings>
+      </nb-sidebar>
+    </nb-layout>
+  `,
+})
+export class DefaultLayoutComponent implements OnDestroy {
+
+  
+  layout: any = {};
+  sidebar: any = {};
+
+  private alive = true;
+
+  currentTheme: string;
+
+  constructor(protected stateService: StateService,
+              protected menuService: NbMenuService,
+              protected themeService: NbThemeService,
+              protected bpService: NbMediaBreakpointsService,
+              protected sidebarService: NbSidebarService) {
+    this.stateService.onLayoutState()
+      .pipe(takeWhile(() => this.alive))
+      .subscribe((layout: string) => this.layout = layout);
+
+    this.stateService.onSidebarState()
+      .pipe(takeWhile(() => this.alive))
+      .subscribe((sidebar: string) => {
+        this.sidebar = sidebar;
+      });
+
+    const isBp = this.bpService.getByName('is');
+    this.menuService.onItemSelect()
+      .pipe(
+        takeWhile(() => this.alive),
+        withLatestFrom(this.themeService.onMediaQueryChange()),
+        delay(20),
+      )
+      .subscribe(([item, [bpFrom, bpTo]]: [any, [NbMediaBreakpoint, NbMediaBreakpoint]]) => {
+
+        if (bpTo.width <= isBp.width) {
+          this.sidebarService.collapse('menu-sidebar');
+        }
+      });
+
+    this.themeService.getJsTheme()
+      .pipe(takeWhile(() => this.alive))
+      .subscribe(theme => {
+        this.currentTheme = theme.name;
+    });
+  }
+
+  ngOnDestroy() {
+    this.alive = false;
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/index.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/index.ts
new file mode 100644
index 0000000..359dd9c
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/index.ts
@@ -0,0 +1,7 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+export * from './one-column/one-column.layout';
+export * from './default/default.layout';
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/one-column/one-column.layout.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/one-column/one-column.layout.scss
new file mode 100644
index 0000000..f8ab596
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/one-column/one-column.layout.scss
@@ -0,0 +1,180 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+@import '../../styles/themes';
+@import '~bootstrap/scss/mixins/breakpoints';
+@import '~@nebular/theme/styles/global/bootstrap/breakpoints';
+
+@include nb-install-component() {
+  nb-layout-column.small {
+    flex: 0.15 !important;
+  }
+
+  nb-sidebar.settings-sidebar {
+    $sidebar-width: 7.5rem;
+
+    transition: width 0.3s ease;
+    width: $sidebar-width;
+    overflow: hidden;
+
+    &.collapsed {
+      width: 0;
+
+      /deep/ .main-container {
+        width: 0;
+
+        .scrollable {
+          width: $sidebar-width;
+          padding: 1.25rem;
+        }
+      }
+    }
+
+    /deep/ .main-container {
+      width: $sidebar-width;
+      background: nb-theme(color-bg);
+      transition: width 0.3s ease;
+      overflow: hidden;
+
+      .scrollable {
+        width: $sidebar-width;
+      }
+
+      @include nb-for-theme(cosmic) {
+        background: nb-theme(layout-bg);
+      }
+    }
+  }
+
+  nb-sidebar.menu-sidebar {
+
+    margin-top: nb-theme(sidebar-header-gap);
+
+    @include nb-for-theme(corporate) {
+      margin-top: 0;
+    }
+
+    /deep/ .main-container {
+      height:
+        calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important;
+      @include nb-ltr(border-top-right-radius, nb-theme(radius));
+      @include nb-rtl(border-top-left-radius, nb-theme(radius));
+
+      @include nb-for-theme(corporate) {
+        border: 1px solid nb-theme(separator);
+        height:
+          calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important;
+      }
+    }
+
+    /deep/ .scrollable {
+      @include nb-for-theme(corporate) {
+        padding-top: 0;
+
+        .menu-item:first-child {
+          border-top: none;
+        }
+      }
+    }
+
+    /deep/ nb-sidebar-header {
+      padding-bottom: 0.5rem;
+      text-align: center;
+    }
+
+    background: transparent;
+
+    .main-btn {
+      padding: 0.75rem 2.5rem;
+      margin-top: -2rem;
+      font-weight: bold;
+      transition: padding 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.48);
+
+      @include nb-for-theme(corporate) {
+        border-radius: nb-theme(radius);
+      }
+
+      i {
+        font-size: 2rem;
+        text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+      }
+      span {
+        @include nb-ltr(padding-left, 0.25rem);
+        @include nb-rtl(padding-right, 0.25rem);
+      }
+
+      i, span {
+        vertical-align: middle;
+      }
+    }
+
+    &.compacted {
+
+      /deep/ nb-sidebar-header {
+        padding-left: 0;
+        padding-right: 0;
+      }
+
+      .main-btn {
+        width: 46px;
+        height: 44px;
+        padding: 0.375rem;
+        border-radius: 5px;
+        transition: none;
+
+        span {
+          display: none;
+        }
+      }
+    }
+  }
+
+  @include media-breakpoint-down(xs) {
+    .main-content {
+      padding: 0.75rem !important;
+
+    }
+  }
+
+  @include media-breakpoint-down(sm) {
+
+    nb-sidebar.menu-sidebar {
+
+      margin-top: 0;
+
+      /deep/ .main-container {
+        height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important;
+        @include nb-ltr(border-top-right-radius, 0);
+        @include nb-rtl(border-top-left-radius, 0);
+
+        .scrollable {
+          padding-top: 0;
+        }
+      }
+    }
+
+    .main-btn {
+      display: none;
+    }
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/one-column/one-column.layout.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/one-column/one-column.layout.ts
new file mode 100644
index 0000000..cc227c5
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/layouts/one-column/one-column.layout.ts
@@ -0,0 +1,56 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Component, OnDestroy } from '@angular/core';
+import { NbThemeService } from '@nebular/theme';
+import { takeWhile } from 'rxjs/operators/takeWhile';
+
+// TODO: move layouts into the framework
+@Component({
+  selector: 'ngx-one-column-layout',
+  styleUrls: ['./one-column.layout.scss'],
+  template: `
+    <nb-layout>
+      <nb-layout-header fixed>
+        <ngx-header></ngx-header>
+      </nb-layout-header>
+
+      <nb-sidebar class="menu-sidebar" tag="menu-sidebar" responsive>
+        <nb-sidebar-header *ngIf="currentTheme !== 'corporate'">
+          <a href="https://github.com/apache/incubator-servicecomb-saga" target='_blank' class="btn btn-hero-success main-btn">
+            <i class="ion ion-social-github"></i> <span>Support Us</span>
+          </a>
+        </nb-sidebar-header>
+        <ng-content select="nb-menu"></ng-content>
+      </nb-sidebar>
+
+      <nb-layout-column>
+        <ng-content select="router-outlet"></ng-content>
+      </nb-layout-column>
+
+      <nb-layout-footer fixed>
+        <ngx-footer></ngx-footer>
+      </nb-layout-footer>
+    </nb-layout>
+  `,
+})
+export class OneColumnLayoutComponent implements OnDestroy {
+
+  private alive = true;
+
+  currentTheme: string;
+
+  constructor(protected themeService: NbThemeService) {
+    this.themeService.getJsTheme()
+      .pipe(takeWhile(() => this.alive))
+      .subscribe(theme => {
+        this.currentTheme = theme.name;
+    });
+  }
+
+  ngOnDestroy() {
+    this.alive = false;
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/capitalize.pipe.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/capitalize.pipe.ts
new file mode 100644
index 0000000..d7fe7f0
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/capitalize.pipe.ts
@@ -0,0 +1,16 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({ name: 'ngxCapitalize' })
+export class CapitalizePipe implements PipeTransform {
+
+  transform(input: string): string {
+    return input && input.length
+      ? (input.charAt(0).toUpperCase() + input.slice(1).toLowerCase())
+      : input;
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/index.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/index.ts
new file mode 100644
index 0000000..c36c380
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/index.ts
@@ -0,0 +1,11 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+export * from './capitalize.pipe';
+export * from './plural.pipe';
+export * from './round.pipe';
+export * from './timing.pipe';
+export * from './number-with-commas.pipe';
+export * from './no-sanitize.pipe';
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/no-sanitize.pipe.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/no-sanitize.pipe.ts
new file mode 100644
index 0000000..5c03f4d
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/no-sanitize.pipe.ts
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Pipe, PipeTransform } from '@angular/core';
+import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
+
+@Pipe({ name: 'noSanitize' })
+export class NoSanitizePipe implements PipeTransform {
+   constructor(private domSanitizer: DomSanitizer) {
+
+   }
+   transform(html: string): SafeHtml {
+      return this.domSanitizer.bypassSecurityTrustHtml(html);
+   }
+}
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/number-with-commas.pipe.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/number-with-commas.pipe.ts
new file mode 100644
index 0000000..fe42335
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/number-with-commas.pipe.ts
@@ -0,0 +1,14 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({ name: 'ngxNumberWithCommas' })
+export class NumberWithCommasPipe implements PipeTransform {
+
+  transform(input: number): string {
+    return new Intl.NumberFormat().format(input);
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/plural.pipe.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/plural.pipe.ts
new file mode 100644
index 0000000..aaad2fd
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/plural.pipe.ts
@@ -0,0 +1,19 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({ name: 'ngxPlural' })
+export class PluralPipe implements PipeTransform {
+
+  transform(input: number, label: string, pluralLabel: string = ''): string {
+    input = input || 0;
+    return input === 1
+      ? `${input} ${label}`
+      : pluralLabel
+        ? `${input} ${pluralLabel}`
+        : `${input} ${label}s`;
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/round.pipe.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/round.pipe.ts
new file mode 100644
index 0000000..9264a4f
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/round.pipe.ts
@@ -0,0 +1,14 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({ name: 'ngxRound' })
+export class RoundPipe implements PipeTransform {
+
+  transform(input: number): number {
+    return Math.round(input);
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/timing.pipe.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/timing.pipe.ts
new file mode 100644
index 0000000..04b9f5e
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/pipes/timing.pipe.ts
@@ -0,0 +1,23 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({ name: 'timing' })
+export class TimingPipe implements PipeTransform {
+  transform(time: number): string {
+    if (time) {
+      const minutes = Math.floor(time / 60);
+      const seconds = Math.floor(time % 60);
+      return `${this.initZero(minutes)}${minutes}:${this.initZero(seconds)}${seconds}`;
+    }
+
+    return '00:00';
+  }
+
+  private initZero(time: number): string {
+    return time < 10 ? '0' : '';
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/bootstrap-rtl.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/bootstrap-rtl.scss
new file mode 100644
index 0000000..d28ee4c
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/bootstrap-rtl.scss
@@ -0,0 +1,216 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+@import './themes';
+
+@mixin bootstrap-rtl() {
+  .btn-group:not(.btn-divided-group) > .btn:not(.dropdown-toggle) {
+    &:first-child {
+      @include nb-ltr() {
+        border-top-left-radius: nb-theme(btn-border-radius);
+        border-bottom-left-radius: nb-theme(btn-border-radius);
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+      };
+      @include nb-rtl() {
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+        border-top-right-radius: nb-theme(btn-border-radius);
+        border-bottom-right-radius: nb-theme(btn-border-radius);
+      };
+    }
+    &:last-child {
+      @include nb-ltr() {
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+        border-top-right-radius: nb-theme(btn-border-radius);
+        border-bottom-right-radius: nb-theme(btn-border-radius);
+      };
+      @include nb-rtl() {
+        border-top-left-radius: nb-theme(btn-border-radius);
+        border-bottom-left-radius: nb-theme(btn-border-radius);
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+      };
+    }
+  }
+
+  .btn-group.dropdown {
+    & > .btn:first-of-type.dropdown-toggle {
+      @include nb-ltr() {
+        border-top-left-radius: nb-theme(btn-border-radius);
+        border-top-right-radius: 0;
+      };
+      @include nb-rtl() {
+        border-top-left-radius: 0;
+        border-top-right-radius: nb-theme(btn-border-radius);
+      };
+    }
+    & > .btn:last-of-type.dropdown-toggle {
+      @include nb-ltr() {
+        border-top-left-radius: 0;
+        border-top-right-radius: nb-theme(btn-border-radius);
+      };
+      @include nb-rtl() {
+        border-top-left-radius: nb-theme(btn-border-radius);
+        border-top-right-radius: 0;
+      };
+    }
+
+    &:not(.show) {
+      & > .btn:first-of-type.dropdown-toggle {
+        @include nb-ltr() {
+          border-bottom-left-radius: nb-theme(btn-border-radius);
+          border-bottom-right-radius: 0;
+        };
+        @include nb-rtl() {
+          border-bottom-left-radius: 0;
+          border-bottom-right-radius: nb-theme(btn-border-radius);
+        };
+      }
+      & > .btn:last-of-type.dropdown-toggle {
+        @include nb-ltr() {
+          border-bottom-left-radius: 0;
+          border-bottom-right-radius: nb-theme(btn-border-radius);
+        };
+        @include nb-rtl() {
+          border-bottom-left-radius: nb-theme(btn-border-radius);
+          border-bottom-right-radius: 0;
+        };
+      }
+    }
+  }
+
+  .btn-group.dropup {
+    & > .btn:first-of-type.dropdown-toggle {
+      @include nb-ltr() {
+        border-bottom-left-radius: nb-theme(btn-border-radius);
+        border-bottom-right-radius: 0;
+      };
+      @include nb-rtl() {
+        border-bottom-left-radius: 0;
+        border-bottom-right-radius: nb-theme(btn-border-radius);
+      };
+    }
+    & > .btn:last-of-type.dropdown-toggle {
+      @include nb-ltr() {
+        border-bottom-left-radius: 0;
+        border-bottom-right-radius: nb-theme(btn-border-radius);
+      };
+      @include nb-rtl() {
+        border-bottom-left-radius: nb-theme(btn-border-radius);
+        border-bottom-right-radius: 0;
+      };
+    }
+
+    &:not(.show) {
+      & > .btn:first-of-type.dropdown-toggle {
+        @include nb-ltr() {
+          border-top-left-radius: nb-theme(btn-border-radius);
+          border-top-right-radius: 0;
+        };
+        @include nb-rtl() {
+          border-top-left-radius: 0;
+          border-top-right-radius: nb-theme(btn-border-radius);
+        };
+      }
+      & > .btn:last-of-type.dropdown-toggle {
+        @include nb-ltr() {
+          border-top-left-radius: 0;
+          border-top-right-radius: nb-theme(btn-border-radius);
+        };
+        @include nb-rtl() {
+          border-top-left-radius: nb-theme(btn-border-radius);
+          border-top-right-radius: 0;
+        };
+      }
+    }
+  }
+
+  .btn-divided-group {
+    .btn:not(:first-child) {
+      @include nb-ltr(margin-left, 0.5rem);
+      @include nb-rtl(margin-right, 0.5rem);
+      border-radius: nb-theme(btn-border-radius);
+    }
+  }
+
+  .input-group-addon,
+  .input-group-icon {
+    @include nb-ltr() {
+      border-left: nb-theme(form-control-border);
+      border-right: none;
+    };
+    @include nb-rtl() {
+      border-left: none;
+      border-right: nb-theme(form-control-border);
+    };
+  }
+
+  .input-group {
+    .form-control:first-child:not(:only-child),
+    .input-group-addon:first-child,
+    .input-group-prepend .btn:first-child,
+    .input-group-btn .btn:first-child {
+      @include nb-ltr() {
+        border-top-left-radius: nb-theme(form-control-border-radius);
+        border-bottom-left-radius: nb-theme(form-control-border-radius);
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+      };
+      @include nb-rtl() {
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+        border-top-right-radius: nb-theme(form-control-border-radius);
+        border-bottom-right-radius: nb-theme(form-control-border-radius);
+      };
+    }
+    .form-control:last-child:not(:only-child),
+    .input-group-addon:last-child,
+    .input-group-append .btn:last-child,
+    .input-group-btn .btn:last-child {
+      @include nb-ltr() {
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+        border-top-right-radius: nb-theme(form-control-border-radius);
+        border-bottom-right-radius: nb-theme(form-control-border-radius);
+      };
+      @include nb-rtl() {
+        border-top-left-radius: nb-theme(form-control-border-radius);
+        border-bottom-left-radius: nb-theme(form-control-border-radius);
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+      };
+    }
+
+    .dropdown.show .btn.dropdown-toggle {
+      border-bottom-left-radius: 0;
+      border-bottom-right-radius: 0;
+    }
+
+    .dropup.show .btn.dropdown-toggle {
+      border-top-left-radius: 0;
+      border-top-right-radius: 0;
+    }
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/font-size.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/font-size.scss
new file mode 100644
index 0000000..ed0c1ad
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/font-size.scss
@@ -0,0 +1,26 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+html {
+  font-size: 14px;
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/pace.theme.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/pace.theme.scss
new file mode 100644
index 0000000..b39cd67
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/pace.theme.scss
@@ -0,0 +1,40 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+
+ @mixin ngx-pace-theme() {
+
+  .pace .pace-progress {
+    background: nb-theme(color-fg-highlight);
+  }
+
+  .pace .pace-progress-inner {
+    box-shadow: 0 0 10px nb-theme(color-fg-highlight), 0 0 5px nb-theme(color-fg-highlight);
+  }
+
+  .pace .pace-activity {
+    display: none;
+    // border-top-color: nb-theme(color-fg-highlight);
+    // border-left-color: nb-theme(color-fg-highlight);
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/styles.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/styles.scss
new file mode 100644
index 0000000..ed8ca9a
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/styles.scss
@@ -0,0 +1,54 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+// themes - our custom or/and out of the box themes
+@import 'themes';
+
+// framework component themes (styles tied to theme variables)
+@import '~@nebular/theme/styles/globals';
+@import '~@nebular/auth/styles/all';
+
+// global app font size
+@import './font-size';
+
+// loading progress bar theme
+@import './pace.theme';
+
+@import './bootstrap-rtl';
+
+// install the framework and custom global styles
+@include nb-install() {
+
+  // framework global styles
+  @include nb-theme-global();
+  @include nb-auth-global();
+
+  // loading progress bar
+  @include ngx-pace-theme();
+
+  // fixed in rc.9 and can be removed after upgrade
+  .custom-control .custom-control-indicator {
+    border-radius: 50%; // TODO: quickfix for https://github.com/akveo/nebular/issues/275
+  }
+  @include bootstrap-rtl();
+};
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/theme.corporate.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/theme.corporate.ts
new file mode 100644
index 0000000..2bc58e7
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/theme.corporate.ts
@@ -0,0 +1,309 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+export const CORPORATE_THEME = {
+  name: 'corporate',
+  base: 'default',
+  variables: {
+    temperature: [
+      '#ffa36b',
+      '#ffa36b',
+      '#ff9e7a',
+      '#ff9888',
+      '#ff8ea0',
+    ],
+
+    solar: {
+      gradientLeft: '#ff8ea0',
+      gradientRight: '#ffa36b',
+      shadowColor: 'rgba(0, 0, 0, 0)',
+      radius: ['80%', '90%'],
+    },
+
+    traffic: {
+      colorBlack: '#ffffff',
+      tooltipBg: '#eef2f5',
+      tooltipBorderColor: '#eef2f5',
+      tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: '400',
+
+      lineBg: '#cae6f3',
+      lineShadowBlur: '0',
+      itemColor: '#bcc3cc',
+      itemBorderColor: '#bcc3cc',
+      itemEmphasisBorderColor: '#74a2ff',
+      shadowLineDarkBg: 'rgba(0, 0, 0, 0)',
+      shadowLineShadow: 'rgba(0, 0, 0, 0)',
+      gradFrom: '#ffffff',
+      gradTo: '#ffffff',
+    },
+
+    electricity: {
+      tooltipBg: '#edf0f4',
+      tooltipLineColor: '#bdc4cd',
+      tooltipLineWidth: '0',
+      tooltipBorderColor: '#ebeef2',
+      tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+
+      axisLineColor: 'rgba(0, 0, 0, 0)',
+      xAxisTextColor: '#2a2a2a',
+      yAxisSplitLine: '#ebeef2',
+
+      itemBorderColor: '#73a1ff',
+      lineStyle: 'solid',
+      lineWidth: '4',
+      lineGradFrom: '#bdc4cd',
+      lineGradTo: '#c0c8d1',
+      lineShadow: 'rgba(0, 0, 0, 0)',
+
+      areaGradFrom: 'rgba(255, 255, 255, 0)',
+      areaGradTo: 'rgba(255, 255, 255, 0)',
+      shadowLineDarkBg: 'rgba(255, 255, 255, 0)',
+    },
+
+    bubbleMap: {
+      titleColor: '#484848',
+      areaColor: '#dddddd',
+      areaHoverColor: '#cccccc',
+      areaBorderColor: '#ebeef2',
+    },
+
+    profitBarAnimationEchart: {
+      textColor: '#b2bac2',
+
+      firstAnimationBarColor: '#719efc',
+      secondAnimationBarColor: '#5dcfe3',
+
+      splitLineStyleOpacity: '0.06',
+      splitLineStyleWidth: '1',
+      splitLineStyleColor: '#000000',
+
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: '400',
+      tooltipFontSize: '16',
+      tooltipBg: '#eef2f5',
+      tooltipBorderColor: '#eef2f5',
+      tooltipBorderWidth: '3',
+      tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
+    },
+
+    trafficBarEchart: {
+      gradientFrom: '#ff8ea0',
+      gradientTo: '#ffa36b',
+      shadow: 'rgba(0, 0, 0, 0)',
+      shadowBlur: '0',
+
+      axisTextColor: '#b2bac2',
+      axisFontSize: '12',
+
+      tooltipBg: '#edf0f4',
+      tooltipBorderColor: '#ebeef2',
+      tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+    },
+
+    countryOrders: {
+      countryBorderColor: 'rgba(255, 255, 255, 1)',
+      countryFillColor: 'rgba(236, 242, 245, 1)',
+      countryBorderWidth: '1',
+      hoveredCountryBorderColor: 'rgba(113, 158, 252, 1)',
+      hoveredCountryFillColor: 'rgba(199, 216, 247, 1)',
+      hoveredCountryBorderWidth: '3',
+
+      chartAxisLineColor: 'rgba(0, 0, 0, 0)',
+      chartAxisTextColor: '#b2bac2',
+      chartAxisFontSize: '16',
+      chartGradientTo: 'rgba(113, 158, 252, 1)',
+      chartGradientFrom: 'rgba(113, 158, 252, 1)',
+      chartAxisSplitLine: '#ebeef2',
+      chartShadowLineColor: '#2f296b',
+
+      chartLineBottomShadowColor: 'rgba(113, 158, 252, 1)',
+
+      chartInnerLineColor: '#eceff4',
+    },
+
+    echarts: {
+      bg: '#ffffff',
+      textColor: '#484848',
+      axisLineColor: '#bbbbbb',
+      splitLineColor: '#ebeef2',
+      itemHoverShadowColor: 'rgba(0, 0, 0, 0.5)',
+      tooltipBackgroundColor: '#6a7985',
+      areaOpacity: '0.7',
+    },
+
+    chartjs: {
+      axisLineColor: '#cccccc',
+      textColor: '#484848',
+    },
+
+    orders: {
+      tooltipBg: '#ffffff',
+      tooltipLineColor: 'rgba(0, 0, 0, 0)',
+      tooltipLineWidth: '0',
+      tooltipBorderColor: '#ebeef2',
+      tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+      tooltipFontSize: '20',
+
+      axisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      axisFontSize: '16',
+      axisTextColor: '#b2bac2',
+      yAxisSplitLine: 'rgba(161, 161 ,229, 0.2)',
+
+      itemBorderColor: '#73a1ff',
+      lineStyle: 'solid',
+      lineWidth: '4',
+
+      // first line
+      firstAreaGradFrom: 'rgba(227, 236, 254, 0.7)',
+      firstAreaGradTo: 'rgba(227, 236, 254, 0.7)',
+      firstShadowLineDarkBg: 'rgba(0, 0, 0, 0)',
+
+      // second line
+      secondLineGradFrom: 'rgba(93, 207, 227, 1)',
+      secondLineGradTo: 'rgba(93, 207, 227, 1)',
+
+      secondAreaGradFrom: 'rgba(0, 0, 0, 0)',
+      secondAreaGradTo: 'rgba(0, 0, 0, 0)',
+      secondShadowLineDarkBg: 'rgba(0, 0, 0, 0)',
+
+      // third line
+      thirdLineGradFrom: 'rgba(113, 158, 252, 1)',
+      thirdLineGradTo: 'rgba(113, 158, 252, 1)',
+
+      thirdAreaGradFrom: 'rgba(0, 0, 0, 0)',
+      thirdAreaGradTo: 'rgba(0, 0, 0, 0)',
+      thirdShadowLineDarkBg: 'rgba(0, 0, 0, 0)',
+    },
+
+    profit: {
+      bg: '#ffffff',
+      textColor: '#ffffff',
+      axisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      splitLineColor: 'rgba(161, 161 ,229, 0.2)',
+      areaOpacity: '1',
+
+      axisFontSize: '16',
+      axisTextColor: '#b2bac2',
+
+      // first bar
+      firstLineGradFrom: '#719efc',
+      firstLineGradTo: '#719efc',
+      firstLineShadow: 'rgba(14, 16, 48, 0.4)',
+
+      // second bar
+      secondLineGradFrom: '#5dcfe3',
+      secondLineGradTo: '#5dcfe3',
+      secondLineShadow: 'rgba(14, 16, 48, 0.4)',
+
+      // third bar
+      thirdLineGradFrom: '#e3ecfe',
+      thirdLineGradTo: '#e3ecfe',
+      thirdLineShadow: 'rgba(14, 16, 48, 0.4)',
+    },
+
+    orderProfitLegend: {
+      firstItem: '#719efc',
+      secondItem: '#5dcfe3',
+      thirdItem: '#e3ecfe',
+    },
+
+    visitors: {
+      tooltipBg: '#ffffff',
+      tooltipLineColor: 'rgba(0, 0, 0, 0)',
+      tooltipLineWidth: '0',
+      tooltipBorderColor: '#ebeef2',
+      tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+      tooltipFontSize: '20',
+
+      axisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      axisFontSize: '16',
+      axisTextColor: '#b2bac2',
+      yAxisSplitLine: 'rgba(161, 161 ,229, 0.2)',
+
+      itemBorderColor: '#73a1ff',
+      lineStyle: 'dotted',
+      lineWidth: '6',
+      lineGradFrom: '#73a1ff',
+      lineGradTo: '#73a1ff',
+      lineShadow: 'rgba(0, 0, 0, 0)',
+
+      areaGradFrom: 'rgba(146, 181, 252, 1)',
+      areaGradTo: 'rgba(146, 181, 252, 1)',
+      shadowLineDarkBg: '#a695ff',
+
+      innerLineStyle: 'solid',
+      innerLineWidth: '1',
+
+      innerAreaGradFrom: 'rgba(227, 236, 254, 1)',
+      innerAreaGradTo: 'rgba(227, 236, 254, 1)',
+    },
+
+    visitorsLegend: {
+      firstIcon: '#e3ecfe',
+      secondIcon: '#719efc',
+    },
+
+    visitorsPie: {
+      firstPieGradientLeft: '#94e2ed',
+      firstPieGradientRight: '#94e2ed',
+      firstPieShadowColor: 'rgba(0, 0, 0, 0)',
+      firstPieRadius: ['65%', '90%'],
+
+      secondPieGradientLeft: '#719efc',
+      secondPieGradientRight: '#719efc',
+      secondPieShadowColor: '#b2cafb',
+      secondPieRadius: ['63%', '92%'],
+      shadowOffsetX: '-4',
+      shadowOffsetY: '-4',
+    },
+
+    visitorsPieLegend: {
+      firstSection: '#719efc',
+      secondSection: '#99e5ee',
+    },
+
+    earningPie: {
+      radius: ['65%', '100%'],
+      center: ['50%', '50%'],
+
+      fontSize: '22',
+
+      firstPieGradientLeft: '#719efc',
+      firstPieGradientRight: '#719efc',
+      firstPieShadowColor: 'rgba(0, 0, 0, 0)',
+
+      secondPieGradientLeft: '#ff9f6f',
+      secondPieGradientRight: '#ff9f6f',
+      secondPieShadowColor: 'rgba(0, 0, 0, 0)',
+
+      thirdPieGradientLeft: '#ff5e83',
+      thirdPieGradientRight: '#ff5e83',
+      thirdPieShadowColor: 'rgba(0, 0, 0, 0)',
+    },
+
+    earningLine: {
+      gradFrom: '#e3ecfe',
+      gradTo: '#e3ecfe',
+
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: '400',
+      tooltipFontSize: '16',
+      tooltipBg: '#eef2f5',
+      tooltipBorderColor: '#eef2f5',
+      tooltipBorderWidth: '3',
+      tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
+    },
+  },
+};
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/theme.cosmic.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/theme.cosmic.ts
new file mode 100644
index 0000000..27b1d69
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/theme.cosmic.ts
@@ -0,0 +1,309 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+export const COSMIC_THEME = {
+  name: 'cosmic',
+  base: 'default',
+  variables: {
+
+    temperature: [
+      '#2ec7fe',
+      '#31ffad',
+      '#7bff24',
+      '#fff024',
+      '#f7bd59',
+    ],
+
+    solar: {
+      gradientLeft: '#7bff24',
+      gradientRight: '#2ec7fe',
+      shadowColor: '#19977E',
+      radius: ['70%', '90%'],
+    },
+
+    traffic: {
+      colorBlack: '#000000',
+      tooltipBg: 'rgba(0, 255, 170, 0.35)',
+      tooltipBorderColor: '#00d977',
+      tooltipExtraCss: 'box-shadow: 0px 2px 46px 0 rgba(0, 255, 170, 0.35); border-radius: 10px; padding: 4px 16px;',
+      tooltipTextColor: '#ffffff',
+      tooltipFontWeight: 'normal',
+
+      lineBg: '#d1d1ff',
+      lineShadowBlur: '14',
+      itemColor: '#BEBBFF',
+      itemBorderColor: '#ffffff',
+      itemEmphasisBorderColor: '#ffffff',
+      shadowLineDarkBg: '#655ABD',
+      shadowLineShadow: 'rgba(33, 7, 77, 0.5)',
+      gradFrom: 'rgba(118, 89, 255, 0.4)',
+      gradTo: 'rgba(164, 84, 255, 0.5)',
+    },
+
+    electricity: {
+      tooltipBg: 'rgba(0, 255, 170, 0.35)',
+      tooltipLineColor: 'rgba(255, 255, 255, 0.1)',
+      tooltipLineWidth: '1',
+      tooltipBorderColor: '#00d977',
+      tooltipExtraCss: 'box-shadow: 0px 2px 46px 0 rgba(0, 255, 170, 0.35); border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#ffffff',
+      tooltipFontWeight: 'normal',
+
+      axisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      xAxisTextColor: '#a1a1e5',
+      yAxisSplitLine: 'rgba(161, 161 ,229, 0.2)',
+
+      itemBorderColor: '#ffffff',
+      lineStyle: 'dotted',
+      lineWidth: '6',
+      lineGradFrom: '#00ffaa',
+      lineGradTo: '#fff835',
+      lineShadow: 'rgba(14, 16, 48, 0.4)',
+
+      areaGradFrom: 'rgba(188, 92, 255, 0.5)',
+      areaGradTo: 'rgba(188, 92, 255, 0)',
+      shadowLineDarkBg: '#a695ff',
+    },
+
+    bubbleMap: {
+      titleColor: '#ffffff',
+      areaColor: '#2c2961',
+      areaHoverColor: '#a1a1e5',
+      areaBorderColor: '#654ddb',
+    },
+
+    profitBarAnimationEchart: {
+      textColor: '#ffffff',
+
+      firstAnimationBarColor: '#0088ff',
+      secondAnimationBarColor: '#7659ff',
+
+      splitLineStyleOpacity: '0.06',
+      splitLineStyleWidth: '1',
+      splitLineStyleColor: '#000000',
+
+      tooltipTextColor: '#ffffff',
+      tooltipFontWeight: 'normal',
+      tooltipFontSize: '16',
+      tooltipBg: 'rgba(0, 255, 170, 0.35)',
+      tooltipBorderColor: '#00d977',
+      tooltipBorderWidth: '3',
+      tooltipExtraCss: 'box-shadow: 0px 2px 46px 0 rgba(0, 255, 170, 0.35); border-radius: 10px; padding: 4px 16px;',
+    },
+
+    trafficBarEchart: {
+      gradientFrom: '#fc0',
+      gradientTo: '#ffa100',
+      shadow: '#ffb600',
+      shadowBlur: '5',
+
+      axisTextColor: '#a1a1e5',
+      axisFontSize: '12',
+
+      tooltipBg: 'rgba(0, 255, 170, 0.35)',
+      tooltipBorderColor: '#00d977',
+      tooltipExtraCss: 'box-shadow: 0px 2px 46px 0 rgba(0, 255, 170, 0.35); border-radius: 10px; padding: 4px 16px;',
+      tooltipTextColor: '#ffffff',
+      tooltipFontWeight: 'normal',
+    },
+
+    countryOrders: {
+      countryBorderColor: '#525dbd',
+      countryFillColor: '#4f41a6',
+      countryBorderWidth: '2',
+      hoveredCountryBorderColor: '#00f9a6',
+      hoveredCountryFillColor: '#377aa7',
+      hoveredCountryBorderWidth: '3',
+
+      chartAxisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      chartAxisTextColor: '#a1a1e5',
+      chartAxisFontSize: '16',
+      chartGradientTo: '#00c7c7',
+      chartGradientFrom: '#00d977',
+      chartAxisSplitLine: 'rgba(161, 161 ,229, 0.2)',
+      chartShadowBarColor: '#2f296b',
+
+      chartLineBottomShadowColor: '#00977e',
+
+      chartInnerLineColor: '#2f296b',
+    },
+
+    echarts: {
+      bg: '#3d3780',
+      textColor: '#ffffff',
+      axisLineColor: '#a1a1e5',
+      splitLineColor: '#342e73',
+      itemHoverShadowColor: 'rgba(0, 0, 0, 0.5)',
+      tooltipBackgroundColor: '#6a7985',
+      areaOpacity: '1',
+    },
+
+    chartjs: {
+      axisLineColor: '#a1a1e5',
+      textColor: '#ffffff',
+    },
+
+    orders: {
+      tooltipBg: 'rgba(0, 255, 170, 0.35)',
+      tooltipLineColor: 'rgba(255, 255, 255, 0.1)',
+      tooltipLineWidth: '1',
+      tooltipBorderColor: '#00d977',
+      tooltipExtraCss: 'box-shadow: 0px 2px 46px 0 rgba(0, 255, 170, 0.35); border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#ffffff',
+      tooltipFontWeight: 'normal',
+      tooltipFontSize: '20',
+
+      axisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      axisFontSize: '16',
+      axisTextColor: '#a1a1e5',
+      yAxisSplitLine: 'rgba(161, 161 ,229, 0.2)',
+
+      itemBorderColor: '#ffffff',
+      lineStyle: 'solid',
+      lineWidth: '4',
+
+      // first line
+      firstAreaGradFrom: 'rgba(78, 64, 164, 1)',
+      firstAreaGradTo: 'rgba(78, 64, 164, 1)',
+      firstShadowLineDarkBg: '#018dff',
+
+      // second line
+      secondLineGradFrom: '#00bece',
+      secondLineGradTo: '#00da78',
+
+      secondAreaGradFrom: 'rgba(38, 139, 145, 0.8)',
+      secondAreaGradTo: 'rgba(38, 139, 145, 0.5)',
+      secondShadowLineDarkBg: '#2c5a85',
+
+      // third line
+      thirdLineGradFrom: '#8069ff',
+      thirdLineGradTo: '#8357ff',
+
+      thirdAreaGradFrom: 'rgba(118, 73, 208, 0.7)',
+      thirdAreaGradTo: 'rgba(188, 92, 255, 0.4)',
+      thirdShadowLineDarkBg: '#a695ff',
+    },
+
+    profit: {
+      bg: '#3d3780',
+      textColor: '#ffffff',
+      axisLineColor: '#a1a1e5',
+      splitLineColor: '#342e73',
+      areaOpacity: '1',
+
+      axisFontSize: '16',
+      axisTextColor: '#a1a1e5',
+
+      // first bar
+      firstLineGradFrom: '#00bece',
+      firstLineGradTo: '#00da78',
+      firstLineShadow: 'rgba(14, 16, 48, 0.4)',
+
+      // second bar
+      secondLineGradFrom: '#8069ff',
+      secondLineGradTo: '#8357ff',
+      secondLineShadow: 'rgba(14, 16, 48, 0.4)',
+
+      // third bar
+      thirdLineGradFrom: '#4e40a4',
+      thirdLineGradTo: '#4e40a4',
+      thirdLineShadow: 'rgba(14, 16, 48, 0.4)',
+    },
+
+    orderProfitLegend: {
+      firstItem: 'linear-gradient(90deg, #00c7c7 0%, #00d977 100%)',
+      secondItem: 'linear-gradient(90deg, #a454ff 0%, #7659ff 100%)',
+      thirdItem: '#4e40a4',
+    },
+
+    visitors: {
+      tooltipBg: 'rgba(0, 255, 170, 0.35)',
+      tooltipLineColor: 'rgba(255, 255, 255, 0.1)',
+      tooltipLineWidth: '1',
+      tooltipBorderColor: '#00d977',
+      tooltipExtraCss: 'box-shadow: 0px 2px 46px 0 rgba(0, 255, 170, 0.35); border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#ffffff',
+      tooltipFontWeight: 'normal',
+
+      axisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      axisFontSize: '16',
+      axisTextColor: '#a1a1e5',
+      yAxisSplitLine: 'rgba(161, 161 ,229, 0.2)',
+
+      itemBorderColor: '#ffffff',
+      lineStyle: 'dotted',
+      lineWidth: '6',
+      lineGradFrom: '#ffffff',
+      lineGradTo: '#ffffff',
+      lineShadow: 'rgba(14, 16, 48, 0.4)',
+
+      areaGradFrom: 'rgba(188, 92, 255, 1)',
+      areaGradTo: 'rgba(188, 92, 255, 0.5)',
+      shadowLineDarkBg: '#a695ff',
+
+      innerLineStyle: 'solid',
+      innerLineWidth: '1',
+
+      innerAreaGradFrom: 'rgba(59, 165, 243, 1)',
+      innerAreaGradTo: 'rgba(4, 133, 243 , 1)',
+    },
+
+    visitorsLegend: {
+      firstIcon: 'linear-gradient(90deg, #0088ff 0%, #3dafff 100%)',
+      secondIcon: 'linear-gradient(90deg, #a454ff 0%, #7659ff 100%)',
+    },
+
+    visitorsPie: {
+      firstPieGradientLeft: '#7bff24',
+      firstPieGradientRight: '#2ec7fe',
+      firstPieShadowColor: '#19977E',
+      firstPieRadius: ['70%', '90%'],
+
+      secondPieGradientLeft: '#ff894a',
+      secondPieGradientRight: '#ffcc10',
+      secondPieShadowColor: '#cf7c1c',
+      secondPieRadius: ['60%', '95%'],
+      shadowOffsetX: '0',
+      shadowOffsetY: '3',
+    },
+
+    visitorsPieLegend: {
+      firstSection: 'linear-gradient(90deg, #ffcb17 0%, #ff874c 100%)',
+      secondSection: 'linear-gradient(90deg, #00c7c7 0%, #00d977 100%)',
+    },
+
+    earningPie: {
+      radius: ['65%', '100%'],
+      center: ['50%', '50%'],
+
+      fontSize: '22',
+
+      firstPieGradientLeft: '#00d77f',
+      firstPieGradientRight: '#00d77f',
+      firstPieShadowColor: 'rgba(0, 0, 0, 0)',
+
+      secondPieGradientLeft: '#7756f7',
+      secondPieGradientRight: '#7756f7',
+      secondPieShadowColor: 'rgba(0, 0, 0, 0)',
+
+      thirdPieGradientLeft: '#ffca00',
+      thirdPieGradientRight: '#ffca00',
+      thirdPieShadowColor: 'rgba(0, 0, 0, 0)',
+    },
+
+    earningLine: {
+      gradFrom: 'rgba(118, 89, 255, 0.4)',
+      gradTo: 'rgba(164, 84, 255, 0.5)',
+
+      tooltipTextColor: '#ffffff',
+      tooltipFontWeight: 'normal',
+      tooltipFontSize: '16',
+      tooltipBg: 'rgba(0, 255, 170, 0.35)',
+      tooltipBorderColor: '#00d977',
+      tooltipBorderWidth: '3',
+      tooltipExtraCss: 'box-shadow: 0px 2px 46px 0 rgba(0, 255, 170, 0.35); border-radius: 10px; padding: 4px 16px;',
+    },
+  },
+};
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/theme.default.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/theme.default.ts
new file mode 100644
index 0000000..7a98e5c
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/theme.default.ts
@@ -0,0 +1,312 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+export const DEFAULT_THEME = {
+  name: 'default',
+  base: null,
+  variables: {
+
+    // Safari fix
+    temperature: [
+      '#42db7d',
+      '#42db7d',
+      '#42db7d',
+      '#42db7d',
+      '#42db7d',
+    ],
+
+    solar: {
+      gradientLeft: '#42db7d',
+      gradientRight: '#42db7d',
+      shadowColor: 'rgba(0, 0, 0, 0)',
+      radius: ['80%', '90%'],
+    },
+
+    traffic: {
+      colorBlack: '#000000',
+      tooltipBg: '#ffffff',
+      tooltipBorderColor: '#c0c8d1',
+      tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+
+      lineBg: '#c0c8d1',
+      lineShadowBlur: '1',
+      itemColor: '#bcc3cc',
+      itemBorderColor: '#bcc3cc',
+      itemEmphasisBorderColor: '#42db7d',
+      shadowLineDarkBg: 'rgba(0, 0, 0, 0)',
+      shadowLineShadow: 'rgba(0, 0, 0, 0)',
+      gradFrom: '#ebeef2',
+      gradTo: '#ebeef2',
+    },
+
+    electricity: {
+      tooltipBg: '#ffffff',
+      tooltipLineColor: 'rgba(0, 0, 0, 0)',
+      tooltipLineWidth: '0',
+      tooltipBorderColor: '#ebeef2',
+      tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+
+      axisLineColor: 'rgba(0, 0, 0, 0)',
+      xAxisTextColor: '#2a2a2a',
+      yAxisSplitLine: '#ebeef2',
+
+      itemBorderColor: '#42db7d',
+      lineStyle: 'solid',
+      lineWidth: '4',
+      lineGradFrom: '#42db7d',
+      lineGradTo: '#42db7d',
+      lineShadow: 'rgba(0, 0, 0, 0)',
+
+      areaGradFrom: 'rgba(235, 238, 242, 0.5)',
+      areaGradTo: 'rgba(235, 238, 242, 0.5)',
+      shadowLineDarkBg: 'rgba(0, 0, 0, 0)',
+    },
+
+    bubbleMap: {
+      titleColor: '#484848',
+      areaColor: '#dddddd',
+      areaHoverColor: '#cccccc',
+      areaBorderColor: '#ebeef2',
+    },
+
+    profitBarAnimationEchart: {
+      textColor: '#484848',
+
+      firstAnimationBarColor: '#3edd81',
+      secondAnimationBarColor: '#8d7fff',
+
+      splitLineStyleOpacity: '0.06',
+      splitLineStyleWidth: '1',
+      splitLineStyleColor: '#000000',
+
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+      tooltipFontSize: '16',
+      tooltipBg: '#ffffff',
+      tooltipBorderColor: '#c0c8d1',
+      tooltipBorderWidth: '3',
+      tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
+    },
+
+    trafficBarEchart: {
+      gradientFrom: '#fc0',
+      gradientTo: '#ffa100',
+      shadow: '#ffb600',
+      shadowBlur: '0',
+
+      axisTextColor: '#b2bac2',
+      axisFontSize: '12',
+
+      tooltipBg: '#ffffff',
+      tooltipBorderColor: '#c0c8d1',
+      tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+    },
+
+    countryOrders: {
+      countryBorderColor: 'rgba(255, 255, 255, 1)',
+      countryFillColor: 'rgba(236, 242, 245, 1)',
+      countryBorderWidth: '1',
+      hoveredCountryBorderColor: '#40dc7e',
+      hoveredCountryFillColor: '#c7f4d9',
+      hoveredCountryBorderWidth: '3',
+
+      chartAxisLineColor: 'rgba(0, 0, 0, 0)',
+      chartAxisTextColor: '#b2bac2',
+      chartAxisFontSize: '16',
+      chartGradientTo: '#3edd81',
+      chartGradientFrom: '#3bddaf',
+      chartAxisSplitLine: '#ebeef2',
+      chartShadowLineColor: '#2f296b',
+
+      chartLineBottomShadowColor: '#eceff4',
+
+      chartInnerLineColor: '#eceff4',
+    },
+
+    echarts: {
+      bg: '#ffffff',
+      textColor: '#484848',
+      axisLineColor: '#bbbbbb',
+      splitLineColor: '#ebeef2',
+      itemHoverShadowColor: 'rgba(0, 0, 0, 0.5)',
+      tooltipBackgroundColor: '#6a7985',
+      areaOpacity: '0.7',
+    },
+
+    chartjs: {
+      axisLineColor: '#cccccc',
+      textColor: '#484848',
+    },
+
+    orders: {
+      tooltipBg: '#ffffff',
+      tooltipLineColor: 'rgba(0, 0, 0, 0)',
+      tooltipLineWidth: '0',
+      tooltipBorderColor: '#ebeef2',
+      tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+      tooltipFontSize: '20',
+
+      axisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      axisFontSize: '16',
+      axisTextColor: '#b2bac2',
+      yAxisSplitLine: 'rgba(161, 161 ,229, 0.2)',
+
+      itemBorderColor: '#42db7d',
+      lineStyle: 'solid',
+      lineWidth: '4',
+
+      // first line
+      firstAreaGradFrom: 'rgba(236, 242, 245, 0.8)',
+      firstAreaGradTo: 'rgba(236, 242, 245, 0.8)',
+      firstShadowLineDarkBg: 'rgba(0, 0, 0, 0)',
+
+      // second line
+      secondLineGradFrom: 'rgba(164, 123, 255, 1)',
+      secondLineGradTo: 'rgba(164, 123, 255, 1)',
+
+      secondAreaGradFrom: 'rgba(188, 92, 255, 0.2)',
+      secondAreaGradTo: 'rgba(188, 92, 255, 0)',
+      secondShadowLineDarkBg: 'rgba(0, 0, 0, 0)',
+
+      // third line
+      thirdLineGradFrom: 'rgba(55, 220, 136, 1)',
+      thirdLineGradTo: 'rgba(55, 220, 136, 1)',
+
+      thirdAreaGradFrom: 'rgba(31 ,106, 124, 0.2)',
+      thirdAreaGradTo: 'rgba(4, 126, 230, 0)',
+      thirdShadowLineDarkBg: 'rgba(0, 0, 0, 0)',
+    },
+
+    // TODO: need design for default theme
+    profit: {
+      bg: '#ffffff',
+      textColor: '#ffffff',
+      axisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      splitLineColor: 'rgba(161, 161 ,229, 0.2)',
+      areaOpacity: '1',
+
+      axisFontSize: '16',
+      axisTextColor: '#b2bac2',
+
+      // first bar
+      firstLineGradFrom: '#00bece',
+      firstLineGradTo: '#00da78',
+      firstLineShadow: 'rgba(14, 16, 48, 0.4)',
+
+      // second bar
+      secondLineGradFrom: '#8069ff',
+      secondLineGradTo: '#8357ff',
+      secondLineShadow: 'rgba(14, 16, 48, 0.4)',
+
+      // third bar
+      thirdLineGradFrom: 'rgba(236, 242, 245, 0.8)',
+      thirdLineGradTo: 'rgba(236, 242, 245, 0.8)',
+      thirdLineShadow: 'rgba(14, 16, 48, 0.4)',
+    },
+
+    orderProfitLegend: {
+      firstItem: 'linear-gradient(90deg, #3edd81 0%, #3bddad 100%)',
+      secondItem: 'linear-gradient(90deg, #8d7fff 0%, #b17fff 100%)',
+      thirdItem: 'rgba(236, 242, 245, 0.8)',
+    },
+
+    visitors: {
+      tooltipBg: '#ffffff',
+      tooltipLineColor: 'rgba(0, 0, 0, 0)',
+      tooltipLineWidth: '0',
+      tooltipBorderColor: '#ebeef2',
+      tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+      tooltipFontSize: '20',
+
+      axisLineColor: 'rgba(161, 161 ,229, 0.3)',
+      axisFontSize: '16',
+      axisTextColor: '#b2bac2',
+      yAxisSplitLine: 'rgba(161, 161 ,229, 0.2)',
+
+      itemBorderColor: '#42db7d',
+      lineStyle: 'dotted',
+      lineWidth: '6',
+      lineGradFrom: '#ffffff',
+      lineGradTo: '#ffffff',
+      lineShadow: 'rgba(14, 16, 48, 0)',
+
+      areaGradFrom: 'rgba(188, 92, 255, 1)',
+      areaGradTo: 'rgba(188, 92, 255, 0.5)',
+      shadowLineDarkBg: '#a695ff',
+
+      innerLineStyle: 'solid',
+      innerLineWidth: '1',
+
+      innerAreaGradFrom: 'rgba(60, 221, 156, 1)',
+      innerAreaGradTo: 'rgba(60, 221, 156, 1)',
+    },
+
+    visitorsLegend: {
+      firstIcon: 'linear-gradient(90deg, #3edd81 0%, #3bddad 100%)',
+      secondIcon: 'linear-gradient(90deg, #8d7fff 0%, #b17fff 100%)',
+    },
+
+    visitorsPie: {
+      firstPieGradientLeft: '#8defbb',
+      firstPieGradientRight: '#8defbb',
+      firstPieShadowColor: 'rgba(0, 0, 0, 0)',
+      firstPieRadius: ['70%', '90%'],
+
+      secondPieGradientLeft: '#ff894a',
+      secondPieGradientRight: '#ffcc10',
+      secondPieShadowColor: 'rgba(0, 0, 0, 0)',
+      secondPieRadius: ['60%', '97%'],
+      shadowOffsetX: '0',
+      shadowOffsetY: '0',
+    },
+
+    visitorsPieLegend: {
+      firstSection: 'linear-gradient(90deg, #ffcb17 0%, #ff874c 100%)',
+      secondSection: '#8defbb',
+    },
+
+    earningPie: {
+      radius: ['65%', '100%'],
+      center: ['50%', '50%'],
+
+      fontSize: '22',
+
+      firstPieGradientLeft: '#00d77f',
+      firstPieGradientRight: '#00d77f',
+      firstPieShadowColor: 'rgba(0, 0, 0, 0)',
+
+      secondPieGradientLeft: '#7756f7',
+      secondPieGradientRight: '#7756f7',
+      secondPieShadowColor: 'rgba(0, 0, 0, 0)',
+
+      thirdPieGradientLeft: '#ffca00',
+      thirdPieGradientRight: '#ffca00',
+      thirdPieShadowColor: 'rgba(0, 0, 0, 0)',
+    },
+
+    earningLine: {
+      gradFrom: 'rgba(188, 92, 255, 0.5)',
+      gradTo: 'rgba(188, 92, 255, 0.5)',
+
+      tooltipTextColor: '#2a2a2a',
+      tooltipFontWeight: 'bolder',
+      tooltipFontSize: '16',
+      tooltipBg: '#ffffff',
+      tooltipBorderColor: '#c0c8d1',
+      tooltipBorderWidth: '3',
+      tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
+    },
+  },
+};
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/themes.scss b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/themes.scss
new file mode 100644
index 0000000..d3012c3
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/styles/themes.scss
@@ -0,0 +1,120 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+// @nebular theming framework
+@import '~@nebular/theme/styles/theming';
+// @nebular out of the box themes
+@import '~@nebular/theme/styles/themes';
+
+// which themes you what to enable (empty to enable all)
+$nb-enabled-themes: (default, cosmic, corporate);
+
+$nb-themes: nb-register-theme((
+ // app wise variables for each theme
+  sidebar-header-gap: 2rem,
+  sidebar-header-height: initial,
+  layout-content-width: 1400px,
+
+  font-main: Roboto,
+  font-secondary: Exo,
+
+  switcher-background: #ebeff5,
+  switcher-background-percentage: 50%,
+  drops-icon-line-gadient: -webkit-linear-gradient(#01dbb5, #0bbb79),
+
+  list-item-border-width: 1px,
+
+  slide-out-container-width: 30%,
+  slide-out-background: linear-gradient(270deg, #f7fafb 0%, #ecf2f5 100%),
+  slide-out-shadow-color: 0 4px 14px 0 #a2d2c8,
+  slide-out-shadow-color-rtl: 0 4px 14px 0 #a2d2c8,
+
+  chart-panel-summary-box-shadow: none,
+  chart-panel-summary-background-color: #ecf2f5,
+  chart-panel-summary-border-color: #ebeff1,
+  chart-panel-summary-border-width: 1px,
+
+  ecommerce-card-border-width: 1px,
+
+  progress-bar-background: linear-gradient(90deg, #3edd81 0%, #3bddaf 100%),
+), default, default);
+
+$nb-themes: nb-register-theme((
+  // app wise variables for each theme
+  sidebar-header-gap: 2rem,
+  sidebar-header-height: initial,
+  layout-content-width: 1400px,
+
+  font-main: Roboto,
+  font-secondary: Exo,
+
+  switcher-background: #4e41a5,
+  switcher-background-percentage: 14%,
+  drops-icon-line-gadient: -webkit-linear-gradient(#a258fe, #7958fa),
+
+  list-item-border-width: 1px,
+
+  slide-out-container-width: 30%,
+  slide-out-background: radial-gradient(circle, #302c6e 0%, #423f8c 100%),
+  slide-out-shadow-color: 2px 0 3px rgba(19, 19, 94, 0.9),
+  slide-out-shadow-color-rtl: -2px 0 3px rgba(19, 19, 94, 0.9),
+
+  chart-panel-summary-box-shadow: none,
+  chart-panel-summary-background-color: rgba(0, 0, 0, 0.1),
+  chart-panel-summary-border-color: #332e73,
+  chart-panel-summary-border-width: 1px,
+
+  ecommerce-card-border-width: 1px,
+
+  progress-bar-background: linear-gradient(90deg, #00c7c7 0%, #00d977 100%),
+), cosmic, cosmic);
+
+$nb-themes: nb-register-theme((
+  // app wise variables for each theme
+  sidebar-header-gap: 2rem,
+  sidebar-header-height: initial,
+  layout-content-width: 1400px,
+
+  font-main: Roboto,
+  font-secondary: Exo,
+
+  switcher-background: #2b2d34,
+  switcher-background-percentage: 14%,
+  drops-icon-line-gadient: -webkit-linear-gradient(#e9e8eb, #a7a2be),
+
+  list-item-border-width: 1px,
+
+  slide-out-container-width: 30%,
+  slide-out-background: 	linear-gradient(270deg, #f7fafb 0%, #ecf2f5 100%),
+  slide-out-shadow-color: 0 4px 14px 0 #a2d2c8,
+  slide-out-shadow-color-rtl: 0 4px 14px 0 #a2d2c8,
+
+  chart-panel-summary-box-shadow: none,
+  chart-panel-summary-background-color: #f7fafb,
+  chart-panel-summary-border-color: #ebeff1,
+  chart-panel-summary-border-width: 1px,
+
+  ecommerce-card-border-width: 1px,
+
+  progress-bar-background: linear-gradient(90deg, #ff9f6f 0%, #ff8b97 100%),
+), corporate, corporate);
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/@theme/theme.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/@theme/theme.module.ts
new file mode 100644
index 0000000..c816a96
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/@theme/theme.module.ts
@@ -0,0 +1,124 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { ModuleWithProviders, NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+
+import {
+  NbActionsModule,
+  NbCardModule,
+  NbLayoutModule,
+  NbMenuModule,
+  NbRouteTabsetModule,
+  NbSearchModule,
+  NbSidebarModule,
+  NbTabsetModule,
+  NbThemeModule,
+  NbUserModule,
+  NbCheckboxModule,
+  NbPopoverModule,
+  NbContextMenuModule,
+  NbProgressBarModule,
+  NbSpinnerModule,
+} from '@nebular/theme';
+
+import { NbSecurityModule } from '@nebular/security';
+
+import {
+  FooterComponent,
+  HeaderComponent,
+  ThemeSettingsComponent,
+  SwitcherComponent,
+  ThemeSwitcherComponent,
+  ThemeSwitcherListComponent,
+} from './components';
+import {
+  CapitalizePipe,
+  PluralPipe,
+  RoundPipe,
+  TimingPipe,
+  NumberWithCommasPipe,
+  NoSanitizePipe
+} from './pipes';
+import {
+  OneColumnLayoutComponent,
+  DefaultLayoutComponent,
+} from './layouts';
+import { DEFAULT_THEME } from './styles/theme.default';
+import { COSMIC_THEME } from './styles/theme.cosmic';
+import { CORPORATE_THEME } from './styles/theme.corporate';
+
+const BASE_MODULES = [CommonModule, FormsModule, ReactiveFormsModule];
+
+const NB_MODULES = [
+  NbCardModule,
+  NbLayoutModule,
+  NbTabsetModule,
+  NbRouteTabsetModule,
+  NbMenuModule,
+  NbUserModule,
+  NbActionsModule,
+  NbSearchModule,
+  NbSidebarModule,
+  NbCheckboxModule,
+  NbPopoverModule,
+  NbContextMenuModule,
+  NgbModule,
+  NbSecurityModule, // *nbIsGranted directive,
+  NbProgressBarModule,
+  NbSpinnerModule
+];
+
+const COMPONENTS = [
+  SwitcherComponent,
+  ThemeSwitcherComponent,
+  ThemeSwitcherListComponent,
+  HeaderComponent,
+  FooterComponent,
+  ThemeSettingsComponent,
+  OneColumnLayoutComponent,
+  DefaultLayoutComponent,
+];
+
+const ENTRY_COMPONENTS = [
+  ThemeSwitcherListComponent,
+];
+
+const PIPES = [
+  CapitalizePipe,
+  PluralPipe,
+  RoundPipe,
+  TimingPipe,
+  NumberWithCommasPipe,
+  NoSanitizePipe,
+];
+
+const NB_THEME_PROVIDERS = [
+  ...NbThemeModule.forRoot(
+    {
+      name: 'default',
+    },
+    [ DEFAULT_THEME, COSMIC_THEME, CORPORATE_THEME ],
+  ).providers,
+  ...NbSidebarModule.forRoot().providers,
+  ...NbMenuModule.forRoot().providers,
+];
+
+@NgModule({
+  imports: [...BASE_MODULES, ...NB_MODULES],
+  exports: [...BASE_MODULES, ...NB_MODULES, ...COMPONENTS, ...PIPES],
+  declarations: [...COMPONENTS, ...PIPES],
+  entryComponents: [...ENTRY_COMPONENTS],
+})
+export class ThemeModule {
+  static forRoot(): ModuleWithProviders {
+    return <ModuleWithProviders>{
+      ngModule: ThemeModule,
+      providers: [...NB_THEME_PROVIDERS],
+    };
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/app-routing.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/app-routing.module.ts
new file mode 100644
index 0000000..ccc05ca
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/app-routing.module.ts
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { ExtraOptions, RouterModule, Routes } from '@angular/router';
+import { NgModule } from '@angular/core';
+import {
+  NbAuthComponent,
+  NbLoginComponent,
+  NbLogoutComponent,
+  NbRegisterComponent,
+  NbRequestPasswordComponent,
+  NbResetPasswordComponent,
+} from '@nebular/auth';
+
+const routes: Routes = [
+  { path: 'pages', loadChildren: 'app/pages/pages.module#PagesModule' },
+  { path: '', redirectTo: 'pages', pathMatch: 'full' },
+  { path: '**', redirectTo: 'pages' },
+];
+
+const config: ExtraOptions = {
+  useHash: true,
+};
+
+@NgModule({
+  imports: [RouterModule.forRoot(routes, config)],
+  exports: [RouterModule],
+})
+export class AppRoutingModule {
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/app.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/app.component.ts
new file mode 100644
index 0000000..8ceed64
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/app.component.ts
@@ -0,0 +1,22 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Component, OnInit } from '@angular/core';
+import { AnalyticsService } from './@core/utils/analytics.service';
+
+@Component({
+  selector: 'ngx-app',
+  template: `<toaster-container [toasterconfig]="config"></toaster-container>
+            <router-outlet></router-outlet>`,
+})
+export class AppComponent implements OnInit {
+
+  constructor(private analytics: AnalyticsService) {
+  }
+
+  ngOnInit(): void {
+    this.analytics.trackPageViews();
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/app.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/app.module.ts
new file mode 100644
index 0000000..d93b5bc
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/app.module.ts
@@ -0,0 +1,38 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { APP_BASE_HREF } from '@angular/common';
+import { BrowserModule } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { NgModule } from '@angular/core';
+import { HttpClientModule } from '@angular/common/http';
+import { CoreModule } from './@core/core.module';
+import { ToasterModule } from 'angular2-toaster';
+
+import { AppComponent } from './app.component';
+import { AppRoutingModule } from './app-routing.module';
+import { ThemeModule } from './@theme/theme.module';
+import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+
+@NgModule({
+  declarations: [AppComponent],
+  imports: [
+    BrowserModule,
+    BrowserAnimationsModule,
+    HttpClientModule,
+    AppRoutingModule,
+    ToasterModule.forRoot(),
+
+    NgbModule.forRoot(),
+    ThemeModule.forRoot(),
+    CoreModule.forRoot(),
+  ],
+  bootstrap: [AppComponent],
+  providers: [
+    { provide: APP_BASE_HREF, useValue: '/' },
+  ],
+})
+export class AppModule {
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/count-cards/count-cards.component.html b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/count-cards/count-cards.component.html
new file mode 100644
index 0000000..e662f15
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/count-cards/count-cards.component.html
@@ -0,0 +1,23 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<nb-card status="{{type}}">
+  <nb-card-header>
+    <div class="count-card-icon-container">
+        <i class="count-card-icon {{iconClass}}"></i>
+    </div>
+    {{title}} 
+    <span class="float-right count-card-number">{{number}}</span>
+  </nb-card-header>
+</nb-card>
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/count-cards/count-cards.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/count-cards/count-cards.component.scss
new file mode 100644
index 0000000..97274b1
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/count-cards/count-cards.component.scss
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+.count-card-icon-container {
+    border-radius: 3px;
+    background-color: #414141;
+    padding: 15px;
+    margin-top: -30px;
+    margin-right: 15px;
+    float: left;
+    box-shadow: 0 4px 20px 0 rgba(0,0,0,.14),0 7px 10px -5px rgba(255,152,0,.4);
+
+    .count-card-icon {
+        font-size: 1.25em;
+        color: #fff;
+    }
+    
+}
+.count-card-number{
+    font-size: 1.25em;
+    font-weight: 700;
+    color: #fff;
+    text-shadow: 1px 1px #7d7d7d;
+}
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/count-cards/count-cards.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/count-cards/count-cards.component.ts
new file mode 100644
index 0000000..9b4692e
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/count-cards/count-cards.component.ts
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Component, OnInit, Input } from '@angular/core';
+
+@Component({
+  selector: 'ngx-count-card',
+  templateUrl: './count-cards.component.html',
+  styleUrls: ['./count-cards.component.scss']
+})
+export class CountCardsComponent implements OnInit {
+
+  @Input() title: string;
+  @Input() footer: string;
+  @Input() number: number;
+  @Input() iconClass: string;
+  @Input() footerIconClass: string;
+  @Input() type: string;
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.component.html b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.component.html
new file mode 100644
index 0000000..c849fa3
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.component.html
@@ -0,0 +1,64 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<div [nbSpinner]="loading" nbSpinnerStatus="success" nbSpinnerSize="xxlarge">
+  <div class="row">
+    <div class="col-md-12">
+      <nb-card class="quick-stats-container-card" status="default">
+        <nb-card-header>
+            <div class="d-flex justify-content-between">
+                <div class="">
+                  <span class="card-header-title">Quick Stats</span>
+                  <small class="ml-2 text-muted"><i class="far fa-clock"></i> Last updated {{updatedAt}}</small>
+                </div>
+                <div class="">
+                  <nb-actions size="medium">
+                    <nb-action nbPopover="Refresh" nbPopoverMode="hint" icon="fas fa-sync-alt" (click)="refresh()" shape="semi-round" outline status="info"></nb-action>
+                  </nb-actions>
+                </div>
+              </div>
+        </nb-card-header>
+      </nb-card>
+    </div>
+    
+  </div>
+  <div class="row">
+    <div class="col-xxxl-2 col-md-2" *ngFor="let statusCard of statusCards">
+      <ngx-count-card [title]="statusCard.title"
+                      [type]="statusCard.type" 
+                      [iconClass]="statusCard.iconClass"
+                      [number]="statusCard.number"
+                      [footerIconClass]="statusCard.footerIconClass"
+                      [footer]="statusCard.footer">
+      </ngx-count-card>
+    </div>
+  </div>
+
+  <div class="row">
+    <div class="col-md-6">
+      <ngx-recent-table [transactionStatus]="'COMMITTED'" [showTitle]='true' [showActions]='true'></ngx-recent-table>
+    </div>
+    <div class="col-md-6">
+      <ngx-recent-table [transactionStatus]="'PENDING'" [showTitle]='true' [showActions]='true'></ngx-recent-table>
+    </div>
+  </div>
+  <div class="row">
+    <div class="col-md-6">
+      <ngx-recent-table [transactionStatus]="'COMPENSATING'" [showTitle]='true' [showActions]='true'></ngx-recent-table>
+    </div>
+    <div class="col-md-6">
+      <ngx-recent-table [transactionStatus]="'ROLLBACKED'" [showTitle]='true' [showActions]='true'></ngx-recent-table>
+    </div>
+  </div>
+</div>
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.component.scss
new file mode 100644
index 0000000..464b99c
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.component.scss
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+.count-card-icon-container {
+    border-radius: 3px;
+    background-color: #414141;
+    padding: 15px;
+    margin-top: -30px;
+    margin-right: 15px;
+    float: left;
+    box-shadow: 0 4px 20px 0 rgba(0,0,0,.14),0 7px 10px -5px rgba(255,152,0,.4);
+
+    
+}
+.count-card-icon {
+    font-size: 1.25em;
+    color: #fff;
+    text-align: center;
+}
+
+.count-card-number{
+    font-size: 1.25em;
+    font-weight: 700;
+    color: #fff;
+    text-shadow: 1px 1px #7d7d7d;
+}
+.quick-stats-container-card{
+    background: none;
+    box-shadow: none;
+}
+
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.component.ts
new file mode 100644
index 0000000..01c404a
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.component.ts
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { NbThemeService, NbSpinnerService } from '@nebular/theme';
+import { takeWhile } from 'rxjs/operators/takeWhile' ;
+import { SagaeventsService } from '../../@core/data/saga-events.service';
+import { UtilService } from '../../@core/utils/util.service';
+import * as _ from 'underscore';
+import { RecentTableComponent } from './recent-table/recent-table.component';
+
+interface CountCardSettings {
+  title: string;
+  footer: string;
+  number: number;
+  iconClass: string;
+  footerIconClass: string;
+  type: string;
+}
+
+@Component({
+  selector: 'ngx-dashboard',
+  templateUrl: './dashboard.component.html',
+  styleUrls: ['./dashboard.component.scss'],
+})
+export class DashboardComponent implements OnDestroy {
+
+  private alive = true;
+  private loading = false;
+  succTransactionsArr = [];
+  failedTransactionsArr = [];
+  committedTransArr =[];
+  pendingTransArr =[];
+  compensatingTransArr =[];
+  rollbackedTransArr =[];
+  successTxSettings: any;
+  failedTxSettings: any;
+  isGlobalTx: boolean = true;
+  committedTransactions: number;
+  compensatingTransactions: number;
+  failureRate: number;
+  pendingTransactions: number;
+  rollbackTransactions: number;
+  totalTransactions: number;
+  updatedAt: any;
+
+  totalTxCard: CountCardSettings = {
+    title: 'Total',
+    footer: 'Last updated few hours ago',
+    type: 'info',
+    number: 0,
+    iconClass: 'fas fa-exchange-alt',
+    footerIconClass: 'far fa-clock',
+  };
+
+  committedTxCard: CountCardSettings = {
+    title: 'Committed',
+    footer: 'Last updated few hours ago',
+    type: 'success',
+    number: 0,
+    iconClass: 'far fa-check-circle',
+    footerIconClass: 'far fa-clock',
+  };
+
+  pendingTxCard: CountCardSettings = {
+    title: 'Pending',
+    footer: 'Last updated few hours ago',
+    type: 'danger',
+    number: 0,
+    iconClass: 'fas fa-exclamation-circle',
+    footerIconClass: 'far fa-clock',
+  };
+
+  compensatingTxCard: CountCardSettings = {
+    title: 'Compensating',
+    footer: 'Last updated few hours ago',
+    type: 'danger',
+    number: 0,
+    iconClass: 'fas fa-exclamation-circle',
+    footerIconClass: 'far fa-clock',
+  };
+
+  rollbackTxCard: CountCardSettings = {
+    title: 'Rollback',
+    footer: 'Last updated few hours ago',
+    type: 'danger',
+    number: 0,
+    iconClass: 'fas fa-exclamation-circle',
+    footerIconClass: 'far fa-clock',
+  };
+
+  rateTxCard: CountCardSettings = {
+    title: 'Failure Rate',
+    footer: 'Last updated few hours ago',
+    type: 'primary',
+    number: 0,
+    iconClass: 'fas fa-percent',
+    footerIconClass: 'far fa-clock',
+  };
+
+
+  statusCards: string;
+
+  commonStatusCardsSet: CountCardSettings[] = [
+    this.totalTxCard,
+    this.committedTxCard,
+    this.pendingTxCard,
+    this.compensatingTxCard,
+    this.rollbackTxCard,
+    this.rateTxCard,
+  ];
+
+  statusCardsByThemes: {
+    default: CountCardSettings[];
+    cosmic: CountCardSettings[];
+    corporate: CountCardSettings[];
+  } = {
+    default: this.commonStatusCardsSet,
+    cosmic: this.commonStatusCardsSet,
+    corporate: [
+      {
+        ...this.totalTxCard,
+        type: 'info',
+      },
+      {
+        ...this.committedTxCard,
+        type: 'success',
+      },
+      {
+        ...this.pendingTxCard,
+        type: 'danger',
+      },
+      {
+        ...this.compensatingTxCard,
+        type: 'danger',
+      },
+      {
+        ...this.rollbackTxCard,
+        type: 'danger',
+      },
+      {
+        ...this.rateTxCard,
+        type: 'primary',
+      },
+    ],
+  };
+
+  constructor(private themeService: NbThemeService, private events: SagaeventsService, private util: UtilService) {
+    this.themeService.getJsTheme()
+      .pipe(takeWhile(() => this.alive))
+      .subscribe(theme => {
+        this.statusCards = this.statusCardsByThemes[theme.name];
+    });
+    this.getAllStats();
+  }
+  refresh(){
+    this.getAllStats();
+  }
+
+  //Get all stats
+  getAllStats(){
+    this.loading = true;
+    this.events.getAllStats().subscribe(data =>{
+      this.totalTxCard.number = data.body.totalTransactions;
+      this.committedTxCard.number = data.body.committedTransactions;
+      this.pendingTxCard.number = data.body.pendingTransactions;
+      this.compensatingTxCard.number = data.body.compensatingTransactions;
+      this.rollbackTxCard.number = data.body.rollbackTransactions;
+      this.rateTxCard.number = data.body.failureRate;
+      this.updatedAt = new Date(data.body.updatedAt);
+      this.loading = false;
+    },
+    (error) => {
+      this.util.error("Error!", "Something went wrong. The stats could not be fetched.");
+      this.loading = false;
+    });
+  }
+
+  ngOnDestroy() {
+    this.alive = false;
+    this.util.clearToasts();
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.module.ts
new file mode 100644
index 0000000..ebfe6eb
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/dashboard.module.ts
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule } from '@angular/core';
+import { Ng2SmartTableModule } from 'ng2-smart-table';
+
+import { ThemeModule } from '../../@theme/theme.module';
+import { DashboardComponent } from './dashboard.component';
+
+import { CountCardsComponent } from './count-cards/count-cards.component';
+import { RecentTableComponent } from './recent-table/recent-table.component';
+
+@NgModule({
+  imports: [
+    ThemeModule,
+    Ng2SmartTableModule,
+  ],
+  declarations: [
+    DashboardComponent,
+    CountCardsComponent,
+    RecentTableComponent,
+  ],
+  providers: [
+  ],
+})
+export class DashboardModule { }
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/recent-table/recent-table.component.html b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/recent-table/recent-table.component.html
new file mode 100644
index 0000000..a2476a9
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/recent-table/recent-table.component.html
@@ -0,0 +1,60 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<nb-card  status="info" class="recent-card">
+    <nb-card-header>
+      <div class="d-flex justify-content-between">
+        <div class="">
+          <span *ngIf="showTitle" class="card-header-title">Recent {{transactionStatus}} transactions</span>
+        </div>
+        <div class="">
+          <nb-actions *ngIf="showActions" size="small" inverse="true">
+            <nb-action nbPopover="View All Transactions" nbPopoverMode="hint" icon="fas fa-external-link-alt" (click)="showAll(transactionStatus)"></nb-action>
+            <nb-action nbPopover="Refresh" nbPopoverMode="hint" icon="fas fa-sync-alt" (click)="refreshTable()"></nb-action>
+          </nb-actions>
+        </div>
+      </div>
+    </nb-card-header>
+    <nb-card-body>
+      <div class="table-responsive-sm">
+        <table class="table">
+          <thead>
+            <tr class="d-flex">
+              <th class="col-1">ID</th>
+              <th class="col-1">Service Name</th>
+              <th class="col-1">Instance ID</th>
+              <th class="col-2">Global Tx ID</th>
+              <th class="col-2">Local Tx ID</th>
+              <th class="col-2">Created At</th>
+              <th class="col-3">Compensation Method</th>
+            </tr>
+          </thead>
+          <tbody *ngIf="txCount">
+            <tr *ngFor="let event of recTransactionsArr | slice:0:5" class="d-flex">
+              <td class="col-1">{{event.surrogateId}}</td>
+              <td class="col-1">{{event.serviceName}}</td>
+              <td class="col-1">{{event.instanceId}}</td>
+              <td class="col-2">{{event.globalTxId}}</td>
+              <td class="col-2">{{event.localTxId}}</td>
+              <td class="col-2">{{event.creationTime | date:'MMMM d, y, h:mm:ss a zzzz'}}</td>
+              <td nbPopover="{{event.compensationMethod}}"  nbPopoverMode="hover" class="col-3 text-truncate">{{event.compensationMethod?event.compensationMethod:'-'}}</td>
+            </tr>
+          </tbody>
+          <tbody *ngIf='!txCount'>
+            <p class="d-flex justify-content-center align-items-center mt-5">No Data Available.</p>
+          </tbody>
+        </table>
+      </div>
+    </nb-card-body>
+  </nb-card>
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/recent-table/recent-table.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/recent-table/recent-table.component.scss
new file mode 100644
index 0000000..54519b9
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/recent-table/recent-table.component.scss
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+.recent-card{
+    min-height: 527px;
+}
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/recent-table/recent-table.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/recent-table/recent-table.component.ts
new file mode 100644
index 0000000..a0b7808
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/dashboard/recent-table/recent-table.component.ts
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Component, OnInit, Input } from '@angular/core';
+import { SagaeventsService } from '../../../@core/data/saga-events.service';
+import { UtilService } from '../../../@core/utils/util.service';
+import { NavigationEnd, ActivatedRoute, Router } from '@angular/router';
+import * as _ from 'underscore';
+
+@Component({
+  selector: 'ngx-recent-table',
+  templateUrl: './recent-table.component.html',
+  styleUrls: ['./recent-table.component.scss']
+})
+export class RecentTableComponent implements OnInit {
+  @Input() transactionStatus: string;
+  @Input() cardType: string;
+  @Input() showTitle: boolean;
+  @Input() showActions: boolean;
+  private loading = false;
+  recTransactionsArr: any;
+  txCount: number;
+
+
+  constructor(private events: SagaeventsService, private util: UtilService, private router: Router) {
+   }
+
+  ngOnInit() {
+    this.getRecentTransactions(this.transactionStatus);
+  }
+
+  refreshTable(){
+    this.getRecentTransactions(this.transactionStatus);
+  }
+
+  showAll(status: any){
+    let url = '/pages/transactions/' + status.toLowerCase();
+    this.router.navigate([url], {queryParams: {type: status}});
+  }
+
+  getRecentTransactions(status: any){
+    this.loading = true;
+    this.events.getRecentTransactions(status).subscribe(data => {
+      this.recTransactionsArr = _.sortBy(data.body, function(item){
+        return -item['creationTime']; //Sorted by Create time
+      });
+      this.txCount = data.body.length;
+      this.loading = false;
+      let message = 'All recent ' + status + ' transactions have been fetched.';
+      this.util.success("", message);
+    },
+    (error) => {
+      this.recTransactionsArr = [];
+      let message = 'Something went wrong. The ' + status + ' transactions could not be fetched.';
+      this.util.error("Error!", message);
+    });
+  }
+
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/miscellaneous-routing.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/miscellaneous-routing.module.ts
new file mode 100644
index 0000000..aa2885b
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/miscellaneous-routing.module.ts
@@ -0,0 +1,30 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { MiscellaneousComponent } from './miscellaneous.component';
+import { NotFoundComponent } from './not-found/not-found.component';
+
+const routes: Routes = [{
+  path: '',
+  component: MiscellaneousComponent,
+  children: [{
+    path: '404',
+    component: NotFoundComponent,
+  }],
+}];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class MiscellaneousRoutingModule { }
+
+export const routedComponents = [
+  MiscellaneousComponent,
+  NotFoundComponent,
+];
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/miscellaneous.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/miscellaneous.component.ts
new file mode 100644
index 0000000..a75713e
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/miscellaneous.component.ts
@@ -0,0 +1,15 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'ngx-miscellaneous',
+  template: `
+    <router-outlet></router-outlet>
+  `,
+})
+export class MiscellaneousComponent {
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/miscellaneous.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/miscellaneous.module.ts
new file mode 100644
index 0000000..2c37c39
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/miscellaneous.module.ts
@@ -0,0 +1,19 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { NgModule } from '@angular/core';
+import { ThemeModule } from '../../@theme/theme.module';
+import { MiscellaneousRoutingModule, routedComponents } from './miscellaneous-routing.module';
+
+@NgModule({
+  imports: [
+    ThemeModule,
+    MiscellaneousRoutingModule,
+  ],
+  declarations: [
+    ...routedComponents,
+  ],
+})
+export class MiscellaneousModule { }
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/not-found/not-found.component.html b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/not-found/not-found.component.html
new file mode 100644
index 0000000..0a50058
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/not-found/not-found.component.html
@@ -0,0 +1,29 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<div class="row">
+  <div class="col-md-12">
+    <nb-card>
+      <nb-card-body>
+        <div class="flex-centered col-xl-4 col-lg-6 col-md-8 col-sm-12">
+          <h2 class="title">404 Page Not Found</h2>
+          <small class="sub-title">The page you were looking for doesn't exist</small>
+          <button (click)="goToHome()" type="button" class="btn btn-block btn-hero-primary">
+            Take me home
+          </button>
+        </div>
+      </nb-card-body>
+    </nb-card>
+  </div>
+</div>
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/not-found/not-found.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/not-found/not-found.component.scss
new file mode 100644
index 0000000..5321a4f
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/not-found/not-found.component.scss
@@ -0,0 +1,43 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+.flex-centered {
+  margin: auto;
+}
+nb-card-body {
+  display: flex;
+}
+
+.title {
+  text-align: center;
+}
+
+.sub-title {
+  text-align: center;
+  display: block;
+  margin-bottom: 3rem;
+}
+
+.btn {
+  margin-bottom: 2rem;
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/not-found/not-found.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/not-found/not-found.component.ts
new file mode 100644
index 0000000..cea8863
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/miscellaneous/not-found/not-found.component.ts
@@ -0,0 +1,22 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { NbMenuService } from '@nebular/theme';
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'ngx-not-found',
+  styleUrls: ['./not-found.component.scss'],
+  templateUrl: './not-found.component.html',
+})
+export class NotFoundComponent {
+
+  constructor(private menuService: NbMenuService) {
+  }
+
+  goToHome() {
+    this.menuService.navigateHome();
+  }
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/pages-menu.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/pages-menu.ts
new file mode 100644
index 0000000..7979100
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/pages-menu.ts
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NbMenuItem } from '@nebular/theme';
+
+export const MENU_ITEMS: NbMenuItem[] = [
+  {
+    title: 'Dashboard',
+    icon: 'icon ion-speedometer',
+    link: '/pages/dashboard',
+    home: true,
+  },
+  {
+    title: 'Saga Transactions',
+    icon: 'fas fa-exchange-alt',
+    link: '/pages/transactions',
+    expanded: false,
+    children: [
+      {
+        title: 'All Transactions',
+        link: '/pages/transactions',
+        queryParams: {type: "ALL"},
+      },
+      {
+        title: 'Committed Transactions',
+        link: '/pages/transactions/committed',
+        queryParams: {type: "COMMITTED"},
+      },
+      {
+        title: 'Pending Transactions',
+        link: '/pages/transactions/pending',
+        queryParams: {type: "PENDING"},
+      },
+      {
+        title: 'Compensating Transactions',
+        link: '/pages/transactions/compensating',
+        queryParams: {type: "COMPENSATING"},
+      },
+      {
+        title: 'Rollback Transactions',
+        link: '/pages/transactions/rollbacked',
+        queryParams: {type: "ROLLBACKED"},
+      }
+    ],
+  },{
+    title: 'Find Transactions',
+    icon: 'icon ion-search',
+    link: '/pages/find',
+  },
+];
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/pages-routing.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/pages-routing.module.ts
new file mode 100644
index 0000000..55dc5a1
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/pages-routing.module.ts
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { RouterModule, Routes } from '@angular/router';
+import { NgModule } from '@angular/core';
+
+import { PagesComponent } from './pages.component';
+import { DashboardComponent } from './dashboard/dashboard.component';
+import {TransactionsComponent} from './transactions/transactions.component';
+import {FindTransactionComponent} from './transactions/findTransaction.component'
+import { NotFoundComponent } from './miscellaneous/not-found/not-found.component';
+
+const routes: Routes = [{
+  path: '',
+  component: PagesComponent,
+  children: [{
+    path: 'dashboard',
+    component: DashboardComponent,
+  },  {
+    path: 'transactions',
+    component: TransactionsComponent,
+  },{
+    path: 'transactions/committed',
+    component: TransactionsComponent,
+  },
+  {
+    path: 'transactions/pending',
+    component: TransactionsComponent,
+  },
+  {
+    path: 'transactions/compensating',
+    component: TransactionsComponent,
+  },
+  {
+    path: 'transactions/rollbacked',
+    component: TransactionsComponent,
+  },
+  {
+    path: 'find',
+    component: FindTransactionComponent,
+  },
+  {
+    path: '',
+    redirectTo: 'dashboard',
+    pathMatch: 'full',
+  }, {
+    path: '**',
+    component: NotFoundComponent,
+  }],
+}];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class PagesRoutingModule {
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/pages.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/pages.component.ts
new file mode 100644
index 0000000..b44d069
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/pages.component.ts
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */import { Component } from '@angular/core';
+
+import { MENU_ITEMS } from './pages-menu';
+
+@Component({
+  selector: 'ngx-pages',
+  template: `
+  <ngx-default-layout>
+  <nb-menu [items]="menu"></nb-menu>
+  
+  <router-outlet></router-outlet>
+  </ngx-default-layout>
+  `,
+})
+export class PagesComponent {
+
+  menu = MENU_ITEMS;
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/pages.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/pages.module.ts
new file mode 100644
index 0000000..2df6cc8
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/pages.module.ts
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule } from '@angular/core';
+
+import { PagesComponent } from './pages.component';
+import { DashboardModule } from './dashboard/dashboard.module';
+import { TransactionsModule } from './transactions/transactions.module';
+import { PagesRoutingModule } from './pages-routing.module';
+import { ThemeModule } from '../@theme/theme.module';
+
+import { MiscellaneousModule } from './miscellaneous/miscellaneous.module';
+
+const PAGES_COMPONENTS = [
+  PagesComponent,
+];
+
+@NgModule({
+  imports: [
+    PagesRoutingModule,
+    ThemeModule,
+    DashboardModule,
+    TransactionsModule,
+    MiscellaneousModule,
+  ],
+  declarations: [
+    ...PAGES_COMPONENTS,
+  ],
+})
+export class PagesModule {
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/customRender.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/customRender.component.ts
new file mode 100644
index 0000000..0d5c6db
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/customRender.component.ts
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Component, Input, OnInit } from '@angular/core';
+import { NavigationEnd, ActivatedRoute, Router } from '@angular/router';
+import { ViewCell } from 'ng2-smart-table';
+
+@Component({
+  template: `
+    <a href="javascript:void(0)" title="View Transactions" class="nav-link" (click)="showDetails(value)">{{value}}</a>
+  `,
+})
+export class CustomRenderComponent implements ViewCell, OnInit {
+
+  renderValue: string;
+
+  @Input() value: string | number;
+  @Input() rowData: any;
+
+  constructor(private router: Router){}
+
+  ngOnInit() {
+  }
+  showDetails(gid: any){
+    if(this.value=== this.rowData.globalTxId){
+      this.router.navigate(['/pages/find'], {queryParams: {gid: this.value}});
+    } 
+    if(this.value === this.rowData.serviceName){
+      this.router.navigate(['/pages/find'], {queryParams: {serviceName: this.rowData.serviceName}});
+    }
+    
+  }
+
+}
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/findTransaction.component.html b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/findTransaction.component.html
new file mode 100644
index 0000000..78068ca
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/findTransaction.component.html
@@ -0,0 +1,48 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<nb-card [nbSpinner]="loading" nbSpinnerStatus="success" nbSpinnerSize="xxlarge" status="info">
+      <nb-card-header>
+          <div class="row">
+            <div class="col-4">
+              Find Transactions
+            </div>
+          </div>
+      </nb-card-header>
+      <nb-card-body>
+            <form>
+                <div class="form-group form-row align-items-center">
+                    <div class="col">
+                        <label class="sr-only" for="findGID">Global ID</label>
+                        <input [disabled]="hideGID" (change)="hideName=true;hideGID=false" [(ngModel)]="globalID" required nbInput  type="text" class="form-control mb-2" id="findGID" name="findGID" placeholder="Global ID">
+                        <small class="form-text text-muted">Please enter either Global ID or Micro Service Name.</small>
+                    </div>
+                    <div class="col">
+                        <label class="sr-only" for="findName">Micro Service Name</label>
+                        <div class="input-group mb-4">
+                            <input [disabled]="hideName" (change)="hideGID=true;hideName=false" [(ngModel)]="serviceName" required nbInput type="text" class="form-control" id="findName" name="findName" placeholder="Micro Service Name">
+                        </div>
+                    </div>
+                    <div class="col-auto">
+                        <input nbButton status="success" size="small" class="mb-4" (click)="findTransaction(globalID, serviceName)" value="Find"/>
+                        <input nbButton status="info" size="small" class="mb-4 ml-2" (click)="resetForm()" value="Clear" />
+                    </div>
+                </div>
+            </form>
+            <div>
+                <ngx-transactions-table [showTitle]="false" [title]="Transactions" [showCount]="false" [hideRefresh]="true" [tableData]= "transactionsArr"></ngx-transactions-table>
+            </div>
+
+      </nb-card-body>
+  </nb-card>
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/findTransaction.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/findTransaction.component.ts
new file mode 100644
index 0000000..0586f08
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/findTransaction.component.ts
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {ActivatedRoute, Params} from '@angular/router';
+import { Component, OnInit, Input, OnDestroy, ViewChild } from '@angular/core';
+import { ElementRef, Renderer2 } from '@angular/core';
+import { SagaeventsService } from '../../@core/data/saga-events.service';
+import {TransactionsTableComponent} from './transactionsTable.component';
+import { UtilService } from '../../@core/utils/util.service';
+import * as _ from 'underscore';
+
+@Component({
+    selector: 'ngx-find-transactions',
+    templateUrl: './findTransaction.component.html',
+  })
+  export class FindTransactionComponent implements OnInit { 
+    transactionsArr = [];
+    type: any;
+    globalID: any;
+    serviceName: any;
+    hideGID: boolean;
+    hideName: boolean;
+    loading: boolean;
+
+    constructor(private events: SagaeventsService, private util: UtilService, private activatedRoute: ActivatedRoute){
+        this.activatedRoute.queryParams.subscribe(params => {
+          this.globalID = params['gid'];
+        });
+      }
+
+      findTransaction(gid?:any, name?: any) {
+        this.loading = true;
+        this.util.clearToasts();
+        this.events.findTransaction(gid, name).subscribe(data => {
+          this.transactionsArr = data.body; 
+          if(this.transactionsArr.length){
+            this.util.success("", "All transactions have been fetched");
+          }
+          this.loading = false;
+        },
+        (error) => {
+          this.util.error("Error!", "Something went wrong. The transactions could not be fetched.");
+          this.loading = false;
+        });
+      }
+      resetForm(){
+          this.transactionsArr = [];
+          this.globalID = "";
+          this.serviceName = "";
+          this.hideGID = false;
+          this.hideName = false;
+      }
+
+      ngOnInit() {
+        this.activatedRoute.queryParams.subscribe(params => {
+            this.globalID = params['gid'];
+            this.serviceName = params['serviceName'];
+          if(params['gid']){
+             this.findTransaction(params['gid']);
+          }
+          if(params['serviceName']){
+            this.findTransaction(undefined, params['serviceName']);
+          }
+        });
+      }
+  }
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactions.component.html b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactions.component.html
new file mode 100644
index 0000000..22e0cf4
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactions.component.html
@@ -0,0 +1,15 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<ngx-transactions-table [showTitle]="true" [title]="type" [showCount]="true" [hideRefresh]="false" [tableData]= "transactionsArr"></ngx-transactions-table>
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactions.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactions.component.ts
new file mode 100644
index 0000000..ac7a7ef
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactions.component.ts
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {Router, ActivatedRoute, Params} from '@angular/router';
+import { Component, OnInit, Input, OnDestroy } from '@angular/core';
+import { SagaeventsService } from '../../@core/data/saga-events.service';
+import {TransactionsTableComponent} from './transactionsTable.component';
+import { UtilService } from '../../@core/utils/util.service';
+import * as _ from 'underscore';
+
+@Component({
+    selector: 'ngx-all-transactions',
+    templateUrl: './transactions.component.html',
+  })
+  export class TransactionsComponent implements OnInit { 
+    transactionsArr = [];
+    type: any;
+      constructor(private events: SagaeventsService, private util: UtilService, private activatedRoute: ActivatedRoute){
+        this.activatedRoute.queryParams.subscribe(params => {
+          this.type = params['type'];
+        });
+        this.getAllTransactions(this.type);
+      }
+
+      getAllTransactions(status: any) {
+        this.events.getTransactions(status).subscribe(data => {
+          this.transactionsArr = data.body; 
+          this.util.success("Transactions fetched!", "All transactions have been fetched");
+        },
+        (error) => {
+          this.util.error("Error!", "Something went wrong. The transactions could not be fetched.");
+        });
+      }
+
+      ngOnInit() {
+        this.activatedRoute.queryParams.subscribe(params => {
+          this.type = params['type'];
+        });
+      }
+  }
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactions.module.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactions.module.ts
new file mode 100644
index 0000000..aab07db
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactions.module.ts
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { Ng2SmartTableModule } from 'ng2-smart-table';
+import { CustomRenderComponent } from './customRender.component';
+
+import { ThemeModule } from '../../@theme/theme.module';
+import { TransactionsTableComponent} from './transactionsTable.component';
+import { TransactionsComponent} from './transactions.component';
+import { FindTransactionComponent } from './findTransaction.component';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    ThemeModule,
+    Ng2SmartTableModule,
+  ],
+  entryComponents: [CustomRenderComponent],
+  declarations: [TransactionsTableComponent , TransactionsComponent, FindTransactionComponent, CustomRenderComponent]
+})
+export class TransactionsModule { }
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactionsTable.component.html b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactionsTable.component.html
new file mode 100644
index 0000000..b2e5973
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactionsTable.component.html
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<div *ngIf="!hideRefresh" class="row">
+  <div class="col-xxxl-12 col-md-12 mb-4">
+      <button title="Refresh" (click)="refresh()" class="float-left" nbButton shape="semi-round" outline status="info"><i class="fas  fa-sync-alt"></i></button>
+  </div>
+</div>
+<nb-card status="info">
+    <nb-card-header>
+        <div class="row">
+          <div class="col-4">
+            <span *ngIf="showTitle">{{title}}</span>
+          </div>
+          <div class=" float-right offset-4 col-4">
+            <span *ngIf="showCount">Total Transactions: {{tableData.length}}</span>
+          </div>
+        </div>
+    </nb-card-header>
+    <nb-card-body>
+        <ng2-smart-table [settings]='settings' [source]='tableData'></ng2-smart-table>
+    </nb-card-body>
+</nb-card>
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactionsTable.component.scss b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactionsTable.component.scss
new file mode 100644
index 0000000..4bedc40
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactionsTable.component.scss
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+:host /deep/ ng2-smart-table table tr td{
+    /* font-size:0.9em; */
+    word-break: break-all;
+    }
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactionsTable.component.ts b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactionsTable.component.ts
new file mode 100644
index 0000000..581c493
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/app/pages/transactions/transactionsTable.component.ts
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Component, OnInit, Input, OnDestroy } from '@angular/core';
+import { DomSanitizer, SafeResourceUrl, SafeUrl} from '@angular/platform-browser';
+import { RouterModule, Routes, Router } from '@angular/router';
+import { NbThemeService } from '@nebular/theme';
+import { takeWhile } from 'rxjs/operators/takeWhile' ;
+import { SagaeventsService } from '../../@core/data/saga-events.service';
+import { UtilService } from '../../@core/utils/util.service';
+import * as _ from 'underscore';
+
+import { CustomRenderComponent } from './customRender.component';
+
+
+
+@Component({
+  selector: 'ngx-transactions-table',
+  templateUrl: './transactionsTable.component.html',
+  styleUrls: ['./transactionsTable.component.scss']
+})
+export class TransactionsTableComponent implements OnInit, OnDestroy {
+  @Input() tableData: any;
+  @Input() hideRefresh: boolean;
+  @Input() showTitle: boolean;
+  @Input() title: string;
+  @Input() showCount: boolean;
+
+  private alive = true;
+  transactions: any;
+  settings: any;
+
+  constructor(private events: SagaeventsService, private util: UtilService, private router: Router, private sanitizer: DomSanitizer) { }
+
+  ngOnInit() {
+    this.transactions = this.tableData;
+    this.setTransactionsTable();
+  }
+
+  refresh(){
+    this. setTransactionsTable();
+  }
+
+  setTransactionsTable() {
+    this.settings = {
+      pager: {
+        perPage: 10,
+      },
+      add: {
+        addButtonContent: '<i class="nb-plus"></i>',
+        createButtonContent: '<i class="nb-checkmark"></i>',
+        cancelButtonContent: '<i class="nb-close"></i>',
+      },
+      edit: {
+        editButtonContent: '<i class="nb-edit"></i>',
+        saveButtonContent: '<i class="nb-checkmark"></i>',
+        cancelButtonContent: '<i class="nb-close"></i>',
+      },
+      delete: {
+        deleteButtonContent: '<i class="nb-trash"></i>',
+        confirmDelete: true,
+      },
+      actions: {
+        add: false,
+        edit: false,
+        delete: false,
+        position: 'right',
+      },
+      columns: {
+        surrogateId: {
+          title: 'ID',
+          filter: true,
+          sort: true,
+          editable: false,
+          width: '5%',
+        },
+        serviceName: {
+          title: 'Service Name',
+          filter: true,
+          sort: true,
+          editable: false,
+          width: '9%',
+          type:'custom',
+          renderComponent: CustomRenderComponent,
+        },
+        instanceId: {
+          title: 'Instance ID',
+          editable: false,
+          width: '11%',
+        },
+        globalTxId: {
+          title: 'Global ID',
+          filter: true,
+          sort: true,
+          width: '16%',
+          editable: false,
+          type:'custom',
+          renderComponent: CustomRenderComponent,
+        },
+        localTxId: {
+          title: 'Local ID',
+          filter: true,
+          sort: true,
+          width: '15%',
+          editable: false
+        },
+        compensationMethod: {
+          title: 'Compensation Method',
+          editable: false,
+          width: '20%',
+        },
+      },
+
+    };
+  }
+
+  ngOnDestroy() {
+    this.alive = false;
+    this.util.clearToasts();
+  }
+
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/assets/images/square_pattern.svg b/saga-web/src/main/resources/saga-frontend/src/assets/images/square_pattern.svg
new file mode 100644
index 0000000..dda0f42
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/assets/images/square_pattern.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150"><defs><style>.cls-1{fill:none;stroke:#ebeef2;stroke-miterlimit:10;}</style></defs><title>Asset 2_svg</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><line class="cls-1" x1="75" x2="75" y2="150"/><line class="cls-1" x1="150" y1="75" y2="75"/></g></g></svg>
\ No newline at end of file
diff --git a/saga-web/src/main/resources/saga-frontend/src/assets/images/square_pattern_cosmic.svg b/saga-web/src/main/resources/saga-frontend/src/assets/images/square_pattern_cosmic.svg
new file mode 100644
index 0000000..fa11141
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/assets/images/square_pattern_cosmic.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150"><defs><style>.cls-1{fill:none;stroke:#342e73;stroke-miterlimit:10;}</style></defs><title>Asset 2_svg</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><line class="cls-1" x1="75" x2="75" y2="150"/><line class="cls-1" x1="150" y1="75" y2="75"/></g></g></svg>
diff --git a/saga-web/src/main/resources/saga-frontend/src/environments/environment.prod.ts b/saga-web/src/main/resources/saga-frontend/src/environments/environment.prod.ts
new file mode 100644
index 0000000..868175c
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/environments/environment.prod.ts
@@ -0,0 +1,9 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+export const environment = {
+  production: true,
+  apiUrl: 'http://127.0.0.1:8090',
+};
diff --git a/saga-web/src/main/resources/saga-frontend/src/environments/environment.ts b/saga-web/src/main/resources/saga-frontend/src/environments/environment.ts
new file mode 100644
index 0000000..29ab5e3
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/environments/environment.ts
@@ -0,0 +1,15 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+// The file contents for the current environment will overwrite these during build.
+// The build system defaults to the dev environment which uses `environment.ts`, but if you do
+// `ng build --env=prod` then `environment.prod.ts` will be used instead.
+// The list of which env maps to which file can be found in `.angular-cli.json`.
+
+export const environment = {
+  production: false,
+  
+  apiUrl: 'http://127.0.0.1:8090',
+};
diff --git a/saga-web/src/main/resources/saga-frontend/src/favicon.ico b/saga-web/src/main/resources/saga-frontend/src/favicon.ico
new file mode 100644
index 0000000..a4895ba
Binary files /dev/null and b/saga-web/src/main/resources/saga-frontend/src/favicon.ico differ
diff --git a/saga-web/src/main/resources/saga-frontend/src/favicon.png b/saga-web/src/main/resources/saga-frontend/src/favicon.png
new file mode 100644
index 0000000..49f3f2a
Binary files /dev/null and b/saga-web/src/main/resources/saga-frontend/src/favicon.png differ
diff --git a/saga-web/src/main/resources/saga-frontend/src/index.html b/saga-web/src/main/resources/saga-frontend/src/index.html
new file mode 100644
index 0000000..7deef5f
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/index.html
@@ -0,0 +1,48 @@
+<!-- 
+The MIT License (MIT)
+
+Copyright (c) 2017 akveo.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ -->
+<!doctype html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>ServiceComb Saga</title>
+
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link rel="icon" type="image/png" href="favicon.png">
+  <link rel="icon" type="image/x-icon" href="favicon.ico">
+</head>
+<body>
+  <ngx-app>Loading...</ngx-app>
+
+  <style>@-webkit-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-moz-keyframes spin{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.spinner{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1003;background: #000000;overflow:hidden}  .spinner div:first-child{display:block;position:relative;left:50%;top:50%;width:150px;height:150px;margin:-75px 0 0 -75px;border-radius:50% [...]
+  <div id="nb-global-spinner" class="spinner">
+    <div class="blob blob-0"></div>
+    <div class="blob blob-1"></div>
+    <div class="blob blob-2"></div>
+    <div class="blob blob-3"></div>
+    <div class="blob blob-4"></div>
+    <div class="blob blob-5"></div>
+  </div>
+
+</body>
+</html>
diff --git a/saga-web/src/main/resources/saga-frontend/src/main.ts b/saga-web/src/main/resources/saga-frontend/src/main.ts
new file mode 100644
index 0000000..359bdbd
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/main.ts
@@ -0,0 +1,17 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+import { enableProdMode } from '@angular/core';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app/app.module';
+import { environment } from './environments/environment';
+
+if (environment.production) {
+  enableProdMode();
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule)
+  .catch(err => console.error(err));
diff --git a/saga-web/src/main/resources/saga-frontend/src/polyfills.ts b/saga-web/src/main/resources/saga-frontend/src/polyfills.ts
new file mode 100644
index 0000000..421e93e
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/polyfills.ts
@@ -0,0 +1,76 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+/**
+ * This file includes polyfills needed by Angular and is loaded before the app.
+ * You can add your own extra polyfills to this file.
+ *
+ * This file is divided into 2 sections:
+ *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
+ *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
+ *      file.
+ *
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
+ * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
+ * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
+ *
+ * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
+ */
+
+/***************************************************************************************************
+ * BROWSER POLYFILLS
+ */
+
+/** IE9, IE10 and IE11 requires all of the following polyfills. **/
+import 'core-js/es6/symbol';
+import 'core-js/es6/object';
+import 'core-js/es6/function';
+import 'core-js/es6/parse-int';
+import 'core-js/es6/parse-float';
+import 'core-js/es6/number';
+import 'core-js/es6/math';
+import 'core-js/es6/string';
+import 'core-js/es6/date';
+import 'core-js/es6/array';
+import 'core-js/es6/regexp';
+import 'core-js/es6/map';
+import 'core-js/es6/set';
+
+/** IE10 and IE11 requires the following for NgClass support on SVG elements */
+import 'classlist.js';  // Run `npm install --save classlist.js`.
+
+/** IE10 and IE11 requires the following to support `@angular/animation`. */
+import 'web-animations-js';  // Run `npm install --save web-animations-js`.
+
+
+/** Evergreen browsers require these. **/
+import 'core-js/es6/reflect';
+import 'core-js/es7/reflect';
+
+
+/** ALL Firefox browsers require the following to support `@angular/animation`. **/
+// import 'web-animations-js';  // Run `npm install --save web-animations-js`.
+
+
+/***************************************************************************************************
+ * Zone JS is required by Angular itself.
+ */
+import 'zone.js/dist/zone';  // Included with Angular CLI.
+
+
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */
+
+/**
+ * Date, currency, decimal and percent pipes.
+ * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
+ */
+import 'core-js/es7/array';
+import 'core-js/es7/object';
+
+if (typeof SVGElement.prototype.contains === 'undefined') {
+  SVGElement.prototype.contains = HTMLDivElement.prototype.contains;
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/tsconfig.app.json b/saga-web/src/main/resources/saga-frontend/src/tsconfig.app.json
new file mode 100644
index 0000000..d2f5b48
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/tsconfig.app.json
@@ -0,0 +1,27 @@
+{
+  "extends": "../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "../out-tsc/app",
+    "module": "es2015",
+    "baseUrl": "./",
+    "types": [],
+    "paths": {
+      "@angular/*": [
+        "../node_modules/@angular/*"
+      ],
+      "@nebular/*": [
+        "../node_modules/@nebular/*"
+      ]
+    }
+  },
+  "exclude": [
+    "test.ts",
+    "**/*.spec.ts",
+    "../node_modules/@nebular/**/*.spec.ts"
+  ],
+  "include": [
+    "../src/*.ts",
+    "../src/**/*.ts",
+    "../node_modules/@nebular/**/*.ts"
+  ]
+}
diff --git a/saga-web/src/main/resources/saga-frontend/src/typings.d.ts b/saga-web/src/main/resources/saga-frontend/src/typings.d.ts
new file mode 100644
index 0000000..47a1963
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/src/typings.d.ts
@@ -0,0 +1,15 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See licenses/LICENSE-ngxadmin for license information.
+ */
+
+/* SystemJS module definition */
+declare var module: NodeModule;
+interface NodeModule {
+  id: string;
+}
+
+declare var tinymce: any;
+
+declare var echarts: any;
diff --git a/saga-web/src/main/resources/saga-frontend/tsconfig.json b/saga-web/src/main/resources/saga-frontend/tsconfig.json
new file mode 100644
index 0000000..d82d78b
--- /dev/null
+++ b/saga-web/src/main/resources/saga-frontend/tsconfig.json
@@ -0,0 +1,22 @@
+{
+  "compileOnSave": false,
+  "compilerOptions": {
+    "outDir": "./dist/out-tsc",
+    "sourceMap": true,
+    "declaration": false,
+    "moduleResolution": "node",
+    "emitDecoratorMetadata": true,
+    "experimentalDecorators": true,
+    "target": "es5",
+    "typeRoots": [
+      "node_modules/@types"
+    ],
+    "lib": [
+      "es2017",
+      "dom"
+    ],
+    "plugins": [
+      { "name": "tslint-language-service"}
+    ]
+  }
+}