[no-issue] error image resolver mimetype should not be part of datatable (#3415)

* move error image custom logic form datatable to documentlist

* change travis

* [fix-test-log] added optional function to data row interface

* [no-issue] fixed datatable tests

* [no-issue] fixing tests
This commit is contained in:
Eugenio Romano
2018-06-08 00:27:01 +02:00
committed by GitHub
parent 346dff436d
commit 08fd49c4e3
16 changed files with 131 additions and 99 deletions

View File

@@ -71,11 +71,20 @@ jobs:
- # Test expors - # Test expors
script: npm run test-export script: npm run test-export
- stage: Update Apps dependencies - stage: Update Apps dependencies
- # Test Update generator-ng2-alfresco-app
if: tag =~ .*beta.* if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n generator-ng2-alfresco-app script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n generator-ng2-alfresco-app
- # Test Update alfresco-content-app
if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n alfresco-content-app script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n alfresco-content-app
- # Test Update adf-app-manager-ui
if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n adf-app-manager-ui script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n adf-app-manager-ui
- # Test Update aalfresco-ng2-components
if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n alfresco-ng2-components script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n alfresco-ng2-components
- # Test Update alfresco-modeler-app
if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n alfresco-modeler-app script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n alfresco-modeler-app
- stage: Deploy PR - stage: Deploy PR
script: node ./scripts/pr-deploy.js -n $TRAVIS_BUILD_NUMBER -u $RANCHER_TOKEN -p $RANCHER_SECRET -s $REPO_RANCHER --image "docker:$REPO_DOCKER/adf/demo-shell:$TRAVIS_BUILD_NUMBER" --env $ENVIRONMENT_NAME -r $ENVIRONMENT_URL || exit 1 script: node ./scripts/pr-deploy.js -n $TRAVIS_BUILD_NUMBER -u $RANCHER_TOKEN -p $RANCHER_SECRET -s $REPO_RANCHER --image "docker:$REPO_DOCKER/adf/demo-shell:$TRAVIS_BUILD_NUMBER" --env $ENVIRONMENT_NAME -r $ENVIRONMENT_URL || exit 1

View File

@@ -95,6 +95,7 @@
"CUSTOM_FILTER" :"Custom extensions filter", "CUSTOM_FILTER" :"Custom extensions filter",
"MAX_SIZE" : "Max size filter", "MAX_SIZE" : "Max size filter",
"ENABLE_VERSIONING" :"Enable versioning", "ENABLE_VERSIONING" :"Enable versioning",
"THUMBNAILS" :"Enable Thumbnails",
"DESCRIPTION_UPLOAD" : "Enable upload", "DESCRIPTION_UPLOAD" : "Enable upload",
"ENABLE_INFINITE_SCROLL":"Enable Infinite Scrolling", "ENABLE_INFINITE_SCROLL":"Enable Infinite Scrolling",
"MULTISELECT_DESCRIPTION" : "Use Cmd (Mac) or Ctrl (Windows) to toggle selection of multiple items", "MULTISELECT_DESCRIPTION" : "Use Cmd (Mac) or Ctrl (Windows) to toggle selection of multiple items",

View File

@@ -199,6 +199,7 @@
[sorting]="sorting" [sorting]="sorting"
[sortingMode]="sortingMode" [sortingMode]="sortingMode"
[showHeader]="showHeader" [showHeader]="showHeader"
[thumbnails]="thumbnails"
(error)="onNavigationError($event)" (error)="onNavigationError($event)"
(success)="resetError()" (success)="resetError()"
(ready)="emitReadyEvent($event)" (ready)="emitReadyEvent($event)"
@@ -477,6 +478,12 @@
</mat-slide-toggle> </mat-slide-toggle>
</section> </section>
<section>
<mat-slide-toggle [color]="'primary'" (click)="toggleThumbnails()" >{{'DOCUMENT_LIST.THUMBNAILS' |
translate}}
</mat-slide-toggle>
</section>
<section> <section>
<mat-slide-toggle [color]="'primary'" [(ngModel)]="versioning"> <mat-slide-toggle [color]="'primary'" [(ngModel)]="versioning">
{{'DOCUMENT_LIST.ENABLE_VERSIONING' | translate}} {{'DOCUMENT_LIST.ENABLE_VERSIONING' | translate}}

View File

@@ -178,6 +178,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
supportedPages: number[]; supportedPages: number[];
currentSiteid = ''; currentSiteid = '';
warnOnMultipleUploads = false; warnOnMultipleUploads = false;
thumbnails = false;
private onCreateFolder: Subscription; private onCreateFolder: Subscription;
private onEditFolder: Subscription; private onEditFolder: Subscription;
@@ -213,6 +214,11 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
return this.folderUpload; return this.folderUpload;
} }
toggleThumbnails() {
this.thumbnails = !this.thumbnails;
this.documentList.reload();
}
ngOnInit() { ngOnInit() {
if (!this.pagination) { if (!this.pagination) {
this.pagination = <Pagination>{ this.pagination = <Pagination>{

View File

@@ -23,7 +23,7 @@ import {
import { import {
ContentService, DataCellEvent, DataColumn, DataRowActionEvent, DataSorting, DataTableComponent, ContentService, DataCellEvent, DataColumn, DataRowActionEvent, DataSorting, DataTableComponent,
DisplayMode, ObjectDataColumn, PaginatedComponent, AppConfigService, DataColumnListComponent, DisplayMode, ObjectDataColumn, PaginatedComponent, AppConfigService, DataColumnListComponent,
UserPreferencesService, PaginationModel UserPreferencesService, PaginationModel, ThumbnailService
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging } from 'alfresco-js-api'; import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging } from 'alfresco-js-api';
@@ -243,7 +243,8 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
private appConfig: AppConfigService, private appConfig: AppConfigService,
private preferences: UserPreferencesService, private preferences: UserPreferencesService,
private customResourcesService: CustomResourcesService, private customResourcesService: CustomResourcesService,
private contentService: ContentService) { private contentService: ContentService,
private thumbnailService: ThumbnailService) {
} }
getContextActions(node: MinimalNodeEntity) { getContextActions(node: MinimalNodeEntity) {
@@ -333,7 +334,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
ngOnInit() { ngOnInit() {
this.loadLayoutPresets(); this.loadLayoutPresets();
this.data = new ShareDataTableAdapter(this.documentListService, null, this.getDefaultSorting(), this.sortingMode); this.data = new ShareDataTableAdapter(this.documentListService, this.thumbnailService, null, this.getDefaultSorting(), this.sortingMode);
this.data.thumbnails = this.thumbnails; this.data.thumbnails = this.thumbnails;
this.data.permissionsStyle = this.permissionsStyle; this.data.permissionsStyle = this.permissionsStyle;
@@ -371,7 +372,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
} }
if (!this.data) { if (!this.data) {
this.data = new ShareDataTableAdapter(this.documentListService, schema, this.getDefaultSorting(), this.sortingMode); this.data = new ShareDataTableAdapter(this.documentListService, this.thumbnailService, schema, this.getDefaultSorting(), this.sortingMode);
} else if (schema && schema.length > 0) { } else if (schema && schema.length > 0) {
this.data.setColumns(schema); this.data.setColumns(schema);
} }
@@ -384,7 +385,10 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
this.resetSelection(); this.resetSelection();
if (this.data) {
this.data.thumbnails = this.thumbnails;
}
if (changes.sortingMode && !changes.sortingMode.firstChange && this.data) { if (changes.sortingMode && !changes.sortingMode.firstChange && this.data) {
this.data.sortingMode = changes.sortingMode.currentValue; this.data.sortingMode = changes.sortingMode.currentValue;
} }

View File

@@ -15,8 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { DataRow } from '@alfresco/adf-core'; import { DataRow, ObjectUtils, ThumbnailService } from '@alfresco/adf-core';
import { ObjectUtils } from '@alfresco/adf-core';
import { MinimalNode, MinimalNodeEntity } from 'alfresco-js-api'; import { MinimalNode, MinimalNodeEntity } from 'alfresco-js-api';
import { PermissionStyleModel } from './../models/permissions-style.model'; import { PermissionStyleModel } from './../models/permissions-style.model';
import { DocumentListService } from './../services/document-list.service'; import { DocumentListService } from './../services/document-list.service';
@@ -34,7 +33,10 @@ export class ShareDataRow implements DataRow {
return this.obj; return this.obj;
} }
constructor(private obj: MinimalNodeEntity, private documentListService: DocumentListService, private permissionsStyle: PermissionStyleModel[]) { constructor(private obj: MinimalNodeEntity,
private documentListService: DocumentListService,
private permissionsStyle: PermissionStyleModel[],
private thumbnailService?: ThumbnailService) {
if (!obj) { if (!obj) {
throw new Error(ShareDataRow.ERR_OBJECT_NOT_FOUND); throw new Error(ShareDataRow.ERR_OBJECT_NOT_FOUND);
} }
@@ -91,6 +93,10 @@ export class ShareDataRow implements DataRow {
return ObjectUtils.getValue(this.obj.entry, key); return ObjectUtils.getValue(this.obj.entry, key);
} }
imageErrorResolver(event: Event): any {
return this.thumbnailService.getMimeTypeIcon(this.obj.entry.content.mimeType);
}
hasValue(key: string): boolean { hasValue(key: string): boolean {
return this.getValue(key) !== undefined; return this.getValue(key) !== undefined;
} }

View File

@@ -33,12 +33,12 @@ describe('ShareDataTableAdapter', () => {
}); });
it('should use client sorting by default', () => { it('should use client sorting by default', () => {
const adapter = new ShareDataTableAdapter(documentListService, []); const adapter = new ShareDataTableAdapter(documentListService, null, []);
expect(adapter.sortingMode).toBe('client'); expect(adapter.sortingMode).toBe('client');
}); });
it('should not be case sensitive for sorting mode value', () => { it('should not be case sensitive for sorting mode value', () => {
const adapter = new ShareDataTableAdapter(documentListService, []); const adapter = new ShareDataTableAdapter(documentListService, null, []);
adapter.sortingMode = 'CLIENT'; adapter.sortingMode = 'CLIENT';
expect(adapter.sortingMode).toBe('client'); expect(adapter.sortingMode).toBe('client');
@@ -48,7 +48,7 @@ describe('ShareDataTableAdapter', () => {
}); });
it('should fallback to client sorting for unknown values', () => { it('should fallback to client sorting for unknown values', () => {
const adapter = new ShareDataTableAdapter(documentListService, []); const adapter = new ShareDataTableAdapter(documentListService, null, []);
adapter.sortingMode = 'SeRvEr'; adapter.sortingMode = 'SeRvEr';
expect(adapter.sortingMode).toBe('server'); expect(adapter.sortingMode).toBe('server');
@@ -59,28 +59,27 @@ describe('ShareDataTableAdapter', () => {
it('should setup rows and columns with constructor', () => { it('should setup rows and columns with constructor', () => {
let schema = [<DataColumn> {}]; let schema = [<DataColumn> {}];
let adapter = new ShareDataTableAdapter(documentListService, schema); let adapter = new ShareDataTableAdapter(documentListService, null, schema);
expect(adapter.getRows()).toEqual([]); expect(adapter.getRows()).toEqual([]);
expect(adapter.getColumns()).toEqual(schema); expect(adapter.getColumns()).toEqual(schema);
}); });
it('should setup columns when constructor is missing schema', () => { it('should setup columns when constructor is missing schema', () => {
let adapter = new ShareDataTableAdapter(documentListService, null); const adapter = new ShareDataTableAdapter(documentListService, null, null);
expect(adapter.getColumns()).toEqual([]); expect(adapter.getColumns()).toEqual([]);
}); });
it('should set new columns', () => { it('should set new columns', () => {
let columns = [<DataColumn> {}, <DataColumn> {}]; let columns = [<DataColumn> {}, <DataColumn> {}];
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
adapter.setColumns(columns); adapter.setColumns(columns);
expect(adapter.getColumns()).toEqual(columns); expect(adapter.getColumns()).toEqual(columns);
}); });
it('should reset columns', () => { it('should reset columns', () => {
let columns = [<DataColumn> {}, <DataColumn> {}]; let columns = [<DataColumn> {}, <DataColumn> {}];
let adapter = new ShareDataTableAdapter(documentListService, columns); let adapter = new ShareDataTableAdapter(documentListService, null, columns);
expect(adapter.getColumns()).toEqual(columns); expect(adapter.getColumns()).toEqual(columns);
adapter.setColumns(null); adapter.setColumns(null);
@@ -89,7 +88,7 @@ describe('ShareDataTableAdapter', () => {
it('should set new rows', () => { it('should set new rows', () => {
let rows = [<DataRow> {}, <DataRow> {}]; let rows = [<DataRow> {}, <DataRow> {}];
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
expect(adapter.getRows()).toEqual([]); expect(adapter.getRows()).toEqual([]);
adapter.setRows(rows); adapter.setRows(rows);
@@ -98,7 +97,7 @@ describe('ShareDataTableAdapter', () => {
it('should reset rows', () => { it('should reset rows', () => {
let rows = [<DataRow> {}, <DataRow> {}]; let rows = [<DataRow> {}, <DataRow> {}];
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
adapter.setRows(rows); adapter.setRows(rows);
expect(adapter.getRows()).toEqual(rows); expect(adapter.getRows()).toEqual(rows);
@@ -108,7 +107,7 @@ describe('ShareDataTableAdapter', () => {
}); });
it('should sort new rows', () => { it('should sort new rows', () => {
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
spyOn(adapter, 'sort').and.callThrough(); spyOn(adapter, 'sort').and.callThrough();
let rows = [<DataRow> {}]; let rows = [<DataRow> {}];
@@ -118,7 +117,7 @@ describe('ShareDataTableAdapter', () => {
}); });
it('should fail when getting value for missing row', () => { it('should fail when getting value for missing row', () => {
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
let check = () => { let check = () => {
return adapter.getValue(null, <DataColumn> {}); return adapter.getValue(null, <DataColumn> {});
}; };
@@ -126,7 +125,7 @@ describe('ShareDataTableAdapter', () => {
}); });
it('should fail when getting value for missing column', () => { it('should fail when getting value for missing column', () => {
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
let check = () => { let check = () => {
return adapter.getValue(<DataRow> {}, null); return adapter.getValue(<DataRow> {}, null);
}; };
@@ -145,7 +144,7 @@ describe('ShareDataTableAdapter', () => {
}; };
let row = new ShareDataRow(file, documentListService, null); let row = new ShareDataRow(file, documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
let value = adapter.getValue(row, col); let value = adapter.getValue(row, col);
expect(value).toBe(rawValue); expect(value).toBe(rawValue);
@@ -154,7 +153,7 @@ describe('ShareDataTableAdapter', () => {
it('should generate fallback icon for a file thumbnail with missing mime type', () => { it('should generate fallback icon for a file thumbnail with missing mime type', () => {
spyOn(documentListService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneouse.svg`); spyOn(documentListService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneouse.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
let file = new FileNode(); let file = new FileNode();
file.entry.content.mimeType = null; file.entry.content.mimeType = null;
@@ -170,7 +169,7 @@ describe('ShareDataTableAdapter', () => {
it('should generate fallback icon for a file with no content entry', () => { it('should generate fallback icon for a file with no content entry', () => {
spyOn(documentListService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneouse.svg`); spyOn(documentListService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneouse.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
let file = new FileNode(); let file = new FileNode();
file.entry.content = null; file.entry.content = null;
@@ -189,7 +188,7 @@ describe('ShareDataTableAdapter', () => {
let file = new FileNode(); let file = new FileNode();
file.entry['icon'] = imageUrl; file.entry['icon'] = imageUrl;
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
let row = new ShareDataRow(file, documentListService, null); let row = new ShareDataRow(file, documentListService, null);
let col = <DataColumn> { type: 'image', key: 'icon' }; let col = <DataColumn> { type: 'image', key: 'icon' };
@@ -200,7 +199,7 @@ describe('ShareDataTableAdapter', () => {
it('should resolve folder icon', () => { it('should resolve folder icon', () => {
spyOn(documentListService, 'getMimeTypeIcon').and.returnValue(`assets/images/ft_ic_folder.svg`); spyOn(documentListService, 'getMimeTypeIcon').and.returnValue(`assets/images/ft_ic_folder.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
let row = new ShareDataRow(new FolderNode(), documentListService, null); let row = new ShareDataRow(new FolderNode(), documentListService, null);
let col = <DataColumn> { type: 'image', key: '$thumbnail' }; let col = <DataColumn> { type: 'image', key: '$thumbnail' };
@@ -212,7 +211,7 @@ describe('ShareDataTableAdapter', () => {
it('should resolve file thumbnail', () => { it('should resolve file thumbnail', () => {
let imageUrl = 'http://<addresss>'; let imageUrl = 'http://<addresss>';
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
adapter.thumbnails = true; adapter.thumbnails = true;
let file = new FileNode(); let file = new FileNode();
@@ -227,7 +226,7 @@ describe('ShareDataTableAdapter', () => {
it('should resolve fallback file icon for unknown node', () => { it('should resolve fallback file icon for unknown node', () => {
spyOn(documentListService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneous.svg`); spyOn(documentListService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneous.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
let file = new FileNode(); let file = new FileNode();
file.entry.isFile = false; file.entry.isFile = false;
@@ -244,7 +243,7 @@ describe('ShareDataTableAdapter', () => {
it('should resolve file icon for content type', () => { it('should resolve file icon for content type', () => {
spyOn(documentListService, 'getMimeTypeIcon').and.returnValue(`assets/images/ft_ic_raster_image.svg`); spyOn(documentListService, 'getMimeTypeIcon').and.returnValue(`assets/images/ft_ic_raster_image.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null); let adapter = new ShareDataTableAdapter(documentListService, null, null);
let file = new FileNode(); let file = new FileNode();
file.entry.isFile = false; file.entry.isFile = false;
@@ -265,7 +264,7 @@ describe('ShareDataTableAdapter', () => {
let folder = new FolderNode(); let folder = new FolderNode();
let col = <DataColumn> { key: 'name' }; let col = <DataColumn> { key: 'name' };
let adapter = new ShareDataTableAdapter(documentListService, [col]); let adapter = new ShareDataTableAdapter(documentListService, null, [col]);
adapter.setSorting(new DataSorting('name', 'asc')); adapter.setSorting(new DataSorting('name', 'asc'));
adapter.setRows([ adapter.setRows([
@@ -288,7 +287,7 @@ describe('ShareDataTableAdapter', () => {
file2.entry['dateProp'] = new Date(2016, 6, 30, 13, 14, 2); file2.entry['dateProp'] = new Date(2016, 6, 30, 13, 14, 2);
let col = <DataColumn> { key: 'dateProp' }; let col = <DataColumn> { key: 'dateProp' };
let adapter = new ShareDataTableAdapter(documentListService, [col]); let adapter = new ShareDataTableAdapter(documentListService, null, [col]);
adapter.setRows([ adapter.setRows([
new ShareDataRow(file2, documentListService, null), new ShareDataRow(file2, documentListService, null),
@@ -318,7 +317,7 @@ describe('ShareDataTableAdapter', () => {
file4.entry.content.sizeInBytes = 2852791665; // 2.66 GB file4.entry.content.sizeInBytes = 2852791665; // 2.66 GB
let col = <DataColumn> { key: 'content.sizeInBytes' }; let col = <DataColumn> { key: 'content.sizeInBytes' };
let adapter = new ShareDataTableAdapter(documentListService, [col]); let adapter = new ShareDataTableAdapter(documentListService, null, [col]);
adapter.setRows([ adapter.setRows([
new ShareDataRow(file3, documentListService, null), new ShareDataRow(file3, documentListService, null),
@@ -351,7 +350,7 @@ describe('ShareDataTableAdapter', () => {
let file6 = new FileNode('b'); let file6 = new FileNode('b');
let col = <DataColumn> { key: 'name' }; let col = <DataColumn> { key: 'name' };
let adapter = new ShareDataTableAdapter(documentListService, [col]); let adapter = new ShareDataTableAdapter(documentListService, null, [col]);
adapter.setRows([ adapter.setRows([
new ShareDataRow(file4, documentListService, null), new ShareDataRow(file4, documentListService, null),

View File

@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { DataColumn, DataRow, DataSorting, DataTableAdapter } from '@alfresco/adf-core'; import { DataColumn, DataRow, DataSorting, DataTableAdapter, ThumbnailService } from '@alfresco/adf-core';
import { NodePaging } from 'alfresco-js-api'; import { NodePaging } from 'alfresco-js-api';
import { PermissionStyleModel } from './../models/permissions-style.model'; import { PermissionStyleModel } from './../models/permissions-style.model';
import { DocumentListService } from './../services/document-list.service'; import { DocumentListService } from './../services/document-list.service';
@@ -51,6 +51,7 @@ export class ShareDataTableAdapter implements DataTableAdapter {
} }
constructor(private documentListService: DocumentListService, constructor(private documentListService: DocumentListService,
private thumbnailService: ThumbnailService,
schema: DataColumn[] = [], schema: DataColumn[] = [],
sorting?: DataSorting, sorting?: DataSorting,
sortingMode: string = 'client') { sortingMode: string = 'client') {
@@ -207,7 +208,7 @@ export class ShareDataTableAdapter implements DataTableAdapter {
if (page && page.list) { if (page && page.list) {
let data = page.list.entries; let data = page.list.entries;
if (data && data.length > 0) { if (data && data.length > 0) {
rows = data.map(item => new ShareDataRow(item, this.documentListService, this.permissionsStyle)); rows = data.map(item => new ShareDataRow(item, this.documentListService, this.permissionsStyle, this.thumbnailService));
if (this.filter) { if (this.filter) {
rows = rows.filter(this.filter); rows = rows.filter(this.filter);

View File

@@ -93,16 +93,17 @@
<div *ngIf="!col.template" class="cell-container"> <div *ngIf="!col.template" class="cell-container">
<ng-container [ngSwitch]="col.type"> <ng-container [ngSwitch]="col.type">
<div *ngSwitchCase="'image'" class="cell-value"> <div *ngSwitchCase="'image'" class="cell-value">
<mat-icon *ngIf="isIconValue(row, col); else no_iconvalue">{{ asIconValue(row, col) }}</mat-icon> <mat-icon *ngIf="isIconValue(row, col); else no_iconvalue">{{ asIconValue(row, col) }}
</mat-icon>
<ng-template #no_iconvalue> <ng-template #no_iconvalue>
<mat-icon class="adf-datatable-selected" <mat-icon class="adf-datatable-selected"
*ngIf="row.isSelected; else no_selected_row" svgIcon="selected"> *ngIf="row.isSelected; else no_selected_row" svgIcon="selected">
</mat-icon> </mat-icon>
<ng-template #no_selected_row> <ng-template #no_selected_row>
<img <img
alt="{{ iconAltTextKey(data.getValue(row, col)) | translate }}" alt="{{ iconAltTextKey(data.getValue(row, col)) | translate }}"
src="{{ data.getValue(row, col) }}" src="{{ data.getValue(row, col) }}"
(error)="onImageLoadingError($event, row.obj.entry.content.mimeType)"> (error)="onImageLoadingError($event, row)">
</ng-template> </ng-template>
</ng-template> </ng-template>
</div> </div>
@@ -206,7 +207,7 @@
<div *ngIf="loading" <div *ngIf="loading"
[class.adf-datatable-row]="display === 'list'" [class.adf-datatable-row]="display === 'list'"
[class.adf-data-table-card-loading]="display === 'gallery'"> [class.adf-data-table-card-loading]="display === 'gallery'">
<div class="adf-datatable-table-cell" > <div class="adf-datatable-table-cell">
<ng-template *ngIf="loadingTemplate" <ng-template *ngIf="loadingTemplate"
ngFor [ngForOf]="[data]" ngFor [ngForOf]="[data]"
[ngForTemplate]="loadingTemplate"> [ngForTemplate]="loadingTemplate">

View File

@@ -29,7 +29,22 @@ import { CoreTestingModule } from '../../../testing/core.testing.module';
import { DataColumnListComponent } from '../../../data-column/data-column-list.component'; import { DataColumnListComponent } from '../../../data-column/data-column-list.component';
import { DataColumnComponent } from '../../../data-column/data-column.component'; import { DataColumnComponent } from '../../../data-column/data-column.component';
describe('DataTable', () => { class FakeDataRow implements DataRow {
isDropTarget = false;
isSelected = true;
hasValue(key: any) {
return true;
}
getValue() {
return '1';
}
imageErrorResolver() {
return './assets/images/ft_ic_miscellaneous.svg';
}
}
/*tslint:disable:ban*/
fdescribe('DataTable', () => {
let fixture: ComponentFixture<DataTableComponent>; let fixture: ComponentFixture<DataTableComponent>;
let dataTable: DataTableComponent; let dataTable: DataTableComponent;
@@ -881,9 +896,9 @@ describe('DataTable', () => {
src: 'missing-image' src: 'missing-image'
} }
}; };
const row = new FakeDataRow();
dataTable.fallbackThumbnail = '<fallback>'; dataTable.fallbackThumbnail = '<fallback>';
dataTable.onImageLoadingError(event); dataTable.onImageLoadingError(event, row);
expect(event.target.src).toBe(dataTable.fallbackThumbnail); expect(event.target.src).toBe(dataTable.fallbackThumbnail);
}); });
@@ -894,23 +909,12 @@ describe('DataTable', () => {
src: originalSrc src: originalSrc
} }
}; };
const row = new FakeDataRow();
dataTable.fallbackThumbnail = null; dataTable.fallbackThumbnail = null;
dataTable.onImageLoadingError(event); dataTable.onImageLoadingError(event, row);
expect(event.target.src).toBe('./assets/images/ft_ic_miscellaneous.svg' ); expect(event.target.src).toBe('./assets/images/ft_ic_miscellaneous.svg' );
}); });
it('should replace image source with icon if fallback is not available and mimeType is provided', () => {
let event = <any> {
target: {
src: 'missing-image'
}
};
dataTable.onImageLoadingError(event, 'image/png');
expect(event.target.src).toBe('./assets/images/ft_ic_raster_image.svg');
});
it('should not get cell tooltip when row is not provided', () => { it('should not get cell tooltip when row is not provided', () => {
const col = <DataColumn> { key: 'name', type: 'text' }; const col = <DataColumn> { key: 'name', type: 'text' };
expect(dataTable.getCellTooltip(null, col)).toBeNull(); expect(dataTable.getCellTooltip(null, col)).toBeNull();

View File

@@ -27,7 +27,6 @@ import { DataRowEvent } from '../../data/data-row-event.model';
import { DataRow } from '../../data/data-row.model'; import { DataRow } from '../../data/data-row.model';
import { DataSorting } from '../../data/data-sorting.model'; import { DataSorting } from '../../data/data-sorting.model';
import { DataTableAdapter } from '../../data/datatable-adapter'; import { DataTableAdapter } from '../../data/datatable-adapter';
import { ThumbnailService } from '../../../services/thumbnail.service';
import { ObjectDataRow } from '../../data/object-datarow.model'; import { ObjectDataRow } from '../../data/object-datarow.model';
import { ObjectDataTableAdapter } from '../../data/object-datatable-adapter'; import { ObjectDataTableAdapter } from '../../data/object-datatable-adapter';
@@ -175,8 +174,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
private dataRowsChanged: Subscription; private dataRowsChanged: Subscription;
constructor(private elementRef: ElementRef, constructor(private elementRef: ElementRef,
differs: IterableDiffers, differs: IterableDiffers) {
private thumbnailService?: ThumbnailService) {
if (differs) { if (differs) {
this.differ = differs.find([]).create(null); this.differ = differs.find([]).create(null);
} }
@@ -511,15 +509,14 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
this.emitRowSelectionEvent(domEventName, row); this.emitRowSelectionEvent(domEventName, row);
} }
onImageLoadingError(event: Event, mimeType?: string) { onImageLoadingError(event: Event, row: DataRow) {
if (event) { if (event) {
let element = <any> event.target; let element = <any> event.target;
if (this.fallbackThumbnail) { if (this.fallbackThumbnail) {
element.src = this.fallbackThumbnail; element.src = this.fallbackThumbnail;
} else { } else {
element.src = this.thumbnailService.getMimeTypeIcon(mimeType); element.src = row.imageErrorResolver(event);
} }
} }
} }

View File

@@ -19,6 +19,10 @@ export interface DataRow {
isSelected: boolean; isSelected: boolean;
isDropTarget?: boolean; isDropTarget?: boolean;
cssClass?: string; cssClass?: string;
hasValue(key: string): boolean; hasValue(key: string): boolean;
getValue(key: string): any; getValue(key: string): any;
imageErrorResolver?(event: Event): any;
} }

View File

@@ -35,4 +35,8 @@ export class ObjectDataRow implements DataRow {
hasValue(key: string): boolean { hasValue(key: string): boolean {
return this.getValue(key) !== undefined; return this.getValue(key) !== undefined;
} }
imageErrorResolver(event: Event): string {
return '';
}
} }

View File

@@ -31,27 +31,23 @@ describe('ProcessFiltersComponent', () => {
let mockErrorFilterPromise; let mockErrorFilterPromise;
beforeEach(() => { beforeEach(() => {
fakeGlobalFilterPromise = new Promise(function (resolve, reject) { fakeGlobalFilterPromise = Promise.resolve([
resolve([ new FilterProcessRepresentationModel({
new FilterProcessRepresentationModel({ name: 'FakeInvolvedTasks',
name: 'FakeInvolvedTasks', filter: { state: 'open', assignment: 'fake-involved' }
filter: { state: 'open', assignment: 'fake-involved' } }),
}), new FilterProcessRepresentationModel({
new FilterProcessRepresentationModel({ name: 'FakeMyTasks',
name: 'FakeMyTasks', filter: { state: 'open', assignment: 'fake-assignee' }
filter: { state: 'open', assignment: 'fake-assignee' } }),
}), new FilterProcessRepresentationModel({
new FilterProcessRepresentationModel({ name: 'Running',
name: 'Running', filter: { state: 'open', assignment: 'fake-running' }
filter: { state: 'open', assignment: 'fake-running' } })
}) ]);
]);
});
mockErrorFilterPromise = new Promise(function (resolve, reject) { mockErrorFilterPromise = Promise.reject({
reject({ error: 'wrong request'
error: 'wrong request'
});
}); });
processFilterService = new ProcessFilterService(null); processFilterService = new ProcessFilterService(null);
@@ -96,12 +92,7 @@ describe('ProcessFiltersComponent', () => {
}); });
it('should return the filter task list, filtered By Name', (done) => { it('should return the filter task list, filtered By Name', (done) => {
spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(Observable.fromPromise(Promise.resolve({ id: 1 })));
let fakeDeployedApplicationsPromise = new Promise(function (resolve, reject) {
resolve({ id: 1 });
});
spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(Observable.fromPromise(fakeDeployedApplicationsPromise));
spyOn(processFilterService, 'getProcessFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise)); spyOn(processFilterService, 'getProcessFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
let change = new SimpleChange(null, 'test', true); let change = new SimpleChange(null, 'test', true);

View File

@@ -64,9 +64,7 @@ describe('TaskFiltersComponent', () => {
error: 'wrong request' error: 'wrong request'
}; };
let mockErrorFilterPromise = new Promise(function (resolve, reject) { let mockErrorFilterPromise = new Promise.reject(mockErrorFilterList);
reject(mockErrorFilterList);
});
let component: TaskFiltersComponent; let component: TaskFiltersComponent;
let fixture: ComponentFixture<TaskFiltersComponent>; let fixture: ComponentFixture<TaskFiltersComponent>;
@@ -180,7 +178,7 @@ describe('TaskFiltersComponent', () => {
it('should select the task filter based on the input by name param', (done) => { it('should select the task filter based on the input by name param', (done) => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise)); spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
component.filterParam = new FilterParamsModel({name: 'FakeMyTasks1'}); component.filterParam = new FilterParamsModel({ name: 'FakeMyTasks1' });
const appId = '1'; const appId = '1';
let change = new SimpleChange(null, appId, true); let change = new SimpleChange(null, appId, true);
@@ -199,7 +197,7 @@ describe('TaskFiltersComponent', () => {
it('should select the default task filter if filter input does not exist', (done) => { it('should select the default task filter if filter input does not exist', (done) => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise)); spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
component.filterParam = new FilterParamsModel({name: 'UnexistableFilter'}); component.filterParam = new FilterParamsModel({ name: 'UnexistableFilter' });
const appId = '1'; const appId = '1';
let change = new SimpleChange(null, appId, true); let change = new SimpleChange(null, appId, true);
@@ -219,7 +217,7 @@ describe('TaskFiltersComponent', () => {
it('should select the task filter based on the input by index param', (done) => { it('should select the task filter based on the input by index param', (done) => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise)); spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
component.filterParam = new FilterParamsModel({index: 2}); component.filterParam = new FilterParamsModel({ index: 2 });
const appId = '1'; const appId = '1';
let change = new SimpleChange(null, appId, true); let change = new SimpleChange(null, appId, true);
@@ -239,7 +237,7 @@ describe('TaskFiltersComponent', () => {
it('should select the task filter based on the input by id param', (done) => { it('should select the task filter based on the input by id param', (done) => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise)); spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
component.filterParam = new FilterParamsModel({id: 10}); component.filterParam = new FilterParamsModel({ id: 10 });
const appId = '1'; const appId = '1';
let change = new SimpleChange(null, appId, true); let change = new SimpleChange(null, appId, true);
@@ -289,18 +287,18 @@ describe('TaskFiltersComponent', () => {
expect(component.getFiltersByAppId).toHaveBeenCalledWith(appId); expect(component.getFiltersByAppId).toHaveBeenCalledWith(appId);
}); });
it('should change current filter when filterParam (id) changes', async() => { it('should change current filter when filterParam (id) changes', async () => {
component.filters = fakeGlobalFilter; component.filters = fakeGlobalFilter;
component.currentFilter = null; component.currentFilter = null;
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
expect(component.currentFilter.id).toEqual(fakeGlobalFilter[2].id); expect(component.currentFilter.id).toEqual(fakeGlobalFilter[2].id);
}); });
const change = new SimpleChange(null, {id : fakeGlobalFilter[2].id}, true); const change = new SimpleChange(null, { id: fakeGlobalFilter[2].id }, true);
component.ngOnChanges({ 'filterParam': change }); component.ngOnChanges({ 'filterParam': change });
}); });
it('should change current filter when filterParam (name) changes', async() => { it('should change current filter when filterParam (name) changes', async () => {
component.filters = fakeGlobalFilter; component.filters = fakeGlobalFilter;
component.currentFilter = null; component.currentFilter = null;
@@ -308,7 +306,7 @@ describe('TaskFiltersComponent', () => {
expect(component.currentFilter.name).toEqual(fakeGlobalFilter[2].name); expect(component.currentFilter.name).toEqual(fakeGlobalFilter[2].name);
}); });
const change = new SimpleChange(null, {name : fakeGlobalFilter[2].name}, true); const change = new SimpleChange(null, { name: fakeGlobalFilter[2].name }, true);
component.ngOnChanges({ 'filterParam': change }); component.ngOnChanges({ 'filterParam': change });
}); });

View File

@@ -241,7 +241,7 @@ describe('TaskHeaderComponent', () => {
})); }));
it('should call the service\'s unclaim method on unclaiming', async(() => { it('should call the service\'s unclaim method on unclaiming', async(() => {
spyOn(service, 'unclaimTask'); spyOn(service, 'unclaimTask').and.returnValue(Observable.of(true));
component.taskDetails = new TaskDetailsModel(claimedTaskDetailsMock); component.taskDetails = new TaskDetailsModel(claimedTaskDetailsMock);
component.refreshData(); component.refreshData();
fixture.detectChanges(); fixture.detectChanges();