[AAE-7817] Add columns selector for processes and tasks tasks (#7612)

* [AAE-7817] Add columns selector for processes and tasks tasks

* cr

* Update

* fix unit tests

* preserve order while sorting

* add input toggle to show main actions

* fix test
This commit is contained in:
Bartosz Sekuła
2022-05-17 08:41:14 +02:00
committed by GitHub
parent 1e3099b99b
commit 95fc295688
16 changed files with 271 additions and 33 deletions

View File

@@ -9,6 +9,7 @@
[actions]="showActions"
[actionsPosition]="actionsPosition"
[contextMenu]="showContextMenu"
[showMainDatatableActions]="showMainDatatableActions"
(showRowActionsMenu)="onShowRowActionsMenu($event)"
(showRowContextMenu)="onShowRowContextMenu($event)"
(executeRowAction)="onExecuteRowAction($event)"
@@ -39,4 +40,14 @@
<ng-content select="adf-custom-empty-content-template"></ng-content>
</ng-template>
</adf-no-content-template>
<adf-main-menu-datatable-template>
<ng-template let-mainMenuTrigger>
<adf-datatable-column-selector
[columns]="columns"
[mainMenuTrigger]="mainMenuTrigger"
(submitColumnsVisibility)="onColumnsVisibilityChange($event)">
</adf-datatable-column-selector>
</ng-template>
</adf-main-menu-datatable-template>
</adf-datatable>

View File

@@ -19,6 +19,8 @@ import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import {
AppConfigService,
ColumnsSelectorComponent,
DataColumn,
DataRowEvent,
ObjectDataRow,
setupTestBed
@@ -225,6 +227,64 @@ describe('ProcessListCloudComponent', () => {
fixture.detectChanges();
});
it('should not shown columns selector by default', () => {
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
const appName = new SimpleChange(null, 'FAKE-APP-NAME', true);
component.ngOnChanges({ appName });
fixture.detectChanges();
const mainMenuButton = fixture.debugElement.query(By.css('[data-automation-id="adf-datatable-main-menu-button"]'));
expect(mainMenuButton).toBeFalsy();
});
it('should shown columns selector', () => {
component.showMainDatatableActions = true;
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
const appName = new SimpleChange(null, 'FAKE-APP-NAME', true);
component.ngOnChanges({ appName });
fixture.detectChanges();
const mainMenuButton = fixture.debugElement.query(By.css('[data-automation-id="adf-datatable-main-menu-button"]'));
expect(mainMenuButton).toBeTruthy();
});
it('should hide columns on applying new columns visibility through columns selector', () => {
component.showMainDatatableActions = true;
fixture.detectChanges();
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
const appName = new SimpleChange(null, 'FAKE-APP-NAME', true);
component.ngOnChanges({ appName });
fixture.detectChanges();
const mainMenuButton = fixture.debugElement.query(By.css('[data-automation-id="adf-datatable-main-menu-button"]'));
mainMenuButton.triggerEventHandler('click', {});
fixture.detectChanges();
const columnSelectorMenu = fixture.debugElement.query(By.css('adf-datatable-column-selector'));
expect(columnSelectorMenu).toBeTruthy();
const newColumns = (component.columns as DataColumn[]).map((column, index) => ({
...column,
isHidden: index !== 0 // only first one is shown
}));
const columnsSelectorInstance = columnSelectorMenu.componentInstance as ColumnsSelectorComponent;
expect(columnsSelectorInstance.columns).toBe(component.columns, 'should use columns as input');
columnSelectorMenu.triggerEventHandler('submitColumnsVisibility', newColumns);
fixture.detectChanges();
const displayedColumns = fixture.debugElement.queryAll(By.css('.adf-datatable-cell-header'));
expect(displayedColumns.length).toBe(2, 'only column with isHidden set to false and action column should be shown');
});
it('should reload tasks when reload() is called', (done) => {
component.appName = 'fake';
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));

View File

@@ -159,6 +159,10 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
@Input()
showContextMenu: boolean = false;
/** Toggle main datatable actions. */
@Input()
showMainDatatableActions: boolean = false;
/** Emitted when a row in the process list is clicked. */
@Output()
rowClick: EventEmitter<string> = new EventEmitter<string>();
@@ -223,14 +227,22 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
map((preferences => {
const preferencesList = preferences?.list?.entries ?? [];
const columnsOrder = preferencesList.find(preference => preference.entry.key === ProcessListCloudPreferences.columnOrder);
const columnsVisibility = preferencesList.find(preference => preference.entry.key === ProcessListCloudPreferences.columnsVisibility);
return {
columnsOrder: columnsOrder ? JSON.parse(columnsOrder.entry.value) : undefined
columnsOrder: columnsOrder ? JSON.parse(columnsOrder.entry.value) : undefined,
columnsVisibility: columnsVisibility ? JSON.parse(columnsVisibility.entry.value) : undefined
};
}))
)
.subscribe(({ columnsOrder }) => {
this.columnsOrder = columnsOrder;
.subscribe(({ columnsOrder, columnsVisibility }) => {
if (columnsVisibility) {
this.columnsVisibility = columnsVisibility;
}
if (columnsOrder) {
this.columnsOrder = columnsOrder;
}
this.createDatatableSchema();
});
@@ -326,12 +338,33 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
}
onColumnOrderChanged(columnsWithNewOrder: DataColumn[]): void {
this.columnsOrder = columnsWithNewOrder.map(column => column.id);
if (this.appName) {
const newColumnsOrder = columnsWithNewOrder.map(column => column.id);
this.cloudPreferenceService.updatePreference(
this.appName,
ProcessListCloudPreferences.columnOrder,
newColumnsOrder
this.columnsOrder
);
}
}
onColumnsVisibilityChange(columns: DataColumn[]): void {
this.columnsVisibility = columns.reduce((visibleColumnsMap, column) => {
if (column.isHidden !== undefined) {
visibleColumnsMap[column.id] = !column.isHidden;
}
return visibleColumnsMap;
}, {});
this.createColumns();
if (this.appName) {
this.cloudPreferenceService.updatePreference(
this.appName,
ProcessListCloudPreferences.columnsVisibility,
this.columnsVisibility
);
}
}

View File

@@ -1,4 +1,5 @@
// eslint-disable-next-line no-shadow
export enum ProcessListCloudPreferences {
columnOrder = 'processes-cloud-list-columns-order'
columnOrder = 'processes-cloud-list-columns-order',
columnsVisibility = 'processes-cloud-columns-visibility'
}

View File

@@ -18,12 +18,14 @@
export const processCloudPresetsDefaultModel = {
default: [
{
id: 'id',
key: 'name',
type: 'text',
title: 'ADF_CLOUD_PROCESS_LIST.PROPERTIES.NAME',
sortable: true
},
{
id: 'startDate',
key: 'startDate',
type: 'date',
title: 'ADF_CLOUD_PROCESS_LIST.PROPERTIES.START_DATE',

View File

@@ -12,6 +12,7 @@
[actionsPosition]="actionsPosition"
[contextMenu]="showContextMenu"
[resolverFn]="boundReplacePriorityValues"
[showMainDatatableActions]="showMainDatatableActions"
(showRowActionsMenu)="onShowRowActionsMenu($event)"
(showRowContextMenu)="onShowRowContextMenu($event)"
(executeRowAction)="onExecuteRowAction($event)"
@@ -40,5 +41,15 @@
<ng-content select="adf-custom-empty-content-template"></ng-content>
</ng-template>
</adf-no-content-template>
<adf-main-menu-datatable-template>
<ng-template let-mainMenuTrigger>
<adf-datatable-column-selector
[columns]="columns"
[mainMenuTrigger]="mainMenuTrigger"
(submitColumnsVisibility)="onColumnsVisibilityChange($event)">
</adf-datatable-column-selector>
</ng-template>
</adf-main-menu-datatable-template>
</adf-datatable>
</ng-container>

View File

@@ -76,6 +76,10 @@ export abstract class BaseTaskListCloudComponent extends DataTableSchema impleme
@Input()
showContextMenu: boolean = false;
/** Toggles main datatable actions. */
@Input()
showMainDatatableActions: boolean = false;
/** Emitted before the context menu is displayed for a row. */
@Output()
showRowContextMenu = new EventEmitter<DataCellEvent>();
@@ -160,11 +164,23 @@ export abstract class BaseTaskListCloudComponent extends DataTableSchema impleme
take(1),
map((preferences => {
const preferencesList = preferences?.list?.entries ?? [];
const searchedPreferences = preferencesList.find(preference => preference.entry.key === TasksListCloudPreferences.columnOrder);
return searchedPreferences ? JSON.parse(searchedPreferences.entry.value) : null;
const columnsOrder = preferencesList.find(preference => preference.entry.key === TasksListCloudPreferences.columnOrder);
const columnsVisibility = preferencesList.find(preference => preference.entry.key === TasksListCloudPreferences.columnsVisibility);
return {
columnsOrder: columnsOrder ? JSON.parse(columnsOrder.entry.value) : undefined,
columnsVisibility: columnsVisibility ? JSON.parse(columnsVisibility.entry.value) : undefined
};
}))
).subscribe(columnsOrder => {
this.columnsOrder = columnsOrder;
).subscribe(({ columnsOrder, columnsVisibility }) => {
if (columnsOrder) {
this.columnsOrder = columnsOrder;
}
if (columnsVisibility) {
this.columnsVisibility = columnsVisibility;
}
this.createDatatableSchema();
}
);
@@ -261,6 +277,26 @@ export abstract class BaseTaskListCloudComponent extends DataTableSchema impleme
}
}
onColumnsVisibilityChange(columns: DataColumn[]): void {
this.columnsVisibility = columns.reduce((visibleColumnsMap, column) => {
if (column.isHidden !== undefined) {
visibleColumnsMap[column.id] = !column.isHidden;
}
return visibleColumnsMap;
}, {});
this.createColumns();
if (this.appName) {
this.cloudPreferenceService.updatePreference(
this.appName,
TasksListCloudPreferences.columnsVisibility,
this.columnsVisibility
);
}
}
setSorting(sortDetail) {
const sorting = sortDetail ? {
orderBy: sortDetail.key,

View File

@@ -18,7 +18,7 @@
import { Component, SimpleChange, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { AppConfigService, setupTestBed, DataRowEvent, ObjectDataRow, EcmUserModel } from '@alfresco/adf-core';
import { AppConfigService, setupTestBed, DataRowEvent, ObjectDataRow, EcmUserModel, DataColumn, ColumnsSelectorComponent } from '@alfresco/adf-core';
import { TaskListCloudService } from '../services/task-list-cloud.service';
import { TaskListCloudComponent } from './task-list-cloud.component';
import { fakeGlobalTask, fakeCustomSchema } from '../mock/fake-task-response.mock';
@@ -34,9 +34,9 @@ import { TASK_LIST_CLOUD_TOKEN } from '../../../services/cloud-token.service';
template: `
<adf-cloud-task-list #taskListCloud>
<data-columns>
<data-column key="name" title="ADF_CLOUD_TASK_LIST.PROPERTIES.NAME" class="adf-full-width adf-name-column"></data-column>
<data-column key="created" title="ADF_CLOUD_TASK_LIST.PROPERTIES.CREATED" class="adf-hidden"></data-column>
<data-column key="startedBy" title="ADF_CLOUD_TASK_LIST.PROPERTIES.CREATED" class="adf-desktop-only dw-dt-col-3 adf-ellipsis-cell">
<data-column id="name" key="name" title="ADF_CLOUD_TASK_LIST.PROPERTIES.NAME" class="adf-full-width adf-name-column"></data-column>
<data-column id="created" key="created" title="ADF_CLOUD_TASK_LIST.PROPERTIES.CREATED" class="adf-hidden"></data-column>
<data-column id="startedBy" key="startedBy" title="ADF_CLOUD_TASK_LIST.PROPERTIES.CREATED" class="adf-desktop-only dw-dt-col-3 adf-ellipsis-cell">
<ng-template let-entry="$implicit">
<div>{{getFullName(entry.row?.obj?.startedBy)}}</div>
</ng-template>
@@ -193,6 +193,37 @@ describe('TaskListCloudComponent', () => {
expect(component.columns).toEqual(fakeCustomSchema);
});
it('should hide columns on applying new columns visibility through columns selector', () => {
component.showMainDatatableActions = true;
spyOn(taskListCloudService, 'getTaskByRequest').and.returnValue(of(fakeGlobalTask));
const appName = new SimpleChange(null, 'FAKE-APP-NAME', true);
component.ngOnChanges({ appName });
fixture.detectChanges();
const mainMenuButton = fixture.debugElement.query(By.css('[data-automation-id="adf-datatable-main-menu-button"]'));
mainMenuButton.triggerEventHandler('click', {});
fixture.detectChanges();
const columnSelectorMenu = fixture.debugElement.query(By.css('adf-datatable-column-selector'));
expect(columnSelectorMenu).toBeTruthy();
const columnsSelectorInstance = columnSelectorMenu.componentInstance as ColumnsSelectorComponent;
expect(columnsSelectorInstance.columns).toBe(component.columns, 'should pass columns as input');
const newColumns = (component.columns as DataColumn[]).map((column, index) => ({
...column,
isHidden: index !== 0 // only first one is shown
}));
columnSelectorMenu.triggerEventHandler('submitColumnsVisibility', newColumns);
fixture.detectChanges();
const displayedColumns = fixture.debugElement.queryAll(By.css('.adf-datatable-cell-header'));
expect(displayedColumns.length).toBe(2, 'only column with isHidden set to false and action column should be shown');
});
it('should fetch custom schemaColumn when the input presetColumn is defined', () => {
component.presetColumn = 'fakeCustomSchema';
fixture.detectChanges();

View File

@@ -18,12 +18,14 @@
export const taskPresetsCloudDefaultModel = {
default: [
{
id: 'name',
key: 'name',
type: 'text',
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.NAME',
sortable: true
},
{
id: 'created',
key: 'created',
type: 'text',
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.CREATED',
@@ -31,6 +33,7 @@ export const taskPresetsCloudDefaultModel = {
sortable: true
},
{
id: 'assignee',
key: 'assignee',
type: 'text',
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.ASSIGNEE',

View File

@@ -1,4 +1,5 @@
// eslint-disable-next-line no-shadow
export enum TasksListCloudPreferences {
columnOrder = 'tasks-list-cloud-columns-order'
columnOrder = 'tasks-list-cloud-columns-order',
columnsVisibility = 'tasks-list-cloud-columns-visibility'
}