diff --git a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts index d3c832d3e2e..7e0b6f0f886 100644 --- a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts +++ b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts @@ -1,8 +1,7 @@ import { ChangeDetectorRef, Component, Inject } from '@angular/core'; import { BrowseByMetadataPageComponent, - browseParamsToOptions, - getBrowseSearchOptions + browseParamsToOptions } from '../browse-by-metadata-page/browse-by-metadata-page.component'; import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; @@ -11,7 +10,7 @@ import { BrowseService } from '../../core/browse/browse.service'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { StartsWithType } from '../../shared/starts-with/starts-with-decorator'; import { PaginationService } from '../../core/pagination/pagination.service'; -import { map } from 'rxjs/operators'; +import { map, take } from 'rxjs/operators'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { isValidDate } from '../../shared/date.util'; @@ -52,15 +51,16 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent { ngOnInit(): void { const sortConfig = new SortOptions('default', SortDirection.ASC); this.startsWithType = StartsWithType.date; - // include the thumbnail configuration in browse search options - this.updatePage(getBrowseSearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig, this.fetchThumbnails)); 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, - this.currentPagination$, this.currentSort$]).pipe( - map(([routeParams, queryParams, data, currentPage, currentSort]) => { - return [Object.assign({}, routeParams, queryParams, data), currentPage, currentSort]; + observableCombineLatest( + [ this.route.params.pipe(take(1)), + this.route.queryParams, + this.currentPagination$, + this.currentSort$]).pipe( + map(([routeParams, queryParams, currentPage, currentSort]) => { + return [Object.assign({}, routeParams, queryParams), currentPage, currentSort]; }) ).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => { const metadataKeys = params.browseDefinition ? params.browseDefinition.metadataKeys : this.defaultMetadataKeys; diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts index c03cf03429f..fe407a2fb0d 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts @@ -15,7 +15,7 @@ import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.serv import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { StartsWithType } from '../../shared/starts-with/starts-with-decorator'; import { PaginationService } from '../../core/pagination/pagination.service'; -import { filter, map, mergeMap } from 'rxjs/operators'; +import { filter, map, mergeMap, take } from 'rxjs/operators'; import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Bitstream } from '../../core/shared/bitstream.model'; import { Collection } from '../../core/shared/collection.model'; @@ -152,7 +152,11 @@ export class BrowseByMetadataPageComponent 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( + observableCombineLatest( + [ this.route.params.pipe(take(1)), + this.route.queryParams, + this.currentPagination$, + this.currentSort$]).pipe( map(([routeParams, queryParams, currentPage, currentSort]) => { return [Object.assign({}, routeParams, queryParams),currentPage,currentSort]; }) diff --git a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts index 58df79ebe85..11dc2a2a6aa 100644 --- a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts +++ b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts @@ -4,13 +4,13 @@ import { ActivatedRoute, Params, Router } from '@angular/router'; import { hasValue } from '../../shared/empty.util'; import { BrowseByMetadataPageComponent, - browseParamsToOptions, getBrowseSearchOptions + browseParamsToOptions } from '../browse-by-metadata-page/browse-by-metadata-page.component'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { BrowseService } from '../../core/browse/browse.service'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { PaginationService } from '../../core/pagination/pagination.service'; -import { map } from 'rxjs/operators'; +import { map, take } from 'rxjs/operators'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { AppConfig, APP_CONFIG } from '../../../config/app-config.interface'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; @@ -38,12 +38,10 @@ export class BrowseByTitlePageComponent extends BrowseByMetadataPageComponent { ngOnInit(): void { const sortConfig = new SortOptions('dc.title', SortDirection.ASC); - // include the thumbnail configuration in browse search options - this.updatePage(getBrowseSearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig, this.fetchThumbnails)); 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( + observableCombineLatest([this.route.params.pipe(take(1)), this.route.queryParams, this.currentPagination$, this.currentSort$]).pipe( map(([routeParams, queryParams, currentPage, currentSort]) => { return [Object.assign({}, routeParams, queryParams),currentPage,currentSort]; }) diff --git a/src/app/menu.resolver.spec.ts b/src/app/menu.resolver.spec.ts index 838d5a53c5b..12d5efa24e1 100644 --- a/src/app/menu.resolver.spec.ts +++ b/src/app/menu.resolver.spec.ts @@ -16,9 +16,11 @@ import { MenuServiceStub } from './shared/testing/menu-service.stub'; import { MenuID } from './shared/menu/menu-id.model'; import { BrowseService } from './core/browse/browse.service'; import { cold } from 'jasmine-marbles'; -import createSpy = jasmine.createSpy; import { createSuccessfulRemoteDataObject$ } from './shared/remote-data.utils'; import { createPaginatedList } from './shared/testing/utils.test'; +import createSpy = jasmine.createSpy; +import { AuthService } from './core/auth/auth.service'; +import { AuthServiceStub } from './shared/testing/auth-service.stub'; const BOOLEAN = { t: true, f: false }; const MENU_STATE = { @@ -61,6 +63,7 @@ describe('MenuResolver', () => { { provide: BrowseService, useValue: browseService }, { provide: AuthorizationDataService, useValue: authorizationService }, { provide: ScriptDataService, useValue: scriptService }, + { provide: AuthService, useValue: AuthServiceStub }, { provide: NgbModal, useValue: { open: () => {/*comment*/ @@ -80,19 +83,19 @@ describe('MenuResolver', () => { describe('resolve', () => { it('should create all menus', (done) => { spyOn(resolver, 'createPublicMenu$').and.returnValue(observableOf(true)); - spyOn(resolver, 'createAdminMenu$').and.returnValue(observableOf(true)); + spyOn(resolver, 'createAdminMenuIfLoggedIn$').and.returnValue(observableOf(true)); resolver.resolve(null, null).subscribe(resolved => { expect(resolved).toBeTrue(); expect(resolver.createPublicMenu$).toHaveBeenCalled(); - expect(resolver.createAdminMenu$).toHaveBeenCalled(); + expect(resolver.createAdminMenuIfLoggedIn$).toHaveBeenCalled(); done(); }); }); it('should return an Observable that emits true as soon as all menus are created', () => { spyOn(resolver, 'createPublicMenu$').and.returnValue(cold('--(t|)', BOOLEAN)); - spyOn(resolver, 'createAdminMenu$').and.returnValue(cold('----(t|)', BOOLEAN)); + spyOn(resolver, 'createAdminMenuIfLoggedIn$').and.returnValue(cold('----(t|)', BOOLEAN)); expect(resolver.resolve(null, null)).toBeObservable(cold('----(t|)', BOOLEAN)); }); diff --git a/src/app/menu.resolver.ts b/src/app/menu.resolver.ts index cad6a6ec570..83c9351c7f0 100644 --- a/src/app/menu.resolver.ts +++ b/src/app/menu.resolver.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; -import { combineLatest as observableCombineLatest, combineLatest, Observable } from 'rxjs'; +import { combineLatest as observableCombineLatest, combineLatest, Observable, of as observableOf } from 'rxjs'; import { MenuID } from './shared/menu/menu-id.model'; import { MenuState } from './shared/menu/menu-state.model'; import { MenuItemType } from './shared/menu/menu-item-type.model'; @@ -12,7 +12,7 @@ import { RemoteData } from './core/data/remote-data'; import { TextMenuItemModel } from './shared/menu/menu-item/models/text.model'; import { BrowseService } from './core/browse/browse.service'; import { MenuService } from './shared/menu/menu.service'; -import { filter, find, map, take } from 'rxjs/operators'; +import { filter, find, map, mergeMap, take } from 'rxjs/operators'; import { hasValue } from './shared/empty.util'; import { FeatureID } from './core/data/feature-authorization/feature-id'; import { @@ -47,6 +47,7 @@ import { import { ExportBatchSelectorComponent } from './shared/dso-selector/modal-wrappers/export-batch-selector/export-batch-selector.component'; +import { AuthService } from './core/auth/auth.service'; /** * Creates all of the app's menus @@ -61,6 +62,7 @@ export class MenuResolver implements Resolve { protected authorizationService: AuthorizationDataService, protected modalService: NgbModal, protected scriptDataService: ScriptDataService, + protected authService: AuthService, ) { } @@ -70,7 +72,7 @@ export class MenuResolver implements Resolve { resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { return combineLatest([ this.createPublicMenu$(), - this.createAdminMenu$(), + this.createAdminMenuIfLoggedIn$(), ]).pipe( map((menusDone: boolean[]) => menusDone.every(Boolean)), ); @@ -146,6 +148,15 @@ export class MenuResolver implements Resolve { return this.waitForMenu$(MenuID.PUBLIC); } + /** + * Initialize all menu sections and items for {@link MenuID.ADMIN}, only if the user is logged in. + */ + createAdminMenuIfLoggedIn$() { + return this.authService.isAuthenticated().pipe( + mergeMap((isAuthenticated) => isAuthenticated ? this.createAdminMenu$() : observableOf(true)), + ); + } + /** * Initialize all menu sections and items for {@link MenuID.ADMIN} */