mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
@@ -0,0 +1,20 @@
|
||||
/*!
|
||||
* @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 { DataColumn, DataRow } from '@alfresco/core';
|
||||
|
||||
export type ImageResolver = (row: DataRow, column: DataColumn) => string;
|
20
lib/content-services/document-list/data/row-filter.model.ts
Normal file
20
lib/content-services/document-list/data/row-filter.model.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/*!
|
||||
* @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 { ShareDataRow } from './share-data-row.model';
|
||||
|
||||
export type RowFilter = (value: ShareDataRow, index: number, array: ShareDataRow[]) => any;
|
@@ -0,0 +1,97 @@
|
||||
/*!
|
||||
* @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 { DataRow } from '@alfresco/core';
|
||||
import { ObjectUtils } from '@alfresco/core';
|
||||
import { MinimalNode, MinimalNodeEntity } from 'alfresco-js-api';
|
||||
import { PermissionStyleModel } from './../models/permissions-style.model';
|
||||
import { DocumentListService } from './../services/document-list.service';
|
||||
|
||||
export class ShareDataRow implements DataRow {
|
||||
|
||||
static ERR_OBJECT_NOT_FOUND: string = 'Object source not found';
|
||||
|
||||
cache: { [key: string]: any } = {};
|
||||
isSelected: boolean = false;
|
||||
isDropTarget: boolean;
|
||||
cssClass: string = '';
|
||||
|
||||
get node(): MinimalNodeEntity {
|
||||
return this.obj;
|
||||
}
|
||||
|
||||
constructor(private obj: MinimalNodeEntity, private documentListService: DocumentListService, private permissionsStyle: PermissionStyleModel[]) {
|
||||
if (!obj) {
|
||||
throw new Error(ShareDataRow.ERR_OBJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
this.isDropTarget = this.isFolderAndHasPermissionToUpload(obj);
|
||||
|
||||
if (permissionsStyle) {
|
||||
this.cssClass = this.getPermissionClass(obj);
|
||||
}
|
||||
}
|
||||
|
||||
getPermissionClass(nodeEntity: MinimalNodeEntity): string {
|
||||
let permissionsClasses = '';
|
||||
|
||||
this.permissionsStyle.forEach((currentPermissionsStyle: PermissionStyleModel) => {
|
||||
|
||||
if (this.applyPermissionStyleToFolder(nodeEntity.entry, currentPermissionsStyle) || this.applyPermissionStyleToFile(nodeEntity.entry, currentPermissionsStyle)) {
|
||||
|
||||
if (this.documentListService.hasPermission(nodeEntity.entry, currentPermissionsStyle.permission)) {
|
||||
permissionsClasses += ` ${currentPermissionsStyle.css}`;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return permissionsClasses;
|
||||
}
|
||||
|
||||
private applyPermissionStyleToFile(node: MinimalNode, currentPermissionsStyle: PermissionStyleModel): boolean {
|
||||
return (currentPermissionsStyle.isFile && node.isFile);
|
||||
}
|
||||
|
||||
private applyPermissionStyleToFolder(node: MinimalNode, currentPermissionsStyle: PermissionStyleModel): boolean {
|
||||
return (currentPermissionsStyle.isFolder && node.isFolder);
|
||||
}
|
||||
|
||||
isFolderAndHasPermissionToUpload(obj: MinimalNodeEntity): boolean {
|
||||
return this.isFolder(obj) && this.documentListService.hasPermission(obj.entry, 'create');
|
||||
}
|
||||
|
||||
isFolder(obj: MinimalNodeEntity): boolean {
|
||||
return obj.entry && obj.entry.isFolder;
|
||||
}
|
||||
|
||||
cacheValue(key: string, value: any): any {
|
||||
this.cache[key] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
getValue(key: string): any {
|
||||
if (this.cache[key] !== undefined) {
|
||||
return this.cache[key];
|
||||
}
|
||||
return ObjectUtils.getValue(this.obj.entry, key);
|
||||
}
|
||||
|
||||
hasValue(key: string): boolean {
|
||||
return this.getValue(key) !== undefined;
|
||||
}
|
||||
}
|
@@ -0,0 +1,485 @@
|
||||
/*!
|
||||
* @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 { async, TestBed } from '@angular/core/testing';
|
||||
import { DataColumn, DataRow, DataSorting } from '@alfresco/core';
|
||||
import { FileNode, FolderNode } from './../../mock';
|
||||
import { DocumentListService } from './../services/document-list.service';
|
||||
import { ShareDataRow } from './share-data-row.model';
|
||||
import { ShareDataTableAdapter } from './share-datatable-adapter';
|
||||
|
||||
describe('ShareDataTableAdapter', () => {
|
||||
|
||||
let documentListService: DocumentListService;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [],
|
||||
providers: [
|
||||
DocumentListService
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
documentListService = TestBed.get(DocumentListService);
|
||||
});
|
||||
|
||||
it('should setup rows and columns with constructor', () => {
|
||||
let schema = [<DataColumn> {}];
|
||||
let adapter = new ShareDataTableAdapter(documentListService, schema);
|
||||
|
||||
expect(adapter.getRows()).toEqual([]);
|
||||
expect(adapter.getColumns()).toEqual(schema);
|
||||
});
|
||||
|
||||
it('should setup columns when constructor is missing schema', () => {
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
expect(adapter.getColumns()).toEqual([]);
|
||||
});
|
||||
|
||||
it('should set new columns', () => {
|
||||
let columns = [<DataColumn> {}, <DataColumn> {}];
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
adapter.setColumns(columns);
|
||||
expect(adapter.getColumns()).toEqual(columns);
|
||||
});
|
||||
|
||||
it('should reset columns', () => {
|
||||
let columns = [<DataColumn> {}, <DataColumn> {}];
|
||||
let adapter = new ShareDataTableAdapter(documentListService, columns);
|
||||
|
||||
expect(adapter.getColumns()).toEqual(columns);
|
||||
adapter.setColumns(null);
|
||||
expect(adapter.getColumns()).toEqual([]);
|
||||
});
|
||||
|
||||
it('should set new rows', () => {
|
||||
let rows = [<DataRow> {}, <DataRow> {}];
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
expect(adapter.getRows()).toEqual([]);
|
||||
adapter.setRows(rows);
|
||||
expect(adapter.getRows()).toEqual(rows);
|
||||
});
|
||||
|
||||
it('should reset rows', () => {
|
||||
let rows = [<DataRow> {}, <DataRow> {}];
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
adapter.setRows(rows);
|
||||
expect(adapter.getRows()).toEqual(rows);
|
||||
|
||||
adapter.setRows(null);
|
||||
expect(adapter.getRows()).toEqual([]);
|
||||
});
|
||||
|
||||
it('should sort new rows', () => {
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
spyOn(adapter, 'sort').and.callThrough();
|
||||
|
||||
let rows = [<DataRow> {}];
|
||||
adapter.setRows(rows);
|
||||
|
||||
expect(adapter.sort).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should fail when getting value for missing row', () => {
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
let check = () => {
|
||||
return adapter.getValue(null, <DataColumn> {});
|
||||
};
|
||||
expect(check).toThrowError(adapter.ERR_ROW_NOT_FOUND);
|
||||
});
|
||||
|
||||
it('should fail when getting value for missing column', () => {
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
let check = () => {
|
||||
return adapter.getValue(<DataRow> {}, null);
|
||||
};
|
||||
expect(check).toThrowError(adapter.ERR_COL_NOT_FOUND);
|
||||
});
|
||||
|
||||
it('should covert cell value to formatted date', () => {
|
||||
let rawValue = new Date(2015, 6, 15, 21, 43, 11); // Wed Jul 15 2015 21:43:11 GMT+0100 (BST);
|
||||
let dateValue = 'Jul 15, 2015, 9:43:11 PM';
|
||||
|
||||
let file = new FileNode();
|
||||
file.entry.createdAt = rawValue;
|
||||
|
||||
let col = <DataColumn> {
|
||||
key: 'createdAt',
|
||||
type: 'date',
|
||||
format: 'medium' // Jul 15, 2015, 9:43:11 PM
|
||||
};
|
||||
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toBe(dateValue);
|
||||
});
|
||||
|
||||
it('should use default date format as fallback', () => {
|
||||
let rawValue = new Date(2015, 6, 15, 21, 43, 11); // Wed Jul 15 2015 21:43:11 GMT+0100 (BST);
|
||||
let dateValue = 'Jul 15, 2015, 9:43:11 PM';
|
||||
|
||||
let file = new FileNode();
|
||||
file.entry.createdAt = rawValue;
|
||||
|
||||
let col = <DataColumn> {
|
||||
key: 'createdAt',
|
||||
type: 'date',
|
||||
format: null
|
||||
};
|
||||
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toBe(dateValue);
|
||||
});
|
||||
|
||||
it('should return date value as string', () => {
|
||||
let rawValue = new Date(2015, 6, 15, 21, 43, 11); // Wed Jul 15 2015 21:43:11 GMT+0100 (BST);
|
||||
|
||||
let file = new FileNode();
|
||||
file.entry.createdAt = rawValue;
|
||||
|
||||
let col = <DataColumn> {
|
||||
key: 'createdAt',
|
||||
type: 'string'
|
||||
};
|
||||
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toBe(rawValue);
|
||||
});
|
||||
|
||||
it('should log error when having date conversion issues', () => {
|
||||
let dateValue = <Date> {};
|
||||
let file = new FileNode();
|
||||
file.entry.createdAt = <any> dateValue;
|
||||
|
||||
let col = <DataColumn> {
|
||||
key: 'createdAt',
|
||||
type: 'date',
|
||||
format: 'medium'
|
||||
};
|
||||
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
spyOn(console, 'error').and.stub();
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toBe('Error');
|
||||
expect(console.error).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should generate fallback icon for a file thumbnail with missing mime type', () => {
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
let file = new FileNode();
|
||||
file.entry.content.mimeType = null;
|
||||
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let col = <DataColumn> {type: 'image', key: '$thumbnail'};
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toContain(`assets/images/ft_ic_miscellaneous`);
|
||||
expect(value).toContain(`svg`);
|
||||
});
|
||||
|
||||
it('should generate fallback icon for a file with no content entry', () => {
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
let file = new FileNode();
|
||||
file.entry.content = null;
|
||||
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let col = <DataColumn> {type: 'image', key: '$thumbnail'};
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toContain(`assets/images/ft_ic_miscellaneous`);
|
||||
expect(value).toContain(`svg`);
|
||||
});
|
||||
|
||||
it('should return image value unmodified', () => {
|
||||
let imageUrl = 'http://<address>';
|
||||
|
||||
let file = new FileNode();
|
||||
file.entry['icon'] = imageUrl;
|
||||
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let col = <DataColumn> {type: 'image', key: 'icon'};
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toBe(imageUrl);
|
||||
});
|
||||
|
||||
it('should resolve folder icon', () => {
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
let row = new ShareDataRow(new FolderNode(), documentListService, null);
|
||||
let col = <DataColumn> {type: 'image', key: '$thumbnail'};
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toContain(`assets/images/ft_ic_folder`);
|
||||
expect(value).toContain(`svg`);
|
||||
});
|
||||
|
||||
it('should resolve file thumbnail', () => {
|
||||
let imageUrl: string = 'http://<addresss>';
|
||||
spyOn(documentListService, 'getDocumentThumbnailUrl').and.returnValue(imageUrl);
|
||||
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
adapter.thumbnails = true;
|
||||
|
||||
let file = new FileNode();
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let col = <DataColumn> {type: 'image', key: '$thumbnail'};
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toBe(imageUrl);
|
||||
expect(documentListService.getDocumentThumbnailUrl).toHaveBeenCalledWith(file);
|
||||
});
|
||||
|
||||
it('should resolve fallback file icon for unknown node', () => {
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
let file = new FileNode();
|
||||
file.entry.isFile = false;
|
||||
file.entry.isFolder = false;
|
||||
file.entry.content = null;
|
||||
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let col = <DataColumn> {type: 'image', key: '$thumbnail'};
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toContain(`assets/images/ft_ic_miscellaneous`);
|
||||
expect(value).toContain(`svg`);
|
||||
});
|
||||
|
||||
it('should resolve file icon for content type', () => {
|
||||
let adapter = new ShareDataTableAdapter(documentListService, null);
|
||||
|
||||
let file = new FileNode();
|
||||
file.entry.isFile = false;
|
||||
file.entry.isFolder = false;
|
||||
file.entry.content.mimeType = 'image/png';
|
||||
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
let col = <DataColumn> {type: 'image', key: '$thumbnail'};
|
||||
|
||||
let value = adapter.getValue(row, col);
|
||||
expect(value).toContain(`assets/images/ft_ic_raster_image`);
|
||||
expect(value).toContain(`svg`);
|
||||
});
|
||||
|
||||
it('should put folders on top upon sort', () => {
|
||||
let file1 = new FileNode('file1');
|
||||
let file2 = new FileNode('file2');
|
||||
let folder = new FolderNode();
|
||||
|
||||
let col = <DataColumn> {key: 'name'};
|
||||
let adapter = new ShareDataTableAdapter(documentListService, [col]);
|
||||
adapter.setSorting(new DataSorting('name', 'asc'));
|
||||
|
||||
adapter.setRows([
|
||||
new ShareDataRow(file2, documentListService, null),
|
||||
new ShareDataRow(file1, documentListService, null),
|
||||
new ShareDataRow(folder, documentListService, null)
|
||||
]);
|
||||
|
||||
let sorted = adapter.getRows();
|
||||
expect((<ShareDataRow> sorted[0]).node).toBe(folder);
|
||||
expect((<ShareDataRow> sorted[1]).node).toBe(file1);
|
||||
expect((<ShareDataRow> sorted[2]).node).toBe(file2);
|
||||
});
|
||||
|
||||
it('should sort by dates up to ms', () => {
|
||||
let file1 = new FileNode('file1');
|
||||
file1.entry['dateProp'] = new Date(2016, 6, 30, 13, 14, 1);
|
||||
|
||||
let file2 = new FileNode('file2');
|
||||
file2.entry['dateProp'] = new Date(2016, 6, 30, 13, 14, 2);
|
||||
|
||||
let col = <DataColumn> {key: 'dateProp'};
|
||||
let adapter = new ShareDataTableAdapter(documentListService, [col]);
|
||||
|
||||
adapter.setRows([
|
||||
new ShareDataRow(file2, documentListService, null),
|
||||
new ShareDataRow(file1, documentListService, null)
|
||||
]);
|
||||
|
||||
adapter.sort('dateProp', 'asc');
|
||||
|
||||
let rows = adapter.getRows();
|
||||
expect((<ShareDataRow> rows[0]).node).toBe(file1);
|
||||
expect((<ShareDataRow> rows[1]).node).toBe(file2);
|
||||
|
||||
adapter.sort('dateProp', 'desc');
|
||||
expect((<ShareDataRow> rows[0]).node).toBe(file2);
|
||||
expect((<ShareDataRow> rows[1]).node).toBe(file1);
|
||||
});
|
||||
|
||||
it('should sort by file size', () => {
|
||||
let file1 = new FileNode('file1');
|
||||
let file2 = new FileNode('file2');
|
||||
let file3 = new FileNode('file3');
|
||||
let file4 = new FileNode('file4');
|
||||
|
||||
file1.entry.content.sizeInBytes = 146; // 146 bytes
|
||||
file2.entry.content.sizeInBytes = 10075; // 9.84 KB
|
||||
file3.entry.content.sizeInBytes = 4224120; // 4.03 MB
|
||||
file4.entry.content.sizeInBytes = 2852791665; // 2.66 GB
|
||||
|
||||
let col = <DataColumn> {key: 'content.sizeInBytes'};
|
||||
let adapter = new ShareDataTableAdapter(documentListService, [col]);
|
||||
|
||||
adapter.setRows([
|
||||
new ShareDataRow(file3, documentListService, null),
|
||||
new ShareDataRow(file4, documentListService, null),
|
||||
new ShareDataRow(file1, documentListService, null),
|
||||
new ShareDataRow(file2, documentListService, null)
|
||||
]);
|
||||
|
||||
adapter.sort('content.sizeInBytes', 'asc');
|
||||
let rows = adapter.getRows();
|
||||
|
||||
expect((<ShareDataRow> rows[0]).node).toBe(file1);
|
||||
expect((<ShareDataRow> rows[1]).node).toBe(file2);
|
||||
expect((<ShareDataRow> rows[2]).node).toBe(file3);
|
||||
expect((<ShareDataRow> rows[3]).node).toBe(file4);
|
||||
|
||||
adapter.sort('content.sizeInBytes', 'desc');
|
||||
expect((<ShareDataRow> rows[0]).node).toBe(file4);
|
||||
expect((<ShareDataRow> rows[1]).node).toBe(file3);
|
||||
expect((<ShareDataRow> rows[2]).node).toBe(file2);
|
||||
expect((<ShareDataRow> rows[3]).node).toBe(file1);
|
||||
});
|
||||
|
||||
it('should sort by name', () => {
|
||||
let file1 = new FileNode('file1');
|
||||
let file2 = new FileNode('file11');
|
||||
let file3 = new FileNode('file20');
|
||||
let file4 = new FileNode('file11-1'); // auto rename
|
||||
let file5 = new FileNode('a');
|
||||
let file6 = new FileNode('b');
|
||||
|
||||
let col = <DataColumn> {key: 'name'};
|
||||
let adapter = new ShareDataTableAdapter(documentListService, [col]);
|
||||
|
||||
adapter.setRows([
|
||||
new ShareDataRow(file4, documentListService, null),
|
||||
new ShareDataRow(file6, documentListService, null),
|
||||
new ShareDataRow(file3, documentListService, null),
|
||||
new ShareDataRow(file1, documentListService, null),
|
||||
new ShareDataRow(file2, documentListService, null),
|
||||
new ShareDataRow(file5, documentListService, null)
|
||||
]);
|
||||
|
||||
adapter.sort('name', 'asc');
|
||||
let rows = adapter.getRows();
|
||||
|
||||
expect((<ShareDataRow> rows[0]).node).toBe(file5);
|
||||
expect((<ShareDataRow> rows[1]).node).toBe(file6);
|
||||
expect((<ShareDataRow> rows[2]).node).toBe(file1);
|
||||
expect((<ShareDataRow> rows[3]).node).toBe(file2);
|
||||
expect((<ShareDataRow> rows[4]).node).toBe(file4);
|
||||
expect((<ShareDataRow> rows[5]).node).toBe(file3);
|
||||
|
||||
adapter.sort('name', 'desc');
|
||||
expect((<ShareDataRow> rows[0]).node).toBe(file3);
|
||||
expect((<ShareDataRow> rows[1]).node).toBe(file4);
|
||||
expect((<ShareDataRow> rows[2]).node).toBe(file2);
|
||||
expect((<ShareDataRow> rows[3]).node).toBe(file1);
|
||||
expect((<ShareDataRow> rows[4]).node).toBe(file6);
|
||||
expect((<ShareDataRow> rows[5]).node).toBe(file5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ShareDataRow', () => {
|
||||
|
||||
let documentListService: DocumentListService;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [],
|
||||
providers: [
|
||||
DocumentListService
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
documentListService = TestBed.get(DocumentListService);
|
||||
});
|
||||
|
||||
it('should wrap node', () => {
|
||||
let file = new FileNode();
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
expect(row.node).toBe(file);
|
||||
});
|
||||
|
||||
it('should require object source', () => {
|
||||
expect(() => {
|
||||
return new ShareDataRow(null, documentListService, null);
|
||||
}).toThrowError(ShareDataRow.ERR_OBJECT_NOT_FOUND);
|
||||
});
|
||||
|
||||
it('should resolve value from node entry', () => {
|
||||
let file = new FileNode('test');
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
expect(row.getValue('name')).toBe('test');
|
||||
});
|
||||
|
||||
it('should check value', () => {
|
||||
let file = new FileNode('test');
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
|
||||
expect(row.hasValue('name')).toBeTruthy();
|
||||
expect(row.hasValue('missing')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should be set as drop target when user has permission for that node', () => {
|
||||
let file = new FolderNode('test');
|
||||
file.entry['allowableOperations'] = ['create'];
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
|
||||
expect(row.isDropTarget).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not be set as drop target when user has permission for that node', () => {
|
||||
let file = new FolderNode('test');
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
|
||||
expect(row.isDropTarget).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not be set as drop target when element is not a Folder', () => {
|
||||
let file = new FileNode('test');
|
||||
let row = new ShareDataRow(file, documentListService, null);
|
||||
|
||||
expect(row.isDropTarget).toBeFalsy();
|
||||
});
|
||||
|
||||
});
|
@@ -0,0 +1,252 @@
|
||||
/*!
|
||||
* @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 { DataColumn, DataRow, DataSorting, DataTableAdapter } from '@alfresco/core';
|
||||
import { TimeAgoPipe } from '@alfresco/core';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { NodePaging } from 'alfresco-js-api';
|
||||
import { PermissionStyleModel } from './../models/permissions-style.model';
|
||||
import { DocumentListService } from './../services/document-list.service';
|
||||
import { ImageResolver } from './image-resolver.model';
|
||||
import { RowFilter } from './row-filter.model';
|
||||
import { ShareDataRow } from './share-data-row.model';
|
||||
|
||||
export class ShareDataTableAdapter implements DataTableAdapter {
|
||||
|
||||
ERR_ROW_NOT_FOUND: string = 'Row not found';
|
||||
ERR_COL_NOT_FOUND: string = 'Column not found';
|
||||
|
||||
private sorting: DataSorting;
|
||||
private rows: DataRow[];
|
||||
private columns: DataColumn[];
|
||||
private page: NodePaging;
|
||||
|
||||
private filter: RowFilter;
|
||||
private imageResolver: ImageResolver;
|
||||
|
||||
thumbnails: boolean = false;
|
||||
permissionsStyle: PermissionStyleModel[];
|
||||
selectedRow: DataRow;
|
||||
|
||||
constructor(private documentListService: DocumentListService,
|
||||
schema: DataColumn[] = [],
|
||||
sorting?: DataSorting) {
|
||||
this.rows = [];
|
||||
this.columns = schema || [];
|
||||
this.sorting = sorting;
|
||||
}
|
||||
|
||||
getRows(): Array<DataRow> {
|
||||
return this.rows;
|
||||
}
|
||||
|
||||
// TODO: disable this api
|
||||
setRows(rows: Array<DataRow>) {
|
||||
this.rows = rows || [];
|
||||
this.sort();
|
||||
}
|
||||
|
||||
getColumns(): Array<DataColumn> {
|
||||
return this.columns;
|
||||
}
|
||||
|
||||
setColumns(columns: Array<DataColumn>) {
|
||||
this.columns = columns || [];
|
||||
}
|
||||
|
||||
getValue(row: DataRow, col: DataColumn): any {
|
||||
if (!row) {
|
||||
throw new Error(this.ERR_ROW_NOT_FOUND);
|
||||
}
|
||||
if (!col) {
|
||||
throw new Error(this.ERR_COL_NOT_FOUND);
|
||||
}
|
||||
let dataRow: ShareDataRow = <ShareDataRow> row;
|
||||
let value: any = row.getValue(col.key);
|
||||
if (dataRow.cache[col.key] !== undefined) {
|
||||
return dataRow.cache[col.key];
|
||||
}
|
||||
|
||||
if (col.type === 'date') {
|
||||
try {
|
||||
const result = this.formatDate(col, value);
|
||||
return dataRow.cacheValue(col.key, result);
|
||||
} catch (err) {
|
||||
console.error(`Error parsing date ${value} to format ${col.format}`);
|
||||
return 'Error';
|
||||
}
|
||||
}
|
||||
|
||||
if (col.key === '$thumbnail') {
|
||||
|
||||
if (this.imageResolver) {
|
||||
let resolved = this.imageResolver(row, col);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
const node = (<ShareDataRow> row).node;
|
||||
|
||||
if (node.entry.isFolder) {
|
||||
return this.documentListService.getMimeTypeIcon('folder');
|
||||
}
|
||||
|
||||
if (node.entry.isFile) {
|
||||
if (this.thumbnails) {
|
||||
return this.documentListService.getDocumentThumbnailUrl(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.entry.content) {
|
||||
const mimeType = node.entry.content.mimeType;
|
||||
if (mimeType) {
|
||||
return this.documentListService.getMimeTypeIcon(mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
return this.documentListService.getDefaultMimeTypeIcon();
|
||||
}
|
||||
|
||||
if (col.type === 'image') {
|
||||
|
||||
if (this.imageResolver) {
|
||||
let resolved = this.imageResolver(row, col);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dataRow.cacheValue(col.key, value);
|
||||
}
|
||||
|
||||
formatDate(col: DataColumn, value: any): string {
|
||||
if (col.type === 'date') {
|
||||
const format = col.format || 'medium';
|
||||
if (format === 'timeAgo') {
|
||||
const timeAgoPipe = new TimeAgoPipe();
|
||||
return timeAgoPipe.transform(value);
|
||||
} else {
|
||||
const datePipe = new DatePipe('en-US');
|
||||
return datePipe.transform(value, format);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
getSorting(): DataSorting {
|
||||
return this.sorting;
|
||||
}
|
||||
|
||||
setSorting(sorting: DataSorting): void {
|
||||
this.sorting = sorting;
|
||||
|
||||
this.sortRows(this.rows, this.sorting);
|
||||
}
|
||||
|
||||
sort(key?: string, direction?: string): void {
|
||||
let sorting = this.sorting || new DataSorting();
|
||||
if (key) {
|
||||
sorting.key = key;
|
||||
sorting.direction = direction || 'asc';
|
||||
}
|
||||
this.setSorting(sorting);
|
||||
}
|
||||
|
||||
setFilter(filter: RowFilter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
setImageResolver(resolver: ImageResolver) {
|
||||
this.imageResolver = resolver;
|
||||
}
|
||||
|
||||
private sortRows(rows: DataRow[], sorting: DataSorting) {
|
||||
const options: Intl.CollatorOptions = {};
|
||||
|
||||
if (sorting && sorting.key && rows && rows.length > 0) {
|
||||
|
||||
if (sorting.key.includes('sizeInBytes') || sorting.key === 'name') {
|
||||
options.numeric = true;
|
||||
}
|
||||
|
||||
rows.sort((a: ShareDataRow, b: ShareDataRow) => {
|
||||
if (a.node.entry.isFolder !== b.node.entry.isFolder) {
|
||||
return a.node.entry.isFolder ? -1 : 1;
|
||||
}
|
||||
|
||||
let left = a.getValue(sorting.key);
|
||||
if (left) {
|
||||
left = (left instanceof Date) ? left.valueOf().toString() : left.toString();
|
||||
} else {
|
||||
left = '';
|
||||
}
|
||||
|
||||
let right = b.getValue(sorting.key);
|
||||
if (right) {
|
||||
right = (right instanceof Date) ? right.valueOf().toString() : right.toString();
|
||||
} else {
|
||||
right = '';
|
||||
}
|
||||
|
||||
return sorting.direction === 'asc'
|
||||
? left.localeCompare(right, undefined, options)
|
||||
: right.localeCompare(left, undefined, options);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public loadPage(page: NodePaging, merge: boolean = false) {
|
||||
this.page = page;
|
||||
|
||||
let rows = [];
|
||||
|
||||
if (page && page.list) {
|
||||
let data = page.list.entries;
|
||||
if (data && data.length > 0) {
|
||||
rows = data.map(item => new ShareDataRow(item, this.documentListService, this.permissionsStyle));
|
||||
|
||||
if (this.filter) {
|
||||
rows = rows.filter(this.filter);
|
||||
}
|
||||
|
||||
// Sort by first sortable or just first column
|
||||
if (this.columns && this.columns.length > 0) {
|
||||
let sorting = this.getSorting();
|
||||
if (sorting) {
|
||||
this.sortRows(rows, sorting);
|
||||
} else {
|
||||
let sortable = this.columns.filter(c => c.sortable);
|
||||
if (sortable.length > 0) {
|
||||
this.sort(sortable[0].key, 'asc');
|
||||
} else {
|
||||
this.sort(this.columns[0].key, 'asc');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (merge) {
|
||||
this.rows = this.rows.concat(rows);
|
||||
} else {
|
||||
this.rows = rows;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user