mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-09-17 14:21:29 +00:00
Performance improvements (#1166)
#1166 * Update angular libs document-list: performance improvements caching ‘heavy’ cell evaluations (i.e. date pipe) code/test fixes document-list: performance improvements Removed ‘AfterViewChecked’ bottleneck as underlying data-table already does it. data-table: performance improvements
This commit is contained in:
committed by
Eugenio Romano
parent
0f563e38bb
commit
3ca2c28a41
@@ -1,5 +1,4 @@
|
|||||||
<div *ngIf="!fileShowed">
|
<div class="container">
|
||||||
<div class="container">
|
|
||||||
<alfresco-upload-drag-area
|
<alfresco-upload-drag-area
|
||||||
[currentFolderPath]="currentPath"
|
[currentFolderPath]="currentPath"
|
||||||
[versioning] = "versioning"
|
[versioning] = "versioning"
|
||||||
@@ -102,11 +101,11 @@
|
|||||||
[supportedPageSizes]="[5, 10, 15, 20]">
|
[supportedPageSizes]="[5, 10, 15, 20]">
|
||||||
</alfresco-pagination>
|
</alfresco-pagination>
|
||||||
</alfresco-upload-drag-area>
|
</alfresco-upload-drag-area>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<context-menu-holder></context-menu-holder>
|
<context-menu-holder></context-menu-holder>
|
||||||
|
|
||||||
<div class="p-10">
|
<div class="p-10">
|
||||||
<ul>
|
<ul>
|
||||||
<li>Current path: {{documentList.currentFolderPath}}</li>
|
<li>Current path: {{documentList.currentFolderPath}}</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -122,47 +121,47 @@
|
|||||||
<button (click)="fileDialog.toggleShowDialog()">Show/Hide File Dialog</button>
|
<button (click)="fileDialog.toggleShowDialog()">Show/Hide File Dialog</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<p style="width:250px;margin: 20px;">
|
<p style="width:250px;margin: 20px;">
|
||||||
<label for="switch-multiple-file" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label for="switch-multiple-file" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input type="checkbox" id="switch-multiple-file" class="mdl-switch__input" (change)="toggleMultipleFileUpload()" >
|
<input type="checkbox" id="switch-multiple-file" class="mdl-switch__input" (change)="toggleMultipleFileUpload()" >
|
||||||
<span class="mdl-switch__label">Multiple File Upload</span>
|
<span class="mdl-switch__label">Multiple File Upload</span>
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<p style="width:250px;margin: 20px;">
|
<p style="width:250px;margin: 20px;">
|
||||||
<label for="switch-folder-upload" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label for="switch-folder-upload" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input type="checkbox" id="switch-folder-upload" class="mdl-switch__input" (change)="toggleFolder()">
|
<input type="checkbox" id="switch-folder-upload" class="mdl-switch__input" (change)="toggleFolder()">
|
||||||
<span class="mdl-switch__label">Folder Upload</span>
|
<span class="mdl-switch__label">Folder Upload</span>
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p style="width:250px;margin: 20px;">
|
<p style="width:250px;margin: 20px;">
|
||||||
<label for="switch-accepted-file-type" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label for="switch-accepted-file-type" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input type="checkbox" id="switch-accepted-file-type" class="mdl-switch__input" (change)="toggleAcceptedFilesType()">
|
<input type="checkbox" id="switch-accepted-file-type" class="mdl-switch__input" (change)="toggleAcceptedFilesType()">
|
||||||
<span class="mdl-switch__label">Filter extension</span>
|
<span class="mdl-switch__label">Filter extension</span>
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p style="width:250px;margin: 20px;">
|
<p style="width:250px;margin: 20px;">
|
||||||
<label for="switch-versioning" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label for="switch-versioning" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input type="checkbox" id="switch-versioning" class="mdl-switch__input" (change)="toggleVersioning()">
|
<input type="checkbox" id="switch-versioning" class="mdl-switch__input" (change)="toggleVersioning()">
|
||||||
<span class="mdl-switch__label">Versioning</span>
|
<span class="mdl-switch__label">Versioning</span>
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h5>Upload</h5>
|
<h5>Upload</h5>
|
||||||
<br>
|
<br>
|
||||||
<div *ngIf="acceptedFilesTypeShow">
|
<div *ngIf="acceptedFilesTypeShow">
|
||||||
<label class="mdl-input__label">Extension accepted
|
<label class="mdl-input__label">Extension accepted
|
||||||
<input type="text" data-automation-id="accepted-files-type" [(ngModel)]="acceptedFilesType">
|
<input type="text" data-automation-id="accepted-files-type" [(ngModel)]="acceptedFilesType">
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!acceptedFilesTypeShow">
|
<div *ngIf="!acceptedFilesTypeShow">
|
||||||
<alfresco-upload-button data-automation-id="multiple-file-upload"
|
<alfresco-upload-button data-automation-id="multiple-file-upload"
|
||||||
[currentFolderPath]="currentPath"
|
[currentFolderPath]="currentPath"
|
||||||
[multipleFiles]="multipleFileUpload"
|
[multipleFiles]="multipleFileUpload"
|
||||||
@@ -171,8 +170,8 @@
|
|||||||
(onSuccess)="documentList.reload()">
|
(onSuccess)="documentList.reload()">
|
||||||
<div class="mdl-spinner mdl-js-spinner is-active"></div>
|
<div class="mdl-spinner mdl-js-spinner is-active"></div>
|
||||||
</alfresco-upload-button>
|
</alfresco-upload-button>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="acceptedFilesTypeShow">
|
<div *ngIf="acceptedFilesTypeShow">
|
||||||
<alfresco-upload-button data-automation-id="multiple-file-upload"
|
<alfresco-upload-button data-automation-id="multiple-file-upload"
|
||||||
[currentFolderPath]="currentPath"
|
[currentFolderPath]="currentPath"
|
||||||
acceptedFilesType="{{acceptedFilesType}}"
|
acceptedFilesType="{{acceptedFilesType}}"
|
||||||
@@ -182,9 +181,8 @@
|
|||||||
(onSuccess)="documentList.reload()">
|
(onSuccess)="documentList.reload()">
|
||||||
<div class="mdl-spinner mdl-js-spinner is-active"></div>
|
<div class="mdl-spinner mdl-js-spinner is-active"></div>
|
||||||
</alfresco-upload-button>
|
</alfresco-upload-button>
|
||||||
</div>
|
|
||||||
<file-uploading-dialog #fileDialog></file-uploading-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
|
<file-uploading-dialog #fileDialog></file-uploading-dialog>
|
||||||
|
|
||||||
<div *ngIf="fileShowed">
|
<div *ngIf="fileShowed">
|
||||||
<alfresco-viewer [(showViewer)]="fileShowed"
|
<alfresco-viewer [(showViewer)]="fileShowed"
|
||||||
|
@@ -16,7 +16,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
// import { enableProdMode } from '@angular/core';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
|
// enableProdMode();
|
||||||
const platform = platformBrowserDynamic();
|
const platform = platformBrowserDynamic();
|
||||||
platform.bootstrapModule(AppModule);
|
platform.bootstrapModule(AppModule);
|
||||||
|
@@ -53,23 +53,21 @@
|
|||||||
"alfresco"
|
"alfresco"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/common": "2.0.0",
|
"@angular/common": "~2.2.0",
|
||||||
"@angular/compiler": "2.0.0",
|
"@angular/compiler": "~2.2.0",
|
||||||
"@angular/core": "2.0.0",
|
"@angular/core": "~2.2.0",
|
||||||
"@angular/forms": "2.0.0",
|
"@angular/forms": "~2.2.0",
|
||||||
"@angular/http": "2.0.0",
|
"@angular/http": "~2.2.0",
|
||||||
"@angular/platform-browser": "2.0.0",
|
"@angular/platform-browser": "~2.2.0",
|
||||||
"@angular/platform-browser-dynamic": "2.0.0",
|
"@angular/platform-browser-dynamic": "~2.2.0",
|
||||||
"@angular/router": "3.0.0",
|
"@angular/router": "~3.2.0",
|
||||||
"@angular/upgrade": "2.0.0",
|
|
||||||
"@types/node": "^6.0.42",
|
"systemjs": "0.19.40",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
"reflect-metadata": "^0.1.3",
|
"reflect-metadata": "^0.1.8",
|
||||||
"rxjs": "5.0.0-beta.12",
|
"rxjs": "5.0.0-beta.12",
|
||||||
"systemjs": "0.19.27",
|
"zone.js": "^0.6.26",
|
||||||
"zone.js": "^0.6.23",
|
|
||||||
|
|
||||||
"rimraf": "2.5.2",
|
|
||||||
"material-design-icons": "2.2.3",
|
"material-design-icons": "2.2.3",
|
||||||
"material-design-lite": "1.2.1",
|
"material-design-lite": "1.2.1",
|
||||||
"ng2-translate": "2.5.0",
|
"ng2-translate": "2.5.0",
|
||||||
@@ -100,9 +98,11 @@
|
|||||||
"element.scrollintoviewifneeded-polyfill": "^1.0.1"
|
"element.scrollintoviewifneeded-polyfill": "^1.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^6.0.42",
|
||||||
"@types/core-js": "^0.9.32",
|
"@types/core-js": "^0.9.32",
|
||||||
"@types/jasmine": "^2.2.33",
|
"@types/jasmine": "^2.2.33",
|
||||||
"concurrently": "^2.2.0",
|
"concurrently": "^2.2.0",
|
||||||
|
"rimraf": "2.5.2",
|
||||||
"license-check": "1.1.5",
|
"license-check": "1.1.5",
|
||||||
"mime": "^1.3.4",
|
"mime": "^1.3.4",
|
||||||
"tslint": "3.15.1",
|
"tslint": "3.15.1",
|
||||||
|
@@ -172,13 +172,13 @@ describe('DataTable', () => {
|
|||||||
let handler = jasmine.createSpyObj('componentHandler', ['upgradeAllRegistered']);
|
let handler = jasmine.createSpyObj('componentHandler', ['upgradeAllRegistered']);
|
||||||
window['componentHandler'] = handler;
|
window['componentHandler'] = handler;
|
||||||
|
|
||||||
dataTable.ngAfterViewChecked();
|
dataTable.ngOnInit();
|
||||||
expect(handler.upgradeAllRegistered).toHaveBeenCalled();
|
expect(handler.upgradeAllRegistered).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should upgrade MDL components only when component handler present', () => {
|
it('should upgrade MDL components only when component handler present', () => {
|
||||||
expect(window['componentHandler']).toBeNull();
|
expect(window['componentHandler']).toBeNull();
|
||||||
dataTable.ngAfterViewChecked();
|
dataTable.ngOnInit();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should invert "select all" status', () => {
|
it('should invert "select all" status', () => {
|
||||||
|
@@ -15,16 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { Component, OnInit, Input, Output, EventEmitter, TemplateRef } from '@angular/core';
|
||||||
Component,
|
|
||||||
OnInit,
|
|
||||||
Input,
|
|
||||||
Output,
|
|
||||||
EventEmitter,
|
|
||||||
AfterViewChecked,
|
|
||||||
TemplateRef
|
|
||||||
} from '@angular/core';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DataTableAdapter,
|
DataTableAdapter,
|
||||||
DataRow,
|
DataRow,
|
||||||
@@ -42,7 +33,7 @@ declare var componentHandler;
|
|||||||
styleUrls: ['./datatable.component.css'],
|
styleUrls: ['./datatable.component.css'],
|
||||||
templateUrl: './datatable.component.html'
|
templateUrl: './datatable.component.html'
|
||||||
})
|
})
|
||||||
export class DataTableComponent implements OnInit, AfterViewChecked {
|
export class DataTableComponent implements OnInit {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
data: DataTableAdapter;
|
data: DataTableAdapter;
|
||||||
@@ -79,9 +70,7 @@ export class DataTableComponent implements OnInit, AfterViewChecked {
|
|||||||
if (!this.data) {
|
if (!this.data) {
|
||||||
this.data = new ObjectDataTableAdapter([], []);
|
this.data = new ObjectDataTableAdapter([], []);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewChecked() {
|
|
||||||
// workaround for MDL issues with dynamic components
|
// workaround for MDL issues with dynamic components
|
||||||
if (componentHandler) {
|
if (componentHandler) {
|
||||||
componentHandler.upgradeAllRegistered();
|
componentHandler.upgradeAllRegistered();
|
||||||
|
@@ -272,11 +272,6 @@ describe('DocumentList', () => {
|
|||||||
expect(documentList.executeContentAction).not.toHaveBeenCalled();
|
expect(documentList.executeContentAction).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should upgrade material design components', () => {
|
|
||||||
documentList.ngAfterViewChecked();
|
|
||||||
expect(componentHandler.upgradeAllRegistered).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should subscribe to context action handler', () => {
|
it('should subscribe to context action handler', () => {
|
||||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||||
spyOn(documentList, 'contextActionCallback').and.stub();
|
spyOn(documentList, 'contextActionCallback').and.stub();
|
||||||
|
@@ -22,7 +22,6 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
AfterContentInit,
|
AfterContentInit,
|
||||||
AfterViewChecked,
|
|
||||||
TemplateRef,
|
TemplateRef,
|
||||||
NgZone,
|
NgZone,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
@@ -41,15 +40,13 @@ import {
|
|||||||
ImageResolver
|
ImageResolver
|
||||||
} from './../data/share-datatable-adapter';
|
} from './../data/share-datatable-adapter';
|
||||||
|
|
||||||
declare var componentHandler;
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
moduleId: module.id,
|
moduleId: module.id,
|
||||||
selector: 'alfresco-document-list',
|
selector: 'alfresco-document-list',
|
||||||
styleUrls: ['./document-list.css'],
|
styleUrls: ['./document-list.css'],
|
||||||
templateUrl: './document-list.html'
|
templateUrl: './document-list.html'
|
||||||
})
|
})
|
||||||
export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit {
|
export class DocumentList implements OnInit, AfterContentInit {
|
||||||
|
|
||||||
static SINGLE_CLICK_NAVIGATION: string = 'click';
|
static SINGLE_CLICK_NAVIGATION: string = 'click';
|
||||||
static DOUBLE_CLICK_NAVIGATION: string = 'dblclick';
|
static DOUBLE_CLICK_NAVIGATION: string = 'dblclick';
|
||||||
@@ -196,16 +193,8 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewChecked() {
|
|
||||||
// workaround for MDL issues with dynamic components
|
|
||||||
if (componentHandler) {
|
|
||||||
componentHandler.upgradeAllRegistered();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isMobile(): boolean {
|
isMobile(): boolean {
|
||||||
return !!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
return !!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getNodeActions(node: MinimalNodeEntity): ContentActionModel[] {
|
getNodeActions(node: MinimalNodeEntity): ContentActionModel[] {
|
||||||
|
@@ -203,8 +203,8 @@ describe('ShareDataTableAdapter', () => {
|
|||||||
spyOn(console, 'error').and.stub();
|
spyOn(console, 'error').and.stub();
|
||||||
|
|
||||||
let value = adapter.getValue(row, col);
|
let value = adapter.getValue(row, col);
|
||||||
expect(value).toBe(dateValue);
|
expect(value).toBe('Error');
|
||||||
expect(console.error).toHaveBeenCalledWith(`Error parsing date ${value} to format ${col.format}`);
|
expect(console.error).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate fallback icon for a file thumbnail with unknown mime type', () => {
|
it('should generate fallback icon for a file thumbnail with unknown mime type', () => {
|
||||||
|
@@ -121,15 +121,21 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid
|
|||||||
if (!col) {
|
if (!col) {
|
||||||
throw new Error(this.ERR_COL_NOT_FOUND);
|
throw new Error(this.ERR_COL_NOT_FOUND);
|
||||||
}
|
}
|
||||||
let value = row.getValue(col.key);
|
let dataRow: ShareDataRow = <ShareDataRow> row;
|
||||||
|
let value: any = row.getValue(col.key);
|
||||||
|
if (dataRow.cache[col.key] !== undefined) {
|
||||||
|
return dataRow.cache[col.key];
|
||||||
|
}
|
||||||
|
|
||||||
if (col.type === 'date') {
|
if (col.type === 'date') {
|
||||||
let datePipe = new DatePipe('en-US');
|
let datePipe = new DatePipe('en-US');
|
||||||
let format = col.format || this.DEFAULT_DATE_FORMAT;
|
let format = col.format || this.DEFAULT_DATE_FORMAT;
|
||||||
try {
|
try {
|
||||||
return datePipe.transform(value, format);
|
let result = datePipe.transform(value, format);
|
||||||
|
return dataRow.cacheValue(col.key, result);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error parsing date ${value} to format ${format}`);
|
console.error(`Error parsing date ${value} to format ${format}`);
|
||||||
|
return 'Error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +180,7 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return dataRow.cacheValue(col.key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
getSorting(): DataSorting {
|
getSorting(): DataSorting {
|
||||||
@@ -308,6 +314,7 @@ export class ShareDataRow implements DataRow {
|
|||||||
|
|
||||||
static ERR_OBJECT_NOT_FOUND: string = 'Object source not found';
|
static ERR_OBJECT_NOT_FOUND: string = 'Object source not found';
|
||||||
|
|
||||||
|
cache: { [key: string]: any } = {};
|
||||||
isSelected: boolean = false;
|
isSelected: boolean = false;
|
||||||
|
|
||||||
get node(): NodeMinimalEntry {
|
get node(): NodeMinimalEntry {
|
||||||
@@ -320,7 +327,15 @@ export class ShareDataRow implements DataRow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheValue(key: string, value: any): any {
|
||||||
|
this.cache[key] = value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
getValue(key: string): any {
|
getValue(key: string): any {
|
||||||
|
if (this.cache[key] !== undefined) {
|
||||||
|
return this.cache[key];
|
||||||
|
}
|
||||||
return ObjectUtils.getValue(this.obj.entry, key);
|
return ObjectUtils.getValue(this.obj.entry, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user