mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-09 17:52:34 -05:00
Isolate features (#6792)
* working; new query and scripting * working; removing manage from menus and combining data explorer contributions * consolidate dashboard contributions; move manage action to dashboard contributions; make groupings the same * fix notebook actions * fix tests
This commit is contained in:
@@ -14,7 +14,6 @@ import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ContextKeyExpr, ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
|
||||
import { QueryEditor } from 'sql/workbench/parts/query/browser/queryEditor';
|
||||
import { QueryResultsEditor } from 'sql/workbench/parts/query/browser/queryResultsEditor';
|
||||
@@ -34,6 +33,9 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { TimeElapsedStatusBarContributions, RowCountStatusBarContributions, QueryStatusStatusBarContributions } from 'sql/workbench/parts/query/browser/statusBarItems';
|
||||
import { SqlFlavorStatusbarItem } from 'sql/workbench/parts/query/browser/flavorStatus';
|
||||
import { NewQueryTask, OE_NEW_QUERY_ACTION_ID, DE_NEW_QUERY_COMMAND_ID } from 'sql/workbench/parts/query/browser/queryActions';
|
||||
import { TreeNodeContextKey } from 'sql/workbench/parts/objectExplorer/common/treeNodeContextKey';
|
||||
import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/common/mssqlNodeContext';
|
||||
|
||||
const gridCommandsWeightBonus = 100; // give our commands a little bit more weight over other default list/tree commands
|
||||
|
||||
@@ -61,7 +63,30 @@ const queryEditorDescriptor = new EditorDescriptor(
|
||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
||||
.registerEditor(queryEditorDescriptor, [new SyncDescriptor(QueryInput)]);
|
||||
|
||||
let actionRegistry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
|
||||
const actionRegistry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
|
||||
|
||||
new NewQueryTask().registerTask();
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, {
|
||||
group: '0_query',
|
||||
order: 0,
|
||||
command: {
|
||||
id: OE_NEW_QUERY_ACTION_ID,
|
||||
title: localize('newQuery', "New Query")
|
||||
},
|
||||
when: ContextKeyExpr.or(ContextKeyExpr.and(TreeNodeContextKey.Status.notEqualsTo('Unavailable'), TreeNodeContextKey.NodeType.isEqualTo('Server')), ContextKeyExpr.and(TreeNodeContextKey.Status.notEqualsTo('Unavailable'), TreeNodeContextKey.NodeType.isEqualTo('Database')))
|
||||
});
|
||||
|
||||
// New Query
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: '0_query',
|
||||
order: 0,
|
||||
command: {
|
||||
id: DE_NEW_QUERY_COMMAND_ID,
|
||||
title: localize('newQuery', "New Query")
|
||||
},
|
||||
when: MssqlNodeContext.IsDatabaseOrServer
|
||||
});
|
||||
|
||||
// Query Actions
|
||||
actionRegistry.registerWorkbenchAction(
|
||||
@@ -74,15 +99,12 @@ actionRegistry.registerWorkbenchAction(
|
||||
RunQueryKeyboardAction.LABEL
|
||||
);
|
||||
|
||||
// Touch Bar
|
||||
if (isMacintosh) {
|
||||
// Only show Run Query if the active editor is a query editor.
|
||||
MenuRegistry.appendMenuItem(MenuId.TouchBarContext, {
|
||||
command: { id: RunQueryKeyboardAction.ID, title: RunQueryKeyboardAction.LABEL },
|
||||
group: 'query',
|
||||
when: ContextKeyEqualsExpr.create('activeEditor', 'workbench.editor.queryEditor')
|
||||
});
|
||||
}
|
||||
// Only show Run Query if the active editor is a query editor.
|
||||
MenuRegistry.appendMenuItem(MenuId.TouchBarContext, {
|
||||
command: { id: RunQueryKeyboardAction.ID, title: RunQueryKeyboardAction.LABEL },
|
||||
group: 'query',
|
||||
when: ContextKeyEqualsExpr.create('activeEditor', 'workbench.editor.queryEditor')
|
||||
});
|
||||
|
||||
actionRegistry.registerWorkbenchAction(
|
||||
new SyncActionDescriptor(
|
||||
@@ -260,7 +282,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
});
|
||||
|
||||
// Intellisense and other configuration options
|
||||
let registryProperties = {
|
||||
const registryProperties = {
|
||||
'sql.saveAsCsv.includeHeaders': {
|
||||
'type': 'boolean',
|
||||
'description': localize('sql.saveAsCsv.includeHeaders', "[Optional] When true, column headers are included when saving results as CSV"),
|
||||
@@ -480,7 +502,7 @@ let registryProperties = {
|
||||
};
|
||||
|
||||
// Setup keybindings
|
||||
let initialShortcuts = [
|
||||
const initialShortcuts = [
|
||||
{ name: 'sp_help', primary: KeyMod.Alt + KeyCode.F2 },
|
||||
// Note: using Ctrl+Shift+N since Ctrl+N is used for "open editor at index" by default. This means it's different from SSMS
|
||||
{ name: 'sp_who', primary: KeyMod.WinCtrl + KeyMod.Shift + KeyCode.KEY_1 },
|
||||
@@ -512,7 +534,7 @@ for (let i = 0; i < 9; i++) {
|
||||
}
|
||||
|
||||
// Register the query-related configuration options
|
||||
let configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigExtensions.Configuration);
|
||||
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigExtensions.Configuration);
|
||||
configurationRegistry.registerConfiguration({
|
||||
'id': 'sqlEditor',
|
||||
'title': 'SQL Editor',
|
||||
|
||||
@@ -11,7 +11,6 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { append, $ } from 'vs/base/browser/dom';
|
||||
|
||||
@@ -21,13 +20,27 @@ import {
|
||||
IConnectionParams,
|
||||
INewConnectionParams,
|
||||
ConnectionType,
|
||||
RunQueryOnConnectionMode
|
||||
RunQueryOnConnectionMode,
|
||||
IConnectionCompletionOptions,
|
||||
IConnectableInput
|
||||
} from 'sql/platform/connection/common/connectionManagement';
|
||||
import { QueryEditor } from 'sql/workbench/parts/query/browser/queryEditor';
|
||||
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
|
||||
import { attachEditableDropdownStyler, attachSelectBoxStyler } from 'sql/platform/theme/common/styler';
|
||||
import { Dropdown } from 'sql/base/parts/editableDropdown/browser/dropdown';
|
||||
import { Task } from 'sql/platform/tasks/browser/tasksRegistry';
|
||||
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { getCurrentGlobalConnection } from 'sql/workbench/browser/taskUtilities';
|
||||
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { OEAction } from 'sql/workbench/parts/objectExplorer/browser/objectExplorerActions';
|
||||
import { TreeViewItemHandleArg } from 'sql/workbench/common/views';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { IQueryManagementService } from 'sql/platform/query/common/queryManagement';
|
||||
|
||||
/**
|
||||
@@ -98,6 +111,83 @@ export abstract class QueryTaskbarAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export function openNewQuery(accessor: ServicesAccessor, profile?: IConnectionProfile, initalContent?: string, onConnection?: RunQueryOnConnectionMode): Promise<void> {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const objectExplorerService = accessor.get(IObjectExplorerService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
if (!profile) {
|
||||
profile = getCurrentGlobalConnection(objectExplorerService, connectionManagementService, editorService);
|
||||
}
|
||||
return queryEditorService.newSqlEditor(initalContent).then((owner: IConnectableInput) => {
|
||||
// Connect our editor to the input connection
|
||||
let options: IConnectionCompletionOptions = {
|
||||
params: { connectionType: ConnectionType.editor, runQueryOnCompletion: onConnection, input: owner },
|
||||
saveTheConnection: false,
|
||||
showDashboard: false,
|
||||
showConnectionDialogOnError: true,
|
||||
showFirewallRuleOnError: true
|
||||
};
|
||||
if (profile) {
|
||||
return connectionManagementService.connect(profile, owner.uri, options).then();
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
// --- actions
|
||||
export class NewQueryTask extends Task {
|
||||
public static ID = 'newQuery';
|
||||
public static LABEL = nls.localize('newQueryTask.newQuery', "New Query");
|
||||
public static ICON = 'new-query';
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: NewQueryTask.ID,
|
||||
title: NewQueryTask.LABEL,
|
||||
iconPath: undefined,
|
||||
iconClass: NewQueryTask.ICON
|
||||
});
|
||||
}
|
||||
|
||||
public runTask(accessor: ServicesAccessor, profile: IConnectionProfile): Promise<void> {
|
||||
return openNewQuery(accessor, profile);
|
||||
}
|
||||
}
|
||||
|
||||
export const OE_NEW_QUERY_ACTION_ID = 'objectExplorer.newQuery';
|
||||
|
||||
CommandsRegistry.registerCommand(OE_NEW_QUERY_ACTION_ID, (accessor: ServicesAccessor, actionContext: any) => {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
return instantiationService.createInstance(OEAction, NewQueryTask.ID, NewQueryTask.LABEL).run(actionContext);
|
||||
});
|
||||
|
||||
export const DE_NEW_QUERY_COMMAND_ID = 'dataExplorer.newQuery';
|
||||
|
||||
// New Query
|
||||
CommandsRegistry.registerCommand({
|
||||
id: DE_NEW_QUERY_COMMAND_ID,
|
||||
handler: (accessor, args: TreeViewItemHandleArg) => {
|
||||
if (args.$treeItem) {
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionService = accessor.get(IConnectionManagementService);
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
return queryEditorService.newSqlEditor().then((owner: IConnectableInput) => {
|
||||
// Connect our editor to the input connection
|
||||
let options: IConnectionCompletionOptions = {
|
||||
params: { connectionType: ConnectionType.editor, input: owner },
|
||||
saveTheConnection: false,
|
||||
showDashboard: false,
|
||||
showConnectionDialogOnError: true,
|
||||
showFirewallRuleOnError: true
|
||||
};
|
||||
return connectionService.connect(new ConnectionProfile(capabilitiesService, args.$treeItem.payload), owner.uri, options);
|
||||
});
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Action class that runs a query in the active SQL text document.
|
||||
*/
|
||||
@@ -109,8 +199,7 @@ export class RunQueryAction extends QueryTaskbarAction {
|
||||
constructor(
|
||||
editor: QueryEditor,
|
||||
@IQueryModelService protected readonly queryModelService: IQueryModelService,
|
||||
@IConnectionManagementService connectionManagementService: IConnectionManagementService,
|
||||
@IExtensionTipsService private readonly extensionTipsService: IExtensionTipsService
|
||||
@IConnectionManagementService connectionManagementService: IConnectionManagementService
|
||||
) {
|
||||
super(connectionManagementService, editor, RunQueryAction.ID, RunQueryAction.EnabledClass);
|
||||
this.label = nls.localize('runQueryLabel', "Run");
|
||||
@@ -480,7 +569,6 @@ export class ListDatabasesActionItem implements IActionViewItem {
|
||||
|
||||
public actionRunner: IActionRunner;
|
||||
private _toDispose: IDisposable[];
|
||||
private _context: any;
|
||||
private _currentDatabaseName: string;
|
||||
private _isConnected: boolean;
|
||||
private _databaseListDropdown: HTMLElement;
|
||||
@@ -537,7 +625,6 @@ export class ListDatabasesActionItem implements IActionViewItem {
|
||||
}
|
||||
|
||||
public setActionContext(context: any): void {
|
||||
this._context = context;
|
||||
}
|
||||
|
||||
public isEnabled(): boolean {
|
||||
|
||||
@@ -69,7 +69,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
|
||||
test('setClass sets child CSS class correctly', (done) => {
|
||||
// If I create a RunQueryAction
|
||||
let queryAction: QueryTaskbarAction = new RunQueryAction(undefined, undefined, undefined, undefined);
|
||||
let queryAction: QueryTaskbarAction = new RunQueryAction(undefined, undefined, undefined);
|
||||
|
||||
// "class should automatically get set to include the base class and the RunQueryAction class
|
||||
let className = RunQueryAction.EnabledClass;
|
||||
@@ -93,7 +93,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
editor.setup(x => x.input).returns(() => testQueryInput.object);
|
||||
|
||||
// If I create a QueryTaskbarAction and I pass a non-connected editor to _getConnectedQueryEditorUri
|
||||
let queryAction: QueryTaskbarAction = new RunQueryAction(undefined, undefined, connectionManagementService.object, undefined);
|
||||
let queryAction: QueryTaskbarAction = new RunQueryAction(undefined, undefined, connectionManagementService.object);
|
||||
let connected: boolean = queryAction.isConnected(editor.object);
|
||||
|
||||
// I should get an unconnected state
|
||||
@@ -136,7 +136,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
});
|
||||
|
||||
// If I call run on RunQueryAction when I am not connected
|
||||
let queryAction: RunQueryAction = new RunQueryAction(editor.object, queryModelService.object, connectionManagementService.object, undefined);
|
||||
let queryAction: RunQueryAction = new RunQueryAction(editor.object, queryModelService.object, connectionManagementService.object);
|
||||
isConnected = false;
|
||||
calledRunQueryOnInput = false;
|
||||
queryAction.run();
|
||||
@@ -195,7 +195,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
let queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose);
|
||||
|
||||
// If I call run on RunQueryAction when I have a non empty selection
|
||||
let queryAction: RunQueryAction = new RunQueryAction(queryEditor.object, queryModelService.object, connectionManagementService.object, undefined);
|
||||
let queryAction: RunQueryAction = new RunQueryAction(queryEditor.object, queryModelService.object, connectionManagementService.object);
|
||||
isSelectionEmpty = false;
|
||||
queryAction.run();
|
||||
|
||||
@@ -266,7 +266,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
/// End Setup Test ///
|
||||
|
||||
////// If I call run on RunQueryAction while disconnected and with an undefined selection
|
||||
let queryAction: RunQueryAction = new RunQueryAction(queryEditor.object, undefined, connectionManagementService.object, undefined);
|
||||
let queryAction: RunQueryAction = new RunQueryAction(queryEditor.object, undefined, connectionManagementService.object);
|
||||
isConnected = false;
|
||||
selectionToReturnInGetSelection = undefined;
|
||||
queryAction.run();
|
||||
|
||||
@@ -54,7 +54,7 @@ suite('SQL QueryEditor Tests', () => {
|
||||
return new Promise((resolve) => resolve(mockEditor));
|
||||
});
|
||||
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((input) => {
|
||||
return new Promise((resolve) => resolve(new RunQueryAction(undefined, undefined, undefined, undefined)));
|
||||
return new Promise((resolve) => resolve(new RunQueryAction(undefined, undefined, undefined)));
|
||||
});
|
||||
// Setup hook to capture calls to create the listDatabase action
|
||||
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((classDef, editor, action) => {
|
||||
@@ -64,7 +64,7 @@ suite('SQL QueryEditor Tests', () => {
|
||||
}
|
||||
}
|
||||
// Default
|
||||
return new RunQueryAction(undefined, undefined, undefined, undefined);
|
||||
return new RunQueryAction(undefined, undefined, undefined);
|
||||
});
|
||||
|
||||
// Mock EditorDescriptorService to give us a mock editor description
|
||||
@@ -269,7 +269,7 @@ suite('SQL QueryEditor Tests', () => {
|
||||
|
||||
queryActionInstantiationService.setup(x => x.createInstance(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((input) => {
|
||||
// Default
|
||||
return new RunQueryAction(undefined, undefined, undefined, undefined);
|
||||
return new RunQueryAction(undefined, undefined, undefined);
|
||||
});
|
||||
|
||||
// Setup hook to capture calls to create the listDatabase action
|
||||
@@ -280,7 +280,7 @@ suite('SQL QueryEditor Tests', () => {
|
||||
return item;
|
||||
}
|
||||
// Default
|
||||
return new RunQueryAction(undefined, undefined, undefined, undefined);
|
||||
return new RunQueryAction(undefined, undefined, undefined);
|
||||
});
|
||||
|
||||
let fileInput = new UntitledEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService.object, undefined, undefined);
|
||||
|
||||
Reference in New Issue
Block a user