From 4a9891cae22f84a7c17f57caf84afebc690a2faf Mon Sep 17 00:00:00 2001 From: FyloZ Date: Tue, 13 Apr 2021 16:38:44 -0400 Subject: [PATCH] =?UTF-8?q?Int=C3=A9gration=20du=20nouveau=20standard=20d'?= =?UTF-8?q?erreur.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../accounts/pages/login/login.component.ts | 21 +- .../accounts/services/account.service.ts | 25 ++- .../mix-editor/mix-editor.component.ts | 17 +- .../mix-table/mix-table.component.ts | 2 +- .../colors/pages/edit/edit.component.ts | 11 +- .../colors/pages/explore/explore.component.ts | 19 +- .../colors/pages/list/list.component.ts | 6 +- .../pages/mix/mix-add/mix-add.component.ts | 6 +- .../pages/mix/mix-edit/mix-edit.component.ts | 4 +- .../company/pages/add/add.component.ts | 8 +- .../company/pages/edit/edit.component.ts | 20 +- .../employees/pages/add/add.component.ts | 10 +- .../employees/pages/edit/edit.component.ts | 13 +- .../password-edit/password-edit.component.ts | 10 +- .../modules/groups/pages/add/add.component.ts | 7 +- .../groups/pages/edit/edit.component.ts | 13 +- .../groups/pages/list/list.component.ts | 6 +- .../material-type/pages/add/add.component.ts | 14 +- .../pages/edit/edit.component.ts | 27 +-- .../material/pages/add/add.component.ts | 8 +- .../material/pages/edit/edit.component.ts | 209 +++++++++--------- .../components/subscribing.component.ts | 18 +- .../modules/shared/service/error.service.ts | 39 ++-- 23 files changed, 273 insertions(+), 240 deletions(-) diff --git a/src/app/modules/accounts/pages/login/login.component.ts b/src/app/modules/accounts/pages/login/login.component.ts index 0601ec5..8f5443a 100644 --- a/src/app/modules/accounts/pages/login/login.component.ts +++ b/src/app/modules/accounts/pages/login/login.component.ts @@ -1,23 +1,16 @@ import {Component, OnInit} from '@angular/core' import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms' import {AccountService} from '../../services/account.service' -import {Router} from '@angular/router' -import {ErrorHandler, ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ActivatedRoute, Router} from '@angular/router' +import {ErrorService} from '../../../shared/service/error.service' +import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' @Component({ selector: 'cre-login', templateUrl: './login.component.html', styleUrls: ['./login.component.sass'] }) -export class LoginComponent implements ErrorHandler, OnInit { - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 401, - messageProducer: () => 'Les identifiants entrés sont invalides.' - }, { - filter: error => error.status === 404 || error.status === 403, - consumer: () => console.warn('No default user is defined on this computer') - }] - +export class LoginComponent extends ErrorHandlingComponent implements OnInit { form: FormGroup idFormControl: FormControl passwordFormControl: FormControl @@ -25,9 +18,11 @@ export class LoginComponent implements ErrorHandler, OnInit { constructor( private formBuilder: FormBuilder, private accountService: AccountService, - private errorService: ErrorService, - private router: Router + errorService: ErrorService, + router: Router, + activatedRoute: ActivatedRoute ) { + super(errorService, activatedRoute, router) } ngOnInit(): void { diff --git a/src/app/modules/accounts/services/account.service.ts b/src/app/modules/accounts/services/account.service.ts index ab037e2..77175bf 100644 --- a/src/app/modules/accounts/services/account.service.ts +++ b/src/app/modules/accounts/services/account.service.ts @@ -8,6 +8,7 @@ import {ApiService} from '../../shared/service/api.service' import {Employee, EmployeePermission} from '../../shared/model/employee' import {ErrorService} from '../../shared/service/error.service' import {globalLoadingWheel} from '../../shared/components/loading-wheel/loading-wheel.component' +import {AlertService} from '../../shared/service/alert.service' @Injectable({ providedIn: 'root' @@ -19,7 +20,8 @@ export class AccountService implements OnDestroy { private http: HttpClient, private api: ApiService, private appState: AppState, - private errorService: ErrorService + private errorService: ErrorService, + private alertService: AlertService ) { } @@ -39,10 +41,17 @@ export class AccountService implements OnDestroy { .pipe( take(1), takeUntil(this.destroy$), - ).subscribe({ - next: employee => this.appState.authenticatedEmployee = employee, - error: err => this.errorService.handleError(err) - }) + ).subscribe( + { + next: employee => this.appState.authenticatedEmployee = employee, + error: err => { + if (err.status === 404 || err.status === 403) { + console.warn('No default user is defined on this computer') + } else { + this.errorService.handleError(err) + } + } + }) } } @@ -65,7 +74,11 @@ export class AccountService implements OnDestroy { success() }, error: err => { - this.errorService.handleError(err) + if (err.status === 401) { + this.alertService.pushError('Les identifiants entrés sont invalides') + } else { + this.errorService.handleError(err) + } globalLoadingWheel.hide() } }) diff --git a/src/app/modules/colors/components/mix-editor/mix-editor.component.ts b/src/app/modules/colors/components/mix-editor/mix-editor.component.ts index a0bdfef..11e37a8 100644 --- a/src/app/modules/colors/components/mix-editor/mix-editor.component.ts +++ b/src/app/modules/colors/components/mix-editor/mix-editor.component.ts @@ -52,13 +52,15 @@ export class MixEditorComponent extends ErrorHandlingComponent { columns = ['position', 'buttonsPosition', 'material', 'quantity', 'units', 'buttonRemove'] deleting = false - handledErrorModels = [{ - filter: error => error.status === 409 && !this.deleting, - messageProducer: error => `Un mélange avec le nom '${error.id}' existe déjà dans cette recette` + errorHandlers = [{ + filter: error => error.type === 'notfound-mix-id', + consumer: error => this.urlUtils.navigateTo('/color/list') }, { - filter: error => error.error && error.error.status === 409 && this.deleting, - consumer: () => this.deleting = false, - messageProducer: () => 'Ce mélange est utilisé par un ou plusieurs autres mélanges' + filter: error => error.type === 'exists-material-name', + messageProducer: error => `Un produit avec le nom '${error.name}' existe déjà` + }, { + filter: error => error.type === 'cannotdelete-mix', + messageProducer: error => 'Ce mélange est utilisé par un ou plusieurs autres mélanges' }] constructor( @@ -95,8 +97,7 @@ export class MixEditorComponent extends ErrorHandlingComponent { this.addBlankMixMaterial() } this.generateForm() - }, - '/color/list' + } ) } diff --git a/src/app/modules/colors/components/mix-table/mix-table.component.ts b/src/app/modules/colors/components/mix-table/mix-table.component.ts index 9832e3c..fd0a172 100644 --- a/src/app/modules/colors/components/mix-table/mix-table.component.ts +++ b/src/app/modules/colors/components/mix-table/mix-table.component.ts @@ -128,7 +128,7 @@ export class MixTableComponent extends SubscribingComponent { isInLowQuantity(materialId: number): boolean { return this.deductErrorBody.mix === this.mix.id && - this.deductErrorBody.lowQuantities.filter(l => l.material === materialId).length > 0 + this.deductErrorBody.lowQuantities.filter(l => l.materialId == materialId).length > 0 } round(quantity: number): number { diff --git a/src/app/modules/colors/pages/edit/edit.component.ts b/src/app/modules/colors/pages/edit/edit.component.ts index c4606ad..5382f21 100644 --- a/src/app/modules/colors/pages/edit/edit.component.ts +++ b/src/app/modules/colors/pages/edit/edit.component.ts @@ -10,7 +10,7 @@ import {AccountService} from '../../../accounts/services/account.service' import {EmployeePermission} from '../../../shared/model/employee' import {EntityEditComponent} from '../../../shared/components/entity-edit/entity-edit.component' import {ImagesEditorComponent} from '../../components/images-editor/images-editor.component' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' import {AlertService} from '../../../shared/service/alert.service' import {GroupService} from '../../../groups/services/group.service' import {AppState} from '../../../shared/app-state' @@ -105,9 +105,9 @@ export class EditComponent extends ErrorHandlingComponent { units$ = new Subject() submittedValues: any | null - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 409, - messageProducer: () => `Une couleur avec le nom '${this.submittedValues.name}' et la bannière '${this.recipe.company.name}' existe déjà` + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'notfound-recipe-id', + consumer: error => this.urlUtils.navigateTo('/color/list') }] constructor( @@ -137,8 +137,7 @@ export class EditComponent extends ErrorHandlingComponent { if (recipeStepCount(this.recipe) == 0) { this.alertService.pushWarning('Il n\'y a aucune étape dans cette recette') } - }, - '/color/list' + } ) } diff --git a/src/app/modules/colors/pages/explore/explore.component.ts b/src/app/modules/colors/pages/explore/explore.component.ts index 21e3807..e112d4b 100644 --- a/src/app/modules/colors/pages/explore/explore.component.ts +++ b/src/app/modules/colors/pages/explore/explore.component.ts @@ -2,9 +2,9 @@ import {Component} from '@angular/core' import {RecipeService} from '../../services/recipe.service' import {ActivatedRoute, Router} from '@angular/router' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' -import {MixMaterialDto, Recipe, recipeMixCount, recipeNoteForGroupId, recipeStepCount, recipeApprobationExpired} from '../../../shared/model/recipe.model' +import {MixMaterialDto, Recipe, recipeMixCount, recipeNoteForGroupId, recipeStepCount} from '../../../shared/model/recipe.model' import {Observable, Subject} from 'rxjs' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' import {AlertService} from '../../../shared/service/alert.service' import {GlobalAlertHandlerComponent} from '../../../shared/components/global-alert-handler/global-alert-handler.component' import {InventoryService} from '../../../material/service/inventory.service' @@ -32,9 +32,13 @@ export class ExploreComponent extends ErrorHandlingComponent { groupsNote = new Map() deductedMixId: number | null - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 409, - consumer: error => this.deductErrorBody = {mix: this.deductedMixId, lowQuantities: error.error.lowQuantities}, + + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'notfound-recipe-id', + consumer: error => this.urlUtils.navigateTo('/color/list') + }, { + filter: error => error.type === 'notenoughinventory-multiple', + consumer: error => this.deductErrorBody = {mix: this.deductedMixId, lowQuantities: error.lowQuantities}, messageProducer: () => 'Certains produit ne sont pas en quantité suffisante dans l\'inventaire' }] @@ -68,8 +72,7 @@ export class ExploreComponent extends ErrorHandlingComponent { if (recipeMixCount(this.recipe) <= 0 || recipeStepCount(this.recipe) <= 0) { this.alertService.pushWarning('Cette recette n\'est pas complète') } - }, - '/colors/list' + } ) } @@ -82,7 +85,7 @@ export class ExploreComponent extends ErrorHandlingComponent { this.units$.next(unit) } - changeQuantity(event: { mixId: number, mixMaterial: MixMaterialDto}) { + changeQuantity(event: { mixId: number, mixMaterial: MixMaterialDto }) { if (!this.quantitiesChanges.has(event.mixId)) { this.quantitiesChanges.set(event.mixId, new Map()) } diff --git a/src/app/modules/colors/pages/list/list.component.ts b/src/app/modules/colors/pages/list/list.component.ts index 3bc4f20..1b42eb4 100644 --- a/src/app/modules/colors/pages/list/list.component.ts +++ b/src/app/modules/colors/pages/list/list.component.ts @@ -3,9 +3,9 @@ import {ErrorHandlingComponent} from '../../../shared/components/subscribing.com import {RecipeService} from '../../services/recipe.service' import {EmployeePermission} from '../../../shared/model/employee' import {AccountService} from '../../../accounts/services/account.service' -import {getRecipeLuma, recipeApprobationExpired, Recipe} from '../../../shared/model/recipe.model' +import {getRecipeLuma, Recipe, recipeApprobationExpired} from '../../../shared/model/recipe.model' import {ActivatedRoute, Router} from '@angular/router' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorService} from '../../../shared/service/error.service' @Component({ selector: 'cre-list', @@ -19,8 +19,6 @@ export class ListComponent extends ErrorHandlingComponent { panelForcedExpanded = false hiddenRecipes = [] - handledErrorModels: ErrorModel[] - constructor( private recipeService: RecipeService, private accountService: AccountService, diff --git a/src/app/modules/colors/pages/mix/mix-add/mix-add.component.ts b/src/app/modules/colors/pages/mix/mix-add/mix-add.component.ts index 3916658..0cae5af 100644 --- a/src/app/modules/colors/pages/mix/mix-add/mix-add.component.ts +++ b/src/app/modules/colors/pages/mix/mix-add/mix-add.component.ts @@ -2,9 +2,9 @@ import {Component} from '@angular/core' import {Material} from '../../../../shared/model/material.model' import {MaterialService} from '../../../../material/service/material.service' import {ActivatedRoute, Router} from '@angular/router' -import {ErrorHandlingComponent, SubscribingComponent} from '../../../../shared/components/subscribing.component' +import {ErrorHandlingComponent} from '../../../../shared/components/subscribing.component' import {MixService} from '../../../services/mix.service' -import {ErrorHandler, ErrorModel, ErrorService} from '../../../../shared/service/error.service' +import {ErrorService} from '../../../../shared/service/error.service' @Component({ selector: 'cre-mix-add', @@ -15,8 +15,6 @@ export class MixAddComponent extends ErrorHandlingComponent { recipeId: number | null materials: Material[] | null - handledErrorModels: ErrorModel[] - constructor( private materialService: MaterialService, private mixService: MixService, diff --git a/src/app/modules/colors/pages/mix/mix-edit/mix-edit.component.ts b/src/app/modules/colors/pages/mix/mix-edit/mix-edit.component.ts index b80d096..5b360fd 100644 --- a/src/app/modules/colors/pages/mix/mix-edit/mix-edit.component.ts +++ b/src/app/modules/colors/pages/mix/mix-edit/mix-edit.component.ts @@ -4,7 +4,7 @@ import {ErrorHandlingComponent} from '../../../../shared/components/subscribing. import {Material} from '../../../../shared/model/material.model' import {MaterialService} from '../../../../material/service/material.service' import {MixService} from '../../../services/mix.service' -import {ErrorModel, ErrorService} from '../../../../shared/service/error.service' +import {ErrorHandlerComponent, ErrorService} from '../../../../shared/service/error.service' import {MixMaterialDto} from '../../../../shared/model/recipe.model' import {AlertService} from '../../../../shared/service/alert.service' @@ -18,8 +18,6 @@ export class MixEditComponent extends ErrorHandlingComponent { recipeId: number | null materials: Material[] | null - handledErrorModels: ErrorModel[] - constructor( private materialService: MaterialService, private mixService: MixService, diff --git a/src/app/modules/company/pages/add/add.component.ts b/src/app/modules/company/pages/add/add.component.ts index 96a7243..83d3ff7 100644 --- a/src/app/modules/company/pages/add/add.component.ts +++ b/src/app/modules/company/pages/add/add.component.ts @@ -3,7 +3,7 @@ import {CompanyService} from '../../service/company.service' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' import {FormField} from '../../../shared/components/entity-add/entity-add.component' import {ActivatedRoute, Router} from '@angular/router' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' @Component({ selector: 'cre-add', @@ -25,9 +25,9 @@ export class AddComponent extends ErrorHandlingComponent { ] submittedValues: any | null - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 409, - messageProducer: () => `Une bannière avec le nom '${this.submittedValues.name}' existe déjà` + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'exists-company-name', + messageProducer: error => `Une bannière avec le nom '${error.name}' existe déjà` }] constructor( diff --git a/src/app/modules/company/pages/edit/edit.component.ts b/src/app/modules/company/pages/edit/edit.component.ts index 5037b3e..8564f8f 100644 --- a/src/app/modules/company/pages/edit/edit.component.ts +++ b/src/app/modules/company/pages/edit/edit.component.ts @@ -4,7 +4,7 @@ import {Company} from '../../../shared/model/company.model' import {FormField} from '../../../shared/components/entity-add/entity-add.component' import {CompanyService} from '../../service/company.service' import {ActivatedRoute, Router} from '@angular/router' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorHandlerComponent, ErrorService} from '../../../shared/service/error.service' @Component({ selector: 'cre-edit', @@ -26,13 +26,15 @@ export class EditComponent extends ErrorHandlingComponent { } ] - deleting = false - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 409 && !this.deleting, - messageProducer: error => `Une bannière avec le nom '${error.error.id}' existe déjà` + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'notfound-company-id', + consumer: error => this.urlUtils.navigateTo('/catalog/company/list') }, { - filter: error => error.status === 409 && this.deleting, - messageProducer: () => 'Cette bannière est utilisée par une ou plusieurs recettes' + filter: error => error.type === 'exists-company-name', + messageProducer: error => `Une bannière avec le nom '${error.name}' existe déjà` + }, { + filter: error => error.type === 'cannotdelete-company', + messageProducer: error => 'Cette bannière est utilisée par une ou plusieurs recettes' }] constructor( @@ -51,8 +53,7 @@ export class EditComponent extends ErrorHandlingComponent { this.subscribeEntityById( this.companyService, id, - company => this.company = company, - '/catalog/company/list' + company => this.company = company ) } @@ -64,7 +65,6 @@ export class EditComponent extends ErrorHandlingComponent { } delete() { - this.deleting = true this.subscribeAndNavigate( this.companyService.delete(this.company.id), '/catalog/company/list' diff --git a/src/app/modules/employees/pages/add/add.component.ts b/src/app/modules/employees/pages/add/add.component.ts index 21f2d51..60033cd 100644 --- a/src/app/modules/employees/pages/add/add.component.ts +++ b/src/app/modules/employees/pages/add/add.component.ts @@ -8,7 +8,7 @@ import {GroupService} from '../../../groups/services/group.service' import {EmployeeService} from '../../services/employee.service' import {ActivatedRoute, Router} from '@angular/router' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' -import {ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' import {FormField} from '../../../shared/components/entity-add/entity-add.component' import {map} from 'rxjs/operators' @@ -75,6 +75,14 @@ export class AddComponent extends ErrorHandlingComponent { type: 'permissions' }] + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'exists-employee-id', + messageProducer: error => `Un utilisateur avec l'identifiant ${error.id} existe déjà` + }, { + filter: error => error.type === 'exists-employee-fullName', + messageProducer: error => `Un utilisateur nommé '${error.fullName}' existe déjà` + }] + constructor( private employeeService: EmployeeService, private groupService: GroupService, diff --git a/src/app/modules/employees/pages/edit/edit.component.ts b/src/app/modules/employees/pages/edit/edit.component.ts index afa4023..97fd9e2 100644 --- a/src/app/modules/employees/pages/edit/edit.component.ts +++ b/src/app/modules/employees/pages/edit/edit.component.ts @@ -6,7 +6,7 @@ import {ActivatedRoute, Router} from '@angular/router' import {Employee} from '../../../shared/model/employee' import {AccountService} from '../../../accounts/services/account.service' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' -import {ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' import {FormField} from '../../../shared/components/entity-add/entity-add.component' import {map} from 'rxjs/operators' @@ -58,6 +58,14 @@ export class EditComponent extends ErrorHandlingComponent { type: 'permissions' }] + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'notfound-employee-id', + consumer: error => this.urlUtils.navigateTo('/employee/list') + }, { + filter: error => error.type === 'exists-employee-fullName', + messageProducer: error => `Un utilisateur nommé '${error.fullName}' existe déjà` + }] + constructor( private accountService: AccountService, private employeeService: EmployeeService, @@ -74,8 +82,7 @@ export class EditComponent extends ErrorHandlingComponent { this.subscribeEntityById( this.employeeService, id, - employee => this.employee = employee, - '/employee/list' + employee => this.employee = employee ) this.formFields[this.formFields.length - 1].template = this.permissionsTemplateRef diff --git a/src/app/modules/employees/pages/password-edit/password-edit.component.ts b/src/app/modules/employees/pages/password-edit/password-edit.component.ts index 0be7343..4670eae 100644 --- a/src/app/modules/employees/pages/password-edit/password-edit.component.ts +++ b/src/app/modules/employees/pages/password-edit/password-edit.component.ts @@ -4,7 +4,7 @@ import {EmployeeService} from '../../services/employee.service' import {Employee} from '../../../shared/model/employee' import {ActivatedRoute, Router} from '@angular/router' import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms' -import {ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' @Component({ selector: 'cre-password-edit', @@ -17,6 +17,11 @@ export class PasswordEditComponent extends ErrorHandlingComponent { form: FormGroup passwordControl = new FormControl(null, Validators.compose([Validators.required, Validators.minLength(8)])) + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'notfound-employee-id', + consumer: error => this.urlUtils.navigateTo('/employee/list') + }] + constructor( private employeeService: EmployeeService, private formBuilder: FormBuilder, @@ -32,8 +37,7 @@ export class PasswordEditComponent extends ErrorHandlingComponent { this.subscribeEntityById( this.employeeService, id, - employee => this.employee = employee, - '/employee/list' + employee => this.employee = employee ) this.form = this.formBuilder.group({ diff --git a/src/app/modules/groups/pages/add/add.component.ts b/src/app/modules/groups/pages/add/add.component.ts index 34e7623..743c0a2 100644 --- a/src/app/modules/groups/pages/add/add.component.ts +++ b/src/app/modules/groups/pages/add/add.component.ts @@ -4,7 +4,7 @@ import {GroupService} from '../../services/group.service' import {ActivatedRoute, Router} from '@angular/router' import {currentPermissionsFieldComponent} from '../../../shared/components/permissions-field/permissions-field.component' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' -import {ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' import {FormField} from '../../../shared/components/entity-add/entity-add.component' @Component({ @@ -32,6 +32,11 @@ export class AddComponent extends ErrorHandlingComponent { type: 'permissions' }] + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'exists-employeegroup-name', + messageProducer: error => `Un groupe avec le nom '${error.name}' existe déjà` + }] + constructor( private groupService: GroupService, errorService: ErrorService, diff --git a/src/app/modules/groups/pages/edit/edit.component.ts b/src/app/modules/groups/pages/edit/edit.component.ts index cdbca83..5c47e54 100644 --- a/src/app/modules/groups/pages/edit/edit.component.ts +++ b/src/app/modules/groups/pages/edit/edit.component.ts @@ -6,7 +6,7 @@ import {Validators} from '@angular/forms' import {currentPermissionsFieldComponent} from '../../../shared/components/permissions-field/permissions-field.component' import {AccountService} from '../../../accounts/services/account.service' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' -import {ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' import {FormField} from '../../../shared/components/entity-add/entity-add.component' @Component({ @@ -35,6 +35,14 @@ export class EditComponent extends ErrorHandlingComponent { }] group: EmployeeGroup | null + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'notfound-employeegroup-id', + consumer: error => this.urlUtils.navigateTo('/group/list') + }, { + filter: error => error.type === 'exists-employeegroup-name', + messageProducer: error => `Un groupe avec le nom '${error.name}' existe déjà` + }] + constructor( private accountService: AccountService, private groupService: GroupService, @@ -50,8 +58,7 @@ export class EditComponent extends ErrorHandlingComponent { this.subscribeEntityById( this.groupService, id, - group => this.group = group, - '/group/list' + group => this.group = group ) this.formFields[this.formFields.length - 1].template = this.permissionsTemplateRef diff --git a/src/app/modules/groups/pages/list/list.component.ts b/src/app/modules/groups/pages/list/list.component.ts index 15743bb..24e1ae4 100644 --- a/src/app/modules/groups/pages/list/list.component.ts +++ b/src/app/modules/groups/pages/list/list.component.ts @@ -4,7 +4,7 @@ import {EmployeeGroup, EmployeePermission} from '../../../shared/model/employee' import {AccountService} from '../../../accounts/services/account.service' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' import {ActivatedRoute, Router} from '@angular/router' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' import {AlertService} from '../../../shared/service/alert.service' @Component({ @@ -29,8 +29,8 @@ export class ListComponent extends ErrorHandlingComponent { permission: EmployeePermission.EDIT_USERS }] - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 404, + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'nodefaultgroup', consumer: () => this.alertService.pushWarning('Aucun groupe par défaut n\'a été défini sur cet ordinateur') }] diff --git a/src/app/modules/material-type/pages/add/add.component.ts b/src/app/modules/material-type/pages/add/add.component.ts index dd765a1..9b2fe76 100644 --- a/src/app/modules/material-type/pages/add/add.component.ts +++ b/src/app/modules/material-type/pages/add/add.component.ts @@ -4,7 +4,7 @@ import {Validators} from '@angular/forms' import {MaterialTypeService} from '../../service/material-type.service' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' import {ActivatedRoute, Router} from '@angular/router' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' @Component({ selector: 'cre-add', @@ -45,14 +45,13 @@ export class AddComponent extends ErrorHandlingComponent { type: 'checkbox' } ] - submittedValues: any | null - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 409 && error.error.id === this.submittedValues.name, - messageProducer: error => `Un type de produit avec le nom '${error.error.id}' existe déjà` + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'exists-materialtype-name', + messageProducer: error => `Un type de produit avec le nom '${error.name}' existe déjà` }, { - filter: error => error.status === 409 && error.error.id === this.submittedValues.prefix, - messageProducer: error => `Un type de produit avec le préfixe '${error.error.id}' existe déjà` + filter: error => error.type === 'exists-materialtype-prefix', + messageProducer: error => `Un type de produit avec le préfixe '${error.prefix}' existe déjà` }] constructor( @@ -65,7 +64,6 @@ export class AddComponent extends ErrorHandlingComponent { } submit(values) { - this.submittedValues = values this.subscribeAndNavigate( this.materialTypeService.save(values.name, values.prefix, values.usePercentages), '/catalog/materialtype/list' diff --git a/src/app/modules/material-type/pages/edit/edit.component.ts b/src/app/modules/material-type/pages/edit/edit.component.ts index 73e8a69..fcf3755 100644 --- a/src/app/modules/material-type/pages/edit/edit.component.ts +++ b/src/app/modules/material-type/pages/edit/edit.component.ts @@ -5,7 +5,7 @@ import {ErrorHandlingComponent} from '../../../shared/components/subscribing.com import {MaterialTypeService} from '../../service/material-type.service' import {FormField} from '../../../shared/components/entity-add/entity-add.component' import {Validators} from '@angular/forms' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' @Component({ selector: 'cre-edit', @@ -42,18 +42,18 @@ export class EditComponent extends ErrorHandlingComponent { } ] - deleting = false - submittedValues: any | null - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 409 && !this.deleting && error.error.id === this.submittedValues.name, - messageProducer: error => `Un type de produit avec le nom '${error.error.id}' existe déjà` + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'notfound-materialtype-id', + consumer: error => this.urlUtils.navigateTo('/catalog/materialtype/list') }, { - filter: error => error.status === 409 && !this.deleting && error.error.id === this.submittedValues.prefix, - messageProducer: error => `Un type de produit avec le préfixe '${error.error.id}' existe déjà` + filter: error => error.type === 'exists-materialtype-name', + messageProducer: error => `Un type de produit avec le nom '${error.name}' existe déjà` }, { - filter: error => error.status === 409 && this.deleting, - consumer: () => this.deleting = true, - messageProducer: () => 'Ce type de produit est utilisé dans une ou plusieurs recettes ou produits' + filter: error => error.type === 'exists-materialtype-prefix', + messageProducer: error => `Un type de produit avec le préfixe '${error.prefix}' existe déjà` + }, { + filter: error => error.type === 'cannotdelete-materialtype', + messageProducer: error => 'Ce type de produit est utilisé dans une ou plusieurs recettes ou produits' }] constructor( @@ -72,13 +72,11 @@ export class EditComponent extends ErrorHandlingComponent { this.subscribeEntityById( this.materialTypeService, id, - materialType => this.materialType = materialType, - '/employee/list' + materialType => this.materialType = materialType ) } submit(values) { - this.submittedValues = values this.subscribeAndNavigate( this.materialTypeService.update(this.materialType.id, values.name, values.prefix), '/catalog/materialtype/list' @@ -86,7 +84,6 @@ export class EditComponent extends ErrorHandlingComponent { } delete() { - this.deleting = true this.subscribeAndNavigate( this.materialTypeService.delete(this.materialType.id), '/catalog/materialtype/list' diff --git a/src/app/modules/material/pages/add/add.component.ts b/src/app/modules/material/pages/add/add.component.ts index 0faa0c4..cfc3eef 100644 --- a/src/app/modules/material/pages/add/add.component.ts +++ b/src/app/modules/material/pages/add/add.component.ts @@ -6,7 +6,7 @@ import {MaterialTypeService} from '../../../material-type/service/material-type. import {ActivatedRoute, Router} from '@angular/router' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' import {map} from 'rxjs/operators' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorHandlerComponent, ErrorService} from '../../../shared/service/error.service' @Component({ selector: 'cre-add', @@ -60,9 +60,9 @@ export class AddComponent extends ErrorHandlingComponent { } ] - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 409, - messageProducer: error => `Un produit avec le nom '${error.error.id}' existe déjà` + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'exists-material-name', + messageProducer: error => `Un produit avec le nom '${error.name}' existe déjà` }] constructor( diff --git a/src/app/modules/material/pages/edit/edit.component.ts b/src/app/modules/material/pages/edit/edit.component.ts index 236075d..e5dea2b 100644 --- a/src/app/modules/material/pages/edit/edit.component.ts +++ b/src/app/modules/material/pages/edit/edit.component.ts @@ -8,122 +8,121 @@ import {ActivatedRoute, Router} from '@angular/router' import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component' import {Material} from '../../../shared/model/material.model' import {environment} from '../../../../../environments/environment' -import {ErrorModel, ErrorService} from '../../../shared/service/error.service' +import {ErrorHandler, ErrorService} from '../../../shared/service/error.service' @Component({ - selector: 'cre-edit', - templateUrl: './edit.component.html', - styleUrls: ['./edit.component.sass'] + selector: 'cre-edit', + templateUrl: './edit.component.html', + styleUrls: ['./edit.component.sass'] }) export class EditComponent extends ErrorHandlingComponent { - @ViewChild('simdutTemplate', {static: true}) simdutTemplateRef + @ViewChild('simdutTemplate', {static: true}) simdutTemplateRef - material: Material | null - formFields: FormField[] = [ - { - name: 'name', - label: 'Code', - icon: 'form-textbox', - type: 'text', - required: true, - errorMessages: [ - {conditionFn: (errors) => errors.required, message: 'Un code est requis'} - ] - }, - { - name: 'inventoryQuantity', - label: 'Quantité en inventaire', - icon: 'beaker-outline', - type: 'number', - required: true, - validator: Validators.min(0), - errorMessages: [ - {conditionFn: errors => errors.required, message: 'Une quantité en inventaire est requise'}, - {conditionFn: errors => errors.min, message: 'La quantité doit être supérieure ou égale à 0'} - ], - step: '0.01' - }, - { - name: 'materialType', - label: 'Type de produit', - icon: 'shape-outline', - type: 'select', - required: true, - errorMessages: [ - {conditionFn: errors => errors.required, message: 'Un type de produit est requis'} - ], - valueFn: material => material.materialType.id, - options$: this.materialTypeService.all.pipe(map(types => types.map(t => { - return {value: t.id, label: t.name} - }))) - }, - { - name: 'simdutFile', - label: 'Fiche signalitique', - icon: 'file-outline', - type: 'file', - fileType: 'application/pdf' - } - ] - hasSimdut = false - selectedSimdutFile: File | null - - deleting = false - handledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 409 && !this.deleting, - messageProducer: error => `Un produit avec le nom '${error.error.id}' existe déjà` - }, { - filter: error => error.status === 409 && this.deleting, - consumer: () => this.deleting = false, - messageProducer: () => `Ce produit est utilisé dans une plusieurs recettes` - }] - - constructor( - private materialService: MaterialService, - private materialTypeService: MaterialTypeService, - errorService: ErrorService, - router: Router, - activatedRoute: ActivatedRoute - ) { - super(errorService, activatedRoute, router) + material: Material | null + formFields: FormField[] = [ + { + name: 'name', + label: 'Code', + icon: 'form-textbox', + type: 'text', + required: true, + errorMessages: [ + {conditionFn: (errors) => errors.required, message: 'Un code est requis'} + ] + }, + { + name: 'inventoryQuantity', + label: 'Quantité en inventaire', + icon: 'beaker-outline', + type: 'number', + required: true, + validator: Validators.min(0), + errorMessages: [ + {conditionFn: errors => errors.required, message: 'Une quantité en inventaire est requise'}, + {conditionFn: errors => errors.min, message: 'La quantité doit être supérieure ou égale à 0'} + ], + step: '0.01' + }, + { + name: 'materialType', + label: 'Type de produit', + icon: 'shape-outline', + type: 'select', + required: true, + errorMessages: [ + {conditionFn: errors => errors.required, message: 'Un type de produit est requis'} + ], + valueFn: material => material.materialType.id, + options$: this.materialTypeService.all.pipe(map(types => types.map(t => { + return {value: t.id, label: t.name} + }))) + }, + { + name: 'simdutFile', + label: 'Fiche signalitique', + icon: 'file-outline', + type: 'file', + fileType: 'application/pdf' } + ] + hasSimdut = false + selectedSimdutFile: File | null - ngOnInit() { - super.ngOnInit() + errorHandlers: ErrorHandler[] = [{ + filter: error => error.type === 'notfound-material-id', + consumer: error => this.urlUtils.navigateTo('/catalog/material/list') + }, { + filter: error => error.type === 'exists-material-name', + messageProducer: error => `Un produit avec le nom '${error.name}' existe déjà` + }, { + filter: error => error.type === 'cannotdelete-material', + messageProducer: error => `Ce produit est utilisé dans une plusieurs recettes` + }] - this.formFields[3].template = this.simdutTemplateRef + constructor( + private materialService: MaterialService, + private materialTypeService: MaterialTypeService, + errorService: ErrorService, + router: Router, + activatedRoute: ActivatedRoute + ) { + super(errorService, activatedRoute, router) + } - const id = parseInt(this.activatedRoute.snapshot.paramMap.get('id')) - this.subscribeEntityById( - this.materialService, - id, - material => this.material = material, - '/catalog/material/list' - ) + ngOnInit() { + super.ngOnInit() - this.subscribe( - this.materialService.hasSimdut(id), - b => this.hasSimdut = b - ) - } + this.formFields[3].template = this.simdutTemplateRef - submit(values) { - this.subscribeAndNavigate( - this.materialService.update(this.material.id, values.name, values.inventoryQuantity, values.materialType, this.selectedSimdutFile), - '/catalog/material/list' - ) - } + const id = parseInt(this.activatedRoute.snapshot.paramMap.get('id')) + this.subscribeEntityById( + this.materialService, + id, + material => this.material = material + ) - delete() { - this.deleting = true - this.subscribeAndNavigate( - this.materialService.delete(this.material.id), - '/catalog/material/list' - ) - } + this.subscribe( + this.materialService.hasSimdut(id), + b => this.hasSimdut = b + ) + } - openSimdutUrl() { - const simdutUrl = environment.apiUrl + `/material/${this.material.id}/simdut` - window.open(simdutUrl, '_blank') - } + submit(values) { + this.subscribeAndNavigate( + this.materialService.update(this.material.id, values.name, values.inventoryQuantity, values.materialType, this.selectedSimdutFile), + '/catalog/material/list' + ) + } + + delete() { + this.subscribeAndNavigate( + this.materialService.delete(this.material.id), + '/catalog/material/list' + ) + } + + openSimdutUrl() { + const simdutUrl = environment.apiUrl + `/material/${this.material.id}/simdut` + window.open(simdutUrl, '_blank') + } } diff --git a/src/app/modules/shared/components/subscribing.component.ts b/src/app/modules/shared/components/subscribing.component.ts index c73a786..2c58970 100644 --- a/src/app/modules/shared/components/subscribing.component.ts +++ b/src/app/modules/shared/components/subscribing.component.ts @@ -3,7 +3,7 @@ import {OnDestroy, OnInit} from '@angular/core' import {Observable, Subject} from 'rxjs' import {ActivatedRoute, Router} from '@angular/router' import {UrlUtils} from '../utils/url.utils' -import {ErrorHandler, ErrorModel, ErrorService} from '../service/error.service' +import {ErrorHandler, ErrorHandlerComponent, ErrorService} from '../service/error.service' import {globalLoadingWheel} from './loading-wheel/loading-wheel.component' export abstract class SubscribingComponent implements OnInit, OnDestroy { @@ -47,7 +47,7 @@ export abstract class SubscribingComponent implements OnInit, OnDestroy { ) } - subscribeEntityById(service: any, id: number, resultConsumer: (T) => void, notFoundRoute: string, showWheel = true) { + subscribeEntityById(service: any, id: number, resultConsumer: (T) => void, showWheel = true) { this.showLoadingWheel(showWheel) this.subscribers$.push(service.getById(id) .pipe(take(1), takeUntil(this.destroy$)) @@ -57,8 +57,8 @@ export abstract class SubscribingComponent implements OnInit, OnDestroy { this.hideLoadingWheel(showWheel) }, error: err => { - this.handleNotFoundError(err, notFoundRoute) this.hideLoadingWheel(showWheel) + this.errorService.handleError(err) } })) } @@ -71,14 +71,6 @@ export abstract class SubscribingComponent implements OnInit, OnDestroy { this.destroy$.complete() } - handleNotFoundError(error: any, route: string) { - if (error.status === 404) { - this.urlUtils.navigateTo(route) - } else { - this.errorService.handleError(error) - } - } - protected showLoadingWheel(shouldShowWheel) { if (shouldShowWheel) { globalLoadingWheel.show() @@ -92,8 +84,8 @@ export abstract class SubscribingComponent implements OnInit, OnDestroy { } } -export abstract class ErrorHandlingComponent extends SubscribingComponent implements ErrorHandler { - handledErrorModels: ErrorModel[] = [] +export abstract class ErrorHandlingComponent extends SubscribingComponent implements ErrorHandlerComponent { + errorHandlers: ErrorHandler[] = [] protected constructor( errorService: ErrorService, diff --git a/src/app/modules/shared/service/error.service.ts b/src/app/modules/shared/service/error.service.ts index 8c16715..299cc24 100644 --- a/src/app/modules/shared/service/error.service.ts +++ b/src/app/modules/shared/service/error.service.ts @@ -7,13 +7,10 @@ import {AppState} from '../app-state' }) export class ErrorService { private static readonly UNKNOWN_ERROR_MESSAGE = 'Une erreur inconnue est survenue' - private defaultHandledErrorModels: ErrorModel[] = [{ - filter: error => error.status === 0 && error.statusText === 'Unknown Error' || error.status === 502, - consumer: () => this.appState.isServerOnline = false - }, { + private defaultHandledErrorModels: ErrorHandler[] = [{ filter: error => error.status === 400, consumer: error => console.error(error), - messageProducer: () => 'Certaines informations dans la requête étaient invalides' + messageProducer: () => 'Certaines informations étaient invalides' }, { filter: error => error.status === 401, messageProducer: () => 'Vous devez être connecté pour effectuer cette action' @@ -31,7 +28,7 @@ export class ErrorService { messageProducer: () => ErrorService.UNKNOWN_ERROR_MESSAGE }] - private activeHandler: ErrorHandler + private activeHandler: ErrorHandlerComponent constructor( private alertService: AlertService, @@ -39,17 +36,25 @@ export class ErrorService { ) { } - handleError(error: any) { + handleError(response: any) { let matchingModels + if (this.isServerOfflineError(response)) { + this.appState.isServerOnline = false + return + } + + const error = response.error + if (this.activeHandler) { - matchingModels = this.activeHandler.handledErrorModels.filter(m => m.filter(error)) // Find error models whose filter matches the current error + matchingModels = this.activeHandler.errorHandlers.filter(m => m.filter(error)) // Find error models whose filter matches the current error } else { console.warn('An error occurred but no handler was set') + console.error(error) } if (!matchingModels || matchingModels.length == 0) { // If none are found, search in defaults handlers - matchingModels = this.defaultHandledErrorModels.filter(m => m.filter(error)) + matchingModels = errorHandlers.filter(m => m.filter(error)) } if (!matchingModels || matchingModels.length == 0) { // If still none are found, handle as an unknown error @@ -72,7 +77,7 @@ export class ErrorService { } consumeUnknownError(error: any) { - console.error(error) + console.error('An unknown error occurred', error) this.pushUnknownError() } @@ -80,16 +85,20 @@ export class ErrorService { this.alertService.pushError(ErrorService.UNKNOWN_ERROR_MESSAGE) } - set activeErrorHandler(handler: ErrorHandler) { + set activeErrorHandler(handler: ErrorHandlerComponent) { this.activeHandler = handler } + + private isServerOfflineError(response: any): boolean { + return response.status === 0 && response.statusText === 'Unknown Error' + } } /** * An error handler, defining models of errors that this type will handle */ -export interface ErrorHandler { - handledErrorModels: ErrorModel[] +export interface ErrorHandlerComponent { + errorHandlers: ErrorHandler[] } /** @@ -100,7 +109,7 @@ export interface ErrorHandler { * * To work correctly a model must define at least one handler (consumer or message producer). */ -export class ErrorModel { +export class ErrorHandler { constructor( public filter: (error: any) => Boolean, public consumer?: (error: any) => void, @@ -108,3 +117,5 @@ export class ErrorModel { ) { } } + +const errorHandlers: ErrorHandler[] = []