[ACS-8706] split context menu to allow injecting actions (#4203)

* ACS-8706 split context menu to allow injecting actions

* ACS-8706 fix class naming, add context menu components unit tests

* ACS-8706 add context menu service, effects and directive unit tests

* ACS-8706 review remarks - redundant condition, directive unit tests

* ACS-8706 improve unit testing approach, remove unnecessary class attributes

* ACS-8706 documentation

* ACS-8706 fix sonar issues

* ACS-8706 replace takeUntil with takeUntilDestroyed

* ACS-8706 fix sonar lint issue

* ACS-8706 change incorrect import path
This commit is contained in:
Grzegorz Jaśkowski
2024-11-08 08:26:33 +01:00
committed by GitHub
parent 38e667b334
commit 71764b09e2
18 changed files with 642 additions and 95 deletions

View File

@@ -23,9 +23,21 @@
*/
import { ContextActionsDirective } from './contextmenu.directive';
import { ContextMenu } from '@alfresco/aca-shared/store';
import { ContextMenu, CustomContextMenu } from '@alfresco/aca-shared/store';
import { ContentActionRef, ContentActionType } from '@alfresco/adf-extensions';
import { fakeAsync, tick } from '@angular/core/testing';
const customActionsMock: ContentActionRef[] = [
{
type: ContentActionType.default,
id: 'action',
title: 'action',
actions: {
click: 'event'
}
}
];
describe('ContextActionsDirective', () => {
let directive: ContextActionsDirective;
@@ -45,24 +57,6 @@ describe('ContextActionsDirective', () => {
expect(directive.execute).not.toHaveBeenCalled();
});
it('should call service to render context menu', fakeAsync(() => {
const el = document.createElement('div');
el.className = 'adf-datatable-cell adf-datatable-cell--text adf-datatable-row';
const fragment = document.createDocumentFragment();
fragment.appendChild(el);
const target = fragment.querySelector('div');
const mouseEventMock: any = { preventDefault: () => {}, target };
directive.ngOnInit();
directive.onContextMenuEvent(mouseEventMock);
tick(500);
expect(storeMock.dispatch).toHaveBeenCalledWith(new ContextMenu(mouseEventMock));
}));
it('should not call service to render context menu if the datatable is empty', fakeAsync(() => {
storeMock.dispatch.calls.reset();
const el = document.createElement('div');
@@ -82,4 +76,34 @@ describe('ContextActionsDirective', () => {
expect(storeMock.dispatch).not.toHaveBeenCalled();
}));
describe('Context Menu rendering', () => {
let mouseEventMock: any;
beforeEach(() => {
const el = document.createElement('div');
el.className = 'adf-datatable-cell adf-datatable-cell--text adf-datatable-row';
const fragment = document.createDocumentFragment();
fragment.appendChild(el);
const target = fragment.querySelector('div');
mouseEventMock = { preventDefault: () => {}, target };
});
it('should call service to render context menu', fakeAsync(() => {
directive.ngOnInit();
directive.onContextMenuEvent(mouseEventMock);
tick(500);
expect(storeMock.dispatch).toHaveBeenCalledWith(new ContextMenu(mouseEventMock));
}));
it('should call service to render custom context menu if custom actions are provided', fakeAsync(() => {
directive.customActions = customActionsMock;
directive.ngOnInit();
directive.onContextMenuEvent(mouseEventMock);
tick(500);
expect(storeMock.dispatch).toHaveBeenCalledWith(new CustomContextMenu(mouseEventMock, customActionsMock));
}));
});
});

View File

@@ -26,7 +26,8 @@ import { Directive, HostListener, Input, OnInit, OnDestroy } from '@angular/core
import { debounceTime, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { Store } from '@ngrx/store';
import { AppStore, ContextMenu } from '@alfresco/aca-shared/store';
import { AppStore, ContextMenu, CustomContextMenu } from '@alfresco/aca-shared/store';
import { ContentActionRef } from '@alfresco/adf-extensions';
@Directive({
standalone: true,
@@ -41,6 +42,9 @@ export class ContextActionsDirective implements OnInit, OnDestroy {
@Input('acaContextEnable')
enabled = true;
@Input()
customActions: ContentActionRef[] = [];
@HostListener('contextmenu', ['$event'])
onContextMenuEvent(event: MouseEvent) {
if (event) {
@@ -59,7 +63,11 @@ export class ContextActionsDirective implements OnInit, OnDestroy {
ngOnInit() {
this.execute$.pipe(debounceTime(300), takeUntil(this.onDestroy$)).subscribe((event: MouseEvent) => {
this.store.dispatch(new ContextMenu(event));
if (this.customActions?.length) {
this.store.dispatch(new CustomContextMenu(event, this.customActions));
} else {
this.store.dispatch(new ContextMenu(event));
}
});
}