mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-15 18:46:36 -05:00
Merge from master
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { ITreeItem } from 'sql/workbench/common/views';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { TreeNode } from 'sql/parts/objectExplorer/common/treeNode';
|
||||
import { IConnectionManagementService, ConnectionType } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService';
|
||||
import { IConnectionDialogService } from 'sql/workbench/services/connection/common/connectionDialogService';
|
||||
|
||||
import { IConnectionProfile } from 'sqlops';
|
||||
|
||||
import { TreeItemCollapsibleState } from 'vs/workbench/common/views';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
import { hash } from 'vs/base/common/hash';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export const SERVICE_ID = 'oeShimService';
|
||||
export const IOEShimService = createDecorator<IOEShimService>(SERVICE_ID);
|
||||
|
||||
export interface IOEShimService {
|
||||
_serviceBrand: any;
|
||||
getChildren(node: ITreeItem, identifier: any): TPromise<ITreeItem[]>;
|
||||
providerExists(providerId: string): boolean;
|
||||
}
|
||||
|
||||
export class OEShimService implements IOEShimService {
|
||||
_serviceBrand: any;
|
||||
|
||||
// maps a datasource to a provider handle to a session
|
||||
private sessionMap = new Map<any, Map<number, string>>();
|
||||
private nodeIdMap = new Map<string, string>();
|
||||
|
||||
constructor(
|
||||
@IObjectExplorerService private oe: IObjectExplorerService,
|
||||
@IConnectionManagementService private cm: IConnectionManagementService,
|
||||
@IConnectionDialogService private cd: IConnectionDialogService,
|
||||
@ICapabilitiesService private capabilities: ICapabilitiesService
|
||||
) {
|
||||
}
|
||||
|
||||
private async createSession(providerId: string, node: ITreeItem): TPromise<string> {
|
||||
let deferred = new Deferred<string>();
|
||||
let connProfile = new ConnectionProfile(this.capabilities, node.payload);
|
||||
connProfile.saveProfile = false;
|
||||
if (this.cm.providerRegistered(providerId)) {
|
||||
connProfile = new ConnectionProfile(this.capabilities, await this.cd.openDialogAndWait(this.cm, { connectionType: ConnectionType.default, showDashboard: false }, connProfile, undefined, false));
|
||||
}
|
||||
let sessionResp = await this.oe.createNewSession(providerId, connProfile);
|
||||
let disp = this.oe.onUpdateObjectExplorerNodes(e => {
|
||||
if (e.connection.id === connProfile.id) {
|
||||
let rootNode = this.oe.getSession(sessionResp.sessionId).rootNode;
|
||||
// this is how we know it was shimmed
|
||||
if (rootNode.nodePath) {
|
||||
node.handle = this.oe.getSession(sessionResp.sessionId).rootNode.nodePath;
|
||||
}
|
||||
}
|
||||
disp.dispose();
|
||||
deferred.resolve(sessionResp.sessionId);
|
||||
});
|
||||
return TPromise.wrap(deferred.promise);
|
||||
}
|
||||
|
||||
public async getChildren(node: ITreeItem, identifier: any): TPromise<ITreeItem[]> {
|
||||
try {
|
||||
if (!this.sessionMap.has(identifier)) {
|
||||
this.sessionMap.set(identifier, new Map<number, string>());
|
||||
}
|
||||
if (!this.sessionMap.get(identifier).has(hash(node.payload || node.childProvider))) {
|
||||
this.sessionMap.get(identifier).set(hash(node.payload || node.childProvider), await this.createSession(node.childProvider, node));
|
||||
}
|
||||
if (this.nodeIdMap.has(node.handle)) {
|
||||
node.handle = this.nodeIdMap.get(node.handle);
|
||||
}
|
||||
let sessionId = this.sessionMap.get(identifier).get(hash(node.payload || node.childProvider));
|
||||
let treeNode = new TreeNode(undefined, undefined, undefined, node.handle, undefined, undefined, undefined, undefined, undefined, undefined);
|
||||
let profile: IConnectionProfile = node.payload || {
|
||||
providerName: node.childProvider,
|
||||
authenticationType: undefined,
|
||||
azureTenantId: undefined,
|
||||
connectionName: undefined,
|
||||
databaseName: undefined,
|
||||
groupFullName: undefined,
|
||||
groupId: undefined,
|
||||
id: undefined,
|
||||
options: undefined,
|
||||
password: undefined,
|
||||
savePassword: undefined,
|
||||
saveProfile: undefined,
|
||||
serverName: undefined,
|
||||
userName: undefined,
|
||||
};
|
||||
treeNode.connection = new ConnectionProfile(this.capabilities, profile);
|
||||
return TPromise.wrap(this.oe.resolveTreeNodeChildren({
|
||||
success: undefined,
|
||||
sessionId,
|
||||
rootNode: undefined,
|
||||
errorMessage: undefined
|
||||
}, treeNode).then(e => e.map(n => this.mapNodeToITreeItem(n, node))));
|
||||
} catch (e) {
|
||||
return TPromise.as([]);
|
||||
}
|
||||
}
|
||||
|
||||
private mapNodeToITreeItem(node: TreeNode, parentNode: ITreeItem): ITreeItem {
|
||||
let icon: string;
|
||||
let iconDark: string;
|
||||
if (equalsIgnoreCase(parentNode.childProvider, 'mssql')) {
|
||||
if (node.iconType) {
|
||||
icon = (typeof node.iconType === 'string') ? node.iconType : node.iconType.id;
|
||||
} else {
|
||||
icon = node.nodeTypeId;
|
||||
if (node.nodeStatus) {
|
||||
icon = node.nodeTypeId + '_' + node.nodeStatus;
|
||||
}
|
||||
if (node.nodeSubType) {
|
||||
icon = node.nodeTypeId + '_' + node.nodeSubType;
|
||||
}
|
||||
}
|
||||
icon = icon.toLowerCase();
|
||||
iconDark = icon;
|
||||
} else {
|
||||
icon = node.iconType as string;
|
||||
// this is just because we need to have some mapping
|
||||
iconDark = node.nodeSubType;
|
||||
}
|
||||
let handle = generateUuid();
|
||||
this.nodeIdMap.set(handle, node.nodePath);
|
||||
return {
|
||||
parentHandle: node.parent.id,
|
||||
handle,
|
||||
collapsibleState: node.isAlwaysLeaf ? TreeItemCollapsibleState.None : TreeItemCollapsibleState.Collapsed,
|
||||
label: {
|
||||
label: node.label
|
||||
},
|
||||
icon: URI.parse(icon),
|
||||
iconDark: URI.parse(iconDark),
|
||||
childProvider: node.childProvider || parentNode.childProvider,
|
||||
providerHandle: parentNode.childProvider,
|
||||
payload: node.payload || parentNode.payload,
|
||||
contextValue: node.nodeTypeId
|
||||
};
|
||||
}
|
||||
|
||||
public providerExists(providerId: string): boolean {
|
||||
return this.oe.providerRegistered(providerId);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import 'vs/css!sql/media/actionBarLabel';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { localize } from 'vs/nls';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ToggleViewletAction } from 'vs/workbench/browser/viewlet';
|
||||
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
@@ -17,6 +17,8 @@ import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/co
|
||||
import { VIEWLET_ID } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ConnectionViewlet } from 'sql/workbench/parts/connection/electron-browser/connectionViewlet';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { ToggleViewletAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
|
||||
// Viewlet Action
|
||||
export class OpenConnectionsViewletAction extends ToggleViewletAction {
|
||||
@@ -27,9 +29,9 @@ export class OpenConnectionsViewletAction extends ToggleViewletAction {
|
||||
id: string,
|
||||
label: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService
|
||||
@IPartService partService: IPartService
|
||||
) {
|
||||
super(id, label, VIEWLET_ID, viewletService, editorGroupService);
|
||||
super(viewletDescriptor, partService, viewletService);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,14 @@ export interface ObjectExplorerCallbacks {
|
||||
}
|
||||
|
||||
export class TreeNode {
|
||||
/**
|
||||
* Informs who provides the children to a node, used by data explorer tree view api
|
||||
*/
|
||||
public childProvider: string;
|
||||
/**
|
||||
* Holds the connection profile for nodes, used by data explorer tree view api
|
||||
*/
|
||||
public payload: any;
|
||||
/**
|
||||
* id for TreeNode
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
import 'vs/css!./media/serverGroupDialog';
|
||||
import { Builder } from 'vs/base/browser/builder';
|
||||
import { Builder } from 'sql/base/browser/builder';
|
||||
import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox';
|
||||
import { MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
|
||||
@@ -59,7 +59,7 @@ export class OEAction extends ExecuteCommandAction {
|
||||
super(id, label, commandService);
|
||||
}
|
||||
|
||||
public async run(actionContext: any): TPromise<boolean> {
|
||||
public async run(actionContext: any): Promise<boolean> {
|
||||
this._treeSelectionHandler = this._instantiationService.createInstance(TreeSelectionHandler);
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ export class OEScriptSelectAction extends ScriptSelectAction {
|
||||
super(id, label, _queryEditorService, _connectionManagementService, _scriptingService);
|
||||
}
|
||||
|
||||
public async run(actionContext: any): TPromise<boolean> {
|
||||
public async run(actionContext: any): Promise<boolean> {
|
||||
this._treeSelectionHandler = this._instantiationService.createInstance(TreeSelectionHandler);
|
||||
if (actionContext instanceof ObjectExplorerActionsContext) {
|
||||
//set objectExplorerTreeNode for context menu clicks
|
||||
@@ -213,7 +213,7 @@ export class OEEditDataAction extends EditDataAction {
|
||||
super(id, label, _queryEditorService, _connectionManagementService, _scriptingService);
|
||||
}
|
||||
|
||||
public async run(actionContext: any): TPromise<boolean> {
|
||||
public async run(actionContext: any): Promise<boolean> {
|
||||
this._treeSelectionHandler = this._instantiationService.createInstance(TreeSelectionHandler);
|
||||
if (actionContext instanceof ObjectExplorerActionsContext) {
|
||||
//set objectExplorerTreeNode for context menu clicks
|
||||
@@ -247,7 +247,7 @@ export class OEScriptCreateAction extends ScriptCreateAction {
|
||||
super(id, label, _queryEditorService, _connectionManagementService, _scriptingService, _errorMessageService);
|
||||
}
|
||||
|
||||
public async run(actionContext: any): TPromise<boolean> {
|
||||
public async run(actionContext: any): Promise<boolean> {
|
||||
this._treeSelectionHandler = this._instantiationService.createInstance(TreeSelectionHandler);
|
||||
if (actionContext instanceof ObjectExplorerActionsContext) {
|
||||
//set objectExplorerTreeNode for context menu clicks
|
||||
@@ -283,7 +283,7 @@ export class OEScriptExecuteAction extends ScriptExecuteAction {
|
||||
super(id, label, _queryEditorService, _connectionManagementService, _scriptingService, _errorMessageService);
|
||||
}
|
||||
|
||||
public async run(actionContext: any): TPromise<boolean> {
|
||||
public async run(actionContext: any): Promise<boolean> {
|
||||
this._treeSelectionHandler = this._instantiationService.createInstance(TreeSelectionHandler);
|
||||
if (actionContext instanceof ObjectExplorerActionsContext) {
|
||||
//set objectExplorerTreeNode for context menu clicks
|
||||
@@ -319,7 +319,7 @@ export class OEScriptAlterAction extends ScriptAlterAction {
|
||||
super(id, label, _queryEditorService, _connectionManagementService, _scriptingService, _errorMessageService);
|
||||
}
|
||||
|
||||
public async run(actionContext: any): TPromise<boolean> {
|
||||
public async run(actionContext: any): Promise<boolean> {
|
||||
this._treeSelectionHandler = this._instantiationService.createInstance(TreeSelectionHandler);
|
||||
if (actionContext instanceof ObjectExplorerActionsContext) {
|
||||
//set objectExplorerTreeNode for context menu clicks
|
||||
@@ -355,7 +355,7 @@ export class OEScriptDeleteAction extends ScriptDeleteAction {
|
||||
super(id, label, _queryEditorService, _connectionManagementService, _scriptingService, _errorMessageService);
|
||||
}
|
||||
|
||||
public async run(actionContext: any): TPromise<boolean> {
|
||||
public async run(actionContext: any): Promise<boolean> {
|
||||
this._treeSelectionHandler = this._instantiationService.createInstance(TreeSelectionHandler);
|
||||
if (actionContext instanceof ObjectExplorerActionsContext) {
|
||||
//set objectExplorerTreeNode for context menu clicks
|
||||
|
||||
@@ -59,29 +59,29 @@ export class ServerTreeActionProvider extends ContributableActionProvider {
|
||||
/**
|
||||
* Return actions given an element in the tree
|
||||
*/
|
||||
public getActions(tree: ITree, element: any): TPromise<IAction[]> {
|
||||
public getActions(tree: ITree, element: any): IAction[] {
|
||||
if (element instanceof ConnectionProfile) {
|
||||
return TPromise.as(this.getConnectionActions(tree, element));
|
||||
return this.getConnectionActions(tree, element);
|
||||
}
|
||||
if (element instanceof ConnectionProfileGroup) {
|
||||
return TPromise.as(this.getConnectionProfileGroupActions(tree, element));
|
||||
return this.getConnectionProfileGroupActions(tree, element);
|
||||
}
|
||||
if (element instanceof TreeNode) {
|
||||
return TPromise.as(this.getObjectExplorerNodeActions({
|
||||
return this.getObjectExplorerNodeActions({
|
||||
tree: tree,
|
||||
profile: element.getConnectionProfile(),
|
||||
treeNode: element
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
return TPromise.as([]);
|
||||
return [];
|
||||
}
|
||||
|
||||
public hasSecondaryActions(tree: ITree, element: any): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
public getSecondaryActions(tree: ITree, element: any): TPromise<IAction[]> {
|
||||
public getSecondaryActions(tree: ITree, element: any): IAction[] {
|
||||
return super.getSecondaryActions(tree, element);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import 'vs/css!./media/serverTreeActions';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import * as builder from 'vs/base/browser/builder';
|
||||
import * as builder from 'sql/base/browser/builder';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { attachListStyler } from 'vs/platform/theme/common/styler';
|
||||
@@ -100,7 +100,7 @@ export class ServerTreeView {
|
||||
if (!this._connectionManagementService.hasRegisteredServers()) {
|
||||
this._activeConnectionsFilterAction.enabled = false;
|
||||
this._buttonSection = $('div.button-section').appendTo(container);
|
||||
var connectButton = new Button(this._buttonSection);
|
||||
var connectButton = new Button(this._buttonSection.getHTMLElement());
|
||||
connectButton.label = localize('serverTree.addConnection', 'Add Connection');
|
||||
this._toDispose.push(attachButtonStyler(connectButton, this._themeService));
|
||||
this._toDispose.push(connectButton.onDidClick(() => {
|
||||
@@ -221,7 +221,7 @@ export class ServerTreeView {
|
||||
this._treeSelectionHandler.onTreeActionStateChange(false);
|
||||
});
|
||||
});
|
||||
}).done(null, errors.onUnexpectedError);
|
||||
}).then(null, errors.onUnexpectedError);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ export class ServerTreeView {
|
||||
} else {
|
||||
treeInput = filteredResults[0];
|
||||
}
|
||||
this._tree.setInput(treeInput).done(() => {
|
||||
this._tree.setInput(treeInput).then(() => {
|
||||
if (this.messages.isHidden()) {
|
||||
self._tree.getFocus();
|
||||
self._tree.expandAll(ConnectionProfileGroup.getSubgroups(treeInput));
|
||||
@@ -346,7 +346,7 @@ export class ServerTreeView {
|
||||
// Add all connections to tree root and set tree input
|
||||
let treeInput = new ConnectionProfileGroup('searchroot', undefined, 'searchroot', undefined, undefined);
|
||||
treeInput.addConnections(filteredResults);
|
||||
this._tree.setInput(treeInput).done(() => {
|
||||
this._tree.setInput(treeInput).then(() => {
|
||||
if (this.messages.isHidden()) {
|
||||
self._tree.getFocus();
|
||||
self._tree.expandAll(ConnectionProfileGroup.getSubgroups(treeInput));
|
||||
|
||||
@@ -16,7 +16,7 @@ export class TreeSelectionHandler {
|
||||
progressRunner: IProgressRunner;
|
||||
|
||||
private _clicks: number = 0;
|
||||
private _doubleClickTimeoutId: number = -1;
|
||||
private _doubleClickTimeoutTimer: NodeJS.Timer = undefined;
|
||||
|
||||
constructor( @IProgressService private _progressService: IProgressService) {
|
||||
|
||||
@@ -47,8 +47,8 @@ export class TreeSelectionHandler {
|
||||
}
|
||||
|
||||
// clear pending click timeouts to avoid sending multiple events on double-click
|
||||
if (this._doubleClickTimeoutId !== -1) {
|
||||
clearTimeout(this._doubleClickTimeoutId);
|
||||
if (this._doubleClickTimeoutTimer) {
|
||||
clearTimeout(this._doubleClickTimeoutTimer);
|
||||
}
|
||||
|
||||
let isKeyboard = event && event.payload && event.payload.origin === 'keyboard';
|
||||
@@ -56,14 +56,14 @@ export class TreeSelectionHandler {
|
||||
// grab the current selection for use later
|
||||
let selection = tree.getSelection();
|
||||
|
||||
this._doubleClickTimeoutId = setTimeout(() => {
|
||||
this._doubleClickTimeoutTimer = setTimeout(() => {
|
||||
// don't send tree update events while dragging
|
||||
if (!TreeUpdateUtils.isInDragAndDrop) {
|
||||
let isDoubleClick = this._clicks > 1;
|
||||
this.handleTreeItemSelected(connectionManagementService, objectExplorerService, isDoubleClick, isKeyboard, selection, tree, connectionCompleteCallback);
|
||||
}
|
||||
this._clicks = 0;
|
||||
this._doubleClickTimeoutId = -1;
|
||||
this._doubleClickTimeoutTimer = undefined;
|
||||
}, 300);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export class TreeUpdateUtils {
|
||||
treeInput = TreeUpdateUtils.getTreeInput(connectionManagementService, providers);
|
||||
}
|
||||
|
||||
tree.setInput(treeInput).done(() => {
|
||||
tree.setInput(treeInput).then(() => {
|
||||
// Make sure to expand all folders that where expanded in the previous session
|
||||
if (targetsToExpand) {
|
||||
tree.expandAll(targetsToExpand);
|
||||
|
||||
Reference in New Issue
Block a user