Skip to content

Commit

Permalink
[AAE-7819] Change column order - enable drag and drop for datatable -…
Browse files Browse the repository at this point in the history
… [1/3] (#7567)

* [AAE-7819] Enable drag and drop for datatable [1/3]

* [AAE-7819] Change column order - load and save columns order preferences for PROCESSES - [2/3] (#7568)

* [AAE-7819] Load and save column order preferences for processes

* [AAE-7819] Load and save column order preferences for tasks [3/3] (#7569)

* fix css

* fix icon module import

* Fix unit tests

* Fix test

* Fix e2e

* Fix C279927
  • Loading branch information
BSekula committed Apr 11, 2022
1 parent e89cea7 commit 48c3fac
Show file tree
Hide file tree
Showing 33 changed files with 614 additions and 136 deletions.
14 changes: 7 additions & 7 deletions demo-shell/src/app/components/datatable/datatable.component.ts
Expand Up @@ -227,13 +227,13 @@ export class DataTableComponent {
],
[
{ type: 'image', key: 'icon', title: '', srTitle: 'Thumbnail' },
{ type: 'text', key: 'id', title: 'Id', sortable: true , cssClass: '' },
{ type: 'date', key: 'createdOn', title: 'Created On', sortable: true, cssClass: 'adf-ellipsis-cell adf-expand-cell-2' },
{ type: 'text', key: 'name', title: 'Name', cssClass: 'adf-ellipsis-cell', sortable: true },
{ type: 'text', key: 'createdBy.name', title: 'Created By', sortable: true, cssClass: ''},
{ type: 'json', key: 'json', title: 'Json', cssClass: 'adf-expand-cell-2'},
{ type: 'text', key: 'users', title: 'Users', cssClass: 'adf-expand-cell-2'},
{ type: 'json', key: 'status', title: 'Status', cssClass: 'adf-expand-cell-2'}
{ type: 'text', key: 'id', title: 'Id', sortable: true , cssClass: '', draggable: true},
{ type: 'date', key: 'createdOn', title: 'Created On', sortable: true, cssClass: 'adf-ellipsis-cell adf-expand-cell-2', draggable: true },
{ type: 'text', key: 'name', title: 'Name', cssClass: 'adf-ellipsis-cell', sortable: true, draggable: true },
{ type: 'text', key: 'createdBy.name', title: 'Created By', sortable: true, cssClass: '', draggable: true},
{ type: 'json', key: 'json', title: 'Json', cssClass: 'adf-expand-cell-2', draggable: true},
{ type: 'text', key: 'users', title: 'Users', cssClass: 'adf-expand-cell-2', draggable: true},
{ type: 'json', key: 'status', title: 'Status', cssClass: 'adf-expand-cell-2', draggable: true}
]
);

Expand Down
2 changes: 2 additions & 0 deletions docs/core/components/data-column.component.md
Expand Up @@ -43,6 +43,7 @@ Defines column properties for DataTable, Tasklist, Document List and other compo

| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| id | `string` | '' | Column identifier. |
| copyContent | `boolean` | | Enables/disables a [Clipboard directive](../../core/directives/clipboard.directive.md) to allow copying of cell contents. |
| cssClass | `string` | | Additional CSS class to be applied to column (header and cells). |
| editable | `boolean` | false | Toggles the editing support of the column data. |
Expand All @@ -51,6 +52,7 @@ Defines column properties for DataTable, Tasklist, Document List and other compo
| formatTooltip | `Function` | | Custom tooltip formatter function. |
| key | `string` | | Data source key. Can be either a column/property key like `title` or a property path like `createdBy.name`. |
| sortable | `boolean` | true | Toggles ability to sort by this column, for example by clicking the column header. |
| draggable | `boolean` | false | Toggles drag and drop for header column. |
| sortingKey | `string` | | When using server side sorting the column used by the api call where the sorting will be performed |
| srTitle | `string` | | Title to be used for screen readers. |
| title | `string` | "" | Display title of the column, typically used for column headers. You can use the i18n resource key to get it translated automatically. |
Expand Down
8 changes: 4 additions & 4 deletions e2e/core/pages/content-services.page.ts
Expand Up @@ -63,10 +63,10 @@ export class ContentServicesPage {
errorSnackBar = $('simple-snack-bar[class*="mat-simple-snackbar"]');
emptyPagination = $('adf-pagination[class*="adf-pagination__empty"]');
dragAndDrop = $$('adf-upload-drag-area div').first();
nameHeader = $$('div[data-automation-id="auto_id_name"] > span').first();
sizeHeader = $$('div[data-automation-id="auto_id_content.sizeInBytes"] > span').first();
createdByHeader = $$('div[data-automation-id="auto_id_createdByUser.displayName"] > span').first();
createdHeader = $$('div[data-automation-id="auto_id_createdAt"] > span').first();
nameHeader = $$('div[data-automation-id="auto_header_content_id_name"] > span').first();
sizeHeader = $$('div[data-automation-id="auto_header_content_id_content.sizeInBytes"] > span').first();
createdByHeader = $$('div[data-automation-id="auto_header_content_id_createdByUser.displayName"] > span').first();
createdHeader = $$('div[data-automation-id="auto_header_content_id_createdAt"] > span').first();
recentFiles = $('.app-container-recent');
recentFilesExpanded = $('.app-container-recent mat-expansion-panel-header.mat-expanded');
recentFilesClosed = $('.app-container-recent mat-expansion-panel-header');
Expand Down
Expand Up @@ -59,6 +59,8 @@ import { DocumentListModule } from '../document-list.module';
import { TranslateModule } from '@ngx-translate/core';
import { ShareDataRow } from '../data/share-data-row.model';
import { DocumentLoaderNode } from '../models/document-folder.model';
import { matIconRegistryMock } from '../../testing/mat-icon-registry-mock';
import { domSanitizerMock } from '../../testing/dom-sanitizer-mock';

describe('DocumentList', () => {

Expand Down Expand Up @@ -1139,7 +1141,7 @@ describe('DocumentList', () => {

it('should display [empty folder] template ', () => {
fixture.detectChanges();
documentList.dataTable = new DataTableComponent(null, null);
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock);
expect(documentList.dataTable).toBeDefined();
expect(fixture.debugElement.query(By.css('adf-empty-list'))).not.toBeNull();
});
Expand All @@ -1157,7 +1159,7 @@ describe('DocumentList', () => {
});

it('should empty folder NOT show the pagination', () => {
documentList.dataTable = new DataTableComponent(null, null);
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock);

expect(documentList.isEmpty()).toBeTruthy();
expect(element.querySelector('alfresco-pagination')).toBe(null);
Expand Down
5 changes: 5 additions & 0 deletions lib/content-services/src/lib/testing/dom-sanitizer-mock.ts
@@ -0,0 +1,5 @@
import { DomSanitizer } from '@angular/platform-browser';

export const domSanitizerMock = {
bypassSecurityTrustResourceUrl: () => {}
} as any as DomSanitizer;
@@ -0,0 +1,5 @@
import { MatIconRegistry } from '@angular/material/icon';

export const matIconRegistryMock = {
addSvgIconInNamespace: () => {}
} as any as MatIconRegistry;
1 change: 1 addition & 0 deletions lib/core/assets/images/drag_indicator_24px.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions lib/core/data-column/data-column.component.ts
Expand Up @@ -25,6 +25,9 @@ import { Component, ContentChild, Input, OnInit, TemplateRef } from '@angular/co
})
export class DataColumnComponent implements OnInit {

@Input()
id: string = '';

/** Data source key. Can be either a column/property key like `title`
* or a property path like `createdBy.name`.
*/
Expand All @@ -45,6 +48,10 @@ export class DataColumnComponent implements OnInit {
@Input()
sortable: boolean = true;

/* Enable drag and drop for header column */
@Input()
draggable: boolean = false;

/** Display title of the column, typically used for column headers. You can use the
* i18n resource key to get it translated automatically.
*/
Expand Down
67 changes: 60 additions & 7 deletions lib/core/datatable/components/datatable/datatable.component.html
Expand Up @@ -8,21 +8,26 @@
[class.adf-datatable--empty--header-visible]="isEmpty() && isHeaderVisible()">
<div *ngIf="isHeaderVisible()" class="adf-datatable-header" role="rowgroup" [ngClass]="{ 'adf-sr-only': !isHeaderVisible() }">
<adf-datatable-row
cdkDropList
cdkDropListOrientation="horizontal"
data-automation-id="datatable-row-header"
[disabled]="!isHeaderVisible()"
class="adf-datatable-row"
*ngIf="display === 'list'"
role="row">

<!-- Actions (left) -->
<div *ngIf="actions && actionsPosition === 'left'" class="adf-actions-column adf-datatable-cell-header">
<span class="adf-sr-only">{{ 'ADF-DATATABLE.ACCESSIBILITY.ACTIONS' | translate }}</span>
</div>

<!-- Columns -->
<div *ngIf="multiselect" class="adf-datatable-cell-header adf-datatable-checkbox">
<mat-checkbox [indeterminate]="isSelectAllIndeterminate" [checked]="isSelectAllChecked" (change)="onSelectAllClick($event)" class="adf-checkbox-sr-only">{{ 'ADF-DATATABLE.ACCESSIBILITY.SELECT_ALL' | translate }}</mat-checkbox>
</div>

<div class="adf-datatable-cell--{{col.type || 'text'}} {{col.cssClass}} adf-datatable-cell-header"
*ngFor="let col of data.getColumns()"
*ngFor="let col of data.getColumns(); let columnIndex = index"
[class.adf-sortable]="col.sortable"
[attr.data-automation-id]="'auto_id_' + col.key"
[class.adf-datatable__header--sorted-asc]="isColumnSorted(col, 'asc')"
Expand All @@ -32,14 +37,59 @@
role="columnheader"
[attr.tabindex]="isHeaderVisible() ? 0 : null"
[attr.aria-sort]="col.sortable ? (getAriaSort(col) | translate) : null"
cdkDrag
cdkDragBoundary="adf-datatable-row"
cdkDragLockAxis="x"
(cdkDragStarted)="isDraggingHeaderColumn = true"
(cdkDragDropped)="onDropHeaderColumn($event)"
[cdkDragDisabled]="!col.draggable"
(mouseenter)="hoveredHeaderColumnIndex = columnIndex"
(mouseleave)="hoveredHeaderColumnIndex = -1"
adf-drop-zone dropTarget="header" [dropColumn]="col">
<ng-container *ngIf="!col.header">
<span *ngIf="col.title" class="adf-datatable-cell-value">{{ col.title | translate}}</span>
<span *ngIf="col.title && col.sortable" class="adf-sr-only" aria-live="polite">{{ getSortLiveAnnouncement(col) | translate: { string: col.title | translate } }}</span>

<div
*ngIf="!col.header"
[attr.data-automation-id]="'auto_header_content_id_' + col.key"
class="adf-datatable-cell-header-content"
[class.adf-datatable-cell-header-content--hovered]="hoveredHeaderColumnIndex === columnIndex && !isDraggingHeaderColumn"
>
<span
*ngIf="hoveredHeaderColumnIndex === columnIndex && col.draggable"
class="adf-datatable-cell-header-drag-icon-placeholder"
[attr.data-automation-id]="'adf-datatable-cell-header-drag-icon-placeholder-'+col.key"
></span>

<span *ngIf="col.title" class="adf-datatable-cell-value"> {{col.title | translate}}</span>

<span *ngIf="col.title && col.sortable && isDraggingHeaderColumn" class="adf-sr-only" aria-live="polite">
{{ getSortLiveAnnouncement(col) | translate: { string: col.title | translate } }}
</span>

<ng-template *ngIf="allowFiltering" [ngTemplateOutlet]="headerFilterTemplate" [ngTemplateOutletContext]="{$implicit: col}"></ng-template>
</ng-container>

<span
[class.adf-datatable__header--sorted-asc]="isColumnSorted(col, 'asc')"
[class.adf-datatable__header--sorted-desc]="isColumnSorted(col, 'desc')">
</span>
</div>

<ng-template *ngIf="col.header" [ngTemplateOutlet]="col.header" [ngTemplateOutletContext]="{$implicit: col}"></ng-template>

<div
*ngIf="col.draggable"
cdkDragHandle
class="adf-datatable-cell-header-drag-icon"
>
<adf-icon
*ngIf="hoveredHeaderColumnIndex === columnIndex"
value="adf:drag_indicator"
[attr.data-automation-id]="'adf-datatable-cell-header-drag-icon-'+col.key">
</adf-icon>
</div>

<div class="adf-drop-header-cell-placeholder" *cdkDragPlaceholder></div>
</div>

<!-- Actions (right) -->
<div *ngIf="actions && actionsPosition === 'right'" class="adf-actions-column adf-datatable-cell-header adf-datatable__actions-cell">
<span class="adf-sr-only">{{ 'ADF-DATATABLE.ACCESSIBILITY.ACTIONS' | translate }}</span>
Expand All @@ -58,7 +108,10 @@
</mat-form-field>
</div>

<div class="adf-datatable-body" role="rowgroup">
<div
class="adf-datatable-body"
[class.adf-blur-datatable-body]="isDraggingHeaderColumn"
role="rowgroup">
<ng-container *ngIf="!loading && !noPermission">
<adf-datatable-row *ngFor="let row of data.getRows(); let idx = index"
[row]="row"
Expand Down Expand Up @@ -171,7 +224,7 @@
[tooltip]="getCellTooltip(row, col)">
</adf-filesize-cell>
</div>
<div *ngSwitchCase="'text'" [attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1" class="adf-cell-value"
<div *ngSwitchCase="'text'" [attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1" class="adf-cell-value"
[attr.data-automation-id]="'text_' + data.getValue(row, col, resolverFn)">
<adf-datatable-cell
[copyContent]="col.copyContent"
Expand Down

0 comments on commit 48c3fac

Please sign in to comment.