#340 document list now wraps and extends datatable

This commit is contained in:
Denys Vuika
2016-07-05 14:19:07 +01:00
parent f54955b8eb
commit e414135bd2
9 changed files with 132 additions and 180 deletions

View File

@@ -10,6 +10,8 @@
<alfresco-document-list
#documentList
[currentFolderPath]="currentPath"
[contextMenuActions]="true"
[contentActions]="true"
(preview)="showFile($event)"
(folderChange)="onFolderChanged($event)">
<!--

View File

@@ -14,9 +14,25 @@
:host .data-cell {
cursor: default;
}
:host .cell-value {}
:host .column-header {
cursor: pointer;
user-select: none;
-webkit-user-select: none; /* Chrome/Safari/Opera */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
-webkit-touch-callout: none; /* iOS Safari */
}
/* Empty folder */
:host .no-content-container {
padding: 0 !important;
}
:host .no-content-container > img {
width: 100%;
}
/* Utils */

View File

@@ -15,6 +15,7 @@
</th>
<th class="mdl-data-table__cell--non-numeric non-selectable {{col.cssClass}}"
*ngFor="let col of data.getColumns()"
[attr.data-automation-id]="'auto_id_' + col.key"
[class.column-header]="col.title"
[class.mdl-data-table__header--sorted-ascending]="isColumnSorted(col, 'asc')"
[class.mdl-data-table__header--sorted-descending]="isColumnSorted(col, 'desc')"
@@ -43,7 +44,7 @@
class="mdl-data-table__cell--non-numeric non-selectable data-cell {{col.cssClass}}"
(click)="onRowClick(row, $event)"
(dblclick)="onRowDblClick(row, $event)"
[context-menu]="getContextActions(row, col)">
[context-menu]="getContextMenuActions(row, col)">
<div *ngSwitchCase="'image'" class="cell-value">
<i *ngIf="isIconValue(row, col)" class="material-icons icon-cell">{{asIconValue(row, col)}}</i>
<img *ngIf="!isIconValue(row, col)" class="image-cell" alt="" src="{{data.getValue(row, col)}}">
@@ -60,11 +61,25 @@
</td>
<td *ngIf="actions"><!-- todo: actions --></td>
<td *ngIf="actions">
<!-- action menu -->
<button [id]="'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]="'action_menu_' + idx">
<li class="mdl-menu__item"
[attr.data-automation-id]="action.title"
*ngFor="let action of getRowActions(row)"
(click)="onExecuteRowAction(row, action)">
{{action.title}}
</li>
</ul>
</td>
</tr>
<tr *ngIf="data.getRows().length === 0">
<td class="mdl-data-table__cell--non-numeric empty-folder-content"
<td class="mdl-data-table__cell--non-numeric no-content-container"
[attr.colspan]="1 + data.getColumns().length">
<template *ngIf="noContentTemplate"
ngFor [ngForOf]="[data]"

View File

@@ -26,7 +26,6 @@ import {
TemplateRef
} from '@angular/core';
// import { Subject } from 'rxjs/Rx';
import { CONTEXT_MENU_DIRECTIVES } from 'ng2-alfresco-core';
import {
@@ -70,7 +69,13 @@ export class DataTableComponent implements OnInit, AfterViewChecked {
isSelectAllChecked: boolean = false;
@Output()
showContextMenu: EventEmitter<any> = new EventEmitter();
showRowContextMenu: EventEmitter<any> = new EventEmitter();
@Output()
showRowActionsMenu: EventEmitter<any> = new EventEmitter();
@Output()
executeRowAction: EventEmitter<any> = new EventEmitter();
// TODO: left for reference, will be removed during future revisions
constructor(/*private _ngZone?: NgZone*/) {
@@ -169,9 +174,20 @@ export class DataTableComponent implements OnInit, AfterViewChecked {
return false;
}
getContextActions(row: DataRow, col: DataColumn) {
getContextMenuActions(row: DataRow, col: DataColumn) {
let args = { row: row, col: col, actions: [] };
this.showContextMenu.emit({ args: args });
this.showRowContextMenu.emit({ args: args });
return args.actions;
}
getRowActions(row: DataRow, col: DataColumn) {
let args = { row: row, col: col, actions: [] };
this.showRowActionsMenu.emit({ args: args });
return args.actions;
}
onExecuteRowAction(row: DataRow, action: any) {
let args = { row: row, action: action };
this.executeRowAction.emit({ args: args });
}
}

View File

@@ -55,6 +55,9 @@ import {
<alfresco-document-list #doclist
#documentList
[currentFolderPath]="currentPath"
[contextMenuActions]="true"
[contentActions]="true"
[multiselect]="true"
(folderChange)="onFolderChanged($event)">
<!--
<empty-folder-content>

View File

@@ -1,60 +1,5 @@
:host .full-width { width: 100%; }
:host .thumbnail {
width: 48px;
height: 48px;
cursor: default;
}
:host .column-header {
cursor: pointer;
user-select: none;
-webkit-user-select: none; /* Chrome/Safari/Opera */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
-webkit-touch-callout: none; /* iOS Safari */
}
:host .parent-folder-link { cursor: default; }
:host .parent-folder-link > td { text-align: left; }
:host .data-cell {
cursor: default;
}
:host .cell-value {}
/* Empty folder */
:host .empty-folder-content {
padding: 0 !important;
}
:host .empty-folder-content > img {
width: 100%;
}
/* Utils */
:host .non-selectable {
user-select: none;
-webkit-user-select: none; /* Chrome/Safari/Opera */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
-webkit-touch-callout: none; /* iOS Safari */
}
:host .sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}
:host .ellipsis-cell > div
{
position: relative;

View File

@@ -1,6 +1,10 @@
<alfresco-datatable
[data]="data"
(showContextMenu)="onRowContextMenu($event)"
[actions]="contentActions"
[multiselect]="multiselect"
(showRowContextMenu)="onShowRowContextMenu($event)"
(showRowActionsMenu)="onShowRowActionsMenu($event)"
(executeRowAction)="onExecuteRowAction($event)"
(rowClick)="onRowClick($event)"
(rowDblClick)="onRowDblClick($event)">
<no-content-template>
@@ -9,107 +13,3 @@
</template>
</no-content-template>
</alfresco-datatable>
<table *ngIf="folder" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
<thead>
<tr>
<!-- Columns -->
<th class="mdl-data-table__cell--non-numeric non-selectable {{col.cssClass}}"
*ngFor="let col of columns"
[class.column-header]="col.title"
[attr.data-automation-id]="'auto_id_' + col.source"
[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'"
(click)="onColumnHeaderClick(col)">
<span *ngIf="col.srTitle" class="cell-value sr-only">{{col.srTitle}}</span>
<span *ngIf="col.title" class="cell-value">{{col.title}}</span>
</th>
<!-- Actions -->
<th>
<span class="sr-only">Actions</span>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let content of folder.list.entries; let idx = index"
[attr.data-automation-id]="getObjectValue(content.entry, 'name')">
<!-- Columns -->
<td *ngFor="let col of columns" [ngSwitch]="col.type"
class="mdl-data-table__cell--non-numeric non-selectable data-cell {{col.cssClass}}"
(click)="onItemClick(content, $event)"
(dblclick)="onItemDblClick(content, $event)"
[context-menu]="getContextActions(content)"
[attr.data-automation-id]="col.source === '$thumbnail' ? '$thumbnail' : col.source + '_' + getObjectValue(content.entry, col.source)">
<div *ngSwitchCase="'image'" class="cell-value">
<img class="thumbnail" [src]="getCellValue(content, col)">
</div>
<div *ngSwitchCase="'date'" class="cell-value">
<span>{{ getCellValue(content, col) }}</span>
</div>
<div *ngSwitchDefault class="cell-value">
<span>{{ getCellValue(content, col) }}</span>
</div>
</td>
<!-- Actions: folder -->
<td *ngIf="content.entry.isFolder">
<!-- action buttons -->
<button class="mdl-button mdl-js-button mdl-button--icon"
*ngFor="let action of getContentActions('folder', 'button')"
(click)="executeContentAction(content, action)">
<i class="material-icons">{{action.icon}}</i>
</button>
<!-- 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"
[attr.data-automation-id]="action.title"
*ngFor="let 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="let 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"
[attr.data-automation-id]="action.title"
*ngFor="let action of getContentActions('document', 'menu')"
(click)="executeContentAction(content, action)">
{{action.title}}
</li>
</ul>
</td>
</tr>
<tr *ngIf="folder?.list?.entries?.length === 0">
<td class="mdl-data-table__cell--non-numeric empty-folder-content"
[attr.colspan]="1 + columns?.length">
<template *ngIf="emptyFolderTemplate"
ngFor [ngForOf]="[folder]"
[ngForTemplate]="emptyFolderTemplate">
</template>
<img *ngIf="!emptyFolderTemplate"
[src]="baseComponentPath + '/img/document-list.empty-folder.png'">
</td>
</tr>
</tbody>
</table>

View File

@@ -79,6 +79,15 @@ export class DocumentList implements OnInit, AfterViewInit, AfterViewChecked, Af
@Input()
thumbnails: boolean = false;
@Input()
multiselect: boolean = false;
@Input()
contentActions: boolean = false;
@Input()
contextMenuActions: boolean = false;
@Output()
itemClick: EventEmitter<any> = new EventEmitter();
@@ -182,6 +191,7 @@ export class DocumentList implements OnInit, AfterViewInit, AfterViewChecked, Af
}
ngOnInit() {
this.data.thumbnails = this.thumbnails;
this.displayFolderContent(this.currentFolderPath);
this.contextActionHandler.subscribe(val => this.contextActionCallback(val));
}
@@ -198,10 +208,10 @@ export class DocumentList implements OnInit, AfterViewInit, AfterViewChecked, Af
ngAfterViewInit() {
if (this.dataTable) {
// this.dataTable.contextActionResolver = this.resolveContextAction;
if (this.emptyFolderTemplate) {
this.dataTable.noContentTemplate = this.emptyFolderTemplate;
}
}
}
@@ -233,6 +243,20 @@ export class DocumentList implements OnInit, AfterViewInit, AfterViewChecked, Af
return [];
}
getNodeActions(node: MinimalNodeEntity): ContentActionModel[] {
let target = null;
if (node.entry.isFile) {
target = 'document';
}
if (node.entry.isFolder) {
target = 'folder';
}
return this.getContentActions(target, 'menu');
}
/**
* Invoked when list row is clicked.
* @param item Underlying node item
@@ -549,11 +573,33 @@ export class DocumentList implements OnInit, AfterViewInit, AfterViewChecked, Af
this.data.setSorting(new DataSorting('id', 'asc'));
}
onRowContextMenu(event) {
let args = event.args;
let node = (<ShareDataRow> args.row).node;
if (node) {
args.actions = this.getContextActions(node) || [];
onShowRowContextMenu(event) {
if (this.contextMenuActions) {
let args = event.args;
let node = (<ShareDataRow> args.row).node;
if (node) {
args.actions = this.getContextActions(node) || [];
}
}
};
}
onShowRowActionsMenu(event) {
if (this.contentActions) {
let args = event.args;
let node = (<ShareDataRow> args.row).node;
if (node) {
args.actions = this.getNodeActions(node) || [];
}
}
}
onExecuteRowAction(event) {
if (this.contentActions) {
let args = event.args;
let node = (<ShareDataRow> args.row).node;
let action = (<ContentActionModel> args.action);
this.executeContentAction(node, action);
}
}
}

View File

@@ -25,13 +25,14 @@ import {
import { NodePaging, MinimalNodeEntity } from './../models/document-library.model';
import { AlfrescoService as DataService } from './../services/alfresco.service';
export class ShareDataTableAdapter implements DataTableAdapter {
private sorting: DataSorting;
private rows: DataRow[];
private columns: DataColumn[];
thumbnails: boolean = false;
constructor(private dataService: DataService,
private basePath: string,
schema: DataColumn[]) {
@@ -84,14 +85,22 @@ export class ShareDataTableAdapter implements DataTableAdapter {
if (col.type === 'image') {
if (col.key === '$thumbnail') {
let isFolder = <boolean> row.getValue('isFolder');
if (isFolder) {
let node = (<ShareDataRow> row).node;
if (node.entry.isFolder) {
return `${this.basePath}/img/ft_ic_folder.svg`;
}
let isFile = <boolean> row.getValue('isFile');
if (isFile) {
let mimeType = row.getValue('content.mimeType');
if (node.entry.isFile) {
if (this.thumbnails) {
if (this.dataService) {
return this.dataService.getDocumentThumbnailUrl(node);
}
return null;
}
let mimeType = node.entry.content.mimeType;
if (mimeType) {
let icon = this.dataService.getMimeTypeIcon(mimeType);
if (icon) {