From 86a5cb27b77d370540a31f54d4f02def254d77d5 Mon Sep 17 00:00:00 2001 From: Charles Gagnon Date: Tue, 2 Feb 2021 16:15:31 -0800 Subject: [PATCH] Add debounce to pg parameters search filter (#14140) * Add debounce to pg parameters search filter * Update tsconfig --- extensions/arc/src/common/utils.ts | 32 +++++++++++++++++++ .../postgres/postgresParametersPage.ts | 18 +++++++---- extensions/arc/tsconfig.json | 1 + 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/extensions/arc/src/common/utils.ts b/extensions/arc/src/common/utils.ts index 95644b940e..43f97f903d 100644 --- a/extensions/arc/src/common/utils.ts +++ b/extensions/arc/src/common/utils.ts @@ -295,3 +295,35 @@ export async function tryExecuteAction(action: () => T | PromiseLike): Pro } return { result, error }; } + +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); + }; +} + +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); + }; + }); +} diff --git a/extensions/arc/src/ui/dashboards/postgres/postgresParametersPage.ts b/extensions/arc/src/ui/dashboards/postgres/postgresParametersPage.ts index 7c9c227ea5..1ed853dab9 100644 --- a/extensions/arc/src/ui/dashboards/postgres/postgresParametersPage.ts +++ b/extensions/arc/src/ui/dashboards/postgres/postgresParametersPage.ts @@ -11,6 +11,7 @@ import { UserCancelledError } from '../../../common/api'; import { IconPathHelper, cssStyles } from '../../../constants'; import { DashboardPage } from '../../components/dashboardPage'; import { EngineSettingsModel, PostgresModel } from '../../../models/postgresModel'; +import { debounce } from '../../../common/utils'; export type ParametersModel = { parameterName: string, @@ -358,15 +359,20 @@ export class PostgresParametersPage extends DashboardPage { this.disposables.push( this.searchBox.onTextChanged(() => { - if (!this.searchBox!.value) { - this.parametersTable.data = this._parameters.map(p => [p.parameterName, p.valueContainer, p.description, p.resetButton]); - } else { - this.filterParameters(this.searchBox!.value); - } + this.onSearchFilter(); }) ); } + @debounce(500) + private onSearchFilter(): void { + if (!this.searchBox!.value) { + this.parametersTable.data = this._parameters.map(p => [p.parameterName, p.valueContainer, p.description, p.resetButton]); + } else { + this.filterParameters(this.searchBox!.value); + } + } + private filterParameters(search: string): void { this.parametersTable.data = this._parameters .filter(p => p.parameterName?.search(search) !== -1 || p.description?.search(search) !== -1) @@ -375,7 +381,7 @@ export class PostgresParametersPage extends DashboardPage { private handleOnTextChanged(component: azdata.InputBoxComponent, currentValue: string | undefined): boolean { if (!component.valid) { - // If invalid value retun false and enable discard button + // If invalid value return false and enable discard button this.discardButton!.enabled = true; return false; } else if (component.value === currentValue) { diff --git a/extensions/arc/tsconfig.json b/extensions/arc/tsconfig.json index 2c6d7abf5b..bd69e58723 100644 --- a/extensions/arc/tsconfig.json +++ b/extensions/arc/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../shared.tsconfig.json", "compileOnSave": true, "compilerOptions": { + "experimentalDecorators": true, "outDir": "./out", "lib": [ "es6",