mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-23 17:23:02 -05:00
fix query result grid shortcut keys (#23206)
* fix query result grid shortcut keys * add comment
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { TableFilteringEnabledContextKey, InTableContextKey, InQueryResultGridContextKey } from 'sql/workbench/services/componentContext/browser/contextKeys';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IQueryResultGrid } from 'sql/workbench/contrib/query/browser/gridPanel';
|
||||
import { HeaderFilter } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
|
||||
|
||||
export const SERVICE_ID = 'componentContextService';
|
||||
export const IComponentContextService = createDecorator<IComponentContextService>(SERVICE_ID);
|
||||
|
||||
export interface ComponentRegistrationResult extends IDisposable {
|
||||
componentContextKeyService: IContextKeyService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Service to register components and find out the active component for keybindings.
|
||||
*/
|
||||
export interface IComponentContextService {
|
||||
_serviceBrand: undefined;
|
||||
/**
|
||||
* Register a table
|
||||
* @param table The table to register
|
||||
* @param contextKeyService The context key service to use for the table. If not provided, the global context key service will be used.
|
||||
*/
|
||||
registerTable(table: Table<any>, contextKeyService?: IContextKeyService): ComponentRegistrationResult;
|
||||
/**
|
||||
* Get the table that has the focus.
|
||||
*/
|
||||
getActiveTable(): Table<any> | undefined;
|
||||
|
||||
/**
|
||||
* Register a query result grid
|
||||
* @param grid The grid to register
|
||||
* @param contextKeyService The context key service to use for the grid. If not provided, the global context key service will be used.
|
||||
*/
|
||||
registerQueryResultGrid(grid: IQueryResultGrid, contextKeyService?: IContextKeyService): ComponentRegistrationResult;
|
||||
/**
|
||||
* Get the grid that has the focus.
|
||||
*/
|
||||
getActiveQueryResultGrid(): IQueryResultGrid | undefined;
|
||||
}
|
||||
|
||||
enum ComponentType {
|
||||
Table = 'Table',
|
||||
QueryResultGrid = 'QueryResultGrid'
|
||||
}
|
||||
|
||||
export class ComponentContextService implements IComponentContextService {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private _components: Map<number, { type: ComponentType, component: any }> = new Map<number, { type: ComponentType, component: any }>();
|
||||
private _currentId: number = 1;
|
||||
|
||||
constructor(@IContextKeyService private readonly _contextKeyService: IContextKeyService) { }
|
||||
|
||||
public registerTable(table: Table<any>, contextKeyService?: IContextKeyService): ComponentRegistrationResult {
|
||||
return this.registerComponent(ComponentType.Table, table, table.grid.getContainerNode(), contextKeyService, (service) => {
|
||||
InTableContextKey.bindTo(service).set(true);
|
||||
TableFilteringEnabledContextKey.bindTo(service).set(table.grid.getPlugins().find(p => p instanceof HeaderFilter) !== undefined)
|
||||
});
|
||||
}
|
||||
|
||||
public getActiveTable(): Table<any> | undefined {
|
||||
return this.getActiveComponent<Table<any>>(ComponentType.Table, (table) => table.grid.getContainerNode());
|
||||
}
|
||||
|
||||
public registerQueryResultGrid(grid: IQueryResultGrid, contextKeyService?: IContextKeyService): ComponentRegistrationResult {
|
||||
return this.registerComponent(ComponentType.QueryResultGrid, grid, grid.htmlElement, contextKeyService, (service) => {
|
||||
InQueryResultGridContextKey.bindTo(service).set(true);
|
||||
});
|
||||
}
|
||||
|
||||
public getActiveQueryResultGrid(): IQueryResultGrid | undefined {
|
||||
return this.getActiveComponent<IQueryResultGrid>(ComponentType.QueryResultGrid, (grid) => grid.htmlElement);
|
||||
}
|
||||
|
||||
private registerComponent(type: ComponentType, component: any, htmlElement: HTMLElement, contextKeyService: IContextKeyService, contextSetter: (contextKeyService: IContextKeyService) => void): ComponentRegistrationResult {
|
||||
const parentContextKeyService = contextKeyService ?? this._contextKeyService;
|
||||
const id = this._currentId++;
|
||||
this._components.set(id, { type, component });
|
||||
const service = parentContextKeyService.createScoped(htmlElement);
|
||||
contextSetter(service);
|
||||
return {
|
||||
componentContextKeyService: service,
|
||||
dispose: () => {
|
||||
this._components.delete(id);
|
||||
service.dispose();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component that has the focus.
|
||||
* @param type type of the component to look for.
|
||||
* @param elementGetter function to get the html element of the component.
|
||||
* @returns the component that has the focus or undefined if no component has the focus.
|
||||
*/
|
||||
private getActiveComponent<T>(type: ComponentType, elementGetter: (component: T) => HTMLElement): T | undefined {
|
||||
for (const item of this._components.values()) {
|
||||
if (item.type === type && elementGetter(item.component).contains(document.activeElement)) {
|
||||
return item.component;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
// Table
|
||||
export const InTableContextKey = new RawContextKey<boolean>('inTable', true);
|
||||
export const TableFilteringEnabledContextKey = new RawContextKey<boolean>('filteringEnabled', false);
|
||||
|
||||
// Query Result Grid
|
||||
export const InQueryResultGridContextKey = new RawContextKey<boolean>('inQueryResultGrid', true);
|
||||
@@ -53,7 +53,7 @@ import { IDisposableDataProvider } from 'sql/base/common/dataProvider';
|
||||
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfiguration';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { ITableService } from 'sql/workbench/services/table/browser/tableService';
|
||||
import { IComponentContextService } from 'sql/workbench/services/componentContext/browser/componentContextService';
|
||||
|
||||
const labelDisplay = nls.localize("insights.item", "Item");
|
||||
const valueDisplay = nls.localize("insights.value", "Value");
|
||||
@@ -92,7 +92,7 @@ class InsightTableView extends ViewPane {
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IAccessibilityService private _accessibilityService: IAccessibilityService,
|
||||
@IQuickInputService private _quickInputService: IQuickInputService,
|
||||
@ITableService private readonly _tableService: ITableService
|
||||
@IComponentContextService private readonly _componentContextService: IComponentContextService
|
||||
) {
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class InsightTableView extends ViewPane {
|
||||
columns: this.columns,
|
||||
dataProvider: this.data
|
||||
}, this.tableOptions);
|
||||
this._register(this._tableService.registerTable(this._table));
|
||||
this._register(this._componentContextService.registerTable(this._table));
|
||||
}
|
||||
|
||||
protected override layoutBody(size: number): void {
|
||||
|
||||
@@ -50,7 +50,7 @@ import { MediaDeviceType } from 'sql/workbench/contrib/backup/common/constants';
|
||||
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfiguration';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { ITableService } from 'sql/workbench/services/table/browser/tableService';
|
||||
import { IComponentContextService } from 'sql/workbench/services/componentContext/browser/componentContextService';
|
||||
|
||||
interface FileListElement {
|
||||
logicalFileName: string;
|
||||
@@ -163,7 +163,7 @@ export class RestoreDialog extends Modal {
|
||||
@ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService,
|
||||
@IAccessibilityService private _accessibilityService: IAccessibilityService,
|
||||
@IQuickInputService private _quickInputService: IQuickInputService,
|
||||
@ITableService private readonly _tableService: ITableService
|
||||
@IComponentContextService private readonly _componentContextService: IComponentContextService
|
||||
) {
|
||||
super(localize('RestoreDialogTitle', "Restore database"), TelemetryKeys.ModalDialogName.Restore, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, { hasErrors: true, width: 'wide', hasSpinner: true });
|
||||
// view model
|
||||
@@ -319,7 +319,7 @@ export class RestoreDialog extends Modal {
|
||||
this._restorePlanTable.setTableTitle(localize('restorePlan', "Restore plan"));
|
||||
this._restorePlanTable.setSelectionModel(new RowSelectionModel({ selectActiveRow: false }));
|
||||
this._restorePlanTable.onSelectedRowsChanged((e, data) => this.backupFileCheckboxChanged(e, data));
|
||||
this._register(this._tableService.registerTable(this._restorePlanTable));
|
||||
this._register(this._componentContextService.registerTable(this._restorePlanTable));
|
||||
|
||||
// Content in general tab
|
||||
const generalTab = DOM.$('.restore-dialog');
|
||||
@@ -369,7 +369,7 @@ export class RestoreDialog extends Modal {
|
||||
this._fileListTable = this._register(new Table<FileListElement>(this._fileListTableContainer, this._accessibilityService, this._quickInputService,
|
||||
{ dataProvider: this._fileListData, columns }, { enableColumnReorder: false }));
|
||||
this._fileListTable.setSelectionModel(new RowSelectionModel());
|
||||
this._register(this._tableService.registerTable(this._fileListTable));
|
||||
this._register(this._componentContextService.registerTable(this._fileListTable));
|
||||
|
||||
// Content in options tab
|
||||
const optionsContentElement = DOM.$('.restore-dialog');
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { HeaderFilter } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
export const InTable = new RawContextKey<boolean>('inTable', true);
|
||||
export const FilteringEnabled = new RawContextKey<boolean>('filteringEnabled', false);
|
||||
|
||||
export class TableContext implements IDisposable {
|
||||
private _inTable: IContextKey<boolean>;
|
||||
private _filteringEnabled: IContextKey<boolean>;
|
||||
|
||||
constructor(contextKeyService: IContextKeyService, table: Table<Slick.SlickData>) {
|
||||
this._inTable = InTable.bindTo(contextKeyService);
|
||||
this._filteringEnabled = FilteringEnabled.bindTo(contextKeyService);
|
||||
this._inTable.set(true);
|
||||
this._filteringEnabled.set(table.grid.getPlugins().find(p => p instanceof HeaderFilter) !== undefined);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { TableContext } from 'sql/workbench/services/table/browser/tableContext';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
export const SERVICE_ID = 'tableService';
|
||||
export const ITableService = createDecorator<ITableService>(SERVICE_ID);
|
||||
|
||||
/**
|
||||
* Service to manage the table components used by the application.
|
||||
*/
|
||||
export interface ITableService {
|
||||
_serviceBrand: undefined;
|
||||
/**
|
||||
* Register a table
|
||||
*/
|
||||
registerTable(table: Table<any>): IDisposable;
|
||||
/**
|
||||
* Get the table that has the focus.
|
||||
*/
|
||||
getActiveTable(): Table<any> | undefined;
|
||||
}
|
||||
|
||||
export class TableService implements ITableService {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private _tables: Map<number, Table<any>> = new Map<number, Table<any>>();
|
||||
private _currentId: number = 1;
|
||||
|
||||
constructor(@IContextKeyService private readonly _contextKeyService: IContextKeyService) { }
|
||||
|
||||
registerTable(table: Table<any>): IDisposable {
|
||||
const id = this._currentId++;
|
||||
this._tables.set(id, table);
|
||||
const service = this._contextKeyService.createScoped(table.grid.getContainerNode());
|
||||
const context = new TableContext(service, table);
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
this._tables.delete(id);
|
||||
service.dispose();
|
||||
context.dispose();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getActiveTable(): Table<any> | undefined {
|
||||
for (const table of this._tables.values()) {
|
||||
if (table?.grid.getContainerNode().contains(document.activeElement)) {
|
||||
return table;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user