diff --git a/alfa-client/libs/collaboration-shared/src/lib/collaboration.service.ts b/alfa-client/libs/collaboration-shared/src/lib/collaboration.service.ts index 736d0cb47f6cd6ed943688a389a6f8f5e9acb388..f210a1133df3293f5bfa9da2bdd97fe033af1f6c 100644 --- a/alfa-client/libs/collaboration-shared/src/lib/collaboration.service.ts +++ b/alfa-client/libs/collaboration-shared/src/lib/collaboration.service.ts @@ -42,7 +42,7 @@ export class CollaborationService { order: CommandOrder.CREATE_COLLABORATION_REQUEST, body: collaborationRequest, }, - snackBarMessage: 'Die Zuarbeit wurde angefragt', + snackBarMessage: 'Die Zuarbeit wurde angefragt.', }); } } 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 2099588d498d90965f498e9c9c8a1bce56d9bce5..f264006658fe044ac57ad9a2926427046ba6f029 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 @@ -99,4 +99,12 @@ describe('OrganisationsEinheitService', () => { expect(searchService.selectResult).toHaveBeenCalledWith(organisationsEinheitResource); }); }); + + describe('clear selected result', () => { + it('should call service', () => { + service.clearSelectedResult(); + + expect(searchService.clearSelectedResult).toHaveBeenCalled(); + }); + }); }); 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 f4fadaf317dfd2bc7bf9103e8bd4d953613c21aa..495c115446391b8d126feef91bc6b02ad9c24134 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 @@ -30,4 +30,8 @@ export class OrganisationsEinheitService { public selectSearchResult(organisationsEinheitResource: OrganisationsEinheitResource): void { this.searchService.selectResult(organisationsEinheitResource); } + + public clearSelectedResult(): void { + this.searchService.clearSelectedResult(); + } } 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 85649462f34ddd362382333feed07cf10693ed88..a5e6e9e22dc4c22f174f59115b1bb954d1addaf3 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 @@ -155,4 +155,12 @@ describe('CollaborationInVorgangContainerComponent', () => { expect(service.hideRequestForm).toHaveBeenCalled(); }); }); + + describe('ngOnDestroy', () => { + it('should call service to clear selected result', () => { + component.ngOnDestroy(); + + expect(organisationsEinheitSearchService.clearSelectedResult).toHaveBeenCalled(); + }); + }); }); diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.ts index 63127377e2c066b9a8eedaa7e2ca7b58c74ba8fa..50c5d04bcffdbd5cd7171a14c5f696839b7447ea 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.ts +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang-container.component.ts @@ -1,6 +1,6 @@ import { OrganisationsEinheitResource } from '@alfa-client/collaboration-shared'; import { StateResource } from '@alfa-client/tech-shared'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { CollaborationListResource } from 'libs/collaboration-shared/src/lib/collaboration.model'; import { CollaborationService } from 'libs/collaboration-shared/src/lib/collaboration.service'; import { OrganisationsEinheitResourceSearchService } from 'libs/collaboration-shared/src/lib/organisations-einheit-resource-search.service'; @@ -10,7 +10,7 @@ import { Observable } from 'rxjs'; selector: 'alfa-collaboration-in-vorgang-container', templateUrl: './collaboration-in-vorgang-container.component.html', }) -export class CollaborationInVorgangContainerComponent implements OnInit { +export class CollaborationInVorgangContainerComponent implements OnInit, OnDestroy { public collaborationStateListResource$: Observable<StateResource<CollaborationListResource>>; public isRequestFormVisible$: Observable<boolean>; public selectedOrganisationsEinheit$: Observable<OrganisationsEinheitResource>; @@ -33,4 +33,8 @@ export class CollaborationInVorgangContainerComponent implements OnInit { public hideRequestForm(): void { this.service.hideRequestForm(); } + + ngOnDestroy(): void { + this.searchService.clearSelectedResult(); + } } diff --git a/alfa-client/libs/command-shared/src/lib/+state/command.effects.spec.ts b/alfa-client/libs/command-shared/src/lib/+state/command.effects.spec.ts index c461fcffe58c1bff6b679c9175b70af066484b98..2ee1199a7ec572ca5c33e21ed788c098f2b95015 100644 --- a/alfa-client/libs/command-shared/src/lib/+state/command.effects.spec.ts +++ b/alfa-client/libs/command-shared/src/lib/+state/command.effects.spec.ts @@ -1,4 +1,3 @@ -import { TestBed } from '@angular/core/testing'; import { ApiError, ApiErrorAction, @@ -7,6 +6,7 @@ import { } from '@alfa-client/tech-shared'; import { Mock, mock } from '@alfa-client/test-utils'; import { SnackBarService } from '@alfa-client/ui'; +import { TestBed } from '@angular/core/testing'; import { provideMockActions } from '@ngrx/effects/testing'; import { Action, Store, createAction, props } from '@ngrx/store'; import { TypedAction } from '@ngrx/store/src/models'; @@ -26,7 +26,12 @@ import { CommandLinkRel } from '../command.linkrel'; import { CREATE_COMMAND_MESSAGE_BY_ORDER, CommandErrorMessage } from '../command.message'; import { CommandListResource, CommandResource, CreateCommandProps } from '../command.model'; import { CommandRepository } from '../command.repository'; -import { CommandProps, LoadCommandListSuccessProps, createCommandFailure } from './command.actions'; +import { + CommandProps, + LoadCommandListSuccessProps, + SnackBarProps, + createCommandFailure, +} from './command.actions'; import { CommandEffects } from './command.effects'; import * as CommandActions from './command.actions'; @@ -35,13 +40,17 @@ describe('CommandEffects', () => { let actions: Observable<Action>; let effects: CommandEffects; - const repository: Mock<CommandRepository> = mock(CommandRepository); - const snackBarService: Mock<SnackBarService> = mock(SnackBarService); - const store: Mock<SnackBarService> = mock(SnackBarService); + let repository: Mock<CommandRepository>; + let snackBarService: Mock<SnackBarService>; + let store: Mock<Store>; let testScheduler: TestScheduler; beforeEach(() => { + repository = mock(CommandRepository); + snackBarService = mock(SnackBarService); + store = mock(Store); + testScheduler = new TestScheduler((actual, expected) => expect(actual).toEqual(expected)); TestBed.configureTestingModule({ @@ -374,7 +383,8 @@ describe('CommandEffects', () => { const createCommandProps: CreateCommandProps = createCreateCommandProps(); const command: CommandResource = createCommandResource(); - it('should show snackBar on existing snackBarMessage', () => { + it('should call handle snackbar by command', () => { + effects.handleSnackbarByCommand = jest.fn(); const showSnackbarAction: TypedAction<string> = CommandActions.showSnackbar({ createCommandProps, command, @@ -383,6 +393,19 @@ describe('CommandEffects', () => { actions = of(showSnackbarAction); effects.showSnackbar$.subscribe(); + expect(effects.handleSnackbarByCommand).toHaveBeenCalled(); + }); + }); + + describe('handle snackbar by command', () => { + const createCommandProps: CreateCommandProps = createCreateCommandProps(); + const command: CommandResource = createCommandResource(); + + it('should show snackBar on existing snackBarMessage', () => { + const snackBarProps: SnackBarProps = { createCommandProps, command }; + + effects.handleSnackbarByCommand(snackBarProps); + expect(snackBarService.show).toHaveBeenCalledWith( command, createCommandProps.snackBarMessage, @@ -390,13 +413,12 @@ describe('CommandEffects', () => { }); it('should show snackBar on undefined snackBarMessage', () => { - const showSnackbarAction: TypedAction<string> = CommandActions.showSnackbar({ + const snackBarProps: SnackBarProps = { createCommandProps: { ...createCommandProps, snackBarMessage: undefined }, command, - }); + }; - actions = of(showSnackbarAction); - effects.showSnackbar$.subscribe(); + effects.handleSnackbarByCommand(snackBarProps); expect(snackBarService.show).toHaveBeenCalledWith( command, @@ -404,16 +426,24 @@ describe('CommandEffects', () => { ); }); - //Faellt um, wenn man ihn mit den anderen Tests zusammen laufen laesst - it.skip('FIXME should NOT show snackBar on empty snackBarMessage', () => { - const showSnackbarAction: TypedAction<string> = CommandActions.showSnackbar({ + it('should NOT show snackBar on empty snackBarMessage', () => { + const snackBarProps: SnackBarProps = { createCommandProps: { ...createCommandProps, snackBarMessage: EMPTY_STRING }, command, - }); - snackBarService.show.mockClear(); + }; - effects.showSnackbar$.subscribe(); - actions = of(showSnackbarAction); + effects.handleSnackbarByCommand(snackBarProps); + + expect(snackBarService.show).not.toHaveBeenCalled(); + }); + + it('should NOT show snackBar on existing error message', () => { + const snackBarProps: SnackBarProps = { + createCommandProps, + command: { ...command, errorMessage: 'dummyErrorMessage' }, + }; + + effects.handleSnackbarByCommand(snackBarProps); expect(snackBarService.show).not.toHaveBeenCalled(); }); diff --git a/alfa-client/libs/command-shared/src/lib/+state/command.effects.ts b/alfa-client/libs/command-shared/src/lib/+state/command.effects.ts index 3d7151381f57a1c9843bf17179f320bd3c28022c..76c42d3899bc776736f109e5af66d73cccd23aa1 100644 --- a/alfa-client/libs/command-shared/src/lib/+state/command.effects.ts +++ b/alfa-client/libs/command-shared/src/lib/+state/command.effects.ts @@ -1,14 +1,21 @@ -import { Injectable } from '@angular/core'; +import { EMPTY_STRING } from '@alfa-client/tech-shared'; import { SnackBarService } from '@alfa-client/ui'; +import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { TypedAction } from '@ngrx/store/src/models'; +import { isEmpty, isEqual, isUndefined } from 'lodash-es'; import { of } from 'rxjs'; import { catchError, delay, map, mergeMap, switchMap, tap } from 'rxjs/operators'; import { COMMAND_ERROR_MESSAGES, CREATE_COMMAND_MESSAGE_BY_ORDER } from '../command.message'; import { CommandListResource, CommandResource, CreateCommandProps } from '../command.model'; import { CommandRepository } from '../command.repository'; -import { hasCommandError, isConcurrentModification, isPending, isRevokeable } from '../command.util'; +import { + hasCommandError, + isConcurrentModification, + isPending, + isRevokeable, +} from '../command.util'; import { CommandProps, LoadCommandListProps, @@ -27,8 +34,6 @@ import { showRevokeSnackbar, showSnackbar, } from './command.actions'; -import { isEqual, isUndefined } from 'lodash-es'; -import { EMPTY_STRING } from '@alfa-client/tech-shared'; @Injectable() export class CommandEffects { @@ -99,6 +104,8 @@ export class CommandEffects { } if (hasCommandError(command) && isConcurrentModification(command.errorMessage)) { this.showError(command); + //FIXME Anstelle der createCommandSucess Action sollte eine createCommandFailure Action geworfen werden. + //Hierzu muss ein HttpErrorResponse für die errorMessage definieren werden return [createCommandSuccess({ command }), publishConcurrentModificationAction()]; } return [createCommandSuccess({ command }), showSnackbar({ createCommandProps, command })]; @@ -131,15 +138,20 @@ export class CommandEffects { () => this.actions$.pipe( ofType(showSnackbar), - tap((props: SnackBarProps) => { - if (!isEqual(props.createCommandProps.snackBarMessage, EMPTY_STRING)) { - this.snackbarService.show(props.command, this.getSnackBarMessage(props)); - } - }), + tap((props: SnackBarProps) => this.handleSnackbarByCommand(props)), ), { dispatch: false }, ); + handleSnackbarByCommand(props: SnackBarProps): void { + if ( + !isEqual(props.createCommandProps.snackBarMessage, EMPTY_STRING) && + isEmpty(props.command.errorMessage) + ) { + this.snackbarService.show(props.command, this.getSnackBarMessage(props)); + } + } + private getSnackBarMessage(props: SnackBarProps): string { return isUndefined(props.createCommandProps.snackBarMessage) ? CREATE_COMMAND_MESSAGE_BY_ORDER[props.command.order] diff --git a/alfa-client/libs/tech-shared/src/lib/pipe/to-embedded-resource.pipe.spec.ts b/alfa-client/libs/tech-shared/src/lib/pipe/to-embedded-resource.pipe.spec.ts index a4873730938d80aa0efe333f7177aca4e2e4ff28..eef4a6cad0cd8c46e932d45a93b11eab29005b62 100644 --- a/alfa-client/libs/tech-shared/src/lib/pipe/to-embedded-resource.pipe.spec.ts +++ b/alfa-client/libs/tech-shared/src/lib/pipe/to-embedded-resource.pipe.spec.ts @@ -23,7 +23,7 @@ */ import { getEmbeddedResource } from '@ngxp/rest'; import { DummyListLinkRel } from 'libs/tech-shared/test/dummy'; -import { createDummyListResource } from 'libs/tech-shared/test/resource'; +import { createDummyListResource, toResource } from 'libs/tech-shared/test/resource'; import { ListResource } from '../resource/resource.util'; import { EMPTY_ARRAY } from '../tech.util'; import { ToEmbeddedResourcesPipe } from './to-embedded-resource.pipe'; @@ -55,5 +55,11 @@ describe('ToEmbeddedResourcesPipe', () => { expect(result).toBe(EMPTY_ARRAY); }); + + it('should return empty array non existing resources', () => { + const result: unknown[] = pipe.transform(toResource({}), DummyListLinkRel.LIST); + + expect(result).toBe(EMPTY_ARRAY); + }); }); }); diff --git a/alfa-client/libs/tech-shared/src/lib/pipe/to-embedded-resource.pipe.ts b/alfa-client/libs/tech-shared/src/lib/pipe/to-embedded-resource.pipe.ts index 77e51945183b3b392c2b3d49647af0bf4a0e02ea..f310e40a994c86031869c1137adf3a3387864b38 100644 --- a/alfa-client/libs/tech-shared/src/lib/pipe/to-embedded-resource.pipe.ts +++ b/alfa-client/libs/tech-shared/src/lib/pipe/to-embedded-resource.pipe.ts @@ -23,7 +23,7 @@ */ import { Pipe, PipeTransform } from '@angular/core'; import { Resource, getEmbeddedResource } from '@ngxp/rest'; -import { isNil } from 'lodash-es'; +import { isNil, isNull } from 'lodash-es'; import { LinkRelationName } from '../resource/resource.model'; import { ListResource } from '../resource/resource.util'; import { EMPTY_ARRAY } from '../tech.util'; @@ -32,6 +32,7 @@ import { EMPTY_ARRAY } from '../tech.util'; export class ToEmbeddedResourcesPipe implements PipeTransform { transform(listResource: ListResource, linkRel: LinkRelationName): Resource[] { if (isNil(listResource) || isNil(linkRel)) return EMPTY_ARRAY; - return getEmbeddedResource(listResource, linkRel); + const embeddedReources: Resource[] = getEmbeddedResource(listResource, linkRel); + return isNull(embeddedReources) ? EMPTY_ARRAY : embeddedReources; } } 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 acbd45df651fd4343be7601e8a9886850f133f0e..1c1d30cbcd83ef02da378247d4e2792ff750d3a0 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 @@ -191,4 +191,16 @@ describe('ResourceSearchService', () => { expect(service.selectedResource.value).toEqual(dummyResource); }); }); + + describe('clear select result', () => { + const dummyResource: Resource = createDummyResource(); + + it('should update selected resource to null', () => { + service.selectedResource.next(dummyResource); + + service.clearSelectedResult(); + + expect(service.selectedResource.value).toBeNull(); + }); + }); }); 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 d23b4be986f9a8fb880e582c5925f525459bf3dc..f8e52663e186ba7c2ebe4b8d6bec0dd593163e3a 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 @@ -98,4 +98,8 @@ export class ResourceSearchService< public selectResult(selected: I): void { this.selectedResource.next(selected); } + + public clearSelectedResult(): void { + this.selectedResource.next(null); + } } diff --git a/pom.xml b/pom.xml index bac9e0e473b07a7e6bbc10f857de168643db407e..a824ac03c6c5b1db540c09c85bb3cb6fb6b694b6 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ <parent> <groupId>de.ozgcloud.common</groupId> <artifactId>ozgcloud-common-parent</artifactId> - <version>4.4.0-SNAPSHOT</version> + <version>4.3.2</version> </parent> <groupId>de.ozgcloud.alfa</groupId>