diff --git a/src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts b/src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts index 0be651c2ba2..c813de329b0 100644 --- a/src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts +++ b/src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts @@ -89,6 +89,7 @@ describe('BrowseByDateComponent', () => { getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData([]), getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData([firstItem]), getFirstItemFor: (definition: string, scope?: string, sortDirection?: SortDirection) => null, + getConfiguredSortDirection: () => of(SortDirection.DESC), }; const mockDsoService = { diff --git a/src/app/browse-by/browse-by-date/browse-by-date.component.ts b/src/app/browse-by/browse-by-date/browse-by-date.component.ts index 9b5b7bb2e0a..c65f16cfd5f 100644 --- a/src/app/browse-by/browse-by-date/browse-by-date.component.ts +++ b/src/app/browse-by/browse-by-date/browse-by-date.component.ts @@ -11,7 +11,6 @@ import { } from '@angular/core'; import { ActivatedRoute, - Params, Router, } from '@angular/router'; import { @@ -27,7 +26,6 @@ import { import { DSpaceObjectDataService } from '@dspace/core/data/dspace-object-data.service'; import { RemoteData } from '@dspace/core/data/remote-data'; import { PaginationService } from '@dspace/core/pagination/pagination.service'; -import { PaginationComponentOptions } from '@dspace/core/pagination/pagination-component-options.model'; import { Item } from '@dspace/core/shared/item.model'; import { isValidDate } from '@dspace/shared/utils/date.util'; import { @@ -41,8 +39,8 @@ import { of, } from 'rxjs'; import { - distinctUntilChanged, map, + switchMap, } from 'rxjs/operators'; import { ThemedBrowseByComponent } from 'src/app/shared/browse-by/themed-browse-by.component'; @@ -96,27 +94,23 @@ export class BrowseByDateComponent extends BrowseByMetadataComponent implements this.loading$ = of(false); return; } - const sortConfig = new SortOptions('default', SortDirection.ASC); + this.browseId = this.route.snapshot.params.id; this.startsWithType = StartsWithType.date; - this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); - this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig); - const routeParams$: Observable = observableCombineLatest([ - this.route.params, - this.route.queryParams, - ]).pipe( - map(([params, queryParams]: [Params, Params]) => Object.assign({}, params, queryParams)), - distinctUntilChanged((prev: Params, curr: Params) => prev.id === curr.id && prev.startsWith === curr.startsWith), - ); + this.subs.push( - observableCombineLatest([ - routeParams$, - this.scope$, - this.currentPagination$, - this.currentSort$, - ]).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => { + this.browseService.getConfiguredSortDirection(this.browseId, SortDirection.ASC).pipe( + map((sortDir) => new SortOptions(this.browseId, sortDir)), + switchMap((sortConfig) => { + this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); + this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig, false); + return observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.route.data, this.currentPagination$, this.currentSort$]).pipe( + map(([routeParams, queryParams, scope, data, currentPage, currentSort]) => ({ + params: Object.assign({}, routeParams, queryParams, data), scope, currentPage, currentSort, + }))); + })).subscribe(({ params, scope, currentPage, currentSort }) => { const metadataKeys = params.browseDefinition ? params.browseDefinition.metadataKeys : this.defaultMetadataKeys; - this.browseId = params.id || this.defaultBrowseId; this.startsWith = +params.startsWith || params.startsWith; + this.browseId = params.id || this.defaultBrowseId; const searchOptions = browseParamsToOptions(params, scope, currentPage, currentSort, this.browseId, this.fetchThumbnails); this.updatePageWithItems(searchOptions, this.value, undefined); this.updateStartsWithOptions(this.browseId, metadataKeys, params.scope); diff --git a/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.spec.ts b/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.spec.ts index ec393d706b8..00e95a82d33 100644 --- a/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.spec.ts +++ b/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.spec.ts @@ -117,6 +117,7 @@ describe('BrowseByMetadataComponent', () => { const mockBrowseService = { getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData(mockEntries), getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData(mockItems), + getConfiguredSortDirection: () => of(SortDirection.ASC), }; const mockDsoService = { diff --git a/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts b/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts index 4ddd9f1ba26..f88f8a374cb 100644 --- a/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts +++ b/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts @@ -14,7 +14,6 @@ import { } from '@angular/core'; import { ActivatedRoute, - Params, Router, } from '@angular/router'; import { @@ -51,8 +50,8 @@ import { Subscription, } from 'rxjs'; import { - distinctUntilChanged, map, + switchMap, } from 'rxjs/operators'; import { ThemedBrowseByComponent } from 'src/app/shared/browse-by/themed-browse-by.component'; @@ -215,24 +214,18 @@ export class BrowseByMetadataComponent implements OnInit, OnChanges, OnDestroy { this.loading$ = of(false); return; } - const sortConfig = new SortOptions('default', SortDirection.ASC); - this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); - this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig); - const routeParams$: Observable = observableCombineLatest([ - this.route.params, - this.route.queryParams, - ]).pipe( - map(([params, queryParams]: [Params, Params]) => Object.assign({}, params, queryParams)), - distinctUntilChanged((prev: Params, curr: Params) => prev.id === curr.id && prev.authority === curr.authority && prev.value === curr.value && prev.startsWith === curr.startsWith), - ); + this.browseId = this.route.snapshot.params.id; this.subs.push( - observableCombineLatest([ - routeParams$, - this.scope$, - this.currentPagination$, - this.currentSort$, - ]).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => { - this.browseId = params.id || this.defaultBrowseId; + this.browseService.getConfiguredSortDirection(this.browseId, SortDirection.ASC).pipe( + map((sortDir) => new SortOptions(this.browseId, sortDir)), + switchMap((sortConfig) => { + this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig, false); + this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); + return observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.currentPagination$, this.currentSort$]).pipe( + map(([routeParams, queryParams, scope, currentPage, currentSort]) => ({ + params: Object.assign({}, routeParams, queryParams), scope, currentPage, currentSort, + }))); + })).subscribe(({ params, scope, currentPage, currentSort }) => { this.authority = params.authority; if (typeof params.value === 'string') { @@ -256,9 +249,8 @@ export class BrowseByMetadataComponent implements OnInit, OnChanges, OnDestroy { } else { this.updatePage(browseParamsToOptions(params, scope, currentPage, currentSort, this.browseId, false)); } + this.updateStartsWithTextOptions(); })); - this.updateStartsWithTextOptions(); - } ngOnChanges(changes: SimpleChanges): void { diff --git a/src/app/browse-by/browse-by-title/browse-by-title.component.spec.ts b/src/app/browse-by/browse-by-title/browse-by-title.component.spec.ts index e8ea1f6aa0d..e5580e9799f 100644 --- a/src/app/browse-by/browse-by-title/browse-by-title.component.spec.ts +++ b/src/app/browse-by/browse-by-title/browse-by-title.component.spec.ts @@ -17,6 +17,7 @@ import { import { RouterTestingModule } from '@angular/router/testing'; import { APP_CONFIG } from '@dspace/config/app-config.interface'; import { BrowseService } from '@dspace/core/browse/browse.service'; +import { SortDirection } from '@dspace/core/cache/models/sort-options.model'; import { DSpaceObjectDataService } from '@dspace/core/data/dspace-object-data.service'; import { ItemDataService } from '@dspace/core/data/item-data.service'; import { PaginationService } from '@dspace/core/pagination/pagination.service'; @@ -76,6 +77,7 @@ describe('BrowseByTitleComponent', () => { const mockBrowseService = { getBrowseItemsFor: () => toRemoteData(mockItems), getBrowseEntriesFor: () => toRemoteData([]), + getConfiguredSortDirection: () => of(SortDirection.ASC), }; const mockDsoService = { diff --git a/src/app/browse-by/browse-by-title/browse-by-title.component.ts b/src/app/browse-by/browse-by-title/browse-by-title.component.ts index 7de996d448b..49aa0c32871 100644 --- a/src/app/browse-by/browse-by-title/browse-by-title.component.ts +++ b/src/app/browse-by/browse-by-title/browse-by-title.component.ts @@ -6,21 +6,18 @@ import { Component, OnInit, } from '@angular/core'; -import { Params } from '@angular/router'; import { SortDirection, SortOptions, } from '@dspace/core/cache/models/sort-options.model'; -import { PaginationComponentOptions } from '@dspace/core/pagination/pagination-component-options.model'; import { TranslateModule } from '@ngx-translate/core'; import { combineLatest as observableCombineLatest, - Observable, of, } from 'rxjs'; import { - distinctUntilChanged, map, + switchMap, } from 'rxjs/operators'; import { environment } from '../../../environments/environment'; @@ -52,28 +49,23 @@ export class BrowseByTitleComponent extends BrowseByMetadataComponent implements this.loading$ = of(false); return; } - const sortConfig = new SortOptions('dc.title', SortDirection.ASC); - this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); - this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig); - const routeParams$: Observable = observableCombineLatest([ - this.route.params, - this.route.queryParams, - ]).pipe( - map(([params, queryParams]: [Params, Params]) => Object.assign({}, params, queryParams)), - distinctUntilChanged((prev: Params, curr: Params) => prev.id === curr.id && prev.startsWith === curr.startsWith), - ); + this.browseId = this.route.snapshot.params.id; this.subs.push( - observableCombineLatest([ - routeParams$, - this.scope$, - this.currentPagination$, - this.currentSort$, - ]).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => { + this.browseService.getConfiguredSortDirection(this.browseId, SortDirection.ASC).pipe( + map((sortDir) => new SortOptions(this.browseId, sortDir)), + switchMap((sortConfig) => { + this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig, false); + this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); + return observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.currentPagination$, this.currentSort$]).pipe( + map(([routeParams, queryParams, scope, currentPage, currentSort]) => ({ + params: Object.assign({}, routeParams, queryParams), scope, currentPage, currentSort, + })), + ); + })).subscribe(({ params, scope, currentPage, currentSort }) => { this.startsWith = +params.startsWith || params.startsWith; - this.browseId = params.id || this.defaultBrowseId; this.updatePageWithItems(browseParamsToOptions(params, scope, currentPage, currentSort, this.browseId, this.fetchThumbnails), undefined, undefined); + this.updateStartsWithTextOptions(); })); - this.updateStartsWithTextOptions(); } } diff --git a/src/app/core/browse/browse.service.ts b/src/app/core/browse/browse.service.ts index 86be32e3b0f..d9509e49a08 100644 --- a/src/app/core/browse/browse.service.ts +++ b/src/app/core/browse/browse.service.ts @@ -134,6 +134,29 @@ export class BrowseService { return this.hrefOnlyDataService.findListByHref(href$); } + /* + * Get the sort direction for a browse index based on its unique id + * @param browseId The unique id of the browse index + * @param defaultDirection The default sort direction to return if the browse index has no sort direction configured + * @returns {Observable} The sort direction of the browse index + */ + getConfiguredSortDirection(browseId: string, defaultDirection: SortDirection): Observable { + return this.getBrowseDefinitions().pipe( + getRemoteDataPayload(), + getPaginatedListPayload(), + map((browseDefinitions: BrowseDefinition[]) => browseDefinitions + .find((def: BrowseDefinition) => def.id === browseId), + ), + map((browseDef: BrowseDefinition) => { + if (browseDef.order === SortDirection.ASC || browseDef.order === SortDirection.DESC) { + return browseDef.order; + } else { + return defaultDirection; + } + }), + ); + } + /** * Get all items linked to a certain metadata value * @param {string} filterValue metadata value to filter by (e.g. author's name) diff --git a/src/app/core/shared/browse-definition.model.ts b/src/app/core/shared/browse-definition.model.ts index 78dc94d4d33..8b59a6b0534 100644 --- a/src/app/core/shared/browse-definition.model.ts +++ b/src/app/core/shared/browse-definition.model.ts @@ -5,6 +5,7 @@ import { import { BrowseByDataType } from '../browse/browse-by-data-type'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { SortDirection } from '../cache/models/sort-options.model'; /** * Base class for BrowseDefinition models @@ -17,6 +18,9 @@ export abstract class BrowseDefinition extends CacheableObject { @autoserializeAs('metadata') metadataKeys: string[]; + @autoserialize + order: SortDirection; + /** * Get the render type of the BrowseDefinition model */