From 2bf565392a0215d89f6f8a1d1c1ef90b99c0201c Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Fri, 6 Oct 2023 14:46:27 +0200 Subject: [PATCH 01/83] CST-10639 Added new fields in the item-view (Endorsed Reviewed and Dataset) --- .../publication/publication.component.html | 12 ++++++++++++ src/assets/i18n/en.json5 | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/src/app/item-page/simple/item-types/publication/publication.component.html b/src/app/item-page/simple/item-types/publication/publication.component.html index 3749f63964..e5aae24377 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.html +++ b/src/app/item-page/simple/item-types/publication/publication.component.html @@ -84,6 +84,18 @@ [label]="'item.page.uri'"> + + + + + +
{{"item.page.link.full" | translate}} diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 2a22e715cc..2de9e8ef3e 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2410,6 +2410,12 @@ "item.page.citation": "Citation", + "item.page.endorsed-by": "Endorsed", + + "item.page.is-reviewed-by": "Review", + + "item.page.is-supplemented-by": "Dataset", + "item.page.collections": "Collections", "item.page.collections.loading": "Loading...", From 4dd339235f054329d35744ddb38402d020a2735c Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Fri, 6 Oct 2023 15:13:58 +0200 Subject: [PATCH 02/83] CST-10639 Fixed fields in the item-view (Endorsed Reviewed and Dataset) --- .../simple/item-types/publication/publication.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/item-page/simple/item-types/publication/publication.component.html b/src/app/item-page/simple/item-types/publication/publication.component.html index e5aae24377..3014fcb302 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.html +++ b/src/app/item-page/simple/item-types/publication/publication.component.html @@ -89,11 +89,11 @@ [label]="'item.page.endorsed-by'">
From 71adb5b7c895173e5f95d7b7351ca82292309a07 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Fri, 6 Oct 2023 15:17:57 +0200 Subject: [PATCH 03/83] CST-10639 Fixed field in the item-view (Endorsement) --- src/assets/i18n/en.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 2de9e8ef3e..564dfe49ea 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2410,7 +2410,7 @@ "item.page.citation": "Citation", - "item.page.endorsed-by": "Endorsed", + "item.page.endorsed-by": "Endorsement", "item.page.is-reviewed-by": "Review", From 8f63b54d713977c62c6ec775935a2c26e498a7eb Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Mon, 9 Oct 2023 15:55:24 +0200 Subject: [PATCH 04/83] CST-11045 Located component, working on adding new accordion --- .../models/notify-service-submission.model.ts | 25 +++++++++++++++++++ ...eitem-section-form-notify-service.model.ts | 17 +++++++++++++ .../models/workspaceitem-sections.model.ts | 4 +++ .../form/submission-form.component.html | 11 ++++++-- 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/app/core/submission/models/notify-service-submission.model.ts create mode 100644 src/app/core/submission/models/workspaceitem-section-form-notify-service.model.ts diff --git a/src/app/core/submission/models/notify-service-submission.model.ts b/src/app/core/submission/models/notify-service-submission.model.ts new file mode 100644 index 0000000000..f2075103ae --- /dev/null +++ b/src/app/core/submission/models/notify-service-submission.model.ts @@ -0,0 +1,25 @@ +/** + * An interface to represent a notifyService object + */ +export class NotifyServiceObject { + + /** + * The notifyService object + */ + id: string; + + /** + * The access condition name + */ + name: string; + + /** + * Possible start date of the access condition + */ + startDate: string; + + /** + * Possible end date of the access condition + */ + endDate: string; +} diff --git a/src/app/core/submission/models/workspaceitem-section-form-notify-service.model.ts b/src/app/core/submission/models/workspaceitem-section-form-notify-service.model.ts new file mode 100644 index 0000000000..b614eb9140 --- /dev/null +++ b/src/app/core/submission/models/workspaceitem-section-form-notify-service.model.ts @@ -0,0 +1,17 @@ +import {NotifyServiceObject} from './notify-service-submission.model' +/** + * An interface to represent the submission's item accesses condition. + */ +export interface WorkspaceitemSectionNotifyServiceRequestItemDissemination extends NotifyServiceObject { + /** + * The access condition id + */ + id: string; + + /** + * Boolean that indicates whether the current item must be findable via search or browse. + */ + discoverable: boolean; + + +} diff --git a/src/app/core/submission/models/workspaceitem-sections.model.ts b/src/app/core/submission/models/workspaceitem-sections.model.ts index a3ccd49dac..f5747c3326 100644 --- a/src/app/core/submission/models/workspaceitem-sections.model.ts +++ b/src/app/core/submission/models/workspaceitem-sections.model.ts @@ -5,6 +5,7 @@ import { WorkspaceitemSectionUploadObject } from './workspaceitem-section-upload import { WorkspaceitemSectionCcLicenseObject } from './workspaceitem-section-cc-license.model'; import {WorkspaceitemSectionIdentifiersObject} from './workspaceitem-section-identifiers.model'; import { WorkspaceitemSectionSherpaPoliciesObject } from './workspaceitem-section-sherpa-policies.model'; +import { WorkspaceitemSectionNotifyServiceRequestItemDissemination } from './workspaceitem-section-form-notify-service.model'; /** * An interface to represent submission's section object. @@ -25,4 +26,7 @@ export type WorkspaceitemSectionDataType | WorkspaceitemSectionAccessesObject | WorkspaceitemSectionSherpaPoliciesObject | WorkspaceitemSectionIdentifiersObject + | WorkspaceitemSectionNotifyServiceRequestItemDissemination | string; + + diff --git a/src/app/submission/form/submission-form.component.html b/src/app/submission/form/submission-form.component.html index 4a916cfe23..fa04a6793c 100644 --- a/src/app/submission/form/submission-form.component.html +++ b/src/app/submission/form/submission-form.component.html @@ -1,6 +1,7 @@
+

ds-submission-upload-files

@@ -9,7 +10,9 @@
- ds-submission-form-collection

+
+

ds-submission-form-section-add

@@ -28,12 +32,15 @@
+

ds-submission-section-container

+ [sectionData]="object"> +
From 6d794cd51f7de4d8032c747f1320445275a85ff2 Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Wed, 18 Oct 2023 09:29:52 +0200 Subject: [PATCH 05/83] [CST-12235] LDN inbox mechanism for home (partial commit) --- .../notify-info/notify-info.service.ts | 19 ++++++++- src/app/home-page/home-page.component.ts | 39 +++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/app/core/coar-notify/notify-info/notify-info.service.ts b/src/app/core/coar-notify/notify-info/notify-info.service.ts index a88181a9ab..b489677634 100644 --- a/src/app/core/coar-notify/notify-info/notify-info.service.ts +++ b/src/app/core/coar-notify/notify-info/notify-info.service.ts @@ -1,14 +1,17 @@ import { Injectable } from '@angular/core'; -import { getFirstSucceededRemoteData } from '../../shared/operators'; +import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../../shared/operators'; import { ConfigurationDataService } from '../../data/configuration-data.service'; import { map, Observable } from 'rxjs'; import { DefaultAppConfig } from '../../../../config/default-app-config'; +import { ConfigurationProperty } from '../../shared/configuration-property.model'; @Injectable({ providedIn: 'root' }) export class NotifyInfoService { + private relationLink = 'http://www.w3.org/ns/ldp#inbox'; + constructor( private configService: ConfigurationDataService, ) {} @@ -24,6 +27,16 @@ export class NotifyInfoService { ); } + getCoarLdnLocalInboxUrl(): Observable { + return this.configService.findByPropertyName('ldn.notify.local-inbox-endpoint').pipe( + getFirstSucceededRemoteData(), + getRemoteDataPayload(), + map((response: ConfigurationProperty) => { + return response.values; + }) + ); + } + getCoarLdnRestApiUrl(): string { const appConfig = new DefaultAppConfig(); const restConfig = appConfig.rest; @@ -35,4 +48,8 @@ export class NotifyInfoService { return `${ssl ? 'https' : 'http'}://${host}:${port}${namespace}`; } + + getRelationLink(): string{ + return this.relationLink; + } } diff --git a/src/app/home-page/home-page.component.ts b/src/app/home-page/home-page.component.ts index c151cbbb16..1e0833c0d1 100644 --- a/src/app/home-page/home-page.component.ts +++ b/src/app/home-page/home-page.component.ts @@ -1,9 +1,14 @@ -import { Component, OnInit } from '@angular/core'; -import { map } from 'rxjs/operators'; +import { Component, Inject, OnInit, PLATFORM_ID } from '@angular/core'; +import { map, switchMap } from 'rxjs/operators'; import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { Site } from '../core/shared/site.model'; import { environment } from '../../environments/environment'; +import { isPlatformServer } from '@angular/common'; +import { ServerResponseService } from '../core/services/server-response.service'; +import { NotifyInfoService } from '../core/coar-notify/notify-info/notify-info.service'; +import { LinkDefinition, LinkHeadService } from '../core/services/link-head.service'; + @Component({ selector: 'ds-home-page', styleUrls: ['./home-page.component.scss'], @@ -13,10 +18,24 @@ export class HomePageComponent implements OnInit { site$: Observable; recentSubmissionspageSize: number; + constructor( private route: ActivatedRoute, + private responseService: ServerResponseService, + private notifyInfoService: NotifyInfoService, + protected linkHeadService: LinkHeadService, + @Inject(PLATFORM_ID) private platformId: string ) { this.recentSubmissionspageSize = environment.homePage.recentSubmissions.pageSize; + this.notifyInfoService.isCoarConfigEnabled().pipe( + switchMap((coarLdnEnabled: boolean) => { + if (coarLdnEnabled) { + return this.notifyInfoService.getCoarLdnLocalInboxUrl(); + } + }) + ).subscribe((coarRestApiUrls: string[]) => { + this.initPageLinks(coarRestApiUrls); + }); } ngOnInit(): void { @@ -24,4 +43,18 @@ export class HomePageComponent implements OnInit { map((data) => data.site as Site), ); } + + private initPageLinks(coarRestApiUrls: string[]): void { + const rel = this.notifyInfoService.getRelationLink(); + coarRestApiUrls.forEach((coarRestApiUrl: string) => { + let tag: LinkDefinition = { + href: coarRestApiUrl, + rel: rel + }; + this.linkHeadService.addTag(tag); + if (isPlatformServer(this.platformId)) { + this.responseService.setHeader('Link', `<${coarRestApiUrl}>; rel="${rel}"`); + } + }); + } } From 318f057ca42771c56775b51e3a4f93f8d95f16ba Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Tue, 24 Oct 2023 11:06:38 +0200 Subject: [PATCH 06/83] [CST-12145] partial commit --- .../quality-assurance-event-data.service.ts | 26 +++++++++++++ .../quality-assurance-topic-data.service.ts | 29 ++++++++++++++ src/app/item-page/item-page.module.ts | 2 + .../item-page/simple/item-page.component.html | 1 + .../item-page/simple/item-page.component.ts | 2 +- .../qa-event-notification.component.html | 1 + .../qa-event-notification.component.scss | 0 .../qa-event-notification.component.spec.ts | 23 +++++++++++ .../qa-event-notification.component.ts | 34 ++++++++++++++++ .../my-dspace-page.component.html | 1 + .../my-dspace-page/my-dspace-page.module.ts | 4 +- ...ace-qa-events-notifications.component.html | 1 + ...ace-qa-events-notifications.component.scss | 0 ...-qa-events-notifications.component.spec.ts | 23 +++++++++++ ...space-qa-events-notifications.component.ts | 39 +++++++++++++++++++ 15 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 src/app/item-page/simple/qa-event-notification/qa-event-notification.component.html create mode 100644 src/app/item-page/simple/qa-event-notification/qa-event-notification.component.scss create mode 100644 src/app/item-page/simple/qa-event-notification/qa-event-notification.component.spec.ts create mode 100644 src/app/item-page/simple/qa-event-notification/qa-event-notification.component.ts create mode 100644 src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.html create mode 100644 src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.scss create mode 100644 src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.spec.ts create mode 100644 src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts diff --git a/src/app/core/suggestion-notifications/qa/events/quality-assurance-event-data.service.ts b/src/app/core/suggestion-notifications/qa/events/quality-assurance-event-data.service.ts index 7f7e68afaa..5e9a4f430b 100644 --- a/src/app/core/suggestion-notifications/qa/events/quality-assurance-event-data.service.ts +++ b/src/app/core/suggestion-notifications/qa/events/quality-assurance-event-data.service.ts @@ -84,6 +84,32 @@ export class QualityAssuranceEventDataService extends IdentifiableDataService[]): Observable>> { + options.searchParams = [ + { + fieldName: 'topic', + fieldValue: topic + } + ]; + + if (hasValue(target)) { + options.searchParams.push({ + fieldName: 'target', + fieldValue: target + }); + } + + return this.searchData.searchBy('findByTopic', options, true, true, ...linksToFollow); + } + /** * Clear findByTopic requests from cache */ diff --git a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts index 2bf5195bf1..0f52771f51 100644 --- a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts +++ b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts @@ -16,6 +16,7 @@ import { IdentifiableDataService } from '../../../data/base/identifiable-data.se import { dataService } from '../../../data/base/data-service.decorator'; import { QUALITY_ASSURANCE_TOPIC_OBJECT } from '../models/quality-assurance-topic-object.resource-type'; import { FindAllData, FindAllDataImpl } from '../../../data/base/find-all-data'; +import { hasValue } from 'src/app/shared/empty.util'; /** * The service handling all Quality Assurance topic REST requests. @@ -62,6 +63,34 @@ export class QualityAssuranceTopicDataService extends IdentifiableDataService>. + */ + public getTopicsByTargetAndSource(target: string, source?: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { + options.searchParams = [ + { + fieldName: 'target', + fieldValue: target + } + ]; + + if (hasValue(source)) { + options.searchParams.push({ + fieldName: 'source', + fieldValue: source + }); + } + + return this.findAllData.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + } + /** * Clear FindAll topics requests from cache */ diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index a8d41d1535..5aa1b6e508 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -60,6 +60,7 @@ import { ThemedItemAlertsComponent } from './alerts/themed-item-alerts.component import { ThemedFullFileSectionComponent } from './full/field-components/file-section/themed-full-file-section.component'; +import { QaEventNotificationComponent } from './simple/qa-event-notification/qa-event-notification.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -103,6 +104,7 @@ const DECLARATIONS = [ ItemAlertsComponent, ThemedItemAlertsComponent, BitstreamRequestACopyPageComponent, + QaEventNotificationComponent ]; @NgModule({ diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index cc9983bb35..37a5e0c4cb 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -2,6 +2,7 @@
+ diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index b9be6bebfb..9d0867c9ef 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -32,7 +32,7 @@ import { LinkDefinition, LinkHeadService } from '../../core/services/link-head.s styleUrls: ['./item-page.component.scss'], templateUrl: './item-page.component.html', changeDetection: ChangeDetectionStrategy.OnPush, - animations: [fadeInOut] + animations: [fadeInOut], }) export class ItemPageComponent implements OnInit, OnDestroy { diff --git a/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.html b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.html new file mode 100644 index 0000000000..807c15a19c --- /dev/null +++ b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.html @@ -0,0 +1 @@ +

qa-event-notification works!

diff --git a/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.scss b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.spec.ts b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.spec.ts new file mode 100644 index 0000000000..1be125c73c --- /dev/null +++ b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { QaEventNotificationComponent } from './qa-event-notification.component'; + +describe('QaEventNotificationComponent', () => { + let component: QaEventNotificationComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ QaEventNotificationComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(QaEventNotificationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); 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 new file mode 100644 index 0000000000..b5163e0757 --- /dev/null +++ b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.ts @@ -0,0 +1,34 @@ +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { Item } from '../../../core/shared/item.model'; +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { QualityAssuranceEventDataService } from '../../../core/suggestion-notifications/qa/events/quality-assurance-event-data.service'; +import { QualityAssuranceTopicDataService } from '../../../core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service'; + +@Component({ + selector: 'ds-qa-event-notification', + templateUrl: './qa-event-notification.component.html', + styleUrls: ['./qa-event-notification.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [QualityAssuranceTopicDataService, QualityAssuranceEventDataService] +}) +export class QaEventNotificationComponent { + + @Input() item: Item; + + constructor( + protected qualityAssuranceEventDataService: QualityAssuranceEventDataService, + protected qualityAssuranceTopicDataService: QualityAssuranceTopicDataService, + ) { } + + ngOnInit(): void { + this.getTopics(); + } + + getTopics(): void { + this.qualityAssuranceTopicDataService.getTopicsByTargetAndSource(this.item.id, 'coar-notify', {}, true, true).pipe( + getFirstCompletedRemoteData(), + ).subscribe((topics) => { + console.log(topics); + }); + } +} diff --git a/src/app/my-dspace-page/my-dspace-page.component.html b/src/app/my-dspace-page/my-dspace-page.component.html index c5e49b0cec..70bcf1b7bc 100644 --- a/src/app/my-dspace-page/my-dspace-page.component.html +++ b/src/app/my-dspace-page/my-dspace-page.component.html @@ -1,4 +1,5 @@
+
diff --git a/src/app/my-dspace-page/my-dspace-page.module.ts b/src/app/my-dspace-page/my-dspace-page.module.ts index b75806cec7..60726bacc4 100644 --- a/src/app/my-dspace-page/my-dspace-page.module.ts +++ b/src/app/my-dspace-page/my-dspace-page.module.ts @@ -16,6 +16,7 @@ import { ThemedMyDSpacePageComponent } from './themed-my-dspace-page.component'; import { SearchModule } from '../shared/search/search.module'; import { UploadModule } from '../shared/upload/upload.module'; import { SuggestionNotificationsModule } from '../suggestion-notifications/suggestion-notifications.module'; +import { MyDspaceQaEventsNotificationsComponent } from './my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component'; const DECLARATIONS = [ MyDSpacePageComponent, @@ -23,7 +24,8 @@ const DECLARATIONS = [ MyDSpaceNewSubmissionComponent, CollectionSelectorComponent, MyDSpaceNewSubmissionDropdownComponent, - MyDSpaceNewExternalDropdownComponent + MyDSpaceNewExternalDropdownComponent, + MyDspaceQaEventsNotificationsComponent, ]; @NgModule({ diff --git a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.html b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.html new file mode 100644 index 0000000000..db0611e8f8 --- /dev/null +++ b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.html @@ -0,0 +1 @@ +

my-dspace-qa-events-notifications works!

diff --git a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.scss b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.spec.ts b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.spec.ts new file mode 100644 index 0000000000..177dd92fd0 --- /dev/null +++ b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MyDspaceQaEventsNotificationsComponent } from './my-dspace-qa-events-notifications.component'; + +describe('MyDspaceQaEventsNotificationsComponent', () => { + let component: MyDspaceQaEventsNotificationsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ MyDspaceQaEventsNotificationsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(MyDspaceQaEventsNotificationsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts new file mode 100644 index 0000000000..d0c42d9bcb --- /dev/null +++ b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts @@ -0,0 +1,39 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { QualityAssuranceSourceDataService } from '../../core/suggestion-notifications/qa/source/quality-assurance-source-data.service'; +import { getFirstCompletedRemoteData } from 'src/app/core/shared/operators'; +import { map } from 'rxjs'; +import { RemoteData } from 'src/app/core/data/remote-data'; +import { PaginatedList } from 'src/app/core/data/paginated-list.model'; +import { QualityAssuranceSourceObject } from 'src/app/core/suggestion-notifications/qa/models/quality-assurance-source.model'; + +@Component({ + selector: 'ds-my-dspace-qa-events-notifications', + templateUrl: './my-dspace-qa-events-notifications.component.html', + styleUrls: ['./my-dspace-qa-events-notifications.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class MyDspaceQaEventsNotificationsComponent { + + constructor(private qualityAssuranceSourceDataService: QualityAssuranceSourceDataService) { } + + ngOnInit(): void { + this.getSources(); + } + + getSources() { + this.qualityAssuranceSourceDataService.getSource('coar-notify') + .pipe( + getFirstCompletedRemoteData(), + map((rd: RemoteData) => { + if (rd.hasSucceeded) { + return rd.payload; + } else { + throw new Error('Can\'t retrieve Quality Assurance source'); + } + }) + ) + .subscribe((sources) => { + console.log(sources); + }); + } +} From 422a223c40718b8a89c81caeff913208fc5227bc Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Tue, 24 Oct 2023 15:14:55 +0200 Subject: [PATCH 07/83] [CST-12235] support for the LDN inbox for root & /home & /item/:uuid pages --- .../notify-info/notify-info.service.ts | 19 ++++-- src/app/home-page/home-page.component.ts | 47 +++++++++++--- .../full/full-item-page.component.spec.ts | 2 + .../full/full-item-page.component.ts | 4 +- .../simple/item-page.component.spec.ts | 9 +++ .../item-page/simple/item-page.component.ts | 61 ++++++++++++++++++- 6 files changed, 125 insertions(+), 17 deletions(-) diff --git a/src/app/core/coar-notify/notify-info/notify-info.service.ts b/src/app/core/coar-notify/notify-info/notify-info.service.ts index b489677634..4b2d572d3c 100644 --- a/src/app/core/coar-notify/notify-info/notify-info.service.ts +++ b/src/app/core/coar-notify/notify-info/notify-info.service.ts @@ -10,7 +10,10 @@ import { ConfigurationProperty } from '../../shared/configuration-property.model }) export class NotifyInfoService { - private relationLink = 'http://www.w3.org/ns/ldp#inbox'; + /** + * The relation link for the inbox + */ + private _inboxRelationLink = 'http://www.w3.org/ns/ldp#inbox'; constructor( private configService: ConfigurationDataService, @@ -27,7 +30,11 @@ export class NotifyInfoService { ); } - getCoarLdnLocalInboxUrl(): Observable { + /** + * Get the url of the local inbox from the REST configuration + * @returns the url of the local inbox + */ + getCoarLdnLocalInboxUrls(): Observable { return this.configService.findByPropertyName('ldn.notify.local-inbox-endpoint').pipe( getFirstSucceededRemoteData(), getRemoteDataPayload(), @@ -49,7 +56,11 @@ export class NotifyInfoService { return `${ssl ? 'https' : 'http'}://${host}:${port}${namespace}`; } - getRelationLink(): string{ - return this.relationLink; + /** + * Method to get the relation link for the inbox + * @returns the relation link for the inbox + */ + getInboxRelationLink(): string { + return this._inboxRelationLink; } } diff --git a/src/app/home-page/home-page.component.ts b/src/app/home-page/home-page.component.ts index 1e0833c0d1..585fd06fe6 100644 --- a/src/app/home-page/home-page.component.ts +++ b/src/app/home-page/home-page.component.ts @@ -1,23 +1,28 @@ -import { Component, Inject, OnInit, PLATFORM_ID } from '@angular/core'; +import { Component, Inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core'; import { map, switchMap } from 'rxjs/operators'; import { ActivatedRoute } from '@angular/router'; -import { Observable, of } from 'rxjs'; +import { Observable } from 'rxjs'; import { Site } from '../core/shared/site.model'; import { environment } from '../../environments/environment'; import { isPlatformServer } from '@angular/common'; import { ServerResponseService } from '../core/services/server-response.service'; import { NotifyInfoService } from '../core/coar-notify/notify-info/notify-info.service'; import { LinkDefinition, LinkHeadService } from '../core/services/link-head.service'; +import { isNotEmpty } from '../shared/empty.util'; @Component({ selector: 'ds-home-page', styleUrls: ['./home-page.component.scss'], templateUrl: './home-page.component.html' }) -export class HomePageComponent implements OnInit { +export class HomePageComponent implements OnInit, OnDestroy { site$: Observable; recentSubmissionspageSize: number; + /** + * An array of LinkDefinition objects representing inbox links for the home page. + */ + inboxLinks: LinkDefinition[] = []; constructor( private route: ActivatedRoute, @@ -27,14 +32,18 @@ export class HomePageComponent implements OnInit { @Inject(PLATFORM_ID) private platformId: string ) { this.recentSubmissionspageSize = environment.homePage.recentSubmissions.pageSize; + // Get COAR REST API URLs from REST configuration + // only if COAR configuration is enabled this.notifyInfoService.isCoarConfigEnabled().pipe( switchMap((coarLdnEnabled: boolean) => { if (coarLdnEnabled) { - return this.notifyInfoService.getCoarLdnLocalInboxUrl(); + return this.notifyInfoService.getCoarLdnLocalInboxUrls(); } }) ).subscribe((coarRestApiUrls: string[]) => { - this.initPageLinks(coarRestApiUrls); + if (coarRestApiUrls.length > 0) { + this.initPageLinks(coarRestApiUrls); + } }); } @@ -44,17 +53,37 @@ export class HomePageComponent implements OnInit { ); } + /** + * Initializes page links for COAR REST API URLs. + * @param coarRestApiUrls An array of COAR REST API URLs. + */ private initPageLinks(coarRestApiUrls: string[]): void { - const rel = this.notifyInfoService.getRelationLink(); + const rel = this.notifyInfoService.getInboxRelationLink(); + let links = ''; coarRestApiUrls.forEach((coarRestApiUrl: string) => { + // Add link to head let tag: LinkDefinition = { href: coarRestApiUrl, rel: rel }; + this.inboxLinks.push(tag); this.linkHeadService.addTag(tag); - if (isPlatformServer(this.platformId)) { - this.responseService.setHeader('Link', `<${coarRestApiUrl}>; rel="${rel}"`); - } + + links = links + (isNotEmpty(links) ? ', ' : '') + `<${coarRestApiUrl}> ; rel="${rel}"`; + }); + + if (isPlatformServer(this.platformId)) { + // Add link to response header + this.responseService.setHeader('Link', links); + } + } + + /** + * It removes the inbox links from the head of the html. + */ + ngOnDestroy(): void { + this.inboxLinks.forEach((link: LinkDefinition) => { + this.linkHeadService.removeTag(`href='${link.href}'`); }); } } diff --git a/src/app/item-page/full/full-item-page.component.spec.ts b/src/app/item-page/full/full-item-page.component.spec.ts index 9fc078c2cd..c1917f77f4 100644 --- a/src/app/item-page/full/full-item-page.component.spec.ts +++ b/src/app/item-page/full/full-item-page.component.spec.ts @@ -23,6 +23,7 @@ import { RemoteData } from '../../core/data/remote-data'; import { ServerResponseService } from '../../core/services/server-response.service'; import { SignpostingDataService } from '../../core/data/signposting-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; +import { NotifyInfoService } from '../../core/coar-notify/notify-info/notify-info.service'; const mockItem: Item = Object.assign(new Item(), { bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), @@ -122,6 +123,7 @@ describe('FullItemPageComponent', () => { { provide: ServerResponseService, useValue: serverResponseService }, { provide: SignpostingDataService, useValue: signpostingDataService }, { provide: LinkHeadService, useValue: linkHeadService }, + { provide: NotifyInfoService, useValue: {} }, { provide: PLATFORM_ID, useValue: 'server' } ], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/item-page/full/full-item-page.component.ts b/src/app/item-page/full/full-item-page.component.ts index 31dd2c5fc2..da79fc04cc 100644 --- a/src/app/item-page/full/full-item-page.component.ts +++ b/src/app/item-page/full/full-item-page.component.ts @@ -19,6 +19,7 @@ import { AuthorizationDataService } from '../../core/data/feature-authorization/ import { ServerResponseService } from '../../core/services/server-response.service'; import { SignpostingDataService } from '../../core/data/signposting-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; +import { NotifyInfoService } from '../../core/coar-notify/notify-info/notify-info.service'; /** * This component renders a full item page. @@ -55,9 +56,10 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit, protected responseService: ServerResponseService, protected signpostingDataService: SignpostingDataService, protected linkHeadService: LinkHeadService, + protected notifyInfoService: NotifyInfoService, @Inject(PLATFORM_ID) protected platformId: string, ) { - super(route, router, items, authService, authorizationService, responseService, signpostingDataService, linkHeadService, platformId); + super(route, router, items, authService, authorizationService, responseService, signpostingDataService, linkHeadService,notifyInfoService, platformId); } /*** AoT inheritance fix, will hopefully be resolved in the near future **/ diff --git a/src/app/item-page/simple/item-page.component.spec.ts b/src/app/item-page/simple/item-page.component.spec.ts index b3202108f4..b8354496da 100644 --- a/src/app/item-page/simple/item-page.component.spec.ts +++ b/src/app/item-page/simple/item-page.component.spec.ts @@ -26,6 +26,7 @@ import { ServerResponseService } from '../../core/services/server-response.servi import { SignpostingDataService } from '../../core/data/signposting-data.service'; import { LinkDefinition, LinkHeadService } from '../../core/services/link-head.service'; import { SignpostingLink } from '../../core/data/signposting-links.model'; +import { NotifyInfoService } from '../../core/coar-notify/notify-info/notify-info.service'; const mockItem: Item = Object.assign(new Item(), { bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), @@ -62,6 +63,7 @@ describe('ItemPageComponent', () => { let serverResponseService: jasmine.SpyObj; let signpostingDataService: jasmine.SpyObj; let linkHeadService: jasmine.SpyObj; + let notifyInfoService: jasmine.SpyObj; const mockMetadataService = { /* eslint-disable no-empty,@typescript-eslint/no-empty-function */ @@ -94,6 +96,12 @@ describe('ItemPageComponent', () => { removeTag: jasmine.createSpy('removeTag'), }); + notifyInfoService = jasmine.createSpyObj('NotifyInfoService', { + getInboxRelationLink: 'http://www.w3.org/ns/ldp#inbox', + isCoarConfigEnabled: observableOf(true), + getCoarLdnLocalInboxUrls: observableOf(['http://test.org', 'http://test2.org']), + }); + TestBed.configureTestingModule({ imports: [TranslateModule.forRoot({ loader: { @@ -112,6 +120,7 @@ describe('ItemPageComponent', () => { { provide: ServerResponseService, useValue: serverResponseService }, { provide: SignpostingDataService, useValue: signpostingDataService }, { provide: LinkHeadService, useValue: linkHeadService }, + { provide: NotifyInfoService, useValue: notifyInfoService}, { provide: PLATFORM_ID, useValue: 'server' }, ], diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index b9be6bebfb..2e4e357572 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -2,8 +2,8 @@ import { ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit, PLATFORM import { ActivatedRoute, Router } from '@angular/router'; import { isPlatformServer } from '@angular/common'; -import { Observable } from 'rxjs'; -import { map, take } from 'rxjs/operators'; +import { Observable, combineLatest } from 'rxjs'; +import { map, switchMap, take } from 'rxjs/operators'; import { ItemDataService } from '../../core/data/item-data.service'; import { RemoteData } from '../../core/data/remote-data'; @@ -21,6 +21,7 @@ import { SignpostingDataService } from '../../core/data/signposting-data.service import { SignpostingLink } from '../../core/data/signposting-links.model'; import { isNotEmpty } from '../../shared/empty.util'; import { LinkDefinition, LinkHeadService } from '../../core/services/link-head.service'; +import { NotifyInfoService } from 'src/app/core/coar-notify/notify-info/notify-info.service'; /** * This component renders a simple item page. @@ -68,6 +69,13 @@ export class ItemPageComponent implements OnInit, OnDestroy { */ signpostingLinks: SignpostingLink[] = []; + /** + * An array of LinkDefinition objects representing inbox links for the item page. + */ + inboxTags: LinkDefinition[] = []; + + coarRestApiUrls: string[] = []; + constructor( protected route: ActivatedRoute, protected router: Router, @@ -77,6 +85,7 @@ export class ItemPageComponent implements OnInit, OnDestroy { protected responseService: ServerResponseService, protected signpostingDataService: SignpostingDataService, protected linkHeadService: LinkHeadService, + protected notifyInfoService: NotifyInfoService, @Inject(PLATFORM_ID) protected platformId: string ) { this.initPageLinks(); @@ -106,7 +115,8 @@ export class ItemPageComponent implements OnInit, OnDestroy { */ private initPageLinks(): void { this.route.params.subscribe(params => { - this.signpostingDataService.getLinks(params.id).pipe(take(1)).subscribe((signpostingLinks: SignpostingLink[]) => { + combineLatest([this.signpostingDataService.getLinks(params.id).pipe(take(1)), this.getCoarLdnLocalInboxUrls()]) + .subscribe(([signpostingLinks, coarRestApiUrls]) => { let links = ''; this.signpostingLinks = signpostingLinks; @@ -124,6 +134,11 @@ export class ItemPageComponent implements OnInit, OnDestroy { this.linkHeadService.addTag(tag); }); + if (coarRestApiUrls.length > 0) { + let inboxLinks = this.initPageInboxLinks(coarRestApiUrls); + links = links + (isNotEmpty(links) ? ', ' : '') + inboxLinks; + } + if (isPlatformServer(this.platformId)) { this.responseService.setHeader('Link', links); } @@ -131,9 +146,49 @@ export class ItemPageComponent implements OnInit, OnDestroy { }); } + /** + * Sets the COAR LDN local inbox URL if COAR configuration is enabled. + * If the COAR LDN local inbox URL is retrieved successfully, initializes the page inbox links. + */ + private getCoarLdnLocalInboxUrls(): Observable { + return this.notifyInfoService.isCoarConfigEnabled().pipe( + switchMap((coarLdnEnabled: boolean) => { + if (coarLdnEnabled) { + return this.notifyInfoService.getCoarLdnLocalInboxUrls(); + } + }) + ); + } + + /** + * Initializes the page inbox links. + * @param coarRestApiUrls - An array of COAR REST API URLs. + */ + private initPageInboxLinks(coarRestApiUrls: string[]): string { + const rel = this.notifyInfoService.getInboxRelationLink(); + let links = ''; + + coarRestApiUrls.forEach((coarRestApiUrl: string) => { + // Add link to head + let tag: LinkDefinition = { + href: coarRestApiUrl, + rel: rel + }; + this.inboxTags.push(tag); + this.linkHeadService.addTag(tag); + + links = links + (isNotEmpty(links) ? ', ' : '') + `<${coarRestApiUrl}> ; rel="${rel}"`; + }); + + return links; + } + ngOnDestroy(): void { this.signpostingLinks.forEach((link: SignpostingLink) => { this.linkHeadService.removeTag(`href='${link.href}'`); }); + this.inboxTags.forEach((link: LinkDefinition) => { + this.linkHeadService.removeTag(`href='${link.href}'`); + }); } } From 494295cd97ce81bbb45b73d515b9656528326833 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Tue, 24 Oct 2023 15:26:11 +0200 Subject: [PATCH 08/83] CST-11045 added sections parts --- ...eitem-section-form-notify-service.model.ts | 16 ++- .../ldn-service/ldn-service.component.html | 0 .../ldn-service/ldn-service.component.scss | 0 .../ldn-service/ldn-service.component.spec.ts | 23 ++++ .../ldn-service/ldn-service.component.ts | 129 ++++++++++++++++++ .../sections/ldn-service/ldn-service.model.ts | 27 ++++ src/app/submission/sections/sections-type.ts | 1 + src/app/submission/submission.module.ts | 3 + 8 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 src/app/submission/sections/ldn-service/ldn-service.component.html create mode 100644 src/app/submission/sections/ldn-service/ldn-service.component.scss create mode 100644 src/app/submission/sections/ldn-service/ldn-service.component.spec.ts create mode 100644 src/app/submission/sections/ldn-service/ldn-service.component.ts create mode 100644 src/app/submission/sections/ldn-service/ldn-service.model.ts diff --git a/src/app/core/submission/models/workspaceitem-section-form-notify-service.model.ts b/src/app/core/submission/models/workspaceitem-section-form-notify-service.model.ts index b614eb9140..c952dc6100 100644 --- a/src/app/core/submission/models/workspaceitem-section-form-notify-service.model.ts +++ b/src/app/core/submission/models/workspaceitem-section-form-notify-service.model.ts @@ -1,17 +1,21 @@ import {NotifyServiceObject} from './notify-service-submission.model' +import { LdnService } from '../../../admin/admin-ldn-services/ldn-services-model/ldn-services.model'; /** - * An interface to represent the submission's item accesses condition. + * An interface to represent the submission's item ldn-services condition. */ export interface WorkspaceitemSectionNotifyServiceRequestItemDissemination extends NotifyServiceObject { /** - * The access condition id + * The ldn-review service */ - id: string; + reviewService: LdnService; /** - * Boolean that indicates whether the current item must be findable via search or browse. + * The ldn-endorse service */ - discoverable: boolean; - + endorseService: LdnService; + /** + * The ldn-ingest service + */ + ingestService: LdnService; } diff --git a/src/app/submission/sections/ldn-service/ldn-service.component.html b/src/app/submission/sections/ldn-service/ldn-service.component.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/submission/sections/ldn-service/ldn-service.component.scss b/src/app/submission/sections/ldn-service/ldn-service.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/submission/sections/ldn-service/ldn-service.component.spec.ts b/src/app/submission/sections/ldn-service/ldn-service.component.spec.ts new file mode 100644 index 0000000000..ec36f1f010 --- /dev/null +++ b/src/app/submission/sections/ldn-service/ldn-service.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LdnServiceComponent } from './ldn-service.component'; + +describe('LdnServiceComponent', () => { + let component: LdnServiceComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LdnServiceComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(LdnServiceComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/submission/sections/ldn-service/ldn-service.component.ts b/src/app/submission/sections/ldn-service/ldn-service.component.ts new file mode 100644 index 0000000000..6690395e72 --- /dev/null +++ b/src/app/submission/sections/ldn-service/ldn-service.component.ts @@ -0,0 +1,129 @@ +import { ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core'; +import { DynamicFormControlEvent } from '@ng-dynamic-forms/core'; +import { Observable, Subscription } from 'rxjs'; +import { SectionModelComponent } from '../models/section.model'; +import { renderSectionFor } from '../sections-decorator'; +import { SectionsType } from '../sections-type'; +import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner'; +import { FormComponent } from '../../../shared/form/form.component'; +import { CollectionDataService } from '../../../core/data/collection-data.service'; +import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; +import { SectionFormOperationsService } from '../form/section-form-operations.service'; +import { FormService } from '../../../shared/form/form.service'; +import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; +import { SectionsService } from '../sections.service'; +import { SubmissionService } from '../../submission.service'; +import { TranslateService } from '@ngx-translate/core'; +import { SectionDataObject } from '../models/section-data.model'; +import { + WorkspaceitemSectionNotifyServiceRequestItemDissemination +} from '../../../core/submission/models/workspaceitem-section-form-notify-service.model'; +import { hasValue } from '../../../shared/empty.util'; +/** + * This component represents a section that contains the submission ldn-service form. + */ +@Component({ + selector: 'ds-ldn-service', + templateUrl: './ldn-service.component.html', + styleUrls: ['./ldn-service.component.scss'] +}) +@renderSectionFor(SectionsType.LdnService) +export class LdnServiceComponent extends SectionModelComponent { + + /** + * The [[JsonPatchOperationPathCombiner]] object + * @type {JsonPatchOperationPathCombiner} + */ + protected pathCombiner: JsonPatchOperationPathCombiner; + + /** + * Array to track all subscriptions and unsubscribe them onDestroy + * @type {Array} + */ + protected subs: Subscription[] = []; + + /** + * A boolean representing if div should start collapsed + */ + public isCollapsed = false; + + /** + * The FormComponent reference + */ + @ViewChild('formRef') private formRef: FormComponent; + + /** + * Initialize instance variables + * + * @param {ChangeDetectorRef} changeDetectorRef + * @param {CollectionDataService} collectionDataService + * @param {FormBuilderService} formBuilderService + * @param {SectionFormOperationsService} formOperationsService + * @param {FormService} formService + * @param {JsonPatchOperationsBuilder} operationsBuilder + * @param {SectionsService} sectionService + * @param {SubmissionService} submissionService + * @param {TranslateService} translateService + * @param {string} injectedCollectionId + * @param {SectionDataObject} injectedSectionData + * @param {string} injectedSubmissionId + */ + constructor(protected changeDetectorRef: ChangeDetectorRef, + protected collectionDataService: CollectionDataService, + protected formBuilderService: FormBuilderService, + protected formOperationsService: SectionFormOperationsService, + protected formService: FormService, + protected operationsBuilder: JsonPatchOperationsBuilder, + protected sectionService: SectionsService, + protected submissionService: SubmissionService, + protected translateService: TranslateService, + @Inject('collectionIdProvider') public injectedCollectionId: string, + @Inject('sectionDataProvider') public injectedSectionData: SectionDataObject, + @Inject('submissionIdProvider') public injectedSubmissionId: string) { + super(injectedCollectionId, injectedSectionData, injectedSubmissionId); + } + + /** + * Initialize all instance variables + */ + onSectionInit() { + this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionData.id); + this.subs.push( + this.sectionService.getSectionData(this.submissionId, this.sectionData.id, this.sectionData.sectionType) + .subscribe((ldnServicesSection: WorkspaceitemSectionNotifyServiceRequestItemDissemination) => { + console.log(ldnServicesSection); + }) + ); + } + + + + /** + * Method called when a form dfChange event is fired. + * Dispatch form operations based on changes. + */ + onChange(event: DynamicFormControlEvent) { + const path = this.formOperationsService.getFieldPathSegmentedFromChangeEvent(event); + const value = this.formOperationsService.getFieldValueFromChangeEvent(event); + if (value) { + this.operationsBuilder.add(this.pathCombiner.getPath(path), value.value.toString(), false, true); + this.sectionService.dispatchRemoveSectionErrors(this.submissionId, this.sectionData.id); + } else { + this.operationsBuilder.remove(this.pathCombiner.getPath(path)); + } + } + + /** + * Unsubscribe from all subscriptions + */ + onSectionDestroy() { + this.subs + .filter((subscription) => hasValue(subscription)) + .forEach((subscription) => subscription.unsubscribe()); + } + + protected getSectionStatus(): Observable { + return undefined; + } + +} diff --git a/src/app/submission/sections/ldn-service/ldn-service.model.ts b/src/app/submission/sections/ldn-service/ldn-service.model.ts new file mode 100644 index 0000000000..fb441dd362 --- /dev/null +++ b/src/app/submission/sections/ldn-service/ldn-service.model.ts @@ -0,0 +1,27 @@ +export const SECTION_LDN_SERVICE_FORM_LAYOUT = { + + granted: { + element: { + container: 'custom-control custom-checkbox pl-1', + control: 'custom-control-input', + label: 'custom-control-label pt-1' + } + } +}; + +export const SECTION_LDN_SERVICE_FORM_MODEL = [ + { + id: 'granted', + label: 'submission.sections.license.granted-label', + required: true, + value: false, + validators: { + required: null + }, + errorMessages: { + required: 'submission.sections.license.required', + notgranted: 'submission.sections.license.notgranted' + }, + type: 'CHECKBOX', + } +]; diff --git a/src/app/submission/sections/sections-type.ts b/src/app/submission/sections/sections-type.ts index 6bca8a7252..40f6f85e0e 100644 --- a/src/app/submission/sections/sections-type.ts +++ b/src/app/submission/sections/sections-type.ts @@ -9,4 +9,5 @@ export enum SectionsType { SherpaPolicies = 'sherpaPolicy', Identifiers = 'identifiers', Collection = 'collection', + LdnService = 'ldn-service' } diff --git a/src/app/submission/submission.module.ts b/src/app/submission/submission.module.ts index cf0ab2b369..8f35bb4420 100644 --- a/src/app/submission/submission.module.ts +++ b/src/app/submission/submission.module.ts @@ -67,6 +67,7 @@ import { } from './sections/sherpa-policies/metadata-information/metadata-information.component'; import { SectionFormOperationsService } from './sections/form/section-form-operations.service'; import {SubmissionSectionIdentifiersComponent} from './sections/identifiers/section-identifiers.component'; +import { LdnServiceComponent } from './sections/ldn-service/ldn-service.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -76,6 +77,7 @@ const ENTRY_COMPONENTS = [ SubmissionSectionCcLicensesComponent, SubmissionSectionAccessesComponent, SubmissionSectionSherpaPoliciesComponent, + LdnServiceComponent ]; const DECLARATIONS = [ @@ -114,6 +116,7 @@ const DECLARATIONS = [ CoreModule.forRoot(), SharedModule, StoreModule.forFeature('submission', submissionReducers, storeModuleConfig as StoreConfig), + EffectsModule.forFeature(), EffectsModule.forFeature(submissionEffects), JournalEntitiesModule.withEntryComponents(), ResearchEntitiesModule.withEntryComponents(), From c93c2a62344a57995f9ba60567b912118d296426 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Tue, 24 Oct 2023 16:52:03 +0200 Subject: [PATCH 09/83] CST-12174 fixed red selected form section both for inbound and outbound pattens --- .../ldn-service-form-edit.component.html | 21 +++++++++++-------- .../ldn-service-form-edit.component.scss | 4 +--- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html index 368b312cd1..568f3ed46f 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html @@ -79,12 +79,12 @@
+ formGroupName="notifyServiceInboundPatterns" [class.marked-for-deletion]="markedForDeletionInboundPattern.includes(i)"> -
+
-
+
- diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.scss b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.scss index b686e6533b..0b244d76db 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.scss +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.scss @@ -1,8 +1,6 @@ form { - max-width: 800px; font-size: 14px; position: relative; - } input[type="text"], @@ -127,7 +125,7 @@ form button.btn.btn-primary[type="submit"] { } .marked-for-deletion { - background-color: #ffcccc; + background-color: lighten($red, 30%); } From 7ed4d1457df7e9d794c2b28e63dfd44f726387df Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Wed, 25 Oct 2023 21:09:07 +0200 Subject: [PATCH 10/83] CST-11045 Provided coarnotify section logic and dataservices for configs --- .../ldn-services-data.service.ts | 6 +- .../ldn-service.constrain.model.ts | 2 +- src/app/core/core.module.ts | 12 +- .../form/submission-form.component.html | 5 + .../section-container.component.html | 4 +- .../ldn-service/ldn-service.component.scss | 0 .../ldn-service/ldn-service.component.spec.ts | 23 -- .../ldn-service/ldn-service.component.ts | 129 -------- .../coar-notify-config-data.service.ts | 122 +++++++ .../section-coar-notify-model.ts | 74 +++++ ...ction-coar-notify-service.resource-type.ts | 13 + ...coar-notify-workspaceitems-data-service.ts | 117 +++++++ .../section-coar-notify.component.html | 31 ++ .../section-coar-notify.component.scss} | 0 .../section-coar-notify.component.spec.ts | 23 ++ .../section-coar-notify.component.ts | 308 ++++++++++++++++++ ...mission-coar-notify-workspaceitem.model.ts | 35 ++ .../submission-coar-notify.config.ts | 39 +++ src/app/submission/sections/sections-type.ts | 2 +- src/app/submission/submission.module.ts | 10 +- src/app/submission/submission.service.ts | 1 + 21 files changed, 792 insertions(+), 164 deletions(-) delete mode 100644 src/app/submission/sections/ldn-service/ldn-service.component.scss delete mode 100644 src/app/submission/sections/ldn-service/ldn-service.component.spec.ts delete mode 100644 src/app/submission/sections/ldn-service/ldn-service.component.ts create mode 100644 src/app/submission/sections/section-coar-notify/coar-notify-config-data.service.ts create mode 100644 src/app/submission/sections/section-coar-notify/section-coar-notify-model.ts create mode 100644 src/app/submission/sections/section-coar-notify/section-coar-notify-service.resource-type.ts create mode 100644 src/app/submission/sections/section-coar-notify/section-coar-notify-workspaceitems-data-service.ts create mode 100644 src/app/submission/sections/section-coar-notify/section-coar-notify.component.html rename src/app/submission/sections/{ldn-service/ldn-service.component.html => section-coar-notify/section-coar-notify.component.scss} (100%) create mode 100644 src/app/submission/sections/section-coar-notify/section-coar-notify.component.spec.ts create mode 100644 src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts create mode 100644 src/app/submission/sections/section-coar-notify/submission-coar-notify-workspaceitem.model.ts create mode 100644 src/app/submission/sections/section-coar-notify/submission-coar-notify.config.ts diff --git a/src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service.ts b/src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service.ts index 35f9bee04f..cdd259447a 100644 --- a/src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service.ts +++ b/src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service.ts @@ -28,7 +28,7 @@ import { ChangeAnalyzer } from '../../../core/data/change-analyzer'; import { Operation } from 'fast-json-patch'; import { RestRequestMethod } from 'src/app/core/data/rest-request-method'; import { CreateData, CreateDataImpl } from '../../../core/data/base/create-data'; -import { ldnServiceConstrain } from '../ldn-services-model/ldn-service.constrain.model'; +import { LdnServiceConstrain } from '../ldn-services-model/ldn-service.constrain.model'; import { getFirstCompletedRemoteData } from 'src/app/core/shared/operators'; import { hasValue } from 'src/app/shared/empty.util'; @@ -92,7 +92,7 @@ export class LdnServicesService extends IdentifiableDataService impl return this.deleteData.deleteByHref(href, copyVirtualMetadata); } - public invoke(serviceName: string, serviceId: string, parameters: ldnServiceConstrain[], files: File[]): Observable> { + public invoke(serviceName: string, serviceId: string, parameters: LdnServiceConstrain[], files: File[]): Observable> { const requestId = this.requestService.generateRequestId(); this.getBrowseEndpoint().pipe( take(1), @@ -115,7 +115,7 @@ export class LdnServicesService extends IdentifiableDataService impl ); } - private getInvocationFormData(constrain: ldnServiceConstrain[], files: File[]): FormData { + private getInvocationFormData(constrain: LdnServiceConstrain[], files: File[]): FormData { const form: FormData = new FormData(); form.set('properties', JSON.stringify(constrain)); files.forEach((file: File) => { diff --git a/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service.constrain.model.ts b/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service.constrain.model.ts index 69a9baf273..500cefbd52 100644 --- a/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service.constrain.model.ts +++ b/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service.constrain.model.ts @@ -1,3 +1,3 @@ -export class ldnServiceConstrain { +export class LdnServiceConstrain { void: any; } diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 88da00f02c..d0f2dbbbaf 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -190,7 +190,11 @@ import { SuggestionSource } from './suggestion-notifications/reciter-suggestions import { LdnServicesService } from '../admin/admin-ldn-services/ldn-services-data/ldn-services-data.service'; import { LdnService } from '../admin/admin-ldn-services/ldn-services-model/ldn-services.model'; import { LdnItemfiltersService } from '../admin/admin-ldn-services/ldn-services-data/ldn-itemfilters-data.service'; -import { Itemfilter } from "../admin/admin-ldn-services/ldn-services-model/ldn-service-itemfilters"; +import { Itemfilter } from '../admin/admin-ldn-services/ldn-services-model/ldn-service-itemfilters'; +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'; /** * When not in production, endpoint responses can be mocked for testing purposes @@ -315,7 +319,8 @@ const PROVIDERS = [ OrcidHistoryDataService, SupervisionOrderDataService, LdnServicesService, - LdnItemfiltersService + LdnItemfiltersService, + CoarNotifyConfigDataService ]; /** @@ -398,7 +403,8 @@ export const models = SuggestionTarget, SuggestionSource, LdnService, - Itemfilter + Itemfilter, + SubmissionCoarNotifyConfig ]; diff --git a/src/app/submission/form/submission-form.component.html b/src/app/submission/form/submission-form.component.html index fa04a6793c..c79364e2af 100644 --- a/src/app/submission/form/submission-form.component.html +++ b/src/app/submission/form/submission-form.component.html @@ -38,9 +38,14 @@ [sectionData]="object"> +
+ diff --git a/src/app/submission/sections/container/section-container.component.html b/src/app/submission/sections/container/section-container.component.html index e6ae9d1b9c..f39ba72ffa 100644 --- a/src/app/submission/sections/container/section-container.component.html +++ b/src/app/submission/sections/container/section-container.component.html @@ -42,10 +42,10 @@
-
+
aaaaaaaaa
-
\ No newline at end of file +
diff --git a/src/app/submission/sections/ldn-service/ldn-service.component.scss b/src/app/submission/sections/ldn-service/ldn-service.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/submission/sections/ldn-service/ldn-service.component.spec.ts b/src/app/submission/sections/ldn-service/ldn-service.component.spec.ts deleted file mode 100644 index ec36f1f010..0000000000 --- a/src/app/submission/sections/ldn-service/ldn-service.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { LdnServiceComponent } from './ldn-service.component'; - -describe('LdnServiceComponent', () => { - let component: LdnServiceComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ LdnServiceComponent ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(LdnServiceComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/submission/sections/ldn-service/ldn-service.component.ts b/src/app/submission/sections/ldn-service/ldn-service.component.ts deleted file mode 100644 index 6690395e72..0000000000 --- a/src/app/submission/sections/ldn-service/ldn-service.component.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core'; -import { DynamicFormControlEvent } from '@ng-dynamic-forms/core'; -import { Observable, Subscription } from 'rxjs'; -import { SectionModelComponent } from '../models/section.model'; -import { renderSectionFor } from '../sections-decorator'; -import { SectionsType } from '../sections-type'; -import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner'; -import { FormComponent } from '../../../shared/form/form.component'; -import { CollectionDataService } from '../../../core/data/collection-data.service'; -import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; -import { SectionFormOperationsService } from '../form/section-form-operations.service'; -import { FormService } from '../../../shared/form/form.service'; -import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; -import { SectionsService } from '../sections.service'; -import { SubmissionService } from '../../submission.service'; -import { TranslateService } from '@ngx-translate/core'; -import { SectionDataObject } from '../models/section-data.model'; -import { - WorkspaceitemSectionNotifyServiceRequestItemDissemination -} from '../../../core/submission/models/workspaceitem-section-form-notify-service.model'; -import { hasValue } from '../../../shared/empty.util'; -/** - * This component represents a section that contains the submission ldn-service form. - */ -@Component({ - selector: 'ds-ldn-service', - templateUrl: './ldn-service.component.html', - styleUrls: ['./ldn-service.component.scss'] -}) -@renderSectionFor(SectionsType.LdnService) -export class LdnServiceComponent extends SectionModelComponent { - - /** - * The [[JsonPatchOperationPathCombiner]] object - * @type {JsonPatchOperationPathCombiner} - */ - protected pathCombiner: JsonPatchOperationPathCombiner; - - /** - * Array to track all subscriptions and unsubscribe them onDestroy - * @type {Array} - */ - protected subs: Subscription[] = []; - - /** - * A boolean representing if div should start collapsed - */ - public isCollapsed = false; - - /** - * The FormComponent reference - */ - @ViewChild('formRef') private formRef: FormComponent; - - /** - * Initialize instance variables - * - * @param {ChangeDetectorRef} changeDetectorRef - * @param {CollectionDataService} collectionDataService - * @param {FormBuilderService} formBuilderService - * @param {SectionFormOperationsService} formOperationsService - * @param {FormService} formService - * @param {JsonPatchOperationsBuilder} operationsBuilder - * @param {SectionsService} sectionService - * @param {SubmissionService} submissionService - * @param {TranslateService} translateService - * @param {string} injectedCollectionId - * @param {SectionDataObject} injectedSectionData - * @param {string} injectedSubmissionId - */ - constructor(protected changeDetectorRef: ChangeDetectorRef, - protected collectionDataService: CollectionDataService, - protected formBuilderService: FormBuilderService, - protected formOperationsService: SectionFormOperationsService, - protected formService: FormService, - protected operationsBuilder: JsonPatchOperationsBuilder, - protected sectionService: SectionsService, - protected submissionService: SubmissionService, - protected translateService: TranslateService, - @Inject('collectionIdProvider') public injectedCollectionId: string, - @Inject('sectionDataProvider') public injectedSectionData: SectionDataObject, - @Inject('submissionIdProvider') public injectedSubmissionId: string) { - super(injectedCollectionId, injectedSectionData, injectedSubmissionId); - } - - /** - * Initialize all instance variables - */ - onSectionInit() { - this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionData.id); - this.subs.push( - this.sectionService.getSectionData(this.submissionId, this.sectionData.id, this.sectionData.sectionType) - .subscribe((ldnServicesSection: WorkspaceitemSectionNotifyServiceRequestItemDissemination) => { - console.log(ldnServicesSection); - }) - ); - } - - - - /** - * Method called when a form dfChange event is fired. - * Dispatch form operations based on changes. - */ - onChange(event: DynamicFormControlEvent) { - const path = this.formOperationsService.getFieldPathSegmentedFromChangeEvent(event); - const value = this.formOperationsService.getFieldValueFromChangeEvent(event); - if (value) { - this.operationsBuilder.add(this.pathCombiner.getPath(path), value.value.toString(), false, true); - this.sectionService.dispatchRemoveSectionErrors(this.submissionId, this.sectionData.id); - } else { - this.operationsBuilder.remove(this.pathCombiner.getPath(path)); - } - } - - /** - * Unsubscribe from all subscriptions - */ - onSectionDestroy() { - this.subs - .filter((subscription) => hasValue(subscription)) - .forEach((subscription) => subscription.unsubscribe()); - } - - protected getSectionStatus(): Observable { - return undefined; - } - -} diff --git a/src/app/submission/sections/section-coar-notify/coar-notify-config-data.service.ts b/src/app/submission/sections/section-coar-notify/coar-notify-config-data.service.ts new file mode 100644 index 0000000000..7b8d309667 --- /dev/null +++ b/src/app/submission/sections/section-coar-notify/coar-notify-config-data.service.ts @@ -0,0 +1,122 @@ +import { Injectable } from '@angular/core'; +import { dataService } from '../../../core/data/base/data-service.decorator'; +import { IdentifiableDataService } from '../../../core/data/base/identifiable-data.service'; +import { FindAllData, FindAllDataImpl } from '../../../core/data/base/find-all-data'; +import { DeleteData, DeleteDataImpl } from '../../../core/data/base/delete-data'; +import { RequestService } from '../../../core/data/request.service'; +import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; +import { ObjectCacheService } from '../../../core/cache/object-cache.service'; +import { HALEndpointService } from '../../../core/shared/hal-endpoint.service'; +import { NotificationsService } from '../../../shared/notifications/notifications.service'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; +import { FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; +import { Observable } from 'rxjs'; +import { RemoteData } from '../../../core/data/remote-data'; +import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { NoContent } from '../../../core/shared/NoContent.model'; +import { map, take } from 'rxjs/operators'; +import { URLCombiner } from '../../../core/url-combiner/url-combiner'; +import { MultipartPostRequest } from '../../../core/data/request.models'; +import { RestRequest } from '../../../core/data/rest-request.model'; +import { SUBMISSION_COAR_NOTIFY_CONFIG } from './section-coar-notify-service.resource-type'; +import { SubmissionCoarNotifyConfig } from './submission-coar-notify.config'; +import { CreateData, CreateDataImpl } from '../../../core/data/base/create-data'; +import { PatchData, PatchDataImpl } from '../../../core/data/base/patch-data'; +import { ChangeAnalyzer } from '../../../core/data/change-analyzer'; +import { Operation } from 'fast-json-patch'; +import { RestRequestMethod } from '../../../core/data/rest-request-method'; +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { hasValue } from '../../../shared/empty.util'; + + +/** + * A service responsible for fetching/sending data from/to the REST API on the CoarNotifyConfig endpoint + */ +@Injectable() +@dataService(SUBMISSION_COAR_NOTIFY_CONFIG) +export class CoarNotifyConfigDataService extends IdentifiableDataService implements FindAllData, DeleteData, PatchData, CreateData { + createData: CreateDataImpl; + private findAllData: FindAllDataImpl; + private deleteData: DeleteDataImpl; + private patchData: PatchDataImpl; + private comparator: ChangeAnalyzer; + + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + ) { + super('submissioncoarnotifyconfigs', requestService, rdbService, objectCache, halService); + + this.findAllData = new FindAllDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive); + this.deleteData = new DeleteDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive, this.constructIdEndpoint); + this.patchData = new PatchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.comparator, this.responseMsToLive, this.constructIdEndpoint); + this.createData = new CreateDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive); + } + + + create(object: SubmissionCoarNotifyConfig): Observable> { + return this.createData.create(object); + } + + patch(object: SubmissionCoarNotifyConfig, operations: Operation[]): Observable> { + return this.patchData.patch(object, operations); + } + + update(object: SubmissionCoarNotifyConfig): Observable> { + return this.patchData.update(object); + } + + commitUpdates(method?: RestRequestMethod): void { + return this.patchData.commitUpdates(method); + } + + createPatchFromCache(object: SubmissionCoarNotifyConfig): Observable { + return this.patchData.createPatchFromCache(object); + } + + findAll(options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.findAllData.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + } + + public delete(objectId: string, copyVirtualMetadata?: string[]): Observable> { + return this.deleteData.delete(objectId, copyVirtualMetadata); + } + + public deleteByHref(href: string, copyVirtualMetadata?: string[]): Observable> { + return this.deleteData.deleteByHref(href, copyVirtualMetadata); + } + + public invoke(serviceName: string, serviceId: string, files: File[]): Observable> { + const requestId = this.requestService.generateRequestId(); + this.getBrowseEndpoint().pipe( + take(1), + map((endpoint: string) => new URLCombiner(endpoint, serviceName, 'submissioncoarnotifyconfigmodel', serviceId).toString()), + map((endpoint: string) => { + const body = this.getInvocationFormData(files); + return new MultipartPostRequest(requestId, endpoint, body); + }) + ).subscribe((request: RestRequest) => this.requestService.send(request)); + + return this.rdbService.buildFromRequestUUID(requestId); + } + + public SubmissionCoarNotifyConfigModelWithNameExistsAndCanExecute(scriptName: string): Observable { + return this.findById(scriptName).pipe( + getFirstCompletedRemoteData(), + map((rd: RemoteData) => { + return hasValue(rd.payload); + }), + ); + } + + private getInvocationFormData(files: File[]): FormData { + const form: FormData = new FormData(); + files.forEach((file: File) => { + form.append('file', file); + }); + return form; + } +} diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify-model.ts b/src/app/submission/sections/section-coar-notify/section-coar-notify-model.ts new file mode 100644 index 0000000000..c8904fdca3 --- /dev/null +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify-model.ts @@ -0,0 +1,74 @@ +export const REQUEST_REVIEW_DROPDOWN = { + element: { + container: 'custom-control custom-select pl-1', + control: 'custom-select', + label: 'custom-control-label pt-1' + } +}; + +export const REQUEST_ENDORSEMENT_DROPDOWN = { + element: { + container: 'custom-control custom-select pl-1', + control: 'custom-select', + label: 'custom-control-label pt-1' + } +}; + +export const REQUEST_INGEST_DROPDOWN = { + element: { + container: 'custom-control custom-select pl-1', + control: 'custom-select', + label: 'custom-control-label pt-1' + } +}; + +export const SECTION_COAR_FORM_LAYOUT = { + requestReview: REQUEST_REVIEW_DROPDOWN, + requestEndorsement: REQUEST_ENDORSEMENT_DROPDOWN, + requestIngest: REQUEST_INGEST_DROPDOWN +}; + +export const SECTION_COAR_FORM_MODEL = [ + { + id: 'requestReview', + label: 'submission.sections.license.request-review-label', + required: false, + value: '', + validators: { + required: null + }, + errorMessages: { + required: 'submission.sections.license.required', + notgranted: 'submission.sections.license.notgranted' + }, + type: 'SELECT', + }, + { + id: 'requestEndorsement', + label: 'submission.sections.license.request-endorsement-label', + required: false, + value: '', + validators: { + required: null + }, + errorMessages: { + required: 'submission.sections.license.required', + notgranted: 'submission.sections.license.notgranted' + }, + type: 'SELECT', + }, + { + id: 'requestIngest', + label: 'submission.sections.license.request-ingest-label', + required: false, + value: '', + validators: { + required: null + }, + errorMessages: { + required: 'submission.sections.license.required', + notgranted: 'submission.sections.license.notgranted' + }, + type: 'SELECT', + } +]; diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify-service.resource-type.ts b/src/app/submission/sections/section-coar-notify/section-coar-notify-service.resource-type.ts new file mode 100644 index 0000000000..53e41783ce --- /dev/null +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify-service.resource-type.ts @@ -0,0 +1,13 @@ +/** + * The resource type for Ldn-Services + * + * Needs to be in a separate file to prevent circular + * dependencies in webpack. + */ +import { ResourceType } from '../../../core/shared/resource-type'; + + +export const SUBMISSION_COAR_NOTIFY_CONFIG = new ResourceType('submissioncoarnotifyconfig'); + +export const COAR_NOTIFY_WORKSPACEITEM = new ResourceType('workspaceitem'); + diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify-workspaceitems-data-service.ts b/src/app/submission/sections/section-coar-notify/section-coar-notify-workspaceitems-data-service.ts new file mode 100644 index 0000000000..dd287b096a --- /dev/null +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify-workspaceitems-data-service.ts @@ -0,0 +1,117 @@ +import { Injectable } from '@angular/core'; +import { dataService } from '../../../core/data/base/data-service.decorator'; +import { IdentifiableDataService } from '../../../core/data/base/identifiable-data.service'; +import { FindAllData, FindAllDataImpl } from '../../../core/data/base/find-all-data'; +import { DeleteData, DeleteDataImpl } from '../../../core/data/base/delete-data'; +import { RequestService } from '../../../core/data/request.service'; +import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; +import { ObjectCacheService } from '../../../core/cache/object-cache.service'; +import { HALEndpointService } from '../../../core/shared/hal-endpoint.service'; +import { NotificationsService } from '../../../shared/notifications/notifications.service'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; +import { FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; +import { Observable } from 'rxjs'; +import { RemoteData } from '../../../core/data/remote-data'; +import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { NoContent } from '../../../core/shared/NoContent.model'; +import { map, take } from 'rxjs/operators'; +import { URLCombiner } from '../../../core/url-combiner/url-combiner'; +import { MultipartPostRequest } from '../../../core/data/request.models'; +import { RestRequest } from '../../../core/data/rest-request.model'; +import { COAR_NOTIFY_WORKSPACEITEM } from './section-coar-notify-service.resource-type'; +import { LdnService } from '../../../admin/admin-ldn-services/ldn-services-model/ldn-services.model'; +import { SubmissionCoarNotifyConfig } from './submission-coar-notify.config'; + + +/** + * A service responsible for fetching/sending data from/to the REST API on the ldnservices endpoint + */ +@Injectable() +@dataService(COAR_NOTIFY_WORKSPACEITEM) +export class SectionCoarNotifyWorkspaceitemsDataService extends IdentifiableDataService implements FindAllData, DeleteData, PatchData, CreateData { + createData: CreateDataImpl; + private findAllData: FindAllDataImpl; + private deleteData: DeleteDataImpl; + private patchData: PatchDataImpl; + private comparator: ChangeAnalyzer; + + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + ) { + super('ldnservices', requestService, rdbService, objectCache, halService); + + this.findAllData = new FindAllDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive); + this.deleteData = new DeleteDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive, this.constructIdEndpoint); + this.patchData = new PatchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.comparator, this.responseMsToLive, this.constructIdEndpoint); + this.createData = new CreateDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive); + } + + + create(object: LdnService): Observable> { + return this.createData.create(object); + } + + patch(object: LdnService, operations: Operation[]): Observable> { + return this.patchData.patch(object, operations); + } + + update(object: LdnService): Observable> { + return this.patchData.update(object); + } + + commitUpdates(method?: RestRequestMethod): void { + return this.patchData.commitUpdates(method); + } + + createPatchFromCache(object: LdnService): Observable { + return this.patchData.createPatchFromCache(object); + } + + findAll(options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.findAllData.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + } + + public delete(objectId: string, copyVirtualMetadata?: string[]): Observable> { + return this.deleteData.delete(objectId, copyVirtualMetadata); + } + + public deleteByHref(href: string, copyVirtualMetadata?: string[]): Observable> { + return this.deleteData.deleteByHref(href, copyVirtualMetadata); + } + + public invoke(serviceName: string, serviceId: string, parameters: ldnServiceConstrain[], files: File[]): Observable> { + const requestId = this.requestService.generateRequestId(); + this.getBrowseEndpoint().pipe( + take(1), + map((endpoint: string) => new URLCombiner(endpoint, serviceName, 'processes', serviceId).toString()), + map((endpoint: string) => { + const body = this.getInvocationFormData(parameters, files); + return new MultipartPostRequest(requestId, endpoint, body); + }) + ).subscribe((request: RestRequest) => this.requestService.send(request)); + + return this.rdbService.buildFromRequestUUID(requestId); + } + + public ldnServiceWithNameExistsAndCanExecute(scriptName: string): Observable { + return this.findById(scriptName).pipe( + getFirstCompletedRemoteData(), + map((rd: RemoteData) => { + return hasValue(rd.payload); + }), + ); + } + + private getInvocationFormData(constrain: ldnServiceConstrain[], files: File[]): FormData { + const form: FormData = new FormData(); + form.set('properties', JSON.stringify(constrain)); + files.forEach((file: File) => { + form.append('file', file); + }); + return form; + } +} diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html new file mode 100644 index 0000000000..4d0d92c714 --- /dev/null +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html @@ -0,0 +1,31 @@ +
+ + + +
diff --git a/src/app/submission/sections/ldn-service/ldn-service.component.html b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss similarity index 100% rename from src/app/submission/sections/ldn-service/ldn-service.component.html rename to src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.spec.ts b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.spec.ts new file mode 100644 index 0000000000..c83479284a --- /dev/null +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SubmissionSectionCoarNotifyComponent } from './section-coar-notify.component'; + +describe('LdnServiceComponent', () => { + let component: SubmissionSectionCoarNotifyComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SubmissionSectionCoarNotifyComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SubmissionSectionCoarNotifyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts new file mode 100644 index 0000000000..992eae0b52 --- /dev/null +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts @@ -0,0 +1,308 @@ +import { ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core'; +import { DynamicFormControlEvent, DynamicFormControlModel, DynamicFormLayout } from '@ng-dynamic-forms/core'; +import { Observable, Subscription } from 'rxjs'; +import { SectionModelComponent } from '../models/section.model'; +import { renderSectionFor } from '../sections-decorator'; +import { SectionsType } from '../sections-type'; +import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner'; +import { FormComponent } from '../../../shared/form/form.component'; +import { CollectionDataService } from '../../../core/data/collection-data.service'; +import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; +import { SectionFormOperationsService } from '../form/section-form-operations.service'; +import { FormService } from '../../../shared/form/form.service'; +import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; +import { SectionsService } from '../sections.service'; +import { SubmissionService } from '../../submission.service'; +import { TranslateService } from '@ngx-translate/core'; +import { SectionDataObject } from '../models/section-data.model'; + +import { hasValue, isNotEmpty } from '../../../shared/empty.util'; + +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { LdnServicesService } from '../../../admin/admin-ldn-services/ldn-services-data/ldn-services-data.service'; +import { isLoading } from '../../../core/data/request-entry-state.model'; +import { LdnService } from '../../../admin/admin-ldn-services/ldn-services-model/ldn-services.model'; +import { SECTION_COAR_FORM_LAYOUT, SECTION_COAR_FORM_MODEL } from './section-coar-notify-model'; +import { + CoarNotifyConfigDataService +} from './coar-notify-config-data.service'; +import { RemoteData } from '../../../core/data/remote-data'; +import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { SubmissionCoarNotifyConfig } from './submission-coar-notify.config'; +import { FormFieldPreviousValueObject } from '../../../shared/form/builder/models/form-field-previous-value-object'; +import { UntypedFormGroup } from '@angular/forms'; +import { AlertType } from '../../../shared/alert/aletr-type'; + +export interface CoarNotifyDropdownSelector { + ldnService: LdnService; +} + +/** + * This component represents a section that contains the submission section-coar-notify form. + */ +@Component({ + selector: 'ds-submission-section-coar-notify', + templateUrl: './section-coar-notify.component.html', + styleUrls: ['./section-coar-notify.component.scss'] +}) +@renderSectionFor(SectionsType.CoarNotify) + +export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent { + + requestReview: LdnService; + requestEndorsement: LdnService; + requestIngest: LdnService; + + coarNotifyConfigRD$: Observable>>; + + ldnServicesRD$: Observable>>; + + selectedServiceValues: any[] = []; + + /** + * The AlertType enumeration + * @type {AlertType} + */ + public AlertTypeEnum = AlertType; + /** + * The form model + * @type {DynamicFormControlModel[]} + */ + public formModel: DynamicFormControlModel[]; + /** + * The form id + * @type {string} + */ + public formId: string; + /** + * The [[DynamicFormLayout]] object + * @type {DynamicFormLayout} + */ + public formLayout: DynamicFormLayout = SECTION_COAR_FORM_LAYOUT; + /** + * A FormGroup that combines all inputs + */ + formGroup: UntypedFormGroup; + /** + * A boolean representing if div should start collapsed + */ + public isCollapsed = false; + protected readonly AlertType = AlertType; + /** + * The [[JsonPatchOperationPathCombiner]] object + * @type {JsonPatchOperationPathCombiner} + */ + protected pathCombiner: JsonPatchOperationPathCombiner; + /** + * A map representing all field on their way to be removed + * @type {Map} + */ + protected fieldsOnTheirWayToBeRemoved: Map = new Map(); + /** + * The [FormFieldPreviousValueObject] object + * @type {FormFieldPreviousValueObject} + */ + protected previousValue: FormFieldPreviousValueObject = new FormFieldPreviousValueObject(); + /** + * Array to track all subscriptions and unsubscribe them onDestroy + * @type {Array} + */ + protected subs: Subscription[] = []; + protected readonly isLoading = isLoading; + /** + * The FormComponent reference + */ + @ViewChild('formRef') private formRef: FormComponent; + + /** + * Initialize instance variables + * + * @param {ChangeDetectorRef} changeDetectorRef + * @param ldnServicesService + * @param {CollectionDataService} collectionDataService + * @param {FormBuilderService} formBuilderService + * @param {SectionFormOperationsService} formOperationsService + * @param {FormService} formService + * @param {JsonPatchOperationsBuilder} operationsBuilder + * @param {SectionsService} sectionService + * @param {SubmissionService} submissionService + * @param {TranslateService} translateService + * @param {CoarNotifyConfigDataService} coarNotifyConfigDataService + * @param {string} injectedCollectionId + * @param {SectionDataObject} injectedSectionData + * @param {string} injectedSubmissionId + */ + constructor(protected changeDetectorRef: ChangeDetectorRef, + protected ldnServicesService: LdnServicesService, + protected collectionDataService: CollectionDataService, + protected formBuilderService: FormBuilderService, + protected formOperationsService: SectionFormOperationsService, + protected formService: FormService, + protected operationsBuilder: JsonPatchOperationsBuilder, + protected sectionService: SectionsService, + protected submissionService: SubmissionService, + protected translateService: TranslateService, + protected coarNotifyConfigDataService: CoarNotifyConfigDataService, + @Inject('collectionIdProvider') public injectedCollectionId: string, + @Inject('sectionDataProvider') public injectedSectionData: SectionDataObject, + @Inject('submissionIdProvider') public injectedSubmissionId: string) { + super(injectedCollectionId, injectedSectionData, injectedSubmissionId); + } + + /** + * Initialize all instance variables + */ + onSectionInit() { + this.formModel = this.formBuilderService.fromJSON(SECTION_COAR_FORM_MODEL); + this.setCoarNotifyConfig(); + this.fetchLdnServices(); + this.coarNotifyConfigRD$.subscribe(data => { + console.log(data); + }); + this.ldnServicesRD$.subscribe(data => { + console.log(data); + }); + this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionData.id); + } + + /** + * Method called when section is initialized + * Retriev available NotifyConfigs + */ + setCoarNotifyConfig() { + this.coarNotifyConfigRD$ = this.coarNotifyConfigDataService.findAll().pipe( + getFirstCompletedRemoteData()); + } + + /** + * Handle the customEvent (ex. drag-drop move event). + * The customEvent is stored inside event.$event + * @param event + */ + onCustomEvent(event: DynamicFormControlEvent) { + this.formOperationsService.dispatchOperationsFromEvent( + this.pathCombiner, + event, + this.previousValue, + null); + } + + /** + * Method called when a form dfChange event is fired. + * Dispatch form operations based on changes. + */ + onChange(event: DynamicFormControlEvent) { + const path = this.formOperationsService.getFieldPathSegmentedFromChangeEvent(event); + const value = this.formOperationsService.getFieldValueFromChangeEvent(event); + if (value) { + this.operationsBuilder.add(this.pathCombiner.getPath(path), value.value.toString(), false, true); + this.sectionService.dispatchRemoveSectionErrors(this.submissionId, this.sectionData.id); + } else { + this.operationsBuilder.remove(this.pathCombiner.getPath(path)); + } + } + + /** + * Method called when a form remove event is fired. + * Dispatch form operations based on changes. + * + * @param event + * the [[DynamicFormControlEvent]] emitted + */ + onRemove(event: DynamicFormControlEvent): void { + const fieldId = this.formBuilderService.getId(event.model); + const fieldIndex = this.formOperationsService.getArrayIndexFromEvent(event); + + // Keep track that this field will be removed + if (this.fieldsOnTheirWayToBeRemoved.has(fieldId)) { + const indexes = this.fieldsOnTheirWayToBeRemoved.get(fieldId); + indexes.push(fieldIndex); + this.fieldsOnTheirWayToBeRemoved.set(fieldId, indexes); + } else { + this.fieldsOnTheirWayToBeRemoved.set(fieldId, [fieldIndex]); + } + + this.formOperationsService.dispatchOperationsFromEvent( + this.pathCombiner, + event, + this.previousValue, + this.hasStoredValue(fieldId, fieldIndex)); + + } + + /** + * Check if the specified form field has already a value stored + * + * @param fieldId + * the section data retrieved from the serverù + * @param index + * the section data retrieved from the server + */ + hasStoredValue(fieldId, index): boolean { + if (isNotEmpty(this.sectionData.data)) { + return this.sectionData.data.hasOwnProperty(fieldId) && + isNotEmpty(this.sectionData.data[fieldId][index]) && + !this.isFieldToRemove(fieldId, index); + } else { + return false; + } + } + + /** + * Check if the specified field is on the way to be removed + * + * @param fieldId + * the section data retrieved from the serverù + * @param index + * the section data retrieved from the server + */ + isFieldToRemove(fieldId, index) { + return this.fieldsOnTheirWayToBeRemoved.has(fieldId) && this.fieldsOnTheirWayToBeRemoved.get(fieldId).includes(index); + } + + /** + * Method called when a form dfFocus event is fired. + * Initialize [FormFieldPreviousValueObject] instance. + * + * @param event + * the [[DynamicFormControlEvent]] emitted + */ + onFocus(event: DynamicFormControlEvent): void { + const value = this.formOperationsService.getFieldValueFromChangeEvent(event); + const path = this.formBuilderService.getPath(event.model); + if (this.formBuilderService.hasMappedGroupValue(event.model)) { + this.previousValue.path = path; + this.previousValue.value = this.formOperationsService.getQualdropValueMap(event); + } else if (isNotEmpty(value) && ((typeof value === 'object' && isNotEmpty(value.value)) || (typeof value === 'string'))) { + this.previousValue.path = path; + this.previousValue.value = value; + } + } + + /** + * Unsubscribe from all subscriptions + */ + onSectionDestroy() { + this.subs + .filter((subscription) => hasValue(subscription)) + .forEach((subscription) => subscription.unsubscribe()); + } + + /** + * Method called when section is initialized + * Retriev available NotifyConfigs + */ + fetchLdnServices() { + this.ldnServicesRD$ = this.ldnServicesService.findAll().pipe( + getFirstCompletedRemoteData() + ); + } + + protected getSectionStatus(): Observable { + return undefined; + } + + hasInboundPattern(service: any, patternType: string): boolean { + return service.notifyServiceInboundPatterns.some(pattern => pattern.pattern === patternType); + } +} diff --git a/src/app/submission/sections/section-coar-notify/submission-coar-notify-workspaceitem.model.ts b/src/app/submission/sections/section-coar-notify/submission-coar-notify-workspaceitem.model.ts new file mode 100644 index 0000000000..85374502bc --- /dev/null +++ b/src/app/submission/sections/section-coar-notify/submission-coar-notify-workspaceitem.model.ts @@ -0,0 +1,35 @@ +import { CacheableObject } from '../../../core/cache/cacheable-object.model'; +import { autoserialize, deserialize, deserializeAs, inheritSerialization } from 'cerialize'; + +import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; +import { typedObject } from '../../../core/cache/builders/build-decorators'; +import { COAR_NOTIFY_WORKSPACEITEM } from "./section-coar-notify-service.resource-type"; + + +/** An CoarNotify and its properties. */ +@typedObject +@inheritSerialization(CacheableObject) +export class SubmissionCoarNotifyWorkspaceitemModel extends CacheableObject { + static type = COAR_NOTIFY_WORKSPACEITEM; + + @excludeFromEquals + @autoserialize + endorsement?: number[]; + + @deserializeAs('id') + review?: number[]; + + @autoserialize + ingest?: number[]; + + @deserialize + _links: { + self: { + href: string; + }; + }; + + get self(): string { + return this._links.self.href; + } +} diff --git a/src/app/submission/sections/section-coar-notify/submission-coar-notify.config.ts b/src/app/submission/sections/section-coar-notify/submission-coar-notify.config.ts new file mode 100644 index 0000000000..04973f80c8 --- /dev/null +++ b/src/app/submission/sections/section-coar-notify/submission-coar-notify.config.ts @@ -0,0 +1,39 @@ +import { ResourceType } from '../../../core/shared/resource-type'; +import { CacheableObject } from '../../../core/cache/cacheable-object.model'; +import { autoserialize, deserialize, deserializeAs, inheritSerialization } from 'cerialize'; + +import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; +import { typedObject } from '../../../core/cache/builders/build-decorators'; +import { SUBMISSION_COAR_NOTIFY_CONFIG } from './section-coar-notify-service.resource-type'; + + +/** A SubmissionCoarNotifyConfig and its properties. */ +@typedObject +@inheritSerialization(CacheableObject) +export class SubmissionCoarNotifyConfig extends CacheableObject { + static type = SUBMISSION_COAR_NOTIFY_CONFIG; + + @excludeFromEquals + @autoserialize + type: ResourceType; + + @autoserialize + id: string; + + @deserializeAs('id') + uuid: string; + + @autoserialize + patterns: string[]; + + @deserialize + _links: { + self: { + href: string; + }; + }; + + get self(): string { + return this._links.self.href; + } +} diff --git a/src/app/submission/sections/sections-type.ts b/src/app/submission/sections/sections-type.ts index 40f6f85e0e..5f71d1731d 100644 --- a/src/app/submission/sections/sections-type.ts +++ b/src/app/submission/sections/sections-type.ts @@ -9,5 +9,5 @@ export enum SectionsType { SherpaPolicies = 'sherpaPolicy', Identifiers = 'identifiers', Collection = 'collection', - LdnService = 'ldn-service' + CoarNotify = 'coarnotify' } diff --git a/src/app/submission/submission.module.ts b/src/app/submission/submission.module.ts index 8f35bb4420..f4f479e204 100644 --- a/src/app/submission/submission.module.ts +++ b/src/app/submission/submission.module.ts @@ -67,7 +67,11 @@ import { } from './sections/sherpa-policies/metadata-information/metadata-information.component'; import { SectionFormOperationsService } from './sections/form/section-form-operations.service'; import {SubmissionSectionIdentifiersComponent} from './sections/identifiers/section-identifiers.component'; -import { LdnServiceComponent } from './sections/ldn-service/ldn-service.component'; +import { SubmissionSectionCoarNotifyComponent } from './sections/section-coar-notify/section-coar-notify.component'; +import { + CoarNotifyConfigDataService +} from './sections/section-coar-notify/coar-notify-config-data.service'; +import { LdnServicesService } from '../admin/admin-ldn-services/ldn-services-data/ldn-services-data.service'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -77,7 +81,7 @@ const ENTRY_COMPONENTS = [ SubmissionSectionCcLicensesComponent, SubmissionSectionAccessesComponent, SubmissionSectionSherpaPoliciesComponent, - LdnServiceComponent + SubmissionSectionCoarNotifyComponent ]; const DECLARATIONS = [ @@ -138,6 +142,8 @@ const DECLARATIONS = [ SubmissionAccessesConfigDataService, SectionAccessesService, SectionFormOperationsService, + CoarNotifyConfigDataService, + LdnServicesService ] }) diff --git a/src/app/submission/submission.service.ts b/src/app/submission/submission.service.ts index 9eb8cf110a..7057f78c2f 100644 --- a/src/app/submission/submission.service.ts +++ b/src/app/submission/submission.service.ts @@ -298,6 +298,7 @@ export class SubmissionService { sectionObject.id = sectionId; sectionObject.sectionType = sections[sectionId].sectionType; availableSections.push(sectionObject); + console.log(sectionObject); }); return availableSections; }), From 90652b62cef72fcfb7bc29d7b3abee2f943d3fcb Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Wed, 25 Oct 2023 21:41:11 +0200 Subject: [PATCH 11/83] CST-12174 Added filters for empty string patterns removal --- .../ldn-service-form/ldn-service-form.component.ts | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.ts b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.ts index 6b908cdae2..55fa1638c4 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.ts +++ b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.ts @@ -131,18 +131,12 @@ export class LdnServiceFormComponent implements OnInit { return; } + this.formModel.value.notifyServiceInboundPatterns = this.formModel.value.notifyServiceInboundPatterns.filter((pattern: { pattern: string; }) => pattern.pattern !== ''); + this.formModel.value.notifyServiceOutboundPatterns = this.formModel.value.notifyServiceOutboundPatterns.filter((pattern: { pattern: string; }) => pattern.pattern !== ''); + + console.log(this.formModel.value); const values = this.formModel.value; - const inboundPatternValue = this.formModel.get('inboundPattern').value; - const outboundPatternValue = this.formModel.get('outboundPattern').value; - - if (inboundPatternValue === '') { - values.notifyServiceInboundPatterns = []; - } - if (outboundPatternValue === '') { - values.notifyServiceOutboundPatterns = []; - } - const ldnServiceData = this.ldnServicesService.create(values); ldnServiceData.pipe( From 12c60b7fad2da85e1e2039fd962a4471450f98a3 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Wed, 25 Oct 2023 21:44:41 +0200 Subject: [PATCH 12/83] CST-12174 Removed console log --- .../ldn-service-form/ldn-service-form.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.ts b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.ts index 55fa1638c4..a2c4919a4d 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.ts +++ b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.ts @@ -134,7 +134,6 @@ export class LdnServiceFormComponent implements OnInit { this.formModel.value.notifyServiceInboundPatterns = this.formModel.value.notifyServiceInboundPatterns.filter((pattern: { pattern: string; }) => pattern.pattern !== ''); this.formModel.value.notifyServiceOutboundPatterns = this.formModel.value.notifyServiceOutboundPatterns.filter((pattern: { pattern: string; }) => pattern.pattern !== ''); - console.log(this.formModel.value); const values = this.formModel.value; const ldnServiceData = this.ldnServicesService.create(values); From 0682b7b45f14d6ae215c2a4770ee088ef2ed5954 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Wed, 25 Oct 2023 23:03:24 +0200 Subject: [PATCH 13/83] CST-11045 Dynamically creating dropdowns based on the coarconfig --- .../section-coar-notify.component.html | 38 ++++--------- .../section-coar-notify.component.ts | 57 ++++++++++++------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html index 4d0d92c714..c9d79293ac 100644 --- a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html @@ -1,31 +1,15 @@
- - +
diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts index 992eae0b52..726f5ec6c4 100644 --- a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts @@ -57,12 +57,11 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent ldnServicesRD$: Observable>>; - selectedServiceValues: any[] = []; - /** - * The AlertType enumeration - * @type {AlertType} - */ + patterns: string[] = []; + selectedServices: { [key: string]: LdnService } = {}; + patternsLoaded = false; + public AlertTypeEnum = AlertType; /** * The form model @@ -171,7 +170,15 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent */ setCoarNotifyConfig() { this.coarNotifyConfigRD$ = this.coarNotifyConfigDataService.findAll().pipe( - getFirstCompletedRemoteData()); + getFirstCompletedRemoteData() + ); + + this.coarNotifyConfigRD$.subscribe((data) => { + if (data.hasSucceeded) { + this.patterns = data.payload.page[0].patterns; + this.patternsLoaded = true; + } + }); } /** @@ -181,10 +188,10 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent */ onCustomEvent(event: DynamicFormControlEvent) { this.formOperationsService.dispatchOperationsFromEvent( - this.pathCombiner, - event, - this.previousValue, - null); + this.pathCombiner, + event, + this.previousValue, + null); } /** @@ -223,10 +230,10 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent } this.formOperationsService.dispatchOperationsFromEvent( - this.pathCombiner, - event, - this.previousValue, - this.hasStoredValue(fieldId, fieldIndex)); + this.pathCombiner, + event, + this.previousValue, + this.hasStoredValue(fieldId, fieldIndex)); } @@ -241,8 +248,8 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent hasStoredValue(fieldId, index): boolean { if (isNotEmpty(this.sectionData.data)) { return this.sectionData.data.hasOwnProperty(fieldId) && - isNotEmpty(this.sectionData.data[fieldId][index]) && - !this.isFieldToRemove(fieldId, index); + isNotEmpty(this.sectionData.data[fieldId][index]) && + !this.isFieldToRemove(fieldId, index); } else { return false; } @@ -284,8 +291,8 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent */ onSectionDestroy() { this.subs - .filter((subscription) => hasValue(subscription)) - .forEach((subscription) => subscription.unsubscribe()); + .filter((subscription) => hasValue(subscription)) + .forEach((subscription) => subscription.unsubscribe()); } /** @@ -293,9 +300,19 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent * Retriev available NotifyConfigs */ fetchLdnServices() { - this.ldnServicesRD$ = this.ldnServicesService.findAll().pipe( + this.ldnServicesRD$ = this.ldnServicesService.findAll().pipe( getFirstCompletedRemoteData() - ); + ); + + this.ldnServicesRD$.subscribe((data) => { + if (this.patternsLoaded) { + this.patterns.forEach((pattern) => { + this.selectedServices[pattern] = data.payload.page.find((service) => + this.hasInboundPattern(service, `Request ${pattern}`) + ); + }); + } + }); } protected getSectionStatus(): Observable { From 5ed9f46096404e50e20a9c096d3f4c3225a95bbc Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Thu, 26 Oct 2023 18:47:25 +0200 Subject: [PATCH 14/83] CST-11045 Improved css and remove console log and interpolation, added small notify regarding service compatibility --- .../ldn-services-data.service.ts | 4 ++ .../form/submission-form.component.html | 5 --- .../section-container.component.html | 2 +- .../section-coar-notify.component.html | 42 ++++++++++++------ .../section-coar-notify.component.scss | 15 +++++++ .../section-coar-notify.component.ts | 38 ++++++++++++++-- src/assets/i18n/en.json5 | 2 + src/assets/images/notify_logo.png | Bin 0 -> 19269 bytes 8 files changed, 85 insertions(+), 23 deletions(-) create mode 100644 src/assets/images/notify_logo.png diff --git a/src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service.ts b/src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service.ts index cdd259447a..5ffab2000b 100644 --- a/src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service.ts +++ b/src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service.ts @@ -84,6 +84,10 @@ export class LdnServicesService extends IdentifiableDataService impl return this.findAllData.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); } + /*findByPattern(options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.findAllData.find + }*/ + public delete(objectId: string, copyVirtualMetadata?: string[]): Observable> { return this.deleteData.delete(objectId, copyVirtualMetadata); } diff --git a/src/app/submission/form/submission-form.component.html b/src/app/submission/form/submission-form.component.html index c79364e2af..8fa1760d8f 100644 --- a/src/app/submission/form/submission-form.component.html +++ b/src/app/submission/form/submission-form.component.html @@ -1,7 +1,6 @@
-

ds-submission-upload-files

@@ -10,7 +9,6 @@
-

ds-submission-form-collection

-

ds-submission-form-section-add

@@ -32,7 +29,6 @@
-

ds-submission-section-container

@@ -44,7 +40,6 @@
diff --git a/src/app/submission/sections/container/section-container.component.html b/src/app/submission/sections/container/section-container.component.html index f39ba72ffa..99bcec168f 100644 --- a/src/app/submission/sections/container/section-container.component.html +++ b/src/app/submission/sections/container/section-container.component.html @@ -42,7 +42,7 @@
-
aaaaaaaaa +
diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html index c9d79293ac..75318b937f 100644 --- a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html @@ -1,15 +1,29 @@ -
- - +
+ +
+ +
+ + {{selectedServices[pattern]?.name}} +
+ +
+
+ Select a service for {{ pattern }} of this item + + Coar-Notify-Pattern + + The selected service is compatible with the item according to its current status. {{ selectedServices[pattern].name }}: {{ selectedServices[pattern].description }} + + + {{ 'ldn-new-service.form.label.addPattern' | translate }} +
+
diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss index e69de29bb2..c06ef5951c 100644 --- a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss @@ -0,0 +1,15 @@ +.add-pattern-link { + color: #0048ff; + cursor: pointer; +} +.ds-alert-coar{ + position: relative +} + +.coar-img-submission{ + position: absolute; top: 0; left: 0; width: 50px; height: 50px; +} + +.ds-alert-box{ + +} diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts index 726f5ec6c4..39c8c9753d 100644 --- a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts @@ -61,6 +61,8 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent patterns: string[] = []; selectedServices: { [key: string]: LdnService } = {}; patternsLoaded = false; + selectedService: any; + public AlertTypeEnum = AlertType; /** @@ -181,6 +183,18 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent }); } + + addService() { + this.patterns.push(''); + } + + + removeService(index: number) { + if (index >= 0 && index < this.patterns.length) { + this.patterns.splice(index, 1); + } + } + /** * Handle the customEvent (ex. drag-drop move event). * The customEvent is stored inside event.$event @@ -301,25 +315,43 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent */ fetchLdnServices() { this.ldnServicesRD$ = this.ldnServicesService.findAll().pipe( - getFirstCompletedRemoteData() + getFirstCompletedRemoteData() ); this.ldnServicesRD$.subscribe((data) => { if (this.patternsLoaded) { this.patterns.forEach((pattern) => { this.selectedServices[pattern] = data.payload.page.find((service) => - this.hasInboundPattern(service, `Request ${pattern}`) + this.hasInboundPattern(service, pattern) ); + + //console.log('Pattern:', pattern); + //console.log('Service:', this.selectedServices[pattern]); + + if (this.selectedServices[pattern]) { + //console.log('Name:', this.selectedServices[pattern].name); + //console.log('Description:', this.selectedServices[pattern].description); + } }); } }); } + protected getSectionStatus(): Observable { return undefined; } hasInboundPattern(service: any, patternType: string): boolean { - return service.notifyServiceInboundPatterns.some(pattern => pattern.pattern === patternType); + //console.log('Pattern Type:', patternType); + //console.log('Inbound Patterns in Service:', service.notifyServiceInboundPatterns); + + const hasPattern = service.notifyServiceInboundPatterns.some((pattern: { pattern: string; }) => { + //console.log('Checking Pattern:', pattern.pattern); + return pattern.pattern === patternType; + }); + + //console.log('Has Inbound Pattern:', hasPattern); + return hasPattern; } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 40f0150022..58453db518 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1982,6 +1982,8 @@ "info.coar-notify.breadcrumbs": "Notify Support", + "submission.sections.notify.info": "The selected service is compatible with the item according to its current status. {{ service.name }}: {{ service.description }}", + "info.feedback.head": "Feedback", "info.feedback.title": "Feedback", diff --git a/src/assets/images/notify_logo.png b/src/assets/images/notify_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0350c641df9cb51c2c6a81c0a6badb96adcd5c87 GIT binary patch literal 19269 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 Date: Thu, 26 Oct 2023 19:26:33 +0200 Subject: [PATCH 15/83] [CST-12145] parial commit --- .../quality-assurance-topic-data.service.ts | 7 +++- .../qa-event-notification.component.html | 6 ++- .../qa-event-notification.component.ts | 42 +++++++++++++++---- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts index 0f52771f51..92ae87e252 100644 --- a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts +++ b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts @@ -17,6 +17,7 @@ import { dataService } from '../../../data/base/data-service.decorator'; import { QUALITY_ASSURANCE_TOPIC_OBJECT } from '../models/quality-assurance-topic-object.resource-type'; import { FindAllData, FindAllDataImpl } from '../../../data/base/find-all-data'; import { hasValue } from 'src/app/shared/empty.util'; +import { SearchData, SearchDataImpl } from 'src/app/core/data/base/search-data'; /** * The service handling all Quality Assurance topic REST requests. @@ -26,6 +27,9 @@ import { hasValue } from 'src/app/shared/empty.util'; export class QualityAssuranceTopicDataService extends IdentifiableDataService { private findAllData: FindAllData; + private searchData: SearchData; + + private searchByTargetMethod = 'byTarget'; /** * Initialize service variables @@ -44,6 +48,7 @@ export class QualityAssuranceTopicDataService extends IdentifiableDataServiceqa-event-notification works!

+ + asdfasdf + + +asfasdfasdf 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 b5163e0757..ecb9904cef 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,8 +1,12 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { Item } from '../../../core/shared/item.model'; -import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { getFirstCompletedRemoteData, getPaginatedListPayload, getRemoteDataPayload } from '../../../core/shared/operators'; import { QualityAssuranceEventDataService } from '../../../core/suggestion-notifications/qa/events/quality-assurance-event-data.service'; import { QualityAssuranceTopicDataService } from '../../../core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service'; +import { QualityAssuranceTopicObject } from 'src/app/core/suggestion-notifications/qa/models/quality-assurance-topic.model'; +import { Observable, concatMap, from, map, mergeMap, of, switchMap, tap } from 'rxjs'; +import { QualityAssuranceEventObject } from 'src/app/core/suggestion-notifications/qa/models/quality-assurance-event.model'; +import { AlertType } from 'src/app/shared/alert/aletr-type'; @Component({ selector: 'ds-qa-event-notification', @@ -15,20 +19,40 @@ export class QaEventNotificationComponent { @Input() item: Item; + events: QualityAssuranceEventObject[] = []; + + AlertTypeInfo = AlertType.Info; + constructor( - protected qualityAssuranceEventDataService: QualityAssuranceEventDataService, - protected qualityAssuranceTopicDataService: QualityAssuranceTopicDataService, + private qualityAssuranceEventDataService: QualityAssuranceEventDataService, + private qualityAssuranceTopicDataService: QualityAssuranceTopicDataService, ) { } ngOnInit(): void { - this.getTopics(); + this.getEventsByTopicsAndTarget(); } - getTopics(): void { - this.qualityAssuranceTopicDataService.getTopicsByTargetAndSource(this.item.id, 'coar-notify', {}, true, true).pipe( + getEventsByTopicsAndTarget(): void { + // TODO: add source 'coar-notify' + this.qualityAssuranceTopicDataService.getTopicsByTargetAndSource(this.item.id).pipe( getFirstCompletedRemoteData(), - ).subscribe((topics) => { - console.log(topics); - }); + getRemoteDataPayload(), + getPaginatedListPayload(), + tap((topics: QualityAssuranceTopicObject[]) => console.log(topics, 'topics')), + mergeMap((topics: QualityAssuranceTopicObject[]) => { + return from(topics).pipe( + concatMap((topic: QualityAssuranceTopicObject) => { + return this.qualityAssuranceEventDataService.getEventsByTopicAndTarget(topic.name, this.item.id).pipe( + tap((events: any) => console.log(events, 'events')), + ); + } ) + ); + }), + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + getPaginatedListPayload(), + ).subscribe((events: QualityAssuranceEventObject[]) => { + this.events = events; + console.log(events, 'events2')}); } } From b102ef7165e32ad39a01b9ad22752dddcfe4764a Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Thu, 26 Oct 2023 19:28:44 +0200 Subject: [PATCH 16/83] [CST-12235] changed property name to ldn.notify.inbox --- src/app/core/coar-notify/notify-info/notify-info.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/core/coar-notify/notify-info/notify-info.service.ts b/src/app/core/coar-notify/notify-info/notify-info.service.ts index 4b2d572d3c..87bbc0a9cd 100644 --- a/src/app/core/coar-notify/notify-info/notify-info.service.ts +++ b/src/app/core/coar-notify/notify-info/notify-info.service.ts @@ -35,7 +35,7 @@ export class NotifyInfoService { * @returns the url of the local inbox */ getCoarLdnLocalInboxUrls(): Observable { - return this.configService.findByPropertyName('ldn.notify.local-inbox-endpoint').pipe( + return this.configService.findByPropertyName('ldn.notify.inbox').pipe( getFirstSucceededRemoteData(), getRemoteDataPayload(), map((response: ConfigurationProperty) => { From e9dd340e712870faf8fe998ca431c638da81f479 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Fri, 27 Oct 2023 16:23:01 +0200 Subject: [PATCH 17/83] CST-11045 Added jsona5 text for coar submission section --- src/assets/i18n/en.json5 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 58453db518..0a68ae3934 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -4762,6 +4762,8 @@ "submission.sections.submit.progressbar.sherpaPolicies": "Publisher open access policy information", + "submission.sections.submit.progressbar.coarnotify": "COAR Notify", + "submission.sections.sherpa-policy.title-empty": "No publisher policy information available. If your work has an associated ISSN, please enter it above to see any related publisher open access policies.", "submission.sections.status.errors.title": "Errors", From 92d66c911a303ad0054f271e867b5fe7c0c11f31 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Fri, 27 Oct 2023 16:24:17 +0200 Subject: [PATCH 18/83] CST-11045 CSS refactor + dropdown data correctly populated --- .../section-coar-notify.component.html | 52 ++++++--- .../section-coar-notify.component.scss | 15 ++- .../section-coar-notify.component.ts | 109 +++++++++++------- src/app/submission/submission.module.ts | 33 +++--- 4 files changed, 131 insertions(+), 78 deletions(-) diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html index 75318b937f..f2c7fd0947 100644 --- a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html @@ -1,27 +1,41 @@
- -
- - {{selectedServices[pattern]?.name}} -
- + +
+ +
+ +
+
+ Select a service for {{ pattern }} of this item +
+
+
+ Coar-Notify-Pattern + +
The selected service is compatible with the item according to its current status.
+
+
+ + +
{{ selectedServices[pattern].name }}: {{ selectedServices[pattern].description }}
- Select a service for {{ pattern }} of this item - - Coar-Notify-Pattern - - The selected service is compatible with the item according to its current status. {{ selectedServices[pattern].name }}: {{ selectedServices[pattern].description }} - - + +
{{ 'ldn-new-service.form.label.addPattern' | translate }}
diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss index c06ef5951c..f1504fdff6 100644 --- a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.scss @@ -2,14 +2,21 @@ color: #0048ff; cursor: pointer; } -.ds-alert-coar{ + +.ds-alert-coar { position: relative } -.coar-img-submission{ - position: absolute; top: 0; left: 0; width: 50px; height: 50px; +.coar-img-submission { + max-height: var(--ds-header-logo-height); } -.ds-alert-box{ +.icon-check { + color: rgba(6, 68, 6, 0.42); + font-size: var(--ds-header-logo-height); +} + + +.ds-alert-box { } diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts index 39c8c9753d..3cf040acd9 100644 --- a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.ts @@ -23,15 +23,14 @@ import { LdnServicesService } from '../../../admin/admin-ldn-services/ldn-servic import { isLoading } from '../../../core/data/request-entry-state.model'; import { LdnService } from '../../../admin/admin-ldn-services/ldn-services-model/ldn-services.model'; import { SECTION_COAR_FORM_LAYOUT, SECTION_COAR_FORM_MODEL } from './section-coar-notify-model'; -import { - CoarNotifyConfigDataService -} from './coar-notify-config-data.service'; +import { CoarNotifyConfigDataService } from './coar-notify-config-data.service'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; import { SubmissionCoarNotifyConfig } from './submission-coar-notify.config'; import { FormFieldPreviousValueObject } from '../../../shared/form/builder/models/form-field-previous-value-object'; import { UntypedFormGroup } from '@angular/forms'; import { AlertType } from '../../../shared/alert/aletr-type'; +import { filter, map, take } from "rxjs/operators"; export interface CoarNotifyDropdownSelector { ldnService: LdnService; @@ -60,8 +59,11 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent patterns: string[] = []; selectedServices: { [key: string]: LdnService } = {}; + patternServices: { [key: string]: LdnService } = {}; + patternsLoaded = false; - selectedService: any; + patternObservables: Observable>[]>; + public AlertTypeEnum = AlertType; @@ -172,7 +174,7 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent */ setCoarNotifyConfig() { this.coarNotifyConfigRD$ = this.coarNotifyConfigDataService.findAll().pipe( - getFirstCompletedRemoteData() + getFirstCompletedRemoteData() ); this.coarNotifyConfigRD$.subscribe((data) => { @@ -202,10 +204,10 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent */ onCustomEvent(event: DynamicFormControlEvent) { this.formOperationsService.dispatchOperationsFromEvent( - this.pathCombiner, - event, - this.previousValue, - null); + this.pathCombiner, + event, + this.previousValue, + null); } /** @@ -244,10 +246,10 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent } this.formOperationsService.dispatchOperationsFromEvent( - this.pathCombiner, - event, - this.previousValue, - this.hasStoredValue(fieldId, fieldIndex)); + this.pathCombiner, + event, + this.previousValue, + this.hasStoredValue(fieldId, fieldIndex)); } @@ -262,8 +264,8 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent hasStoredValue(fieldId, index): boolean { if (isNotEmpty(this.sectionData.data)) { return this.sectionData.data.hasOwnProperty(fieldId) && - isNotEmpty(this.sectionData.data[fieldId][index]) && - !this.isFieldToRemove(fieldId, index); + isNotEmpty(this.sectionData.data[fieldId][index]) && + !this.isFieldToRemove(fieldId, index); } else { return false; } @@ -305,8 +307,8 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent */ onSectionDestroy() { this.subs - .filter((subscription) => hasValue(subscription)) - .forEach((subscription) => subscription.unsubscribe()); + .filter((subscription) => hasValue(subscription)) + .forEach((subscription) => subscription.unsubscribe()); } /** @@ -314,44 +316,73 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent * Retriev available NotifyConfigs */ fetchLdnServices() { - this.ldnServicesRD$ = this.ldnServicesService.findAll().pipe( - getFirstCompletedRemoteData() - ); + if (!this.ldnServicesRD$) { + this.ldnServicesRD$ = this.ldnServicesService.findAll().pipe( + getFirstCompletedRemoteData() + ); + } this.ldnServicesRD$.subscribe((data) => { if (this.patternsLoaded) { this.patterns.forEach((pattern) => { - this.selectedServices[pattern] = data.payload.page.find((service) => - this.hasInboundPattern(service, pattern) - ); + const servicesWithPattern = this.getServicesWithPattern(pattern, data?.payload?.page); - //console.log('Pattern:', pattern); - //console.log('Service:', this.selectedServices[pattern]); + if (servicesWithPattern.length > 0) { + this.selectedServices[pattern] = servicesWithPattern[0]; + } + + console.log('Pattern:', pattern); + console.log('Service:', this.selectedServices[pattern]); if (this.selectedServices[pattern]) { - //console.log('Name:', this.selectedServices[pattern].name); - //console.log('Description:', this.selectedServices[pattern].description); + console.log('Name:', this.selectedServices[pattern].name); + console.log('Description:', this.selectedServices[pattern].description); } }); } }); } + getServicesWithPattern(pattern: string, services: LdnService[] | null): LdnService[] { + if (services) { + return services.filter((service) => this.hasInboundPattern(service, pattern)); + } + return []; + } + + + filterServices(pattern: string): LdnService[] { + let ldnServices: LdnService[] = []; + + this.ldnServicesRD$.pipe( + filter((rd) => rd.hasSucceeded), + map((rd) => rd.payload.page) + ).subscribe((services) => { + ldnServices = services.filter((service) => this.hasInboundPattern(service, pattern)); + }); + + return ldnServices; + } + + + + + + hasInboundPattern(service: any, patternType: string): boolean { + console.log('Pattern Type:', patternType); + console.log('Inbound Patterns in Service:', service.notifyServiceInboundPatterns); + + const hasPattern = service.notifyServiceInboundPatterns.some((pattern: { pattern: string; }) => { + console.log('Checking Pattern:', pattern.pattern); + return pattern.pattern === patternType; + }); + + console.log('Has Inbound Pattern:', hasPattern); + return hasPattern; + } protected getSectionStatus(): Observable { return undefined; } - hasInboundPattern(service: any, patternType: string): boolean { - //console.log('Pattern Type:', patternType); - //console.log('Inbound Patterns in Service:', service.notifyServiceInboundPatterns); - - const hasPattern = service.notifyServiceInboundPatterns.some((pattern: { pattern: string; }) => { - //console.log('Checking Pattern:', pattern.pattern); - return pattern.pattern === patternType; - }); - - //console.log('Has Inbound Pattern:', hasPattern); - return hasPattern; - } } diff --git a/src/app/submission/submission.module.ts b/src/app/submission/submission.module.ts index f4f479e204..d839565f8d 100644 --- a/src/app/submission/submission.module.ts +++ b/src/app/submission/submission.module.ts @@ -10,7 +10,7 @@ import { SubmissionFormFooterComponent } from './form/footer/submission-form-foo import { SubmissionFormComponent } from './form/submission-form.component'; import { SubmissionFormSectionAddComponent } from './form/section-add/submission-form-section-add.component'; import { SubmissionSectionContainerComponent } from './sections/container/section-container.component'; -import { CommonModule } from '@angular/common'; +import { CommonModule, NgOptimizedImage } from '@angular/common'; import { Action, StoreConfig, StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; import { submissionReducers, SubmissionState } from './submission.reducers'; @@ -115,21 +115,22 @@ const DECLARATIONS = [ ]; @NgModule({ - imports: [ - CommonModule, - CoreModule.forRoot(), - SharedModule, - StoreModule.forFeature('submission', submissionReducers, storeModuleConfig as StoreConfig), - EffectsModule.forFeature(), - EffectsModule.forFeature(submissionEffects), - JournalEntitiesModule.withEntryComponents(), - ResearchEntitiesModule.withEntryComponents(), - FormModule, - NgbModalModule, - NgbCollapseModule, - NgbAccordionModule, - UploadModule, - ], + imports: [ + CommonModule, + CoreModule.forRoot(), + SharedModule, + StoreModule.forFeature('submission', submissionReducers, storeModuleConfig as StoreConfig), + EffectsModule.forFeature(), + EffectsModule.forFeature(submissionEffects), + JournalEntitiesModule.withEntryComponents(), + ResearchEntitiesModule.withEntryComponents(), + FormModule, + NgbModalModule, + NgbCollapseModule, + NgbAccordionModule, + UploadModule, + NgOptimizedImage, + ], declarations: DECLARATIONS, exports: [ ...DECLARATIONS, From e87c12cca30d98fc7ef19199323410a2f6cf082d Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Fri, 27 Oct 2023 18:28:52 +0200 Subject: [PATCH 19/83] [CST-12145] implementation of item-page & y dspace coar-notify notifications --- .../admin-notifications-routing.module.ts | 15 +++++ .../quality-assurance-event-data.service.ts | 18 +---- .../quality-assurance-topic-data.service.ts | 31 +-------- .../qa-event-notification.component.html | 12 ++-- .../qa-event-notification.component.scss | 8 +++ .../qa-event-notification.component.ts | 67 ++++++++++++++----- ...ace-qa-events-notifications.component.html | 12 +++- ...ace-qa-events-notifications.component.scss | 8 +++ ...space-qa-events-notifications.component.ts | 31 ++++----- .../quality-assurance-topics.component.ts | 8 +++ .../quality-assurance-topics.service.ts | 18 +++++ src/assets/i18n/en.json5 | 4 ++ src/assets/i18n/it.json5 | 8 +++ 13 files changed, 153 insertions(+), 87 deletions(-) diff --git a/src/app/admin/admin-notifications/admin-notifications-routing.module.ts b/src/app/admin/admin-notifications/admin-notifications-routing.module.ts index 60fa679777..6d02ac8292 100644 --- a/src/app/admin/admin-notifications/admin-notifications-routing.module.ts +++ b/src/app/admin/admin-notifications/admin-notifications-routing.module.ts @@ -49,6 +49,21 @@ import { SourceDataResolver } from './admin-quality-assurance-source-page-compon showBreadcrumbsFluid: false } }, + { + canActivate: [ AuthenticatedGuard ], + path: `${QUALITY_ASSURANCE_EDIT_PATH}/:sourceId/:targetId`, + component: AdminQualityAssuranceTopicsPageComponent, + pathMatch: 'full', + resolve: { + breadcrumb: I18nBreadcrumbResolver, + openaireQualityAssuranceTopicsParams: AdminQualityAssuranceTopicsPageResolver + }, + data: { + title: 'admin.quality-assurance.page.title', + breadcrumbKey: 'admin.quality-assurance', + showBreadcrumbsFluid: false + } + }, { canActivate: [ AuthenticatedGuard ], path: `${QUALITY_ASSURANCE_EDIT_PATH}`, diff --git a/src/app/core/suggestion-notifications/qa/events/quality-assurance-event-data.service.ts b/src/app/core/suggestion-notifications/qa/events/quality-assurance-event-data.service.ts index 5e9a4f430b..6c333cc6f5 100644 --- a/src/app/core/suggestion-notifications/qa/events/quality-assurance-event-data.service.ts +++ b/src/app/core/suggestion-notifications/qa/events/quality-assurance-event-data.service.ts @@ -86,27 +86,11 @@ export class QualityAssuranceEventDataService extends IdentifiableDataService[]): Observable>> { - options.searchParams = [ - { - fieldName: 'topic', - fieldValue: topic - } - ]; - - if (hasValue(target)) { - options.searchParams.push({ - fieldName: 'target', - fieldValue: target - }); - } - + public searchEventsByTopic(options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig[]): Observable>> { return this.searchData.searchBy('findByTopic', options, true, true, ...linksToFollow); } diff --git a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts index 92ae87e252..626674a5ad 100644 --- a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts +++ b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts @@ -16,8 +16,7 @@ import { IdentifiableDataService } from '../../../data/base/identifiable-data.se import { dataService } from '../../../data/base/data-service.decorator'; import { QUALITY_ASSURANCE_TOPIC_OBJECT } from '../models/quality-assurance-topic-object.resource-type'; import { FindAllData, FindAllDataImpl } from '../../../data/base/find-all-data'; -import { hasValue } from 'src/app/shared/empty.util'; -import { SearchData, SearchDataImpl } from 'src/app/core/data/base/search-data'; +import { SearchData, SearchDataImpl } from '../../../../core/data/base/search-data'; /** * The service handling all Quality Assurance topic REST requests. @@ -68,34 +67,6 @@ export class QualityAssuranceTopicDataService extends IdentifiableDataService>. - */ - public getTopicsByTargetAndSource(target: string, source?: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { - options.searchParams = [ - { - fieldName: 'target', - fieldValue: target - } - ]; - - if (hasValue(source)) { - options.searchParams.push({ - fieldName: 'source', - fieldValue: source - }); - } - - return this.searchData.searchBy(this.searchByTargetMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); - } - /** * Clear FindAll topics requests from cache */ diff --git a/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.html b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.html index be0e7ac763..eb663fceb0 100644 --- a/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.html +++ b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.html @@ -1,5 +1,9 @@ - - asdfasdf - + +
+ +
+
{{'item.qa-event-notification.check.notification-info' | translate : {num: (events$ | async)?.length} }}
+ +
+
-asfasdfasdf diff --git a/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.scss b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.scss index e69de29bb2..1cc0db27c8 100644 --- a/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.scss +++ b/src/app/item-page/simple/qa-event-notification/qa-event-notification.component.scss @@ -0,0 +1,8 @@ + +.notify-logo { + max-height: var(--ds-header-logo-height); +} + +.sections-gap { + gap: 1rem; +} 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 ecb9904cef..455629c026 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 { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { Item } from '../../../core/shared/item.model'; import { getFirstCompletedRemoteData, getPaginatedListPayload, getRemoteDataPayload } from '../../../core/shared/operators'; import { QualityAssuranceEventDataService } from '../../../core/suggestion-notifications/qa/events/quality-assurance-event-data.service'; import { QualityAssuranceTopicDataService } from '../../../core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service'; -import { QualityAssuranceTopicObject } from 'src/app/core/suggestion-notifications/qa/models/quality-assurance-topic.model'; -import { Observable, concatMap, from, map, mergeMap, of, switchMap, tap } from 'rxjs'; -import { QualityAssuranceEventObject } from 'src/app/core/suggestion-notifications/qa/models/quality-assurance-event.model'; -import { AlertType } from 'src/app/shared/alert/aletr-type'; +import { QualityAssuranceTopicObject } from '../../../core/suggestion-notifications/qa/models/quality-assurance-topic.model'; +import { Observable, concatMap, from, mergeMap } from 'rxjs'; +import { QualityAssuranceEventObject } from '../../../core/suggestion-notifications/qa/models/quality-assurance-event.model'; +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'; @Component({ selector: 'ds-qa-event-notification', @@ -15,44 +17,73 @@ import { AlertType } from 'src/app/shared/alert/aletr-type'; changeDetection: ChangeDetectionStrategy.OnPush, providers: [QualityAssuranceTopicDataService, QualityAssuranceEventDataService] }) -export class QaEventNotificationComponent { +/** + * Component for displaying quality assurance event notifications for an item. + */ +export class QaEventNotificationComponent implements OnInit { + /** + * The item to display quality assurance event notifications for. + */ @Input() item: Item; - events: QualityAssuranceEventObject[] = []; + /** + * An observable of quality assurance events for the item. + */ + events$: Observable; + /** + * The type of alert to display for the notification. + */ AlertTypeInfo = AlertType.Info; + /** + * The source of the quality assurance events. + */ + source = 'coar-notify'; + constructor( private qualityAssuranceEventDataService: QualityAssuranceEventDataService, private qualityAssuranceTopicDataService: QualityAssuranceTopicDataService, ) { } - ngOnInit(): void { + ngOnInit() { this.getEventsByTopicsAndTarget(); } - getEventsByTopicsAndTarget(): void { - // TODO: add source 'coar-notify' - this.qualityAssuranceTopicDataService.getTopicsByTargetAndSource(this.item.id).pipe( + /** + * Retrieves quality assurance events by topics and target. + * First, it retrieves the topics by target and source. + * -> target: item.id + * -> source: 'coar-notify' + * Then, it retrieves the events by topic and target. + */ + getEventsByTopicsAndTarget() { + const findListTopicOptions: FindListOptions = { + searchParams: [new RequestParam('source', this.source), new RequestParam('target', this.item.id)] + }; + + // const findListEventOptions: FindListOptions = { + // searchParams: [new RequestParam('topic', topic.name), new RequestParam('target', this.item.id)] + // }; + + this.events$ = this.qualityAssuranceTopicDataService.getTopics(findListTopicOptions).pipe( getFirstCompletedRemoteData(), getRemoteDataPayload(), getPaginatedListPayload(), - tap((topics: QualityAssuranceTopicObject[]) => console.log(topics, 'topics')), mergeMap((topics: QualityAssuranceTopicObject[]) => { return from(topics).pipe( concatMap((topic: QualityAssuranceTopicObject) => { - return this.qualityAssuranceEventDataService.getEventsByTopicAndTarget(topic.name, this.item.id).pipe( - tap((events: any) => console.log(events, 'events')), - ); + const findListEventOptions: FindListOptions = { + searchParams: [new RequestParam('topic', topic.name), new RequestParam('target', this.item.id)] + }; + return this.qualityAssuranceEventDataService.searchEventsByTopic(findListEventOptions); } ) ); }), getFirstCompletedRemoteData(), getRemoteDataPayload(), getPaginatedListPayload(), - ).subscribe((events: QualityAssuranceEventObject[]) => { - this.events = events; - console.log(events, 'events2')}); + ); } } diff --git a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.html b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.html index db0611e8f8..fb73cff905 100644 --- a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.html +++ b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.html @@ -1 +1,11 @@ -

my-dspace-qa-events-notifications works!

+ + +
+ +
+
{{'item.qa-event-notification.check.notification-info' | translate : {num: source.totalEvents} }}
+ +
+
+
+
diff --git a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.scss b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.scss index e69de29bb2..1cc0db27c8 100644 --- a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.scss +++ b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.scss @@ -0,0 +1,8 @@ + +.notify-logo { + max-height: var(--ds-header-logo-height); +} + +.sections-gap { + gap: 1rem; +} diff --git a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts index d0c42d9bcb..8b7127dd89 100644 --- a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts +++ b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts @@ -1,9 +1,7 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { QualityAssuranceSourceDataService } from '../../core/suggestion-notifications/qa/source/quality-assurance-source-data.service'; -import { getFirstCompletedRemoteData } from 'src/app/core/shared/operators'; -import { map } from 'rxjs'; -import { RemoteData } from 'src/app/core/data/remote-data'; -import { PaginatedList } from 'src/app/core/data/paginated-list.model'; +import { getFirstCompletedRemoteData, getPaginatedListPayload, getRemoteDataPayload } from '../../core/shared/operators'; +import { Observable, of, tap } from 'rxjs'; import { QualityAssuranceSourceObject } from 'src/app/core/suggestion-notifications/qa/models/quality-assurance-source.model'; @Component({ @@ -12,7 +10,9 @@ import { QualityAssuranceSourceObject } from 'src/app/core/suggestion-notificati styleUrls: ['./my-dspace-qa-events-notifications.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class MyDspaceQaEventsNotificationsComponent { +export class MyDspaceQaEventsNotificationsComponent implements OnInit { + + sources$: Observable = of([]); constructor(private qualityAssuranceSourceDataService: QualityAssuranceSourceDataService) { } @@ -21,19 +21,16 @@ export class MyDspaceQaEventsNotificationsComponent { } getSources() { - this.qualityAssuranceSourceDataService.getSource('coar-notify') + this.sources$ = this.qualityAssuranceSourceDataService.getSources() .pipe( getFirstCompletedRemoteData(), - map((rd: RemoteData) => { - if (rd.hasSucceeded) { - return rd.payload; - } else { - throw new Error('Can\'t retrieve Quality Assurance source'); + tap((rd) => { + if (rd.hasFailed) { + throw new Error('Can\'t retrieve Quality Assurance sources'); } - }) - ) - .subscribe((sources) => { - console.log(sources); - }); + }), + getRemoteDataPayload(), + getPaginatedListPayload(), + ); } } diff --git a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.ts b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.ts index 3c8b4f8f38..6d96795ea3 100644 --- a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.ts +++ b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.ts @@ -60,6 +60,12 @@ export class QualityAssuranceTopicsComponent implements OnInit { */ public sourceId: string; + /** + * This property represents a targetId (item-id) which is used to retrive a topic + * @type {string} + */ + public targetId: string; + /** * Initialize the component variables. * @param {PaginationService} paginationService @@ -80,7 +86,9 @@ export class QualityAssuranceTopicsComponent implements OnInit { */ ngOnInit(): void { this.sourceId = this.activatedRoute.snapshot.paramMap.get('sourceId'); + this.targetId = this.activatedRoute.snapshot.paramMap.get('targetId'); this.qualityAssuranceTopicsService.setSourceId(this.sourceId); + this.qualityAssuranceTopicsService.setTargetId(this.targetId); this.topics$ = this.notificationsStateService.getQualityAssuranceTopics(); this.totalElements$ = this.notificationsStateService.getQualityAssuranceTopicsTotals(); } diff --git a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.service.ts b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.service.ts index 6820791dff..c94ffe72d4 100644 --- a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.service.ts +++ b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.service.ts @@ -13,6 +13,7 @@ import { import { RequestParam } from '../../../core/cache/models/request-param.model'; import { FindListOptions } from '../../../core/data/find-list-options.model'; import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { hasValue } from '../../../shared/empty.util'; /** * The service handling all Quality Assurance topic requests to the REST service. @@ -33,6 +34,11 @@ export class QualityAssuranceTopicsService { */ sourceId: string; + /** + * targetId used to get topics + */ + targetId: string; + /** * Return the list of Quality Assurance topics managing pagination and errors. * @@ -53,6 +59,10 @@ export class QualityAssuranceTopicsService { searchParams: [new RequestParam('source', this.sourceId)] }; + if (hasValue(this.targetId)) { + findListOptions.searchParams.push(new RequestParam('target', this.targetId)); + } + return this.qualityAssuranceTopicRestService.getTopics(findListOptions).pipe( getFirstCompletedRemoteData(), map((rd: RemoteData>) => { @@ -72,4 +82,12 @@ export class QualityAssuranceTopicsService { setSourceId(sourceId: string) { this.sourceId = sourceId; } + + /** + * set targetId which is used to get topics + * @param targetId string + */ + setTargetId(targetId: string) { + this.targetId = targetId; + } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 7a68fc60c8..7e0eea931e 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2448,6 +2448,10 @@ "item.truncatable-part.show-less": "Collapse", + "item.qa-event-notification.check.notification-info": "There are {{num}} pending review to check", + + "item.qa-event-notification-info.check.button": "Check", + "workflow-item.search.result.delete-supervision.modal.header": "Delete Supervision Order", "workflow-item.search.result.delete-supervision.modal.info": "Are you sure you want to delete Supervision Order", diff --git a/src/assets/i18n/it.json5 b/src/assets/i18n/it.json5 index 4131d0bee6..961fea3ae7 100644 --- a/src/assets/i18n/it.json5 +++ b/src/assets/i18n/it.json5 @@ -3723,6 +3723,14 @@ // "item.truncatable-part.show-less": "Collapse", "item.truncatable-part.show-less": "Riduci", + // "item.qa-event-notification.check.notification-info": "There are {{num}} pending review to check", + // TODO New key - Add a translation + "item.qa-event-notification.check.notification-info": "There are {{num}} pending review to check", + + // "item.qa-event-notification-info.check.button": "Check", + // TODO New key - Add a translation + "item.qa-event-notification-info.check.button": "Check", + // "workflow-item.search.result.delete-supervision.modal.header": "Delete Supervision Order", // TODO New key - Add a translation "workflow-item.search.result.delete-supervision.modal.header": "Delete Supervision Order", From 8e0af9bceed05c9795d03966cd87b3462b21ebd4 Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Mon, 30 Oct 2023 10:57:04 +0100 Subject: [PATCH 20/83] [CST-12145] commented code --- .../topics/quality-assurance-topic-data.service.ts | 12 ++++++++++++ .../qa-event-notification.component.ts | 6 +----- .../my-dspace-qa-events-notifications.component.ts | 8 ++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts index 626674a5ad..bb98e6fabf 100644 --- a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts +++ b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts @@ -67,6 +67,18 @@ export class QualityAssuranceTopicDataService extends IdentifiableDataService[]): Observable>> { + return this.searchData.searchBy(this.searchByTargetMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + } + /** * Clear FindAll topics requests from cache */ 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 455629c026..0a26045e39 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 @@ -63,11 +63,7 @@ export class QaEventNotificationComponent implements OnInit { searchParams: [new RequestParam('source', this.source), new RequestParam('target', this.item.id)] }; - // const findListEventOptions: FindListOptions = { - // searchParams: [new RequestParam('topic', topic.name), new RequestParam('target', this.item.id)] - // }; - - this.events$ = this.qualityAssuranceTopicDataService.getTopics(findListTopicOptions).pipe( + this.events$ = this.qualityAssuranceTopicDataService.searchTopics(findListTopicOptions).pipe( getFirstCompletedRemoteData(), getRemoteDataPayload(), getPaginatedListPayload(), diff --git a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts index 8b7127dd89..9992ec9ff8 100644 --- a/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts +++ b/src/app/my-dspace-page/my-dspace-qa-events-notifications/my-dspace-qa-events-notifications.component.ts @@ -12,6 +12,9 @@ import { QualityAssuranceSourceObject } from 'src/app/core/suggestion-notificati }) export class MyDspaceQaEventsNotificationsComponent implements OnInit { + /** + * An Observable that emits an array of QualityAssuranceSourceObject. + */ sources$: Observable = of([]); constructor(private qualityAssuranceSourceDataService: QualityAssuranceSourceDataService) { } @@ -20,6 +23,11 @@ export class MyDspaceQaEventsNotificationsComponent implements OnInit { this.getSources(); } + /** + * Retrieves the sources for Quality Assurance. + * @returns An Observable of the sources for Quality Assurance. + * @throws An error if the retrieval of Quality Assurance sources fails. + */ getSources() { this.sources$ = this.qualityAssuranceSourceDataService.getSources() .pipe( From b927761df3cfbe847d1d33ffb715f334e7ec0792 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Mon, 30 Oct 2023 15:33:12 +0100 Subject: [PATCH 21/83] CST-11045 Dropdown behavior improved, working on multiple dropdowns --- .../section-coar-notify.component.html | 15 ++-- .../section-coar-notify.component.ts | 75 ++++++------------- 2 files changed, 31 insertions(+), 59 deletions(-) diff --git a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html index f2c7fd0947..2ce46d0520 100644 --- a/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html +++ b/src/app/submission/sections/section-coar-notify/section-coar-notify.component.html @@ -1,10 +1,11 @@
- +
- + + @@ -14,9 +15,9 @@
- Select a service for {{ pattern }} of this item -
-
+ Select a service for {{ pattern }} of this item +
+
Coar-Notify-Pattern @@ -27,7 +28,7 @@ -
{{ selectedServices[pattern].name }}: {{ selectedServices[pattern].description }}
+
{{ selectedServicesByPattern[pattern].name }}: {{ selectedServicesByPattern[pattern].description }}
@@ -182,7 +182,7 @@ [ngValue]="pattern.name">{{ pattern.name }}
- Please select at least a pattern. + {{ 'ldn-new-service.form.error.patterns' | translate }}
diff --git a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.scss b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.scss index 2c4c406530..87ddbeb893 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.scss +++ b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.scss @@ -131,7 +131,9 @@ form button.btn.btn-primary[type="submit"] { z-index: var(--ds-submission-footer-z-index); } - +div + div { + margin-bottom: 40px; +} diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index be244bbb1e..2121cc803b 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -939,6 +939,12 @@ "ldn-new-service.form.label.placeholder.selectedItemFilter": "No Item Filter Selected", "ldn-new-service.form.label.ItemFilter": "Item Filter", "ldn-new-service.form.label.automatic": "Automatic", + "ldn-new-service.form.error.name": "Name is required", + "ldn-new-service.form.error.url": "URL is required", + "ldn-new-service.form.error.ldnurl": "LDN URL is required", + "ldn-new-service.form.error.patterns": "At least a pattern is required", + "ldn-new-service.form.error.score": "Please enter a valid score (between 0 and 1). Use the “.” as decimal separator", + "ldn-new-service.form.label.outboundPattern": "Outbound Patterns", "ldn-new-service.form.label.placeholder.outboundPattern": "Select an Outbound Pattern", "ldn-new-service.form.label.addPattern": "+ Add more", From f4b8c7f1f1deb128c9671e9fc054b1e28e6555a5 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Fri, 10 Nov 2023 10:44:39 +0100 Subject: [PATCH 45/83] CST-12179 Removed comments --- .../ldn-service-coar-patterns.ts | 105 +++++------------- 1 file changed, 27 insertions(+), 78 deletions(-) diff --git a/src/app/admin/admin-ldn-services/ldn-services-patterns/ldn-service-coar-patterns.ts b/src/app/admin/admin-ldn-services/ldn-services-patterns/ldn-service-coar-patterns.ts index a882d5db11..8620bfc80c 100644 --- a/src/app/admin/admin-ldn-services/ldn-services-patterns/ldn-service-coar-patterns.ts +++ b/src/app/admin/admin-ldn-services/ldn-services-patterns/ldn-service-coar-patterns.ts @@ -1,82 +1,31 @@ export const notifyPatterns = [ - //{ - 'ack-accept', - //name: 'ldn-service.form.pattern.acknowledge-and-accept.label', - //description: 'ldn-service.form.pattern.acknowledge-and-accept.description', - //category: 'ldn-service.form.pattern.acknowledge-and-accept.category' - //}, - //{ - 'ack-reject', - //name: 'ldn-service.form.pattern.acknowledge-and-reject.label', - //description: 'ldn-service.form.pattern.acknowledge-and-reject.description', - //category: 'ldn-service.form.pattern.acknowledge-and-reject.category' - //}, - //{ - 'ack-tentative-accept', - //name: 'ldn-service.form.pattern.acknowledge-and-tentatively-accept.label', - //description: 'ldn-service.form.pattern.acknowledge-and-tentatively-accept.description', - //category: 'ldn-service.form.pattern.acknowledge-and-tentatively-accept.category' - //}, - //{ - 'ack-tentative-reject', - //name: 'ldn-service.form.pattern.acknowledge-and-tentatively-reject.label', - //description: 'ldn-service.form.pattern.acknowledge-and-tentatively-reject.description', - //category: 'ldn-service.form.pattern.acknowledge-and-tentatively-reject.category' - //}, - //{ - 'announce-endorsement', - //name: 'ldn-service.form.pattern.announce-endorsement.label', - //description: 'ldn-service.form.pattern.announce-endorsement.description', - //category: 'ldn-service.form.pattern.announce-endorsement.category' - //}, - //{ - 'announce-ingest', - //name: 'ldn-service.form.pattern.announce-ingest.label', - //description: 'ldn-service.form.pattern.announce-ingest.description', - //category: 'ldn-service.form.pattern.announce-ingest.category' - //}, - //{ - 'announce-relationship', - //name: 'ldn-service.form.pattern.announce-relationship.label', - //description: 'ldn-service.form.pattern.announce-relationship.description', - //category: 'ldn-service.form.pattern.announce-relationship.category' - //}, - //{ - 'announce-review', - //name: 'ldn-service.form.pattern.announce-review.label', - //description: 'ldn-service.form.pattern.announce-review.description', - //category: 'ldn-service.form.pattern.announce-review.category' - //}, - //{ - 'announce-service-result', - //name: 'ldn-service.form.pattern.announce-service-result.label', - //description: 'ldn-service.form.pattern.announce-service-result.description', - //category: 'ldn-service.form.pattern.announce-service-result.category' - //}, - //{ - 'request-endorsement', - //name: 'ldn-service.form.pattern.request-endorsement.label', - //description: 'ldn-service.form.pattern.request-endorsement.description', - //category: 'ldn-service.form.pattern.request-endorsement.category' - //}, - //{ - 'request-ingest', - //name: 'ldn-service.form.pattern.request-ingest.label', - //description: 'ldn-service.form.pattern.request-ingest.description', - //category: 'ldn-service.form.pattern.request-ingest.category' - //}, - //{ - 'request-review', - //name: 'ldn-service.form.pattern.request-review.label', - //description: 'ldn-service.form.pattern.request-review.description', - //category: 'ldn-service.form.pattern.request-review.category' - //}, - //{ - 'undo-offer', - //name: 'ldn-service.form.pattern.undo-offer.label', - //description: 'ldn-service.form.pattern.undo-offer.description', - //category: 'ldn-service.form.pattern.undo-offer.category' - //} + + 'ack-accept', + + 'ack-reject', + + 'ack-tentative-accept', + + 'ack-tentative-reject', + + 'announce-endorsement', + + 'announce-ingest', + + 'announce-relationship', + + 'announce-review', + + 'announce-service-result', + + 'request-endorsement', + + 'request-ingest', + + 'request-review', + + 'undo-offer', + ]; From 6675f9cd6aa455bdfb193e3c76ed87875d40c091 Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Fri, 10 Nov 2023 11:20:33 +0100 Subject: [PATCH 46/83] [CST-12535] improvements --- ...ality-assurance-topic-data.service.spec.ts | 19 +++++++++ .../quality-assurance-topic-data.service.ts | 20 ++++++++++ .../quality-assurance-topics.component.html | 6 ++- ...quality-assurance-topics.component.spec.ts | 2 + .../quality-assurance-topics.component.ts | 40 ++++++++++++++++++- src/assets/i18n/en.json5 | 2 + 6 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.spec.ts b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.spec.ts index c9b1407a53..277da6e4ba 100644 --- a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.spec.ts +++ b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.spec.ts @@ -81,6 +81,7 @@ describe('QualityAssuranceTopicDataService', () => { ); spyOn((service as any).searchData, 'searchBy').and.callThrough(); + spyOn((service as any), 'findById').and.callThrough(); }); describe('searchTopicsByTarget', () => { @@ -133,4 +134,22 @@ describe('QualityAssuranceTopicDataService', () => { }); }); + describe('getTopic', () => { + it('should call findByHref', (done) => { + service.getTopic(qualityAssuranceTopicObjectMorePid.id).subscribe( + (res) => { + expect((service as any).findById).toHaveBeenCalledWith(qualityAssuranceTopicObjectMorePid.id, true, true); + } + ); + done(); + }); + + it('should return a RemoteData for the object with the given URL', () => { + const result = service.getTopic(qualityAssuranceTopicObjectMorePid.id); + const expected = cold('(a)', { + a: qaTopicObjectRD + }); + expect(result).toBeObservable(expected); + }); + }); }); diff --git a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts index 6944e43a56..86c8f5eeaa 100644 --- a/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts +++ b/src/app/core/suggestion-notifications/qa/topics/quality-assurance-topic-data.service.ts @@ -16,6 +16,7 @@ import { IdentifiableDataService } from '../../../data/base/identifiable-data.se import { dataService } from '../../../data/base/data-service.decorator'; import { QUALITY_ASSURANCE_TOPIC_OBJECT } from '../models/quality-assurance-topic-object.resource-type'; import { SearchData, SearchDataImpl } from '../../../../core/data/base/search-data'; +import { FindAllData, FindAllDataImpl } from '../../../data/base/find-all-data'; /** * The service handling all Quality Assurance topic REST requests. @@ -24,6 +25,7 @@ import { SearchData, SearchDataImpl } from '../../../../core/data/base/search-da @dataService(QUALITY_ASSURANCE_TOPIC_OBJECT) export class QualityAssuranceTopicDataService extends IdentifiableDataService { + private findAllData: FindAllData; private searchData: SearchData; private searchByTargetMethod = 'byTarget'; @@ -45,6 +47,7 @@ export class QualityAssuranceTopicDataService extends IdentifiableDataService> + * The Quality Assurance topic. + */ + public getTopic(id: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable> { + return this.findById(id, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + } } diff --git a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.html b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.html index c13929bf8a..68de6aec7a 100644 --- a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.html +++ b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.html @@ -2,7 +2,11 @@
diff --git a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.spec.ts b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.spec.ts index 52700d778b..4137fdfae1 100644 --- a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.spec.ts +++ b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.spec.ts @@ -16,6 +16,7 @@ import { SuggestionNotificationsStateService } from '../../suggestion-notificati import { cold } from 'jasmine-marbles'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; import { PaginationService } from '../../../core/pagination/pagination.service'; +import { ItemDataService } from '../../../core/data/item-data.service'; describe('QualityAssuranceTopicsComponent test suite', () => { let fixture: ComponentFixture; @@ -49,6 +50,7 @@ describe('QualityAssuranceTopicsComponent test suite', () => { }, }}}, { provide: PaginationService, useValue: paginationService }, + { provide: ItemDataService, useValue: {} }, QualityAssuranceTopicsComponent, ], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.ts b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.ts index b04bb4fbf2..0f7a111089 100644 --- a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.ts +++ b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; -import { distinctUntilChanged, take } from 'rxjs/operators'; +import { distinctUntilChanged, map, take, tap } from 'rxjs/operators'; import { SortOptions } from '../../../core/cache/models/sort-options.model'; import { @@ -15,6 +15,10 @@ import { } from '../../../admin/admin-notifications/admin-quality-assurance-topics-page/admin-quality-assurance-topics-page-resolver.service'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { ActivatedRoute } from '@angular/router'; +import { ItemDataService } from '../../../core/data/item-data.service'; +import { getFirstCompletedRemoteData, getRemoteDataPayload } from '../../../core/shared/operators'; +import { Item } from '../../../core/shared/item.model'; +import { getItemPageRoute } from '../../../item-page/item-page-routing-paths'; /** * Component to display the Quality Assurance topic list. @@ -65,6 +69,11 @@ export class QualityAssuranceTopicsComponent implements OnInit { */ public targetId: string; + /** + * The URL of the item page. + */ + public itemPageUrl: string; + /** * Initialize the component variables. * @param {PaginationService} paginationService @@ -75,7 +84,8 @@ export class QualityAssuranceTopicsComponent implements OnInit { constructor( private paginationService: PaginationService, private activatedRoute: ActivatedRoute, - private notificationsStateService: SuggestionNotificationsStateService + private notificationsStateService: SuggestionNotificationsStateService, + private itemService: ItemDataService ) { this.sourceId = this.activatedRoute.snapshot.params.sourceId; this.targetId = this.activatedRoute.snapshot.params.targetId; @@ -156,6 +166,32 @@ export class QualityAssuranceTopicsComponent implements OnInit { } } + /** + * Returns an Observable that emits the title of the target item. + * The target item is retrieved by its ID using the itemService. + * The title is extracted from the first metadata value of the item. + * The item page URL is also set in the component. + * @returns An Observable that emits the title of the target item. + */ + getTargetItemTitle(): Observable { + return this.itemService.findById(this.targetId).pipe( + take(1), + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + tap((item: Item) => this.itemPageUrl = getItemPageRoute(item)), + map((item: Item) => item.firstMetadataValue('dc.title')) + ); + } + + /** + * Returns the page route for the given item. + * @param item The item to get the page route for. + * @returns The page route for the given item. + */ + getItemPageRoute(item: Item): string { + return getItemPageRoute(item); + } + /** * Unsubscribe from all subscriptions. */ diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index fd887d742c..a559f4cccf 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3232,6 +3232,8 @@ "quality-assurance.topics.description": "Below you can see all the topics received from the subscriptions to {{source}}.", + "quality-assurance.topics.description-with-target": "Below you can see all the topics received from the subscriptions to {{source}} in regards to the", + "quality-assurance.source.description": "Below you can see all the notification's sources.", "quality-assurance.topics": "Current Topics", From 3aaeaa63979108e51571e7b7ac739c39b8f3e9d5 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Fri, 10 Nov 2023 19:41:11 +0100 Subject: [PATCH 47/83] CST-12179 Removed comments --- .../ldn-service-form-edit.component.html | 521 ++++++++---------- .../ldn-service-form.component.html | 481 ++++++++-------- .../ldn-service-form.component.scss | 6 +- 3 files changed, 457 insertions(+), 551 deletions(-) diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html index d4029e91ea..2ba1b7028d 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html @@ -1,310 +1,271 @@
-
-
-

{{ 'ldn-edit-registered-service.title' | translate }}

-
- -
- -
- -
-
-
-
+ +
+

{{ 'ldn-edit-registered-service.title' | translate }}

+
+ +
+ +
+ +
+
+
+
-
- - -
- {{ 'ldn-new-service.form.error.name' | translate }} +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + + +
+ + +
+ + +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+ + + + +
+
+
-
- -
-   -
- - -
- - -
- -
-   -
- - -
- - -
- {{ 'ldn-new-service.form.error.url' | translate }} -
-
- -
-   -
- - -
- - -
- {{ 'ldn-new-service.form.error.ldnurl' | translate }} -
-
- -
-   -
- - -
- - -
- {{ 'ldn-new-service.form.error.score' | translate }} -
-
- -
-   -
- -
-
- -
-
- -
-
- -
-
-
-
- -
- - - - -
-
- -
- -
- - - -
- -
- -
-
-
-
- - -
- - - - -
-
+
+ + +
+ +
+ +
+
+
+
+ + +
+
+ + +
+
+
+
- {{ 'ldn-new-service.form.label.addPattern' | translate }} + {{ 'ldn-new-service.form.label.addPattern' | translate }} -
-   -
-
-
- -
-
- -
-
- -
-
-
-
+
+
+ +
+
+ +
+
+ +
+
+
+
-
+
- + - -
-
- -
-
- - - -
- -
- -
-
-
-
- -
- - -
-
+ +
+
+ +
+
+ + -
+
- {{ 'ldn-new-service.form.label.addPattern' | translate }} +
+ +
+
+
+
+ +
+
+ + +
+
+
+ +
+ + {{ 'ldn-new-service.form.label.addPattern' | translate }} - -
-   -
- - + +
-
+
- - - + + + +
-
+
- - - + + + +
diff --git a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html index d64e5f90b9..325caeb2fe 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html +++ b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html @@ -1,298 +1,247 @@
-
-
-

{{ 'ldn-create-service.title' | translate }}

-
- -
- - -
- {{ 'ldn-new-service.form.error.name' | translate }} + +
+

{{ 'ldn-create-service.title' | translate }}

+
+ +
+ + +
+ + + +
+ + +
+ + + +
+ + +
+ + + +
+ + +
+ + + +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+ + + + +
+
+ +
+ + +
+ + + +
+ +
+ +
+
-
+
-
-   -
- - -
- - -
- -
-   -
- - -
- - -
- {{ 'ldn-new-service.form.error.url' | translate }} -
-
- -
-   -
- - -
- - -
- {{ 'ldn-new-service.form.error.ldnurl' | translate }} -
-
- -
-   -
- - -
- - -
- {{ 'ldn-new-service.form.error.score' | translate }} +
+
+ +
-
-   -
+ {{ 'ldn-new-service.form.label.addPattern' | translate }} - -
-
- -
-
- -
-
- -
-
-
-
+ +
+
+ +
+
+ +
+
+ +
+
+
+
-
+
- + - -
-
- -
- {{ 'ldn-new-service.form.error.patterns' | translate }} -
-
- - -
- - - -
- -
- -
-
-
-
- -
- -
-
+ +
+
+ +
+
+ + -
+
- {{ 'ldn-new-service.form.label.addPattern' | translate }} - - -
-   -
- - -
-
- +
+ +
+
-
- -
-
-
-
-
-
+
-
- - - - -
-
- -
- {{ 'ldn-new-service.form.error.patterns' | translate }} -
-
-
- - - -
- -
- -
-
-
-
- -
- -
-
-
- -
- - {{ 'ldn-new-service.form.label.addPattern' | translate }} - -
-   -
- -
+
+
- + {{ 'ldn-new-service.form.label.addPattern' | translate }} + + + +
-
+
- - - + + + +
-
+
- - - + + + +
diff --git a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.scss b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.scss index 87ddbeb893..eb5a70c7ee 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.scss +++ b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.scss @@ -1,8 +1,6 @@ form { - max-width: 800px; font-size: 14px; position: relative; - } input[type="text"], @@ -131,9 +129,7 @@ form button.btn.btn-primary[type="submit"] { z-index: var(--ds-submission-footer-z-index); } -div + div { - margin-bottom: 40px; -} + From 075c53a1f48d0572e20278fc4f4ad444e3281e54 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Fri, 10 Nov 2023 20:00:42 +0100 Subject: [PATCH 48/83] CST-12179 Using json5 and error are logged under the various sections if the form is not valid we simply close the modal --- .../ldn-service-form-edit.component.html | 22 +++++++++++++++ .../ldn-service-form.component.html | 28 ++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html index 2ba1b7028d..67eada6b7b 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html @@ -20,6 +20,9 @@ [placeholder]="'ldn-new-service.form.placeholder.name' | translate" formControlName="name" id="name" name="name" type="text"> +
+ {{ 'ldn-new-service.form.error.name' | translate }} +
@@ -36,6 +39,9 @@ [placeholder]="'ldn-new-service.form.placeholder.url' | translate" formControlName="url" id="url" name="url" type="text"> +
+ {{ 'ldn-new-service.form.error.url' | translate }} +
@@ -47,6 +53,22 @@ id="ldnUrl" name="ldnUrl" type="text"> +
+ {{ 'ldn-new-service.form.error.ldnurl' | translate }} +
+
+ + +
+ + +
+ {{ 'ldn-new-service.form.error.score' | translate }} +
diff --git a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html index 325caeb2fe..1baa5c5066 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html +++ b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html @@ -10,6 +10,9 @@ [placeholder]="'ldn-new-service.form.placeholder.name' | translate" formControlName="name" id="name" name="name" type="text"> +
+ {{ 'ldn-new-service.form.error.name' | translate }} +
@@ -28,6 +31,9 @@ [placeholder]="'ldn-new-service.form.placeholder.url' | translate" formControlName="url" id="url" name="url" type="text"> +
+ {{ 'ldn-new-service.form.error.url' | translate }} +
@@ -39,8 +45,22 @@ id="ldnUrl" name="ldnUrl" type="text"> +
+ {{ 'ldn-new-service.form.error.ldnurl' | translate }} +
+
+ +
+ + +
+ {{ 'ldn-new-service.form.error.score' | translate }} +
-
@@ -71,6 +91,9 @@ +
+ {{ 'ldn-new-service.form.error.patterns' | translate }} +
@@ -138,6 +161,9 @@ +
+ {{ 'ldn-new-service.form.error.patterns' | translate }} +
@@ -157,7 +163,7 @@
- + {{'quality-assurance.events.back' | translate}} diff --git a/src/app/suggestion-notifications/qa/events/quality-assurance-events.component.spec.ts b/src/app/suggestion-notifications/qa/events/quality-assurance-events.component.spec.ts index 04ece87fbb..a4254962b2 100644 --- a/src/app/suggestion-notifications/qa/events/quality-assurance-events.component.spec.ts +++ b/src/app/suggestion-notifications/qa/events/quality-assurance-events.component.spec.ts @@ -42,6 +42,7 @@ import { SortDirection, SortOptions } from '../../../core/cache/models/sort-opti import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; import { FindListOptions } from '../../../core/data/find-list-options.model'; +import { ItemDataService } from 'src/app/core/data/item-data.service'; describe('QualityAssuranceEventsComponent test suite', () => { let fixture: ComponentFixture; @@ -118,6 +119,7 @@ describe('QualityAssuranceEventsComponent test suite', () => { { provide: NotificationsService, useValue: new NotificationsServiceStub() }, { provide: TranslateService, useValue: getMockTranslateService() }, { provide: PaginationService, useValue: paginationService }, + { provide: ItemDataService, useValue: {} }, QualityAssuranceEventsComponent ], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/suggestion-notifications/qa/events/quality-assurance-events.component.ts b/src/app/suggestion-notifications/qa/events/quality-assurance-events.component.ts index 742047e76f..fee2557a12 100644 --- a/src/app/suggestion-notifications/qa/events/quality-assurance-events.component.ts +++ b/src/app/suggestion-notifications/qa/events/quality-assurance-events.component.ts @@ -1,5 +1,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { Location } from '@angular/common'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; @@ -26,10 +27,12 @@ import { ProjectEntryImportModalComponent, QualityAssuranceEventData } from '../project-entry-import-modal/project-entry-import-modal.component'; -import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { getFirstCompletedRemoteData, getRemoteDataPayload } from '../../../core/shared/operators'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { Item } from '../../../core/shared/item.model'; import { FindListOptions } from '../../../core/data/find-list-options.model'; +import { getItemPageRoute } from '../../../item-page/item-page-routing-paths'; +import { ItemDataService } from '../../../core/data/item-data.service'; /** * Component to display the Quality Assurance event list. @@ -105,6 +108,26 @@ export class QualityAssuranceEventsComponent implements OnInit, OnDestroy { */ protected subs: Subscription[] = []; + /** + * The target item id, retrieved from the topic-id composition. + */ + public targetId: string; + + /** + * The URL of the item page/target. + */ + public itemPageUrl: string; + + /** + * Plain topic name (without the source id) + */ + public selectedTopicName: string; + + /** + * The source id, retrieved from the topic-id composition. + */ + public sourceId: string; + /** * Initialize the component variables. * @param {ActivatedRoute} activatedRoute @@ -120,7 +143,9 @@ export class QualityAssuranceEventsComponent implements OnInit, OnDestroy { private notificationsService: NotificationsService, private qualityAssuranceEventRestService: QualityAssuranceEventDataService, private paginationService: PaginationService, - private translateService: TranslateService + private translateService: TranslateService, + private itemService: ItemDataService, + private _location: Location ) { } @@ -137,6 +162,10 @@ export class QualityAssuranceEventsComponent implements OnInit, OnDestroy { const regEx = /!/g; this.showTopic = id.replace(regEx, '/'); this.topic = id; + const splitList = this.showTopic?.split(':'); + this.targetId = splitList.length > 2 ? splitList.pop() : null; + this.sourceId = splitList[0]; + this.selectedTopicName = splitList[1]; return this.getQualityAssuranceEvents(); }) ).subscribe((events: QualityAssuranceEventData[]) => { @@ -423,4 +452,37 @@ export class QualityAssuranceEventsComponent implements OnInit, OnDestroy { last() ); } + + /** + * Returns the page route for the given item. + * @param item The item to get the page route for. + * @returns The page route for the given item. + */ + public getItemPageRoute(item: Item): string { + return getItemPageRoute(item); + } + + /** + * Returns an Observable that emits the title of the target item. + * The target item is retrieved by its ID using the itemService. + * The title is extracted from the first metadata value of the item. + * The item page URL is also set in the component. + * @returns An Observable that emits the title of the target item. + */ + public getTargetItemTitle(): Observable { + return this.itemService.findById(this.targetId).pipe( + take(1), + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + tap((item: Item) => this.itemPageUrl = getItemPageRoute(item)), + map((item: Item) => item.firstMetadataValue('dc.title')) + ); + } + + /** + * Navigates back to the previous location in the browser's history stack. + */ + public goBack() { + this._location.back(); + } } diff --git a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.html b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.html index 68de6aec7a..5fa32d46fc 100644 --- a/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.html +++ b/src/app/suggestion-notifications/qa/topics/quality-assurance-topics.component.html @@ -44,7 +44,7 @@ diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index d4d3cb77fa..e306274e06 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3260,7 +3260,9 @@ "quality-assurance.source.error.service.retrieve": "An error occurred while loading the Quality Assurance source", - "quality-assurance.events.description": "Below the list of all the suggestions for the selected topic.", + "quality-assurance.events.description": "Below the list of all the suggestions for the selected topic {{topic}}, related to {{source}}.", + + "quality-assurance.events.description-with-topic-and-target": "Below the list of all the suggestions for the selected topic {{topic}}, related to {{source}} and ", "quality-assurance.loading": "Loading ...", From 721b80a0e678880772c89412e114eb8189ed37b4 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Tue, 14 Nov 2023 13:13:39 +0100 Subject: [PATCH 50/83] CST-12455 Changes for the page to be using an ngbdropdown logic are still required and being worked on --- .../ldn-service-form-edit.component.html | 121 ++++++++++++------ .../ldn-service-form-edit.component.scss | 8 +- .../ldn-service-form-edit.component.ts | 56 +++++++- .../ldn-service-form.component.html | 100 +++++++++++---- .../ldn-service-form.component.scss | 10 +- .../ldn-service-form.component.ts | 26 ++++ 6 files changed, 247 insertions(+), 74 deletions(-) diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html index 56105ce805..192a6633a2 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html @@ -69,12 +69,12 @@
- +
-
- +
+
-
+
@@ -86,34 +86,55 @@
- -
+
+
+ + -
- - - -
- -
- -
-
+ +
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.outboundPattern' | translate) }}
+
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.description' | translate) : ('' | translate) }}
+ +
+ +
+
+
+ + + +
+ +
+ +
+
+
+
+
-
+
@@ -162,16 +183,36 @@
- +
+
+ + + + +
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.outboundPattern' | translate) }}
+
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.description' | translate) : ('' | translate) }}
+ +
+ +
+
+
- +
@@ -214,7 +255,7 @@ {{ 'ldn-new-service.form.label.submit' | translate }}
-
@@ -243,7 +284,7 @@ -
diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.scss b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.scss index 0b244d76db..2fc1e693f0 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.scss +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.scss @@ -1,3 +1,6 @@ +@import '../../../shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.scss'; +@import '../../../shared/form/form.component.scss'; + form { font-size: 14px; position: relative; @@ -28,7 +31,6 @@ textarea { .add-pattern-link { color: #0048ff; cursor: pointer; - margin-left: 10px; } .remove-pattern-link { @@ -93,6 +95,10 @@ textarea { margin-top: 10px; } +.small-text { + font-size: 0.7em; + color: #888; +} .toggle-switch { cursor: pointer; margin-top: 3px; diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.ts b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.ts index f0422e39e4..cb2805f069 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.ts +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.ts @@ -5,7 +5,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { LdnServicesService } from '../ldn-services-data/ldn-services-data.service'; import { notifyPatterns } from '../ldn-services-patterns/ldn-service-coar-patterns'; import { animate, state, style, transition, trigger } from '@angular/animations'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import {NgbDropdownConfig, NgbModal} from '@ng-bootstrap/ng-bootstrap'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { LdnService } from '../ldn-services-model/ldn-services.model'; @@ -19,6 +19,7 @@ import { Observable } from 'rxjs'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { FindListOptions } from '../../../core/data/find-list-options.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; +import {pattern} from "isbot"; @Component({ selector: 'ds-ldn-service-form-edit', @@ -65,6 +66,8 @@ export class LdnServiceFormEditComponent implements OnInit { private deletedOutboundPatterns: number[] = []; private modalRef: any; private service: LdnService; + selectedOutboundPatterns: string[]; + selectedInboundPatterns: string[]; constructor( protected ldnServicesService: LdnServicesService, @@ -164,8 +167,10 @@ export class LdnServiceFormEditComponent implements OnInit { this.createReplaceOperation(patchOperations, 'ldnUrl', '/ldnurl'); this.createReplaceOperation(patchOperations, 'url', '/url'); - this.handlePatterns(patchOperations, 'notifyServiceInboundPatterns'); - this.handlePatterns(patchOperations, 'notifyServiceOutboundPatterns'); + + + this.handlePatterns(patchOperations, 'notifyServiceInboundPatterns', this.selectedInboundPatterns); + this.handlePatterns(patchOperations, 'notifyServiceOutboundPatterns', this.selectedOutboundPatterns); this.deletedInboundPatterns.forEach(index => { const removeOperation: Operation = { @@ -201,6 +206,37 @@ export class LdnServiceFormEditComponent implements OnInit { } + selectOutboundPattern(patternValue: string, index: number): void { + // this.selectedOutboundPatterns = patternValue; + const patternArray = (this.formModel.get('notifyServiceOutboundPatterns') as FormArray).controls[index] + console.log((this.formModel.get('notifyServiceOutboundPatterns') as FormArray)) + patternArray.patchValue({pattern: patternValue} ) + //console.log(patternArray); + //this.getPatternControlNames(index) + } + + selectInboundPattern(patternValue: string, index: number): void { + // this.selectedInboundPatterns = patternValue; + const patternArray = (this.formModel.get('notifyServiceInboundPatterns') as FormArray).controls[index] + console.log((this.formModel.get('notifyServiceInboundPatterns') as FormArray)) + console.log(patternArray) + //console.log(patternArray); + //this.getPatternControlNames(index) + } + + + + getOutboundPatternControlNames(index: number) { + const patternArrayValue = (this.formModel.get('notifyServiceOutboundPatterns') as FormArray).controls[index]?.value + return patternArrayValue + } + + getInboundPatternControlNames(index: number) { + const patternArrayValue = (this.formModel.get('notifyServiceInboundPatterns') as FormArray).controls[index]?.value + return patternArrayValue + } + + toggleAutomatic(i: number) { const automaticControl = this.formModel.get(`notifyServiceInboundPatterns.${i}.automatic`); if (automaticControl) { @@ -245,6 +281,7 @@ export class LdnServiceFormEditComponent implements OnInit { patchService() { this.deleteMarkedInboundPatterns(); this.deleteMarkedOutboundPatterns(); + const patchOperations = this.generatePatchOperations(); @@ -343,11 +380,16 @@ export class LdnServiceFormEditComponent implements OnInit { } } - private handlePatterns(patchOperations: any[], formArrayName: string): void { + private handlePatterns(patchOperations: any[], formArrayName: string, selectedPatterns: string[]): void { + const patternsArray = this.formModel.get(formArrayName) as FormArray; for (let i = 0; i < patternsArray.length; i++) { + const patternGroup = patternsArray.at(i) as FormGroup; + console.warn('Calling setValueForControlInOutboundArray', formArrayName, i, selectedPatterns); + this.setValueForControlInOutboundArray(formArrayName, i, selectedPatterns[i] ) + const patternValue = patternGroup.value; if (patternGroup.dirty) { @@ -406,4 +448,10 @@ export class LdnServiceFormEditComponent implements OnInit { automatic: '', }); } + + setValueForControlInOutboundArray(formArrayName: string, index: number, value: string) { + const formArray = this.formModel.get(formArrayName) as FormArray; + console.warn('inside setValueForControlInOutboundArray', formArray); + formArray.at(index).setValue(value); + } } diff --git a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html index 1b4aa9048d..de7949614d 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html +++ b/src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html @@ -60,10 +60,10 @@
- +
-
- +
+
@@ -76,18 +76,41 @@
-
- +
+
+
+ + + + +
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.inboundPattern' | translate) }}
+
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.description' | translate) : ('' | translate) }}
+ +
+ +
+
+
- +
+
@@ -129,7 +153,7 @@
- +
@@ -145,16 +169,37 @@
- +
+
+ + + + +
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.outboundPattern' | translate) }}
+
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.description' | translate) : ('' | translate) }}
+ +
+ +
+
+
+
- + -
-
-
+
+ +
+
+
-
+
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.outboundPattern' | translate) }}
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.description' | translate) : ('' | translate) }}
- +
+
+
+
- -
- -
- -
-
+
+
+ +
+ + +
+ +
+   +
+ + +
+ + +
+ +
+   +
+ + +
+ + +
+ +
+   +
+ + +
+ + +
+ +
+   +
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+ + + + +
+
+
+
+ + + + +
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.outboundPattern' | translate) }}
+
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.description' | translate) : ('' | translate) }}
+ +
+
+
-
- -
- - -
- -
-   -
- - -
- - -
- -
-   -
- - -
- - -
- -
-   -
- - -
- - -
- -
-   -
- -
-
- -
-
- -
-
- -
-
-
-
- -
- - - - -
-
-
-
- - - - -
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.outboundPattern' | translate) }}
-
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.description' | translate) : ('' | translate) }}
- -
- -
-
-
-
- -
- - - -
- -
- -
-
-
-
- - -
- - - - -
-
+
+
+ + +
+ +
+ +
+
+
+
+ + +
+ + + + +
+
+
- {{ 'ldn-new-service.form.label.addPattern' | translate }} -
-   -
+ {{ 'ldn-new-service.form.label.addPattern' | translate }} -
-
- -
-
- -
-
- -
-
-
-
+
+   +
-
+
+
+ +
+
+ +
+
+ +
+
+
+
- +
- -
-
-
-
- - + - -
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.outboundPattern' | translate) }}
-
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.description' | translate) : ('' | translate) }}
- -
- -
-
-
-
- -
- - - -
+ +
+
+
+
+ + -
- -
-
-
-
- -
- - -
+ +
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.outboundPattern' | translate) }}
+
{{ selectedOutboundPatterns ? ('ldn-service.form.pattern.' + selectedOutboundPatterns + '.description' | translate) : ('' | translate) }}
+ +
+
+
+
+
+ +
+ + -
+
- {{ 'ldn-new-service.form.label.addPattern' | translate }} +
+ +
+
+
+
+ +
+ + +
+
+ +
+ + {{ 'ldn-new-service.form.label.addPattern' | translate }} -
-   -
- - +
+   +
+ +
-
+
- - - + + + +
-
+
- - - + + + +
From 35c45850e796539eddf7f56e100005e133c30f02 Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Wed, 15 Nov 2023 11:57:14 +0100 Subject: [PATCH 53/83] CST-12455 Itemfilter dropdown for the edit inboundpatterns is working, now changing all remaining code and finalizing task --- .../ldn-service-form-edit.component.html | 37 +++++++++++++++---- .../ldn-service-form-edit.component.ts | 14 +++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html index 0ea17d6fdd..51abf43f04 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html @@ -103,11 +103,11 @@ /> -
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.outboundPattern' | translate) }}
+
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.label' | translate) : ('ldn-new-service.form.label.placeholder.inboundPattern' | translate) }}
{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.description' | translate) : ('' | translate) }}
-
+
+
+
+
diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.ts b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.ts index 9c0e60040c..fdb07226aa 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.ts +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.ts @@ -67,6 +67,7 @@ export class LdnServiceFormEditComponent implements OnInit { private modalRef: any; private service: LdnService; selectedOutboundPatterns: string[]; + selectedInboundItemfilters: any; selectedInboundPatterns: string[]; constructor( @@ -214,6 +215,16 @@ export class LdnServiceFormEditComponent implements OnInit { //this.getPatternControlNames(index) } + selectInboundItemFilter(filterValue: string, index: number): void { + // this.selectedOutboundPatterns = patternValue; + const filterArray = (this.formModel.get('notifyServiceInboundPatterns') as FormArray) + console.log((this.formModel.get('notifyServiceInboundPatterns') as FormArray)) + filterArray.controls[index].patchValue({constraint: filterValue} ) + + //console.log(patternArray); + //this.getPatternControlNames(index) + } + selectInboundPattern(patternValue: string, index: number): void { // this.selectedOutboundPatterns = patternValue; const patternArray = (this.formModel.get('notifyServiceInboundPatterns') as FormArray) @@ -474,4 +485,7 @@ export class LdnServiceFormEditComponent implements OnInit { //console.warn('inside setValueForControlInOutboundArray', formArray); //formArray.at(index).setValue(value); //} + + + } From 778a06724b33e036ce4ed4080d276f981e3e1dac Mon Sep 17 00:00:00 2001 From: Mattia Vianelli Date: Wed, 15 Nov 2023 12:48:53 +0100 Subject: [PATCH 54/83] CST-12455 Edit page logic is working now finishing up the styling for the page --- .../ldn-service-form-edit.component.html | 50 +- .../ldn-service-form-edit.component.ts | 892 +++++++++--------- 2 files changed, 483 insertions(+), 459 deletions(-) diff --git a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html index 51abf43f04..2940ee0039 100644 --- a/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html +++ b/src/app/admin/admin-ldn-services/ldn-service-form-edit/ldn-service-form-edit.component.html @@ -108,7 +108,8 @@ class="small-text">{{ selectedInboundPatterns ? ('ldn-service.form.pattern.' + selectedInboundPatterns + '.description' | translate) : ('' | translate) }}
-
- +