Adding aria-labels to checkbox cells in declarative table (#23204)

This commit is contained in:
Aasim Khan
2023-06-09 15:28:53 -07:00
committed by GitHub
parent 58082402aa
commit 604c1e7861
3 changed files with 100 additions and 51 deletions

View File

@@ -56,9 +56,7 @@ describe('import extension modify Column Page', function () {
should.notEqual(modifyColumnsPage.form, undefined, 'form should not be undefined'); should.notEqual(modifyColumnsPage.form, undefined, 'form should not be undefined');
}); });
it('handleImport updates table value correctly when import is successful', async function() { it('handleImport updates table value correctly when import is successful', async function () {
let testProseColumns = [ let testProseColumns = [
{ {
columnName: 'column1', columnName: 'column1',
@@ -75,8 +73,35 @@ describe('import extension modify Column Page', function () {
]; ];
let testTableData = [ let testTableData = [
[ 'column1', 'nvarchar(50)', false, false], [
[ 'column2', 'nvarchar(50)', false, false] {
value: 'column1'
}, {
value: 'nvarchar(50)'
}, {
value: false,
ariaLabel: constants.primaryKeyText,
enabled: true
}, {
value: false,
ariaLabel: constants.allowNullsText,
enabled: true
}
], [
{
value: 'column2'
}, {
value: 'nvarchar(50)'
}, {
value: false,
ariaLabel: constants.primaryKeyText,
enabled: true
}, {
value: false,
ariaLabel: constants.allowNullsText,
enabled: true
}
]
]; ];
mockImportModel.object.proseColumns = testProseColumns; mockImportModel.object.proseColumns = testProseColumns;
@@ -98,7 +123,7 @@ describe('import extension modify Column Page', function () {
await modifyColumnsPage.onPageEnter(); await modifyColumnsPage.onPageEnter();
// checking if all the required components are correctly initialized // checking if all the required components are correctly initialized
should.deepEqual(modifyColumnsPage.table.data, testTableData); should.deepEqual(modifyColumnsPage.table.dataValues, testTableData);
}); });
}); });

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata'; import * as azdata from 'azdata';
import { ColumnMetadata, ColumnMetadataArray } from '../api/models'; import { ColumnMetadata } from '../api/models';
import { ImportPage } from '../api/importPage'; import { ImportPage } from '../api/importPage';
import * as constants from '../../common/constants'; import * as constants from '../../common/constants';
@@ -83,8 +83,25 @@ export class ModifyColumnsPage extends ImportPage {
this._form = form; this._form = form;
} }
private static convertMetadata(column: ColumnMetadata): any[] { private static convertMetadata(column: ColumnMetadata): azdata.DeclarativeTableCellValue[] {
return [column.columnName, column.dataType, false, column.nullable]; return [
{
value: column.columnName,
},
{
value: column.dataType,
},
{
value: false,
ariaLabel: constants.primaryKeyText,
enabled: true
},
{
value: column.nullable,
ariaLabel: constants.allowNullsText,
enabled: true
}
];
} }
async start(): Promise<boolean> { async start(): Promise<boolean> {
@@ -94,12 +111,12 @@ export class ModifyColumnsPage extends ImportPage {
this.table.onDataChanged((e) => { this.table.onDataChanged((e) => {
this.model.proseColumns = []; this.model.proseColumns = [];
this.table.data.forEach((row) => { this.table.dataValues.forEach((row) => {
this.model.proseColumns.push({ this.model.proseColumns.push({
columnName: row[0].value, columnName: <string>row[0].value,
dataType: row[1].value, dataType: <string>row[1].value,
primaryKey: row[2].value, primaryKey: <boolean>row[2].value,
nullable: row[3].value nullable: <boolean>row[3].value
}); });
}); });
}); });
@@ -131,7 +148,7 @@ export class ModifyColumnsPage extends ImportPage {
this.instance.changeNextButtonLabel(constants.importDataText); this.instance.changeNextButtonLabel(constants.importDataText);
this.loading.loading = false; this.loading.loading = false;
this.instance.registerNavigationValidator((info) => { this.instance.registerNavigationValidator((info) => {
return this.table.data && this.table.data.length > 0; return this.table.dataValues && this.table.dataValues.length > 0;
}); });
return true; return true;
} }
@@ -147,7 +164,7 @@ export class ModifyColumnsPage extends ImportPage {
private emptyTable() { private emptyTable() {
this.table.updateProperties({ this.table.updateProperties({
data: [], dataValues: [],
columns: [] columns: []
}); });
} }
@@ -160,13 +177,13 @@ export class ModifyColumnsPage extends ImportPage {
} }
private async populateTable() { private async populateTable() {
let data: ColumnMetadataArray[] = []; let data: azdata.DeclarativeTableCellValue[][] = [];
this.model.proseColumns.forEach((column) => { this.model.proseColumns.forEach((column) => {
data.push(ModifyColumnsPage.convertMetadata(column)); data.push(ModifyColumnsPage.convertMetadata(column));
}); });
this.table.updateProperties({ this.table.updateProperties(<azdata.DeclarativeTableProperties>{
columns: [{ columns: [{
displayName: constants.columnNameText, displayName: constants.columnNameText,
valueType: azdata.DeclarativeDataType.string, valueType: azdata.DeclarativeDataType.string,
@@ -191,7 +208,7 @@ export class ModifyColumnsPage extends ImportPage {
width: '100px', width: '100px',
showCheckAll: true showCheckAll: true
}], }],
data: data dataValues: data
}); });
} }
} }

View File

@@ -4,9 +4,8 @@
<tr role="row"> <tr role="row">
<ng-container *ngFor="let column of columns; let c = index;"> <ng-container *ngFor="let column of columns; let c = index;">
<th class="declarative-table-header" aria-sort="none" [style.width]="getColumnWidth(column)" <th class="declarative-table-header" aria-sort="none" [style.width]="getColumnWidth(column)"
[ngClass]="{'declarative-table-cell-checkbox' : isCheckBox(c)}" [ngClass]="{'declarative-table-cell-checkbox' : isCheckBox(c)}" [ngStyle]="column.headerCssStyles"
[ngStyle]="column.headerCssStyles" [attr.aria-label]="getHeaderAriaLabel(c)" [attr.aria-label]="getHeaderAriaLabel(c)" *ngIf="showColumn(column)">
*ngIf="showColumn(column)">
{{column.displayName}} {{column.displayName}}
<checkbox *ngIf="headerCheckboxVisible(c)" [checked]="isHeaderChecked(c)" <checkbox *ngIf="headerCheckboxVisible(c)" [checked]="isHeaderChecked(c)"
[aria-label]="getCheckAllColumnAriaLabel(c)" (onChange)="onHeaderCheckBoxChanged($event,c)" [aria-label]="getCheckAllColumnAriaLabel(c)" (onChange)="onHeaderCheckBoxChanged($event,c)"
@@ -18,36 +17,44 @@
<tbody role="rowgroup"> <tbody role="rowgroup">
<ng-container *ngIf="data.length > 0"> <ng-container *ngIf="data.length > 0">
<ng-container *ngFor="let row of data;let r = index;"> <ng-container *ngFor="let row of data;let r = index;">
<tr [style.display]="isFiltered(r) ? 'none' : ''" class="declarative-table-row" [ngStyle]="getRowStyle(r)" role="row" [attr.tabindex]="enableRowSelection ? 0 : null" (click)="onRowSelected(r)" (keydown)="onKey($event,r)"> <tr [style.display]="isFiltered(r) ? 'none' : ''" class="declarative-table-row"
[ngStyle]="getRowStyle(r)" role="row" [attr.tabindex]="enableRowSelection ? 0 : null"
(click)="onRowSelected(r)" (keydown)="onKey($event,r)">
<ng-container *ngFor="let cellData of row;let c = index;trackBy:trackByFnCols"> <ng-container *ngFor="let cellData of row;let c = index;trackBy:trackByFnCols">
<td class="declarative-table-cell" [style.width]="getColumnWidth(c)" <ng-container *ngIf="c<columns?.length">
[attr.aria-label]="getAriaLabel(r, c)" <td class="declarative-table-cell" [style.width]="getColumnWidth(c)"
[ngClass]="{'declarative-table-cell-checkbox' : isCheckBox(c)}" [attr.aria-label]="getAriaLabel(r, c)"
[ngStyle]="mergeCss(columns[c].rowCssStyles, cellData.style)" role="gridcell" [ngClass]="{'declarative-table-cell-checkbox' : isCheckBox(c)}"
*ngIf="showColumn(columns[c])"> [ngStyle]="mergeCss(columns[c].rowCssStyles, cellData.style)" role="gridcell"
<checkbox *ngIf="isCheckBox(c)" label="" (onChange)="onCheckBoxChanged($event,r,c)" *ngIf="showColumn(columns[c])">
[enabled]="isControlEnabled(r, c)" [checked]="isChecked(r,c)" <checkbox *ngIf="isCheckBox(c)" label="" [aria-label]="getAriaLabel(r,c)"
[ngStyle]="mergeCss(columns[c].rowCssStyles, cellData.style)"> (onChange)="onCheckBoxChanged($event,r,c)" [enabled]="isControlEnabled(r, c)"
</checkbox> [checked]="isChecked(r,c)"
<select-box *ngIf="isSelectBox(c)" [options]="getOptions(c)" [ngStyle]="mergeCss(columns[c].rowCssStyles, cellData.style)">
(onDidSelect)="onSelectBoxChanged($event,r,c)" </checkbox>
[selectedOption]="getSelectedOptionDisplayName(r,c)"> <select-box *ngIf="isSelectBox(c)" [options]="getOptions(c)"
</select-box> (onDidSelect)="onSelectBoxChanged($event,r,c)"
<editable-select-box *ngIf="isEditableSelectBox(c)" [options]="getOptions(c)" [selectedOption]="getSelectedOptionDisplayName(r,c)">
(onDidSelect)="onSelectBoxChanged($event,r,c)" </select-box>
[selectedOption]="getSelectedOptionDisplayName(r,c)"> <editable-select-box *ngIf="isEditableSelectBox(c)" [options]="getOptions(c)"
</editable-select-box> (onDidSelect)="onSelectBoxChanged($event,r,c)"
<input-box *ngIf="isInputBox(c)" [value]="cellData.value" [selectedOption]="getSelectedOptionDisplayName(r,c)">
(onDidChange)="onInputBoxChanged($event,r,c)"></input-box> </editable-select-box>
<span *ngIf="isLabel(c)"> <input-box *ngIf="isInputBox(c)" [value]="cellData.value"
{{cellData.value}} (onDidChange)="onInputBoxChanged($event,r,c)"></input-box>
</span> <span *ngIf="isLabel(c)">
<model-component-wrapper *ngIf="isComponent(c) && getItemDescriptor(cellData.value)" {{cellData.value}}
[descriptor]="getItemDescriptor(cellData.value)" [modelStore]="modelStore"> </span>
</model-component-wrapper> <model-component-wrapper *ngIf="isComponent(c) && getItemDescriptor(cellData.value)"
<button *ngIf="isContextMenuColumn(c)" [title]="contextMenuButtonTitle" [attr.aria-label]="contextMenuButtonTitle" class="codicon toggle-more" (click)="onContextMenuButtonClick($event,r,c)" (keydown)="onContextMenuButtonKeyDown($event,r,c)"> [descriptor]="getItemDescriptor(cellData.value)" [modelStore]="modelStore">
</button> </model-component-wrapper>
</td> <button *ngIf="isContextMenuColumn(c)" [title]="contextMenuButtonTitle"
[attr.aria-label]="contextMenuButtonTitle" class="codicon toggle-more"
(click)="onContextMenuButtonClick($event,r,c)"
(keydown)="onContextMenuButtonKeyDown($event,r,c)">
</button>
</td>
</ng-container>
</ng-container> </ng-container>
</tr> </tr>
</ng-container> </ng-container>