From d76a0b3196c65b47c8051831ab69e245dcbd68d9 Mon Sep 17 00:00:00 2001 From: Spencer Ofwiti Date: Mon, 15 Mar 2021 14:54:46 +0300 Subject: [PATCH] Add error dialog box. - Add service for handling creation of error dialog. - Refactor directory layout. --- src/app/{_helpers => _eth}/accountIndex.ts | 0 src/app/_eth/index.ts | 3 ++ src/app/{_helpers => _eth}/registry.spec.ts | 2 +- src/app/{_helpers => _eth}/registry.ts | 0 .../{_helpers => _eth}/token-registry.spec.ts | 2 +- src/app/{_helpers => _eth}/token-registry.ts | 0 src/app/_helpers/error.interceptor.ts | 25 -------------- .../error.interceptor.spec.ts | 2 +- src/app/_interceptors/error.interceptor.ts | 32 ++++++++++++++++++ .../http-config.interceptor.spec.ts | 16 +++++++++ .../_interceptors/http-config.interceptor.ts | 29 ++++++++++++++++ src/app/_interceptors/index.ts | 3 ++ .../logging.interceptor.spec.ts | 0 .../logging.interceptor.ts | 10 +++--- src/app/_pgp/index.ts | 2 ++ .../{_helpers => _pgp}/pgp-key-store.spec.ts | 2 +- src/app/{_helpers => _pgp}/pgp-key-store.ts | 0 src/app/{_helpers => _pgp}/pgp-signer.spec.ts | 4 +-- src/app/{_helpers => _pgp}/pgp-signer.ts | 2 +- .../_services/error-dialog.service.spec.ts | 16 +++++++++ src/app/_services/error-dialog.service.ts | 33 +++++++++++++++++++ .../error-dialog/error-dialog.component.html | 13 ++++++++ .../error-dialog/error-dialog.component.scss | 0 .../error-dialog.component.spec.ts | 25 ++++++++++++++ .../error-dialog/error-dialog.component.ts | 14 ++++++++ src/app/shared/shared.module.ts | 16 +++++---- 26 files changed, 209 insertions(+), 42 deletions(-) rename src/app/{_helpers => _eth}/accountIndex.ts (100%) create mode 100644 src/app/_eth/index.ts rename src/app/{_helpers => _eth}/registry.spec.ts (80%) rename src/app/{_helpers => _eth}/registry.ts (100%) rename src/app/{_helpers => _eth}/token-registry.spec.ts (77%) rename src/app/{_helpers => _eth}/token-registry.ts (100%) delete mode 100644 src/app/_helpers/error.interceptor.ts rename src/app/{_helpers => _interceptors}/error.interceptor.spec.ts (82%) create mode 100644 src/app/_interceptors/error.interceptor.ts create mode 100644 src/app/_interceptors/http-config.interceptor.spec.ts create mode 100644 src/app/_interceptors/http-config.interceptor.ts create mode 100644 src/app/_interceptors/index.ts rename src/app/{_helpers => _interceptors}/logging.interceptor.spec.ts (100%) rename src/app/{_helpers => _interceptors}/logging.interceptor.ts (78%) create mode 100644 src/app/_pgp/index.ts rename src/app/{_helpers => _pgp}/pgp-key-store.spec.ts (67%) rename src/app/{_helpers => _pgp}/pgp-key-store.ts (100%) rename src/app/{_helpers => _pgp}/pgp-signer.spec.ts (58%) rename src/app/{_helpers => _pgp}/pgp-signer.ts (97%) create mode 100644 src/app/_services/error-dialog.service.spec.ts create mode 100644 src/app/_services/error-dialog.service.ts create mode 100644 src/app/shared/error-dialog/error-dialog.component.html create mode 100644 src/app/shared/error-dialog/error-dialog.component.scss create mode 100644 src/app/shared/error-dialog/error-dialog.component.spec.ts create mode 100644 src/app/shared/error-dialog/error-dialog.component.ts diff --git a/src/app/_helpers/accountIndex.ts b/src/app/_eth/accountIndex.ts similarity index 100% rename from src/app/_helpers/accountIndex.ts rename to src/app/_eth/accountIndex.ts diff --git a/src/app/_eth/index.ts b/src/app/_eth/index.ts new file mode 100644 index 0000000..aed7851 --- /dev/null +++ b/src/app/_eth/index.ts @@ -0,0 +1,3 @@ +export * from '@app/_eth/accountIndex'; +export * from '@app/_eth/registry'; +export * from '@app/_eth/token-registry'; diff --git a/src/app/_helpers/registry.spec.ts b/src/app/_eth/registry.spec.ts similarity index 80% rename from src/app/_helpers/registry.spec.ts rename to src/app/_eth/registry.spec.ts index 79ec68a..ffc4a39 100644 --- a/src/app/_helpers/registry.spec.ts +++ b/src/app/_eth/registry.spec.ts @@ -1,4 +1,4 @@ -import { Registry } from '@app/_helpers/registry'; +import { Registry } from '@app/_eth/registry'; import {environment} from '@src/environments/environment'; describe('Registry', () => { diff --git a/src/app/_helpers/registry.ts b/src/app/_eth/registry.ts similarity index 100% rename from src/app/_helpers/registry.ts rename to src/app/_eth/registry.ts diff --git a/src/app/_helpers/token-registry.spec.ts b/src/app/_eth/token-registry.spec.ts similarity index 77% rename from src/app/_helpers/token-registry.spec.ts rename to src/app/_eth/token-registry.spec.ts index bc66a23..9c5b881 100644 --- a/src/app/_helpers/token-registry.spec.ts +++ b/src/app/_eth/token-registry.spec.ts @@ -1,4 +1,4 @@ -import { TokenRegistry } from '@app/_helpers/token-registry'; +import { TokenRegistry } from '@app/_eth/token-registry'; import {environment} from '@src/environments/environment'; describe('TokenRegistry', () => { diff --git a/src/app/_helpers/token-registry.ts b/src/app/_eth/token-registry.ts similarity index 100% rename from src/app/_helpers/token-registry.ts rename to src/app/_eth/token-registry.ts diff --git a/src/app/_helpers/error.interceptor.ts b/src/app/_helpers/error.interceptor.ts deleted file mode 100644 index 4b1511e..0000000 --- a/src/app/_helpers/error.interceptor.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Injectable } from '@angular/core'; -import { - HttpRequest, - HttpHandler, - HttpEvent, - HttpInterceptor -} from '@angular/common/http'; -import {Observable, throwError} from 'rxjs'; -import {catchError} from 'rxjs/operators'; - -@Injectable() -export class ErrorInterceptor implements HttpInterceptor { - - constructor() {} - - intercept(request: HttpRequest, next: HttpHandler): Observable> { - return next.handle(request).pipe(catchError(err => { - if ([401, 403].indexOf(err.status) !== -1) { - location.reload(true); - } - const error = err.error.message || err.statusText; - return throwError(error); - })); - } -} diff --git a/src/app/_helpers/error.interceptor.spec.ts b/src/app/_interceptors/error.interceptor.spec.ts similarity index 82% rename from src/app/_helpers/error.interceptor.spec.ts rename to src/app/_interceptors/error.interceptor.spec.ts index 42c01bc..2e1c4f7 100644 --- a/src/app/_helpers/error.interceptor.spec.ts +++ b/src/app/_interceptors/error.interceptor.spec.ts @@ -1,6 +1,6 @@ import { TestBed } from '@angular/core/testing'; -import { ErrorInterceptor } from '@app/_helpers/error.interceptor'; +import { ErrorInterceptor } from '@app/_interceptors/error.interceptor'; describe('ErrorInterceptor', () => { beforeEach(() => TestBed.configureTestingModule({ diff --git a/src/app/_interceptors/error.interceptor.ts b/src/app/_interceptors/error.interceptor.ts new file mode 100644 index 0000000..d1aaee9 --- /dev/null +++ b/src/app/_interceptors/error.interceptor.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; +import { + HttpRequest, + HttpHandler, + HttpEvent, + HttpInterceptor, HttpErrorResponse +} from '@angular/common/http'; +import {Observable, throwError} from 'rxjs'; +import {catchError} from 'rxjs/operators'; +import {ErrorDialogService} from '@app/_services'; + +@Injectable() +export class ErrorInterceptor implements HttpInterceptor { + + constructor(private errorDialogService: ErrorDialogService) {} + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + return next.handle(request).pipe(catchError((err: HttpErrorResponse) => { + const data = { + message: err.error.message || err.statusText, + reason: err && err.error && err.error.reason ? err.error.reason : '', + status: err.status + }; + this.errorDialogService.openDialog(data); + if ([401, 403].indexOf(err.status) !== -1) { + location.reload(true); + } + // const error = err.error.message || err.statusText; + return throwError(err); + })); + } +} diff --git a/src/app/_interceptors/http-config.interceptor.spec.ts b/src/app/_interceptors/http-config.interceptor.spec.ts new file mode 100644 index 0000000..55c3822 --- /dev/null +++ b/src/app/_interceptors/http-config.interceptor.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { HttpConfigInterceptor } from './http-config.interceptor'; + +describe('HttpConfigInterceptor', () => { + beforeEach(() => TestBed.configureTestingModule({ + providers: [ + HttpConfigInterceptor + ] + })); + + it('should be created', () => { + const interceptor: HttpConfigInterceptor = TestBed.inject(HttpConfigInterceptor); + expect(interceptor).toBeTruthy(); + }); +}); diff --git a/src/app/_interceptors/http-config.interceptor.ts b/src/app/_interceptors/http-config.interceptor.ts new file mode 100644 index 0000000..67cf3c0 --- /dev/null +++ b/src/app/_interceptors/http-config.interceptor.ts @@ -0,0 +1,29 @@ +import { Injectable } from '@angular/core'; +import { + HttpRequest, + HttpHandler, + HttpEvent, + HttpInterceptor +} from '@angular/common/http'; +import { Observable } from 'rxjs'; + +@Injectable() +export class HttpConfigInterceptor implements HttpInterceptor { + + constructor() {} + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + const token = sessionStorage.getItem(btoa('CICADA_SESSION_TOKEN')); + + if (token) { + request = request.clone({headers: request.headers.set('Authorization', 'Bearer ' + token)}); + } + + if (!request.headers.has('Content-Type')) { + request = request.clone({headers: request.headers.set('Content-Type', 'application/json')}); + } + + request = request.clone({headers: request.headers.set('Accept', 'application/json')}); + return next.handle(request); + } +} diff --git a/src/app/_interceptors/index.ts b/src/app/_interceptors/index.ts new file mode 100644 index 0000000..a9ce065 --- /dev/null +++ b/src/app/_interceptors/index.ts @@ -0,0 +1,3 @@ +export * from '@app/_interceptors/error.interceptor'; +export * from '@app/_interceptors/http-config.interceptor'; +export * from '@app/_interceptors/logging.interceptor'; diff --git a/src/app/_helpers/logging.interceptor.spec.ts b/src/app/_interceptors/logging.interceptor.spec.ts similarity index 100% rename from src/app/_helpers/logging.interceptor.spec.ts rename to src/app/_interceptors/logging.interceptor.spec.ts diff --git a/src/app/_helpers/logging.interceptor.ts b/src/app/_interceptors/logging.interceptor.ts similarity index 78% rename from src/app/_helpers/logging.interceptor.ts rename to src/app/_interceptors/logging.interceptor.ts index a0e2c95..4858a5b 100644 --- a/src/app/_helpers/logging.interceptor.ts +++ b/src/app/_interceptors/logging.interceptor.ts @@ -3,9 +3,10 @@ import { HttpRequest, HttpHandler, HttpEvent, - HttpInterceptor, HttpResponse + HttpInterceptor, + HttpResponse } from '@angular/common/http'; -import { Observable } from 'rxjs'; +import {Observable} from 'rxjs'; import {LoggingService} from '@app/_services/logging.service'; import {finalize, tap} from 'rxjs/operators'; @@ -26,9 +27,10 @@ export class LoggingInterceptor implements HttpInterceptor { if (event instanceof HttpResponse) { status = 'succeeded'; } - }, error => status = 'failed'), finalize(() => { + }, error => status = 'failed'), + finalize(() => { const elapsedTime = Date.now() - startTime; - const message = `${request.method} ${request.urlWithParams} ${status} in ${elapsedTime} ms`; + const message = `${request.method} request for ${request.urlWithParams} ${status} in ${elapsedTime} ms`; this.loggingService.sendInfoLevelMessage(message); })); } diff --git a/src/app/_pgp/index.ts b/src/app/_pgp/index.ts new file mode 100644 index 0000000..3544957 --- /dev/null +++ b/src/app/_pgp/index.ts @@ -0,0 +1,2 @@ +export * from '@app/_pgp/pgp-key-store'; +export * from '@app/_pgp/pgp-signer'; diff --git a/src/app/_helpers/pgp-key-store.spec.ts b/src/app/_pgp/pgp-key-store.spec.ts similarity index 67% rename from src/app/_helpers/pgp-key-store.spec.ts rename to src/app/_pgp/pgp-key-store.spec.ts index e7e84b2..d91331c 100644 --- a/src/app/_helpers/pgp-key-store.spec.ts +++ b/src/app/_pgp/pgp-key-store.spec.ts @@ -1,4 +1,4 @@ -import { MutablePgpKeyStore } from '@app/_helpers/pgp-key-store'; +import { MutablePgpKeyStore } from '@app/_pgp/pgp-key-store'; describe('PgpKeyStore', () => { it('should create an instance', () => { diff --git a/src/app/_helpers/pgp-key-store.ts b/src/app/_pgp/pgp-key-store.ts similarity index 100% rename from src/app/_helpers/pgp-key-store.ts rename to src/app/_pgp/pgp-key-store.ts diff --git a/src/app/_helpers/pgp-signer.spec.ts b/src/app/_pgp/pgp-signer.spec.ts similarity index 58% rename from src/app/_helpers/pgp-signer.spec.ts rename to src/app/_pgp/pgp-signer.spec.ts index 37136c0..116a27c 100644 --- a/src/app/_helpers/pgp-signer.spec.ts +++ b/src/app/_pgp/pgp-signer.spec.ts @@ -1,5 +1,5 @@ -import { PGPSigner } from '@app/_helpers/pgp-signer'; -import {MutableKeyStore, MutablePgpKeyStore} from '@app/_helpers/pgp-key-store'; +import { PGPSigner } from '@app/_pgp/pgp-signer'; +import {MutableKeyStore, MutablePgpKeyStore} from '@app/_pgp/pgp-key-store'; const keystore: MutableKeyStore = new MutablePgpKeyStore(); describe('PgpSigner', () => { diff --git a/src/app/_helpers/pgp-signer.ts b/src/app/_pgp/pgp-signer.ts similarity index 97% rename from src/app/_helpers/pgp-signer.ts rename to src/app/_pgp/pgp-signer.ts index a86b851..d9826c4 100644 --- a/src/app/_helpers/pgp-signer.ts +++ b/src/app/_pgp/pgp-signer.ts @@ -1,4 +1,4 @@ -import {MutableKeyStore} from '@app/_helpers/pgp-key-store'; +import {MutableKeyStore} from '@app/_pgp/pgp-key-store'; import {LoggingService} from '@app/_services/logging.service'; const openpgp = require('openpgp'); diff --git a/src/app/_services/error-dialog.service.spec.ts b/src/app/_services/error-dialog.service.spec.ts new file mode 100644 index 0000000..2cdabc8 --- /dev/null +++ b/src/app/_services/error-dialog.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { ErrorDialogService } from './error-dialog.service'; + +describe('ErrorDialogService', () => { + let service: ErrorDialogService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ErrorDialogService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/_services/error-dialog.service.ts b/src/app/_services/error-dialog.service.ts new file mode 100644 index 0000000..9560674 --- /dev/null +++ b/src/app/_services/error-dialog.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import {MatDialog} from '@angular/material/dialog'; +import {ErrorDialogComponent} from '@app/shared/error-dialog/error-dialog.component'; +import {LoggingService} from '@app/_services/logging.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ErrorDialogService { + public isDialogOpen: boolean = false; + + constructor( + public dialog: MatDialog, + private loggingService: LoggingService + ) { } + + openDialog(data): any { + if (this.isDialogOpen) { + return false; + } + this.isDialogOpen = true; + const dialogRef = this.dialog.open(ErrorDialogComponent, { + width: '300px', + data + }); + + dialogRef.afterClosed().subscribe(result => { + this.loggingService.sendInfoLevelMessage('The dialog was closed'); + this.isDialogOpen = false; + const res = result; + }); + } +} diff --git a/src/app/shared/error-dialog/error-dialog.component.html b/src/app/shared/error-dialog/error-dialog.component.html new file mode 100644 index 0000000..52e980e --- /dev/null +++ b/src/app/shared/error-dialog/error-dialog.component.html @@ -0,0 +1,13 @@ +
+
+

+ Message: {{ data.message }} +

+

+ Reason: {{ data.reason }} +

+

+ Status: {{ data.status }} +

+
+
diff --git a/src/app/shared/error-dialog/error-dialog.component.scss b/src/app/shared/error-dialog/error-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/shared/error-dialog/error-dialog.component.spec.ts b/src/app/shared/error-dialog/error-dialog.component.spec.ts new file mode 100644 index 0000000..f104b5a --- /dev/null +++ b/src/app/shared/error-dialog/error-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ErrorDialogComponent } from './error-dialog.component'; + +describe('ErrorDialogComponent', () => { + let component: ErrorDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ErrorDialogComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ErrorDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/error-dialog/error-dialog.component.ts b/src/app/shared/error-dialog/error-dialog.component.ts new file mode 100644 index 0000000..e959264 --- /dev/null +++ b/src/app/shared/error-dialog/error-dialog.component.ts @@ -0,0 +1,14 @@ +import {Component, ChangeDetectionStrategy, Inject} from '@angular/core'; +import {MAT_DIALOG_DATA} from '@angular/material/dialog'; + +@Component({ + selector: 'app-error-dialog', + templateUrl: './error-dialog.component.html', + styleUrls: ['./error-dialog.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ErrorDialogComponent { + + constructor(@Inject(MAT_DIALOG_DATA) public data: string) { } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 46823b5..b559ab4 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -8,6 +8,8 @@ import { MenuToggleDirective } from '@app/shared/_directives/menu-toggle.directi import {RouterModule} from '@angular/router'; import {MatIconModule} from '@angular/material/icon'; import {TokenRatioPipe} from '@app/shared/_pipes/token-ratio.pipe'; +import { ErrorDialogComponent } from './error-dialog/error-dialog.component'; +import {MatDialogModule} from '@angular/material/dialog'; @@ -18,7 +20,8 @@ import {TokenRatioPipe} from '@app/shared/_pipes/token-ratio.pipe'; SidebarComponent, MenuSelectionDirective, MenuToggleDirective, - TokenRatioPipe + TokenRatioPipe, + ErrorDialogComponent ], exports: [ TopbarComponent, @@ -27,10 +30,11 @@ import {TokenRatioPipe} from '@app/shared/_pipes/token-ratio.pipe'; MenuSelectionDirective, TokenRatioPipe ], - imports: [ - CommonModule, - RouterModule, - MatIconModule - ] + imports: [ + CommonModule, + RouterModule, + MatIconModule, + MatDialogModule, + ] }) export class SharedModule { }