108588: Fixed browse by issue date show loading icon indefinitely when empty

(cherry picked from commit 6f51bd866c)
This commit is contained in:
Alexandre Vryghem
2023-12-18 00:01:59 +01:00
parent 0f09920cb1
commit f2dab663ca
5 changed files with 41 additions and 11 deletions

View File

@@ -23,6 +23,7 @@ import { PaginationServiceStub } from '../../shared/testing/pagination-service.s
import { APP_CONFIG } from '../../../config/app-config.interface'; import { APP_CONFIG } from '../../../config/app-config.interface';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';
import { SortDirection } from '../../core/cache/models/sort-options.model'; import { SortDirection } from '../../core/cache/models/sort-options.model';
import { cold } from 'jasmine-marbles';
describe('BrowseByDatePageComponent', () => { describe('BrowseByDatePageComponent', () => {
let comp: BrowseByDatePageComponent; let comp: BrowseByDatePageComponent;
@@ -112,9 +113,13 @@ describe('BrowseByDatePageComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should initialize the list of items', () => { it('should initialize the list of items', (done: DoneFn) => {
expect(comp.loading$).toBeObservable(cold('(a|)', {
a: false,
}));
comp.items$.subscribe((result) => { comp.items$.subscribe((result) => {
expect(result.payload.page).toEqual([firstItem]); expect(result.payload.page).toEqual([firstItem]);
done();
}); });
}); });

View File

@@ -4,7 +4,7 @@ import {
browseParamsToOptions, browseParamsToOptions,
getBrowseSearchOptions getBrowseSearchOptions
} from '../browse-by-metadata-page/browse-by-metadata-page.component'; } from '../browse-by-metadata-page/browse-by-metadata-page.component';
import { combineLatest as observableCombineLatest } from 'rxjs'; import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { hasValue, isNotEmpty } from '../../shared/empty.util';
import { ActivatedRoute, Params, Router } from '@angular/router'; import { ActivatedRoute, Params, Router } from '@angular/router';
import { BrowseService } from '../../core/browse/browse.service'; import { BrowseService } from '../../core/browse/browse.service';
@@ -85,12 +85,21 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
* @param scope The scope under which to fetch the earliest item for * @param scope The scope under which to fetch the earliest item for
*/ */
updateStartsWithOptions(definition: string, metadataKeys: string[], scope?: string) { updateStartsWithOptions(definition: string, metadataKeys: string[], scope?: string) {
const firstItemRD = this.browseService.getFirstItemFor(definition, scope, SortDirection.ASC); const firstItemRD$: Observable<RemoteData<Item>> = this.browseService.getFirstItemFor(definition, scope, SortDirection.ASC);
const lastItemRD = this.browseService.getFirstItemFor(definition, scope, SortDirection.DESC); const lastItemRD$: Observable<RemoteData<Item>> = this.browseService.getFirstItemFor(definition, scope, SortDirection.DESC);
this.loading$ = observableCombineLatest([
firstItemRD$,
lastItemRD$,
]).pipe(
map(([firstItemRD, lastItemRD]: [RemoteData<Item>, RemoteData<Item>]) => firstItemRD.isLoading || lastItemRD.isLoading)
);
this.subs.push( this.subs.push(
observableCombineLatest([firstItemRD, lastItemRD]).subscribe(([firstItem, lastItem]) => { observableCombineLatest([
let lowerLimit: number = this.getLimit(firstItem, metadataKeys, this.appConfig.browseBy.defaultLowerLimit); firstItemRD$,
let upperLimit: number = this.getLimit(lastItem, metadataKeys, new Date().getUTCFullYear()); lastItemRD$,
]).subscribe(([firstItemRD, lastItemRD]: [RemoteData<Item>, RemoteData<Item>]) => {
let lowerLimit: number = this.getLimit(firstItemRD, metadataKeys, this.appConfig.browseBy.defaultLowerLimit);
let upperLimit: number = this.getLimit(lastItemRD, metadataKeys, new Date().getUTCFullYear());
const options: number[] = []; const options: number[] = [];
const oneYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.oneYearLimit) / 5) * 5; const oneYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.oneYearLimit) / 5) * 5;
const fiveYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.fiveYearLimit) / 10) * 10; const fiveYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.fiveYearLimit) / 10) * 10;

View File

@@ -32,7 +32,7 @@
<section class="comcol-page-browse-section"> <section class="comcol-page-browse-section">
<div class="browse-by-metadata w-100"> <div class="browse-by-metadata w-100">
<ds-themed-browse-by *ngIf="startsWithOptions" class="col-xs-12 w-100" <ds-themed-browse-by *ngIf="!(loading$ | async)" class="col-xs-12 w-100"
title="{{'browse.title' | translate: title="{{'browse.title' | translate:
{ {
collection: dsoNameService.getName((parent$ | async)?.payload), collection: dsoNameService.getName((parent$ | async)?.payload),
@@ -49,7 +49,7 @@
(prev)="goPrev()" (prev)="goPrev()"
(next)="goNext()"> (next)="goNext()">
</ds-themed-browse-by> </ds-themed-browse-by>
<ds-themed-loading *ngIf="!startsWithOptions" message="{{'loading.browse-by-page' | translate}}"></ds-themed-loading> <ds-themed-loading *ngIf="loading$ | async" message="{{'loading.browse-by-page' | translate}}"></ds-themed-loading>
</div> </div>
</section> </section>
<ng-container *ngVar="(parent$ | async) as parent"> <ng-container *ngVar="(parent$ | async) as parent">

View File

@@ -30,6 +30,7 @@ import { PaginationService } from '../../core/pagination/pagination.service';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { APP_CONFIG } from '../../../config/app-config.interface'; import { APP_CONFIG } from '../../../config/app-config.interface';
import { cold } from 'jasmine-marbles';
describe('BrowseByMetadataPageComponent', () => { describe('BrowseByMetadataPageComponent', () => {
let comp: BrowseByMetadataPageComponent; let comp: BrowseByMetadataPageComponent;
@@ -149,9 +150,13 @@ describe('BrowseByMetadataPageComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should fetch items', () => { it('should fetch items', (done: DoneFn) => {
expect(comp.loading$).toBeObservable(cold('(a|)', {
a: false,
}));
comp.items$.subscribe((result) => { comp.items$.subscribe((result) => {
expect(result.payload.page).toEqual(mockItems); expect(result.payload.page).toEqual(mockItems);
done();
}); });
}); });

View File

@@ -1,4 +1,4 @@
import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; import { combineLatest as observableCombineLatest, Observable, Subscription, of as observableOf } from 'rxjs';
import { Component, Inject, OnInit, OnDestroy } from '@angular/core'; import { Component, Inject, OnInit, OnDestroy } from '@angular/core';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { PaginatedList } from '../../core/data/paginated-list.model'; import { PaginatedList } from '../../core/data/paginated-list.model';
@@ -122,6 +122,11 @@ export class BrowseByMetadataPageComponent implements OnInit, OnDestroy {
*/ */
fetchThumbnails: boolean; fetchThumbnails: boolean;
/**
* Observable determining if the loading animation needs to be shown
*/
loading$ = observableOf(true);
public constructor(protected route: ActivatedRoute, public constructor(protected route: ActivatedRoute,
protected browseService: BrowseService, protected browseService: BrowseService,
protected dsoService: DSpaceObjectDataService, protected dsoService: DSpaceObjectDataService,
@@ -200,6 +205,9 @@ export class BrowseByMetadataPageComponent implements OnInit, OnDestroy {
*/ */
updatePage(searchOptions: BrowseEntrySearchOptions) { updatePage(searchOptions: BrowseEntrySearchOptions) {
this.browseEntries$ = this.browseService.getBrowseEntriesFor(searchOptions); this.browseEntries$ = this.browseService.getBrowseEntriesFor(searchOptions);
this.loading$ = this.browseEntries$.pipe(
map((browseEntriesRD: RemoteData<PaginatedList<BrowseEntry>>) => browseEntriesRD.isLoading),
);
this.items$ = undefined; this.items$ = undefined;
} }
@@ -214,6 +222,9 @@ export class BrowseByMetadataPageComponent implements OnInit, OnDestroy {
*/ */
updatePageWithItems(searchOptions: BrowseEntrySearchOptions, value: string, authority: string) { updatePageWithItems(searchOptions: BrowseEntrySearchOptions, value: string, authority: string) {
this.items$ = this.browseService.getBrowseItemsFor(value, authority, searchOptions); this.items$ = this.browseService.getBrowseItemsFor(value, authority, searchOptions);
this.loading$ = this.items$.pipe(
map((itemsRD: RemoteData<PaginatedList<Item>>) => itemsRD.isLoading),
);
} }
/** /**