diff --git a/alfa-client/apps/demo/src/app/app.component.ts b/alfa-client/apps/demo/src/app/app.component.ts index 5e26d7aa7ffcf45c1908da08fed80ccd1ea71f81..fbd58a87093ed57b19c83b1e1c78151e75ca1b66 100644 --- a/alfa-client/apps/demo/src/app/app.component.ts +++ b/alfa-client/apps/demo/src/app/app.component.ts @@ -16,6 +16,7 @@ import { FileIconComponent, FileUploadButtonComponent, InstantSearchComponent, + OfficeIconComponent, RadioButtonCardComponent, SaveIconComponent, SendIconComponent, @@ -54,6 +55,7 @@ import { CustomStepperComponent } from './components/cdk-demo/custom-stepper.com RadioButtonCardComponent, ReactiveFormsModule, InstantSearchComponent, + OfficeIconComponent, SaveIconComponent, SendIconComponent, StampIconComponent, diff --git a/alfa-client/libs/collaboration-shared/src/lib/organisations-einheit.service.spec.ts b/alfa-client/libs/collaboration-shared/src/lib/organisations-einheit.service.spec.ts index ba19de13fb1d851f885e9c0a4cc9b2cb0f97cec3..b1d9a7a6511203304b7367a91df208012eaf3070 100644 --- a/alfa-client/libs/collaboration-shared/src/lib/organisations-einheit.service.spec.ts +++ b/alfa-client/libs/collaboration-shared/src/lib/organisations-einheit.service.spec.ts @@ -1,10 +1,17 @@ import { StateResource, createStateResource } from '@alfa-client/tech-shared'; import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import faker from '@faker-js/faker'; -import { of } from 'rxjs'; -import { createOrganisationsEinheitListResource } from '../../test/organisations-einheit'; +import { Observable, of } from 'rxjs'; +import { singleColdCompleted } from '../../../tech-shared/test/marbles'; +import { + createOrganisationsEinheitListResource, + createOrganisationsEinheitResource, +} from '../../test/organisations-einheit'; import { OrganisationsEinheitResourceSearchService } from './organisations-einheit-resource-search.service'; -import { OrganisationsEinheitListResource } from './organisations-einheit.model'; +import { + OrganisationsEinheitListResource, + OrganisationsEinheitResource, +} from './organisations-einheit.model'; import { OrganisationsEinheitService } from './organisations-einheit.service'; jest.mock('./organisations-einheit-resource-search.service'); @@ -60,4 +67,39 @@ describe('OrganisationsEinheitService', () => { expect(searchService.clearResultList).toHaveBeenCalledWith(); }); }); + + describe('get selected result', () => { + const organisationsEinheitStateResource: StateResource<OrganisationsEinheitResource> = + createStateResource(createOrganisationsEinheitResource()); + + beforeEach(() => { + searchService.getSelectedResult.mockReturnValue(of(organisationsEinheitStateResource)); + }); + + it('should call service', () => { + service.getSelectedResult(); + + expect(searchService.getSelectedResult).toHaveBeenCalled(); + }); + + it('should return result', () => { + const selectedResult$: Observable<StateResource<OrganisationsEinheitResource>> = + service.getSelectedResult(); + + expect(selectedResult$).toBeObservable( + singleColdCompleted(organisationsEinheitStateResource), + ); + }); + }); + + describe('select search result', () => { + const organisationsEinheitResource: OrganisationsEinheitResource = + createOrganisationsEinheitResource(); + + it('should call service', () => { + service.selectSearchResult(organisationsEinheitResource); + + expect(searchService.selectResult).toHaveBeenCalledWith(organisationsEinheitResource); + }); + }); }); diff --git a/alfa-client/libs/collaboration-shared/src/lib/organisations-einheit.service.ts b/alfa-client/libs/collaboration-shared/src/lib/organisations-einheit.service.ts index 78d83f788d6902f3b562ad2a4fac42f6c03b889d..64e7ad7d286c23556b3a5fbfa305dfc4bea06d86 100644 --- a/alfa-client/libs/collaboration-shared/src/lib/organisations-einheit.service.ts +++ b/alfa-client/libs/collaboration-shared/src/lib/organisations-einheit.service.ts @@ -2,7 +2,10 @@ import { StateResource } from '@alfa-client/tech-shared'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { OrganisationsEinheitResourceSearchService } from './organisations-einheit-resource-search.service'; -import { OrganisationsEinheitListResource } from './organisations-einheit.model'; +import { + OrganisationsEinheitListResource, + OrganisationsEinheitResource, +} from './organisations-einheit.model'; @Injectable() export class OrganisationsEinheitService { @@ -19,4 +22,12 @@ export class OrganisationsEinheitService { public clearSearchResult(): void { this.searchService.clearResultList(); } + + public getSelectedResult(): Observable<StateResource<OrganisationsEinheitResource>> { + return this.searchService.getSelectedResult(); + } + + public selectSearchResult(organisationsEinheitResource: OrganisationsEinheitResource): void { + this.searchService.selectResult(organisationsEinheitResource); + } } diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.html b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.html index f885f5dd33cd4b9fbff5a2ef0deea90831537ac7..f27618ee6c09178f91b15400a43babd3d4088d6a 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.html +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.html @@ -10,8 +10,8 @@ </ng-template> <ng-container *ngIf="isRequestFormVisible$ | async; else anfrageErstellenButton"> - <alfa-collaboration-request-container - data-test-id="collaboration-request-container" - (hideRequestForm)="hideRequestForm()" - ></alfa-collaboration-request-container> + <alfa-collaboration-request-form + data-test-id="collaboration-request-form" + (hide)="hideRequestForm()" + ></alfa-collaboration-request-form> </ng-container> diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.spec.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.spec.ts index d5814a551c15475c3a9b9ca7923dec353a5461d2..cf09233c2433ac766cbc1b600069666d836013b5 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.spec.ts +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.spec.ts @@ -12,14 +12,14 @@ import { getDataTestIdAttributeOf, getDataTestIdOf } from 'libs/tech-shared/test import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; import { CollaborationInVorgangContainerComponent } from './collaboration-in-vorgang-container.component'; -import { CollaborationRequestContainerComponent } from './collaboration-request-container/collaboration-request-container.component'; +import { CollaborationRequestFormComponent } from './collaboration-request-form/collaboration-request-form.component'; describe('CollaborationInVorgangContainerComponent', () => { let component: CollaborationInVorgangContainerComponent; let fixture: ComponentFixture<CollaborationInVorgangContainerComponent>; const anfrageErstellenButton: string = getDataTestIdAttributeOf('anfrage-erstellen-button'); - const collaborationRequestContainer: string = getDataTestIdOf('collaboration-request-container'); + const collaborationRequestForm: string = getDataTestIdOf('collaboration-request-form'); const service: Mock<CollaborationService> = { ...mock(CollaborationService), @@ -31,7 +31,7 @@ describe('CollaborationInVorgangContainerComponent', () => { declarations: [ CollaborationInVorgangContainerComponent, MockComponent(ButtonComponent), - MockComponent(CollaborationRequestContainerComponent), + MockComponent(CollaborationRequestFormComponent), MockComponent(CollaborationIconComponent), ], providers: [ @@ -97,13 +97,13 @@ describe('CollaborationInVorgangContainerComponent', () => { it('should be shown', () => { fixture.detectChanges(); - existsAsHtmlElement(fixture, collaborationRequestContainer); + existsAsHtmlElement(fixture, collaborationRequestForm); }); it('should call service on hideFormular output', () => { fixture.detectChanges(); - dispatchEventFromFixture(fixture, collaborationRequestContainer, 'hideRequestForm'); + dispatchEventFromFixture(fixture, collaborationRequestForm, 'hide'); expect(service.hideRequestForm).toHaveBeenCalled(); }); @@ -114,7 +114,7 @@ describe('CollaborationInVorgangContainerComponent', () => { fixture.detectChanges(); - notExistsAsHtmlElement(fixture, collaborationRequestContainer); + notExistsAsHtmlElement(fixture, collaborationRequestForm); }); }); }); diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component.html b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component.html deleted file mode 100644 index fc5a9bdaac4d763e39bfd519a350fd0f8366a9d2..0000000000000000000000000000000000000000 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component.html +++ /dev/null @@ -1,15 +0,0 @@ -<div class="my-6"> - <alfa-collaboration-request-form></alfa-collaboration-request-form> -</div> - -<div class="flex items-center gap-6"> - <ods-button text="Zuarbeit anfragen" dataTestId="collaboration-request-send-button"></ods-button> - <ods-button - variant="outline" - text="Abbrechen" - dataTestId="collaboration-request-cancel-button" - (clickEmitter)="hideRequestForm.emit()" - > - <ods-close-icon icon class="fill-primary"></ods-close-icon> - </ods-button> -</div> diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component.spec.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component.spec.ts deleted file mode 100644 index 1b299e0a115db133a3fd5195126398ef3c1c990d..0000000000000000000000000000000000000000 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component.spec.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { dispatchEventFromFixture } from '@alfa-client/test-utils'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ButtonComponent, CloseIconComponent } from '@ods/system'; -import { getDataTestIdAttributeOf } from 'libs/tech-shared/test/data-test'; -import { MockComponent } from 'ng-mocks'; -import { CollaborationRequestContainerComponent } from './collaboration-request-container.component'; -import { CollaborationRequestFormComponent } from './collaboration-request-form/collaboration-request-form.component'; - -describe('CollaborationRequestContainerComponent', () => { - let component: CollaborationRequestContainerComponent; - let fixture: ComponentFixture<CollaborationRequestContainerComponent>; - - const cancelButton: string = getDataTestIdAttributeOf('collaboration-request-cancel-button'); - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - CollaborationRequestContainerComponent, - MockComponent(ButtonComponent), - MockComponent(CloseIconComponent), - MockComponent(CollaborationRequestFormComponent), - ], - }).compileComponents(); - - fixture = TestBed.createComponent(CollaborationRequestContainerComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('cancel button', () => { - it('should emit hideRequestForm', () => { - const emitSpy: jest.SpyInstance = (component.hideRequestForm.emit = jest.fn()); - - dispatchEventFromFixture(fixture, cancelButton, 'clickEmitter'); - - expect(emitSpy).toHaveBeenCalled(); - }); - }); -}); diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component.ts deleted file mode 100644 index e8fa92a4ccb8f6745c556cce327ba4735f87e655..0000000000000000000000000000000000000000 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Component, EventEmitter, Output } from '@angular/core'; - -@Component({ - selector: 'alfa-collaboration-request-container', - templateUrl: './collaboration-request-container.component.html', -}) -export class CollaborationRequestContainerComponent { - @Output() public hideRequestForm: EventEmitter<void> = new EventEmitter<void>(); -} diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component.html b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component.html deleted file mode 100644 index 4ec3871317691230a820fb47413f1e5c771d0805..0000000000000000000000000000000000000000 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component.html +++ /dev/null @@ -1,15 +0,0 @@ -<div class="mb-6"> - <alfa-organisations-einheit-in-collaboration-container></alfa-organisations-einheit-in-collaboration-container> -</div> -<form [formGroup]="formService.form" class="flex flex-col gap-2"> - <ods-text-editor - label="Titel" - [formControlName]="formServiceClass.FIELD_TITLE" - [isRequired]="true" - ></ods-text-editor> - <ods-textarea-editor - label="Nachricht" - [formControlName]="formServiceClass.FIELD_NACHRICHT" - [isRequired]="true" - ></ods-textarea-editor> -</form> diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration.request.formservice.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration.request.formservice.ts deleted file mode 100644 index 2cb39040c5fdd34ae2d77138aba820a89ae4e17c..0000000000000000000000000000000000000000 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration.request.formservice.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { CommandResource } from '@alfa-client/command-shared'; -import { AbstractFormService, EMPTY_STRING, StateResource } from '@alfa-client/tech-shared'; -import { Injectable } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; -import { Observable, of } from 'rxjs'; - -@Injectable() -export class CollaborationRequestFormService extends AbstractFormService { - public static readonly FIELD_TITLE = 'titel'; - public static readonly FIELD_NACHRICHT = 'nachricht'; - - constructor(formBuilder: UntypedFormBuilder) { - super(formBuilder); - } - - protected initForm(): UntypedFormGroup { - return this.formBuilder.group({ - [CollaborationRequestFormService.FIELD_TITLE]: new UntypedFormControl(null), - [CollaborationRequestFormService.FIELD_NACHRICHT]: new UntypedFormControl(null), - }); - } - - protected doSubmit(): Observable<StateResource<CommandResource>> { - return of(); - } - - protected getPathPrefix(): string { - return EMPTY_STRING; - } -} diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component.html b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component.html new file mode 100644 index 0000000000000000000000000000000000000000..d2cb5eb2d470b1275c22300d5440f78d5465c5ed --- /dev/null +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component.html @@ -0,0 +1,32 @@ +<alfa-organisations-einheit-container + [fieldControl]="formService.form.controls.organisationseinheit" +></alfa-organisations-einheit-container> + +<form [formGroup]="formService.form" class="mt-4 flex flex-col gap-2"> + <ods-text-editor + label="Titel" + [formControlName]="formServiceClass.FIELD_TITLE" + [isRequired]="true" + ></ods-text-editor> + <ods-textarea-editor + label="Nachricht" + [formControlName]="formServiceClass.FIELD_NACHRICHT" + [isRequired]="true" + ></ods-textarea-editor> +</form> + +<div class="mt-4 flex items-center gap-6"> + <ods-button + text="Zuarbeit anfragen" + dataTestId="collaboration-request-send-button" + (clickEmitter)="formService.submit()" + ></ods-button> + <ods-button + variant="outline" + text="Abbrechen" + dataTestId="collaboration-request-cancel-button" + (clickEmitter)="hide.emit()" + > + <ods-close-icon icon class="fill-primary"></ods-close-icon> + </ods-button> +</div> diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component.spec.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component.spec.ts similarity index 53% rename from alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component.spec.ts rename to alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component.spec.ts index ca5d83441f78b2666e48f8452d2476b5f0755666..e9d674ae5d0d85b070adaac2278b30d66927cb6a 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component.spec.ts +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component.spec.ts @@ -1,26 +1,34 @@ -import { Mock, mock } from '@alfa-client/test-utils'; +import { dispatchEventFromFixture } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; +import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { TextEditorComponent, TextareaEditorComponent } from '@ods/component'; +import { ButtonComponent, CloseIconComponent } from '@ods/system'; +import { getDataTestIdAttributeOf } from 'libs/tech-shared/test/data-test'; import { MockComponent } from 'ng-mocks'; -import { OrganisationsEinheitInCollaborationContainerComponent } from '../../../organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component'; import { CollaborationRequestFormComponent } from './collaboration-request-form.component'; import { CollaborationRequestFormService } from './collaboration.request.formservice'; +import { OrganisationsEinheitContainerComponent } from './organisations-einheit-container/organisations-einheit-container.component'; describe('CollaborationRequestFormComponent', () => { let component: CollaborationRequestFormComponent; let fixture: ComponentFixture<CollaborationRequestFormComponent>; - const formService: Mock<CollaborationRequestFormService> = mock(CollaborationRequestFormService); + const cancelButton: string = getDataTestIdAttributeOf('collaboration-request-cancel-button'); + + const formService: CollaborationRequestFormService = new CollaborationRequestFormService( + new FormBuilder(), + ); beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ReactiveFormsModule], declarations: [ CollaborationRequestFormComponent, + MockComponent(ButtonComponent), + MockComponent(CloseIconComponent), MockComponent(TextEditorComponent), MockComponent(TextareaEditorComponent), - MockComponent(OrganisationsEinheitInCollaborationContainerComponent), + MockComponent(OrganisationsEinheitContainerComponent), ], providers: [ { @@ -38,4 +46,14 @@ describe('CollaborationRequestFormComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + describe('cancel button', () => { + it('should emit hideRequestForm', () => { + const emitSpy: jest.SpyInstance = (component.hide.emit = jest.fn()); + + dispatchEventFromFixture(fixture, cancelButton, 'clickEmitter'); + + expect(emitSpy).toHaveBeenCalled(); + }); + }); }); diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component.ts similarity index 76% rename from alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component.ts rename to alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component.ts index 682db1d4f83289c061ff5d733745a42947915530..4dcfcb9ce9658a59b3f87777522b3a99d5cce2d2 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component.ts +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, EventEmitter, Output } from '@angular/core'; import { CollaborationRequestFormService } from './collaboration.request.formservice'; @Component({ @@ -7,6 +7,8 @@ import { CollaborationRequestFormService } from './collaboration.request.formser providers: [CollaborationRequestFormService], }) export class CollaborationRequestFormComponent { + @Output() public hide: EventEmitter<void> = new EventEmitter<void>(); + constructor(readonly formService: CollaborationRequestFormService) {} public readonly formServiceClass = CollaborationRequestFormService; diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration.request.formservice.spec.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration.request.formservice.spec.ts similarity index 100% rename from alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration.request.formservice.spec.ts rename to alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration.request.formservice.spec.ts diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration.request.formservice.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration.request.formservice.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb6812cfda23cd62542bde49af42a42148c2ebba --- /dev/null +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration.request.formservice.ts @@ -0,0 +1,38 @@ +import { CommandResource } from '@alfa-client/command-shared'; +import { AbstractFormService, StateResource } from '@alfa-client/tech-shared'; +import { Injectable } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; +import { ResourceUri } from '@ngxp/rest'; +import { Observable, of } from 'rxjs'; + +@Injectable() +export class CollaborationRequestFormService extends AbstractFormService { + public static readonly FIELD_ORGANISATIONS_EINHEIT: string = 'organisationseinheit'; + public static readonly FIELD_TITLE: string = 'titel'; + public static readonly FIELD_NACHRICHT: string = 'nachricht'; + + private static readonly PATH_PREFIX: string = 'command.body'; + + constructor(formBuilder: FormBuilder) { + super(formBuilder); + } + + protected initForm(): FormGroup { + return this.formBuilder.group({ + [CollaborationRequestFormService.FIELD_ORGANISATIONS_EINHEIT]: new FormControl<ResourceUri>( + null, + ), + [CollaborationRequestFormService.FIELD_TITLE]: new FormControl<string>(null), + [CollaborationRequestFormService.FIELD_NACHRICHT]: new FormControl<string>(null), + }); + } + + protected doSubmit(): Observable<StateResource<CommandResource>> { + console.info('FormValue: ', this.getFormValue()); + return of(); + } + + protected getPathPrefix(): string { + return CollaborationRequestFormService.PATH_PREFIX; + } +} diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component.html b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component.html new file mode 100644 index 0000000000000000000000000000000000000000..36cee6fb596565233bad6c63435fe246bd75fe06 --- /dev/null +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component.html @@ -0,0 +1,21 @@ +<ng-container *ngIf="organisationsEinheitResource; else searchButton"> + <div class="flex items-center gap-3"> + <ods-office-icon size="large" class="flex-none" /> + <alfa-organisations-einheit + data-test-id="organisations-einheit-in-collaboration" + [organisationsEinheitResource]="organisationsEinheitResource" + ></alfa-organisations-einheit> + </div> +</ng-container> +<ng-template #searchButton> + <div class="flex items-center gap-3"> + <ods-button + variant="outline" + text="Zuständige Stelle auswählen" + data-test-id="organisations-einheit-search-button" + (clickEmitter)="openSearchDialog()" + > + <ods-search-icon icon /> + </ods-button> + </div> +</ng-template> diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component.spec.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..49f71ddf4203ac77dd0d4f0aa2baa697d896706e --- /dev/null +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component.spec.ts @@ -0,0 +1,168 @@ +import { OrganisationsEinheitResource } from '@alfa-client/collaboration-shared'; +import { + Mock, + dispatchEventFromFixture, + existsAsHtmlElement, + getMockComponent, + mock, +} from '@alfa-client/test-utils'; +import { OzgcloudDialogService } from '@alfa-client/ui'; +import { DialogConfig, DialogRef } from '@angular/cdk/dialog'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormControl } from '@angular/forms'; +import { getUrl } from '@ngxp/rest'; +import { ButtonComponent, OfficeIconComponent } from '@ods/system'; +import { createOrganisationsEinheitResource } from 'libs/collaboration-shared/test/organisations-einheit'; +import { SearchIconComponent } from 'libs/design-system/src/lib/icons/search-icon/search-icon.component'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { MockComponent } from 'ng-mocks'; +import { Subject } from 'rxjs'; +import { SearchOrganisationsEinheitContainerComponent } from '../../../search-organisations-einheit-container/search-organisations-einheit-container.component'; +import { OrganisationsEinheitContainerComponent } from './organisations-einheit-container.component'; +import { OrganisationsEinheitComponent } from './organisations-einheit/organisations-einheit.component'; + +describe('OrganisationsEinheitContainerComponent', () => { + let component: OrganisationsEinheitContainerComponent; + let fixture: ComponentFixture<OrganisationsEinheitContainerComponent>; + + const searchOrganisationsEinheit: string = getDataTestIdOf('organisations-einheit-search-button'); + const organisationsEinheitComp: string = getDataTestIdOf( + 'organisations-einheit-in-collaboration', + ); + + const organisationsEinheitResource: OrganisationsEinheitResource = + createOrganisationsEinheitResource(); + + const dialogService: Mock<OzgcloudDialogService> = mock(OzgcloudDialogService); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + OrganisationsEinheitContainerComponent, + MockComponent(SearchIconComponent), + MockComponent(OfficeIconComponent), + MockComponent(ButtonComponent), + MockComponent(OrganisationsEinheitComponent), + ], + providers: [ + { + provide: OzgcloudDialogService, + useValue: dialogService, + }, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(OrganisationsEinheitContainerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('search zustaendige stelle button', () => { + beforeEach(() => { + component.organisationsEinheitResource = undefined; + }); + + it('should be visible on missing organisationsEinheit', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, searchOrganisationsEinheit); + }); + it('should call openSearchDialog', () => { + component.openSearchDialog = jest.fn(); + + fixture.detectChanges(); + dispatchEventFromFixture(fixture, searchOrganisationsEinheit, 'clickEmitter'); + + expect(component.openSearchDialog).toHaveBeenCalled(); + }); + }); + + describe('organisationsEinheit component', () => { + beforeEach(() => { + component.organisationsEinheitResource = organisationsEinheitResource; + }); + + it('should be visible on existing organisationsEinheit', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, organisationsEinheitComp); + }); + + it('should be called with resource', () => { + fixture.detectChanges(); + + const comp: OrganisationsEinheitComponent = getMockComponent<OrganisationsEinheitComponent>( + fixture, + OrganisationsEinheitComponent, + ); + expect(comp.organisationsEinheitResource).toBe(organisationsEinheitResource); + }); + }); + + describe('open search dialog', () => { + beforeEach(() => { + component.listenToDialogClose = jest.fn(); + }); + + it('should call dialog service', () => { + const DIALOG_CONFIG: DialogConfig = { + backdropClass: ['backdrop-blur-1', 'bg-greybackdrop'], + }; + + component.openSearchDialog(); + + expect(dialogService.openInCallingComponentContext).toHaveBeenCalledWith( + SearchOrganisationsEinheitContainerComponent, + component.viewContainerRef, + null, + DIALOG_CONFIG, + ); + }); + + it('should call listenToDialogClose', () => { + component.openSearchDialog(); + + expect(component.listenToDialogClose).toHaveBeenCalled(); + }); + }); + + describe('listen to dialog close, after closed', () => { + it('should call handleDialogClosed', () => { + const closedSubj: Subject<OrganisationsEinheitResource> = new Subject(); + component.dialogRef = <DialogRef>{ closed: closedSubj.asObservable() }; + component.handleDialogClosed = jest.fn(); + + component.listenToDialogClose(); + closedSubj.next(organisationsEinheitResource); + + expect(component.handleDialogClosed).toHaveBeenCalledWith(organisationsEinheitResource); + }); + }); + + describe('handle dialog closed', () => { + beforeEach(() => { + component.fieldControl = new FormControl(); + }); + + it('should set organisationsEinheit', () => { + component.organisationsEinheitResource = undefined; + + component.handleDialogClosed(organisationsEinheitResource); + + expect(component.organisationsEinheitResource).toBe(organisationsEinheitResource); + }); + + it('should patch fieldControl with resource uri', () => { + const fieldControlPatchSpy: jest.SpyInstance = (component.fieldControl.patchValue = + jest.fn()); + + component.handleDialogClosed(organisationsEinheitResource); + + expect(fieldControlPatchSpy).toHaveBeenCalledWith(getUrl(organisationsEinheitResource)); + }); + }); +}); diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..872efeefb5fb60b6f26fae4c2800bea525b4149c --- /dev/null +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component.ts @@ -0,0 +1,55 @@ +import { + OrganisationsEinheitResource, + OrganisationsEinheitService, +} from '@alfa-client/collaboration-shared'; +import { OzgcloudDialogService } from '@alfa-client/ui'; +import { DialogConfig, DialogRef } from '@angular/cdk/dialog'; +import { Component, Input, ViewContainerRef } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { ResourceUri, getUrl } from '@ngxp/rest'; +import { first } from 'rxjs'; +import { SearchOrganisationsEinheitContainerComponent } from '../../../search-organisations-einheit-container/search-organisations-einheit-container.component'; + +const DIALOG_CONFIG: DialogConfig = { + backdropClass: ['backdrop-blur-1', 'bg-greybackdrop'], +}; + +@Component({ + selector: 'alfa-organisations-einheit-container', + templateUrl: './organisations-einheit-container.component.html', + providers: [OrganisationsEinheitService], +}) +export class OrganisationsEinheitContainerComponent { + @Input() public fieldControl: FormControl<ResourceUri>; + + public organisationsEinheitResource: OrganisationsEinheitResource; + + dialogRef: DialogRef; + + constructor( + private readonly dialogService: OzgcloudDialogService, + readonly viewContainerRef: ViewContainerRef, + ) {} + + public openSearchDialog(): void { + this.dialogRef = + this.dialogService.openInCallingComponentContext<SearchOrganisationsEinheitContainerComponent>( + SearchOrganisationsEinheitContainerComponent, + this.viewContainerRef, + null, + DIALOG_CONFIG, + ); + this.listenToDialogClose(); + } + + listenToDialogClose(): void { + this.dialogRef.closed + .pipe(first()) + .subscribe((result: OrganisationsEinheitResource) => this.handleDialogClosed(result)); + } + + handleDialogClosed(organisationsEinheitResource: OrganisationsEinheitResource): void { + this.organisationsEinheitResource = organisationsEinheitResource; + this.fieldControl.patchValue(getUrl(organisationsEinheitResource)); + } +} diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component.html b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component.html new file mode 100644 index 0000000000000000000000000000000000000000..57d9280a6f6c3909e5d5c4494a245a803517d7a3 --- /dev/null +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component.html @@ -0,0 +1,2 @@ +<p class="font-bold">{{ name }}</p> +<p>{{ address }}</p> diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component.spec.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..490dab5d431c35493aa38e8c323ea990706c0ec3 --- /dev/null +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component.spec.ts @@ -0,0 +1,58 @@ +import { OrganisationsEinheitResource } from '@alfa-client/collaboration-shared'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { createOrganisationsEinheitResource } from 'libs/collaboration-shared/test/organisations-einheit'; +import { OrganisationsEinheitComponent } from './organisations-einheit.component'; + +describe('OrganisationsEinheitComponent', () => { + let component: OrganisationsEinheitComponent; + let fixture: ComponentFixture<OrganisationsEinheitComponent>; + + const organisationsEinheitResource: OrganisationsEinheitResource = + createOrganisationsEinheitResource(); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [OrganisationsEinheitComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(OrganisationsEinheitComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('set organisationsEinheit', () => { + it('should call update by organisationsEinehit', () => { + component.updateByOrganisationsEinheit = jest.fn(); + + component.organisationsEinheitResource = organisationsEinheitResource; + + expect(component.updateByOrganisationsEinheit).toHaveBeenCalledWith( + organisationsEinheitResource, + ); + }); + }); + + describe('update by organisationsEinheit', () => { + it('should set name', () => { + component.name = null; + + component.updateByOrganisationsEinheit(organisationsEinheitResource); + + expect(component.name).toEqual(organisationsEinheitResource.name); + }); + + it('should set address', () => { + component.address = null; + + component.updateByOrganisationsEinheit(organisationsEinheitResource); + + expect(component.address).toEqual( + `${organisationsEinheitResource.anschrift.strasse} ${organisationsEinheitResource.anschrift.hausnummer}, ${organisationsEinheitResource.anschrift.plz} ${organisationsEinheitResource.anschrift.ort}`, + ); + }); + }); +}); diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..ff94e74f550eee641eaf4645b166838d5048badb --- /dev/null +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component.ts @@ -0,0 +1,26 @@ +import { Anschrift, OrganisationsEinheitResource } from '@alfa-client/collaboration-shared'; +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'alfa-organisations-einheit', + templateUrl: './organisations-einheit.component.html', +}) +export class OrganisationsEinheitComponent { + @Input() public set organisationsEinheitResource( + organisationsEinheit: OrganisationsEinheitResource, + ) { + this.updateByOrganisationsEinheit(organisationsEinheit); + } + + public name: string; + public address: string; + + updateByOrganisationsEinheit(organisationsEinheit: OrganisationsEinheitResource): void { + this.name = organisationsEinheit.name; + this.address = this.buildAddress(organisationsEinheit.anschrift); + } + + private buildAddress(anschrift: Anschrift): string { + return `${anschrift.strasse} ${anschrift.hausnummer}, ${anschrift.plz} ${anschrift.ort}`; + } +} diff --git a/alfa-client/libs/collaboration/src/lib/collaboration.module.ts b/alfa-client/libs/collaboration/src/lib/collaboration.module.ts index ee832d7f2aff01bd0e454c20166abe61f56a4d17..bbe069e5b79e331041e43cbb62ed661f085e2d72 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration.module.ts +++ b/alfa-client/libs/collaboration/src/lib/collaboration.module.ts @@ -9,13 +9,14 @@ import { CloseIconComponent, CollaborationIconComponent, InstantSearchComponent, + OfficeIconComponent, SaveIconComponent, + SearchIconComponent, } from '@ods/system'; -import { SearchIconComponent } from 'libs/design-system/src/lib/icons/search-icon/search-icon.component'; import { CollaborationInVorgangContainerComponent } from './collaboration-in-vorgang-container/collaboration-in-vorgang-container.component'; -import { CollaborationRequestContainerComponent } from './collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-container.component'; -import { CollaborationRequestFormComponent } from './collaboration-in-vorgang-container/collaboration-request-container/collaboration-request-form/collaboration-request-form.component'; -import { OrganisationsEinheitInCollaborationContainerComponent } from './organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component'; +import { CollaborationRequestFormComponent } from './collaboration-in-vorgang-container/collaboration-request-form/collaboration-request-form.component'; +import { OrganisationsEinheitContainerComponent } from './collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit-container.component'; +import { OrganisationsEinheitComponent } from './collaboration-in-vorgang-container/collaboration-request-form/organisations-einheit-container/organisations-einheit/organisations-einheit.component'; import { SearchOrganisationsEinheitContainerComponent } from './search-organisations-einheit-container/search-organisations-einheit-container.component'; import { SearchOrganisationsEinheitFormComponent } from './search-organisations-einheit-container/search-organisations-einheit-form/search-organisations-einheit-form.component'; @@ -23,6 +24,7 @@ import { SearchOrganisationsEinheitFormComponent } from './search-organisations- imports: [ CommonModule, ButtonComponent, + OfficeIconComponent, SaveIconComponent, CloseIconComponent, SearchIconComponent, @@ -37,11 +39,11 @@ import { SearchOrganisationsEinheitFormComponent } from './search-organisations- ], declarations: [ CollaborationInVorgangContainerComponent, - CollaborationRequestContainerComponent, CollaborationRequestFormComponent, SearchOrganisationsEinheitContainerComponent, SearchOrganisationsEinheitFormComponent, - OrganisationsEinheitInCollaborationContainerComponent, + OrganisationsEinheitContainerComponent, + OrganisationsEinheitComponent, ], exports: [CollaborationInVorgangContainerComponent], }) diff --git a/alfa-client/libs/collaboration/src/lib/organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component.html b/alfa-client/libs/collaboration/src/lib/organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component.html deleted file mode 100644 index 93730ca61b0bf1ecfeb05b2223d50164ec0aa33d..0000000000000000000000000000000000000000 --- a/alfa-client/libs/collaboration/src/lib/organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component.html +++ /dev/null @@ -1,8 +0,0 @@ -<ods-button - variant="outline" - text="Zuständige Stelle auswählen" - data-test-id="organisations-einheit-search-button" - (clickEmitter)="openSearchDialog()" -> - <ods-search-icon icon /> -</ods-button> diff --git a/alfa-client/libs/collaboration/src/lib/organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component.spec.ts b/alfa-client/libs/collaboration/src/lib/organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component.spec.ts deleted file mode 100644 index b25d5c1fa3c027ef30e7306f5d23dd84713f06ae..0000000000000000000000000000000000000000 --- a/alfa-client/libs/collaboration/src/lib/organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Mock, dispatchEventFromFixture, mock } from '@alfa-client/test-utils'; -import { OzgcloudDialogService } from '@alfa-client/ui'; -import { DialogConfig } from '@angular/cdk/dialog'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ButtonComponent } from '@ods/system'; -import { SearchIconComponent } from 'libs/design-system/src/lib/icons/search-icon/search-icon.component'; -import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; -import { MockComponent } from 'ng-mocks'; -import { SearchOrganisationsEinheitContainerComponent } from '../search-organisations-einheit-container/search-organisations-einheit-container.component'; -import { OrganisationsEinheitInCollaborationContainerComponent } from './organisations-einheit-in-collaboration-container.component'; - -describe('OrganisationsEinheitInCollaborationContainerComponent', () => { - let component: OrganisationsEinheitInCollaborationContainerComponent; - let fixture: ComponentFixture<OrganisationsEinheitInCollaborationContainerComponent>; - - const searchOrganisationsEinheit: string = getDataTestIdOf('organisations-einheit-search-button'); - - const dialogService: Mock<OzgcloudDialogService> = mock(OzgcloudDialogService); - const dialogConfig: DialogConfig = { - disableClose: true, - hasBackdrop: true, - backdropClass: 'blur-dialog-backdrop', - }; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - OrganisationsEinheitInCollaborationContainerComponent, - MockComponent(SearchIconComponent), - MockComponent(ButtonComponent), - ], - providers: [ - { - provide: OzgcloudDialogService, - useValue: dialogService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(OrganisationsEinheitInCollaborationContainerComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('search zustaendige stelle button', () => { - it('should call dialog service on click', () => { - dispatchEventFromFixture(fixture, searchOrganisationsEinheit, 'clickEmitter'); - - expect(dialogService.openInCallingComponentContext).toHaveBeenCalledWith( - SearchOrganisationsEinheitContainerComponent, - component.viewContainerRef, - null, - dialogConfig, - ); - }); - }); -}); diff --git a/alfa-client/libs/collaboration/src/lib/organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component.ts b/alfa-client/libs/collaboration/src/lib/organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component.ts deleted file mode 100644 index 6635341d8a4b10c13e8a951bc4e7afdf079ad277..0000000000000000000000000000000000000000 --- a/alfa-client/libs/collaboration/src/lib/organisations-einheit-in-collaboration-container/organisations-einheit-in-collaboration-container.component.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { OrganisationsEinheitService } from '@alfa-client/collaboration-shared'; -import { OzgcloudDialogService } from '@alfa-client/ui'; -import { Component, ViewContainerRef } from '@angular/core'; -import { SearchOrganisationsEinheitContainerComponent } from '../search-organisations-einheit-container/search-organisations-einheit-container.component'; - -@Component({ - selector: 'alfa-organisations-einheit-in-collaboration-container', - templateUrl: './organisations-einheit-in-collaboration-container.component.html', - providers: [OrganisationsEinheitService], -}) -export class OrganisationsEinheitInCollaborationContainerComponent { - constructor( - private dialogService: OzgcloudDialogService, - readonly viewContainerRef: ViewContainerRef, - ) {} - - public openSearchDialog(): void { - this.dialogService.openInCallingComponentContext<SearchOrganisationsEinheitContainerComponent>( - SearchOrganisationsEinheitContainerComponent, - this.viewContainerRef, - null, - { disableClose: true, hasBackdrop: true, backdropClass: 'blur-dialog-backdrop' }, - ); - } -} diff --git a/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.spec.ts b/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.spec.ts index d7d74a5aa81ff1cf7f5d7e16c8af2420516c6d4f..21d770d9c3bd231de7d5d039c5a29f079c04476b 100644 --- a/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.spec.ts +++ b/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.spec.ts @@ -169,7 +169,7 @@ describe('SearchOrganisationsEinheitContainerComponent', () => { it('should close dialog', () => { component.selectSearchResult(organisationsEinheitResource); - expect(dialogRefMock.close).toHaveBeenCalled(); + expect(dialogRefMock.close).toHaveBeenCalledWith(organisationsEinheitResource); }); }); diff --git a/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.ts b/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.ts index dd3f724e4758682d8f502f6afc8e9bb65e55bf52..b27e9b6358068fe7e7871cdc27dc8d434abd8ad3 100644 --- a/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.ts +++ b/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.ts @@ -37,7 +37,7 @@ export class SearchOrganisationsEinheitContainerComponent implements OnInit { public selectSearchResult(organisationsEinheit: OrganisationsEinheitResource): void { this.service.clearSearchResult(); - this.dialogRef.close(); + this.dialogRef.close(organisationsEinheit); } public clearSearchResult(): void { diff --git a/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-form/search-organisations-einheit-form.component.ts b/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-form/search-organisations-einheit-form.component.ts index aeb0eac486bf69940afb9f119a695b00ca8c61d4..2e49ca660d004820de961dd252ef7ed156040a1a 100644 --- a/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-form/search-organisations-einheit-form.component.ts +++ b/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-form/search-organisations-einheit-form.component.ts @@ -1,6 +1,6 @@ import { OrganisationsEinheitResource } from '@alfa-client/collaboration-shared'; import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { InstantSearchResult } from 'libs/design-system/src/lib/instant-search/instant-search/instant-search.model'; +import { InstantSearchResult } from '@ods/system'; import { SearchOrganisationsEinheitFormService } from '../search-organisations-einheit.formservice'; @Component({ diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts index b2a574838f9116b672a021322bfa1b5a009f147c..16c66be88076bf07e9c5bf7ec2b4052fa5a20d89 100644 --- a/alfa-client/libs/design-system/src/index.ts +++ b/alfa-client/libs/design-system/src/index.ts @@ -18,11 +18,14 @@ export * from './lib/icons/collaboration-icon/collaboration-icon.component'; export * from './lib/icons/exclamation-icon/exclamation-icon.component'; export * from './lib/icons/file-icon/file-icon.component'; export * from './lib/icons/iconVariants'; +export * from './lib/icons/office-icon/office-icon.component'; export * from './lib/icons/save-icon/save-icon.component'; +export * from './lib/icons/search-icon/search-icon.component'; export * from './lib/icons/send-icon/send-icon.component'; export * from './lib/icons/spinner-icon/spinner-icon.component'; export * from './lib/icons/stamp-icon/stamp-icon.component'; export * from './lib/instant-search/instant-search/instant-search.component'; +export * from './lib/instant-search/instant-search/instant-search.model'; export * from './lib/popup/popup-list-item/popup-list-item.component'; export * from './lib/popup/popup/popup.component'; export * from './lib/testbtn/testbtn.component'; diff --git a/alfa-client/libs/design-system/src/lib/icons/office-icon/office-icon.component.spec.ts b/alfa-client/libs/design-system/src/lib/icons/office-icon/office-icon.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..b41f00f7375d9ef6362471bda4734fa271f18ead --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/office-icon/office-icon.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { OfficeIconComponent } from './office-icon.component'; + +describe('SaveIconComponent', () => { + let component: OfficeIconComponent; + let fixture: ComponentFixture<OfficeIconComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [OfficeIconComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(OfficeIconComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/design-system/src/lib/icons/office-icon/office-icon.component.ts b/alfa-client/libs/design-system/src/lib/icons/office-icon/office-icon.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..25bdbb57d5011b3135a55be56cae8121c1611485 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/office-icon/office-icon.component.ts @@ -0,0 +1,28 @@ +import { NgClass } from '@angular/common'; +import { Component, Input } from '@angular/core'; +import { twMerge } from 'tailwind-merge'; + +import { IconVariants, iconVariants } from '../iconVariants'; + +@Component({ + selector: 'ods-office-icon', + standalone: true, + imports: [NgClass], + template: `<svg + [ngClass]="twMerge(iconVariants({ size }), 'fill-black', class)" + viewBox="0 0 24 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path + d="M2 21V4.75L7 1L12 4.75V7H22V21H2ZM4 19H6V17H4V19ZM4 15H6V13H4V15ZM4 11H6V9H4V11ZM4 7H6V5H4V7ZM8 7H10V5H8V7ZM8 19H20V9H8V19ZM14 13V11H18V13H14ZM14 17V15H18V17H14ZM10 13V11H12V13H10ZM10 17V15H12V17H10Z" + /> + </svg>`, +}) +export class OfficeIconComponent { + @Input() size: IconVariants['size'] = 'medium'; + @Input() class: string = undefined; + + iconVariants = iconVariants; + twMerge = twMerge; +} diff --git a/alfa-client/libs/design-system/src/lib/icons/office-icon/office-icon.stories.ts b/alfa-client/libs/design-system/src/lib/icons/office-icon/office-icon.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..8a54d90c40add3636c0f41c9748ab529f09fc253 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/office-icon/office-icon.stories.ts @@ -0,0 +1,27 @@ +import type { Meta, StoryObj } from '@storybook/angular'; + +import { OfficeIconComponent } from './office-icon.component'; + +const meta: Meta<OfficeIconComponent> = { + title: 'Icons/Save icon', + component: OfficeIconComponent, + excludeStories: /.*Data$/, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj<OfficeIconComponent>; + +export const Default: Story = { + args: { size: 'large' }, + argTypes: { + size: { + control: 'select', + options: ['small', 'medium', 'large', 'extra-large', 'full'], + description: 'Size of icon. Property "full" means 100%', + table: { + defaultValue: { summary: 'medium' }, + }, + }, + }, +}; diff --git a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js index 2ad76e5342c66c35ccc434bb8b99b96135c961e7..b17ef3c855216e3e735314a6e0b17984d4b3068f 100644 --- a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js +++ b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js @@ -115,6 +115,12 @@ module.exports = { error: 'hsl(var(--color-error))', focus: 'hsl(var(--color-focus))', }, + backgroundColor: { + greybackdrop: 'rgb(229, 229, 229, 0.95)', + }, + backdropBlur: { + 1: '1px', + }, }, }, plugins: [], diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource-search.service.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource-search.service.spec.ts index b39409cd8a23bef515b35609429264afd276d8e0..cec2eb392cca4a78a1ae77660048157d00169deb 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/resource-search.service.spec.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/resource-search.service.spec.ts @@ -1,10 +1,11 @@ import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { fakeAsync, tick } from '@angular/core/testing'; import faker from '@faker-js/faker'; -import { Resource } from '@ngxp/rest'; +import { Resource, getUrl } from '@ngxp/rest'; import { DummyLinkRel } from 'libs/tech-shared/test/dummy'; import { createDummyListResource, createDummyResource } from 'libs/tech-shared/test/resource'; -import { BehaviorSubject, of } from 'rxjs'; +import { BehaviorSubject, Observable, of } from 'rxjs'; +import { singleColdCompleted } from '../../../test/marbles'; import { EMPTY_STRING } from '../tech.util'; import { ResourceSearchService } from './resource-search.service'; import { LinkRelationName, ListItemResource, SearchResourceServiceConfig } from './resource.model'; @@ -167,4 +168,61 @@ describe('ResourceSearchService', () => { expect(service.listResource.value).toEqual({ ...stateListResource, loading: true }); }); }); + + describe('get selected', () => { + const dummyStateResource: StateResource<Resource> = createStateResource(createDummyResource()); + + it('should return selected resource', () => { + service.getSelectedResult = jest.fn().mockReturnValue(of(dummyStateResource)); + const selectedResult$: Observable<StateResource<Resource>> = service.getSelectedResult(); + + expect(selectedResult$).toBeObservable(singleColdCompleted(dummyStateResource)); + }); + }); + + describe('select result', () => { + const dummyResource: Resource = createDummyResource(); + + beforeEach(() => { + service.setSelectedResourceLoading = jest.fn(); + repository.getResource.mockReturnValue(of(dummyResource)); + }); + + it('should call setSelectedResourceLoading', () => { + service.selectResult(dummyResource); + + expect(service.setSelectedResourceLoading).toHaveBeenCalled(); + }); + + it('should call repository', () => { + service.selectResult(dummyResource); + + expect(repository.getResource).toHaveBeenCalledWith(getUrl(dummyResource)); + }); + + it('should update selected resource', () => { + service.selectedResource.next(createEmptyStateResource()); + + service.selectResult(dummyResource); + + expect(service.selectedResource.value).toEqual(createStateResource(dummyResource)); + }); + }); + + describe('set selected resource loading', () => { + const selectedDummyResource: Resource = createDummyResource(); + const selectedDummyStateResource: StateResource<Resource> = + createStateResource(selectedDummyResource); + + it('should set loading flag to true', () => { + service.selectedResource.next(selectedDummyStateResource); + + service.setSelectedResourceLoading(); + + expect(service.selectedResource.value).toEqual({ + ...selectedDummyStateResource, + loading: true, + }); + }); + }); }); diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource-search.service.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource-search.service.ts index 84d143a1caf35df4ba1574ef4b948fef891a1cac..c21f6e99a23e4392ef858d4ef5bd4e655a894fae 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/resource-search.service.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/resource-search.service.ts @@ -1,4 +1,4 @@ -import { Resource } from '@ngxp/rest'; +import { Resource, getUrl } from '@ngxp/rest'; import { isEmpty } from 'lodash-es'; import { BehaviorSubject, Observable, first, map, tap, withLatestFrom } from 'rxjs'; import { EMPTY_STRING, isNotEmpty } from '../tech.util'; @@ -25,6 +25,9 @@ export class ResourceSearchService< createEmptyStateResource(), ); readonly searchBy: BehaviorSubject<string> = new BehaviorSubject<string>(EMPTY_STRING); + readonly selectedResource: BehaviorSubject<StateResource<I>> = new BehaviorSubject< + StateResource<I> + >(createEmptyStateResource()); constructor( private config: SearchResourceServiceConfig<B>, @@ -85,8 +88,33 @@ export class ResourceSearchService< this.dispatchInitSearch(searchBy); } - private dispatchInitSearch(searchBy: string) { + private dispatchInitSearch(searchBy: string): void { this.searchBy.next(searchBy); this.listResource.next({ ...this.listResource.value, loading: true }); } + + public getSelectedResult(): Observable<StateResource<I>> { + return this.selectedResource.asObservable(); + } + + public selectResult(selected: I): void { + this.dispatchInitSelectResult(selected); + } + + private dispatchInitSelectResult(selected: I) { + this.setSelectedResourceLoading(); + this.repository + .getResource(getUrl(selected)) + .pipe(first()) + .subscribe((result: I) => { + this.selectedResource.next(createStateResource(result)); + }); + } + + setSelectedResourceLoading(): void { + this.selectedResource.next({ + ...this.selectedResource.value, + loading: true, + }); + } }