AAE-28910 Add subtitle for columns (#10479)

* AAE-28910 Add subtitle for column and column selector

* Add test

* Change subTitle name

* fix units

* fix units
This commit is contained in:
Bartosz Sekula 2024-12-09 11:29:58 -05:00 committed by GitHub
parent ce5cdb40a8
commit d1d72cb575
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 145 additions and 52 deletions

View File

@ -45,7 +45,23 @@
[checked]="!column.isHidden" [checked]="!column.isHidden"
[disabled]="isCheckboxDisabled(column)" [disabled]="isCheckboxDisabled(column)"
(change)="changeColumnVisibility(column)"> (change)="changeColumnVisibility(column)">
<div class="adf-columns-selector-list-content">{{column.title | translate}}</div> <div class="adf-columns-selector-list-content">
{{column.title | translate}}
</div>
<div
*ngIf="column.subtitle"
class="
adf-columns-selector-list-content
adf-columns-selector-subtitle
"
>
<mat-icon class="adf-columns-selector-subtitle-icon">
device_hub
</mat-icon>
<span>
{{column.subtitle | translate}}
</span>
</div>
</mat-checkbox> </mat-checkbox>
</div> </div>
</div> </div>

View File

@ -27,8 +27,7 @@ $adf-columns-selector-space: 12px;
&-list-container { &-list-container {
max-height: 350px; max-height: 350px;
overflow-x: hidden; overflow: hidden auto;
overflow-y: auto;
} }
&-list-item { &-list-item {
@ -47,6 +46,22 @@ $adf-columns-selector-space: 12px;
width: 210px; width: 210px;
} }
&-subtitle {
color: var(--adf-theme-foreground-text-color);
font-size: var(--theme-caption-font-size);
opacity: 0.6;
display: flex;
column-gap: 3px;
align-items: center;
}
&-subtitle-icon {
margin-top: 3px;
height: var(--theme-caption-font-size);
width: var(--theme-caption-font-size);
font-size: var(--theme-caption-font-size);
}
&-column-checkbox { &-column-checkbox {
padding: 0 20px; padding: 0 20px;
} }

View File

@ -153,10 +153,10 @@ describe('ColumnsSelectorComponent', () => {
const checkBoxName = await firstColumnCheckbox.getLabelText(); const checkBoxName = await firstColumnCheckbox.getLabelText();
const toggledColumnItem = component.columnItems.find((item) => item.title === checkBoxName); const toggledColumnItem = component.columnItems.find((item) => item.title === checkBoxName);
expect(toggledColumnItem.isHidden).toBeFalsy(); expect(toggledColumnItem?.isHidden).toBe(undefined);
await firstColumnCheckbox.toggle(); await firstColumnCheckbox.toggle();
expect(toggledColumnItem.isHidden).toBe(true); expect(toggledColumnItem?.isHidden).toBeTrue();
}); });
describe('checkboxes', () => { describe('checkboxes', () => {
@ -207,9 +207,11 @@ describe('ColumnsSelectorComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
const checkboxes = await loader.getAllHarnesses(MatCheckboxHarness); const checkboxes = await loader.getAllHarnesses(MatCheckboxHarness);
const labeTextOne = await checkboxes[0].getLabelText();
const labeTextTwo = await checkboxes[1].getLabelText();
expect(await checkboxes[0].getLabelText()).toBe(shownDataColumn.title); expect(labeTextOne).toBe(shownDataColumn.title!);
expect(await checkboxes[1].getLabelText()).toBe(hiddenDataColumn.title); expect(labeTextTwo).toBe(hiddenDataColumn.title!);
}); });
it('should NOT show hidden columns at the end of the list if sorting is disabled', async () => { it('should NOT show hidden columns at the end of the list if sorting is disabled', async () => {
@ -219,9 +221,31 @@ describe('ColumnsSelectorComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
const checkboxes = await loader.getAllHarnesses(MatCheckboxHarness); const checkboxes = await loader.getAllHarnesses(MatCheckboxHarness);
const labeTextOne = await checkboxes[0].getLabelText();
const labeTextTwo = await checkboxes[1].getLabelText();
expect(await checkboxes[0].getLabelText()).toBe(hiddenDataColumn.title); expect(labeTextOne).toBe(hiddenDataColumn.title!);
expect(await checkboxes[1].getLabelText()).toBe(shownDataColumn.title); expect(labeTextTwo).toBe(shownDataColumn.title!);
});
it('should show subtitle', async () => {
const column: DataColumn = {
id: 'shownDataColumn',
title: 'title',
subtitle: 'subtitle',
key: 'shownDataColumn',
type: 'text'
};
component.columns = [column];
component.columnsSorting = false;
menuOpenedTrigger.next();
fixture.detectChanges();
const checkboxes = await loader.getAllHarnesses(MatCheckboxHarness);
const labeTextOne = await checkboxes[0].getLabelText();
expect(labeTextOne).toBe(`${column.title} device_hub ${column.subtitle}`);
}); });
}); });
}); });

View File

@ -4,7 +4,8 @@
class="adf-full-width adf-datatable-list" class="adf-full-width adf-datatable-list"
[class.adf-sticky-header]="isStickyHeaderEnabled()" [class.adf-sticky-header]="isStickyHeaderEnabled()"
[class.adf-datatable--empty]="(isEmpty() && !isHeaderVisible()) || loading" [class.adf-datatable--empty]="(isEmpty() && !isHeaderVisible()) || loading"
[class.adf-datatable--empty--header-visible]="isEmpty() && isHeaderVisible()"> [class.adf-datatable--empty--header-visible]="isEmpty() && isHeaderVisible()"
>
<div *ngIf="isHeaderVisible()" class="adf-datatable-header" role="rowgroup" [ngClass]="{ 'adf-sr-only': !isHeaderVisible() }"> <div *ngIf="isHeaderVisible()" class="adf-datatable-header" role="rowgroup" [ngClass]="{ 'adf-sr-only': !isHeaderVisible() }">
<adf-datatable-row <adf-datatable-row
cdkDropList cdkDropList
@ -60,7 +61,9 @@
[cdkDragDisabled]="!col.draggable" [cdkDragDisabled]="!col.draggable"
(mouseenter)="hoveredHeaderColumnIndex = columnIndex" (mouseenter)="hoveredHeaderColumnIndex = columnIndex"
(mouseleave)="hoveredHeaderColumnIndex = -1" (mouseleave)="hoveredHeaderColumnIndex = -1"
adf-drop-zone dropTarget="header" [dropColumn]="col"> adf-drop-zone dropTarget="header"
[dropColumn]="col"
>
<div <div
adf-resizable adf-resizable
@ -77,7 +80,21 @@
!isResizing && col.sortable}" !isResizing && col.sortable}"
> >
<ng-container *ngIf="!col.header"> <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"
title="{{col.title | translate}}"
class="adf-datatable-cell-value"
>
{{col.title | translate}}
</span>
<span
*ngIf="col.subtitle"
title="{{col.subtitle | translate}}"
class="adf-datatable-cell-value adf-datatable-cell-header_subtitle"
>
({{col.subtitle | translate}})
</span>
<span *ngIf="col.title && col.sortable && isDraggingHeaderColumn" class="adf-sr-only" aria-live="polite"> <span *ngIf="col.title && col.sortable && isDraggingHeaderColumn" class="adf-sr-only" aria-live="polite">
{{ getSortLiveAnnouncement(col) | translate: { string: col.title | translate } }} {{ getSortLiveAnnouncement(col) | translate: { string: col.title | translate } }}
@ -232,7 +249,9 @@
{{ 'ADF-DATATABLE.ACCESSIBILITY.SELECT_FILE' | translate }} {{ 'ADF-DATATABLE.ACCESSIBILITY.SELECT_FILE' | translate }}
</mat-checkbox> </mat-checkbox>
</label> </label>
<div *ngFor="let col of getVisibleColumns(); let lastColumn = last;"
<div
*ngFor="let col of getVisibleColumns(); let lastColumn = last;"
role="gridcell" role="gridcell"
class="adf-datatable-cell adf-datatable-cell--{{col.type || 'text'}} {{col.cssClass}} adf-datatable-cell-data" 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"
@ -245,7 +264,8 @@
[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) && !lastColumn && {'flex': getFlexValue(col)}"> [ngStyle]="(col.width) && !lastColumn && {'flex': getFlexValue(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">
@ -271,16 +291,22 @@
</ng-template> </ng-template>
</ng-template> </ng-template>
</div> </div>
<div *ngSwitchCase="'icon'" class="adf-cell-value"> <div *ngSwitchCase="'icon'" class="adf-cell-value">
<adf-icon-cell <adf-icon-cell
[data]="data" [data]="data"
[column]="col" [column]="col"
[row]="row" [row]="row"
[resolverFn]="resolverFn" [resolverFn]="resolverFn"
[tooltip]="getCellTooltip(row, col)" /> [tooltip]="getCellTooltip(row, col)"
/>
</div> </div>
<div *ngSwitchCase="'date'" class="adf-cell-value adf-cell-date" [attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1" <div
[attr.data-automation-id]="'date_' + (data.getValue(row, col, resolverFn) | adfLocalizedDate: 'medium') "> *ngSwitchCase="'date'"
class="adf-cell-value adf-cell-date"
[attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1"
[attr.data-automation-id]="'date_' + (data.getValue(row, col, resolverFn) | adfLocalizedDate: 'medium') "
>
<adf-date-cell class="adf-datatable-center-date-column-ie" <adf-date-cell class="adf-datatable-center-date-column-ie"
[data]="data" [data]="data"
[column]="col" [column]="col"
@ -289,6 +315,7 @@
[tooltip]="getCellTooltip(row, col)" [tooltip]="getCellTooltip(row, col)"
[dateConfig]="col.dateConfig" /> [dateConfig]="col.dateConfig" />
</div> </div>
<div *ngSwitchCase="'location'" [attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1" class="adf-cell-value" <div *ngSwitchCase="'location'" [attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1" class="adf-cell-value"
[attr.data-automation-id]="'location' + data.getValue(row, col, resolverFn)"> [attr.data-automation-id]="'location' + data.getValue(row, col, resolverFn)">
<adf-location-cell <adf-location-cell

View File

@ -524,6 +524,11 @@ $data-table-cell-min-width-file-size: $data-table-cell-min-width-1 !default;
color: var(--adf-theme-foreground-text-color); color: var(--adf-theme-foreground-text-color);
box-sizing: border-box; box-sizing: border-box;
&_subtitle {
margin-left: 3px;
opacity: 0.6;
}
&.adf-sortable { &.adf-sortable {
@include adf-no-select; @include adf-no-select;

View File

@ -76,6 +76,9 @@ export class DataColumnComponent implements OnInit {
@Input() @Input()
title: string = ''; title: string = '';
@Input()
subtitle: string = '';
@ContentChild(TemplateRef) @ContentChild(TemplateRef)
template: any; template: any;

View File

@ -27,6 +27,7 @@ export interface DataColumn<T = unknown> {
format?: string; format?: string;
sortable?: boolean; sortable?: boolean;
title?: string; title?: string;
subtitle?: string;
srTitle?: string; srTitle?: string;
cssClass?: string; cssClass?: string;
template?: TemplateRef<any>; template?: TemplateRef<any>;

View File

@ -27,6 +27,7 @@ export class ObjectDataColumn<T = unknown> implements DataColumn<T> {
format: string; format: string;
sortable: boolean; sortable: boolean;
title: string; title: string;
subtitle?: string;
srTitle: string; srTitle: string;
cssClass: string; cssClass: string;
template?: TemplateRef<any>; template?: TemplateRef<any>;
@ -52,6 +53,7 @@ export class ObjectDataColumn<T = unknown> implements DataColumn<T> {
this.format = input.format; this.format = input.format;
this.sortable = input.sortable; this.sortable = input.sortable;
this.title = input.title; this.title = input.title;
this.subtitle = input.subtitle;
this.srTitle = input.srTitle; this.srTitle = input.srTitle;
this.cssClass = input.cssClass; this.cssClass = input.cssClass;
this.template = input.template; this.template = input.template;