#181 Context menu implementation

This commit is contained in:
Denys Vuika 2016-06-13 13:37:06 +01:00
parent 8e5f120e94
commit dda57d8b8b
9 changed files with 286 additions and 6 deletions

View File

@ -109,6 +109,8 @@
</alfresco-document-list>
</alfresco-upload-drag-area>
<context-menu-holder></context-menu-holder>
<div class="p-10">
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-1">
<input type="checkbox" id="checkbox-1" class="mdl-checkbox__input" [(ngModel)]="breadcrumb">

View File

@ -25,6 +25,7 @@ import {
MDL,
AlfrescoContentService
} from 'ng2-alfresco-core/dist/ng2-alfresco-core';
import { CONTEXT_MENU_DIRECTIVES } from 'ng2-alfresco-core/dist/ng2-alfresco-core';
import { ALFRESCO_ULPOAD_COMPONENTS } from 'ng2-alfresco-upload/dist/ng2-alfresco-upload';
import { AlfrescoPipeTranslate } from 'ng2-alfresco-core/dist/ng2-alfresco-core';
import { VIEWERCOMPONENT } from 'ng2-alfresco-viewer/dist/ng2-alfresco-viewer';
@ -35,7 +36,13 @@ declare let __moduleName: string;
moduleId: __moduleName,
selector: 'files-component',
templateUrl: './files.component.html',
directives: [DOCUMENT_LIST_DIRECTIVES, MDL, ALFRESCO_ULPOAD_COMPONENTS, VIEWERCOMPONENT],
directives: [
DOCUMENT_LIST_DIRECTIVES,
MDL,
ALFRESCO_ULPOAD_COMPONENTS,
VIEWERCOMPONENT,
CONTEXT_MENU_DIRECTIVES
],
providers: [DOCUMENT_LIST_PROVIDERS],
pipes: [AlfrescoPipeTranslate]
})
@ -63,11 +70,11 @@ export class FilesComponent {
}
myCustomAction1(event) {
alert('Custom document action for ' + event.value.displayName);
alert('Custom document action for ' + event.value.entry.name);
}
myFolderAction1(event) {
alert('Custom folder action for ' + event.value.displayName);
alert('Custom folder action for ' + event.value.entry.name);
}
refreshDocumentList() {

View File

@ -21,6 +21,9 @@ import { AlfrescoTranslationService } from './src/services/AlfrescoTranslationSe
import { AlfrescoPipeTranslate } from './src/services/AlfrescoPipeTranslate.service';
import { AlfrescoAuthenticationService } from './src/services/AlfrescoAuthenticationService.service';
import { AlfrescoContentService } from './src/services/AlfrescoContentService.service';
import { ContextMenuService } from './src/services/context-menu.service';
import { ContextMenuHolderComponent } from './src/components/context-menu-holder.component';
import { ContextMenuDirective } from './src/components/context-menu.directive';
export * from './src/services/AlfrescoSettingsService.service';
export * from './src/services/AlfrescoTranslationLoader.service';
@ -30,12 +33,26 @@ export * from './src/material/MaterialDesignLiteUpgradeElement';
export * from './src/services/AlfrescoAuthenticationService.service';
export * from './src/services/AlfrescoContentService.service';
export * from './src/services/context-menu.service';
export * from './src/components/context-menu-holder.component';
export * from './src/components/context-menu.directive';
export const ALFRESCO_CORE_PROVIDERS: [any] = [
AlfrescoAuthenticationService,
AlfrescoContentService,
AlfrescoSettingsService,
AlfrescoTranslationLoader,
AlfrescoTranslationService,
AlfrescoPipeTranslate
AlfrescoPipeTranslate,
ContextMenuService
];
export const CONTEXT_MENU_PROVIDERS: [any] = [
ContextMenuService
];
export const CONTEXT_MENU_DIRECTIVES: [any] = [
ContextMenuHolderComponent,
ContextMenuDirective
];

View File

@ -0,0 +1,101 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component } from 'angular2/core';
import { ContextMenuService } from './../services/context-menu.service';
@Component({
selector:'context-menu-holder',
styles:[
`
.menu-container {
background: #fff;
display: block;
margin: 0;
padding: 0;
border: none;
overflow: visible;
z-index: 9999;
}
.context-menu {
list-style-type: none;
position: static;
height: auto;
width: auto;
min-width: 124px;
padding: 8px 0;
margin: 0;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
border-radius: 2px;
}
.context-menu .link {
opacity: 1;
}
`
],
host:{
'(document:click)':'clickedOutside()'
//'(click)':'clickInside()'
},
template: `
<div [ngStyle]="locationCss" class="menu-container">
<ul class="context-menu">
<li (click)="link.subject.next(link)" class="mdl-menu__item link" *ngFor="#link of links">
{{link.title || link.model?.title}}
</li>
</ul>
</div>
`
})
export class ContextMenuHolderComponent {
links = [];
isShown = false;
private mouseLocation :{ left: number, top: number} = { left:0, top:0 };
constructor(
private _contextMenuService: ContextMenuService) {
_contextMenuService.show.subscribe(e => this.showMenu(e.event, e.obj));
}
get locationCss(){
return {
position: 'fixed',
display: this.isShown ? 'block': 'none',
left: this.mouseLocation.left + 'px',
top: this.mouseLocation.top + 'px'
};
}
clickedOutside(){
this.isShown = false;
}
showMenu(e, links) {
this.isShown = true;
this.links = links;
this.mouseLocation = {
left: e.clientX,
top: e.clientY
};
}
}

View File

@ -0,0 +1,38 @@
/*!
* @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, Input } from 'angular2/core';
import { ContextMenuService } from './../services/context-menu.service';
@Directive({
selector:'[context-menu]',
host: {
'(contextmenu)':'onShowContextMenu($event)'
}
})
export class ContextMenuDirective {
@Input('context-menu')
links;
constructor(
private _contextMenuService: ContextMenuService) {}
onShowContextMenu(event: MouseEvent) {
this._contextMenuService.show.next({ event: event, obj: this.links });
event.preventDefault();
}
}

View File

@ -0,0 +1,24 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Injectable} from 'angular2/core';
import {Subject} from 'rxjs/Rx';
@Injectable()
export class ContextMenuService {
public show: Subject<{event: MouseEvent, obj: any[]}> = new Subject();
}

View File

@ -44,6 +44,7 @@
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 *ngSwitchWhen="'image'" class="cell-value">
<img class="thumbnail" [src]="getCellValue(content, col)">

View File

@ -27,6 +27,8 @@ import {
TemplateRef
} from 'angular2/core';
import { DatePipe } from 'angular2/common';
import { Subject } from 'rxjs/Rx';
import { CONTEXT_MENU_DIRECTIVES } from 'ng2-alfresco-core/dist/ng2-alfresco-core';
import { AlfrescoService } from './../services/alfresco.service';
import { MinimalNodeEntity, NodePaging } from './../models/document-library.model';
import { ContentActionModel } from './../models/content-action.model';
@ -42,6 +44,7 @@ declare let __moduleName: string;
styleUrls: ['./document-list.css'],
templateUrl: './document-list.html',
providers: [AlfrescoService],
directives: [CONTEXT_MENU_DIRECTIVES],
host: {
'(contextmenu)': 'onShowContextMenu($event)'
}
@ -117,8 +120,66 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
direction: 'asc'
};
contextActionHandler: Subject<any> = new Subject();
testActions: any[];
constructor(
private _alfrescoService: AlfrescoService) {}
private _alfrescoService: AlfrescoService) {
this.testActions = [
{
title: 'Item 1',
subject: new Subject()
},
{
title: 'Item 2',
subject: new Subject()
},
{
title: 'Item 3',
subject: new Subject()
},
{
title: 'Item 4',
subject: new Subject()
}
];
}
getContextActions(node: MinimalNodeEntity) {
if (node && node.entry) {
let targetType;
if (node.entry.isFolder) {
targetType = 'folder';
}
if (node.entry.isFile) {
targetType = 'document';
}
if (targetType) {
let actions = this.getContentActions(targetType, 'menu');
if (actions && actions.length > 0) {
return actions.map(a => {
return {
model: a,
node: node,
subject: this.contextActionHandler
}
});
}
}
}
return null;
}
contextActionCallback(action) {
if (action) {
this.executeContentAction(action.node, action.model);
}
}
/**
* Determines whether navigation to parent folder is available.
@ -131,6 +192,7 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
ngOnInit() {
this.changePath(this.currentFolderPath);
this.contextActionHandler.subscribe(val => this.contextActionCallback(val));
}
ngOnChanges(change) {
@ -337,7 +399,7 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
* @param action Action to be executed against the context.
*/
executeContentAction(node: MinimalNodeEntity, action: ContentActionModel) {
if (action) {
if (node && node.entry && action) {
action.handler(node, this);
}
}
@ -513,3 +575,5 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
}
}
}

View File

@ -0,0 +1,26 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
import {Injectable} from 'angular2/core';
import {Subject} from 'rxjs/Rx';
@Injectable()
export class ContextMenuService {
public show: Subject<{event: MouseEvent, obj: any[]}> = new Subject();
}
*/