mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-3930] fix infinite pagination (#4275)
* refactoring infinite pagination * fix lint * fix import reuqest pagination from core * fix failing unit test
This commit is contained in:
@@ -143,7 +143,7 @@ export class ContentNodeDialogService {
|
||||
actionName: action,
|
||||
currentFolderId: contentEntry.parentId,
|
||||
imageResolver: this.imageResolver.bind(this),
|
||||
rowFilter: this.rowFilter.bind(this, contentEntry.id),
|
||||
where: '(isFolder=true)',
|
||||
isSelectionValid: this.isCopyMoveSelectionValid.bind(this),
|
||||
excludeSiteContent: excludeSiteContent || ContentNodeDialogService.nonDocumentSiteContent,
|
||||
select: select
|
||||
@@ -186,7 +186,7 @@ export class ContentNodeDialogService {
|
||||
currentFolderId: contentEntry.id,
|
||||
imageResolver: this.imageResolver.bind(this),
|
||||
isSelectionValid: this.hasPermissionOnNodeFolder.bind(this),
|
||||
rowFilter: this.rowFilter.bind(this, contentEntry.id),
|
||||
where: '(isFolder=true)',
|
||||
select: select
|
||||
};
|
||||
|
||||
@@ -232,16 +232,6 @@ export class ContentNodeDialogService {
|
||||
return null;
|
||||
}
|
||||
|
||||
private rowFilter(currentNodeId: string, row: ShareDataRow): boolean {
|
||||
const node: Node = row.node.entry;
|
||||
|
||||
if (node.id === currentNodeId || node.isFile) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private isNodeFile(entry: Node): boolean {
|
||||
return entry.isFile;
|
||||
}
|
||||
|
@@ -56,7 +56,7 @@
|
||||
[adf-highlight]="searchTerm"
|
||||
adf-highlight-selector=".adf-name-location-cell-name"
|
||||
[showHeader]="false"
|
||||
[node]="nodes"
|
||||
[node]="nodePaging"
|
||||
[maxItems]="pageSize"
|
||||
[rowFilter]="_rowFilter"
|
||||
[imageResolver]="imageResolver"
|
||||
@@ -65,6 +65,7 @@
|
||||
[contextMenuActions]="false"
|
||||
[contentActions]="false"
|
||||
[allowDropFiles]="false"
|
||||
[where]="where"
|
||||
(folderChange)="onFolderChange()"
|
||||
(ready)="onFolderLoaded()"
|
||||
(node-dblclick)="onNodeDoubleClick($event)"
|
||||
|
@@ -517,7 +517,7 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
|
||||
it('should clear the search field, nodes and chosenNode when clicking on the X (clear) icon', () => {
|
||||
component.chosenNode = <Node> {};
|
||||
component.nodes = {
|
||||
component.nodePaging = {
|
||||
list: {
|
||||
entries: [{ entry: component.chosenNode }]
|
||||
}
|
||||
@@ -528,7 +528,7 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
component.clear();
|
||||
|
||||
expect(component.searchTerm).toBe('');
|
||||
expect(component.nodes).toEqual(null);
|
||||
expect(component.nodePaging).toEqual(null);
|
||||
expect(component.chosenNode).toBeNull();
|
||||
expect(component.showingSearchResults).toBeFalsy();
|
||||
});
|
||||
|
@@ -19,7 +19,7 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild, ViewEncapsul
|
||||
import { AlfrescoApiService, HighlightDirective, UserPreferencesService, PaginationModel } from '@alfresco/adf-core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Node, NodePaging, Pagination, SiteEntry, SitePaging } from '@alfresco/js-api';
|
||||
import { DocumentListComponent, PaginationStrategy } from '../document-list/components/document-list.component';
|
||||
import { DocumentListComponent } from '../document-list/components/document-list.component';
|
||||
import { RowFilter } from '../document-list/data/row-filter.model';
|
||||
import { ImageResolver } from '../document-list/data/image-resolver.model';
|
||||
import { ContentNodeSelectorService } from './content-node-selector.service';
|
||||
@@ -62,6 +62,13 @@ export class ContentNodeSelectorPanelComponent implements OnInit {
|
||||
|
||||
_rowFilter: RowFilter = defaultValidation;
|
||||
|
||||
/** Custom where filter function. See the
|
||||
* [Document List component](document-list.component.md)
|
||||
* for more information.
|
||||
*/
|
||||
@Input()
|
||||
where: string;
|
||||
|
||||
/** Custom row filter function. See the
|
||||
* [Document List component](document-list.component.md#custom-row-filter)
|
||||
* for more information.
|
||||
@@ -125,7 +132,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit {
|
||||
@ViewChild(HighlightDirective)
|
||||
highlighter: HighlightDirective;
|
||||
|
||||
nodes: NodePaging | null = null;
|
||||
nodePaging: NodePaging | null = null;
|
||||
siteId: null | string;
|
||||
searchTerm: string = '';
|
||||
showingSearchResults: boolean = false;
|
||||
@@ -133,7 +140,6 @@ export class ContentNodeSelectorPanelComponent implements OnInit {
|
||||
inDialog: boolean = false;
|
||||
_chosenNode: Node = null;
|
||||
folderIdToShow: string | null = null;
|
||||
paginationStrategy: PaginationStrategy = PaginationStrategy.Infinite;
|
||||
pagination: BehaviorSubject<PaginationModel>;
|
||||
|
||||
skipCount: number = 0;
|
||||
@@ -255,7 +261,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit {
|
||||
*/
|
||||
clearSearch() {
|
||||
this.searchTerm = '';
|
||||
this.nodes = null;
|
||||
this.nodePaging = null;
|
||||
this.skipCount = 0;
|
||||
this.chosenNode = null;
|
||||
this.showingSearchResults = false;
|
||||
@@ -276,7 +282,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit {
|
||||
* Load the first page of a new search result
|
||||
*/
|
||||
private startNewSearch(): void {
|
||||
this.nodes = null;
|
||||
this.nodePaging = null;
|
||||
this.skipCount = 0;
|
||||
this.chosenNode = null;
|
||||
this.folderIdToShow = null;
|
||||
@@ -313,14 +319,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit {
|
||||
this.showingSearchResults = true;
|
||||
this.loadingSearchResults = false;
|
||||
|
||||
// DocumentList hack, since data displaying for preloaded nodes is a little bit messy there
|
||||
if (!this.nodes) {
|
||||
this.nodes = nodePaging;
|
||||
} else {
|
||||
this.documentList.data.loadPage(nodePaging, true);
|
||||
}
|
||||
|
||||
this.pagination.next(nodePaging.list.pagination);
|
||||
this.nodePaging = nodePaging;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -25,6 +25,7 @@ export interface ContentNodeSelectorComponentData {
|
||||
dropdownHideMyFiles?: boolean;
|
||||
dropdownSiteList?: SitePaging;
|
||||
rowFilter?: any;
|
||||
where?: string;
|
||||
imageResolver?: any;
|
||||
isSelectionValid?: (entry: Node) => boolean;
|
||||
breadcrumbTransform?: (node) => any;
|
||||
|
@@ -13,6 +13,7 @@
|
||||
[isSelectionValid]="data?.isSelectionValid"
|
||||
[breadcrumbTransform]="data?.breadcrumbTransform"
|
||||
[excludeSiteContent]="data?.excludeSiteContent"
|
||||
[where]="data?.where"
|
||||
(select)="onSelect($event)">
|
||||
</adf-content-node-selector-panel>
|
||||
</mat-dialog-content>
|
||||
@@ -30,4 +31,4 @@
|
||||
(click)="onClick()"
|
||||
data-automation-id="content-node-selector-actions-choose">{{ buttonActionName | translate }}
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
</mat-dialog-actions>
|
||||
|
@@ -48,13 +48,13 @@ export class NodeSharedDirective implements OnChanges {
|
||||
|
||||
constructor(private dialog: MatDialog, private zone: NgZone) {}
|
||||
|
||||
shareNode(node: NodeEntry) {
|
||||
if (node && node.entry && node.entry.isFile) {
|
||||
shareNode(nodeEntry: NodeEntry) {
|
||||
if (nodeEntry && nodeEntry.entry && nodeEntry.entry.isFile) {
|
||||
this.dialog.open(ShareDialogComponent, {
|
||||
width: '600px',
|
||||
panelClass: 'adf-share-link-dialog',
|
||||
data: {
|
||||
node: node,
|
||||
node: nodeEntry,
|
||||
baseShareUrl: this.baseShareUrl
|
||||
}
|
||||
});
|
||||
@@ -63,7 +63,7 @@ export class NodeSharedDirective implements OnChanges {
|
||||
|
||||
ngOnChanges() {
|
||||
this.zone.onStable.subscribe(() => {
|
||||
if (this.node) {
|
||||
if (this.node && this.node.entry) {
|
||||
this.isFile = this.node.entry.isFile;
|
||||
this.isShared = this.node.entry.properties['qshare:sharedId'];
|
||||
}
|
||||
|
@@ -1269,6 +1269,24 @@ describe('DocumentList', () => {
|
||||
documentList.ngOnChanges({ currentFolderId: new SimpleChange(null, '-root-', false) });
|
||||
|
||||
expect(documentListService.getFolder).toHaveBeenCalledWith(null, {
|
||||
where: undefined,
|
||||
maxItems: 25,
|
||||
skipCount: 0,
|
||||
rootFolderId: 'fake-id'
|
||||
}, ['test-include']);
|
||||
});
|
||||
|
||||
it('should add where in the server request when present', () => {
|
||||
fixture.detectChanges();
|
||||
documentList.currentFolderId = 'fake-id';
|
||||
documentList.includeFields = ['test-include'];
|
||||
documentList.where = '(isFolder=true)';
|
||||
spyOn(documentListService, 'getFolder').and.callThrough();
|
||||
|
||||
documentList.ngOnChanges({ currentFolderId: new SimpleChange(null, '-root-', false) });
|
||||
|
||||
expect(documentListService.getFolder).toHaveBeenCalledWith(null, {
|
||||
where: '(isFolder=true)',
|
||||
maxItems: 25,
|
||||
skipCount: 0,
|
||||
rootFolderId: 'fake-id'
|
||||
|
@@ -39,7 +39,8 @@ import {
|
||||
ThumbnailService,
|
||||
CustomLoadingContentTemplateDirective,
|
||||
CustomNoPermissionTemplateDirective,
|
||||
CustomEmptyContentTemplateDirective
|
||||
CustomEmptyContentTemplateDirective,
|
||||
RequestPaginationModel
|
||||
} from '@alfresco/adf-core';
|
||||
|
||||
import { Node, NodeEntry, NodePaging } from '@alfresco/js-api';
|
||||
@@ -88,6 +89,10 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
@Input()
|
||||
includeFields: string[];
|
||||
|
||||
/** filter the Node list using the where condition of the rest api for example (isFolder=true) see the rest api documentation for more information. */
|
||||
@Input()
|
||||
where: string;
|
||||
|
||||
/** Change the display mode of the table. Can be "list" or "gallery". */
|
||||
@Input()
|
||||
display: string = DisplayMode.List;
|
||||
@@ -260,7 +265,9 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
// @deprecated 3.0.0
|
||||
folderNode: Node;
|
||||
|
||||
private _pagination: BehaviorSubject<PaginationModel>;
|
||||
private _pagination: PaginationModel;
|
||||
private $pagination: BehaviorSubject<PaginationModel>;
|
||||
|
||||
private layoutPresets = {};
|
||||
private subscriptions: Subscription[] = [];
|
||||
private rowMenuCache: { [key: string]: ContentActionModel[] } = {};
|
||||
@@ -274,6 +281,13 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
private customResourcesService: CustomResourcesService,
|
||||
private contentService: ContentService,
|
||||
private thumbnailService: ThumbnailService) {
|
||||
|
||||
this._pagination = <PaginationModel> {
|
||||
maxItems: this.maxItems || this.preferences.paginationSize,
|
||||
skipCount: 0,
|
||||
totalItems: 0,
|
||||
hasMoreItems: false
|
||||
};
|
||||
}
|
||||
|
||||
getContextActions(node: NodeEntry) {
|
||||
@@ -310,17 +324,10 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
}
|
||||
|
||||
get pagination(): BehaviorSubject<PaginationModel> {
|
||||
if (!this._pagination) {
|
||||
let maxItems = this.maxItems || this.preferences.paginationSize;
|
||||
let defaultPagination = <PaginationModel> {
|
||||
maxItems: maxItems,
|
||||
skipCount: 0,
|
||||
totalItems: 0,
|
||||
hasMoreItems: false
|
||||
};
|
||||
this._pagination = new BehaviorSubject<PaginationModel>(defaultPagination);
|
||||
if (!this.$pagination) {
|
||||
this.$pagination = new BehaviorSubject<PaginationModel>(this._pagination);
|
||||
}
|
||||
return this._pagination;
|
||||
return this.$pagination;
|
||||
}
|
||||
|
||||
isMobile(): boolean {
|
||||
@@ -412,7 +419,9 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
this.loadFolder();
|
||||
} else if (this.data) {
|
||||
if (changes.node && changes.node.currentValue) {
|
||||
this.data.loadPage(changes.node.currentValue);
|
||||
let merge = this._pagination ? this._pagination.merge : false;
|
||||
|
||||
this.data.loadPage(changes.node.currentValue, merge);
|
||||
this.onDataReady(changes.node.currentValue);
|
||||
} else if (changes.imageResolver) {
|
||||
this.data.setImageResolver(changes.imageResolver.currentValue);
|
||||
@@ -424,7 +433,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
this.ngZone.run(() => {
|
||||
this.resetSelection();
|
||||
if (this.node) {
|
||||
this.data.loadPage(this.node, this.pagination.getValue().merge);
|
||||
this.data.loadPage(this.node, this._pagination.merge);
|
||||
this.onDataReady(this.node);
|
||||
} else {
|
||||
this.loadFolder();
|
||||
@@ -579,7 +588,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
}
|
||||
|
||||
loadFolder() {
|
||||
if (!this.pagination.getValue().merge) {
|
||||
if (!this._pagination.merge) {
|
||||
this.setLoadingState(true);
|
||||
}
|
||||
|
||||
@@ -593,33 +602,36 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
loadFolderByNodeId(nodeId: string) {
|
||||
if (this.customResourcesService.isCustomSource(nodeId)) {
|
||||
this.updateCustomSourceData(nodeId);
|
||||
this.customResourcesService.loadFolderByNodeId(nodeId, this.pagination.getValue(), this.includeFields)
|
||||
.subscribe((page: NodePaging) => {
|
||||
this.onPageLoaded(page);
|
||||
this.customResourcesService.loadFolderByNodeId(nodeId, this._pagination, this.includeFields)
|
||||
.subscribe((nodePaging: NodePaging) => {
|
||||
this.onPageLoaded(nodePaging);
|
||||
}, (err) => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
} else {
|
||||
let pagination = this.pagination.getValue();
|
||||
|
||||
this.documentListService.getFolder(null, {
|
||||
maxItems: pagination.maxItems,
|
||||
skipCount: pagination.skipCount,
|
||||
rootFolderId: nodeId
|
||||
maxItems: this._pagination.maxItems,
|
||||
skipCount: this._pagination.skipCount,
|
||||
rootFolderId: nodeId,
|
||||
where: this.where
|
||||
}, this.includeFields)
|
||||
.subscribe((nodePaging: NodePaging) => {
|
||||
this.data.loadPage(nodePaging, this.pagination.getValue().merge);
|
||||
this.setLoadingState(false);
|
||||
this.onDataReady(nodePaging);
|
||||
this.documentListService.getFolderNode(nodeId, this.includeFields).subscribe((nodeEntry: NodeEntry) => {
|
||||
this.folderNode = nodeEntry.entry;
|
||||
this.$folderNode.next(this.folderNode);
|
||||
});
|
||||
this.onPageLoaded(nodePaging);
|
||||
this.getSourceNodeWithPath(nodeId);
|
||||
}, (err) => {
|
||||
this.handleError(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getSourceNodeWithPath(nodeId: string) {
|
||||
this.documentListService.getFolderNode(nodeId, this.includeFields).subscribe((nodeEntry: NodeEntry) => {
|
||||
this.folderNode = nodeEntry.entry;
|
||||
this.$folderNode.next(this.folderNode);
|
||||
});
|
||||
}
|
||||
|
||||
resetSelection() {
|
||||
this.dataTable.resetSelection();
|
||||
this.selection = [];
|
||||
@@ -628,7 +640,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
|
||||
onPageLoaded(nodePaging: NodePaging) {
|
||||
if (nodePaging) {
|
||||
this.data.loadPage(nodePaging, this.pagination.getValue().merge);
|
||||
this.data.loadPage(nodePaging, this._pagination.merge);
|
||||
this.setLoadingState(false);
|
||||
this.onDataReady(nodePaging);
|
||||
}
|
||||
@@ -787,12 +799,13 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
||||
|
||||
private onDataReady(nodePaging: NodePaging) {
|
||||
this.ready.emit(nodePaging);
|
||||
|
||||
this.pagination.next(nodePaging.list.pagination);
|
||||
}
|
||||
|
||||
updatePagination(pagination: PaginationModel) {
|
||||
this.pagination.next(pagination);
|
||||
updatePagination(requestPaginationModel: RequestPaginationModel) {
|
||||
this._pagination.maxItems = requestPaginationModel.maxItems;
|
||||
this._pagination.merge = requestPaginationModel.merge;
|
||||
this._pagination.skipCount = requestPaginationModel.skipCount;
|
||||
this.reload();
|
||||
}
|
||||
|
||||
|
@@ -245,11 +245,11 @@ export class ShareDataTableAdapter implements DataTableAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
public loadPage(page: NodePaging, merge: boolean = false) {
|
||||
public loadPage(nodePaging: NodePaging, merge: boolean = false) {
|
||||
let shareDataRows: ShareDataRow[] = [];
|
||||
|
||||
if (page && page.list) {
|
||||
let nodeEntries: NodeEntry[] = page.list.entries;
|
||||
if (nodePaging && nodePaging.list) {
|
||||
let nodeEntries: NodeEntry[] = nodePaging.list.entries;
|
||||
if (nodeEntries && nodeEntries.length > 0) {
|
||||
shareDataRows = nodeEntries.map((item) => new ShareDataRow(item, this.contentService, this.permissionsStyle, this.thumbnailService));
|
||||
|
||||
|
@@ -105,6 +105,9 @@ export class DocumentListService {
|
||||
if (opts.skipCount) {
|
||||
params.skipCount = opts.skipCount;
|
||||
}
|
||||
if (opts.where) {
|
||||
params.where = opts.where;
|
||||
}
|
||||
}
|
||||
|
||||
return from(this.apiService.getInstance().nodes.getNodeChildren(rootNodeId, params)).pipe(
|
||||
|
Reference in New Issue
Block a user