From 2fa82832137e221f30072fe63cedd005fe121ba1 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 19 May 2016 10:58:15 +0100 Subject: [PATCH] #82 datatable project cleanup basic implementation of main features: - custom data sources - column types - sorting by columns - click events --- .../datatable/datatable-demo.component.html | 71 +--- .../datatable/datatable-demo.component.ts | 33 +- .../ng2-alfresco-datatable.ts | 37 +- .../src/assets/alfresco.service.mock.ts | 41 --- .../components/data-action-list.component.ts | 42 --- .../components/data-action.component.spec.ts | 179 --------- .../src/components/data-action.component.ts | 101 ------ .../data-column-list.component.spec.ts | 49 --- .../components/data-column-list.component.ts | 41 --- .../components/data-column.component.spec.ts | 80 ---- .../src/components/data-column.component.ts | 63 ---- .../src/components/datatable.component.css | 4 + .../src/components/datatable.component.html | 93 +---- .../components/datatable.component.spec.ts | 321 +--------------- .../src/components/datatable.component.ts | 342 ++---------------- .../datatable-adapter.ts} | 28 +- .../src/data/object-datatable-adapter.ts | 135 +++++++ .../src/models/column-sorting.model.ts | 21 -- .../src/models/data-action.model.ts | 28 -- .../src/models/document-library.model.ts | 117 ------ .../src/services/alfresco.service.ts | 120 ------ .../services/document-actions.service.spec.ts | 58 --- .../src/services/document-actions.service.ts | 72 ---- .../services/folder-actions.service.spec.ts | 53 --- .../src/services/folder-actions.service.ts | 53 --- 25 files changed, 253 insertions(+), 1929 deletions(-) delete mode 100644 ng2-components/ng2-alfresco-datatable/src/assets/alfresco.service.mock.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/components/data-action-list.component.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/components/data-action.component.spec.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/components/data-action.component.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/components/data-column-list.component.spec.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/components/data-column-list.component.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/components/data-column.component.spec.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/components/data-column.component.ts rename ng2-components/ng2-alfresco-datatable/src/{models/data-column.model.ts => data/datatable-adapter.ts} (56%) create mode 100644 ng2-components/ng2-alfresco-datatable/src/data/object-datatable-adapter.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/models/column-sorting.model.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/models/data-action.model.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/models/document-library.model.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/services/alfresco.service.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/services/document-actions.service.spec.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/services/document-actions.service.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/services/folder-actions.service.spec.ts delete mode 100644 ng2-components/ng2-alfresco-datatable/src/services/folder-actions.service.ts diff --git a/demo-shell-ng2/app/components/datatable/datatable-demo.component.html b/demo-shell-ng2/app/components/datatable/datatable-demo.component.html index c018d6a9a8..80f379b1cc 100644 --- a/demo-shell-ng2/app/components/datatable/datatable-demo.component.html +++ b/demo-shell-ng2/app/components/datatable/datatable-demo.component.html @@ -1,72 +1,3 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
diff --git a/demo-shell-ng2/app/components/datatable/datatable-demo.component.ts b/demo-shell-ng2/app/components/datatable/datatable-demo.component.ts index 180e29e910..738ca1a8d1 100644 --- a/demo-shell-ng2/app/components/datatable/datatable-demo.component.ts +++ b/demo-shell-ng2/app/components/datatable/datatable-demo.component.ts @@ -1,4 +1,4 @@ -/** +/*! * @license * Copyright 2016 Alfresco Software, Ltd. * @@ -20,7 +20,7 @@ import {TranslatePipe} from 'ng2-translate/ng2-translate'; import { ALFRESCO_DATATABLE_DIRECTIVES, - ALFRESCO_DATATABLE_PROVIDERS + ObjectDataTableAdapter, DataSorting } from 'ng2-alfresco-datatable/ng2-alfresco-datatable'; declare let __moduleName:string; @@ -30,9 +30,34 @@ declare let __moduleName:string; selector: 'datatable-demo', templateUrl: './datatable-demo.component.html', directives: [ALFRESCO_DATATABLE_DIRECTIVES], - providers: [ALFRESCO_DATATABLE_PROVIDERS], pipes: [TranslatePipe] }) export class DataTableDemoComponent { - + data: ObjectDataTableAdapter; + + constructor() { + + let imageUrl = 'http://placehold.it/140x100'; + let createdBy = { + name: 'Denys Vuika', + email: 'denys.vuika@alfresco.com' + }; + + this.data = new ObjectDataTableAdapter( + [ + { id: 1, name: 'Name 1', createdBy: createdBy, icon: 'material-icons://folder_open' }, + { id: 2, name: 'Name 2', createdBy: createdBy, icon: 'material-icons://accessibility' }, + { id: 3, name: 'Name 3', createdBy: createdBy, icon: 'material-icons://alarm' }, + { id: 4, name: 'Image 1', createdBy: createdBy, icon: imageUrl } + ], + [ + { type: 'image', key: 'icon', title: '', srTitle: 'Thumbnail' }, + { type: 'text', key: 'id', title: 'Id', sortable: true}, + { type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true }, + { type: 'text', key: 'createdBy.name', title: 'Created By', sortable: true } + ] + ); + + this.data.setSorting(new DataSorting('name', 'asc')); + } } diff --git a/ng2-components/ng2-alfresco-datatable/ng2-alfresco-datatable.ts b/ng2-components/ng2-alfresco-datatable/ng2-alfresco-datatable.ts index 2860c7015b..e1791a1457 100644 --- a/ng2-components/ng2-alfresco-datatable/ng2-alfresco-datatable.ts +++ b/ng2-components/ng2-alfresco-datatable/ng2-alfresco-datatable.ts @@ -16,43 +16,14 @@ */ import { DataTableComponent } from './src/components/datatable.component'; -import { DataColumnComponent } from './src/components/data-column.component'; -import { DataColumnListComponent } from './src/components/data-column-list.component'; -import { DataActionComponent } from './src/components/data-action.component'; -import { DataActionListComponent } from './src/components/data-action-list.component'; - -import { FolderActionsService } from './src/services/folder-actions.service'; -import { DocumentActionsService } from './src/services/document-actions.service'; -import { AlfrescoService } from './src/services/alfresco.service'; // components export * from './src/components/datatable.component'; -export * from './src/components/data-column.component'; -export * from './src/components/data-column-list.component'; -export * from './src/components/data-action.component'; -export * from './src/components/data-action-list.component'; - -// models -export * from './src/models/data-action.model'; -export * from './src/models/data-column.model'; -export * from './src/models/column-sorting.model'; - -// services -export * from './src/services/folder-actions.service'; -export * from './src/services/document-actions.service'; -export * from './src/services/alfresco.service'; +// data +export * from './src/data/datatable-adapter'; +export * from './src/data/object-datatable-adapter'; export const ALFRESCO_DATATABLE_DIRECTIVES: [any] = [ - DataTableComponent, - DataColumnComponent, - DataColumnListComponent, - DataActionComponent, - DataActionListComponent -]; - -export const ALFRESCO_DATATABLE_PROVIDERS: [any] = [ - AlfrescoService, - FolderActionsService, - DocumentActionsService + DataTableComponent ]; diff --git a/ng2-components/ng2-alfresco-datatable/src/assets/alfresco.service.mock.ts b/ng2-components/ng2-alfresco-datatable/src/assets/alfresco.service.mock.ts deleted file mode 100644 index 8cee299e13..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/assets/alfresco.service.mock.ts +++ /dev/null @@ -1,41 +0,0 @@ -/*! - * @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 {Http} from 'angular2/http'; -import {Observable} from 'rxjs/Observable'; - -import {AlfrescoSettingsService} from 'ng2-alfresco-core/services'; -import {AlfrescoService} from './../../src/services/alfresco.service'; - -export class AlfrescoServiceMock extends AlfrescoService { - - _folderToReturn: any = {}; - - constructor( - http: Http = null, - settings: AlfrescoSettingsService = null - ) { - super(http, settings); - } - - getFolder(folder: string) { - return Observable.create(observer => { - observer.next(this._folderToReturn); - observer.complete(); - }); - } -} diff --git a/ng2-components/ng2-alfresco-datatable/src/components/data-action-list.component.ts b/ng2-components/ng2-alfresco-datatable/src/components/data-action-list.component.ts deleted file mode 100644 index 2f695f055c..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/data-action-list.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -/*! - * @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} from 'angular2/core'; - -import { DataTableComponent } from './datatable.component'; -import { DataActionModel } from './../models/data-action.model'; - -@Component({ - selector: 'data-actions', - template: '' -}) -export class DataActionListComponent { - - constructor( - private dataTable: DataTableComponent) { - } - - /** - * Registers action handler within the parent document list component. - * @param action Action model to register. - */ - registerAction(action: DataActionModel): void { - if (this.dataTable && action) { - this.dataTable.actions.push(action); - } - } -} diff --git a/ng2-components/ng2-alfresco-datatable/src/components/data-action.component.spec.ts b/ng2-components/ng2-alfresco-datatable/src/components/data-action.component.spec.ts deleted file mode 100644 index 279bdb39aa..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/data-action.component.spec.ts +++ /dev/null @@ -1,179 +0,0 @@ -/*! - * @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 { - it, - describe, - expect, - beforeEach -} from 'angular2/testing'; -import {EventEmitter} from 'angular2/core'; - -import { AlfrescoServiceMock } from '../assets/alfresco.service.mock'; -import { DataTableComponent } from './datatable.component'; -import { DataActionListComponent } from './data-action-list.component'; -import { DataActionComponent } from './data-action.component'; -import {DocumentActionsService} from '../services/document-actions.service'; -import {FolderActionsService} from '../services/folder-actions.service'; - -describe('ContentAction', () => { - - let dataTable: DataTableComponent; - let actionList: DataActionListComponent; - - beforeEach(() => { - let alfrescoServiceMock = new AlfrescoServiceMock(); - dataTable = new DataTableComponent(alfrescoServiceMock); - actionList = new DataActionListComponent(dataTable); - }); - - it('should register within parent actions list', () => { - spyOn(actionList, 'registerAction').and.stub(); - - let action = new DataActionComponent(actionList, null, null); - action.ngOnInit(); - - expect(actionList.registerAction).toHaveBeenCalled(); - }); - - it('should setup and register model', () => { - let action = new DataActionComponent(actionList, null, null); - action.type = 'button'; - action.target = 'document'; - action.title = ''; - action.icon = '<icon>'; - - expect(dataTable.actions.length).toBe(0); - action.ngOnInit(); - - expect(dataTable.actions.length).toBe(1); - - let model = dataTable.actions[0]; - expect(model.type).toBe(action.type); - expect(model.target).toBe(action.target); - expect(model.title).toBe(action.title); - expect(model.icon).toBe(action.icon); - }); - - it('should get action handler from document actions service', () => { - - let handler = function() {}; - let documentActions = new DocumentActionsService(null); - spyOn(documentActions, 'getHandler').and.returnValue(handler); - - let action = new DataActionComponent(actionList, documentActions, null); - action.type = 'button'; - action.target = 'document'; - action.handler = '<handler>'; - action.ngOnInit(); - - expect(documentActions.getHandler).toHaveBeenCalledWith(action.handler); - expect(dataTable.actions.length).toBe(1); - - let model = dataTable.actions[0]; - expect(model.handler).toBe(handler); - }); - - it('should get action handler from folder actions service', () => { - let handler = function() {}; - let folderActions = new FolderActionsService(); - spyOn(folderActions, 'getHandler').and.returnValue(handler); - - let action = new DataActionComponent(actionList, null, folderActions); - action.type = 'button'; - action.target = 'folder'; - action.handler = '<handler>'; - action.ngOnInit(); - - expect(folderActions.getHandler).toHaveBeenCalledWith(action.handler); - expect(dataTable.actions.length).toBe(1); - - let model = dataTable.actions[0]; - expect(model.handler).toBe(handler); - }); - - it('should require target to get system handler', () => { - let folderActions = new FolderActionsService(); - spyOn(folderActions, 'getHandler').and.stub(); - - let documentActions = new DocumentActionsService(null); - spyOn(documentActions, 'getHandler').and.stub(); - - let action = new DataActionComponent(actionList, documentActions, folderActions); - action.type = 'button'; - action.handler = '<handler>'; - - action.ngOnInit(); - expect(dataTable.actions.length).toBe(1); - expect(folderActions.getHandler).not.toHaveBeenCalled(); - expect(documentActions.getHandler).not.toHaveBeenCalled(); - - action.target = 'document'; - action.ngOnInit(); - expect(documentActions.getHandler).toHaveBeenCalled(); - - action.target = 'folder'; - action.ngOnInit(); - expect(folderActions.getHandler).toHaveBeenCalled(); - }); - - it('should be case insensitive for document target', () => { - let documentActions = new DocumentActionsService(null); - spyOn(documentActions, 'getHandler').and.stub(); - - let action = new DataActionComponent(actionList, documentActions, null); - action.target = 'DoCuMeNt'; - action.type = 'button'; - action.handler = '<handler>'; - - action.ngOnInit(); - expect(documentActions.getHandler).toHaveBeenCalledWith(action.handler); - }); - - it('should be case insensitive for folder target', () => { - let folderActions = new FolderActionsService(); - spyOn(folderActions, 'getHandler').and.stub(); - - let action = new DataActionComponent(actionList, null, folderActions); - action.target = 'FoLdEr'; - action.type = 'button'; - action.handler = '<handler>'; - - action.ngOnInit(); - expect(folderActions.getHandler).toHaveBeenCalledWith(action.handler); - }); - - it('should use custom "execute" emitter', (done) => { - let emitter = new EventEmitter(); - - emitter.subscribe(e => { - expect(e.value).toBe('<obj>'); - done(); - }); - - let action = new DataActionComponent(actionList, null, null); - action.target = 'document'; - action.type = 'button'; - action.execute = emitter; - - action.ngOnInit(); - expect(dataTable.actions.length).toBe(1); - - let model = dataTable.actions[0]; - model.handler('<obj>'); - }); -}); diff --git a/ng2-components/ng2-alfresco-datatable/src/components/data-action.component.ts b/ng2-components/ng2-alfresco-datatable/src/components/data-action.component.ts deleted file mode 100644 index 4f48742eac..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/data-action.component.ts +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * @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, - OnInit, - Input, - Output, - EventEmitter -} from 'angular2/core'; - -import { DataActionModel, DataActionHandler } from './../models/data-action.model'; -import { DataActionListComponent } from './data-action-list.component'; -import {DocumentActionsService} from '../services/document-actions.service'; -import {FolderActionsService} from '../services/folder-actions.service'; - -@Component({ - selector: 'data-action', - template: '' -}) -export class DataActionComponent implements OnInit { - - @Input() - title: string = 'Action'; - - @Input() - icon: string; - - @Input() - handler: string; - - @Input() - type: string; - - @Input() - target: string; - - @Output() - execute = new EventEmitter(); - - constructor( - private list: DataActionListComponent, - private documentActions: DocumentActionsService, - private folderActions: FolderActionsService) { - } - - ngOnInit() { - let model = new DataActionModel(); - model.type = this.type; - model.title = this.title; - model.icon = this.icon; - model.target = this.target; - - if (this.handler) { - model.handler = this.getSystemHandler(this.target, this.handler); - } else if (this.execute) { - model.handler = (document: any): void => { - this.execute.emit({ - value: document - }); - }; - } - - this.list.registerAction(model); - } - - private getSystemHandler(target: string, name: string): DataActionHandler { - if (target) { - let ltarget = target.toLowerCase(); - - if (ltarget === 'document') { - if (this.documentActions) { - return this.documentActions.getHandler(name); - } - return null; - } - - if (ltarget === 'folder') { - if (this.folderActions) { - return this.folderActions.getHandler(name); - } - return null; - } - } - return null; - } -} diff --git a/ng2-components/ng2-alfresco-datatable/src/components/data-column-list.component.spec.ts b/ng2-components/ng2-alfresco-datatable/src/components/data-column-list.component.spec.ts deleted file mode 100644 index 4e7d58603a..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/data-column-list.component.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * @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 { - it, - describe, - expect, - beforeEach -} from 'angular2/testing'; - -import { DataTableComponent } from './datatable.component'; -import { AlfrescoServiceMock } from '../assets/alfresco.service.mock'; -import { DataColumnListComponent } from './data-column-list.component'; -import { DataColumnModel } from '../models/data-column.model'; - -describe('ContentColumnList', () => { - - let dataTable: DataTableComponent; - let dataColumnList: DataColumnListComponent; - - beforeEach(() => { - let alfrescoServiceMock = new AlfrescoServiceMock(); - dataTable = new DataTableComponent(alfrescoServiceMock); - dataColumnList = new DataColumnListComponent(dataTable); - }); - - it('should register column within parent document list', () => { - expect(dataTable.columns.length).toBe(0); - - dataColumnList.registerColumn(new DataColumnModel()); - - expect(dataTable.columns.length).toBe(1); - }); - -}); diff --git a/ng2-components/ng2-alfresco-datatable/src/components/data-column-list.component.ts b/ng2-components/ng2-alfresco-datatable/src/components/data-column-list.component.ts deleted file mode 100644 index de2615e6cd..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/data-column-list.component.ts +++ /dev/null @@ -1,41 +0,0 @@ -/*! - * @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 } from 'angular2/core'; -import { DataTableComponent } from './datatable.component'; -import { DataColumnModel } from '../models/data-column.model'; - -@Component({ - selector: 'data-columns', - template: '' -}) -export class DataColumnListComponent { - - constructor( - private dataTable: DataTableComponent) { - } - - /** - * Registers column model within the parent document list component. - * @param column Column definition model to register. - */ - registerColumn(column: DataColumnModel): void { - if (this.dataTable && column) { - this.dataTable.columns.push(column); - } - } -} diff --git a/ng2-components/ng2-alfresco-datatable/src/components/data-column.component.spec.ts b/ng2-components/ng2-alfresco-datatable/src/components/data-column.component.spec.ts deleted file mode 100644 index 49202cbad0..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/data-column.component.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -/*! - * @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 { - it, - describe, - expect, - beforeEach -} from 'angular2/testing'; - -import {AlfrescoServiceMock} from '../assets/alfresco.service.mock'; -import { DataTableComponent } from './datatable.component'; -import { DataColumnComponent } from './data-column.component'; -import { DataColumnListComponent } from './data-column-list.component'; - -describe('ContentColumn', () => { - - let dataTable: DataTableComponent; - let columnList: DataColumnListComponent; - - beforeEach(() => { - let alfrescoServiceMock = new AlfrescoServiceMock(); - dataTable = new DataTableComponent(alfrescoServiceMock); - columnList = new DataColumnListComponent(dataTable); - }); - - it('should register model within parent column list', () => { - spyOn(columnList, 'registerColumn').and.callThrough(); - - let column = new DataColumnComponent(columnList); - column.ngOnInit(); - - expect(columnList.registerColumn).toHaveBeenCalled(); - }); - - it('should setup model properties during registration', () => { - - let column = new DataColumnComponent(columnList); - column.title = '<title>'; - column.srTitle = '<sr-title>'; - column.source = '<source>'; - column.cssClass = '<css-class>'; - column.ngOnInit(); - - expect(dataTable.columns.length).toBe(1); - - let model = dataTable.columns[0]; - expect(model.title).toBe(column.title); - expect(model.srTitle).toBe(column.srTitle); - expect(model.source).toBe(column.source); - expect(model.cssClass).toBe(column.cssClass); - }); - - it('should setup screen reader title for thumbnail column', () => { - - let column = new DataColumnComponent(columnList); - column.source = '$thumbnail'; - column.ngOnInit(); - - expect(dataTable.columns.length).toBe(1); - - let model = dataTable.columns[0]; - expect(model.srTitle).toBe('Thumbnail'); - }); - -}); diff --git a/ng2-components/ng2-alfresco-datatable/src/components/data-column.component.ts b/ng2-components/ng2-alfresco-datatable/src/components/data-column.component.ts deleted file mode 100644 index e38fc54756..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/data-column.component.ts +++ /dev/null @@ -1,63 +0,0 @@ -/*! - * @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, OnInit, Input } from 'angular2/core'; - -import { DataColumnListComponent } from './data-column-list.component'; -import { DataColumnModel } from './../models/data-column.model'; - -@Component({ - selector: 'data-column', - template: '' -}) -export class DataColumnComponent implements OnInit { - - @Input() - title: string = ''; - - /** - * Title to be used for screen readers. - */ - @Input('sr-title') - srTitle: string; - - @Input() - source: string; - - @Input('class') - cssClass: string; - - constructor( - private columns: DataColumnListComponent) { - } - - ngOnInit() { - let model = new DataColumnModel(); - model.title = this.title; - model.srTitle = this.srTitle; - model.source = this.source; - model.cssClass = this.cssClass; - - if (!model.srTitle && model.source === '$thumbnail') { - model.srTitle = 'Thumbnail'; - } - - if (this.columns) { - this.columns.registerColumn(model); - } - } -} diff --git a/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.css b/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.css index 9c54596092..8eca18be77 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.css +++ b/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.css @@ -11,6 +11,10 @@ cursor: pointer; } +:host .data-cell { + cursor: pointer; +} + :host .column-header { cursor: pointer; user-select: none; diff --git a/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.html b/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.html index 06ef08a953..48405ffa97 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.html +++ b/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.html @@ -1,18 +1,12 @@ -<ol *ngIf="breadcrumb" class="breadcrumb"> - <li *ngFor="#r of route; #last = last" [class.active]="last" [ngSwitch]="last"> - <span *ngSwitchWhen="true">{{r.name}}</span> - <a *ngSwitchDefault href="#" (click)="goToRoute(r, $event)">{{r.name}}</a> - </li> -</ol> -<table *ngIf="folder" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width"> +<table *ngIf="data" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width"> <thead> <tr> <!-- Columns --> <th class="mdl-data-table__cell--non-numeric {{col.cssClass}}" - *ngFor="#col of columns" + *ngFor="#col of data.columns" [class.column-header]="col.title" - [class.mdl-data-table__header--sorted-ascending]="sorting.key === col.source && sorting.direction === 'asc'" - [class.mdl-data-table__header--sorted-descending]="sorting.key === col.source && sorting.direction === 'desc'" + [class.mdl-data-table__header--sorted-ascending]="isColumnSorted(col, 'asc')" + [class.mdl-data-table__header--sorted-descending]="isColumnSorted(col, 'desc')" (click)="onColumnHeaderClick(col)"> <span *ngIf="col.srTitle" class="sr-only">{{col.srTitle}}</span> <span *ngIf="col.title">{{col.title}}</span> @@ -24,77 +18,28 @@ </tr> </thead> <tbody> - <tr class="parent-folder-link" *ngIf="canNavigateParent()" (click)="onNavigateParentClick($event)"> - <td [attr.colspan]="1 + columns?.length"> - <button class="mdl-button mdl-js-button mdl-button--icon" - (click)="onNavigateParentClick($event)"> - <i class="material-icons">arrow_upward</i> - </button> - </td> - </tr> + <!-- todo: special 'navigate parent row' support --> - <tr *ngFor="#content of folder.list.entries; #idx = index"> - <!-- Columns --> - <td *ngFor="#col of columns" [ngSwitch]="col.source" - class="mdl-data-table__cell--non-numeric {{content.entry.isFolder ? 'folder-row-cell' : 'document-row-cell'}} {{col.cssClass}}" - (click)="onItemClick(content, $event)"> - <div *ngSwitchWhen="'$thumbnail'"> - <div *ngIf="content.entry.isFolder"> - <i class="material-icons folder-thumbnail">{{folderIcon || 'folder_open'}}</i> - </div> - <div *ngIf="!content.entry.isFolder"> - <img class="document-thumbnail" alt="" src="{{getDocumentThumbnailUrl(content)}}"> - </div> + <tr *ngFor="#row of data.rows; #idx = index"> + + <td *ngFor="#col of data.columns" [ngSwitch]="col.type" + class="mdl-data-table__cell--non-numeric data-cell {{col.cssClass}}" + (click)="onRowClicked(row, $event)"> + <div *ngSwitchWhen="'image'"> + <i *ngIf="isIconValue(row, col)" class="material-icons folder-thumbnail">{{asIconValue(row, col)}}</i> + <img *ngIf="!isIconValue(row, col)" class="document-thumbnail" alt="" src="{{data.getValue(row, col)}}"> + </div> + <div *ngSwitchWhen="'text'"> + {{data.getValue(row, col)}} </div> <span *ngSwitchDefault> - {{getObjectValue(content.entry, col.source)}} + <!-- empty cell for unknown column type --> </span> + </td> - <!-- Actions: folder --> - <td *ngIf="content.entry.isFolder"> - <!-- action buttons --> - <button class="mdl-button mdl-js-button mdl-button--icon" - *ngFor="#action of getContentActions('folder', 'button')" - (click)="executeContentAction(content, action)"> - <i class="material-icons">{{action.icon}}</i> - </button> + <td><!-- todo: actions --></td> - <!-- action menu --> - <button [id]="'folder_action_menu_' + idx" class="mdl-button mdl-js-button mdl-button--icon"> - <i class="material-icons">more_vert</i> - </button> - <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" - [attr.for]="'folder_action_menu_' + idx"> - <li class="mdl-menu__item" - *ngFor="#action of getContentActions('folder', 'menu')" - (click)="executeContentAction(content, action)"> - {{action.title}} - </li> - </ul> - </td> - <!-- Actions: document --> - <td *ngIf="!content.entry.isFolder"> - <!-- action buttons --> - <button class="mdl-button mdl-js-button mdl-button--icon" - *ngFor="#action of getContentActions('document', 'button')" - (click)="executeContentAction(content, action)"> - <i class="material-icons">{{action.icon}}</i> - </button> - - <!-- action menu --> - <button [id]="'document_action_menu_' + idx" class="mdl-button mdl-js-button mdl-button--icon"> - <i class="material-icons">more_vert</i> - </button> - <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" - [attr.for]="'document_action_menu_' + idx"> - <li class="mdl-menu__item" - *ngFor="#action of getContentActions('document', 'menu')" - (click)="executeContentAction(content, action)"> - {{action.title}} - </li> - </ul> - </td> </tr> </tbody> </table> diff --git a/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.spec.ts b/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.spec.ts index 4ce97c17b6..83ad44c5ab 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.spec.ts +++ b/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.spec.ts @@ -23,20 +23,14 @@ import { } from 'angular2/testing'; import { DataTableComponent } from './datatable.component'; -import { DataColumnModel } from './../models/data-column.model'; -import { AlfrescoServiceMock } from '../assets/alfresco.service.mock'; -import { MinimalNodeEntity, MinimalNodeEntryEntity } from '../models/document-library.model'; -import { DataActionModel } from './../models/data-action.model'; -describe('DocumentList', () => { +describe('DataTable', () => { - let alfrescoServiceMock: AlfrescoServiceMock; let dataTable: DataTableComponent; let eventMock: any; beforeEach(() => { - alfrescoServiceMock = new AlfrescoServiceMock(); - dataTable = new DataTableComponent(alfrescoServiceMock); + dataTable = new DataTableComponent(); eventMock = { preventDefault: function () { @@ -45,315 +39,8 @@ describe('DocumentList', () => { }; }); - it('should setup default columns', () => { - spyOn(dataTable, 'setupDefaultColumns').and.callThrough(); - - dataTable.ngAfterContentInit(); - - expect(dataTable.setupDefaultColumns).toHaveBeenCalled(); - expect(dataTable.columns.length).not.toBe(0); - }); - - it('should use custom columns instead of default ones', () => { - let column: DataColumnModel = { - title: 'title', - source: 'source', - cssClass: 'css', - srTitle: '' - }; - dataTable.columns.push(column); - - dataTable.ngAfterContentInit(); - expect(dataTable.columns.length).toBe(1); - expect(dataTable.columns[0]).toBe(column); - }); - - it('should setup default root for breadcrumb', () => { - dataTable.ngOnInit(); - expect(dataTable.route.length).toBe(1); - expect(dataTable.route[0]).toBe(dataTable.rootFolder); - }); - - it('should display custom root path', () => { - spyOn(dataTable, 'displayFolderContent').and.stub(); - - let root = { - name: '<root>', - path: '<path>' - }; - - dataTable.currentFolderPath = root.path; - dataTable.rootFolder = root; - dataTable.ngOnInit(); - expect(dataTable.displayFolderContent).toHaveBeenCalledWith(root.path); - }); - - it('should fetch folder', () => { - let folder = { - 'nodeRef': 'workspace://SpacesStore/8bb36efb-c26d-4d2b-9199-ab6922f53c28' - }; - alfrescoServiceMock._folderToReturn = folder; - dataTable.ngOnInit(); - - expect(dataTable.folder).toBe(folder); - }); - - it('should get content url', () => { - let url = 'URL'; - spyOn(alfrescoServiceMock, 'getContentUrl').and.returnValue(url); - - let result = dataTable.getContentUrl(null); - - expect(result).toBe(url); - expect(alfrescoServiceMock.getContentUrl).toHaveBeenCalled(); - }); - - it('should return no content url without service', () => { - let table = new DataTableComponent(null); - let node = new MinimalNodeEntity(); - expect(table.getContentUrl(node)).toBeNull(); - }); - - it('should get thumbnail url', () => { - let url = 'URL'; - spyOn(alfrescoServiceMock, 'getDocumentThumbnailUrl').and.returnValue(url); - - let result = dataTable.getDocumentThumbnailUrl(null); - - expect(result).toBe(url); - expect(alfrescoServiceMock.getDocumentThumbnailUrl).toHaveBeenCalled(); - }); - - it('should get no thumbnail url without service', () => { - let table = new DataTableComponent(null); - let node = new MinimalNodeEntity(); - expect(table.getDocumentThumbnailUrl(node)).toBeNull(); - }); - - it('should execute action with node', () => { - let node = new MinimalNodeEntity(); - let action = new DataActionModel(); - action.handler = function () { - console.log('mock handler'); - }; - - spyOn(action, 'handler').and.stub(); - - dataTable.executeContentAction(node, action); - expect(action.handler).toHaveBeenCalledWith(node); - - }); - - it('should execute action without node provided', () => { - let action = new DataActionModel(); - action.handler = function () { - console.log('mock handler'); - }; - - spyOn(action, 'handler').and.stub(); - dataTable.executeContentAction(null, action); - expect(action.handler).toHaveBeenCalledWith(null); - }); - - it('should update current folder path', () => { - expect(dataTable.currentFolderPath).toBe(dataTable.rootFolder.path); - - let path = '<path>'; - dataTable.displayFolderContent(path); - - expect(dataTable.currentFolderPath).toBe(path); - }); - - it('should give no content actions for empty target', () => { - let actions = dataTable.getContentActions(null, 'button'); - expect(actions.length).toBe(0); - }); - - it('should give no content actions for empty type', () => { - let actions = dataTable.getContentActions('folder', null); - expect(actions.length).toBe(0); - }); - - it('should filter content actions for various types and targets', () => { - let folderButton = new DataActionModel(); - folderButton.target = 'folder'; - folderButton.type = 'button'; - - let folderMenu = new DataActionModel(); - folderMenu.target = 'folder'; - folderMenu.type = 'menu'; - - let documentButton = new DataActionModel(); - documentButton.target = 'document'; - documentButton.type = 'button'; - - let documentMenu = new DataActionModel(); - documentMenu.target = 'document'; - documentMenu.type = 'menu'; - - dataTable.actions = [ - folderButton, - folderMenu, - documentButton, - documentMenu - ]; - - let actions = dataTable.getContentActions('folder', 'button'); - expect(actions.length).toBe(1); - expect(actions[0]).toBe(folderButton); - - actions = dataTable.getContentActions('folder', 'menu'); - expect(actions.length).toBe(1); - expect(actions[0]).toBe(folderMenu); - - actions = dataTable.getContentActions('document', 'button'); - expect(actions.length).toBe(1); - expect(actions[0]).toBe(documentButton); - - actions = dataTable.getContentActions('document', 'menu'); - expect(actions.length).toBe(1); - expect(actions[0]).toBe(documentMenu); - }); - - it('should be case insensitive when filtering content actions', () => { - let documentButton = new DataActionModel(); - documentButton.target = 'document'; - documentButton.type = 'button'; - - dataTable.actions = [documentButton]; - - let actions = dataTable.getContentActions('DoCuMeNt', 'BUTTON'); - expect(actions.length).toBe(1); - expect(actions[0]).toBe(documentButton); - }); - - it('should find no content actions', () => { - let documentButton = new DataActionModel(); - documentButton.target = 'document'; - documentButton.type = 'button'; - - dataTable.actions = [documentButton]; - - let actions = dataTable.getContentActions('unknown', 'value'); - expect(actions.length).toBe(0); - }); - - it('should emit itemClick event', (done) => { - let node: MinimalNodeEntity = new MinimalNodeEntity(); - dataTable.itemClick.subscribe(e => { - expect(e.value).toBe(node); - done(); - }); - dataTable.onItemClick(node); - }); - - it('should prevent default events for item click', () => { - spyOn(eventMock, 'preventDefault').and.stub(); - - dataTable.onItemClick(null, eventMock); - expect(eventMock.preventDefault).toHaveBeenCalled(); - }); - - it('should display folder content on click', () => { - let path = '/'; - - let node = new MinimalNodeEntity(); - node.entry = new MinimalNodeEntryEntity(); - node.entry.isFolder = true; - node.entry.name = '<display name>'; - - spyOn(dataTable, 'getNodePath').and.returnValue(path); - spyOn(dataTable, 'displayFolderContent').and.stub(); - - dataTable.onItemClick(node); - - expect(dataTable.displayFolderContent).toHaveBeenCalledWith(path); - - let routeEntry = dataTable.route.pop(); - expect(routeEntry.name).toBe(node.entry.name); - expect(routeEntry.path).toBe(path); - }); - - it('should not display folder content when no target node provided', () => { - expect(dataTable.navigate).toBe(true); - spyOn(dataTable, 'displayFolderContent').and.stub(); - - dataTable.onItemClick(null); - expect(dataTable.displayFolderContent).not.toHaveBeenCalled(); - - }); - - it('should display folder content only on folder node click', () => { - expect(dataTable.navigate).toBe(true); - spyOn(dataTable, 'displayFolderContent').and.stub(); - - let node = new MinimalNodeEntity(); - node.entry = new MinimalNodeEntryEntity(); - node.entry.isFolder = false; - - dataTable.onItemClick(node); - - expect(dataTable.displayFolderContent).not.toHaveBeenCalled(); - }); - - it('should not display folder content on click when navigation is off', () => { - spyOn(dataTable, 'displayFolderContent').and.stub(); - - let node = new MinimalNodeEntity(); - node.entry = new MinimalNodeEntryEntity(); - node.entry.isFolder = true; - node.entry.name = '<display name>'; - - dataTable.navigate = false; - dataTable.onItemClick(node); - - expect(dataTable.displayFolderContent).not.toHaveBeenCalled(); - }); - - it('should require node to get path', () => { - expect(dataTable.getNodePath(null)).toBe(null); - }); - - /* - it('should get node path', () => { - let location = new LocationEntity(); - location.site = 'swsdp'; - location.container = 'documentLibrary'; - location.path = '\/'; - - let node = new DocumentEntity(); - node.fileName = 'fileName'; - node.location = location; - - expect(documentList.getNodePath(node)).toBe('swsdp/documentLibrary/fileName'); - }); - */ - - it('should return root object value', () => { - let target = { - key1: 'value1' - }; - - expect(dataTable.getObjectValue(target, 'key1')).toBe('value1'); - }); - - it('should return no object value when key is missing', () => { - let target = { - key1: 'value1' - }; - expect(dataTable.getObjectValue(target, 'missing')).toBeUndefined(); - }); - - it('should return nested object value', () => { - let target = { - key1: { - key2: { - key3: 'value1' - } - } - }; - - expect(dataTable.getObjectValue(target, 'key1.key2.key3')).toBe('value1'); + it('should pass', () => { + expect(true).toBe(true); }); }); diff --git a/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.ts b/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.ts index 9efd23dc18..30660d1dc3 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.ts +++ b/ng2-components/ng2-alfresco-datatable/src/components/datatable.component.ts @@ -21,15 +21,16 @@ import { Input, Output, EventEmitter, - AfterContentInit, AfterViewChecked } from 'angular2/core'; -import { AlfrescoService } from './../services/alfresco.service'; -import { MinimalNodeEntity, NodePaging } from './../models/document-library.model'; -import { DataActionModel } from './../models/data-action.model'; -import { DataColumnModel } from './../models/data-column.model'; -import { ColumnSortingModel } from './../models/column-sorting.model'; +import { + DataTableAdapter, + DataRow, + DataColumn, + DataSorting +} from './../data/datatable-adapter'; +import { ObjectDataTableAdapter } from '../data/object-datatable-adapter'; declare var componentHandler; declare let __moduleName: string; @@ -38,85 +39,21 @@ declare let __moduleName: string; moduleId: __moduleName, selector: 'alfresco-datatable', styleUrls: ['./datatable.component.css'], - templateUrl: './datatable.component.html', - providers: [AlfrescoService] + templateUrl: './datatable.component.html' }) -export class DataTableComponent implements OnInit, AfterViewChecked, AfterContentInit { - - DEFAULT_ROOT_FOLDER: string = '/Sites/swsdp/documentLibrary'; +export class DataTableComponent implements OnInit, AfterViewChecked { @Input() - navigate: boolean = true; - - @Input() - breadcrumb: boolean = false; - - @Input('folder-icon') - folderIcon: string; + data: DataTableAdapter; @Output() - itemClick: EventEmitter<any> = new EventEmitter(); - - @Output() - folderClick: EventEmitter<any> = new EventEmitter(); - - rootFolder = { - name: '', - path: '' - }; - - @Input() - currentFolderPath: string = ''; - - folder: NodePaging; - errorMessage; - - route: any[] = []; - - actions: DataActionModel[] = []; - columns: DataColumnModel[] = []; - - sorting: ColumnSortingModel = { - key: 'name', - direction: 'asc' - }; - - /** - * Determines whether navigation to parent folder is available. - * @returns {boolean} - */ - canNavigateParent(): boolean { - return this.navigate && !this.breadcrumb && - this.currentFolderPath !== this.rootFolder.path; - } - - constructor( - private _alfrescoService: AlfrescoService) { - } - - _createRootFolder(): any { - let folderArray = this.currentFolderPath.split('/'); - let nameFolder = folderArray[folderArray.length - 1]; - return { - name: nameFolder, - path: this.currentFolderPath - }; - } + onRowClick: EventEmitter<any> = new EventEmitter(); ngOnInit() { - this.currentFolderPath = this.currentFolderPath || this.DEFAULT_ROOT_FOLDER; - this.rootFolder = this._createRootFolder(); - this.route.push(this.rootFolder); - this.displayFolderContent(this.rootFolder.path); - } - - ngOnChanges(change) { - this.reload(); - } - - ngAfterContentInit() { - if (!this.columns || this.columns.length === 0) { - this.setupDefaultColumns(); + if (this.data) { + console.log(this.data); + } else { + this.data = new ObjectDataTableAdapter([], []); } } @@ -127,251 +64,34 @@ export class DataTableComponent implements OnInit, AfterViewChecked, AfterConten } } - /** - * Get a list of content actions based on target and type. - * @param target Target to filter actions by. - * @param type Type to filter actions by. - * @returns {ContentActionModel[]} List of actions filtered by target and type. - */ - getContentActions(target: string, type: string): DataActionModel[] { - if (target && type) { - - let ltarget = target.toLowerCase(); - let ltype = type.toLowerCase(); - - return this.actions.filter(entry => { - return entry.target.toLowerCase() === ltarget && - entry.type.toLowerCase() === ltype; - }); - } - return []; - } - - /** - * Invoked when 'parent folder' element is clicked. - * @param e DOM event - */ - onNavigateParentClick(e) { + onRowClicked(row: DataRow, e?) { if (e) { e.preventDefault(); } - if (this.navigate) { - this.route.pop(); - let parent = this.route.length > 0 ? this.route[this.route.length - 1] : this.rootFolder; - if (parent) { - this.folderClick.emit({ - value: parent.path - }); - this.displayFolderContent(parent.path); - } - } - } - - /** - * Invoked when list row is clicked. - * @param item Underlying node item - * @param e DOM event (optional) - */ - onItemClick(item: MinimalNodeEntity, e = null) { - if (e) { - e.preventDefault(); - } - - this.itemClick.emit({ - value: item + this.onRowClick.emit({ + value: row }); + } - if (this.navigate && item && item.entry) { - if (item.entry.isFolder) { - let path = this.getNodePath(item); - - this.folderClick.emit({ - value: path - }); - - this.route.push({ - name: item.entry.name, - path: path - }); - this.displayFolderContent(path); - } + onColumnHeaderClick(column: DataColumn) { + if (column && column.sortable) { + let current = this.data.getSorting(); + let newDirection = current.direction === 'asc' ? 'desc' : 'asc'; + this.data.setSorting(new DataSorting(column.key, newDirection)); } } - /** - * Invoked when a breadcrumb route is clicked. - * @param r Route to navigate to - * @param e DOM event - */ - goToRoute(r, e) { - if (e) { - e.preventDefault(); - } - - if (this.navigate) { - let idx = this.route.indexOf(r); - if (idx > -1) { - this.route.splice(idx + 1); - this.displayFolderContent(r.path); - } - } + isIconValue(row: DataRow, col: DataColumn) { + return row.getValue(col.key).startsWith('material-icons://'); } - /** - * Gets content URL for the given node. - * @param node Node to get URL for. - * @returns {string} URL address. - */ - getContentUrl(node: MinimalNodeEntity): string { - if (this._alfrescoService) { - return this._alfrescoService.getContentUrl(node); - } - return null; + asIconValue(row: DataRow, col: DataColumn) { + return row.getValue(col.key).replace('material-icons://', ''); } - /** - * Gets thumbnail URL for the given document node. - * @param node Node to get URL for. - * @returns {string} URL address. - */ - getDocumentThumbnailUrl(node: MinimalNodeEntity): string { - if (this._alfrescoService) { - return this._alfrescoService.getDocumentThumbnailUrl(node); - } - return null; - } - - /** - * Invoked when executing content action for a document or folder. - * @param node Node to be the context of the execution. - * @param action Action to be executed against the context. - */ - executeContentAction(node: MinimalNodeEntity, action: DataActionModel) { - if (action) { - action.handler(node); - } - } - - /** - * Loads and displays folder content - * @param path Node path - */ - displayFolderContent(path) { - if (path !== null) { - this.currentFolderPath = path; - this._alfrescoService - .getFolder(path) - .subscribe( - folder => this.folder = this.sort(folder, this.sorting), - error => this.errorMessage = <any>error - ); - } - } - - reload() { - if (this.currentFolderPath) { - this.displayFolderContent(this.currentFolderPath); - } - } - - /** - * Gets a path for a given node. - * @param node - * @returns {string} - */ - getNodePath(node: MinimalNodeEntity): string { - if (node) { - let pathWithCompanyHome = node.entry.path.name; - return pathWithCompanyHome.replace('/Company Home', '') + '/' + node.entry.name; - } - return null; - } - - /** - * Gets a value from an object by composed key - * documentList.getObjectValue({ item: { nodeType: 'cm:folder' }}, 'item.nodeType') ==> 'cm:folder' - * @param target - * @param key - * @returns {string} - */ - getObjectValue(target: any, key: string): any { - let keys = key.split('.'); - key = ''; - - do { - key += keys.shift(); - let value = target[key]; - if (value !== undefined && (typeof value === 'object' || !keys.length)) { - target = value; - key = ''; - } else if (!keys.length) { - target = undefined; - } else { - key += '.'; - } - } while (keys.length); - - return target; - } - - /** - * Creates a set of predefined columns. - */ - setupDefaultColumns(): void { - let thumbnailCol = new DataColumnModel(); - thumbnailCol.source = '$thumbnail'; - - let nameCol = new DataColumnModel(); - nameCol.title = 'Name'; - nameCol.source = 'name'; - nameCol.cssClass = 'full-width name-column'; - - this.columns = [ - thumbnailCol, - nameCol - ]; - } - - onColumnHeaderClick(column: DataColumnModel) { - if (column && this._isSortableColumn(column)) { - if (this.sorting.key === column.source) { - this.sorting.direction = this.sorting.direction === 'asc' ? 'desc' : 'asc'; - } else { - this.sorting = <ColumnSortingModel> { - key: column.source, - direction: 'asc' - }; - } - this.sort(this.folder, this.sorting); - } - } - - sort(node: NodePaging, options: ColumnSortingModel) { - if (this._hasEntries(node)) { - node.list.entries.sort((a: MinimalNodeEntity, b: MinimalNodeEntity) => { - if (a.entry.isFolder !== b.entry.isFolder) { - return options.direction === 'asc' - ? (a.entry.isFolder ? -1 : 1) - : (a.entry.isFolder ? 1 : -1); - } - - let left = this.getObjectValue(a.entry, options.key).toString(); - let right = this.getObjectValue(b.entry, options.key).toString(); - - return options.direction === 'asc' - ? left.localeCompare(right) - : right.localeCompare(left); - }); - } - return node; - } - - private _hasEntries(node: NodePaging): boolean { - return (node && node.list && node.list.entries && node.list.entries.length > 0); - } - - private _isSortableColumn(column: DataColumnModel) { - return column && column.source && !column.source.startsWith('$'); + isColumnSorted(col: DataColumn, direction: string) { + let sorting = this.data.getSorting(); + return sorting.key === col.key && sorting.direction === direction; } } diff --git a/ng2-components/ng2-alfresco-datatable/src/models/data-column.model.ts b/ng2-components/ng2-alfresco-datatable/src/data/datatable-adapter.ts similarity index 56% rename from ng2-components/ng2-alfresco-datatable/src/models/data-column.model.ts rename to ng2-components/ng2-alfresco-datatable/src/data/datatable-adapter.ts index 5d3c6772a2..9b430e7f94 100644 --- a/ng2-components/ng2-alfresco-datatable/src/models/data-column.model.ts +++ b/ng2-components/ng2-alfresco-datatable/src/data/datatable-adapter.ts @@ -15,9 +15,33 @@ * limitations under the License. */ -export class DataColumnModel { +export interface DataTableAdapter { + + rows: DataRow[]; + columns: DataColumn[]; + + getValue(row: DataRow, col: DataColumn): any; + getSorting(): DataSorting; + setSorting(sorting: DataSorting): void; +} + +export interface DataRow { + hasValue(key: string): boolean; + getValue(key: string): any; +} + +export interface DataColumn { + key: string; + type: string; // text|image + sortable: boolean; title: string; srTitle: string; - source: string; cssClass: string; } + +export class DataSorting { + constructor( + public key: string, + public direction: string) { + } +} diff --git a/ng2-components/ng2-alfresco-datatable/src/data/object-datatable-adapter.ts b/ng2-components/ng2-alfresco-datatable/src/data/object-datatable-adapter.ts new file mode 100644 index 0000000000..51e8eed3dd --- /dev/null +++ b/ng2-components/ng2-alfresco-datatable/src/data/object-datatable-adapter.ts @@ -0,0 +1,135 @@ +/*! + * @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 { + DataTableAdapter, + DataRow, + DataColumn, + DataSorting +} from './datatable-adapter'; + +// Simple implementation of the DataTableAdapter interface. +export class ObjectDataTableAdapter implements DataTableAdapter { + + private _sorting; + + rows: DataRow[]; + columns: DataColumn[]; + + constructor(data: any[], schema: DataColumn[]) { + this.rows = []; + + if (data && data.length > 0) { + + this.rows = data.map(item => { + return new ObjectDataRow(item); + }); + + this.columns = schema.map(item => { + return new ObjectDataColumn(item); + }); + } + } + + getValue(row: DataRow, col: DataColumn): any { + return row.getValue(col.key); + } + + getSorting(): DataSorting { + return this._sorting; + } + + getColumnByKey(key: string) { + let columns = this.columns.filter(col => col.key === key); + return columns.length > 0 ? columns[0] : null; + } + + setSorting(sorting: DataSorting): void { + this._sorting = sorting; + + this.rows.sort((a: DataRow, b: DataRow) => { + let left = a.getValue(sorting.key).toString(); + let right = b.getValue(sorting.key).toString(); + + return sorting.direction === 'asc' + ? left.localeCompare(right) + : right.localeCompare(left); + }); + } +} + +// Simple implementation of the DataRow interface. +class ObjectDataRow implements DataRow { + constructor( + private obj: any) { + } + + /** + * Gets a value from an object by composed key + * documentList.getObjectValue({ item: { nodeType: 'cm:folder' }}, 'item.nodeType') ==> 'cm:folder' + * @param target + * @param key + * @returns {string} + */ + getObjectValue(target: any, key: string): any { + let keys = key.split('.'); + key = ''; + + do { + key += keys.shift(); + let value = target[key]; + if (value !== undefined && (typeof value === 'object' || !keys.length)) { + target = value; + key = ''; + } else if (!keys.length) { + target = undefined; + } else { + key += '.'; + } + } while (keys.length); + + return target; + } + + getValue(key: string): any { + return this.getObjectValue(this.obj, key); + } + + hasValue(key: string): boolean { + return this.getValue(key) ? true : false; + } +} + +// Simple implementation of the DataColumn interface. +class ObjectDataColumn implements DataColumn { + + key: string; + type: string; // text|image + sortable: boolean; + title: string; + srTitle: string; + cssClass: string; + + constructor(private obj: any) { + this.key = obj.key; + this.type = obj.type; + this.sortable = obj.sortable; + this.title = obj.title; + this.srTitle = obj.srTitle; + this.cssClass = obj.cssClass; + } +} diff --git a/ng2-components/ng2-alfresco-datatable/src/models/column-sorting.model.ts b/ng2-components/ng2-alfresco-datatable/src/models/column-sorting.model.ts deleted file mode 100644 index 10c0dc9123..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/models/column-sorting.model.ts +++ /dev/null @@ -1,21 +0,0 @@ -/*! - * @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. - */ - -export class ColumnSortingModel { - key: string; - direction: string = 'asc'; -} diff --git a/ng2-components/ng2-alfresco-datatable/src/models/data-action.model.ts b/ng2-components/ng2-alfresco-datatable/src/models/data-action.model.ts deleted file mode 100644 index eada0c502b..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/models/data-action.model.ts +++ /dev/null @@ -1,28 +0,0 @@ -/*! - * @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. - */ - -export class DataActionModel { - icon: string; - title: string; - handler: DataActionHandler; - type: string; - target: string; -} - -export interface DataActionHandler { - (obj: any): any; -} diff --git a/ng2-components/ng2-alfresco-datatable/src/models/document-library.model.ts b/ng2-components/ng2-alfresco-datatable/src/models/document-library.model.ts deleted file mode 100644 index 8859ae1c3b..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/models/document-library.model.ts +++ /dev/null @@ -1,117 +0,0 @@ -/*! - * @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. - */ - -// note: contains only limited subset of available fields - -export class FolderEntity { - items: DocumentEntity[]; -} - -export class DocumentEntity { - nodeRef: string; - nodeType: string; - type: string; - mimetype: string; - isFolder: boolean; - isLink: boolean; - fileName: string; - displayName: string; - status: string; - title: string; - description: string; - author: string; - createdOn: string; - createdBy: string; - createdByUser: string; - modifiedOn: string; - modifiedBy: string; - modifiedByUser: string; - lockedBy: string; - lockedByUser: string; - size: number; - version: string; - contentUrl: string; - webdavUrl: string; - actionSet: string; - tags: string[]; - activeWorkflows: string; - location: LocationEntity; -} - -export class LocationEntity { - repositoryId: string; - site: string; - siteTitle: string; - container: string; - path: string; - file: string; - parent: LocationParentEntity; -} - -export class LocationParentEntity { - nodeRef: string; -} - -export class NodePaging { - list: NodePagingList; -} - -export class NodePagingList { - entries: MinimalNodeEntity[]; -} - -export class MinimalNodeEntity { - entry: MinimalNodeEntryEntity; -} - -export class MinimalNodeEntryEntity { - id: string; - parentId: string; - name: string; - nodeType: string; - isFolder: boolean; - isFile: boolean; - modifiedAt: string; - modifiedByUser: UserInfo; - createdAt: string; - createdByUser: UserInfo; - content: ContentInfo; - path: PathInfoEntity; -} - -export class UserInfo { - displayName: string; - id: string; -} - -export class ContentInfo { - mimeType: string; - mimeTypeName: string; - sizeInBytes: number; - encoding: string; -} - -export class PathInfoEntity { - elements: PathElementEntity; - isComplete: boolean; - name: string; -} - -export class PathElementEntity { - id: string; - name: string; -} diff --git a/ng2-components/ng2-alfresco-datatable/src/services/alfresco.service.ts b/ng2-components/ng2-alfresco-datatable/src/services/alfresco.service.ts deleted file mode 100644 index 743e73281f..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/services/alfresco.service.ts +++ /dev/null @@ -1,120 +0,0 @@ -/*! - * @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 { Injectable } from 'angular2/core'; -import { Http, Response } from 'angular2/http'; -import { Observable } from 'rxjs/Observable'; - -import { AlfrescoSettingsService } from 'ng2-alfresco-core/services'; -import { NodePaging, MinimalNodeEntity } from './../models/document-library.model'; - -declare let AlfrescoApi: any; - -/** - * Internal service used by Document List component. - */ -@Injectable() -export class AlfrescoService { - - private _host: string = 'http://127.0.0.1:8080'; - private _baseUrlPath: string = '/alfresco/api/-default-/public/alfresco/versions/1'; - - constructor(private http: Http, - private settings: AlfrescoSettingsService) { - if (settings) { - this._host = settings.host; - } - } - - public get host(): string { - return this._host; - } - - public set host(value: string) { - this._host = value; - } - - private getBaseUrl(): string { - return this.host + this._baseUrlPath; - } - - private getAlfrescoTicket() { - return localStorage.getItem('token'); - } - - private getAlfrescoClient() { - let defaultClient = new AlfrescoApi.ApiClient(); - defaultClient.basePath = this.getBaseUrl(); - - // Configure HTTP basic authorization: basicAuth - let basicAuth = defaultClient.authentications['basicAuth']; - basicAuth.username = 'ROLE_TICKET'; - basicAuth.password = this.getAlfrescoTicket(); - - return defaultClient; - } - - private getNodesPromise(folder: string) { - let alfrescoClient = this.getAlfrescoClient(); - let apiInstance = new AlfrescoApi.NodesApi(alfrescoClient); - let nodeId = '-root-'; - let opts = { - relativePath: folder, - include: ['path'] - }; - return apiInstance.getNodeChildren(nodeId, opts); - } - - /** - * Gets the folder node with the content. - * @param folder Path to folder. - * @returns {Observable<NodePaging>} Folder entity. - */ - getFolder(folder: string) { - return Observable.fromPromise(this.getNodesPromise(folder)) - .map(res => <NodePaging> res) - .do(data => console.log('Node data', data)) // eyeball results in the console - .catch(this.handleError); - } - - /** - * Get thumbnail URL for the given document node. - * @param document Node to get URL for. - * @returns {string} URL address. - */ - getDocumentThumbnailUrl(document: MinimalNodeEntity) { - return this.getContentUrl(document) + '/thumbnails/doclib?c=queue&ph=true&lastModified=1&alf_ticket=' + this.getAlfrescoTicket(); - } - - /** - * Get content URL for the given node. - * @param document Node to get URL for. - * @returns {string} URL address. - */ - getContentUrl(document: MinimalNodeEntity) { - return this._host + - '/alfresco/service/api/node/workspace/SpacesStore/' + - document.entry.id + '/content'; - } - - private handleError(error: Response) { - // in a real world app, we may send the error to some remote logging infrastructure - // instead of just logging it to the console - console.error(error); - return Observable.throw(error || 'Server error'); - } -} diff --git a/ng2-components/ng2-alfresco-datatable/src/services/document-actions.service.spec.ts b/ng2-components/ng2-alfresco-datatable/src/services/document-actions.service.spec.ts deleted file mode 100644 index 98e5f96733..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/services/document-actions.service.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -/*! - * @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 { - it, - describe, - expect, - beforeEach -} from 'angular2/testing'; - -import { DataActionHandler } from './../models/data-action.model'; -import { DocumentActionsService } from './document-actions.service'; -import { AlfrescoServiceMock } from '../assets/alfresco.service.mock'; - -describe('DocumentActionsService', () => { - - let service: DocumentActionsService; - - beforeEach(() => { - let alfrescoServiceMock = new AlfrescoServiceMock(); - service = new DocumentActionsService(alfrescoServiceMock); - }); - - it('should register default download action', () => { - expect(service.getHandler('download')).not.toBeNull(); - }); - - it('should register custom action handler', () => { - let handler: DataActionHandler = function (obj: any) {}; - service.setHandler('<key>', handler); - expect(service.getHandler('<key>')).toBe(handler); - }); - - it('should not find handler that is not registered', () => { - expect(service.getHandler('<missing>')).toBeNull(); - }); - - it('should be case insensitive for keys', () => { - let handler: DataActionHandler = function (obj: any) {}; - service.setHandler('<key>', handler); - expect(service.getHandler('<KEY>')).toBe(handler); - - }); -}); diff --git a/ng2-components/ng2-alfresco-datatable/src/services/document-actions.service.ts b/ng2-components/ng2-alfresco-datatable/src/services/document-actions.service.ts deleted file mode 100644 index e39e6af347..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/services/document-actions.service.ts +++ /dev/null @@ -1,72 +0,0 @@ -/*! - * @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 {Injectable} from 'angular2/core'; - -import { DataActionHandler } from './../models/data-action.model'; -import { AlfrescoService } from './alfresco.service'; - -@Injectable() -export class DocumentActionsService { - private handlers: { [id: string]: DataActionHandler; } = {}; - - constructor(private _alfrescoService: AlfrescoService) { - this.setupActionHandlers(); - } - - getHandler(key: string): DataActionHandler { - if (key) { - let lkey = key.toLowerCase(); - return this.handlers[lkey] || null; - } - return null; - } - - setHandler(key: string, handler: DataActionHandler): void { - if (key) { - let lkey = key.toLowerCase(); - this.handlers[lkey] = handler; - } - } - - private setupActionHandlers() { - this.handlers['download'] = this.download.bind(this); - - // todo: just for dev/demo purposes, to be replaced with real actions - this.handlers['system1'] = this.handleStandardAction1.bind(this); - this.handlers['system2'] = this.handleStandardAction2.bind(this); - } - - private handleStandardAction1(obj: any) { - window.alert('standard document action 1'); - } - - private handleStandardAction2(obj: any) { - window.alert('standard document action 2'); - } - - private download(obj: any) { - if (this._alfrescoService && obj && !obj.isFolder) { - let link = document.createElement('a'); - document.body.appendChild(link); - link.setAttribute('download', 'download'); - link.href = this._alfrescoService.getContentUrl(obj); - link.click(); - document.body.removeChild(link); - } - } -} diff --git a/ng2-components/ng2-alfresco-datatable/src/services/folder-actions.service.spec.ts b/ng2-components/ng2-alfresco-datatable/src/services/folder-actions.service.spec.ts deleted file mode 100644 index ed9e1edd90..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/services/folder-actions.service.spec.ts +++ /dev/null @@ -1,53 +0,0 @@ -/*! - * @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 { - it, - describe, - expect, - beforeEach -} from 'angular2/testing'; - -import { FolderActionsService } from './folder-actions.service'; -import { DataActionHandler } from './../models/data-action.model'; - -describe('FolderActionsService', () => { - - let service: FolderActionsService; - - beforeEach(() => { - service = new FolderActionsService(); - }); - - it('should register custom action handler', () => { - let handler: DataActionHandler = function (obj: any) {}; - service.setHandler('<key>', handler); - expect(service.getHandler('<key>')).toBe(handler); - }); - - it('should not find handler that is not registered', () => { - expect(service.getHandler('<missing>')).toBeNull(); - }); - - it('should be case insensitive for keys', () => { - let handler: DataActionHandler = function (obj: any) {}; - service.setHandler('<key>', handler); - expect(service.getHandler('<KEY>')).toBe(handler); - - }); - -}); diff --git a/ng2-components/ng2-alfresco-datatable/src/services/folder-actions.service.ts b/ng2-components/ng2-alfresco-datatable/src/services/folder-actions.service.ts deleted file mode 100644 index 6270fc1fcc..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/services/folder-actions.service.ts +++ /dev/null @@ -1,53 +0,0 @@ -/*! - * @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 {Injectable} from 'angular2/core'; -import { DataActionHandler } from './../models/data-action.model'; - -@Injectable() -export class FolderActionsService { - private handlers: { [id: string]: DataActionHandler; } = {}; - - constructor() { - // todo: just for dev/demo purposes, to be replaced with real actions - this.handlers['system1'] = this.handleStandardAction1.bind(this); - this.handlers['system2'] = this.handleStandardAction2.bind(this); - } - - getHandler(key: string): DataActionHandler { - if (key) { - let lkey = key.toLowerCase(); - return this.handlers[lkey] || null; - } - return null; - } - - setHandler(key: string, handler: DataActionHandler): void { - if (key) { - let lkey = key.toLowerCase(); - this.handlers[lkey] = handler; - } - } - - private handleStandardAction1(document: any) { - window.alert('standard folder action 1'); - } - - private handleStandardAction2(document: any) { - window.alert('standard folder action 2'); - } -}