mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-3444] Site list displays only a certain number of sites. (#4368)
* add infinite scrolling to sites loading * add infinite scrolling to sites loading * add infinite scrolling to sites loading
This commit is contained in:
@@ -21,6 +21,9 @@
|
||||
"NO_LABEL": "No"
|
||||
}
|
||||
},
|
||||
"ADF_DROPDOWN": {
|
||||
"LOADING": "Loading..."
|
||||
},
|
||||
"ADF_CONFIRM_DIALOG": {
|
||||
"TITLE": "Confirm",
|
||||
"ACTION": "Do you want to proceed?",
|
||||
|
@@ -1,17 +1,20 @@
|
||||
<div id="site-dropdown-container" class="adf-site-dropdown-container">
|
||||
<mat-form-field>
|
||||
<mat-select
|
||||
#siteSelect
|
||||
data-automation-id="site-my-files-option"
|
||||
class="adf-site-dropdown-list-element"
|
||||
id="site-dropdown"
|
||||
placeholder="{{placeholder | translate}}"
|
||||
floatPlaceholder="never"
|
||||
data-automation-id="site-my-files-select"
|
||||
[(value)]="selected"
|
||||
(selectionChange)="selectedSite($event)">
|
||||
<mat-option *ngFor="let site of siteList?.list.entries" [value]="site">
|
||||
<mat-option *ngFor="let site of siteList?.list.entries;" [value]="site">
|
||||
{{ site.entry.title | translate}}
|
||||
</mat-option>
|
||||
<mat-option *ngIf="showLoading()" disabled="true" data-automation-id="site-loading">
|
||||
{{ 'ADF_DROPDOWN.LOADING' | translate}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
@@ -46,6 +46,106 @@ describe('DropdownSitesComponent', () => {
|
||||
|
||||
describe('Rendering tests', () => {
|
||||
|
||||
describe('Infinite Loading', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
siteService = TestBed.get(SitesService);
|
||||
fixture = TestBed.createComponent(DropdownSitesComponent);
|
||||
debug = fixture.debugElement;
|
||||
element = fixture.nativeElement;
|
||||
component = fixture.componentInstance;
|
||||
}));
|
||||
|
||||
it('Should show loading item if there are more itemes', async(() => {
|
||||
spyOn(siteService, 'getSites').and.returnValue(of({
|
||||
'list': {
|
||||
'pagination': {
|
||||
'count': 2,
|
||||
'hasMoreItems': true,
|
||||
'totalItems': 2,
|
||||
'skipCount': 0,
|
||||
'maxItems': 100
|
||||
},
|
||||
'entries': [
|
||||
{
|
||||
'entry': {
|
||||
'role': 'SiteManager',
|
||||
'visibility': 'PUBLIC',
|
||||
'guid': 'fake-1',
|
||||
'description': 'fake-test-site',
|
||||
'id': 'fake-test-site',
|
||||
'preset': 'site-dashboard',
|
||||
'title': 'fake-test-site'
|
||||
}
|
||||
},
|
||||
{
|
||||
'entry': {
|
||||
'role': 'SiteManager',
|
||||
'visibility': 'PUBLIC',
|
||||
'guid': 'fake-2',
|
||||
'description': 'This is a Sample Alfresco Team site.',
|
||||
'id': 'swsdp',
|
||||
'preset': 'site-dashboard',
|
||||
'title': 'fake-test-2'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('[data-automation-id="lsite-loading"]')).toBeDefined();
|
||||
});
|
||||
}));
|
||||
|
||||
it('Should not show loading item if there are more itemes', async(() => {
|
||||
spyOn(siteService, 'getSites').and.returnValue(of({
|
||||
'list': {
|
||||
'pagination': {
|
||||
'count': 2,
|
||||
'hasMoreItems': false,
|
||||
'totalItems': 2,
|
||||
'skipCount': 0,
|
||||
'maxItems': 100
|
||||
},
|
||||
'entries': [
|
||||
{
|
||||
'entry': {
|
||||
'role': 'SiteManager',
|
||||
'visibility': 'PUBLIC',
|
||||
'guid': 'fake-1',
|
||||
'description': 'fake-test-site',
|
||||
'id': 'fake-test-site',
|
||||
'preset': 'site-dashboard',
|
||||
'title': 'fake-test-site'
|
||||
}
|
||||
},
|
||||
{
|
||||
'entry': {
|
||||
'role': 'SiteManager',
|
||||
'visibility': 'PUBLIC',
|
||||
'guid': 'fake-2',
|
||||
'description': 'This is a Sample Alfresco Team site.',
|
||||
'id': 'swsdp',
|
||||
'preset': 'site-dashboard',
|
||||
'title': 'fake-test-2'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('[data-automation-id="lsite-loading"]')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('Sites', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
@@ -93,7 +193,7 @@ describe('DropdownSitesComponent', () => {
|
||||
}));
|
||||
|
||||
function openSelectBox() {
|
||||
const selectBox = debug.query(By.css(('[data-automation-id="site-my-files-select"] .mat-select-trigger')));
|
||||
const selectBox = debug.query(By.css(('[data-automation-id="site-my-files-option"] .mat-select-trigger')));
|
||||
selectBox.triggerEventHandler('click', null);
|
||||
}
|
||||
|
||||
|
@@ -15,9 +15,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { SitesService, LogService } from '@alfresco/adf-core';
|
||||
import { SitePaging, SiteEntry } from '@alfresco/js-api';
|
||||
import { MatSelect } from '@angular/material';
|
||||
|
||||
export enum Relations {
|
||||
Members = 'members',
|
||||
@@ -68,6 +69,15 @@ export class DropdownSitesComponent implements OnInit {
|
||||
@Output()
|
||||
change: EventEmitter<SiteEntry> = new EventEmitter();
|
||||
|
||||
@ViewChild('siteSelect')
|
||||
siteSelect: MatSelect;
|
||||
|
||||
private loading = true;
|
||||
private skipCount = 0;
|
||||
private readonly MAX_ITEMS = 50;
|
||||
private readonly ITEM_HEIGHT = 45;
|
||||
private readonly ITEM_HEIGHT_TO_WAIT_BEFORE_LOAD_NEXT = (this.ITEM_HEIGHT * (this.MAX_ITEMS / 2));
|
||||
|
||||
selected: SiteEntry = null;
|
||||
|
||||
public MY_FILES_VALUE = '-my-';
|
||||
@@ -77,22 +87,47 @@ export class DropdownSitesComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (!this.siteList) {
|
||||
this.setDefaultSiteList();
|
||||
this.siteSelect.openedChange.subscribe(() => {
|
||||
if (this.siteSelect.panelOpen) {
|
||||
this.siteSelect.panel.nativeElement.addEventListener('scroll', (event) => this.loadAllOnScroll(event));
|
||||
}
|
||||
});
|
||||
|
||||
if (!this.siteList) {
|
||||
this.loadSiteList();
|
||||
}
|
||||
}
|
||||
|
||||
loadAllOnScroll(event) {
|
||||
if (this.isInfiniteScrollingEnabled() && this.isScrollInNextFetchArea(event)) {
|
||||
this.loading = true;
|
||||
this.loadSiteList();
|
||||
}
|
||||
}
|
||||
|
||||
isScrollInNextFetchArea(event) {
|
||||
return event.target.scrollTop >= (event.target.scrollHeight - event.target.offsetHeight - this.ITEM_HEIGHT_TO_WAIT_BEFORE_LOAD_NEXT);
|
||||
}
|
||||
|
||||
selectedSite(event: any) {
|
||||
this.change.emit(event.value);
|
||||
}
|
||||
|
||||
private setDefaultSiteList() {
|
||||
let extendedOptions = null;
|
||||
private loadSiteList() {
|
||||
let extendedOptions: any = {
|
||||
skipCount: this.skipCount,
|
||||
maxItems: this.MAX_ITEMS
|
||||
};
|
||||
|
||||
this.skipCount += this.MAX_ITEMS;
|
||||
|
||||
if (this.relations) {
|
||||
extendedOptions = { relations: [this.relations] };
|
||||
extendedOptions.relations = [this.relations];
|
||||
}
|
||||
|
||||
this.sitesService.getSites(extendedOptions).subscribe((sitePaging: SitePaging) => {
|
||||
|
||||
if (!this.siteList) {
|
||||
this.siteList = this.relations === Relations.Members ? this.filteredResultsByMember(sitePaging) : sitePaging;
|
||||
|
||||
if (!this.hideMyFiles) {
|
||||
@@ -111,13 +146,30 @@ export class DropdownSitesComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
let siteList: SitePaging = this.relations === Relations.Members ? this.filteredResultsByMember(sitePaging) : sitePaging;
|
||||
|
||||
this.siteList.list.entries = this.siteList.list.entries.concat(siteList.list.entries);
|
||||
this.siteList.list.pagination = sitePaging.list.pagination;
|
||||
}
|
||||
|
||||
this.selected = this.siteList.list.entries.find((site: SiteEntry) => site.entry.id === this.value);
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
(error) => {
|
||||
this.logService.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
showLoading(): boolean {
|
||||
return this.loading && (this.siteList && this.siteList.list.pagination && this.siteList.list.pagination.hasMoreItems);
|
||||
}
|
||||
|
||||
isInfiniteScrollingEnabled(): boolean {
|
||||
return !this.loading && (this.siteList && this.siteList.list.pagination && this.siteList.list.pagination.hasMoreItems);
|
||||
}
|
||||
|
||||
private filteredResultsByMember(sites: SitePaging): SitePaging {
|
||||
const loggedUserName = this.sitesService.getEcmCurrentLoggedUserName();
|
||||
sites.list.entries = sites.list.entries.filter((site) => this.isCurrentUserMember(site, loggedUserName));
|
||||
|
Reference in New Issue
Block a user