[ACS-6565] ADW - Document List View Header - UX Bugs (Additional fixes) (#9404)

This commit is contained in:
jacekpluta
2024-03-08 20:53:52 +01:00
committed by GitHub
parent 5d545b5f0d
commit 7ed137551c
5 changed files with 56 additions and 66 deletions

View File

@@ -9,7 +9,7 @@
(change)="changeHandler($event, option)" (change)="changeHandler($event, option)"
class="adf-facet-filter"> class="adf-facet-filter">
<div matTooltip="{{ option.name | translate }}" <div matTooltip="{{ option.name | translate }}"
matTooltipPosition="right" matTooltipPosition="before"
class="adf-search-check-list-label"> class="adf-search-check-list-label">
{{ option.name | translate }} {{ option.name | translate }}
</div> </div>

View File

@@ -27,17 +27,19 @@
<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>
<div class="adf-datatable-cell--{{col.type || 'text'}} {{col.cssClass}} adf-datatable-cell-header" <div
class="adf-datatable-cell--{{col.type || 'text'}} {{col.cssClass}} adf-datatable-cell-header adf-datatable-cell-data"
*ngFor=" *ngFor="
let col of (data.getColumns() | filterOutEvery:'isHidden':true); let col of (data.getColumns() | filterOutEvery:'isHidden':true);
let columnIndex = index" let columnIndex = index
let lastColumn = last"
[attr.data-automation-id]="'auto_id_' + col.key" [attr.data-automation-id]="'auto_id_' + col.key"
[ngClass]="{ [ngClass]="{
'adf-sortable': col.sortable, 'adf-sortable': col.sortable,
'adf-datatable__cursor--pointer': !isResizing, 'adf-datatable__cursor--pointer': !isResizing,
'adf-datatable__header--sorted-asc': isColumnSorted(col, 'asc'), 'adf-datatable__header--sorted-asc': isColumnSorted(col, 'asc'),
'adf-datatable__header--sorted-desc': isColumnSorted(col, 'desc')}" 'adf-datatable__header--sorted-desc': isColumnSorted(col, 'desc')}"
[ngStyle]="(col.width) && {'flex': getFlexValue(col)}" [ngStyle]="(col.width) && !lastColumn && {'flex-basis': getFlexBasisValue(col)}"
[attr.aria-label]="col.title | translate" [attr.aria-label]="col.title | translate"
(click)="onColumnHeaderClick(col, $event)" (click)="onColumnHeaderClick(col, $event)"
(keyup.enter)="onColumnHeaderClick(col, $event)" (keyup.enter)="onColumnHeaderClick(col, $event)"
@@ -45,7 +47,6 @@
[attr.tabindex]="isHeaderVisible() ? 0 : null" [attr.tabindex]="isHeaderVisible() ? 0 : null"
[attr.aria-sort]="col.sortable ? (getAriaSort(col) | translate) : null" [attr.aria-sort]="col.sortable ? (getAriaSort(col) | translate) : null"
cdkDrag cdkDrag
cdkDragBoundary="adf-datatable-row"
cdkDragLockAxis="x" cdkDragLockAxis="x"
(cdkDragStarted)="isDraggingHeaderColumn = true" (cdkDragStarted)="isDraggingHeaderColumn = true"
(cdkDragDropped)="onDropHeaderColumn($event)" (cdkDragDropped)="onDropHeaderColumn($event)"
@@ -90,13 +91,19 @@
<ng-template *ngIf="allowFiltering" [ngTemplateOutlet]="headerFilterTemplate" [ngTemplateOutletContext]="{$implicit: col}"></ng-template> <ng-template *ngIf="allowFiltering" [ngTemplateOutlet]="headerFilterTemplate" [ngTemplateOutletContext]="{$implicit: col}"></ng-template>
<span <span
*ngIf="hoveredHeaderColumnIndex === columnIndex && col.draggable && !isResizing" *ngIf="col.draggable"
class="adf-datatable-cell-header-drag-icon-placeholder" cdkDragHandle
[attr.data-automation-id]="'adf-datatable-cell-header-drag-icon-placeholder-'+col.key" [ngClass]="{ 'adf-datatable-cell-header-drag-icon': !isResizing }"
></span> >
<adf-icon
*ngIf="hoveredHeaderColumnIndex === columnIndex && !isResizing"
value="adf:drag_indicator"
[attr.data-automation-id]="'adf-datatable-cell-header-drag-icon-'+col.key">
</adf-icon>
</span>
</div> </div>
<div <div
*ngIf="isResizingEnabled && col.resizable" *ngIf="isResizingEnabled && col.resizable && !lastColumn"
[ngClass]="hoveredHeaderColumnIndex === columnIndex && !isResizing || resizingColumnIndex === columnIndex ? 'adf-datatable__resize-handle-visible' : 'adf-datatable__resize-handle-hidden'" [ngClass]="hoveredHeaderColumnIndex === columnIndex && !isResizing || resizingColumnIndex === columnIndex ? 'adf-datatable__resize-handle-visible' : 'adf-datatable__resize-handle-hidden'"
adf-resize-handle adf-resize-handle
(click)="$event.stopPropagation()" (click)="$event.stopPropagation()"
@@ -104,18 +111,6 @@
[resizableContainer]="resizableElement"> [resizableContainer]="resizableElement">
<div class="adf-datatable__resize-handle--divider"></div> <div class="adf-datatable__resize-handle--divider"></div>
</div> </div>
<div
*ngIf="col.draggable"
cdkDragHandle
[ngClass]="{ 'adf-datatable-cell-header-drag-icon': !isResizing }"
>
<adf-icon
*ngIf="hoveredHeaderColumnIndex === columnIndex && !isResizing"
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 class="adf-drop-header-cell-placeholder" *cdkDragPlaceholder></div>
</div> </div>
@@ -207,9 +202,11 @@
{{ 'ADF-DATATABLE.ACCESSIBILITY.SELECT_FILE' | translate }} {{ 'ADF-DATATABLE.ACCESSIBILITY.SELECT_FILE' | translate }}
</mat-checkbox> </mat-checkbox>
</label> </label>
<div *ngFor="let col of (data.getColumns() | filterOutEvery:'isHidden':true);" <div *ngFor="
let col of (data.getColumns() | filterOutEvery:'isHidden':true),
let lastColumn = last;"
role="gridcell" role="gridcell"
class="adf-datatable-cell adf-datatable-cell--{{col.type || 'text'}} {{col.cssClass}}" class="adf-datatable-cell adf-datatable-cell--{{col.type || 'text'}} {{col.cssClass}} adf-datatable-cell-data"
[attr.title]="col.title | translate" [attr.title]="col.title | translate"
[attr.data-automation-id]="getAutomationValue(row)" [attr.data-automation-id]="getAutomationValue(row)"
[attr.aria-selected]="row.isSelected" [attr.aria-selected]="row.isSelected"
@@ -219,7 +216,7 @@
[adf-context-menu]="getContextMenuActions(row, col)" [adf-context-menu]="getContextMenuActions(row, col)"
[adf-context-menu-enabled]="contextMenu" [adf-context-menu-enabled]="contextMenu"
adf-drop-zone dropTarget="cell" [dropColumn]="col" [dropRow]="row" adf-drop-zone dropTarget="cell" [dropColumn]="col" [dropRow]="row"
[ngStyle]="(col.width) && {'flex': getFlexValue(col)}"> [ngStyle]="(col.width) && !lastColumn && {'flex-basis': getFlexBasisValue(col)}">
<div *ngIf="!col.template" class="adf-datatable-cell-container"> <div *ngIf="!col.template" class="adf-datatable-cell-container">
<ng-container [ngSwitch]="data.getColumnType(row, col)"> <ng-container [ngSwitch]="data.getColumnType(row, col)">
<div *ngSwitchCase="'image'" class="adf-cell-value"> <div *ngSwitchCase="'image'" class="adf-cell-value">

View File

@@ -390,6 +390,17 @@ $data-table-cell-min-width-file-size: $data-table-cell-min-width-1 !default;
min-width: $data-table-cell-min-width-2; min-width: $data-table-cell-min-width-2;
} }
.adf-datatable-header, .adf-datatable-body {
.adf-datatable-cell-data {
flex-grow: 0;
flex-shrink: 1;
&:not(:has(~ .adf-datatable-cell-data)) {
flex-grow: 1;
}
}
}
/* stylelint-disable-next-line no-duplicate-selectors */ /* stylelint-disable-next-line no-duplicate-selectors */
.adf-datatable-cell, .adf-datatable-cell,
.adf-datatable-cell-header { .adf-datatable-cell-header {
@@ -404,11 +415,6 @@ $data-table-cell-min-width-file-size: $data-table-cell-min-width-1 !default;
box-sizing: content-box; box-sizing: content-box;
} }
&:last-child {
padding-right: 15px;
box-sizing: content-box;
}
.adf-datatable-cell-container { .adf-datatable-cell-container {
overflow: hidden; overflow: hidden;
min-height: inherit; min-height: inherit;
@@ -436,6 +442,7 @@ $data-table-cell-min-width-file-size: $data-table-cell-min-width-1 !default;
.adf-datatable-actions-menu { .adf-datatable-actions-menu {
margin-left: auto; margin-left: auto;
justify-content: end; justify-content: end;
padding-right: 15px;
} }
.adf-cell-value { .adf-cell-value {
@@ -626,7 +633,7 @@ $data-table-cell-min-width-file-size: $data-table-cell-min-width-1 !default;
.adf-datatable__header--sorted-asc, .adf-datatable__header--sorted-asc,
.adf-datatable__header--sorted-desc { .adf-datatable__header--sorted-desc {
color: var(--adf-theme-foreground-text-color); color: var(--adf-theme-foreground-text-color);
padding-right: 0.5rem; padding-right: 0.25rem;
&::after { &::after {
@include typo-icon; @include typo-icon;
@@ -661,10 +668,10 @@ $data-table-cell-min-width-file-size: $data-table-cell-min-width-1 !default;
align-items: center; align-items: center;
margin: 0 2px; margin: 0 2px;
padding: 0 8px; padding: 0 8px;
column-gap: 5px;
.adf-datatable-cell-header-drag-icon-placeholder { .adf-datatable-cell-header-drag-icon-placeholder {
min-width: 15px; padding: 0;
margin: 0;
} }
&--hovered { &--hovered {
@@ -674,19 +681,15 @@ $data-table-cell-min-width-file-size: $data-table-cell-min-width-1 !default;
} }
.adf-datatable-cell-header-drag-icon { .adf-datatable-cell-header-drag-icon {
position: absolute; margin-left: auto;
top: 0;
bottom: 0;
right: 10px;
margin: auto;
color: #ccc;
cursor: move; cursor: move;
width: 24px; margin-right: -0.5rem;
height: 24px; padding-left: -0.5rem;
} }
.adf-datatable-cell-value { .adf-datatable-cell-value {
padding: 10px 0 !important; padding-top: 10px;
padding-bottom: 10px;
line-height: 24px; line-height: 24px;
word-break: break-word; word-break: break-word;
} }

View File

@@ -1524,21 +1524,15 @@ describe('Drag&Drop column header', () => {
fixture.detectChanges(); fixture.detectChanges();
let dragIcon = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-datatable-cell-header-drag-icon-name"]'); let dragIcon = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-datatable-cell-header-drag-icon-name"]');
let dragIconPlaceholder = fixture.debugElement.nativeElement.querySelector(
'[data-automation-id="adf-datatable-cell-header-drag-icon-placeholder-name"]'
);
expect(dragIcon).toBeTruthy(); expect(dragIcon).toBeTruthy();
expect(dragIconPlaceholder).toBeTruthy();
headerColumn.dispatchEvent(new MouseEvent('mouseleave')); headerColumn.dispatchEvent(new MouseEvent('mouseleave'));
fixture.detectChanges(); fixture.detectChanges();
dragIcon = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-datatable-cell-header-drag-icon-name"]'); dragIcon = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-datatable-cell-header-drag-icon-name"]');
dragIconPlaceholder = fixture.debugElement.nativeElement.querySelector(
'[data-automation-id="adf-datatable-cell-header-drag-icon-placeholder-name"]'
);
expect(dragIcon).toBeFalsy(); expect(dragIcon).toBeFalsy();
expect(dragIconPlaceholder).toBeFalsy();
}); });
it('should not show drag indicator icon, when drag and drop is disabled', () => { it('should not show drag indicator icon, when drag and drop is disabled', () => {
@@ -1549,12 +1543,8 @@ describe('Drag&Drop column header', () => {
fixture.detectChanges(); fixture.detectChanges();
const dragIcon = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-datatable-cell-header-drag-icon-id"]'); const dragIcon = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-datatable-cell-header-drag-icon-id"]');
const dragIconPlaceholder = fixture.debugElement.nativeElement.querySelector(
'[data-automation-id="adf-datatable-cell-header-drag-icon-placeholder-id"]'
);
expect(dragIcon).toBeFalsy(); expect(dragIcon).toBeFalsy();
expect(dragIconPlaceholder).toBeFalsy();
}); });
it('should emit on change column order', () => { it('should emit on change column order', () => {
@@ -1748,20 +1738,20 @@ describe('Column Resizing', () => {
}); });
}); });
it('should display resize handle for each column by default', () => { it('should display resize handle for each column, but not for the last one, by default', () => {
dataTable.isResizingEnabled = true; dataTable.isResizingEnabled = true;
fixture.detectChanges(); fixture.detectChanges();
expect(getResizeHandlersCount()).toBe(2); expect(getResizeHandlersCount()).toBe(1);
}); });
it('should NOT display resize handle for the column when the column has resizable param set to false', () => { it('should NOT display resize handle for the column when the column has resizable param set to false and column is not the last one', () => {
dataTable.isResizingEnabled = true; dataTable.isResizingEnabled = true;
dataTableSchema[0].resizable = false; dataTableSchema[0].resizable = false;
dataTable.data = new ObjectDataTableAdapter([...data], [...dataTableSchema]); dataTable.data = new ObjectDataTableAdapter([...data], [...dataTableSchema]);
fixture.detectChanges(); fixture.detectChanges();
expect(getResizeHandlersCount()).toBe(1); expect(getResizeHandlersCount()).toBe(0);
}); });
it('should display resize handle when the feature is Enabled [isResizingEnabled=true]', () => { it('should display resize handle when the feature is Enabled [isResizingEnabled=true]', () => {
@@ -1895,7 +1885,7 @@ describe('Column Resizing', () => {
fixture.detectChanges(); fixture.detectChanges();
const headerColumns: HTMLElement[] = fixture.debugElement.nativeElement.querySelectorAll('.adf-datatable-cell-header'); const headerColumns: HTMLElement[] = fixture.debugElement.nativeElement.querySelectorAll('.adf-datatable-cell-header');
expect(headerColumns[0].style.flex).toBe('0 1 125px'); expect(headerColumns[0].style.flexBasis).toBe('125px');
})); }));
it('should set the column header to 100px on resizing when its width goes below 100', fakeAsync(() => { it('should set the column header to 100px on resizing when its width goes below 100', fakeAsync(() => {
@@ -1904,7 +1894,7 @@ describe('Column Resizing', () => {
fixture.detectChanges(); fixture.detectChanges();
const headerColumns: HTMLElement[] = fixture.debugElement.nativeElement.querySelectorAll('.adf-datatable-cell-header'); const headerColumns: HTMLElement[] = fixture.debugElement.nativeElement.querySelectorAll('.adf-datatable-cell-header');
expect(headerColumns[0].style.flex).toBe('0 1 100px'); expect(headerColumns[0].style.flexBasis).toBe('100px');
})); }));
it('should set the style of all the table cells under the resizing header on resizing', fakeAsync(() => { it('should set the style of all the table cells under the resizing header on resizing', fakeAsync(() => {
@@ -1916,8 +1906,8 @@ describe('Column Resizing', () => {
const firstCell: HTMLElement = tableBody.querySelector('[data-automation-id="name1"]'); const firstCell: HTMLElement = tableBody.querySelector('[data-automation-id="name1"]');
const secondCell: HTMLElement = tableBody.querySelector('[data-automation-id="name2"]'); const secondCell: HTMLElement = tableBody.querySelector('[data-automation-id="name2"]');
expect(firstCell.style.flex).toBe('0 1 130px'); expect(firstCell.style.flexBasis).toBe('130px');
expect(secondCell.style.flex).toBe('0 1 130px'); expect(secondCell.style.flexBasis).toBe('130px');
})); }));
it('should set the style of all the table cells under the resizing header to 100px on resizing when its width goes below 100', fakeAsync(() => { it('should set the style of all the table cells under the resizing header to 100px on resizing when its width goes below 100', fakeAsync(() => {
@@ -1929,8 +1919,8 @@ describe('Column Resizing', () => {
const firstCell: HTMLElement = tableBody.querySelector('[data-automation-id="name1"]'); const firstCell: HTMLElement = tableBody.querySelector('[data-automation-id="name1"]');
const secondCell: HTMLElement = tableBody.querySelector('[data-automation-id="name2"]'); const secondCell: HTMLElement = tableBody.querySelector('[data-automation-id="name2"]');
expect(firstCell.style.flex).toBe('0 1 100px'); expect(firstCell.style.flexBasis).toBe('100px');
expect(secondCell.style.flex).toBe('0 1 100px'); expect(secondCell.style.flexBasis).toBe('100px');
})); }));
it('should unblur the body and set the resizing to false upon resizing ends', () => { it('should unblur the body and set the resizing to false upon resizing ends', () => {

View File

@@ -971,8 +971,8 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
this.updateColumnsWidths(); this.updateColumnsWidths();
} }
getFlexValue({ width = 0 }: DataColumn): string { getFlexBasisValue({ width = 0 }: DataColumn): string {
return `0 1 ${width < DataTableComponent.MINIMUM_COLUMN_SIZE ? DataTableComponent.MINIMUM_COLUMN_SIZE : width}px`; return `${width < DataTableComponent.MINIMUM_COLUMN_SIZE ? DataTableComponent.MINIMUM_COLUMN_SIZE : width}px`;
} }
filterDisabledColumns(index: number, _drag: CdkDrag, drop: CdkDropList): boolean { filterDisabledColumns(index: number, _drag: CdkDrag, drop: CdkDropList): boolean {