SQL Migration extension - accessibility bug - fixes filter enter and focus (#15953)

* fix filter enter and focus

* debounce and fix search

* refactor null check and undo change/remove await

* using control types to improve and remove 'any'
This commit is contained in:
brian-harris
2021-07-02 19:11:50 -07:00
committed by GitHub
parent 9f77c74b9f
commit 19e25f04b1
4 changed files with 59 additions and 2 deletions

View File

@@ -156,3 +156,35 @@ export function findDropDownItemIndex(dropDown: DropDownComponent, value: string
return -1;
}
export function debounce(delay: number): Function {
return decorate((fn, key) => {
const timerKey = `$debounce$${key}`;
return function (this: any, ...args: any[]) {
clearTimeout(this[timerKey]);
this[timerKey] = setTimeout(() => fn.apply(this, args), delay);
};
});
}
export function decorate(decorator: (fn: Function, key: string) => Function): Function {
return (_target: any, key: string, descriptor: any) => {
let fnKey: string | null = null;
let fn: Function | null = null;
if (typeof descriptor.value === 'function') {
fnKey = 'value';
fn = descriptor.value;
} else if (typeof descriptor.get === 'function') {
fnKey = 'get';
fn = descriptor.get;
}
if (!fn || !fnKey) {
throw new Error('not supported');
}
descriptor[fnKey] = decorator(fn, key);
};
}

View File

@@ -46,7 +46,7 @@ export class AssessmentResultsDialog {
}).component();
flex.addItem(await this._tree.createRootContainer(view), { flex: '1 1 auto' });
view.initializeModel(flex);
await view.initializeModel(flex);
resolve();
} catch (ex) {
reject(ex);

View File

@@ -7,6 +7,7 @@ import { SqlMigrationAssessmentResultItem, SqlMigrationImpactedObjectInfo } from
import { IconPath, IconPathHelper } from '../../constants/iconPathHelper';
import { MigrationStateModel, MigrationTargetType } from '../../models/stateMachine';
import * as constants from '../../constants/strings';
import { debounce } from '../../api/utils';
const styleLeft: azdata.CssStyles = {
'border': 'none',
@@ -201,10 +202,13 @@ export class SqlDatabaseTree {
private createSearchComponent(): azdata.DivContainer {
let resourceSearchBox = this._view.modelBuilder.inputBox().withProps({
stopEnterPropagation: true,
placeHolder: constants.SEARCH,
width: 200
}).component();
resourceSearchBox.onTextChanged(value => this._filterTableList(value));
const searchContainer = this._view.modelBuilder.divContainer().withItems([resourceSearchBox]).withProps({
CSSStyles: {
'width': '200px',
@@ -215,6 +219,26 @@ export class SqlDatabaseTree {
return searchContainer;
}
@debounce(500)
private _filterTableList(value: string): void {
if (this._databaseTableValues && value?.length > 0) {
const filter: number[] = [];
this._databaseTableValues.forEach((row, index) => {
const flexContainer: azdata.FlexContainer = row[1]?.value as azdata.FlexContainer;
const textComponent: azdata.TextComponent = flexContainer.items[1] as azdata.TextComponent;
const cellText = textComponent.value?.toLowerCase();
const searchText: string = value.toLowerCase();
if (cellText?.includes(searchText)) {
filter.push(index);
}
});
this._databaseTable.setFilter(filter);
} else {
this._databaseTable.setFilter(undefined);
}
}
private createInstanceComponent(): azdata.DivContainer {
this._instanceTable = this._view.modelBuilder.declarativeTable().withProps(
{

View File

@@ -33,7 +33,7 @@ export class MigrationStatusDialog {
initialize() {
let tab = azdata.window.createTab('');
tab.registerContent((view: azdata.ModelView) => {
tab.registerContent(async (view: azdata.ModelView) => {
this._view = view;
this._statusDropdown = this._view.modelBuilder.dropDown().withProps({
@@ -85,6 +85,7 @@ export class MigrationStatusDialog {
private createSearchAndRefreshContainer(): azdata.FlexContainer {
this._searchBox = this._view.modelBuilder.inputBox().withProps({
stopEnterPropagation: true,
placeHolder: loc.SEARCH_FOR_MIGRATIONS,
width: '360px'
}).component();