From da18a21e7c3ea123a61a4e6ecb7f0b0d298f67e6 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 22 May 2017 15:46:54 +0100 Subject: [PATCH] [ADF-551] sorting for document list (#1891) * table cell component - table cell component with performance improvements * permissions and sorting fixes - fixed ability to set default sorting - fixed permission evaluation - new: context menu now also works with permissions - disabled tags column in demo shell due to performance implications * fix unit tests * fix tsconfig for unit testing --- .../app/components/files/files.component.html | 3 ++ demo-shell-ng2/tsconfig.json | 3 -- .../ng2-activiti-analytics/tsconfig.json | 3 -- .../ng2-activiti-diagrams/tsconfig.json | 3 -- .../ng2-activiti-form/tsconfig.json | 3 -- .../ng2-activiti-processlist/tsconfig.json | 3 -- .../ng2-activiti-tasklist/tsconfig.json | 3 -- .../context-menu-holder.component.ts | 14 +++++- .../ng2-alfresco-core/tsconfig.json | 3 -- .../ng2-alfresco-datatable/index.ts | 2 + .../datatable/datatable-cell.component.ts | 48 +++++++++++++++++++ .../datatable/datatable.component.html | 6 +-- .../datatable/datatable.component.spec.ts | 6 ++- .../datatable/datatable.component.ts | 2 +- .../src/components/datatable/index.ts | 1 + .../ng2-alfresco-datatable/tsconfig.json | 3 -- .../content-action.component.ts | 6 ++- .../content-column-list.component.spec.ts | 2 + .../content-column.component.spec.ts | 2 + .../document-list.component.spec.ts | 4 +- .../src/components/document-list.component.ts | 48 ++++++++----------- .../src/data/share-datatable-adapter.ts | 4 +- .../src/models/content-action.model.ts | 5 +- .../ng2-alfresco-documentlist/tsconfig.json | 3 -- .../ng2-alfresco-login/tsconfig.json | 3 -- .../ng2-alfresco-search/tsconfig.json | 3 -- .../ng2-alfresco-social/tsconfig.json | 3 -- ng2-components/ng2-alfresco-tag/tsconfig.json | 3 -- .../ng2-alfresco-upload/tsconfig.json | 3 -- .../ng2-alfresco-userinfo/tsconfig.json | 3 -- .../ng2-alfresco-viewer/tsconfig.json | 3 -- .../ng2-alfresco-webscript/tsconfig.json | 3 -- 32 files changed, 112 insertions(+), 92 deletions(-) create mode 100644 ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable-cell.component.ts diff --git a/demo-shell-ng2/app/components/files/files.component.html b/demo-shell-ng2/app/components/files/files.component.html index e07602fd09..5787f84ba3 100644 --- a/demo-shell-ng2/app/components/files/files.component.html +++ b/demo-shell-ng2/app/components/files/files.component.html @@ -45,6 +45,8 @@ --> + + @@ -82,6 +85,15 @@ export class ContextMenuHolderComponent { this.isShown = false; } + onMenuItemClick(event: Event, menuItem: any): void { + if (menuItem && menuItem.model && menuItem.model.disabled) { + event.preventDefault(); + event.stopImmediatePropagation(); + return; + } + menuItem.subject.next(menuItem); + } + showMenu(e, links) { this.isShown = true; this.links = links; diff --git a/ng2-components/ng2-alfresco-core/tsconfig.json b/ng2-components/ng2-alfresco-core/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-core/tsconfig.json +++ b/ng2-components/ng2-alfresco-core/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-datatable/index.ts b/ng2-components/ng2-alfresco-datatable/index.ts index 6e3c447446..4ebed2eb97 100644 --- a/ng2-components/ng2-alfresco-datatable/index.ts +++ b/ng2-components/ng2-alfresco-datatable/index.ts @@ -27,9 +27,11 @@ export * from './src/components/datatable/data-row-action.event'; import { DataTableComponent } from './src/components/datatable/datatable.component'; import { NoContentTemplateComponent } from './src/components/datatable/no-content-template.component'; import { PaginationComponent } from './src/components/pagination/pagination.component'; +import { DataTableCellComponent } from './src/components/datatable/datatable-cell.component'; export const ALFRESCO_DATATABLE_DIRECTIVES: [any] = [ DataTableComponent, + DataTableCellComponent, NoContentTemplateComponent, PaginationComponent ]; diff --git a/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable-cell.component.ts b/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable-cell.component.ts new file mode 100644 index 0000000000..d03020274c --- /dev/null +++ b/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable-cell.component.ts @@ -0,0 +1,48 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; +import { DataTableAdapter, DataColumn, DataRow } from '../../data/index'; + +@Component({ + selector: 'alfresco-datatable-cell', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '{{value}}' +}) +export class DataTableCellComponent { + + @Input() + data: DataTableAdapter; + + @Input() + column: DataColumn; + + @Input() + row: DataRow; + + @Input() + value: any; + + constructor() { } + + ngOnInit() { + if (this.column && this.column.key && this.row && this.data) { + this.value = this.data.getValue(this.row, this.column); + } + } + +} diff --git a/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.html b/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.html index db3f470479..b3894ed078 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.html +++ b/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.html @@ -70,10 +70,10 @@ (error)="onImageLoadingError($event)">
- {{data.getValue(row, col)}} +
- {{data.getValue(row, col)}} +
@@ -95,7 +95,7 @@
    -
  • diff --git a/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.spec.ts b/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.spec.ts index 1211e0f2ce..d6694b778f 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.spec.ts +++ b/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.spec.ts @@ -20,6 +20,7 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { CoreModule } from 'ng2-alfresco-core'; import { MdCheckboxChange } from '@angular/material'; import { DataTableComponent } from './datatable.component'; +import { DataTableCellComponent } from './datatable-cell.component'; import { DataRow, DataColumn, @@ -40,7 +41,10 @@ describe('DataTable', () => { imports: [ CoreModule.forRoot() ], - declarations: [DataTableComponent] + declarations: [ + DataTableCellComponent, + DataTableComponent + ] }).compileComponents(); })); diff --git a/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.ts b/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.ts index b88c61eddf..d9130df2b2 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.ts +++ b/ng2-components/ng2-alfresco-datatable/src/components/datatable/datatable.component.ts @@ -258,7 +258,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges { } onExecuteRowAction(row: DataRow, action: any) { - if (action.disabled) { + if (action.disabled || action.disabled) { event.stopPropagation(); } else { this.executeRowAction.emit(new DataRowActionEvent(row, action)); diff --git a/ng2-components/ng2-alfresco-datatable/src/components/datatable/index.ts b/ng2-components/ng2-alfresco-datatable/src/components/datatable/index.ts index 37153cd18f..0e872f6241 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/datatable/index.ts +++ b/ng2-components/ng2-alfresco-datatable/src/components/datatable/index.ts @@ -17,3 +17,4 @@ export * from './datatable.component'; export * from './no-content-template.component'; +export * from './datatable-cell.component'; diff --git a/ng2-components/ng2-alfresco-datatable/tsconfig.json b/ng2-components/ng2-alfresco-datatable/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-datatable/tsconfig.json +++ b/ng2-components/ng2-alfresco-datatable/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/content-action/content-action.component.ts b/ng2-components/ng2-alfresco-documentlist/src/components/content-action/content-action.component.ts index 07cf03f0d0..017e295c59 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/content-action/content-action.component.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/content-action/content-action.component.ts @@ -47,6 +47,9 @@ export class ContentActionComponent implements OnInit, OnChanges { @Input() disableWithNoPermission: boolean; + @Input() + disabled: boolean = false; + @Output() execute = new EventEmitter(); @@ -68,7 +71,8 @@ export class ContentActionComponent implements OnInit, OnChanges { icon: this.icon, permission: this.permission, disableWithNoPermission: this.disableWithNoPermission, - target: this.target + target: this.target, + disabled: this.disabled }); if (this.handler) { diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/content-column/content-column-list.component.spec.ts b/ng2-components/ng2-alfresco-documentlist/src/components/content-column/content-column-list.component.spec.ts index 3cccfcebc2..8827f8d124 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/content-column/content-column-list.component.spec.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/content-column/content-column-list.component.spec.ts @@ -30,6 +30,8 @@ describe('ContentColumnList', () => { let service = new DocumentListServiceMock(); documentList = new DocumentListComponent(service, null, null, null); columnList = new ContentColumnListComponent(documentList); + + documentList.ngOnInit(); }); it('should register column within parent document list', () => { diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/content-column/content-column.component.spec.ts b/ng2-components/ng2-alfresco-documentlist/src/components/content-column/content-column.component.spec.ts index e06c860619..1f8d05e04c 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/content-column/content-column.component.spec.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/content-column/content-column.component.spec.ts @@ -29,6 +29,8 @@ describe('ContentColumn', () => { let service = new DocumentListServiceMock(); documentList = new DocumentListComponent(service, null, null, null); columnList = new ContentColumnListComponent(documentList); + + documentList.ngOnInit(); }); it('should register model within parent column list', () => { diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts index 0a89e5daed..31db4c803e 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts @@ -157,11 +157,11 @@ describe('DocumentList', () => { let actions = documentList.getNodeActions(new FolderNode()); expect(actions.length).toBe(1); - expect(actions[0]).toBe(folderMenu); + expect(actions[0].target).toBe(folderMenu.target); actions = documentList.getNodeActions(new FileNode()); expect(actions.length).toBe(1); - expect(actions[0]).toBe(documentMenu); + expect(actions[0].target).toBe(documentMenu.target); }); it('should disable the action if there is no permission for the file and disableWithNoPermission true', () => { diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts index 0917888c41..5416dd916e 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts @@ -28,7 +28,8 @@ import { ObjectDataColumn, DataCellEvent, DataRowActionEvent, - DataColumn + DataColumn, + DataSorting } from 'ng2-alfresco-datatable'; import { DocumentListService } from './../services/document-list.service'; import { ContentActionModel } from './../models/content-action.model'; @@ -156,8 +157,6 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni private translateService: AlfrescoTranslationService, private el: ElementRef) { - this.data = new ShareDataTableAdapter(this.documentListService); - if (translateService) { translateService.addTranslationFolder('ng2-alfresco-documentlist', 'node_modules/ng2-alfresco-documentlist/src'); } @@ -186,6 +185,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni } ngOnInit() { + this.data = new ShareDataTableAdapter(this.documentListService, null, this.getDefaultSorting()); this.data.thumbnails = this.thumbnails; this.contextActionHandler.subscribe(val => this.contextActionCallback(val)); @@ -200,7 +200,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni } if (!this.data) { - this.data = new ShareDataTableAdapter(this.documentListService, schema); + this.data = new ShareDataTableAdapter(this.documentListService, schema, this.getDefaultSorting()); } else if (schema && schema.length > 0) { this.data.setColumns(schema); } @@ -209,18 +209,6 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni if (!columns || columns.length === 0) { this.setupDefaultColumns(); } - - // TODO: commented out as Permissions feature (Context Menus and Row Actions) breaks all component functionality - /* - if (this.sorting) { - const [ key, direction ] = this.sorting; - - this.data.setSorting({ - key, - direction: direction || 'asc' - }); - } - */ } ngOnChanges(changes: SimpleChanges) { @@ -294,28 +282,21 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni if (target) { let ltarget = target.toLowerCase(); - let actionWithPermission = this.checkPermissions(node); - - let actionsByTarget = actionWithPermission.filter(entry => { + let actionsByTarget = this.actions.filter(entry => { return entry.target.toLowerCase() === ltarget; + }).map(action => new ContentActionModel(action)); + + actionsByTarget.forEach((action) => { + this.checkPermission(node, action); }); - let cloneActions = Object.create(actionsByTarget); - return cloneActions; + return actionsByTarget; } } return []; } - checkPermissions(node: MinimalNodeEntity): ContentActionModel[] { - let actionsPermission: ContentActionModel[] = []; - this.actions.forEach((action) => { - actionsPermission.push(this.checkPermission(node, action)); - }); - return actionsPermission; - } - checkPermission(node: any, action: ContentActionModel): ContentActionModel { if (action.permission) { if (this.hasPermissions(node)) { @@ -562,4 +543,13 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni this.navigationMode = DocumentListComponent.SINGLE_CLICK_NAVIGATION; } } + + private getDefaultSorting(): DataSorting { + let defaultSorting: DataSorting; + if (this.sorting) { + const [ key, direction ] = this.sorting; + defaultSorting = new DataSorting(key, direction); + } + return defaultSorting; + } } diff --git a/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts b/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts index 47a6982c8c..4daad2b849 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts @@ -41,9 +41,11 @@ export class ShareDataTableAdapter implements DataTableAdapter { selectedRow: DataRow; constructor(private documentListService: DocumentListService, - schema: DataColumn[] = []) { + schema: DataColumn[] = [], + sorting?: DataSorting) { this.rows = []; this.columns = schema || []; + this.sorting = sorting; } getRows(): Array { diff --git a/ng2-components/ng2-alfresco-documentlist/src/models/content-action.model.ts b/ng2-components/ng2-alfresco-documentlist/src/models/content-action.model.ts index e8523bf156..46a293b021 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/models/content-action.model.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/models/content-action.model.ts @@ -21,8 +21,8 @@ export class ContentActionModel { handler: ContentActionHandler; target: string; permission: string; - disableWithNoPermission: boolean; - disabled: boolean; + disableWithNoPermission: boolean = false; + disabled: boolean = false; constructor(obj?: any) { if (obj) { @@ -32,6 +32,7 @@ export class ContentActionModel { this.target = obj.target; this.permission = obj.permission; this.disableWithNoPermission = obj.disableWithNoPermission; + this.disabled = obj.disabled; } } } diff --git a/ng2-components/ng2-alfresco-documentlist/tsconfig.json b/ng2-components/ng2-alfresco-documentlist/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-documentlist/tsconfig.json +++ b/ng2-components/ng2-alfresco-documentlist/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-login/tsconfig.json b/ng2-components/ng2-alfresco-login/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-login/tsconfig.json +++ b/ng2-components/ng2-alfresco-login/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-search/tsconfig.json b/ng2-components/ng2-alfresco-search/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-search/tsconfig.json +++ b/ng2-components/ng2-alfresco-search/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-social/tsconfig.json b/ng2-components/ng2-alfresco-social/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-social/tsconfig.json +++ b/ng2-components/ng2-alfresco-social/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-tag/tsconfig.json b/ng2-components/ng2-alfresco-tag/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-tag/tsconfig.json +++ b/ng2-components/ng2-alfresco-tag/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-upload/tsconfig.json b/ng2-components/ng2-alfresco-upload/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-upload/tsconfig.json +++ b/ng2-components/ng2-alfresco-upload/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-userinfo/tsconfig.json b/ng2-components/ng2-alfresco-userinfo/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-userinfo/tsconfig.json +++ b/ng2-components/ng2-alfresco-userinfo/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-viewer/tsconfig.json b/ng2-components/ng2-alfresco-viewer/tsconfig.json index ba1ef9cea2..42e2a54cc8 100644 --- a/ng2-components/ng2-alfresco-viewer/tsconfig.json +++ b/ng2-components/ng2-alfresco-viewer/tsconfig.json @@ -41,9 +41,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [ diff --git a/ng2-components/ng2-alfresco-webscript/tsconfig.json b/ng2-components/ng2-alfresco-webscript/tsconfig.json index 875b81f937..dbb645722f 100644 --- a/ng2-components/ng2-alfresco-webscript/tsconfig.json +++ b/ng2-components/ng2-alfresco-webscript/tsconfig.json @@ -21,9 +21,6 @@ "es2015", "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], "suppressImplicitAnyIndexErrors": true }, "exclude": [