#340 Empty content template and context menu for datatable

This commit is contained in:
Denys Vuika
2016-07-05 12:37:07 +01:00
parent e3924fdaa3
commit 236926c1ca
9 changed files with 132 additions and 19 deletions

View File

@@ -26,17 +26,20 @@ import { ContextMenuService } from './../services/context-menu.service';
}) })
export class ContextMenuDirective { export class ContextMenuDirective {
@Input('context-menu') @Input('context-menu')
links; links: any[];
constructor( constructor(
private _contextMenuService: ContextMenuService) {} private _contextMenuService: ContextMenuService) {}
onShowContextMenu(event?: MouseEvent) { onShowContextMenu(event?: MouseEvent) {
if (this._contextMenuService) {
this._contextMenuService.show.next({event: event, obj: this.links});
}
if (event) { if (event) {
event.preventDefault(); event.preventDefault();
} }
if (this.links && this.links.length > 0) {
if (this._contextMenuService) {
this._contextMenuService.show.next({event: event, obj: this.links});
}
}
} }
} }

View File

@@ -16,14 +16,17 @@
*/ */
import { DataTableComponent } from './src/components/datatable.component'; import { DataTableComponent } from './src/components/datatable.component';
import { NoContentTemplateComponent } from './src/components/no-content-template.component';
// components // components
export * from './src/components/datatable.component'; export * from './src/components/datatable.component';
export * from './src/components/no-content-template.component';
// data // data
export * from './src/data/datatable-adapter'; export * from './src/data/datatable-adapter';
export * from './src/data/object-datatable-adapter'; export * from './src/data/object-datatable-adapter';
export const ALFRESCO_DATATABLE_DIRECTIVES: [any] = [ export const ALFRESCO_DATATABLE_DIRECTIVES: [any] = [
DataTableComponent DataTableComponent,
NoContentTemplateComponent
]; ];

View File

@@ -66,7 +66,8 @@
"reflect-metadata": "0.1.3", "reflect-metadata": "0.1.3",
"rxjs": "5.0.0-beta.6", "rxjs": "5.0.0-beta.6",
"zone.js": "0.6.12", "zone.js": "0.6.12",
"rimraf": "2.5.2" "rimraf": "2.5.2",
"ng2-alfresco-core": "^0.1.35"
}, },
"peerDependencies": { "peerDependencies": {
"material-design-icons": "^2.2.3", "material-design-icons": "^2.2.3",

View File

@@ -42,7 +42,8 @@
<td *ngFor="let col of data.getColumns()" [ngSwitch]="col.type" <td *ngFor="let col of data.getColumns()" [ngSwitch]="col.type"
class="mdl-data-table__cell--non-numeric non-selectable data-cell {{col.cssClass}}" class="mdl-data-table__cell--non-numeric non-selectable data-cell {{col.cssClass}}"
(click)="onRowClick(row, $event)" (click)="onRowClick(row, $event)"
(dblclick)="onRowDblClick(row, $event)"> (dblclick)="onRowDblClick(row, $event)"
[context-menu]="getContextActions(row, col)">
<div *ngSwitchCase="'image'" class="cell-value"> <div *ngSwitchCase="'image'" class="cell-value">
<i *ngIf="isIconValue(row, col)" class="material-icons icon-cell">{{asIconValue(row, col)}}</i> <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)}}"> <img *ngIf="!isIconValue(row, col)" class="image-cell" alt="" src="{{data.getValue(row, col)}}">
@@ -62,5 +63,14 @@
<td *ngIf="actions"><!-- todo: actions --></td> <td *ngIf="actions"><!-- todo: actions --></td>
</tr> </tr>
<tr *ngIf="data.getRows().length === 0">
<td class="mdl-data-table__cell--non-numeric empty-folder-content"
[attr.colspan]="1 + data.getColumns().length">
<template *ngIf="noContentTemplate"
ngFor [ngForOf]="[data]"
[ngForTemplate]="noContentTemplate">
</template>
</td>
</tr>
</tbody> </tbody>
</table> </table>

View File

@@ -22,9 +22,13 @@ import {
Input, Input,
Output, Output,
EventEmitter, EventEmitter,
AfterViewChecked AfterViewChecked,
TemplateRef
} from '@angular/core'; } from '@angular/core';
// import { Subject } from 'rxjs/Rx';
import { CONTEXT_MENU_DIRECTIVES } from 'ng2-alfresco-core';
import { import {
DataTableAdapter, DataTableAdapter,
DataRow, DataRow,
@@ -41,7 +45,8 @@ declare let __moduleName: string;
moduleId: __moduleName, moduleId: __moduleName,
selector: 'alfresco-datatable', selector: 'alfresco-datatable',
styleUrls: ['./datatable.component.css'], styleUrls: ['./datatable.component.css'],
templateUrl: './datatable.component.html' templateUrl: './datatable.component.html',
directives: [CONTEXT_MENU_DIRECTIVES]
}) })
export class DataTableComponent implements OnInit, AfterViewChecked { export class DataTableComponent implements OnInit, AfterViewChecked {
@@ -55,13 +60,18 @@ export class DataTableComponent implements OnInit, AfterViewChecked {
actions: boolean = false; actions: boolean = false;
@Output() @Output()
rowClick: EventEmitter<DataRowEvent> = new EventEmitter(); rowClick: EventEmitter<DataRowEvent> = new EventEmitter<DataRowEvent>();
@Output() @Output()
rowDblClick: EventEmitter<DataRowEvent> = new EventEmitter(); rowDblClick: EventEmitter<DataRowEvent> = new EventEmitter<DataRowEvent>();
noContentTemplate: TemplateRef<any>;
isSelectAllChecked: boolean = false; isSelectAllChecked: boolean = false;
@Output()
showContextMenu: EventEmitter<any> = new EventEmitter();
// TODO: left for reference, will be removed during future revisions // TODO: left for reference, will be removed during future revisions
constructor(/*private _ngZone?: NgZone*/) { constructor(/*private _ngZone?: NgZone*/) {
} }
@@ -158,4 +168,10 @@ export class DataTableComponent implements OnInit, AfterViewChecked {
} }
return false; return false;
} }
getContextActions(row: DataRow, col: DataColumn) {
let args = { row: row, col: col, actions: [] };
this.showContextMenu.emit({ args: args });
return args.actions;
}
} }

View File

@@ -0,0 +1,41 @@
/*!
* @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 {
Directive,
ContentChild,
TemplateRef,
AfterContentInit
} from '@angular/core';
import { DataTableComponent } from './datatable.component';
@Directive({
selector: 'no-content-template'
})
export class NoContentTemplateComponent implements AfterContentInit {
@ContentChild(TemplateRef)
template: any;
constructor(
private dataTable: DataTableComponent) {
}
ngAfterContentInit() {
this.dataTable.noContentTemplate = this.template;
}
}

View File

@@ -56,7 +56,13 @@ import {
#documentList #documentList
[currentFolderPath]="currentPath" [currentFolderPath]="currentPath"
(folderChange)="onFolderChanged($event)"> (folderChange)="onFolderChanged($event)">
<!--
<empty-folder-content>
<template>
<h1>Sorry, no content here</h1>
</template>
</empty-folder-content>
-->
<content-columns> <content-columns>
<content-column source="$thumbnail" type="image"></content-column> <content-column source="$thumbnail" type="image"></content-column>
<content-column <content-column
@@ -195,11 +201,13 @@ class DocumentListDemo implements OnInit {
} }
myCustomAction1(event) { myCustomAction1(event) {
alert('Custom document action for ' + event.value.displayName); let entry = event.value.entry;
alert(`Custom document action for ${entry.name}`);
} }
myFolderAction1(event) { myFolderAction1(event) {
alert('Custom folder action for ' + event.value.displayName); let entry = event.value.entry;
alert(`Custom folder action for ${entry.name}`);
} }
login() { login() {

View File

@@ -1,8 +1,15 @@
<alfresco-datatable <alfresco-datatable
[data]="data" [data]="data"
(showContextMenu)="onRowContextMenu($event)"
(rowClick)="onRowClick($event)" (rowClick)="onRowClick($event)"
(rowDblClick)="onRowDblClick($event)"> (rowDblClick)="onRowDblClick($event)">
<no-content-template>
<template>
<img [src]="baseComponentPath + '/img/document-list.empty-folder.png'">
</template>
</no-content-template>
</alfresco-datatable> </alfresco-datatable>
<table *ngIf="folder" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width"> <table *ngIf="folder" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
<thead> <thead>
<tr> <tr>

View File

@@ -22,10 +22,12 @@ import {
Output, Output,
EventEmitter, EventEmitter,
AfterContentInit, AfterContentInit,
AfterViewInit,
AfterViewChecked, AfterViewChecked,
OnChanges, OnChanges,
TemplateRef, TemplateRef,
NgZone NgZone,
ViewChild
} from '@angular/core'; } from '@angular/core';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { Subject } from 'rxjs/Rx'; import { Subject } from 'rxjs/Rx';
@@ -34,7 +36,8 @@ import { CONTEXT_MENU_DIRECTIVES } from 'ng2-alfresco-core';
import { import {
ALFRESCO_DATATABLE_DIRECTIVES, ALFRESCO_DATATABLE_DIRECTIVES,
DataSorting, DataSorting,
DataRowEvent DataRowEvent,
DataTableComponent
} from 'ng2-alfresco-datatable'; } from 'ng2-alfresco-datatable';
import { AlfrescoService } from './../services/alfresco.service'; import { AlfrescoService } from './../services/alfresco.service';
@@ -58,7 +61,7 @@ declare let __moduleName: string;
'(contextmenu)': 'onShowContextMenu($event)' '(contextmenu)': 'onShowContextMenu($event)'
} }
}) })
export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit, OnChanges { export class DocumentList implements OnInit, AfterViewInit, AfterViewChecked, AfterContentInit, OnChanges {
static SINGLE_CLICK_NAVIGATION: string = 'click'; static SINGLE_CLICK_NAVIGATION: string = 'click';
static DOUBLE_CLICK_NAVIGATION: string = 'dblclick'; static DOUBLE_CLICK_NAVIGATION: string = 'dblclick';
@@ -88,6 +91,9 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
@Output() @Output()
preview: EventEmitter<any> = new EventEmitter(); preview: EventEmitter<any> = new EventEmitter();
@ViewChild(DataTableComponent)
dataTable: DataTableComponent;
private _path = this.DEFAULT_ROOT_FOLDER; private _path = this.DEFAULT_ROOT_FOLDER;
get currentFolderPath(): string { get currentFolderPath(): string {
@@ -137,7 +143,8 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
constructor( constructor(
private alfrescoService: AlfrescoService, private alfrescoService: AlfrescoService,
private ngZone: NgZone) { private ngZone: NgZone) {
this.setupTable();
this.setupData();
} }
getContextActions(node: MinimalNodeEntity) { getContextActions(node: MinimalNodeEntity) {
@@ -189,6 +196,15 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
} }
} }
ngAfterViewInit() {
if (this.dataTable) {
// this.dataTable.contextActionResolver = this.resolveContextAction;
if (this.emptyFolderTemplate) {
this.dataTable.noContentTemplate = this.emptyFolderTemplate;
}
}
}
ngAfterViewChecked() { ngAfterViewChecked() {
// workaround for MDL issues with dynamic components // workaround for MDL issues with dynamic components
if (componentHandler) { if (componentHandler) {
@@ -518,7 +534,7 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
return column && column.source && !column.source.startsWith('$'); return column && column.source && !column.source.startsWith('$');
} }
private setupTable() { private setupData() {
this.data = new ShareDataTableAdapter( this.data = new ShareDataTableAdapter(
this.alfrescoService, this.alfrescoService,
this.baseComponentPath, this.baseComponentPath,
@@ -532,4 +548,12 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
this.data.setSorting(new DataSorting('id', 'asc')); 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) || [];
}
};
} }