mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-06-02 17:34:51 +00:00
Context menu - library files fix (#815)
This commit is contained in:
parent
94f2762940
commit
43b55102be
@ -6,7 +6,7 @@ import {
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { fromEvent, Subscription } from 'rxjs';
|
||||
import { delay } from 'rxjs/operators';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
@Directive({
|
||||
selector: '[acaContextMenuOutsideEvent]'
|
||||
@ -22,7 +22,7 @@ export class OutsideEventDirective implements OnInit, OnDestroy {
|
||||
ngOnInit() {
|
||||
this.subscriptions = this.subscriptions.concat([
|
||||
fromEvent(document.body, 'click')
|
||||
.pipe(delay(1))
|
||||
.pipe(filter(event => !this.findAncestor(event.target as Element)))
|
||||
.subscribe(() => this.clickOutside.next())
|
||||
]);
|
||||
}
|
||||
@ -31,4 +31,15 @@ export class OutsideEventDirective implements OnInit, OnDestroy {
|
||||
this.subscriptions.forEach(subscription => subscription.unsubscribe());
|
||||
this.subscriptions = [];
|
||||
}
|
||||
|
||||
private findAncestor(el: Element): boolean {
|
||||
const className = 'aca-context-menu';
|
||||
|
||||
if (el.classList.contains(className)) {
|
||||
return true;
|
||||
}
|
||||
// tslint:disable-next-line:curly
|
||||
while ((el = el.parentElement) && !el.classList.contains(className));
|
||||
return !!el;
|
||||
}
|
||||
}
|
||||
|
@ -23,20 +23,24 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Directive, HostListener, Input } from '@angular/core';
|
||||
import {
|
||||
Directive,
|
||||
HostListener,
|
||||
Input,
|
||||
OnInit,
|
||||
OnDestroy
|
||||
} 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';
|
||||
import { debounceTime } from 'rxjs/operators';
|
||||
import { Subject, fromEvent, Subscription } from 'rxjs';
|
||||
|
||||
@Directive({
|
||||
selector: '[acaContextActions]'
|
||||
})
|
||||
export class ContextActionsDirective {
|
||||
export class ContextActionsDirective implements OnInit, OnDestroy {
|
||||
private execute$: Subject<any> = new Subject();
|
||||
private subscriptions: Subscription[] = [];
|
||||
private overlayRef: ContextMenuOverlayRef = null;
|
||||
|
||||
// tslint:disable-next-line:no-input-rename
|
||||
@ -49,40 +53,44 @@ export class ContextActionsDirective {
|
||||
event.preventDefault();
|
||||
|
||||
if (this.enabled) {
|
||||
this.execute(event);
|
||||
const target = this.getTarget(event);
|
||||
if (target) {
|
||||
this.execute(event, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
private documentList: DocumentListComponent,
|
||||
private store: Store<AppStore>,
|
||||
private contextMenuService: ContextMenuService
|
||||
) {}
|
||||
constructor(private contextMenuService: ContextMenuService) {}
|
||||
|
||||
private execute(event: MouseEvent) {
|
||||
// todo: review this in ADF
|
||||
const selected = this.getSelectedRow(event);
|
||||
|
||||
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) {
|
||||
ngOnInit() {
|
||||
this.subscriptions.push(
|
||||
fromEvent(document.body, 'contextmenu').subscribe(() => {
|
||||
if (this.overlayRef) {
|
||||
this.overlayRef.close();
|
||||
}
|
||||
}),
|
||||
|
||||
this.execute$.pipe(debounceTime(300)).subscribe((event: MouseEvent) => {
|
||||
this.render(event);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscriptions.forEach(subscription => subscription.unsubscribe());
|
||||
this.subscriptions = [];
|
||||
this.execute$ = null;
|
||||
}
|
||||
|
||||
execute(event: MouseEvent, target: Element) {
|
||||
if (!this.isSelected(target)) {
|
||||
target.dispatchEvent(new MouseEvent('click'));
|
||||
}
|
||||
this.execute$.next(event);
|
||||
}
|
||||
|
||||
private render(event: MouseEvent) {
|
||||
this.overlayRef = this.contextMenuService.open({
|
||||
source: event,
|
||||
hasBackdrop: false,
|
||||
@ -91,46 +99,24 @@ export class ContextActionsDirective {
|
||||
});
|
||||
}
|
||||
|
||||
private updateSelection() {
|
||||
this.store.dispatch(
|
||||
new SetSelectedNodesAction(this.documentList.selection)
|
||||
private getTarget(event: MouseEvent): Element {
|
||||
return this.findAncestor(<Element>event.target, 'adf-datatable-table-cell');
|
||||
}
|
||||
|
||||
private isSelected(target): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.findAncestor(target, 'adf-datatable-row').classList.contains(
|
||||
'is-selected'
|
||||
);
|
||||
}
|
||||
|
||||
private isInSelection(row: DataRow): MinimalNodeEntity {
|
||||
return this.documentList.selection.find(
|
||||
selected => row.getValue('name') === selected.entry.name
|
||||
);
|
||||
}
|
||||
|
||||
private getSelectedRow(event): 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 {
|
||||
if (el.classList.contains(className)) {
|
||||
return el;
|
||||
}
|
||||
// tslint:disable-next-line:curly
|
||||
while ((el = el.parentElement) && !el.classList.contains(className));
|
||||
return el;
|
||||
|
@ -24,39 +24,40 @@
|
||||
*/
|
||||
|
||||
import { ContextActionsDirective } from './context-menu.directive';
|
||||
import { fakeAsync, tick } from '@angular/core/testing';
|
||||
|
||||
describe('ContextActionsDirective', () => {
|
||||
let directive;
|
||||
const contextMenuServiceMock = <any>{
|
||||
open: jasmine.createSpy('open')
|
||||
};
|
||||
const storeMock = <any>{};
|
||||
const documentListMock = <any>{};
|
||||
|
||||
beforeEach(() => {
|
||||
directive = new ContextActionsDirective(
|
||||
documentListMock,
|
||||
storeMock,
|
||||
contextMenuServiceMock
|
||||
);
|
||||
directive = new ContextActionsDirective(contextMenuServiceMock);
|
||||
});
|
||||
|
||||
it('should not render context menu when disable property is false', () => {
|
||||
it('should not render context menu when `enabled` property is false', () => {
|
||||
directive.enabled = false;
|
||||
spyOn(directive, 'getSelectedRow').and.returnValue({});
|
||||
|
||||
directive.onContextMenuEvent(new MouseEvent('contextmenu'));
|
||||
|
||||
expect(contextMenuServiceMock.open).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should render context menu when disable property is true', () => {
|
||||
directive.enabled = true;
|
||||
spyOn(directive, 'getSelectedRow').and.returnValue({});
|
||||
spyOn(directive, 'isInSelection').and.returnValue(true);
|
||||
it('should call service to render context menu', fakeAsync(() => {
|
||||
const el = document.createElement('div');
|
||||
el.className =
|
||||
'adf-data-table-cell adf-datatable-table-cell adf-datatable-row';
|
||||
|
||||
directive.onContextMenuEvent(new MouseEvent('contextmenu'));
|
||||
const fragment = document.createDocumentFragment();
|
||||
fragment.appendChild(el);
|
||||
const target = fragment.querySelector('div');
|
||||
|
||||
directive.ngOnInit();
|
||||
|
||||
directive.onContextMenuEvent(<any>{ preventDefault: () => {}, target });
|
||||
|
||||
tick(500);
|
||||
|
||||
expect(contextMenuServiceMock.open).toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user