You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by ne...@apache.org on 2022/06/02 22:16:26 UTC

[helix] branch master updated: Upgrade helix-front to Angular 10.2 (#2129)

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

nealsun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/helix.git


The following commit(s) were added to refs/heads/master by this push:
     new 3a9990c2b Upgrade helix-front to Angular 10.2 (#2129)
3a9990c2b is described below

commit 3a9990c2bd61e1a81af699667ee3177475e4bfbf
Author: Micah Stubbs <mi...@gmail.com>
AuthorDate: Thu Jun 2 15:16:20 2022 -0700

    Upgrade helix-front to Angular 10.2 (#2129)
    
    Fix security vulnerabilities in helix-front dependencies.
    Upgrade helix-front dependencies to improve contributor productivity.
---
 helix-front/.nvmrc                                 |  2 +-
 helix-front/angular.json                           |  6 +-
 helix-front/client/app/app.component.spec.ts       | 10 ++--
 helix-front/client/app/app.component.ts            | 22 ++++++-
 .../helix-list/helix-list.component.spec.ts        |  4 +-
 .../cluster-detail.component.spec.ts               |  4 +-
 .../cluster-list/cluster-list.component.spec.ts    |  4 +-
 .../cluster/cluster-list/cluster-list.component.ts |  6 +-
 .../client/app/cluster/cluster.component.spec.ts   |  6 +-
 .../client/app/cluster/cluster.component.ts        |  2 +-
 .../client/app/cluster/shared/cluster.model.ts     |  4 +-
 .../config-detail/config-detail.component.spec.ts  |  7 ++-
 .../controller-detail.component.spec.ts            | 10 ++--
 helix-front/client/app/core/helix.service.ts       |  2 +-
 helix-front/client/app/core/user.service.ts        |  2 +-
 .../app/dashboard/dashboard.component.spec.ts      |  7 ++-
 .../client/app/dashboard/dashboard.component.ts    | 30 +++++-----
 .../history-list/history-list.component.spec.ts    |  4 +-
 .../history/history-list/history-list.component.ts |  6 +-
 .../client/app/history/shared/history.service.ts   | 12 ++--
 .../instance-detail.component.spec.ts              |  4 +-
 .../instance-list/instance-list.component.spec.ts  |  4 +-
 .../instance-list/instance-list.component.ts       |  2 +-
 .../client/app/instance/shared/instance.service.ts |  2 +-
 .../partition-detail.component.spec.ts             |  4 +-
 .../partition-list.component.spec.ts               |  4 +-
 .../resource-detail-for-instance.component.spec.ts |  4 +-
 .../resource-detail.component.spec.ts              |  4 +-
 .../resource-list/resource-list.component.spec.ts  |  4 +-
 .../resource-node-viewer.component.spec.ts         |  4 +-
 .../client/app/resource/shared/resource.model.ts   | 10 ++--
 .../app/resource/shared/resource.service.spec.ts   |  4 +-
 .../client/app/resource/shared/resource.service.ts | 14 ++---
 .../shared/data-table/data-table.component.spec.ts |  4 +-
 .../app/shared/data-table/data-table.component.ts  |  2 +-
 .../detail-header/detail-header.component.spec.ts  |  6 +-
 .../alert-dialog/alert-dialog.component.spec.ts    |  4 +-
 .../confirm-dialog.component.spec.ts               |  4 +-
 .../input-dialog/input-dialog.component.spec.ts    |  4 +-
 .../disabled-label.component.spec.ts               |  4 +-
 .../input-inline/input-inline.component.spec.ts    |  6 +-
 .../shared/input-inline/input-inline.component.ts  | 50 ++++++++--------
 .../json-viewer/json-viewer.component.spec.ts      |  6 +-
 .../shared/json-viewer/json-viewer.component.ts    |  2 +-
 .../key-value-pairs.component.spec.ts              |  4 +-
 .../key-value-pairs/key-value-pairs.component.ts   |  2 +-
 helix-front/client/app/shared/models/node.model.ts |  2 +-
 .../node-viewer/node-viewer.component.spec.ts      |  4 +-
 .../shared/node-viewer/node-viewer.component.ts    | 12 ++--
 helix-front/client/app/shared/shared.module.ts     |  5 --
 .../state-label/state-label.component.spec.ts      |  8 ++-
 .../job-detail/job-detail.component.spec.ts        | 11 ++--
 .../workflow/job-list/job-list.component.spec.ts   |  4 +-
 .../client/app/workflow/shared/workflow.model.ts   |  2 +-
 .../workflow-dag/workflow-dag.component.spec.ts    |  4 +-
 .../workflow-dag/workflow-dag.component.ts         |  2 +-
 .../workflow-detail.component.spec.ts              |  4 +-
 .../workflow-list/workflow-list.component.spec.ts  |  8 +--
 .../workflow-list/workflow-list.component.ts       | 13 +++-
 helix-front/package.json                           | 69 +++++++++++-----------
 helix-front/server/controllers/user.ts             |  7 ++-
 helix-front/tsconfig.json                          |  2 +-
 helix-front/tslint.json                            | 19 +++---
 63 files changed, 259 insertions(+), 229 deletions(-)

diff --git a/helix-front/.nvmrc b/helix-front/.nvmrc
index ceeec5689..76c257078 100644
--- a/helix-front/.nvmrc
+++ b/helix-front/.nvmrc
@@ -1 +1 @@
-v10.13.0
+v12.20.2
diff --git a/helix-front/angular.json b/helix-front/angular.json
index 6700114bc..b16e8965f 100644
--- a/helix-front/angular.json
+++ b/helix-front/angular.json
@@ -93,8 +93,8 @@
           "builder": "@angular-devkit/build-angular:tslint",
           "options": {
             "tsConfig": [
-              "src/tsconfig.app.json",
-              "src/tsconfig.spec.json"
+              "client/tsconfig.app.json",
+              "client/tsconfig.spec.json"
             ],
             "exclude": []
           }
@@ -129,7 +129,7 @@
   "schematics": {
     "@schematics/angular:component": {
       "prefix": "hi",
-      "styleext": "scss"
+      "style": "scss"
     },
     "@schematics/angular:directive": {
       "prefix": "hi"
diff --git a/helix-front/client/app/app.component.spec.ts b/helix-front/client/app/app.component.spec.ts
index 600dbb10d..c8de680ad 100644
--- a/helix-front/client/app/app.component.spec.ts
+++ b/helix-front/client/app/app.component.spec.ts
@@ -1,4 +1,4 @@
-import { TestBed, async } from '@angular/core/testing';
+import { TestBed, waitForAsync } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 // import { Angulartics2 } from 'angulartics2';
@@ -8,7 +8,7 @@ import { TestingModule } from '../testing/testing.module';
 import { AppComponent } from './app.component';
 
 describe('AppComponent', () => {
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule,
@@ -28,19 +28,19 @@ describe('AppComponent', () => {
     }).compileComponents();
   }));
 
-  it('should create the app', async(() => {
+  it('should create the app', waitForAsync(() => {
     const fixture = TestBed.createComponent(AppComponent);
     const app = fixture.debugElement.componentInstance;
     expect(app).toBeTruthy();
   }));
 
-  it(`should have a variable controlling footer`, async(() => {
+  it(`should have a variable controlling footer`, waitForAsync(() => {
     const fixture = TestBed.createComponent(AppComponent);
     const app = fixture.debugElement.componentInstance;
     expect(app.footerEnabled).toBeDefined();
   }));
 
-  xit('should render title in a mat-toolbar', async(() => {
+  xit('should render title in a mat-toolbar', waitForAsync(() => {
     const fixture = TestBed.createComponent(AppComponent);
     fixture.detectChanges();
     const compiled = fixture.debugElement.nativeElement;
diff --git a/helix-front/client/app/app.component.ts b/helix-front/client/app/app.component.ts
index a1403d791..42d45c36e 100644
--- a/helix-front/client/app/app.component.ts
+++ b/helix-front/client/app/app.component.ts
@@ -88,13 +88,29 @@ export class AppComponent implements OnInit {
             .subscribe(
               isAuthorized => {
                 if (!isAuthorized) {
-                  this.helper.showError("You're not part of helix-admin group or password incorrect");
+                  this.helper.showError('You\'re not part of helix-admin group or password incorrect');
                 }
                 this.currentUser = this.service.getCurrentUser();
               },
-              error => this.helper.showError(error)
+              error => {
+                // since rest API simply throws 404 instead of empty config when config is not initialized yet
+                // frontend has to treat 404 as normal result
+                if (error != 'Not Found') {
+                  this.helper.showError(error);
+                }
+                this.isLoading = false;
+              },
             );
         }
-      });
+      },
+      error => {
+        // since rest API simply throws 404 instead of empty config when config is not initialized yet
+        // frontend has to treat 404 as normal result
+        if (error != 'Not Found') {
+          this.helper.showError(error);
+        }
+        this.isLoading = false;
+      },
+      );
   }
 }
diff --git a/helix-front/client/app/chooser/helix-list/helix-list.component.spec.ts b/helix-front/client/app/chooser/helix-list/helix-list.component.spec.ts
index 6d5c7a745..057e85901 100644
--- a/helix-front/client/app/chooser/helix-list/helix-list.component.spec.ts
+++ b/helix-front/client/app/chooser/helix-list/helix-list.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -9,7 +9,7 @@ describe('HelixListComponent', () => {
   let component: HelixListComponent;
   let fixture: ComponentFixture<HelixListComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/cluster/cluster-detail/cluster-detail.component.spec.ts b/helix-front/client/app/cluster/cluster-detail/cluster-detail.component.spec.ts
index 458620a90..0cb5f8304 100644
--- a/helix-front/client/app/cluster/cluster-detail/cluster-detail.component.spec.ts
+++ b/helix-front/client/app/cluster/cluster-detail/cluster-detail.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -8,7 +8,7 @@ describe('ClusterDetailComponent', () => {
   let component: ClusterDetailComponent;
   let fixture: ComponentFixture<ClusterDetailComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/cluster/cluster-list/cluster-list.component.spec.ts b/helix-front/client/app/cluster/cluster-list/cluster-list.component.spec.ts
index ab81aca1d..af811b6a9 100644
--- a/helix-front/client/app/cluster/cluster-list/cluster-list.component.spec.ts
+++ b/helix-front/client/app/cluster/cluster-list/cluster-list.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -8,7 +8,7 @@ describe('ClusterListComponent', () => {
   let component: ClusterListComponent;
   let fixture: ComponentFixture<ClusterListComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/cluster/cluster-list/cluster-list.component.ts b/helix-front/client/app/cluster/cluster-list/cluster-list.component.ts
index 7144575e1..3c77b3939 100644
--- a/helix-front/client/app/cluster/cluster-list/cluster-list.component.ts
+++ b/helix-front/client/app/cluster/cluster-list/cluster-list.component.ts
@@ -16,9 +16,9 @@ import { InputDialogComponent } from '../../shared/dialog/input-dialog/input-dia
 export class ClusterListComponent implements OnInit {
 
   clusters: Cluster[] = [];
-  errorMessage: string = '';
-  isLoading: boolean = true;
-  can: boolean = false;
+  errorMessage = '';
+  isLoading = true;
+  can = false;
   service = '';
 
   constructor(
diff --git a/helix-front/client/app/cluster/cluster.component.spec.ts b/helix-front/client/app/cluster/cluster.component.spec.ts
index c2d85ed4c..187452fb8 100644
--- a/helix-front/client/app/cluster/cluster.component.spec.ts
+++ b/helix-front/client/app/cluster/cluster.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 import { FlexLayoutModule } from '@angular/flex-layout';
 
@@ -9,7 +9,7 @@ describe('ClusterComponent', () => {
   let component: ClusterComponent;
   let fixture: ComponentFixture<ClusterComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         FlexLayoutModule,
@@ -34,7 +34,7 @@ describe('ClusterComponent', () => {
     expect(component).toBeTruthy();
   });
 
-  it('should contain cluster list', async(() => {
+  it('should contain cluster list', waitForAsync(() => {
     fixture.detectChanges();
     const compiled = fixture.debugElement.nativeElement;
     expect(compiled.querySelector('hi-cluster-list')).toBeDefined();
diff --git a/helix-front/client/app/cluster/cluster.component.ts b/helix-front/client/app/cluster/cluster.component.ts
index ea915bef5..bd62c629b 100644
--- a/helix-front/client/app/cluster/cluster.component.ts
+++ b/helix-front/client/app/cluster/cluster.component.ts
@@ -24,7 +24,7 @@ export class ClusterComponent implements OnInit {
       change.forEach((item) => {
         this.isNarrowView = (item.mqAlias === 'xs' || item.mqAlias === 'sm');
       })
-      
+
     });
   }
 
diff --git a/helix-front/client/app/cluster/shared/cluster.model.ts b/helix-front/client/app/cluster/shared/cluster.model.ts
index 0ac9402a1..cd93ac530 100644
--- a/helix-front/client/app/cluster/shared/cluster.model.ts
+++ b/helix-front/client/app/cluster/shared/cluster.model.ts
@@ -23,8 +23,8 @@ export class Cluster {
     this.resources = obj.resources;
     this.inMaintenance = obj.maintenance;
 
-    let ins: Instance[] = [];
-    for (let instance of obj.instances) {
+    const ins: Instance[] = [];
+    for (const instance of obj.instances) {
       ins.push(new Instance(
         instance,
         this.name,
diff --git a/helix-front/client/app/configuration/config-detail/config-detail.component.spec.ts b/helix-front/client/app/configuration/config-detail/config-detail.component.spec.ts
index d6a721ecf..ff4b89cb0 100644
--- a/helix-front/client/app/configuration/config-detail/config-detail.component.spec.ts
+++ b/helix-front/client/app/configuration/config-detail/config-detail.component.spec.ts
@@ -1,5 +1,6 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { HttpClientTestingModule } from '@angular/common/http/testing'
 
 import { TestingModule } from '../../../testing/testing.module';
 import { ConfigDetailComponent } from './config-detail.component';
@@ -8,10 +9,10 @@ describe('ConfigDetailComponent', () => {
   let component: ConfigDetailComponent;
   let fixture: ComponentFixture<ConfigDetailComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
-        TestingModule
+        TestingModule, HttpClientTestingModule
       ],
       declarations: [
         ConfigDetailComponent
diff --git a/helix-front/client/app/controller/controller-detail/controller-detail.component.spec.ts b/helix-front/client/app/controller/controller-detail/controller-detail.component.spec.ts
index df01bda94..26de2b26b 100644
--- a/helix-front/client/app/controller/controller-detail/controller-detail.component.spec.ts
+++ b/helix-front/client/app/controller/controller-detail/controller-detail.component.spec.ts
@@ -1,6 +1,6 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
-import { HttpClientModule } from '@angular/common/http';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { RouterTestingModule } from '@angular/router/testing';
 
 import { ControllerDetailComponent } from './controller-detail.component';
@@ -9,11 +9,11 @@ describe('ControllerDetailComponent', () => {
   let component: ControllerDetailComponent;
   let fixture: ComponentFixture<ControllerDetailComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
-        HttpClientModule,
-        RouterTestingModule
+        HttpClientTestingModule,
+        RouterTestingModule,
       ],
       declarations: [ ControllerDetailComponent ],
       schemas: [
diff --git a/helix-front/client/app/core/helix.service.ts b/helix-front/client/app/core/helix.service.ts
index a5c329d60..e705104c8 100644
--- a/helix-front/client/app/core/helix.service.ts
+++ b/helix-front/client/app/core/helix.service.ts
@@ -71,7 +71,7 @@ export class HelixService {
   }
 
   protected getHeaders() {
-    let headers = new HttpHeaders();
+    const headers = new HttpHeaders();
     headers.append('Accept', 'application/json');
     headers.append('Content-Type', 'application/json');
     return headers;
diff --git a/helix-front/client/app/core/user.service.ts b/helix-front/client/app/core/user.service.ts
index 65a488b6d..6608a3f2d 100644
--- a/helix-front/client/app/core/user.service.ts
+++ b/helix-front/client/app/core/user.service.ts
@@ -31,7 +31,7 @@ export class UserService {
   }
 
   protected getHeaders() {
-    let headers = new HttpHeaders();
+    const headers = new HttpHeaders();
     headers.append('Accept', 'application/json');
     headers.append('Content-Type', 'application/json');
     return headers;
diff --git a/helix-front/client/app/dashboard/dashboard.component.spec.ts b/helix-front/client/app/dashboard/dashboard.component.spec.ts
index 2c1c53ae6..d91c5c9da 100644
--- a/helix-front/client/app/dashboard/dashboard.component.spec.ts
+++ b/helix-front/client/app/dashboard/dashboard.component.spec.ts
@@ -1,5 +1,6 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 
 import { VisModule } from 'ngx-vis';
 
@@ -10,9 +11,9 @@ describe('DashboardComponent', () => {
   let component: DashboardComponent;
   let fixture: ComponentFixture<DashboardComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
-      imports: [ TestingModule, VisModule ],
+      imports: [ TestingModule, VisModule, HttpClientTestingModule ],
       schemas: [ NO_ERRORS_SCHEMA ],
       declarations: [ DashboardComponent ]
     })
diff --git a/helix-front/client/app/dashboard/dashboard.component.ts b/helix-front/client/app/dashboard/dashboard.component.ts
index 9c45aa604..e4604a4f4 100644
--- a/helix-front/client/app/dashboard/dashboard.component.ts
+++ b/helix-front/client/app/dashboard/dashboard.component.ts
@@ -5,8 +5,8 @@ import {
   AfterViewInit,
   OnDestroy
 } from '@angular/core';
-import { Router, ActivatedRoute } from '@angular/router';
-import { Observable, Subscription } from 'rxjs';
+import { ActivatedRoute } from '@angular/router';
+import { Subscription } from 'rxjs';
 import { map } from 'rxjs/operators';
 
 import * as _ from 'lodash';
@@ -27,7 +27,7 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy {
   public visNetworkData: Data;
   public visNetworkOptions: Options;
   public nodes: Node[];
-  public edges: Edge[]; 
+  public edges: Edge[];
 
   public clusterName: string;
   public isLoading = false;
@@ -39,7 +39,7 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy {
   public updateInterval = 3000;
 
   public constructor(
-    private el:ElementRef,
+    private el: ElementRef,
     private route: ActivatedRoute,
     protected visNetworkService: VisNetworkService,
     protected resourceService: ResourceService,
@@ -82,7 +82,7 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy {
   }
 
   ngOnInit() {
-    this.nodes = 
+    this.nodes = [];
     this.edges = [];
     this.visNetworkData = { nodes: this.nodes, edges: this.edges }
     this.visNetworkOptions = {
@@ -131,20 +131,22 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy {
 
   initDashboard() {
     // resize container according to the parent
-    let width = this.el.nativeElement.offsetWidth;
-    let height = this.el.nativeElement.offsetHeight - 36;
-    let dashboardDom = this.el.nativeElement.getElementsByClassName(this.visNetwork)[0];
+    const width = this.el.nativeElement.offsetWidth;
+    const height = this.el.nativeElement.offsetHeight - 36;
+    const dashboardDom = this.el.nativeElement.getElementsByClassName(this.visNetwork)[0];
     dashboardDom.style.width = `${ width }px`;
     dashboardDom.style.height = `${ height }px`;
 
     // load data
-    this.route.parent.params
-      .pipe(map(p => p.name))
-      .subscribe(name => {
-        this.clusterName = name;
-        this.fetchResources();
-        // this.updateResources();
+    if (this.route && this.route.parent) {
+      this.route.parent.params
+        .pipe(map(p => p.name))
+        .subscribe(name => {
+          this.clusterName = name;
+          this.fetchResources();
+          // this.updateResources();
       });
+    }
   }
 
   ngAfterViewInit() {
diff --git a/helix-front/client/app/history/history-list/history-list.component.spec.ts b/helix-front/client/app/history/history-list/history-list.component.spec.ts
index d0aabb31e..6bc188506 100644
--- a/helix-front/client/app/history/history-list/history-list.component.spec.ts
+++ b/helix-front/client/app/history/history-list/history-list.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 import { HttpClientModule } from '@angular/common/http';
 import { RouterTestingModule } from '@angular/router/testing';
@@ -9,7 +9,7 @@ describe('HistoryListComponent', () => {
   let component: HistoryListComponent;
   let fixture: ComponentFixture<HistoryListComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         HttpClientModule,
diff --git a/helix-front/client/app/history/history-list/history-list.component.ts b/helix-front/client/app/history/history-list/history-list.component.ts
index eee1ff7b2..58e6b04ac 100644
--- a/helix-front/client/app/history/history-list/history-list.component.ts
+++ b/helix-front/client/app/history/history-list/history-list.component.ts
@@ -36,9 +36,9 @@ export class HistoryListComponent implements OnInit {
 
   ngOnInit() {
     if (this.route.parent) {
-      let clusterName = this.route.parent.snapshot.params['cluster_name'];
-      let instanceName = this.route.parent.snapshot.params['instance_name'];
-      let observable = instanceName
+      const clusterName = this.route.parent.snapshot.params['cluster_name'];
+      const instanceName = this.route.parent.snapshot.params['instance_name'];
+      const observable = instanceName
         ? this.service.getInstanceHistory(clusterName, instanceName)
         : this.service.getControllerHistory(clusterName);
 
diff --git a/helix-front/client/app/history/shared/history.service.ts b/helix-front/client/app/history/shared/history.service.ts
index f495c0689..548aaec88 100644
--- a/helix-front/client/app/history/shared/history.service.ts
+++ b/helix-front/client/app/history/shared/history.service.ts
@@ -23,17 +23,17 @@ export class HistoryService extends HelixService {
 
   protected parseHistory(data: any): History[] {
 
-    let histories: History[] = [];
+    const histories: History[] = [];
 
     if (data) {
-      for (let record of data) {
+      for (const record of data) {
         // controller: {DATE=2017-04-13-22:33:55, CONTROLLER=ltx1-app1133.stg.linkedin.com_12923, TIME=1492122835198}
         // instance: {DATE=2017-05-01T08:21:42:114, SESSION=55a8e28052bcb56, TIME=1493626902114}
-        let history = new History();
+        const history = new History();
 
-        for (let seg of _.words(record, /[^{}, ]+/g)) {
-          let name = _.words(seg, /[^=]+/g)[0];
-          let value = _.words(seg, /[^=]+/g)[1];
+        for (const seg of _.words(record, /[^{}, ]+/g)) {
+          const name = _.words(seg, /[^=]+/g)[0];
+          const value = _.words(seg, /[^=]+/g)[1];
           if (name == 'DATE') {
             history.date = value;
           } else if (name == 'CONTROLLER') {
diff --git a/helix-front/client/app/instance/instance-detail/instance-detail.component.spec.ts b/helix-front/client/app/instance/instance-detail/instance-detail.component.spec.ts
index 229e9d465..2389954b3 100644
--- a/helix-front/client/app/instance/instance-detail/instance-detail.component.spec.ts
+++ b/helix-front/client/app/instance/instance-detail/instance-detail.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -8,7 +8,7 @@ describe('InstanceDetailComponent', () => {
   let component: InstanceDetailComponent;
   let fixture: ComponentFixture<InstanceDetailComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/instance/instance-list/instance-list.component.spec.ts b/helix-front/client/app/instance/instance-list/instance-list.component.spec.ts
index 73687bf49..ef97a26f0 100644
--- a/helix-front/client/app/instance/instance-list/instance-list.component.spec.ts
+++ b/helix-front/client/app/instance/instance-list/instance-list.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 import { RouterTestingModule } from '@angular/router/testing';
 
@@ -8,7 +8,7 @@ describe('InstanceListComponent', () => {
   let component: InstanceListComponent;
   let fixture: ComponentFixture<InstanceListComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         RouterTestingModule
diff --git a/helix-front/client/app/instance/instance-list/instance-list.component.ts b/helix-front/client/app/instance/instance-list/instance-list.component.ts
index 985e193c0..74e993443 100644
--- a/helix-front/client/app/instance/instance-list/instance-list.component.ts
+++ b/helix-front/client/app/instance/instance-list/instance-list.component.ts
@@ -43,7 +43,7 @@ export class InstanceListComponent implements OnInit {
   }
 
   onSelect({ selected }) {
-    let row = selected[0];
+    const row = selected[0];
     this.router.navigate([row.name], { relativeTo: this.route });
   }
 
diff --git a/helix-front/client/app/instance/shared/instance.service.ts b/helix-front/client/app/instance/shared/instance.service.ts
index e74605624..0645a647c 100644
--- a/helix-front/client/app/instance/shared/instance.service.ts
+++ b/helix-front/client/app/instance/shared/instance.service.ts
@@ -52,7 +52,7 @@ export class InstanceService extends HelixService {
   public create(clusterName: string, host: string, port: string, enabled: boolean) {
     const name = `${ host }_${ port }`;
 
-    let node = new Node(null);
+    const node = new Node(null);
     node.appendSimpleField('HELIX_ENABLED', enabled ? 'true' : 'false');
     node.appendSimpleField('HELIX_HOST', host);
     node.appendSimpleField('HELIX_PORT', port);
diff --git a/helix-front/client/app/resource/partition-detail/partition-detail.component.spec.ts b/helix-front/client/app/resource/partition-detail/partition-detail.component.spec.ts
index 412dc886e..88a6e5d1f 100644
--- a/helix-front/client/app/resource/partition-detail/partition-detail.component.spec.ts
+++ b/helix-front/client/app/resource/partition-detail/partition-detail.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { PartitionDetailComponent } from './partition-detail.component';
@@ -7,7 +7,7 @@ describe('PartitionDetailComponent', () => {
   let component: PartitionDetailComponent;
   let fixture: ComponentFixture<PartitionDetailComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       declarations: [ PartitionDetailComponent ],
       schemas: [
diff --git a/helix-front/client/app/resource/partition-list/partition-list.component.spec.ts b/helix-front/client/app/resource/partition-list/partition-list.component.spec.ts
index 9a5c01745..407c819f2 100644
--- a/helix-front/client/app/resource/partition-list/partition-list.component.spec.ts
+++ b/helix-front/client/app/resource/partition-list/partition-list.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -9,7 +9,7 @@ describe('PartitionListComponent', () => {
   let component: PartitionListComponent;
   let fixture: ComponentFixture<PartitionListComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/resource/resource-detail-for-instance/resource-detail-for-instance.component.spec.ts b/helix-front/client/app/resource/resource-detail-for-instance/resource-detail-for-instance.component.spec.ts
index db0c1ff2c..055651246 100644
--- a/helix-front/client/app/resource/resource-detail-for-instance/resource-detail-for-instance.component.spec.ts
+++ b/helix-front/client/app/resource/resource-detail-for-instance/resource-detail-for-instance.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 import { HttpClientModule } from '@angular/common/http';
 import { RouterTestingModule } from '@angular/router/testing';
@@ -10,7 +10,7 @@ describe('ResourceDetailForInstanceComponent', () => {
   let component: ResourceDetailForInstanceComponent;
   let fixture: ComponentFixture<ResourceDetailForInstanceComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [ HttpClientModule, RouterTestingModule ],
       declarations: [ ResourceDetailForInstanceComponent ],
diff --git a/helix-front/client/app/resource/resource-detail/resource-detail.component.spec.ts b/helix-front/client/app/resource/resource-detail/resource-detail.component.spec.ts
index 31721acd6..11b838abd 100644
--- a/helix-front/client/app/resource/resource-detail/resource-detail.component.spec.ts
+++ b/helix-front/client/app/resource/resource-detail/resource-detail.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -9,7 +9,7 @@ describe('ResourceDetailComponent', () => {
   let component: ResourceDetailComponent;
   let fixture: ComponentFixture<ResourceDetailComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/resource/resource-list/resource-list.component.spec.ts b/helix-front/client/app/resource/resource-list/resource-list.component.spec.ts
index f954647be..4b361ff86 100644
--- a/helix-front/client/app/resource/resource-list/resource-list.component.spec.ts
+++ b/helix-front/client/app/resource/resource-list/resource-list.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -9,7 +9,7 @@ describe('ResourceListComponent', () => {
   let component: ResourceListComponent;
   let fixture: ComponentFixture<ResourceListComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/resource/resource-node-viewer/resource-node-viewer.component.spec.ts b/helix-front/client/app/resource/resource-node-viewer/resource-node-viewer.component.spec.ts
index a174b153b..01616da9c 100644
--- a/helix-front/client/app/resource/resource-node-viewer/resource-node-viewer.component.spec.ts
+++ b/helix-front/client/app/resource/resource-node-viewer/resource-node-viewer.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -9,7 +9,7 @@ describe('ResourceNodeViewerComponent', () => {
   let component: ResourceNodeViewerComponent;
   let fixture: ComponentFixture<ResourceNodeViewerComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [ TestingModule ],
       declarations: [ ResourceNodeViewerComponent ],
diff --git a/helix-front/client/app/resource/shared/resource.model.ts b/helix-front/client/app/resource/shared/resource.model.ts
index 4b38f4600..459134638 100644
--- a/helix-front/client/app/resource/shared/resource.model.ts
+++ b/helix-front/client/app/resource/shared/resource.model.ts
@@ -67,13 +67,13 @@ export class Resource {
 
     // fetch partition names from externalView.mapFields is (relatively) more stable
     this.partitions = [];
-    for (let partitionName in externalView.mapFields) {
-      let partition = new Partition(partitionName);
+    for (const partitionName in externalView.mapFields) {
+      const partition = new Partition(partitionName);
 
       // in FULL_ATUO mode, externalView is more important
       // if preferences list exists, fetch instances from it, else whatever
       if (this.rebalanceMode != 'FULL_AUTO' && idealState.listFields[partitionName]) {
-        for (let replicaName of idealState.listFields[partitionName]) {
+        for (const replicaName of idealState.listFields[partitionName]) {
           partition.replicas.push(<IReplica>{
             instanceName: replicaName,
             externalView: _.get(externalView, ['mapFields', partitionName, replicaName]),
@@ -81,7 +81,7 @@ export class Resource {
           });
         }
       } else if (this.rebalanceMode != 'FULL_AUTO' && idealState.mapFields[partitionName]) {
-        for (let replicaName in idealState.mapFields[partitionName]) {
+        for (const replicaName in idealState.mapFields[partitionName]) {
           partition.replicas.push(<IReplica>{
             instanceName: replicaName,
             externalView: _.get(externalView, ['mapFields', partitionName, replicaName]),
@@ -89,7 +89,7 @@ export class Resource {
           });
         }
       } else {
-        for (let replicaName in externalView.mapFields[partitionName]) {
+        for (const replicaName in externalView.mapFields[partitionName]) {
           partition.replicas.push(<IReplica>{
             instanceName: replicaName,
             externalView: _.get(externalView, ['mapFields', partitionName, replicaName]),
diff --git a/helix-front/client/app/resource/shared/resource.service.spec.ts b/helix-front/client/app/resource/shared/resource.service.spec.ts
index 686dd41b2..63c748399 100644
--- a/helix-front/client/app/resource/shared/resource.service.spec.ts
+++ b/helix-front/client/app/resource/shared/resource.service.spec.ts
@@ -1,13 +1,13 @@
 import { TestBed, inject } from '@angular/core/testing';
-import { HttpClientModule } from '@angular/common/http';
 import { RouterTestingModule } from '@angular/router/testing';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 
 import { ResourceService } from './resource.service';
 
 describe('ResourceService', () => {
   beforeEach(() => {
     TestBed.configureTestingModule({
-      imports: [HttpClientModule, RouterTestingModule],
+      imports: [HttpClientTestingModule, RouterTestingModule],
       providers: [ResourceService]
     });
   });
diff --git a/helix-front/client/app/resource/shared/resource.service.ts b/helix-front/client/app/resource/shared/resource.service.ts
index 27596c547..6d9f0b433 100644
--- a/helix-front/client/app/resource/shared/resource.service.ts
+++ b/helix-front/client/app/resource/shared/resource.service.ts
@@ -15,8 +15,8 @@ export class ResourceService extends HelixService {
     return this
       .request(`/clusters/${ clusterName }/resources`).pipe(
       map(data => {
-        let res: Resource[] = [];
-        for (let name of data.idealStates) {
+        const res: Resource[] = [];
+        for (const name of data.idealStates) {
           res.push(<Resource>({
             cluster: clusterName,
             name: name,
@@ -31,9 +31,9 @@ export class ResourceService extends HelixService {
     return this
       .request(`/clusters/${ clusterName }/instances/${ instanceName }/resources`).pipe(
       map(data => {
-        let res: any[] = [];
+        const res: any[] = [];
         if (data) {
-          for (let resource of data.resources) {
+          for (const resource of data.resources) {
             res.push({
               name: resource
             });
@@ -61,7 +61,7 @@ export class ResourceService extends HelixService {
     return this
       .request(`/clusters/${ clusterName }/instances/${ instanceName }/resources/${ resourceName }`).pipe(
       map(data => {
-        let ret = {
+        const ret = {
           bucketSize: data.simpleFields.BUCKET_SIZE,
           sessionId: data.simpleFields.SESSION_ID,
           stateModelDef: data.simpleFields.STATE_MODEL_DEF,
@@ -69,8 +69,8 @@ export class ResourceService extends HelixService {
           partitions: []
         };
 
-        for (let partition in data.mapFields) {
-          let par = data.mapFields[partition];
+        for (const partition in data.mapFields) {
+          const par = data.mapFields[partition];
 
           ret.partitions.push({
             name: partition,
diff --git a/helix-front/client/app/shared/data-table/data-table.component.spec.ts b/helix-front/client/app/shared/data-table/data-table.component.spec.ts
index b6bff7932..c1f18fcea 100644
--- a/helix-front/client/app/shared/data-table/data-table.component.spec.ts
+++ b/helix-front/client/app/shared/data-table/data-table.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -8,7 +8,7 @@ describe('DataTableComponent', () => {
   let component: DataTableComponent;
   let fixture: ComponentFixture<DataTableComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/shared/data-table/data-table.component.ts b/helix-front/client/app/shared/data-table/data-table.component.ts
index aa471d328..c238ddfee 100644
--- a/helix-front/client/app/shared/data-table/data-table.component.ts
+++ b/helix-front/client/app/shared/data-table/data-table.component.ts
@@ -45,7 +45,7 @@ export class DataTableComponent implements OnInit {
   }
 
   onCreate() {
-    let data = {
+    const data = {
       title: 'Create a new item',
       message: 'Please enter the following information to continue:',
       values: {}
diff --git a/helix-front/client/app/shared/detail-header/detail-header.component.spec.ts b/helix-front/client/app/shared/detail-header/detail-header.component.spec.ts
index 25e7a3ce0..fc9ac98af 100644
--- a/helix-front/client/app/shared/detail-header/detail-header.component.spec.ts
+++ b/helix-front/client/app/shared/detail-header/detail-header.component.spec.ts
@@ -1,5 +1,6 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 
 import { DetailHeaderComponent } from './detail-header.component';
 
@@ -7,9 +8,10 @@ describe('DetailHeaderComponent', () => {
   let component: DetailHeaderComponent;
   let fixture: ComponentFixture<DetailHeaderComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       declarations: [ DetailHeaderComponent ],
+      imports: [HttpClientTestingModule],
       schemas: [
         /* avoid importing modules */
         NO_ERRORS_SCHEMA
diff --git a/helix-front/client/app/shared/dialog/alert-dialog/alert-dialog.component.spec.ts b/helix-front/client/app/shared/dialog/alert-dialog/alert-dialog.component.spec.ts
index 07f246ebb..ea820b04d 100644
--- a/helix-front/client/app/shared/dialog/alert-dialog/alert-dialog.component.spec.ts
+++ b/helix-front/client/app/shared/dialog/alert-dialog/alert-dialog.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { AlertDialogComponent } from './alert-dialog.component';
 
@@ -6,7 +6,7 @@ describe('AlertDialogComponent', () => {
   let component: AlertDialogComponent;
   let fixture: ComponentFixture<AlertDialogComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       declarations: [ AlertDialogComponent ]
     })
diff --git a/helix-front/client/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts b/helix-front/client/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts
index 3fdc21252..af62740a8 100644
--- a/helix-front/client/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts
+++ b/helix-front/client/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { ConfirmDialogComponent } from './confirm-dialog.component';
 
@@ -6,7 +6,7 @@ describe('ConfirmDialogComponent', () => {
   let component: ConfirmDialogComponent;
   let fixture: ComponentFixture<ConfirmDialogComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       declarations: [ ConfirmDialogComponent ]
     })
diff --git a/helix-front/client/app/shared/dialog/input-dialog/input-dialog.component.spec.ts b/helix-front/client/app/shared/dialog/input-dialog/input-dialog.component.spec.ts
index f3300d018..90cfd82e3 100644
--- a/helix-front/client/app/shared/dialog/input-dialog/input-dialog.component.spec.ts
+++ b/helix-front/client/app/shared/dialog/input-dialog/input-dialog.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { InputDialogComponent } from './input-dialog.component';
 
@@ -6,7 +6,7 @@ describe('InputDialogComponent', () => {
   let component: InputDialogComponent;
   let fixture: ComponentFixture<InputDialogComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       declarations: [ InputDialogComponent ]
     })
diff --git a/helix-front/client/app/shared/disabled-label/disabled-label.component.spec.ts b/helix-front/client/app/shared/disabled-label/disabled-label.component.spec.ts
index 0ad484818..c0f519e2a 100644
--- a/helix-front/client/app/shared/disabled-label/disabled-label.component.spec.ts
+++ b/helix-front/client/app/shared/disabled-label/disabled-label.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { DisabledLabelComponent } from './disabled-label.component';
 
@@ -6,7 +6,7 @@ describe('DisabledLabelComponent', () => {
   let component: DisabledLabelComponent;
   let fixture: ComponentFixture<DisabledLabelComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       declarations: [ DisabledLabelComponent ]
     })
diff --git a/helix-front/client/app/shared/input-inline/input-inline.component.spec.ts b/helix-front/client/app/shared/input-inline/input-inline.component.spec.ts
index c48666a44..1c5438a0d 100644
--- a/helix-front/client/app/shared/input-inline/input-inline.component.spec.ts
+++ b/helix-front/client/app/shared/input-inline/input-inline.component.spec.ts
@@ -1,5 +1,6 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 
 import { InputInlineComponent } from './input-inline.component';
 
@@ -7,9 +8,10 @@ describe('InputInlineComponent', () => {
   let component: InputInlineComponent;
   let fixture: ComponentFixture<InputInlineComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       declarations: [ InputInlineComponent ],
+      imports: [HttpClientTestingModule],
       schemas: [
         /* avoid importing modules */
         NO_ERRORS_SCHEMA
diff --git a/helix-front/client/app/shared/input-inline/input-inline.component.ts b/helix-front/client/app/shared/input-inline/input-inline.component.ts
index 5d361f064..e2ef25f2b 100644
--- a/helix-front/client/app/shared/input-inline/input-inline.component.ts
+++ b/helix-front/client/app/shared/input-inline/input-inline.component.ts
@@ -7,28 +7,6 @@ import { ControlValueAccessor } from '@angular/forms';
   styleUrls: ['./input-inline.component.scss']
 })
 export class InputInlineComponent implements ControlValueAccessor, OnInit {
-
-  @ViewChild('inputControl', {static: true}) inputControl: ElementRef;
-
-  @Output('update') change: EventEmitter<string> = new EventEmitter<string>();
-
-  @Input() label: string = '';
-  @Input() min: number = -9999;
-  @Input() max: number = 99999999;
-  @Input() minlength: number = 0;
-  @Input() maxlength: number = 2555;
-  @Input() type: string = 'text';
-  @Input() required: boolean = false;
-  @Input() focus: Function = _ => { };
-  @Input() blur: Function = _ => { };
-  @Input() pattern: string = null;
-  @Input() errorLabel: string = 'Invalid input value';
-  @Input() editLabel: string = 'Click to edit';
-  @Input() disabled: boolean = false;
-
-  editing: boolean = false;
-
-  private _value: string = '';
   @Input()
   get value(): any {
     return this._value;
@@ -39,15 +17,37 @@ export class InputInlineComponent implements ControlValueAccessor, OnInit {
       this.onChange(v);
     }
   }
+;
 
-  private lastValue: string = '';
+  @ViewChild('inputControl', {static: true}) inputControl: ElementRef;
+
+  @Output('update') change: EventEmitter<string> = new EventEmitter<string>();
+
+  @Input() label = '';
+  @Input() min = -9999;
+  @Input() max = 99999999;
+  @Input() minlength = 0;
+  @Input() maxlength = 2555;
+  @Input() type = 'text';
+  @Input() required = false;
+  @Input() pattern: string = null;
+  @Input() errorLabel = 'Invalid input value';
+  @Input() editLabel = 'Click to edit';
+  @Input() disabled = false;
+
+  editing = false;
+
+  private _value = '';
+
+  private lastValue = '';
 
   // Required forControlValueAccessor interface
   public onChange: any = Function.prototype;
   public onTouched: any = Function.prototype;
+  @Input() focus: Function = _ => { };
+  @Input() blur: Function = _ => { };
   public registerOnChange(fn: (_: any) => {}): void { this.onChange = fn; }
-  public registerOnTouched(fn: () => {}): void { this.onTouched = fn; };
-  writeValue(value: any) {
+  public registerOnTouched(fn: () => {}): void { this.onTouched = fn; }  writeValue(value: any) {
     this._value = value;
   }
 
diff --git a/helix-front/client/app/shared/json-viewer/json-viewer.component.spec.ts b/helix-front/client/app/shared/json-viewer/json-viewer.component.spec.ts
index 4f7c05735..42e2b1633 100644
--- a/helix-front/client/app/shared/json-viewer/json-viewer.component.spec.ts
+++ b/helix-front/client/app/shared/json-viewer/json-viewer.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { RouterTestingModule } from '@angular/router/testing';
 
 import { JsonViewerComponent } from './json-viewer.component';
@@ -7,9 +7,9 @@ describe('JsonViewerComponent', () => {
   let component: JsonViewerComponent;
   let fixture: ComponentFixture<JsonViewerComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
-      imports:[
+      imports: [
         RouterTestingModule
       ],
       declarations: [ JsonViewerComponent ]
diff --git a/helix-front/client/app/shared/json-viewer/json-viewer.component.ts b/helix-front/client/app/shared/json-viewer/json-viewer.component.ts
index ea2ffa984..33247a580 100644
--- a/helix-front/client/app/shared/json-viewer/json-viewer.component.ts
+++ b/helix-front/client/app/shared/json-viewer/json-viewer.component.ts
@@ -18,7 +18,7 @@ export class JsonViewerComponent implements OnInit {
   ngOnInit() {
     // MODE 2: use in router
     if (this.route.snapshot.data.path) {
-      let path = this.route.snapshot.data.path;
+      const path = this.route.snapshot.data.path;
 
       // try parent data first
       this.obj = _.get(this.route.parent, `snapshot.data.${ path }`);
diff --git a/helix-front/client/app/shared/key-value-pairs/key-value-pairs.component.spec.ts b/helix-front/client/app/shared/key-value-pairs/key-value-pairs.component.spec.ts
index ddf010b78..7ad062f5b 100644
--- a/helix-front/client/app/shared/key-value-pairs/key-value-pairs.component.spec.ts
+++ b/helix-front/client/app/shared/key-value-pairs/key-value-pairs.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { KeyValuePairsComponent } from './key-value-pairs.component';
 
@@ -6,7 +6,7 @@ describe('KeyValuePairsComponent', () => {
   let component: KeyValuePairsComponent;
   let fixture: ComponentFixture<KeyValuePairsComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       declarations: [ KeyValuePairsComponent ]
     })
diff --git a/helix-front/client/app/shared/key-value-pairs/key-value-pairs.component.ts b/helix-front/client/app/shared/key-value-pairs/key-value-pairs.component.ts
index 086345cd2..5d6fb90fd 100644
--- a/helix-front/client/app/shared/key-value-pairs/key-value-pairs.component.ts
+++ b/helix-front/client/app/shared/key-value-pairs/key-value-pairs.component.ts
@@ -5,7 +5,7 @@ import * as _ from 'lodash';
 // good doc: https://angular.io/docs/ts/latest/api/core/index/ContentChildren-decorator.html
 
 @Directive({ selector: 'hi-key-value-pair' })
-export class KeyValuePairDirective{
+export class KeyValuePairDirective {
   @Input() name: string;
   @Input() prop: string;
 }
diff --git a/helix-front/client/app/shared/models/node.model.ts b/helix-front/client/app/shared/models/node.model.ts
index f09a9bdd1..87f25551b 100644
--- a/helix-front/client/app/shared/models/node.model.ts
+++ b/helix-front/client/app/shared/models/node.model.ts
@@ -73,7 +73,7 @@ export class Node {
   }
 
   public json(id: string): string {
-    let obj = {
+    const obj = {
       id: id,
       simpleFields: {},
       listFields: {},
diff --git a/helix-front/client/app/shared/node-viewer/node-viewer.component.spec.ts b/helix-front/client/app/shared/node-viewer/node-viewer.component.spec.ts
index d66b1eedf..179d1003e 100644
--- a/helix-front/client/app/shared/node-viewer/node-viewer.component.spec.ts
+++ b/helix-front/client/app/shared/node-viewer/node-viewer.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 import { TestingModule } from '../../../testing/testing.module';
 
@@ -8,7 +8,7 @@ describe('NodeViewerComponent', () => {
   let component: NodeViewerComponent;
   let fixture: ComponentFixture<NodeViewerComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/shared/node-viewer/node-viewer.component.ts b/helix-front/client/app/shared/node-viewer/node-viewer.component.ts
index 54f9b2088..4abb7a0d1 100644
--- a/helix-front/client/app/shared/node-viewer/node-viewer.component.ts
+++ b/helix-front/client/app/shared/node-viewer/node-viewer.component.ts
@@ -180,7 +180,7 @@ export class NodeViewerComponent implements OnInit {
             value: []
           }];
 
-          let newNode: Node = new Node(null);
+          const newNode: Node = new Node(null);
           if (type === 'list') {
             newNode.listFields = entry;
           } else if (type === 'map') {
@@ -209,7 +209,7 @@ export class NodeViewerComponent implements OnInit {
   }
 
   onDelete(type, row) {
-    let newNode: Node = new Node(null);
+    const newNode: Node = new Node(null);
 
     if (type === 'simple') {
       newNode.appendSimpleField(row.name, '');
@@ -223,9 +223,9 @@ export class NodeViewerComponent implements OnInit {
   }
 
   created(type, data, key) {
-    let newNode: Node = new Node(null);
+    const newNode: Node = new Node(null);
 
-    switch(type) {
+    switch (type) {
       case 'simple':
         newNode.appendSimpleField(data.name.value, data.value.value);
         break;
@@ -269,9 +269,9 @@ export class NodeViewerComponent implements OnInit {
       return;
     }
 
-    let newNode: Node = new Node(null);
+    const newNode: Node = new Node(null);
 
-    switch(type) {
+    switch (type) {
       case 'simple':
         newNode.appendSimpleField(row.name, value);
         break;
diff --git a/helix-front/client/app/shared/shared.module.ts b/helix-front/client/app/shared/shared.module.ts
index 0aa75d1ea..b3e773175 100644
--- a/helix-front/client/app/shared/shared.module.ts
+++ b/helix-front/client/app/shared/shared.module.ts
@@ -45,11 +45,6 @@ import { DisabledLabelComponent } from './disabled-label/disabled-label.componen
     ConfirmDialogComponent,
     DisabledLabelComponent
   ],
-  entryComponents: [
-    InputDialogComponent,
-    AlertDialogComponent,
-    ConfirmDialogComponent
-  ],
   exports: [
     RouterModule,
     MaterialModule,
diff --git a/helix-front/client/app/shared/state-label/state-label.component.spec.ts b/helix-front/client/app/shared/state-label/state-label.component.spec.ts
index 1a9b42936..bfa05bd27 100644
--- a/helix-front/client/app/shared/state-label/state-label.component.spec.ts
+++ b/helix-front/client/app/shared/state-label/state-label.component.spec.ts
@@ -1,4 +1,5 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 
 import { StateLabelComponent } from './state-label.component';
 
@@ -6,9 +7,10 @@ describe('StateLabelComponent', () => {
   let component: StateLabelComponent;
   let fixture: ComponentFixture<StateLabelComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
-      declarations: [ StateLabelComponent ]
+      declarations: [ StateLabelComponent ],
+      imports: [HttpClientTestingModule]
     })
     .compileComponents();
   }));
diff --git a/helix-front/client/app/workflow/job-detail/job-detail.component.spec.ts b/helix-front/client/app/workflow/job-detail/job-detail.component.spec.ts
index 7f6141e27..15a4fc077 100644
--- a/helix-front/client/app/workflow/job-detail/job-detail.component.spec.ts
+++ b/helix-front/client/app/workflow/job-detail/job-detail.component.spec.ts
@@ -1,8 +1,9 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { of } from 'rxjs';
-
 import { NO_ERRORS_SCHEMA } from '@angular/core';
-import { Observable } from 'rxjs/Observable';
+import { waitForAsync, ComponentFixture, TestBed,  } from '@angular/core/testing';
+import { of, Observable } from 'rxjs';
+
+import { } from '@angular/core';
+
 
 import { TestingModule } from '../../../testing/testing.module';
 import { JobDetailComponent } from './job-detail.component';
@@ -12,7 +13,7 @@ describe('JobDetailComponent', () => {
   let component: JobDetailComponent;
   let fixture: ComponentFixture<JobDetailComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [ TestingModule ],
       providers: [
diff --git a/helix-front/client/app/workflow/job-list/job-list.component.spec.ts b/helix-front/client/app/workflow/job-list/job-list.component.spec.ts
index d9f75acda..8480618de 100644
--- a/helix-front/client/app/workflow/job-list/job-list.component.spec.ts
+++ b/helix-front/client/app/workflow/job-list/job-list.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
@@ -9,7 +9,7 @@ describe('JobListComponent', () => {
   let component: JobListComponent;
   let fixture: ComponentFixture<JobListComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [ TestingModule ],
       declarations: [ JobListComponent ],
diff --git a/helix-front/client/app/workflow/shared/workflow.model.ts b/helix-front/client/app/workflow/shared/workflow.model.ts
index 4a1e42fef..520e326ba 100644
--- a/helix-front/client/app/workflow/shared/workflow.model.ts
+++ b/helix-front/client/app/workflow/shared/workflow.model.ts
@@ -64,7 +64,7 @@ export class Workflow {
   }
 
   protected parseJobs(list: string[], parents: any): Job[] {
-    let result: Job[] = [];
+    const result: Job[] = [];
 
     _.forEach(list, jobName => {
       result.push(new Job(
diff --git a/helix-front/client/app/workflow/workflow-dag/workflow-dag.component.spec.ts b/helix-front/client/app/workflow/workflow-dag/workflow-dag.component.spec.ts
index 40b600c5c..e94b54296 100644
--- a/helix-front/client/app/workflow/workflow-dag/workflow-dag.component.spec.ts
+++ b/helix-front/client/app/workflow/workflow-dag/workflow-dag.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
@@ -9,7 +9,7 @@ describe('WorkflowDagComponent', () => {
   let component: WorkflowDagComponent;
   let fixture: ComponentFixture<WorkflowDagComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [ TestingModule ],
       declarations: [ WorkflowDagComponent ],
diff --git a/helix-front/client/app/workflow/workflow-dag/workflow-dag.component.ts b/helix-front/client/app/workflow/workflow-dag/workflow-dag.component.ts
index 28d6de660..89418f20c 100644
--- a/helix-front/client/app/workflow/workflow-dag/workflow-dag.component.ts
+++ b/helix-front/client/app/workflow/workflow-dag/workflow-dag.component.ts
@@ -25,7 +25,7 @@ export class WorkflowDagComponent implements OnInit, AfterViewInit {
   @ViewChild('graph', {static: true})
   graph;
 
-  constructor(protected el:ElementRef) { }
+  constructor(protected el: ElementRef) { }
 
   ngOnInit() {
     this.loadJobs();
diff --git a/helix-front/client/app/workflow/workflow-detail/workflow-detail.component.spec.ts b/helix-front/client/app/workflow/workflow-detail/workflow-detail.component.spec.ts
index 731a6d428..96d13ce51 100644
--- a/helix-front/client/app/workflow/workflow-detail/workflow-detail.component.spec.ts
+++ b/helix-front/client/app/workflow/workflow-detail/workflow-detail.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 
 import { TestingModule } from '../../../testing/testing.module';
@@ -9,7 +9,7 @@ describe('WorkflowDetailComponent', () => {
   let component: WorkflowDetailComponent;
   let fixture: ComponentFixture<WorkflowDetailComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
       imports: [
         TestingModule
diff --git a/helix-front/client/app/workflow/workflow-list/workflow-list.component.spec.ts b/helix-front/client/app/workflow/workflow-list/workflow-list.component.spec.ts
index 23144b32a..8ef31d41b 100644
--- a/helix-front/client/app/workflow/workflow-list/workflow-list.component.spec.ts
+++ b/helix-front/client/app/workflow/workflow-list/workflow-list.component.spec.ts
@@ -1,18 +1,18 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 import { RouterTestingModule } from '@angular/router/testing';
 
 import { WorkflowListComponent } from './workflow-list.component';
 import { WorkflowService } from '../shared/workflow.service';
-import { HttpClientModule } from '@angular/common/http';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 
 describe('WorkflowListComponent', () => {
   let component: WorkflowListComponent;
   let fixture: ComponentFixture<WorkflowListComponent>;
 
-  beforeEach(async(() => {
+  beforeEach(waitForAsync(() => {
     TestBed.configureTestingModule({
-      imports: [ HttpClientModule, RouterTestingModule ],
+      imports: [ HttpClientTestingModule, RouterTestingModule ],
       declarations: [ WorkflowListComponent ],
       providers: [ WorkflowService ],
       schemas: [
diff --git a/helix-front/client/app/workflow/workflow-list/workflow-list.component.ts b/helix-front/client/app/workflow/workflow-list/workflow-list.component.ts
index 08963d907..347e1f1d3 100644
--- a/helix-front/client/app/workflow/workflow-list/workflow-list.component.ts
+++ b/helix-front/client/app/workflow/workflow-list/workflow-list.component.ts
@@ -1,7 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 import { Router, ActivatedRoute } from '@angular/router';
 
-import { WorkflowService } from '../shared/workflow.service';
+import { WorkflowService } from '../shared/workflow.service'; 
 
 @Component({
   selector: 'hi-workflow-list',
@@ -17,7 +17,7 @@ export class WorkflowListComponent implements OnInit {
   constructor(
     private router: Router,
     private route: ActivatedRoute,
-    private service: WorkflowService
+    private service: WorkflowService,
   ) { }
 
   ngOnInit() {
@@ -29,7 +29,14 @@ export class WorkflowListComponent implements OnInit {
         .getAll(this.clusterName)
         .subscribe(
           workflows => this.workflows = workflows,
-          error => console.log(error),
+          error => {
+            // since rest API simply throws 404 instead of empty config when config is not initialized yet
+            // frontend has to treat 404 as normal result
+            if (error != 'Not Found') {
+              console.error(error);
+            }
+            this.isLoading = false;
+          },
           () => this.isLoading = false
         );
     }
diff --git a/helix-front/package.json b/helix-front/package.json
index eba5744cc..14b0723ae 100644
--- a/helix-front/package.json
+++ b/helix-front/package.json
@@ -18,6 +18,7 @@
     "prod": "npm run build && node dist/server/app.js",
     "test": "ng test",
     "lint": "ng lint",
+    "lint:fix": "ng lint -- --fix",
     "lint:tslint": "./node_modules/.bin/tslint -c tslint.json -p tsconfig.json",
     "e2e": "ng e2e",
     "smoke": "ng lint && ng test --sr && npm run build",
@@ -26,28 +27,28 @@
     "type:check:watch": "npm run type:check -- --watch"
   },
   "engines": {
-    "node": "10.13.0",
-    "npm": "6.4.1"
+    "node": "12.20.2",
+    "npm": "6.14.11"
   },
   "dependencies": {
-    "@angular/animations": "9.1.13",
-    "@angular/cdk": "9.2.4",
-    "@angular/common": "9.1.13",
-    "@angular/compiler": "9.1.13",
-    "@angular/core": "9.1.13",
-    "@angular/flex-layout": "^9.0.0-beta.31",
-    "@angular/forms": "9.1.13",
-    "@angular/material": "^9.2.4",
-    "@angular/platform-browser": "9.1.13",
-    "@angular/platform-browser-dynamic": "9.1.13",
-    "@angular/platform-server": "9.1.13",
-    "@angular/router": "9.1.13",
+    "@angular/animations": "10.2.5",
+    "@angular/cdk": "10.2.7",
+    "@angular/common": "10.2.5",
+    "@angular/compiler": "10.2.5",
+    "@angular/core": "10.2.5",
+    "@angular/flex-layout": "^10.0.0-beta.32",
+    "@angular/forms": "10.2.5",
+    "@angular/material": "^10.2.7",
+    "@angular/platform-browser": "10.2.5",
+    "@angular/platform-browser-dynamic": "10.2.5",
+    "@angular/platform-server": "10.2.5",
+    "@angular/router": "10.2.5",
     "@egjs/hammerjs": "^2.0.17",
-    "@swimlane/ngx-charts": "^13.0.4",
-    "@swimlane/ngx-datatable": "^17.1.0",
-    "@swimlane/ngx-graph": "^7.0.0",
+    "@swimlane/ngx-charts": "^16.0.0",
+    "@swimlane/ngx-datatable": "^18.0.0",
+    "@swimlane/ngx-graph": "^7.2.0",
     "ajv": "^6.9.1",
-    "angulartics2": "^9.1.0",
+    "angulartics2": "^10.1.0",
     "body-parser": "^1.17.2",
     "component-emitter": "^1.3.0",
     "core-js": "^2.4.1",
@@ -67,8 +68,8 @@
     "rxjs": "^6.5.5",
     "rxjs-compat": "^6.0.0-rc.0",
     "sass": "^1.51.0",
-    "tsickle": "^0.38.1",
-    "tslib": "^1.10.0",
+    "tsickle": "github:angular/tsickle#fdf6e86717648f1b9603752cb83486fa6dcac38f",
+    "tslib": "^2.0.0",
     "uuid": "^7.0.3",
     "vis": "^4.21.0",
     "vis-data": "^6.5.1",
@@ -77,30 +78,30 @@
     "zone.js": "~0.10.2"
   },
   "devDependencies": {
-    "@angular-devkit/build-angular": "~0.901.15",
-    "@angular/cli": "9.1.15",
-    "@angular/compiler-cli": "9.1.13",
+    "@angular-devkit/build-angular": "~0.1002.4",
+    "@angular/cli": "10.2.4",
+    "@angular/compiler-cli": "10.2.5",
     "@types/hammerjs": "^2.0.34",
     "@types/jasmine": "2.5.38",
     "@types/lodash": "4.14.120",
     "@types/node": "^12.11.1",
     "@types/request": "^2.0.0",
-    "codelyzer": "^6.0.1",
+    "codelyzer": "^6.0.2",
     "concurrently": "^3.5.0",
-    "jasmine-core": "~2.5.2",
-    "jasmine-spec-reporter": "~3.2.0",
-    "karma": "~1.4.1",
-    "karma-chrome-launcher": "~2.0.0",
+    "jasmine-core": "^3.8.0",
+    "jasmine-spec-reporter": "~5.0.0",
+    "karma": "~5.0.0",
+    "karma-chrome-launcher": "~3.1.0",
     "karma-cli": "~1.0.1",
-    "karma-coverage-istanbul-reporter": "^0.2.0",
-    "karma-jasmine": "~1.1.0",
-    "karma-jasmine-html-reporter": "^0.2.2",
+    "karma-coverage-istanbul-reporter": "~3.0.2",
+    "karma-jasmine": "~4.0.0",
+    "karma-jasmine-html-reporter": "^1.5.0",
     "karma-phantomjs-launcher": "^1.0.4",
     "nodemon": "1.11.0",
-    "protractor": "~5.1.0",
+    "protractor": "~7.0.0",
     "rxjs-tslint": "^0.1.8",
     "ts-node": "~2.0.0",
-    "tslint": "^5.8.0",
-    "typescript": "3.8.3"
+    "tslint": "^5.20.1",
+    "typescript": "4.0.8"
   }
 }
diff --git a/helix-front/server/controllers/user.ts b/helix-front/server/controllers/user.ts
index 77272551e..ef22352a6 100644
--- a/helix-front/server/controllers/user.ts
+++ b/helix-front/server/controllers/user.ts
@@ -29,7 +29,12 @@ export class UserCtrl {
   }
 
   protected can(req: Request, res: Response) {
-    res.json(req.session.isAdmin ? true : false);
+    try {
+      return res.json(req.session.isAdmin ? true : false);
+    } catch (err) {
+      console.log('error from can', err)
+      return false
+    }
   }
 
   protected login(request: Request, response: Response) {
diff --git a/helix-front/tsconfig.json b/helix-front/tsconfig.json
index e0ec30b9d..a10f859d7 100644
--- a/helix-front/tsconfig.json
+++ b/helix-front/tsconfig.json
@@ -18,6 +18,6 @@
       "es2016",
       "dom"
     ],
-    "module": "es2015"
+    "module": "es2020"
   }
 }
diff --git a/helix-front/tslint.json b/helix-front/tslint.json
index 531a803b7..a9482b75b 100644
--- a/helix-front/tslint.json
+++ b/helix-front/tslint.json
@@ -12,7 +12,7 @@
     ],
     "curly": true,
     "eofline": true,
-    "forin": true,
+    "forin": { "severity": "off" },
     "import-blacklist": [true],
     "import-spacing": true,
     "indent": [
@@ -22,7 +22,7 @@
     "interface-over-type-literal": true,
     "label-position": true,
     "max-line-length": [
-      true,
+      "off",
       140
     ],
     "member-access": false,
@@ -48,13 +48,12 @@
     "no-empty-interface": true,
     "no-eval": true,
     "no-inferrable-types": [true, "ignore-params"],
-    "no-shadowed-variable": true,
+    "no-shadowed-variable": { "severity": "off" },
     "no-string-literal": false,
     "no-string-throw": true,
     "no-switch-case-fall-through": true,
     "no-trailing-whitespace": true,
     "no-unused-expression": true,
-    "no-use-before-declare": true,
     "no-var-keyword": true,
     "object-literal-sort-keys": false,
     "one-line": [
@@ -69,12 +68,12 @@
       true,
       "single"
     ],
-    "radix": true,
+    "radix": { "severity": "off" },
     "semicolon": [
       "always"
     ],
     "triple-equals": [
-      true,
+      "off",
       "allow-null-check"
     ],
     "typedef-whitespace": [
@@ -87,7 +86,6 @@
         "variable-declaration": "nospace"
       }
     ],
-    "typeof-compare": true,
     "unified-signatures": true,
     "variable-name": false,
     "whitespace": [
@@ -99,13 +97,10 @@
       "check-type"
     ],
 
-    "directive-selector": [true, "attribute", "hi", "camelCase"],
+    "directive-selector": ["off", "attribute", "hi", "camelCase"],
     "component-selector": [true, "element", "hi", "kebab-case"],
-    "use-input-property-decorator": true,
-    "use-output-property-decorator": true,
-    "use-host-property-decorator": true,
     "no-input-rename": true,
-    "no-output-rename": true,
+    "no-output-rename": { "severity": "off" },
     "use-life-cycle-interface": true,
     "use-pipe-transform-interface": true,
     "component-class-suffix": true,