Add networkerror notify

This commit is contained in:
rubikscraft 2022-03-20 22:11:17 +01:00
parent 26c3918bcc
commit 8c88c5f24e
No known key found for this signature in database
GPG key ID: 1463EBE9200A5CD4
12 changed files with 87 additions and 38 deletions

View file

@ -87,7 +87,6 @@ export class UserManageController {
@Post('info')
async getUser(@Body() body: UserInfoRequest): Promise<UserInfoResponse> {
console.log(body);
const user = await this.usersService.findOne(body.username);
if (HasFailed(user)) {
this.logger.warn(user.getReason());

View file

@ -8,6 +8,7 @@ import { AppRoutingModule } from './app.routing.module';
import { FooterModule } from './components/footer/footer.module';
import { HeaderModule } from './components/header/header.module';
import { GuardsModule } from './guards/guards.module';
import { UtilModule } from './util/util.module';
@NgModule({
declarations: [AppComponent],
@ -17,6 +18,7 @@ import { GuardsModule } from './guards/guards.module';
PortalModule,
MatSidenavModule,
UtilModule.forRoot(),
GuardsModule,
AppRoutingModule,

View file

@ -3,7 +3,6 @@ import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { UtilModule } from 'src/app/util/util.module';
import { CopyFieldComponent } from './copyfield.component';
@NgModule({
declarations: [CopyFieldComponent],
@ -12,7 +11,6 @@ import { CopyFieldComponent } from './copyfield.component';
MatInputModule,
MatIconModule,
MatButtonModule,
UtilModule,
],
exports: [CopyFieldComponent],
})

View file

@ -5,7 +5,6 @@ import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatToolbarModule } from '@angular/material/toolbar';
import { RouterModule } from '@angular/router';
import { UtilModule } from 'src/app/util/util.module';
import { HeaderComponent } from './header.component';
@NgModule({
@ -16,7 +15,6 @@ import { HeaderComponent } from './header.component';
RouterModule,
MatIconModule,
MatMenuModule,
UtilModule,
],
declarations: [HeaderComponent],
exports: [HeaderComponent],

View file

@ -24,12 +24,12 @@ export class PermissionGuard implements CanActivate, CanActivateChild {
childRoute: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) {
console.log('canActivateChild');
//console.log('canActivateChild');
return await this.can(childRoute, state);
}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
console.log('canActivate');
//console.log('canActivate');
return await this.can(route, state);
}

View file

@ -0,0 +1,4 @@
export interface ApiError {
error: any;
url: RequestInfo;
}

View file

@ -1,4 +1,4 @@
import { Component, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { SysPreferenceResponse } from 'picsur-shared/dist/dto/api/pref.dto';
import { SysprefService as SysPrefService } from 'src/app/services/api/syspref.service';
@ -6,7 +6,7 @@ import { SysprefService as SysPrefService } from 'src/app/services/api/syspref.s
@Component({
templateUrl: './settings-syspref.component.html',
})
export class SettingsSysprefComponent implements OnInit, OnChanges {
export class SettingsSysprefComponent implements OnInit {
render = true;
preferences: SysPreferenceResponse[] = [];
@ -32,10 +32,6 @@ export class SettingsSysprefComponent implements OnInit, OnChanges {
});
}
ngOnChanges(changes: SimpleChanges): void {
console.log('cahnges', changes);
}
private compareFlatObjectArray(a: any[], b: any[]): boolean {
if (a.length !== b.length) {
return false;

View file

@ -32,12 +32,12 @@ export class SettingsUsersComponent implements OnInit {
return this.updateSubject
.pipe(throttleTime(500, undefined, { leading: true, trailing: true }))
.subscribe(async (pageEvent: PageEvent) => {
let amount = await this.fetchUsers(
let success = await this.fetchUsers(
pageEvent.pageSize,
pageEvent.pageIndex
);
if (amount === 0) {
if ( pageEvent.previousPageIndex === pageEvent.pageIndex - 1){
if (!success) {
if (pageEvent.previousPageIndex === pageEvent.pageIndex - 1) {
this.paginator.previousPage();
} else {
this.paginator.firstPage();
@ -49,12 +49,15 @@ export class SettingsUsersComponent implements OnInit {
private async fetchUsers(
pageSize: number,
pageIndex: number
): Promise<number> {
): Promise<boolean> {
const result = await this.userManageService.getUsers(pageSize, pageIndex);
if (HasFailed(result)) return 0;
if (HasFailed(result)) return false;
this.dataSubject.next(result);
if (result.length > 0) {
this.dataSubject.next(result);
return true;
}
return result.length;
return false;
}
}

View file

@ -3,6 +3,8 @@ import { ClassConstructor, plainToClass } from 'class-transformer';
import { ApiResponse, ApiSuccessResponse } from 'picsur-shared/dist/dto/api';
import { AsyncFailable, Fail, HasFailed } from 'picsur-shared/dist/types';
import { strictValidate } from 'picsur-shared/dist/util/validate';
import { Subject } from 'rxjs';
import { ApiError } from 'src/app/models/api-error';
import { MultiPartRequest } from '../../models/multi-part-request';
import { KeyService } from './key.service';
@ -12,6 +14,12 @@ import { KeyService } from './key.service';
export class ApiService {
private readonly logger = console;
private errorSubject = new Subject<ApiError>();
public get networkErrors() {
return this.errorSubject.asObservable();
}
constructor(private keyService: KeyService) {}
public async get<T extends Object>(
@ -128,9 +136,12 @@ export class ApiService {
options.headers = headers;
return await window.fetch(url, options);
} catch (e: any) {
this.logger.warn(e);
return Fail('Something went wrong');
} catch (error: any) {
this.errorSubject.next({
error,
url,
});
return Fail('Network Error');
}
}
}

View file

@ -111,7 +111,6 @@ export class SysprefService {
}
private sync() {
console.warn('System preferences have been flushed');
this.sysprefObservable.next(
([] as SysPreferenceResponse[]).concat(this.snapshot)
);

View file

@ -0,0 +1,32 @@
import { Injectable } from '@angular/core';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { SnackBarType } from '../models/snack-bar-type';
import { ApiService } from '../services/api/api.service';
import { UtilService } from './util.service';
@Injectable({
providedIn: 'root',
})
export class ApiErrorService {
constructor(
private apiSerivce: ApiService,
private utilService: UtilService
) {
this.subscribeErrors();
}
@AutoUnsubscribe()
private subscribeErrors() {
return this.apiSerivce.networkErrors.subscribe((error) => {
let url = '';
if (typeof error.url === 'string') url = error.url;
else url = error.url.url;
if (url.startsWith('/api')) {
this.utilService.showSnackBar('Network Error', SnackBarType.Error);
}
console.warn(error.error);
});
}
}

View file

@ -1,24 +1,31 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ModuleWithProviders, NgModule } from '@angular/core';
import {
MatSnackBarModule,
MAT_SNACK_BAR_DEFAULT_OPTIONS
} from '@angular/material/snack-bar';
import { RouterModule } from '@angular/router';
import { UtilService } from './util.service';
import { ApiErrorService } from './apierror.service';
@NgModule({
declarations: [],
providers: [
UtilService,
{
provide: MAT_SNACK_BAR_DEFAULT_OPTIONS,
useValue: {
duration: 4000,
horizontalPosition: 'left',
},
},
],
imports: [CommonModule, MatSnackBarModule, RouterModule],
})
export class UtilModule {}
export class UtilModule {
static forRoot(): ModuleWithProviders<UtilModule> {
return {
ngModule: UtilModule,
providers: [
{
provide: MAT_SNACK_BAR_DEFAULT_OPTIONS,
useValue: {
duration: 4000,
horizontalPosition: 'left',
},
},
],
};
}
// Start apiErrorService
constructor(private apiErrorService: ApiErrorService) {}
}