66155: Show more/less incremental on item pages + loading component for entities

This commit is contained in:
Kristof De Langhe
2019-11-14 13:29:39 +01:00
parent 576b5328c3
commit aedd4b99ee
5 changed files with 119 additions and 48 deletions

View File

@@ -405,8 +405,8 @@
"item.page.link.full": "Full item page",
"item.page.link.simple": "Simple item page",
"item.page.person.search.title": "Articles by this author",
"item.page.related-items.view-more": "View more",
"item.page.related-items.view-less": "View less",
"item.page.related-items.view-more": "Show {{ amount }} more",
"item.page.related-items.view-less": "Hide last {{ amount }}",
"item.page.subject": "Keywords",
"item.page.uri": "URI",

View File

@@ -1,11 +1,18 @@
<ds-metadata-field-wrapper *ngIf="representations$ && (representations$ | async)?.length > 0" [label]="label">
<ds-item-type-switcher *ngFor="let rep of (representations$ | async)"
[object]="rep" [viewMode]="viewMode">
</ds-item-type-switcher>
<div *ngIf="(representations$ | async)?.length < total" class="mt-2">
<a [routerLink]="" (click)="viewMore()">{{'item.page.related-items.view-more' | translate}}</a>
</div>
<div *ngIf="limit > originalLimit" class="mt-2">
<a [routerLink]="" (click)="viewLess()">{{'item.page.related-items.view-less' | translate}}</a>
</div>
<ds-metadata-field-wrapper [label]="label">
<ng-container *ngVar="(representations$ | async) as representations">
<ds-item-type-switcher *ngFor="let rep of representations"
[object]="rep" [viewMode]="viewMode">
</ds-item-type-switcher>
<ds-loading *ngIf="loading" message="{{'loading.default' | translate}}"></ds-loading>
<div class="d-inline-block w-100 mt-2" *ngIf="representations?.length > 0">
<div *ngIf="representations?.length < total" class="float-left">
<a [routerLink]="" (click)="viewMore()">{{'item.page.related-items.view-more' |
translate:{ amount: (total - representations?.length < incrementBy) ? total - representations?.length : incrementBy } }}</a>
</div>
<div *ngIf="limit > originalLimit" class="float-right">
<a [routerLink]="" (click)="viewLess()">{{'item.page.related-items.view-less' |
translate:{ amount: (representations?.length < limit) ? limit - representations?.length : incrementBy } }}</a>
</div>
</div>
</ng-container>
</ds-metadata-field-wrapper>

View File

@@ -1,4 +1,4 @@
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { MetadataRepresentation } from '../../../core/shared/metadata-representation/metadata-representation.model';
import { ItemViewMode } from '../../../shared/items/item-type-decorator';
import { Observable } from 'rxjs/internal/Observable';
@@ -12,6 +12,8 @@ import { filter, map, switchMap } from 'rxjs/operators';
import { getSucceededRemoteData } from '../../../core/shared/operators';
import { Relationship } from '../../../core/shared/item-relationships/relationship.model';
import { ItemMetadataRepresentation } from '../../../core/shared/metadata-representation/item/item-metadata-representation.model';
import { Subscription } from 'rxjs/internal/Subscription';
import { PaginatedList } from '../../../core/data/paginated-list';
@Component({
selector: 'ds-metadata-representation-list',
@@ -23,7 +25,7 @@ import { ItemMetadataRepresentation } from '../../../core/shared/metadata-repres
* It expects an itemType to resolve the metadata to a an item
* It expects a label to put on top of the list
*/
export class MetadataRepresentationListComponent implements OnInit {
export class MetadataRepresentationListComponent implements OnInit, OnDestroy {
/**
* The parent of the list of related items to display
*/
@@ -51,6 +53,18 @@ export class MetadataRepresentationListComponent implements OnInit {
*/
@Input() limit = 10;
/**
* The amount to increment the list by when clicking "view more"
* Defaults to 10
* The default can optionally be overridden by providing the limit as input to the component
*/
@Input() incrementBy = 10;
/**
* Is the list (re-)loading?
*/
loading = false;
/**
* A list of metadata-representations to display
*/
@@ -73,6 +87,11 @@ export class MetadataRepresentationListComponent implements OnInit {
*/
total: number;
/**
* Subscription on representations used to update the "loading" property of this component
*/
representationsSub: Subscription;
constructor(public relationshipService: RelationshipService) {
}
@@ -88,6 +107,9 @@ export class MetadataRepresentationListComponent implements OnInit {
const metadata = this.parentItem.findMetadataSortedByPlace(this.metadataField);
this.total = metadata.length;
this.representations$ = this.resolveMetadataRepresentations(metadata);
this.representationsSub = this.representations$.subscribe((represenations: MetadataRepresentation[]) => {
this.loading = represenations.length !== this.limit && represenations.length !== this.total;
});
}
/**
@@ -124,18 +146,31 @@ export class MetadataRepresentationListComponent implements OnInit {
}
/**
* Expand the list to display all metadata representations
* Expand the list to display more metadata representations
*/
viewMore() {
this.limit = 9999;
this.limit = this.limit + this.incrementBy;
this.loading = true;
this.setRepresentations();
}
/**
* Collapse the list to display the originally displayed metadata representations
* Collapse the list to display less metadata representations
*/
viewLess() {
this.limit = this.originalLimit;
if (this.limit > this.originalLimit) {
this.limit = this.limit - this.incrementBy;
}
this.loading = true;
this.setRepresentations();
}
/**
* Unsubscribe from the representations subscription
*/
ngOnDestroy(): void {
if (this.representationsSub) {
this.representationsSub.unsubscribe();
}
}
}

View File

@@ -32,10 +32,24 @@ export class RelatedItemsComponent implements OnInit, OnDestroy {
@Input() relationType: string;
/**
* Default options to start a search request with
* Optional input, should you wish a different page size (or other options)
* The max amount of relations to display
* Defaults to 5
* The default can optionally be overridden by providing the limit as input to the component
*/
@Input() options = Object.assign(new FindAllOptions(), { elementsPerPage: 5 });
@Input() limit = 5;
/**
* The amount to increment the list by when clicking "view more"
* Defaults to 5
* The default can optionally be overridden by providing the limit as input to the component
*/
@Input() incrementBy = 5;
/**
* Default options to start a search request with
* Optional input
*/
@Input() options = new FindAllOptions();
/**
* An i18n label to use as a title for the list (usually describes the relation)
@@ -43,20 +57,15 @@ export class RelatedItemsComponent implements OnInit, OnDestroy {
@Input() label: string;
/**
* Completely hide the component until there's at least one item visible
* Is the list (re-)loading?
*/
@HostBinding('class.d-none') hidden = true;
loading = false;
/**
* The list of related items
*/
items$: Observable<RemoteData<PaginatedList<Item>>>;
/**
* Search options for displaying all elements in a list
*/
allOptions = Object.assign(new FindAllOptions(), { elementsPerPage: 9999 });
/**
* The view-mode we're currently on
* @type {ElementViewMode}
@@ -64,12 +73,13 @@ export class RelatedItemsComponent implements OnInit, OnDestroy {
viewMode = ItemViewMode.Element;
/**
* Whether or not the list is currently expanded to show all related items
* The originally provided limit
* Used for comparing the current size with the original
*/
showingAll = false;
originalLimit: number;
/**
* Subscription on items used to update the "hidden" property of this component
* Subscription on items used to update the "loading" property of this component
*/
itemSub: Subscription;
@@ -77,26 +87,38 @@ export class RelatedItemsComponent implements OnInit, OnDestroy {
}
ngOnInit(): void {
this.items$ = this.relationshipService.getRelatedItemsByLabel(this.parentItem, this.relationType, this.options);
this.originalLimit = this.limit;
this.reloadItems();
}
/**
* Reload the current list of items (using the current limit)
*/
reloadItems() {
this.items$ = this.relationshipService.getRelatedItemsByLabel(this.parentItem, this.relationType, Object.assign(this.options, { elementsPerPage: this.limit }));
this.itemSub = this.items$.subscribe((itemsRD: RemoteData<PaginatedList<Item>>) => {
this.hidden = !(itemsRD.hasSucceeded && itemsRD.payload && itemsRD.payload.page.length > 0);
this.loading = !(itemsRD.hasSucceeded && itemsRD.payload && itemsRD.payload.page.length > 0);
});
}
/**
* Expand the list to display all related items
* Expand the list to display more
*/
viewMore() {
this.items$ = this.relationshipService.getRelatedItemsByLabel(this.parentItem, this.relationType, this.allOptions);
this.showingAll = true;
this.limit = this.limit + this.incrementBy;
this.loading = true;
this.reloadItems();
}
/**
* Collapse the list to display the originally displayed items
* Collapse the list to display less
*/
viewLess() {
this.items$ = this.relationshipService.getRelatedItemsByLabel(this.parentItem, this.relationType, this.options);
this.showingAll = false;
if (this.limit > this.originalLimit) {
this.limit = this.limit - this.incrementBy;
}
this.loading = true;
this.reloadItems();
}
/**

View File

@@ -1,11 +1,18 @@
<ds-metadata-field-wrapper *ngIf="(items$ | async)?.payload?.page?.length > 0" [label]="label">
<ds-item-type-switcher *ngFor="let item of (items$ | async)?.payload?.page"
<ds-metadata-field-wrapper [label]="label">
<ng-container *ngVar="(items$ | async) as itemsRD">
<ds-item-type-switcher *ngFor="let item of itemsRD?.payload?.page"
[object]="item" [viewMode]="viewMode">
</ds-item-type-switcher>
<div *ngIf="(items$ | async)?.payload?.page?.length < (items$ | async)?.payload?.totalElements" class="mt-2" id="view-more">
<a [routerLink]="" (click)="viewMore()">{{'item.page.related-items.view-more' | translate}}</a>
</div>
<div *ngIf="showingAll" class="mt-2" id="view-less">
<a [routerLink]="" (click)="viewLess()">{{'item.page.related-items.view-less' | translate}}</a>
</div>
</ds-item-type-switcher>
<ds-loading *ngIf="loading" message="{{'loading.default' | translate}}"></ds-loading>
<div class="d-inline-block w-100 mt-2" *ngIf="itemsRD?.payload?.page?.length > 0">
<div *ngIf="itemsRD?.payload?.page?.length < itemsRD?.payload?.totalElements" class="float-left" id="view-more">
<a [routerLink]="" (click)="viewMore()">{{'item.page.related-items.view-more' |
translate:{ amount: (itemsRD?.payload?.totalElements - itemsRD?.payload?.page?.length < incrementBy) ? itemsRD?.payload?.totalElements - itemsRD?.payload?.page?.length : incrementBy } }}</a>
</div>
<div *ngIf="limit > originalLimit" class="float-right" id="view-less">
<a [routerLink]="" (click)="viewLess()">{{'item.page.related-items.view-less' |
translate:{ amount: (itemsRD?.payload?.page?.length < limit) ? limit - itemsRD?.payload?.page?.length : incrementBy } }}</a>
</div>
</div>
</ng-container>
</ds-metadata-field-wrapper>