Skip to content

Commit

Permalink
rework error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
kcinay055679 committed Jan 14, 2025
1 parent 610fcfd commit 9ef62c1
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 29 deletions.
4 changes: 3 additions & 1 deletion frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import { ApplicationTopBarComponent } from './components/application-top-bar/app
import { A11yModule } from '@angular/cdk/a11y';
import { CustomizationService } from './services/customization.service';
import { MetricCheckInDirective } from './components/checkin/check-in-form-metric/metric-check-in-directive';
import { ErrorComponent } from './shared/custom/error/error.component';

function initOauthFactory(configService: ConfigService, oauthService: OAuthService) {
return async() => {
Expand Down Expand Up @@ -170,7 +171,8 @@ export const MY_FORMATS = {
CdkDrag,
A11yModule,
CdkDragHandle,
SharedModule
SharedModule,
ErrorComponent
],
providers: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
</option>
</select>

<mat-error *ngFor="let error of getErrorMessages('unit')">{{ error }}</mat-error>
<app-error [form]="keyResultForm" [controlPath]="['metric', 'unit']"></app-error>

</div>
</div>
</div>
Expand All @@ -66,7 +67,7 @@
{{ user.firstName + " " + user.lastName }}
</mat-option>
</mat-autocomplete>
<mat-error *ngFor="let error of getErrorMessages('owner')">{{ error }}</mat-error>
<app-error [form]="keyResultForm" [controlPath]="['metric', 'owner']"></app-error>
</div>
</div>
</div>
Expand All @@ -85,7 +86,7 @@
formControlName="baseline"
id="baseline"
/>
<mat-error *ngFor="let error of getErrorMessages('baseline')">{{ error }}</mat-error>
<app-error [form]="keyResultForm" [controlPath]="['metric', 'baseline']"></app-error>
</div>
</div>
</div>
Expand All @@ -101,7 +102,8 @@
formControlName="targetGoal"
id="target-goal"
/>
<mat-error *ngFor="let error of getErrorMessages('targetGoal')">{{ error }}</mat-error>
<app-error [form]="keyResultForm" [controlPath]="['metric', 'targetGoal']"></app-error>

</div>
</div>
</div>
Expand All @@ -117,7 +119,8 @@
formControlName="stretchGoal"
id="stretch-goal"
/>
<mat-error *ngFor="let error of getErrorMessages('stretchGoal')">{{ error }}</mat-error>
<app-error [form]="keyResultForm" [controlPath]="['metric', 'stretchGoal']"></app-error>

</div>
</div>
</div>
Expand All @@ -138,7 +141,7 @@
id="commit-zone"
[attr.data-testId]="'commit-zone'"
></textarea>
<mat-error *ngFor="let error of getErrorMessages('commitZone')">{{ error }}</mat-error>
<app-error [form]="keyResultForm" [controlPath]="['ordinal', 'commitZone']"></app-error>
</div>
</div>
</div>
Expand All @@ -154,7 +157,7 @@
formControlName="targetZone"
id="target-zone"
></textarea>
<mat-error *ngFor="let error of getErrorMessages('targetZone')">{{ error }}</mat-error>
<app-error [form]="keyResultForm" [controlPath]="['ordinal', 'targetZone']"></app-error>
</div>
</div>
</div>
Expand All @@ -170,9 +173,11 @@
formControlName="stretchZone"
id="stretch-zone"
></textarea>
<mat-error *ngFor="let error of getErrorMessages('stretchZone')">{{ error }}</mat-error>
<app-error [form]="keyResultForm" [controlPath]="['ordinal','stretchZone']"></app-error>
</div>
</div>
</div>
</div>
</ng-template>


Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input } from '@angular/core';
import { KeyResult } from '../../shared/types/model/key-result';
import { ControlContainer, FormGroup, FormGroupDirective, ValidationErrors } from '@angular/forms';
import { ControlContainer, FormGroup, FormGroupDirective } from '@angular/forms';
import { KeyResultMetric } from '../../shared/types/model/key-result-metric';
import { KeyResultOrdinal } from '../../shared/types/model/key-result-ordinal';
import { Unit } from '../../shared/types/enums/unit';
Expand Down Expand Up @@ -43,25 +43,6 @@ export class KeyResultTypeComponent {
}
}

getErrorMessage(
error: string, field: string, firstNumber: number | null, secondNumber: number | null
): string {
console.log(error);
return field + this.translate.instant('DIALOG_ERRORS.' + error)
.format(firstNumber, secondNumber);
}


getErrorMessages(controlName: string) {
const formField = this.keyResultForm.get(controlName);
if (!formField?.errors) {
return;
}
return Object.keys(formField.errors)
.map((errorKey: any) => this.translate.instant('ERRORS.' + errorKey, formField.errors?.[errorKey] || { error: {} } as ValidationErrors));
}


invalidOwner() {
return this.keyResultForm.get('owner')?.invalid || false;
}
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/app/shared/custom/error/error.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<mat-error *ngFor="let error of getErrorMessages()">{{ error }}</mat-error>

Empty file.
24 changes: 24 additions & 0 deletions frontend/src/app/shared/custom/error/error.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ErrorComponent } from './error.component';

describe('ErrorComponent', () => {
let component: ErrorComponent;
let fixture: ComponentFixture<ErrorComponent>;

beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ErrorComponent]
})
.compileComponents();

fixture = TestBed.createComponent(ErrorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component)
.toBeTruthy();
});
});
38 changes: 38 additions & 0 deletions frontend/src/app/shared/custom/error/error.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Component, Input } from '@angular/core';
import { MatError } from '@angular/material/form-field';
import { NgForOf } from '@angular/common';
import { FormGroup, ValidationErrors } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';

@Component({
selector: 'app-error',
imports: [MatError,
NgForOf],
templateUrl: './error.component.html',
styleUrl: './error.component.scss'
})
export class ErrorComponent {
@Input() form?: FormGroup;

@Input() controlPath: string[] = [];

@Input() name?: string;


constructor(private translate: TranslateService) {
}

getErrorMessages() {
const displayName = this.name || this.controlPath[this.controlPath.length - 1];
let formField = this.form;
for (const key of this.controlPath) {
formField = formField?.get(key) as FormGroup;
}
if (!formField?.errors || !formField?.dirty || !formField?.touched) {
return;
}
return Object.keys(formField.errors)
.map((errorKey: any) => this.translate.instant('DIALOG_ERRORS.' + errorKey.toUpperCase(), { fieldName: displayName,
...formField.errors?.[errorKey] || { error: {} } as ValidationErrors }));
}
}
3 changes: 3 additions & 0 deletions frontend/src/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
}
},
"DIALOG_ERRORS": {
"REQUIRED": "{{fieldName}} ist ein Pflichtfeld.",
"MINLENGTH": "{{fieldName}} muss mindestens {{requiredLength}} Zeichen lang sein.",
"MAXLENGTH": "{{fieldName}} darf maximal {{requiredLength}} Zeichen lang sein.",
"MUST_BE_NUMBER": " muss eine Zahl sein.",
"MUST_SELECT": " muss ausgewählt sein.",
"MAX_VALUE": " darf maximal eine Länge von {0} Zeichen haben.",
Expand Down

0 comments on commit 9ef62c1

Please sign in to comment.