From 61597627c61631052e01adf280d3543b43a49d8a Mon Sep 17 00:00:00 2001 From: Jan Klattenhoff Date: Wed, 15 Jan 2025 14:20:59 +0100 Subject: [PATCH 1/6] feat(qualifikation-form): add qualification form component --- .../qualifikation-form.component.css | 0 .../qualifikation-form.component.html | 1 + .../qualifikation-form.component.spec.ts | 23 +++++++++++++++++++ .../qualifikation-form.component.ts | 12 ++++++++++ 4 files changed, 36 insertions(+) create mode 100644 src/app/components/qualifikation-form/qualifikation-form.component.css create mode 100644 src/app/components/qualifikation-form/qualifikation-form.component.html create mode 100644 src/app/components/qualifikation-form/qualifikation-form.component.spec.ts create mode 100644 src/app/components/qualifikation-form/qualifikation-form.component.ts diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.css b/src/app/components/qualifikation-form/qualifikation-form.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.html b/src/app/components/qualifikation-form/qualifikation-form.component.html new file mode 100644 index 0000000..f8e7cc9 --- /dev/null +++ b/src/app/components/qualifikation-form/qualifikation-form.component.html @@ -0,0 +1 @@ +

qualifikation-form works!

diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.spec.ts b/src/app/components/qualifikation-form/qualifikation-form.component.spec.ts new file mode 100644 index 0000000..3571e98 --- /dev/null +++ b/src/app/components/qualifikation-form/qualifikation-form.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { QualifikationFormComponent } from './qualifikation-form.component'; + +describe('QualifikationFormComponent', () => { + let component: QualifikationFormComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [QualifikationFormComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(QualifikationFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.ts b/src/app/components/qualifikation-form/qualifikation-form.component.ts new file mode 100644 index 0000000..35a62c3 --- /dev/null +++ b/src/app/components/qualifikation-form/qualifikation-form.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-qualifikation-form', + standalone: true, + imports: [], + templateUrl: './qualifikation-form.component.html', + styleUrl: './qualifikation-form.component.css' +}) +export class QualifikationFormComponent { + +} From c11772f08b50af69821498222f0b943279c1fdaf Mon Sep 17 00:00:00 2001 From: Jan Klattenhoff Date: Wed, 15 Jan 2025 15:57:31 +0100 Subject: [PATCH 2/6] feat: add qualification editing functionality and styles --- src/app/app.routes.ts | 3 +- .../qualifikation-form.component.css | 131 ++++++++++++++++++ .../qualifikation-form.component.html | 50 ++++++- .../qualifikation-form.component.ts | 82 ++++++++++- ...qualifikaton-bearbeiten-view.component.css | 131 ------------------ ...ualifikaton-bearbeiten-view.component.html | 37 +---- .../qualifikaton-bearbeiten-view.component.ts | 28 +++- src/app/service/skill.service.ts | 7 +- 8 files changed, 296 insertions(+), 173 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 5fcbcba..c9981e2 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -32,8 +32,9 @@ export const routes: Routes = [ component: EmployeeDetailComponent, }, { - path: "qualifikationbearbeiten", + path: "qualifikationbearbeiten/:id", component: QualifikatonBearbeitenViewComponent, + canActivate: [AuthGuard], }, { path: "**", diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.css b/src/app/components/qualifikation-form/qualifikation-form.component.css index e69de29..886cc52 100644 --- a/src/app/components/qualifikation-form/qualifikation-form.component.css +++ b/src/app/components/qualifikation-form/qualifikation-form.component.css @@ -0,0 +1,131 @@ +body { + font-family: sans-serif; + margin: 0; + padding: 20px; + background-color: #f0f0f0; +} + +.container { + width: 100%; + max-width: 800px; + margin: 0 auto; + padding: 20px; + background-color: #fff; +} + +h1, h2 { + font-size: 1.8rem; + margin-bottom: 15px; +} + +.back-button { + background-color: #ccc; + color: #333; + border: none; + padding: 8px 12px; + border-radius: 3px; + margin-bottom: 15px; +} + +.form-group { + margin-bottom: 15px; +} + +label { + display: block; + margin-bottom: 5px; +} + +input[type="text"] { + width: 100%; + padding: 10px; + border: 1px solid #ccc; + border-radius: 1px; +} + +.employee-list { + list-style: none; + padding: 0; +} + +.employee-list li { + display: flex; + align-items: center; + margin-bottom: 5px; +} + +.employee-icon { + margin-right: 5px; +} + +.add-employee-section { + margin-top: 15px; +} + +.add-employee-section select { + padding: 10px; + border: 1px solid #ddd; + border-radius: 3px; + margin-right: 10px; +} + +.add-employee-button { + background-color: #06a63b; + color: #fff; + padding: 10px 15px; + border: none; + border-radius: 3px; + cursor: pointer; + margin-top: 10px; +} + +.save-button { + background-color: #007bff; + color: #fff; + padding: 10px 15px; + border: none; + border-radius: 3px; + cursor: pointer; + margin-top: 20px; + display: block; + width: 100%; +} + +.delete-skill-button { + color: #fff; + padding: 5px 8px; + border: none; + cursor: pointer; + margin-left: 4px; + margin-right: 4px; + border-radius: 3px; +} + +.delete-skill-button img { + width: 15px; + height: 15px; +} + +.add-employee-section { + margin-top: 15px; +} + +.add-employee-section label { + display: block; + margin-bottom: 5px; + font-weight: bold; +} + +.add-employee-section input[type="text"] { + width: 100%; + padding: 10px; + border: 1px solid #ddd; + border-radius: 3px; +} + +.employee-container { + border: 1px solid #ccc; + padding: 20px; + border-radius: 1px; + margin-bottom: 20px; +} diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.html b/src/app/components/qualifikation-form/qualifikation-form.component.html index f8e7cc9..e1d52d1 100644 --- a/src/app/components/qualifikation-form/qualifikation-form.component.html +++ b/src/app/components/qualifikation-form/qualifikation-form.component.html @@ -1 +1,49 @@ -

qualifikation-form works!

+
+
+ + +
+ + +
+ +
+

Employees possessing the qualification

+ +
    + @for (employee of (employees | async)?.employees; track employee) { + @if (!isEmployeeHidden(employee.id)) { +
  • + + {{employee.firstName}} {{employee.lastName}} +
  • + } + } + @for (employee of addedEmployees | async; track employee) { +
  • + + {{employee.firstName}} {{employee.lastName}} +
  • + } +
+ +
+ + + +
+
+ + +
+
diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.ts b/src/app/components/qualifikation-form/qualifikation-form.component.ts index 35a62c3..27309ca 100644 --- a/src/app/components/qualifikation-form/qualifikation-form.component.ts +++ b/src/app/components/qualifikation-form/qualifikation-form.component.ts @@ -1,12 +1,90 @@ -import { Component } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { EmployeesForAQualificationDTO, QualificationGetDTO } from '../../models/skill'; +import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { SkillService } from '../../service/skill.service'; +import { EmployeeService } from '../../service/employee.service'; +import { Observable, of, tap } from 'rxjs'; +import { EmployeeNameDataDTO, EmployeeResponseDTO } from '../../models/mitarbeiter'; +import { AsyncPipe } from '@angular/common'; @Component({ selector: 'app-qualifikation-form', standalone: true, - imports: [], + imports: [ReactiveFormsModule, AsyncPipe], templateUrl: './qualifikation-form.component.html', styleUrl: './qualifikation-form.component.css' }) export class QualifikationFormComponent { + @Input() skill!: QualificationGetDTO; + @Output() skillChange = new EventEmitter(); + public skillForm!: FormGroup; + public employees: Observable = of(); + public allEmployees: Observable> = of([]); + public hiddenEmployees: Array = []; + public addedEmployees: Observable> = of([]); + public addedEmployeesIds: Array = []; + errorMessages: Record = {}; + + constructor(private skillService: SkillService, private employeeService: EmployeeService) { } + + removeEmployee(id: number) { + this.hiddenEmployees.push(id); + } + + isEmployeeHidden(id: number) { + for (const employeeId of this.hiddenEmployees) { + if (id == employeeId) { + return true + } + } + + return false; + } + + employeeHasSkill(employee: EmployeeResponseDTO) { + + for (const id of this.addedEmployeesIds) { + console.log(id, employee.id); + if (id == employee.id) { + return true; + } + } + + for (const employeeSkill of employee.skillSet || []) { + if (employeeSkill.id == this.skill.id) { + return true; + } + } + + return false; + } + + addEmployee() { + console.log("a"); + const employeeId = this.skillForm.get("newEmployee")?.value; + this.employeeService.getEmployeeById(employeeId).subscribe(employee => { + this.addedEmployees.pipe(tap(employeeList => { + employeeList.push(employee); + this.addedEmployeesIds.push(employee.id); + })).subscribe(); + }); + } + + setUpForm() { + this.skillForm = new FormGroup({ + name: new FormControl(this.skill.skill, Validators.required), + newEmployee: new FormControl(), + }); + } + + ngOnChanges(): void { + this.setUpForm(); + this.employees = this.skillService.getEmployeesBySkill(this.skill.id); + } + + ngOnInit() { + this.setUpForm(); + this.allEmployees = this.employeeService.getAllEmployees(); + } } diff --git a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.css b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.css index 886cc52..e69de29 100644 --- a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.css +++ b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.css @@ -1,131 +0,0 @@ -body { - font-family: sans-serif; - margin: 0; - padding: 20px; - background-color: #f0f0f0; -} - -.container { - width: 100%; - max-width: 800px; - margin: 0 auto; - padding: 20px; - background-color: #fff; -} - -h1, h2 { - font-size: 1.8rem; - margin-bottom: 15px; -} - -.back-button { - background-color: #ccc; - color: #333; - border: none; - padding: 8px 12px; - border-radius: 3px; - margin-bottom: 15px; -} - -.form-group { - margin-bottom: 15px; -} - -label { - display: block; - margin-bottom: 5px; -} - -input[type="text"] { - width: 100%; - padding: 10px; - border: 1px solid #ccc; - border-radius: 1px; -} - -.employee-list { - list-style: none; - padding: 0; -} - -.employee-list li { - display: flex; - align-items: center; - margin-bottom: 5px; -} - -.employee-icon { - margin-right: 5px; -} - -.add-employee-section { - margin-top: 15px; -} - -.add-employee-section select { - padding: 10px; - border: 1px solid #ddd; - border-radius: 3px; - margin-right: 10px; -} - -.add-employee-button { - background-color: #06a63b; - color: #fff; - padding: 10px 15px; - border: none; - border-radius: 3px; - cursor: pointer; - margin-top: 10px; -} - -.save-button { - background-color: #007bff; - color: #fff; - padding: 10px 15px; - border: none; - border-radius: 3px; - cursor: pointer; - margin-top: 20px; - display: block; - width: 100%; -} - -.delete-skill-button { - color: #fff; - padding: 5px 8px; - border: none; - cursor: pointer; - margin-left: 4px; - margin-right: 4px; - border-radius: 3px; -} - -.delete-skill-button img { - width: 15px; - height: 15px; -} - -.add-employee-section { - margin-top: 15px; -} - -.add-employee-section label { - display: block; - margin-bottom: 5px; - font-weight: bold; -} - -.add-employee-section input[type="text"] { - width: 100%; - padding: 10px; - border: 1px solid #ddd; - border-radius: 3px; -} - -.employee-container { - border: 1px solid #ccc; - padding: 20px; - border-radius: 1px; - margin-bottom: 20px; -} diff --git a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.html b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.html index 2370e98..adfe33c 100644 --- a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.html +++ b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.html @@ -1,36 +1 @@ -
- - -
- - -
- -
-

Employees possessing the qualification

- -
    -
  • - - Max Mustermann -
  • -
  • - - Mehdi Boudjoudi -
  • -
- -
- - - -
-
- - -
- + diff --git a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts index ed93e94..ed279c8 100644 --- a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts +++ b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts @@ -1,12 +1,38 @@ import { Component } from '@angular/core'; +import { QualifikationFormComponent } from '../qualifikation-form/qualifikation-form.component'; +import { SkillService } from '../../service/skill.service'; +import { FormGroup } from '@angular/forms'; +import { QualificationGetDTO } from '../../models/skill'; +import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-qualifikaton-bearbeiten-view', standalone: true, - imports: [], + imports: [QualifikationFormComponent], templateUrl: './qualifikaton-bearbeiten-view.component.html', styleUrl: './qualifikaton-bearbeiten-view.component.css' }) export class QualifikatonBearbeitenViewComponent { + public skill!: QualificationGetDTO; + constructor(private skillService: SkillService, private route: ActivatedRoute) {} + + submitted(skill: QualificationGetDTO) { + + } + + ngOnInit(): void { + this.skill = { + id: 0, + skill: '', + }; + + this.skillService.getAllSkills().subscribe(skills => { + for (const skill of skills) { + if (skill.id == Number(this.route.snapshot.params['id'])) { + this.skill = skill; + } + } + }); + } } diff --git a/src/app/service/skill.service.ts b/src/app/service/skill.service.ts index 9f6764b..8b044ef 100644 --- a/src/app/service/skill.service.ts +++ b/src/app/service/skill.service.ts @@ -1,7 +1,8 @@ import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; -import { QualificationGetDTO } from "../models/skill"; +import { EmployeesForAQualificationDTO, QualificationGetDTO } from "../models/skill"; import { Observable } from "rxjs"; +import { EmployeeNameDataDTO } from "../models/mitarbeiter"; @Injectable({ providedIn: 'root' @@ -17,4 +18,8 @@ export class SkillService { getAllSkills(): Observable> { return this.http.get>(`${SkillService.BASE_URL}/qualifications`); } + + getEmployeesBySkill(id: number): Observable { + return this.http.get(`${SkillService.BASE_URL}/qualifications/${id}/employees`); + } } From c9a4b5063f3228ae1dd850f59adaee6b6e15ff30 Mon Sep 17 00:00:00 2001 From: Jan Klattenhoff Date: Wed, 15 Jan 2025 16:29:11 +0100 Subject: [PATCH 3/6] EOD --- .../qualifikation-form/qualifikation-form.component.html | 4 ++++ .../qualifikation-form/qualifikation-form.component.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.html b/src/app/components/qualifikation-form/qualifikation-form.component.html index e1d52d1..d00be94 100644 --- a/src/app/components/qualifikation-form/qualifikation-form.component.html +++ b/src/app/components/qualifikation-form/qualifikation-form.component.html @@ -31,6 +31,7 @@ } +
- @for (employee of allEmployees | async; track employee) { - @if (!employeeHasSkill(employee)) { + @for (employee of addableEmployees; track employee) { } - } - +
+ } diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.ts b/src/app/components/qualifikation-form/qualifikation-form.component.ts index a6f1e82..166d26b 100644 --- a/src/app/components/qualifikation-form/qualifikation-form.component.ts +++ b/src/app/components/qualifikation-form/qualifikation-form.component.ts @@ -19,58 +19,11 @@ export class QualifikationFormComponent { @Output() skillChange = new EventEmitter(); public skillForm!: FormGroup; - public employees: Observable = of(); - public allEmployees: Observable> = of([]); - public hiddenEmployees: Array = []; - public addedEmployees: Observable> = of([]); - public addedEmployeesIds: Array = []; - errorMessages: Record = {}; + public addableEmployees: Array = []; + public addedEmployees: Array = []; constructor(private skillService: SkillService, private employeeService: EmployeeService) { } - removeEmployee(id: number) { - this.hiddenEmployees.push(id); - } - - isEmployeeHidden(id: number) { - for (const employeeId of this.hiddenEmployees) { - if (id == employeeId) { - return true - } - } - - return false; - } - - employeeHasSkill(employee: EmployeeResponseDTO) { - - for (const id of this.addedEmployeesIds) { - console.log(id, employee.id); - if (id == employee.id) { - return true; - } - } - - for (const employeeSkill of employee.skillSet || []) { - if (employeeSkill.id == this.skill.id) { - return true; - } - } - - return false; - } - - addEmployee() { - console.log("a"); - const employeeId = this.skillForm.get("newEmployee")?.value; - this.employeeService.getEmployeeById(employeeId).subscribe(employee => { - this.addedEmployees.pipe(tap(employeeList => { - employeeList.push(employee); - this.addedEmployeesIds.push(employee.id); - })).subscribe(); - }); - } - setUpForm() { this.skillForm = new FormGroup({ name: new FormControl(this.skill.skill, Validators.required), @@ -78,13 +31,54 @@ export class QualifikationFormComponent { }); } + + addEmployee() { + console.log("called"); + const employeeId = Number(this.skillForm.get("newEmployee")?.value); + const employee = this.addableEmployees.find(emp => emp.id === employeeId); + + if (employee) { + this.addableEmployees = this.addableEmployees.filter(emp => emp.id !== employeeId); + + this.addedEmployees.push(employee); + } + } + + removeEmployee(employeeId: number) { + const employee = this.addedEmployees.find(emp => emp.id === employeeId); + + if (employee) { + this.addedEmployees = this.addedEmployees.filter(emp => emp.id !== employeeId); + + this.employeeService.getEmployeeById(employee.id).subscribe(employeeDto => { + this.addableEmployees.push(employeeDto); + }); + } + } + + updateEmployeeLists() { + if (this.skill.id != -1) { + this.employeeService.getAllEmployees().subscribe(employees => { + this.addableEmployees = employees; + + this.skillService.getEmployeesBySkill(this.skill.id).subscribe(addedEmployeesResponse => { + this.addedEmployees = addedEmployeesResponse.employees; + + this.addableEmployees = this.addableEmployees.filter(employee => { + return !this.addedEmployees.some(added => added.id === employee.id); + }); + }); + }); + } + } + ngOnChanges(): void { this.setUpForm(); - this.employees = this.skillService.getEmployeesBySkill(this.skill.id); + this.updateEmployeeLists(); } ngOnInit() { this.setUpForm(); - this.allEmployees = this.employeeService.getAllEmployees(); + this.updateEmployeeLists(); } } diff --git a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts index ed279c8..2ad4759 100644 --- a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts +++ b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts @@ -23,7 +23,7 @@ export class QualifikatonBearbeitenViewComponent { ngOnInit(): void { this.skill = { - id: 0, + id: -1, skill: '', }; From 611962104014082550cfc1b41c4df5723a464c1c Mon Sep 17 00:00:00 2001 From: Jan Klattenhoff Date: Wed, 15 Jan 2025 20:45:17 +0100 Subject: [PATCH 5/6] feat(qualifikation-form): implement submit functionality and navigation --- .../qualifikation-form.component.html | 6 +----- .../qualifikation-form.component.ts | 21 +++++++++++++++++-- .../qualifikaton-bearbeiten-view.component.ts | 2 +- src/app/service/employee.service.ts | 12 ++++++++++- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.html b/src/app/components/qualifikation-form/qualifikation-form.component.html index cdd67ea..933437f 100644 --- a/src/app/components/qualifikation-form/qualifikation-form.component.html +++ b/src/app/components/qualifikation-form/qualifikation-form.component.html @@ -32,11 +32,7 @@ } - - - - - + diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.ts b/src/app/components/qualifikation-form/qualifikation-form.component.ts index 166d26b..da59dec 100644 --- a/src/app/components/qualifikation-form/qualifikation-form.component.ts +++ b/src/app/components/qualifikation-form/qualifikation-form.component.ts @@ -6,6 +6,7 @@ import { EmployeeService } from '../../service/employee.service'; import { concatMap, every, from, lastValueFrom, Observable, of, switchMap, take, tap } from 'rxjs'; import { EmployeeNameDataDTO, EmployeeResponseDTO } from '../../models/mitarbeiter'; import { AsyncPipe } from '@angular/common'; +import { Router } from '@angular/router'; @Component({ selector: 'app-qualifikation-form', @@ -22,7 +23,7 @@ export class QualifikationFormComponent { public addableEmployees: Array = []; public addedEmployees: Array = []; - constructor(private skillService: SkillService, private employeeService: EmployeeService) { } + constructor(private skillService: SkillService, private employeeService: EmployeeService, private router: Router) { } setUpForm() { this.skillForm = new FormGroup({ @@ -33,7 +34,6 @@ export class QualifikationFormComponent { addEmployee() { - console.log("called"); const employeeId = Number(this.skillForm.get("newEmployee")?.value); const employee = this.addableEmployees.find(emp => emp.id === employeeId); @@ -72,6 +72,23 @@ export class QualifikationFormComponent { } } + submit() { + for (const employee of this.addedEmployees) { + this.employeeService.getEmployeeById(employee.id).subscribe(employeeResponse => { + this.employeeService.addSkillToEmployee(this.skill.id, employeeResponse); + }); + } + + for (const employee of this.addableEmployees) { + this.employeeService.removeSkillFromEmployee(this.skill.id, employee); + } + + this.skill.skill = this.skillForm.get("name")?.value; + this.skillChange.emit(this.skill); + + this.router.navigate(["/qualifikationen"]); + } + ngOnChanges(): void { this.setUpForm(); this.updateEmployeeLists(); diff --git a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts index 2ad4759..6e569a8 100644 --- a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts +++ b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts @@ -18,7 +18,7 @@ export class QualifikatonBearbeitenViewComponent { constructor(private skillService: SkillService, private route: ActivatedRoute) {} submitted(skill: QualificationGetDTO) { - + console.log(skill); } ngOnInit(): void { diff --git a/src/app/service/employee.service.ts b/src/app/service/employee.service.ts index 17062f7..caaf5e1 100644 --- a/src/app/service/employee.service.ts +++ b/src/app/service/employee.service.ts @@ -54,10 +54,20 @@ export class EmployeeService { return this.http.get(`${SkillService.BASE_URL}/employees/${id}`); } + removeSkillFromEmployee(skillId: number, employee: EmployeeResponseDTO) { + let employeePut = this.responseDtoToPutDto(employee); + if (employeePut.skillSet.indexOf(skillId) != 1) { + employeePut.skillSet = employeePut.skillSet.filter(skill => skill != skillId); + } + + this.http.put(`${SkillService.BASE_URL}/employees/${employee.id}`, employeePut).subscribe(); + } addSkillToEmployee(skillId: number, employee: EmployeeResponseDTO) { let employeePut = this.responseDtoToPutDto(employee); - employeePut.skillSet.push(skillId); + if (employeePut.skillSet.indexOf(skillId) == -1) { + employeePut.skillSet.push(skillId); + } this.http.put(`${SkillService.BASE_URL}/employees/${employee.id}`, employeePut).subscribe(); } From 703d64479962efcbba2bc81dfc7037eeae122cce Mon Sep 17 00:00:00 2001 From: Jan Klattenhoff Date: Thu, 16 Jan 2025 10:46:27 +0100 Subject: [PATCH 6/6] feat: add error handling for skill form validation --- .../mitarbeiter-form.component.ts | 2 +- .../qualifikation-form.component.html | 3 +++ .../qualifikation-form.component.ts | 25 +++++++++++++++++++ .../qualifikaton-bearbeiten-view.component.ts | 2 +- src/app/service/skill.service.ts | 12 ++++++++- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/app/components/mitarbeiter-form/mitarbeiter-form.component.ts b/src/app/components/mitarbeiter-form/mitarbeiter-form.component.ts index 0e73354..f9ed6af 100644 --- a/src/app/components/mitarbeiter-form/mitarbeiter-form.component.ts +++ b/src/app/components/mitarbeiter-form/mitarbeiter-form.component.ts @@ -104,7 +104,7 @@ export class MitarbeiterFormComponent { Object.keys(this.mitarbeiterForm.controls).forEach(field => { const control = this.mitarbeiterForm.get(field); - if (control && control.errors && control.touched) { + if (control && control.errors) { this.errorMessages[field] = Object.keys(control.errors) .map(errorKey => this.validationErrorMessages[errorKey] || `Unknown error: ${errorKey}`) .join(' '); diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.html b/src/app/components/qualifikation-form/qualifikation-form.component.html index 933437f..a881a16 100644 --- a/src/app/components/qualifikation-form/qualifikation-form.component.html +++ b/src/app/components/qualifikation-form/qualifikation-form.component.html @@ -3,6 +3,9 @@
+ @if (errorMessages['name']) { +
{{errorMessages['name']}}
+ }
diff --git a/src/app/components/qualifikation-form/qualifikation-form.component.ts b/src/app/components/qualifikation-form/qualifikation-form.component.ts index da59dec..608ac05 100644 --- a/src/app/components/qualifikation-form/qualifikation-form.component.ts +++ b/src/app/components/qualifikation-form/qualifikation-form.component.ts @@ -22,9 +22,29 @@ export class QualifikationFormComponent { public skillForm!: FormGroup; public addableEmployees: Array = []; public addedEmployees: Array = []; + errorMessages: Record = {}; + constructor(private skillService: SkillService, private employeeService: EmployeeService, private router: Router) { } + private validationErrorMessages: Record = { + required: "This field is required", + }; + + updateErrorMessages(): void { + this.errorMessages = {}; + + Object.keys(this.skillForm.controls).forEach(field => { + const control = this.skillForm.get(field); + + if (control && control.errors) { + this.errorMessages[field] = Object.keys(control.errors) + .map(errorKey => this.validationErrorMessages[errorKey] || `Unknown error: ${errorKey}`) + .join(' '); + } + }); + } + setUpForm() { this.skillForm = new FormGroup({ name: new FormControl(this.skill.skill, Validators.required), @@ -73,6 +93,11 @@ export class QualifikationFormComponent { } submit() { + this.updateErrorMessages(); + if (!this.skillForm.valid) { + return; + } + for (const employee of this.addedEmployees) { this.employeeService.getEmployeeById(employee.id).subscribe(employeeResponse => { this.employeeService.addSkillToEmployee(this.skill.id, employeeResponse); diff --git a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts index 6e569a8..791b8ec 100644 --- a/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts +++ b/src/app/components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component.ts @@ -18,7 +18,7 @@ export class QualifikatonBearbeitenViewComponent { constructor(private skillService: SkillService, private route: ActivatedRoute) {} submitted(skill: QualificationGetDTO) { - console.log(skill); + this.skillService.updateSkill(skill); } ngOnInit(): void { diff --git a/src/app/service/skill.service.ts b/src/app/service/skill.service.ts index 8b044ef..9e0beb1 100644 --- a/src/app/service/skill.service.ts +++ b/src/app/service/skill.service.ts @@ -1,6 +1,6 @@ import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; -import { EmployeesForAQualificationDTO, QualificationGetDTO } from "../models/skill"; +import { EmployeesForAQualificationDTO, QualificationGetDTO, QualificationPostDTO } from "../models/skill"; import { Observable } from "rxjs"; import { EmployeeNameDataDTO } from "../models/mitarbeiter"; @@ -11,10 +11,20 @@ export class SkillService { public static readonly BASE_URL = "http://localhost:8089"; + getToPutDto(skill: QualificationGetDTO): QualificationPostDTO { + return { + skill: skill.skill, + } + } + constructor(private http: HttpClient) { } + updateSkill(skill: QualificationGetDTO) { + this.http.put(`${SkillService.BASE_URL}/qualifications/${skill.id}`, this.getToPutDto(skill)).subscribe(); + } + getAllSkills(): Observable> { return this.http.get>(`${SkillService.BASE_URL}/qualifications`); }