[ACA-3000][ACA-2999] FE - Provide way to show ContextMenu on Task/Process list (#5596)

* [ACA-3000] FE - Provide way to show ContextMenu on Task list

* * Updated docs

* * Added unit tests to the recent changes
This commit is contained in:
siva kumar
2020-04-14 14:22:57 +05:30
committed by GitHub
parent ecca9220f1
commit 63063699fd
13 changed files with 394 additions and 11 deletions

View File

@@ -270,14 +270,16 @@
}, },
"TOOLTIP_MESSAGE": { "TOOLTIP_MESSAGE": {
"START_INPUT": "Starting page" "START_INPUT": "Starting page"
} },
"TASK_CONTEXT_MENU": "Task List Context Menu"
}, },
"PROCESS_LIST_DEMO": { "PROCESS_LIST_DEMO": {
"ERROR_MESSAGE": { "ERROR_MESSAGE": {
"APP_ID_REQUIRED_ERROR": "Insert App ID", "APP_ID_REQUIRED_ERROR": "Insert App ID",
"APP_ID_TYPE_ERROR": "App ID must be a number", "APP_ID_TYPE_ERROR": "App ID must be a number",
"NUMBER_GREATER_THAN": "Value must be greater than or equal to {{ value }}" "NUMBER_GREATER_THAN": "Value must be greater than or equal to {{ value }}"
} },
"PROCESS_CONTEXT_MENU": "Process List Context Menu"
}, },
"GROUP-TITLE1-TRANSLATION-KEY": "CUSTOM TITLE TRANSLATION ONE", "GROUP-TITLE1-TRANSLATION-KEY": "CUSTOM TITLE TRANSLATION ONE",
"GROUP-TITLE2-TRANSLATION-KEY": "CUSTOM TITLE TRANSLATION TWO", "GROUP-TITLE2-TRANSLATION-KEY": "CUSTOM TITLE TRANSLATION TWO",

View File

@@ -47,6 +47,8 @@
[state]="taskFilter?.filter?.state" [state]="taskFilter?.filter?.state"
[sort]="taskFilter?.filter?.sort" [sort]="taskFilter?.filter?.sort"
[landingTaskId]="currentTaskId" [landingTaskId]="currentTaskId"
[showContextMenu]="taskContextMenu"
(showRowContextMenu)="onShowTaskRowContextMenu($event)"
(rowClick)="onTaskRowClick($event)" (rowClick)="onTaskRowClick($event)"
(success)="onSuccessTaskList()" (success)="onSuccessTaskList()"
(row-click)="onRowClick($event)" (row-click)="onRowClick($event)"
@@ -161,6 +163,8 @@
[page]="processPage" [page]="processPage"
[size]="paginationPageSize" [size]="paginationPageSize"
[sort]="processFilter?.filter?.sort" [sort]="processFilter?.filter?.sort"
[showContextMenu]="processContextMenu"
(showRowContextMenu)="onShowProcessRowContextMenu($event)"
(rowClick)="onProcessRowClick($event)" (rowClick)="onProcessRowClick($event)"
(row-dblclick)="onProcessRowDblClick($event)" (row-dblclick)="onProcessRowDblClick($event)"
[multiselect]="multiSelectProcess" [multiselect]="multiSelectProcess"
@@ -280,6 +284,12 @@
<mat-slide-toggle id="adf-task-multiselect" [(ngModel)]="multiSelectTask" >Multiselect Task List <mat-slide-toggle id="adf-task-multiselect" [(ngModel)]="multiSelectTask" >Multiselect Task List
</mat-slide-toggle> </mat-slide-toggle>
</div> </div>
<div>
<mat-slide-toggle id="adf-task-context-menu" [(ngModel)]="taskContextMenu" >Show Task list Context menu</mat-slide-toggle>
</div>
<div>
<mat-slide-toggle id="adf-process-context-menu" [(ngModel)]="processContextMenu" >Show Process list Context menu</mat-slide-toggle>
</div>
<br> <br>
<mat-radio-group [(ngModel)]="selectionMode"> <mat-radio-group [(ngModel)]="selectionMode">
<mat-radio-button value="multiple">multiple</mat-radio-button> <mat-radio-button value="multiple">multiple</mat-radio-button>

View File

@@ -36,7 +36,7 @@ import {
import { import {
FORM_FIELD_VALIDATORS, FormRenderingService, FormService, FORM_FIELD_VALIDATORS, FormRenderingService, FormService,
DynamicTableRow, ValidateDynamicTableRowEvent, AppConfigService, PaginationComponent, UserPreferenceValues, DynamicTableRow, ValidateDynamicTableRowEvent, AppConfigService, PaginationComponent, UserPreferenceValues,
AlfrescoApiService, UserPreferencesService, LogService AlfrescoApiService, UserPreferencesService, LogService, DataCellEvent
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { AnalyticsReportListComponent } from '@alfresco/adf-insights'; import { AnalyticsReportListComponent } from '@alfresco/adf-insights';
@@ -118,6 +118,8 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
multiSelectTask = false; multiSelectTask = false;
multiSelectProcess = false; multiSelectProcess = false;
selectionMode = 'single'; selectionMode = 'single';
taskContextMenu = false;
processContextMenu = false;
private tabs = { tasks: 0, processes: 1, reports: 2 }; private tabs = { tasks: 0, processes: 1, reports: 2 };
@@ -526,4 +528,33 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
this.currentTaskId = null; this.currentTaskId = null;
} }
onShowTaskRowContextMenu(event: DataCellEvent) {
event.value.actions = [
{
data: event.value.row['obj'],
model: {
key: 'taskDetails',
icon: 'open',
title: 'TASK_LIST_DEMO.TASK_CONTEXT_MENU',
visible: true
},
subject: new Subject()
}
];
}
onShowProcessRowContextMenu(event: DataCellEvent) {
event.value.actions = [
{
data: event.value.row['obj'],
model: {
key: 'processDetails',
icon: 'open',
title: 'PROCESS_LIST_DEMO.PROCESS_CONTEXT_MENU',
visible: true
},
subject: new Subject()
}
];
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -64,6 +64,7 @@ when the process list is empty:
| size | `number` | | The number of processes to fetch in each page. | | size | `number` | | The number of processes to fetch in each page. |
| sort | `string` | | Defines the sort ordering of the list. Possible values are `created-desc`, `created-asc`, `ended-desc`, `ended-asc`. | | sort | `string` | | Defines the sort ordering of the list. Possible values are `created-desc`, `created-asc`, `ended-desc`, `ended-asc`. |
| state | `string` | | Defines the state of the processes. Possible values are `running`, `completed` and `all` | | state | `string` | | Defines the state of the processes. Possible values are `running`, `completed` and `all` |
| showContextMenu | `boolean` | false | Toggles custom context menu for the component. |
### Events ### Events
@@ -72,6 +73,7 @@ when the process list is empty:
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs while loading the list of process instances from the server. | | error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs while loading the list of process instances from the server. |
| rowClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when a row in the process list is clicked. | | rowClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when a row in the process list is clicked. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessListModel`](../../../lib/process-services/src/lib/process-list/models/process-list.model.ts)`>` | Emitted when the list of process instances has been loaded successfully from the server. | | success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessListModel`](../../../lib/process-services/src/lib/process-list/models/process-list.model.ts)`>` | Emitted when the list of process instances has been loaded successfully from the server. |
| showRowContextMenu | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`DataCellEvent`](../../../lib/core/datatable/components/datatable/data-cell.event.ts)`>` | Emitted before the context menu is displayed for a row. |
## Details ## Details
@@ -186,6 +188,48 @@ The Process Instance List also supports pagination:
</adf-pagination> </adf-pagination>
``` ```
#### showRowContextMenu event
Emitted before the context menu is displayed for a row.
Note that the ProcessInstanceListComponent itself does not populate the context menu with items. You can provide all necessary content via the handler.
```html
<adf-process-instance-list
[contextMenu]="true"
(showRowContextMenu)="onShowRowContextMenu($event)">
</adf-process-instance-list>
```
Event properties:
```ts
value: {
row: DataRow,
col: DataColumn,
actions: []
}
```
Handler example:
```ts
onShowRowContextMenu(event: DataCellEvent) {
event.value.actions = [
{ title: 'Process List Context Menu' },
{ ... }
]
}
```
![](../../docassets/images/process-instance-list-context-menu.png)
This event is cancellable. You can use `event.preventDefault()` to prevent the default behavior.
The ProcessInstanceList will automatically render the supplied menu items.
See the [ContextMenu](https://www.npmjs.com/package/ng2-alfresco-core)
documentation for more details on the format and behavior of context actions.
## See also ## See also
- [Data column component](../../core/components/data-column.component.md) - [Data column component](../../core/components/data-column.component.md)

View File

@@ -73,6 +73,7 @@ when the task list is empty:
| start | `number` | | Starting point of the list within the full set of tasks. | | start | `number` | | Starting point of the list within the full set of tasks. |
| state | `string` | | Current state of the process. Possible values are: `completed`, `active`. | | state | `string` | | Current state of the process. Possible values are: `completed`, `active`. |
| taskId | `string` | | The id of a task | | taskId | `string` | | The id of a task |
| showContextMenu | `boolean` | false | Toggles custom context menu for the component. |
### Events ### Events
@@ -82,6 +83,7 @@ when the task list is empty:
| rowClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when a task in the list is clicked | | rowClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when a task in the list is clicked |
| rowsSelected | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any[]>` | Emitted when rows are selected/unselected | | rowsSelected | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any[]>` | Emitted when rows are selected/unselected |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task list is loaded | | success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task list is loaded |
| showRowContextMenu | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`DataCellEvent`](../../../lib/core/datatable/components/datatable/data-cell.event.ts)`>` | Emitted before the context menu is displayed for a row. |
## Details ## Details
@@ -228,6 +230,50 @@ typical tasklist:
You can customize the styling of a column and also add features like tooltips and automatic translation of column titles. See the [Data Column component](../../core/components/data-column.component.md) page for more information about these features. You can customize the styling of a column and also add features like tooltips and automatic translation of column titles. See the [Data Column component](../../core/components/data-column.component.md) page for more information about these features.
#### showRowContextMenu event
Emitted before the context menu is displayed for a row.
Note that the TaskListComponent itself does not populate the context menu with items.
You can provide all necessary content via the handler.
```html
<adf-tasklist
[contextMenu]="true"
(showRowContextMenu)="onShowRowContextMenu($event)">
</adf-tasklist>
```
Event properties:
```ts
value: {
row: DataRow,
col: DataColumn,
actions: []
}
```
Handler example:
```ts
onShowRowContextMenu(event: DataCellEvent) {
event.value.actions = [
{ title: 'Task List Context Menu' },
{ ... }
]
}
```
![](../../docassets/images/task-list-context-menu.png)
This event is cancellable. You can use `event.preventDefault()` to prevent the default behavior.
The TaskListComponent will automatically render the supplied menu items.
See the [ContextMenu](https://www.npmjs.com/package/ng2-alfresco-core)
documentation for more details on the format and behavior of context actions.
## See also ## See also
- [Data column component](../../core/components/data-column.component.md) - [Data column component](../../core/components/data-column.component.md)

View File

@@ -7,6 +7,8 @@
[selectionMode]="selectionMode" [selectionMode]="selectionMode"
[multiselect]="multiselect" [multiselect]="multiselect"
[resolverFn]="resolverFn" [resolverFn]="resolverFn"
[contextMenu]="showContextMenu"
(showRowContextMenu)="onShowRowContextMenu($event)"
(rowClick)="onRowClick($event)" (rowClick)="onRowClick($event)"
(row-keyup)="onRowKeyUp($event)"> (row-keyup)="onRowKeyUp($event)">
<adf-loading-content-template> <adf-loading-content-template>

View File

@@ -15,14 +15,14 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, SimpleChange, ViewChild } from '@angular/core'; import { Component, SimpleChange, ViewChild, OnInit, Output, EventEmitter } from '@angular/core';
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { of, throwError } from 'rxjs'; import { of, throwError, Subject } from 'rxjs';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { ProcessInstanceListComponent } from './process-list.component'; import { ProcessInstanceListComponent } from './process-list.component';
import { import {
AppConfigService, setupTestBed, CoreModule, DataTableModule, DataRow, DataColumn, AppConfigService, setupTestBed, CoreModule, DataTableModule, DataRow, DataColumn,
DataRowEvent, ObjectDataRow, ObjectDataTableAdapter DataRowEvent, ObjectDataRow, ObjectDataTableAdapter, DataCellEvent
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { fakeProcessInstance, fakeProcessInstancesWithNoName, fakeProcessInstancesEmpty, fakeProcessCustomSchema } from '../../mock'; import { fakeProcessInstance, fakeProcessInstancesWithNoName, fakeProcessInstancesEmpty, fakeProcessCustomSchema } from '../../mock';
import { ProcessService } from '../services/process.service'; import { ProcessService } from '../services/process.service';
@@ -527,3 +527,115 @@ describe('Process List: Custom EmptyTemplateComponent', () => {
}); });
}); });
}); });
@Component({
template: `
<adf-process-instance-list
[appId]="appId"
[showContextMenu]="true"
(showRowContextMenu)="onShowRowContextMenu($event)"
#processlistComponentInstance>
<data-columns>
<data-column key="name" title="ADF_PROCESS_LIST.PROPERTIES.NAME" class="adf-full-width adf-name-column"></data-column>
<data-column key="created" title="ADF_PROCESS_LIST.PROPERTIES.END_DATE" class="adf-hidden"></data-column>
<data-column key="startedBy" title="ADF_PROCESS_LIST.PROPERTIES.CREATED" class="adf-desktop-only dw-dt-col-3 adf-ellipsis-cell">
<ng-template let-entry="$implicit">
<div>{{entry.row.obj.startedBy | fullName}}</div>
</ng-template>
</data-column>
</data-columns>
</adf-process-instance-list>`
})
class ProcessListContextMenuComponent implements OnInit {
appId: number;
@Output()
contextAction = new EventEmitter<any>();
private performAction$ = new Subject<any>();
ngOnInit() {
this.performContextActions();
}
onShowRowContextMenu(event: DataCellEvent) {
event.value.actions = [
{
data: event.value.row['obj'],
model:
{
key: 'processDetails',
icon: 'open',
title: 'View Process Details',
visible: true
},
subject: this.performAction$
},
{
data: event.value.row['obj'],
model:
{
key: 'cancel',
icon: 'open',
title: 'Cancel Process',
visible: true
},
subject: this.performAction$
}
];
}
performContextActions() {
this.performAction$
.subscribe((action: any) => {
this.contextAction.emit(action.data);
});
}
}
describe('ProcessListContextMenuComponent', () => {
let fixture: ComponentFixture<ProcessListContextMenuComponent>;
let customComponent: ProcessListContextMenuComponent;
let processService: ProcessService;
let element: HTMLElement;
setupTestBed({
imports: [CoreModule.forRoot()],
declarations: [ProcessInstanceListComponent, ProcessListContextMenuComponent],
providers: [ProcessService]
});
beforeEach(() => {
fixture = TestBed.createComponent(ProcessListContextMenuComponent);
customComponent = fixture.componentInstance;
element = fixture.nativeElement;
processService = TestBed.get(ProcessService);
customComponent.appId = 12345;
spyOn(processService, 'getProcesses').and.returnValue(of(fakeProcessInstance));
fixture.detectChanges();
});
afterEach(() => {
const event = new KeyboardEvent('keydown', {
bubbles : true, cancelable : true, key : 'Escape'
});
document.querySelector('.cdk-overlay-backdrop').dispatchEvent(event);
fixture.detectChanges();
});
it('Should be able to show context menu on process list', async () => {
const contextMenu = element.querySelector(`[data-automation-id="text_${fakeProcessInstance.data[0].name}"]`);
const contextActionSpy = spyOn(customComponent.contextAction, 'emit').and.callThrough();
contextMenu.dispatchEvent(new MouseEvent('contextmenu', { bubbles: true }));
fixture.detectChanges();
await fixture.whenStable();
const contextActions = document.querySelectorAll('.mat-menu-item');
expect(contextActions.length).toBe(2);
expect(contextActions[0]['disabled']).toBe(false, 'View Process Details action not enabled');
expect(contextActions[1]['disabled']).toBe(false, 'Cancel Process action not enabled');
contextActions[0].dispatchEvent(new Event('click'));
fixture.detectChanges();
expect(contextActionSpy).toHaveBeenCalled();
});
});

View File

@@ -27,7 +27,8 @@ import {
PaginatedComponent, PaginatedComponent,
PaginationComponent, PaginationComponent,
PaginationModel, PaginationModel,
UserPreferencesService UserPreferencesService,
DataCellEvent
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { import {
AfterContentInit, AfterContentInit,
@@ -110,6 +111,14 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
@Input() @Input()
selectFirstRow: boolean = true; selectFirstRow: boolean = true;
/** Toggles custom context menu for the component. */
@Input()
showContextMenu: boolean = false;
/** Emitted before the context menu is displayed for a row. */
@Output()
showRowContextMenu = new EventEmitter<DataCellEvent>();
/** /**
* Resolver function is used to show dynamic complex column objects * Resolver function is used to show dynamic complex column objects
* see the docs to learn how to configure a resolverFn. * see the docs to learn how to configure a resolverFn.
@@ -284,6 +293,10 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
} }
} }
onShowRowContextMenu(event: DataCellEvent) {
this.showRowContextMenu.emit(event);
}
private createRequestNode(): ProcessFilterParamRepresentationModel { private createRequestNode(): ProcessFilterParamRepresentationModel {
return new ProcessFilterParamRepresentationModel({ return new ProcessFilterParamRepresentationModel({
appDefinitionId: this.appId, appDefinitionId: this.appId,

View File

@@ -8,6 +8,8 @@
[loading]="isLoading" [loading]="isLoading"
[multiselect]="multiselect" [multiselect]="multiselect"
[selectionMode]="selectionMode" [selectionMode]="selectionMode"
[contextMenu]="showContextMenu"
(showRowContextMenu)="onShowRowContextMenu($event)"
(row-select)="onRowSelect($event)" (row-select)="onRowSelect($event)"
(row-unselect)="onRowUnselect($event)" (row-unselect)="onRowUnselect($event)"
(rowClick)="onRowClick($event)" (rowClick)="onRowClick($event)"

View File

@@ -15,16 +15,16 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, SimpleChange, ViewChild } from '@angular/core'; import { Component, SimpleChange, ViewChild, OnInit, Output, EventEmitter } from '@angular/core';
import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { AppConfigService, setupTestBed, CoreModule, DataTableModule, DataRowEvent, ObjectDataRow } from '@alfresco/adf-core'; import { AppConfigService, setupTestBed, CoreModule, DataTableModule, DataRowEvent, ObjectDataRow, DataCellEvent } from '@alfresco/adf-core';
import { TaskListService } from '../services/tasklist.service'; import { TaskListService } from '../services/tasklist.service';
import { TaskListComponent } from './task-list.component'; import { TaskListComponent } from './task-list.component';
import { ProcessTestingModule } from '../../testing/process.testing.module'; import { ProcessTestingModule } from '../../testing/process.testing.module';
import { fakeGlobalTask, fakeCustomSchema, fakeEmptyTask, paginatedTask } from '../../mock'; import { fakeGlobalTask, fakeCustomSchema, fakeEmptyTask, paginatedTask } from '../../mock';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { of } from 'rxjs'; import { of, Subject } from 'rxjs';
import { TaskListModule } from '../task-list.module'; import { TaskListModule } from '../task-list.module';
declare let jasmine: any; declare let jasmine: any;
@@ -807,3 +807,112 @@ describe('Task List: Custom EmptyTemplateComponent', () => {
}); });
}); });
}); });
@Component({
template: `
<adf-tasklist
[showContextMenu]="true"
(showRowContextMenu)="onShowRowContextMenu($event)"
#taskList>
<data-columns>
<data-column key="name" title="ADF_TASK_LIST.PROPERTIES.NAME" class="full-width name-column"></data-column>
<data-column key="created" title="ADF_TASK_LIST.PROPERTIES.CREATED" class="hidden"></data-column>
<data-column key="startedBy" title="ADF_TASK_LIST.PROPERTIES.CREATED" class="desktop-only dw-dt-col-3 ellipsis-cell">
<ng-template let-entry="$implicit">
<div>{{entry.row?.obj?.startedBy | fullName}}</div>
</ng-template>
</data-column>
</data-columns>
</adf-tasklist>`
})
class TaskListContextMenuComponent implements OnInit {
@Output()
contextAction = new EventEmitter<any>();
private performAction$ = new Subject<any>();
ngOnInit() {
this.performContextActions();
}
onShowRowContextMenu(event: DataCellEvent) {
event.value.actions = [
{
data: event.value.row['obj'],
model:
{
key: 'taskDetails',
icon: 'open',
title: 'View Task Details',
visible: true
},
subject: this.performAction$
},
{
data: event.value.row['obj'],
model:
{
key: 'cancel',
icon: 'open',
title: 'Cancel Process',
visible: true
},
subject: this.performAction$
}
];
}
performContextActions() {
this.performAction$
.subscribe((action: any) => {
this.contextAction.emit(action.data);
});
}
}
describe('TaskListContextMenuComponent', () => {
let fixture: ComponentFixture<TaskListContextMenuComponent>;
let customComponent: TaskListContextMenuComponent;
let taskListService: TaskListService;
let element: HTMLElement;
setupTestBed({
imports: [CoreModule.forRoot()],
declarations: [TaskListComponent, TaskListContextMenuComponent],
providers: [TaskListService]
});
beforeEach(() => {
fixture = TestBed.createComponent(TaskListContextMenuComponent);
customComponent = fixture.componentInstance;
element = fixture.nativeElement;
taskListService = TestBed.get(TaskListService);
spyOn(taskListService, 'findTasksByState').and.returnValues(of(fakeGlobalTask));
fixture.detectChanges();
});
afterEach(() => {
const event = new KeyboardEvent('keydown', {
bubbles : true, cancelable : true, key : 'Escape'
});
document.querySelector('.cdk-overlay-backdrop').dispatchEvent(event);
fixture.detectChanges();
});
it('Should be able to show context menu on task list', async () => {
const contextMenu = element.querySelector(`[data-automation-id="text_${fakeGlobalTask.data[0].name}"]`);
const contextActionSpy = spyOn(customComponent.contextAction, 'emit').and.callThrough();
contextMenu.dispatchEvent(new MouseEvent('contextmenu', { bubbles: true }));
fixture.detectChanges();
await fixture.whenStable();
const contextActions = document.querySelectorAll('.mat-menu-item');
expect(contextActions.length).toBe(2);
expect(contextActions[0]['disabled']).toBe(false, 'View Task Details action not enabled');
expect(contextActions[1]['disabled']).toBe(false, 'Cancel Task action not enabled');
contextActions[0].dispatchEvent(new Event('click'));
fixture.detectChanges();
expect(contextActionSpy).toHaveBeenCalled();
});
});

View File

@@ -18,7 +18,7 @@
import { import {
DataRowEvent, DataTableAdapter, DataTableSchema, CustomEmptyContentTemplateDirective, CustomLoadingContentTemplateDirective, DataRowEvent, DataTableAdapter, DataTableSchema, CustomEmptyContentTemplateDirective, CustomLoadingContentTemplateDirective,
AppConfigService, PaginationComponent, PaginatedComponent, AppConfigService, PaginationComponent, PaginatedComponent,
UserPreferencesService, UserPreferenceValues, PaginationModel } from '@alfresco/adf-core'; UserPreferencesService, UserPreferenceValues, PaginationModel, DataCellEvent } from '@alfresco/adf-core';
import { import {
AfterContentInit, Component, ContentChild, EventEmitter, AfterContentInit, Component, ContentChild, EventEmitter,
Input, OnChanges, Output, SimpleChanges, OnDestroy, OnInit } from '@angular/core'; Input, OnChanges, Output, SimpleChanges, OnDestroy, OnInit } from '@angular/core';
@@ -123,6 +123,14 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
@Input() @Input()
start: number; start: number;
/** Toggles custom context menu for the component. */
@Input()
showContextMenu: boolean = false;
/** Emitted before the context menu is displayed for a row. */
@Output()
showRowContextMenu = new EventEmitter<DataCellEvent>();
/** Emitted when a task in the list is clicked */ /** Emitted when a task in the list is clicked */
@Output() @Output()
rowClick = new EventEmitter<string>(); rowClick = new EventEmitter<string>();
@@ -356,6 +364,10 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
} }
} }
onShowRowContextMenu(event: DataCellEvent) {
this.showRowContextMenu.emit(event);
}
/** /**
* Optimize name field * Optimize name field
* @param instances * @param instances