mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
AAE-28454 Improve datatable actions display (#10445)
* AAE-28454 Improve datatable actions display * AAE-28454 Improve datatable style
This commit is contained in:
parent
c92d34f2f8
commit
70a38aecda
@ -31,101 +31,106 @@
|
|||||||
<mat-checkbox [indeterminate]="isSelectAllIndeterminate" [checked]="isSelectAllChecked" (change)="onSelectAllClick($event)" class="adf-checkbox-sr-only">{{ 'ADF-DATATABLE.ACCESSIBILITY.SELECT_ALL' | translate }}</mat-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>
|
||||||
|
|
||||||
|
<ng-container
|
||||||
|
*ngFor="
|
||||||
|
let col of getVisibleColumns();
|
||||||
|
let columnIndex = index
|
||||||
|
let lastColumn = last"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="adf-datatable-cell--{{col.type || 'text'}} {{col.cssClass}} adf-datatable-cell-header adf-datatable-cell-data"
|
class="adf-datatable-cell--{{col.type || 'text'}} {{col.cssClass}} adf-datatable-cell-header adf-datatable-cell-data"
|
||||||
*ngFor="
|
*ngIf="col.title || !showProvidedActions"
|
||||||
let col of getVisibleColumns();
|
[attr.data-automation-id]="'auto_id_' + col.key"
|
||||||
let columnIndex = index
|
[ngClass]="{
|
||||||
let lastColumn = last"
|
'adf-sortable': col.sortable,
|
||||||
[attr.data-automation-id]="'auto_id_' + col.key"
|
'adf-datatable__cursor--pointer': !isResizing,
|
||||||
[ngClass]="{
|
'adf-datatable__header--sorted-asc': isColumnSorted(col, 'asc'),
|
||||||
'adf-sortable': col.sortable,
|
'adf-datatable__header--sorted-desc': isColumnSorted(col, 'desc')}"
|
||||||
'adf-datatable__cursor--pointer': !isResizing,
|
[ngStyle]="(col.width) && !lastColumn && {'flex': getFlexValue(col)}"
|
||||||
'adf-datatable__header--sorted-asc': isColumnSorted(col, 'asc'),
|
[attr.aria-label]="col.title | translate"
|
||||||
'adf-datatable__header--sorted-desc': isColumnSorted(col, 'desc')}"
|
(click)="onColumnHeaderClick(col, $event)"
|
||||||
[ngStyle]="(col.width) && !lastColumn && {'flex': getFlexValue(col)}"
|
(keyup.enter)="onColumnHeaderClick(col, $event)"
|
||||||
[attr.aria-label]="col.title | translate"
|
role="columnheader"
|
||||||
(click)="onColumnHeaderClick(col, $event)"
|
[attr.tabindex]="isHeaderVisible() ? 0 : null"
|
||||||
(keyup.enter)="onColumnHeaderClick(col, $event)"
|
[attr.aria-sort]="col.sortable ? (getAriaSort(col) | translate) : null"
|
||||||
role="columnheader"
|
cdkDrag
|
||||||
[attr.tabindex]="isHeaderVisible() ? 0 : null"
|
cdkDragLockAxis="x"
|
||||||
[attr.aria-sort]="col.sortable ? (getAriaSort(col) | translate) : null"
|
(cdkDragStarted)="isDraggingHeaderColumn = true"
|
||||||
cdkDrag
|
(cdkDragDropped)="onDropHeaderColumn($event)"
|
||||||
cdkDragLockAxis="x"
|
[cdkDragDisabled]="!col.draggable"
|
||||||
(cdkDragStarted)="isDraggingHeaderColumn = true"
|
(mouseenter)="hoveredHeaderColumnIndex = columnIndex"
|
||||||
(cdkDragDropped)="onDropHeaderColumn($event)"
|
(mouseleave)="hoveredHeaderColumnIndex = -1"
|
||||||
[cdkDragDisabled]="!col.draggable"
|
adf-drop-zone dropTarget="header" [dropColumn]="col">
|
||||||
(mouseenter)="hoveredHeaderColumnIndex = columnIndex"
|
|
||||||
(mouseleave)="hoveredHeaderColumnIndex = -1"
|
|
||||||
adf-drop-zone dropTarget="header" [dropColumn]="col">
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
adf-resizable
|
adf-resizable
|
||||||
#resizableElement="adf-resizable"
|
#resizableElement="adf-resizable"
|
||||||
[coverPadding]="10"
|
[coverPadding]="10"
|
||||||
(resizing)="onResizing($event, columnIndex)"
|
(resizing)="onResizing($event, columnIndex)"
|
||||||
(resizeStart)="resizingColumnIndex = columnIndex"
|
(resizeStart)="resizingColumnIndex = columnIndex"
|
||||||
(resizeEnd)="onResizingEnd()"
|
(resizeEnd)="onResizingEnd()"
|
||||||
[attr.data-automation-id]="'auto_header_content_id_' + col.key"
|
[attr.data-automation-id]="'auto_header_content_id_' + col.key"
|
||||||
class="adf-datatable-cell-header-content"
|
class="adf-datatable-cell-header-content"
|
||||||
[ngClass]="{ 'adf-datatable-cell-header-content--hovered':
|
[ngClass]="{ 'adf-datatable-cell-header-content--hovered':
|
||||||
hoveredHeaderColumnIndex === columnIndex &&
|
hoveredHeaderColumnIndex === columnIndex &&
|
||||||
!isDraggingHeaderColumn &&
|
!isDraggingHeaderColumn &&
|
||||||
!isResizing && col.sortable}"
|
!isResizing && col.sortable}"
|
||||||
|
>
|
||||||
|
<ng-container *ngIf="!col.header">
|
||||||
|
<span *ngIf="col.title" title="{{col.title | translate}}" 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>
|
||||||
|
|
||||||
|
<span *ngIf="!col.title && !col.sortable && !headerFilterTemplate" [attr.title]="'ADF-DATATABLE.ACCESSIBILITY.EMPTY_HEADER' | translate"></span>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<div *ngIf="col.header" class="adf-datatable-cell-value">
|
||||||
|
<ng-template [ngTemplateOutlet]="col.header" [ngTemplateOutletContext]="{$implicit: col}"></ng-template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span
|
||||||
|
[class.adf-datatable__header--sorted-asc]="isColumnSorted(col, 'asc')"
|
||||||
|
[class.adf-datatable__header--sorted-desc]="isColumnSorted(col, 'desc')">
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<ng-template *ngIf="allowFiltering" [ngTemplateOutlet]="headerFilterTemplate" [ngTemplateOutletContext]="{$implicit: col}"></ng-template>
|
||||||
|
|
||||||
|
<span
|
||||||
|
*ngIf="col.draggable"
|
||||||
|
cdkDragHandle
|
||||||
|
[ngClass]="{ 'adf-datatable-cell-header-drag-icon': !isResizing }"
|
||||||
>
|
>
|
||||||
<ng-container *ngIf="!col.header">
|
<adf-icon
|
||||||
<span *ngIf="col.title" title="{{col.title | translate}}" class="adf-datatable-cell-value">{{col.title | translate}}</span>
|
*ngIf="hoveredHeaderColumnIndex === columnIndex && !isResizing"
|
||||||
|
value="adf:drag_indicator"
|
||||||
<span *ngIf="col.title && col.sortable && isDraggingHeaderColumn" class="adf-sr-only" aria-live="polite">
|
class="adf-datatable-cell-header-drag-icon-visible"
|
||||||
{{ getSortLiveAnnouncement(col) | translate: { string: col.title | translate } }}
|
[attr.data-automation-id]="'adf-datatable-cell-header-drag-icon-'+col.key" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span *ngIf="!col.title && !col.sortable && !headerFilterTemplate" [attr.title]="'ADF-DATATABLE.ACCESSIBILITY.EMPTY_HEADER' | translate"></span>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<div *ngIf="col.header" class="adf-datatable-cell-value">
|
|
||||||
<ng-template [ngTemplateOutlet]="col.header" [ngTemplateOutletContext]="{$implicit: col}"></ng-template>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<span
|
|
||||||
[class.adf-datatable__header--sorted-asc]="isColumnSorted(col, 'asc')"
|
|
||||||
[class.adf-datatable__header--sorted-desc]="isColumnSorted(col, 'desc')">
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<ng-template *ngIf="allowFiltering" [ngTemplateOutlet]="headerFilterTemplate" [ngTemplateOutletContext]="{$implicit: col}"></ng-template>
|
|
||||||
|
|
||||||
<span
|
|
||||||
*ngIf="col.draggable"
|
|
||||||
cdkDragHandle
|
|
||||||
[ngClass]="{ 'adf-datatable-cell-header-drag-icon': !isResizing }"
|
|
||||||
>
|
|
||||||
<adf-icon
|
|
||||||
*ngIf="hoveredHeaderColumnIndex === columnIndex && !isResizing"
|
|
||||||
value="adf:drag_indicator"
|
|
||||||
class="adf-datatable-cell-header-drag-icon-visible"
|
|
||||||
[attr.data-automation-id]="'adf-datatable-cell-header-drag-icon-'+col.key" />
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
*ngIf="isResizingEnabled && col.resizable && !lastColumn"
|
|
||||||
[ngClass]="hoveredHeaderColumnIndex === columnIndex && !isResizing || resizingColumnIndex === columnIndex ? 'adf-datatable__resize-handle-visible' : 'adf-datatable__resize-handle-hidden'"
|
|
||||||
adf-resize-handle
|
|
||||||
tabindex="0"
|
|
||||||
role="button"
|
|
||||||
(click)="$event.stopPropagation()"
|
|
||||||
(keyup.enter)="$event.stopPropagation()"
|
|
||||||
class="adf-datatable__resize-handle"
|
|
||||||
[resizableContainer]="resizableElement">
|
|
||||||
<div class="adf-datatable__resize-handle--divider"></div>
|
|
||||||
</div>
|
|
||||||
<div class="adf-drop-header-cell-placeholder" *cdkDragPlaceholder></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
*ngIf="isResizingEnabled && col.resizable && !lastColumn"
|
||||||
|
[ngClass]="hoveredHeaderColumnIndex === columnIndex && !isResizing || resizingColumnIndex === columnIndex ? 'adf-datatable__resize-handle-visible' : 'adf-datatable__resize-handle-hidden'"
|
||||||
|
adf-resize-handle
|
||||||
|
tabindex="0"
|
||||||
|
role="button"
|
||||||
|
(click)="$event.stopPropagation()"
|
||||||
|
(keyup.enter)="$event.stopPropagation()"
|
||||||
|
class="adf-datatable__resize-handle"
|
||||||
|
[resizableContainer]="resizableElement">
|
||||||
|
<div class="adf-datatable__resize-handle--divider"></div>
|
||||||
|
</div>
|
||||||
|
<div class="adf-drop-header-cell-placeholder" *cdkDragPlaceholder></div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<!-- Header actions (right) -->
|
<!-- Header actions (right) -->
|
||||||
<div
|
<div
|
||||||
*ngIf="(actions && actionsPosition === 'right') ||
|
*ngIf="(actions && actionsPosition === 'right') ||
|
||||||
(mainActionTemplate && showMainDatatableActions)"
|
(mainActionTemplate && showMainDatatableActions)"
|
||||||
class="adf-actions-column adf-datatable-actions-menu adf-datatable-cell-header adf-datatable__actions-cell"
|
class="adf-actions-column adf-datatable-actions-menu adf-datatable-cell-header adf-datatable__actions-cell"
|
||||||
|
[class.adf-datatable-actions-menu-provided]="showProvidedActions"
|
||||||
>
|
>
|
||||||
<ng-container *ngIf="mainActionTemplate">
|
<ng-container *ngIf="mainActionTemplate">
|
||||||
<button
|
<button
|
||||||
@ -367,8 +372,9 @@
|
|||||||
|
|
||||||
<!-- Row actions (right) -->
|
<!-- Row actions (right) -->
|
||||||
<div *ngIf="
|
<div *ngIf="
|
||||||
(actions && actionsPosition === 'right') ||
|
!showProvidedActions &&
|
||||||
(mainActionTemplate && showMainDatatableActions)"
|
((actions && actionsPosition === 'right') ||
|
||||||
|
(mainActionTemplate && showMainDatatableActions))"
|
||||||
role="gridcell"
|
role="gridcell"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="adf-datatable-cell adf-datatable__actions-cell adf-datatable-center-actions-column-ie adf-datatable-actions-menu">
|
class="adf-datatable-cell adf-datatable__actions-cell adf-datatable-center-actions-column-ie adf-datatable-actions-menu">
|
||||||
|
@ -324,6 +324,12 @@ $data-table-cell-min-width-file-size: $data-table-cell-min-width-1 !default;
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
padding-right: 15px;
|
padding-right: 15px;
|
||||||
|
|
||||||
|
&-provided {
|
||||||
|
max-width: 100px !important;
|
||||||
|
justify-content: center;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.adf-datatable-checkbox {
|
.adf-datatable-checkbox {
|
||||||
|
@ -2188,4 +2188,95 @@ describe('Column Resizing', () => {
|
|||||||
dataTable.onDragDrop(data as CdkDragDrop<any>);
|
dataTable.onDragDrop(data as CdkDragDrop<any>);
|
||||||
expect(dataTable.dragDropped.emit).toHaveBeenCalledWith(data);
|
expect(dataTable.dragDropped.emit).toHaveBeenCalledWith(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('show correct column count', () => {
|
||||||
|
it('should display 2 columns for no provided actions and no default actions', () => {
|
||||||
|
dataTable.data = new ObjectDataTableAdapter(
|
||||||
|
[{ name: '1' }],
|
||||||
|
[new ObjectDataColumn({ key: 'name', title: 'Name', sortable: true }), new ObjectDataColumn({ key: 'other', title: 'Other', sortable: true })]
|
||||||
|
);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const visibleColumns = dataTable.getVisibleColumns();
|
||||||
|
|
||||||
|
const datatableCellHeaders = fixture.debugElement.queryAll(By.css('.adf-datatable-cell-header'));
|
||||||
|
const datatableCells = fixture.debugElement.queryAll(By.css('.adf-datatable-cell'));
|
||||||
|
|
||||||
|
expect(visibleColumns.length).toBe(2);
|
||||||
|
|
||||||
|
const expectedNumberOfColumns = 2;
|
||||||
|
|
||||||
|
expect(datatableCellHeaders.length).toBe(expectedNumberOfColumns);
|
||||||
|
expect(datatableCells.length).toBe(expectedNumberOfColumns);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display 2 columns if last column has no title and there are no provided actions and no default actions', () => {
|
||||||
|
dataTable.data = new ObjectDataTableAdapter(
|
||||||
|
[{ name: '1' }],
|
||||||
|
[new ObjectDataColumn({ key: 'name', title: 'Name', sortable: true }), new ObjectDataColumn({ key: 'other', sortable: true })]
|
||||||
|
);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const visibleColumns = dataTable.getVisibleColumns();
|
||||||
|
|
||||||
|
const datatableCellHeaders = fixture.debugElement.queryAll(By.css('.adf-datatable-cell-header'));
|
||||||
|
const datatableCells = fixture.debugElement.queryAll(By.css('.adf-datatable-cell'));
|
||||||
|
|
||||||
|
expect(visibleColumns.length).toBe(2);
|
||||||
|
|
||||||
|
const expectedNumberOfColumns = 2;
|
||||||
|
|
||||||
|
expect(datatableCellHeaders.length).toBe(expectedNumberOfColumns);
|
||||||
|
expect(datatableCells.length).toBe(expectedNumberOfColumns);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display 3 columns if there are default actions', () => {
|
||||||
|
dataTable.data = new ObjectDataTableAdapter(
|
||||||
|
[{ name: '1' }],
|
||||||
|
[new ObjectDataColumn({ key: 'name', title: 'Name', sortable: true }), new ObjectDataColumn({ key: 'other', title: 'Other', sortable: true })]
|
||||||
|
);
|
||||||
|
|
||||||
|
dataTable.actions = true;
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const visibleColumns = dataTable.getVisibleColumns();
|
||||||
|
|
||||||
|
const datatableCellHeaders = fixture.debugElement.queryAll(By.css('.adf-datatable-cell-header'));
|
||||||
|
const datatableCells = fixture.debugElement.queryAll(By.css('.adf-datatable-cell'));
|
||||||
|
|
||||||
|
expect(visibleColumns.length).toBe(2);
|
||||||
|
|
||||||
|
const expectedNumberOfColumns = 3;
|
||||||
|
|
||||||
|
expect(datatableCellHeaders.length).toBe(expectedNumberOfColumns);
|
||||||
|
expect(datatableCells.length).toBe(expectedNumberOfColumns);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display 2 columns if there are default actions and provided actions', () => {
|
||||||
|
dataTable.data = new ObjectDataTableAdapter(
|
||||||
|
[{ name: '1' }],
|
||||||
|
[new ObjectDataColumn({ key: 'name', title: 'Name', sortable: true }), new ObjectDataColumn({ key: 'other', sortable: true })]
|
||||||
|
);
|
||||||
|
|
||||||
|
dataTable.actions = true;
|
||||||
|
dataTable.showProvidedActions = true;
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const visibleColumns = dataTable.getVisibleColumns();
|
||||||
|
|
||||||
|
const datatableCellHeaders = fixture.debugElement.queryAll(By.css('.adf-datatable-cell-header'));
|
||||||
|
const datatableCells = fixture.debugElement.queryAll(By.css('.adf-datatable-cell'));
|
||||||
|
|
||||||
|
expect(visibleColumns.length).toBe(2);
|
||||||
|
|
||||||
|
const expectedNumberOfColumns = 2;
|
||||||
|
|
||||||
|
expect(datatableCellHeaders.length).toBe(expectedNumberOfColumns);
|
||||||
|
expect(datatableCells.length).toBe(expectedNumberOfColumns);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -178,6 +178,10 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
|||||||
@Input()
|
@Input()
|
||||||
showMainDatatableActions: boolean = false;
|
showMainDatatableActions: boolean = false;
|
||||||
|
|
||||||
|
/** Toggles the provided actions. */
|
||||||
|
@Input()
|
||||||
|
showProvidedActions: 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
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
[actionsPosition]="actionsPosition"
|
[actionsPosition]="actionsPosition"
|
||||||
[contextMenu]="showContextMenu"
|
[contextMenu]="showContextMenu"
|
||||||
[showMainDatatableActions]="showMainDatatableActions"
|
[showMainDatatableActions]="showMainDatatableActions"
|
||||||
|
[showProvidedActions]="showProvidedActions"
|
||||||
[isResizingEnabled]="isResizingEnabled"
|
[isResizingEnabled]="isResizingEnabled"
|
||||||
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
||||||
(showRowContextMenu)="onShowRowContextMenu($event)"
|
(showRowContextMenu)="onShowRowContextMenu($event)"
|
||||||
|
@ -192,6 +192,10 @@ export class ProcessListCloudComponent
|
|||||||
@Input()
|
@Input()
|
||||||
showActions: boolean = false;
|
showActions: boolean = false;
|
||||||
|
|
||||||
|
/** Toggles the provided actions. */
|
||||||
|
@Input()
|
||||||
|
showProvidedActions: 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user