From ec62c97b9434f04d36623f080019244a542a9e20 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 11 Jul 2024 13:30:22 -0400 Subject: [PATCH] actions pub/sub service --- .../src/lib/services/action.service.md | 30 ++++++++ .../src/lib/services/action.service.spec.ts | 72 +++++++++++++++++++ .../src/lib/services/action.service.ts | 49 +++++++++++++ projects/aca-shared/src/public-api.ts | 1 + 4 files changed, 152 insertions(+) create mode 100644 projects/aca-shared/src/lib/services/action.service.md create mode 100644 projects/aca-shared/src/lib/services/action.service.spec.ts create mode 100644 projects/aca-shared/src/lib/services/action.service.ts diff --git a/projects/aca-shared/src/lib/services/action.service.md b/projects/aca-shared/src/lib/services/action.service.md new file mode 100644 index 0000000000..52e818284a --- /dev/null +++ b/projects/aca-shared/src/lib/services/action.service.md @@ -0,0 +1,30 @@ +# Action Service + +`service` + +The Action Service is a service that allows you to subscribe to events and publish events. + +## API + +### `dispatch(action: Action): void` + +Dispatch an action. This will notify all subscribers of the action. + +Example: + +```typescript +this.actionService.dispatch({ type: 'MY_ACTION', payload: { foo: 'bar' } }); +``` + +### `ofType(type: string): Observable` + +Subscribe to actions of a specific type. + +Example: + +```typescript +this.actionService.ofType('MY_ACTION').subscribe(action => { + console.log(action); +}); +``` + diff --git a/projects/aca-shared/src/lib/services/action.service.spec.ts b/projects/aca-shared/src/lib/services/action.service.spec.ts new file mode 100644 index 0000000000..cae80fdfc3 --- /dev/null +++ b/projects/aca-shared/src/lib/services/action.service.spec.ts @@ -0,0 +1,72 @@ +/*! + * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * from Hyland Software. If not, see . + */ + +import { TestBed } from '@angular/core/testing'; +import { ActionService } from './action.service'; +import { take } from 'rxjs/operators'; + +describe('ActionService', () => { + let service: ActionService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ActionService); + }); + + it('should dispatch and filter actions by type', (done) => { + const testAction = { type: 'testAction' }; + service + .ofType('testAction') + .pipe(take(1)) + .subscribe((action) => { + expect(action).toEqual(testAction); + done(); + }); + service.dispatch(testAction); + }); + + it('should not emit actions of a different type', () => { + const testAction = { type: 'testAction' }; + const otherAction = { type: 'otherAction' }; + let emitted = false; + + service.ofType(testAction.type).subscribe(() => { + emitted = true; + }); + + service.dispatch(otherAction); + expect(emitted).toBeFalse(); + }); + + it('should handle dispatching null actions gracefully', () => { + expect(() => service.dispatch(null)).not.toThrow(); + }); + + it('should initially emit a startup action', (done) => { + service.actions$.pipe(take(1)).subscribe((action) => { + expect(action.type).toBe('startup'); + done(); + }); + }); +}); diff --git a/projects/aca-shared/src/lib/services/action.service.ts b/projects/aca-shared/src/lib/services/action.service.ts new file mode 100644 index 0000000000..eab33d5710 --- /dev/null +++ b/projects/aca-shared/src/lib/services/action.service.ts @@ -0,0 +1,49 @@ +/*! + * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * from Hyland Software. If not, see . + */ + +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { filter } from 'rxjs/operators'; + +export interface Action { + type: string; + payload?: any; +} + +@Injectable({ providedIn: 'root' }) +export class ActionService { + private actions = new BehaviorSubject({ type: 'startup' }); + + actions$ = this.actions.asObservable(); + + ofType(type: string): Observable { + return this.actions$.pipe(filter((action) => action.type === type)); + } + + dispatch(action: Action): void { + if (action) { + this.actions.next(action); + } + } +} diff --git a/projects/aca-shared/src/public-api.ts b/projects/aca-shared/src/public-api.ts index 7a92faac79..8c1be8b222 100644 --- a/projects/aca-shared/src/public-api.ts +++ b/projects/aca-shared/src/public-api.ts @@ -56,6 +56,7 @@ export * from './lib/services/app.extension.service'; export * from './lib/services/router.extension.service'; export * from './lib/services/app-hook.service'; export * from './lib/services/aca-file-auto-download.service'; +export * from './lib/services/action.service'; export * from './lib/utils/node.utils'; export * from './lib/testing/lib-testing-module';