From c938ef84657f2904cd6fb150d4960d35be1b87fb Mon Sep 17 00:00:00 2001 From: Huy Date: Wed, 8 Jan 2025 11:25:32 +0000 Subject: [PATCH] Implement editing qualifications (#20) Co-authored-by: Phan Huy Tran Reviewed-on: https://git.simonis.lol/angular/ems-frontend/pulls/20 Reviewed-by: Constantin Simonis --- src/app/Qualification.ts | 2 +- .../edit-qualification.component.css | 0 .../edit-qualification.component.html | 24 ++++++ .../edit-qualification.component.ts | 84 +++++++++++++++++++ .../qualifications.component.html | 57 ++++++++----- .../qualifications.component.ts | 22 ++++- src/app/services/qualification.service.ts | 11 ++- 7 files changed, 174 insertions(+), 26 deletions(-) create mode 100644 src/app/edit-qualification/edit-qualification.component.css create mode 100644 src/app/edit-qualification/edit-qualification.component.html create mode 100644 src/app/edit-qualification/edit-qualification.component.ts diff --git a/src/app/Qualification.ts b/src/app/Qualification.ts index d31bd5e..b71d662 100644 --- a/src/app/Qualification.ts +++ b/src/app/Qualification.ts @@ -1,4 +1,4 @@ export class Qualification { - constructor(public skill?: string) { + constructor(public id: number, public skill?: string) { } } diff --git a/src/app/edit-qualification/edit-qualification.component.css b/src/app/edit-qualification/edit-qualification.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/edit-qualification/edit-qualification.component.html b/src/app/edit-qualification/edit-qualification.component.html new file mode 100644 index 0000000..29a10a7 --- /dev/null +++ b/src/app/edit-qualification/edit-qualification.component.html @@ -0,0 +1,24 @@ +

Edit Qualification

+ +
+
+ @if (apiErrorMessage) { + {{ apiErrorMessage }} + } + + + Skill + + + {{ getErrorMessage('skill') }} + + + + + + +
+
+
diff --git a/src/app/edit-qualification/edit-qualification.component.ts b/src/app/edit-qualification/edit-qualification.component.ts new file mode 100644 index 0000000..71d7380 --- /dev/null +++ b/src/app/edit-qualification/edit-qualification.component.ts @@ -0,0 +1,84 @@ +import {Component, inject} from '@angular/core'; +import {FormBuilder, FormsModule, ReactiveFormsModule, Validators} from "@angular/forms"; +import QualificationService from "../services/qualification.service"; +import { + MAT_DIALOG_DATA, + MatDialogActions, + MatDialogContent, + MatDialogRef, + MatDialogTitle +} from "@angular/material/dialog"; +import {MatButton} from "@angular/material/button"; +import {MatError, MatFormField, MatLabel} from "@angular/material/form-field"; +import {MatInput} from "@angular/material/input"; +import {NgIf} from "@angular/common"; +import {Qualification} from "../Qualification"; + +@Component({ + selector: 'app-edit-qualification', + imports: [ + FormsModule, + MatButton, + MatDialogActions, + MatDialogContent, + MatDialogTitle, + MatError, + MatFormField, + MatInput, + MatLabel, + NgIf, + ReactiveFormsModule + ], + templateUrl: './edit-qualification.component.html', + styleUrl: './edit-qualification.component.css' +}) +export class EditQualificationComponent { + public apiErrorMessage: string = ''; + public qualification: Qualification = inject(MAT_DIALOG_DATA); + + private formBuilder: FormBuilder = inject(FormBuilder); + private qualificationService: QualificationService = inject(QualificationService); + private dialogRef: MatDialogRef = inject(MatDialogRef); + + qualificationForm = this.formBuilder.group({ + 'skill': [this.qualification.skill, Validators.required], + }); + + isFieldInvalid(fieldName: string): boolean { + const field = this.qualificationForm.get(fieldName); + + if (!field) { + throw new Error('Form field does not exist: ' + fieldName) + } + + return field.invalid && (field.dirty || field.touched); + } + + getErrorMessage(fieldName: string): string { + const field = this.qualificationForm.get(fieldName); + + if (field?.errors?.['required']) { + return 'This field is required'; + } + + return ''; + } + + edit() { + if (!this.qualificationForm.valid) { + console.error('Validation failed'); + return; + } + + this.qualificationService.edit(this.qualification.id, this.qualificationForm.value).subscribe({ + next: (createdQualification) => { + this.dialogRef.close(createdQualification); + }, + error: (error) => { + console.error('Error creating qualification:', error); + + this.apiErrorMessage = 'API Error'; + } + }); + } +} diff --git a/src/app/qualifications/qualifications.component.html b/src/app/qualifications/qualifications.component.html index f0f7005..7e9d758 100644 --- a/src/app/qualifications/qualifications.component.html +++ b/src/app/qualifications/qualifications.component.html @@ -1,25 +1,42 @@ -

Qualifications

- +
+

Qualifications

+ +
@if (qualifications$ | async; as qualifications) { - @if (qualifications) { - - - - - + @if (qualifications) { +
Skill{{ qualification.skill }}
+ + + + - - - - + + + + - - -
ID{{ qualification.id }}ActionsSkill{{ qualification.skill }}
- } + + Actions + + + + + + + + + + } } diff --git a/src/app/qualifications/qualifications.component.ts b/src/app/qualifications/qualifications.component.ts index 1e9650c..c075121 100644 --- a/src/app/qualifications/qualifications.component.ts +++ b/src/app/qualifications/qualifications.component.ts @@ -14,6 +14,9 @@ import { import QualificationService from "../services/qualification.service"; import {MatDialog} from "@angular/material/dialog"; import {CreateQualificationComponent} from "../create-qualification/create-qualification.component"; +import {MatIcon} from "@angular/material/icon"; +import {MatButton, MatIconButton} from "@angular/material/button"; +import {EditQualificationComponent} from "../edit-qualification/edit-qualification.component"; @Component({ selector: 'app-qualifications', @@ -28,14 +31,17 @@ import {CreateQualificationComponent} from "../create-qualification/create-quali MatHeaderCellDef, MatCellDef, MatHeaderRowDef, - MatRowDef + MatRowDef, + MatIcon, + MatIconButton, + MatButton ], templateUrl: './qualifications.component.html', styleUrl: './qualifications.component.css' }) export class QualificationsComponent implements OnInit{ public qualifications$!: Observable; - public readonly displayedColumns: string[] = ['skill', 'actions']; + public readonly displayedColumns: string[] = ['id', 'skill', 'actions']; private readonly dialog: MatDialog = inject(MatDialog); private readonly qualificationService: QualificationService = inject(QualificationService); @@ -57,4 +63,16 @@ export class QualificationsComponent implements OnInit{ } }); } + + openEditModal(qualification: Qualification) { + const dialogRef = this.dialog.open(EditQualificationComponent, { + data: qualification + }); + + dialogRef.afterClosed().subscribe(result => { + if (result) { + this.loadQualifications(); + } + }); + } } diff --git a/src/app/services/qualification.service.ts b/src/app/services/qualification.service.ts index 752c7ec..50f947b 100644 --- a/src/app/services/qualification.service.ts +++ b/src/app/services/qualification.service.ts @@ -1,7 +1,6 @@ import {inject, Injectable} from "@angular/core"; import {HttpClient} from "@angular/common/http"; -import {Observable} from "rxjs"; -import {Employee} from "../Employee"; +import {map, Observable} from "rxjs"; import {Qualification} from "../Qualification"; @@ -14,10 +13,16 @@ export default class QualificationService { private static readonly BASE_URL = 'http://localhost:8089'; public getAll(): Observable { - return this.http.get(`${QualificationService.BASE_URL}/qualifications`) + return this.http.get(`${QualificationService.BASE_URL}/qualifications`).pipe( + map(qualifications => qualifications.sort((a, b) => a.id - b.id)) + ) } public create(data: any) { return this.http.post(`${QualificationService.BASE_URL}/qualifications`, data) } + + public edit(id: number, data: any) { + return this.http.put(`${QualificationService.BASE_URL}/qualifications/${id}`, data) + } }