forked from hazza/dspace-angular
108588: Passed the scope to the browse sections
This commit is contained in:
@@ -61,16 +61,16 @@ export class BrowseByDateComponent extends BrowseByMetadataComponent implements
|
||||
this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig);
|
||||
this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig);
|
||||
this.subs.push(
|
||||
observableCombineLatest([this.route.params, this.route.queryParams, this.route.data,
|
||||
observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.route.data,
|
||||
this.currentPagination$, this.currentSort$]).pipe(
|
||||
map(([routeParams, queryParams, data, currentPage, currentSort]) => {
|
||||
return [Object.assign({}, routeParams, queryParams, data), currentPage, currentSort];
|
||||
map(([routeParams, queryParams, scope, data, currentPage, currentSort]) => {
|
||||
return [Object.assign({}, routeParams, queryParams, data), scope, currentPage, currentSort];
|
||||
})
|
||||
).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => {
|
||||
).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => {
|
||||
const metadataKeys = params.browseDefinition ? params.browseDefinition.metadataKeys : this.defaultMetadataKeys;
|
||||
this.browseId = params.id || this.defaultBrowseId;
|
||||
this.startsWith = +params.startsWith || params.startsWith;
|
||||
const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId, this.fetchThumbnails);
|
||||
const searchOptions = browseParamsToOptions(params, scope, currentPage, currentSort, this.browseId, this.fetchThumbnails);
|
||||
this.updatePageWithItems(searchOptions, this.value, undefined);
|
||||
this.updateStartsWithOptions(this.browseId, metadataKeys, params.scope);
|
||||
}));
|
||||
|
@@ -1,17 +1,13 @@
|
||||
import { first } from 'rxjs/operators';
|
||||
import { BrowseByGuard } from './browse-by-guard';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
|
||||
import { BrowseByDataType } from './browse-by-switcher/browse-by-data-type';
|
||||
import { ValueListBrowseDefinition } from '../core/shared/value-list-browse-definition.model';
|
||||
import { DSONameServiceMock } from '../shared/mocks/dso-name.service.mock';
|
||||
import { DSONameService } from '../core/breadcrumbs/dso-name.service';
|
||||
import { RouterStub } from '../shared/testing/router.stub';
|
||||
|
||||
describe('BrowseByGuard', () => {
|
||||
describe('canActivate', () => {
|
||||
let guard: BrowseByGuard;
|
||||
let dsoService: any;
|
||||
let translateService: any;
|
||||
let browseDefinitionService: any;
|
||||
let router: any;
|
||||
@@ -25,10 +21,6 @@ describe('BrowseByGuard', () => {
|
||||
const browseDefinition = Object.assign(new ValueListBrowseDefinition(), { type: BrowseByDataType.Metadata, metadataKeys: ['dc.contributor'] });
|
||||
|
||||
beforeEach(() => {
|
||||
dsoService = {
|
||||
findById: (dsoId: string) => observableOf({ payload: { name: name }, hasSucceeded: true })
|
||||
};
|
||||
|
||||
translateService = {
|
||||
instant: () => field
|
||||
};
|
||||
@@ -39,7 +31,7 @@ describe('BrowseByGuard', () => {
|
||||
|
||||
router = new RouterStub() as any;
|
||||
|
||||
guard = new BrowseByGuard(dsoService, translateService, browseDefinitionService, new DSONameServiceMock() as DSONameService, router);
|
||||
guard = new BrowseByGuard(translateService, browseDefinitionService, router);
|
||||
});
|
||||
|
||||
it('should return true, and sets up the data correctly, with a scope and value', () => {
|
||||
@@ -48,6 +40,7 @@ describe('BrowseByGuard', () => {
|
||||
title: field,
|
||||
browseDefinition,
|
||||
},
|
||||
parent: null,
|
||||
params: {
|
||||
id,
|
||||
},
|
||||
@@ -64,7 +57,7 @@ describe('BrowseByGuard', () => {
|
||||
title,
|
||||
id,
|
||||
browseDefinition,
|
||||
collection: name,
|
||||
scope,
|
||||
field,
|
||||
value: '"' + value + '"'
|
||||
};
|
||||
@@ -97,7 +90,7 @@ describe('BrowseByGuard', () => {
|
||||
title,
|
||||
id,
|
||||
browseDefinition,
|
||||
collection: name,
|
||||
scope,
|
||||
field,
|
||||
value: ''
|
||||
};
|
||||
@@ -108,12 +101,48 @@ describe('BrowseByGuard', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should return true, and sets up the data correctly using the community/collection page id, with a scope and without value', () => {
|
||||
const scopedNoValueRoute = {
|
||||
data: {
|
||||
title: field,
|
||||
browseDefinition,
|
||||
},
|
||||
parent: {
|
||||
params: {
|
||||
id: scope,
|
||||
},
|
||||
},
|
||||
params: {
|
||||
id,
|
||||
},
|
||||
queryParams: {
|
||||
},
|
||||
};
|
||||
|
||||
guard.canActivate(scopedNoValueRoute as any, undefined).pipe(
|
||||
first(),
|
||||
).subscribe((canActivate) => {
|
||||
const result = {
|
||||
title,
|
||||
id,
|
||||
browseDefinition,
|
||||
scope,
|
||||
field,
|
||||
value: '',
|
||||
};
|
||||
expect(scopedNoValueRoute.data).toEqual(result);
|
||||
expect(router.navigate).not.toHaveBeenCalled();
|
||||
expect(canActivate).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return true, and sets up the data correctly, without a scope and with a value', () => {
|
||||
const route = {
|
||||
data: {
|
||||
title: field,
|
||||
browseDefinition,
|
||||
},
|
||||
parent: null,
|
||||
params: {
|
||||
id,
|
||||
},
|
||||
@@ -129,7 +158,7 @@ describe('BrowseByGuard', () => {
|
||||
title,
|
||||
id,
|
||||
browseDefinition,
|
||||
collection: '',
|
||||
scope: undefined,
|
||||
field,
|
||||
value: '"' + value + '"'
|
||||
};
|
||||
@@ -147,6 +176,7 @@ describe('BrowseByGuard', () => {
|
||||
data: {
|
||||
title: field,
|
||||
},
|
||||
parent: null,
|
||||
params: {
|
||||
id,
|
||||
},
|
||||
|
@@ -1,15 +1,12 @@
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, Data } from '@angular/router';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { DSpaceObjectDataService } from '../core/data/dspace-object-data.service';
|
||||
import { hasNoValue, hasValue } from '../shared/empty.util';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../core/shared/operators';
|
||||
import { getFirstCompletedRemoteData } from '../core/shared/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { BrowseDefinitionDataService } from '../core/browse/browse-definition-data.service';
|
||||
import { BrowseDefinition } from '../core/shared/browse-definition.model';
|
||||
import { DSONameService } from '../core/breadcrumbs/dso-name.service';
|
||||
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
import { PAGE_NOT_FOUND_PATH } from '../app-routing-paths';
|
||||
|
||||
@@ -19,11 +16,10 @@ import { PAGE_NOT_FOUND_PATH } from '../app-routing-paths';
|
||||
*/
|
||||
export class BrowseByGuard implements CanActivate {
|
||||
|
||||
constructor(protected dsoService: DSpaceObjectDataService,
|
||||
protected translate: TranslateService,
|
||||
protected browseDefinitionService: BrowseDefinitionDataService,
|
||||
protected dsoNameService: DSONameService,
|
||||
protected router: Router,
|
||||
constructor(
|
||||
protected translate: TranslateService,
|
||||
protected browseDefinitionService: BrowseDefinitionDataService,
|
||||
protected router: Router,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -39,25 +35,14 @@ export class BrowseByGuard implements CanActivate {
|
||||
} else {
|
||||
browseDefinition$ = observableOf(route.data.browseDefinition);
|
||||
}
|
||||
const scope = route.queryParams.scope;
|
||||
const scope = route.queryParams.scope ?? route.parent?.params.id;
|
||||
const value = route.queryParams.value;
|
||||
const metadataTranslated = this.translate.instant(`browse.metadata.${id}`);
|
||||
return browseDefinition$.pipe(
|
||||
switchMap((browseDefinition: BrowseDefinition | undefined) => {
|
||||
if (hasValue(browseDefinition)) {
|
||||
if (hasValue(scope)) {
|
||||
const dso$: Observable<DSpaceObject> = this.dsoService.findById(scope).pipe(getFirstSucceededRemoteDataPayload());
|
||||
return dso$.pipe(
|
||||
map((dso: DSpaceObject) => {
|
||||
const name = this.dsoNameService.getName(dso);
|
||||
route.data = this.createData(title, id, browseDefinition, name, metadataTranslated, value, route);
|
||||
return true;
|
||||
})
|
||||
);
|
||||
} else {
|
||||
route.data = this.createData(title, id, browseDefinition, '', metadataTranslated, value, route);
|
||||
return observableOf(true);
|
||||
}
|
||||
route.data = this.createData(title, id, browseDefinition, metadataTranslated, value, route, scope);
|
||||
return observableOf(true);
|
||||
} else {
|
||||
void this.router.navigate([PAGE_NOT_FOUND_PATH]);
|
||||
return observableOf(false);
|
||||
@@ -66,14 +51,14 @@ export class BrowseByGuard implements CanActivate {
|
||||
);
|
||||
}
|
||||
|
||||
private createData(title, id, browseDefinition, collection, field, value, route) {
|
||||
private createData(title: string, id: string, browseDefinition: BrowseDefinition, field: string, value: string, route: ActivatedRouteSnapshot, scope: string): Data {
|
||||
return Object.assign({}, route.data, {
|
||||
title: title,
|
||||
id: id,
|
||||
browseDefinition: browseDefinition,
|
||||
collection: collection,
|
||||
field: field,
|
||||
value: hasValue(value) ? `"${value}"` : ''
|
||||
value: hasValue(value) ? `"${value}"` : '',
|
||||
scope: scope,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -170,7 +170,7 @@ describe('BrowseByMetadataComponent', () => {
|
||||
field: 'fake-field',
|
||||
};
|
||||
|
||||
result = browseParamsToOptions(paramsScope, paginationOptions, sortOptions, 'author', comp.fetchThumbnails);
|
||||
result = browseParamsToOptions(paramsScope, 'fake-scope', paginationOptions, sortOptions, 'author', comp.fetchThumbnails);
|
||||
});
|
||||
|
||||
it('should return BrowseEntrySearchOptions with the correct properties', () => {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
|
||||
import { Component, Inject, OnInit, OnDestroy, Input } from '@angular/core';
|
||||
import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
|
||||
import { Component, Inject, OnInit, OnDestroy, Input, OnChanges } from '@angular/core';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||
@@ -35,7 +35,7 @@ export const BBM_PAGINATION_ID = 'bbm';
|
||||
* 'dc.contributor.*'
|
||||
*/
|
||||
@rendersBrowseBy(BrowseByDataType.Metadata)
|
||||
export class BrowseByMetadataComponent implements OnInit, OnDestroy {
|
||||
export class BrowseByMetadataComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
/**
|
||||
* The optional context
|
||||
@@ -47,6 +47,13 @@ export class BrowseByMetadataComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
@Input() browseByType: BrowseByDataType;
|
||||
|
||||
/**
|
||||
* The ID of the {@link Community} or {@link Collection} of the scope to display
|
||||
*/
|
||||
@Input() scope: string;
|
||||
|
||||
scope$: BehaviorSubject<string> = new BehaviorSubject(undefined);
|
||||
|
||||
/**
|
||||
* The list of browse-entries to display
|
||||
*/
|
||||
@@ -145,12 +152,12 @@ export class BrowseByMetadataComponent implements OnInit, OnDestroy {
|
||||
this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig);
|
||||
this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig);
|
||||
this.subs.push(
|
||||
observableCombineLatest([this.route.params, this.route.queryParams, this.currentPagination$, this.currentSort$]).pipe(
|
||||
map(([routeParams, queryParams, currentPage, currentSort]) => {
|
||||
return [Object.assign({}, routeParams, queryParams),currentPage,currentSort];
|
||||
observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.currentPagination$, this.currentSort$]).pipe(
|
||||
map(([routeParams, queryParams, scope, currentPage, currentSort]) => {
|
||||
return [Object.assign({}, routeParams, queryParams), scope, currentPage, currentSort];
|
||||
})
|
||||
).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => {
|
||||
this.browseId = params.id || this.defaultBrowseId;
|
||||
).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => {
|
||||
this.browseId = params.id || this.defaultBrowseId;
|
||||
this.authority = params.authority;
|
||||
|
||||
if (typeof params.value === 'string'){
|
||||
@@ -164,16 +171,19 @@ export class BrowseByMetadataComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
if (isNotEmpty(this.value)) {
|
||||
this.updatePageWithItems(
|
||||
browseParamsToOptions(params, currentPage, currentSort, this.browseId, this.fetchThumbnails), this.value, this.authority);
|
||||
this.updatePageWithItems(browseParamsToOptions(params, scope, currentPage, currentSort, this.browseId, this.fetchThumbnails), this.value, this.authority);
|
||||
} else {
|
||||
this.updatePage(browseParamsToOptions(params, currentPage, currentSort, this.browseId, false));
|
||||
this.updatePage(browseParamsToOptions(params, scope, currentPage, currentSort, this.browseId, false));
|
||||
}
|
||||
}));
|
||||
this.updateStartsWithTextOptions();
|
||||
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
this.scope$.next(this.scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the StartsWith options with text values
|
||||
* It adds the value "0-9" as well as all letters from A to Z
|
||||
@@ -268,12 +278,14 @@ export function getBrowseSearchOptions(defaultBrowseId: string,
|
||||
/**
|
||||
* Function to transform query and url parameters into searchOptions used to fetch browse entries or items
|
||||
* @param params URL and query parameters
|
||||
* @param scope The scope to show the results
|
||||
* @param paginationConfig Pagination configuration
|
||||
* @param sortConfig Sorting configuration
|
||||
* @param metadata Optional metadata definition to fetch browse entries/items for
|
||||
* @param fetchThumbnail Optional parameter for requesting thumbnail images
|
||||
*/
|
||||
export function browseParamsToOptions(params: any,
|
||||
scope: string,
|
||||
paginationConfig: PaginationComponentOptions,
|
||||
sortConfig: SortOptions,
|
||||
metadata?: string,
|
||||
@@ -283,7 +295,7 @@ export function browseParamsToOptions(params: any,
|
||||
paginationConfig,
|
||||
sortConfig,
|
||||
params.startsWith,
|
||||
params.scope,
|
||||
scope,
|
||||
fetchThumbnail
|
||||
);
|
||||
}
|
||||
|
@@ -15,6 +15,8 @@ export class BrowseBySwitcherComponent extends AbstractComponentLoaderComponent<
|
||||
|
||||
@Input() browseByType: BrowseByDataType;
|
||||
|
||||
@Input() scope: string;
|
||||
|
||||
protected inputNamesDependentForComponent: (keyof this & string)[] = [
|
||||
'context',
|
||||
'browseByType',
|
||||
@@ -23,6 +25,7 @@ export class BrowseBySwitcherComponent extends AbstractComponentLoaderComponent<
|
||||
protected inputNames: (keyof this & string)[] = [
|
||||
'context',
|
||||
'browseByType',
|
||||
'scope',
|
||||
];
|
||||
|
||||
public getComponent(): GenericConstructor<Component> {
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
|
||||
import { Component, OnInit, OnChanges, OnDestroy, Input } from '@angular/core';
|
||||
import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model';
|
||||
import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
||||
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
|
||||
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
|
||||
import { map } from 'rxjs/operators';
|
||||
@@ -19,7 +19,7 @@ import { Context } from '../../core/shared/context.model';
|
||||
* Component for browsing items by metadata in a hierarchical controlled vocabulary
|
||||
*/
|
||||
@rendersBrowseBy(BrowseByDataType.Hierarchy)
|
||||
export class BrowseByTaxonomyComponent implements OnInit, OnDestroy {
|
||||
export class BrowseByTaxonomyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
/**
|
||||
* The optional context
|
||||
@@ -31,6 +31,13 @@ export class BrowseByTaxonomyComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
@Input() browseByType: BrowseByDataType;
|
||||
|
||||
/**
|
||||
* The ID of the {@link Community} or {@link Collection} of the scope to display
|
||||
*/
|
||||
@Input() scope: string;
|
||||
|
||||
scope$: BehaviorSubject<string> = new BehaviorSubject(undefined);
|
||||
|
||||
/**
|
||||
* The {@link VocabularyOptions} object
|
||||
*/
|
||||
@@ -89,6 +96,10 @@ export class BrowseByTaxonomyComponent implements OnInit, OnDestroy {
|
||||
}));
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
this.scope$.next(this.scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds detail to selectedItems, transforms it to be used as query parameter
|
||||
* and adds that to filterValues.
|
||||
|
@@ -29,14 +29,14 @@ export class BrowseByTitleComponent extends BrowseByMetadataComponent implements
|
||||
this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig);
|
||||
this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig);
|
||||
this.subs.push(
|
||||
observableCombineLatest([this.route.params, this.route.queryParams, this.currentPagination$, this.currentSort$]).pipe(
|
||||
map(([routeParams, queryParams, currentPage, currentSort]) => {
|
||||
return [Object.assign({}, routeParams, queryParams), currentPage, currentSort];
|
||||
observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.currentPagination$, this.currentSort$]).pipe(
|
||||
map(([routeParams, queryParams, scope, currentPage, currentSort]) => {
|
||||
return [Object.assign({}, routeParams, queryParams), scope, currentPage, currentSort];
|
||||
})
|
||||
).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => {
|
||||
).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => {
|
||||
this.startsWith = +params.startsWith || params.startsWith;
|
||||
this.browseId = params.id || this.defaultBrowseId;
|
||||
this.updatePageWithItems(browseParamsToOptions(params, currentPage, currentSort, this.browseId, this.fetchThumbnails), undefined, undefined);
|
||||
this.updatePageWithItems(browseParamsToOptions(params, scope, currentPage, currentSort, this.browseId, this.fetchThumbnails), undefined, undefined);
|
||||
}));
|
||||
this.updateStartsWithTextOptions();
|
||||
}
|
||||
|
@@ -1,2 +1,3 @@
|
||||
<ds-browse-by-switcher [browseByType]="browseByType$ | async">
|
||||
<ds-browse-by-switcher [browseByType]="browseByType$ | async"
|
||||
[scope]="scope$ | async">
|
||||
</ds-browse-by-switcher>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { BrowseByDataType } from '../../../../browse-by/browse-by-switcher/browse-by-data-type';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ActivatedRoute, Data } from '@angular/router';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { BrowseDefinition } from '../../../../core/shared/browse-definition.model';
|
||||
|
||||
@@ -14,6 +14,8 @@ export class ComcolBrowseByComponent implements OnInit {
|
||||
|
||||
browseByType$: Observable<BrowseByDataType>;
|
||||
|
||||
scope$: Observable<string>;
|
||||
|
||||
constructor(
|
||||
protected route: ActivatedRoute,
|
||||
) {
|
||||
@@ -26,6 +28,9 @@ export class ComcolBrowseByComponent implements OnInit {
|
||||
this.browseByType$ = this.route.data.pipe(
|
||||
map((data: { browseDefinition: BrowseDefinition }) => data.browseDefinition.getRenderType()),
|
||||
);
|
||||
this.scope$ = this.route.data.pipe(
|
||||
map((data: Data) => data.scope),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user