mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Inform the user about the config for filtering (#15510)
* Inform the user about the config for filtering * comments
This commit is contained in:
@@ -29,15 +29,27 @@ export interface CommandEventArgs<T extends Slick.SlickData> {
|
|||||||
command: HeaderFilterCommands
|
command: HeaderFilterCommands
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ITableFilterOptions {
|
||||||
|
/**
|
||||||
|
* The message to be displayed when the filter is disabled and the user tries to open the filter menu.
|
||||||
|
*/
|
||||||
|
disabledFilterMessage?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ITableFilterStyles extends IButtonStyles, IInputBoxStyles, IListStyles, ICountBadgetyles {
|
export interface ITableFilterStyles extends IButtonStyles, IInputBoxStyles, IListStyles, ICountBadgetyles {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface NotificationProvider {
|
||||||
|
info(message: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
const ShowFilterText: string = localize('headerFilter.showFilter', "Show Filter");
|
const ShowFilterText: string = localize('headerFilter.showFilter', "Show Filter");
|
||||||
|
|
||||||
export class HeaderFilter<T extends Slick.SlickData> {
|
export class HeaderFilter<T extends Slick.SlickData> {
|
||||||
|
|
||||||
public onFilterApplied = new Slick.Event<{ grid: Slick.Grid<T>, column: FilterableColumn<T> }>();
|
public onFilterApplied = new Slick.Event<{ grid: Slick.Grid<T>, column: FilterableColumn<T> }>();
|
||||||
public onCommand = new Slick.Event<CommandEventArgs<T>>();
|
public onCommand = new Slick.Event<CommandEventArgs<T>>();
|
||||||
|
public enabled: boolean = true;
|
||||||
|
|
||||||
private grid!: Slick.Grid<T>;
|
private grid!: Slick.Grid<T>;
|
||||||
private handler = new Slick.EventHandler();
|
private handler = new Slick.EventHandler();
|
||||||
@@ -59,11 +71,10 @@ export class HeaderFilter<T extends Slick.SlickData> {
|
|||||||
private columnDef!: FilterableColumn<T>;
|
private columnDef!: FilterableColumn<T>;
|
||||||
private filterStyles?: ITableFilterStyles;
|
private filterStyles?: ITableFilterStyles;
|
||||||
private disposableStore = new DisposableStore();
|
private disposableStore = new DisposableStore();
|
||||||
private _enabled: boolean = true;
|
|
||||||
private columnButtonMapping: Map<string, HTMLElement> = new Map<string, HTMLElement>();
|
private columnButtonMapping: Map<string, HTMLElement> = new Map<string, HTMLElement>();
|
||||||
private previouslyFocusedElement: HTMLElement;
|
private previouslyFocusedElement: HTMLElement;
|
||||||
|
|
||||||
constructor(private readonly contextViewProvider: IContextViewProvider) {
|
constructor(private readonly contextViewProvider: IContextViewProvider, private readonly notificationProvider?: NotificationProvider, private readonly options?: ITableFilterOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(grid: Slick.Grid<T>): void {
|
public init(grid: Slick.Grid<T>): void {
|
||||||
@@ -104,7 +115,7 @@ export class HeaderFilter<T extends Slick.SlickData> {
|
|||||||
const cell = this.grid.getActiveCell();
|
const cell = this.grid.getActiveCell();
|
||||||
if (cell) {
|
if (cell) {
|
||||||
const column = this.grid.getColumns()[cell.cell] as FilterableColumn<T>;
|
const column = this.grid.getColumns()[cell.cell] as FilterableColumn<T>;
|
||||||
if (column.filterable !== false && this.enabled && this.columnButtonMapping[column.id]) {
|
if (column.filterable !== false && this.columnButtonMapping[column.id]) {
|
||||||
await this.showFilter(this.columnButtonMapping[column.id]);
|
await this.showFilter(this.columnButtonMapping[column.id]);
|
||||||
EventHelper.stop(e, true);
|
EventHelper.stop(e, true);
|
||||||
}
|
}
|
||||||
@@ -123,9 +134,6 @@ export class HeaderFilter<T extends Slick.SlickData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private handleHeaderCellRendered(e: Event, args: Slick.OnHeaderCellRenderedEventArgs<T>) {
|
private handleHeaderCellRendered(e: Event, args: Slick.OnHeaderCellRenderedEventArgs<T>) {
|
||||||
if (!this.enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const column = args.column as FilterableColumn<T>;
|
const column = args.column as FilterableColumn<T>;
|
||||||
if ((<FilterableColumn<T>>column).filterable === false) {
|
if ((<FilterableColumn<T>>column).filterable === false) {
|
||||||
return;
|
return;
|
||||||
@@ -305,6 +313,12 @@ export class HeaderFilter<T extends Slick.SlickData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async showFilter(filterButton: HTMLElement): Promise<void> {
|
private async showFilter(filterButton: HTMLElement): Promise<void> {
|
||||||
|
if (!this.enabled) {
|
||||||
|
if (this.notificationProvider && this.options?.disabledFilterMessage) {
|
||||||
|
this.notificationProvider.info(this.options.disabledFilterMessage);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.previouslyFocusedElement = document.activeElement as HTMLElement;
|
this.previouslyFocusedElement = document.activeElement as HTMLElement;
|
||||||
await this.createFilterMenu(filterButton);
|
await this.createFilterMenu(filterButton);
|
||||||
// Get the absolute coordinates of the filter button
|
// Get the absolute coordinates of the filter button
|
||||||
@@ -482,20 +496,6 @@ export class HeaderFilter<T extends Slick.SlickData> {
|
|||||||
command: command
|
command: command
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public get enabled(): boolean {
|
|
||||||
return this._enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public set enabled(value: boolean) {
|
|
||||||
if (this._enabled !== value) {
|
|
||||||
this._enabled = value;
|
|
||||||
// force the table header to redraw.
|
|
||||||
this.grid.getColumns().forEach((column) => {
|
|
||||||
this.grid.updateColumnHeader(column.id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TableFilterListElement {
|
class TableFilterListElement {
|
||||||
|
|||||||
@@ -208,12 +208,13 @@ class DataResourceTable extends GridTableBase<any> {
|
|||||||
@IConfigurationService configurationService: IConfigurationService,
|
@IConfigurationService configurationService: IConfigurationService,
|
||||||
@IQueryModelService queryModelService: IQueryModelService,
|
@IQueryModelService queryModelService: IQueryModelService,
|
||||||
@IThemeService themeService: IThemeService,
|
@IThemeService themeService: IThemeService,
|
||||||
@IContextViewService contextViewService: IContextViewService
|
@IContextViewService contextViewService: IContextViewService,
|
||||||
|
@INotificationService notificationService: INotificationService
|
||||||
) {
|
) {
|
||||||
super(state, createResultSet(source), {
|
super(state, createResultSet(source), {
|
||||||
actionOrientation: ActionsOrientation.HORIZONTAL,
|
actionOrientation: ActionsOrientation.HORIZONTAL,
|
||||||
inMemoryDataProcessing: true
|
inMemoryDataProcessing: true
|
||||||
}, contextMenuService, instantiationService, editorService, untitledEditorService, configurationService, queryModelService, themeService, contextViewService);
|
}, contextMenuService, instantiationService, editorService, untitledEditorService, configurationService, queryModelService, themeService, contextViewService, notificationService);
|
||||||
this._gridDataProvider = this.instantiationService.createInstance(DataResourceDataProvider, source, this.resultSet, this.cellModel);
|
this._gridDataProvider = this.instantiationService.createInstance(DataResourceDataProvider, source, this.resultSet, this.cellModel);
|
||||||
this._chart = this.instantiationService.createInstance(ChartView, false);
|
this._chart = this.instantiationService.createInstance(ChartView, false);
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
|
|||||||
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
|
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
|
||||||
import { HeaderFilter } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
|
import { HeaderFilter } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
|
||||||
import { HybridDataProvider } from 'sql/base/browser/ui/table/hybridDataProvider';
|
import { HybridDataProvider } from 'sql/base/browser/ui/table/hybridDataProvider';
|
||||||
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
|
|
||||||
const ROW_HEIGHT = 29;
|
const ROW_HEIGHT = 29;
|
||||||
const HEADER_HEIGHT = 26;
|
const HEADER_HEIGHT = 26;
|
||||||
@@ -385,7 +386,8 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
|
|||||||
@IConfigurationService protected readonly configurationService: IConfigurationService,
|
@IConfigurationService protected readonly configurationService: IConfigurationService,
|
||||||
@IQueryModelService private readonly queryModelService: IQueryModelService,
|
@IQueryModelService private readonly queryModelService: IQueryModelService,
|
||||||
@IThemeService private readonly themeService: IThemeService,
|
@IThemeService private readonly themeService: IThemeService,
|
||||||
@IContextViewService private readonly contextViewService: IContextViewService
|
@IContextViewService private readonly contextViewService: IContextViewService,
|
||||||
|
@INotificationService private readonly notificationService: INotificationService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
let config = this.configurationService.getValue<{ rowHeight: number }>('resultsGrid');
|
let config = this.configurationService.getValue<{ rowHeight: number }>('resultsGrid');
|
||||||
@@ -527,7 +529,9 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
|
|||||||
this.table.rerenderGrid();
|
this.table.rerenderGrid();
|
||||||
}));
|
}));
|
||||||
if (this.enableFilteringFeature) {
|
if (this.enableFilteringFeature) {
|
||||||
this.filterPlugin = new HeaderFilter(this.contextViewService);
|
this.filterPlugin = new HeaderFilter(this.contextViewService, this.notificationService, {
|
||||||
|
disabledFilterMessage: localize('resultsGrid.maxRowCountExceeded', "Max row count for filtering/sorting has been exceeded. To update it, you can go to User Settings and change the setting: 'queryEditor.results.inMemoryDataProcessingThreshold'")
|
||||||
|
});
|
||||||
this._register(attachTableFilterStyler(this.filterPlugin, this.themeService));
|
this._register(attachTableFilterStyler(this.filterPlugin, this.themeService));
|
||||||
this.table.registerPlugin(this.filterPlugin);
|
this.table.registerPlugin(this.filterPlugin);
|
||||||
}
|
}
|
||||||
@@ -871,13 +875,14 @@ class GridTable<T> extends GridTableBase<T> {
|
|||||||
@IConfigurationService configurationService: IConfigurationService,
|
@IConfigurationService configurationService: IConfigurationService,
|
||||||
@IQueryModelService queryModelService: IQueryModelService,
|
@IQueryModelService queryModelService: IQueryModelService,
|
||||||
@IThemeService themeService: IThemeService,
|
@IThemeService themeService: IThemeService,
|
||||||
@IContextViewService contextViewService: IContextViewService
|
@IContextViewService contextViewService: IContextViewService,
|
||||||
|
@INotificationService notificationService: INotificationService
|
||||||
) {
|
) {
|
||||||
super(state, resultSet, {
|
super(state, resultSet, {
|
||||||
actionOrientation: ActionsOrientation.VERTICAL,
|
actionOrientation: ActionsOrientation.VERTICAL,
|
||||||
inMemoryDataProcessing: true,
|
inMemoryDataProcessing: true,
|
||||||
inMemoryDataCountThreshold: configurationService.getValue<IQueryEditorConfiguration>('queryEditor').results.inMemoryDataProcessingThreshold,
|
inMemoryDataCountThreshold: configurationService.getValue<IQueryEditorConfiguration>('queryEditor').results.inMemoryDataProcessingThreshold,
|
||||||
}, contextMenuService, instantiationService, editorService, untitledEditorService, configurationService, queryModelService, themeService, contextViewService);
|
}, contextMenuService, instantiationService, editorService, untitledEditorService, configurationService, queryModelService, themeService, contextViewService, notificationService);
|
||||||
this._gridDataProvider = this.instantiationService.createInstance(QueryGridDataProvider, this._runner, resultSet.batchId, resultSet.id);
|
this._gridDataProvider = this.instantiationService.createInstance(QueryGridDataProvider, this._runner, resultSet.batchId, resultSet.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ const queryEditorConfiguration: IConfigurationNode = {
|
|||||||
'queryEditor.results.inMemoryDataProcessingThreshold': {
|
'queryEditor.results.inMemoryDataProcessingThreshold': {
|
||||||
'type': 'number',
|
'type': 'number',
|
||||||
'default': 5000,
|
'default': 5000,
|
||||||
'description': localize('queryEditor.inMemoryDataProcessingThreshold', "Controls the max number of rows allowed to do filtering and sorting in memory. If the number is exceeded, sorting and filtering will be disabled.")
|
'description': localize('queryEditor.inMemoryDataProcessingThreshold', "Controls the max number of rows allowed to do filtering and sorting in memory. If the number is exceeded, sorting and filtering will be disabled. Warning: Increasing this may impact performance.")
|
||||||
},
|
},
|
||||||
'queryEditor.messages.showBatchTime': {
|
'queryEditor.messages.showBatchTime': {
|
||||||
'type': 'boolean',
|
'type': 'boolean',
|
||||||
|
|||||||
Reference in New Issue
Block a user