mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[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:
@@ -20,6 +20,7 @@
|
|||||||
[actions]="true"
|
[actions]="true"
|
||||||
[resolverFn]="resolver"
|
[resolverFn]="resolver"
|
||||||
rowStyleClass="custom-row-style"
|
rowStyleClass="custom-row-style"
|
||||||
|
[showMainDatatableActions]="true"
|
||||||
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
||||||
(executeRowAction)="onExecuteRowAction($event)">
|
(executeRowAction)="onExecuteRowAction($event)">
|
||||||
<!-- HTML column definition demo -->
|
<!-- HTML column definition demo -->
|
||||||
|
@@ -114,11 +114,15 @@ describe('ColumnsSelectorComponent', () => {
|
|||||||
|
|
||||||
const checkboxes = await loader.getAllHarnesses(MatCheckboxHarness);
|
const checkboxes = await loader.getAllHarnesses(MatCheckboxHarness);
|
||||||
|
|
||||||
expect(checkboxes.length).toBe(4);
|
const inputColumnsWithTitle = inputColumns.filter(column => !!column.title);
|
||||||
expect(await checkboxes[0].getLabelText()).toBe(inputColumns[0].title);
|
expect(checkboxes.length).toBe(inputColumnsWithTitle.length);
|
||||||
expect(await checkboxes[1].getLabelText()).toBe(inputColumns[1].title);
|
|
||||||
expect(await checkboxes[2].getLabelText()).toBe(inputColumns[2].title);
|
for await (const checkbox of checkboxes) {
|
||||||
expect(await checkboxes[3].getLabelText()).toBe(inputColumns[4].title);
|
const checkboxLabel = await checkbox.getLabelText();
|
||||||
|
|
||||||
|
const inputColumn = inputColumnsWithTitle.find(inputColumnWithTitle => inputColumnWithTitle.title === checkboxLabel);
|
||||||
|
expect(inputColumn).toBeTruthy('Should have all columns with title');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should filter columns by search text', fakeAsync(async () => {
|
it('should filter columns by search text', fakeAsync(async () => {
|
||||||
@@ -143,9 +147,13 @@ describe('ColumnsSelectorComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const firstColumnCheckbox = await loader.getHarness(MatCheckboxHarness);
|
const firstColumnCheckbox = await loader.getHarness(MatCheckboxHarness);
|
||||||
await firstColumnCheckbox.toggle();
|
const checkBoxName = await firstColumnCheckbox.getLabelText();
|
||||||
|
|
||||||
expect(component.columnItems[0].isHidden).toBe(true);
|
let toggledColumnItem = component.columnItems.find(item => item.title === checkBoxName);
|
||||||
|
expect(toggledColumnItem.isHidden).toBeFalsy();
|
||||||
|
|
||||||
|
await firstColumnCheckbox.toggle();
|
||||||
|
expect(toggledColumnItem.isHidden).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set proper default state for checkboxes', async () => {
|
it('should set proper default state for checkboxes', async () => {
|
||||||
@@ -159,4 +167,30 @@ describe('ColumnsSelectorComponent', () => {
|
|||||||
expect(await checkboxes[2].isChecked()).toBe(true);
|
expect(await checkboxes[2].isChecked()).toBe(true);
|
||||||
expect(await checkboxes[3].isChecked()).toBe(false);
|
expect(await checkboxes[3].isChecked()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should show hidden columns at the end of the list', async () => {
|
||||||
|
const hiddenDataColumn: DataColumn = {
|
||||||
|
id: 'hiddenDataColumn',
|
||||||
|
title: 'hiddenDataColumn',
|
||||||
|
key: 'hiddenDataColumn',
|
||||||
|
type: 'text',
|
||||||
|
isHidden: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const shownDataColumn: DataColumn = {
|
||||||
|
id: 'shownDataColumn',
|
||||||
|
title: 'shownDataColumn',
|
||||||
|
key: 'shownDataColumn',
|
||||||
|
type: 'text'
|
||||||
|
};
|
||||||
|
|
||||||
|
component.columns = [hiddenDataColumn, shownDataColumn];
|
||||||
|
menuOpenedTrigger.next();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const checkboxes = await loader.getAllHarnesses(MatCheckboxHarness);
|
||||||
|
|
||||||
|
expect(await checkboxes[0].getLabelText()).toBe(shownDataColumn.title);
|
||||||
|
expect(await checkboxes[1].getLabelText()).toBe(hiddenDataColumn.title);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -46,7 +46,8 @@ export class ColumnsSelectorComponent implements OnInit, OnDestroy {
|
|||||||
this.mainMenuTrigger.menuOpened.pipe(
|
this.mainMenuTrigger.menuOpened.pipe(
|
||||||
takeUntil(this.onDestroy$)
|
takeUntil(this.onDestroy$)
|
||||||
).subscribe(() => {
|
).subscribe(() => {
|
||||||
this.columnItems = this.columns.map(column => ({...column}));
|
const columns = this.columns.map(column => ({...column}));
|
||||||
|
this.columnItems = this.sortColumns(columns);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.mainMenuTrigger.menuClosed.pipe(
|
this.mainMenuTrigger.menuClosed.pipe(
|
||||||
@@ -80,4 +81,11 @@ export class ColumnsSelectorComponent implements OnInit, OnDestroy {
|
|||||||
this.submitColumnsVisibility.emit(this.columnItems);
|
this.submitColumnsVisibility.emit(this.columnItems);
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sortColumns(columns: DataColumn[]): DataColumn[] {
|
||||||
|
const shownColumns = columns.filter(column => !column.isHidden);
|
||||||
|
const hiddenColumns = columns.filter(column => column.isHidden);
|
||||||
|
|
||||||
|
return [...shownColumns, ...hiddenColumns];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -97,11 +97,13 @@
|
|||||||
|
|
||||||
<!-- Header actions (right) -->
|
<!-- Header actions (right) -->
|
||||||
<div
|
<div
|
||||||
*ngIf="actions && actionsPosition === 'right' || mainActionTemplate"
|
*ngIf="(actions && actionsPosition === 'right') ||
|
||||||
|
(mainActionTemplate && showMainDatatableActions)"
|
||||||
class="adf-actions-column adf-datatable-cell-header adf-datatable__actions-cell"
|
class="adf-actions-column adf-datatable-cell-header adf-datatable__actions-cell"
|
||||||
>
|
>
|
||||||
<ng-container *ngIf="mainActionTemplate">
|
<ng-container *ngIf="mainActionTemplate">
|
||||||
<button
|
<button
|
||||||
|
data-automation-id="adf-datatable-main-menu-button"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
#mainMenuTrigger="matMenuTrigger"
|
#mainMenuTrigger="matMenuTrigger"
|
||||||
[matMenuTriggerFor]="mainMenu">
|
[matMenuTriggerFor]="mainMenu">
|
||||||
@@ -286,7 +288,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Row actions (right) -->
|
<!-- Row actions (right) -->
|
||||||
<div *ngIf="(actions && actionsPosition === 'right') || mainActionTemplate"
|
<div *ngIf="
|
||||||
|
(actions && actionsPosition === 'right') ||
|
||||||
|
(mainActionTemplate && showMainDatatableActions)"
|
||||||
role="gridcell"
|
role="gridcell"
|
||||||
class="adf-datatable-cell adf-datatable__actions-cell adf-datatable-center-actions-column-ie">
|
class="adf-datatable-cell adf-datatable__actions-cell adf-datatable-center-actions-column-ie">
|
||||||
|
|
||||||
|
@@ -112,6 +112,10 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
|||||||
@Input()
|
@Input()
|
||||||
actions: boolean = false;
|
actions: boolean = false;
|
||||||
|
|
||||||
|
/** Toggles the main datatable action. */
|
||||||
|
@Input()
|
||||||
|
showMainDatatableActions: boolean = false;
|
||||||
|
|
||||||
/** Position of the actions dropdown menu. Can be "left" or "right". */
|
/** Position of the actions dropdown menu. Can be "left" or "right". */
|
||||||
@Input()
|
@Input()
|
||||||
actionsPosition: string = 'right'; // left|right
|
actionsPosition: string = 'right'; // left|right
|
||||||
|
@@ -38,8 +38,7 @@ export abstract class DataTableSchema {
|
|||||||
protected columnsOrder: string[] | undefined;
|
protected columnsOrder: string[] | undefined;
|
||||||
protected columnsOrderedByKey: string = 'id';
|
protected columnsOrderedByKey: string = 'id';
|
||||||
|
|
||||||
protected hiddenColumns: string[] | undefined;
|
protected columnsVisibility: { [columnId: string]: boolean } | undefined;
|
||||||
protected hiddenColumnsKey: string = 'id';
|
|
||||||
|
|
||||||
private layoutPresets = {};
|
private layoutPresets = {};
|
||||||
|
|
||||||
@@ -133,14 +132,13 @@ export abstract class DataTableSchema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setHiddenColumns(columns: DataColumn[]): DataColumn[] {
|
private setHiddenColumns(columns: DataColumn[]): DataColumn[] {
|
||||||
if (this.hiddenColumns) {
|
if (this.columnsVisibility) {
|
||||||
return columns.map(column => {
|
return columns.map(column => {
|
||||||
const columnShouldBeHidden = this.hiddenColumns.includes(column[this.hiddenColumnsKey]);
|
const isColumnVisible = this.columnsVisibility[column.id];
|
||||||
|
|
||||||
return {
|
return isColumnVisible === undefined ?
|
||||||
...column,
|
column :
|
||||||
isHidden: columnShouldBeHidden
|
{ ...column, isHidden: !isColumnVisible };
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
[actions]="showActions"
|
[actions]="showActions"
|
||||||
[actionsPosition]="actionsPosition"
|
[actionsPosition]="actionsPosition"
|
||||||
[contextMenu]="showContextMenu"
|
[contextMenu]="showContextMenu"
|
||||||
|
[showMainDatatableActions]="showMainDatatableActions"
|
||||||
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
||||||
(showRowContextMenu)="onShowRowContextMenu($event)"
|
(showRowContextMenu)="onShowRowContextMenu($event)"
|
||||||
(executeRowAction)="onExecuteRowAction($event)"
|
(executeRowAction)="onExecuteRowAction($event)"
|
||||||
@@ -39,4 +40,14 @@
|
|||||||
<ng-content select="adf-custom-empty-content-template"></ng-content>
|
<ng-content select="adf-custom-empty-content-template"></ng-content>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</adf-no-content-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>
|
</adf-datatable>
|
||||||
|
@@ -19,6 +19,8 @@ import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
|
|||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import {
|
import {
|
||||||
AppConfigService,
|
AppConfigService,
|
||||||
|
ColumnsSelectorComponent,
|
||||||
|
DataColumn,
|
||||||
DataRowEvent,
|
DataRowEvent,
|
||||||
ObjectDataRow,
|
ObjectDataRow,
|
||||||
setupTestBed
|
setupTestBed
|
||||||
@@ -225,6 +227,64 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
fixture.detectChanges();
|
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) => {
|
it('should reload tasks when reload() is called', (done) => {
|
||||||
component.appName = 'fake';
|
component.appName = 'fake';
|
||||||
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
||||||
|
@@ -159,6 +159,10 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
@Input()
|
@Input()
|
||||||
showContextMenu: boolean = false;
|
showContextMenu: boolean = false;
|
||||||
|
|
||||||
|
/** Toggle main datatable actions. */
|
||||||
|
@Input()
|
||||||
|
showMainDatatableActions: boolean = false;
|
||||||
|
|
||||||
/** Emitted when a row in the process list is clicked. */
|
/** Emitted when a row in the process list is clicked. */
|
||||||
@Output()
|
@Output()
|
||||||
rowClick: EventEmitter<string> = new EventEmitter<string>();
|
rowClick: EventEmitter<string> = new EventEmitter<string>();
|
||||||
@@ -223,14 +227,22 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
map((preferences => {
|
map((preferences => {
|
||||||
const preferencesList = preferences?.list?.entries ?? [];
|
const preferencesList = preferences?.list?.entries ?? [];
|
||||||
const columnsOrder = preferencesList.find(preference => preference.entry.key === ProcessListCloudPreferences.columnOrder);
|
const columnsOrder = preferencesList.find(preference => preference.entry.key === ProcessListCloudPreferences.columnOrder);
|
||||||
|
const columnsVisibility = preferencesList.find(preference => preference.entry.key === ProcessListCloudPreferences.columnsVisibility);
|
||||||
|
|
||||||
return {
|
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 }) => {
|
.subscribe(({ columnsOrder, columnsVisibility }) => {
|
||||||
this.columnsOrder = columnsOrder;
|
if (columnsVisibility) {
|
||||||
|
this.columnsVisibility = columnsVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnsOrder) {
|
||||||
|
this.columnsOrder = columnsOrder;
|
||||||
|
}
|
||||||
|
|
||||||
this.createDatatableSchema();
|
this.createDatatableSchema();
|
||||||
});
|
});
|
||||||
@@ -326,12 +338,33 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
}
|
}
|
||||||
|
|
||||||
onColumnOrderChanged(columnsWithNewOrder: DataColumn[]): void {
|
onColumnOrderChanged(columnsWithNewOrder: DataColumn[]): void {
|
||||||
|
this.columnsOrder = columnsWithNewOrder.map(column => column.id);
|
||||||
|
|
||||||
if (this.appName) {
|
if (this.appName) {
|
||||||
const newColumnsOrder = columnsWithNewOrder.map(column => column.id);
|
|
||||||
this.cloudPreferenceService.updatePreference(
|
this.cloudPreferenceService.updatePreference(
|
||||||
this.appName,
|
this.appName,
|
||||||
ProcessListCloudPreferences.columnOrder,
|
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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
export enum ProcessListCloudPreferences {
|
export enum ProcessListCloudPreferences {
|
||||||
columnOrder = 'processes-cloud-list-columns-order'
|
columnOrder = 'processes-cloud-list-columns-order',
|
||||||
|
columnsVisibility = 'processes-cloud-columns-visibility'
|
||||||
}
|
}
|
||||||
|
@@ -18,12 +18,14 @@
|
|||||||
export const processCloudPresetsDefaultModel = {
|
export const processCloudPresetsDefaultModel = {
|
||||||
default: [
|
default: [
|
||||||
{
|
{
|
||||||
|
id: 'id',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
title: 'ADF_CLOUD_PROCESS_LIST.PROPERTIES.NAME',
|
title: 'ADF_CLOUD_PROCESS_LIST.PROPERTIES.NAME',
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'startDate',
|
||||||
key: 'startDate',
|
key: 'startDate',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
title: 'ADF_CLOUD_PROCESS_LIST.PROPERTIES.START_DATE',
|
title: 'ADF_CLOUD_PROCESS_LIST.PROPERTIES.START_DATE',
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
[actionsPosition]="actionsPosition"
|
[actionsPosition]="actionsPosition"
|
||||||
[contextMenu]="showContextMenu"
|
[contextMenu]="showContextMenu"
|
||||||
[resolverFn]="boundReplacePriorityValues"
|
[resolverFn]="boundReplacePriorityValues"
|
||||||
|
[showMainDatatableActions]="showMainDatatableActions"
|
||||||
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
||||||
(showRowContextMenu)="onShowRowContextMenu($event)"
|
(showRowContextMenu)="onShowRowContextMenu($event)"
|
||||||
(executeRowAction)="onExecuteRowAction($event)"
|
(executeRowAction)="onExecuteRowAction($event)"
|
||||||
@@ -40,5 +41,15 @@
|
|||||||
<ng-content select="adf-custom-empty-content-template"></ng-content>
|
<ng-content select="adf-custom-empty-content-template"></ng-content>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</adf-no-content-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>
|
</adf-datatable>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@@ -76,6 +76,10 @@ export abstract class BaseTaskListCloudComponent extends DataTableSchema impleme
|
|||||||
@Input()
|
@Input()
|
||||||
showContextMenu: boolean = false;
|
showContextMenu: boolean = false;
|
||||||
|
|
||||||
|
/** Toggles main datatable actions. */
|
||||||
|
@Input()
|
||||||
|
showMainDatatableActions: boolean = false;
|
||||||
|
|
||||||
/** Emitted before the context menu is displayed for a row. */
|
/** Emitted before the context menu is displayed for a row. */
|
||||||
@Output()
|
@Output()
|
||||||
showRowContextMenu = new EventEmitter<DataCellEvent>();
|
showRowContextMenu = new EventEmitter<DataCellEvent>();
|
||||||
@@ -160,11 +164,23 @@ export abstract class BaseTaskListCloudComponent extends DataTableSchema impleme
|
|||||||
take(1),
|
take(1),
|
||||||
map((preferences => {
|
map((preferences => {
|
||||||
const preferencesList = preferences?.list?.entries ?? [];
|
const preferencesList = preferences?.list?.entries ?? [];
|
||||||
const searchedPreferences = preferencesList.find(preference => preference.entry.key === TasksListCloudPreferences.columnOrder);
|
const columnsOrder = preferencesList.find(preference => preference.entry.key === TasksListCloudPreferences.columnOrder);
|
||||||
return searchedPreferences ? JSON.parse(searchedPreferences.entry.value) : null;
|
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 => {
|
).subscribe(({ columnsOrder, columnsVisibility }) => {
|
||||||
this.columnsOrder = columnsOrder;
|
if (columnsOrder) {
|
||||||
|
this.columnsOrder = columnsOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnsVisibility) {
|
||||||
|
this.columnsVisibility = columnsVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
this.createDatatableSchema();
|
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) {
|
setSorting(sortDetail) {
|
||||||
const sorting = sortDetail ? {
|
const sorting = sortDetail ? {
|
||||||
orderBy: sortDetail.key,
|
orderBy: sortDetail.key,
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
import { Component, SimpleChange, ViewChild } from '@angular/core';
|
import { Component, SimpleChange, ViewChild } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
|
import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
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 { TaskListCloudService } from '../services/task-list-cloud.service';
|
||||||
import { TaskListCloudComponent } from './task-list-cloud.component';
|
import { TaskListCloudComponent } from './task-list-cloud.component';
|
||||||
import { fakeGlobalTask, fakeCustomSchema } from '../mock/fake-task-response.mock';
|
import { fakeGlobalTask, fakeCustomSchema } from '../mock/fake-task-response.mock';
|
||||||
@@ -34,9 +34,9 @@ import { TASK_LIST_CLOUD_TOKEN } from '../../../services/cloud-token.service';
|
|||||||
template: `
|
template: `
|
||||||
<adf-cloud-task-list #taskListCloud>
|
<adf-cloud-task-list #taskListCloud>
|
||||||
<data-columns>
|
<data-columns>
|
||||||
<data-column key="name" title="ADF_CLOUD_TASK_LIST.PROPERTIES.NAME" class="adf-full-width adf-name-column"></data-column>
|
<data-column id="name" 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 id="created" 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="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">
|
<ng-template let-entry="$implicit">
|
||||||
<div>{{getFullName(entry.row?.obj?.startedBy)}}</div>
|
<div>{{getFullName(entry.row?.obj?.startedBy)}}</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
@@ -193,6 +193,37 @@ describe('TaskListCloudComponent', () => {
|
|||||||
expect(component.columns).toEqual(fakeCustomSchema);
|
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', () => {
|
it('should fetch custom schemaColumn when the input presetColumn is defined', () => {
|
||||||
component.presetColumn = 'fakeCustomSchema';
|
component.presetColumn = 'fakeCustomSchema';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
@@ -18,12 +18,14 @@
|
|||||||
export const taskPresetsCloudDefaultModel = {
|
export const taskPresetsCloudDefaultModel = {
|
||||||
default: [
|
default: [
|
||||||
{
|
{
|
||||||
|
id: 'name',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.NAME',
|
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.NAME',
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'created',
|
||||||
key: 'created',
|
key: 'created',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.CREATED',
|
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.CREATED',
|
||||||
@@ -31,6 +33,7 @@ export const taskPresetsCloudDefaultModel = {
|
|||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'assignee',
|
||||||
key: 'assignee',
|
key: 'assignee',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.ASSIGNEE',
|
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.ASSIGNEE',
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
export enum TasksListCloudPreferences {
|
export enum TasksListCloudPreferences {
|
||||||
columnOrder = 'tasks-list-cloud-columns-order'
|
columnOrder = 'tasks-list-cloud-columns-order',
|
||||||
|
columnsVisibility = 'tasks-list-cloud-columns-visibility'
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user