From 442426bb2e75002db5975f30cb03eb496f8c5d0d Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Tue, 21 Nov 2023 18:38:49 +0100 Subject: [PATCH] [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.", + }