diff --git a/src/sql/base/browser/ui/table/media/table.css b/src/sql/base/browser/ui/table/media/table.css index 71155a146d..e1a3c7ed72 100644 --- a/src/sql/base/browser/ui/table/media/table.css +++ b/src/sql/base/browser/ui/table/media/table.css @@ -99,6 +99,22 @@ white-space: nowrap; width: 200px; display: grid; + align-content: flex-start; +} + +.slick-header-menu .filter .filter-option { + display: flex; + align-items: center; +} + +.slick-header-menu .filter-menu-button-container { + display: flex; + flex-direction: row; + width: 100%; +} + +.slick-header-menu .filter-menu-button { + flex: 0 0 auto; } .monaco-table label { 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 3c2e2a9cf0..8565579821 100644 --- a/src/sql/base/browser/ui/table/plugins/headerFilter.plugin.ts +++ b/src/sql/base/browser/ui/table/plugins/headerFilter.plugin.ts @@ -21,6 +21,12 @@ export interface CommandEventArgs { command: string } +export type CellValueGetter = (data: any) => string; + +function GetCellValue(data: any): string { + return data?.toString(); +} + const ShowFilterText: string = localize('headerFilter.showFilter', "Show Filter"); export class HeaderFilter { @@ -41,6 +47,9 @@ export class HeaderFilter { private disposableStore = new DisposableStore(); + constructor(private cellValueExtrator: CellValueGetter = GetCellValue) { + } + public init(grid: Slick.Grid): void { this.grid = grid; this.handler.subscribe(this.grid.onHeaderCellRendered, (e: Event, args: Slick.OnHeaderCellRenderedEventArgs) => this.handleHeaderCellRendered(e, args)) @@ -95,7 +104,9 @@ export class HeaderFilter { .addClass('slick-header-menubutton') .data('column', column); - $el.click(() => { + $el.click((e: JQuery.Event) => { + e.stopPropagation(); + e.preventDefault(); this.showFilter($el[0]); }); $el.appendTo(args.node); @@ -197,7 +208,7 @@ export class HeaderFilter { for (let i = 0; i < filterItems.length; i++) { const filtered = this.workingFilters.some(x => x === filterItems[i]); if (filterItems[i] && filterItems[i].indexOf('Error:') < 0) { - filterOptions += ''; } @@ -206,7 +217,11 @@ export class HeaderFilter { .append(jQuery(filterOptions)) .appendTo(this.$menu); - this.okButton = new Button(this.$menu.get(0)); + const $buttonContainer = jQuery('
').appendTo(this.$menu); + const $okButtonDiv = jQuery('
').appendTo($buttonContainer); + const $clearButtonDiv = jQuery('
').appendTo($buttonContainer); + const $cancelButtonDiv = jQuery('
').appendTo($buttonContainer); + this.okButton = new Button($okButtonDiv.get(0)); this.okButton.label = localize('headerFilter.ok', "OK"); this.okButton.title = localize('headerFilter.ok', "OK"); this.okButton.element.id = 'filter-ok-button'; @@ -217,7 +232,7 @@ export class HeaderFilter { this.handleApply(ev, this.columnDef); }); - this.clearButton = new Button(this.$menu.get(0), { secondary: true }); + this.clearButton = new Button($clearButtonDiv.get(0), { secondary: true }); this.clearButton.label = localize('headerFilter.clear', "Clear"); this.clearButton.title = localize('headerFilter.clear', "Clear"); this.clearButton.element.id = 'filter-clear-button'; @@ -228,7 +243,7 @@ export class HeaderFilter { this.handleApply(ev, this.columnDef); }); - this.cancelButton = new Button(this.$menu.get(0), { secondary: true }); + this.cancelButton = new Button($cancelButtonDiv.get(0), { secondary: true }); this.cancelButton.label = localize('headerFilter.cancel', "Cancel"); this.cancelButton.title = localize('headerFilter.cancel', "Cancel"); this.cancelButton.element.id = 'filter-cancel-button'; @@ -249,8 +264,8 @@ export class HeaderFilter { if (menutop + offset.top > jQuery(window).height()) { menutop -= (this.$menu.height() + jQuery(target).height() + 8); } - this.$menu.css('top', menutop) - .css('left', (left > 0 ? left : 0)); + this.$menu.css('top', menutop).css('left', (left > 0 ? left : 0)); + this.okButton.focus(); } public style(styles: IButtonStyles): void { @@ -337,7 +352,7 @@ export class HeaderFilter { dataView.getItems().forEach(items => { const value = items[column.field!]; const valueArr = value instanceof Array ? value : [value]; - valueArr.forEach(v => seen.add(v)); + valueArr.forEach(v => seen.add(this.cellValueExtrator(v))); }); return Array.from(seen);