From 442426bb2e75002db5975f30cb03eb496f8c5d0d Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Tue, 21 Nov 2023 18:38:49 +0100 Subject: [PATCH 1/3] [CST-12709] partial implementation with mock data --- src/app/core/core.module.ts | 10 +- .../notify-services-status-data.service.ts | 49 ++++++++ src/app/item-page/item-page.module.ts | 6 +- .../item-page/simple/item-page.component.html | 1 + .../notify-requests-status.component.html | 5 + .../notify-requests-status.component.scss | 0 .../notify-requests-status.component.ts | 108 ++++++++++++++++++ .../notify-requests-status.model.ts | 68 +++++++++++ .../notify-requests-status.resource-type.ts | 8 ++ .../notify-status.enum.ts | 5 + .../request-status-alert-box.component.html | 32 ++++++ .../request-status-alert-box.component.scss | 7 ++ ...request-status-alert-box.component.spec.ts | 51 +++++++++ .../request-status-alert-box.component.ts | 82 +++++++++++++ src/assets/i18n/en.json5 | 6 + 15 files changed, 434 insertions(+), 4 deletions(-) create mode 100644 src/app/core/data/notify-services-status-data.service.ts create mode 100644 src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.html create mode 100644 src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.scss create mode 100644 src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts create mode 100644 src/app/item-page/simple/notify-requests-status/notify-requests-status.model.ts create mode 100644 src/app/item-page/simple/notify-requests-status/notify-requests-status.resource-type.ts create mode 100644 src/app/item-page/simple/notify-requests-status/notify-status.enum.ts create mode 100644 src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.html create mode 100644 src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.scss create mode 100644 src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.spec.ts create mode 100644 src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.ts diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index d0f2dbbbaf..eef4f1f68e 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -195,6 +195,9 @@ import { CoarNotifyConfigDataService } from '../submission/sections/section-coar-notify/coar-notify-config-data.service'; import { SubmissionCoarNotifyConfig } from '../submission/sections/section-coar-notify/submission-coar-notify.config'; +import { NotifyRequestsStatus } from '../item-page/simple/notify-requests-status/notify-requests-status.model'; +import { NotifyRequestsStatusDataService } from './data/notify-services-status-data.service'; + /** * When not in production, endpoint responses can be mocked for testing purposes @@ -320,7 +323,8 @@ const PROVIDERS = [ SupervisionOrderDataService, LdnServicesService, LdnItemfiltersService, - CoarNotifyConfigDataService + CoarNotifyConfigDataService, + NotifyRequestsStatusDataService ]; /** @@ -404,8 +408,8 @@ export const models = SuggestionSource, LdnService, Itemfilter, - SubmissionCoarNotifyConfig - + SubmissionCoarNotifyConfig, + NotifyRequestsStatus, ]; @NgModule({ diff --git a/src/app/core/data/notify-services-status-data.service.ts b/src/app/core/data/notify-services-status-data.service.ts new file mode 100644 index 0000000000..67bfe18c80 --- /dev/null +++ b/src/app/core/data/notify-services-status-data.service.ts @@ -0,0 +1,49 @@ +import { Injectable } from '@angular/core'; +import { RequestService } from './request.service'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { HALEndpointService } from '../shared/hal-endpoint.service'; +import { IdentifiableDataService } from './base/identifiable-data.service'; +import { dataService } from './base/data-service.decorator'; +import { NotifyRequestsStatus } from '../../item-page/simple/notify-requests-status/notify-requests-status.model'; +import { NOTIFYREQUEST} from '../../item-page/simple/notify-requests-status/notify-requests-status.resource-type'; +import { Observable, map, take, tap } from 'rxjs'; +import { RemoteData } from './remote-data'; +import { GetRequest } from './request.models'; + + +@Injectable() +@dataService(NOTIFYREQUEST) +export class NotifyRequestsStatusDataService extends IdentifiableDataService { + + private notifyRequestLink = 'notifyrequests'; + + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected rdb: RemoteDataBuildService, + ) { + super('ldn', requestService, rdbService, objectCache, halService); + } + + /** + * Retrieves the status of notify requests for a specific item. + * @param itemUuid The UUID of the item. + * @returns An Observable that emits the remote data containing the notify requests status. + */ + getNotifyRequestsStatus(itemUuid: string): Observable> { + const href$ = this.halService.getEndpoint(this.notifyRequestLink).pipe( + tap((url: string) => console.log('url', url) ), + map((url: string) => url + '/' + itemUuid), + ); + + href$.pipe(take(1)).subscribe((url: string) => { + const request = new GetRequest(this.requestService.generateRequestId(), url); + this.requestService.send(request, true); + }); + + return this.rdb.buildFromHref(href$); + } +} diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index 5aa1b6e508..7fd7b3b623 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -61,6 +61,8 @@ import { ThemedFullFileSectionComponent } from './full/field-components/file-section/themed-full-file-section.component'; import { QaEventNotificationComponent } from './simple/qa-event-notification/qa-event-notification.component'; +import { NotifyRequestsStatusComponent } from './simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component'; +import { RequestStatusAlertBoxComponent } from './simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -104,7 +106,9 @@ const DECLARATIONS = [ ItemAlertsComponent, ThemedItemAlertsComponent, BitstreamRequestACopyPageComponent, - QaEventNotificationComponent + QaEventNotificationComponent, + NotifyRequestsStatusComponent, + RequestStatusAlertBoxComponent ]; @NgModule({ diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index 37a5e0c4cb..dc8ed87a86 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -3,6 +3,7 @@
+ diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.html b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.html new file mode 100644 index 0000000000..7736e88896 --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.html @@ -0,0 +1,5 @@ + + + + + diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.scss b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts new file mode 100644 index 0000000000..bd6e1983ed --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts @@ -0,0 +1,108 @@ +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { NotifyRequestsStatus, NotifyStatuses } from '../notify-requests-status.model'; +import { NotifyRequestsStatusDataService } from 'src/app/core/data/notify-services-status-data.service'; +import { RequestStatusEnum } from '../notify-status.enum'; + +@Component({ + selector: 'ds-notify-requests-status', + templateUrl: './notify-requests-status.component.html', + styleUrls: ['./notify-requests-status.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class NotifyRequestsStatusComponent { + + /** + * The UUID of the item. + */ + @Input() itemUuid: string; + + /** + * Map that stores the status of requests and their corresponding notify statuses. + * The keys of the map are instances of the RequestStatusEnum enum, + * and the values are arrays of NotifyStatuses objects. + */ + statusMap: Map = new Map(); + + notifyRequestStatus$: Observable = of( Object.assign(new NotifyRequestsStatus(), { + notifyStatuses: [ + { + serviceName: 'test', + serviceUrl: 'test', + status: RequestStatusEnum.ACCEPTED, + }, + { + serviceName: 'test1', + serviceUrl: 'test', + status: RequestStatusEnum.ACCEPTED, + }, + { + serviceName: 'Review Platform', + serviceUrl: 'test', + status: RequestStatusEnum.ACCEPTED, + }, + { + serviceName: 'Demo Environment', + serviceUrl: 'test', + status: RequestStatusEnum.ACCEPTED, + }, + { + serviceName: 'Additional Information', + serviceUrl: 'test', + status: RequestStatusEnum.ACCEPTED, + }, + { + serviceName: 'Notification Service', + serviceUrl: 'test', + status: RequestStatusEnum.ACCEPTED, + }, + { + serviceName: 'test2', + serviceUrl: 'test', + status: RequestStatusEnum.REJECTED, + }, + { + serviceName: 'test3', + serviceUrl: 'test', + status: RequestStatusEnum.REQUESTED, + }, + { + serviceName: 'test4', + serviceUrl: 'test', + status: RequestStatusEnum.REQUESTED, + } + ], + itemUuid: '8d5fda2d-f380-467e-a86b-0436ac699dab', + })); + + constructor( + private notifyInfoService: NotifyRequestsStatusDataService, + ) { } + + ngOnInit(): void { + this.notifyInfoService.getNotifyRequestsStatus(this.itemUuid).subscribe((data) => { + console.log(data, 'asdasdsa'); + }); + + this.notifyRequestStatus$.subscribe((data) => { + this.groupDataByStatus(data); + console.log(this.statusMap); + }); + } + + /** + * Groups the notify requests status data by status. + * @param notifyRequestsStatus The notify requests status data. + */ + private groupDataByStatus(notifyRequestsStatus: NotifyRequestsStatus): void { + notifyRequestsStatus.notifyStatuses.forEach((notifyStatus: NotifyStatuses) => { + const status = notifyStatus.status; + + if (!this.statusMap.has(status)) { + this.statusMap.set(status, []); + } + + this.statusMap.get(status)?.push(notifyStatus); + }); + } +} diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status.model.ts b/src/app/item-page/simple/notify-requests-status/notify-requests-status.model.ts new file mode 100644 index 0000000000..ab4e41b2c6 --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status.model.ts @@ -0,0 +1,68 @@ +// eslint-disable-next-line max-classes-per-file +import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; +import { typedObject } from '../../../core/cache/builders/build-decorators'; +import { CacheableObject } from '../../../core/cache/cacheable-object.model'; +import { ResourceType } from '../../../core/shared/resource-type'; +import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; +import { NOTIFYREQUEST } from './notify-requests-status.resource-type'; +import { HALLink } from '../../../core/shared/hal-link.model'; +import { RequestStatusEnum } from './notify-status.enum'; + +/** + * Represents the status of notify requests for an item. + */ +@typedObject +@inheritSerialization(CacheableObject) +export class NotifyRequestsStatus implements CacheableObject { + static type = NOTIFYREQUEST; + + /** + * The object type. + */ + @excludeFromEquals + @autoserialize + type: ResourceType; + + /** + * The notify statuses. + */ + @autoserialize + notifyStatuses: NotifyStatuses[]; + + /** + * The UUID of the item. + */ + @autoserialize + itemUuid: string; + + /** + * The links associated with the notify requests status. + */ + @deserialize + _links: { + self: HALLink; + [k: string]: HALLink | HALLink[]; + }; +} + +/** + * Represents the status of a notification request. + */ +export class NotifyStatuses { + /** + * The name of the service. + */ + serviceName: string; + + /** + * The URL of the service. + */ + serviceUrl: string; + + /** + * The status of the notification request. + */ + status: RequestStatusEnum; +} + + diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status.resource-type.ts b/src/app/item-page/simple/notify-requests-status/notify-requests-status.resource-type.ts new file mode 100644 index 0000000000..da7ab2c881 --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status.resource-type.ts @@ -0,0 +1,8 @@ +import {ResourceType} from '../../../core/shared/resource-type'; +/** + * The resource type for the root endpoint + * + * Needs to be in a separate file to prevent circular + * dependencies in webpack. + */ +export const NOTIFYREQUEST = new ResourceType('notifyrequest'); diff --git a/src/app/item-page/simple/notify-requests-status/notify-status.enum.ts b/src/app/item-page/simple/notify-requests-status/notify-status.enum.ts new file mode 100644 index 0000000000..e44c614130 --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/notify-status.enum.ts @@ -0,0 +1,5 @@ +export enum RequestStatusEnum { + ACCEPTED = 'ACCEPTED', + REJECTED = 'REJECTED', + REQUESTED = 'REQUESTED', +} diff --git a/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.html b/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.html new file mode 100644 index 0000000000..5ffc715109 --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.html @@ -0,0 +1,32 @@ + +
+ + + +
+ +
+
+
+
+
+
+
diff --git a/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.scss b/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.scss new file mode 100644 index 0000000000..f852bb8454 --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.scss @@ -0,0 +1,7 @@ +.source-logo { + max-height: var(--ds-header-logo-height); +} + +.sections-gap { + gap: 1rem; +} diff --git a/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.spec.ts b/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.spec.ts new file mode 100644 index 0000000000..f32c9f3bc2 --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.spec.ts @@ -0,0 +1,51 @@ +import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing'; +import { RequestStatusAlertBoxComponent } from './request-status-alert-box.component'; +import { TranslateModule } from '@ngx-translate/core'; +import { RequestStatusEnum } from '../notify-status.enum'; + +describe('RequestStatusAlertBoxComponent', () => { + let component: RequestStatusAlertBoxComponent; + let componentAsAny: any; + let fixture: ComponentFixture; + + const mockData = [ + { + serviceName: 'test', + serviceUrl: 'test', + status: RequestStatusEnum.ACCEPTED, + }, + { + serviceName: 'test1', + serviceUrl: 'test', + status: RequestStatusEnum.REJECTED, + }, + ]; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + declarations: [RequestStatusAlertBoxComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(RequestStatusAlertBoxComponent); + component = fixture.componentInstance; + component.data = mockData; + component.displayOptions = { + alertType: 'alert-danger', + text: 'request-status-alert-box.rejected', + }; + componentAsAny = component; + fixture.detectChanges(); + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('should display the alert box when data is available', fakeAsync(() => { + const alertBoxElement = fixture.nativeElement.querySelector('.alert'); + expect(alertBoxElement).toBeTruthy(); + })); +}); diff --git a/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.ts b/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.ts new file mode 100644 index 0000000000..355980836a --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/request-status-alert-box/request-status-alert-box.component.ts @@ -0,0 +1,82 @@ +import { + ChangeDetectionStrategy, + Component, + Input, + type OnInit, +} from '@angular/core'; +import { NotifyStatuses } from '../notify-requests-status.model'; +import { RequestStatusEnum } from '../notify-status.enum'; + +@Component({ + selector: 'ds-request-status-alert-box', + templateUrl: './request-status-alert-box.component.html', + styleUrls: ['./request-status-alert-box.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +/** + * Represents a component that displays the status of a request. + */ +export class RequestStatusAlertBoxComponent implements OnInit { + /** + * The status of the request. + */ + @Input() status: RequestStatusEnum; + + /** + * The input data for the request status alert box component. + * @type {NotifyStatuses[]} + */ + @Input() data: NotifyStatuses[] = []; + + /** + * The display options for the request status alert box. + */ + displayOptions: NotifyRequestDisplayOptions; + + ngOnInit(): void { + this.prepareDataToDisplay(); + } + + /** + * Prepares the data to be displayed based on the current status. + */ + private prepareDataToDisplay() { + switch (this.status) { + case RequestStatusEnum.ACCEPTED: + this.displayOptions = { + alertType: 'alert-info', + text: 'request-status-alert-box.accepted', + }; + break; + + case RequestStatusEnum.REJECTED: + this.displayOptions = { + alertType: 'alert-danger', + text: 'request-status-alert-box.rejected', + }; + break; + + case RequestStatusEnum.REQUESTED: + this.displayOptions = { + alertType: 'alert-warning', + text: 'request-status-alert-box.requested', + }; + break; + } + } +} + +/** + * Represents the display options for a notification request. + */ +export interface NotifyRequestDisplayOptions { + /** + * The type of alert to display. + * Possible values are 'alert-danger', 'alert-warning', or 'alert-info'. + */ + alertType: 'alert-danger' | 'alert-warning' | 'alert-info'; + /** + * The text to display in the notification. + */ + text: string; +} diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 3cf74b2b24..e754d25722 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -5697,4 +5697,10 @@ "access-control-option-end-date-note": "Select the date until which the related access condition is applied", + "request-status-alert-box.accepted": "The request for {{ serviceName }} has been taken in charge.", + + "request-status-alert-box.rejected": "The request for {{ serviceName }} has been rejected.", + + "request-status-alert-box.requested": "The request for {{ serviceName }} is pending.", + } From df0f1920dcf01587671921461bf1fa4570500175 Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Wed, 22 Nov 2023 15:20:59 +0100 Subject: [PATCH 2/3] [CST-12709] unit tests and final fixes --- .../notify-services-status-data.service.ts | 9 +- .../notify-requests-status.component.spec.ts | 84 +++++++++++ .../notify-requests-status.component.ts | 134 ++++++++---------- .../notify-requests-status.model.ts | 4 +- .../notify-requests-status.resource-type.ts | 2 +- .../qa-event-notification.component.ts | 5 +- 6 files changed, 153 insertions(+), 85 deletions(-) create mode 100644 src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.spec.ts diff --git a/src/app/core/data/notify-services-status-data.service.ts b/src/app/core/data/notify-services-status-data.service.ts index 67bfe18c80..6809ebf842 100644 --- a/src/app/core/data/notify-services-status-data.service.ts +++ b/src/app/core/data/notify-services-status-data.service.ts @@ -16,8 +16,6 @@ import { GetRequest } from './request.models'; @dataService(NOTIFYREQUEST) export class NotifyRequestsStatusDataService extends IdentifiableDataService { - private notifyRequestLink = 'notifyrequests'; - constructor( protected requestService: RequestService, protected rdbService: RemoteDataBuildService, @@ -25,7 +23,7 @@ export class NotifyRequestsStatusDataService extends IdentifiableDataService> { - const href$ = this.halService.getEndpoint(this.notifyRequestLink).pipe( - tap((url: string) => console.log('url', url) ), - map((url: string) => url + '/' + itemUuid), + const href$ = this.getEndpoint().pipe( + map((url: string) => url + '/' + itemUuid ), ); href$.pipe(take(1)).subscribe((url: string) => { diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.spec.ts b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.spec.ts new file mode 100644 index 0000000000..1498265ca4 --- /dev/null +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.spec.ts @@ -0,0 +1,84 @@ +import { ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing'; +import { NotifyRequestsStatusComponent } from './notify-requests-status.component'; +import { NotifyRequestsStatusDataService } from 'src/app/core/data/notify-services-status-data.service'; +import { NotifyRequestsStatus } from '../notify-requests-status.model'; +import { RequestStatusEnum } from '../notify-status.enum'; +import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils'; +import { TranslateModule } from '@ngx-translate/core'; + +describe('NotifyRequestsStatusComponent', () => { + let component: NotifyRequestsStatusComponent; + let fixture: ComponentFixture; + let notifyInfoServiceSpy; + + const mock: NotifyRequestsStatus = Object.assign(new NotifyRequestsStatus(), { + notifyStatus: [], + itemuuid: 'testUuid' + }); + + beforeEach(() => { + notifyInfoServiceSpy = { + getNotifyRequestsStatus:() => createSuccessfulRemoteDataObject$(mock) + }; + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + declarations: [NotifyRequestsStatusComponent], + providers: [ + { provide: NotifyRequestsStatusDataService, useValue: notifyInfoServiceSpy } + ] + }); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(NotifyRequestsStatusComponent); + component = fixture.componentInstance; + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('should fetch data from the service on initialization', fakeAsync(() => { + const mockData: NotifyRequestsStatus = Object.assign(new NotifyRequestsStatus(), { + notifyStatus: [], + itemuuid: 'testUuid' + }); + component.itemUuid = mockData.itemuuid; + spyOn(notifyInfoServiceSpy, 'getNotifyRequestsStatus').and.callThrough(); + component.ngOnInit(); + fixture.detectChanges(); + tick(); + + expect(notifyInfoServiceSpy.getNotifyRequestsStatus).toHaveBeenCalledWith('testUuid'); + expect(component.statusMap.size).toBe(0); + })); + + it('should group data by status', () => { + const mockData: NotifyRequestsStatus = Object.assign(new NotifyRequestsStatus(), { + notifyStatus: [ + { + serviceName: 'test1', + serviceUrl: 'test', + status: RequestStatusEnum.ACCEPTED, + }, + { + serviceName: 'test2', + serviceUrl: 'test', + status: RequestStatusEnum.REJECTED, + }, + { + serviceName: 'test3', + serviceUrl: 'test', + status: RequestStatusEnum.ACCEPTED, + }, + ], + itemUuid: 'testUuid' + }); + fixture.detectChanges(); + (component as any).groupDataByStatus(mockData); + + expect(component.statusMap.size).toBe(2); + expect(component.statusMap.get(RequestStatusEnum.ACCEPTED)?.length).toBe(2); + expect(component.statusMap.get(RequestStatusEnum.REJECTED)?.length).toBe(1); + }); +}); diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts index bd6e1983ed..8b93b62495 100644 --- a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts @@ -1,17 +1,29 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { Observable, of } from 'rxjs'; -import { NotifyRequestsStatus, NotifyStatuses } from '../notify-requests-status.model'; -import { NotifyRequestsStatusDataService } from 'src/app/core/data/notify-services-status-data.service'; +import { + ChangeDetectionStrategy, + Component, + Input, + OnDestroy, + OnInit, +} from '@angular/core'; +import { Subscription, filter } from 'rxjs'; +import { + NotifyRequestsStatus, + NotifyStatuses, +} from '../notify-requests-status.model'; +import { NotifyRequestsStatusDataService } from '../../../../core/data/notify-services-status-data.service'; import { RequestStatusEnum } from '../notify-status.enum'; - +import { + getFirstCompletedRemoteData, + getRemoteDataPayload, +} from '../../../../core/shared/operators'; +import { hasValue } from '../../../../shared/empty.util'; @Component({ selector: 'ds-notify-requests-status', templateUrl: './notify-requests-status.component.html', styleUrls: ['./notify-requests-status.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class NotifyRequestsStatusComponent { - +export class NotifyRequestsStatusComponent implements OnInit, OnDestroy { /** * The UUID of the item. */ @@ -24,85 +36,57 @@ export class NotifyRequestsStatusComponent { */ statusMap: Map = new Map(); - notifyRequestStatus$: Observable = of( Object.assign(new NotifyRequestsStatus(), { - notifyStatuses: [ - { - serviceName: 'test', - serviceUrl: 'test', - status: RequestStatusEnum.ACCEPTED, - }, - { - serviceName: 'test1', - serviceUrl: 'test', - status: RequestStatusEnum.ACCEPTED, - }, - { - serviceName: 'Review Platform', - serviceUrl: 'test', - status: RequestStatusEnum.ACCEPTED, - }, - { - serviceName: 'Demo Environment', - serviceUrl: 'test', - status: RequestStatusEnum.ACCEPTED, - }, - { - serviceName: 'Additional Information', - serviceUrl: 'test', - status: RequestStatusEnum.ACCEPTED, - }, - { - serviceName: 'Notification Service', - serviceUrl: 'test', - status: RequestStatusEnum.ACCEPTED, - }, - { - serviceName: 'test2', - serviceUrl: 'test', - status: RequestStatusEnum.REJECTED, - }, - { - serviceName: 'test3', - serviceUrl: 'test', - status: RequestStatusEnum.REQUESTED, - }, - { - serviceName: 'test4', - serviceUrl: 'test', - status: RequestStatusEnum.REQUESTED, - } - ], - itemUuid: '8d5fda2d-f380-467e-a86b-0436ac699dab', - })); + /** + * An array of subscriptions. + */ + subs: Subscription[] = []; - constructor( - private notifyInfoService: NotifyRequestsStatusDataService, - ) { } + constructor(private notifyInfoService: NotifyRequestsStatusDataService) {} - ngOnInit(): void { - this.notifyInfoService.getNotifyRequestsStatus(this.itemUuid).subscribe((data) => { - console.log(data, 'asdasdsa'); - }); - - this.notifyRequestStatus$.subscribe((data) => { - this.groupDataByStatus(data); - console.log(this.statusMap); - }); - } + ngOnInit(): void { + this.subs.push( + this.notifyInfoService + .getNotifyRequestsStatus(this.itemUuid) + .pipe( + getFirstCompletedRemoteData(), + filter((data) => hasValue(data)), + getRemoteDataPayload() + ) + .subscribe((data: NotifyRequestsStatus) => { + if (hasValue(data)) { + this.groupDataByStatus(data); + } + }) + ); + } /** * Groups the notify requests status data by status. * @param notifyRequestsStatus The notify requests status data. */ private groupDataByStatus(notifyRequestsStatus: NotifyRequestsStatus): void { - notifyRequestsStatus.notifyStatuses.forEach((notifyStatus: NotifyStatuses) => { - const status = notifyStatus.status; + notifyRequestsStatus.notifyStatus.forEach( + (notifyStatus: NotifyStatuses) => { + const status = notifyStatus.status; - if (!this.statusMap.has(status)) { - this.statusMap.set(status, []); + if (!this.statusMap.has(status)) { + this.statusMap.set(status, []); + } + + this.statusMap.get(status)?.push(notifyStatus); } + ); + } - this.statusMap.get(status)?.push(notifyStatus); + /** + * Lifecycle hook that is called when the component is destroyed. + * Unsubscribes from any active subscriptions. + */ + ngOnDestroy(): void { + this.subs.forEach((sub) => { + if (hasValue(sub)) { + sub.unsubscribe(); + } }); } } diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status.model.ts b/src/app/item-page/simple/notify-requests-status/notify-requests-status.model.ts index ab4e41b2c6..81d393ddde 100644 --- a/src/app/item-page/simple/notify-requests-status/notify-requests-status.model.ts +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status.model.ts @@ -27,13 +27,13 @@ export class NotifyRequestsStatus implements CacheableObject { * The notify statuses. */ @autoserialize - notifyStatuses: NotifyStatuses[]; + notifyStatus: NotifyStatuses[]; /** * The UUID of the item. */ @autoserialize - itemUuid: string; + itemuuid: string; /** * The links associated with the notify requests status. diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status.resource-type.ts b/src/app/item-page/simple/notify-requests-status/notify-requests-status.resource-type.ts index da7ab2c881..53b5545fd4 100644 --- a/src/app/item-page/simple/notify-requests-status/notify-requests-status.resource-type.ts +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status.resource-type.ts @@ -5,4 +5,4 @@ import {ResourceType} from '../../../core/shared/resource-type'; * Needs to be in a separate file to prevent circular * dependencies in webpack. */ -export const NOTIFYREQUEST = new ResourceType('notifyrequest'); +export const NOTIFYREQUEST = new ResourceType('notifyrequests'); diff --git a/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.ts b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.ts index 30393367a3..1ecd084cfd 100644 --- a/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.ts +++ b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.ts @@ -1,12 +1,14 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { Item } from '../../../core/shared/item.model'; import { getFirstCompletedRemoteData, getPaginatedListPayload, getRemoteDataPayload } from '../../../core/shared/operators'; -import { Observable } from 'rxjs'; +import { Observable, filter } from 'rxjs'; import { AlertType } from '../../../shared/alert/aletr-type'; import { FindListOptions } from '../../../core/data/find-list-options.model'; import { RequestParam } from '../../../core/cache/models/request-param.model'; import { QualityAssuranceSourceDataService } from '../../../core/suggestion-notifications/qa/source/quality-assurance-source-data.service'; import { QualityAssuranceSourceObject } from '../../../core/suggestion-notifications/qa/models/quality-assurance-source.model'; +import { PaginatedList } from 'src/app/core/data/paginated-list.model'; +import { hasValue } from 'src/app/shared/empty.util'; @Component({ selector: 'ds-qa-event-notification', @@ -47,6 +49,7 @@ export class QaEventNotificationComponent { .pipe( getFirstCompletedRemoteData(), getRemoteDataPayload(), + filter((pl: PaginatedList) => hasValue(pl)), getPaginatedListPayload(), ); } From 75ac289ff6833ceb8b6d4c91d38ae5790848f44b Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Wed, 22 Nov 2023 16:20:15 +0100 Subject: [PATCH 3/3] [CST-12709] chages --- .../notify-requests-status.component.html | 4 +- .../notify-requests-status.component.spec.ts | 14 +++-- .../notify-requests-status.component.ts | 63 +++++++------------ 3 files changed, 33 insertions(+), 48 deletions(-) diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.html b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.html index 7736e88896..c68255f2ed 100644 --- a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.html +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.html @@ -1,5 +1,5 @@ - - + + diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.spec.ts b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.spec.ts index 1498265ca4..0ec4febc0b 100644 --- a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.spec.ts +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.spec.ts @@ -50,7 +50,9 @@ describe('NotifyRequestsStatusComponent', () => { tick(); expect(notifyInfoServiceSpy.getNotifyRequestsStatus).toHaveBeenCalledWith('testUuid'); - expect(component.statusMap.size).toBe(0); + component.requestMap$.subscribe((map) => { + expect(map.size).toBe(0); + }); })); it('should group data by status', () => { @@ -74,11 +76,13 @@ describe('NotifyRequestsStatusComponent', () => { ], itemUuid: 'testUuid' }); + spyOn(notifyInfoServiceSpy, 'getNotifyRequestsStatus').and.returnValue(createSuccessfulRemoteDataObject$(mockData)); fixture.detectChanges(); (component as any).groupDataByStatus(mockData); - - expect(component.statusMap.size).toBe(2); - expect(component.statusMap.get(RequestStatusEnum.ACCEPTED)?.length).toBe(2); - expect(component.statusMap.get(RequestStatusEnum.REJECTED)?.length).toBe(1); + component.requestMap$.subscribe((map) => { + expect(map.size).toBe(2); + expect(map.get(RequestStatusEnum.ACCEPTED)?.length).toBe(2); + expect(map.get(RequestStatusEnum.REJECTED)?.length).toBe(1); + }); }); }); diff --git a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts index 8b93b62495..a04ed96363 100644 --- a/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts +++ b/src/app/item-page/simple/notify-requests-status/notify-requests-status-component/notify-requests-status.component.ts @@ -2,10 +2,9 @@ import { ChangeDetectionStrategy, Component, Input, - OnDestroy, OnInit, } from '@angular/core'; -import { Subscription, filter } from 'rxjs'; +import { Observable, filter, map } from 'rxjs'; import { NotifyRequestsStatus, NotifyStatuses, @@ -23,70 +22,52 @@ import { hasValue } from '../../../../shared/empty.util'; styleUrls: ['./notify-requests-status.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class NotifyRequestsStatusComponent implements OnInit, OnDestroy { +export class NotifyRequestsStatusComponent implements OnInit { /** * The UUID of the item. */ @Input() itemUuid: string; /** - * Map that stores the status of requests and their corresponding notify statuses. - * The keys of the map are instances of the RequestStatusEnum enum, - * and the values are arrays of NotifyStatuses objects. + * Observable representing the request map. + * The map contains request status enums as keys and arrays of notify statuses as values. */ - statusMap: Map = new Map(); + requestMap$: Observable>; - /** - * An array of subscriptions. - */ - subs: Subscription[] = []; - - constructor(private notifyInfoService: NotifyRequestsStatusDataService) {} + constructor(private notifyInfoService: NotifyRequestsStatusDataService) { } ngOnInit(): void { - this.subs.push( - this.notifyInfoService - .getNotifyRequestsStatus(this.itemUuid) - .pipe( - getFirstCompletedRemoteData(), - filter((data) => hasValue(data)), - getRemoteDataPayload() - ) - .subscribe((data: NotifyRequestsStatus) => { - if (hasValue(data)) { - this.groupDataByStatus(data); - } + this.requestMap$ = this.notifyInfoService + .getNotifyRequestsStatus(this.itemUuid) + .pipe( + getFirstCompletedRemoteData(), + filter((data) => hasValue(data)), + getRemoteDataPayload(), + filter((data: NotifyRequestsStatus) => hasValue(data)), + map((data: NotifyRequestsStatus) => { + return this.groupDataByStatus(data); }) - ); + ); } /** * Groups the notify requests status data by status. * @param notifyRequestsStatus The notify requests status data. */ - private groupDataByStatus(notifyRequestsStatus: NotifyRequestsStatus): void { + private groupDataByStatus(notifyRequestsStatus: NotifyRequestsStatus) { + const statusMap: Map = new Map(); notifyRequestsStatus.notifyStatus.forEach( (notifyStatus: NotifyStatuses) => { const status = notifyStatus.status; - if (!this.statusMap.has(status)) { - this.statusMap.set(status, []); + if (!statusMap.has(status)) { + statusMap.set(status, []); } - this.statusMap.get(status)?.push(notifyStatus); + statusMap.get(status)?.push(notifyStatus); } ); - } - /** - * Lifecycle hook that is called when the component is destroyed. - * Unsubscribes from any active subscriptions. - */ - ngOnDestroy(): void { - this.subs.forEach((sub) => { - if (hasValue(sub)) { - sub.unsubscribe(); - } - }); + return statusMap; } }