From b6083b6447a7acb089f8c14bcfa8908d0d2628f4 Mon Sep 17 00:00:00 2001 From: Alan Ren Date: Thu, 31 Mar 2022 11:17:55 -0700 Subject: [PATCH] handle special values in the table filter (#18872) * handle special values in the table filter * pr comments --- .../ui/table/plugins/headerFilter.plugin.ts | 33 ++++++++++++++++--- .../contrib/query/browser/gridPanel.ts | 9 ++++- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/sql/base/browser/ui/table/plugins/headerFilter.plugin.ts b/src/sql/base/browser/ui/table/plugins/headerFilter.plugin.ts index 0bd9854f01..d576c0379d 100644 --- a/src/sql/base/browser/ui/table/plugins/headerFilter.plugin.ts +++ b/src/sql/base/browser/ui/table/plugins/headerFilter.plugin.ts @@ -258,12 +258,23 @@ export class HeaderFilter { } } + // Sort the list to make it easier to find a string + filterItems.sort(); + + // Promote undefined (NULL) to be always at the top of the list + const nullValueIndex = filterItems.indexOf(undefined); + if (nullValueIndex !== -1) { + filterItems.splice(nullValueIndex, 1); + filterItems.unshift(undefined); + } + this.listData = []; for (let i = 0; i < filterItems.length; i++) { const filtered = workingFilters.some(x => x === filterItems[i]); // work item to remove the 'Error:' string check: https://github.com/microsoft/azuredatastudio/issues/15206 - if (filterItems[i] && filterItems[i].indexOf('Error:') < 0) { - this.listData.push(new TableFilterListElement(filterItems[i], filtered)); + const filterItem = filterItems[i]; + if (!filterItem || filterItem.indexOf('Error:') < 0) { + this.listData.push(new TableFilterListElement(filterItem, filtered)); } } @@ -543,8 +554,18 @@ class TableFilterListElement { constructor(val: string, checked: boolean) { this.value = val; this._checked = checked; + + // Handle the values that are visually hard to differentiate. + if (val === undefined) { + this.displayText = localize('tableFilter.nullDisplayText', "(NULL)"); + } else if (val === '') { + this.displayText = localize('tableFilter.blankStringDisplayText', "(Blanks)"); + } else { + this.displayText = val; + } } + public displayText: string; public value: string; public onCheckStateChanged = this._onCheckStateChanged.event; @@ -605,9 +626,11 @@ class TableFilterListRenderer implements IListRenderer extends Disposable implements IView { (offset, count) => { return this.loadData(offset, count); }, undefined, undefined, - (data: ICellValue) => { return data.isNull ? undefined : data?.displayValue; }, + (data: ICellValue) => { + if (!data || data.isNull) { + return undefined; + } + // If the string only contains whitespaces, it will be treated as empty string to make the filtering easier. + // Note: this is the display string and does not impact the export/copy features. + return data.displayValue.trim() === '' ? '' : data.displayValue; + }, { inMemoryDataProcessing: this.options.inMemoryDataProcessing, inMemoryDataCountThreshold: this.options.inMemoryDataCountThreshold