Add error dialog box.
- Add service for handling creation of error dialog. - Refactor directory layout.
This commit is contained in:
parent
3eaa56e0b9
commit
d76a0b3196
3
src/app/_eth/index.ts
Normal file
3
src/app/_eth/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from '@app/_eth/accountIndex';
|
||||
export * from '@app/_eth/registry';
|
||||
export * from '@app/_eth/token-registry';
|
@ -1,4 +1,4 @@
|
||||
import { Registry } from '@app/_helpers/registry';
|
||||
import { Registry } from '@app/_eth/registry';
|
||||
import {environment} from '@src/environments/environment';
|
||||
|
||||
describe('Registry', () => {
|
@ -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', () => {
|
@ -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<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||
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);
|
||||
}));
|
||||
}
|
||||
}
|
@ -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({
|
32
src/app/_interceptors/error.interceptor.ts
Normal file
32
src/app/_interceptors/error.interceptor.ts
Normal file
@ -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<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||
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);
|
||||
}));
|
||||
}
|
||||
}
|
16
src/app/_interceptors/http-config.interceptor.spec.ts
Normal file
16
src/app/_interceptors/http-config.interceptor.spec.ts
Normal file
@ -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();
|
||||
});
|
||||
});
|
29
src/app/_interceptors/http-config.interceptor.ts
Normal file
29
src/app/_interceptors/http-config.interceptor.ts
Normal file
@ -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<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||
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);
|
||||
}
|
||||
}
|
3
src/app/_interceptors/index.ts
Normal file
3
src/app/_interceptors/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from '@app/_interceptors/error.interceptor';
|
||||
export * from '@app/_interceptors/http-config.interceptor';
|
||||
export * from '@app/_interceptors/logging.interceptor';
|
@ -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);
|
||||
}));
|
||||
}
|
2
src/app/_pgp/index.ts
Normal file
2
src/app/_pgp/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from '@app/_pgp/pgp-key-store';
|
||||
export * from '@app/_pgp/pgp-signer';
|
@ -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', () => {
|
@ -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', () => {
|
@ -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');
|
16
src/app/_services/error-dialog.service.spec.ts
Normal file
16
src/app/_services/error-dialog.service.spec.ts
Normal file
@ -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();
|
||||
});
|
||||
});
|
33
src/app/_services/error-dialog.service.ts
Normal file
33
src/app/_services/error-dialog.service.ts
Normal file
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
13
src/app/shared/error-dialog/error-dialog.component.html
Normal file
13
src/app/shared/error-dialog/error-dialog.component.html
Normal file
@ -0,0 +1,13 @@
|
||||
<div>
|
||||
<div>
|
||||
<p>
|
||||
Message: {{ data.message }}
|
||||
</p>
|
||||
<p>
|
||||
Reason: {{ data.reason }}
|
||||
</p>
|
||||
<p>
|
||||
Status: {{ data.status }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
25
src/app/shared/error-dialog/error-dialog.component.spec.ts
Normal file
25
src/app/shared/error-dialog/error-dialog.component.spec.ts
Normal file
@ -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<ErrorDialogComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ErrorDialogComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ErrorDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
14
src/app/shared/error-dialog/error-dialog.component.ts
Normal file
14
src/app/shared/error-dialog/error-dialog.component.ts
Normal file
@ -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) { }
|
||||
|
||||
}
|
@ -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 { }
|
||||
|
Loading…
Reference in New Issue
Block a user