Skip to content

Commit f6db478

Browse files
atarix83vins01-4science
authored andcommitted
Merged in task/main-cris/DSC-2324 (pull request DSpace#3155)
Task/main cris/DSC-2324 Approved-by: Vincenzo Mecca
2 parents 29ea584 + fbfd46f commit f6db478

6 files changed

Lines changed: 174 additions & 131 deletions

File tree

Lines changed: 89 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { CommonModule } from '@angular/common';
22
import { NO_ERRORS_SCHEMA } from '@angular/core';
33
import {
4-
async,
54
ComponentFixture,
65
TestBed,
6+
waitForAsync,
77
} from '@angular/core/testing';
88
import {
99
FormsModule,
@@ -46,7 +46,7 @@ describe('ComcolPageBrowseByComponent', () => {
4646
let configurationServiceStub: any;
4747
let collectionServiceStub: any;
4848

49-
beforeEach(async(() => {
49+
beforeEach(waitForAsync(() => {
5050

5151
collectionServiceStub = {
5252
findById(id: string, ...linksToFollow: FollowLinkConfig<Collection>[]): Observable<RemoteData<Collection>> {
@@ -100,95 +100,95 @@ describe('ComcolPageBrowseByComponent', () => {
100100

101101
}));
102102

103-
it('should create ComcolPageBrowseByComponent for a community with only one option', () => {
104-
fixture = TestBed.createComponent(ComcolPageBrowseByComponent);
105-
component = fixture.componentInstance;
106-
component.id = communityId;
107-
component.contentType = 'community';
108-
109-
fixture.detectChanges();
110-
111-
expect(component.allOptions.length).toEqual(1);
112-
const firstOption = component.allOptions[0];
113-
expect(firstOption.id).toEqual(communityId);
114-
expect(firstOption.label).toEqual('community.all-lists.head');
115-
expect(firstOption.routerLink).toEqual('/communities/' + communityId);
103+
describe('when object is a community', () => {
104+
beforeEach(() => {
105+
fixture = TestBed.createComponent(ComcolPageBrowseByComponent);
106+
component = fixture.componentInstance;
107+
component.id = communityId;
108+
component.contentType = 'community';
109+
110+
fixture.detectChanges();
111+
});
112+
113+
it('should have only two option', () => {
114+
const navElements = fixture.debugElement.queryAll(By.css('.list-group-item'));
115+
expect(navElements).toHaveSize(2);
116+
117+
expect(component.allOptions.length).toEqual(2);
118+
const firstOption = component.allOptions[0];
119+
expect(firstOption.id).toEqual('search');
120+
expect(firstOption.label).toEqual('community.page.browse.search.head');
121+
expect(firstOption.routerLink).toEqual('/communities/' + communityId);
122+
123+
const secondOption = component.allOptions[1];
124+
expect(secondOption.id).toEqual('comcols');
125+
expect(secondOption.label).toEqual('community.all-lists.head');
126+
expect(secondOption.routerLink).toEqual('/communities/' + communityId + '/subcoms-cols');
127+
});
116128
});
117129

118-
it('should create ComcolPageBrowseByComponent for the publication\'s collection with three option', () => {
119-
fixture = TestBed.createComponent(ComcolPageBrowseByComponent);
120-
component = fixture.componentInstance;
121-
component.id = publicationId;
122-
component.contentType = 'collection';
123-
124-
fixture.detectChanges();
125-
126-
expect(component.allOptions.length).toEqual(3);
127-
const firstOption = component.allOptions[0];
128-
expect(firstOption.id).toEqual(publicationId);
129-
expect(firstOption.label).toEqual('collection.page.browse.recent.head');
130-
expect(firstOption.routerLink).toEqual('/collections/' + publicationId);
131-
const secondOption = component.allOptions[1];
132-
expect(secondOption.id).toEqual('author');
133-
expect(secondOption.label).toEqual('browse.comcol.by.author');
134-
expect(secondOption.routerLink).toEqual('/browse/author');
135-
expect(secondOption.params).toEqual({ scope: publicationId });
136-
const thirdOption = component.allOptions[2];
137-
expect(thirdOption.id).toEqual('title');
138-
expect(thirdOption.label).toEqual('browse.comcol.by.title');
139-
expect(thirdOption.routerLink).toEqual('/browse/title');
140-
expect(thirdOption.params).toEqual({ scope: publicationId });
130+
describe('when object is a collection', () => {
131+
beforeEach(() => {
132+
fixture = TestBed.createComponent(ComcolPageBrowseByComponent);
133+
component = fixture.componentInstance;
134+
component.contentType = 'collection';
135+
});
136+
137+
it('should have three options for the publication\'s collection', () => {
138+
component.id = publicationId;
139+
fixture.detectChanges();
140+
141+
const navElements = fixture.debugElement.queryAll(By.css('.list-group-item'));
142+
expect(navElements).toHaveSize(3);
143+
144+
expect(component.allOptions.length).toEqual(3);
145+
const firstOption = component.allOptions[0];
146+
expect(firstOption.id).toEqual('search');
147+
expect(firstOption.label).toEqual('collection.page.browse.search.head');
148+
expect(firstOption.routerLink).toEqual('/collections/' + publicationId);
149+
const secondOption = component.allOptions[1];
150+
expect(secondOption.id).toEqual('author');
151+
expect(secondOption.label).toEqual('browse.comcol.by.author');
152+
expect(secondOption.routerLink).toEqual('/collections/' + publicationId + '/browse/author');
153+
const thirdOption = component.allOptions[2];
154+
expect(thirdOption.id).toEqual('title');
155+
expect(thirdOption.label).toEqual('browse.comcol.by.title');
156+
expect(thirdOption.routerLink).toEqual('/collections/' + publicationId + '/browse/title');
157+
});
158+
159+
it('should have two options for the orgUnit\'s collection', () => {
160+
component.id = orgUnitId;
161+
fixture.detectChanges();
162+
163+
const navElements = fixture.debugElement.queryAll(By.css('.list-group-item'));
164+
expect(navElements).toHaveSize(2);
165+
166+
expect(component.allOptions.length).toEqual(2);
167+
const firstOption = component.allOptions[0];
168+
expect(firstOption.id).toEqual('search');
169+
expect(firstOption.label).toEqual('collection.page.browse.search.head');
170+
expect(firstOption.routerLink).toEqual('/collections/' + orgUnitId);
171+
const secondOption = component.allOptions[1];
172+
expect(secondOption.id).toEqual('ouname');
173+
expect(secondOption.label).toEqual('browse.comcol.by.ouname');
174+
expect(secondOption.routerLink).toEqual('/collections/' + orgUnitId + '/browse/ouname');
175+
});
176+
177+
it('should display browse options when options are more then one', () => {
178+
179+
fixture = TestBed.createComponent(ComcolPageBrowseByComponent);
180+
component = fixture.componentInstance;
181+
component.id = publicationId;
182+
component.contentType = 'collection';
183+
184+
fixture.detectChanges();
185+
186+
expect(component.allOptions.length).toEqual(3);
187+
188+
const navElement = fixture.debugElement.query(By.css('nav'));
189+
expect(navElement).toBeTruthy();
190+
191+
});
141192
});
142193

143-
it('should create ComcolPageBrowseByComponent for the orgUnit\'s collection with two option', () => {
144-
fixture = TestBed.createComponent(ComcolPageBrowseByComponent);
145-
component = fixture.componentInstance;
146-
component.id = orgUnitId;
147-
component.contentType = 'collection';
148-
149-
fixture.detectChanges();
150-
151-
expect(component.allOptions.length).toEqual(2);
152-
const firstOption = component.allOptions[0];
153-
expect(firstOption.id).toEqual(orgUnitId);
154-
expect(firstOption.label).toEqual('collection.page.browse.recent.head');
155-
expect(firstOption.routerLink).toEqual('/collections/' + orgUnitId);
156-
const secondOption = component.allOptions[1];
157-
expect(secondOption.id).toEqual('ouname');
158-
expect(secondOption.label).toEqual('browse.comcol.by.ouname');
159-
expect(secondOption.routerLink).toEqual('/browse/ouname');
160-
expect(secondOption.params).toEqual({ scope: orgUnitId });
161-
});
162-
163-
it('should display browse options when options are more then one', () => {
164-
165-
fixture = TestBed.createComponent(ComcolPageBrowseByComponent);
166-
component = fixture.componentInstance;
167-
component.id = publicationId;
168-
component.contentType = 'collection';
169-
170-
fixture.detectChanges();
171-
172-
expect(component.allOptions.length).toEqual(3);
173-
174-
const navElement = fixture.debugElement.query(By.css('nav'));
175-
expect(navElement).toBeTruthy();
176-
177-
});
178-
179-
it('should not display browse options when options aren\'t more then one', () => {
180-
181-
fixture = TestBed.createComponent(ComcolPageBrowseByComponent);
182-
component = fixture.componentInstance;
183-
component.id = communityId;
184-
component.contentType = 'community';
185-
186-
fixture.detectChanges();
187-
188-
expect(component.allOptions.length).toEqual(1);
189-
190-
const navElement = fixture.debugElement.query(By.css('nav'));
191-
expect(navElement).toBeNull();
192-
193-
});
194194
});

src/app/shared/comcol/comcol-page-browse-by/comcol-page-browse-by.component.ts

Lines changed: 72 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,32 @@ import {
66
import {
77
Component,
88
Input,
9+
OnDestroy,
910
OnInit,
1011
} from '@angular/core';
1112
import { FormsModule } from '@angular/forms';
1213
import {
1314
ActivatedRoute,
14-
Params,
15+
EventType,
16+
NavigationEnd,
1517
Router,
1618
RouterLink,
1719
RouterLinkActive,
20+
Scroll,
1821
} from '@angular/router';
1922
import { TranslateModule } from '@ngx-translate/core';
2023
import {
24+
BehaviorSubject,
25+
combineLatest,
2126
Observable,
2227
of,
28+
Subscription,
2329
} from 'rxjs';
2430
import {
31+
distinctUntilChanged,
32+
filter,
2533
map,
34+
startWith,
2635
switchMap,
2736
} from 'rxjs/operators';
2837

@@ -37,6 +46,7 @@ import {
3746
getFirstSucceededRemoteDataPayload,
3847
getRemoteDataPayload,
3948
} from '../../../core/shared/operators';
49+
import { isNotEmpty } from '../../../shared/empty.util';
4050

4151
export interface ComColPageNavOption {
4252
id: string;
@@ -64,7 +74,7 @@ export interface ComColPageNavOption {
6474
],
6575
standalone: true,
6676
})
67-
export class ComcolPageBrowseByComponent implements OnInit {
77+
export class ComcolPageBrowseByComponent implements OnDestroy, OnInit {
6878
/**
6979
* The ID of the Community or Collection
7080
*/
@@ -75,7 +85,9 @@ export class ComcolPageBrowseByComponent implements OnInit {
7585

7686
allOptions$: Observable<ComColPageNavOption[]>;
7787

78-
currentOptionId$: Observable<string>;
88+
currentOptionId$: BehaviorSubject<string> = new BehaviorSubject(undefined);
89+
90+
subs: Subscription[] = [];
7991

8092
constructor(
8193
private route: ActivatedRoute,
@@ -92,41 +104,35 @@ export class ComcolPageBrowseByComponent implements OnInit {
92104
getFinishedRemoteData(),
93105
getRemoteDataPayload(),
94106
map ( (configProperty) => {
95-
let options = [this.getFirstOptionByContentType()];
107+
const comColRoute = (this.contentType === 'collection') ? getCollectionPageRoute(this.id) : getCommunityPageRoute(this.id);
108+
let options = this.initOptionsByContentType(comColRoute);
96109
if (configProperty) {
97110
options = [...options, ...configProperty.values.map((configValue: string) => ({
98111
id: configValue,
99112
label: `browse.comcol.by.${configValue}`,
100-
routerLink: `/browse/${configValue}`,
101-
params: { scope: this.id },
113+
routerLink: `${comColRoute}/browse/${configValue}`,
102114
}))];
103115
}
104116
this.allOptions = options;
105117
return options;
106118
}),
107119
);
108120

109-
this.currentOptionId$ = this.route.params.pipe(
110-
map((params: Params) => params.id),
111-
);
112-
}
113-
114-
onSelectChange(newId: string) {
115-
const selectedOption = this.allOptions
116-
.find((option: ComColPageNavOption) => option.id === newId);
117-
118-
this.router.navigate([selectedOption.routerLink], { queryParams: selectedOption.params });
119-
}
120-
121-
calculateBrowseProperty(): Observable<string> {
122-
if (this.contentType === 'collection') {
123-
return this.collectionService.findById(this.id).pipe(
124-
getFirstSucceededRemoteDataPayload(),
125-
map( (collection) => collection.firstMetadataValue('dspace.entity.type') ),
126-
map ( (entityType) => entityType ? 'browse.collection.' + entityType : 'browse.collection' ),
127-
);
128-
}
129-
return of('browse.' + this.contentType);
121+
this.subs.push(combineLatest([
122+
this.allOptions$,
123+
this.router.events.pipe(
124+
startWith(this.router),
125+
filter((next: Router|Scroll) => (isNotEmpty((next as Router)?.url) || (next as Scroll)?.type === EventType.Scroll)),
126+
map((next: Router|Scroll) => (next as Router)?.url || ((next as Scroll).routerEvent as NavigationEnd).urlAfterRedirects),
127+
distinctUntilChanged(),
128+
),
129+
]).subscribe(([navOptions, url]: [ComColPageNavOption[], string]) => {
130+
for (const option of navOptions) {
131+
if (option.routerLink === url?.split('?')[0]) {
132+
this.currentOptionId$.next(option.id);
133+
}
134+
}
135+
}));
130136
}
131137

132138
/**
@@ -143,21 +149,49 @@ export class ComcolPageBrowseByComponent implements OnInit {
143149
}
144150
}
145151

146-
getFirstOptionByContentType(): ComColPageNavOption {
152+
private calculateBrowseProperty(): Observable<string> {
147153
if (this.contentType === 'collection') {
148-
return {
149-
id: this.id,
150-
label: 'collection.page.browse.recent.head',
151-
routerLink: getCollectionPageRoute(this.id),
152-
};
154+
return this.collectionService.findById(this.id).pipe(
155+
getFirstSucceededRemoteDataPayload(),
156+
map( (collection) => collection.firstMetadataValue('dspace.entity.type') ),
157+
map ( (entityType) => entityType ? 'browse.collection.' + entityType : 'browse.collection' ),
158+
);
159+
}
160+
return of('browse.' + this.contentType);
161+
}
162+
163+
private initOptionsByContentType(comColRoute: string): ComColPageNavOption[] {
164+
const allOptions = [];
165+
if (this.contentType === 'collection') {
166+
allOptions.push({
167+
id: 'search',
168+
label: 'collection.page.browse.search.head',
169+
routerLink: comColRoute,
170+
});
153171
} else if (this.contentType === 'community') {
154-
return {
155-
id: this.id,
172+
allOptions.push({
173+
id: 'search',
174+
label: 'community.page.browse.search.head',
175+
routerLink: comColRoute,
176+
});
177+
allOptions.push({
178+
id: 'comcols',
156179
label: 'community.all-lists.head',
157-
routerLink: getCommunityPageRoute(this.id),
158-
};
180+
routerLink: `${comColRoute}/subcoms-cols`,
181+
});
159182
}
160-
return null;
183+
184+
return allOptions;
185+
}
186+
187+
ngOnDestroy(): void {
188+
this.subs.forEach((sub: Subscription) => sub.unsubscribe());
161189
}
162190

191+
onSelectChange(newId: string) {
192+
const selectedOption = this.allOptions
193+
.find((option: ComColPageNavOption) => option.id === newId);
194+
195+
this.router.navigate([selectedOption.routerLink], { queryParams: selectedOption.params });
196+
}
163197
}

0 commit comments

Comments
 (0)