Merge branch 'refactor-menu-resolvers-7.6' into refactor-menu-resolvers-9.0

This commit is contained in:
Yana De Pauw
2025-02-14 11:19:58 +01:00
4 changed files with 50 additions and 46 deletions

View File

@@ -14,7 +14,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
const item: Item = Object.assign(new Item(), { const item: Item = Object.assign(new Item(), {
uuid: 'test-item-uuid', uuid: 'test-item-uuid',
type: ITEM.value, type: ITEM.value,
_links: { self: { href: 'self-link' } }, _links: {self: {href: 'self-link'}},
metadata: { metadata: {
'dc.title': [{ 'dc.title': [{
'value': 'Untyped Item', 'value': 'Untyped Item',
@@ -25,7 +25,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
const item2: Item = Object.assign(new Item(), { const item2: Item = Object.assign(new Item(), {
uuid: 'test-item2-uuid', uuid: 'test-item2-uuid',
type: ITEM.value, type: ITEM.value,
_links: { self: { href: 'self-link' } }, _links: {self: {href: 'self-link'}},
metadata: { metadata: {
'dc.title': [{ 'dc.title': [{
'value': 'Untyped Item 2', 'value': 'Untyped Item 2',
@@ -36,7 +36,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
const person: Item = Object.assign(new Item(), { const person: Item = Object.assign(new Item(), {
uuid: 'test-uuid', uuid: 'test-uuid',
type: ITEM.value, type: ITEM.value,
_links: { self: { href: 'self-link' } }, _links: {self: {href: 'self-link'}},
metadata: { metadata: {
'dc.title': [{ 'dc.title': [{
'value': 'Person Entity', 'value': 'Person Entity',
@@ -50,7 +50,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
const collection: Collection = Object.assign(new Collection(), { const collection: Collection = Object.assign(new Collection(), {
uuid: 'test-collection-uuid', uuid: 'test-collection-uuid',
type: COLLECTION.value, type: COLLECTION.value,
_links: { self: { href: 'self-link' } }, _links: {self: {href: 'self-link'}},
metadata: { metadata: {
'dc.title': [{ 'dc.title': [{
'value': 'Collection', 'value': 'Collection',
@@ -75,7 +75,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
describe('getRouteContext', () => { describe('getRouteContext', () => {
it('should get the dso from the route', (done) => { it('should get the dso from the route', (done) => {
const route = { data: { dso: createSuccessfulRemoteDataObject(item) } } as any; const route = {data: {dso: createSuccessfulRemoteDataObject(item)}} as any;
provider.getRouteContext(route, undefined).subscribe((dso) => { provider.getRouteContext(route, undefined).subscribe((dso) => {
expect(dso).toEqual(item); expect(dso).toEqual(item);
@@ -83,25 +83,25 @@ describe('DSpaceObjectPageMenuProvider', () => {
}); });
}); });
it('return undefined when no DSO is present on the current route', (done) => { it('return the first parent DSO when no DSO is present on the current route', (done) => {
const route = { const route = {
data: {}, data: {},
parent: { parent: {
data: {}, data: {},
parent: { parent: {
data: { dso: createSuccessfulRemoteDataObject(item) }, data: {dso: createSuccessfulRemoteDataObject(item)},
parent: { data: { dso: createSuccessfulRemoteDataObject(item2) } }, parent: {data: {dso: createSuccessfulRemoteDataObject(item2)}},
}, },
}, },
} as any; } as any;
provider.getRouteContext(route, undefined).subscribe((dso) => { provider.getRouteContext(route, undefined).subscribe((dso) => {
expect(dso).toBeUndefined(); expect(dso).toEqual(item);
done(); done();
}); });
}); });
it('should return undefined when no dso is found in the route', (done) => { it('should return undefined when no dso is found in the route', (done) => {
const route = { data: {}, parent: { data: {}, parent: { data: {}, parent: { data: {} } } } } as any; const route = {data: {}, parent: {data: {}, parent: {data: {}, parent: {data: {}}}}} as any;
provider.getRouteContext(route, undefined).subscribe((dso) => { provider.getRouteContext(route, undefined).subscribe((dso) => {
expect(dso).toBeUndefined(); expect(dso).toBeUndefined();

View File

@@ -16,7 +16,7 @@ import {
import { RemoteData } from '../../../../core/data/remote-data'; import { RemoteData } from '../../../../core/data/remote-data';
import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
import { hasValue } from '../../../empty.util'; import { hasNoValue, hasValue } from '../../../empty.util';
import { AbstractRouteContextMenuProvider } from './route-context.menu'; import { AbstractRouteContextMenuProvider } from './route-context.menu';
/** /**
@@ -28,7 +28,13 @@ export abstract class DSpaceObjectPageMenuProvider extends AbstractRouteContextM
* Retrieve the dso from the current route data * Retrieve the dso from the current route data
*/ */
public getRouteContext(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<DSpaceObject | undefined> { public getRouteContext(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<DSpaceObject | undefined> {
const dsoRD: RemoteData<DSpaceObject> = route.data.dso; let dsoRD: RemoteData<DSpaceObject> = route.data.dso;
// Check if one of the parent routes has a DSO
while (hasValue(route.parent) && hasNoValue(dsoRD)) {
route = route.parent;
dsoRD = route.data.dso;
}
if (hasValue(dsoRD) && dsoRD.hasSucceeded && hasValue(dsoRD.payload)) { if (hasValue(dsoRD) && dsoRD.hasSucceeded && hasValue(dsoRD.payload)) {
return of(dsoRD.payload); return of(dsoRD.payload);
} else { } else {

View File

@@ -7,29 +7,16 @@
*/ */
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import { combineLatest, map, Observable, } from 'rxjs';
ActivatedRouteSnapshot,
RouterStateSnapshot,
} from '@angular/router';
import {
combineLatest,
map,
Observable,
of,
} from 'rxjs';
import { getDSORoute } from '../../../app-routing-paths';
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
import { RemoteData } from '../../../core/data/remote-data'; import { hasValue, } from '../../empty.util';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import {
hasNoValue,
hasValue,
} from '../../empty.util';
import { MenuItemType } from '../menu-item-type.model'; import { MenuItemType } from '../menu-item-type.model';
import { PartialMenuSection } from '../menu-provider.model'; import { PartialMenuSection } from '../menu-provider.model';
import { AbstractRouteContextMenuProvider } from './helper-providers/route-context.menu'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { getDSORoute } from '../../../app-routing-paths';
import { DSpaceObjectPageMenuProvider } from './helper-providers/dso.menu';
/** /**
* Menu provider to create the statistics menu section depending on the page it is on * Menu provider to create the statistics menu section depending on the page it is on
@@ -37,28 +24,14 @@ import { AbstractRouteContextMenuProvider } from './helper-providers/route-conte
* In all other cases the menu section will contain a link to the repository wide statistics * In all other cases the menu section will contain a link to the repository wide statistics
*/ */
@Injectable() @Injectable()
export class StatisticsMenuProvider extends AbstractRouteContextMenuProvider<DSpaceObject> { export class StatisticsMenuProvider extends DSpaceObjectPageMenuProvider {
constructor( constructor(
protected authorizationService: AuthorizationDataService, protected authorizationService: AuthorizationDataService,
) { ) {
super(); super();
} }
public getRouteContext(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<DSpaceObject> {
let dsoRD: RemoteData<DSpaceObject> = route.data.dso;
// Check if one of the parent routes has a DSO
while (hasValue(route.parent) && hasNoValue(dsoRD)) {
route = route.parent;
dsoRD = route.data.dso;
}
if (hasValue(dsoRD) && dsoRD.hasSucceeded && hasValue(dsoRD.payload)) {
return of(dsoRD.payload);
} else {
return of(undefined);
}
}
public getSectionsForContext(dso: DSpaceObject): Observable<PartialMenuSection[]> { public getSectionsForContext(dso: DSpaceObject): Observable<PartialMenuSection[]> {
return combineLatest([ return combineLatest([
this.authorizationService.isAuthorized(FeatureID.CanViewUsageStatistics, dso?._links.self.href), this.authorizationService.isAuthorized(FeatureID.CanViewUsageStatistics, dso?._links.self.href),
@@ -88,4 +61,9 @@ export class StatisticsMenuProvider extends AbstractRouteContextMenuProvider<DSp
}), }),
); );
} }
protected isApplicable(dso: DSpaceObject): boolean {
return true;
}
} }

View File

@@ -1326,6 +1326,8 @@
"collection.page.news": "News", "collection.page.news": "News",
"collection.page.options": "Options",
"collection.search.results.head": "Search Results", "collection.search.results.head": "Search Results",
"collection.select.confirm": "Confirm selected", "collection.select.confirm": "Confirm selected",
@@ -1562,6 +1564,8 @@
"community.page.news": "News", "community.page.news": "News",
"community.page.options": "Options",
"community.all-lists.head": "Subcommunities and Collections", "community.all-lists.head": "Subcommunities and Collections",
"community.search.results.head": "Search Results", "community.search.results.head": "Search Results",
@@ -2764,6 +2768,8 @@
"item.page.link.simple": "Simple item page", "item.page.link.simple": "Simple item page",
"item.page.options": "Options",
"item.page.orcid.title": "ORCID", "item.page.orcid.title": "ORCID",
"item.page.orcid.tooltip": "Open ORCID setting page", "item.page.orcid.tooltip": "Open ORCID setting page",
@@ -3092,6 +3098,8 @@
"journal.page.publisher": "Publisher", "journal.page.publisher": "Publisher",
"journal.page.options": "Options",
"journal.page.titleprefix": "Journal: ", "journal.page.titleprefix": "Journal: ",
"journal.search.results.head": "Journal Search Results", "journal.search.results.head": "Journal Search Results",
@@ -3116,6 +3124,8 @@
"journalissue.page.number": "Number", "journalissue.page.number": "Number",
"journalissue.page.options": "Options",
"journalissue.page.titleprefix": "Journal Issue: ", "journalissue.page.titleprefix": "Journal Issue: ",
"journalissue.search.results.head": "Journal Issue Search Results", "journalissue.search.results.head": "Journal Issue Search Results",
@@ -3128,6 +3138,8 @@
"journalvolume.page.issuedate": "Issue Date", "journalvolume.page.issuedate": "Issue Date",
"journalvolume.page.options": "Options",
"journalvolume.page.titleprefix": "Journal Volume: ", "journalvolume.page.titleprefix": "Journal Volume: ",
"journalvolume.page.volume": "Volume", "journalvolume.page.volume": "Volume",
@@ -3678,6 +3690,8 @@
"orgunit.page.id": "ID", "orgunit.page.id": "ID",
"orgunit.page.options": "Options",
"orgunit.page.titleprefix": "Organizational Unit: ", "orgunit.page.titleprefix": "Organizational Unit: ",
"orgunit.page.ror": "ROR Identifier", "orgunit.page.ror": "ROR Identifier",
@@ -3714,6 +3728,8 @@
"person.page.link.full": "Show all metadata", "person.page.link.full": "Show all metadata",
"person.page.options": "Options",
"person.page.orcid": "ORCID", "person.page.orcid": "ORCID",
"person.page.staffid": "Staff ID", "person.page.staffid": "Staff ID",
@@ -3956,6 +3972,8 @@
"project.page.keyword": "Keywords", "project.page.keyword": "Keywords",
"project.page.options": "Options",
"project.page.status": "Status", "project.page.status": "Status",
"project.page.titleprefix": "Research Project: ", "project.page.titleprefix": "Research Project: ",
@@ -3976,6 +3994,8 @@
"publication.page.publisher": "Publisher", "publication.page.publisher": "Publisher",
"publication.page.options": "Options",
"publication.page.titleprefix": "Publication: ", "publication.page.titleprefix": "Publication: ",
"publication.page.volume-title": "Volume Title", "publication.page.volume-title": "Volume Title",