Skip to content

Commit 0fec539

Browse files
committed
Fix merge issues and tests
- Migrate create-report sections to a new provider - Fix menu component test - Add dso option sections to com/col sub paths - Fix issue with breadcrumbs on the collection page
1 parent c19af67 commit 0fec539

11 files changed

Lines changed: 240 additions & 17 deletions

File tree

src/app/app-routes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export const APP_ROUTES: Route[] = [
106106
path: COLLECTION_MODULE_PATH,
107107
loadChildren: () => import('./collection-page/collection-page-routes')
108108
.then((m) => m.ROUTES),
109-
data: { showBreadcrumbs: false, enableRSS: true },
109+
data: { enableRSS: true },
110110
canActivate: [endUserAgreementCurrentUserGuard],
111111
},
112112
{

src/app/app.menus.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { AdminSearchMenuProvider } from './shared/menu/providers/admin-search.me
1313
import { BrowseMenuProvider } from './shared/menu/providers/browse.menu';
1414
import { SubscribeMenuProvider } from './shared/menu/providers/comcol-subscribe.menu';
1515
import { CommunityListMenuProvider } from './shared/menu/providers/community-list.menu';
16+
import { CreateReportMenuProvider } from './shared/menu/providers/create-report.menu';
1617
import { CurationMenuProvider } from './shared/menu/providers/curation.menu';
1718
import { DSpaceObjectEditMenuProvider } from './shared/menu/providers/dso-edit.menu';
1819
import { DsoOptionMenuProvider } from './shared/menu/providers/dso-option.menu';
@@ -42,6 +43,7 @@ export const MENUS = buildMenuStructure({
4243
ImportMenuProvider,
4344
ExportMenuProvider,
4445
AccessControlMenuProvider,
46+
CreateReportMenuProvider,
4547
AdminSearchMenuProvider,
4648
RegistriesMenuProvider,
4749
CurationMenuProvider,
@@ -54,11 +56,17 @@ export const MENUS = buildMenuStructure({
5456
DsoOptionMenuProvider.withSubs([
5557
SubscribeMenuProvider.onRoute(
5658
MenuRoute.SIMPLE_COMMUNITY_PAGE,
59+
MenuRoute.SIMPLE_COMMUNITY_BROWSE_PAGE,
60+
MenuRoute.SIMPLE_COMMUNITY_SUBCOLCOM_PAGE,
5761
MenuRoute.SIMPLE_COLLECTION_PAGE,
62+
MenuRoute.SIMPLE_COLLECTION_BROWSE_PAGE,
5863
),
5964
DSpaceObjectEditMenuProvider.onRoute(
6065
MenuRoute.SIMPLE_COMMUNITY_PAGE,
66+
MenuRoute.SIMPLE_COMMUNITY_BROWSE_PAGE,
67+
MenuRoute.SIMPLE_COMMUNITY_SUBCOLCOM_PAGE,
6168
MenuRoute.SIMPLE_COLLECTION_PAGE,
69+
MenuRoute.SIMPLE_COLLECTION_BROWSE_PAGE,
6270
MenuRoute.SIMPLE_ITEM_PAGE,
6371
MenuRoute.FULL_ITEM_PAGE,
6472
),

src/app/collection-page/collection-page-routes.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,10 @@ export const ROUTES: Route[] = [
9797
resolve: {
9898
breadcrumb: browseByI18nBreadcrumbResolver,
9999
},
100-
data: { breadcrumbKey: 'browse.metadata' },
100+
data: {
101+
breadcrumbKey: 'browse.metadata',
102+
menuRoute: MenuRoute.SIMPLE_COLLECTION_BROWSE_PAGE,
103+
},
101104
},
102105
],
103106
},

src/app/community-page/community-page-routes.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ export const ROUTES: Route[] = [
8383
resolve: {
8484
breadcrumb: i18nBreadcrumbResolver,
8585
},
86-
data: { breadcrumbKey: 'community.subcoms-cols' },
86+
data: {
87+
breadcrumbKey: 'community.subcoms-cols',
88+
menuRoute: MenuRoute.SIMPLE_COMMUNITY_SUBCOLCOM_PAGE,
89+
},
8790
},
8891
{
8992
path: 'browse/:id',
@@ -93,7 +96,10 @@ export const ROUTES: Route[] = [
9396
resolve: {
9497
breadcrumb: browseByI18nBreadcrumbResolver,
9598
},
96-
data: { breadcrumbKey: 'browse.metadata' },
99+
data: {
100+
breadcrumbKey: 'browse.metadata',
101+
menuRoute: MenuRoute.SIMPLE_COMMUNITY_BROWSE_PAGE,
102+
},
97103
},
98104
],
99105
},

src/app/shared/menu/menu-route.model.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
*/
44
export enum MenuRoute {
55
SIMPLE_COMMUNITY_PAGE = 'simple-community-page',
6+
SIMPLE_COMMUNITY_BROWSE_PAGE = 'simple-community-browse-page',
7+
SIMPLE_COMMUNITY_SUBCOLCOM_PAGE = 'simple-community-subcolcom-page',
68
SIMPLE_COLLECTION_PAGE = 'simple-collection-page',
9+
SIMPLE_COLLECTION_BROWSE_PAGE = 'simple-collection-browse-page',
710
SIMPLE_ITEM_PAGE = 'simple-item-page',
811
FULL_ITEM_PAGE = 'full-item-page',
912
}

src/app/shared/menu/menu.component.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ describe('MenuComponent', () => {
125125
id: 'section1',
126126
active: false,
127127
visible: true,
128+
alwaysRenderExpandable: false,
128129
model: {
129130
type: MenuItemType.LINK,
130131
text: 'test',
@@ -190,6 +191,7 @@ describe('MenuComponent', () => {
190191
id: 'section1',
191192
active: false,
192193
visible: true,
194+
alwaysRenderExpandable: false,
193195
model: {
194196
type: MenuItemType.LINK,
195197
text: 'test',
@@ -201,6 +203,7 @@ describe('MenuComponent', () => {
201203
parentID: 'section1',
202204
active: false,
203205
visible: true,
206+
alwaysRenderExpandable: false,
204207
model: {
205208
type: MenuItemType.LINK,
206209
text: 'test',
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
9+
import { TestBed } from '@angular/core/testing';
10+
import { of as observableOf } from 'rxjs';
11+
12+
import { ConfigurationDataService } from '../../../core/data/configuration-data.service';
13+
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
14+
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
15+
import { ConfigurationProperty } from '../../../core/shared/configuration-property.model';
16+
import { createSuccessfulRemoteDataObject$ } from '../../remote-data.utils';
17+
import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub';
18+
import { ConfigurationDataServiceStub } from '../../testing/configuration-data.service.stub';
19+
import { LinkMenuItemModel } from '../menu-item/models/link.model';
20+
import { TextMenuItemModel } from '../menu-item/models/text.model';
21+
import { MenuItemType } from '../menu-item-type.model';
22+
import { PartialMenuSection } from '../menu-provider.model';
23+
import { CreateReportMenuProvider } from './create-report.menu';
24+
25+
describe('CreateReportMenuProvider', () => {
26+
const expectedTopSection: PartialMenuSection = {
27+
visible: true,
28+
model: {
29+
type: MenuItemType.TEXT,
30+
text: 'menu.section.reports',
31+
} as TextMenuItemModel,
32+
icon: 'file-alt',
33+
};
34+
35+
const expectedSubSections: PartialMenuSection[] = [
36+
{
37+
visible: true,
38+
model: {
39+
type: MenuItemType.LINK,
40+
text: 'menu.section.reports.collections',
41+
link: '/admin/reports/collections',
42+
} as LinkMenuItemModel,
43+
icon: 'user-check',
44+
},
45+
{
46+
visible: true,
47+
model: {
48+
type: MenuItemType.LINK,
49+
text: 'menu.section.reports.queries',
50+
link: '/admin/reports/queries',
51+
} as LinkMenuItemModel,
52+
icon: 'user-check',
53+
},
54+
];
55+
56+
let provider: CreateReportMenuProvider;
57+
let authorizationServiceStub = new AuthorizationDataServiceStub();
58+
let configurationDataService = new ConfigurationDataServiceStub();
59+
60+
beforeEach(() => {
61+
spyOn(authorizationServiceStub, 'isAuthorized').and.callFake((id: FeatureID) => {
62+
if (id === FeatureID.CanManageGroups) {
63+
return observableOf(false);
64+
} else {
65+
return observableOf(true);
66+
}
67+
});
68+
69+
spyOn(configurationDataService, 'findByPropertyName').and.callFake((property: string) => {
70+
return createSuccessfulRemoteDataObject$(Object.assign({}, new ConfigurationProperty(), { values: ['true'] }));
71+
});
72+
73+
TestBed.configureTestingModule({
74+
providers: [
75+
CreateReportMenuProvider,
76+
{ provide: AuthorizationDataService, useValue: authorizationServiceStub },
77+
{ provide: ConfigurationDataService, useValue: configurationDataService },
78+
],
79+
});
80+
provider = TestBed.inject(CreateReportMenuProvider);
81+
});
82+
83+
it('should be created', () => {
84+
expect(provider).toBeTruthy();
85+
});
86+
87+
it('getTopSection should return expected menu section', (done) => {
88+
provider.getTopSection().subscribe((section) => {
89+
expect(section).toEqual(expectedTopSection);
90+
done();
91+
});
92+
});
93+
94+
it('getSubSections should return expected menu sections', (done) => {
95+
provider.getSubSections().subscribe((sections) => {
96+
expect(sections).toEqual(expectedSubSections);
97+
done();
98+
});
99+
});
100+
});
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
9+
import { Injectable } from '@angular/core';
10+
import {
11+
combineLatest as observableCombineLatest,
12+
Observable,
13+
} from 'rxjs';
14+
import { map } from 'rxjs/operators';
15+
16+
import { ConfigurationDataService } from '../../../core/data/configuration-data.service';
17+
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
18+
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
19+
import { RemoteData } from '../../../core/data/remote-data';
20+
import { ConfigurationProperty } from '../../../core/shared/configuration-property.model';
21+
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
22+
import { LinkMenuItemModel } from '../menu-item/models/link.model';
23+
import { TextMenuItemModel } from '../menu-item/models/text.model';
24+
import { MenuItemType } from '../menu-item-type.model';
25+
import { PartialMenuSection } from '../menu-provider.model';
26+
import { AbstractExpandableMenuProvider } from './helper-providers/expandable-menu-provider';
27+
28+
/**
29+
* Menu provider to create the report menu sections
30+
*/
31+
@Injectable()
32+
export class CreateReportMenuProvider extends AbstractExpandableMenuProvider {
33+
constructor(
34+
protected authorizationService: AuthorizationDataService,
35+
protected configurationDataService: ConfigurationDataService,
36+
) {
37+
super();
38+
}
39+
40+
getSubSections(): Observable<PartialMenuSection[]> {
41+
return observableCombineLatest([
42+
this.configurationDataService.findByPropertyName('contentreport.enable').pipe(
43+
getFirstCompletedRemoteData(),
44+
map((res: RemoteData<ConfigurationProperty>) => res.hasSucceeded && res.payload && res.payload.values[0] === 'true'),
45+
),
46+
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
47+
]).pipe(
48+
map(([reportEnabled, isSiteAdmin]: [boolean, boolean]) => {
49+
return [
50+
/* Collections Report */
51+
{
52+
visible: isSiteAdmin && reportEnabled,
53+
model: {
54+
type: MenuItemType.LINK,
55+
text: 'menu.section.reports.collections',
56+
link: '/admin/reports/collections',
57+
} as LinkMenuItemModel,
58+
icon: 'user-check',
59+
},
60+
/* Queries Report */
61+
{
62+
visible: isSiteAdmin && reportEnabled,
63+
model: {
64+
type: MenuItemType.LINK,
65+
text: 'menu.section.reports.queries',
66+
link: '/admin/reports/queries',
67+
} as LinkMenuItemModel,
68+
icon: 'user-check',
69+
},
70+
];
71+
}));
72+
}
73+
74+
getTopSection(): Observable<PartialMenuSection> {
75+
return observableCombineLatest([
76+
this.configurationDataService.findByPropertyName('contentreport.enable').pipe(
77+
getFirstCompletedRemoteData(),
78+
map((res: RemoteData<ConfigurationProperty>) => res.hasSucceeded && res.payload && res.payload.values[0] === 'true'),
79+
),
80+
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
81+
]).pipe(
82+
map(([reportEnabled, isSiteAdmin]: [boolean, boolean]) => {
83+
return {
84+
visible: isSiteAdmin && reportEnabled,
85+
model: {
86+
type: MenuItemType.TEXT,
87+
text: 'menu.section.reports',
88+
} as TextMenuItemModel,
89+
icon: 'file-alt',
90+
};
91+
}));
92+
}
93+
}

src/app/shared/menu/providers/helper-providers/dso.menu.spec.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
1414
const item: Item = Object.assign(new Item(), {
1515
uuid: 'test-item-uuid',
1616
type: ITEM.value,
17-
_links: {self: {href: 'self-link'}},
17+
_links: { self: { href: 'self-link' } },
1818
metadata: {
1919
'dc.title': [{
2020
'value': 'Untyped Item',
@@ -25,7 +25,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
2525
const item2: Item = Object.assign(new Item(), {
2626
uuid: 'test-item2-uuid',
2727
type: ITEM.value,
28-
_links: {self: {href: 'self-link'}},
28+
_links: { self: { href: 'self-link' } },
2929
metadata: {
3030
'dc.title': [{
3131
'value': 'Untyped Item 2',
@@ -36,7 +36,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
3636
const person: Item = Object.assign(new Item(), {
3737
uuid: 'test-uuid',
3838
type: ITEM.value,
39-
_links: {self: {href: 'self-link'}},
39+
_links: { self: { href: 'self-link' } },
4040
metadata: {
4141
'dc.title': [{
4242
'value': 'Person Entity',
@@ -50,7 +50,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
5050
const collection: Collection = Object.assign(new Collection(), {
5151
uuid: 'test-collection-uuid',
5252
type: COLLECTION.value,
53-
_links: {self: {href: 'self-link'}},
53+
_links: { self: { href: 'self-link' } },
5454
metadata: {
5555
'dc.title': [{
5656
'value': 'Collection',
@@ -75,7 +75,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
7575

7676
describe('getRouteContext', () => {
7777
it('should get the dso from the route', (done) => {
78-
const route = {data: {dso: createSuccessfulRemoteDataObject(item)}} as any;
78+
const route = { data: { dso: createSuccessfulRemoteDataObject(item) } } as any;
7979

8080
provider.getRouteContext(route, undefined).subscribe((dso) => {
8181
expect(dso).toEqual(item);
@@ -89,8 +89,8 @@ describe('DSpaceObjectPageMenuProvider', () => {
8989
parent: {
9090
data: {},
9191
parent: {
92-
data: {dso: createSuccessfulRemoteDataObject(item)},
93-
parent: {data: {dso: createSuccessfulRemoteDataObject(item2)}},
92+
data: { dso: createSuccessfulRemoteDataObject(item) },
93+
parent: { data: { dso: createSuccessfulRemoteDataObject(item2) } },
9494
},
9595
},
9696
} as any;
@@ -101,7 +101,7 @@ describe('DSpaceObjectPageMenuProvider', () => {
101101
});
102102
});
103103
it('should return undefined when no dso is found in the route', (done) => {
104-
const route = {data: {}, parent: {data: {}, parent: {data: {}, parent: {data: {}}}}} as any;
104+
const route = { data: {}, parent: { data: {}, parent: { data: {}, parent: { data: {} } } } } as any;
105105

106106
provider.getRouteContext(route, undefined).subscribe((dso) => {
107107
expect(dso).toBeUndefined();

src/app/shared/menu/providers/helper-providers/dso.menu.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ import {
1616

1717
import { RemoteData } from '../../../../core/data/remote-data';
1818
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
19-
import { hasNoValue, hasValue } from '../../../empty.util';
19+
import {
20+
hasNoValue,
21+
hasValue,
22+
} from '../../../empty.util';
2023
import { AbstractRouteContextMenuProvider } from './route-context.menu';
2124

2225
/**

0 commit comments

Comments
 (0)