From bfaea741d5ec2d2c2023e49542f670da40eba9a9 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 12:00:00 +0100 Subject: [PATCH 001/142] Throw error for tests without expectations --- karma.conf.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/karma.conf.js b/karma.conf.js index 8418312b1a..f96558bfaf 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -15,7 +15,10 @@ module.exports = function (config) { ], client: { clearContext: false, // leave Jasmine Spec Runner output visible in browser - captureConsole: false + captureConsole: false, + jasmine: { + failSpecWithNoExpectations: true + } }, coverageIstanbulReporter: { dir: require('path').join(__dirname, './coverage/dspace-angular'), From 3640d75e101d15107b3bc96237a4f79b21f2f9fd Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 13:10:57 +0200 Subject: [PATCH 002/142] Fix objectUpdatesReducer no expectation tests Added a expect().nothing() to the test who don't expect anything but just ensure that no error is thrown --- .../object-updates.reducer.spec.ts | 44 +++++++++++++++---- .../object-updates/object-updates.reducer.ts | 2 +- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/app/core/data/object-updates/object-updates.reducer.spec.ts b/src/app/core/data/object-updates/object-updates.reducer.spec.ts index 08944a073f..90e0b70dbd 100644 --- a/src/app/core/data/object-updates/object-updates.reducer.spec.ts +++ b/src/app/core/data/object-updates/object-updates.reducer.spec.ts @@ -12,7 +12,7 @@ import { SetEditableFieldUpdateAction, SetValidFieldUpdateAction } from './object-updates.actions'; -import { OBJECT_UPDATES_TRASH_PATH, objectUpdatesReducer } from './object-updates.reducer'; +import { OBJECT_UPDATES_TRASH_PATH, objectUpdatesReducer, ObjectUpdatesState } from './object-updates.reducer'; import { Relationship } from '../../shared/item-relationships/relationship.model'; import { FieldChangeType } from './field-change-type.model'; @@ -56,7 +56,7 @@ const modDate = new Date(2010, 2, 11); const uuid = identifiable1.uuid; const url = 'test-object.url/edit'; describe('objectUpdatesReducer', () => { - const testState = { + const testState: ObjectUpdatesState = { [url]: { fieldStates: { [identifiable1.uuid]: { @@ -79,9 +79,6 @@ describe('objectUpdatesReducer', () => { [identifiable2.uuid]: { field: { uuid: identifiable2.uuid, - key: 'dc.titl', - language: null, - value: 'New title' }, changeType: FieldChangeType.ADD } @@ -93,7 +90,7 @@ describe('objectUpdatesReducer', () => { } }; - const discardedTestState = { + const discardedTestState: ObjectUpdatesState = { [url]: { fieldStates: { [identifiable1.uuid]: { @@ -139,9 +136,6 @@ describe('objectUpdatesReducer', () => { [identifiable2.uuid]: { field: { uuid: identifiable2.uuid, - key: 'dc.titl', - language: null, - value: 'New title' }, changeType: FieldChangeType.ADD } @@ -173,48 +167,80 @@ describe('objectUpdatesReducer', () => { const action = new InitializeFieldsAction(url, [identifiable1, identifiable2], modDate); // testState has already been frozen above objectUpdatesReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should perform the SET_EDITABLE_FIELD action without affecting the previous state', () => { const action = new SetEditableFieldUpdateAction(url, uuid, false); // testState has already been frozen above objectUpdatesReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should perform the ADD_FIELD action without affecting the previous state', () => { const action = new AddFieldUpdateAction(url, identifiable1update, FieldChangeType.UPDATE); // testState has already been frozen above objectUpdatesReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should perform the DISCARD action without affecting the previous state', () => { const action = new DiscardObjectUpdatesAction(url, null); // testState has already been frozen above objectUpdatesReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should perform the REINSTATE action without affecting the previous state', () => { const action = new ReinstateObjectUpdatesAction(url); // testState has already been frozen above objectUpdatesReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should perform the REMOVE action without affecting the previous state', () => { const action = new RemoveFieldUpdateAction(url, uuid); // testState has already been frozen above objectUpdatesReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should perform the REMOVE_FIELD action without affecting the previous state', () => { const action = new RemoveFieldUpdateAction(url, uuid); // testState has already been frozen above objectUpdatesReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should perform the SELECT_VIRTUAL_METADATA action without affecting the previous state', () => { const action = new SelectVirtualMetadataAction(url, relationship.uuid, identifiable1.uuid, true); // testState has already been frozen above objectUpdatesReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should initialize all fields when the INITIALIZE action is dispatched, based on the payload', () => { diff --git a/src/app/core/data/object-updates/object-updates.reducer.ts b/src/app/core/data/object-updates/object-updates.reducer.ts index 14bacc52db..5c03001972 100644 --- a/src/app/core/data/object-updates/object-updates.reducer.ts +++ b/src/app/core/data/object-updates/object-updates.reducer.ts @@ -77,7 +77,7 @@ export interface DeleteRelationship extends RelationshipIdentifiable { */ export interface ObjectUpdatesEntry { fieldStates: FieldStates; - fieldUpdates: FieldUpdates; + fieldUpdates?: FieldUpdates; virtualMetadataSources: VirtualMetadataSources; lastModified: Date; patchOperationService?: GenericConstructor; From abc8640b5e35b1abdaad181b7f26feed9b624d77 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 13:13:27 +0200 Subject: [PATCH 003/142] Fix MetadataRepresentationListElementComponent no expectation tests Also fixed incorrect regex in isLink() --- ...adata-representation-list-element.component.spec.ts | 10 +++------- .../metadata-representation-list-element.component.ts | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.spec.ts b/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.spec.ts index dc8febe84a..cf85154a19 100644 --- a/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.spec.ts +++ b/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.spec.ts @@ -19,7 +19,7 @@ describe('MetadataRepresentationListElementComponent', () => { let fixture: ComponentFixture; beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ + return TestBed.configureTestingModule({ imports: [], declarations: [MetadataRepresentationListElementComponent], schemas: [NO_ERRORS_SCHEMA] @@ -39,9 +39,7 @@ describe('MetadataRepresentationListElementComponent', () => { comp.mdRepresentation = mockMetadataRepresentation; }); it('isLink correctly detects a non-URL string as false', () => { - waitForAsync(() => { - expect(comp.isLink()).toBe(false); - }); + expect(comp.isLink()).toBe(false); }); }); @@ -50,9 +48,7 @@ describe('MetadataRepresentationListElementComponent', () => { comp.mdRepresentation = mockMetadataRepresentationUrl; }); it('isLink correctly detects a URL string as true', () => { - waitForAsync(() => { - expect(comp.isLink()).toBe(true); - }); + expect(comp.isLink()).toBe(true); }); }); diff --git a/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.ts b/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.ts index d8f8621ca6..3539502843 100644 --- a/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.ts +++ b/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.ts @@ -25,7 +25,7 @@ export class MetadataRepresentationListElementComponent { */ isLink(): boolean { // Match any string that begins with http:// or https:// - const linkPattern = new RegExp(/^https?\/\/.*/); + const linkPattern = new RegExp(/^https?:\/\/.*/); return linkPattern.test(this.mdRepresentation.getValue()); } From e0db4284b3a502c2d6cc2a504a029f16f2957bc5 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 13:19:28 +0200 Subject: [PATCH 004/142] Fix CollectionSearchResultListElementComponent no expectation tests - Wrong css class was used - The check to see if the offset was defined did not exist --- .../collection-search-result-list-element.component.spec.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.spec.ts b/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.spec.ts index e5ea60b35d..5e5dbcd73b 100644 --- a/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.spec.ts +++ b/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { CollectionSearchResultListElementComponent } from './collection-search-result-list-element.component'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { of as observableOf } from 'rxjs'; -import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; +import { ChangeDetectionStrategy, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; import { TruncatePipe } from '../../../utils/truncate.pipe'; import { Collection } from '../../../../core/shared/collection.model'; @@ -98,7 +98,8 @@ describe('CollectionSearchResultListElementComponent', () => { describe('when environment is set to show thumbnail images', () => { it('should offset content', () => { - const offset = fixture.debugElement.query(By.css('offset-md-2')); + const offset: DebugElement = fixture.debugElement.query(By.css('.offset-md-2')); + expect(offset).not.toBeNull(); }); }); From 063c54e93f4d04f01ac002e5e673d163891f4eb3 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 13:20:41 +0200 Subject: [PATCH 005/142] Fix SearchHierarchyFilterComponent no expectation tests Reverted the way you detect when an item is selected by using observables again instead of promises. The reason why it didn't work without the old observable approach was because `VocabularyTreeviewModalComponent` didn't have a `select` `@Output` like `VocabularyTreeviewComponent` --- .../vocabulary-treeview-modal.component.ts | 9 ++++++++- .../search-hierarchy-filter.component.spec.ts | 13 +++++++------ .../search-hierarchy-filter.component.ts | 19 +++++++++++++------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/app/shared/form/vocabulary-treeview-modal/vocabulary-treeview-modal.component.ts b/src/app/shared/form/vocabulary-treeview-modal/vocabulary-treeview-modal.component.ts index c6b0bf20fe..8213b91f9c 100644 --- a/src/app/shared/form/vocabulary-treeview-modal/vocabulary-treeview-modal.component.ts +++ b/src/app/shared/form/vocabulary-treeview-modal/vocabulary-treeview-modal.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model'; import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; @@ -33,6 +33,12 @@ export class VocabularyTreeviewModalComponent { */ @Input() multiSelect = false; + /** + * An event fired when a vocabulary entry is selected. + * Event's payload equals to {@link VocabularyEntryDetail} selected. + */ + @Output() select: EventEmitter = new EventEmitter(null); + /** * Initialize instance variables * @@ -46,6 +52,7 @@ export class VocabularyTreeviewModalComponent { * Method called on entry select */ onSelect(item: VocabularyEntryDetail) { + this.select.emit(item); this.activeModal.close(item); } } diff --git a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts index e6c74d8047..33306c400b 100644 --- a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts @@ -1,5 +1,5 @@ import { SearchHierarchyFilterComponent } from './search-hierarchy-filter.component'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { DebugElement, EventEmitter, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; import { VocabularyService } from '../../../../../core/submission/vocabularies/vocabulary.service'; @@ -56,7 +56,7 @@ describe('SearchHierarchyFilterComponent', () => { }; beforeEach(() => { - TestBed.configureTestingModule({ + return TestBed.configureTestingModule({ imports: [ CommonModule, NgbModule, @@ -138,8 +138,9 @@ describe('SearchHierarchyFilterComponent', () => { describe('when selecting a value from the vocabulary tree', () => { - it('should add a new search filter to the existing search filters', () => { - waitForAsync(() => expect(router.navigate).toHaveBeenCalledWith([testSearchLink], { + it('should add a new search filter to the existing search filters', fakeAsync(() => { + tick(); + expect(router.navigate).toHaveBeenCalledWith([testSearchLink], { queryParams: { [`f.${testSearchFilter}`]: [ ...alreadySelectedValues, @@ -147,8 +148,8 @@ describe('SearchHierarchyFilterComponent', () => { ].map((value => `${value},equals`)), }, queryParamsHandling: 'merge', - })); - }); + }); + })); }); }); }); diff --git a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts index f9b3f2bff9..0353ae20a8 100644 --- a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, OnInit } from '@angular/core'; +import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { renderFacetFor } from '../search-filter-type-decorator'; import { FilterType } from '../../../models/filter-type.model'; import { facetLoad, SearchFacetFilterComponent } from '../search-facet-filter/search-facet-filter.component'; @@ -21,7 +21,7 @@ import { FacetValue } from '../../../models/facet-value.model'; import { getFacetValueForType } from '../../../search.utils'; import { filter, map, take } from 'rxjs/operators'; import { VocabularyService } from '../../../../../core/submission/vocabularies/vocabulary.service'; -import { Observable, BehaviorSubject } from 'rxjs'; +import { Observable, BehaviorSubject, Subscription } from 'rxjs'; import { PageInfo } from '../../../../../core/shared/page-info.model'; import { environment } from '../../../../../../environments/environment'; import { addOperatorToFilterValue } from '../../../search.utils'; @@ -38,7 +38,9 @@ import { VocabularyTreeviewModalComponent } from '../../../../form/vocabulary-tr * Component that represents a hierarchy facet for a specific filter configuration */ @renderFacetFor(FilterType.hierarchy) -export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent implements OnInit { +export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent implements OnDestroy, OnInit { + + subscriptions: Subscription[] = []; constructor(protected searchService: SearchService, protected filterService: SearchFilterService, @@ -56,6 +58,11 @@ export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent i vocabularyExists$: Observable; + ngOnDestroy(): void { + super.ngOnDestroy(); + this.subscriptions.forEach((subscription: Subscription) => subscription.unsubscribe()); + } + /** * Submits a new active custom value to the filter from the input field * Overwritten method from parent component, adds the "query" operator to the received data before passing it on @@ -91,11 +98,11 @@ export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent i name: this.getVocabularyEntry(), closed: true }; - modalRef.result.then((detail: VocabularyEntryDetail) => { + this.subscriptions.push(modalRef.componentInstance.select.subscribe((detail: VocabularyEntryDetail) => { this.selectedValues$ .pipe(take(1)) .subscribe((selectedValues) => { - this.router.navigate( + void this.router.navigate( [this.searchService.getSearchLink()], { queryParams: { @@ -106,7 +113,7 @@ export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent i }, ); }); - }).catch(); + })); } /** From 7ef3a914f9b1e85ddef29bbe9ff50af610c397e1 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 13:23:02 +0200 Subject: [PATCH 006/142] Fix ItemComponent no expectation tests - renamed `showBackButton` to `showBackButton$` because it's an observable - `showBackButton$` only emits `true` when the back button should be shown, it does not emit `false` when it should be hidden, it just did nothing --- .../journal-issue/journal-issue.component.html | 2 +- .../journal-volume/journal-volume.component.html | 2 +- .../item-pages/journal/journal.component.html | 2 +- .../item-pages/org-unit/org-unit.component.html | 2 +- .../item-pages/person/person.component.html | 2 +- .../item-pages/project/project.component.html | 2 +- .../item-types/publication/publication.component.html | 2 +- .../simple/item-types/shared/item.component.spec.ts | 11 ++++++----- .../simple/item-types/shared/item.component.ts | 9 ++++----- .../untyped-item/untyped-item.component.html | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html b/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html index 75f4587a3d..3648b53b51 100644 --- a/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html +++ b/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/entity-groups/journal-entities/item-pages/journal-volume/journal-volume.component.html b/src/app/entity-groups/journal-entities/item-pages/journal-volume/journal-volume.component.html index 213581a519..b906905b47 100644 --- a/src/app/entity-groups/journal-entities/item-pages/journal-volume/journal-volume.component.html +++ b/src/app/entity-groups/journal-entities/item-pages/journal-volume/journal-volume.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/entity-groups/journal-entities/item-pages/journal/journal.component.html b/src/app/entity-groups/journal-entities/item-pages/journal/journal.component.html index 3b2cce061b..e8a6904242 100644 --- a/src/app/entity-groups/journal-entities/item-pages/journal/journal.component.html +++ b/src/app/entity-groups/journal-entities/item-pages/journal/journal.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html index c79d19e267..aa3188bc1d 100644 --- a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html +++ b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.html b/src/app/entity-groups/research-entities/item-pages/person/person.component.html index 83a2e76dd8..ec99c845be 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.html +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/entity-groups/research-entities/item-pages/project/project.component.html b/src/app/entity-groups/research-entities/item-pages/project/project.component.html index 0d9679ef1e..944766b6f7 100644 --- a/src/app/entity-groups/research-entities/item-pages/project/project.component.html +++ b/src/app/entity-groups/research-entities/item-pages/project/project.component.html @@ -1,4 +1,4 @@ - +
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..84754df5e4 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 @@ -1,4 +1,4 @@ - +
{ fixture.detectChanges(); })); - it('should hide back button',() => { + it('should hide back button', () => { spyOn(mockRouteService, 'getPreviousUrl').and.returnValue(observableOf('/item')); - comp.showBackButton.subscribe((val) => { + comp.ngOnInit(); + comp.showBackButton$.subscribe((val) => { expect(val).toBeFalse(); }); }); it('should show back button for search', () => { spyOn(mockRouteService, 'getPreviousUrl').and.returnValue(observableOf(searchUrl)); comp.ngOnInit(); - comp.showBackButton.subscribe((val) => { + comp.showBackButton$.subscribe((val) => { expect(val).toBeTrue(); }); }); it('should show back button for browse', () => { spyOn(mockRouteService, 'getPreviousUrl').and.returnValue(observableOf(browseUrl)); comp.ngOnInit(); - comp.showBackButton.subscribe((val) => { + comp.showBackButton$.subscribe((val) => { expect(val).toBeTrue(); }); }); it('should show back button for recent submissions', () => { spyOn(mockRouteService, 'getPreviousUrl').and.returnValue(observableOf(recentSubmissionsUrl)); comp.ngOnInit(); - comp.showBackButton.subscribe((val) => { + comp.showBackButton$.subscribe((val) => { expect(val).toBeTrue(); }); }); diff --git a/src/app/item-page/simple/item-types/shared/item.component.ts b/src/app/item-page/simple/item-types/shared/item.component.ts index 93e6a0b346..edcfd57a69 100644 --- a/src/app/item-page/simple/item-types/shared/item.component.ts +++ b/src/app/item-page/simple/item-types/shared/item.component.ts @@ -5,7 +5,7 @@ import { getItemPageRoute } from '../../../item-page-routing-paths'; import { RouteService } from '../../../../core/services/route.service'; import { Observable } from 'rxjs'; import { getDSpaceQuery, isIiifEnabled, isIiifSearchEnabled } from './item-iiif-utils'; -import { filter, map, take } from 'rxjs/operators'; +import { map, take } from 'rxjs/operators'; import { Router } from '@angular/router'; @Component({ @@ -27,7 +27,7 @@ export class ItemComponent implements OnInit { /** * Used to show or hide the back to results button in the view. */ - showBackButton: Observable; + showBackButton$: Observable; /** * Route to the item page @@ -73,10 +73,9 @@ export class ItemComponent implements OnInit { this.itemPageRoute = getItemPageRoute(this.object); // hide/show the back button - this.showBackButton = this.routeService.getPreviousUrl().pipe( - filter(url => this.previousRoute.test(url)), + this.showBackButton$ = this.routeService.getPreviousUrl().pipe( + map((url: string) => this.previousRoute.test(url)), take(1), - map(() => true) ); // check to see if iiif viewer is required. this.iiifEnabled = isIiifEnabled(this.object); diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index 904b7e039c..064f8a7764 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -1,4 +1,4 @@ - +
Date: Sat, 1 Jul 2023 13:28:36 +0200 Subject: [PATCH 007/142] Fix ItemVersionsComponent no expectation tests - The buttons are now not disabled anymore but hidden when you don't have the correct authorization - Wrong css class was used for the edit buttons --- .../versions/item-versions.component.spec.ts | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/app/item-page/versions/item-versions.component.spec.ts b/src/app/item-page/versions/item-versions.component.spec.ts index e46f1585d7..f710d4332e 100644 --- a/src/app/item-page/versions/item-versions.component.spec.ts +++ b/src/app/item-page/versions/item-versions.component.spec.ts @@ -4,7 +4,7 @@ import { } from '@angular/core/testing'; import { VarDirective } from '../../shared/utils/var.directive'; import { TranslateModule } from '@ngx-translate/core'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; import { Item } from '../../core/shared/item.model'; import { Version } from '../../core/shared/version.model'; import { VersionHistory } from '../../core/shared/version-history.model'; @@ -220,20 +220,21 @@ describe('ItemVersionsComponent', () => { authorizationServiceSpy.isAuthorized.and.callFake(canDelete); })); it('should not disable the delete button', () => { - const deleteButtons = fixture.debugElement.queryAll(By.css(`.version-row-element-delete`)); - deleteButtons.forEach((btn) => { + const deleteButtons: DebugElement[] = fixture.debugElement.queryAll(By.css('.version-row-element-delete')); + expect(deleteButtons.length).not.toBe(0); + deleteButtons.forEach((btn: DebugElement) => { expect(btn.nativeElement.disabled).toBe(false); }); }); - it('should disable other buttons', () => { - const createButtons = fixture.debugElement.queryAll(By.css(`.version-row-element-create`)); - createButtons.forEach((btn) => { - expect(btn.nativeElement.disabled).toBe(true); - }); - const editButtons = fixture.debugElement.queryAll(By.css(`.version-row-element-create`)); - editButtons.forEach((btn) => { - expect(btn.nativeElement.disabled).toBe(true); - }); + + it('should hide the create buttons', () => { + const createButtons: DebugElement[] = fixture.debugElement.queryAll(By.css('.version-row-element-create')); + expect(createButtons.length).toBe(0); + }); + + it('should hide the edit buttons', () => { + const editButtons: DebugElement[] = fixture.debugElement.queryAll(By.css('.version-row-element-edit')); + expect(editButtons.length).toBe(0); }); }); From a524805fafd92fd8bba8e67924840ae6320d701b Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 13:49:07 +0200 Subject: [PATCH 008/142] Fix CommunitySearchResultListElementComponent no expectation tests - Wrong css class was used - The check to see if the offset was defined did not exist --- .../community-search-result-list-element.component.spec.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.spec.ts b/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.spec.ts index ce12f5f7da..cb9492c945 100644 --- a/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.spec.ts +++ b/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { CommunitySearchResultListElementComponent } from './community-search-result-list-element.component'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { of as observableOf } from 'rxjs'; -import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; +import { ChangeDetectionStrategy, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; import { TruncatePipe } from '../../../utils/truncate.pipe'; import { Community } from '../../../../core/shared/community.model'; @@ -99,7 +99,8 @@ describe('CommunitySearchResultListElementComponent', () => { describe('when environment is set to show thumbnail images', () => { it('should offset content', () => { - const offset = fixture.debugElement.query(By.css('offset-md-2')); + const offset: DebugElement = fixture.debugElement.query(By.css('.offset-md-2')); + expect(offset).not.toBeNull(); }); }); }); From b83a0b3f9b1694036a1723d0487dc93a9eb955ea Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 14:19:15 +0200 Subject: [PATCH 009/142] Fix SubmissionSectionUploadFileComponent no expectation tests The fixture.whenStable() was not awaited --- .../upload/file/section-upload-file.component.spec.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/app/submission/sections/upload/file/section-upload-file.component.spec.ts b/src/app/submission/sections/upload/file/section-upload-file.component.spec.ts index 4f62ceef6c..e2f600654d 100644 --- a/src/app/submission/sections/upload/file/section-upload-file.component.spec.ts +++ b/src/app/submission/sections/upload/file/section-upload-file.component.spec.ts @@ -180,7 +180,7 @@ describe('SubmissionSectionUploadFileComponent test suite', () => { expect(comp.fileData).toEqual(fileData); }); - it('should call deleteFile on delete confirmation', () => { + it('should call deleteFile on delete confirmation', async () => { spyOn(compAsAny, 'deleteFile'); comp.fileData = fileData; @@ -196,9 +196,8 @@ describe('SubmissionSectionUploadFileComponent test suite', () => { fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(compAsAny.deleteFile).toHaveBeenCalled(); - }); + await fixture.whenStable(); + expect(compAsAny.deleteFile).toHaveBeenCalled(); }); it('should delete file properly', () => { From b4a3882dcf410dc14fb34f1c112659474a5b10ca Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 15:22:13 +0200 Subject: [PATCH 010/142] Fix findSuccessfulAccordingTo no expectation tests - The isWithdrawn was set twice to mockItem1 - The expected observable was not correctly compared --- src/app/item-page/edit-item-page/edit-item-operators.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/item-page/edit-item-page/edit-item-operators.spec.ts b/src/app/item-page/edit-item-page/edit-item-operators.spec.ts index e7bd5b98ce..f72ace495f 100644 --- a/src/app/item-page/edit-item-page/edit-item-operators.spec.ts +++ b/src/app/item-page/edit-item-page/edit-item-operators.spec.ts @@ -18,7 +18,7 @@ describe('findSuccessfulAccordingTo', () => { mockItem1.isWithdrawn = true; mockItem2 = new Item(); - mockItem1.isWithdrawn = false; + mockItem2.isWithdrawn = false; predicate = (rd: RemoteData) => isNotEmpty(rd.payload) ? rd.payload.isWithdrawn : false; }); @@ -34,7 +34,7 @@ describe('findSuccessfulAccordingTo', () => { const source = hot('abcde', testRD); const result = source.pipe(findSuccessfulAccordingTo(predicate)); - result.subscribe((value) => expect(value).toEqual(testRD.d)); + expect(result).toBeObservable(hot('---(d|)', { d: testRD.d })); }); }); From c1875cade3a6557b1ae8621cca41a44879d21054 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 1 Jul 2023 17:42:22 +0200 Subject: [PATCH 011/142] Add expect().nothing() to reducer tests without expectations, who only exist to check if an error is thrown --- .../core/cache/object-cache.reducer.spec.ts | 16 ++++++++++++ .../cache/server-sync-buffer.reducer.spec.ts | 8 ++++++ src/app/shared/host-window.reducer.spec.ts | 4 +++ src/app/shared/menu/menu.reducer.spec.ts | 25 +++++++++++++++++++ .../search-filter.reducer.spec.ts | 9 +++++++ .../shared/sidebar/sidebar.reducer.spec.ts | 9 +++++++ .../truncatable/truncatable.reducer.spec.ts | 9 +++++++ 7 files changed, 80 insertions(+) diff --git a/src/app/core/cache/object-cache.reducer.spec.ts b/src/app/core/cache/object-cache.reducer.spec.ts index 919edc8e57..df22a65da7 100644 --- a/src/app/core/cache/object-cache.reducer.spec.ts +++ b/src/app/core/cache/object-cache.reducer.spec.ts @@ -126,6 +126,10 @@ describe('objectCacheReducer', () => { deepFreeze(state); objectCacheReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should remove the specified object from the cache in response to the REMOVE action', () => { @@ -149,6 +153,10 @@ describe('objectCacheReducer', () => { const action = new RemoveFromObjectCacheAction(selfLink1); // testState has already been frozen above objectCacheReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set the timestamp of all objects in the cache in response to a RESET_TIMESTAMPS action', () => { @@ -164,6 +172,10 @@ describe('objectCacheReducer', () => { const action = new ResetObjectCacheTimestampsAction(new Date().getTime()); // testState has already been frozen above objectCacheReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should perform the ADD_PATCH action without affecting the previous state', () => { @@ -174,6 +186,10 @@ describe('objectCacheReducer', () => { }]); // testState has already been frozen above objectCacheReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should when the ADD_PATCH action dispatched', () => { diff --git a/src/app/core/cache/server-sync-buffer.reducer.spec.ts b/src/app/core/cache/server-sync-buffer.reducer.spec.ts index 51ba010c1e..087080a194 100644 --- a/src/app/core/cache/server-sync-buffer.reducer.spec.ts +++ b/src/app/core/cache/server-sync-buffer.reducer.spec.ts @@ -52,12 +52,20 @@ describe('serverSyncBufferReducer', () => { const action = new AddToSSBAction(selfLink1, RestRequestMethod.POST); // testState has already been frozen above serverSyncBufferReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should perform the EMPTY action without affecting the previous state', () => { const action = new EmptySSBAction(); // testState has already been frozen above serverSyncBufferReducer(testState, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should empty the buffer if the EmptySSBAction is dispatched without a payload', () => { diff --git a/src/app/shared/host-window.reducer.spec.ts b/src/app/shared/host-window.reducer.spec.ts index f580c0e1da..f8e5802e30 100644 --- a/src/app/shared/host-window.reducer.spec.ts +++ b/src/app/shared/host-window.reducer.spec.ts @@ -44,6 +44,10 @@ describe('hostWindowReducer', () => { const action = new HostWindowResizeAction(1024, 768); hostWindowReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); }); diff --git a/src/app/shared/menu/menu.reducer.spec.ts b/src/app/shared/menu/menu.reducer.spec.ts index 2865e887fc..58b1251bb6 100644 --- a/src/app/shared/menu/menu.reducer.spec.ts +++ b/src/app/shared/menu/menu.reducer.spec.ts @@ -180,6 +180,7 @@ describe('menusReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set collapsed to false for the correct menu in response to the EXPAND_MENU action', () => { @@ -201,6 +202,7 @@ describe('menusReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set collapsed to false for the correct menu in response to the TOGGLE_MENU action when collapsed is true', () => { @@ -231,6 +233,7 @@ describe('menusReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set previewCollapsed to true for the correct menu in response to the COLLAPSE_MENU_PREVIEW action', () => { @@ -252,6 +255,7 @@ describe('menusReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set previewCollapsed to false for the correct menu in response to the EXPAND_MENU_PREVIEW action', () => { @@ -273,6 +277,7 @@ describe('menusReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set visible to true for the correct menu in response to the SHOW_MENU action', () => { @@ -294,6 +299,7 @@ describe('menusReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set previewCollapsed to false for the correct menu in response to the HIDE_MENU action', () => { @@ -315,6 +321,7 @@ describe('menusReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set add a new section for the correct menu in response to the ADD_SECTION action', () => { @@ -347,6 +354,7 @@ describe('menusReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should remove a section for the correct menu in response to the REMOVE_SECTION action', () => { @@ -383,6 +391,10 @@ describe('menusReducer', () => { const action = new ActivateMenuSectionAction(menuID, topSectionID); menusReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set active to false for the correct menu section in response to the DEACTIVATE_SECTION action', () => { @@ -401,6 +413,10 @@ describe('menusReducer', () => { const action = new DeactivateMenuSectionAction(menuID, topSectionID); menusReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set active to false for the correct menu in response to the TOGGLE_ACTIVE_SECTION action when active is true', () => { @@ -430,6 +446,7 @@ describe('menusReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set visible to true for the correct menu section in response to the SHOW_SECTION action', () => { @@ -448,6 +465,10 @@ describe('menusReducer', () => { const action = new ShowMenuSectionAction(menuID, topSectionID); menusReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set visible to false for the correct menu section in response to the HIDE_SECTION action', () => { @@ -466,5 +487,9 @@ describe('menusReducer', () => { const action = new HideMenuSectionAction(menuID, topSectionID); menusReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); }); diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.reducer.spec.ts b/src/app/shared/search/search-filters/search-filter/search-filter.reducer.spec.ts index aa64589d2e..e94f175a8a 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.reducer.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.reducer.spec.ts @@ -60,6 +60,7 @@ describe('filterReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set filterCollapsed to false in response to the EXPAND action', () => { @@ -78,6 +79,10 @@ describe('filterReducer', () => { const action = new SearchFilterExpandAction(filterName1); filterReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should flip the value of filterCollapsed in response to the TOGGLE action', () => { @@ -99,6 +104,10 @@ describe('filterReducer', () => { const action = new SearchFilterToggleAction(filterName1); filterReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set filterCollapsed to true in response to the INITIALIZE action with isOpenByDefault to false when no state has been set for this filter', () => { diff --git a/src/app/shared/sidebar/sidebar.reducer.spec.ts b/src/app/shared/sidebar/sidebar.reducer.spec.ts index 76962f60c1..ffb3dbaabc 100644 --- a/src/app/shared/sidebar/sidebar.reducer.spec.ts +++ b/src/app/shared/sidebar/sidebar.reducer.spec.ts @@ -47,6 +47,7 @@ describe('sidebarReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set sidebarCollapsed to false in response to the EXPAND action', () => { @@ -63,6 +64,10 @@ describe('sidebarReducer', () => { const action = new SidebarExpandAction(); sidebarReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should flip the value of sidebarCollapsed in response to the TOGGLE action', () => { @@ -82,6 +87,10 @@ describe('sidebarReducer', () => { const action = new SidebarToggleAction(); sidebarReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); }); diff --git a/src/app/shared/truncatable/truncatable.reducer.spec.ts b/src/app/shared/truncatable/truncatable.reducer.spec.ts index 9866f382f7..a4628c309e 100644 --- a/src/app/shared/truncatable/truncatable.reducer.spec.ts +++ b/src/app/shared/truncatable/truncatable.reducer.spec.ts @@ -53,6 +53,7 @@ describe('truncatableReducer', () => { // no expect required, deepFreeze will ensure an exception is thrown if the state // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should set filterCollapsed to false in response to the EXPAND action', () => { @@ -71,6 +72,10 @@ describe('truncatableReducer', () => { const action = new TruncatableExpandAction(id1); truncatableReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); it('should flip the value of filterCollapsed in response to the TOGGLE action', () => { @@ -92,5 +97,9 @@ describe('truncatableReducer', () => { const action = new TruncatableToggleAction(id2); truncatableReducer(state, action); + + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail + expect().nothing(); }); }); From c2010b5d5e49931687ee1435c461323107ec87b8 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sun, 2 Jul 2023 15:14:05 +0200 Subject: [PATCH 012/142] Fix SubscriptionsDataService no expectation tests The test's searchData & the searchData from the SubscriptionsDataService were not linked --- .../subscriptions/subscriptions-data.service.spec.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/app/shared/subscriptions/subscriptions-data.service.spec.ts b/src/app/shared/subscriptions/subscriptions-data.service.spec.ts index 9c4c69123d..790fde3ca0 100644 --- a/src/app/shared/subscriptions/subscriptions-data.service.spec.ts +++ b/src/app/shared/subscriptions/subscriptions-data.service.spec.ts @@ -12,7 +12,6 @@ import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { getMockRequestService } from '../mocks/request.service.mock'; import { getMockRemoteDataBuildService } from '../mocks/remote-data-build.service.mock'; -import { SearchDataImpl } from '../../core/data/base/search-data'; import { NotificationsServiceStub } from '../testing/notifications-service.stub'; import { HALEndpointServiceStub } from '../testing/hal-endpoint-service.stub'; import { createPaginatedList } from '../testing/utils.test'; @@ -22,7 +21,6 @@ describe('SubscriptionsDataService', () => { let service: SubscriptionsDataService; - let searchData: SearchDataImpl; let comparator: DSOChangeAnalyzer; let http: HttpClient; @@ -121,11 +119,11 @@ describe('SubscriptionsDataService', () => { }); it('should get the subscriptions', () => { + spyOn((service as any).searchData, 'searchBy'); const id = 'test-id'; const ePersonId = 'test-ePersonId'; - service.getSubscriptionsByPersonDSO(ePersonId, id).subscribe(() => { - expect(searchData.searchBy).toHaveBeenCalled(); - }); + service.getSubscriptionsByPersonDSO(ePersonId, id); + expect((service as any).searchData.searchBy).toHaveBeenCalled(); }); }); From b7dfe0f23dcf31a60ec20b75a9f707ba33a31ae7 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 8 Jul 2023 16:35:11 +0200 Subject: [PATCH 013/142] Fix EPersonDataService no expectation tests - The store dispatch was not called through so the store was never updated - To initialize the store using provideMockStore I rewrote the test to work through injection --- .../core/eperson/eperson-data.service.spec.ts | 115 ++++++++---------- src/app/core/eperson/eperson-data.service.ts | 2 +- 2 files changed, 50 insertions(+), 67 deletions(-) diff --git a/src/app/core/eperson/eperson-data.service.spec.ts b/src/app/core/eperson/eperson-data.service.spec.ts index b4b939eebf..13efc34c7e 100644 --- a/src/app/core/eperson/eperson-data.service.spec.ts +++ b/src/app/core/eperson/eperson-data.service.spec.ts @@ -1,39 +1,39 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { TestBed, waitForAsync } from '@angular/core/testing'; -import { Store, StoreModule } from '@ngrx/store'; -import { compare, Operation } from 'fast-json-patch'; -import { getTestScheduler } from 'jasmine-marbles'; -import { Observable, of as observableOf } from 'rxjs'; -import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { TestScheduler } from 'rxjs/testing'; +import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { Store } from '@ngrx/store'; +import { cold } from 'jasmine-marbles'; +import { of as observableOf } from 'rxjs'; import { EPeopleRegistryCancelEPersonAction, EPeopleRegistryEditEPersonAction } from '../../access-control/epeople-registry/epeople-registry.actions'; import { RequestParam } from '../cache/models/request-param.model'; -import { ChangeAnalyzer } from '../data/change-analyzer'; import { PatchRequest, PostRequest } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { Item } from '../shared/item.model'; -import { EPersonDataService } from './eperson-data.service'; +import { editEPersonSelector, EPersonDataService } from './eperson-data.service'; import { EPerson } from './models/eperson.model'; import { EPersonMock, EPersonMock2 } from '../../shared/testing/eperson.mock'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { createNoContentRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { getMockRemoteDataBuildServiceHrefMap } from '../../shared/mocks/remote-data-build.service.mock'; -import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { createPaginatedList, createRequestEntry$ } from '../../shared/testing/utils.test'; import { CoreState } from '../core-state.model'; import { FindListOptions } from '../data/find-list-options.model'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; +import { compare, Operation } from 'fast-json-patch'; +import { Item } from '../shared/item.model'; +import { ChangeAnalyzer } from '../data/change-analyzer'; describe('EPersonDataService', () => { let service: EPersonDataService; - let store: Store; + let store: MockStore; let requestService: RequestService; - let scheduler: TestScheduler; let epeople; @@ -43,50 +43,38 @@ describe('EPersonDataService', () => { let epeople$; let rdbService; - function initTestService() { - return new EPersonDataService( - requestService, - rdbService, - null, - halService, - new DummyChangeAnalyzer() as any, - null, - store, - ); - } + const initialState = { + epeopleRegistry: { + editEPerson: null + }, + }; - function init() { + beforeEach(waitForAsync(() => { restEndpointURL = 'https://rest.api/dspace-spring-rest/api/eperson'; epersonsEndpoint = `${restEndpointURL}/epersons`; epeople = [EPersonMock, EPersonMock2]; epeople$ = createSuccessfulRemoteDataObject$(createPaginatedList([epeople])); rdbService = getMockRemoteDataBuildServiceHrefMap(undefined, { 'https://rest.api/dspace-spring-rest/api/eperson/epersons': epeople$ }); halService = new HALEndpointServiceStub(restEndpointURL); + requestService = getMockRequestService(createRequestEntry$(epeople)); TestBed.configureTestingModule({ - imports: [ - CommonModule, - StoreModule.forRoot({}), - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useClass: TranslateLoaderMock - } - }), + providers: [ + EPersonDataService, + { provide: RequestService, useValue: requestService }, + { provide: RemoteDataBuildService, useValue: rdbService }, + { provide: HALEndpointService, useValue: halService }, + provideMockStore({ initialState }), + { provide: ObjectCacheService, useValue: {} }, + { provide: DSOChangeAnalyzer, useClass: DummyChangeAnalyzer }, + { provide: NotificationsService, useClass: NotificationsServiceStub }, ], - declarations: [], - providers: [], - schemas: [CUSTOM_ELEMENTS_SCHEMA] }); - } - beforeEach(() => { - init(); - requestService = getMockRequestService(createRequestEntry$(epeople)); - store = new Store(undefined, undefined, undefined); - service = initTestService(); - spyOn(store, 'dispatch'); - }); + service = TestBed.inject(EPersonDataService); + store = TestBed.inject(Store) as MockStore; + spyOn(store, 'dispatch').and.callThrough(); + })); describe('searchByScope', () => { beforeEach(() => { @@ -239,34 +227,29 @@ describe('EPersonDataService', () => { }); describe('clearEPersonRequests', () => { - beforeEach(waitForAsync(() => { - scheduler = getTestScheduler(); - halService = { - getEndpoint(linkPath: string): Observable { - return observableOf(restEndpointURL + '/' + linkPath); - } - } as HALEndpointService; - initTestService(); - service.clearEPersonRequests(); - })); - it('should remove the eperson hrefs in the request service', () => { - expect(requestService.removeByHrefSubstring).toHaveBeenCalledWith(epersonsEndpoint); + beforeEach(() => { + spyOn(halService, 'getEndpoint').and.callFake((linkPath: string) => { + return observableOf(`${restEndpointURL}/${linkPath}`); + }); }); + it('should remove the eperson hrefs in the request service', fakeAsync(() => { + service.clearEPersonRequests(); + tick(); + + expect(requestService.removeByHrefSubstring).toHaveBeenCalledWith(epersonsEndpoint); + })); }); describe('getActiveEPerson', () => { it('should retrieve the ePerson currently getting edited, if any', () => { - service.editEPerson(EPersonMock); + // Update the state with the ePerson (the provideMockStore doesn't update itself when dispatch is called) + store.overrideSelector(editEPersonSelector, EPersonMock); - service.getActiveEPerson().subscribe((activeEPerson: EPerson) => { - expect(activeEPerson).toEqual(EPersonMock); - }); + expect(service.getActiveEPerson()).toBeObservable(cold('a', { a: EPersonMock })); }); it('should retrieve the ePerson currently getting edited, null if none being edited', () => { - service.getActiveEPerson().subscribe((activeEPerson: EPerson) => { - expect(activeEPerson).toEqual(null); - }); + expect(service.getActiveEPerson()).toBeObservable(cold('a', { a: null })); }); }); diff --git a/src/app/core/eperson/eperson-data.service.ts b/src/app/core/eperson/eperson-data.service.ts index d30030365c..d6d579bf2f 100644 --- a/src/app/core/eperson/eperson-data.service.ts +++ b/src/app/core/eperson/eperson-data.service.ts @@ -36,7 +36,7 @@ import { RestRequestMethod } from '../data/rest-request-method'; import { dataService } from '../data/base/data-service.decorator'; const ePeopleRegistryStateSelector = (state: AppState) => state.epeopleRegistry; -const editEPersonSelector = createSelector(ePeopleRegistryStateSelector, (ePeopleRegistryState: EPeopleRegistryState) => ePeopleRegistryState.editEPerson); +export const editEPersonSelector = createSelector(ePeopleRegistryStateSelector, (ePeopleRegistryState: EPeopleRegistryState) => ePeopleRegistryState.editEPerson); /** * A service to retrieve {@link EPerson}s from the REST API & EPerson related CRUD actions From 4b1a8a90a6418b1862cd0cad7d95a99d80e6ac83 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Wed, 12 Jul 2023 14:31:09 +0200 Subject: [PATCH 014/142] Fix ObjectUpdatesEffects no expectation tests Because of the switch from BehaviourSubject to Subject the tests always failed because of a timout because the previous state is not kept with Subject and should be manually triggered during the tests --- .../object-updates.effects.spec.ts | 84 +++++++++++-------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/src/app/core/data/object-updates/object-updates.effects.spec.ts b/src/app/core/data/object-updates/object-updates.effects.spec.ts index ffd20a7300..2a21d1923e 100644 --- a/src/app/core/data/object-updates/object-updates.effects.spec.ts +++ b/src/app/core/data/object-updates/object-updates.effects.spec.ts @@ -1,5 +1,6 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; import { Observable, Subject } from 'rxjs'; +import { take } from 'rxjs/operators'; import { provideMockActions } from '@ngrx/effects/testing'; import { cold, hot } from 'jasmine-marbles'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -11,13 +12,10 @@ import { RemoveFieldUpdateAction, RemoveObjectUpdatesAction } from './object-updates.actions'; -import { - INotification, - Notification -} from '../../../shared/notifications/models/notification.model'; +import { INotification, Notification } from '../../../shared/notifications/models/notification.model'; +import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub'; +import { Action } from '@ngrx/store'; import { NotificationType } from '../../../shared/notifications/models/notification-type'; -import { filter } from 'rxjs/operators'; -import { hasValue } from '../../../shared/empty.util'; import { NoOpAction } from '../../../shared/ngrx/no-op.action'; describe('ObjectUpdatesEffects', () => { @@ -31,13 +29,7 @@ describe('ObjectUpdatesEffects', () => { providers: [ ObjectUpdatesEffects, provideMockActions(() => actions), - { - provide: NotificationsService, - useValue: { - remove: (notification) => { /* empty */ - } - } - }, + { provide: NotificationsService, useClass: NotificationsServiceStub }, ], }); })); @@ -59,7 +51,6 @@ describe('ObjectUpdatesEffects', () => { action = new RemoveObjectUpdatesAction(testURL); }); it('should emit the action from the actionMap\'s value which key matches the action\'s URL', () => { - action = new RemoveObjectUpdatesAction(testURL); actions = hot('--a-', { a: action }); (updatesEffects as any).actionMap$[testURL].subscribe((act) => emittedAction = act); const expected = cold('--b-', { b: undefined }); @@ -81,14 +72,19 @@ describe('ObjectUpdatesEffects', () => { removeAction = new RemoveObjectUpdatesAction(testURL); }); it('should return a RemoveObjectUpdatesAction', () => { - actions = hot('a|', { a: new DiscardObjectUpdatesAction(testURL, infoNotification) }); - updatesEffects.removeAfterDiscardOrReinstateOnUndo$.pipe( - filter(((action) => hasValue(action)))) - .subscribe((t) => { - expect(t).toEqual(removeAction); - } - ) - ; + actions = hot('a', { a: new DiscardObjectUpdatesAction(testURL, infoNotification) }); + + // Because we use Subject and not BehaviourSubject we need to subscribe to it beforehand because it does not + // keep track of the current state + let emittedAction: Action | undefined; + updatesEffects.removeAfterDiscardOrReinstateOnUndo$.subscribe((action: Action | NoOpAction) => { + emittedAction = action; + }); + + // This expect ensures that the mapLastActions$ was processed + expect(updatesEffects.mapLastActions$).toBeObservable(cold('a', { a: undefined })); + + expect(emittedAction).toEqual(removeAction); }); }); @@ -98,12 +94,24 @@ describe('ObjectUpdatesEffects', () => { infoNotification.options.timeOut = 10; }); it('should return an action with type NO_ACTION', () => { - actions = hot('a', { a: new DiscardObjectUpdatesAction(testURL, infoNotification) }); - actions = hot('b', { b: new ReinstateObjectUpdatesAction(testURL) }); - updatesEffects.removeAfterDiscardOrReinstateOnUndo$.subscribe((t) => { - expect(t).toEqual(new NoOpAction()); - } - ); + actions = hot('--(ab)', { + a: new DiscardObjectUpdatesAction(testURL, infoNotification), + b: new ReinstateObjectUpdatesAction(testURL), + }); + + // Because we use Subject and not BehaviourSubject we need to subscribe to it beforehand because it does not + // keep track of the current state + let emittedAction: Action | undefined; + updatesEffects.removeAfterDiscardOrReinstateOnUndo$.pipe( + take(2) + ).subscribe((action: Action | NoOpAction) => { + emittedAction = action; + }); + + // This expect ensures that the mapLastActions$ was processed + expect(updatesEffects.mapLastActions$).toBeObservable(cold('--(ab)', { a: undefined, b: undefined })); + + expect(emittedAction).toEqual(new RemoveObjectUpdatesAction(testURL)); }); }); @@ -113,12 +121,22 @@ describe('ObjectUpdatesEffects', () => { infoNotification.options.timeOut = 10; }); it('should return a RemoveObjectUpdatesAction', () => { - actions = hot('a', { a: new DiscardObjectUpdatesAction(testURL, infoNotification) }); - actions = hot('b', { b: new RemoveFieldUpdateAction(testURL, testUUID) }); + actions = hot('--(ab)', { + a: new DiscardObjectUpdatesAction(testURL, infoNotification), + b: new RemoveFieldUpdateAction(testURL, testUUID), + }); - updatesEffects.removeAfterDiscardOrReinstateOnUndo$.subscribe((t) => - expect(t).toEqual(new RemoveObjectUpdatesAction(testURL)) - ); + // Because we use Subject and not BehaviourSubject we need to subscribe to it beforehand because it does not + // keep track of the current state + let emittedAction: Action | undefined; + updatesEffects.removeAfterDiscardOrReinstateOnUndo$.subscribe((action: Action | NoOpAction) => { + emittedAction = action; + }); + + // This expect ensures that the mapLastActions$ was processed + expect(updatesEffects.mapLastActions$).toBeObservable(cold('--(ab)', { a: undefined, b: undefined })); + + expect(emittedAction).toEqual(new RemoveObjectUpdatesAction(testURL)); }); }); }); From 430b3b2e36d7dd8ffd198c8bd5be402600bdd9e6 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 15 Jul 2023 10:14:03 +0200 Subject: [PATCH 015/142] Fix TopLevelCommunityListComponent, CommunityPageSubCollectionListComponent, CommunityPageSubCommunityListComponent no expectation tests Because their child components use a themed component the changes need to be detected twice, this is a side effect from the component being created dynamically --- ...page-sub-collection-list.component.spec.ts | 26 +++++++++---------- ...-page-sub-community-list.component.spec.ts | 26 +++++++++---------- ...top-level-community-list.component.spec.ts | 22 ++++++++-------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts index bca3c42a95..be52a3b30c 100644 --- a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts @@ -30,7 +30,7 @@ import { ConfigurationProperty } from '../../core/shared/configuration-property. import { createPaginatedList } from '../../shared/testing/utils.test'; import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; -describe('CommunityPageSubCollectionList Component', () => { +describe('CommunityPageSubCollectionListComponent', () => { let comp: CommunityPageSubCollectionListComponent; let fixture: ComponentFixture; let collectionDataServiceStub: any; @@ -177,19 +177,19 @@ describe('CommunityPageSubCollectionList Component', () => { }); - it('should display a list of collections', () => { - waitForAsync(() => { - subCollList = collections; - fixture.detectChanges(); + it('should display a list of collections', async () => { + subCollList = collections; + fixture.detectChanges(); + await fixture.whenStable(); + fixture.detectChanges(); - const collList = fixture.debugElement.queryAll(By.css('li')); - expect(collList.length).toEqual(5); - expect(collList[0].nativeElement.textContent).toContain('Collection 1'); - expect(collList[1].nativeElement.textContent).toContain('Collection 2'); - expect(collList[2].nativeElement.textContent).toContain('Collection 3'); - expect(collList[3].nativeElement.textContent).toContain('Collection 4'); - expect(collList[4].nativeElement.textContent).toContain('Collection 5'); - }); + const collList = fixture.debugElement.queryAll(By.css('li')); + expect(collList.length).toEqual(5); + expect(collList[0].nativeElement.textContent).toContain('Collection 1'); + expect(collList[1].nativeElement.textContent).toContain('Collection 2'); + expect(collList[2].nativeElement.textContent).toContain('Collection 3'); + expect(collList[3].nativeElement.textContent).toContain('Collection 4'); + expect(collList[4].nativeElement.textContent).toContain('Collection 5'); }); it('should not display the header when list of collections is empty', () => { diff --git a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts index 0a14fe6dd1..2f38c00cdb 100644 --- a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts +++ b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts @@ -30,7 +30,7 @@ import { SearchConfigurationServiceStub } from '../../shared/testing/search-conf import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; import { createPaginatedList } from '../../shared/testing/utils.test'; -describe('CommunityPageSubCommunityListComponent Component', () => { +describe('CommunityPageSubCommunityListComponent', () => { let comp: CommunityPageSubCommunityListComponent; let fixture: ComponentFixture; let communityDataServiceStub: any; @@ -179,19 +179,19 @@ describe('CommunityPageSubCommunityListComponent Component', () => { }); - it('should display a list of sub-communities', () => { - waitForAsync(() => { - subCommList = subcommunities; - fixture.detectChanges(); + it('should display a list of sub-communities', async () => { + subCommList = subcommunities; + fixture.detectChanges(); + await fixture.whenStable(); + fixture.detectChanges(); - const subComList = fixture.debugElement.queryAll(By.css('li')); - expect(subComList.length).toEqual(5); - expect(subComList[0].nativeElement.textContent).toContain('SubCommunity 1'); - expect(subComList[1].nativeElement.textContent).toContain('SubCommunity 2'); - expect(subComList[2].nativeElement.textContent).toContain('SubCommunity 3'); - expect(subComList[3].nativeElement.textContent).toContain('SubCommunity 4'); - expect(subComList[4].nativeElement.textContent).toContain('SubCommunity 5'); - }); + const subComList = fixture.debugElement.queryAll(By.css('li')); + expect(subComList.length).toEqual(5); + expect(subComList[0].nativeElement.textContent).toContain('SubCommunity 1'); + expect(subComList[1].nativeElement.textContent).toContain('SubCommunity 2'); + expect(subComList[2].nativeElement.textContent).toContain('SubCommunity 3'); + expect(subComList[3].nativeElement.textContent).toContain('SubCommunity 4'); + expect(subComList[4].nativeElement.textContent).toContain('SubCommunity 5'); }); it('should not display the header when list of sub-communities is empty', () => { diff --git a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts index d1a3d3631f..a3332e4a83 100644 --- a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts +++ b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts @@ -32,7 +32,7 @@ import { SearchConfigurationServiceStub } from '../../shared/testing/search-conf import { APP_CONFIG } from 'src/config/app-config.interface'; import { environment } from 'src/environments/environment.test'; -describe('TopLevelCommunityList Component', () => { +describe('TopLevelCommunityListComponent', () => { let comp: TopLevelCommunityListComponent; let fixture: ComponentFixture; let communityDataServiceStub: any; @@ -173,17 +173,17 @@ describe('TopLevelCommunityList Component', () => { }); - it('should display a list of top-communities', () => { - waitForAsync(() => { - const subComList = fixture.debugElement.queryAll(By.css('li')); + it('should display a list of top-communities', async () => { + await fixture.whenStable(); + fixture.detectChanges(); + const subComList = fixture.debugElement.queryAll(By.css('li')); - expect(subComList.length).toEqual(5); - expect(subComList[0].nativeElement.textContent).toContain('TopCommunity 1'); - expect(subComList[1].nativeElement.textContent).toContain('TopCommunity 2'); - expect(subComList[2].nativeElement.textContent).toContain('TopCommunity 3'); - expect(subComList[3].nativeElement.textContent).toContain('TopCommunity 4'); - expect(subComList[4].nativeElement.textContent).toContain('TopCommunity 5'); - }); + expect(subComList.length).toEqual(5); + expect(subComList[0].nativeElement.textContent).toContain('TopCommunity 1'); + expect(subComList[1].nativeElement.textContent).toContain('TopCommunity 2'); + expect(subComList[2].nativeElement.textContent).toContain('TopCommunity 3'); + expect(subComList[3].nativeElement.textContent).toContain('TopCommunity 4'); + expect(subComList[4].nativeElement.textContent).toContain('TopCommunity 5'); }); }); From b8b9da25251ce59a0ab2a77220c6d5e6143e6420 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 15 Jul 2023 13:19:32 +0200 Subject: [PATCH 016/142] Fix BrowseByComponent no expectation tests - Because the custom theme is disabled by default I replaced it with the dspace theme who is still enabled by default - Because the child components use a themed component the changes need to be detected twice, this is a side effect from the component being created dynamically --- src/app/browse-by/browse-by.module.ts | 2 + .../browse-by/browse-by.component.spec.ts | 59 ++++++------------- .../browse-by/shared-browse-by.module.ts | 14 +++-- 3 files changed, 29 insertions(+), 46 deletions(-) diff --git a/src/app/browse-by/browse-by.module.ts b/src/app/browse-by/browse-by.module.ts index c0e2d3f9ff..ec9f22347f 100644 --- a/src/app/browse-by/browse-by.module.ts +++ b/src/app/browse-by/browse-by.module.ts @@ -14,6 +14,7 @@ import { ThemedBrowseByTaxonomyPageComponent } from './browse-by-taxonomy-page/t import { SharedBrowseByModule } from '../shared/browse-by/shared-browse-by.module'; import { DsoPageModule } from '../shared/dso-page/dso-page.module'; import { FormModule } from '../shared/form/form.module'; +import { SharedModule } from '../shared/shared.module'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -35,6 +36,7 @@ const ENTRY_COMPONENTS = [ ComcolModule, DsoPageModule, FormModule, + SharedModule, ], declarations: [ BrowseBySwitcherComponent, diff --git a/src/app/shared/browse-by/browse-by.component.spec.ts b/src/app/shared/browse-by/browse-by.component.spec.ts index 9317a68007..ab98cd583e 100644 --- a/src/app/shared/browse-by/browse-by.component.spec.ts +++ b/src/app/shared/browse-by/browse-by.component.spec.ts @@ -5,7 +5,6 @@ import { By } from '@angular/platform-browser'; import { Component, NO_ERRORS_SCHEMA } from '@angular/core'; import { of as observableOf } from 'rxjs'; import { CommonModule } from '@angular/common'; -import { Item } from '../../core/shared/item.model'; import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; @@ -48,10 +47,10 @@ import { SharedModule } from '../shared.module'; import { BrowseByRoutingModule } from '../../browse-by/browse-by-routing.module'; import { AccessControlRoutingModule } from '../../access-control/access-control-routing.module'; -@listableObjectComponent(BrowseEntry, ViewMode.ListElement, DEFAULT_CONTEXT, 'custom') +@listableObjectComponent(BrowseEntry, ViewMode.ListElement, DEFAULT_CONTEXT, 'dspace') @Component({ // eslint-disable-next-line @angular-eslint/component-selector - selector: '', + selector: 'ds-browse-entry-list-element', template: '' }) class MockThemedBrowseEntryListElementComponent { @@ -61,28 +60,6 @@ describe('BrowseByComponent', () => { let comp: BrowseByComponent; let fixture: ComponentFixture; - const mockItems = [ - Object.assign(new Item(), { - id: 'fakeId-1', - metadata: [ - { - key: 'dc.title', - value: 'First Fake Title' - } - ] - }), - Object.assign(new Item(), { - id: 'fakeId-2', - metadata: [ - { - key: 'dc.title', - value: 'Second Fake Title' - } - ] - }) - ]; - const mockItemsRD$ = createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), mockItems)); - const groupDataService = jasmine.createSpyObj('groupsDataService', { findListByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), getGroupRegistryRouterLink: '', @@ -113,8 +90,8 @@ describe('BrowseByComponent', () => { let themeService; beforeEach(waitForAsync(() => { - themeService = getMockThemeService('dspace'); - TestBed.configureTestingModule({ + themeService = getMockThemeService('base'); + void TestBed.configureTestingModule({ imports: [ BrowseByRoutingModule, AccessControlRoutingModule, @@ -200,40 +177,40 @@ describe('BrowseByComponent', () => { }); describe('when theme is base', () => { - beforeEach(() => { + beforeEach(async () => { themeService.getThemeName.and.returnValue('base'); themeService.getThemeName$.and.returnValue(observableOf('base')); fixture.detectChanges(); + await fixture.whenStable(); + fixture.detectChanges(); }); it('should use the base component to render browse entries', () => { - waitForAsync(() => { - const componentLoaders = fixture.debugElement.queryAll(By.directive(ListableObjectComponentLoaderComponent)); - expect(componentLoaders.length).toEqual(browseEntries.length); - componentLoaders.forEach((componentLoader) => { - const browseEntry = componentLoader.query(By.css('ds-browse-entry-list-element')); - expect(browseEntry.componentInstance).toBeInstanceOf(BrowseEntryListElementComponent); - }); + const componentLoaders = fixture.debugElement.queryAll(By.directive(ListableObjectComponentLoaderComponent)); + expect(componentLoaders.length).toEqual(browseEntries.length); + componentLoaders.forEach((componentLoader) => { + const browseEntry = componentLoader.query(By.css('ds-browse-entry-list-element')); + expect(browseEntry.componentInstance).toBeInstanceOf(BrowseEntryListElementComponent); }); }); }); - describe('when theme is custom', () => { - beforeEach(() => { - themeService.getThemeName.and.returnValue('custom'); - themeService.getThemeName$.and.returnValue(observableOf('custom')); + describe('when theme is dspace', () => { + beforeEach(async () => { + themeService.getThemeName.and.returnValue('dspace'); + themeService.getThemeName$.and.returnValue(observableOf('dspace')); + fixture.detectChanges(); + await fixture.whenStable(); fixture.detectChanges(); }); it('should use the themed component to render browse entries', () => { - waitForAsync(() => { const componentLoaders = fixture.debugElement.queryAll(By.directive(ListableObjectComponentLoaderComponent)); expect(componentLoaders.length).toEqual(browseEntries.length); componentLoaders.forEach((componentLoader) => { const browseEntry = componentLoader.query(By.css('ds-browse-entry-list-element')); expect(browseEntry.componentInstance).toBeInstanceOf(MockThemedBrowseEntryListElementComponent); }); - }); }); }); }); diff --git a/src/app/shared/browse-by/shared-browse-by.module.ts b/src/app/shared/browse-by/shared-browse-by.module.ts index ae42576e9b..430ca64426 100644 --- a/src/app/shared/browse-by/shared-browse-by.module.ts +++ b/src/app/shared/browse-by/shared-browse-by.module.ts @@ -6,10 +6,14 @@ import { ResultsBackButtonModule } from '../results-back-button/results-back-but import { BrowseByRoutingModule } from '../../browse-by/browse-by-routing.module'; import { AccessControlRoutingModule } from '../../access-control/access-control-routing.module'; +const DECLARATIONS = [ + BrowseByComponent, +]; + @NgModule({ declarations: [ - BrowseByComponent, -], + ...DECLARATIONS, + ], imports: [ ResultsBackButtonModule, BrowseByRoutingModule, @@ -18,8 +22,8 @@ import { AccessControlRoutingModule } from '../../access-control/access-control- SharedModule, ], exports: [ - BrowseByComponent, - SharedModule, + ...DECLARATIONS, ] }) -export class SharedBrowseByModule { } +export class SharedBrowseByModule { +} From 8d84efb1a9c14be2d9afe9a8d4fd02f7469af2f6 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sun, 16 Jul 2023 14:58:22 +0200 Subject: [PATCH 017/142] Fix AuthInterceptor no expectation tests - Removed duplicate request - Added expect().nothing() because httpMock.expectNone will throw an error when a request is made --- src/app/core/auth/auth.interceptor.spec.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/app/core/auth/auth.interceptor.spec.ts b/src/app/core/auth/auth.interceptor.spec.ts index 04bbc4acaf..1cf812fcbf 100644 --- a/src/app/core/auth/auth.interceptor.spec.ts +++ b/src/app/core/auth/auth.interceptor.spec.ts @@ -20,9 +20,7 @@ describe(`AuthInterceptor`, () => { const authServiceStub = new AuthServiceStub(); const store: Store = jasmine.createSpyObj('store', { - /* eslint-disable no-empty,@typescript-eslint/no-empty-function */ dispatch: {}, - /* eslint-enable no-empty, @typescript-eslint/no-empty-function */ select: observableOf(true) }); @@ -46,6 +44,10 @@ describe(`AuthInterceptor`, () => { httpMock = TestBed.inject(HttpTestingController); }); + afterEach(() => { + httpMock.verify(); + }); + describe('when has a valid token', () => { it('should not add an Authorization header when we’re sending a HTTP request to \'authn\' endpoint that is not the logout endpoint', () => { @@ -95,14 +97,11 @@ describe(`AuthInterceptor`, () => { }); it('should redirect to login', () => { - - service.request(RestRequestMethod.POST, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user').subscribe((response) => { - expect(response).toBeTruthy(); - }); - service.request(RestRequestMethod.POST, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user'); httpMock.expectNone('dspace-spring-rest/api/submission/workspaceitems'); + // HttpTestingController.expectNone will throw an error when a requests is made + expect().nothing(); }); }); From c4bff4d9c7f3b72655f449e3ef30d9170f69a54f Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 29 Jul 2023 19:18:58 +0200 Subject: [PATCH 018/142] Fix test without it's/it's not running because they are in a waitForAsync function --- src/app/core/shared/item.model.spec.ts | 4 +- .../item-bitstreams.component.spec.ts | 14 ----- .../item-page-field.component.spec.ts | 52 +++++++---------- ...nk-metadata-list-element.component.spec.ts | 57 ++++++++++++------- 4 files changed, 61 insertions(+), 66 deletions(-) diff --git a/src/app/core/shared/item.model.spec.ts b/src/app/core/shared/item.model.spec.ts index 732ae5b19c..96cca5dd50 100644 --- a/src/app/core/shared/item.model.spec.ts +++ b/src/app/core/shared/item.model.spec.ts @@ -12,14 +12,13 @@ describe('Item', () => { const bitstream1Path = 'document.pdf'; const bitstream2Path = 'otherfile.doc'; - const nonExistingBundleName = 'c1e568f7-d14e-496b-bdd7-07026998cc00'; let bitstreams; let remoteDataThumbnail; let remoteDataThumbnailList; let remoteDataFiles; let remoteDataBundles; - beforeEach(() => { + it('should be possible to create an Item without any errors', () => { const thumbnail = { content: thumbnailPath }; @@ -51,5 +50,6 @@ describe('Item', () => { remoteDataBundles = createSuccessfulRemoteDataObject$(createPaginatedList(bundles)); item = Object.assign(new Item(), { bundles: remoteDataBundles }); + expect().nothing(); }); }); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts index 10e1812131..3177ea9e33 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts @@ -191,20 +191,6 @@ describe('ItemBitstreamsComponent', () => { }); }); - describe('when dropBitstream is called', () => { - const event = { - fromIndex: 0, - toIndex: 50, - // eslint-disable-next-line no-empty,@typescript-eslint/no-empty-function - finish: () => { - } - }; - - beforeEach(() => { - comp.dropBitstream(bundle, event); - }); - }); - describe('when dropBitstream is called', () => { beforeEach((done) => { comp.dropBitstream(bundle, { diff --git a/src/app/item-page/simple/field-components/specific-field/item-page-field.component.spec.ts b/src/app/item-page/simple/field-components/specific-field/item-page-field.component.spec.ts index 15b7a9df21..5fc4644c72 100644 --- a/src/app/item-page/simple/field-components/specific-field/item-page-field.component.spec.ts +++ b/src/app/item-page/simple/field-components/specific-field/item-page-field.component.spec.ts @@ -37,8 +37,8 @@ describe('ItemPageFieldComponent', () => { } }); - const buildTestEnvironment = async () => { - await TestBed.configureTestingModule({ + beforeEach(waitForAsync(() => { + void TestBed.configureTestingModule({ imports: [ RouterTestingModule.withRoutes([]), TranslateModule.forRoot({ @@ -65,19 +65,16 @@ describe('ItemPageFieldComponent', () => { comp.fields = mockFields; comp.label = mockLabel; fixture.detectChanges(); - }; - - it('should display display the correct metadata value', waitForAsync(async () => { - await buildTestEnvironment(); - expect(fixture.nativeElement.innerHTML).toContain(mockValue); })); - describe('when markdown is disabled in the environment config', () => { + it('should display display the correct metadata value', () => { + expect(fixture.nativeElement.innerHTML).toContain(mockValue); + }); - beforeEach(waitForAsync(async () => { + describe('when markdown is disabled in the environment config', () => { + beforeEach( () => { appConfig.markdown.enabled = false; - await buildTestEnvironment(); - })); + }); describe('and markdown is disabled in this component', () => { @@ -105,11 +102,9 @@ describe('ItemPageFieldComponent', () => { }); describe('when markdown is enabled in the environment config', () => { - - beforeEach(waitForAsync(async () => { + beforeEach(() => { appConfig.markdown.enabled = true; - await buildTestEnvironment(); - })); + }); describe('and markdown is disabled in this component', () => { @@ -139,12 +134,13 @@ describe('ItemPageFieldComponent', () => { describe('test rendering of configured browse links', () => { beforeEach(() => { + appConfig.markdown.enabled = false; + comp.enableMarkdown = true; fixture.detectChanges(); }); - waitForAsync(() => { - it('should have a browse link', () => { - expect(fixture.debugElement.query(By.css('a.ds-browse-link')).nativeElement.innerHTML).toContain(mockValue); - }); + + it('should have a browse link', async () => { + expect(fixture.debugElement.query(By.css('a.ds-browse-link')).nativeElement.innerHTML).toContain(mockValue); }); }); @@ -153,10 +149,9 @@ describe('ItemPageFieldComponent', () => { comp.urlRegex = '^test'; fixture.detectChanges(); }); - waitForAsync(() => { - it('should have a rendered (non-browse) link since the value matches ^test', () => { - expect(fixture.debugElement.query(By.css('a.ds-simple-metadata-link')).nativeElement.innerHTML).toContain(mockValue); - }); + + it('should have a rendered (non-browse) link since the value matches ^test', () => { + expect(fixture.debugElement.query(By.css('a.ds-simple-metadata-link')).nativeElement.innerHTML).toContain(mockValue); }); }); @@ -165,14 +160,11 @@ describe('ItemPageFieldComponent', () => { comp.urlRegex = '^nope'; fixture.detectChanges(); }); - beforeEach(waitForAsync(() => { - it('should NOT have a rendered (non-browse) link since the value matches ^test', () => { - expect(fixture.debugElement.query(By.css('a.ds-simple-metadata-link'))).toBeNull(); - }); - })); + + it('should NOT have a rendered (non-browse) link since the value matches ^test', () => { + expect(fixture.debugElement.query(By.css('a.ds-simple-metadata-link'))).toBeNull(); + }); }); - - }); export function mockItemWithMetadataFieldsAndValue(fields: string[], value: string): Item { diff --git a/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.spec.ts b/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.spec.ts index 3527b9fddd..1eb97a03bf 100644 --- a/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.spec.ts +++ b/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.spec.ts @@ -1,24 +1,36 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { BrowseLinkMetadataListElementComponent } from './browse-link-metadata-list-element.component'; -import { MetadatumRepresentation } from '../../../../core/shared/metadata-representation/metadatum/metadatum-representation.model'; +import { + MetadatumRepresentation +} from '../../../../core/shared/metadata-representation/metadatum/metadatum-representation.model'; +import { + MetadataRepresentationType +} from '../../../../core/shared/metadata-representation/metadata-representation.model'; +import { ValueListBrowseDefinition } from '../../../../core/shared/value-list-browse-definition.model'; const mockMetadataRepresentation = Object.assign(new MetadatumRepresentation('type'), { key: 'dc.contributor.author', - value: 'Test Author' -}); + value: 'Test Author', + browseDefinition: Object.assign(new ValueListBrowseDefinition(), { + id: 'author', + }), +} as Partial); const mockMetadataRepresentationWithUrl = Object.assign(new MetadatumRepresentation('type'), { key: 'dc.subject', - value: 'http://purl.org/test/subject' -}); + value: 'https://purl.org/test/subject', + browseDefinition: Object.assign(new ValueListBrowseDefinition(), { + id: 'subject', + }), +} as Partial); describe('BrowseLinkMetadataListElementComponent', () => { let comp: BrowseLinkMetadataListElementComponent; let fixture: ComponentFixture; beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ + void TestBed.configureTestingModule({ imports: [], declarations: [BrowseLinkMetadataListElementComponent], schemas: [NO_ERRORS_SCHEMA] @@ -27,35 +39,40 @@ describe('BrowseLinkMetadataListElementComponent', () => { }).compileComponents(); })); - beforeEach(waitForAsync(() => { + beforeEach(() => { fixture = TestBed.createComponent(BrowseLinkMetadataListElementComponent); comp = fixture.componentInstance; - comp.mdRepresentation = mockMetadataRepresentation; - fixture.detectChanges(); - })); + }); + + describe('with normal metadata', () => { + beforeEach(() => { + comp.mdRepresentation = mockMetadataRepresentation; + spyOnProperty(comp.mdRepresentation, 'representationType', 'get').and.returnValue(MetadataRepresentationType.BrowseLink); + fixture.detectChanges(); + }); - waitForAsync(() => { it('should contain the value as a browse link', () => { expect(fixture.debugElement.nativeElement.textContent).toContain(mockMetadataRepresentation.value); }); + it('should NOT match isLink', () => { - expect(comp.isLink).toBe(false); + expect(comp.isLink()).toBe(false); }); }); - beforeEach(waitForAsync(() => { - fixture = TestBed.createComponent(BrowseLinkMetadataListElementComponent); - comp = fixture.componentInstance; - comp.mdRepresentation = mockMetadataRepresentationWithUrl; - fixture.detectChanges(); - })); + describe('with metadata wit an url', () => { + beforeEach(() => { + comp.mdRepresentation = mockMetadataRepresentationWithUrl; + spyOnProperty(comp.mdRepresentation, 'representationType', 'get').and.returnValue(MetadataRepresentationType.BrowseLink); + fixture.detectChanges(); + }); - waitForAsync(() => { it('should contain the value expected', () => { expect(fixture.debugElement.nativeElement.textContent).toContain(mockMetadataRepresentationWithUrl.value); }); + it('should match isLink', () => { - expect(comp.isLink).toBe(true); + expect(comp.isLink()).toBe(true); }); }); From 230adc16c841b4bcff73dab9513458693d7be4b9 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 15 Dec 2023 23:43:10 +0100 Subject: [PATCH 019/142] Fixed failing EPeopleRegistryComponent test Buttons to which you don't have access are now hidden by default instead of disabled --- .../epeople-registry.component.spec.ts | 61 +++++++------------ 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts b/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts index e2cee5e935..db5405c70b 100644 --- a/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts +++ b/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts @@ -5,8 +5,8 @@ import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { BrowserModule, By } from '@angular/platform-browser'; -import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; +import { NgbModule, NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateModule } from '@ngx-translate/core'; import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import { RemoteData } from '../../core/data/remote-data'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; @@ -18,8 +18,6 @@ import { EPeopleRegistryComponent } from './epeople-registry.component'; import { EPersonMock, EPersonMock2 } from '../../shared/testing/eperson.mock'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { getMockFormBuilderService } from '../../shared/mocks/form-builder-service.mock'; -import { getMockTranslateService } from '../../shared/mocks/translate.service.mock'; -import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; import { RouterStub } from '../../shared/testing/router.stub'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; @@ -31,17 +29,15 @@ import { FindListOptions } from '../../core/data/find-list-options.model'; describe('EPeopleRegistryComponent', () => { let component: EPeopleRegistryComponent; let fixture: ComponentFixture; - let translateService: TranslateService; let builderService: FormBuilderService; - let mockEPeople; + let mockEPeople: EPerson[]; let ePersonDataServiceStub: any; let authorizationService: AuthorizationDataService; - let modalService; + let modalService: NgbModal; + let paginationService: PaginationServiceStub; - let paginationService; - - beforeEach(waitForAsync(() => { + beforeEach(waitForAsync(async () => { jasmine.getEnv().allowRespy(true); mockEPeople = [EPersonMock, EPersonMock2]; ePersonDataServiceStub = { @@ -99,7 +95,7 @@ describe('EPeopleRegistryComponent', () => { deleteEPerson(ePerson: EPerson): Observable { this.allEpeople = this.allEpeople.filter((ePerson2: EPerson) => { return (ePerson2.uuid !== ePerson.uuid); - }); + }); return observableOf(true); }, editEPerson(ePerson: EPerson) { @@ -119,17 +115,11 @@ describe('EPeopleRegistryComponent', () => { isAuthorized: observableOf(true) }); builderService = getMockFormBuilderService(); - translateService = getMockTranslateService(); paginationService = new PaginationServiceStub(); - TestBed.configureTestingModule({ + await TestBed.configureTestingModule({ imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule, - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useClass: TranslateLoaderMock - } - }), + TranslateModule.forRoot(), ], declarations: [EPeopleRegistryComponent], providers: [ @@ -148,7 +138,7 @@ describe('EPeopleRegistryComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(EPeopleRegistryComponent); component = fixture.componentInstance; - modalService = (component as any).modalService; + modalService = TestBed.inject(NgbModal); spyOn(modalService, 'open').and.returnValue(Object.assign({ componentInstance: Object.assign({ response: observableOf(true) }) })); fixture.detectChanges(); }); @@ -158,10 +148,10 @@ describe('EPeopleRegistryComponent', () => { }); it('should display list of ePeople', () => { - const ePeopleIdsFound = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child')); + const ePeopleIdsFound: DebugElement[] = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child')); expect(ePeopleIdsFound.length).toEqual(2); mockEPeople.map((ePerson: EPerson) => { - expect(ePeopleIdsFound.find((foundEl) => { + expect(ePeopleIdsFound.find((foundEl: DebugElement) => { return (foundEl.nativeElement.textContent.trim() === ePerson.uuid); })).toBeTruthy(); }); @@ -169,7 +159,7 @@ describe('EPeopleRegistryComponent', () => { describe('search', () => { describe('when searching with scope/query (scope metadata)', () => { - let ePeopleIdsFound; + let ePeopleIdsFound: DebugElement[]; beforeEach(fakeAsync(() => { component.search({ scope: 'metadata', query: EPersonMock2.name }); tick(); @@ -179,14 +169,14 @@ describe('EPeopleRegistryComponent', () => { it('should display search result', () => { expect(ePeopleIdsFound.length).toEqual(1); - expect(ePeopleIdsFound.find((foundEl) => { + expect(ePeopleIdsFound.find((foundEl: DebugElement) => { return (foundEl.nativeElement.textContent.trim() === EPersonMock2.uuid); })).toBeTruthy(); }); }); describe('when searching with scope/query (scope email)', () => { - let ePeopleIdsFound; + let ePeopleIdsFound: DebugElement[]; beforeEach(fakeAsync(() => { component.search({ scope: 'email', query: EPersonMock.email }); tick(); @@ -196,7 +186,7 @@ describe('EPeopleRegistryComponent', () => { it('should display search result', () => { expect(ePeopleIdsFound.length).toEqual(1); - expect(ePeopleIdsFound.find((foundEl) => { + expect(ePeopleIdsFound.find((foundEl: DebugElement) => { return (foundEl.nativeElement.textContent.trim() === EPersonMock.uuid); })).toBeTruthy(); }); @@ -228,19 +218,12 @@ describe('EPeopleRegistryComponent', () => { }); }); - describe('delete EPerson button when the isAuthorized returns false', () => { - let ePeopleDeleteButton; - beforeEach(() => { - spyOn(authorizationService, 'isAuthorized').and.returnValue(observableOf(false)); - component.initialisePage(); - fixture.detectChanges(); - }); - it('should be disabled', () => { - ePeopleDeleteButton = fixture.debugElement.queryAll(By.css('#epeople tr td div button.delete-button')); - ePeopleDeleteButton.forEach((deleteButton: DebugElement) => { - expect(deleteButton.nativeElement.disabled).toBe(true); - }); - }); + it('should hide delete EPerson button when the isAuthorized returns false', () => { + spyOn(authorizationService, 'isAuthorized').and.returnValue(observableOf(false)); + component.initialisePage(); + fixture.detectChanges(); + + expect(fixture.debugElement.query(By.css('#epeople tr td div button.delete-button'))).toBeNull(); }); }); From e1cda4fa049fb1c437e07f7860ef2ff81e11b5da Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Thu, 21 Dec 2023 18:06:39 +0100 Subject: [PATCH 020/142] prepare dashboard config --- .../admin-notify-dashboard.component.html | 1 + .../admin-notify-dashboard.component.scss | 0 .../admin-notify-dashboard.component.spec.ts | 23 +++++++++++++++++++ .../admin-notify-dashboard.component.ts | 10 ++++++++ src/app/admin/admin.module.ts | 4 +++- src/app/menu.resolver.ts | 12 ++++++++++ src/assets/i18n/en.json5 | 2 ++ 7 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.scss create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html new file mode 100644 index 0000000000..90fa077e91 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -0,0 +1 @@ +

admin-notify-dashboard works!

diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts new file mode 100644 index 0000000000..4df980e1df --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; + +describe('AdminNotifyDashboardComponent', () => { + let component: AdminNotifyDashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AdminNotifyDashboardComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminNotifyDashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts new file mode 100644 index 0000000000..7959d9917f --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-admin-notify-dashboard', + templateUrl: './admin-notify-dashboard.component.html', + styleUrls: ['./admin-notify-dashboard.component.scss'] +}) +export class AdminNotifyDashboardComponent { + +} diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index 3dc0036854..ee0d3b0d4e 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -12,6 +12,7 @@ import { ExpandableAdminSidebarSectionComponent } from './admin-sidebar/expandab import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component'; import { UiSwitchModule } from 'ngx-ui-switch'; import { UploadModule } from '../shared/upload/upload.module'; +import { AdminNotifyDashboardComponent } from './admin-notify-dashboard/admin-notify-dashboard.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -34,7 +35,8 @@ const ENTRY_COMPONENTS = [ declarations: [ AdminCurationTasksComponent, MetadataImportPageComponent, - BatchImportPageComponent + BatchImportPageComponent, + AdminNotifyDashboardComponent ] }) export class AdminModule { diff --git a/src/app/menu.resolver.ts b/src/app/menu.resolver.ts index 23ba31b103..c4f2991fe2 100644 --- a/src/app/menu.resolver.ts +++ b/src/app/menu.resolver.ts @@ -679,6 +679,18 @@ export class MenuResolver implements Resolve { icon: 'exclamation-circle', index: 12 }, + { + id: 'notify_dashboard', + active: false, + visible: authorized, + model: { + type: MenuItemType.LINK, + text: 'menu.section.notify-dasboard', + link: '/admin/notify-dasboard' + } as LinkMenuItemModel, + icon: 'gauge', + index: 13 + }, ]; menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, Object.assign(menuSection, { diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index f7a9e2c072..d68229f19b 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3075,6 +3075,8 @@ "menu.section.icon.export": "Export menu section", + "menu.section.notify-dasboard": "Notify Dashboard", + "menu.section.icon.find": "Find menu section", "menu.section.icon.health": "Health check menu section", From 7445591148e068b9ac300dcfd972fa1c014dbc6c Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Thu, 21 Dec 2023 18:10:45 +0100 Subject: [PATCH 021/142] add route, renaming --- src/app/admin/admin-routing.module.ts | 7 +++++++ src/app/menu.resolver.ts | 4 ++-- src/assets/i18n/en.json5 | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/app/admin/admin-routing.module.ts b/src/app/admin/admin-routing.module.ts index 3acc219bce..ecafa0232f 100644 --- a/src/app/admin/admin-routing.module.ts +++ b/src/app/admin/admin-routing.module.ts @@ -8,6 +8,7 @@ import { I18nBreadcrumbsService } from '../core/breadcrumbs/i18n-breadcrumbs.ser import { AdminCurationTasksComponent } from './admin-curation-tasks/admin-curation-tasks.component'; import { LDN_PATH, REGISTRIES_MODULE_PATH, NOTIFICATIONS_MODULE_PATH } from './admin-routing-paths'; import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component'; +import { AdminNotifyDashboardComponent } from "./admin-notify-dashboard/admin-notify-dashboard.component"; @NgModule({ imports: [ @@ -69,6 +70,12 @@ import { BatchImportPageComponent } from './admin-import-batch-page/batch-import loadChildren: () => import('../system-wide-alert/system-wide-alert.module').then((m) => m.SystemWideAlertModule), data: {title: 'admin.system-wide-alert.title', breadcrumbKey: 'admin.system-wide-alert'} }, + { + path: 'notify-dashboard', + resolve: { breadcrumb: I18nBreadcrumbResolver }, + component: AdminNotifyDashboardComponent, + data: {title: 'todo', breadcrumbKey: 'todo'} + }, ]), ], providers: [ diff --git a/src/app/menu.resolver.ts b/src/app/menu.resolver.ts index c4f2991fe2..671440d48d 100644 --- a/src/app/menu.resolver.ts +++ b/src/app/menu.resolver.ts @@ -685,8 +685,8 @@ export class MenuResolver implements Resolve { visible: authorized, model: { type: MenuItemType.LINK, - text: 'menu.section.notify-dasboard', - link: '/admin/notify-dasboard' + text: 'menu.section.notify-dashboard', + link: '/admin/notify-dashboard' } as LinkMenuItemModel, icon: 'gauge', index: 13 diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index d68229f19b..8a504fac47 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3075,7 +3075,7 @@ "menu.section.icon.export": "Export menu section", - "menu.section.notify-dasboard": "Notify Dashboard", + "menu.section.notify-dashboard": "Notify Dashboard", "menu.section.icon.find": "Find menu section", From 604fb4f3d172360e22d79e283d6858f42e23490d Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 22 Dec 2023 10:42:38 +0100 Subject: [PATCH 022/142] add components, refactor sidebar section, add config --- .../admin-notify-dashboard-routing.module.ts | 37 +++++++++++ .../admin-notify-dashboard.component.html | 29 ++++++++- .../admin-notify-dashboard.module.ts | 25 ++++++++ .../admin-notify-logs.component.html | 1 + .../admin-notify-logs.component.scss | 0 .../admin-notify-logs.component.spec.ts | 23 +++++++ .../admin-notify-logs.component.ts | 10 +++ .../admin-notify-metrics.component.html | 11 ++++ .../admin-notify-metrics.component.scss | 0 .../admin-notify-metrics.component.spec.ts | 23 +++++++ .../admin-notify-metrics.component.ts | 13 ++++ .../admin-notify-metrics.config.ts | 64 +++++++++++++++++++ .../admin-notify-metrics.model.ts | 10 +++ src/app/admin/admin-routing-paths.ts | 3 +- src/app/admin/admin-routing.module.ts | 14 ++-- src/app/admin/admin.module.ts | 2 - src/app/menu.resolver.ts | 44 ++++++++----- src/assets/i18n/en.json5 | 14 +++- 18 files changed, 296 insertions(+), 27 deletions(-) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.scss create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.html create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.scss create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.spec.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts new file mode 100644 index 0000000000..447a1fe39a --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts @@ -0,0 +1,37 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver'; +import { I18nBreadcrumbsService } from '../../core/breadcrumbs/i18n-breadcrumbs.service'; +import { AuthenticatedGuard } from "../../core/auth/authenticated.guard"; +import { AdminNotifyDashboardComponent } from "./admin-notify-dashboard.component"; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { + canActivate: [ AuthenticatedGuard ], + path: '', + component: AdminNotifyDashboardComponent, + pathMatch: 'full', + resolve: { + breadcrumb: I18nBreadcrumbResolver, + }, + data: { + title: 'admin.notify.dashboard.page.title', + breadcrumbKey: 'admin.notify.dashboard', + showBreadcrumbsFluid: false + } + }, + ]) + ], + providers: [ + I18nBreadcrumbResolver, + I18nBreadcrumbsService, + ] +}) +/** + * Routing module for the Notifications section of the admin sidebar + */ +export class AdminNotifyDashboardRoutingModule { + +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html index 90fa077e91..4b432adb38 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -1 +1,28 @@ -

admin-notify-dashboard works!

+
+
+
+

{{'admin-notify-dashboard.title'| translate}}

+ +
+
+
diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts new file mode 100644 index 0000000000..0074d13ce0 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { SharedModule } from '../../shared/shared.module'; +import { AdminNotifyDashboardComponent } from "./admin-notify-dashboard.component"; +import { AdminNotifyDashboardRoutingModule } from "./admin-notify-dashboard-routing.module"; +import { AdminNotifyMetricsComponent } from './admin-notify-metrics/admin-notify-metrics.component'; +import { AdminNotifyLogsComponent } from './admin-notify-logs/admin-notify-logs.component'; + +@NgModule({ + imports: [ + CommonModule, + SharedModule, + RouterModule, + AdminNotifyDashboardRoutingModule, + ], + declarations: [ + AdminNotifyDashboardComponent, + AdminNotifyMetricsComponent, + AdminNotifyLogsComponent + ] +}) +export class AdminNotifyDashboardModule { + +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html new file mode 100644 index 0000000000..494e082ddf --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html @@ -0,0 +1 @@ +

admin-notify-logs works!

diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts new file mode 100644 index 0000000000..12a0feae64 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdminNotifyLogsComponent } from './admin-notify-logs.component'; + +describe('AdminNotifyLogsComponent', () => { + let component: AdminNotifyLogsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AdminNotifyLogsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminNotifyLogsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts new file mode 100644 index 0000000000..67552130a0 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-admin-notify-logs', + templateUrl: './admin-notify-logs.component.html', + styleUrls: ['./admin-notify-logs.component.scss'] +}) +export class AdminNotifyLogsComponent { + +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.html new file mode 100644 index 0000000000..f4e0e45279 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.html @@ -0,0 +1,11 @@ +
+
+
+
+ +
0
+
{{ box.title | translate }}
+
+
+
+
diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.spec.ts new file mode 100644 index 0000000000..10e256a701 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdminNotifyMetricsComponent } from './admin-notify-metrics.component'; + +describe('AdminNotifyMetricsComponent', () => { + let component: AdminNotifyMetricsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AdminNotifyMetricsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminNotifyMetricsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts new file mode 100644 index 0000000000..d1d7ca4bd5 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; +import { AdminNotifyMetricsRow } from "./admin-notify-metrics.model"; +import { AdminNotifyMetricsRowsConfig } from "./admin-notify-metrics.config"; + +@Component({ + selector: 'ds-admin-notify-metrics', + templateUrl: './admin-notify-metrics.component.html', + styleUrls: ['./admin-notify-metrics.component.scss'] +}) +export class AdminNotifyMetricsComponent { + + boxesConfig: AdminNotifyMetricsRow[] = AdminNotifyMetricsRowsConfig; +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts new file mode 100644 index 0000000000..7880e78ebf --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts @@ -0,0 +1,64 @@ +import { AdminNotifyMetricsRow } from "./admin-notify-metrics.model"; + +export const AdminNotifyMetricsRowsConfig: AdminNotifyMetricsRow[] = [ + { + title: 'Number of received LDN', + boxes: [ + { + color: 'blue', + title: 'Accepted', + index: 0 + }, + { + color: 'green', + title: 'Processed LDN', + index: 1 + }, + { + color: 'red', + title: 'Failure', + index: 2 + }, + { + color: 'red', + title: 'Untrusted', + index: 3 + }, + { + color: 'grey', + title: 'Incoming LDM messages', + index: 4 + }, + ] + }, + { + title: 'Number of generated LDN', + boxes: [ + { + color: 'green', + title: 'Delivered', + index: 0 + }, + { + color: 'blue', + title: 'Queued', + index: 1 + }, + { + color: 'yellow', + title: 'Queued for retry', + index: 2 + }, + { + color: 'red', + title: 'Failure', + index: 3 + }, + { + color: 'grey', + title: 'Outgoing LDM messages', + index: 4 + }, + ] + } +] diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts new file mode 100644 index 0000000000..3b47deffa1 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts @@ -0,0 +1,10 @@ +export interface AdminNotifyMetricsBox { + color: string; + title: string; + index: number +} + +export interface AdminNotifyMetricsRow { + title: string; + boxes: AdminNotifyMetricsBox[] +} diff --git a/src/app/admin/admin-routing-paths.ts b/src/app/admin/admin-routing-paths.ts index 511680bfd8..c08139bd87 100644 --- a/src/app/admin/admin-routing-paths.ts +++ b/src/app/admin/admin-routing-paths.ts @@ -4,6 +4,8 @@ import { getAdminModuleRoute } from '../app-routing-paths'; export const REGISTRIES_MODULE_PATH = 'registries'; export const NOTIFICATIONS_MODULE_PATH = 'notifications'; +export const NOTIFY_DASHBOARD_MODULE_PATH = 'notify-dashboard'; + export const LDN_PATH = 'ldn'; export function getRegistriesModuleRoute() { @@ -13,7 +15,6 @@ export function getRegistriesModuleRoute() { export function getNotificationsModuleRoute() { return new URLCombiner(getAdminModuleRoute(), NOTIFICATIONS_MODULE_PATH).toString(); } - export function getLdnServicesModuleRoute() { return new URLCombiner(getAdminModuleRoute(), LDN_PATH).toString(); } diff --git a/src/app/admin/admin-routing.module.ts b/src/app/admin/admin-routing.module.ts index ecafa0232f..e30a5b20fb 100644 --- a/src/app/admin/admin-routing.module.ts +++ b/src/app/admin/admin-routing.module.ts @@ -6,7 +6,12 @@ import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.reso import { AdminWorkflowPageComponent } from './admin-workflow-page/admin-workflow-page.component'; import { I18nBreadcrumbsService } from '../core/breadcrumbs/i18n-breadcrumbs.service'; import { AdminCurationTasksComponent } from './admin-curation-tasks/admin-curation-tasks.component'; -import { LDN_PATH, REGISTRIES_MODULE_PATH, NOTIFICATIONS_MODULE_PATH } from './admin-routing-paths'; +import { + LDN_PATH, + REGISTRIES_MODULE_PATH, + NOTIFICATIONS_MODULE_PATH, + NOTIFY_DASHBOARD_MODULE_PATH +} from './admin-routing-paths'; import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component'; import { AdminNotifyDashboardComponent } from "./admin-notify-dashboard/admin-notify-dashboard.component"; @@ -71,10 +76,9 @@ import { AdminNotifyDashboardComponent } from "./admin-notify-dashboard/admin-no data: {title: 'admin.system-wide-alert.title', breadcrumbKey: 'admin.system-wide-alert'} }, { - path: 'notify-dashboard', - resolve: { breadcrumb: I18nBreadcrumbResolver }, - component: AdminNotifyDashboardComponent, - data: {title: 'todo', breadcrumbKey: 'todo'} + path: NOTIFY_DASHBOARD_MODULE_PATH, + loadChildren: () => import('./admin-notify-dashboard/admin-notify-dashboard.module') + .then((m) => m.AdminNotifyDashboardModule), }, ]), ], diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index ee0d3b0d4e..d77c3213b3 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -12,7 +12,6 @@ import { ExpandableAdminSidebarSectionComponent } from './admin-sidebar/expandab import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component'; import { UiSwitchModule } from 'ngx-ui-switch'; import { UploadModule } from '../shared/upload/upload.module'; -import { AdminNotifyDashboardComponent } from './admin-notify-dashboard/admin-notify-dashboard.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -36,7 +35,6 @@ const ENTRY_COMPONENTS = [ AdminCurationTasksComponent, MetadataImportPageComponent, BatchImportPageComponent, - AdminNotifyDashboardComponent ] }) export class AdminModule { diff --git a/src/app/menu.resolver.ts b/src/app/menu.resolver.ts index 671440d48d..15848963c9 100644 --- a/src/app/menu.resolver.ts +++ b/src/app/menu.resolver.ts @@ -362,19 +362,6 @@ export class MenuResolver implements Resolve { icon: 'terminal', index: 10 }, - /* LDN Services */ - { - id: 'ldn_services', - active: false, - visible: isSiteAdmin, - model: { - type: MenuItemType.LINK, - text: 'menu.section.services', - link: '/admin/ldn/services' - } as LinkMenuItemModel, - icon: 'inbox', - index: 14 - }, { id: 'health', active: false, @@ -679,17 +666,40 @@ export class MenuResolver implements Resolve { icon: 'exclamation-circle', index: 12 }, + /* COAR Notify section */ { - id: 'notify_dashboard', + id: 'coar_notify', active: false, visible: authorized, + model: { + type: MenuItemType.TEXT, + text: 'menu.section.coar_notify' + } as TextMenuItemModel, + icon: 'inbox', + index: 13 + }, + { + id: 'notify_dashboard', + active: false, + parentID: 'coar_notify', + visible: authorized, model: { type: MenuItemType.LINK, - text: 'menu.section.notify-dashboard', + text: 'menu.section.notify_dashboard', link: '/admin/notify-dashboard' } as LinkMenuItemModel, - icon: 'gauge', - index: 13 + }, + /* LDN Services */ + { + id: 'ldn_services', + active: false, + parentID: 'coar_notify', + visible: authorized, + model: { + type: MenuItemType.LINK, + text: 'menu.section.services', + link: '/admin/ldn/services' + } as LinkMenuItemModel, }, ]; diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 8a504fac47..0acbba29c7 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -28,6 +28,8 @@ "admin.notifications.recitersuggestion.page.title": "Suggestions", + "admin.notify.dashboard": "Dashboard", + "error-page.description.401": "unauthorized", "error-page.description.403": "forbidden", @@ -3075,7 +3077,9 @@ "menu.section.icon.export": "Export menu section", - "menu.section.notify-dashboard": "Notify Dashboard", + "menu.section.notify_dashboard": "Dashboard", + + "menu.section.coar_notify": "COAR Notify", "menu.section.icon.find": "Find menu section", @@ -3439,6 +3443,14 @@ "quality-assurance.event.reason": "Reason", + "admin-notify-dashboard.title": "Notify Dashboard", + + "admin-notify-dashboard.metrics": "Notify metrics", + + "admin-notify-dashboard.logs": "Notify logs", + + "admin.notify.dashboard.breadcrumbs": "Dashboard", + "orgunit.listelement.badge": "Organizational Unit", "orgunit.listelement.no-title": "Untitled", From 5d8ba546764b16124bb536d34f419164586ea390 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 22 Dec 2023 17:26:46 +0100 Subject: [PATCH 023/142] add new component, add mock, refactor --- .../admin-notify-dashboard-routing.module.ts | 4 +- .../admin-notify-dashboard.component.spec.ts | 3 ++ .../admin-notify-dashboard.component.ts | 43 +++++++++++++++++-- .../admin-notify-dashboard.module.ts | 11 ++--- .../admin-notify-logs.component.spec.ts | 2 + .../admin-notify-metrics.component.html | 14 +++--- .../admin-notify-metrics.component.spec.ts | 2 + .../admin-notify-metrics.component.ts | 4 +- .../admin-notify-metrics.config.ts | 36 ++++++---------- .../admin-notify-metrics.model.ts | 3 +- src/app/admin/admin-routing.module.ts | 1 - .../notification-box.component.html | 6 +++ .../notification-box.component.scss | 7 +++ .../notification-box.component.spec.ts | 23 ++++++++++ .../notification-box.component.ts | 13 ++++++ src/app/shared/shared.module.ts | 4 +- 16 files changed, 131 insertions(+), 45 deletions(-) create mode 100644 src/app/shared/notification-box/notification-box.component.html create mode 100644 src/app/shared/notification-box/notification-box.component.scss create mode 100644 src/app/shared/notification-box/notification-box.component.spec.ts create mode 100644 src/app/shared/notification-box/notification-box.component.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts index 447a1fe39a..778815e1fb 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts @@ -2,8 +2,8 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver'; import { I18nBreadcrumbsService } from '../../core/breadcrumbs/i18n-breadcrumbs.service'; -import { AuthenticatedGuard } from "../../core/auth/authenticated.guard"; -import { AdminNotifyDashboardComponent } from "./admin-notify-dashboard.component"; +import { AuthenticatedGuard } from '../../core/auth/authenticated.guard'; +import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; @NgModule({ imports: [ diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts index 4df980e1df..c5afaa3b59 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts @@ -1,6 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; +import { TranslateModule } from '@ngx-translate/core'; +import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; describe('AdminNotifyDashboardComponent', () => { let component: AdminNotifyDashboardComponent; @@ -8,6 +10,7 @@ describe('AdminNotifyDashboardComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), NgbNavModule], declarations: [ AdminNotifyDashboardComponent ] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 7959d9917f..56f5091969 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -1,10 +1,47 @@ -import { Component } from '@angular/core'; +import { Component, Inject, OnInit } from '@angular/core'; +import { SearchConfigurationService } from "../../core/shared/search/search-configuration.service"; +import { SearchService } from "../../core/shared/search/search.service"; +import { PaginatedSearchOptions } from "../../shared/search/models/paginated-search-options.model"; +import { SEARCH_CONFIG_SERVICE } from "../../my-dspace-page/my-dspace-page.component"; +import { PaginationComponentOptions } from "../../shared/pagination/pagination-component-options.model"; +import { SearchFilterConfig } from "../../shared/search/models/search-filter-config.model"; @Component({ selector: 'ds-admin-notify-dashboard', templateUrl: './admin-notify-dashboard.component.html', - styleUrls: ['./admin-notify-dashboard.component.scss'] + styleUrls: ['./admin-notify-dashboard.component.scss'], + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationService + } + ] }) -export class AdminNotifyDashboardComponent { +export class AdminNotifyDashboardComponent implements OnInit{ + mockFilterConfig : SearchFilterConfig = Object.assign(new SearchFilterConfig(), { + type: { + value: "discovery-filter" + }, + pageSize: 10, + name: "author", + filterType: "text", + _links: { + self: { + href: "https://dspace-coar.4science.cloud/server/api/discover/facets/author" + } + } + }); + mockPaginatedSearchOptions = new PaginatedSearchOptions({ + pagination: Object.assign(new PaginationComponentOptions(), { id: 'page-id', currentPage: 1, pageSize: 20 }), + configuration: '', + }); + + constructor(private searchService: SearchService, + @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService, + ) {} + + ngOnInit() { + this.searchService.getFacetValuesFor(this.mockFilterConfig, 1, this.mockPaginatedSearchOptions).subscribe(c => console.log(c)) + } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts index 0074d13ce0..ec6d63d8e1 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts @@ -1,18 +1,19 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; -import { SharedModule } from '../../shared/shared.module'; -import { AdminNotifyDashboardComponent } from "./admin-notify-dashboard.component"; -import { AdminNotifyDashboardRoutingModule } from "./admin-notify-dashboard-routing.module"; +import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; +import { AdminNotifyDashboardRoutingModule } from './admin-notify-dashboard-routing.module'; import { AdminNotifyMetricsComponent } from './admin-notify-metrics/admin-notify-metrics.component'; import { AdminNotifyLogsComponent } from './admin-notify-logs/admin-notify-logs.component'; +import { SharedModule } from '../../shared/shared.module'; + @NgModule({ imports: [ CommonModule, - SharedModule, RouterModule, - AdminNotifyDashboardRoutingModule, + SharedModule, + AdminNotifyDashboardRoutingModule ], declarations: [ AdminNotifyDashboardComponent, diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts index 12a0feae64..b1f89a4f76 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyLogsComponent } from './admin-notify-logs.component'; +import { TranslateModule } from '@ngx-translate/core'; describe('AdminNotifyLogsComponent', () => { let component: AdminNotifyLogsComponent; @@ -8,6 +9,7 @@ describe('AdminNotifyLogsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], declarations: [ AdminNotifyLogsComponent ] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.html index f4e0e45279..c3ba6364dc 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.html @@ -1,11 +1,9 @@ -
-
-
-
- -
0
-
{{ box.title | translate }}
-
+
+
{{ row.title | translate }}
+
+
+
+ diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.spec.ts index 10e256a701..bf3a86ec2e 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyMetricsComponent } from './admin-notify-metrics.component'; +import { TranslateModule } from '@ngx-translate/core'; describe('AdminNotifyMetricsComponent', () => { let component: AdminNotifyMetricsComponent; @@ -8,6 +9,7 @@ describe('AdminNotifyMetricsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], declarations: [ AdminNotifyMetricsComponent ] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts index d1d7ca4bd5..bea0f654ec 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; -import { AdminNotifyMetricsRow } from "./admin-notify-metrics.model"; -import { AdminNotifyMetricsRowsConfig } from "./admin-notify-metrics.config"; +import { AdminNotifyMetricsRow } from './admin-notify-metrics.model'; +import { AdminNotifyMetricsRowsConfig } from './admin-notify-metrics.config'; @Component({ selector: 'ds-admin-notify-metrics', diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts index 7880e78ebf..6406f91d0b 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts @@ -1,33 +1,29 @@ -import { AdminNotifyMetricsRow } from "./admin-notify-metrics.model"; +import { AdminNotifyMetricsRow } from './admin-notify-metrics.model'; export const AdminNotifyMetricsRowsConfig: AdminNotifyMetricsRow[] = [ { title: 'Number of received LDN', boxes: [ { - color: 'blue', + color: '#B8DAFF', title: 'Accepted', - index: 0 }, { - color: 'green', + color: '#D4EDDA', title: 'Processed LDN', - index: 1 }, { - color: 'red', + color: '#FDBBC7', title: 'Failure', - index: 2 }, { - color: 'red', + color: '#FDBBC7', title: 'Untrusted', - index: 3 }, { - color: 'grey', + color: '#43515F', title: 'Incoming LDM messages', - index: 4 + textColor: '#fff' }, ] }, @@ -35,30 +31,26 @@ export const AdminNotifyMetricsRowsConfig: AdminNotifyMetricsRow[] = [ title: 'Number of generated LDN', boxes: [ { - color: 'green', + color: '#D4EDDA', title: 'Delivered', - index: 0 }, { - color: 'blue', + color: '#B8DAFF', title: 'Queued', - index: 1 }, { - color: 'yellow', + color: '#FDEEBB', title: 'Queued for retry', - index: 2 }, { - color: 'red', + color: '#FDBBC7', title: 'Failure', - index: 3 }, { - color: 'grey', + color: '#43515F', title: 'Outgoing LDM messages', - index: 4 + textColor: '#fff' }, ] } -] +]; diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts index 3b47deffa1..6fb673575c 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts @@ -1,7 +1,8 @@ export interface AdminNotifyMetricsBox { color: string; + textColor?: string; title: string; - index: number + count?: number } export interface AdminNotifyMetricsRow { diff --git a/src/app/admin/admin-routing.module.ts b/src/app/admin/admin-routing.module.ts index e30a5b20fb..801b698d56 100644 --- a/src/app/admin/admin-routing.module.ts +++ b/src/app/admin/admin-routing.module.ts @@ -13,7 +13,6 @@ import { NOTIFY_DASHBOARD_MODULE_PATH } from './admin-routing-paths'; import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component'; -import { AdminNotifyDashboardComponent } from "./admin-notify-dashboard/admin-notify-dashboard.component"; @NgModule({ imports: [ diff --git a/src/app/shared/notification-box/notification-box.component.html b/src/app/shared/notification-box/notification-box.component.html new file mode 100644 index 0000000000..1c83717f96 --- /dev/null +++ b/src/app/shared/notification-box/notification-box.component.html @@ -0,0 +1,6 @@ +
+
+
{{ boxConfig.count ?? 0 }}
+
{{ boxConfig.title | translate }}
+
+
diff --git a/src/app/shared/notification-box/notification-box.component.scss b/src/app/shared/notification-box/notification-box.component.scss new file mode 100644 index 0000000000..9813f4aa7a --- /dev/null +++ b/src/app/shared/notification-box/notification-box.component.scss @@ -0,0 +1,7 @@ +.box-container { + min-width: max-content; +} +.box-counter { + font-size: calc(var(--bs-font-size-lg) * 1.5); +} + diff --git a/src/app/shared/notification-box/notification-box.component.spec.ts b/src/app/shared/notification-box/notification-box.component.spec.ts new file mode 100644 index 0000000000..2e4346dba6 --- /dev/null +++ b/src/app/shared/notification-box/notification-box.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NotificationBoxComponent } from './notification-box.component'; + +describe('NotificationBoxComponent', () => { + let component: NotificationBoxComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ NotificationBoxComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(NotificationBoxComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/notification-box/notification-box.component.ts b/src/app/shared/notification-box/notification-box.component.ts new file mode 100644 index 0000000000..fc28620cc2 --- /dev/null +++ b/src/app/shared/notification-box/notification-box.component.ts @@ -0,0 +1,13 @@ +import { Component, Input } from '@angular/core'; +import { + AdminNotifyMetricsBox +} from "../../admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model"; + +@Component({ + selector: 'ds-notification-box', + templateUrl: './notification-box.component.html', + styleUrls: ['./notification-box.component.scss'] +}) +export class NotificationBoxComponent { + @Input() boxConfig: AdminNotifyMetricsBox; +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 7f59016f8c..61482fb61a 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -285,6 +285,7 @@ import { NgxPaginationModule } from 'ngx-pagination'; import { SplitPipe } from './utils/split.pipe'; import { ThemedUserMenuComponent } from './auth-nav-menu/user-menu/themed-user-menu.component'; import { ThemedLangSwitchComponent } from './lang-switch/themed-lang-switch.component'; +import { NotificationBoxComponent } from './notification-box/notification-box.component'; const MODULES = [ CommonModule, @@ -469,7 +470,8 @@ const ENTRY_COMPONENTS = [ AdvancedClaimedTaskActionRatingComponent, EpersonGroupListComponent, EpersonSearchBoxComponent, - GroupSearchBoxComponent + GroupSearchBoxComponent, + NotificationBoxComponent ]; const PROVIDERS = [ From e39e034329627e0fdf7ad4d429dedba285bd6a7c Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Thu, 28 Dec 2023 17:06:27 +0100 Subject: [PATCH 024/142] update config and integrate rest --- .../admin-notify-dashboard.component.html | 2 +- .../admin-notify-dashboard.component.ts | 50 ++++++-------- .../admin-notify-metrics.component.ts | 6 +- .../admin-notify-metrics.config.ts | 56 --------------- .../admin-notify-metrics.model.ts | 1 + src/config/app-config.interface.ts | 4 ++ src/config/default-app-config.ts | 68 +++++++++++++++++++ src/environments/environment.test.ts | 65 ++++++++++++++++++ 8 files changed, 161 insertions(+), 91 deletions(-) delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html index 4b432adb38..e366fbc909 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -8,7 +8,7 @@ {{'admin-notify-dashboard.metrics' | translate}}
- +
diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 56f5091969..abaf9f05b5 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -1,47 +1,35 @@ -import { Component, Inject, OnInit } from '@angular/core'; -import { SearchConfigurationService } from "../../core/shared/search/search-configuration.service"; +import { Component, OnInit } from '@angular/core'; import { SearchService } from "../../core/shared/search/search.service"; +import { environment } from "../../../environments/environment"; import { PaginatedSearchOptions } from "../../shared/search/models/paginated-search-options.model"; -import { SEARCH_CONFIG_SERVICE } from "../../my-dspace-page/my-dspace-page.component"; import { PaginationComponentOptions } from "../../shared/pagination/pagination-component-options.model"; -import { SearchFilterConfig } from "../../shared/search/models/search-filter-config.model"; +import { concatAll, concatWith, flatMap, forkJoin, from, mergeAll, switchMap } from "rxjs"; +import { concat, delay } from "rxjs/operators"; +import { getFirstSucceededRemoteData } from "../../core/shared/operators"; @Component({ selector: 'ds-admin-notify-dashboard', templateUrl: './admin-notify-dashboard.component.html', styleUrls: ['./admin-notify-dashboard.component.scss'], - providers: [ - { - provide: SEARCH_CONFIG_SERVICE, - useClass: SearchConfigurationService - } - ] }) export class AdminNotifyDashboardComponent implements OnInit{ - mockFilterConfig : SearchFilterConfig = Object.assign(new SearchFilterConfig(), { - type: { - value: "discovery-filter" - }, - pageSize: 10, - name: "author", - filterType: "text", - _links: { - self: { - href: "https://dspace-coar.4science.cloud/server/api/discover/facets/author" - } - } - }); - mockPaginatedSearchOptions = new PaginatedSearchOptions({ - pagination: Object.assign(new PaginationComponentOptions(), { id: 'page-id', currentPage: 1, pageSize: 20 }), - configuration: '', + metricsConfig = environment.notifyMetrics; + private singleResultOptions = Object.assign(new PaginationComponentOptions(), { + id: 'single-result-options', + pageSize: 1 }); - - constructor(private searchService: SearchService, - @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService, - ) {} + constructor(private searchService: SearchService) {} ngOnInit() { - this.searchService.getFacetValuesFor(this.mockFilterConfig, 1, this.mockPaginatedSearchOptions).subscribe(c => console.log(c)) + const discoveryConfigurations = this.metricsConfig + .map(row => row.boxes) + .map(boxes => boxes.map(box => box.config).filter(config => !!config)); + const mergedConfigurations = discoveryConfigurations[0].concat(discoveryConfigurations[1]); + const searchConfigurations = mergedConfigurations + .map(config => Object.assign(new PaginatedSearchOptions({}), + { configuration: config, pagination: this.singleResultOptions } + )); + // TODO: check for search completion before executing next one } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts index bea0f654ec..57f834f872 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts @@ -1,6 +1,5 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { AdminNotifyMetricsRow } from './admin-notify-metrics.model'; -import { AdminNotifyMetricsRowsConfig } from './admin-notify-metrics.config'; @Component({ selector: 'ds-admin-notify-metrics', @@ -9,5 +8,6 @@ import { AdminNotifyMetricsRowsConfig } from './admin-notify-metrics.config'; }) export class AdminNotifyMetricsComponent { - boxesConfig: AdminNotifyMetricsRow[] = AdminNotifyMetricsRowsConfig; + @Input() + boxesConfig: AdminNotifyMetricsRow[]; } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts deleted file mode 100644 index 6406f91d0b..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.config.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { AdminNotifyMetricsRow } from './admin-notify-metrics.model'; - -export const AdminNotifyMetricsRowsConfig: AdminNotifyMetricsRow[] = [ - { - title: 'Number of received LDN', - boxes: [ - { - color: '#B8DAFF', - title: 'Accepted', - }, - { - color: '#D4EDDA', - title: 'Processed LDN', - }, - { - color: '#FDBBC7', - title: 'Failure', - }, - { - color: '#FDBBC7', - title: 'Untrusted', - }, - { - color: '#43515F', - title: 'Incoming LDM messages', - textColor: '#fff' - }, - ] - }, - { - title: 'Number of generated LDN', - boxes: [ - { - color: '#D4EDDA', - title: 'Delivered', - }, - { - color: '#B8DAFF', - title: 'Queued', - }, - { - color: '#FDEEBB', - title: 'Queued for retry', - }, - { - color: '#FDBBC7', - title: 'Failure', - }, - { - color: '#43515F', - title: 'Outgoing LDM messages', - textColor: '#fff' - }, - ] - } -]; diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts index 6fb673575c..ab0f9cfa91 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts @@ -2,6 +2,7 @@ export interface AdminNotifyMetricsBox { color: string; textColor?: string; title: string; + config: string; count?: number } diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index e610257dbf..e3f2b40db4 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -23,6 +23,9 @@ import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; +import { + AdminNotifyMetricsRow +} from "../app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model"; interface AppConfig extends Config { ui: UIServerConfig; @@ -50,6 +53,7 @@ interface AppConfig extends Config { markdown: MarkdownConfig; vocabularies: FilterVocabularyConfig[]; comcolSelectionSort: DiscoverySortConfig; + notifyMetrics: AdminNotifyMetricsRow[]; } /** diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 6150e1ad02..22f9d8322d 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -23,6 +23,9 @@ import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; +import { + AdminNotifyMetricsRow +} from "../app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model"; export class DefaultAppConfig implements AppConfig { production = false; @@ -443,4 +446,69 @@ export class DefaultAppConfig implements AppConfig { sortField:'dc.title', sortDirection:'ASC', }; + + notifyMetrics: AdminNotifyMetricsRow[] = [ + { + title: 'Number of received LDN', + boxes: [ + { + color: '#B8DAFF', + title: 'Accepted', + config: 'NOTIFY.incoming.accepted' + }, + { + color: '#D4EDDA', + title: 'Processed LDN', + config: 'NOTIFY.incoming.processed' + }, + { + color: '#FDBBC7', + title: 'Failure', + config: 'NOTIFY.incoming.failure' + }, + { + color: '#FDBBC7', + title: 'Untrusted', + config: 'NOTIFY.incoming.untrusted' + }, + { + color: '#43515F', + title: 'Involved items', + textColor: '#fff', + config: '' + }, + ] + }, + { + title: 'Number of generated LDN', + boxes: [ + { + color: '#D4EDDA', + title: 'Delivered', + config: 'NOTIFY.outgoing.delivered' + }, + { + color: '#B8DAFF', + title: 'Queued', + config: 'NOTIFY.outgoing.queued' + }, + { + color: '#FDEEBB', + title: 'Queued for retry', + config: 'NOTIFY.outgoing.queued_for_retry' + }, + { + color: '#FDBBC7', + title: 'Failure', + config: 'NOTIFY.outgoing.failure' + }, + { + color: '#43515F', + title: 'Involved items', + textColor: '#fff', + config: '' + }, + ] + } + ] } diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 806a45fbd5..8858e95a2a 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -317,5 +317,70 @@ export const environment: BuildConfig = { vocabulary: 'srsc', enabled: true } + ], + + notifyMetrics: [ + { + title: 'Number of received LDN', + boxes: [ + { + color: '#B8DAFF', + title: 'Accepted', + config: 'NOTIFY.incoming.accepted' + }, + { + color: '#D4EDDA', + title: 'Processed LDN', + config: 'NOTIFY.incoming.processed' + }, + { + color: '#FDBBC7', + title: 'Failure', + config: 'NOTIFY.incoming.failure' + }, + { + color: '#FDBBC7', + title: 'Untrusted', + config: 'NOTIFY.incoming.untrusted' + }, + { + color: '#43515F', + title: 'Incoming LDM messages', + textColor: '#fff', + config: '' + }, + ] + }, + { + title: 'Number of generated LDN', + boxes: [ + { + color: '#D4EDDA', + title: 'Delivered', + config: 'NOTIFY.outgoing.delivered' + }, + { + color: '#B8DAFF', + title: 'Queued', + config: 'NOTIFY.outgoing.queued' + }, + { + color: '#FDEEBB', + title: 'Queued for retry', + config: 'NOTIFY.outgoing.queued_for_retry' + }, + { + color: '#FDBBC7', + title: 'Failure', + config: 'NOTIFY.outgoing.failure' + }, + { + color: '#43515F', + title: 'Outgoing LDM messages', + textColor: '#fff', + config: '' + }, + ] + } ] }; From fec6550cba8b0fefdfeb87d3c242a97f1c77db51 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 29 Dec 2023 11:45:13 +0100 Subject: [PATCH 025/142] finalize config and mapping --- .../admin-notify-dashboard.component.html | 2 +- .../admin-notify-dashboard.component.ts | 71 ++++++++++++++++--- ...dmin-notify-message-search-result.model.ts | 8 +++ .../models/admin-notify-message.model.ts | 31 ++++++++ .../admin-notify-message.resource-type.ts | 9 +++ src/app/core/core.module.ts | 2 + 6 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 src/app/admin/admin-notify-dashboard/models/admin-notify-message-search-result.model.ts create mode 100644 src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts create mode 100644 src/app/admin/admin-notify-dashboard/models/admin-notify-message.resource-type.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html index e366fbc909..2975fdde9c 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -8,7 +8,7 @@ {{'admin-notify-dashboard.metrics' | translate}}
- +
diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index abaf9f05b5..b4e03d5ec7 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -3,10 +3,21 @@ import { SearchService } from "../../core/shared/search/search.service"; import { environment } from "../../../environments/environment"; import { PaginatedSearchOptions } from "../../shared/search/models/paginated-search-options.model"; import { PaginationComponentOptions } from "../../shared/pagination/pagination-component-options.model"; -import { concatAll, concatWith, flatMap, forkJoin, from, mergeAll, switchMap } from "rxjs"; -import { concat, delay } from "rxjs/operators"; -import { getFirstSucceededRemoteData } from "../../core/shared/operators"; +import { + listableObjectComponent +} from "../../shared/object-collection/shared/listable-object/listable-object.decorator"; +import { ViewMode } from "../../core/shared/view-mode.model"; +import { Context } from "../../core/shared/context.model"; +import { AdminNotifySearchResult } from "./models/admin-notify-message-search-result.model"; +import { forkJoin, Observable } from "rxjs"; +import { getFirstCompletedRemoteData } from "../../core/shared/operators"; +import { map } from "rxjs/operators"; +import { SearchObjects } from "../../shared/search/models/search-objects.model"; +import { AdminNotifyMetricsBox, AdminNotifyMetricsRow } from "./admin-notify-metrics/admin-notify-metrics.model"; +import { DSpaceObject } from "../../core/shared/dspace-object.model"; + +@listableObjectComponent(AdminNotifySearchResult, ViewMode.GridElement, Context.AdminSearch) @Component({ selector: 'ds-admin-notify-dashboard', templateUrl: './admin-notify-dashboard.component.html', @@ -14,7 +25,9 @@ import { getFirstSucceededRemoteData } from "../../core/shared/operators"; }) export class AdminNotifyDashboardComponent implements OnInit{ - metricsConfig = environment.notifyMetrics; + public notifyMetricsRows$: Observable + + private metricsConfig = environment.notifyMetrics; private singleResultOptions = Object.assign(new PaginationComponentOptions(), { id: 'single-result-options', pageSize: 1 @@ -22,14 +35,56 @@ export class AdminNotifyDashboardComponent implements OnInit{ constructor(private searchService: SearchService) {} ngOnInit() { - const discoveryConfigurations = this.metricsConfig + const mertricsRowsConfigurations = this.metricsConfig .map(row => row.boxes) .map(boxes => boxes.map(box => box.config).filter(config => !!config)); - const mergedConfigurations = discoveryConfigurations[0].concat(discoveryConfigurations[1]); - const searchConfigurations = mergedConfigurations + const flatConfigurations = [].concat(...mertricsRowsConfigurations.map((config) => config)); + const searchConfigurations = flatConfigurations .map(config => Object.assign(new PaginatedSearchOptions({}), { configuration: config, pagination: this.singleResultOptions } )); - // TODO: check for search completion before executing next one + + this.notifyMetricsRows$ = forkJoin(searchConfigurations.map(config => this.searchService.search(config) + .pipe( + getFirstCompletedRemoteData(), + map(response => this.mapSearchObjectsToMetricsBox(response.payload)), + ) + ) + ).pipe( + map(metricBoxes => this.mapUpdatedBoxesToMetricsRows(metricBoxes)) + ) + } + + /** + * Function to map received SearchObjects to notify boxes config + * + * @param searchObject The object to map + * @private + */ + private mapSearchObjectsToMetricsBox(searchObject: SearchObjects) : AdminNotifyMetricsBox { + const objectConfig = searchObject.configuration; + const count = searchObject.pageInfo.totalElements; + const metricsBoxes = [].concat(...this.metricsConfig.map((config) => config.boxes)); + + return { + ...metricsBoxes.find(box => box.config === objectConfig), + count + } + } + + /** + * Function to map updated boxes with count to each row of the configuration + * + * @param boxes The object to map + * @private + */ + private mapUpdatedBoxesToMetricsRows(boxes: AdminNotifyMetricsBox[]) : AdminNotifyMetricsRow[] { + return this.metricsConfig.map(row => { + return { + ...row, + boxes: row.boxes.map(box => boxes.find(boxWithCount => boxWithCount.config === box.config)) + .filter(box => !!box) + } + }) } } diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message-search-result.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message-search-result.model.ts new file mode 100644 index 0000000000..254151ce76 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message-search-result.model.ts @@ -0,0 +1,8 @@ +import { AdminNotifyMessage } from "./admin-notify-message.model"; +import { searchResultFor } from "../../../shared/search/search-result-element-decorator"; +import { SearchResult } from "../../../shared/search/models/search-result.model"; + + +@searchResultFor(AdminNotifyMessage) +export class AdminNotifySearchResult extends SearchResult { +} diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts new file mode 100644 index 0000000000..440c084d0f --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -0,0 +1,31 @@ +import { deserialize, inheritSerialization } from 'cerialize'; +import { typedObject } from "../../../core/cache/builders/build-decorators"; +import { ADMIN_NOTIFY_MESSAGE } from "./admin-notify-message.resource-type"; +import { excludeFromEquals } from "../../../core/utilities/equals.decorators"; +import { DSpaceObject } from "../../../core/shared/dspace-object.model"; + +/** + * A message that includes admin notify info + */ +@typedObject +@inheritSerialization(DSpaceObject) +export class AdminNotifyMessage extends DSpaceObject { + static type = ADMIN_NOTIFY_MESSAGE; + + /** + * The type of the message + */ + @excludeFromEquals + type = ADMIN_NOTIFY_MESSAGE; + + @deserialize + _links: { + self: { + href: string; + }; + }; + + get self(): string { + return this._links.self.href; + } +} diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.resource-type.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.resource-type.ts new file mode 100644 index 0000000000..f8d7c4d1f6 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.resource-type.ts @@ -0,0 +1,9 @@ +import { ResourceType } from "../../../core/shared/resource-type"; + +/** + * The resource type for AdminNotifyMessage + * + * Needs to be in a separate file to prevent circular + * dependencies in webpack. + */ +export const ADMIN_NOTIFY_MESSAGE = new ResourceType('message'); diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index eef4f1f68e..728419c574 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -197,6 +197,7 @@ import { import { SubmissionCoarNotifyConfig } from '../submission/sections/section-coar-notify/submission-coar-notify.config'; import { NotifyRequestsStatus } from '../item-page/simple/notify-requests-status/notify-requests-status.model'; import { NotifyRequestsStatusDataService } from './data/notify-services-status-data.service'; +import { AdminNotifyMessage } from "../admin/admin-notify-dashboard/models/admin-notify-message.model"; /** @@ -410,6 +411,7 @@ export const models = Itemfilter, SubmissionCoarNotifyConfig, NotifyRequestsStatus, + AdminNotifyMessage ]; @NgModule({ From 01a41570d630e103c3f24962efa206956baaf837 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 29 Dec 2023 12:23:45 +0100 Subject: [PATCH 026/142] fix lint, fix aggregate count, add translations --- .../admin-notify-dashboard.component.html | 2 +- .../admin-notify-dashboard.component.ts | 67 ++++++++++++------- .../admin-notify-logs.component.html | 1 - .../admin-notify-metrics.model.ts | 3 +- ...dmin-notify-message-search-result.model.ts | 6 +- .../models/admin-notify-message.model.ts | 8 +-- .../admin-notify-message.resource-type.ts | 2 +- src/app/core/core.module.ts | 2 +- .../notification-box.component.ts | 2 +- src/assets/i18n/en.json5 | 20 ++++++ src/config/app-config.interface.ts | 2 +- src/config/default-app-config.ts | 34 +++++----- src/environments/environment.test.ts | 30 +++++---- 13 files changed, 110 insertions(+), 69 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html index 2975fdde9c..2402583c61 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -8,7 +8,7 @@ {{'admin-notify-dashboard.metrics' | translate}}
- +
diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index b4e03d5ec7..1307974fc9 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -1,20 +1,20 @@ import { Component, OnInit } from '@angular/core'; -import { SearchService } from "../../core/shared/search/search.service"; -import { environment } from "../../../environments/environment"; -import { PaginatedSearchOptions } from "../../shared/search/models/paginated-search-options.model"; -import { PaginationComponentOptions } from "../../shared/pagination/pagination-component-options.model"; +import { SearchService } from '../../core/shared/search/search.service'; +import { environment } from '../../../environments/environment'; +import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; +import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { listableObjectComponent -} from "../../shared/object-collection/shared/listable-object/listable-object.decorator"; -import { ViewMode } from "../../core/shared/view-mode.model"; -import { Context } from "../../core/shared/context.model"; -import { AdminNotifySearchResult } from "./models/admin-notify-message-search-result.model"; -import { forkJoin, Observable } from "rxjs"; -import { getFirstCompletedRemoteData } from "../../core/shared/operators"; -import { map } from "rxjs/operators"; -import { SearchObjects } from "../../shared/search/models/search-objects.model"; -import { AdminNotifyMetricsBox, AdminNotifyMetricsRow } from "./admin-notify-metrics/admin-notify-metrics.model"; -import { DSpaceObject } from "../../core/shared/dspace-object.model"; +} from '../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { ViewMode } from '../../core/shared/view-mode.model'; +import { Context } from '../../core/shared/context.model'; +import { AdminNotifySearchResult } from './models/admin-notify-message-search-result.model'; +import { forkJoin, Observable } from 'rxjs'; +import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { map } from 'rxjs/operators'; +import { SearchObjects } from '../../shared/search/models/search-objects.model'; +import { AdminNotifyMetricsBox, AdminNotifyMetricsRow } from './admin-notify-metrics/admin-notify-metrics.model'; +import { DSpaceObject } from '../../core/shared/dspace-object.model'; @listableObjectComponent(AdminNotifySearchResult, ViewMode.GridElement, Context.AdminSearch) @@ -25,7 +25,7 @@ import { DSpaceObject } from "../../core/shared/dspace-object.model"; }) export class AdminNotifyDashboardComponent implements OnInit{ - public notifyMetricsRows$: Observable + public notifyMetricsRows$: Observable; private metricsConfig = environment.notifyMetrics; private singleResultOptions = Object.assign(new PaginationComponentOptions(), { @@ -52,7 +52,7 @@ export class AdminNotifyDashboardComponent implements OnInit{ ) ).pipe( map(metricBoxes => this.mapUpdatedBoxesToMetricsRows(metricBoxes)) - ) + ); } /** @@ -61,30 +61,47 @@ export class AdminNotifyDashboardComponent implements OnInit{ * @param searchObject The object to map * @private */ - private mapSearchObjectsToMetricsBox(searchObject: SearchObjects) : AdminNotifyMetricsBox { - const objectConfig = searchObject.configuration; + private mapSearchObjectsToMetricsBox(searchObject: SearchObjects): AdminNotifyMetricsBox { const count = searchObject.pageInfo.totalElements; + const objectConfig = searchObject.configuration; const metricsBoxes = [].concat(...this.metricsConfig.map((config) => config.boxes)); return { ...metricsBoxes.find(box => box.config === objectConfig), count - } + }; } /** * Function to map updated boxes with count to each row of the configuration * - * @param boxes The object to map + * @param boxesWithCount The object to map * @private */ - private mapUpdatedBoxesToMetricsRows(boxes: AdminNotifyMetricsBox[]) : AdminNotifyMetricsRow[] { + private mapUpdatedBoxesToMetricsRows(boxesWithCount: AdminNotifyMetricsBox[]): AdminNotifyMetricsRow[] { return this.metricsConfig.map(row => { return { ...row, - boxes: row.boxes.map(box => boxes.find(boxWithCount => boxWithCount.config === box.config)) - .filter(box => !!box) - } - }) + boxes: row.boxes.map(rowBox => { + if (rowBox.isRowAggregateCount) { + const currentRowBoxesWithCount = row.boxes.filter(box => !box.isRowAggregateCount) + .map(notAggregateBox => { + return { + ...notAggregateBox, + count: boxesWithCount.find(boxWithCount => boxWithCount.config === notAggregateBox.config)?.count + } + }) + return { + ...rowBox, + count: currentRowBoxesWithCount.map(box => box.count).reduce((accumulator, currentValue) => { + return accumulator + currentValue; + },0) + }; + } else { + return boxesWithCount.find(boxWithCount => boxWithCount.config === rowBox.config); + } + }) + }; + }); } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html index 494e082ddf..e69de29bb2 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html @@ -1 +0,0 @@ -

admin-notify-logs works!

diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts index ab0f9cfa91..190d14df0a 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts @@ -3,7 +3,8 @@ export interface AdminNotifyMetricsBox { textColor?: string; title: string; config: string; - count?: number + count?: number; + isRowAggregateCount?: boolean; } export interface AdminNotifyMetricsRow { diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message-search-result.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message-search-result.model.ts index 254151ce76..236a564f20 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message-search-result.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message-search-result.model.ts @@ -1,6 +1,6 @@ -import { AdminNotifyMessage } from "./admin-notify-message.model"; -import { searchResultFor } from "../../../shared/search/search-result-element-decorator"; -import { SearchResult } from "../../../shared/search/models/search-result.model"; +import { AdminNotifyMessage } from './admin-notify-message.model'; +import { searchResultFor } from '../../../shared/search/search-result-element-decorator'; +import { SearchResult } from '../../../shared/search/models/search-result.model'; @searchResultFor(AdminNotifyMessage) diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts index 440c084d0f..d0047ec392 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -1,8 +1,8 @@ import { deserialize, inheritSerialization } from 'cerialize'; -import { typedObject } from "../../../core/cache/builders/build-decorators"; -import { ADMIN_NOTIFY_MESSAGE } from "./admin-notify-message.resource-type"; -import { excludeFromEquals } from "../../../core/utilities/equals.decorators"; -import { DSpaceObject } from "../../../core/shared/dspace-object.model"; +import { typedObject } from '../../../core/cache/builders/build-decorators'; +import { ADMIN_NOTIFY_MESSAGE } from './admin-notify-message.resource-type'; +import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; +import { DSpaceObject } from '../../../core/shared/dspace-object.model'; /** * A message that includes admin notify info diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.resource-type.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.resource-type.ts index f8d7c4d1f6..994146adb3 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.resource-type.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.resource-type.ts @@ -1,4 +1,4 @@ -import { ResourceType } from "../../../core/shared/resource-type"; +import { ResourceType } from '../../../core/shared/resource-type'; /** * The resource type for AdminNotifyMessage diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 728419c574..fd0ff1e39c 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -197,7 +197,7 @@ import { import { SubmissionCoarNotifyConfig } from '../submission/sections/section-coar-notify/submission-coar-notify.config'; import { NotifyRequestsStatus } from '../item-page/simple/notify-requests-status/notify-requests-status.model'; import { NotifyRequestsStatusDataService } from './data/notify-services-status-data.service'; -import { AdminNotifyMessage } from "../admin/admin-notify-dashboard/models/admin-notify-message.model"; +import { AdminNotifyMessage } from '../admin/admin-notify-dashboard/models/admin-notify-message.model'; /** diff --git a/src/app/shared/notification-box/notification-box.component.ts b/src/app/shared/notification-box/notification-box.component.ts index fc28620cc2..899d55cd74 100644 --- a/src/app/shared/notification-box/notification-box.component.ts +++ b/src/app/shared/notification-box/notification-box.component.ts @@ -1,7 +1,7 @@ import { Component, Input } from '@angular/core'; import { AdminNotifyMetricsBox -} from "../../admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model"; +} from '../../admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model'; @Component({ selector: 'ds-notification-box', diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 0acbba29c7..fa5326c92c 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3449,6 +3449,26 @@ "admin-notify-dashboard.logs": "Notify logs", + "admin-notify-dashboard.received-ldn": "Number of received LDN", + + "admin-notify-dashboard.generated-ldn": "Number of generated LDN", + + "admin-notify-dashboard.accepted": "Accepted", + + "admin-notify-dashboard.processed": "Processed LDN", + + "admin-notify-dashboard.failure": "Failure", + + "admin-notify-dashboard.untrusted": "Untrusted", + + "admin-notify-dashboard.delivered": "Delivered", + + "admin-notify-dashboard.queued": "Queued", + + "admin-notify-dashboard.queued-for-retry": "Queued for retry", + + "admin-notify-dashboard.involved-items": "Involved items", + "admin.notify.dashboard.breadcrumbs": "Dashboard", "orgunit.listelement.badge": "Organizational Unit", diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index e3f2b40db4..c2433272f5 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -25,7 +25,7 @@ import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; import { AdminNotifyMetricsRow -} from "../app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model"; +} from '../app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model'; interface AppConfig extends Config { ui: UIServerConfig; diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 22f9d8322d..3b8717ba86 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -25,7 +25,7 @@ import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; import { AdminNotifyMetricsRow -} from "../app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model"; +} from '../app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model'; export class DefaultAppConfig implements AppConfig { production = false; @@ -449,66 +449,68 @@ export class DefaultAppConfig implements AppConfig { notifyMetrics: AdminNotifyMetricsRow[] = [ { - title: 'Number of received LDN', + title: 'admin-notify-dashboard.received-ldn', boxes: [ { color: '#B8DAFF', - title: 'Accepted', + title: 'admin-notify-dashboard.accepted', config: 'NOTIFY.incoming.accepted' }, { color: '#D4EDDA', - title: 'Processed LDN', + title: 'admin-notify-dashboard.processed', config: 'NOTIFY.incoming.processed' }, { color: '#FDBBC7', - title: 'Failure', + title: 'admin-notify-dashboard.failure', config: 'NOTIFY.incoming.failure' }, { color: '#FDBBC7', - title: 'Untrusted', + title: 'admin-notify-dashboard.untrusted', config: 'NOTIFY.incoming.untrusted' }, { color: '#43515F', - title: 'Involved items', + title: 'admin-notify-dashboard.involved-items', textColor: '#fff', - config: '' + config: '', + isRowAggregateCount: true }, ] }, { - title: 'Number of generated LDN', + title: 'admin-notify-dashboard.generated-ldn', boxes: [ { color: '#D4EDDA', - title: 'Delivered', + title: 'admin-notify-dashboard.delivered', config: 'NOTIFY.outgoing.delivered' }, { color: '#B8DAFF', - title: 'Queued', + title: 'admin-notify-dashboard.queued', config: 'NOTIFY.outgoing.queued' }, { color: '#FDEEBB', - title: 'Queued for retry', + title: 'admin-notify-dashboard.queued-for-retry', config: 'NOTIFY.outgoing.queued_for_retry' }, { color: '#FDBBC7', - title: 'Failure', + title: 'admin-notify-dashboard.failure', config: 'NOTIFY.outgoing.failure' }, { color: '#43515F', - title: 'Involved items', + title: 'admin-notify-dashboard.involved-items', textColor: '#fff', - config: '' + config: '', + isRowAggregateCount: true }, ] } - ] + ]; } diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 8858e95a2a..165b311de8 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -321,64 +321,66 @@ export const environment: BuildConfig = { notifyMetrics: [ { - title: 'Number of received LDN', + title: 'admin-notify-dashboard.received-ldn', boxes: [ { color: '#B8DAFF', - title: 'Accepted', + title: 'admin-notify-dashboard.accepted', config: 'NOTIFY.incoming.accepted' }, { color: '#D4EDDA', - title: 'Processed LDN', + title: 'admin-notify-dashboard.processed', config: 'NOTIFY.incoming.processed' }, { color: '#FDBBC7', - title: 'Failure', + title: 'admin-notify-dashboard.failure', config: 'NOTIFY.incoming.failure' }, { color: '#FDBBC7', - title: 'Untrusted', + title: 'admin-notify-dashboard.untrusted', config: 'NOTIFY.incoming.untrusted' }, { color: '#43515F', - title: 'Incoming LDM messages', + title: 'admin-notify-dashboard.involved-items', textColor: '#fff', - config: '' + config: '', + isRowAggregateCount: true }, ] }, { - title: 'Number of generated LDN', + title: 'admin-notify-dashboard.generated-ldn', boxes: [ { color: '#D4EDDA', - title: 'Delivered', + title: 'admin-notify-dashboard.delivered', config: 'NOTIFY.outgoing.delivered' }, { color: '#B8DAFF', - title: 'Queued', + title: 'admin-notify-dashboard.queued', config: 'NOTIFY.outgoing.queued' }, { color: '#FDEEBB', - title: 'Queued for retry', + title: 'admin-notify-dashboard.queued-for-retry', config: 'NOTIFY.outgoing.queued_for_retry' }, { color: '#FDBBC7', - title: 'Failure', + title: 'admin-notify-dashboard.failure', config: 'NOTIFY.outgoing.failure' }, { color: '#43515F', - title: 'Outgoing LDM messages', + title: 'admin-notify-dashboard.involved-items', textColor: '#fff', - config: '' + config: '', + isRowAggregateCount: true }, ] } From a43cb352fd8df72e38bedabfbfe34099a53728e5 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 29 Dec 2023 12:25:54 +0100 Subject: [PATCH 027/142] fix lint --- .../admin-notify-dashboard.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 1307974fc9..e25a5688a9 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -89,8 +89,8 @@ export class AdminNotifyDashboardComponent implements OnInit{ return { ...notAggregateBox, count: boxesWithCount.find(boxWithCount => boxWithCount.config === notAggregateBox.config)?.count - } - }) + }; + }); return { ...rowBox, count: currentRowBoxesWithCount.map(box => box.count).reduce((accumulator, currentValue) => { From 6a41dce3be037a241af912bf9027bd4e8de4b116 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 29 Dec 2023 12:45:47 +0100 Subject: [PATCH 028/142] fix tests --- .../admin-notify-dashboard.component.spec.ts | 24 ++++++++++++++++++- .../admin-notify-dashboard.component.ts | 1 + .../notification-box.component.spec.ts | 14 +++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts index c5afaa3b59..47ff2b2fde 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts @@ -3,15 +3,37 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; import { TranslateModule } from '@ngx-translate/core'; import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; +import { SearchService } from "../../core/shared/search/search.service"; +import { createSuccessfulRemoteDataObject$ } from "../../shared/remote-data.utils"; +import { buildPaginatedList } from "../../core/data/paginated-list.model"; +import { AdminNotifySearchResult } from "./models/admin-notify-message-search-result.model"; +import { AdminNotifyMessage } from "./models/admin-notify-message.model"; describe('AdminNotifyDashboardComponent', () => { let component: AdminNotifyDashboardComponent; let fixture: ComponentFixture; + let item1; + let item2; + let item3; + let searchResult1; + let searchResult2; + let searchResult3; + let results; + beforeEach(async () => { + item1 = Object.assign(new AdminNotifyMessage(), { uuid: 'e1c51c69-896d-42dc-8221-1d5f2ad5516e' }); + item2 = Object.assign(new AdminNotifyMessage(), { uuid: 'c8279647-1acc-41ae-b036-951d5f65649b' }); + item3 = Object.assign(new AdminNotifyMessage(), { uuid: 'c3bcbff5-ec0c-4831-8e4c-94b9c933ccac' }); + searchResult1 = Object.assign(new AdminNotifySearchResult(), { indexableObject: item1 }); + searchResult2 = Object.assign(new AdminNotifySearchResult(), { indexableObject: item2 }); + searchResult3 = Object.assign(new AdminNotifySearchResult(), { indexableObject: item3 }); + results = buildPaginatedList(undefined, [searchResult1, searchResult2, searchResult3]); + await TestBed.configureTestingModule({ imports: [TranslateModule.forRoot(), NgbNavModule], - declarations: [ AdminNotifyDashboardComponent ] + declarations: [ AdminNotifyDashboardComponent ], + providers: [{ provide: SearchService, useValue: { search: () => createSuccessfulRemoteDataObject$(results)}}] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index e25a5688a9..a03333d276 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -83,6 +83,7 @@ export class AdminNotifyDashboardComponent implements OnInit{ return { ...row, boxes: row.boxes.map(rowBox => { + // TODO remove aggregate once rest is updated if (rowBox.isRowAggregateCount) { const currentRowBoxesWithCount = row.boxes.filter(box => !box.isRowAggregateCount) .map(notAggregateBox => { diff --git a/src/app/shared/notification-box/notification-box.component.spec.ts b/src/app/shared/notification-box/notification-box.component.spec.ts index 2e4346dba6..99070740e4 100644 --- a/src/app/shared/notification-box/notification-box.component.spec.ts +++ b/src/app/shared/notification-box/notification-box.component.spec.ts @@ -1,19 +1,33 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NotificationBoxComponent } from './notification-box.component'; +import { TranslateModule } from "@ngx-translate/core"; +import { + AdminNotifyMetricsBox +} from "../../admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model"; describe('NotificationBoxComponent', () => { let component: NotificationBoxComponent; let fixture: ComponentFixture; + let mockBoxConfig: AdminNotifyMetricsBox; beforeEach(async () => { + mockBoxConfig = { + "color": "#D4EDDA", + "title": "admin-notify-dashboard.delivered", + "config": "NOTIFY.outgoing.delivered", + "count": 79 + } + await TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], declarations: [ NotificationBoxComponent ] }) .compileComponents(); fixture = TestBed.createComponent(NotificationBoxComponent); component = fixture.componentInstance; + component.boxConfig = mockBoxConfig; fixture.detectChanges(); }); From 055cc50cfb77000f551baa075264b8a8e4a37b7b Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 29 Dec 2023 12:49:31 +0100 Subject: [PATCH 029/142] reduce inner space --- src/app/shared/notification-box/notification-box.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/notification-box/notification-box.component.html b/src/app/shared/notification-box/notification-box.component.html index 1c83717f96..924db37d9d 100644 --- a/src/app/shared/notification-box/notification-box.component.html +++ b/src/app/shared/notification-box/notification-box.component.html @@ -1,6 +1,6 @@
-
{{ boxConfig.count ?? 0 }}
+
{{ boxConfig.count ?? 0 }}
{{ boxConfig.title | translate }}
From cd4b6a416989c3aa62232ee24a507bb5a61532fd Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 29 Dec 2023 15:09:37 +0100 Subject: [PATCH 030/142] refactor, align config with rest --- .../admin-notify-dashboard.component.ts | 21 +------------------ .../admin-notify-metrics.model.ts | 1 - src/config/default-app-config.ts | 6 ++---- src/environments/environment.test.ts | 6 ++---- 4 files changed, 5 insertions(+), 29 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index a03333d276..71be6424df 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -82,26 +82,7 @@ export class AdminNotifyDashboardComponent implements OnInit{ return this.metricsConfig.map(row => { return { ...row, - boxes: row.boxes.map(rowBox => { - // TODO remove aggregate once rest is updated - if (rowBox.isRowAggregateCount) { - const currentRowBoxesWithCount = row.boxes.filter(box => !box.isRowAggregateCount) - .map(notAggregateBox => { - return { - ...notAggregateBox, - count: boxesWithCount.find(boxWithCount => boxWithCount.config === notAggregateBox.config)?.count - }; - }); - return { - ...rowBox, - count: currentRowBoxesWithCount.map(box => box.count).reduce((accumulator, currentValue) => { - return accumulator + currentValue; - },0) - }; - } else { - return boxesWithCount.find(boxWithCount => boxWithCount.config === rowBox.config); - } - }) + boxes: row.boxes.map(rowBox =>boxesWithCount.find(boxWithCount => boxWithCount.config === rowBox.config)) }; }); } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts index 190d14df0a..bbceb10c20 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model.ts @@ -4,7 +4,6 @@ export interface AdminNotifyMetricsBox { title: string; config: string; count?: number; - isRowAggregateCount?: boolean; } export interface AdminNotifyMetricsRow { diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 3b8717ba86..12a99397d5 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -475,8 +475,7 @@ export class DefaultAppConfig implements AppConfig { color: '#43515F', title: 'admin-notify-dashboard.involved-items', textColor: '#fff', - config: '', - isRowAggregateCount: true + config: 'NOTIFY.incoming.involvedItems', }, ] }, @@ -507,8 +506,7 @@ export class DefaultAppConfig implements AppConfig { color: '#43515F', title: 'admin-notify-dashboard.involved-items', textColor: '#fff', - config: '', - isRowAggregateCount: true + config: 'NOTIFY.outgoing.involvedItems', }, ] } diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 165b311de8..de07503343 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -347,8 +347,7 @@ export const environment: BuildConfig = { color: '#43515F', title: 'admin-notify-dashboard.involved-items', textColor: '#fff', - config: '', - isRowAggregateCount: true + config: 'NOTIFY.incoming.involvedItems', }, ] }, @@ -379,8 +378,7 @@ export const environment: BuildConfig = { color: '#43515F', title: 'admin-notify-dashboard.involved-items', textColor: '#fff', - config: '', - isRowAggregateCount: true + config: 'NOTIFY.outgoing.involvedItems', }, ] } From 664dd855ea7a74c38d4cfc05121eef3bc1d018b8 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 29 Dec 2023 15:19:03 +0100 Subject: [PATCH 031/142] fix lint --- .../admin-notify-dashboard.component.spec.ts | 10 +++++----- .../notification-box.component.spec.ts | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts index 47ff2b2fde..51486024a9 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.spec.ts @@ -3,11 +3,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; import { TranslateModule } from '@ngx-translate/core'; import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; -import { SearchService } from "../../core/shared/search/search.service"; -import { createSuccessfulRemoteDataObject$ } from "../../shared/remote-data.utils"; -import { buildPaginatedList } from "../../core/data/paginated-list.model"; -import { AdminNotifySearchResult } from "./models/admin-notify-message-search-result.model"; -import { AdminNotifyMessage } from "./models/admin-notify-message.model"; +import { SearchService } from '../../core/shared/search/search.service'; +import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { buildPaginatedList } from '../../core/data/paginated-list.model'; +import { AdminNotifySearchResult } from './models/admin-notify-message-search-result.model'; +import { AdminNotifyMessage } from './models/admin-notify-message.model'; describe('AdminNotifyDashboardComponent', () => { let component: AdminNotifyDashboardComponent; diff --git a/src/app/shared/notification-box/notification-box.component.spec.ts b/src/app/shared/notification-box/notification-box.component.spec.ts index 99070740e4..a4118f81e3 100644 --- a/src/app/shared/notification-box/notification-box.component.spec.ts +++ b/src/app/shared/notification-box/notification-box.component.spec.ts @@ -1,10 +1,10 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NotificationBoxComponent } from './notification-box.component'; -import { TranslateModule } from "@ngx-translate/core"; +import { TranslateModule } from '@ngx-translate/core'; import { AdminNotifyMetricsBox -} from "../../admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model"; +} from '../../admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model'; describe('NotificationBoxComponent', () => { let component: NotificationBoxComponent; @@ -13,11 +13,11 @@ describe('NotificationBoxComponent', () => { beforeEach(async () => { mockBoxConfig = { - "color": "#D4EDDA", - "title": "admin-notify-dashboard.delivered", - "config": "NOTIFY.outgoing.delivered", - "count": 79 - } + 'color': '#D4EDDA', + 'title': 'admin-notify-dashboard.delivered', + 'config': 'NOTIFY.outgoing.delivered', + 'count': 79 + }; await TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], From 7d3dbc3e46e64bb4bdd24f51e414cdb01e183b41 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Tue, 2 Jan 2024 10:26:27 +0100 Subject: [PATCH 032/142] add validation message for ldnUrl already associated --- .../ldn-service-form.component.html | 9 ++++++-- .../ldn-service-form.component.ts | 23 ++++++++++++++++++- src/assets/i18n/en.json5 | 1 + 3 files changed, 30 insertions(+), 3 deletions(-) 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 16fed56ca4..1cf5a1d3f2 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 @@ -57,8 +57,13 @@ id="ldnUrl" name="ldnUrl" type="text"> -
- {{ 'ldn-new-service.form.error.ldnurl' | translate }} +
+
+ {{ 'ldn-new-service.form.error.ldnurl' | translate }} +
+
+ {{ 'ldn-new-service.form.error.ldnurl.ldnUrlAlreadyAssociated' | translate }} +
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 60206b5b00..a6c0e23656 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 @@ -9,7 +9,12 @@ import { TemplateRef, ViewChild } from '@angular/core'; -import {FormArray, FormBuilder, FormGroup, Validators} from '@angular/forms'; +import { + FormArray, + FormBuilder, + FormGroup, + Validators +} from '@angular/forms'; import {LDN_SERVICE} from '../ldn-services-model/ldn-service.resource-type'; import {ActivatedRoute, Router} from '@angular/router'; import {LdnServicesService} from '../ldn-services-data/ldn-services-data.service'; @@ -198,6 +203,9 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy { this.sendBack(); this.closeModal(); } else { + if (!this.formModel.errors) { + this.showLdnUrlError(); + } this.notificationService.error(this.translateService.get('ldn-service-notification.created.failure.title'), this.translateService.get('ldn-service-notification.created.failure.body')); this.closeModal(); @@ -486,6 +494,9 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy { this.notificationService.success(this.translateService.get('admin.registries.services-formats.modify.success.head'), this.translateService.get('admin.registries.services-formats.modify.success.content')); } else { + if (!this.formModel.errors) { + this.showLdnUrlError(); + } this.notificationService.error(this.translateService.get('admin.registries.services-formats.modify.failure.head'), this.translateService.get('admin.registries.services-formats.modify.failure.content')); this.closeModal(); @@ -708,4 +719,14 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy { automatic: '', }); } + + + /** + * Show ldnUrl error in case of unprocessable entity and provided value + */ + private showLdnUrlError(): void { + const control = this.formModel.controls.ldnUrl; + const controlErrors = control.errors || {}; + control.setErrors({...controlErrors, ldnUrlAlreadyAssociated: true }); + } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index f7a9e2c072..e746a10bd6 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -998,6 +998,7 @@ "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.ldnurl.ldnUrlAlreadyAssociated": "This LDN Inbox URL is associated to another registered service. Please enter a different LDN Inbox URL", "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", From 3616e66155900e114fe97a437e9bea25b80f1256 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Tue, 2 Jan 2024 10:28:44 +0100 Subject: [PATCH 033/142] refactor fn name --- .../ldn-service-form/ldn-service-form.component.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 a6c0e23656..d5ad1f36e0 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 @@ -204,7 +204,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy { this.closeModal(); } else { if (!this.formModel.errors) { - this.showLdnUrlError(); + this.setLdnUrlError(); } this.notificationService.error(this.translateService.get('ldn-service-notification.created.failure.title'), this.translateService.get('ldn-service-notification.created.failure.body')); @@ -495,7 +495,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy { this.translateService.get('admin.registries.services-formats.modify.success.content')); } else { if (!this.formModel.errors) { - this.showLdnUrlError(); + this.setLdnUrlError(); } this.notificationService.error(this.translateService.get('admin.registries.services-formats.modify.failure.head'), this.translateService.get('admin.registries.services-formats.modify.failure.content')); @@ -722,9 +722,9 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy { /** - * Show ldnUrl error in case of unprocessable entity and provided value + * set ldnUrl error in case of unprocessable entity and provided value */ - private showLdnUrlError(): void { + private setLdnUrlError(): void { const control = this.formModel.controls.ldnUrl; const controlErrors = control.errors || {}; control.setErrors({...controlErrors, ldnUrlAlreadyAssociated: true }); From c4b8eaba72649f02eca0d576e0f4d19217fdf545 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Tue, 2 Jan 2024 14:47:15 +0100 Subject: [PATCH 034/142] add base config --- .../admin-notify-dashboard.module.ts | 6 +- ...admin-notify-logs-configuration.service.ts | 93 +++++++++++++++++++ .../admin-notify-logs.component.html | 3 + .../admin-notify-logs.component.ts | 17 +++- 4 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-configuration.service.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts index ec6d63d8e1..efcb8dfe70 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts @@ -6,6 +6,8 @@ import { AdminNotifyDashboardRoutingModule } from './admin-notify-dashboard-rout import { AdminNotifyMetricsComponent } from './admin-notify-metrics/admin-notify-metrics.component'; import { AdminNotifyLogsComponent } from './admin-notify-logs/admin-notify-logs.component'; import { SharedModule } from '../../shared/shared.module'; +import { SearchModule } from "../../shared/search/search.module"; +import { SearchPageModule } from "../../search-page/search-page.module"; @NgModule({ @@ -13,7 +15,9 @@ import { SharedModule } from '../../shared/shared.module'; CommonModule, RouterModule, SharedModule, - AdminNotifyDashboardRoutingModule + AdminNotifyDashboardRoutingModule, + SearchModule, + SearchPageModule, ], declarations: [ AdminNotifyDashboardComponent, diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-configuration.service.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-configuration.service.ts new file mode 100644 index 0000000000..51033e9819 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-configuration.service.ts @@ -0,0 +1,93 @@ +import { SearchConfigurationService } from "../../../core/shared/search/search-configuration.service"; +import { PaginationComponentOptions } from "../../../shared/pagination/pagination-component-options.model"; +import { SortDirection, SortOptions } from "../../../core/cache/models/sort-options.model"; +import { RouteService } from "../../../core/services/route.service"; +import { ActivatedRoute } from "@angular/router"; +import { LinkService } from "../../../core/cache/builders/link.service"; +import { HALEndpointService } from "../../../core/shared/hal-endpoint.service"; +import { RequestService } from "../../../core/data/request.service"; +import { RemoteDataBuildService } from "../../../core/cache/builders/remote-data-build.service"; +import { PaginationService } from '../../../core/pagination/pagination.service'; +import { Injectable } from "@angular/core"; +import { PaginatedSearchOptions } from "../../../shared/search/models/paginated-search-options.model"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { hasValue } from "../../../shared/empty.util"; + + + +/** + * Service that performs all actions that have to do with the current notify configuration + */ +@Injectable() +export class AdminNotifyLogsConfigurationService extends SearchConfigurationService { + + + /** + * Endpoint link path for retrieving general search results + */ + private searchLinkPath = 'discover/search/objects'; + /** + * Default pagination settings + */ + protected defaultPagination = Object.assign(new PaginationComponentOptions(), { + id: 'notify-logs-page', + pageSize: 10, + currentPage: 1 + }); + /** + * Default sort settings + */ + protected defaultSort = new SortOptions('dc.date.issued', SortDirection.DESC); + + /** + * Default scope setting + */ + protected defaultScope = ''; + + /** + * Default query setting + */ + protected defaultQuery = ''; + + + /** + * Initialize class + * + * @param {roleService} roleService + * @param {RouteService} routeService + * @param {PaginationService} paginationService + * @param {ActivatedRoute} route + * @param linkService + * @param halService + * @param requestService + * @param rdb + */ + constructor( + protected routeService: RouteService, + protected paginationService: PaginationService, + protected route: ActivatedRoute, + protected linkService: LinkService, + protected halService: HALEndpointService, + protected requestService: RequestService, + protected rdb: RemoteDataBuildService) { + + super(routeService, paginationService, route, linkService, halService, requestService, rdb); + + // override parent class initialization + this._defaults = null; + this.initDefaults(); + } + + getEndpoint(searchOptions?: PaginatedSearchOptions): Observable { + return this.halService.getEndpoint(this.searchLinkPath).pipe( + map((url: string) => { + if (hasValue(searchOptions)) { + return (searchOptions as PaginatedSearchOptions).toRestUrl(url); + } else { + return url; + } + }) + ); + } +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html index e69de29bb2..2378b97a9d 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html @@ -0,0 +1,3 @@ + + + diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts index 67552130a0..7db2fe5f20 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts @@ -1,10 +1,23 @@ -import { Component } from '@angular/core'; +import { Component, Inject } from '@angular/core'; +import { SEARCH_CONFIG_SERVICE } from "../../../my-dspace-page/my-dspace-page.component"; +import { AdminNotifyLogsConfigurationService } from "./admin-notify-logs-configuration.service"; +import { SearchConfigurationService } from "../../../core/shared/search/search-configuration.service"; +import { Context } from "../../../core/shared/context.model"; @Component({ selector: 'ds-admin-notify-logs', templateUrl: './admin-notify-logs.component.html', - styleUrls: ['./admin-notify-logs.component.scss'] + styleUrls: ['./admin-notify-logs.component.scss'], + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: AdminNotifyLogsConfigurationService + } + ] }) export class AdminNotifyLogsComponent { + constructor(@Inject(SEARCH_CONFIG_SERVICE) private searchConfigService: SearchConfigurationService) { + } + protected readonly context = Context.Search; } From 457c3b351f9304264fc1efff63010fe971eb95a1 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Wed, 3 Jan 2024 17:27:38 +0100 Subject: [PATCH 035/142] refactor, decouple pagination and configuration --- .../admin-notify-dashboard-routing.module.ts | 6 +- .../admin-notify-dashboard.component.html | 3 +- .../admin-notify-dashboard.component.ts | 8 -- .../admin-notify-dashboard.module.ts | 14 ++- .../admin-notify-incoming.component.html | 9 ++ .../admin-notify-incoming.component.scss} | 0 .../admin-notify-incoming.component.spec.ts} | 10 +- .../admin-notify-incoming.component.ts | 20 ++++ ...admin-notify-logs-configuration.service.ts | 93 ------------------- .../admin-notify-logs.component.html | 3 - .../admin-notify-logs.component.ts | 23 ----- .../admin-notify-outgoing.component.html | 9 ++ .../admin-notify-outgoing.component.scss | 0 .../admin-notify-outgoing.component.spec.ts | 25 +++++ .../admin-notify-outgoing.component.ts | 20 ++++ .../admin-notify-search-result.component.html | 7 ++ .../admin-notify-search-result.component.scss | 0 ...min-notify-search-result.component.spec.ts | 22 +++++ .../admin-notify-search-result.component.ts | 24 +++++ .../models/admin-notify-message.model.ts | 46 ++++++++- src/app/core/shared/context.model.ts | 2 + .../search/search-configuration.service.ts | 21 ++++- .../notification-box.component.ts | 6 ++ src/app/shared/search/search.component.ts | 11 ++- .../shared/search/themed-search.component.ts | 4 +- src/assets/i18n/en.json5 | 16 ++++ 26 files changed, 256 insertions(+), 146 deletions(-) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.html rename src/app/admin/admin-notify-dashboard/admin-notify-logs/{admin-notify-logs.component.scss => admin-notify-incoming/admin-notify-incoming.component.scss} (100%) rename src/app/admin/admin-notify-dashboard/admin-notify-logs/{admin-notify-logs.component.spec.ts => admin-notify-incoming/admin-notify-incoming.component.spec.ts} (60%) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-configuration.service.ts delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.scss create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts index 778815e1fb..b917116216 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts @@ -2,14 +2,16 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver'; import { I18nBreadcrumbsService } from '../../core/breadcrumbs/i18n-breadcrumbs.service'; -import { AuthenticatedGuard } from '../../core/auth/authenticated.guard'; import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; +import { + SiteAdministratorGuard +} from '../../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard'; @NgModule({ imports: [ RouterModule.forChild([ { - canActivate: [ AuthenticatedGuard ], + canActivate: [SiteAdministratorGuard], path: '', component: AdminNotifyDashboardComponent, pathMatch: 'full', diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html index 2402583c61..6d4e340299 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -16,7 +16,8 @@ {{'admin-notify-dashboard.logs' | translate}}
- + +
diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 71be6424df..d6d8a24cd9 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -3,12 +3,6 @@ import { SearchService } from '../../core/shared/search/search.service'; import { environment } from '../../../environments/environment'; import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; -import { - listableObjectComponent -} from '../../shared/object-collection/shared/listable-object/listable-object.decorator'; -import { ViewMode } from '../../core/shared/view-mode.model'; -import { Context } from '../../core/shared/context.model'; -import { AdminNotifySearchResult } from './models/admin-notify-message-search-result.model'; import { forkJoin, Observable } from 'rxjs'; import { getFirstCompletedRemoteData } from '../../core/shared/operators'; import { map } from 'rxjs/operators'; @@ -16,8 +10,6 @@ import { SearchObjects } from '../../shared/search/models/search-objects.model'; import { AdminNotifyMetricsBox, AdminNotifyMetricsRow } from './admin-notify-metrics/admin-notify-metrics.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; - -@listableObjectComponent(AdminNotifySearchResult, ViewMode.GridElement, Context.AdminSearch) @Component({ selector: 'ds-admin-notify-dashboard', templateUrl: './admin-notify-dashboard.component.html', diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts index efcb8dfe70..06747dd2d5 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts @@ -4,10 +4,14 @@ import { RouterModule } from '@angular/router'; import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; import { AdminNotifyDashboardRoutingModule } from './admin-notify-dashboard-routing.module'; import { AdminNotifyMetricsComponent } from './admin-notify-metrics/admin-notify-metrics.component'; -import { AdminNotifyLogsComponent } from './admin-notify-logs/admin-notify-logs.component'; +import { AdminNotifyIncomingComponent } from './admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component'; import { SharedModule } from '../../shared/shared.module'; -import { SearchModule } from "../../shared/search/search.module"; -import { SearchPageModule } from "../../search-page/search-page.module"; +import { SearchModule } from '../../shared/search/search.module'; +import { SearchPageModule } from '../../search-page/search-page.module'; +import { AdminNotifySearchResultComponent } from './admin-notify-search-result/admin-notify-search-result.component'; +import { + AdminNotifyOutgoingComponent +} from './admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component'; @NgModule({ @@ -22,7 +26,9 @@ import { SearchPageModule } from "../../search-page/search-page.module"; declarations: [ AdminNotifyDashboardComponent, AdminNotifyMetricsComponent, - AdminNotifyLogsComponent + AdminNotifyIncomingComponent, + AdminNotifyOutgoingComponent, + AdminNotifySearchResultComponent ] }) export class AdminNotifyDashboardModule { diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.html new file mode 100644 index 0000000000..868469ad55 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.html @@ -0,0 +1,9 @@ + + diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.scss similarity index 100% rename from src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.scss rename to src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.scss diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts similarity index 60% rename from src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts rename to src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts index b1f89a4f76..d32e100686 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts @@ -1,20 +1,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { AdminNotifyLogsComponent } from './admin-notify-logs.component'; +import { AdminNotifyIncomingComponent } from './admin-notify-incoming.component'; import { TranslateModule } from '@ngx-translate/core'; describe('AdminNotifyLogsComponent', () => { - let component: AdminNotifyLogsComponent; - let fixture: ComponentFixture; + let component: AdminNotifyIncomingComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], - declarations: [ AdminNotifyLogsComponent ] + declarations: [ AdminNotifyIncomingComponent ] }) .compileComponents(); - fixture = TestBed.createComponent(AdminNotifyLogsComponent); + fixture = TestBed.createComponent(AdminNotifyIncomingComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts new file mode 100644 index 0000000000..b1a05616a8 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts @@ -0,0 +1,20 @@ +import { Component } from '@angular/core'; +import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; +import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; +import { Context } from '../../../../core/shared/context.model'; + + +@Component({ + selector: 'ds-admin-notify-incoming', + templateUrl: './admin-notify-incoming.component.html', + styleUrls: ['./admin-notify-incoming.component.scss'], + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationService + } + ] +}) +export class AdminNotifyIncomingComponent { + protected readonly context = Context.CoarNotify; +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-configuration.service.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-configuration.service.ts deleted file mode 100644 index 51033e9819..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-configuration.service.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { SearchConfigurationService } from "../../../core/shared/search/search-configuration.service"; -import { PaginationComponentOptions } from "../../../shared/pagination/pagination-component-options.model"; -import { SortDirection, SortOptions } from "../../../core/cache/models/sort-options.model"; -import { RouteService } from "../../../core/services/route.service"; -import { ActivatedRoute } from "@angular/router"; -import { LinkService } from "../../../core/cache/builders/link.service"; -import { HALEndpointService } from "../../../core/shared/hal-endpoint.service"; -import { RequestService } from "../../../core/data/request.service"; -import { RemoteDataBuildService } from "../../../core/cache/builders/remote-data-build.service"; -import { PaginationService } from '../../../core/pagination/pagination.service'; -import { Injectable } from "@angular/core"; -import { PaginatedSearchOptions } from "../../../shared/search/models/paginated-search-options.model"; -import { Observable } from "rxjs"; -import { map } from "rxjs/operators"; -import { hasValue } from "../../../shared/empty.util"; - - - -/** - * Service that performs all actions that have to do with the current notify configuration - */ -@Injectable() -export class AdminNotifyLogsConfigurationService extends SearchConfigurationService { - - - /** - * Endpoint link path for retrieving general search results - */ - private searchLinkPath = 'discover/search/objects'; - /** - * Default pagination settings - */ - protected defaultPagination = Object.assign(new PaginationComponentOptions(), { - id: 'notify-logs-page', - pageSize: 10, - currentPage: 1 - }); - /** - * Default sort settings - */ - protected defaultSort = new SortOptions('dc.date.issued', SortDirection.DESC); - - /** - * Default scope setting - */ - protected defaultScope = ''; - - /** - * Default query setting - */ - protected defaultQuery = ''; - - - /** - * Initialize class - * - * @param {roleService} roleService - * @param {RouteService} routeService - * @param {PaginationService} paginationService - * @param {ActivatedRoute} route - * @param linkService - * @param halService - * @param requestService - * @param rdb - */ - constructor( - protected routeService: RouteService, - protected paginationService: PaginationService, - protected route: ActivatedRoute, - protected linkService: LinkService, - protected halService: HALEndpointService, - protected requestService: RequestService, - protected rdb: RemoteDataBuildService) { - - super(routeService, paginationService, route, linkService, halService, requestService, rdb); - - // override parent class initialization - this._defaults = null; - this.initDefaults(); - } - - getEndpoint(searchOptions?: PaginatedSearchOptions): Observable { - return this.halService.getEndpoint(this.searchLinkPath).pipe( - map((url: string) => { - if (hasValue(searchOptions)) { - return (searchOptions as PaginatedSearchOptions).toRestUrl(url); - } else { - return url; - } - }) - ); - } -} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html deleted file mode 100644 index 2378b97a9d..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts deleted file mode 100644 index 7db2fe5f20..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Component, Inject } from '@angular/core'; -import { SEARCH_CONFIG_SERVICE } from "../../../my-dspace-page/my-dspace-page.component"; -import { AdminNotifyLogsConfigurationService } from "./admin-notify-logs-configuration.service"; -import { SearchConfigurationService } from "../../../core/shared/search/search-configuration.service"; -import { Context } from "../../../core/shared/context.model"; - -@Component({ - selector: 'ds-admin-notify-logs', - templateUrl: './admin-notify-logs.component.html', - styleUrls: ['./admin-notify-logs.component.scss'], - providers: [ - { - provide: SEARCH_CONFIG_SERVICE, - useClass: AdminNotifyLogsConfigurationService - } - ] -}) -export class AdminNotifyLogsComponent { - constructor(@Inject(SEARCH_CONFIG_SERVICE) private searchConfigService: SearchConfigurationService) { - } - - protected readonly context = Context.Search; -} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html new file mode 100644 index 0000000000..af64c69e7a --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html @@ -0,0 +1,9 @@ + + diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts new file mode 100644 index 0000000000..dafa72c52e --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdminNotifyOutgoingComponent } from './admin-notify-outgoing.component'; +import { TranslateModule } from '@ngx-translate/core'; + +describe('AdminNotifyLogsComponent', () => { + let component: AdminNotifyOutgoingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + declarations: [ AdminNotifyOutgoingComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminNotifyOutgoingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts new file mode 100644 index 0000000000..9248b9c25e --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts @@ -0,0 +1,20 @@ +import { Component } from '@angular/core'; +import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; +import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; +import { Context } from '../../../../core/shared/context.model'; + + +@Component({ + selector: 'ds-admin-notify-outgoing', + templateUrl: './admin-notify-outgoing.component.html', + styleUrls: ['./admin-notify-outgoing.component.scss'], + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationService + } + ] +}) +export class AdminNotifyOutgoingComponent { + protected readonly context = Context.CoarNotify; +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html new file mode 100644 index 0000000000..b82a55b903 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html @@ -0,0 +1,7 @@ +
+
{{indexableObject.queueTimeout}}
+
{{indexableObject.source}}
+
{{indexableObject.target}}
+
{{indexableObject.coarNotifyType}}
+
{{indexableObject.queueStatusLabel}}
+
diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts new file mode 100644 index 0000000000..b17a03274f --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AdminNotifySearchResultComponent } from './admin-notify-search-result.component'; + +describe('AdminNotifySearchResultComponent', () => { + let component: AdminNotifySearchResultComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AdminNotifySearchResultComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminNotifySearchResultComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts new file mode 100644 index 0000000000..0df2159b38 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit } from '@angular/core'; +import { + listableObjectComponent +} from '../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model'; +import { ViewMode } from '../../../core/shared/view-mode.model'; +import { Context } from '../../../core/shared/context.model'; +import { + SearchResultListElementComponent +} from '../../../shared/object-list/search-result-list-element/search-result-list-element.component'; +import { AdminNotifyMessage } from '../models/admin-notify-message.model'; + +@listableObjectComponent(AdminNotifySearchResult, ViewMode.ListElement, Context.CoarNotify) +@Component({ + selector: 'ds-admin-notify-search-result', + templateUrl: './admin-notify-search-result.component.html', + styleUrls: ['./admin-notify-search-result.component.scss'] +}) +export class AdminNotifySearchResultComponent extends SearchResultListElementComponent implements OnInit{ + indexableObject: AdminNotifyMessage; + ngOnInit() { + this.indexableObject = this.object.indexableObject; + } +} diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts index d0047ec392..42bdc7b3c2 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -1,8 +1,10 @@ -import { deserialize, inheritSerialization } from 'cerialize'; +import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; import { typedObject } from '../../../core/cache/builders/build-decorators'; import { ADMIN_NOTIFY_MESSAGE } from './admin-notify-message.resource-type'; import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; +import { GenericConstructor } from '../../../core/shared/generic-constructor'; +import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; /** * A message that includes admin notify info @@ -13,11 +15,47 @@ export class AdminNotifyMessage extends DSpaceObject { static type = ADMIN_NOTIFY_MESSAGE; /** - * The type of the message + * The type of the resource */ @excludeFromEquals type = ADMIN_NOTIFY_MESSAGE; + /** + * The type of the notification + */ + @autoserialize + coarNotifyType: string; + + /** + * The type of the activity stream + */ + @autoserialize + source: number; + + /** + * The type of the activity stream + */ + @autoserialize + target: number; + + /** + * The label for the status of the queue + */ + @autoserialize + queueStatusLabel: string; + + /** + * The timeout of the queue + */ + @autoserialize + queueTimeout: string; + + /** + * The status of the queue + */ + @autoserialize + queueStatus: number; + @deserialize _links: { self: { @@ -28,4 +66,8 @@ export class AdminNotifyMessage extends DSpaceObject { get self(): string { return this._links.self.href; } + + getRenderTypes(): (string | GenericConstructor)[] { + return [this.constructor as GenericConstructor]; + } } diff --git a/src/app/core/shared/context.model.ts b/src/app/core/shared/context.model.ts index b4c02bee63..deb7bbeca3 100644 --- a/src/app/core/shared/context.model.ts +++ b/src/app/core/shared/context.model.ts @@ -39,4 +39,6 @@ export enum Context { MyDSpaceValidation = 'mydspaceValidation', Bitstream = 'bitstream', + + CoarNotify = 'coarNotify' } diff --git a/src/app/core/shared/search/search-configuration.service.ts b/src/app/core/shared/search/search-configuration.service.ts index eed93ae201..dbc2f44bc4 100644 --- a/src/app/core/shared/search/search-configuration.service.ts +++ b/src/app/core/shared/search/search-configuration.service.ts @@ -28,6 +28,7 @@ import { FacetConfigResponseParsingService } from '../../data/facet-config-respo import { ViewMode } from '../view-mode.model'; import { SearchFilterConfig } from '../../../shared/search/models/search-filter-config.model'; import { FacetConfigResponse } from '../../../shared/search/models/facet-config-response.model'; +import { DspaceRestResponseParsingService } from '../../data/dspace-rest-response-parsing.service'; /** * Service that performs all actions that have to do with the current search configuration @@ -60,6 +61,11 @@ export class SearchConfigurationService implements OnDestroy { */ public paginatedSearchOptions: BehaviorSubject; + /** + * The name of the param to enhance and store the route config + */ + public routeConfigurationName: string; + /** * Default pagination settings */ @@ -105,7 +111,7 @@ export class SearchConfigurationService implements OnDestroy { protected linkService: LinkService, protected halService: HALEndpointService, protected requestService: RequestService, - protected rdb: RemoteDataBuildService,) { + protected rdb: RemoteDataBuildService) { this.initDefaults(); } @@ -131,7 +137,7 @@ export class SearchConfigurationService implements OnDestroy { getCurrentConfiguration(defaultConfiguration: string) { return observableCombineLatest([ this.routeService.getQueryParameterValue('configuration').pipe(startWith(undefined)), - this.routeService.getRouteParameterValue('configuration').pipe(startWith(undefined)) + this.routeService.getRouteParameterValue(this.routeConfigurationName ?? 'configuration').pipe(startWith(undefined)) ]).pipe( map(([queryConfig, routeConfig]) => { return queryConfig || routeConfig || defaultConfiguration; @@ -483,7 +489,7 @@ export class SearchConfigurationService implements OnDestroy { * @param {string} configurationName the name of the configuration * @returns {Observable>} The found filter configuration */ - getConfig(scope?: string, configurationName?: string): Observable> { + getConfig(scope?: string, configurationName?: string, facetParser?: DspaceRestResponseParsingService): Observable> { const href$ = this.halService.getEndpoint(this.facetLinkPathPrefix).pipe( map((url: string) => this.getConfigUrl(url, scope, configurationName)), ); @@ -534,4 +540,13 @@ export class SearchConfigurationService implements OnDestroy { return { view }; })); } + + /** + * Set param to use for multiple configurations on same page and reload search subscriptions + */ + setRouteConfigurationParamName(configName: string): void { + this.routeConfigurationName = configName; + this.unsubscribeFromSearchOptions(this.paginationID); + this.setSearchSubscription(this.paginationID, this.paginatedSearchOptions.value); + } } diff --git a/src/app/shared/notification-box/notification-box.component.ts b/src/app/shared/notification-box/notification-box.component.ts index 899d55cd74..00082e938f 100644 --- a/src/app/shared/notification-box/notification-box.component.ts +++ b/src/app/shared/notification-box/notification-box.component.ts @@ -2,7 +2,13 @@ import { Component, Input } from '@angular/core'; import { AdminNotifyMetricsBox } from '../../admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.model'; +import { listableObjectComponent } from '../object-collection/shared/listable-object/listable-object.decorator'; +import { + AdminNotifySearchResult +} from '../../admin/admin-notify-dashboard/models/admin-notify-message-search-result.model'; +import { ViewMode } from '../../core/shared/view-mode.model'; +@listableObjectComponent(AdminNotifySearchResult, ViewMode.ListElement) @Component({ selector: 'ds-notification-box', templateUrl: './notification-box.component.html', diff --git a/src/app/shared/search/search.component.ts b/src/app/shared/search/search.component.ts index 61f3a119c8..184dc2fb21 100644 --- a/src/app/shared/search/search.component.ts +++ b/src/app/shared/search/search.component.ts @@ -101,6 +101,11 @@ export class SearchComponent implements OnInit { */ @Input() searchEnabled = true; + /** + * Config param for route service + */ + @Input() routeConfigParam: string; + /** * The width of the sidebar (bootstrap columns) */ @@ -292,8 +297,12 @@ export class SearchComponent implements OnInit { this.searchConfigService.setPaginationId(this.paginationId); + if (this.routeConfigParam) { + this.searchConfigService.setRouteConfigurationParamName(this.routeConfigParam); + } + if (hasValue(this.configuration)) { - this.routeService.setParameter('configuration', this.configuration); + this.routeService.setParameter(this.routeConfigParam ?? 'configuration', this.configuration); } if (hasValue(this.fixedFilterQuery)) { this.routeService.setParameter('fixedFilterQuery', this.fixedFilterQuery); diff --git a/src/app/shared/search/themed-search.component.ts b/src/app/shared/search/themed-search.component.ts index 03f6f37e25..555056eacc 100644 --- a/src/app/shared/search/themed-search.component.ts +++ b/src/app/shared/search/themed-search.component.ts @@ -20,7 +20,7 @@ import { ListableObject } from '../object-collection/shared/listable-object.mode }) export class ThemedSearchComponent extends ThemedComponent { - protected inAndOutputNames: (keyof SearchComponent & keyof this)[] = ['configurationList', 'context', 'configuration', 'fixedFilterQuery', 'useCachedVersionIfAvailable', 'inPlaceSearch', 'linkType', 'paginationId', 'searchEnabled', 'sideBarWidth', 'searchFormPlaceholder', 'selectable', 'selectionConfig', 'showCsvExport', 'showSidebar', 'showThumbnails', 'showViewModes', 'useUniquePageId', 'viewModeList', 'showScopeSelector', 'resultFound', 'deselectObject', 'selectObject', 'trackStatistics', 'query']; + protected inAndOutputNames: (keyof SearchComponent & keyof this)[] = ['configurationList', 'context', 'configuration', 'fixedFilterQuery', 'routeConfigParam', 'useCachedVersionIfAvailable', 'inPlaceSearch', 'linkType', 'paginationId', 'searchEnabled', 'sideBarWidth', 'searchFormPlaceholder', 'selectable', 'selectionConfig', 'showCsvExport', 'showSidebar', 'showThumbnails', 'showViewModes', 'useUniquePageId', 'viewModeList', 'showScopeSelector', 'resultFound', 'deselectObject', 'selectObject', 'trackStatistics', 'query']; @Input() configurationList: SearchConfigurationOption[]; @@ -30,6 +30,8 @@ export class ThemedSearchComponent extends ThemedComponent { @Input() fixedFilterQuery: string; + @Input() routeConfigParam: string; + @Input() useCachedVersionIfAvailable: boolean; @Input() inPlaceSearch: boolean; diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index fa5326c92c..68e6e8cd9d 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3471,6 +3471,22 @@ "admin.notify.dashboard.breadcrumbs": "Dashboard", + "NOTIFY.incoming.search.results.head": "Incoming", + + "search.filters.filter.relateditem.head": "Related item", + + "search.filters.filter.origin.head": "Origin", + + "search.filters.filter.target.head": "Target", + + "search.filters.filter.queue_status.head": "Queue status", + + "search.filters.filter.activity_stream_type.head": "Activity stream type", + + "search.filters.filter.coar_notify_type.head": "Coar notify type", + + "search.filters.filter.notification_type.head": "Notification type", + "orgunit.listelement.badge": "Organizational Unit", "orgunit.listelement.no-title": "Untitled", From d72f522f63560a7beb5c6d10ed3327ff636bfe94 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Wed, 3 Jan 2024 18:01:40 +0100 Subject: [PATCH 036/142] add header translations --- .../admin-notify-dashboard.component.html | 2 + src/assets/i18n/en.json5 | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html index 6d4e340299..37cc33f92a 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -16,7 +16,9 @@ {{'admin-notify-dashboard.logs' | translate}}
+
{{'admin.notify.dashboard.inbound' | translate}}
+
{{'admin.notify.dashboard.outbound' | translate}}
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 68e6e8cd9d..ce5004832e 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3471,6 +3471,12 @@ "admin.notify.dashboard.breadcrumbs": "Dashboard", + "admin.notify.dashboard.inbound": "Inbound messages", + + "admin.notify.dashboard.outbound": "Outbound messages", + + "admin.notify.dashboard.breadcrumbs": "Dashboard", + "NOTIFY.incoming.search.results.head": "Incoming", "search.filters.filter.relateditem.head": "Related item", @@ -3487,6 +3493,38 @@ "search.filters.filter.notification_type.head": "Notification type", + "search.filters.filter.relateditem.label": "Search related items", + + "search.filters.filter.queue_status.label": "Search queue status", + + "search.filters.filter.target.label": "Search target", + + "search.filters.filter.activity_stream_type.label": "Search activity stream type", + + "search.filters.filter.coar_notify_type.label": "Search COAR notify type", + + "search.filters.filter.notification_type.label": "Search notification type", + + "search.filters.filter.relateditem.placeholder": "Related items", + + "search.filters.filter.target.placeholder": "Target", + + "search.filters.filter.queue_status.placeholder": "Queue status", + + "search.filters.filter.activity_stream_type.placeholder": "Activity stream type", + + "search.filters.filter.coar_notify_type.placeholder": "COAR notify type", + + "search.filters.filter.notification_type.placeholder": "Notification type", + + "sorting.queue_last_start_time.DESC": "Last started queue Descending", + + "sorting.queue_last_start_time.ASC": "Last started queue Ascending", + + "sorting.queue_attempts.DESC": "Queue attempted Descending", + + "sorting.queue_attempts.ASC": "Queue attempted Ascending", + "orgunit.listelement.badge": "Organizational Unit", "orgunit.listelement.no-title": "Untitled", From 9617329683ef8b4e664dde691313c7a8b19dd5e9 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Thu, 4 Jan 2024 13:22:53 +0100 Subject: [PATCH 037/142] add new dependencies for facets filters isolation --- .../admin-notify-dashboard.component.ts | 23 ++- .../admin-notify-incoming.component.ts | 25 ++- .../admin-notify-outgoing.component.ts | 27 +++- .../admin-notify-search-result.component.html | 10 +- ...dmin-notify-facet-config-response.model.ts | 35 ++++ ...n-notify-facet-response-parsing.service.ts | 38 +++++ .../config/admin-notify-filter-service.ts | 36 +++++ ...min-notify-search-configuration.service.ts | 149 ++++++++++++++++++ .../admin-notify-search-filter-config.ts | 90 +++++++++++ src/app/core/core.module.ts | 12 +- .../search/search-configuration.service.ts | 4 +- .../shared/search/search-filter.service.ts | 4 +- src/app/core/shared/search/search.service.ts | 1 - .../search-facet-option.component.ts | 5 +- .../search-facet-range-option.component.ts | 5 +- .../search-facet-selected-option.component.ts | 5 +- .../search-facet-filter.component.ts | 3 +- .../search-filter/search-filter.component.ts | 5 +- .../search-hierarchy-filter.component.ts | 3 +- .../search-range-filter.component.ts | 3 +- .../search-filters.component.ts | 3 +- 21 files changed, 457 insertions(+), 29 deletions(-) create mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts create mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts create mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts create mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts create mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index d6d8a24cd9..14c5fde08e 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, InjectionToken, OnInit } from '@angular/core'; import { SearchService } from '../../core/shared/search/search.service'; import { environment } from '../../../environments/environment'; import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; @@ -9,11 +9,32 @@ import { map } from 'rxjs/operators'; import { SearchObjects } from '../../shared/search/models/search-objects.model'; import { AdminNotifyMetricsBox, AdminNotifyMetricsRow } from './admin-notify-metrics/admin-notify-metrics.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; +import { FILTER_CONFIG, SearchFilterService } from "../../core/shared/search/search-filter.service"; +import { SEARCH_CONFIG_SERVICE } from "../../my-dspace-page/my-dspace-page.component"; +import { AdminNotifySearchConfigurationService } from "./config/admin-notify-search-configuration.service"; +import { AdminNotifySearchFilterService } from "./config/admin-notify-filter-service"; +import { AdminNotifySearchFilterConfig } from "./config/admin-notify-search-filter-config"; + +export const FILTER_SEARCH: InjectionToken = new InjectionToken('searchFilterService'); @Component({ selector: 'ds-admin-notify-dashboard', templateUrl: './admin-notify-dashboard.component.html', styleUrls: ['./admin-notify-dashboard.component.scss'], + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: AdminNotifySearchConfigurationService + }, + { + provide: FILTER_SEARCH, + useClass: AdminNotifySearchFilterService + }, + { + provide: FILTER_CONFIG, + useClass: AdminNotifySearchFilterConfig + } + ] }) export class AdminNotifyDashboardComponent implements OnInit{ diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts index b1a05616a8..05a882ba6f 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts @@ -1,7 +1,12 @@ -import { Component } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { Context } from '../../../../core/shared/context.model'; +import { AdminNotifySearchConfigurationService } from "../../config/admin-notify-search-configuration.service"; +import { FILTER_SEARCH } from "../../admin-notify-dashboard.component"; +import { AdminNotifySearchFilterService } from "../../config/admin-notify-filter-service"; +import { FILTER_CONFIG } from "../../../../core/shared/search/search-filter.service"; +import { AdminNotifySearchFilterConfig } from "../../config/admin-notify-search-filter-config"; @Component({ @@ -11,10 +16,26 @@ import { Context } from '../../../../core/shared/context.model'; providers: [ { provide: SEARCH_CONFIG_SERVICE, - useClass: SearchConfigurationService + useClass: AdminNotifySearchConfigurationService + }, + { + provide: FILTER_SEARCH, + useClass: AdminNotifySearchFilterService + }, + { + provide: FILTER_CONFIG, + useClass: AdminNotifySearchFilterConfig } ] }) export class AdminNotifyIncomingComponent { protected readonly context = Context.CoarNotify; + constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: AdminNotifySearchConfigurationService, + @Inject(FILTER_SEARCH) public searchFilterService: AdminNotifySearchFilterService, + @Inject(FILTER_CONFIG) public filterConfig: AdminNotifySearchFilterConfig) { + const incomingPrefix = 'incoming.f' + this.searchConfigService.setParamPrefix(incomingPrefix); + this.searchFilterService.setParamPrefix(incomingPrefix); + this.filterConfig.paramNamePrefix = incomingPrefix; + } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts index 9248b9c25e..45043820fe 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts @@ -1,7 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; -import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { Context } from '../../../../core/shared/context.model'; +import { AdminNotifySearchConfigurationService } from "../../config/admin-notify-search-configuration.service"; +import { FILTER_SEARCH } from "../../admin-notify-dashboard.component"; +import { AdminNotifySearchFilterService } from "../../config/admin-notify-filter-service"; +import { FILTER_CONFIG } from "../../../../core/shared/search/search-filter.service"; +import { AdminNotifySearchFilterConfig } from "../../config/admin-notify-search-filter-config"; @Component({ @@ -11,10 +15,27 @@ import { Context } from '../../../../core/shared/context.model'; providers: [ { provide: SEARCH_CONFIG_SERVICE, - useClass: SearchConfigurationService + useClass: AdminNotifySearchConfigurationService + }, + { + provide: FILTER_SEARCH, + useClass: AdminNotifySearchFilterService + }, + { + provide: FILTER_CONFIG, + useClass: AdminNotifySearchFilterConfig } ] }) export class AdminNotifyOutgoingComponent { protected readonly context = Context.CoarNotify; + + constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: AdminNotifySearchConfigurationService, + @Inject(FILTER_SEARCH) public searchFilterService: AdminNotifySearchFilterService, + @Inject(FILTER_CONFIG) public filterConfig: AdminNotifySearchFilterConfig) { + const outgoingPrefix = 'outgoing.f' + this.searchConfigService.setParamPrefix(outgoingPrefix); + this.searchFilterService.setParamPrefix(outgoingPrefix); + this.filterConfig.paramNamePrefix = outgoingPrefix; + } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html index b82a55b903..40e5cbc195 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html @@ -1,7 +1,7 @@
-
{{indexableObject.queueTimeout}}
-
{{indexableObject.source}}
-
{{indexableObject.target}}
-
{{indexableObject.coarNotifyType}}
-
{{indexableObject.queueStatusLabel}}
+
{{indexableObject.queueTimeout ?? 'n/a'}}
+
{{indexableObject.source ?? 'n/a'}}
+
{{indexableObject.target ?? 'n/a'}}
+
{{indexableObject.coarNotifyType ?? 'n/a'}}
+
{{indexableObject.queueStatusLabel ?? 'n/a'}}
diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts new file mode 100644 index 0000000000..c7ead2b159 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts @@ -0,0 +1,35 @@ +import { typedObject } from '../../../core/cache/builders/build-decorators'; +import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; +import { deserialize } from 'cerialize'; +import { HALLink } from '../../../core/shared/hal-link.model'; +import { CacheableObject } from '../../../core/cache/cacheable-object.model'; +import { AdminNotifySearchFilterConfig } from "./admin-notify-search-filter-config"; +import { FACET_CONFIG_RESPONSE } from "../../../shared/search/models/types/facet-config-response.resouce-type"; + +/** + * The response from the discover/facets endpoint + */ +@typedObject +export class AdminNotifyFacetConfigResponse implements CacheableObject { + static type = FACET_CONFIG_RESPONSE; + + /** + * The object type, + * hardcoded because rest doesn't a unique one. + */ + @excludeFromEquals + type = FACET_CONFIG_RESPONSE; + + /** + * the filters in this response + */ + filters: AdminNotifySearchFilterConfig[]; + + /** + * The {@link HALLink}s for this SearchFilterConfig + */ + @deserialize + _links: { + self: HALLink; + }; +} diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts new file mode 100644 index 0000000000..854e0800fe --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { FacetConfigResponseParsingService } from "../../../core/data/facet-config-response-parsing.service"; +import { RestRequest } from "../../../core/data/rest-request.model"; +import { RawRestResponse } from "../../../core/dspace-rest/raw-rest-response.model"; +import { ParsedResponse } from "../../../core/cache/response.models"; +import { DSpaceSerializer } from "../../../core/dspace-rest/dspace.serializer"; +import { AdminNotifySearchFilterConfig } from "./admin-notify-search-filter-config"; +import { FacetConfigResponse } from "../../../shared/search/models/facet-config-response.model"; + +@Injectable() +export class AdminNotifyFacetResponseParsingService extends FacetConfigResponseParsingService { + parse(request: RestRequest, data: RawRestResponse): ParsedResponse { + + const config = data.payload._embedded.facets; + const serializer = new DSpaceSerializer(AdminNotifySearchFilterConfig); + const filters = serializer.deserializeArray(config); + + const _links = { + self: data.payload._links.self + }; + + // fill in the missing links section + filters.forEach((filterConfig: AdminNotifySearchFilterConfig) => { + _links[filterConfig.name] = { + href: filterConfig._links.self.href + }; + }); + + const facetConfigResponse = Object.assign(new FacetConfigResponse(), { + filters, + _links + }); + + this.addToObjectCache(facetConfigResponse, request, data); + + return new ParsedResponse(data.statusCode, facetConfigResponse._links.self); + } +} diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts new file mode 100644 index 0000000000..55537fcb22 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts @@ -0,0 +1,36 @@ +import { Inject, Injectable } from "@angular/core"; +import { FILTER_CONFIG, SearchFilterService } from "../../../core/shared/search/search-filter.service"; +import { Store } from "@ngrx/store"; +import { SearchFiltersState } from "../../../shared/search/search-filters/search-filter/search-filter.reducer"; +import { RouteService } from "../../../core/services/route.service"; +import { SearchFilterConfig } from "../../../shared/search/models/search-filter-config.model"; + + +/** + * Service that performs all actions that have to do with search filters and facets + */ +@Injectable() +export class AdminNotifySearchFilterService extends SearchFilterService { + + public filterPrefix: string; + constructor(protected store: Store, + protected routeService: RouteService) { + super(store, routeService) + } + + /** + * Fetch the current active filters from the query parameters + * @returns {Observable} + */ + getCurrentFilters() { + return this.routeService.getQueryParamsWithPrefix(`${this.filterPrefix}.`); + } + + /** + * Set prefix to be used for route filters + * @param prefix + */ + setParamPrefix(prefix: string) : void { + this.filterPrefix = prefix; + } +} diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts new file mode 100644 index 0000000000..d90aff290e --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts @@ -0,0 +1,149 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRoute, Params } from '@angular/router'; +import { combineLatest, Observable } from 'rxjs'; +import { first, map, take } from 'rxjs/operators'; +import { SearchConfigurationService } from "../../../core/shared/search/search-configuration.service"; +import { RouteService } from "../../../core/services/route.service"; +import { LinkService } from "../../../core/cache/builders/link.service"; +import { HALEndpointService } from "../../../core/shared/hal-endpoint.service"; +import { RequestService } from "../../../core/data/request.service"; +import { RemoteDataBuildService } from "../../../core/cache/builders/remote-data-build.service"; +import { PaginationService } from "../../../core/pagination/pagination.service"; +import { DspaceRestResponseParsingService } from "../../../core/data/dspace-rest-response-parsing.service"; +import { RemoteData } from "../../../core/data/remote-data"; +import { SearchFilterConfig } from "../../../shared/search/models/search-filter-config.model"; +import { GetRequest } from "../../../core/data/request.models"; +import { GenericConstructor } from "../../../core/shared/generic-constructor"; +import { ResponseParsingService } from "../../../core/data/parsing.service"; +import { FacetConfigResponseParsingService } from "../../../core/data/facet-config-response-parsing.service"; +import { FacetConfigResponse } from "../../../shared/search/models/facet-config-response.model"; +import { hasNoValue, isNotEmpty } from "../../../shared/empty.util"; +import { AdminNotifyFacetResponseParsingService } from "./admin-notify-facet-response-parsing.service"; +import { AdminNotifySearchFilterConfig } from "./admin-notify-search-filter-config"; +import { AdminNotifyFacetConfigResponse } from "./admin-notify-facet-config-response.model"; +import { SearchFilter } from "../../../shared/search/models/search-filter.model"; + + + +/** + * Service that performs all actions that have to do with the current admin notify configuration + */ +@Injectable() +export class AdminNotifySearchConfigurationService extends SearchConfigurationService { + + public paramPrefix: string; + /** + * Initialize class + * + * @param {RouteService} routeService + * @param {PaginationService} paginationService + * @param {ActivatedRoute} route + * @param linkService + * @param halService + * @param requestService + * @param rdb + */ + constructor(protected routeService: RouteService, + protected paginationService: PaginationService, + protected route: ActivatedRoute, + protected linkService: LinkService, + protected halService: HALEndpointService, + protected requestService: RequestService, + protected rdb: RemoteDataBuildService) { + super(routeService, paginationService, route, linkService, halService, requestService, rdb); + } + + /** + * @returns {Observable} Emits the current active filters with their values as they are displayed in the frontend URL + */ + getCurrentFrontendFilters(): Observable { + return this.routeService.getQueryParamsWithPrefix(`${this.paramPrefix}.`); + } + + /** + * Set prefix to be used for route filters + * @param prefix + */ + setParamPrefix(prefix: string) : void { + this.paramPrefix = prefix; + } + + /** + * Request the filter configuration for a given scope or the whole repository + * @param {string} scope UUID of the object for which config the filter config is requested, when no scope is provided the configuration for the whole repository is loaded + * @param {string} configurationName the name of the configuration + * @returns {Observable>} The found filter configuration + */ + getConfig(scope?: string, configurationName?: string): Observable> { + const href$ = this.halService.getEndpoint(this.facetLinkPathPrefix).pipe( + map((url: string) => this.getConfigUrl(url, scope, configurationName)), + ); + + href$.pipe(take(1)).subscribe((url: string) => { + let request = new GetRequest(this.requestService.generateRequestId(), url); + request = Object.assign(request, { + getResponseParser(): GenericConstructor { + return AdminNotifyFacetResponseParsingService; + } + }); + this.requestService.send(request, true); + }); + + return this.rdb.buildFromHref(href$).pipe( + map((rd: RemoteData) => { + if (rd.hasSucceeded) { + let filters: AdminNotifySearchFilterConfig[]; + if (isNotEmpty(rd.payload.filters)) { + filters = rd.payload.filters + .map((filter: any) => Object.assign(new AdminNotifySearchFilterConfig(), filter)); + filters.forEach(filter => filter.namePrefix = this.paramPrefix); + } else { + filters = []; + } + + return new RemoteData( + rd.timeCompleted, + rd.msToLive, + rd.lastUpdated, + rd.state, + rd.errorMessage, + filters, + rd.statusCode, + ); + } else { + return rd as any as RemoteData; + } + }) + ); + } + + /** + * @returns {Observable} Emits the current active filters with their values as they are sent to the backend + */ + getCurrentFilters(): Observable { + return this.getCurrentFrontendFilters().pipe(map((filterParams) => { + if (isNotEmpty(filterParams)) { + const filters = []; + Object.keys(filterParams).forEach((key) => { + // we add one to keep in account the point at the end of the prefix and set back the prefix f. + const updatedKey = `f.${key.substring(this.paramPrefix.length + 1, key.length)}`; + + delete Object.assign(filterParams, {[updatedKey]: filterParams[key] })[key]; + key = updatedKey; + if (key.endsWith('.min') || key.endsWith('.max')) { + const realKey = key.slice(0, -4); + if (hasNoValue(filters.find((f) => f.key === realKey))) { + const min = filterParams[realKey + '.min'] ? filterParams[realKey + '.min'][0] : '*'; + const max = filterParams[realKey + '.max'] ? filterParams[realKey + '.max'][0] : '*'; + filters.push(new SearchFilter(realKey, ['[' + min + ' TO ' + max + ']'], 'equals')); + } + } else { + filters.push(new SearchFilter(key, filterParams[key])); + } + }); + return filters; + } + return []; + })); + } +} diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts new file mode 100644 index 0000000000..8172a52b1d --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts @@ -0,0 +1,90 @@ +import { typedObject } from '../../../core/cache/builders/build-decorators'; +import { SearchFilterConfig } from "../../../shared/search/models/search-filter-config.model"; +import { autoserialize, autoserializeAs, deserialize } from "cerialize"; +import { HALLink } from "../../../core/shared/hal-link.model"; +import { excludeFromEquals } from "../../../core/utilities/equals.decorators"; +import { SEARCH_FILTER_CONFIG } from "../../../shared/search/models/types/search-filter-config.resource-type"; +import { FilterType } from "../../../shared/search/models/filter-type.model"; + +/** + * The configuration for a search filter + */ +@typedObject +export class AdminNotifySearchFilterConfig implements SearchFilterConfig { + @autoserialize + namePrefix: string; + + static type = SEARCH_FILTER_CONFIG; + + /** + * The object type, + * hardcoded because rest doesn't set one. + */ + @excludeFromEquals + type = SEARCH_FILTER_CONFIG; + + /** + * The name of this filter + */ + @autoserialize + name: string; + + /** + * The FilterType of this filter + */ + @autoserializeAs(String, 'facetType') + filterType: FilterType; + + /** + * True if the filter has facets + */ + @autoserialize + hasFacets: boolean; + + /** + * @type {number} The page size used for this facet + */ + @autoserializeAs(String, 'facetLimit') + pageSize = 5; + + /** + * Defines if the item facet is collapsed by default or not on the search page + */ + @autoserialize + isOpenByDefault: boolean; + + /** + * Minimum value possible for this facet in the repository + */ + @autoserialize + maxValue: string; + + /** + * Maximum value possible for this facet in the repository + */ + @autoserialize + minValue: string; + + /** + * The {@link HALLink}s for this SearchFilterConfig + */ + @deserialize + _links: { + self: HALLink; + }; + + /** + * Set prefix to be used for route filters + * @param namePrefix + */ + set paramNamePrefix(namePrefix: string) { + this.namePrefix = namePrefix; + } + + /** + * Name of this configuration that can be used in a url + * @returns Parameter name + */ + get paramName(): string { + return `${this.namePrefix}.${this.name}`; + }} diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index fd0ff1e39c..7c3f1771da 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -198,6 +198,11 @@ import { SubmissionCoarNotifyConfig } from '../submission/sections/section-coar- import { NotifyRequestsStatus } from '../item-page/simple/notify-requests-status/notify-requests-status.model'; import { NotifyRequestsStatusDataService } from './data/notify-services-status-data.service'; import { AdminNotifyMessage } from '../admin/admin-notify-dashboard/models/admin-notify-message.model'; +import { + AdminNotifyFacetResponseParsingService +} from "../admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service"; +import { FILTER_SEARCH } from "../admin/admin-notify-dashboard/admin-notify-dashboard.component"; +import { AdminNotifySearchFilterService } from "../admin/admin-notify-dashboard/config/admin-notify-filter-service"; /** @@ -230,6 +235,10 @@ const PROVIDERS = [ DSOResponseParsingService, { provide: MOCK_RESPONSE_MAP, useValue: mockResponseMap }, { provide: DspaceRestService, useFactory: restServiceFactory, deps: [MOCK_RESPONSE_MAP, HttpClient] }, + { + provide: FILTER_SEARCH, + useClass: SearchFilterService + }, EPersonDataService, LinkHeadService, HALEndpointService, @@ -245,6 +254,7 @@ const PROVIDERS = [ EndpointMapResponseParsingService, FacetValueResponseParsingService, FacetConfigResponseParsingService, + AdminNotifyFacetResponseParsingService, DebugResponseParsingService, SearchResponseParsingService, MyDSpaceResponseParsingService, @@ -284,7 +294,7 @@ const PROVIDERS = [ SearchService, SidebarService, SearchFilterService, - SearchFilterService, + AdminNotifySearchFilterService, SearchConfigurationService, SelectableListService, RelationshipTypeDataService, diff --git a/src/app/core/shared/search/search-configuration.service.ts b/src/app/core/shared/search/search-configuration.service.ts index dbc2f44bc4..36202ae11c 100644 --- a/src/app/core/shared/search/search-configuration.service.ts +++ b/src/app/core/shared/search/search-configuration.service.ts @@ -44,7 +44,7 @@ export class SearchConfigurationService implements OnDestroy { /** * Endpoint link path for retrieving facet config incl values */ - private facetLinkPathPrefix = 'discover/facets/'; + protected facetLinkPathPrefix = 'discover/facets/'; /** * Default pagination id @@ -463,7 +463,7 @@ export class SearchConfigurationService implements OnDestroy { return this.rdb.buildFromHref(href$); } - private getConfigUrl(url: string, scope?: string, configurationName?: string) { + protected getConfigUrl(url: string, scope?: string, configurationName?: string) { const args: string[] = []; if (isNotEmpty(scope)) { diff --git a/src/app/core/shared/search/search-filter.service.ts b/src/app/core/shared/search/search-filter.service.ts index 80ba200d38..4b4d7a80d7 100644 --- a/src/app/core/shared/search/search-filter.service.ts +++ b/src/app/core/shared/search/search-filter.service.ts @@ -34,8 +34,8 @@ export const REFRESH_FILTER: InjectionToken> = new Injectio @Injectable() export class SearchFilterService { - constructor(private store: Store, - private routeService: RouteService) { + constructor(protected store: Store, + protected routeService: RouteService) { } /** diff --git a/src/app/core/shared/search/search.service.ts b/src/app/core/shared/search/search.service.ts index a88a8b0d16..9d85d0db5f 100644 --- a/src/app/core/shared/search/search.service.ts +++ b/src/app/core/shared/search/search.service.ts @@ -162,7 +162,6 @@ export class SearchService implements OnDestroy { getResponseParser: getResponseParserFn, searchOptions: searchOptions }); - this.requestService.send(request, useCachedVersionIfAvailable); }); diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts index cdbab61a30..ad64dc36b6 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts @@ -1,6 +1,6 @@ import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { FacetValue } from '../../../../models/facet-value.model'; import { SearchFilterConfig } from '../../../../models/search-filter-config.model'; @@ -11,6 +11,7 @@ import { hasValue } from '../../../../../empty.util'; import { currentPath } from '../../../../../utils/route.utils'; import { getFacetValueForType } from '../../../../search.utils'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; +import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; @Component({ selector: 'ds-search-facet-option', @@ -64,7 +65,7 @@ export class SearchFacetOptionComponent implements OnInit, OnDestroy { paginationId: string; constructor(protected searchService: SearchService, - protected filterService: SearchFilterService, + @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, protected searchConfigService: SearchConfigurationService, protected router: Router, protected paginationService: PaginationService diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts index b08a54e42b..880262fe17 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts @@ -1,6 +1,6 @@ import { Observable, Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { FacetValue } from '../../../../models/facet-value.model'; import { SearchFilterConfig } from '../../../../models/search-filter-config.model'; @@ -14,6 +14,7 @@ import { SearchConfigurationService } from '../../../../../../core/shared/search import { hasValue } from '../../../../../empty.util'; import { currentPath } from '../../../../../utils/route.utils'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; +import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; const rangeDelimiter = '-'; @@ -64,7 +65,7 @@ export class SearchFacetRangeOptionComponent implements OnInit, OnDestroy { searchLink: string; constructor(protected searchService: SearchService, - protected filterService: SearchFilterService, + @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, protected searchConfigService: SearchConfigurationService, protected router: Router, protected paginationService: PaginationService diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts index 4566b882eb..796a8e652f 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts @@ -1,5 +1,5 @@ import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { SearchFilterConfig } from '../../../../models/search-filter-config.model'; import { SearchService } from '../../../../../../core/shared/search/search.service'; @@ -10,6 +10,7 @@ import { FacetValue } from '../../../../models/facet-value.model'; import { currentPath } from '../../../../../utils/route.utils'; import { getFacetValueForType } from '../../../../search.utils'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; +import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; @Component({ selector: 'ds-search-facet-selected-option', @@ -57,7 +58,7 @@ export class SearchFacetSelectedOptionComponent implements OnInit, OnDestroy { searchLink: string; constructor(protected searchService: SearchService, - protected filterService: SearchFilterService, + @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, protected searchConfigService: SearchConfigurationService, protected router: Router, protected paginationService: PaginationService diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index 2b2eb9b11a..4d031b30a3 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -35,6 +35,7 @@ import { currentPath } from '../../../../utils/route.utils'; import { getFacetValueForType, stripOperatorFromFilterValue } from '../../../search.utils'; import { createPendingRemoteDataObject } from '../../../../remote-data.utils'; import { FacetValues } from '../../../models/facet-values.model'; +import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; @Component({ selector: 'ds-search-facet-filter', @@ -98,7 +99,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { currentUrl: string; constructor(protected searchService: SearchService, - protected filterService: SearchFilterService, + @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, protected rdbs: RemoteDataBuildService, protected router: Router, @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService, diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts index d1d3bd729d..4ed73345ef 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, Input, OnInit } from '@angular/core'; +import { Component, Inject, Input, OnInit, Optional } from '@angular/core'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { filter, map, startWith, switchMap, take } from 'rxjs/operators'; @@ -11,6 +11,7 @@ import { SearchService } from '../../../../core/shared/search/search.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { SequenceService } from '../../../../core/shared/sequence.service'; +import { FILTER_SEARCH } from "../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; @Component({ selector: 'ds-search-filter', @@ -71,7 +72,7 @@ export class SearchFilterComponent implements OnInit { private readonly sequenceId: number; constructor( - private filterService: SearchFilterService, + @Inject(FILTER_SEARCH) private filterService: SearchFilterService, private searchService: SearchService, @Inject(SEARCH_CONFIG_SERVICE) private searchConfigService: SearchConfigurationService, private sequenceService: SequenceService, diff --git a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts index f9b3f2bff9..bbb40781a7 100644 --- a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts @@ -26,6 +26,7 @@ import { PageInfo } from '../../../../../core/shared/page-info.model'; import { environment } from '../../../../../../environments/environment'; import { addOperatorToFilterValue } from '../../../search.utils'; import { VocabularyTreeviewModalComponent } from '../../../../form/vocabulary-treeview-modal/vocabulary-treeview-modal.component'; +import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; @Component({ selector: 'ds-search-hierarchy-filter', @@ -41,7 +42,7 @@ import { VocabularyTreeviewModalComponent } from '../../../../form/vocabulary-tr export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent implements OnInit { constructor(protected searchService: SearchService, - protected filterService: SearchFilterService, + @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, protected rdbs: RemoteDataBuildService, protected router: Router, protected modalService: NgbModal, diff --git a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts index ed20e63c52..d15ac1639c 100644 --- a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts @@ -21,6 +21,7 @@ import { SearchConfigurationService } from '../../../../../core/shared/search/se import { RouteService } from '../../../../../core/services/route.service'; import { hasValue } from '../../../../empty.util'; import { yearFromString } from 'src/app/shared/date.util'; +import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; /** * The suffix for a range filters' minimum in the frontend URL @@ -92,7 +93,7 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple keyboardControl: boolean; constructor(protected searchService: SearchService, - protected filterService: SearchFilterService, + @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, protected router: Router, protected rdbs: RemoteDataBuildService, private translateService: TranslateService, diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index 766939226d..7e252e780d 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -12,6 +12,7 @@ import { SearchFilterService } from '../../../core/shared/search/search-filter.s import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; import { currentPath } from '../../utils/route.utils'; import { hasValue } from '../../empty.util'; +import { FILTER_SEARCH } from "../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; @Component({ selector: 'ds-search-filters', @@ -71,7 +72,7 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { */ constructor( private searchService: SearchService, - private filterService: SearchFilterService, + @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, private router: Router, @Inject(SEARCH_CONFIG_SERVICE) private searchConfigService: SearchConfigurationService) { } From 9386536ca95bfc30863cc9907247c1fc56f3ab5e Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Thu, 4 Jan 2024 14:37:01 +0100 Subject: [PATCH 038/142] fix lint --- .../admin-notify-dashboard.component.ts | 10 ++--- .../admin-notify-incoming.component.ts | 13 +++--- .../admin-notify-outgoing.component.ts | 12 +++--- ...dmin-notify-facet-config-response.model.ts | 4 +- ...n-notify-facet-response-parsing.service.ts | 14 +++---- .../config/admin-notify-filter-service.ts | 15 ++++--- ...min-notify-search-configuration.service.ts | 42 +++++++++---------- .../admin-notify-search-filter-config.ts | 22 ++++++---- src/app/core/core.module.ts | 6 +-- .../search-facet-option.component.ts | 2 +- .../search-facet-range-option.component.ts | 2 +- .../search-facet-selected-option.component.ts | 2 +- .../search-facet-filter.component.ts | 2 +- .../search-filter/search-filter.component.ts | 4 +- .../search-hierarchy-filter.component.ts | 2 +- .../search-range-filter.component.ts | 2 +- .../search-filters.component.ts | 2 +- 17 files changed, 77 insertions(+), 79 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 14c5fde08e..5adc71a497 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -9,11 +9,11 @@ import { map } from 'rxjs/operators'; import { SearchObjects } from '../../shared/search/models/search-objects.model'; import { AdminNotifyMetricsBox, AdminNotifyMetricsRow } from './admin-notify-metrics/admin-notify-metrics.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; -import { FILTER_CONFIG, SearchFilterService } from "../../core/shared/search/search-filter.service"; -import { SEARCH_CONFIG_SERVICE } from "../../my-dspace-page/my-dspace-page.component"; -import { AdminNotifySearchConfigurationService } from "./config/admin-notify-search-configuration.service"; -import { AdminNotifySearchFilterService } from "./config/admin-notify-filter-service"; -import { AdminNotifySearchFilterConfig } from "./config/admin-notify-search-filter-config"; +import { FILTER_CONFIG, SearchFilterService } from '../../core/shared/search/search-filter.service'; +import { SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component'; +import { AdminNotifySearchConfigurationService } from './config/admin-notify-search-configuration.service'; +import { AdminNotifySearchFilterService } from './config/admin-notify-filter-service'; +import { AdminNotifySearchFilterConfig } from './config/admin-notify-search-filter-config'; export const FILTER_SEARCH: InjectionToken = new InjectionToken('searchFilterService'); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts index 05a882ba6f..b43866dc82 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts @@ -1,12 +1,11 @@ import { Component, Inject } from '@angular/core'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; -import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { Context } from '../../../../core/shared/context.model'; -import { AdminNotifySearchConfigurationService } from "../../config/admin-notify-search-configuration.service"; -import { FILTER_SEARCH } from "../../admin-notify-dashboard.component"; -import { AdminNotifySearchFilterService } from "../../config/admin-notify-filter-service"; -import { FILTER_CONFIG } from "../../../../core/shared/search/search-filter.service"; -import { AdminNotifySearchFilterConfig } from "../../config/admin-notify-search-filter-config"; +import { AdminNotifySearchConfigurationService } from '../../config/admin-notify-search-configuration.service'; +import { FILTER_SEARCH } from '../../admin-notify-dashboard.component'; +import { AdminNotifySearchFilterService } from '../../config/admin-notify-filter-service'; +import { FILTER_CONFIG } from '../../../../core/shared/search/search-filter.service'; +import { AdminNotifySearchFilterConfig } from '../../config/admin-notify-search-filter-config'; @Component({ @@ -33,7 +32,7 @@ export class AdminNotifyIncomingComponent { constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: AdminNotifySearchConfigurationService, @Inject(FILTER_SEARCH) public searchFilterService: AdminNotifySearchFilterService, @Inject(FILTER_CONFIG) public filterConfig: AdminNotifySearchFilterConfig) { - const incomingPrefix = 'incoming.f' + const incomingPrefix = 'incoming.f'; this.searchConfigService.setParamPrefix(incomingPrefix); this.searchFilterService.setParamPrefix(incomingPrefix); this.filterConfig.paramNamePrefix = incomingPrefix; diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts index 45043820fe..ae8cd0f13b 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts @@ -1,11 +1,11 @@ import { Component, Inject } from '@angular/core'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { Context } from '../../../../core/shared/context.model'; -import { AdminNotifySearchConfigurationService } from "../../config/admin-notify-search-configuration.service"; -import { FILTER_SEARCH } from "../../admin-notify-dashboard.component"; -import { AdminNotifySearchFilterService } from "../../config/admin-notify-filter-service"; -import { FILTER_CONFIG } from "../../../../core/shared/search/search-filter.service"; -import { AdminNotifySearchFilterConfig } from "../../config/admin-notify-search-filter-config"; +import { AdminNotifySearchConfigurationService } from '../../config/admin-notify-search-configuration.service'; +import { FILTER_SEARCH } from '../../admin-notify-dashboard.component'; +import { AdminNotifySearchFilterService } from '../../config/admin-notify-filter-service'; +import { FILTER_CONFIG } from '../../../../core/shared/search/search-filter.service'; +import { AdminNotifySearchFilterConfig } from '../../config/admin-notify-search-filter-config'; @Component({ @@ -33,7 +33,7 @@ export class AdminNotifyOutgoingComponent { constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: AdminNotifySearchConfigurationService, @Inject(FILTER_SEARCH) public searchFilterService: AdminNotifySearchFilterService, @Inject(FILTER_CONFIG) public filterConfig: AdminNotifySearchFilterConfig) { - const outgoingPrefix = 'outgoing.f' + const outgoingPrefix = 'outgoing.f'; this.searchConfigService.setParamPrefix(outgoingPrefix); this.searchFilterService.setParamPrefix(outgoingPrefix); this.filterConfig.paramNamePrefix = outgoingPrefix; diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts index c7ead2b159..d9f9460a65 100644 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts @@ -3,8 +3,8 @@ import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; import { deserialize } from 'cerialize'; import { HALLink } from '../../../core/shared/hal-link.model'; import { CacheableObject } from '../../../core/cache/cacheable-object.model'; -import { AdminNotifySearchFilterConfig } from "./admin-notify-search-filter-config"; -import { FACET_CONFIG_RESPONSE } from "../../../shared/search/models/types/facet-config-response.resouce-type"; +import { AdminNotifySearchFilterConfig } from './admin-notify-search-filter-config'; +import { FACET_CONFIG_RESPONSE } from '../../../shared/search/models/types/facet-config-response.resouce-type'; /** * The response from the discover/facets endpoint diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts index 854e0800fe..16c986fef6 100644 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts @@ -1,11 +1,11 @@ import { Injectable } from '@angular/core'; -import { FacetConfigResponseParsingService } from "../../../core/data/facet-config-response-parsing.service"; -import { RestRequest } from "../../../core/data/rest-request.model"; -import { RawRestResponse } from "../../../core/dspace-rest/raw-rest-response.model"; -import { ParsedResponse } from "../../../core/cache/response.models"; -import { DSpaceSerializer } from "../../../core/dspace-rest/dspace.serializer"; -import { AdminNotifySearchFilterConfig } from "./admin-notify-search-filter-config"; -import { FacetConfigResponse } from "../../../shared/search/models/facet-config-response.model"; +import { FacetConfigResponseParsingService } from '../../../core/data/facet-config-response-parsing.service'; +import { RestRequest } from '../../../core/data/rest-request.model'; +import { RawRestResponse } from '../../../core/dspace-rest/raw-rest-response.model'; +import { ParsedResponse } from '../../../core/cache/response.models'; +import { DSpaceSerializer } from '../../../core/dspace-rest/dspace.serializer'; +import { AdminNotifySearchFilterConfig } from './admin-notify-search-filter-config'; +import { FacetConfigResponse } from '../../../shared/search/models/facet-config-response.model'; @Injectable() export class AdminNotifyFacetResponseParsingService extends FacetConfigResponseParsingService { diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts index 55537fcb22..ca421957b8 100644 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts @@ -1,9 +1,8 @@ -import { Inject, Injectable } from "@angular/core"; -import { FILTER_CONFIG, SearchFilterService } from "../../../core/shared/search/search-filter.service"; -import { Store } from "@ngrx/store"; -import { SearchFiltersState } from "../../../shared/search/search-filters/search-filter/search-filter.reducer"; -import { RouteService } from "../../../core/services/route.service"; -import { SearchFilterConfig } from "../../../shared/search/models/search-filter-config.model"; +import { Injectable } from '@angular/core'; +import { SearchFilterService } from '../../../core/shared/search/search-filter.service'; +import { Store } from '@ngrx/store'; +import { SearchFiltersState } from '../../../shared/search/search-filters/search-filter/search-filter.reducer'; +import { RouteService } from '../../../core/services/route.service'; /** @@ -15,7 +14,7 @@ export class AdminNotifySearchFilterService extends SearchFilterService { public filterPrefix: string; constructor(protected store: Store, protected routeService: RouteService) { - super(store, routeService) + super(store, routeService); } /** @@ -30,7 +29,7 @@ export class AdminNotifySearchFilterService extends SearchFilterService { * Set prefix to be used for route filters * @param prefix */ - setParamPrefix(prefix: string) : void { + setParamPrefix(prefix: string): void { this.filterPrefix = prefix; } } diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts index d90aff290e..127aa2a5a1 100644 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts @@ -1,27 +1,23 @@ import { Injectable } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; -import { combineLatest, Observable } from 'rxjs'; -import { first, map, take } from 'rxjs/operators'; -import { SearchConfigurationService } from "../../../core/shared/search/search-configuration.service"; -import { RouteService } from "../../../core/services/route.service"; -import { LinkService } from "../../../core/cache/builders/link.service"; -import { HALEndpointService } from "../../../core/shared/hal-endpoint.service"; -import { RequestService } from "../../../core/data/request.service"; -import { RemoteDataBuildService } from "../../../core/cache/builders/remote-data-build.service"; -import { PaginationService } from "../../../core/pagination/pagination.service"; -import { DspaceRestResponseParsingService } from "../../../core/data/dspace-rest-response-parsing.service"; -import { RemoteData } from "../../../core/data/remote-data"; -import { SearchFilterConfig } from "../../../shared/search/models/search-filter-config.model"; -import { GetRequest } from "../../../core/data/request.models"; -import { GenericConstructor } from "../../../core/shared/generic-constructor"; -import { ResponseParsingService } from "../../../core/data/parsing.service"; -import { FacetConfigResponseParsingService } from "../../../core/data/facet-config-response-parsing.service"; -import { FacetConfigResponse } from "../../../shared/search/models/facet-config-response.model"; -import { hasNoValue, isNotEmpty } from "../../../shared/empty.util"; -import { AdminNotifyFacetResponseParsingService } from "./admin-notify-facet-response-parsing.service"; -import { AdminNotifySearchFilterConfig } from "./admin-notify-search-filter-config"; -import { AdminNotifyFacetConfigResponse } from "./admin-notify-facet-config-response.model"; -import { SearchFilter } from "../../../shared/search/models/search-filter.model"; +import { Observable } from 'rxjs'; +import { map, take } from 'rxjs/operators'; +import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service'; +import { RouteService } from '../../../core/services/route.service'; +import { LinkService } from '../../../core/cache/builders/link.service'; +import { HALEndpointService } from '../../../core/shared/hal-endpoint.service'; +import { RequestService } from '../../../core/data/request.service'; +import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; +import { PaginationService } from '../../../core/pagination/pagination.service'; +import { RemoteData } from '../../../core/data/remote-data'; +import { GetRequest } from '../../../core/data/request.models'; +import { GenericConstructor } from '../../../core/shared/generic-constructor'; +import { ResponseParsingService } from '../../../core/data/parsing.service'; +import { hasNoValue, isNotEmpty } from '../../../shared/empty.util'; +import { AdminNotifyFacetResponseParsingService } from './admin-notify-facet-response-parsing.service'; +import { AdminNotifySearchFilterConfig } from './admin-notify-search-filter-config'; +import { AdminNotifyFacetConfigResponse } from './admin-notify-facet-config-response.model'; +import { SearchFilter } from '../../../shared/search/models/search-filter.model'; @@ -64,7 +60,7 @@ export class AdminNotifySearchConfigurationService extends SearchConfigurationSe * Set prefix to be used for route filters * @param prefix */ - setParamPrefix(prefix: string) : void { + setParamPrefix(prefix: string): void { this.paramPrefix = prefix; } diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts index 8172a52b1d..2372313c0d 100644 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts +++ b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts @@ -1,21 +1,24 @@ import { typedObject } from '../../../core/cache/builders/build-decorators'; -import { SearchFilterConfig } from "../../../shared/search/models/search-filter-config.model"; -import { autoserialize, autoserializeAs, deserialize } from "cerialize"; -import { HALLink } from "../../../core/shared/hal-link.model"; -import { excludeFromEquals } from "../../../core/utilities/equals.decorators"; -import { SEARCH_FILTER_CONFIG } from "../../../shared/search/models/types/search-filter-config.resource-type"; -import { FilterType } from "../../../shared/search/models/filter-type.model"; +import { SearchFilterConfig } from '../../../shared/search/models/search-filter-config.model'; +import { autoserialize, autoserializeAs, deserialize } from 'cerialize'; +import { HALLink } from '../../../core/shared/hal-link.model'; +import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; +import { SEARCH_FILTER_CONFIG } from '../../../shared/search/models/types/search-filter-config.resource-type'; +import { FilterType } from '../../../shared/search/models/filter-type.model'; /** * The configuration for a search filter */ @typedObject export class AdminNotifySearchFilterConfig implements SearchFilterConfig { + static type = SEARCH_FILTER_CONFIG; + + /** + * The prefix of this filter + */ @autoserialize namePrefix: string; - static type = SEARCH_FILTER_CONFIG; - /** * The object type, * hardcoded because rest doesn't set one. @@ -87,4 +90,5 @@ export class AdminNotifySearchFilterConfig implements SearchFilterConfig { */ get paramName(): string { return `${this.namePrefix}.${this.name}`; - }} + } +} diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 7c3f1771da..abfd303799 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -200,9 +200,9 @@ import { NotifyRequestsStatusDataService } from './data/notify-services-status-d import { AdminNotifyMessage } from '../admin/admin-notify-dashboard/models/admin-notify-message.model'; import { AdminNotifyFacetResponseParsingService -} from "../admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service"; -import { FILTER_SEARCH } from "../admin/admin-notify-dashboard/admin-notify-dashboard.component"; -import { AdminNotifySearchFilterService } from "../admin/admin-notify-dashboard/config/admin-notify-filter-service"; +} from '../admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service'; +import { FILTER_SEARCH } from '../admin/admin-notify-dashboard/admin-notify-dashboard.component'; +import { AdminNotifySearchFilterService } from '../admin/admin-notify-dashboard/config/admin-notify-filter-service'; /** diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts index ad64dc36b6..fcf8b334e9 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts @@ -11,7 +11,7 @@ import { hasValue } from '../../../../../empty.util'; import { currentPath } from '../../../../../utils/route.utils'; import { getFacetValueForType } from '../../../../search.utils'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; -import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; +import { FILTER_SEARCH } from '../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-facet-option', diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts index 880262fe17..7d0a575c25 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts @@ -14,7 +14,7 @@ import { SearchConfigurationService } from '../../../../../../core/shared/search import { hasValue } from '../../../../../empty.util'; import { currentPath } from '../../../../../utils/route.utils'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; -import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; +import { FILTER_SEARCH } from '../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; const rangeDelimiter = '-'; diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts index 796a8e652f..25f5883a00 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts @@ -10,7 +10,7 @@ import { FacetValue } from '../../../../models/facet-value.model'; import { currentPath } from '../../../../../utils/route.utils'; import { getFacetValueForType } from '../../../../search.utils'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; -import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; +import { FILTER_SEARCH } from '../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-facet-selected-option', diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index 4d031b30a3..37a540a39c 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -35,7 +35,7 @@ import { currentPath } from '../../../../utils/route.utils'; import { getFacetValueForType, stripOperatorFromFilterValue } from '../../../search.utils'; import { createPendingRemoteDataObject } from '../../../../remote-data.utils'; import { FacetValues } from '../../../models/facet-values.model'; -import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; +import { FILTER_SEARCH } from '../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-facet-filter', diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts index 4ed73345ef..d7967e6642 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, Input, OnInit, Optional } from '@angular/core'; +import { Component, Inject, Input, OnInit } from '@angular/core'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { filter, map, startWith, switchMap, take } from 'rxjs/operators'; @@ -11,7 +11,7 @@ import { SearchService } from '../../../../core/shared/search/search.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { SequenceService } from '../../../../core/shared/sequence.service'; -import { FILTER_SEARCH } from "../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; +import { FILTER_SEARCH } from '../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-filter', diff --git a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts index bbb40781a7..fd62e49e32 100644 --- a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts @@ -26,7 +26,7 @@ import { PageInfo } from '../../../../../core/shared/page-info.model'; import { environment } from '../../../../../../environments/environment'; import { addOperatorToFilterValue } from '../../../search.utils'; import { VocabularyTreeviewModalComponent } from '../../../../form/vocabulary-treeview-modal/vocabulary-treeview-modal.component'; -import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; +import { FILTER_SEARCH } from '../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-hierarchy-filter', diff --git a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts index d15ac1639c..788971b4cb 100644 --- a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts @@ -21,7 +21,7 @@ import { SearchConfigurationService } from '../../../../../core/shared/search/se import { RouteService } from '../../../../../core/services/route.service'; import { hasValue } from '../../../../empty.util'; import { yearFromString } from 'src/app/shared/date.util'; -import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; +import { FILTER_SEARCH } from '../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; /** * The suffix for a range filters' minimum in the frontend URL diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index 7e252e780d..e7bedbb30a 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -12,7 +12,7 @@ import { SearchFilterService } from '../../../core/shared/search/search-filter.s import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; import { currentPath } from '../../utils/route.utils'; import { hasValue } from '../../empty.util'; -import { FILTER_SEARCH } from "../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; +import { FILTER_SEARCH } from '../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-filters', From de8c0c952876119496c0948cfe10d50a5f944388 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Thu, 4 Jan 2024 17:15:25 +0100 Subject: [PATCH 039/142] add tabulatable loader and related configuration --- .../admin-notify-dashboard.component.html | 2 +- .../admin-notify-dashboard.component.ts | 29 ++- .../admin-notify-search-result.component.html | 37 +++- .../admin-notify-search-result.component.ts | 22 +- .../models/admin-notify-message.model.ts | 6 + src/app/core/shared/view-mode.model.ts | 1 + .../object-collection.component.html | 17 ++ ...table-object-component-loader.component.ts | 1 - .../tabulatable-objects.decorator.ts | 194 ++++++++++++++++ .../tabulatable-objects.directive.ts | 11 + ...ulatable-result-list-elements.component.ts | 22 ++ .../object-table/object-table.component.html | 32 +++ .../object-table/object-table.component.scss | 0 .../object-table.component.spec.ts | 23 ++ .../object-table/object-table.component.ts | 209 ++++++++++++++++++ src/app/shared/shared.module.ts | 18 +- 16 files changed, 605 insertions(+), 19 deletions(-) create mode 100644 src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts create mode 100644 src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.directive.ts create mode 100644 src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts create mode 100644 src/app/shared/object-table/object-table.component.html create mode 100644 src/app/shared/object-table/object-table.component.scss create mode 100644 src/app/shared/object-table/object-table.component.spec.ts create mode 100644 src/app/shared/object-table/object-table.component.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html index 37cc33f92a..a8aae4998b 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -12,7 +12,7 @@
-
  • +
  • {{'admin-notify-dashboard.logs' | translate}}
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 5adc71a497..77116d97d3 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -14,6 +14,8 @@ import { SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.compo import { AdminNotifySearchConfigurationService } from './config/admin-notify-search-configuration.service'; import { AdminNotifySearchFilterService } from './config/admin-notify-filter-service'; import { AdminNotifySearchFilterConfig } from './config/admin-notify-search-filter-config'; +import { ViewMode } from "../../core/shared/view-mode.model"; +import { Router } from "@angular/router"; export const FILTER_SEARCH: InjectionToken = new InjectionToken('searchFilterService'); @@ -45,7 +47,8 @@ export class AdminNotifyDashboardComponent implements OnInit{ id: 'single-result-options', pageSize: 1 }); - constructor(private searchService: SearchService) {} + constructor(private searchService: SearchService, + private router: Router) {} ngOnInit() { const mertricsRowsConfigurations = this.metricsConfig @@ -99,4 +102,28 @@ export class AdminNotifyDashboardComponent implements OnInit{ }; }); } + + /** + * Activate Table view mode for search result rendering + */ + activateTableMode() { + this.searchService.setViewMode(ViewMode.Table, this.getSearchLinkParts()); + } + + /** + * @returns {string} The base path to the search page, or the current page when inPlaceSearch is true + */ + public getSearchLink(): string { + return this.searchService.getSearchLink(); + } + + /** + * @returns {string[]} The base path to the search page, or the current page when inPlaceSearch is true, split in separate pieces + */ + public getSearchLinkParts(): string[] { + if (this.searchService) { + return []; + } + return this.getSearchLink().split('/'); + } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html index 40e5cbc195..bc703576b2 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html @@ -1,7 +1,34 @@
    -
    {{indexableObject.queueTimeout ?? 'n/a'}}
    -
    {{indexableObject.source ?? 'n/a'}}
    -
    {{indexableObject.target ?? 'n/a'}}
    -
    {{indexableObject.coarNotifyType ?? 'n/a'}}
    -
    {{indexableObject.queueStatusLabel ?? 'n/a'}}
    +
    + + + + + + + + + + + + + + + + + + + +
    TimestampSourceTargetTypeStatus
    +
    {{object.queueTimeout}}
    +
    +
    {{object.source}}
    +
    +
    {{object.target}}
    +
    +
    {{object.coarNotifyType}}
    +
    +
    {{object.queueStatusLabel}}
    +
    +
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index 0df2159b38..4e2a4088d2 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -1,24 +1,26 @@ import { Component, OnInit } from '@angular/core'; -import { - listableObjectComponent -} from '../../../shared/object-collection/shared/listable-object/listable-object.decorator'; import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model'; import { ViewMode } from '../../../core/shared/view-mode.model'; import { Context } from '../../../core/shared/context.model'; -import { - SearchResultListElementComponent -} from '../../../shared/object-list/search-result-list-element/search-result-list-element.component'; import { AdminNotifyMessage } from '../models/admin-notify-message.model'; +import { + tabulatableObjectsComponent +} from "../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator"; +import { + TabulatableResultListElementsComponent +} from "../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component"; +import { PaginatedList } from "../../../core/data/paginated-list.model"; -@listableObjectComponent(AdminNotifySearchResult, ViewMode.ListElement, Context.CoarNotify) +@tabulatableObjectsComponent(AdminNotifySearchResult, ViewMode.Table, Context.CoarNotify) @Component({ selector: 'ds-admin-notify-search-result', templateUrl: './admin-notify-search-result.component.html', styleUrls: ['./admin-notify-search-result.component.scss'] }) -export class AdminNotifySearchResultComponent extends SearchResultListElementComponent implements OnInit{ - indexableObject: AdminNotifyMessage; +export class AdminNotifySearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifyMessage> implements OnInit{ + public indexableObjects: AdminNotifyMessage[]; ngOnInit() { - this.indexableObject = this.object.indexableObject; + this.indexableObjects = this.objects.page.map(object => object.indexableObject); + console.log(this.objects.page) } } diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts index 42bdc7b3c2..be861861b4 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -56,6 +56,12 @@ export class AdminNotifyMessage extends DSpaceObject { @autoserialize queueStatus: number; + /** + * The status of the queue + */ + @autoserialize + indexableObject: AdminNotifyMessage; + @deserialize _links: { self: { diff --git a/src/app/core/shared/view-mode.model.ts b/src/app/core/shared/view-mode.model.ts index a27cb6954b..9c2f499b3d 100644 --- a/src/app/core/shared/view-mode.model.ts +++ b/src/app/core/shared/view-mode.model.ts @@ -7,4 +7,5 @@ export enum ViewMode { GridElement = 'grid', DetailedListElement = 'detailed', StandalonePage = 'standalone', + Table = 'table', } diff --git a/src/app/shared/object-collection/object-collection.component.html b/src/app/shared/object-collection/object-collection.component.html index 3b0dca80ac..45b82dd859 100644 --- a/src/app/shared/object-collection/object-collection.component.html +++ b/src/app/shared/object-collection/object-collection.component.html @@ -58,3 +58,20 @@ + + diff --git a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts index 7a3cc42bf5..3110283ddd 100644 --- a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts +++ b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts @@ -154,7 +154,6 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges } private instantiateComponent(object: ListableObject, changes?: SimpleChanges): void { - const component = this.getComponent(object.getRenderTypes(), this.viewMode, this.context); const viewContainerRef = this.listableObjectDirective.viewContainerRef; diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts new file mode 100644 index 0000000000..9ab9e7c53d --- /dev/null +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts @@ -0,0 +1,194 @@ +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { Context } from '../../../../core/shared/context.model'; +import { hasNoValue, hasValue, isNotEmpty } from '../../../empty.util'; +import { GenericConstructor } from '../../../../core/shared/generic-constructor'; +import { ListableObject } from '../listable-object.model'; +import { environment } from '../../../../../environments/environment'; +import { ThemeConfig } from '../../../../../config/theme.config'; +import { InjectionToken } from '@angular/core'; + +export const DEFAULT_VIEW_MODE = ViewMode.ListElement; +export const DEFAULT_CONTEXT = Context.Any; +export const DEFAULT_THEME = '*'; + +/** + * A class used to compare two matches and their relevancy to determine which of the two gains priority over the other + * + * "level" represents the index of the first default value that was used to find the match with: + * ViewMode being index 0, Context index 1 and theme index 2. Examples: + * - If a default value was used for context, but not view-mode and theme, the "level" will be 1 + * - If a default value was used for view-mode and context, but not for theme, the "level" will be 0 + * - If no default value was used for any of the fields, the "level" will be 3 + * + * "relevancy" represents the amount of values that didn't require a default value to fall back on. Examples: + * - If a default value was used for theme, but not view-mode and context, the "relevancy" will be 2 + * - If a default value was used for view-mode and context, but not for theme, the "relevancy" will be 1 + * - If a default value was used for all fields, the "relevancy" will be 0 + * - If no default value was used for any of the fields, the "relevancy" will be 3 + * + * To determine which of two MatchRelevancies is the most relevant, we compare "level" and "relevancy" in that order. + * If any of the two is higher than the other, that match is most relevant. Examples: + * - { level: 1, relevancy: 1 } is more relevant than { level: 0, relevancy: 2 } + * - { level: 1, relevancy: 1 } is less relevant than { level: 1, relevancy: 2 } + * - { level: 1, relevancy: 1 } is more relevant than { level: 1, relevancy: 0 } + * - { level: 1, relevancy: 1 } is less relevant than { level: 2, relevancy: 0 } + * - { level: 1, relevancy: 1 } is more relevant than null + */ +class MatchRelevancy { + constructor(public match: any, + public level: number, + public relevancy: number) { + } + + isMoreRelevantThan(otherMatch: MatchRelevancy): boolean { + if (hasNoValue(otherMatch)) { + return true; + } + if (otherMatch.level > this.level) { + return false; + } + if (otherMatch.level === this.level && otherMatch.relevancy > this.relevancy) { + return false; + } + return true; + } + + isLessRelevantThan(otherMatch: MatchRelevancy): boolean { + return !this.isMoreRelevantThan(otherMatch); + } +} + +/** + * Factory to allow us to inject getThemeConfigFor so we can mock it in tests + */ +export const GET_THEME_CONFIG_FOR_FACTORY = new InjectionToken<(str) => ThemeConfig>('getThemeConfigFor', { + providedIn: 'root', + factory: () => getThemeConfigFor +}); + +const map = new Map(); + +/** + * Decorator used for rendering a listable object + * @param objectType The object type or entity type the component represents + * @param viewMode The view mode the component represents + * @param context The optional context the component represents + * @param theme The optional theme for the component + */ +export function tabulatableObjectsComponent(objectsType: string | GenericConstructor, viewMode: ViewMode, context: Context = DEFAULT_CONTEXT, theme = DEFAULT_THEME) { + return function decorator(component: any) { + if (hasNoValue(objectsType)) { + return; + } + if (hasNoValue(map.get(objectsType))) { + map.set(objectsType, new Map()); + } + if (hasNoValue(map.get(objectsType).get(viewMode))) { + map.get(objectsType).set(viewMode, new Map()); + } + if (hasNoValue(map.get(objectsType).get(viewMode).get(context))) { + map.get(objectsType).get(viewMode).set(context, new Map()); + } + map.get(objectsType).get(viewMode).get(context).set(theme, component); + }; +} + +/** + * Getter to retrieve the matching listable object component + * + * Looping over the provided types, it'll attempt to find the best match depending on the {@link MatchRelevancy} returned by getMatch() + * The most relevant match between types is kept and eventually returned + * + * @param types The types of which one should match the listable component + * @param viewMode The view mode that should match the components + * @param context The context that should match the components + * @param theme The theme that should match the components + */ +export function getTabulatableObjectsComponent(types: (string | GenericConstructor)[], viewMode: ViewMode, context: Context = DEFAULT_CONTEXT, theme: string = DEFAULT_THEME) { + let currentBestMatch: MatchRelevancy = null; + for (const type of types) { + const typeMap = map.get(type); + if (hasValue(typeMap)) { + const match = getMatch(typeMap, [viewMode, context, theme], [DEFAULT_VIEW_MODE, DEFAULT_CONTEXT, DEFAULT_THEME]); + if (hasNoValue(currentBestMatch) || currentBestMatch.isLessRelevantThan(match)) { + currentBestMatch = match; + } + } + } + return hasValue(currentBestMatch) ? currentBestMatch.match : null; +} + +/** + * Find an object within a nested map, matching the provided keys as best as possible, falling back on defaults wherever + * needed. + * + * Starting off with a Map, it loops over the provided keys, going deeper into the map until it finds a value + * If at some point, no value is found, it'll attempt to use the default value for that index instead + * If the default value exists, the index is stored in the "level" + * If no default value exists, 1 is added to "relevancy" + * See {@link MatchRelevancy} what these represent + * + * @param typeMap a multi-dimensional map + * @param keys the keys of the multi-dimensional map to loop over. Each key represents a level within the map + * @param defaults the default values to use for each level, in case no value is found for the key at that index + * @returns matchAndLevel a {@link MatchRelevancy} object containing the match and its level of relevancy + */ +function getMatch(typeMap: Map, keys: any[], defaults: any[]): MatchRelevancy { + let currentMap = typeMap; + let level = -1; + let relevancy = 0; + for (let i = 0; i < keys.length; i++) { + // If we're currently checking the theme, resolve it first to take extended themes into account + let currentMatch = defaults[i] === DEFAULT_THEME ? resolveTheme(currentMap, keys[i]) : currentMap.get(keys[i]); + if (hasNoValue(currentMatch)) { + currentMatch = currentMap.get(defaults[i]); + if (level === -1) { + level = i; + } + } else { + relevancy++; + } + if (hasValue(currentMatch)) { + if (currentMatch instanceof Map) { + currentMap = currentMatch as Map; + } else { + return new MatchRelevancy(currentMatch, level > -1 ? level : i + 1, relevancy); + } + } else { + return null; + } + } + return null; +} + +/** + * Searches for a ThemeConfig by its name; + */ +export const getThemeConfigFor = (themeName: string): ThemeConfig => { + return environment.themes.find(theme => theme.name === themeName); +}; + +/** + * Find a match in the given map for the given theme name, taking theme extension into account + * + * @param contextMap A map of theme names to components + * @param themeName The name of the theme to check + * @param checkedThemeNames The list of theme names that are already checked + */ +export const resolveTheme = (contextMap: Map, themeName: string, checkedThemeNames: string[] = []): any => { + const match = contextMap.get(themeName); + if (hasValue(match)) { + return match; + } else { + const cfg = getThemeConfigFor(themeName); + if (hasValue(cfg) && isNotEmpty(cfg.extends)) { + const nextTheme = cfg.extends; + const nextCheckedThemeNames = [...checkedThemeNames, themeName]; + if (checkedThemeNames.includes(nextTheme)) { + throw new Error('Theme extension cycle detected: ' + [...nextCheckedThemeNames, nextTheme].join(' -> ')); + } else { + return resolveTheme(contextMap, nextTheme, nextCheckedThemeNames); + } + } + } +}; diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.directive.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.directive.ts new file mode 100644 index 0000000000..88c12dfe76 --- /dev/null +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.directive.ts @@ -0,0 +1,11 @@ +import { Directive, ViewContainerRef } from '@angular/core'; + +@Directive({ + selector: '[dsTabulatableObjects]', +}) +/** + * Directive used as a hook to know where to inject the dynamic listable object component + */ +export class TabulatableObjectsDirective { + constructor(public viewContainerRef: ViewContainerRef) { } +} diff --git a/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts new file mode 100644 index 0000000000..5aa2ca84ee --- /dev/null +++ b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts @@ -0,0 +1,22 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { + AbstractTabulatableElementComponent +} from "../../../object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component"; +import { DSpaceObject } from "../../../../core/shared/dspace-object.model"; +import { TruncatableService } from "../../../truncatable/truncatable.service"; +import { DSONameService } from "../../../../core/breadcrumbs/dso-name.service"; +import { APP_CONFIG, AppConfig } from "../../../../../config/app-config.interface"; +import { PaginatedList } from "../../../../core/data/paginated-list.model"; + +@Component({ + selector: 'ds-search-result-list-element', + template: `` +}) +export class TabulatableResultListElementsComponent, K extends DSpaceObject> extends AbstractTabulatableElementComponent { + public constructor(protected truncatableService: TruncatableService, + public dsoNameService: DSONameService, + @Inject(APP_CONFIG) protected appConfig?: AppConfig) { + super(dsoNameService); + } + +} diff --git a/src/app/shared/object-table/object-table.component.html b/src/app/shared/object-table/object-table.component.html new file mode 100644 index 0000000000..a4fe8cfc38 --- /dev/null +++ b/src/app/shared/object-table/object-table.component.html @@ -0,0 +1,32 @@ + +
    +
    + + +
    +
    + + +
    + + diff --git a/src/app/shared/object-table/object-table.component.scss b/src/app/shared/object-table/object-table.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/shared/object-table/object-table.component.spec.ts b/src/app/shared/object-table/object-table.component.spec.ts new file mode 100644 index 0000000000..b20bed8d89 --- /dev/null +++ b/src/app/shared/object-table/object-table.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ObjectTableComponent } from './object-table.component'; + +describe('ObjectTableComponent', () => { + let component: ObjectTableComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ObjectTableComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ObjectTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/object-table/object-table.component.ts b/src/app/shared/object-table/object-table.component.ts new file mode 100644 index 0000000000..c202c0b865 --- /dev/null +++ b/src/app/shared/object-table/object-table.component.ts @@ -0,0 +1,209 @@ +import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core'; +import { ViewMode } from "../../core/shared/view-mode.model"; +import { PaginationComponentOptions } from "../pagination/pagination-component-options.model"; +import { SortDirection, SortOptions } from "../../core/cache/models/sort-options.model"; +import { CollectionElementLinkType } from "../object-collection/collection-element-link.type"; +import { Context } from "../../core/shared/context.model"; +import { BehaviorSubject} from "rxjs"; +import { RemoteData } from "../../core/data/remote-data"; +import { PaginatedList } from "../../core/data/paginated-list.model"; +import { ListableObject } from "../object-collection/shared/listable-object.model"; +import { fadeIn } from "../animations/fade"; + + +@Component({ + changeDetection: ChangeDetectionStrategy.Default, + encapsulation: ViewEncapsulation.Emulated, + selector: 'ds-object-table', + templateUrl: './object-table.component.html', + styleUrls: ['./object-table.component.scss'], + animations: [fadeIn] +}) +export class ObjectTableComponent { + /** + * The view mode of this component + */ + viewMode = ViewMode.Table; + + /** + * The current pagination configuration + */ + @Input() config: PaginationComponentOptions; + + /** + * The current sort configuration + */ + @Input() sortConfig: SortOptions; + + /** + * Whether or not the pagination should be rendered as simple previous and next buttons instead of the normal pagination + */ + @Input() showPaginator = true; + + /** + * Whether to show the thumbnail preview + */ + @Input() showThumbnails; + + /** + * The whether or not the gear is hidden + */ + @Input() hideGear = false; + + /** + * Whether or not the pager is visible when there is only a single page of results + */ + @Input() hidePagerWhenSinglePage = true; + + /** + * The link type of the listable elements + */ + @Input() linkType: CollectionElementLinkType; + + /** + * The context of the listable elements + */ + @Input() context: Context; + + /** + * Option for hiding the pagination detail + */ + @Input() hidePaginationDetail = false; + + /** + * Behavior subject to output the current listable objects + */ + private _objects$: BehaviorSubject>>; + + /** + * Setter to make sure the observable is turned into an observable + * @param objects The new objects to output + */ + @Input() set objects(objects: RemoteData>) { + this._objects$.next(objects); + } + + /** + * Getter to return the current objects + */ + get objects() { + return this._objects$.getValue(); + } + + /** + * An event fired when the page is changed. + * Event's payload equals to the newly selected page. + */ + @Output() change: EventEmitter<{ + pagination: PaginationComponentOptions, + sort: SortOptions + }> = new EventEmitter<{ + pagination: PaginationComponentOptions, + sort: SortOptions + }>(); + + /** + * An event fired when the page is changed. + * Event's payload equals to the newly selected page. + */ + @Output() pageChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when the page wsize is changed. + * Event's payload equals to the newly selected page size. + */ + @Output() pageSizeChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when the sort direction is changed. + * Event's payload equals to the newly selected sort direction. + */ + @Output() sortDirectionChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when on of the pagination parameters changes + */ + @Output() paginationChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when the sort field is changed. + * Event's payload equals to the newly selected sort field. + */ + @Output() sortFieldChange: EventEmitter = new EventEmitter(); + + /** + * If showPaginator is set to true, emit when the previous button is clicked + */ + @Output() prev = new EventEmitter(); + + /** + * If showPaginator is set to true, emit when the next button is clicked + */ + @Output() next = new EventEmitter(); + + data: any = {}; + + constructor() { + this._objects$ = new BehaviorSubject(undefined); + } + + /** + * Initialize the instance variables + */ + ngOnInit(): void { + console.log('table rendered') + } + + /** + * Emits the current page when it changes + * @param event The new page + */ + onPageChange(event) { + this.pageChange.emit(event); + } + /** + * Emits the current page size when it changes + * @param event The new page size + */ + onPageSizeChange(event) { + this.pageSizeChange.emit(event); + } + /** + * Emits the current sort direction when it changes + * @param event The new sort direction + */ + onSortDirectionChange(event) { + this.sortDirectionChange.emit(event); + } + + /** + * Emits the current sort field when it changes + * @param event The new sort field + */ + onSortFieldChange(event) { + this.sortFieldChange.emit(event); + } + + /** + * Emits the current pagination when it changes + * @param event The new pagination + */ + onPaginationChange(event) { + this.paginationChange.emit(event); + } + + /** + * Go to the previous page + */ + goPrev() { + this.prev.emit(true); + } + + /** + * Go to the next page + */ + goNext() { + this.next.emit(true); + } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 61482fb61a..ce4cb1ed06 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -286,6 +286,17 @@ import { SplitPipe } from './utils/split.pipe'; import { ThemedUserMenuComponent } from './auth-nav-menu/user-menu/themed-user-menu.component'; import { ThemedLangSwitchComponent } from './lang-switch/themed-lang-switch.component'; import { NotificationBoxComponent } from './notification-box/notification-box.component'; +import { ObjectTableComponent } from './object-table/object-table.component'; +import { TabulatableObjectsLoaderComponent } from './object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component'; +import { + TabulatableObjectsDirective +} from "./object-collection/shared/tabulatable-objects/tabulatable-objects.directive"; +import { + AbstractTabulatableElementComponent +} from "./object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component"; +import { + TabulatableResultListElementsComponent +} from "./object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component"; const MODULES = [ CommonModule, @@ -349,7 +360,9 @@ const COMPONENTS = [ ThemedObjectListComponent, ObjectDetailComponent, ObjectGridComponent, + ObjectTableComponent, AbstractListableElementComponent, + AbstractTabulatableElementComponent, ObjectCollectionComponent, PaginationComponent, RSSComponent, @@ -415,6 +428,7 @@ const ENTRY_COMPONENTS = [ CollectionListElementComponent, CommunityListElementComponent, SearchResultListElementComponent, + TabulatableResultListElementsComponent, CommunitySearchResultListElementComponent, CollectionSearchResultListElementComponent, CollectionGridElementComponent, @@ -471,7 +485,8 @@ const ENTRY_COMPONENTS = [ EpersonGroupListComponent, EpersonSearchBoxComponent, GroupSearchBoxComponent, - NotificationBoxComponent + NotificationBoxComponent, + TabulatableObjectsLoaderComponent, ]; const PROVIDERS = [ @@ -490,6 +505,7 @@ const DIRECTIVES = [ RoleDirective, MetadataRepresentationDirective, ListableObjectDirective, + TabulatableObjectsDirective, ClaimedTaskActionsDirective, FileValueAccessorDirective, FileValidator, From b8e353d51c5fb58d286152dd2b36bea41a76b84f Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Thu, 4 Jan 2024 17:16:21 +0100 Subject: [PATCH 040/142] add tabulatable loader missing files --- ...bjects-collection-tabulatable.component.ts | 83 +++++++ .../tabulatable-objects-loader.component.html | 1 + .../tabulatable-objects-loader.component.scss | 3 + ...bulatable-objects-loader.component.spec.ts | 23 ++ .../tabulatable-objects-loader.component.ts | 207 ++++++++++++++++++ 5 files changed, 317 insertions(+) create mode 100644 src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts create mode 100644 src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.html create mode 100644 src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.scss create mode 100644 src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts create mode 100644 src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts diff --git a/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts b/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts new file mode 100644 index 0000000000..57b7c39771 --- /dev/null +++ b/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts @@ -0,0 +1,83 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { ListableObject } from "../listable-object.model"; +import { CollectionElementLinkType } from "../../collection-element-link.type"; +import { Context } from "../../../../core/shared/context.model"; +import { ViewMode } from "../../../../core/shared/view-mode.model"; +import { DSpaceObject } from "../../../../core/shared/dspace-object.model"; +import { DSONameService } from "../../../../core/breadcrumbs/dso-name.service"; +import { RemoteData } from "../../../../core/data/remote-data"; +import { PaginatedList } from "../../../../core/data/paginated-list.model"; + +@Component({ + selector: 'ds-objects-collection-tabulatable', + template: ``, +}) +export class AbstractTabulatableElementComponent> { + + /** + * The object to render in this list element + */ + @Input() objects: T; + + /** + * The link type to determine the type of link rendered in this element + */ + @Input() linkType: CollectionElementLinkType; + + /** + * The identifier of the list this element resides in + */ + @Input() listID: string; + + /** + * The value to display for this element + */ + @Input() value: string; + + /** + * Whether to show the badge label or not + */ + @Input() showLabel = true; + + /** + * Whether to show the thumbnail preview + */ + @Input() showThumbnails; + + /** + * The context we matched on to get this component + */ + @Input() context: Context; + + /** + * The viewmode we matched on to get this component + */ + @Input() viewMode: ViewMode; + + /** + * Emit when the object has been reloaded. + */ + @Output() reloadedObject = new EventEmitter>>(); + + /** + * The available link types + */ + linkTypes = CollectionElementLinkType; + + /** + * The available view modes + */ + viewModes = ViewMode; + + /** + * The available contexts + */ + contexts = Context; + + constructor( + public dsoNameService: DSONameService, + ) { + } + +} + diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.html b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.html new file mode 100644 index 0000000000..ff51746cb9 --- /dev/null +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.html @@ -0,0 +1 @@ + diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.scss b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.scss new file mode 100644 index 0000000000..b9bc65ea45 --- /dev/null +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.scss @@ -0,0 +1,3 @@ +:host { + width: 100%; +} diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts new file mode 100644 index 0000000000..59d0a42ecd --- /dev/null +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TabulatableObjectsLoaderComponent } from './tabulatable-objects-loader.component'; + +describe('TabulatableObjectsComponent', () => { + let component: TabulatableObjectsLoaderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ TabulatableObjectsLoaderComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TabulatableObjectsLoaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts new file mode 100644 index 0000000000..b3c83294b4 --- /dev/null +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts @@ -0,0 +1,207 @@ +import { + ChangeDetectorRef, + Component, + ComponentRef, + EventEmitter, + Input, + OnChanges, + OnDestroy, + OnInit, + Output, + SimpleChanges, + ViewChild +} from '@angular/core'; +import { ListableObject } from "../listable-object.model"; +import { ViewMode } from "../../../../core/shared/view-mode.model"; +import { Context } from "../../../../core/shared/context.model"; +import { CollectionElementLinkType } from "../../collection-element-link.type"; +import { combineLatest, Observable, of as observableOf, Subscription } from "rxjs"; +import { ThemeService } from "../../../theme-support/theme.service"; +import { hasNoValue, hasValue, isNotEmpty } from "../../../empty.util"; +import { take } from "rxjs/operators"; +import { GenericConstructor } from "../../../../core/shared/generic-constructor"; +import { TabulatableObjectsDirective } from "./tabulatable-objects.directive"; +import { PaginatedList } from "../../../../core/data/paginated-list.model"; +import { getTabulatableObjectsComponent } from "./tabulatable-objects.decorator"; + +@Component({ + selector: 'ds-tabulatable-objects-loader', + templateUrl: './tabulatable-objects-loader.component.html', + styleUrls: ['./tabulatable-objects-loader.component.scss'] +}) +/** + * Component for determining what component to use depending on the item's entity type (dspace.entity.type) + */ +export class TabulatableObjectsLoaderComponent implements OnInit, OnChanges, OnDestroy { + /** + * The items to determine the component for + */ + @Input() objects: PaginatedList; + + + /** + * The context of listable object + */ + @Input() context: Context; + + /** + * The type of link used to render the links inside the listable object + */ + @Input() linkType: CollectionElementLinkType; + + /** + * The identifier of the list this element resides in + */ + @Input() listID: string; + + /** + * Whether to show the badge label or not + */ + @Input() showLabel = true; + + /** + * Whether to show the thumbnail preview + */ + @Input() showThumbnails; + + /** + * The value to display for this element + */ + @Input() value: string; + + /** + * Directive hook used to place the dynamic child component + */ + @ViewChild(TabulatableObjectsDirective, { static: true }) tabulatableObjectsDirective: TabulatableObjectsDirective; + + /** + * Emit when the listable object has been reloaded. + */ + @Output() contentChange = new EventEmitter>(); + + /** + * Array to track all subscriptions and unsubscribe them onDestroy + * @type {Array} + */ + protected subs: Subscription[] = []; + + /** + * The reference to the dynamic component + */ + protected compRef: ComponentRef; + + /** + * The view mode used to identify the components + */ + protected viewMode: ViewMode = ViewMode.Table; + + /** + * The list of input and output names for the dynamic component + */ + protected inAndOutputNames: string[] = [ + 'objects', + 'linkType', + 'listID', + 'showLabel', + 'showThumbnails', + 'context', + 'viewMode', + 'value', + 'hideBadges', + 'contentChange', + ]; + + constructor(private cdr: ChangeDetectorRef, private themeService: ThemeService) { + } + + /** + * Setup the dynamic child component + */ + ngOnInit(): void { + this.instantiateComponent(this.objects); + } + + /** + * Whenever the inputs change, update the inputs of the dynamic component + */ + ngOnChanges(changes: SimpleChanges): void { + if (hasNoValue(this.compRef)) { + // sometimes the component has not been initialized yet, so it first needs to be initialized + // before being called again + this.instantiateComponent(this.objects, changes); + } else { + // if an input or output has changed + if (this.inAndOutputNames.some((name: any) => hasValue(changes[name]))) { + this.connectInputsAndOutputs(); + if (this.compRef?.instance && 'ngOnChanges' in this.compRef.instance) { + (this.compRef.instance as any).ngOnChanges(changes); + } + } + } + } + + ngOnDestroy() { + this.subs + .filter((subscription) => hasValue(subscription)) + .forEach((subscription) => subscription.unsubscribe()); + } + + private instantiateComponent(objects: PaginatedList, changes?: SimpleChanges): void { + // objects need to have same render type so we access just the first in the page + const component = this.getComponent(objects.page[0].getRenderTypes(), this.viewMode, this.context); + + const viewContainerRef = this.tabulatableObjectsDirective.viewContainerRef; + viewContainerRef.clear(); + + this.compRef = viewContainerRef.createComponent( + component, { + index: 0, + injector: undefined + } + ); + + if (hasValue(changes)) { + this.ngOnChanges(changes); + } else { + this.connectInputsAndOutputs(); + } + + if ((this.compRef.instance as any).reloadedObject) { + combineLatest([ + observableOf(changes), + (this.compRef.instance as any).reloadedObject.pipe(take(1)) as Observable>, + ]).subscribe(([simpleChanges, reloadedObjects]: [SimpleChanges, PaginatedList]) => { + if (reloadedObjects) { + this.compRef.destroy(); + this.objects = reloadedObjects; + this.instantiateComponent(reloadedObjects, simpleChanges); + this.cdr.detectChanges(); + this.contentChange.emit(reloadedObjects); + } + }); + } + } + + /** + * Fetch the component depending on the item's entity type, view mode and context + * @returns {GenericConstructor} + */ + getComponent(renderTypes: (string | GenericConstructor)[], + viewMode: ViewMode, + context: Context): GenericConstructor { + return getTabulatableObjectsComponent(renderTypes, viewMode, context, this.themeService.getThemeName()); + } + + /** + * Connect the in and outputs of this component to the dynamic component, + * to ensure they're in sync + */ + protected connectInputsAndOutputs(): void { + if (isNotEmpty(this.inAndOutputNames) && hasValue(this.compRef) && hasValue(this.compRef.instance)) { + this.inAndOutputNames.filter((name: any) => this[name] !== undefined).forEach((name: any) => { + this.compRef.instance[name] = this[name]; + }); + } + } + +} From 566c8b34a992676cb2a9bc4bf062f8a9fbca9614 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Thu, 4 Jan 2024 17:21:03 +0100 Subject: [PATCH 041/142] remove log --- .../admin-notify-search-result.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index 4e2a4088d2..3ee86eb3ea 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -21,6 +21,5 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListElem public indexableObjects: AdminNotifyMessage[]; ngOnInit() { this.indexableObjects = this.objects.page.map(object => object.indexableObject); - console.log(this.objects.page) } } From c434c06b04034c0e3542bc74a908127e390b6da2 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Thu, 4 Jan 2024 17:23:29 +0100 Subject: [PATCH 042/142] refactor, fix lint --- .../admin-notify-dashboard.component.ts | 4 ++-- .../admin-notify-search-result.component.html | 14 +++++------ .../admin-notify-search-result.component.ts | 10 ++++---- src/app/core/shared/search/search.service.ts | 8 +++---- ...bjects-collection-tabulatable.component.ts | 15 ++++++------ .../tabulatable-objects-loader.component.ts | 24 +++++++++---------- ...ulatable-result-list-elements.component.ts | 14 +++++------ .../object-table/object-table.component.ts | 22 ++++++++--------- src/app/shared/shared.module.ts | 6 ++--- 9 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 77116d97d3..ba88ce4e6d 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -14,8 +14,8 @@ import { SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.compo import { AdminNotifySearchConfigurationService } from './config/admin-notify-search-configuration.service'; import { AdminNotifySearchFilterService } from './config/admin-notify-filter-service'; import { AdminNotifySearchFilterConfig } from './config/admin-notify-search-filter-config'; -import { ViewMode } from "../../core/shared/view-mode.model"; -import { Router } from "@angular/router"; +import { ViewMode } from '../../core/shared/view-mode.model'; +import { Router } from '@angular/router'; export const FILTER_SEARCH: InjectionToken = new InjectionToken('searchFilterService'); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html index bc703576b2..89b2285422 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html @@ -1,4 +1,4 @@ -
    +
    @@ -11,21 +11,21 @@ - + diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index 3ee86eb3ea..93eca302c1 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -5,11 +5,11 @@ import { Context } from '../../../core/shared/context.model'; import { AdminNotifyMessage } from '../models/admin-notify-message.model'; import { tabulatableObjectsComponent -} from "../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator"; +} from '../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator'; import { TabulatableResultListElementsComponent -} from "../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component"; -import { PaginatedList } from "../../../core/data/paginated-list.model"; +} from '../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; +import { PaginatedList } from '../../../core/data/paginated-list.model'; @tabulatableObjectsComponent(AdminNotifySearchResult, ViewMode.Table, Context.CoarNotify) @Component({ @@ -18,8 +18,8 @@ import { PaginatedList } from "../../../core/data/paginated-list.model"; styleUrls: ['./admin-notify-search-result.component.scss'] }) export class AdminNotifySearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifyMessage> implements OnInit{ - public indexableObjects: AdminNotifyMessage[]; + public notifyMessages: AdminNotifyMessage[]; ngOnInit() { - this.indexableObjects = this.objects.page.map(object => object.indexableObject); + this.notifyMessages = this.objects.page.map(object => object.indexableObject); } } diff --git a/src/app/core/shared/search/search.service.ts b/src/app/core/shared/search/search.service.ts index 9d85d0db5f..986352f29f 100644 --- a/src/app/core/shared/search/search.service.ts +++ b/src/app/core/shared/search/search.service.ts @@ -188,11 +188,11 @@ export class SearchService implements OnDestroy { } /** - * Method to directly attach the indexableObjects to search results, instead of using RemoteData. + * Method to directly attach the notifyMessages to search results, instead of using RemoteData. * For compatibility with the way the search was written originally * * @param sqr$: a SearchObjects RemotaData Observable without its - * indexableObjects attached + * notifyMessages attached * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's * no valid cached version. Defaults to true * @param reRequestOnStale Whether or not the request should automatically be re- @@ -205,7 +205,7 @@ export class SearchService implements OnDestroy { return sqr$.pipe( switchMap((resultsRd: RemoteData>) => { if (hasValue(resultsRd.payload) && isNotEmpty(resultsRd.payload.page)) { - // retrieve the indexableObjects for all search results on the page + // retrieve the notifyMessages for all search results on the page const searchResult$Array: Observable>[] = resultsRd.payload.page.map((result: SearchResult) => this.dspaceObjectService.findByHref(result._links.indexableObject.href, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow as any).pipe( getFirstCompletedRemoteData(), @@ -227,7 +227,7 @@ export class SearchService implements OnDestroy { ); // Swap the original page in the remoteData with the new one, now that the results have the - // correct types, and all indexableObjects are directly attached. + // correct types, and all notifyMessages are directly attached. return observableCombineLatest(searchResult$Array).pipe( map((page: SearchResult[]) => { diff --git a/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts b/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts index 57b7c39771..c6b6b1bb5b 100644 --- a/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts +++ b/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts @@ -1,12 +1,11 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { ListableObject } from "../listable-object.model"; -import { CollectionElementLinkType } from "../../collection-element-link.type"; -import { Context } from "../../../../core/shared/context.model"; -import { ViewMode } from "../../../../core/shared/view-mode.model"; -import { DSpaceObject } from "../../../../core/shared/dspace-object.model"; -import { DSONameService } from "../../../../core/breadcrumbs/dso-name.service"; -import { RemoteData } from "../../../../core/data/remote-data"; -import { PaginatedList } from "../../../../core/data/paginated-list.model"; +import { ListableObject } from '../listable-object.model'; +import { CollectionElementLinkType } from '../../collection-element-link.type'; +import { Context } from '../../../../core/shared/context.model'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; +import { RemoteData } from '../../../../core/data/remote-data'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; @Component({ selector: 'ds-objects-collection-tabulatable', diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts index b3c83294b4..1c68718bd6 100644 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts @@ -11,18 +11,18 @@ import { SimpleChanges, ViewChild } from '@angular/core'; -import { ListableObject } from "../listable-object.model"; -import { ViewMode } from "../../../../core/shared/view-mode.model"; -import { Context } from "../../../../core/shared/context.model"; -import { CollectionElementLinkType } from "../../collection-element-link.type"; -import { combineLatest, Observable, of as observableOf, Subscription } from "rxjs"; -import { ThemeService } from "../../../theme-support/theme.service"; -import { hasNoValue, hasValue, isNotEmpty } from "../../../empty.util"; -import { take } from "rxjs/operators"; -import { GenericConstructor } from "../../../../core/shared/generic-constructor"; -import { TabulatableObjectsDirective } from "./tabulatable-objects.directive"; -import { PaginatedList } from "../../../../core/data/paginated-list.model"; -import { getTabulatableObjectsComponent } from "./tabulatable-objects.decorator"; +import { ListableObject } from '../listable-object.model'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { Context } from '../../../../core/shared/context.model'; +import { CollectionElementLinkType } from '../../collection-element-link.type'; +import { combineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; +import { ThemeService } from '../../../theme-support/theme.service'; +import { hasNoValue, hasValue, isNotEmpty } from '../../../empty.util'; +import { take } from 'rxjs/operators'; +import { GenericConstructor } from '../../../../core/shared/generic-constructor'; +import { TabulatableObjectsDirective } from './tabulatable-objects.directive'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; +import { getTabulatableObjectsComponent } from './tabulatable-objects.decorator'; @Component({ selector: 'ds-tabulatable-objects-loader', diff --git a/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts index 5aa2ca84ee..ed30e78c73 100644 --- a/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts +++ b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts @@ -1,12 +1,12 @@ -import { Component, Inject, OnInit } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { AbstractTabulatableElementComponent -} from "../../../object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component"; -import { DSpaceObject } from "../../../../core/shared/dspace-object.model"; -import { TruncatableService } from "../../../truncatable/truncatable.service"; -import { DSONameService } from "../../../../core/breadcrumbs/dso-name.service"; -import { APP_CONFIG, AppConfig } from "../../../../../config/app-config.interface"; -import { PaginatedList } from "../../../../core/data/paginated-list.model"; +} from '../../../object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component'; +import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; +import { TruncatableService } from '../../../truncatable/truncatable.service'; +import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; +import { APP_CONFIG, AppConfig } from '../../../../../config/app-config.interface'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; @Component({ selector: 'ds-search-result-list-element', diff --git a/src/app/shared/object-table/object-table.component.ts b/src/app/shared/object-table/object-table.component.ts index c202c0b865..b046818707 100644 --- a/src/app/shared/object-table/object-table.component.ts +++ b/src/app/shared/object-table/object-table.component.ts @@ -1,14 +1,14 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core'; -import { ViewMode } from "../../core/shared/view-mode.model"; -import { PaginationComponentOptions } from "../pagination/pagination-component-options.model"; -import { SortDirection, SortOptions } from "../../core/cache/models/sort-options.model"; -import { CollectionElementLinkType } from "../object-collection/collection-element-link.type"; -import { Context } from "../../core/shared/context.model"; -import { BehaviorSubject} from "rxjs"; -import { RemoteData } from "../../core/data/remote-data"; -import { PaginatedList } from "../../core/data/paginated-list.model"; -import { ListableObject } from "../object-collection/shared/listable-object.model"; -import { fadeIn } from "../animations/fade"; +import { ViewMode } from '../../core/shared/view-mode.model'; +import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; +import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; +import { CollectionElementLinkType } from '../object-collection/collection-element-link.type'; +import { Context } from '../../core/shared/context.model'; +import { BehaviorSubject} from 'rxjs'; +import { RemoteData } from '../../core/data/remote-data'; +import { PaginatedList } from '../../core/data/paginated-list.model'; +import { ListableObject } from '../object-collection/shared/listable-object.model'; +import { fadeIn } from '../animations/fade'; @Component({ @@ -151,7 +151,7 @@ export class ObjectTableComponent { * Initialize the instance variables */ ngOnInit(): void { - console.log('table rendered') + console.log('table rendered'); } /** diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index ce4cb1ed06..7e95ba74ee 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -290,13 +290,13 @@ import { ObjectTableComponent } from './object-table/object-table.component'; import { TabulatableObjectsLoaderComponent } from './object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component'; import { TabulatableObjectsDirective -} from "./object-collection/shared/tabulatable-objects/tabulatable-objects.directive"; +} from './object-collection/shared/tabulatable-objects/tabulatable-objects.directive'; import { AbstractTabulatableElementComponent -} from "./object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component"; +} from './object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component'; import { TabulatableResultListElementsComponent -} from "./object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component"; +} from './object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; const MODULES = [ CommonModule, From 6254efa0849bd6d5a8f1f3b31d2271c421970c24 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 5 Jan 2024 12:54:35 +0100 Subject: [PATCH 043/142] add modal, refine table,refactor, fix lint --- .../admin-notify-dashboard.module.ts | 4 +- .../admin-notify-detail-modal.component.html | 14 +++ .../admin-notify-detail-modal.component.scss | 0 ...dmin-notify-detail-modal.component.spec.ts | 23 ++++ .../admin-notify-detail-modal.component.ts | 32 ++++++ .../admin-notify-search-result.component.html | 19 ++-- .../admin-notify-search-result.component.ts | 54 ++++++++- .../models/admin-notify-message.model.ts | 31 ++++- .../object-collection.component.html | 31 +++-- .../listable-object.decorator.ts | 2 +- .../tabulatable-objects.decorator.ts | 106 ++---------------- ...ulatable-result-list-elements.component.ts | 4 +- .../object-table/object-table.component.html | 3 +- .../object-table/object-table.component.ts | 8 -- 14 files changed, 188 insertions(+), 143 deletions(-) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.scss create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts index 06747dd2d5..23200bb9fc 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts @@ -12,6 +12,7 @@ import { AdminNotifySearchResultComponent } from './admin-notify-search-result/a import { AdminNotifyOutgoingComponent } from './admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component'; +import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal/admin-notify-detail-modal.component'; @NgModule({ @@ -28,7 +29,8 @@ import { AdminNotifyMetricsComponent, AdminNotifyIncomingComponent, AdminNotifyOutgoingComponent, - AdminNotifySearchResultComponent + AdminNotifySearchResultComponent, + AdminNotifyDetailModalComponent ] }) export class AdminNotifyDashboardModule { diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html new file mode 100644 index 0000000000..57e1b40c1d --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html @@ -0,0 +1,14 @@ + + diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts new file mode 100644 index 0000000000..7ac979050c --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal.component'; + +describe('AdminNotifyDetailModalComponent', () => { + let component: AdminNotifyDetailModalComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AdminNotifyDetailModalComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminNotifyDetailModalComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts new file mode 100644 index 0000000000..3227e52420 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts @@ -0,0 +1,32 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { AdminNotifyMessage } from '../models/admin-notify-message.model'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + selector: 'ds-admin-notify-detail-modal', + templateUrl: './admin-notify-detail-modal.component.html', + styleUrls: ['./admin-notify-detail-modal.component.scss'] +}) +export class AdminNotifyDetailModalComponent { + @Input() notifyMessage: AdminNotifyMessage; + @Input() notifyMessageKeys: string[]; + + /** + * An event fired when the modal is closed + */ + @Output() + response = new EventEmitter(); + + + constructor(protected activeModal: NgbActiveModal) { + } + + + /** + * Close the modal and set the response to true so RootComponent knows the modal was closed + */ + closeModal() { + this.activeModal.close(); + this.response.emit(true); + } +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html index 89b2285422..80c7faa086 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html @@ -1,22 +1,22 @@ -
    -
    -
    -
    {{object.queueTimeout}}
    +
    {{message.queueTimeout}}
    -
    {{object.source}}
    +
    {{message.source}}
    -
    {{object.target}}
    +
    {{message.target}}
    -
    {{object.coarNotifyType}}
    +
    {{message.coarNotifyType}}
    -
    {{object.queueStatusLabel}}
    +
    {{message.queueStatusLabel}}
    +
    +
    - + + +
    TimestampSourceOrigin Target Type StatusAction
    -
    {{message.queueTimeout}}
    +
    {{message.queueTimeout}}
    -
    {{message.source}}
    +
    {{message.origin}}
    {{message.target}}
    @@ -27,8 +27,13 @@
    {{message.queueStatusLabel}}
    +
    + + +
    +
    -
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index 93eca302c1..f0c9e3f7d8 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, Inject, OnInit } from '@angular/core'; import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model'; import { ViewMode } from '../../../core/shared/view-mode.model'; import { Context } from '../../../core/shared/context.model'; @@ -10,16 +10,60 @@ import { TabulatableResultListElementsComponent } from '../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { TruncatableService } from '../../../shared/truncatable/truncatable.service'; +import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; +import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface'; +import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component'; -@tabulatableObjectsComponent(AdminNotifySearchResult, ViewMode.Table, Context.CoarNotify) +@tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotify) @Component({ selector: 'ds-admin-notify-search-result', templateUrl: './admin-notify-search-result.component.html', styleUrls: ['./admin-notify-search-result.component.scss'] }) -export class AdminNotifySearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifyMessage> implements OnInit{ +export class AdminNotifySearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifySearchResult> implements OnInit{ public notifyMessages: AdminNotifyMessage[]; - ngOnInit() { - this.notifyMessages = this.objects.page.map(object => object.indexableObject); + + private queueStatusMap = { + QUEUE_STATUS_PROCESSED: 'Processed', + QUEUE_STATUS_FAILED: 'Failed', + QUEUE_STATUS_UNMAPPED_ACTION: 'Unmapped action', + }; + + constructor(private modalService: NgbModal, + protected truncatableService: TruncatableService, + public dsoNameService: DSONameService, + @Inject(APP_CONFIG) protected appConfig?: AppConfig) { + super(truncatableService, dsoNameService, appConfig); } + + /** + * Map messages on init for readable representation + */ + ngOnInit() { + this.notifyMessages = this.objects.page.map(object => { + const indexableObject = object.indexableObject; + indexableObject.coarNotifyType = indexableObject.coarNotifyType.split(':')[1]; + indexableObject.queueStatusLabel = this.queueStatusMap[indexableObject.queueStatusLabel]; + return indexableObject; + }); + } + + /** + * Open modal for details visualization + * @param message the message to be displayed + */ + openDetailModal(message: AdminNotifyMessage) { + const modalRef = this.modalService.open(AdminNotifyDetailModalComponent); + const messageKeys = Object.keys(message); + const keysToRead = []; + messageKeys.forEach((key) => { + if (typeof message[key] !== 'object') { + keysToRead.push(key); + } + }); + modalRef.componentInstance.notifyMessage = message; + modalRef.componentInstance.notifyMessageKeys = keysToRead; + } } diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts index be861861b4..a463de483a 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -26,11 +26,35 @@ export class AdminNotifyMessage extends DSpaceObject { @autoserialize coarNotifyType: string; + /** + * The type of the activity + */ + @autoserialize + activityStreamType: string; + + /** + * The object the message reply to + */ + @autoserialize + inReplyTo: string; + + /** + * The attempts of the queue + */ + @autoserialize + queueAttempts: number; + + /** + * Timestamp of the last queue attempt + */ + @autoserialize + queueLastStartTime: string; + /** * The type of the activity stream */ @autoserialize - source: number; + origin: number; /** * The type of the activity stream @@ -56,11 +80,6 @@ export class AdminNotifyMessage extends DSpaceObject { @autoserialize queueStatus: number; - /** - * The status of the queue - */ - @autoserialize - indexableObject: AdminNotifyMessage; @deserialize _links: { diff --git a/src/app/shared/object-collection/object-collection.component.html b/src/app/shared/object-collection/object-collection.component.html index 45b82dd859..179a70bfd7 100644 --- a/src/app/shared/object-collection/object-collection.component.html +++ b/src/app/shared/object-collection/object-collection.component.html @@ -58,20 +58,19 @@ - + diff --git a/src/app/shared/object-collection/shared/listable-object/listable-object.decorator.ts b/src/app/shared/object-collection/shared/listable-object/listable-object.decorator.ts index 470bcfcdaf..f56e983dff 100644 --- a/src/app/shared/object-collection/shared/listable-object/listable-object.decorator.ts +++ b/src/app/shared/object-collection/shared/listable-object/listable-object.decorator.ts @@ -34,7 +34,7 @@ export const DEFAULT_THEME = '*'; * - { level: 1, relevancy: 1 } is less relevant than { level: 2, relevancy: 0 } * - { level: 1, relevancy: 1 } is more relevant than null */ -class MatchRelevancy { +export class MatchRelevancy { constructor(public match: any, public level: number, public relevancy: number) { diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts index 9ab9e7c53d..bfe57149da 100644 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts @@ -1,70 +1,16 @@ import { ViewMode } from '../../../../core/shared/view-mode.model'; import { Context } from '../../../../core/shared/context.model'; -import { hasNoValue, hasValue, isNotEmpty } from '../../../empty.util'; +import { hasNoValue, hasValue } from '../../../empty.util'; import { GenericConstructor } from '../../../../core/shared/generic-constructor'; import { ListableObject } from '../listable-object.model'; -import { environment } from '../../../../../environments/environment'; -import { ThemeConfig } from '../../../../../config/theme.config'; -import { InjectionToken } from '@angular/core'; +import { + DEFAULT_CONTEXT, + DEFAULT_THEME, + DEFAULT_VIEW_MODE, + MatchRelevancy, resolveTheme +} from '../listable-object/listable-object.decorator'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; -export const DEFAULT_VIEW_MODE = ViewMode.ListElement; -export const DEFAULT_CONTEXT = Context.Any; -export const DEFAULT_THEME = '*'; - -/** - * A class used to compare two matches and their relevancy to determine which of the two gains priority over the other - * - * "level" represents the index of the first default value that was used to find the match with: - * ViewMode being index 0, Context index 1 and theme index 2. Examples: - * - If a default value was used for context, but not view-mode and theme, the "level" will be 1 - * - If a default value was used for view-mode and context, but not for theme, the "level" will be 0 - * - If no default value was used for any of the fields, the "level" will be 3 - * - * "relevancy" represents the amount of values that didn't require a default value to fall back on. Examples: - * - If a default value was used for theme, but not view-mode and context, the "relevancy" will be 2 - * - If a default value was used for view-mode and context, but not for theme, the "relevancy" will be 1 - * - If a default value was used for all fields, the "relevancy" will be 0 - * - If no default value was used for any of the fields, the "relevancy" will be 3 - * - * To determine which of two MatchRelevancies is the most relevant, we compare "level" and "relevancy" in that order. - * If any of the two is higher than the other, that match is most relevant. Examples: - * - { level: 1, relevancy: 1 } is more relevant than { level: 0, relevancy: 2 } - * - { level: 1, relevancy: 1 } is less relevant than { level: 1, relevancy: 2 } - * - { level: 1, relevancy: 1 } is more relevant than { level: 1, relevancy: 0 } - * - { level: 1, relevancy: 1 } is less relevant than { level: 2, relevancy: 0 } - * - { level: 1, relevancy: 1 } is more relevant than null - */ -class MatchRelevancy { - constructor(public match: any, - public level: number, - public relevancy: number) { - } - - isMoreRelevantThan(otherMatch: MatchRelevancy): boolean { - if (hasNoValue(otherMatch)) { - return true; - } - if (otherMatch.level > this.level) { - return false; - } - if (otherMatch.level === this.level && otherMatch.relevancy > this.relevancy) { - return false; - } - return true; - } - - isLessRelevantThan(otherMatch: MatchRelevancy): boolean { - return !this.isMoreRelevantThan(otherMatch); - } -} - -/** - * Factory to allow us to inject getThemeConfigFor so we can mock it in tests - */ -export const GET_THEME_CONFIG_FOR_FACTORY = new InjectionToken<(str) => ThemeConfig>('getThemeConfigFor', { - providedIn: 'root', - factory: () => getThemeConfigFor -}); const map = new Map(); @@ -75,7 +21,7 @@ const map = new Map(); * @param context The optional context the component represents * @param theme The optional theme for the component */ -export function tabulatableObjectsComponent(objectsType: string | GenericConstructor, viewMode: ViewMode, context: Context = DEFAULT_CONTEXT, theme = DEFAULT_THEME) { +export function tabulatableObjectsComponent(objectsType: string | GenericConstructor>, viewMode: ViewMode, context: Context = DEFAULT_CONTEXT, theme = DEFAULT_THEME) { return function decorator(component: any) { if (hasNoValue(objectsType)) { return; @@ -107,7 +53,7 @@ export function tabulatableObjectsComponent(objectsType: string | GenericConstru export function getTabulatableObjectsComponent(types: (string | GenericConstructor)[], viewMode: ViewMode, context: Context = DEFAULT_CONTEXT, theme: string = DEFAULT_THEME) { let currentBestMatch: MatchRelevancy = null; for (const type of types) { - const typeMap = map.get(type); + const typeMap = map.get(PaginatedList); if (hasValue(typeMap)) { const match = getMatch(typeMap, [viewMode, context, theme], [DEFAULT_VIEW_MODE, DEFAULT_CONTEXT, DEFAULT_THEME]); if (hasNoValue(currentBestMatch) || currentBestMatch.isLessRelevantThan(match)) { @@ -160,35 +106,3 @@ function getMatch(typeMap: Map, keys: any[], defaults: any[]): MatchRe } return null; } - -/** - * Searches for a ThemeConfig by its name; - */ -export const getThemeConfigFor = (themeName: string): ThemeConfig => { - return environment.themes.find(theme => theme.name === themeName); -}; - -/** - * Find a match in the given map for the given theme name, taking theme extension into account - * - * @param contextMap A map of theme names to components - * @param themeName The name of the theme to check - * @param checkedThemeNames The list of theme names that are already checked - */ -export const resolveTheme = (contextMap: Map, themeName: string, checkedThemeNames: string[] = []): any => { - const match = contextMap.get(themeName); - if (hasValue(match)) { - return match; - } else { - const cfg = getThemeConfigFor(themeName); - if (hasValue(cfg) && isNotEmpty(cfg.extends)) { - const nextTheme = cfg.extends; - const nextCheckedThemeNames = [...checkedThemeNames, themeName]; - if (checkedThemeNames.includes(nextTheme)) { - throw new Error('Theme extension cycle detected: ' + [...nextCheckedThemeNames, nextTheme].join(' -> ')); - } else { - return resolveTheme(contextMap, nextTheme, nextCheckedThemeNames); - } - } - } -}; diff --git a/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts index ed30e78c73..956f750b9e 100644 --- a/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts +++ b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts @@ -2,17 +2,17 @@ import { Component, Inject } from '@angular/core'; import { AbstractTabulatableElementComponent } from '../../../object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component'; -import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; import { TruncatableService } from '../../../truncatable/truncatable.service'; import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; import { APP_CONFIG, AppConfig } from '../../../../../config/app-config.interface'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; +import { SearchResult } from '../../../search/models/search-result.model'; @Component({ selector: 'ds-search-result-list-element', template: `` }) -export class TabulatableResultListElementsComponent, K extends DSpaceObject> extends AbstractTabulatableElementComponent { +export class TabulatableResultListElementsComponent, K extends SearchResult> extends AbstractTabulatableElementComponent { public constructor(protected truncatableService: TruncatableService, public dsoNameService: DSONameService, @Inject(APP_CONFIG) protected appConfig?: AppConfig) { diff --git a/src/app/shared/object-table/object-table.component.html b/src/app/shared/object-table/object-table.component.html index a4fe8cfc38..fcfa4aa691 100644 --- a/src/app/shared/object-table/object-table.component.html +++ b/src/app/shared/object-table/object-table.component.html @@ -15,9 +15,10 @@ (paginationChange)="onPaginationChange($event)" (prev)="goPrev()" (next)="goNext()" + [retainScrollPosition]="true" >
    -
    +
    Date: Fri, 5 Jan 2024 13:22:17 +0100 Subject: [PATCH 044/142] clean up --- .../admin-notify-search-result.component.ts | 9 ++-- .../listable-object.decorator.ts | 2 +- ...bjects-collection-tabulatable.component.ts | 4 -- .../tabulatable-objects.decorator.ts | 51 ++----------------- ...ulatable-result-list-elements.component.ts | 9 +--- 5 files changed, 9 insertions(+), 66 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index f0c9e3f7d8..0f4fbb28d3 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -31,11 +31,8 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListElem QUEUE_STATUS_UNMAPPED_ACTION: 'Unmapped action', }; - constructor(private modalService: NgbModal, - protected truncatableService: TruncatableService, - public dsoNameService: DSONameService, - @Inject(APP_CONFIG) protected appConfig?: AppConfig) { - super(truncatableService, dsoNameService, appConfig); + constructor(private modalService: NgbModal) { + super(); } /** @@ -50,7 +47,7 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListElem }); } - /** + /** * Open modal for details visualization * @param message the message to be displayed */ diff --git a/src/app/shared/object-collection/shared/listable-object/listable-object.decorator.ts b/src/app/shared/object-collection/shared/listable-object/listable-object.decorator.ts index f56e983dff..4f1a04a985 100644 --- a/src/app/shared/object-collection/shared/listable-object/listable-object.decorator.ts +++ b/src/app/shared/object-collection/shared/listable-object/listable-object.decorator.ts @@ -133,7 +133,7 @@ export function getListableObjectComponent(types: (string | GenericConstructor, keys: any[], defaults: any[]): MatchRelevancy { +export function getMatch(typeMap: Map, keys: any[], defaults: any[]): MatchRelevancy { let currentMap = typeMap; let level = -1; let relevancy = 0; diff --git a/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts b/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts index c6b6b1bb5b..3118ec255e 100644 --- a/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts +++ b/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts @@ -73,10 +73,6 @@ export class AbstractTabulatableElementComponent, keys: any[], defaults: any[]): MatchRelevancy { - let currentMap = typeMap; - let level = -1; - let relevancy = 0; - for (let i = 0; i < keys.length; i++) { - // If we're currently checking the theme, resolve it first to take extended themes into account - let currentMatch = defaults[i] === DEFAULT_THEME ? resolveTheme(currentMap, keys[i]) : currentMap.get(keys[i]); - if (hasNoValue(currentMatch)) { - currentMatch = currentMap.get(defaults[i]); - if (level === -1) { - level = i; - } - } else { - relevancy++; - } - if (hasValue(currentMatch)) { - if (currentMatch instanceof Map) { - currentMap = currentMatch as Map; - } else { - return new MatchRelevancy(currentMatch, level > -1 ? level : i + 1, relevancy); - } - } else { - return null; - } - } - return null; -} diff --git a/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts index 956f750b9e..b1be6443b8 100644 --- a/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts +++ b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts @@ -12,11 +12,4 @@ import { SearchResult } from '../../../search/models/search-result.model'; selector: 'ds-search-result-list-element', template: `` }) -export class TabulatableResultListElementsComponent, K extends SearchResult> extends AbstractTabulatableElementComponent { - public constructor(protected truncatableService: TruncatableService, - public dsoNameService: DSONameService, - @Inject(APP_CONFIG) protected appConfig?: AppConfig) { - super(dsoNameService); - } - -} +export class TabulatableResultListElementsComponent, K extends SearchResult> extends AbstractTabulatableElementComponent {} From e9159ce4e808382a178d9ad87718932af2cea00b Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 5 Jan 2024 13:29:16 +0100 Subject: [PATCH 045/142] fix lint --- .../admin-notify-search-result.component.ts | 5 +---- .../objects-collection-tabulatable.component.ts | 1 - .../tabulatable-objects/tabulatable-objects.decorator.ts | 2 +- .../tabulatable-result-list-elements.component.ts | 5 +---- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index 0f4fbb28d3..9c28a7e836 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, OnInit } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model'; import { ViewMode } from '../../../core/shared/view-mode.model'; import { Context } from '../../../core/shared/context.model'; @@ -11,9 +11,6 @@ import { } from '../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; import { PaginatedList } from '../../../core/data/paginated-list.model'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { TruncatableService } from '../../../shared/truncatable/truncatable.service'; -import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; -import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface'; import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component'; @tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotify) diff --git a/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts b/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts index 3118ec255e..9cc49ad134 100644 --- a/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts +++ b/src/app/shared/object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component.ts @@ -3,7 +3,6 @@ import { ListableObject } from '../listable-object.model'; import { CollectionElementLinkType } from '../../collection-element-link.type'; import { Context } from '../../../../core/shared/context.model'; import { ViewMode } from '../../../../core/shared/view-mode.model'; -import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; import { RemoteData } from '../../../../core/data/remote-data'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts index c3c23e67fc..ae7e71f2fc 100644 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator.ts @@ -7,7 +7,7 @@ import { DEFAULT_CONTEXT, DEFAULT_THEME, DEFAULT_VIEW_MODE, getMatch, - MatchRelevancy, resolveTheme + MatchRelevancy } from '../listable-object/listable-object.decorator'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; diff --git a/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts index b1be6443b8..94d132f822 100644 --- a/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts +++ b/src/app/shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component.ts @@ -1,10 +1,7 @@ -import { Component, Inject } from '@angular/core'; +import { Component } from '@angular/core'; import { AbstractTabulatableElementComponent } from '../../../object-collection/shared/objects-collection-tabulatable/objects-collection-tabulatable.component'; -import { TruncatableService } from '../../../truncatable/truncatable.service'; -import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; -import { APP_CONFIG, AppConfig } from '../../../../../config/app-config.interface'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; import { SearchResult } from '../../../search/models/search-result.model'; From af3bfee74e6ec9419a9b016edf8a2dabc5fedc58 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 5 Jan 2024 15:56:58 +0100 Subject: [PATCH 046/142] fix test dependencies --- ...dmin-notify-detail-modal.component.spec.ts | 4 ++- .../admin-notify-incoming.component.spec.ts | 4 ++- .../admin-notify-outgoing.component.spec.ts | 4 ++- .../admin-notify-search-result.component.html | 2 +- .../admin-notify-search-result.component.ts | 13 ++++---- .../models/admin-notify-message.model.ts | 9 ++++++ ...bulatable-objects-loader.component.spec.ts | 30 +++++++++++++++++-- .../tabulatable-objects-loader.component.ts | 2 +- .../object-table/object-table.component.html | 4 +-- 9 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts index 7ac979050c..77a878429c 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal.component'; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; describe('AdminNotifyDetailModalComponent', () => { let component: AdminNotifyDetailModalComponent; @@ -8,7 +9,8 @@ describe('AdminNotifyDetailModalComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ AdminNotifyDetailModalComponent ] + declarations: [ AdminNotifyDetailModalComponent ], + providers: [NgbActiveModal] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts index d32e100686..dba177f8f8 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts @@ -2,6 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyIncomingComponent } from './admin-notify-incoming.component'; import { TranslateModule } from '@ngx-translate/core'; +import { ActivatedRoute } from "@angular/router"; describe('AdminNotifyLogsComponent', () => { let component: AdminNotifyIncomingComponent; @@ -10,7 +11,8 @@ describe('AdminNotifyLogsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], - declarations: [ AdminNotifyIncomingComponent ] + declarations: [ AdminNotifyIncomingComponent ], + providers: [ActivatedRoute] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts index dafa72c52e..3cb67e9636 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts @@ -2,6 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyOutgoingComponent } from './admin-notify-outgoing.component'; import { TranslateModule } from '@ngx-translate/core'; +import { ActivatedRoute } from "@angular/router"; describe('AdminNotifyLogsComponent', () => { let component: AdminNotifyOutgoingComponent; @@ -10,7 +11,8 @@ describe('AdminNotifyLogsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], - declarations: [ AdminNotifyOutgoingComponent ] + declarations: [ AdminNotifyOutgoingComponent ], + providers: [ActivatedRoute] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html index 80c7faa086..a1ba0670bc 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html @@ -30,7 +30,7 @@
    - +
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index 9c28a7e836..8d6430da9f 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model'; import { ViewMode } from '../../../core/shared/view-mode.model'; import { Context } from '../../../core/shared/context.model'; -import { AdminNotifyMessage } from '../models/admin-notify-message.model'; +import { AdminNotifyMessage, QueueStatusMap } from '../models/admin-notify-message.model'; import { tabulatableObjectsComponent } from '../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator'; @@ -12,6 +12,7 @@ import { import { PaginatedList } from '../../../core/data/paginated-list.model'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component'; +import { objects } from "../../../shared/search/search-results/search-results.component.spec"; @tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotify) @Component({ @@ -21,12 +22,7 @@ import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/ad }) export class AdminNotifySearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifySearchResult> implements OnInit{ public notifyMessages: AdminNotifyMessage[]; - - private queueStatusMap = { - QUEUE_STATUS_PROCESSED: 'Processed', - QUEUE_STATUS_FAILED: 'Failed', - QUEUE_STATUS_UNMAPPED_ACTION: 'Unmapped action', - }; + public reprocessStatus = QueueStatusMap.QUEUE_STATUS_QUEUED_FOR_RETRY; constructor(private modalService: NgbModal) { super(); @@ -36,10 +32,11 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListElem * Map messages on init for readable representation */ ngOnInit() { + console.log(this.objects.page.splice(0,2)) this.notifyMessages = this.objects.page.map(object => { const indexableObject = object.indexableObject; indexableObject.coarNotifyType = indexableObject.coarNotifyType.split(':')[1]; - indexableObject.queueStatusLabel = this.queueStatusMap[indexableObject.queueStatusLabel]; + indexableObject.queueStatusLabel = QueueStatusMap[indexableObject.queueStatusLabel]; return indexableObject; }); } diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts index a463de483a..6114ab6084 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -6,6 +6,15 @@ import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { GenericConstructor } from '../../../core/shared/generic-constructor'; import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; +export enum QueueStatusMap { + QUEUE_STATUS_PROCESSED = 'Processed', + QUEUE_STATUS_FAILED = 'Failed', + QUEUE_STATUS_UNMAPPED_ACTION = 'Unmapped action', + QUEUE_STATUS_QUEUED_FOR_RETRY = 'Queued for retry', + QUEUE_STATUS_PROCESSING = 'Processing', + QUEUE_STATUS_QUEUED = 'Queued', + QUEUE_STATUS_UNTRUSTED = 'Untrusted', +}; /** * A message that includes admin notify info */ diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts index 59d0a42ecd..9fe3065714 100644 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts @@ -1,19 +1,45 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { TabulatableObjectsLoaderComponent } from './tabulatable-objects-loader.component'; +import { ThemeService } from "../../../theme-support/theme.service"; +import { provideMockStore } from "@ngrx/store/testing"; +import { ListableObject } from "../listable-object.model"; +import { PaginatedList } from "../../../../core/data/paginated-list.model"; +import { Context } from "../../../../core/shared/context.model"; +import { GenericConstructor } from "../../../../core/shared/generic-constructor"; -describe('TabulatableObjectsComponent', () => { +const testType = 'TestType'; +class TestType extends ListableObject { + getRenderTypes(): (string | GenericConstructor)[] { + return [testType]; + } +} + +class TestTypes extends PaginatedList { + page: TestType[] +} + + +describe('TabulatableObjectsLoaderComponent', () => { let component: TabulatableObjectsLoaderComponent; let fixture: ComponentFixture; + let themeService: ThemeService; + beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ TabulatableObjectsLoaderComponent ] + declarations: [ TabulatableObjectsLoaderComponent ], + providers: [ + provideMockStore({}), + { provide: ThemeService, useValue: themeService }, + ] }) .compileComponents(); fixture = TestBed.createComponent(TabulatableObjectsLoaderComponent); component = fixture.componentInstance; + component.objects = new TestTypes(); + component.context = Context.Search; fixture.detectChanges(); }); diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts index 1c68718bd6..467f2a12fe 100644 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts @@ -148,7 +148,7 @@ export class TabulatableObjectsLoaderComponent implements OnInit, OnChanges, OnD private instantiateComponent(objects: PaginatedList, changes?: SimpleChanges): void { // objects need to have same render type so we access just the first in the page - const component = this.getComponent(objects.page[0].getRenderTypes(), this.viewMode, this.context); + const component = this.getComponent(objects.page[0]?.getRenderTypes(), this.viewMode, this.context); const viewContainerRef = this.tabulatableObjectsDirective.viewContainerRef; viewContainerRef.clear(); diff --git a/src/app/shared/object-table/object-table.component.html b/src/app/shared/object-table/object-table.component.html index fcfa4aa691..8212b5a796 100644 --- a/src/app/shared/object-table/object-table.component.html +++ b/src/app/shared/object-table/object-table.component.html @@ -26,8 +26,8 @@
    - - + + From 7185c5548acad9ef74645c1b8e649daee5c61f91 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Fri, 5 Jan 2024 17:39:00 +0100 Subject: [PATCH 047/142] fix test dependencies, move components in two tabs --- .../admin-notify-dashboard.component.html | 13 ++++-- .../admin-notify-incoming.component.spec.ts | 40 ++++++++++++++++++- .../admin-notify-outgoing.component.spec.ts | 39 +++++++++++++++++- .../admin-notify-search-result.component.ts | 4 +- ...bulatable-objects-loader.component.spec.ts | 25 ++++++++++-- .../tabulatable-objects-loader.component.ts | 2 +- .../search-facet-option.component.spec.ts | 3 +- ...earch-facet-range-option.component.spec.ts | 3 +- ...ch-facet-selected-option.component.spec.ts | 3 +- .../search-facet-filter.component.spec.ts | 3 +- .../search-filter.component.spec.ts | 3 +- .../search-hierarchy-filter.component.spec.ts | 3 +- .../search-range-filter.component.spec.ts | 3 +- .../search-filters.component.spec.ts | 3 +- src/assets/i18n/en.json5 | 4 ++ 15 files changed, 128 insertions(+), 23 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html index a8aae4998b..0184141112 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -12,12 +12,19 @@
  • -
  • - {{'admin-notify-dashboard.logs' | translate}} +
  • + {{'admin.notify.dashboard.inbound' | translate}} -
    +
    {{'admin.notify.dashboard.inbound' | translate}}
    +
    + +
  • +
  • + {{'admin.notify.dashboard.outbound'| translate}} + +
    {{'admin.notify.dashboard.outbound' | translate}}
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts index dba177f8f8..44ef519164 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts @@ -3,16 +3,52 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyIncomingComponent } from './admin-notify-incoming.component'; import { TranslateModule } from '@ngx-translate/core'; import { ActivatedRoute } from "@angular/router"; +import { MockActivatedRoute } from "../../../../shared/mocks/active-router.mock"; +import { provideMockStore } from "@ngrx/store/testing"; +import { HALEndpointService } from "../../../../core/shared/hal-endpoint.service"; +import { SEARCH_CONFIG_SERVICE } from "../../../../my-dspace-page/my-dspace-page.component"; +import { AdminNotifySearchConfigurationService } from "../../config/admin-notify-search-configuration.service"; +import { FILTER_SEARCH } from "../../admin-notify-dashboard.component"; +import { AdminNotifySearchFilterService } from "../../config/admin-notify-filter-service"; +import { FILTER_CONFIG } from "../../../../core/shared/search/search-filter.service"; +import { RouteService } from "../../../../core/services/route.service"; +import { routeServiceStub } from "../../../../shared/testing/route-service.stub"; +import { RequestService } from "../../../../core/data/request.service"; +import { RemoteDataBuildService } from "../../../../core/cache/builders/remote-data-build.service"; +import { getMockRemoteDataBuildService } from "../../../../shared/mocks/remote-data-build.service.mock"; -describe('AdminNotifyLogsComponent', () => { +describe('AdminNotifyIncomingComponent', () => { let component: AdminNotifyIncomingComponent; let fixture: ComponentFixture; + let halService: HALEndpointService; + let requestService: RequestService; + let rdbService: RemoteDataBuildService; + + beforeEach(async () => { + rdbService = getMockRemoteDataBuildService(); + halService = jasmine.createSpyObj('halService', { + 'getRootHref': '/api' + }); + requestService = jasmine.createSpyObj('requestService', { + 'generateRequestId': 'client/1234', + 'send': '', + }); await TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], declarations: [ AdminNotifyIncomingComponent ], - providers: [ActivatedRoute] + providers: [ + { provide: SEARCH_CONFIG_SERVICE, useValue: AdminNotifySearchConfigurationService }, + { provide: FILTER_SEARCH, useValue: AdminNotifySearchFilterService }, + { provide: FILTER_CONFIG, useValue: AdminNotifySearchConfigurationService }, + { provide: RouteService, useValue: routeServiceStub }, + { provide: ActivatedRoute, useValue: new MockActivatedRoute() }, + { provide: HALEndpointService, useValue: halService }, + { provide: RequestService, useValue: requestService }, + { provide: RemoteDataBuildService, useValue: rdbService }, + provideMockStore({}), + ] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts index 3cb67e9636..0fd565fbf3 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts @@ -3,16 +3,51 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyOutgoingComponent } from './admin-notify-outgoing.component'; import { TranslateModule } from '@ngx-translate/core'; import { ActivatedRoute } from "@angular/router"; +import { MockActivatedRoute } from "../../../../shared/mocks/active-router.mock"; +import { provideMockStore } from "@ngrx/store/testing"; +import { HALEndpointService } from "../../../../core/shared/hal-endpoint.service"; +import { SEARCH_CONFIG_SERVICE } from "../../../../my-dspace-page/my-dspace-page.component"; +import { AdminNotifySearchConfigurationService } from "../../config/admin-notify-search-configuration.service"; +import { FILTER_SEARCH } from "../../admin-notify-dashboard.component"; +import { AdminNotifySearchFilterService } from "../../config/admin-notify-filter-service"; +import { FILTER_CONFIG } from "../../../../core/shared/search/search-filter.service"; +import { RouteService } from "../../../../core/services/route.service"; +import { routeServiceStub } from "../../../../shared/testing/route-service.stub"; +import { RequestService } from "../../../../core/data/request.service"; +import { getMockRemoteDataBuildService } from "../../../../shared/mocks/remote-data-build.service.mock"; +import { RemoteDataBuildService } from "../../../../core/cache/builders/remote-data-build.service"; -describe('AdminNotifyLogsComponent', () => { +describe('AdminNotifyOutgoingComponent', () => { let component: AdminNotifyOutgoingComponent; let fixture: ComponentFixture; + let halService: HALEndpointService; + let requestService: RequestService; + let rdbService: RemoteDataBuildService; + beforeEach(async () => { + rdbService = getMockRemoteDataBuildService(); + requestService = jasmine.createSpyObj('requestService', { + 'generateRequestId': 'client/1234', + 'send': '', + }); + halService = jasmine.createSpyObj('halService', { + 'getRootHref': '/api' + }); await TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], declarations: [ AdminNotifyOutgoingComponent ], - providers: [ActivatedRoute] + providers: [ + { provide: SEARCH_CONFIG_SERVICE, useValue: AdminNotifySearchConfigurationService }, + { provide: FILTER_SEARCH, useValue: AdminNotifySearchFilterService }, + { provide: FILTER_CONFIG, useValue: AdminNotifySearchConfigurationService }, + { provide: RouteService, useValue: routeServiceStub }, + { provide: ActivatedRoute, useValue: new MockActivatedRoute() }, + { provide: HALEndpointService, useValue: halService }, + { provide: RequestService, useValue: requestService }, + { provide: RemoteDataBuildService, useValue: rdbService }, + provideMockStore({}), + ] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index 8d6430da9f..23d15002a8 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -12,7 +12,6 @@ import { import { PaginatedList } from '../../../core/data/paginated-list.model'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component'; -import { objects } from "../../../shared/search/search-results/search-results.component.spec"; @tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotify) @Component({ @@ -32,8 +31,7 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListElem * Map messages on init for readable representation */ ngOnInit() { - console.log(this.objects.page.splice(0,2)) - this.notifyMessages = this.objects.page.map(object => { + this.notifyMessages = this.objects?.page.map(object => { const indexableObject = object.indexableObject; indexableObject.coarNotifyType = indexableObject.coarNotifyType.split(':')[1]; indexableObject.queueStatusLabel = QueueStatusMap[indexableObject.queueStatusLabel]; diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts index 9fe3065714..21fd2b94b2 100644 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts @@ -7,6 +7,15 @@ import { ListableObject } from "../listable-object.model"; import { PaginatedList } from "../../../../core/data/paginated-list.model"; import { Context } from "../../../../core/shared/context.model"; import { GenericConstructor } from "../../../../core/shared/generic-constructor"; +import { TabulatableObjectsDirective } from "./tabulatable-objects.directive"; +import { ListableObjectComponentLoaderComponent } from "../listable-object/listable-object-component-loader.component"; +import { ChangeDetectionStrategy } from "@angular/core"; +import { + ItemListElementComponent +} from "../../../object-list/item-list-element/item-types/item/item-list-element.component"; +import { + TabulatableResultListElementsComponent +} from "../../../object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component"; const testType = 'TestType'; class TestType extends ListableObject { @@ -16,7 +25,7 @@ class TestType extends ListableObject { } class TestTypes extends PaginatedList { - page: TestType[] + page: TestType[] = [new TestType()] } @@ -27,19 +36,27 @@ describe('TabulatableObjectsLoaderComponent', () => { let themeService: ThemeService; beforeEach(async () => { + themeService = jasmine.createSpyObj('themeService', { + getThemeName: 'dspace', + }); await TestBed.configureTestingModule({ - declarations: [ TabulatableObjectsLoaderComponent ], + declarations: [ TabulatableObjectsLoaderComponent, TabulatableObjectsDirective ], providers: [ provideMockStore({}), { provide: ThemeService, useValue: themeService }, ] - }) - .compileComponents(); + }).overrideComponent(TabulatableObjectsLoaderComponent, { + set: { + changeDetection: ChangeDetectionStrategy.Default, + entryComponents: [TabulatableResultListElementsComponent] + } + }).compileComponents(); fixture = TestBed.createComponent(TabulatableObjectsLoaderComponent); component = fixture.componentInstance; component.objects = new TestTypes(); component.context = Context.Search; + spyOn(component, 'getComponent').and.returnValue(TabulatableResultListElementsComponent as any); fixture.detectChanges(); }); diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts index 467f2a12fe..0ba9e1cdd4 100644 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts @@ -148,7 +148,7 @@ export class TabulatableObjectsLoaderComponent implements OnInit, OnChanges, OnD private instantiateComponent(objects: PaginatedList, changes?: SimpleChanges): void { // objects need to have same render type so we access just the first in the page - const component = this.getComponent(objects.page[0]?.getRenderTypes(), this.viewMode, this.context); + const component = this.getComponent(objects?.page[0]?.getRenderTypes(), this.viewMode, this.context); const viewContainerRef = this.tabulatableObjectsDirective.viewContainerRef; viewContainerRef.clear(); diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts index 53acb1d911..8c27774f99 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts @@ -19,6 +19,7 @@ import { PaginationComponentOptions } from '../../../../../pagination/pagination import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; import { ShortNumberPipe } from '../../../../../utils/short-number.pipe'; +import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFacetOptionComponent', () => { let comp: SearchFacetOptionComponent; @@ -102,7 +103,7 @@ describe('SearchFacetOptionComponent', () => { } }, { - provide: SearchFilterService, useValue: { + provide: FILTER_SEARCH, useValue: { getSelectedValuesForFilter: () => selectedValues, isFilterActiveWithValue: (paramName: string, filterValue: string) => observableOf(true), getPage: (paramName: string) => page, diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts index b0acf43c32..0f9655c1d5 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts @@ -23,6 +23,7 @@ import { PaginationComponentOptions } from '../../../../../pagination/pagination import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; import { ShortNumberPipe } from '../../../../../utils/short-number.pipe'; +import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFacetRangeOptionComponent', () => { let comp: SearchFacetRangeOptionComponent; @@ -76,7 +77,7 @@ describe('SearchFacetRangeOptionComponent', () => { } }, { - provide: SearchFilterService, useValue: { + provide: FILTER_SEARCH, useValue: { isFilterActiveWithValue: (paramName: string, filterValue: string) => observableOf(true), getPage: (paramName: string) => page, /* eslint-disable no-empty,@typescript-eslint/no-empty-function */ diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts index 15e418842f..aa58d25d31 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts @@ -17,6 +17,7 @@ import { SearchFacetSelectedOptionComponent } from './search-facet-selected-opti import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; +import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFacetSelectedOptionComponent', () => { let comp: SearchFacetSelectedOptionComponent; @@ -126,7 +127,7 @@ describe('SearchFacetSelectedOptionComponent', () => { } }, { - provide: SearchFilterService, useValue: { + provide: FILTER_SEARCH, useValue: { getSelectedValuesForFilter: () => selectedValues, isFilterActiveWithValue: (paramName: string, filterValue: string) => observableOf(true), getPage: (paramName: string) => page, diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts index 92d2e5265b..40852f275d 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts @@ -24,6 +24,7 @@ import { RemoteDataBuildService } from '../../../../../core/cache/builders/remot import { SearchConfigurationServiceStub } from '../../../../testing/search-configuration-service.stub'; import { SEARCH_CONFIG_SERVICE } from '../../../../../my-dspace-page/my-dspace-page.component'; import { createSuccessfulRemoteDataObject$ } from '../../../../remote-data.utils'; +import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFacetFilterComponent', () => { let comp: SearchFacetFilterComponent; @@ -100,7 +101,7 @@ describe('SearchFacetFilterComponent', () => { { provide: IN_PLACE_SEARCH, useValue: false }, { provide: REFRESH_FILTER, useValue: new BehaviorSubject(false) }, { - provide: SearchFilterService, useValue: { + provide: FILTER_SEARCH, useValue: { getSelectedValuesForFilter: () => observableOf(selectedValues), isFilterActiveWithValue: (paramName: string, filterValue: string) => true, getPage: (paramName: string) => page, diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts index 7abe45ca8c..8747747ec7 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts @@ -14,6 +14,7 @@ import { SearchConfigurationServiceStub } from '../../../testing/search-configur import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { SequenceService } from '../../../../core/shared/sequence.service'; import { BrowserOnlyMockPipe } from '../../../testing/browser-only-mock.pipe'; +import { FILTER_SEARCH } from "../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFilterComponent', () => { let comp: SearchFilterComponent; @@ -70,7 +71,7 @@ describe('SearchFilterComponent', () => { providers: [ { provide: SearchService, useValue: searchServiceStub }, { - provide: SearchFilterService, + provide: FILTER_SEARCH, useValue: mockFilterService }, { provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() }, diff --git a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts index e6c74d8047..6ca5c62334 100644 --- a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts @@ -26,6 +26,7 @@ import { SearchConfigurationServiceStub } from '../../../../testing/search-confi import { VocabularyEntryDetail } from '../../../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { FacetValue} from '../../../models/facet-value.model'; import { SearchFilterConfig } from '../../../models/search-filter-config.model'; +import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchHierarchyFilterComponent', () => { @@ -67,7 +68,7 @@ describe('SearchHierarchyFilterComponent', () => { ], providers: [ { provide: SearchService, useValue: searchService }, - { provide: SearchFilterService, useValue: searchFilterService }, + { provide: FILTER_SEARCH, useValue: searchFilterService }, { provide: RemoteDataBuildService, useValue: {} }, { provide: Router, useValue: router }, { provide: NgbModal, useValue: ngbModal }, diff --git a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts index 3a146f5059..7569a33214 100644 --- a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts @@ -25,6 +25,7 @@ import { SEARCH_CONFIG_SERVICE } from '../../../../../my-dspace-page/my-dspace-p import { SearchConfigurationServiceStub } from '../../../../testing/search-configuration-service.stub'; import { createSuccessfulRemoteDataObject$ } from '../../../../remote-data.utils'; import { RouteService } from '../../../../../core/services/route.service'; +import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchRangeFilterComponent', () => { let comp: SearchRangeFilterComponent; @@ -106,7 +107,7 @@ describe('SearchRangeFilterComponent', () => { { provide: IN_PLACE_SEARCH, useValue: false }, { provide: REFRESH_FILTER, useValue: new BehaviorSubject(false) }, { - provide: SearchFilterService, useValue: { + provide: FILTER_SEARCH, useValue: { getSelectedValuesForFilter: () => selectedValues, isFilterActiveWithValue: (paramName: string, filterValue: string) => true, getPage: (paramName: string) => page, diff --git a/src/app/shared/search/search-filters/search-filters.component.spec.ts b/src/app/shared/search/search-filters/search-filters.component.spec.ts index 522459b603..212174d241 100644 --- a/src/app/shared/search/search-filters/search-filters.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filters.component.spec.ts @@ -9,6 +9,7 @@ import { SearchFiltersComponent } from './search-filters.component'; import { SearchService } from '../../../core/shared/search/search.service'; import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub'; +import { FILTER_SEARCH } from "../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFiltersComponent', () => { let comp: SearchFiltersComponent; @@ -36,7 +37,7 @@ describe('SearchFiltersComponent', () => { providers: [ { provide: SearchService, useValue: searchServiceStub }, { provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() }, - { provide: SearchFilterService, useValue: searchFiltersStub }, + { provide: FILTER_SEARCH, useValue: searchFiltersStub }, ], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index ce5004832e..60134d54e3 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3509,6 +3509,10 @@ "search.filters.filter.target.placeholder": "Target", + "search.filters.filter.origin.label": "Search source", + + "search.filters.filter.origin.placeholder": "Source", + "search.filters.filter.queue_status.placeholder": "Queue status", "search.filters.filter.activity_stream_type.placeholder": "Activity stream type", From 4d30bc7035aff0214c6496c32afff7bdf93a51a7 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Mon, 8 Jan 2024 13:07:07 +0100 Subject: [PATCH 048/142] separate results, config routes, add data mapping, add service --- .../admin-notify-dashboard-routing.module.ts | 18 ++- .../admin-notify-dashboard.component.html | 36 ++--- .../admin-notify-dashboard.component.ts | 16 +- .../admin-notify-dashboard.module.ts | 12 +- .../admin-notify-incoming.component.html | 37 ++++- .../admin-notify-incoming.component.spec.ts | 10 +- .../admin-notify-incoming.component.ts | 26 +--- .../admin-notify-outgoing.component.html | 37 ++++- .../admin-notify-outgoing.component.spec.ts | 8 +- .../admin-notify-outgoing.component.ts | 26 +--- ...min-notify-search-result.component.spec.ts | 22 --- .../admin-notify-search-result.component.ts | 58 ------- ...tify-incoming-search-result.component.html | 40 +++++ ...ify-incoming-search-result.component.scss} | 0 ...y-incoming-search-result.component.spec.ts | 22 +++ ...notify-incoming-search-result.component.ts | 97 ++++++++++++ ...ify-outgoing-search-result.component.html} | 12 +- ...tify-outgoing-search-result.component.scss | 0 ...y-outgoing-search-result.component.spec.ts | 22 +++ ...notify-outgoing-search-result.component.ts | 98 ++++++++++++ ...dmin-notify-facet-config-response.model.ts | 35 ----- ...n-notify-facet-response-parsing.service.ts | 38 ----- .../config/admin-notify-filter-service.ts | 35 ----- ...min-notify-search-configuration.service.ts | 145 ------------------ .../admin-notify-search-filter-config.ts | 94 ------------ .../models/admin-notify-message.model.ts | 22 ++- .../services/admin-notify-messages.service.ts | 45 ++++++ src/app/core/core.module.ts | 11 -- src/app/core/shared/context.model.ts | 3 +- .../search-facet-option.component.spec.ts | 3 +- .../search-facet-option.component.ts | 3 +- ...earch-facet-range-option.component.spec.ts | 3 +- .../search-facet-range-option.component.ts | 3 +- ...ch-facet-selected-option.component.spec.ts | 3 +- .../search-facet-selected-option.component.ts | 3 +- .../search-facet-filter.component.spec.ts | 3 +- .../search-facet-filter.component.ts | 3 +- .../search-filter.component.spec.ts | 3 +- .../search-filter/search-filter.component.ts | 3 +- .../search-hierarchy-filter.component.spec.ts | 3 +- .../search-hierarchy-filter.component.ts | 3 +- .../search-range-filter.component.spec.ts | 3 +- .../search-range-filter.component.ts | 3 +- .../search-filters.component.spec.ts | 3 +- .../search-filters.component.ts | 3 +- src/app/shared/search/search.component.ts | 11 +- .../shared/search/themed-search.component.ts | 4 +- 47 files changed, 480 insertions(+), 608 deletions(-) delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.html rename src/app/admin/admin-notify-dashboard/admin-notify-search-result/{admin-notify-search-result.component.scss => incoming/admin-notify-incoming-search-result.component.scss} (100%) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.spec.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.ts rename src/app/admin/admin-notify-dashboard/admin-notify-search-result/{admin-notify-search-result.component.html => outgoing/admin-notify-outgoing-search-result.component.html} (73%) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.scss create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.spec.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.ts delete mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts delete mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts delete mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts delete mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts delete mode 100644 src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts create mode 100644 src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts index b917116216..345dc31ce3 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts @@ -6,6 +6,12 @@ import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.componen import { SiteAdministratorGuard } from '../../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard'; +import { + AdminNotifyIncomingComponent +} from "./admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component"; +import { + AdminNotifyOutgoingComponent +} from "./admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component"; @NgModule({ imports: [ @@ -22,8 +28,18 @@ import { title: 'admin.notify.dashboard.page.title', breadcrumbKey: 'admin.notify.dashboard', showBreadcrumbsFluid: false - } + }, }, + { + path: 'inbound', + component: AdminNotifyIncomingComponent, + canActivate: [SiteAdministratorGuard], + }, + { + path: 'outbound', + component: AdminNotifyOutgoingComponent, + canActivate: [SiteAdministratorGuard], + } ]) ], providers: [ diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html index 0184141112..17d9bf884d 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.html @@ -3,35 +3,19 @@

    {{'admin-notify-dashboard.title'| translate}}

  • diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index ba88ce4e6d..3d4f35a54c 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -9,15 +9,11 @@ import { map } from 'rxjs/operators'; import { SearchObjects } from '../../shared/search/models/search-objects.model'; import { AdminNotifyMetricsBox, AdminNotifyMetricsRow } from './admin-notify-metrics/admin-notify-metrics.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; -import { FILTER_CONFIG, SearchFilterService } from '../../core/shared/search/search-filter.service'; import { SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component'; -import { AdminNotifySearchConfigurationService } from './config/admin-notify-search-configuration.service'; -import { AdminNotifySearchFilterService } from './config/admin-notify-filter-service'; -import { AdminNotifySearchFilterConfig } from './config/admin-notify-search-filter-config'; import { ViewMode } from '../../core/shared/view-mode.model'; import { Router } from '@angular/router'; +import { SearchConfigurationService } from "../../core/shared/search/search-configuration.service"; -export const FILTER_SEARCH: InjectionToken = new InjectionToken('searchFilterService'); @Component({ selector: 'ds-admin-notify-dashboard', @@ -26,15 +22,7 @@ export const FILTER_SEARCH: InjectionToken = new InjectionT providers: [ { provide: SEARCH_CONFIG_SERVICE, - useClass: AdminNotifySearchConfigurationService - }, - { - provide: FILTER_SEARCH, - useClass: AdminNotifySearchFilterService - }, - { - provide: FILTER_CONFIG, - useClass: AdminNotifySearchFilterConfig + useClass: SearchConfigurationService } ] }) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts index 23200bb9fc..498c40a58d 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts @@ -8,11 +8,15 @@ import { AdminNotifyIncomingComponent } from './admin-notify-logs/admin-notify-i import { SharedModule } from '../../shared/shared.module'; import { SearchModule } from '../../shared/search/search.module'; import { SearchPageModule } from '../../search-page/search-page.module'; -import { AdminNotifySearchResultComponent } from './admin-notify-search-result/admin-notify-search-result.component'; +import { AdminNotifyIncomingSearchResultComponent } from './admin-notify-search-result/incoming/admin-notify-incoming-search-result.component'; import { AdminNotifyOutgoingComponent } from './admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component'; import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal/admin-notify-detail-modal.component'; +import { + AdminNotifyOutgoingSearchResultComponent +} from "./admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component"; +import { AdminNotifyMessagesService } from "./services/admin-notify-messages.service"; @NgModule({ @@ -24,12 +28,16 @@ import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal/adm SearchModule, SearchPageModule, ], + providers: [ + AdminNotifyMessagesService + ], declarations: [ AdminNotifyDashboardComponent, AdminNotifyMetricsComponent, AdminNotifyIncomingComponent, AdminNotifyOutgoingComponent, - AdminNotifySearchResultComponent, + AdminNotifyIncomingSearchResultComponent, + AdminNotifyOutgoingSearchResultComponent, AdminNotifyDetailModalComponent ] }) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.html index 868469ad55..3b7272186a 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.html @@ -1,9 +1,30 @@ - +
    +
    +
    +

    {{'admin-notify-dashboard.title'| translate}}

    + +
    +
    +
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts index 44ef519164..14d6c6a1eb 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts @@ -7,15 +7,13 @@ import { MockActivatedRoute } from "../../../../shared/mocks/active-router.mock" import { provideMockStore } from "@ngrx/store/testing"; import { HALEndpointService } from "../../../../core/shared/hal-endpoint.service"; import { SEARCH_CONFIG_SERVICE } from "../../../../my-dspace-page/my-dspace-page.component"; -import { AdminNotifySearchConfigurationService } from "../../config/admin-notify-search-configuration.service"; -import { FILTER_SEARCH } from "../../admin-notify-dashboard.component"; -import { AdminNotifySearchFilterService } from "../../config/admin-notify-filter-service"; -import { FILTER_CONFIG } from "../../../../core/shared/search/search-filter.service"; +import { FILTER_CONFIG, SearchFilterService } from "../../../../core/shared/search/search-filter.service"; import { RouteService } from "../../../../core/services/route.service"; import { routeServiceStub } from "../../../../shared/testing/route-service.stub"; import { RequestService } from "../../../../core/data/request.service"; import { RemoteDataBuildService } from "../../../../core/cache/builders/remote-data-build.service"; import { getMockRemoteDataBuildService } from "../../../../shared/mocks/remote-data-build.service.mock"; +import { SearchConfigurationService } from "../../../../core/shared/search/search-configuration.service"; describe('AdminNotifyIncomingComponent', () => { let component: AdminNotifyIncomingComponent; @@ -39,9 +37,7 @@ describe('AdminNotifyIncomingComponent', () => { imports: [TranslateModule.forRoot()], declarations: [ AdminNotifyIncomingComponent ], providers: [ - { provide: SEARCH_CONFIG_SERVICE, useValue: AdminNotifySearchConfigurationService }, - { provide: FILTER_SEARCH, useValue: AdminNotifySearchFilterService }, - { provide: FILTER_CONFIG, useValue: AdminNotifySearchConfigurationService }, + { provide: SEARCH_CONFIG_SERVICE, useValue: SearchConfigurationService }, { provide: RouteService, useValue: routeServiceStub }, { provide: ActivatedRoute, useValue: new MockActivatedRoute() }, { provide: HALEndpointService, useValue: halService }, diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts index b43866dc82..ffb5306643 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts @@ -1,11 +1,7 @@ import { Component, Inject } from '@angular/core'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { Context } from '../../../../core/shared/context.model'; -import { AdminNotifySearchConfigurationService } from '../../config/admin-notify-search-configuration.service'; -import { FILTER_SEARCH } from '../../admin-notify-dashboard.component'; -import { AdminNotifySearchFilterService } from '../../config/admin-notify-filter-service'; -import { FILTER_CONFIG } from '../../../../core/shared/search/search-filter.service'; -import { AdminNotifySearchFilterConfig } from '../../config/admin-notify-search-filter-config'; +import { SearchConfigurationService } from "../../../../core/shared/search/search-configuration.service"; @Component({ @@ -15,26 +11,12 @@ import { AdminNotifySearchFilterConfig } from '../../config/admin-notify-search- providers: [ { provide: SEARCH_CONFIG_SERVICE, - useClass: AdminNotifySearchConfigurationService - }, - { - provide: FILTER_SEARCH, - useClass: AdminNotifySearchFilterService - }, - { - provide: FILTER_CONFIG, - useClass: AdminNotifySearchFilterConfig + useClass: SearchConfigurationService } ] }) export class AdminNotifyIncomingComponent { - protected readonly context = Context.CoarNotify; - constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: AdminNotifySearchConfigurationService, - @Inject(FILTER_SEARCH) public searchFilterService: AdminNotifySearchFilterService, - @Inject(FILTER_CONFIG) public filterConfig: AdminNotifySearchFilterConfig) { - const incomingPrefix = 'incoming.f'; - this.searchConfigService.setParamPrefix(incomingPrefix); - this.searchFilterService.setParamPrefix(incomingPrefix); - this.filterConfig.paramNamePrefix = incomingPrefix; + protected readonly context = Context.CoarNotifyIncoming; + constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) { } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html index af64c69e7a..050e25c241 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html @@ -1,9 +1,30 @@ - +
    +
    +
    +

    {{'admin-notify-dashboard.title'| translate}}

    + +
    +
    +
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts index 0fd565fbf3..9d3ab2fe46 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts @@ -7,15 +7,13 @@ import { MockActivatedRoute } from "../../../../shared/mocks/active-router.mock" import { provideMockStore } from "@ngrx/store/testing"; import { HALEndpointService } from "../../../../core/shared/hal-endpoint.service"; import { SEARCH_CONFIG_SERVICE } from "../../../../my-dspace-page/my-dspace-page.component"; -import { AdminNotifySearchConfigurationService } from "../../config/admin-notify-search-configuration.service"; -import { FILTER_SEARCH } from "../../admin-notify-dashboard.component"; -import { AdminNotifySearchFilterService } from "../../config/admin-notify-filter-service"; import { FILTER_CONFIG } from "../../../../core/shared/search/search-filter.service"; import { RouteService } from "../../../../core/services/route.service"; import { routeServiceStub } from "../../../../shared/testing/route-service.stub"; import { RequestService } from "../../../../core/data/request.service"; import { getMockRemoteDataBuildService } from "../../../../shared/mocks/remote-data-build.service.mock"; import { RemoteDataBuildService } from "../../../../core/cache/builders/remote-data-build.service"; +import { SearchConfigurationService } from "../../../../core/shared/search/search-configuration.service"; describe('AdminNotifyOutgoingComponent', () => { let component: AdminNotifyOutgoingComponent; @@ -38,9 +36,7 @@ describe('AdminNotifyOutgoingComponent', () => { imports: [TranslateModule.forRoot()], declarations: [ AdminNotifyOutgoingComponent ], providers: [ - { provide: SEARCH_CONFIG_SERVICE, useValue: AdminNotifySearchConfigurationService }, - { provide: FILTER_SEARCH, useValue: AdminNotifySearchFilterService }, - { provide: FILTER_CONFIG, useValue: AdminNotifySearchConfigurationService }, + { provide: SEARCH_CONFIG_SERVICE, useValue: SearchConfigurationService }, { provide: RouteService, useValue: routeServiceStub }, { provide: ActivatedRoute, useValue: new MockActivatedRoute() }, { provide: HALEndpointService, useValue: halService }, diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts index ae8cd0f13b..ac7a5cfafa 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts @@ -1,11 +1,7 @@ import { Component, Inject } from '@angular/core'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { Context } from '../../../../core/shared/context.model'; -import { AdminNotifySearchConfigurationService } from '../../config/admin-notify-search-configuration.service'; -import { FILTER_SEARCH } from '../../admin-notify-dashboard.component'; -import { AdminNotifySearchFilterService } from '../../config/admin-notify-filter-service'; -import { FILTER_CONFIG } from '../../../../core/shared/search/search-filter.service'; -import { AdminNotifySearchFilterConfig } from '../../config/admin-notify-search-filter-config'; +import { SearchConfigurationService } from "../../../../core/shared/search/search-configuration.service"; @Component({ @@ -15,27 +11,13 @@ import { AdminNotifySearchFilterConfig } from '../../config/admin-notify-search- providers: [ { provide: SEARCH_CONFIG_SERVICE, - useClass: AdminNotifySearchConfigurationService - }, - { - provide: FILTER_SEARCH, - useClass: AdminNotifySearchFilterService - }, - { - provide: FILTER_CONFIG, - useClass: AdminNotifySearchFilterConfig + useClass: SearchConfigurationService } ] }) export class AdminNotifyOutgoingComponent { - protected readonly context = Context.CoarNotify; + protected readonly context = Context.CoarNotifyOutgoing; - constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: AdminNotifySearchConfigurationService, - @Inject(FILTER_SEARCH) public searchFilterService: AdminNotifySearchFilterService, - @Inject(FILTER_CONFIG) public filterConfig: AdminNotifySearchFilterConfig) { - const outgoingPrefix = 'outgoing.f'; - this.searchConfigService.setParamPrefix(outgoingPrefix); - this.searchFilterService.setParamPrefix(outgoingPrefix); - this.filterConfig.paramNamePrefix = outgoingPrefix; + constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) { } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts deleted file mode 100644 index b17a03274f..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { AdminNotifySearchResultComponent } from './admin-notify-search-result.component'; - -describe('AdminNotifySearchResultComponent', () => { - let component: AdminNotifySearchResultComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ AdminNotifySearchResultComponent ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(AdminNotifySearchResultComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts deleted file mode 100644 index 23d15002a8..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model'; -import { ViewMode } from '../../../core/shared/view-mode.model'; -import { Context } from '../../../core/shared/context.model'; -import { AdminNotifyMessage, QueueStatusMap } from '../models/admin-notify-message.model'; -import { - tabulatableObjectsComponent -} from '../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator'; -import { - TabulatableResultListElementsComponent -} from '../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; -import { PaginatedList } from '../../../core/data/paginated-list.model'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component'; - -@tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotify) -@Component({ - selector: 'ds-admin-notify-search-result', - templateUrl: './admin-notify-search-result.component.html', - styleUrls: ['./admin-notify-search-result.component.scss'] -}) -export class AdminNotifySearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifySearchResult> implements OnInit{ - public notifyMessages: AdminNotifyMessage[]; - public reprocessStatus = QueueStatusMap.QUEUE_STATUS_QUEUED_FOR_RETRY; - - constructor(private modalService: NgbModal) { - super(); - } - - /** - * Map messages on init for readable representation - */ - ngOnInit() { - this.notifyMessages = this.objects?.page.map(object => { - const indexableObject = object.indexableObject; - indexableObject.coarNotifyType = indexableObject.coarNotifyType.split(':')[1]; - indexableObject.queueStatusLabel = QueueStatusMap[indexableObject.queueStatusLabel]; - return indexableObject; - }); - } - - /** - * Open modal for details visualization - * @param message the message to be displayed - */ - openDetailModal(message: AdminNotifyMessage) { - const modalRef = this.modalService.open(AdminNotifyDetailModalComponent); - const messageKeys = Object.keys(message); - const keysToRead = []; - messageKeys.forEach((key) => { - if (typeof message[key] !== 'object') { - keysToRead.push(key); - } - }); - modalRef.componentInstance.notifyMessage = message; - modalRef.componentInstance.notifyMessageKeys = keysToRead; - } -} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.html new file mode 100644 index 0000000000..06aa551a44 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.html @@ -0,0 +1,40 @@ + +
    + + + + + + + + + + + + + + + + + + + + + +
    TimestampLDN ServiceRepository ItemTypeStatusAction
    +
    {{message.queueTimeout}}
    +
    +
    {{message.origin}}
    +
    +
    {{message.context}}
    +
    +
    {{message.coarNotifyType}}
    +
    +
    {{message.queueStatusLabel}}
    +
    +
    + + +
    +
    +
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.scss similarity index 100% rename from src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss rename to src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.scss diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.spec.ts new file mode 100644 index 0000000000..2db8920d7f --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AdminNotifyIncomingSearchResultComponent } from './admin-notify-incoming-search-result.component'; + +describe('AdminNotifySearchResultComponent', () => { + let component: AdminNotifyIncomingSearchResultComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AdminNotifyIncomingSearchResultComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminNotifyIncomingSearchResultComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.ts new file mode 100644 index 0000000000..11e94c05c5 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.ts @@ -0,0 +1,97 @@ +import { Component, OnInit } from '@angular/core'; +import { AdminNotifySearchResult } from '../../models/admin-notify-message-search-result.model'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { Context } from '../../../../core/shared/context.model'; +import { AdminNotifyMessage, QueueStatusMap } from '../../models/admin-notify-message.model'; +import { + tabulatableObjectsComponent +} from '../../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator'; +import { + TabulatableResultListElementsComponent +} from '../../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { AdminNotifyDetailModalComponent } from '../../admin-notify-detail-modal/admin-notify-detail-modal.component'; +import { LdnServicesService } from "../../../admin-ldn-services/ldn-services-data/ldn-services-data.service"; +import { BehaviorSubject, concatMap, from, Observable, of, scan, switchMap } from "rxjs"; +import { RemoteData } from "../../../../core/data/remote-data"; +import { LdnService } from "../../../admin-ldn-services/ldn-services-model/ldn-services.model"; +import { filter, map, mergeMap, take, tap, toArray } from "rxjs/operators"; +import { getAllSucceededRemoteDataPayload } from "../../../../core/shared/operators"; +import { ItemDataService } from "../../../../core/data/item-data.service"; +import { AdminNotifyMessagesService } from "../../services/admin-notify-messages.service"; + +@tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotifyIncoming) +@Component({ + selector: 'ds-admin-notify-search-result', + templateUrl: './admin-notify-incoming-search-result.component.html', + styleUrls: ['./admin-notify-incoming-search-result.component.scss'] +}) +export class AdminNotifyIncomingSearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifySearchResult> implements OnInit{ + public notifyMessages: AdminNotifyMessage[]; + public notifyMessages$: Observable; + public reprocessStatus = QueueStatusMap.QUEUE_STATUS_QUEUED_FOR_RETRY; + + + + constructor(private modalService: NgbModal, + private ldnServicesService: LdnServicesService, + private itemDataService: ItemDataService, + private adminNotifyMessagesService: AdminNotifyMessagesService) { + super(); + } + + /** + * Map messages on init for readable representation + */ + ngOnInit() { + this.notifyMessages = this.objects?.page.map(object => { + const indexableObject = object.indexableObject; + indexableObject.coarNotifyType = indexableObject.coarNotifyType.split(':')[1]; + indexableObject.queueStatusLabel = QueueStatusMap[indexableObject.queueStatusLabel]; + return indexableObject; + }); + + this.notifyMessages$ = from(this.notifyMessages).pipe( + mergeMap(message => of(message)), + mergeMap(message => + message.origin ? this.ldnServicesService.findById(message.origin.toString()).pipe( + getAllSucceededRemoteDataPayload(), + map(detail => ({...message, origin: detail.name})) + ) : of(message), + ), + mergeMap(message => + message.context ? this.itemDataService.findById(message.context.toString()).pipe( + getAllSucceededRemoteDataPayload(), + map(detail => ({...message, context: detail.name})) + ) : of(message), + ), + scan((acc: any, value: any) => [...acc, value], []), + ) + } + + /** + * Open modal for details visualization + * @param message the message to be displayed + */ + openDetailModal(message: AdminNotifyMessage) { + const modalRef = this.modalService.open(AdminNotifyDetailModalComponent); + const messageKeys = Object.keys(message); + const keysToRead = []; + messageKeys.forEach((key) => { + if (typeof message[key] !== 'object') { + keysToRead.push(key); + } + }); + modalRef.componentInstance.notifyMessage = message; + modalRef.componentInstance.notifyMessageKeys = keysToRead; + } + + /** + * Reprocess message in status QUEUE_STATUS_QUEUED_FOR_RETRY and update results + * @param message + */ + reprocessMessage(message: AdminNotifyMessage) { + // TODO implement reprocess + } +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.html similarity index 73% rename from src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html rename to src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.html index a1ba0670bc..639d66a1f3 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.html @@ -3,20 +3,20 @@ Timestamp - Origin - Target + Repository Item + LDN Service Type Status Action - + -
    {{message.queueTimeout}}
    +
    {{message.queueTimeout}}
    -
    {{message.origin}}
    +
    {{message.object}}
    {{message.target}}
    @@ -30,7 +30,7 @@
    - +
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.spec.ts new file mode 100644 index 0000000000..110feb2e0c --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AdminNotifyOutgoingSearchResultComponent } from './admin-notify-outgoing-search-result.component'; + +describe('AdminNotifySearchResultComponent', () => { + let component: AdminNotifyOutgoingSearchResultComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AdminNotifyOutgoingSearchResultComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminNotifyOutgoingSearchResultComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.ts new file mode 100644 index 0000000000..b5b49a8a71 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.ts @@ -0,0 +1,98 @@ +import { Component, OnInit } from '@angular/core'; +import { AdminNotifySearchResult } from '../../models/admin-notify-message-search-result.model'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { Context } from '../../../../core/shared/context.model'; +import { AdminNotifyMessage, QueueStatusMap } from '../../models/admin-notify-message.model'; +import { + tabulatableObjectsComponent +} from '../../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator'; +import { + TabulatableResultListElementsComponent +} from '../../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { AdminNotifyDetailModalComponent } from '../../admin-notify-detail-modal/admin-notify-detail-modal.component'; +import { LdnServicesService } from "../../../admin-ldn-services/ldn-services-data/ldn-services-data.service"; +import { from, Observable, of, scan, switchMap } from "rxjs"; +import { combineLatest, filter, map, mergeMap } from "rxjs/operators"; +import { getAllSucceededRemoteDataPayload } from "../../../../core/shared/operators"; +import { ItemDataService } from "../../../../core/data/item-data.service"; +import { AdminNotifyMessagesService } from "../../services/admin-notify-messages.service"; + +@tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotifyOutgoing) +@Component({ + selector: 'ds-admin-notify-search-result', + templateUrl: './admin-notify-outgoing-search-result.component.html', + styleUrls: ['./admin-notify-outgoing-search-result.component.scss'] +}) +export class AdminNotifyOutgoingSearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifySearchResult> implements OnInit{ + public notifyMessages: AdminNotifyMessage[]; + public notifyMessages$: Observable; + public reprocessStatus = QueueStatusMap.QUEUE_STATUS_QUEUED_FOR_RETRY; + + constructor(private modalService: NgbModal, + private ldnServicesService: LdnServicesService, + private itemDataService: ItemDataService, + private adminNotifyMessagesService: AdminNotifyMessagesService) { + super(); + } + + /** + * Map messages on init for readable representation + */ + ngOnInit() { + this.mapDetailsToMessages() + } + + /** + * Open modal for details visualization + * @param message the message to be displayed + */ + openDetailModal(message: AdminNotifyMessage) { + const modalRef = this.modalService.open(AdminNotifyDetailModalComponent); + const messageKeys = Object.keys(message); + modalRef.componentInstance.notifyMessage = message; + modalRef.componentInstance.notifyMessageKeys = messageKeys; + } + + /** + * Reprocess message in status QUEUE_STATUS_QUEUED_FOR_RETRY and update results + * @param message + */ + reprocessMessage(message: AdminNotifyMessage) { + this.adminNotifyMessagesService.findById(message.id).pipe(getAllSucceededRemoteDataPayload()).subscribe(response => { + console.log(response); + }) + } + + + /** + * Map readable results to messages + * @private + */ + private mapDetailsToMessages() { + this.notifyMessages = this.objects?.page.map(object => { + const indexableObject = object.indexableObject; + indexableObject.coarNotifyType = indexableObject.coarNotifyType.split(':')[1]; + indexableObject.queueStatusLabel = QueueStatusMap[indexableObject.queueStatusLabel]; + return indexableObject; + }); + + this.notifyMessages$ = from(this.notifyMessages).pipe( + mergeMap(message => of(message)), + mergeMap(message => + message.target ? this.ldnServicesService.findById(message.target.toString()).pipe( + getAllSucceededRemoteDataPayload(), + map(detail => ({...message, target: detail.name})) + ) : of(message), + ), + mergeMap(message => + message.object ? this.itemDataService.findById(message.object.toString()).pipe( + getAllSucceededRemoteDataPayload(), + map(detail => ({...message, object: detail.name})) + ) : of(message), + ), + scan((acc: any, value: any) => [...acc, value], []), + ) + } +} diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts deleted file mode 100644 index d9f9460a65..0000000000 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-config-response.model.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { typedObject } from '../../../core/cache/builders/build-decorators'; -import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; -import { deserialize } from 'cerialize'; -import { HALLink } from '../../../core/shared/hal-link.model'; -import { CacheableObject } from '../../../core/cache/cacheable-object.model'; -import { AdminNotifySearchFilterConfig } from './admin-notify-search-filter-config'; -import { FACET_CONFIG_RESPONSE } from '../../../shared/search/models/types/facet-config-response.resouce-type'; - -/** - * The response from the discover/facets endpoint - */ -@typedObject -export class AdminNotifyFacetConfigResponse implements CacheableObject { - static type = FACET_CONFIG_RESPONSE; - - /** - * The object type, - * hardcoded because rest doesn't a unique one. - */ - @excludeFromEquals - type = FACET_CONFIG_RESPONSE; - - /** - * the filters in this response - */ - filters: AdminNotifySearchFilterConfig[]; - - /** - * The {@link HALLink}s for this SearchFilterConfig - */ - @deserialize - _links: { - self: HALLink; - }; -} diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts deleted file mode 100644 index 16c986fef6..0000000000 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Injectable } from '@angular/core'; -import { FacetConfigResponseParsingService } from '../../../core/data/facet-config-response-parsing.service'; -import { RestRequest } from '../../../core/data/rest-request.model'; -import { RawRestResponse } from '../../../core/dspace-rest/raw-rest-response.model'; -import { ParsedResponse } from '../../../core/cache/response.models'; -import { DSpaceSerializer } from '../../../core/dspace-rest/dspace.serializer'; -import { AdminNotifySearchFilterConfig } from './admin-notify-search-filter-config'; -import { FacetConfigResponse } from '../../../shared/search/models/facet-config-response.model'; - -@Injectable() -export class AdminNotifyFacetResponseParsingService extends FacetConfigResponseParsingService { - parse(request: RestRequest, data: RawRestResponse): ParsedResponse { - - const config = data.payload._embedded.facets; - const serializer = new DSpaceSerializer(AdminNotifySearchFilterConfig); - const filters = serializer.deserializeArray(config); - - const _links = { - self: data.payload._links.self - }; - - // fill in the missing links section - filters.forEach((filterConfig: AdminNotifySearchFilterConfig) => { - _links[filterConfig.name] = { - href: filterConfig._links.self.href - }; - }); - - const facetConfigResponse = Object.assign(new FacetConfigResponse(), { - filters, - _links - }); - - this.addToObjectCache(facetConfigResponse, request, data); - - return new ParsedResponse(data.statusCode, facetConfigResponse._links.self); - } -} diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts deleted file mode 100644 index ca421957b8..0000000000 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-filter-service.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Injectable } from '@angular/core'; -import { SearchFilterService } from '../../../core/shared/search/search-filter.service'; -import { Store } from '@ngrx/store'; -import { SearchFiltersState } from '../../../shared/search/search-filters/search-filter/search-filter.reducer'; -import { RouteService } from '../../../core/services/route.service'; - - -/** - * Service that performs all actions that have to do with search filters and facets - */ -@Injectable() -export class AdminNotifySearchFilterService extends SearchFilterService { - - public filterPrefix: string; - constructor(protected store: Store, - protected routeService: RouteService) { - super(store, routeService); - } - - /** - * Fetch the current active filters from the query parameters - * @returns {Observable} - */ - getCurrentFilters() { - return this.routeService.getQueryParamsWithPrefix(`${this.filterPrefix}.`); - } - - /** - * Set prefix to be used for route filters - * @param prefix - */ - setParamPrefix(prefix: string): void { - this.filterPrefix = prefix; - } -} diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts deleted file mode 100644 index 127aa2a5a1..0000000000 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-configuration.service.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { Injectable } from '@angular/core'; -import { ActivatedRoute, Params } from '@angular/router'; -import { Observable } from 'rxjs'; -import { map, take } from 'rxjs/operators'; -import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service'; -import { RouteService } from '../../../core/services/route.service'; -import { LinkService } from '../../../core/cache/builders/link.service'; -import { HALEndpointService } from '../../../core/shared/hal-endpoint.service'; -import { RequestService } from '../../../core/data/request.service'; -import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; -import { PaginationService } from '../../../core/pagination/pagination.service'; -import { RemoteData } from '../../../core/data/remote-data'; -import { GetRequest } from '../../../core/data/request.models'; -import { GenericConstructor } from '../../../core/shared/generic-constructor'; -import { ResponseParsingService } from '../../../core/data/parsing.service'; -import { hasNoValue, isNotEmpty } from '../../../shared/empty.util'; -import { AdminNotifyFacetResponseParsingService } from './admin-notify-facet-response-parsing.service'; -import { AdminNotifySearchFilterConfig } from './admin-notify-search-filter-config'; -import { AdminNotifyFacetConfigResponse } from './admin-notify-facet-config-response.model'; -import { SearchFilter } from '../../../shared/search/models/search-filter.model'; - - - -/** - * Service that performs all actions that have to do with the current admin notify configuration - */ -@Injectable() -export class AdminNotifySearchConfigurationService extends SearchConfigurationService { - - public paramPrefix: string; - /** - * Initialize class - * - * @param {RouteService} routeService - * @param {PaginationService} paginationService - * @param {ActivatedRoute} route - * @param linkService - * @param halService - * @param requestService - * @param rdb - */ - constructor(protected routeService: RouteService, - protected paginationService: PaginationService, - protected route: ActivatedRoute, - protected linkService: LinkService, - protected halService: HALEndpointService, - protected requestService: RequestService, - protected rdb: RemoteDataBuildService) { - super(routeService, paginationService, route, linkService, halService, requestService, rdb); - } - - /** - * @returns {Observable} Emits the current active filters with their values as they are displayed in the frontend URL - */ - getCurrentFrontendFilters(): Observable { - return this.routeService.getQueryParamsWithPrefix(`${this.paramPrefix}.`); - } - - /** - * Set prefix to be used for route filters - * @param prefix - */ - setParamPrefix(prefix: string): void { - this.paramPrefix = prefix; - } - - /** - * Request the filter configuration for a given scope or the whole repository - * @param {string} scope UUID of the object for which config the filter config is requested, when no scope is provided the configuration for the whole repository is loaded - * @param {string} configurationName the name of the configuration - * @returns {Observable>} The found filter configuration - */ - getConfig(scope?: string, configurationName?: string): Observable> { - const href$ = this.halService.getEndpoint(this.facetLinkPathPrefix).pipe( - map((url: string) => this.getConfigUrl(url, scope, configurationName)), - ); - - href$.pipe(take(1)).subscribe((url: string) => { - let request = new GetRequest(this.requestService.generateRequestId(), url); - request = Object.assign(request, { - getResponseParser(): GenericConstructor { - return AdminNotifyFacetResponseParsingService; - } - }); - this.requestService.send(request, true); - }); - - return this.rdb.buildFromHref(href$).pipe( - map((rd: RemoteData) => { - if (rd.hasSucceeded) { - let filters: AdminNotifySearchFilterConfig[]; - if (isNotEmpty(rd.payload.filters)) { - filters = rd.payload.filters - .map((filter: any) => Object.assign(new AdminNotifySearchFilterConfig(), filter)); - filters.forEach(filter => filter.namePrefix = this.paramPrefix); - } else { - filters = []; - } - - return new RemoteData( - rd.timeCompleted, - rd.msToLive, - rd.lastUpdated, - rd.state, - rd.errorMessage, - filters, - rd.statusCode, - ); - } else { - return rd as any as RemoteData; - } - }) - ); - } - - /** - * @returns {Observable} Emits the current active filters with their values as they are sent to the backend - */ - getCurrentFilters(): Observable { - return this.getCurrentFrontendFilters().pipe(map((filterParams) => { - if (isNotEmpty(filterParams)) { - const filters = []; - Object.keys(filterParams).forEach((key) => { - // we add one to keep in account the point at the end of the prefix and set back the prefix f. - const updatedKey = `f.${key.substring(this.paramPrefix.length + 1, key.length)}`; - - delete Object.assign(filterParams, {[updatedKey]: filterParams[key] })[key]; - key = updatedKey; - if (key.endsWith('.min') || key.endsWith('.max')) { - const realKey = key.slice(0, -4); - if (hasNoValue(filters.find((f) => f.key === realKey))) { - const min = filterParams[realKey + '.min'] ? filterParams[realKey + '.min'][0] : '*'; - const max = filterParams[realKey + '.max'] ? filterParams[realKey + '.max'][0] : '*'; - filters.push(new SearchFilter(realKey, ['[' + min + ' TO ' + max + ']'], 'equals')); - } - } else { - filters.push(new SearchFilter(key, filterParams[key])); - } - }); - return filters; - } - return []; - })); - } -} diff --git a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts b/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts deleted file mode 100644 index 2372313c0d..0000000000 --- a/src/app/admin/admin-notify-dashboard/config/admin-notify-search-filter-config.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { typedObject } from '../../../core/cache/builders/build-decorators'; -import { SearchFilterConfig } from '../../../shared/search/models/search-filter-config.model'; -import { autoserialize, autoserializeAs, deserialize } from 'cerialize'; -import { HALLink } from '../../../core/shared/hal-link.model'; -import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; -import { SEARCH_FILTER_CONFIG } from '../../../shared/search/models/types/search-filter-config.resource-type'; -import { FilterType } from '../../../shared/search/models/filter-type.model'; - -/** - * The configuration for a search filter - */ -@typedObject -export class AdminNotifySearchFilterConfig implements SearchFilterConfig { - static type = SEARCH_FILTER_CONFIG; - - /** - * The prefix of this filter - */ - @autoserialize - namePrefix: string; - - /** - * The object type, - * hardcoded because rest doesn't set one. - */ - @excludeFromEquals - type = SEARCH_FILTER_CONFIG; - - /** - * The name of this filter - */ - @autoserialize - name: string; - - /** - * The FilterType of this filter - */ - @autoserializeAs(String, 'facetType') - filterType: FilterType; - - /** - * True if the filter has facets - */ - @autoserialize - hasFacets: boolean; - - /** - * @type {number} The page size used for this facet - */ - @autoserializeAs(String, 'facetLimit') - pageSize = 5; - - /** - * Defines if the item facet is collapsed by default or not on the search page - */ - @autoserialize - isOpenByDefault: boolean; - - /** - * Minimum value possible for this facet in the repository - */ - @autoserialize - maxValue: string; - - /** - * Maximum value possible for this facet in the repository - */ - @autoserialize - minValue: string; - - /** - * The {@link HALLink}s for this SearchFilterConfig - */ - @deserialize - _links: { - self: HALLink; - }; - - /** - * Set prefix to be used for route filters - * @param namePrefix - */ - set paramNamePrefix(namePrefix: string) { - this.namePrefix = namePrefix; - } - - /** - * Name of this configuration that can be used in a url - * @returns Parameter name - */ - get paramName(): string { - return `${this.namePrefix}.${this.name}`; - } -} diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts index 6114ab6084..1fda25d1ef 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -29,6 +29,12 @@ export class AdminNotifyMessage extends DSpaceObject { @excludeFromEquals type = ADMIN_NOTIFY_MESSAGE; + /** + * The id of the message + */ + @autoserialize + id: string; + /** * The type of the notification */ @@ -47,6 +53,18 @@ export class AdminNotifyMessage extends DSpaceObject { @autoserialize inReplyTo: string; + /** + * The object the message relates to + */ + @autoserialize + object: string; + + /** + * The context of the message + */ + @autoserialize + context: string; + /** * The attempts of the queue */ @@ -63,13 +81,13 @@ export class AdminNotifyMessage extends DSpaceObject { * The type of the activity stream */ @autoserialize - origin: number; + origin: number | string; /** * The type of the activity stream */ @autoserialize - target: number; + target: number | string; /** * The label for the status of the queue diff --git a/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts b/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts new file mode 100644 index 0000000000..8f710d987d --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts @@ -0,0 +1,45 @@ +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 {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 {CreateData, CreateDataImpl} from '../../../core/data/base/create-data'; +import {SearchDataImpl} from '../../../core/data/base/search-data'; +import { ADMIN_NOTIFY_MESSAGE } from "../models/admin-notify-message.resource-type"; +import { AdminNotifyMessage } from "../models/admin-notify-message.model"; + +/** + * Injectable service responsible for fetching/sending data from/to the REST API on the messages endpoint. + * + * @export + * @class AdminNotifyMessagesService + * @extends {IdentifiableDataService} + */ +@Injectable() +@dataService(ADMIN_NOTIFY_MESSAGE) +export class AdminNotifyMessagesService extends IdentifiableDataService { + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + ) { + super('messages', requestService, rdbService, objectCache, halService); + } +} diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index abfd303799..26e32d34e7 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -198,11 +198,6 @@ import { SubmissionCoarNotifyConfig } from '../submission/sections/section-coar- import { NotifyRequestsStatus } from '../item-page/simple/notify-requests-status/notify-requests-status.model'; import { NotifyRequestsStatusDataService } from './data/notify-services-status-data.service'; import { AdminNotifyMessage } from '../admin/admin-notify-dashboard/models/admin-notify-message.model'; -import { - AdminNotifyFacetResponseParsingService -} from '../admin/admin-notify-dashboard/config/admin-notify-facet-response-parsing.service'; -import { FILTER_SEARCH } from '../admin/admin-notify-dashboard/admin-notify-dashboard.component'; -import { AdminNotifySearchFilterService } from '../admin/admin-notify-dashboard/config/admin-notify-filter-service'; /** @@ -235,10 +230,6 @@ const PROVIDERS = [ DSOResponseParsingService, { provide: MOCK_RESPONSE_MAP, useValue: mockResponseMap }, { provide: DspaceRestService, useFactory: restServiceFactory, deps: [MOCK_RESPONSE_MAP, HttpClient] }, - { - provide: FILTER_SEARCH, - useClass: SearchFilterService - }, EPersonDataService, LinkHeadService, HALEndpointService, @@ -254,7 +245,6 @@ const PROVIDERS = [ EndpointMapResponseParsingService, FacetValueResponseParsingService, FacetConfigResponseParsingService, - AdminNotifyFacetResponseParsingService, DebugResponseParsingService, SearchResponseParsingService, MyDSpaceResponseParsingService, @@ -294,7 +284,6 @@ const PROVIDERS = [ SearchService, SidebarService, SearchFilterService, - AdminNotifySearchFilterService, SearchConfigurationService, SelectableListService, RelationshipTypeDataService, diff --git a/src/app/core/shared/context.model.ts b/src/app/core/shared/context.model.ts index deb7bbeca3..1526be1033 100644 --- a/src/app/core/shared/context.model.ts +++ b/src/app/core/shared/context.model.ts @@ -40,5 +40,6 @@ export enum Context { Bitstream = 'bitstream', - CoarNotify = 'coarNotify' + CoarNotifyIncoming = 'coarNotifyIncoming', + CoarNotifyOutgoing = 'coarNotifyOutgoing', } diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts index 8c27774f99..53acb1d911 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts @@ -19,7 +19,6 @@ import { PaginationComponentOptions } from '../../../../../pagination/pagination import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; import { ShortNumberPipe } from '../../../../../utils/short-number.pipe'; -import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFacetOptionComponent', () => { let comp: SearchFacetOptionComponent; @@ -103,7 +102,7 @@ describe('SearchFacetOptionComponent', () => { } }, { - provide: FILTER_SEARCH, useValue: { + provide: SearchFilterService, useValue: { getSelectedValuesForFilter: () => selectedValues, isFilterActiveWithValue: (paramName: string, filterValue: string) => observableOf(true), getPage: (paramName: string) => page, diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts index fcf8b334e9..b14d3187d7 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts @@ -11,7 +11,6 @@ import { hasValue } from '../../../../../empty.util'; import { currentPath } from '../../../../../utils/route.utils'; import { getFacetValueForType } from '../../../../search.utils'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; -import { FILTER_SEARCH } from '../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-facet-option', @@ -65,7 +64,7 @@ export class SearchFacetOptionComponent implements OnInit, OnDestroy { paginationId: string; constructor(protected searchService: SearchService, - @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, + protected filterService: SearchFilterService, protected searchConfigService: SearchConfigurationService, protected router: Router, protected paginationService: PaginationService diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts index 0f9655c1d5..b0acf43c32 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts @@ -23,7 +23,6 @@ import { PaginationComponentOptions } from '../../../../../pagination/pagination import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; import { ShortNumberPipe } from '../../../../../utils/short-number.pipe'; -import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFacetRangeOptionComponent', () => { let comp: SearchFacetRangeOptionComponent; @@ -77,7 +76,7 @@ describe('SearchFacetRangeOptionComponent', () => { } }, { - provide: FILTER_SEARCH, useValue: { + provide: SearchFilterService, useValue: { isFilterActiveWithValue: (paramName: string, filterValue: string) => observableOf(true), getPage: (paramName: string) => page, /* eslint-disable no-empty,@typescript-eslint/no-empty-function */ diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts index 7d0a575c25..6afe994f2f 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts @@ -14,7 +14,6 @@ import { SearchConfigurationService } from '../../../../../../core/shared/search import { hasValue } from '../../../../../empty.util'; import { currentPath } from '../../../../../utils/route.utils'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; -import { FILTER_SEARCH } from '../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; const rangeDelimiter = '-'; @@ -65,7 +64,7 @@ export class SearchFacetRangeOptionComponent implements OnInit, OnDestroy { searchLink: string; constructor(protected searchService: SearchService, - @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, + protected filterService: SearchFilterService, protected searchConfigService: SearchConfigurationService, protected router: Router, protected paginationService: PaginationService diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts index aa58d25d31..15e418842f 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts @@ -17,7 +17,6 @@ import { SearchFacetSelectedOptionComponent } from './search-facet-selected-opti import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; -import { FILTER_SEARCH } from "../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFacetSelectedOptionComponent', () => { let comp: SearchFacetSelectedOptionComponent; @@ -127,7 +126,7 @@ describe('SearchFacetSelectedOptionComponent', () => { } }, { - provide: FILTER_SEARCH, useValue: { + provide: SearchFilterService, useValue: { getSelectedValuesForFilter: () => selectedValues, isFilterActiveWithValue: (paramName: string, filterValue: string) => observableOf(true), getPage: (paramName: string) => page, diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts index 25f5883a00..8479417c57 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts @@ -10,7 +10,6 @@ import { FacetValue } from '../../../../models/facet-value.model'; import { currentPath } from '../../../../../utils/route.utils'; import { getFacetValueForType } from '../../../../search.utils'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; -import { FILTER_SEARCH } from '../../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-facet-selected-option', @@ -58,7 +57,7 @@ export class SearchFacetSelectedOptionComponent implements OnInit, OnDestroy { searchLink: string; constructor(protected searchService: SearchService, - @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, + protected filterService: SearchFilterService, protected searchConfigService: SearchConfigurationService, protected router: Router, protected paginationService: PaginationService diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts index 40852f275d..92d2e5265b 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts @@ -24,7 +24,6 @@ import { RemoteDataBuildService } from '../../../../../core/cache/builders/remot import { SearchConfigurationServiceStub } from '../../../../testing/search-configuration-service.stub'; import { SEARCH_CONFIG_SERVICE } from '../../../../../my-dspace-page/my-dspace-page.component'; import { createSuccessfulRemoteDataObject$ } from '../../../../remote-data.utils'; -import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFacetFilterComponent', () => { let comp: SearchFacetFilterComponent; @@ -101,7 +100,7 @@ describe('SearchFacetFilterComponent', () => { { provide: IN_PLACE_SEARCH, useValue: false }, { provide: REFRESH_FILTER, useValue: new BehaviorSubject(false) }, { - provide: FILTER_SEARCH, useValue: { + provide: SearchFilterService, useValue: { getSelectedValuesForFilter: () => observableOf(selectedValues), isFilterActiveWithValue: (paramName: string, filterValue: string) => true, getPage: (paramName: string) => page, diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index 37a540a39c..2b2eb9b11a 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -35,7 +35,6 @@ import { currentPath } from '../../../../utils/route.utils'; import { getFacetValueForType, stripOperatorFromFilterValue } from '../../../search.utils'; import { createPendingRemoteDataObject } from '../../../../remote-data.utils'; import { FacetValues } from '../../../models/facet-values.model'; -import { FILTER_SEARCH } from '../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-facet-filter', @@ -99,7 +98,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { currentUrl: string; constructor(protected searchService: SearchService, - @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, + protected filterService: SearchFilterService, protected rdbs: RemoteDataBuildService, protected router: Router, @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService, diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts index 8747747ec7..7abe45ca8c 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts @@ -14,7 +14,6 @@ import { SearchConfigurationServiceStub } from '../../../testing/search-configur import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { SequenceService } from '../../../../core/shared/sequence.service'; import { BrowserOnlyMockPipe } from '../../../testing/browser-only-mock.pipe'; -import { FILTER_SEARCH } from "../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFilterComponent', () => { let comp: SearchFilterComponent; @@ -71,7 +70,7 @@ describe('SearchFilterComponent', () => { providers: [ { provide: SearchService, useValue: searchServiceStub }, { - provide: FILTER_SEARCH, + provide: SearchFilterService, useValue: mockFilterService }, { provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() }, diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts index d7967e6642..d1d3bd729d 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts @@ -11,7 +11,6 @@ import { SearchService } from '../../../../core/shared/search/search.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { SequenceService } from '../../../../core/shared/sequence.service'; -import { FILTER_SEARCH } from '../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-filter', @@ -72,7 +71,7 @@ export class SearchFilterComponent implements OnInit { private readonly sequenceId: number; constructor( - @Inject(FILTER_SEARCH) private filterService: SearchFilterService, + private filterService: SearchFilterService, private searchService: SearchService, @Inject(SEARCH_CONFIG_SERVICE) private searchConfigService: SearchConfigurationService, private sequenceService: SequenceService, diff --git a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts index 6ca5c62334..e6c74d8047 100644 --- a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.spec.ts @@ -26,7 +26,6 @@ import { SearchConfigurationServiceStub } from '../../../../testing/search-confi import { VocabularyEntryDetail } from '../../../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { FacetValue} from '../../../models/facet-value.model'; import { SearchFilterConfig } from '../../../models/search-filter-config.model'; -import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchHierarchyFilterComponent', () => { @@ -68,7 +67,7 @@ describe('SearchHierarchyFilterComponent', () => { ], providers: [ { provide: SearchService, useValue: searchService }, - { provide: FILTER_SEARCH, useValue: searchFilterService }, + { provide: SearchFilterService, useValue: searchFilterService }, { provide: RemoteDataBuildService, useValue: {} }, { provide: Router, useValue: router }, { provide: NgbModal, useValue: ngbModal }, diff --git a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts index fd62e49e32..f9b3f2bff9 100644 --- a/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.ts @@ -26,7 +26,6 @@ import { PageInfo } from '../../../../../core/shared/page-info.model'; import { environment } from '../../../../../../environments/environment'; import { addOperatorToFilterValue } from '../../../search.utils'; import { VocabularyTreeviewModalComponent } from '../../../../form/vocabulary-treeview-modal/vocabulary-treeview-modal.component'; -import { FILTER_SEARCH } from '../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-hierarchy-filter', @@ -42,7 +41,7 @@ import { FILTER_SEARCH } from '../../../../../admin/admin-notify-dashboard/admin export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent implements OnInit { constructor(protected searchService: SearchService, - @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, + protected filterService: SearchFilterService, protected rdbs: RemoteDataBuildService, protected router: Router, protected modalService: NgbModal, diff --git a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts index 7569a33214..3a146f5059 100644 --- a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts @@ -25,7 +25,6 @@ import { SEARCH_CONFIG_SERVICE } from '../../../../../my-dspace-page/my-dspace-p import { SearchConfigurationServiceStub } from '../../../../testing/search-configuration-service.stub'; import { createSuccessfulRemoteDataObject$ } from '../../../../remote-data.utils'; import { RouteService } from '../../../../../core/services/route.service'; -import { FILTER_SEARCH } from "../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchRangeFilterComponent', () => { let comp: SearchRangeFilterComponent; @@ -107,7 +106,7 @@ describe('SearchRangeFilterComponent', () => { { provide: IN_PLACE_SEARCH, useValue: false }, { provide: REFRESH_FILTER, useValue: new BehaviorSubject(false) }, { - provide: FILTER_SEARCH, useValue: { + provide: SearchFilterService, useValue: { getSelectedValuesForFilter: () => selectedValues, isFilterActiveWithValue: (paramName: string, filterValue: string) => true, getPage: (paramName: string) => page, diff --git a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts index 788971b4cb..ed20e63c52 100644 --- a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts @@ -21,7 +21,6 @@ import { SearchConfigurationService } from '../../../../../core/shared/search/se import { RouteService } from '../../../../../core/services/route.service'; import { hasValue } from '../../../../empty.util'; import { yearFromString } from 'src/app/shared/date.util'; -import { FILTER_SEARCH } from '../../../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; /** * The suffix for a range filters' minimum in the frontend URL @@ -93,7 +92,7 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple keyboardControl: boolean; constructor(protected searchService: SearchService, - @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, + protected filterService: SearchFilterService, protected router: Router, protected rdbs: RemoteDataBuildService, private translateService: TranslateService, diff --git a/src/app/shared/search/search-filters/search-filters.component.spec.ts b/src/app/shared/search/search-filters/search-filters.component.spec.ts index 212174d241..522459b603 100644 --- a/src/app/shared/search/search-filters/search-filters.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filters.component.spec.ts @@ -9,7 +9,6 @@ import { SearchFiltersComponent } from './search-filters.component'; import { SearchService } from '../../../core/shared/search/search.service'; import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub'; -import { FILTER_SEARCH } from "../../../admin/admin-notify-dashboard/admin-notify-dashboard.component"; describe('SearchFiltersComponent', () => { let comp: SearchFiltersComponent; @@ -37,7 +36,7 @@ describe('SearchFiltersComponent', () => { providers: [ { provide: SearchService, useValue: searchServiceStub }, { provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() }, - { provide: FILTER_SEARCH, useValue: searchFiltersStub }, + { provide: SearchFilterService, useValue: searchFiltersStub }, ], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index e7bedbb30a..63235b3e57 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -12,7 +12,6 @@ import { SearchFilterService } from '../../../core/shared/search/search-filter.s import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; import { currentPath } from '../../utils/route.utils'; import { hasValue } from '../../empty.util'; -import { FILTER_SEARCH } from '../../../admin/admin-notify-dashboard/admin-notify-dashboard.component'; @Component({ selector: 'ds-search-filters', @@ -72,7 +71,7 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { */ constructor( private searchService: SearchService, - @Inject(FILTER_SEARCH) protected filterService: SearchFilterService, + protected filterService: SearchFilterService, private router: Router, @Inject(SEARCH_CONFIG_SERVICE) private searchConfigService: SearchConfigurationService) { } diff --git a/src/app/shared/search/search.component.ts b/src/app/shared/search/search.component.ts index 184dc2fb21..61f3a119c8 100644 --- a/src/app/shared/search/search.component.ts +++ b/src/app/shared/search/search.component.ts @@ -101,11 +101,6 @@ export class SearchComponent implements OnInit { */ @Input() searchEnabled = true; - /** - * Config param for route service - */ - @Input() routeConfigParam: string; - /** * The width of the sidebar (bootstrap columns) */ @@ -297,12 +292,8 @@ export class SearchComponent implements OnInit { this.searchConfigService.setPaginationId(this.paginationId); - if (this.routeConfigParam) { - this.searchConfigService.setRouteConfigurationParamName(this.routeConfigParam); - } - if (hasValue(this.configuration)) { - this.routeService.setParameter(this.routeConfigParam ?? 'configuration', this.configuration); + this.routeService.setParameter('configuration', this.configuration); } if (hasValue(this.fixedFilterQuery)) { this.routeService.setParameter('fixedFilterQuery', this.fixedFilterQuery); diff --git a/src/app/shared/search/themed-search.component.ts b/src/app/shared/search/themed-search.component.ts index 555056eacc..03f6f37e25 100644 --- a/src/app/shared/search/themed-search.component.ts +++ b/src/app/shared/search/themed-search.component.ts @@ -20,7 +20,7 @@ import { ListableObject } from '../object-collection/shared/listable-object.mode }) export class ThemedSearchComponent extends ThemedComponent { - protected inAndOutputNames: (keyof SearchComponent & keyof this)[] = ['configurationList', 'context', 'configuration', 'fixedFilterQuery', 'routeConfigParam', 'useCachedVersionIfAvailable', 'inPlaceSearch', 'linkType', 'paginationId', 'searchEnabled', 'sideBarWidth', 'searchFormPlaceholder', 'selectable', 'selectionConfig', 'showCsvExport', 'showSidebar', 'showThumbnails', 'showViewModes', 'useUniquePageId', 'viewModeList', 'showScopeSelector', 'resultFound', 'deselectObject', 'selectObject', 'trackStatistics', 'query']; + protected inAndOutputNames: (keyof SearchComponent & keyof this)[] = ['configurationList', 'context', 'configuration', 'fixedFilterQuery', 'useCachedVersionIfAvailable', 'inPlaceSearch', 'linkType', 'paginationId', 'searchEnabled', 'sideBarWidth', 'searchFormPlaceholder', 'selectable', 'selectionConfig', 'showCsvExport', 'showSidebar', 'showThumbnails', 'showViewModes', 'useUniquePageId', 'viewModeList', 'showScopeSelector', 'resultFound', 'deselectObject', 'selectObject', 'trackStatistics', 'query']; @Input() configurationList: SearchConfigurationOption[]; @@ -30,8 +30,6 @@ export class ThemedSearchComponent extends ThemedComponent { @Input() fixedFilterQuery: string; - @Input() routeConfigParam: string; - @Input() useCachedVersionIfAvailable: boolean; @Input() inPlaceSearch: boolean; From c57ad8eeb7dd9c2b81520e523d92ff0d8d7f83e7 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Mon, 8 Jan 2024 16:47:24 +0100 Subject: [PATCH 049/142] refactor, add detail mapping, add missing translation, optimize modal --- .../admin-notify-dashboard-routing.module.ts | 16 +++ .../admin-notify-dashboard.module.ts | 8 +- .../admin-notify-detail-modal.component.html | 10 +- .../admin-notify-incoming.component.html | 1 - .../admin-notify-incoming.component.ts | 2 +- .../admin-notify-outgoing.component.html | 1 - .../admin-notify-outgoing.component.ts | 2 +- .../admin-notify-search-result.component.html | 43 ++++++ ...admin-notify-search-result.component.scss} | 0 ...min-notify-search-result.component.spec.ts | 22 ++++ .../admin-notify-search-result.component.ts | 122 ++++++++++++++++++ ...tify-incoming-search-result.component.html | 40 ------ ...y-incoming-search-result.component.spec.ts | 22 ---- ...notify-incoming-search-result.component.ts | 97 -------------- ...tify-outgoing-search-result.component.html | 39 ------ ...tify-outgoing-search-result.component.scss | 0 ...y-outgoing-search-result.component.spec.ts | 22 ---- ...notify-outgoing-search-result.component.ts | 98 -------------- .../models/admin-notify-message.model.ts | 22 +++- .../services/admin-notify-messages.service.ts | 80 +++++++++++- src/app/core/shared/context.model.ts | 3 +- src/assets/i18n/en.json5 | 46 ++++++- 22 files changed, 358 insertions(+), 338 deletions(-) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html rename src/app/admin/admin-notify-dashboard/admin-notify-search-result/{incoming/admin-notify-incoming-search-result.component.scss => admin-notify-search-result.component.scss} (100%) create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts create mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.html delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.spec.ts delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.ts delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.html delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.scss delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.spec.ts delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.ts diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts index 345dc31ce3..7f74c023ff 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts @@ -34,11 +34,27 @@ import { path: 'inbound', component: AdminNotifyIncomingComponent, canActivate: [SiteAdministratorGuard], + resolve: { + breadcrumb: I18nBreadcrumbResolver, + }, + data: { + title: 'admin.notify.dashboard.page.title', + breadcrumbKey: 'admin.notify.dashboard', + showBreadcrumbsFluid: false + }, }, { path: 'outbound', component: AdminNotifyOutgoingComponent, canActivate: [SiteAdministratorGuard], + resolve: { + breadcrumb: I18nBreadcrumbResolver, + }, + data: { + title: 'admin.notify.dashboard.page.title', + breadcrumbKey: 'admin.notify.dashboard', + showBreadcrumbsFluid: false + }, } ]) ], diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts index 498c40a58d..1383b14443 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts @@ -8,14 +8,13 @@ import { AdminNotifyIncomingComponent } from './admin-notify-logs/admin-notify-i import { SharedModule } from '../../shared/shared.module'; import { SearchModule } from '../../shared/search/search.module'; import { SearchPageModule } from '../../search-page/search-page.module'; -import { AdminNotifyIncomingSearchResultComponent } from './admin-notify-search-result/incoming/admin-notify-incoming-search-result.component'; import { AdminNotifyOutgoingComponent } from './admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component'; import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal/admin-notify-detail-modal.component'; import { - AdminNotifyOutgoingSearchResultComponent -} from "./admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component"; + AdminNotifySearchResultComponent +} from "./admin-notify-search-result/admin-notify-search-result.component"; import { AdminNotifyMessagesService } from "./services/admin-notify-messages.service"; @@ -36,8 +35,7 @@ import { AdminNotifyMessagesService } from "./services/admin-notify-messages.ser AdminNotifyMetricsComponent, AdminNotifyIncomingComponent, AdminNotifyOutgoingComponent, - AdminNotifyIncomingSearchResultComponent, - AdminNotifyOutgoingSearchResultComponent, + AdminNotifySearchResultComponent, AdminNotifyDetailModalComponent ] }) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html index 57e1b40c1d..bbbfc22ed4 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html @@ -1,14 +1,14 @@ - diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts index ffb5306643..d895e35ede 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts @@ -16,7 +16,7 @@ import { SearchConfigurationService } from "../../../../core/shared/search/searc ] }) export class AdminNotifyIncomingComponent { - protected readonly context = Context.CoarNotifyIncoming; + protected readonly context = Context.CoarNotify; constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) { } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html index 050e25c241..8b9c031776 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.html @@ -21,7 +21,6 @@ [showViewModes]="false" [searchEnabled]="false" [context]="context" - [useUniquePageId]="true" >
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts index ac7a5cfafa..d85ec2daae 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts @@ -16,7 +16,7 @@ import { SearchConfigurationService } from "../../../../core/shared/search/searc ] }) export class AdminNotifyOutgoingComponent { - protected readonly context = Context.CoarNotifyOutgoing; + protected readonly context = Context.CoarNotify; constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) { } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html new file mode 100644 index 0000000000..310a04c1ed --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html @@ -0,0 +1,43 @@ +
    + + + + + + + + + + + + + + + + + + + + + +
    {{ 'notify-message-result.timestamp' | translate}}{{'notify-message-result.repositoryItem' | translate}}{{ 'notify-message-result.ldnService' | translate}}{{ 'notify-message-result.type' | translate }}{{ 'notify-message-result.status' | translate }}{{ 'notify-message-result.action' | translate }}
    +
    {{message.queueTimeout}}
    +
    +
    {{message.context}}
    +
    {{message.object}}
    +
    +
    {{message.origin}}
    +
    {{message.target}}
    +
    +
    {{message.coarNotifyType}}
    +
    +
    {{message.queueStatusLabel}}
    +
    +
    + + +
    +
    +
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss similarity index 100% rename from src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.scss rename to src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts new file mode 100644 index 0000000000..b17a03274f --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AdminNotifySearchResultComponent } from './admin-notify-search-result.component'; + +describe('AdminNotifySearchResultComponent', () => { + let component: AdminNotifySearchResultComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AdminNotifySearchResultComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminNotifySearchResultComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts new file mode 100644 index 0000000000..f75eab3366 --- /dev/null +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -0,0 +1,122 @@ +import { ChangeDetectorRef, Component, Inject, OnDestroy, OnInit } from '@angular/core'; +import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model'; +import { ViewMode } from '../../../core/shared/view-mode.model'; +import { Context } from '../../../core/shared/context.model'; +import { AdminNotifyMessage, QueueStatusMap } from '../models/admin-notify-message.model'; +import { + tabulatableObjectsComponent +} from '../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator'; +import { + TabulatableResultListElementsComponent +} from '../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; +import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component'; +import { LdnServicesService } from "../../admin-ldn-services/ldn-services-data/ldn-services-data.service"; +import { BehaviorSubject, from, Observable, of, scan, Subscription, switchMap } from "rxjs"; +import { combineLatest, filter, map, mergeMap, tap } from "rxjs/operators"; +import { getAllSucceededRemoteDataPayload } from "../../../core/shared/operators"; +import { ItemDataService } from "../../../core/data/item-data.service"; +import { AdminNotifyMessagesService } from "../services/admin-notify-messages.service"; +import { SearchConfigurationService } from "../../../core/shared/search/search-configuration.service"; +import { SEARCH_CONFIG_SERVICE } from "../../../my-dspace-page/my-dspace-page.component"; + +@tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotify) +@Component({ + selector: 'ds-admin-notify-search-result', + templateUrl: './admin-notify-search-result.component.html', + styleUrls: ['./admin-notify-search-result.component.scss'], + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationService + } + ] +}) +export class AdminNotifySearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifySearchResult> implements OnInit, OnDestroy{ + public messagesSubject$: BehaviorSubject = new BehaviorSubject([]); + public reprocessStatus = QueueStatusMap.QUEUE_STATUS_QUEUED_FOR_RETRY; + //we check on one type of config to render specific table headers + public isInbound: boolean; + + /** + * Array to track all subscriptions and unsubscribe them onDestroy + * @type {Array} + */ + private subs: Subscription[] = []; + + constructor(private modalService: NgbModal, + private adminNotifyMessagesService: AdminNotifyMessagesService, + @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) { + super(); + } + + /** + * Map messages on init for readable representation + */ + ngOnInit() { + this.mapDetailsToMessages() + this.subs.push(this.searchConfigService.getCurrentConfiguration('') + .subscribe(configuration => { + this.isInbound = configuration === 'NOTIFY.incoming'; + }) + ); + } + + ngOnDestroy() { + this.subs.forEach(sub => sub.unsubscribe()); + } + + /** + * Open modal for details visualization + * @param message the message to be displayed + */ + openDetailModal(message: AdminNotifyMessage) { + const modalRef = this.modalService.open(AdminNotifyDetailModalComponent); + const messageToOpen = {...message}; + // we delete not necessary or not readable keys + if (this.isInbound) { + delete messageToOpen.target; + delete messageToOpen.object; + } else { + delete messageToOpen.context; + delete messageToOpen.origin; + } + delete messageToOpen._links; + delete messageToOpen.metadata; + delete messageToOpen.thumbnail; + delete messageToOpen.item; + delete messageToOpen.accessStatus; + delete messageToOpen.queueStatus; + + const messageKeys = Object.keys(messageToOpen); + modalRef.componentInstance.notifyMessage = messageToOpen; + modalRef.componentInstance.notifyMessageKeys = messageKeys; + } + + /** + * Reprocess message in status QUEUE_STATUS_QUEUED_FOR_RETRY and update results + * @param message the message to be reprocessed + */ + reprocessMessage(message: AdminNotifyMessage) { + this.subs.push( + this.adminNotifyMessagesService.reprocessMessage(message, this.messagesSubject$) + .subscribe(response => { + this.messagesSubject$.next(response) + } + ) + ) + } + + + /** + * Map readable results to messages + * @private + */ + private mapDetailsToMessages() { + this.subs.push(this.adminNotifyMessagesService.getDetailedMessages(this.objects?.page.map(pageResult => pageResult.indexableObject)) + .subscribe(response => { + this.messagesSubject$.next(response) + })) + } +} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.html deleted file mode 100644 index 06aa551a44..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.html +++ /dev/null @@ -1,40 +0,0 @@ - -
    - - - - - - - - - - - - - - - - - - - - - -
    TimestampLDN ServiceRepository ItemTypeStatusAction
    -
    {{message.queueTimeout}}
    -
    -
    {{message.origin}}
    -
    -
    {{message.context}}
    -
    -
    {{message.coarNotifyType}}
    -
    -
    {{message.queueStatusLabel}}
    -
    -
    - - -
    -
    -
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.spec.ts deleted file mode 100644 index 2db8920d7f..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { AdminNotifyIncomingSearchResultComponent } from './admin-notify-incoming-search-result.component'; - -describe('AdminNotifySearchResultComponent', () => { - let component: AdminNotifyIncomingSearchResultComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ AdminNotifyIncomingSearchResultComponent ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(AdminNotifyIncomingSearchResultComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.ts deleted file mode 100644 index 11e94c05c5..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/incoming/admin-notify-incoming-search-result.component.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { AdminNotifySearchResult } from '../../models/admin-notify-message-search-result.model'; -import { ViewMode } from '../../../../core/shared/view-mode.model'; -import { Context } from '../../../../core/shared/context.model'; -import { AdminNotifyMessage, QueueStatusMap } from '../../models/admin-notify-message.model'; -import { - tabulatableObjectsComponent -} from '../../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator'; -import { - TabulatableResultListElementsComponent -} from '../../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; -import { PaginatedList } from '../../../../core/data/paginated-list.model'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { AdminNotifyDetailModalComponent } from '../../admin-notify-detail-modal/admin-notify-detail-modal.component'; -import { LdnServicesService } from "../../../admin-ldn-services/ldn-services-data/ldn-services-data.service"; -import { BehaviorSubject, concatMap, from, Observable, of, scan, switchMap } from "rxjs"; -import { RemoteData } from "../../../../core/data/remote-data"; -import { LdnService } from "../../../admin-ldn-services/ldn-services-model/ldn-services.model"; -import { filter, map, mergeMap, take, tap, toArray } from "rxjs/operators"; -import { getAllSucceededRemoteDataPayload } from "../../../../core/shared/operators"; -import { ItemDataService } from "../../../../core/data/item-data.service"; -import { AdminNotifyMessagesService } from "../../services/admin-notify-messages.service"; - -@tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotifyIncoming) -@Component({ - selector: 'ds-admin-notify-search-result', - templateUrl: './admin-notify-incoming-search-result.component.html', - styleUrls: ['./admin-notify-incoming-search-result.component.scss'] -}) -export class AdminNotifyIncomingSearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifySearchResult> implements OnInit{ - public notifyMessages: AdminNotifyMessage[]; - public notifyMessages$: Observable; - public reprocessStatus = QueueStatusMap.QUEUE_STATUS_QUEUED_FOR_RETRY; - - - - constructor(private modalService: NgbModal, - private ldnServicesService: LdnServicesService, - private itemDataService: ItemDataService, - private adminNotifyMessagesService: AdminNotifyMessagesService) { - super(); - } - - /** - * Map messages on init for readable representation - */ - ngOnInit() { - this.notifyMessages = this.objects?.page.map(object => { - const indexableObject = object.indexableObject; - indexableObject.coarNotifyType = indexableObject.coarNotifyType.split(':')[1]; - indexableObject.queueStatusLabel = QueueStatusMap[indexableObject.queueStatusLabel]; - return indexableObject; - }); - - this.notifyMessages$ = from(this.notifyMessages).pipe( - mergeMap(message => of(message)), - mergeMap(message => - message.origin ? this.ldnServicesService.findById(message.origin.toString()).pipe( - getAllSucceededRemoteDataPayload(), - map(detail => ({...message, origin: detail.name})) - ) : of(message), - ), - mergeMap(message => - message.context ? this.itemDataService.findById(message.context.toString()).pipe( - getAllSucceededRemoteDataPayload(), - map(detail => ({...message, context: detail.name})) - ) : of(message), - ), - scan((acc: any, value: any) => [...acc, value], []), - ) - } - - /** - * Open modal for details visualization - * @param message the message to be displayed - */ - openDetailModal(message: AdminNotifyMessage) { - const modalRef = this.modalService.open(AdminNotifyDetailModalComponent); - const messageKeys = Object.keys(message); - const keysToRead = []; - messageKeys.forEach((key) => { - if (typeof message[key] !== 'object') { - keysToRead.push(key); - } - }); - modalRef.componentInstance.notifyMessage = message; - modalRef.componentInstance.notifyMessageKeys = keysToRead; - } - - /** - * Reprocess message in status QUEUE_STATUS_QUEUED_FOR_RETRY and update results - * @param message - */ - reprocessMessage(message: AdminNotifyMessage) { - // TODO implement reprocess - } -} diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.html deleted file mode 100644 index 639d66a1f3..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.html +++ /dev/null @@ -1,39 +0,0 @@ -
    - - - - - - - - - - - - - - - - - - - - - -
    TimestampRepository ItemLDN ServiceTypeStatusAction
    -
    {{message.queueTimeout}}
    -
    -
    {{message.object}}
    -
    -
    {{message.target}}
    -
    -
    {{message.coarNotifyType}}
    -
    -
    {{message.queueStatusLabel}}
    -
    -
    - - -
    -
    -
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.spec.ts deleted file mode 100644 index 110feb2e0c..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { AdminNotifyOutgoingSearchResultComponent } from './admin-notify-outgoing-search-result.component'; - -describe('AdminNotifySearchResultComponent', () => { - let component: AdminNotifyOutgoingSearchResultComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ AdminNotifyOutgoingSearchResultComponent ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(AdminNotifyOutgoingSearchResultComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.ts deleted file mode 100644 index b5b49a8a71..0000000000 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/outgoing/admin-notify-outgoing-search-result.component.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { AdminNotifySearchResult } from '../../models/admin-notify-message-search-result.model'; -import { ViewMode } from '../../../../core/shared/view-mode.model'; -import { Context } from '../../../../core/shared/context.model'; -import { AdminNotifyMessage, QueueStatusMap } from '../../models/admin-notify-message.model'; -import { - tabulatableObjectsComponent -} from '../../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator'; -import { - TabulatableResultListElementsComponent -} from '../../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; -import { PaginatedList } from '../../../../core/data/paginated-list.model'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { AdminNotifyDetailModalComponent } from '../../admin-notify-detail-modal/admin-notify-detail-modal.component'; -import { LdnServicesService } from "../../../admin-ldn-services/ldn-services-data/ldn-services-data.service"; -import { from, Observable, of, scan, switchMap } from "rxjs"; -import { combineLatest, filter, map, mergeMap } from "rxjs/operators"; -import { getAllSucceededRemoteDataPayload } from "../../../../core/shared/operators"; -import { ItemDataService } from "../../../../core/data/item-data.service"; -import { AdminNotifyMessagesService } from "../../services/admin-notify-messages.service"; - -@tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotifyOutgoing) -@Component({ - selector: 'ds-admin-notify-search-result', - templateUrl: './admin-notify-outgoing-search-result.component.html', - styleUrls: ['./admin-notify-outgoing-search-result.component.scss'] -}) -export class AdminNotifyOutgoingSearchResultComponent extends TabulatableResultListElementsComponent, AdminNotifySearchResult> implements OnInit{ - public notifyMessages: AdminNotifyMessage[]; - public notifyMessages$: Observable; - public reprocessStatus = QueueStatusMap.QUEUE_STATUS_QUEUED_FOR_RETRY; - - constructor(private modalService: NgbModal, - private ldnServicesService: LdnServicesService, - private itemDataService: ItemDataService, - private adminNotifyMessagesService: AdminNotifyMessagesService) { - super(); - } - - /** - * Map messages on init for readable representation - */ - ngOnInit() { - this.mapDetailsToMessages() - } - - /** - * Open modal for details visualization - * @param message the message to be displayed - */ - openDetailModal(message: AdminNotifyMessage) { - const modalRef = this.modalService.open(AdminNotifyDetailModalComponent); - const messageKeys = Object.keys(message); - modalRef.componentInstance.notifyMessage = message; - modalRef.componentInstance.notifyMessageKeys = messageKeys; - } - - /** - * Reprocess message in status QUEUE_STATUS_QUEUED_FOR_RETRY and update results - * @param message - */ - reprocessMessage(message: AdminNotifyMessage) { - this.adminNotifyMessagesService.findById(message.id).pipe(getAllSucceededRemoteDataPayload()).subscribe(response => { - console.log(response); - }) - } - - - /** - * Map readable results to messages - * @private - */ - private mapDetailsToMessages() { - this.notifyMessages = this.objects?.page.map(object => { - const indexableObject = object.indexableObject; - indexableObject.coarNotifyType = indexableObject.coarNotifyType.split(':')[1]; - indexableObject.queueStatusLabel = QueueStatusMap[indexableObject.queueStatusLabel]; - return indexableObject; - }); - - this.notifyMessages$ = from(this.notifyMessages).pipe( - mergeMap(message => of(message)), - mergeMap(message => - message.target ? this.ldnServicesService.findById(message.target.toString()).pipe( - getAllSucceededRemoteDataPayload(), - map(detail => ({...message, target: detail.name})) - ) : of(message), - ), - mergeMap(message => - message.object ? this.itemDataService.findById(message.object.toString()).pipe( - getAllSucceededRemoteDataPayload(), - map(detail => ({...message, object: detail.name})) - ) : of(message), - ), - scan((acc: any, value: any) => [...acc, value], []), - ) - } -} diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts index 1fda25d1ef..4c36e01eaf 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -1,10 +1,11 @@ -import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; +import { autoserialize, autoserializeAs, deserialize, inheritSerialization } from 'cerialize'; import { typedObject } from '../../../core/cache/builders/build-decorators'; import { ADMIN_NOTIFY_MESSAGE } from './admin-notify-message.resource-type'; import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { GenericConstructor } from '../../../core/shared/generic-constructor'; import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; +import { Observable } from "rxjs"; export enum QueueStatusMap { QUEUE_STATUS_PROCESSED = 'Processed', @@ -107,6 +108,25 @@ export class AdminNotifyMessage extends DSpaceObject { @autoserialize queueStatus: number; + /** + * Thumbnail link used when browsing items with showThumbs config enabled. + */ + @autoserialize + thumbnail: string; + + /** + * The observable pointing to the item itself + */ + @autoserialize + item: Observable; + + /** + * The observable pointing to the access status of the item + */ + @autoserialize + accessStatus: Observable; + + @deserialize _links: { diff --git a/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts b/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts index 8f710d987d..d61c6f7712 100644 --- a/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts +++ b/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts @@ -10,7 +10,7 @@ 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 { BehaviorSubject, from, Observable, of, scan } from 'rxjs'; import {RemoteData} from '../../../core/data/remote-data'; import {PaginatedList} from '../../../core/data/paginated-list.model'; import {NoContent} from '../../../core/shared/NoContent.model'; @@ -21,7 +21,13 @@ import {RestRequestMethod} from '../../../core/data/rest-request-method'; import {CreateData, CreateDataImpl} from '../../../core/data/base/create-data'; import {SearchDataImpl} from '../../../core/data/base/search-data'; import { ADMIN_NOTIFY_MESSAGE } from "../models/admin-notify-message.resource-type"; -import { AdminNotifyMessage } from "../models/admin-notify-message.model"; +import { AdminNotifyMessage, QueueStatusMap } from "../models/admin-notify-message.model"; +import { SearchResult } from "../../../shared/search/models/search-result.model"; +import { map, mergeMap } from "rxjs/operators"; +import { getAllSucceededRemoteDataPayload } from "../../../core/shared/operators"; +import { AdminNotifySearchResult } from "../models/admin-notify-message-search-result.model"; +import { LdnServicesService } from "../../admin-ldn-services/ldn-services-data/ldn-services-data.service"; +import { ItemDataService } from "../../../core/data/item-data.service"; /** * Injectable service responsible for fetching/sending data from/to the REST API on the messages endpoint. @@ -39,7 +45,77 @@ export class AdminNotifyMessagesService extends IdentifiableDataService { + return from(messages.map(message => this.formatMessageLabels(message))).pipe( + mergeMap(message => + message.target ? this.ldnServicesService.findById(message.target.toString()).pipe( + getAllSucceededRemoteDataPayload(), + map(detail => ({...message, target: detail.name})) + ) : of(message), + ), + mergeMap(message => + message.object ? this.itemDataService.findById(message.object.toString()).pipe( + getAllSucceededRemoteDataPayload(), + map(detail => ({...message, object: detail.name})) + ) : of(message), + ), + mergeMap(message => + message.origin ? this.ldnServicesService.findById(message.origin.toString()).pipe( + getAllSucceededRemoteDataPayload(), + map(detail => ({...message, origin: detail.name})) + ) : of(message), + ), + mergeMap(message => + message.context ? this.itemDataService.findById(message.context.toString()).pipe( + getAllSucceededRemoteDataPayload(), + map(detail => ({...message, context: detail.name})) + ) : of(message), + ), + scan((acc: any, value: any) => [...acc, value], []), + ) + } + + /** + * Reprocess message in status QUEUE_STATUS_QUEUED_FOR_RETRY and update results + * @param message the message to reprocess + * @param messageSubject the current visualised messages source + */ + public reprocessMessage(message: AdminNotifyMessage, messageSubject: BehaviorSubject) : Observable { + return this.findById(message.id).pipe( + getAllSucceededRemoteDataPayload(), + map(reprocessedMessage => this.formatMessageLabels(reprocessedMessage)), + mergeMap((newMessage) => messageSubject.pipe( + map(messages => { + const messageToUpdate = messages.find(currentMessage => currentMessage.id === message.id); + const indexOfMessageToUpdate = messages.indexOf(messageToUpdate); + newMessage.target = messageToUpdate.target; + newMessage.object = messageToUpdate.object; + newMessage.origin = messageToUpdate.origin; + newMessage.context = messageToUpdate.context; + messages[indexOfMessageToUpdate] = newMessage; + return messages + }) + )), + ) + } } diff --git a/src/app/core/shared/context.model.ts b/src/app/core/shared/context.model.ts index 1526be1033..dcebf5794c 100644 --- a/src/app/core/shared/context.model.ts +++ b/src/app/core/shared/context.model.ts @@ -40,6 +40,5 @@ export enum Context { Bitstream = 'bitstream', - CoarNotifyIncoming = 'coarNotifyIncoming', - CoarNotifyOutgoing = 'coarNotifyOutgoing', + CoarNotify = 'coarNotify', } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 60134d54e3..b93abdf993 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3529,7 +3529,51 @@ "sorting.queue_attempts.ASC": "Queue attempted Ascending", - "orgunit.listelement.badge": "Organizational Unit", + "type.notify-detail-modal": "Type", + + "id.notify-detail-modal": "Id", + + "coarNotifyType.notify-detail-modal": "Coar Notify type", + + "activityStreamType.notify-detail-modal": "Activity stream type", + + "inReplyTo.notify-detail-modal": "In reply to", + + "object.notify-detail-modal": "Repository Item", + + "context.notify-detail-modal": "Repository Item", + + "queueAttempts.notify-detail-modal": "Queue attempts", + + "queueLastStartTime.notify-detail-modal": "Queue last started", + + "origin.notify-detail-modal": "LDN Service", + + "target.notify-detail-modal": "LDN Service", + + "queueStatusLabel.notify-detail-modal": "Queue status", + + "queueTimeout.notify-detail-modal": "Queue timeout", + + "notify-message-modal.title": "Message Detail", + + "notify-message-result.timestamp": "Timestamp", + + "notify-message-result.repositoryItem": "Repository Item", + + "notify-message-result.ldnService": "LDN Service", + + "notify-message-result.type": "Type", + + "notify-message-result.status": "Status", + + "notify-message-result.action": "Action", + + "notify-message-result.detail": "Detail", + + "notify-message-result.reprocess": "Reprocess", + + "orgunit.listelement.badge": "Repository Item", "orgunit.listelement.no-title": "Untitled", From c20d79850214244b20074b6f0cda8c3b8cbc5734 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Mon, 8 Jan 2024 18:04:49 +0100 Subject: [PATCH 050/142] clean up, fix tests, add missing translations --- .../admin-notify-dashboard-routing.module.ts | 4 +- .../admin-notify-dashboard.component.ts | 4 +- .../admin-notify-dashboard.module.ts | 4 +- .../admin-notify-detail-modal.component.html | 2 +- ...dmin-notify-detail-modal.component.spec.ts | 4 +- .../admin-notify-incoming.component.spec.ts | 23 ++++---- .../admin-notify-incoming.component.ts | 2 +- .../admin-notify-outgoing.component.spec.ts | 23 ++++---- .../admin-notify-outgoing.component.ts | 2 +- .../admin-notify-search-result.component.html | 14 ++--- ...min-notify-search-result.component.spec.ts | 57 ++++++++++++++++++- .../admin-notify-search-result.component.ts | 24 ++++---- .../models/admin-notify-message.model.ts | 20 +++---- .../services/admin-notify-messages.service.ts | 39 ++++--------- .../search-navbar/search-navbar.component.ts | 1 - ...-object-component-loader.component.spec.ts | 2 +- ...bulatable-objects-loader.component.spec.ts | 31 ++++------ .../search-facet-option.component.ts | 2 +- .../search-facet-range-option.component.ts | 2 +- .../search-facet-selected-option.component.ts | 2 +- src/assets/i18n/en.json5 | 14 +++++ 21 files changed, 159 insertions(+), 117 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts index 7f74c023ff..94f0347f49 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard-routing.module.ts @@ -8,10 +8,10 @@ import { } from '../../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard'; import { AdminNotifyIncomingComponent -} from "./admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component"; +} from './admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component'; import { AdminNotifyOutgoingComponent -} from "./admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component"; +} from './admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component'; @NgModule({ imports: [ diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 3d4f35a54c..3156a4ce45 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -1,4 +1,4 @@ -import { Component, InjectionToken, OnInit } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { SearchService } from '../../core/shared/search/search.service'; import { environment } from '../../../environments/environment'; import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; @@ -12,7 +12,7 @@ import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component'; import { ViewMode } from '../../core/shared/view-mode.model'; import { Router } from '@angular/router'; -import { SearchConfigurationService } from "../../core/shared/search/search-configuration.service"; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; @Component({ diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts index 1383b14443..2b6e1a8880 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.module.ts @@ -14,8 +14,8 @@ import { import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal/admin-notify-detail-modal.component'; import { AdminNotifySearchResultComponent -} from "./admin-notify-search-result/admin-notify-search-result.component"; -import { AdminNotifyMessagesService } from "./services/admin-notify-messages.service"; +} from './admin-notify-search-result/admin-notify-search-result.component'; +import { AdminNotifyMessagesService } from './services/admin-notify-messages.service'; @NgModule({ diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html index bbbfc22ed4..29f4e12f4c 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html @@ -8,7 +8,7 @@
    {{ key + '.notify-detail-modal' | translate}}
    -
    {{ notifyMessage[key] }}
    +
    {{ notifyMessage[key] | translate }}
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts index 77a878429c..e4c701ea9d 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.spec.ts @@ -1,7 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal.component'; -import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateModule } from '@ngx-translate/core'; describe('AdminNotifyDetailModalComponent', () => { let component: AdminNotifyDetailModalComponent; @@ -9,6 +10,7 @@ describe('AdminNotifyDetailModalComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], declarations: [ AdminNotifyDetailModalComponent ], providers: [NgbActiveModal] }) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts index 14d6c6a1eb..f7388c5210 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.spec.ts @@ -2,18 +2,17 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyIncomingComponent } from './admin-notify-incoming.component'; import { TranslateModule } from '@ngx-translate/core'; -import { ActivatedRoute } from "@angular/router"; -import { MockActivatedRoute } from "../../../../shared/mocks/active-router.mock"; -import { provideMockStore } from "@ngrx/store/testing"; -import { HALEndpointService } from "../../../../core/shared/hal-endpoint.service"; -import { SEARCH_CONFIG_SERVICE } from "../../../../my-dspace-page/my-dspace-page.component"; -import { FILTER_CONFIG, SearchFilterService } from "../../../../core/shared/search/search-filter.service"; -import { RouteService } from "../../../../core/services/route.service"; -import { routeServiceStub } from "../../../../shared/testing/route-service.stub"; -import { RequestService } from "../../../../core/data/request.service"; -import { RemoteDataBuildService } from "../../../../core/cache/builders/remote-data-build.service"; -import { getMockRemoteDataBuildService } from "../../../../shared/mocks/remote-data-build.service.mock"; -import { SearchConfigurationService } from "../../../../core/shared/search/search-configuration.service"; +import { ActivatedRoute } from '@angular/router'; +import { MockActivatedRoute } from '../../../../shared/mocks/active-router.mock'; +import { provideMockStore } from '@ngrx/store/testing'; +import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; +import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; +import { RouteService } from '../../../../core/services/route.service'; +import { routeServiceStub } from '../../../../shared/testing/route-service.stub'; +import { RequestService } from '../../../../core/data/request.service'; +import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; +import { getMockRemoteDataBuildService } from '../../../../shared/mocks/remote-data-build.service.mock'; +import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; describe('AdminNotifyIncomingComponent', () => { let component: AdminNotifyIncomingComponent; diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts index d895e35ede..799d959107 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts @@ -1,7 +1,7 @@ import { Component, Inject } from '@angular/core'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { Context } from '../../../../core/shared/context.model'; -import { SearchConfigurationService } from "../../../../core/shared/search/search-configuration.service"; +import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; @Component({ diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts index 9d3ab2fe46..a8af9a7fd6 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.spec.ts @@ -2,18 +2,17 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifyOutgoingComponent } from './admin-notify-outgoing.component'; import { TranslateModule } from '@ngx-translate/core'; -import { ActivatedRoute } from "@angular/router"; -import { MockActivatedRoute } from "../../../../shared/mocks/active-router.mock"; -import { provideMockStore } from "@ngrx/store/testing"; -import { HALEndpointService } from "../../../../core/shared/hal-endpoint.service"; -import { SEARCH_CONFIG_SERVICE } from "../../../../my-dspace-page/my-dspace-page.component"; -import { FILTER_CONFIG } from "../../../../core/shared/search/search-filter.service"; -import { RouteService } from "../../../../core/services/route.service"; -import { routeServiceStub } from "../../../../shared/testing/route-service.stub"; -import { RequestService } from "../../../../core/data/request.service"; -import { getMockRemoteDataBuildService } from "../../../../shared/mocks/remote-data-build.service.mock"; -import { RemoteDataBuildService } from "../../../../core/cache/builders/remote-data-build.service"; -import { SearchConfigurationService } from "../../../../core/shared/search/search-configuration.service"; +import { ActivatedRoute } from '@angular/router'; +import { MockActivatedRoute } from '../../../../shared/mocks/active-router.mock'; +import { provideMockStore } from '@ngrx/store/testing'; +import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; +import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; +import { RouteService } from '../../../../core/services/route.service'; +import { routeServiceStub } from '../../../../shared/testing/route-service.stub'; +import { RequestService } from '../../../../core/data/request.service'; +import { getMockRemoteDataBuildService } from '../../../../shared/mocks/remote-data-build.service.mock'; +import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; +import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; describe('AdminNotifyOutgoingComponent', () => { let component: AdminNotifyOutgoingComponent; diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts index d85ec2daae..1ef71be719 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts @@ -1,7 +1,7 @@ import { Component, Inject } from '@angular/core'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { Context } from '../../../../core/shared/context.model'; -import { SearchConfigurationService } from "../../../../core/shared/search/search-configuration.service"; +import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; @Component({ diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html index 310a04c1ed..c4fd93d2e0 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html @@ -13,21 +13,21 @@ -
    {{message.queueTimeout}}
    +
    {{ message.queueTimeout }}
    -
    {{message.context}}
    -
    {{message.object}}
    +
    {{ message.context }}
    +
    {{ message.object }}
    -
    {{message.origin}}
    -
    {{message.target}}
    +
    {{ message.origin }}
    +
    {{ message.target }}
    -
    {{message.coarNotifyType}}
    +
    {{ message.coarNotifyType }}
    -
    {{message.queueStatusLabel}}
    +
    {{ message.queueStatusLabel | translate}}
    diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts index b17a03274f..0c1eee81c3 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.spec.ts @@ -1,13 +1,68 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdminNotifySearchResultComponent } from './admin-notify-search-result.component'; +import { AdminNotifyMessagesService } from '../services/admin-notify-messages.service'; +import { ObjectCacheService } from '../../../core/cache/object-cache.service'; +import { RequestService } from '../../../core/data/request.service'; +import { HALEndpointService } from '../../../core/shared/hal-endpoint.service'; +import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; +import { cold } from 'jasmine-marbles'; +import { ConfigurationProperty } from '../../../core/shared/configuration-property.model'; +import { RouteService } from '../../../core/services/route.service'; +import { routeServiceStub } from '../../../shared/testing/route-service.stub'; +import { ActivatedRoute } from '@angular/router'; +import { RouterStub } from '../../../shared/testing/router.stub'; +import { TranslateModule } from '@ngx-translate/core'; +import { EMPTY } from 'rxjs'; describe('AdminNotifySearchResultComponent', () => { let component: AdminNotifySearchResultComponent; let fixture: ComponentFixture; + let objectCache: ObjectCacheService; + let requestService: RequestService; + let halService: HALEndpointService; + let rdbService: RemoteDataBuildService; + let adminNotifyMessageService: AdminNotifyMessagesService; + const requestUUID = '34cfed7c-f597-49ef-9cbe-ea351f0023c2'; + const testObject = { + uuid: 'test-property', + name: 'test-property', + values: ['value-1', 'value-2'] + } as ConfigurationProperty; + beforeEach(async () => { + halService = jasmine.createSpyObj('halService', { + getEndpoint: cold('a', { a: '' }) + }); + adminNotifyMessageService = jasmine.createSpyObj('adminNotifyMessageService', { + getDetailedMessages: EMPTY + }); + requestService = jasmine.createSpyObj('requestService', { + generateRequestId: requestUUID, + send: true + }); + rdbService = jasmine.createSpyObj('rdbService', { + buildSingle: cold('a', { + a: { + payload: testObject + } + }) + }); + objectCache = {} as ObjectCacheService; + + await TestBed.configureTestingModule({ - declarations: [ AdminNotifySearchResultComponent ] + imports: [TranslateModule.forRoot()], + declarations: [ AdminNotifySearchResultComponent ], + providers: [ + {provide: AdminNotifyMessagesService, useValue: adminNotifyMessageService}, + { provide: RouteService, useValue: routeServiceStub }, + { provide: ActivatedRoute, useValue: new RouterStub() }, + { provide: HALEndpointService, useValue: halService }, + { provide: ObjectCacheService, useValue: objectCache }, + { provide: RequestService, useValue: requestService }, + { provide: RemoteDataBuildService, useValue: rdbService }, + ] }) .compileComponents(); diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index f75eab3366..dd4a159bf9 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component, Inject, OnDestroy, OnInit } from '@angular/core'; +import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model'; import { ViewMode } from '../../../core/shared/view-mode.model'; import { Context } from '../../../core/shared/context.model'; @@ -12,14 +12,10 @@ import { import { PaginatedList } from '../../../core/data/paginated-list.model'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component'; -import { LdnServicesService } from "../../admin-ldn-services/ldn-services-data/ldn-services-data.service"; -import { BehaviorSubject, from, Observable, of, scan, Subscription, switchMap } from "rxjs"; -import { combineLatest, filter, map, mergeMap, tap } from "rxjs/operators"; -import { getAllSucceededRemoteDataPayload } from "../../../core/shared/operators"; -import { ItemDataService } from "../../../core/data/item-data.service"; -import { AdminNotifyMessagesService } from "../services/admin-notify-messages.service"; -import { SearchConfigurationService } from "../../../core/shared/search/search-configuration.service"; -import { SEARCH_CONFIG_SERVICE } from "../../../my-dspace-page/my-dspace-page.component"; +import { BehaviorSubject, Subscription } from 'rxjs'; +import { AdminNotifyMessagesService } from '../services/admin-notify-messages.service'; +import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service'; +import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; @tabulatableObjectsComponent(PaginatedList, ViewMode.Table, Context.CoarNotify) @Component({ @@ -55,7 +51,7 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListEleme * Map messages on init for readable representation */ ngOnInit() { - this.mapDetailsToMessages() + this.mapDetailsToMessages(); this.subs.push(this.searchConfigService.getCurrentConfiguration('') .subscribe(configuration => { this.isInbound = configuration === 'NOTIFY.incoming'; @@ -102,10 +98,10 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListEleme this.subs.push( this.adminNotifyMessagesService.reprocessMessage(message, this.messagesSubject$) .subscribe(response => { - this.messagesSubject$.next(response) + this.messagesSubject$.next(response); } ) - ) + ); } @@ -116,7 +112,7 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListEleme private mapDetailsToMessages() { this.subs.push(this.adminNotifyMessagesService.getDetailedMessages(this.objects?.page.map(pageResult => pageResult.indexableObject)) .subscribe(response => { - this.messagesSubject$.next(response) - })) + this.messagesSubject$.next(response); + })); } } diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts index 4c36e01eaf..872b699228 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -1,21 +1,21 @@ -import { autoserialize, autoserializeAs, deserialize, inheritSerialization } from 'cerialize'; +import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; import { typedObject } from '../../../core/cache/builders/build-decorators'; import { ADMIN_NOTIFY_MESSAGE } from './admin-notify-message.resource-type'; import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { GenericConstructor } from '../../../core/shared/generic-constructor'; import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; -import { Observable } from "rxjs"; +import { Observable } from 'rxjs'; export enum QueueStatusMap { - QUEUE_STATUS_PROCESSED = 'Processed', - QUEUE_STATUS_FAILED = 'Failed', - QUEUE_STATUS_UNMAPPED_ACTION = 'Unmapped action', - QUEUE_STATUS_QUEUED_FOR_RETRY = 'Queued for retry', - QUEUE_STATUS_PROCESSING = 'Processing', - QUEUE_STATUS_QUEUED = 'Queued', - QUEUE_STATUS_UNTRUSTED = 'Untrusted', -}; + QUEUE_STATUS_PROCESSED = 'notify-queue-status.processed', + QUEUE_STATUS_FAILED = 'notify-queue-status.processed', + QUEUE_STATUS_UNMAPPED_ACTION = 'notify-queue-status.unmapped_action', + QUEUE_STATUS_QUEUED_FOR_RETRY = 'notify-queue-status.queue_retry', + QUEUE_STATUS_PROCESSING = 'notify-queue-status.processing', + QUEUE_STATUS_QUEUED = 'notify-queue-status.queued', + QUEUE_STATUS_UNTRUSTED = 'notify-queue-status.untrusted', +} /** * A message that includes admin notify info */ diff --git a/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts b/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts index d61c6f7712..5820f3b7d6 100644 --- a/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts +++ b/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts @@ -1,33 +1,18 @@ 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 { BehaviorSubject, from, Observable, of, scan } 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 {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 {CreateData, CreateDataImpl} from '../../../core/data/base/create-data'; -import {SearchDataImpl} from '../../../core/data/base/search-data'; -import { ADMIN_NOTIFY_MESSAGE } from "../models/admin-notify-message.resource-type"; -import { AdminNotifyMessage, QueueStatusMap } from "../models/admin-notify-message.model"; -import { SearchResult } from "../../../shared/search/models/search-result.model"; -import { map, mergeMap } from "rxjs/operators"; -import { getAllSucceededRemoteDataPayload } from "../../../core/shared/operators"; -import { AdminNotifySearchResult } from "../models/admin-notify-message-search-result.model"; -import { LdnServicesService } from "../../admin-ldn-services/ldn-services-data/ldn-services-data.service"; -import { ItemDataService } from "../../../core/data/item-data.service"; +import { ADMIN_NOTIFY_MESSAGE } from '../models/admin-notify-message.resource-type'; +import { AdminNotifyMessage, QueueStatusMap } from '../models/admin-notify-message.model'; +import { map, mergeMap } from 'rxjs/operators'; +import { getAllSucceededRemoteDataPayload } from '../../../core/shared/operators'; +import { LdnServicesService } from '../../admin-ldn-services/ldn-services-data/ldn-services-data.service'; +import { ItemDataService } from '../../../core/data/item-data.service'; /** * Injectable service responsible for fetching/sending data from/to the REST API on the messages endpoint. @@ -55,7 +40,7 @@ export class AdminNotifyMessagesService extends IdentifiableDataService { + public getDetailedMessages(messages: AdminNotifyMessage[]): Observable { return from(messages.map(message => this.formatMessageLabels(message))).pipe( mergeMap(message => message.target ? this.ldnServicesService.findById(message.target.toString()).pipe( @@ -92,7 +77,7 @@ export class AdminNotifyMessagesService extends IdentifiableDataService [...acc, value], []), - ) + ); } /** @@ -100,7 +85,7 @@ export class AdminNotifyMessagesService extends IdentifiableDataService) : Observable { + public reprocessMessage(message: AdminNotifyMessage, messageSubject: BehaviorSubject): Observable { return this.findById(message.id).pipe( getAllSucceededRemoteDataPayload(), map(reprocessedMessage => this.formatMessageLabels(reprocessedMessage)), @@ -113,9 +98,9 @@ export class AdminNotifyMessagesService extends IdentifiableDataService)[] { return [testType]; } diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts index 21fd2b94b2..a887482fa7 100644 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.spec.ts @@ -1,31 +1,24 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { TabulatableObjectsLoaderComponent } from './tabulatable-objects-loader.component'; -import { ThemeService } from "../../../theme-support/theme.service"; -import { provideMockStore } from "@ngrx/store/testing"; -import { ListableObject } from "../listable-object.model"; -import { PaginatedList } from "../../../../core/data/paginated-list.model"; -import { Context } from "../../../../core/shared/context.model"; -import { GenericConstructor } from "../../../../core/shared/generic-constructor"; -import { TabulatableObjectsDirective } from "./tabulatable-objects.directive"; -import { ListableObjectComponentLoaderComponent } from "../listable-object/listable-object-component-loader.component"; -import { ChangeDetectionStrategy } from "@angular/core"; -import { - ItemListElementComponent -} from "../../../object-list/item-list-element/item-types/item/item-list-element.component"; +import { ThemeService } from '../../../theme-support/theme.service'; +import { provideMockStore } from '@ngrx/store/testing'; +import { ListableObject } from '../listable-object.model'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; +import { Context } from '../../../../core/shared/context.model'; +import { TabulatableObjectsDirective } from './tabulatable-objects.directive'; +import { ChangeDetectionStrategy } from '@angular/core'; + + import { TabulatableResultListElementsComponent -} from "../../../object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component"; +} from '../../../object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; +import { TestType } from '../listable-object/listable-object-component-loader.component.spec'; const testType = 'TestType'; -class TestType extends ListableObject { - getRenderTypes(): (string | GenericConstructor)[] { - return [testType]; - } -} class TestTypes extends PaginatedList { - page: TestType[] = [new TestType()] + page: TestType[] = [new TestType()]; } diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts index b14d3187d7..cdbab61a30 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.ts @@ -1,6 +1,6 @@ import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; -import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { FacetValue } from '../../../../models/facet-value.model'; import { SearchFilterConfig } from '../../../../models/search-filter-config.model'; diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts index 6afe994f2f..b08a54e42b 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.ts @@ -1,6 +1,6 @@ import { Observable, Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; -import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { FacetValue } from '../../../../models/facet-value.model'; import { SearchFilterConfig } from '../../../../models/search-filter-config.model'; diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts index 8479417c57..4566b882eb 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts @@ -1,5 +1,5 @@ import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; -import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { SearchFilterConfig } from '../../../../models/search-filter-config.model'; import { SearchService } from '../../../../../../core/shared/search/search.service'; diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index b93abdf993..da0d1a3f82 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3573,6 +3573,20 @@ "notify-message-result.reprocess": "Reprocess", + "notify-queue-status.processed": "Processed", + + "notify-queue-status.failed": "Failed", + + "notify-queue-status.queue_retry": "Queued for retry", + + "notify-queue-status.unmapped_action": "Unmapped action", + + "notify-queue-status.processing": "Processing", + + "notify-queue-status.queued": "Queued", + + "notify-queue-status.untrusted": "Untrusted", + "orgunit.listelement.badge": "Repository Item", "orgunit.listelement.no-title": "Untitled", From 937abc0d50ec0c4e95d854ee82cabe87a365bdbf Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Mon, 8 Jan 2024 18:14:16 +0100 Subject: [PATCH 051/142] clean up --- src/app/admin/admin-routing-paths.ts | 1 + src/app/admin/admin.module.ts | 2 +- .../search/search-configuration.service.ts | 23 ++++--------------- .../shared/search/search-filter.service.ts | 4 ++-- src/app/core/shared/search/search.service.ts | 9 ++++---- .../search-navbar/search-navbar.component.ts | 1 + ...table-object-component-loader.component.ts | 1 + .../search-filters.component.ts | 2 +- 8 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/app/admin/admin-routing-paths.ts b/src/app/admin/admin-routing-paths.ts index c08139bd87..df8a3eb855 100644 --- a/src/app/admin/admin-routing-paths.ts +++ b/src/app/admin/admin-routing-paths.ts @@ -15,6 +15,7 @@ export function getRegistriesModuleRoute() { export function getNotificationsModuleRoute() { return new URLCombiner(getAdminModuleRoute(), NOTIFICATIONS_MODULE_PATH).toString(); } + export function getLdnServicesModuleRoute() { return new URLCombiner(getAdminModuleRoute(), LDN_PATH).toString(); } diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index d77c3213b3..3dc0036854 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -34,7 +34,7 @@ const ENTRY_COMPONENTS = [ declarations: [ AdminCurationTasksComponent, MetadataImportPageComponent, - BatchImportPageComponent, + BatchImportPageComponent ] }) export class AdminModule { diff --git a/src/app/core/shared/search/search-configuration.service.ts b/src/app/core/shared/search/search-configuration.service.ts index 36202ae11c..9d93eced8e 100644 --- a/src/app/core/shared/search/search-configuration.service.ts +++ b/src/app/core/shared/search/search-configuration.service.ts @@ -28,7 +28,6 @@ import { FacetConfigResponseParsingService } from '../../data/facet-config-respo import { ViewMode } from '../view-mode.model'; import { SearchFilterConfig } from '../../../shared/search/models/search-filter-config.model'; import { FacetConfigResponse } from '../../../shared/search/models/facet-config-response.model'; -import { DspaceRestResponseParsingService } from '../../data/dspace-rest-response-parsing.service'; /** * Service that performs all actions that have to do with the current search configuration @@ -44,7 +43,7 @@ export class SearchConfigurationService implements OnDestroy { /** * Endpoint link path for retrieving facet config incl values */ - protected facetLinkPathPrefix = 'discover/facets/'; + private facetLinkPathPrefix = 'discover/facets/'; /** * Default pagination id @@ -61,11 +60,6 @@ export class SearchConfigurationService implements OnDestroy { */ public paginatedSearchOptions: BehaviorSubject; - /** - * The name of the param to enhance and store the route config - */ - public routeConfigurationName: string; - /** * Default pagination settings */ @@ -137,7 +131,7 @@ export class SearchConfigurationService implements OnDestroy { getCurrentConfiguration(defaultConfiguration: string) { return observableCombineLatest([ this.routeService.getQueryParameterValue('configuration').pipe(startWith(undefined)), - this.routeService.getRouteParameterValue(this.routeConfigurationName ?? 'configuration').pipe(startWith(undefined)) + this.routeService.getRouteParameterValue('configuration').pipe(startWith(undefined)) ]).pipe( map(([queryConfig, routeConfig]) => { return queryConfig || routeConfig || defaultConfiguration; @@ -463,7 +457,7 @@ export class SearchConfigurationService implements OnDestroy { return this.rdb.buildFromHref(href$); } - protected getConfigUrl(url: string, scope?: string, configurationName?: string) { + private getConfigUrl(url: string, scope?: string, configurationName?: string) { const args: string[] = []; if (isNotEmpty(scope)) { @@ -489,7 +483,7 @@ export class SearchConfigurationService implements OnDestroy { * @param {string} configurationName the name of the configuration * @returns {Observable>} The found filter configuration */ - getConfig(scope?: string, configurationName?: string, facetParser?: DspaceRestResponseParsingService): Observable> { + getConfig(scope?: string, configurationName?: string): Observable> { const href$ = this.halService.getEndpoint(this.facetLinkPathPrefix).pipe( map((url: string) => this.getConfigUrl(url, scope, configurationName)), ); @@ -540,13 +534,4 @@ export class SearchConfigurationService implements OnDestroy { return { view }; })); } - - /** - * Set param to use for multiple configurations on same page and reload search subscriptions - */ - setRouteConfigurationParamName(configName: string): void { - this.routeConfigurationName = configName; - this.unsubscribeFromSearchOptions(this.paginationID); - this.setSearchSubscription(this.paginationID, this.paginatedSearchOptions.value); - } } diff --git a/src/app/core/shared/search/search-filter.service.ts b/src/app/core/shared/search/search-filter.service.ts index 4b4d7a80d7..80ba200d38 100644 --- a/src/app/core/shared/search/search-filter.service.ts +++ b/src/app/core/shared/search/search-filter.service.ts @@ -34,8 +34,8 @@ export const REFRESH_FILTER: InjectionToken> = new Injectio @Injectable() export class SearchFilterService { - constructor(protected store: Store, - protected routeService: RouteService) { + constructor(private store: Store, + private routeService: RouteService) { } /** diff --git a/src/app/core/shared/search/search.service.ts b/src/app/core/shared/search/search.service.ts index 986352f29f..a88a8b0d16 100644 --- a/src/app/core/shared/search/search.service.ts +++ b/src/app/core/shared/search/search.service.ts @@ -162,6 +162,7 @@ export class SearchService implements OnDestroy { getResponseParser: getResponseParserFn, searchOptions: searchOptions }); + this.requestService.send(request, useCachedVersionIfAvailable); }); @@ -188,11 +189,11 @@ export class SearchService implements OnDestroy { } /** - * Method to directly attach the notifyMessages to search results, instead of using RemoteData. + * Method to directly attach the indexableObjects to search results, instead of using RemoteData. * For compatibility with the way the search was written originally * * @param sqr$: a SearchObjects RemotaData Observable without its - * notifyMessages attached + * indexableObjects attached * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's * no valid cached version. Defaults to true * @param reRequestOnStale Whether or not the request should automatically be re- @@ -205,7 +206,7 @@ export class SearchService implements OnDestroy { return sqr$.pipe( switchMap((resultsRd: RemoteData>) => { if (hasValue(resultsRd.payload) && isNotEmpty(resultsRd.payload.page)) { - // retrieve the notifyMessages for all search results on the page + // retrieve the indexableObjects for all search results on the page const searchResult$Array: Observable>[] = resultsRd.payload.page.map((result: SearchResult) => this.dspaceObjectService.findByHref(result._links.indexableObject.href, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow as any).pipe( getFirstCompletedRemoteData(), @@ -227,7 +228,7 @@ export class SearchService implements OnDestroy { ); // Swap the original page in the remoteData with the new one, now that the results have the - // correct types, and all notifyMessages are directly attached. + // correct types, and all indexableObjects are directly attached. return observableCombineLatest(searchResult$Array).pipe( map((page: SearchResult[]) => { diff --git a/src/app/search-navbar/search-navbar.component.ts b/src/app/search-navbar/search-navbar.component.ts index 09bca42a06..98e64f6e10 100644 --- a/src/app/search-navbar/search-navbar.component.ts +++ b/src/app/search-navbar/search-navbar.component.ts @@ -64,6 +64,7 @@ export class SearchNavbarComponent { const queryParams = Object.assign({}, data); const linkToNavigateTo = [this.searchService.getSearchLink().replace('/', '')]; this.searchForm.reset(); + this.router.navigate(linkToNavigateTo, { queryParams: queryParams, queryParamsHandling: 'merge' diff --git a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts index 3110283ddd..7a3cc42bf5 100644 --- a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts +++ b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts @@ -154,6 +154,7 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges } private instantiateComponent(object: ListableObject, changes?: SimpleChanges): void { + const component = this.getComponent(object.getRenderTypes(), this.viewMode, this.context); const viewContainerRef = this.listableObjectDirective.viewContainerRef; diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index 63235b3e57..766939226d 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -71,7 +71,7 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { */ constructor( private searchService: SearchService, - protected filterService: SearchFilterService, + private filterService: SearchFilterService, private router: Router, @Inject(SEARCH_CONFIG_SERVICE) private searchConfigService: SearchConfigurationService) { } From 7ce0bd0ce63bc3d1658547842beb3c2d67e25d14 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Mon, 8 Jan 2024 18:27:43 +0100 Subject: [PATCH 052/142] remove unused method --- .../admin-notify-dashboard.component.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 3156a4ce45..2d9ab79eea 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -10,8 +10,6 @@ import { SearchObjects } from '../../shared/search/models/search-objects.model'; import { AdminNotifyMetricsBox, AdminNotifyMetricsRow } from './admin-notify-metrics/admin-notify-metrics.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component'; -import { ViewMode } from '../../core/shared/view-mode.model'; -import { Router } from '@angular/router'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; @@ -35,8 +33,8 @@ export class AdminNotifyDashboardComponent implements OnInit{ id: 'single-result-options', pageSize: 1 }); - constructor(private searchService: SearchService, - private router: Router) {} + constructor(private searchService: SearchService) { + } ngOnInit() { const mertricsRowsConfigurations = this.metricsConfig @@ -91,13 +89,6 @@ export class AdminNotifyDashboardComponent implements OnInit{ }); } - /** - * Activate Table view mode for search result rendering - */ - activateTableMode() { - this.searchService.setViewMode(ViewMode.Table, this.getSearchLinkParts()); - } - /** * @returns {string} The base path to the search page, or the current page when inPlaceSearch is true */ From 728911899a0927995c040366b44551082abae696 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Tue, 9 Jan 2024 09:36:50 +0100 Subject: [PATCH 053/142] clean up --- .../admin-notify-dashboard.component.scss | 0 .../admin-notify-dashboard.component.ts | 21 ++----------------- .../admin-notify-detail-modal.component.html | 4 ++-- .../admin-notify-detail-modal.component.scss | 0 .../admin-notify-detail-modal.component.ts | 1 - .../admin-notify-incoming.component.scss | 0 .../admin-notify-incoming.component.ts | 1 - .../admin-notify-outgoing.component.scss | 0 .../admin-notify-outgoing.component.ts | 1 - .../admin-notify-metrics.component.scss | 0 .../admin-notify-metrics.component.ts | 1 - .../admin-notify-search-result.component.scss | 0 .../admin-notify-search-result.component.ts | 1 - .../services/admin-notify-messages.service.ts | 2 +- .../tabulatable-objects-loader.component.scss | 3 --- .../tabulatable-objects-loader.component.ts | 1 - src/app/shared/search/search.component.html | 2 +- 17 files changed, 6 insertions(+), 32 deletions(-) delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.scss delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.scss delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.scss delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.scss delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.scss delete mode 100644 src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss delete mode 100644 src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.scss diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts index 2d9ab79eea..d2a20334c7 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-dashboard.component.ts @@ -16,7 +16,6 @@ import { SearchConfigurationService } from '../../core/shared/search/search-conf @Component({ selector: 'ds-admin-notify-dashboard', templateUrl: './admin-notify-dashboard.component.html', - styleUrls: ['./admin-notify-dashboard.component.scss'], providers: [ { provide: SEARCH_CONFIG_SERVICE, @@ -33,6 +32,7 @@ export class AdminNotifyDashboardComponent implements OnInit{ id: 'single-result-options', pageSize: 1 }); + constructor(private searchService: SearchService) { } @@ -84,25 +84,8 @@ export class AdminNotifyDashboardComponent implements OnInit{ return this.metricsConfig.map(row => { return { ...row, - boxes: row.boxes.map(rowBox =>boxesWithCount.find(boxWithCount => boxWithCount.config === rowBox.config)) + boxes: row.boxes.map(rowBox => boxesWithCount.find(boxWithCount => boxWithCount.config === rowBox.config)) }; }); } - - /** - * @returns {string} The base path to the search page, or the current page when inPlaceSearch is true - */ - public getSearchLink(): string { - return this.searchService.getSearchLink(); - } - - /** - * @returns {string[]} The base path to the search page, or the current page when inPlaceSearch is true, split in separate pieces - */ - public getSearchLinkParts(): string[] { - if (this.searchService) { - return []; - } - return this.getSearchLink().split('/'); - } } diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html index 29f4e12f4c..1b7265774d 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html @@ -4,11 +4,11 @@
    -
    + diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts index 3227e52420..fc9420b593 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts @@ -5,7 +5,6 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'ds-admin-notify-detail-modal', templateUrl: './admin-notify-detail-modal.component.html', - styleUrls: ['./admin-notify-detail-modal.component.scss'] }) export class AdminNotifyDetailModalComponent { @Input() notifyMessage: AdminNotifyMessage; diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts index 799d959107..7375a98abe 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component.ts @@ -7,7 +7,6 @@ import { SearchConfigurationService } from '../../../../core/shared/search/searc @Component({ selector: 'ds-admin-notify-incoming', templateUrl: './admin-notify-incoming.component.html', - styleUrls: ['./admin-notify-incoming.component.scss'], providers: [ { provide: SEARCH_CONFIG_SERVICE, diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts index 1ef71be719..290c8ace76 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component.ts @@ -7,7 +7,6 @@ import { SearchConfigurationService } from '../../../../core/shared/search/searc @Component({ selector: 'ds-admin-notify-outgoing', templateUrl: './admin-notify-outgoing.component.html', - styleUrls: ['./admin-notify-outgoing.component.scss'], providers: [ { provide: SEARCH_CONFIG_SERVICE, diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts index 57f834f872..ca5dd0115a 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts @@ -4,7 +4,6 @@ import { AdminNotifyMetricsRow } from './admin-notify-metrics.model'; @Component({ selector: 'ds-admin-notify-metrics', templateUrl: './admin-notify-metrics.component.html', - styleUrls: ['./admin-notify-metrics.component.scss'] }) export class AdminNotifyMetricsComponent { diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts index dd4a159bf9..1414d3de88 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.ts @@ -21,7 +21,6 @@ import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.co @Component({ selector: 'ds-admin-notify-search-result', templateUrl: './admin-notify-search-result.component.html', - styleUrls: ['./admin-notify-search-result.component.scss'], providers: [ { provide: SEARCH_CONFIG_SERVICE, diff --git a/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts b/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts index 5820f3b7d6..3b3fd63ee4 100644 --- a/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts +++ b/src/app/admin/admin-notify-dashboard/services/admin-notify-messages.service.ts @@ -71,7 +71,7 @@ export class AdminNotifyMessagesService extends IdentifiableDataService - message.context ? this.itemDataService.findById(message.context.toString()).pipe( + message.context ? this.itemDataService.findById(message.context).pipe( getAllSucceededRemoteDataPayload(), map(detail => ({...message, context: detail.name})) ) : of(message), diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.scss b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.scss deleted file mode 100644 index b9bc65ea45..0000000000 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -:host { - width: 100%; -} diff --git a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts index 0ba9e1cdd4..b013af9891 100644 --- a/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts +++ b/src/app/shared/object-collection/shared/tabulatable-objects/tabulatable-objects-loader.component.ts @@ -27,7 +27,6 @@ import { getTabulatableObjectsComponent } from './tabulatable-objects.decorator' @Component({ selector: 'ds-tabulatable-objects-loader', templateUrl: './tabulatable-objects-loader.component.html', - styleUrls: ['./tabulatable-objects-loader.component.scss'] }) /** * Component for determining what component to use depending on the item's entity type (dspace.entity.type) diff --git a/src/app/shared/search/search.component.html b/src/app/shared/search/search.component.html index d43f506866..b9525f1318 100644 --- a/src/app/shared/search/search.component.html +++ b/src/app/shared/search/search.component.html @@ -22,7 +22,7 @@
    - +