mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
65600: Pagination for subcommunities works; not yet for collections since it needs authorisation
This commit is contained in:
@@ -4,14 +4,15 @@ import {merge, Observable, of, of as observableOf} from 'rxjs';
|
|||||||
import {CommunityDataService} from '../core/data/community-data.service';
|
import {CommunityDataService} from '../core/data/community-data.service';
|
||||||
import {PaginationComponentOptions} from '../shared/pagination/pagination-component-options.model';
|
import {PaginationComponentOptions} from '../shared/pagination/pagination-component-options.model';
|
||||||
import {SortDirection, SortOptions} from '../core/cache/models/sort-options.model';
|
import {SortDirection, SortOptions} from '../core/cache/models/sort-options.model';
|
||||||
import {catchError, filter, map, switchMap, take, tap} from 'rxjs/operators';
|
import {catchError, defaultIfEmpty, filter, map, switchMap, take, tap} from 'rxjs/operators';
|
||||||
import {Community} from '../core/shared/community.model';
|
import {Community} from '../core/shared/community.model';
|
||||||
import {Collection} from '../core/shared/collection.model';
|
import {Collection} from '../core/shared/collection.model';
|
||||||
import {hasValue, isNotEmpty} from '../shared/empty.util';
|
import {hasValue, isEmpty, isNotEmpty} from '../shared/empty.util';
|
||||||
import {RemoteData} from '../core/data/remote-data';
|
import {RemoteData} from '../core/data/remote-data';
|
||||||
import {PaginatedList} from '../core/data/paginated-list';
|
import {PaginatedList} from '../core/data/paginated-list';
|
||||||
import {getCommunityPageRoute} from '../+community-page/community-page-routing.module';
|
import {getCommunityPageRoute} from '../+community-page/community-page-routing.module';
|
||||||
import {getCollectionPageRoute} from '../+collection-page/collection-page-routing.module';
|
import {getCollectionPageRoute} from '../+collection-page/collection-page-routing.module';
|
||||||
|
import {CollectionDataService} from '../core/data/collection-data.service';
|
||||||
|
|
||||||
export interface FlatNode {
|
export interface FlatNode {
|
||||||
isExpandable: boolean;
|
isExpandable: boolean;
|
||||||
@@ -23,6 +24,8 @@ export interface FlatNode {
|
|||||||
payload: Community | Collection;
|
payload: Community | Collection;
|
||||||
isShowMoreNode: boolean;
|
isShowMoreNode: boolean;
|
||||||
route?: string;
|
route?: string;
|
||||||
|
currentCommunityPage?: number;
|
||||||
|
currentCollectionPage?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const combineAndFlatten = (obsList: Array<Observable<FlatNode[]>>): Observable<FlatNode[]> =>
|
export const combineAndFlatten = (obsList: Array<Observable<FlatNode[]>>): Observable<FlatNode[]> =>
|
||||||
@@ -66,37 +69,42 @@ export const showMoreFlatNode = (
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class CommunityListAdapter {
|
export class CommunityListAdapter {
|
||||||
|
|
||||||
payload$: Array<Observable<PaginatedList<Community>>>;
|
payloads$: Array<Observable<PaginatedList<Community>>>;
|
||||||
|
|
||||||
config: PaginationComponentOptions;
|
topCommunitiesConfig: PaginationComponentOptions;
|
||||||
sortConfig: SortOptions;
|
topCommunitiesSortConfig: SortOptions;
|
||||||
|
|
||||||
constructor(private cds: CommunityDataService) {
|
maxSubCommunitiesPerPage: number;
|
||||||
this.config = new PaginationComponentOptions();
|
|
||||||
this.config.id = 'top-level-pagination';
|
constructor(private communityDataService: CommunityDataService, private collectionDataService: CollectionDataService) {
|
||||||
this.config.pageSize = 5;
|
this.topCommunitiesConfig = new PaginationComponentOptions();
|
||||||
this.config.currentPage = 1;
|
this.topCommunitiesConfig.id = 'top-level-pagination';
|
||||||
this.sortConfig = new SortOptions('dc.title', SortDirection.ASC);
|
this.topCommunitiesConfig.pageSize = 10;
|
||||||
|
this.topCommunitiesConfig.currentPage = 1;
|
||||||
|
this.topCommunitiesSortConfig = new SortOptions('dc.title', SortDirection.ASC);
|
||||||
this.initTopCommunityList()
|
this.initTopCommunityList()
|
||||||
|
|
||||||
|
this.maxSubCommunitiesPerPage = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
private initTopCommunityList(): void {
|
private initTopCommunityList(): void {
|
||||||
this.payload$ = [this.cds.findTop({
|
this.payloads$ = [this.communityDataService.findTop({
|
||||||
currentPage: this.config.currentPage,
|
currentPage: this.topCommunitiesConfig.currentPage,
|
||||||
elementsPerPage: this.config.pageSize,
|
elementsPerPage: this.topCommunitiesConfig.pageSize,
|
||||||
sort: {field: this.sortConfig.field, direction: this.sortConfig.direction}
|
sort: {field: this.topCommunitiesSortConfig.field, direction: this.topCommunitiesSortConfig.direction}
|
||||||
}).pipe(
|
}).pipe(
|
||||||
take(1),
|
take(1),
|
||||||
map((results) => results.payload),
|
map((results) => results.payload),
|
||||||
)];
|
)];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getNextPageTopCommunities(): void {
|
getNextPageTopCommunities(): void {
|
||||||
this.config.currentPage = this.config.currentPage + 1;
|
this.topCommunitiesConfig.currentPage = this.topCommunitiesConfig.currentPage + 1;
|
||||||
this.payload$ = [...this.payload$, this.cds.findTop({
|
this.payloads$ = [...this.payloads$, this.communityDataService.findTop({
|
||||||
currentPage: this.config.currentPage,
|
currentPage: this.topCommunitiesConfig.currentPage,
|
||||||
elementsPerPage: this.config.pageSize,
|
elementsPerPage: this.topCommunitiesConfig.pageSize,
|
||||||
sort: {field: this.sortConfig.field, direction: this.sortConfig.direction}
|
sort: {field: this.topCommunitiesSortConfig.field, direction: this.topCommunitiesSortConfig.direction}
|
||||||
}).pipe(
|
}).pipe(
|
||||||
take(1),
|
take(1),
|
||||||
map((results) => results.payload),
|
map((results) => results.payload),
|
||||||
@@ -104,7 +112,7 @@ export class CommunityListAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadCommunities(expandedNodes: FlatNode[]): Observable<FlatNode[]> {
|
loadCommunities(expandedNodes: FlatNode[]): Observable<FlatNode[]> {
|
||||||
const res = this.payload$.map((payload) => {
|
const res = this.payloads$.map((payload) => {
|
||||||
return payload.pipe(
|
return payload.pipe(
|
||||||
take(1),
|
take(1),
|
||||||
switchMap((result: PaginatedList<Community>) => {
|
switchMap((result: PaginatedList<Community>) => {
|
||||||
@@ -121,12 +129,16 @@ export class CommunityListAdapter {
|
|||||||
parent: FlatNode,
|
parent: FlatNode,
|
||||||
expandedNodes: FlatNode[]): Observable<FlatNode[]> {
|
expandedNodes: FlatNode[]): Observable<FlatNode[]> {
|
||||||
if (isNotEmpty(listOfPaginatedCommunities.page)) {
|
if (isNotEmpty(listOfPaginatedCommunities.page)) {
|
||||||
const isNotAllCommunities = (listOfPaginatedCommunities.totalElements > (listOfPaginatedCommunities.elementsPerPage * this.config.currentPage));
|
let currentPage = this.topCommunitiesConfig.currentPage;
|
||||||
|
if (isNotEmpty(parent)) {
|
||||||
|
currentPage = expandedNodes.find((node: FlatNode) => node.id === parent.id).currentCommunityPage;
|
||||||
|
}
|
||||||
|
const isNotAllCommunities = (listOfPaginatedCommunities.totalElements > (listOfPaginatedCommunities.elementsPerPage * currentPage));
|
||||||
let obsList = listOfPaginatedCommunities.page
|
let obsList = listOfPaginatedCommunities.page
|
||||||
.map((community: Community) =>
|
.map((community: Community) => {
|
||||||
this.transformCommunity(community, level, parent, expandedNodes));
|
return this.transformCommunity(community, level, parent, expandedNodes)
|
||||||
|
});
|
||||||
if (isNotAllCommunities && listOfPaginatedCommunities.currentPage > this.config.currentPage) {
|
if (isNotAllCommunities && listOfPaginatedCommunities.currentPage > currentPage) {
|
||||||
obsList = [...obsList, this.addPossibleShowMoreComunityFlatNode(level, parent)];
|
obsList = [...obsList, this.addPossibleShowMoreComunityFlatNode(level, parent)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,14 +159,25 @@ export class CommunityListAdapter {
|
|||||||
let obsList = [observableOf([communityFlatNode])];
|
let obsList = [observableOf([communityFlatNode])];
|
||||||
|
|
||||||
if (isExpanded) {
|
if (isExpanded) {
|
||||||
const subCommunityNodes$ = community.subcommunities.pipe(
|
const currentPage = expandedNodes.find((node: FlatNode) => node.id === community.id).currentCommunityPage;
|
||||||
filter((rd: RemoteData<PaginatedList<Community>>) => rd.hasSucceeded),
|
let subcoms$ = [];
|
||||||
take(1),
|
for (let i = 1; i <= currentPage ; i++) {
|
||||||
switchMap((rd: RemoteData<PaginatedList<Community>>) =>
|
const p = this.communityDataService.findSubCommunitiesPerParentCommunity(community.uuid,{elementsPerPage: this.maxSubCommunitiesPerPage, currentPage: i})
|
||||||
this.transformListOfCommunities(rd.payload, level + 1, communityFlatNode, expandedNodes))
|
.pipe(
|
||||||
);
|
filter((rd: RemoteData<PaginatedList<Community>>) => rd.hasSucceeded),
|
||||||
|
take(1),
|
||||||
|
switchMap((rd: RemoteData<PaginatedList<Community>>) =>
|
||||||
|
this.transformListOfCommunities(rd.payload, level + 1, communityFlatNode, expandedNodes))
|
||||||
|
|
||||||
obsList = [...obsList, subCommunityNodes$];
|
);
|
||||||
|
subcoms$ = [...subcoms$, p];
|
||||||
|
}
|
||||||
|
|
||||||
|
obsList = [...obsList, combineAndFlatten(subcoms$)];
|
||||||
|
|
||||||
|
// need to be authorized (logged in) to receive collections this way
|
||||||
|
// const cols = this.collectionDataService.getAuthorizedCollectionByCommunity(community.uuid,{elementsPerPage: 2});
|
||||||
|
// cols.pipe(take(1)).subscribe((val) => console.log('cols:', val));
|
||||||
|
|
||||||
const collectionNodes$ = community.collections.pipe(
|
const collectionNodes$ = community.collections.pipe(
|
||||||
filter((rd: RemoteData<PaginatedList<Collection>>) => rd.hasSucceeded),
|
filter((rd: RemoteData<PaginatedList<Collection>>) => rd.hasSucceeded),
|
||||||
|
@@ -4,10 +4,10 @@
|
|||||||
<cdk-tree-node *cdkTreeNodeDef="let node; when: isShowMore" cdkTreeNodePadding
|
<cdk-tree-node *cdkTreeNodeDef="let node; when: isShowMore" cdkTreeNodePadding
|
||||||
class="example-tree-node">
|
class="example-tree-node">
|
||||||
<div class="btn-group"
|
<div class="btn-group"
|
||||||
(click)="getNextPage()">
|
(click)="getNextPage(node)">
|
||||||
<button type="button" class="btn btn-default" cdkTreeNodeToggle
|
<button type="button" class="btn btn-default" cdkTreeNodeToggle
|
||||||
[attr.aria-label]="'toggle ' + node.name"
|
[attr.aria-label]="'toggle ' + node.name"
|
||||||
(click)="getNextPage()">
|
(click)="getNextPage(node)">
|
||||||
<span class="fa fa-plus"
|
<span class="fa fa-plus"
|
||||||
aria-hidden="true"></span>
|
aria-hidden="true"></span>
|
||||||
</button>
|
</button>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<h6 class="align-middle pt-2">
|
<h6 class="align-middle pt-2">
|
||||||
<a [routerLink]="node.route" class="lead">
|
<a [routerLink]="node.route" class="lead">
|
||||||
{{node.name}}
|
{{node.name}} {{node.id}}
|
||||||
</a>
|
</a>
|
||||||
</h6>
|
</h6>
|
||||||
</div>
|
</div>
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<h5 class="align-middle pt-2">
|
<h5 class="align-middle pt-2">
|
||||||
<a [routerLink]="node.route" class="lead">
|
<a [routerLink]="node.route" class="lead">
|
||||||
{{node.name}}
|
{{node.name}} {{node.id}}
|
||||||
</a>
|
</a>
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -2,6 +2,9 @@ import {Component, OnInit} from '@angular/core';
|
|||||||
import {CommunityListAdapter, FlatNode} from '../community-list-adapter';
|
import {CommunityListAdapter, FlatNode} from '../community-list-adapter';
|
||||||
import {CommunityListDatasource} from '../community-list-datasource';
|
import {CommunityListDatasource} from '../community-list-datasource';
|
||||||
import {FlatTreeControl} from '@angular/cdk/tree';
|
import {FlatTreeControl} from '@angular/cdk/tree';
|
||||||
|
import {Collection} from '../../core/shared/collection.model';
|
||||||
|
import {Community} from '../../core/shared/community.model';
|
||||||
|
import {isEmpty} from "../../shared/empty.util";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-community-list',
|
selector: 'ds-community-list',
|
||||||
@@ -42,13 +45,33 @@ export class CommunityListComponent implements OnInit {
|
|||||||
} else {
|
} else {
|
||||||
this.expandedNodes.push(node);
|
this.expandedNodes.push(node);
|
||||||
node.isExpanded = true;
|
node.isExpanded = true;
|
||||||
|
if (isEmpty(node.currentCollectionPage)) {
|
||||||
|
node.currentCollectionPage = 1;
|
||||||
|
}
|
||||||
|
if (isEmpty(node.currentCommunityPage)) {
|
||||||
|
node.currentCommunityPage = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.dataSource.loadCommunities(this.expandedNodes);
|
this.dataSource.loadCommunities(this.expandedNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
getNextPage(): void {
|
getNextPage(node: FlatNode): void {
|
||||||
this.communityListAdapter.getNextPageTopCommunities();
|
if (node.parent != null) {
|
||||||
this.dataSource.loadCommunities(this.expandedNodes);
|
if (node.parent.isExpandable) {
|
||||||
|
if (node.payload instanceof Collection) {
|
||||||
|
const parentNodeInExpandedNodes = this.expandedNodes.find((node2:FlatNode) => node.parent.id === node2.id);
|
||||||
|
parentNodeInExpandedNodes.currentCollectionPage++;
|
||||||
|
}
|
||||||
|
if (node.payload instanceof Community) {
|
||||||
|
const parentNodeInExpandedNodes = this.expandedNodes.find((node2:FlatNode) => node.parent.id === node2.id);
|
||||||
|
parentNodeInExpandedNodes.currentCommunityPage++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dataSource.loadCommunities(this.expandedNodes);
|
||||||
|
} else {
|
||||||
|
this.communityListAdapter.getNextPageTopCommunities();
|
||||||
|
this.dataSource.loadCommunities(this.expandedNodes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
|||||||
export class CommunityDataService extends ComColDataService<Community> {
|
export class CommunityDataService extends ComColDataService<Community> {
|
||||||
protected linkPath = 'communities';
|
protected linkPath = 'communities';
|
||||||
protected topLinkPath = 'communities/search/top';
|
protected topLinkPath = 'communities/search/top';
|
||||||
|
protected subcommunitiesLinkPath = 'communities/search/subCommunities';
|
||||||
protected cds = this;
|
protected cds = this;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -55,4 +56,19 @@ export class CommunityDataService extends ComColDataService<Community> {
|
|||||||
|
|
||||||
return this.rdbService.buildList<Community>(hrefObs) as Observable<RemoteData<PaginatedList<Community>>>;
|
return this.rdbService.buildList<Community>(hrefObs) as Observable<RemoteData<PaginatedList<Community>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findSubCommunitiesPerParentCommunity(parentCommunityUUID: string, options: FindAllOptions = {}): Observable<RemoteData<PaginatedList<Community>>> {
|
||||||
|
const hrefObs = this.getFindAllHref(options, this.subcommunitiesLinkPath + '?parent=' + parentCommunityUUID);
|
||||||
|
console.log('subcomurl', hrefObs.pipe(take(1)).subscribe((val) => console.log('subcomurl', val)));
|
||||||
|
|
||||||
|
hrefObs.pipe(
|
||||||
|
filter((href: string) => hasValue(href)),
|
||||||
|
take(1))
|
||||||
|
.subscribe((href: string) => {
|
||||||
|
const request = new FindAllRequest(this.requestService.generateRequestId(), href, options);
|
||||||
|
this.requestService.configure(request);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.rdbService.buildList<Community>(hrefObs) as Observable<RemoteData<PaginatedList<Community>>>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user