diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html index d3d39a71ceb69e639c38e1ac0219f27eb1c5e6f5..f5d4c159162d6dd81451835562b0565181092687 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html @@ -35,7 +35,13 @@ <div [formGroupName]="UserFormService.ALFA_GROUP" class="flex flex-1 flex-col gap-2"> <h3 class="text-md block font-medium text-text">Alfa</h3> <div class="flex items-center gap-2"> - <ods-checkbox-editor [formControlName]="UserFormService.LOESCHEN" label="Löschen" inputId="delete" /> + <ods-checkbox-editor + [formControlName]="UserFormService.LOESCHEN" + (inputChange)="updateOtherAlfaCheckboxes(UserFormService.LOESCHEN, $event)" + label="Löschen" + inputId="delete" + data-test-id="checkbox-loeschen" + /> <button data-test-id="loschen-role-info-button" tooltip='Diese Rolle hat dieselben Rechte wie die Rolle "User". Zusätzlich kann "Löschen" Löschanträge aus Alfa bestätigen. ' @@ -44,7 +50,13 @@ </button> </div> <div class="flex items-center gap-2"> - <ods-checkbox-editor [formControlName]="UserFormService.USER" label="User" inputId="user" /> + <ods-checkbox-editor + [formControlName]="UserFormService.USER" + (inputChange)="updateOtherAlfaCheckboxes(UserFormService.USER, $event)" + label="User" + inputId="user" + data-test-id="checkbox-user" + /> <button data-test-id="user-role-info-button" tooltip="Diese Rolle kann alle Vorgänge sehen und bearbeiten, wenn diese seiner Organisationseinheit zugewiesen sind." @@ -53,7 +65,13 @@ </button> </div> <div class="flex items-center gap-2"> - <ods-checkbox-editor [formControlName]="UserFormService.POSTSTELLE" label="Poststelle" inputId="post_office" /> + <ods-checkbox-editor + [formControlName]="UserFormService.POSTSTELLE" + (inputChange)="updateOtherAlfaCheckboxes(UserFormService.POSTSTELLE, $event)" + label="Poststelle" + inputId="post_office" + data-test-id="checkbox-poststelle" + /> <button data-test-id="poststelle-role-info-button" tooltip="Diese Rolle kann alle neu eingegangenen Vorgänge sehen."> <ods-info-icon /> </button> diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.spec.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.spec.ts index 5f21edb7a5722e98bd9a0069b3dcb3f9ce8ad10a..dcb15e84da62fcc6809e768d8a537cd1792e0e9c 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.spec.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.spec.ts @@ -1,5 +1,5 @@ import { InvalidParam } from '@alfa-client/tech-shared'; -import { existsAsHtmlElement, getElementComponentFromFixtureByCss } from '@alfa-client/test-utils'; +import { existsAsHtmlElement, getElementComponentFromFixtureByCss, mock, Mock, triggerEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AbstractControl, FormControl, ReactiveFormsModule, UntypedFormGroup } from '@angular/forms'; import { expect } from '@jest/globals'; @@ -19,9 +19,14 @@ describe('UserFormRolesComponent', () => { const validationErrorTestId: string = getDataTestIdOf('rollen-error'); + let formService: Mock<UserFormService>; + beforeEach(async () => { + formService = mock(UserFormService); + await TestBed.configureTestingModule({ imports: [UserFormRolesComponent, ReactiveFormsModule, MockComponent(InfoIconComponent), MockDirective(TooltipDirective)], + providers: [{ provide: UserFormService, useValue: formService }], }).compileComponents(); fixture = TestBed.createComponent(UserFormRolesComponent); @@ -91,6 +96,17 @@ describe('UserFormRolesComponent', () => { control.setErrors(null); }); }); + + describe('update all other alfa checkboxes', () => { + it('should call form service updateAlfaCheckboxes', () => { + const formControlName: string = 'dummy'; + const value: boolean = true; + + component.updateOtherAlfaCheckboxes(formControlName, value); + + expect(formService.updateAlfaCheckboxes).toHaveBeenCalledWith(formControlName, value); + }); + }); }); describe('template', () => { @@ -112,5 +128,50 @@ describe('UserFormRolesComponent', () => { expect(validationErrorComponent.invalidParams).toEqual([invalidParam]); }); }); + + describe('checkbox loeschen', () => { + it('should call updateOtherAlfaCheckboxes on inputChange emit', () => { + component.updateOtherAlfaCheckboxes = jest.fn(); + + triggerEvent({ + fixture, + elementSelector: getDataTestIdOf('checkbox-loeschen'), + name: 'inputChange', + data: true, + }); + + expect(component.updateOtherAlfaCheckboxes).toHaveBeenCalledWith(UserFormService.LOESCHEN, true); + }); + }); + + describe('checkbox user', () => { + it('should call updateOtherAlfaCheckboxes on inputChange emit', () => { + component.updateOtherAlfaCheckboxes = jest.fn(); + + triggerEvent({ + fixture, + elementSelector: getDataTestIdOf('checkbox-user'), + name: 'inputChange', + data: true, + }); + + expect(component.updateOtherAlfaCheckboxes).toHaveBeenCalledWith(UserFormService.USER, true); + }); + }); + + describe('checkbox poststelle', () => { + it('should call updateOtherAlfaCheckboxes on inputChange emit', () => { + component.updateOtherAlfaCheckboxes = jest.fn(); + + triggerEvent({ + fixture, + elementSelector: getDataTestIdOf('checkbox-poststelle'), + name: 'inputChange', + data: true, + }); + + expect(component.updateOtherAlfaCheckboxes).toHaveBeenCalledWith(UserFormService.POSTSTELLE, true); + }); + }); }); }); diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.ts index 7a8c901dab035b8a8364b9ce60c1453a7374711c..9de8f65744c7e9edf0902296732e9f8e05aff0cc 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.ts @@ -1,6 +1,6 @@ import { generateValidationErrorId, InvalidParam } from '@alfa-client/tech-shared'; import { AsyncPipe } from '@angular/common'; -import { Component, Input, OnInit } from '@angular/core'; +import { Component, inject, Input, OnInit } from '@angular/core'; import { AbstractControl, FormControlStatus, ReactiveFormsModule, UntypedFormGroup } from '@angular/forms'; import { CheckboxEditorComponent, ValidationErrorComponent } from '@ods/component'; import { InfoIconComponent, TooltipDirective } from '@ods/system'; @@ -22,6 +22,8 @@ import { UserFormService } from '../user.formservice'; templateUrl: './user-form-roles.component.html', }) export class UserFormRolesComponent implements OnInit { + public readonly formService = inject(UserFormService); + @Input() formGroupParent: UntypedFormGroup; public invalidParams$: Observable<InvalidParam[]> = of([]); @@ -37,4 +39,8 @@ export class UserFormRolesComponent implements OnInit { tap((invalidParams: InvalidParam[]) => (this.isValid = isEmpty(invalidParams))), ); } + + updateOtherAlfaCheckboxes(formControlName: string, value: boolean) { + this.formService.updateAlfaCheckboxes(formControlName, value); + } } diff --git a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.html b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.html index 1cc8b07470d8086854cee7b310342c8697b4eed5..cf21692584c4ef6d986a494166f22ae5cb894328 100644 --- a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.html +++ b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.html @@ -30,6 +30,7 @@ [disabled]="control.disabled" [hasError]="hasError" [ariaDescribedBy]="validationErrorId" + (inputChange)="inputChange.emit($event)" > <ods-validation-error error diff --git a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts index cada7efb7a5dc25e643c2854438cd39f626f70a9..1b06d47d14d99aa302c659974f0c227d59d0905b 100644 --- a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts +++ b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { getElementFromFixture } from '@alfa-client/test-utils'; +import { getElementFromFixture, triggerEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { faker } from '@faker-js/faker'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; @@ -91,4 +91,19 @@ describe('CheckboxEditorComponent', () => { }); }); }); + + describe('input change', () => { + it('should emit input change', () => { + component.inputChange.emit = jest.fn(); + + triggerEvent({ + fixture, + elementSelector: 'ods-checkbox', + name: 'inputChange', + data: true, + }); + + expect(component.inputChange.emit).toHaveBeenCalledWith(true); + }); + }); }); diff --git a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.ts b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.ts index bbb9f693fc54a9760f0bb33b006848b12aba6554..0a098c993e31075992c2716acf82a6bd5a507f17 100644 --- a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.ts +++ b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.ts @@ -22,7 +22,7 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { ConvertForDataTestPipe, generateValidationErrorId } from '@alfa-client/tech-shared'; -import { Component, Input } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { CheckboxComponent } from '@ods/system'; import { FormControlEditorAbstractComponent } from '../formcontrol-editor.abstract.component'; @@ -38,6 +38,8 @@ export class CheckboxEditorComponent extends FormControlEditorAbstractComponent @Input() inputId: string; @Input() label: string; + @Output() inputChange = new EventEmitter<boolean>(); + public readonly validationErrorId: string = generateValidationErrorId(); get hasError(): boolean { diff --git a/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.spec.ts b/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.spec.ts index 508b08e5d85ee35f3ae3215b0a2229f5b416aa6c..f37e2213f3b4d85af20b2e02a509df7ce197125d 100644 --- a/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.spec.ts +++ b/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.spec.ts @@ -21,6 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { triggerEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { CheckboxComponent } from './checkbox.component'; @@ -41,4 +42,17 @@ describe('CheckboxComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should emit input change', () => { + component.inputChange.emit = jest.fn(); + + triggerEvent({ + fixture, + elementSelector: 'input', + name: 'change', + data: { target: { checked: true } }, + }); + + expect(component.inputChange.emit).toHaveBeenCalledWith(true); + }); }); diff --git a/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.ts b/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.ts index 3b3750bd3174bfaeecf2821d4dc29d9e5c6a4d4e..a90820605becdbb48e9ce846cb712b562c5857b6 100644 --- a/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.ts +++ b/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.ts @@ -23,7 +23,7 @@ */ import { ConvertForDataTestPipe, EMPTY_STRING } from '@alfa-client/tech-shared'; import { CommonModule } from '@angular/common'; -import { Component, Input } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; @Component({ @@ -46,6 +46,7 @@ import { FormControl, ReactiveFormsModule } from '@angular/forms'; [attr.disabled]="disabled ? true : null" [attr.data-test-id]="(label | convertForDataTest) + '-checkbox-editor'" [attr.aria-describedby]="ariaDescribedBy" + (change)="inputChangeHandler($event)" /> <label class="leading-5 text-text" [attr.for]="inputId">{{ label }}</label> <svg @@ -71,4 +72,10 @@ export class CheckboxComponent { @Input() disabled: boolean = false; @Input() hasError: boolean = false; @Input() ariaDescribedBy: string = EMPTY_STRING; + + @Output() inputChange = new EventEmitter<boolean>(); + + inputChangeHandler(event: Event) { + this.inputChange.emit((event.target as HTMLInputElement).checked); + } }