mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[ACA-1696] contextmenu (#587)
* enbale contextmenu by default * attach event only when backdrop is set * outside event for contextmenu * apply outside event directive * workaround fro contextmenu event row selection * remove Output parameter * update dockerfile * update docker compose file
This commit is contained in:
parent
5759ea1b62
commit
091e0d3e3f
@ -1,4 +1,4 @@
|
||||
FROM nginx:alpine
|
||||
FROM nginx:stable-alpine
|
||||
LABEL version="1.3"
|
||||
LABEL maintainer="Denys Vuika <denys.vuika@alfresco.com>"
|
||||
|
||||
|
@ -81,7 +81,7 @@ services:
|
||||
# - ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
|
||||
proxy:
|
||||
image: nginx
|
||||
image: nginx:stable-alpine
|
||||
depends_on:
|
||||
- content-app
|
||||
volumes:
|
||||
|
@ -0,0 +1,28 @@
|
||||
import { Directive, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';
|
||||
import { fromEvent, Subscription } from 'rxjs';
|
||||
import { delay } from 'rxjs/operators';
|
||||
|
||||
@Directive({
|
||||
selector: '[acaContextMenuOutsideEvent]'
|
||||
})
|
||||
|
||||
export class OutsideEventDirective implements OnInit, OnDestroy {
|
||||
private subscriptions: Subscription[] = [];
|
||||
|
||||
@Output() clickOutside: EventEmitter<null> = new EventEmitter();
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
this.subscriptions = this.subscriptions.concat([
|
||||
fromEvent(document, 'click')
|
||||
.pipe(delay(1))
|
||||
.subscribe(() => this.clickOutside.next())
|
||||
]);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscriptions.forEach(subscription => subscription.unsubscribe());
|
||||
this.subscriptions = [];
|
||||
}
|
||||
}
|
@ -1,4 +1,8 @@
|
||||
<div mat-menu class="mat-menu-panel" @panelAnimation>
|
||||
<div mat-menu class="mat-menu-panel"
|
||||
@panelAnimation
|
||||
acaContextMenuOutsideEvent
|
||||
(clickOutside)="onClickOutsideEvent()">
|
||||
|
||||
<div class="mat-menu-content">
|
||||
<ng-container *ngFor="let entry of actions" [ngSwitch]="entry.type">
|
||||
<ng-container *ngSwitchCase="'default'">
|
||||
|
@ -68,10 +68,22 @@ export class ContextMenuComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
@ViewChildren(ContextMenuItemDirective)
|
||||
private contextMenuItems: QueryList<ContextMenuItemDirective>;
|
||||
|
||||
@HostListener('contextmenu', ['$event'])
|
||||
handleContextMenu(event: MouseEvent) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
if (this.contextMenuOverlayRef) {
|
||||
this.contextMenuOverlayRef.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('document:keydown.Escape', ['$event'])
|
||||
handleKeydownEscape(event: KeyboardEvent) {
|
||||
if (event) {
|
||||
this.contextMenuOverlayRef.close();
|
||||
if (this.contextMenuOverlayRef) {
|
||||
this.contextMenuOverlayRef.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,6 +103,12 @@ export class ContextMenuComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
private store: Store<AppStore>,
|
||||
) { }
|
||||
|
||||
onClickOutsideEvent() {
|
||||
if (this.contextMenuOverlayRef) {
|
||||
this.contextMenuOverlayRef.close();
|
||||
}
|
||||
}
|
||||
|
||||
runAction(actionId: string) {
|
||||
const context = {
|
||||
selection: this.selection
|
||||
|
@ -26,6 +26,12 @@
|
||||
import { Directive, HostListener, Input } from '@angular/core';
|
||||
import { ContextMenuOverlayRef } from './context-menu-overlay';
|
||||
import { ContextMenuService } from './context-menu.service';
|
||||
import { DocumentListComponent } from '@alfresco/adf-content-services';
|
||||
import { SetSelectedNodesAction } from '../../store/actions';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppStore } from '../../store/states/app.state';
|
||||
import { DataRow } from '@alfresco/adf-core';
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
|
||||
@Directive({
|
||||
selector: '[acaContextActions]'
|
||||
@ -34,11 +40,12 @@ export class ContextActionsDirective {
|
||||
private overlayRef: ContextMenuOverlayRef = null;
|
||||
|
||||
// tslint:disable-next-line:no-input-rename
|
||||
@Input('acaContextEnable') enabled: boolean;
|
||||
@Input('acaContextEnable') enabled = true;
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event) {
|
||||
if (event && this.overlayRef) {
|
||||
this.clearSelection();
|
||||
this.overlayRef.close();
|
||||
}
|
||||
}
|
||||
@ -49,19 +56,84 @@ export class ContextActionsDirective {
|
||||
event.preventDefault();
|
||||
|
||||
if (this.enabled) {
|
||||
this.render(event);
|
||||
this.execute(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(private contextMenuService: ContextMenuService) { }
|
||||
constructor(
|
||||
private documentList: DocumentListComponent,
|
||||
private store: Store<AppStore>,
|
||||
private contextMenuService: ContextMenuService
|
||||
) { }
|
||||
|
||||
private execute(event: MouseEvent) {
|
||||
const selected = this.getSelectedRow();
|
||||
|
||||
if (selected) {
|
||||
if (!this.isInSelection(selected)) {
|
||||
this.clearSelection();
|
||||
|
||||
this.documentList.dataTable.selectRow(selected, true);
|
||||
this.documentList.selection.push((<any>selected).node);
|
||||
|
||||
this.updateSelection();
|
||||
}
|
||||
|
||||
this.render(event);
|
||||
}
|
||||
}
|
||||
|
||||
private render(event: MouseEvent) {
|
||||
if (this.overlayRef) {
|
||||
this.overlayRef.close();
|
||||
}
|
||||
|
||||
this.overlayRef = this.contextMenuService.open({
|
||||
source: event,
|
||||
hasBackdrop: true,
|
||||
hasBackdrop: false,
|
||||
backdropClass: 'cdk-overlay-transparent-backdrop',
|
||||
panelClass: 'cdk-overlay-pane',
|
||||
});
|
||||
}
|
||||
|
||||
private updateSelection() {
|
||||
this.store.dispatch(
|
||||
new SetSelectedNodesAction(this.documentList.selection)
|
||||
);
|
||||
}
|
||||
|
||||
private isInSelection(row: DataRow): MinimalNodeEntity {
|
||||
return this.documentList.selection.find((selected) =>
|
||||
row.getValue('name') === selected.entry.name);
|
||||
}
|
||||
|
||||
private getSelectedRow(): DataRow {
|
||||
const rowElement = this.findAncestor(<HTMLElement>event.target, 'adf-datatable-row');
|
||||
|
||||
if (!rowElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const rowName = rowElement.querySelector('.adf-data-table-cell--text .adf-datatable-cell')
|
||||
.textContent
|
||||
.trim();
|
||||
|
||||
return this.documentList.data.getRows()
|
||||
.find((row: DataRow) => row.getValue('name') === rowName);
|
||||
}
|
||||
|
||||
private clearSelection() {
|
||||
this.documentList.data.getRows().map((row: DataRow) => {
|
||||
return this.documentList.dataTable.selectRow(row, false);
|
||||
});
|
||||
|
||||
this.documentList.selection = [];
|
||||
}
|
||||
|
||||
private findAncestor (el: Element, className: string): Element {
|
||||
// tslint:disable-next-line:curly
|
||||
while ((el = el.parentElement) && !el.classList.contains(className));
|
||||
return el;
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import { ContextActionsDirective } from './context-menu.directive';
|
||||
import { ContextMenuService } from './context-menu.service';
|
||||
import { ContextMenuComponent } from './context-menu.component';
|
||||
import { ContextMenuItemDirective } from './context-menu-item.directive';
|
||||
import { OutsideEventDirective } from './context-menu-outside-event.directive';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -47,9 +48,11 @@ import { ContextMenuItemDirective } from './context-menu-item.directive';
|
||||
declarations: [
|
||||
ContextActionsDirective,
|
||||
ContextMenuComponent,
|
||||
ContextMenuItemDirective
|
||||
ContextMenuItemDirective,
|
||||
OutsideEventDirective
|
||||
],
|
||||
exports: [
|
||||
OutsideEventDirective,
|
||||
ContextActionsDirective,
|
||||
ContextMenuComponent
|
||||
],
|
||||
|
@ -22,11 +22,13 @@ export class ContextMenuService {
|
||||
overlay.backdropClick().subscribe(() => overlayRef.close());
|
||||
|
||||
// prevent native contextmenu on overlay element if config.hasBackdrop is true
|
||||
(<any>overlay)._backdropElement
|
||||
.addEventListener('contextmenu', () => {
|
||||
event.preventDefault();
|
||||
(<any>overlay)._backdropClick.next(null);
|
||||
}, true);
|
||||
if (config.hasBackdrop) {
|
||||
(<any>overlay)._backdropElement
|
||||
.addEventListener('contextmenu', () => {
|
||||
event.preventDefault();
|
||||
(<any>overlay)._backdropClick.next(null);
|
||||
}, true);
|
||||
}
|
||||
|
||||
return overlayRef;
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
<adf-document-list #documentList
|
||||
acaDocumentList
|
||||
acaContextActions
|
||||
[acaContextEnable]="selection.count"
|
||||
[display]="documentDisplayMode$ | async"
|
||||
currentFolderId="-favorites-"
|
||||
selectionMode="multiple"
|
||||
|
@ -27,7 +27,6 @@
|
||||
<adf-document-list #documentList
|
||||
acaDocumentList
|
||||
acaContextActions
|
||||
[acaContextEnable]="selection.count"
|
||||
[display]="documentDisplayMode$ | async"
|
||||
[sorting]="[ 'modifiedAt', 'desc' ]"
|
||||
selectionMode="multiple"
|
||||
|
@ -19,7 +19,6 @@
|
||||
<adf-document-list #documentList
|
||||
acaDocumentList
|
||||
acaContextActions
|
||||
[acaContextEnable]="selection.count"
|
||||
[display]="documentDisplayMode$ | async"
|
||||
currentFolderId="-mysites-"
|
||||
selectionMode="single"
|
||||
|
@ -17,7 +17,6 @@
|
||||
<adf-document-list #documentList
|
||||
acaDocumentList
|
||||
acaContextActions
|
||||
[acaContextEnable]="selection.count"
|
||||
[display]="documentDisplayMode$ | async"
|
||||
currentFolderId="-recent-"
|
||||
selectionMode="multiple"
|
||||
|
@ -17,7 +17,6 @@
|
||||
<adf-document-list #documentList
|
||||
acaDocumentList
|
||||
acaContextActions
|
||||
[acaContextEnable]="selection.count"
|
||||
[display]="documentDisplayMode$ | async"
|
||||
currentFolderId="-sharedlinks-"
|
||||
selectionMode="multiple"
|
||||
|
@ -17,7 +17,6 @@
|
||||
<adf-document-list #documentList
|
||||
acaDocumentList
|
||||
acaContextActions
|
||||
[acaContextEnable]="selection.count"
|
||||
[display]="documentDisplayMode$ | async"
|
||||
currentFolderId="-trashcan-"
|
||||
selectionMode="multiple"
|
||||
|
Loading…
x
Reference in New Issue
Block a user