mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-31 01:25:38 -05:00
move code from parts to contrib (#8319)
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { OptionsDialog } from 'sql/workbench/browser/modal/optionsDialog';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import * as azdata from 'azdata';
|
||||
import { localize } from 'vs/nls';
|
||||
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
||||
|
||||
export class AdvancedPropertiesController {
|
||||
private _advancedDialog: OptionsDialog;
|
||||
private _options: { [name: string]: any };
|
||||
|
||||
constructor(private _onCloseAdvancedProperties: () => void,
|
||||
@IInstantiationService private _instantiationService: IInstantiationService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
private handleOnOk(): void {
|
||||
this._options = this._advancedDialog.optionValues;
|
||||
}
|
||||
|
||||
public showDialog(providerOptions: azdata.ConnectionOption[], options: { [name: string]: any }): void {
|
||||
this._options = options;
|
||||
let serviceOptions = providerOptions.map(option => AdvancedPropertiesController.connectionOptionToServiceOption(option));
|
||||
this.advancedDialog.open(serviceOptions, this._options);
|
||||
}
|
||||
|
||||
public get advancedDialog() {
|
||||
if (!this._advancedDialog) {
|
||||
this._advancedDialog = this._instantiationService.createInstance(
|
||||
OptionsDialog, localize('connectionAdvancedProperties', "Advanced Properties"), TelemetryKeys.ConnectionAdvancedProperties, { hasBackButton: true, cancelLabel: localize('advancedProperties.discard', "Discard") });
|
||||
this._advancedDialog.onCloseEvent(() => this._onCloseAdvancedProperties());
|
||||
this._advancedDialog.onOk(() => this.handleOnOk());
|
||||
this._advancedDialog.render();
|
||||
}
|
||||
return this._advancedDialog;
|
||||
}
|
||||
|
||||
public set advancedDialog(dialog: OptionsDialog) {
|
||||
this._advancedDialog = dialog;
|
||||
}
|
||||
|
||||
public static connectionOptionToServiceOption(connectionOption: azdata.ConnectionOption): azdata.ServiceOption {
|
||||
return {
|
||||
name: connectionOption.name,
|
||||
displayName: connectionOption.displayName,
|
||||
description: connectionOption.description,
|
||||
groupName: connectionOption.groupName,
|
||||
valueType: connectionOption.valueType,
|
||||
defaultValue: connectionOption.defaultValue,
|
||||
objectType: undefined,
|
||||
categoryValues: connectionOption.categoryValues,
|
||||
isRequired: connectionOption.isRequired,
|
||||
isArray: undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IConfigurationRegistry, Extensions as ConfigExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { AddServerGroupAction, AddServerAction } from 'sql/workbench/contrib/objectExplorer/browser/connectionTreeAction';
|
||||
import { ClearRecentConnectionsAction, GetCurrentConnectionStringAction } from 'sql/workbench/contrib/connection/browser/connectionActions';
|
||||
import * as azdata from 'azdata';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ConnectionStatusbarItem } from 'sql/workbench/contrib/connection/browser/connectionStatus';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { integrated, azureMFA } from 'sql/platform/connection/common/constants';
|
||||
import { AuthenticationType } from 'sql/workbench/services/connection/browser/connectionWidget';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
|
||||
workbenchRegistry.registerWorkbenchContribution(ConnectionStatusbarItem, LifecyclePhase.Restored);
|
||||
|
||||
// Connection Dashboard registration
|
||||
|
||||
const actionRegistry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
|
||||
|
||||
// Connection Actions
|
||||
actionRegistry.registerWorkbenchAction(
|
||||
new SyncActionDescriptor(
|
||||
ClearRecentConnectionsAction,
|
||||
ClearRecentConnectionsAction.ID,
|
||||
ClearRecentConnectionsAction.LABEL
|
||||
),
|
||||
ClearRecentConnectionsAction.LABEL
|
||||
);
|
||||
|
||||
actionRegistry.registerWorkbenchAction(
|
||||
new SyncActionDescriptor(
|
||||
AddServerGroupAction,
|
||||
AddServerGroupAction.ID,
|
||||
AddServerGroupAction.LABEL
|
||||
),
|
||||
AddServerGroupAction.LABEL
|
||||
);
|
||||
|
||||
actionRegistry.registerWorkbenchAction(
|
||||
new SyncActionDescriptor(
|
||||
AddServerAction,
|
||||
AddServerAction.ID,
|
||||
AddServerAction.LABEL
|
||||
),
|
||||
AddServerAction.LABEL
|
||||
);
|
||||
|
||||
CommandsRegistry.registerCommand('azdata.connect',
|
||||
function (accessor, args: {
|
||||
serverName: string,
|
||||
providerName: string,
|
||||
authenticationType?: AuthenticationType,
|
||||
userName?: string,
|
||||
password?: string,
|
||||
databaseName?: string
|
||||
}) {
|
||||
const capabilitiesServices = accessor.get(ICapabilitiesService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
if (args && args.serverName && args.providerName
|
||||
&& (args.authenticationType === integrated
|
||||
|| args.authenticationType === azureMFA
|
||||
|| (args.userName && args.password))) {
|
||||
const profile: azdata.IConnectionProfile = {
|
||||
serverName: args.serverName,
|
||||
databaseName: args.databaseName,
|
||||
authenticationType: args.authenticationType,
|
||||
providerName: args.providerName,
|
||||
connectionName: '',
|
||||
userName: args.userName,
|
||||
password: args.password,
|
||||
savePassword: true,
|
||||
groupFullName: undefined,
|
||||
saveProfile: true,
|
||||
id: undefined,
|
||||
groupId: undefined,
|
||||
options: {}
|
||||
};
|
||||
const connectionProfile = ConnectionProfile.fromIConnectionProfile(capabilitiesServices, profile);
|
||||
|
||||
connectionManagementService.connect(connectionProfile, undefined, {
|
||||
saveTheConnection: true,
|
||||
showDashboard: true,
|
||||
params: undefined,
|
||||
showConnectionDialogOnError: true,
|
||||
showFirewallRuleOnError: true
|
||||
});
|
||||
} else {
|
||||
connectionManagementService.showConnectionDialog();
|
||||
}
|
||||
});
|
||||
|
||||
actionRegistry.registerWorkbenchAction(
|
||||
new SyncActionDescriptor(
|
||||
GetCurrentConnectionStringAction,
|
||||
GetCurrentConnectionStringAction.ID,
|
||||
GetCurrentConnectionStringAction.LABEL
|
||||
),
|
||||
GetCurrentConnectionStringAction.LABEL
|
||||
);
|
||||
|
||||
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigExtensions.Configuration);
|
||||
configurationRegistry.registerConfiguration({
|
||||
'id': 'connection',
|
||||
'title': 'Connection',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'sql.maxRecentConnections': {
|
||||
'type': 'number',
|
||||
'default': 25,
|
||||
'description': localize('sql.maxRecentConnectionsDescription', "The maximum number of recently used connections to store in the connection list.")
|
||||
},
|
||||
'sql.defaultEngine': {
|
||||
'type': 'string',
|
||||
'description': localize('sql.defaultEngineDescription', "Default SQL Engine to use. This drives default language provider in .sql files and the default to use when creating a new connection. Valid option is currently MSSQL"),
|
||||
'default': 'MSSQL'
|
||||
},
|
||||
'connection.parseClipboardForConnectionString': {
|
||||
'type': 'boolean',
|
||||
'default': true,
|
||||
'description': localize('connection.parseClipboardForConnectionStringDescription', "Attempt to parse the contents of the clipboard when the connection dialog is opened or a paste is performed.")
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,179 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import nls = require('vs/nls');
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { INotificationService, INotificationActions } from 'vs/platform/notification/common/notification';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IDialogService, IConfirmation, IConfirmationResult } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
||||
import { EditDataInput } from 'sql/workbench/contrib/editData/browser/editDataInput';
|
||||
import { DashboardInput } from 'sql/workbench/contrib/dashboard/browser/dashboardInput';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { find } from 'vs/base/common/arrays';
|
||||
|
||||
/**
|
||||
* Workbench action to clear the recent connnections list
|
||||
*/
|
||||
export class ClearRecentConnectionsAction extends Action {
|
||||
|
||||
public static ID = 'clearRecentConnectionsAction';
|
||||
public static LABEL = nls.localize('ClearRecentlyUsedLabel', "Clear List");
|
||||
public static ICON = 'search-action clear-search-results';
|
||||
|
||||
private _onRecentConnectionsRemoved = new Emitter<void>();
|
||||
public onRecentConnectionsRemoved: Event<void> = this._onRecentConnectionsRemoved.event;
|
||||
|
||||
private _useConfirmationMessage = false;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@INotificationService private _notificationService: INotificationService,
|
||||
@IQuickInputService private _quickInputService: IQuickInputService,
|
||||
@IDialogService private _dialogService: IDialogService,
|
||||
) {
|
||||
super(id, label, ClearRecentConnectionsAction.ICON);
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
public set useConfirmationMessage(value: boolean) {
|
||||
this._useConfirmationMessage = value;
|
||||
}
|
||||
|
||||
public run(): Promise<void> {
|
||||
if (this._useConfirmationMessage) {
|
||||
return this.promptConfirmationMessage().then(result => {
|
||||
if (result.confirmed) {
|
||||
this._connectionManagementService.clearRecentConnectionsList();
|
||||
this._onRecentConnectionsRemoved.fire();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return this.promptQuickOpenService().then(result => {
|
||||
if (result) {
|
||||
this._connectionManagementService.clearRecentConnectionsList();
|
||||
|
||||
const actions: INotificationActions = { primary: [] };
|
||||
this._notificationService.notify({
|
||||
severity: Severity.Info,
|
||||
message: nls.localize('ClearedRecentConnections', "Recent connections list cleared"),
|
||||
actions
|
||||
});
|
||||
this._onRecentConnectionsRemoved.fire();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private promptQuickOpenService(): Promise<boolean> {
|
||||
const self = this;
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
let choices: { key, value }[] = [
|
||||
{ key: nls.localize('connectionAction.yes', "Yes"), value: true },
|
||||
{ key: nls.localize('connectionAction.no', "No"), value: false }
|
||||
];
|
||||
|
||||
self._quickInputService.pick(choices.map(x => x.key), { placeHolder: nls.localize('ClearRecentlyUsedLabel', "Clear List"), ignoreFocusLost: true }).then((choice) => {
|
||||
let confirm = find(choices, x => x.key === choice);
|
||||
resolve(confirm && confirm.value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private promptConfirmationMessage(): Promise<IConfirmationResult> {
|
||||
let confirm: IConfirmation = {
|
||||
message: nls.localize('clearRecentConnectionMessage', "Are you sure you want to delete all the connections from the list?"),
|
||||
primaryButton: nls.localize('connectionDialog.yes', "Yes"),
|
||||
secondaryButton: nls.localize('connectionDialog.no', "No"),
|
||||
type: 'question'
|
||||
};
|
||||
|
||||
return new Promise<IConfirmationResult>((resolve, reject) => {
|
||||
this._dialogService.confirm(confirm).then((confirmed) => {
|
||||
resolve(confirmed);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to delete one recently used connection from the MRU
|
||||
*/
|
||||
export class ClearSingleRecentConnectionAction extends Action {
|
||||
|
||||
public static ID = 'clearSingleRecentConnectionAction';
|
||||
public static LABEL = nls.localize('delete', "Delete");
|
||||
private _onRecentConnectionRemoved = new Emitter<void>();
|
||||
public onRecentConnectionRemoved: Event<void> = this._onRecentConnectionRemoved.event;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
private _connectionProfile: IConnectionProfile,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
) {
|
||||
super(id, label);
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
public run(): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
resolve(this._connectionManagementService.clearRecentConnection(this._connectionProfile));
|
||||
this._onRecentConnectionRemoved.fire();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to retrieve the current connection string
|
||||
*/
|
||||
export class GetCurrentConnectionStringAction extends Action {
|
||||
|
||||
public static ID = 'getCurrentConnectionStringAction';
|
||||
public static LABEL = nls.localize('connectionAction.GetCurrentConnectionString', "Get Current Connection String");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@IEditorService private _editorService: IEditorService,
|
||||
@INotificationService private readonly _notificationService: INotificationService,
|
||||
@IClipboardService private _clipboardService: IClipboardService,
|
||||
) {
|
||||
super(GetCurrentConnectionStringAction.ID, GetCurrentConnectionStringAction.LABEL);
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
public run(): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
let activeInput = this._editorService.activeEditor;
|
||||
if (activeInput && (activeInput instanceof QueryInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput)
|
||||
&& this._connectionManagementService.isConnected(activeInput.uri)) {
|
||||
let includePassword = false;
|
||||
let connectionProfile = this._connectionManagementService.getConnectionProfile(activeInput.uri);
|
||||
this._connectionManagementService.getConnectionString(connectionProfile.id, includePassword).then(result => {
|
||||
|
||||
//Copy to clipboard
|
||||
this._clipboardService.writeText(result);
|
||||
|
||||
let message = result
|
||||
? result
|
||||
: nls.localize('connectionAction.connectionString', "Connection string not available");
|
||||
this._notificationService.info(message);
|
||||
});
|
||||
} else {
|
||||
let message = nls.localize('connectionAction.noConnection', "No active connection available");
|
||||
this._notificationService.info(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
|
||||
import * as TaskUtilities from 'sql/workbench/browser/taskUtilities';
|
||||
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/workbench/services/statusbar/common/statusbar';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
// Connection status bar showing the current global connection
|
||||
export class ConnectionStatusbarItem extends Disposable implements IWorkbenchContribution {
|
||||
|
||||
private static readonly ID = 'status.connection.status';
|
||||
|
||||
private statusItem: IStatusbarEntryAccessor;
|
||||
|
||||
constructor(
|
||||
@IStatusbarService private readonly statusbarService: IStatusbarService,
|
||||
@IConnectionManagementService private readonly connectionManagementService: IConnectionManagementService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IObjectExplorerService private readonly objectExplorerService: IObjectExplorerService,
|
||||
) {
|
||||
super();
|
||||
this.statusItem = this._register(
|
||||
this.statusbarService.addEntry({
|
||||
text: '',
|
||||
},
|
||||
ConnectionStatusbarItem.ID,
|
||||
localize('status.connection.status', "Connection Status"),
|
||||
StatusbarAlignment.RIGHT, 100)
|
||||
);
|
||||
|
||||
this.hide();
|
||||
|
||||
this._register(this.connectionManagementService.onConnect(() => this._updateStatus()));
|
||||
this._register(this.connectionManagementService.onConnectionChanged(() => this._updateStatus()));
|
||||
this._register(this.connectionManagementService.onDisconnect(() => this._updateStatus()));
|
||||
this._register(this.editorService.onDidActiveEditorChange(() => this._updateStatus()));
|
||||
this._register(this.objectExplorerService.onSelectionOrFocusChange(() => this._updateStatus()));
|
||||
}
|
||||
|
||||
private hide() {
|
||||
this.statusbarService.updateEntryVisibility(ConnectionStatusbarItem.ID, false);
|
||||
}
|
||||
|
||||
private show() {
|
||||
this.statusbarService.updateEntryVisibility(ConnectionStatusbarItem.ID, true);
|
||||
}
|
||||
|
||||
// Update the connection status shown in the bar
|
||||
private _updateStatus(): void {
|
||||
let activeConnection = TaskUtilities.getCurrentGlobalConnection(this.objectExplorerService, this.connectionManagementService, this.editorService);
|
||||
if (activeConnection) {
|
||||
this._setConnectionText(activeConnection);
|
||||
this.show();
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Set connection info to connection status bar
|
||||
private _setConnectionText(connectionProfile: IConnectionProfile): void {
|
||||
let text: string = connectionProfile.serverName;
|
||||
if (text) {
|
||||
if (connectionProfile.databaseName && connectionProfile.databaseName !== '') {
|
||||
text = text + ' : ' + connectionProfile.databaseName;
|
||||
} else {
|
||||
text = text + ' : ' + '<default>';
|
||||
}
|
||||
}
|
||||
|
||||
let tooltip: string =
|
||||
'Server: ' + connectionProfile.serverName + '\r\n' +
|
||||
'Database: ' + (connectionProfile.databaseName ? connectionProfile.databaseName : '<default>') + '\r\n';
|
||||
|
||||
if (connectionProfile.userName && connectionProfile.userName !== '') {
|
||||
tooltip = tooltip + 'Login: ' + connectionProfile.userName + '\r\n';
|
||||
}
|
||||
|
||||
this.statusItem.update({
|
||||
text, tooltip
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#E8E8E8" d="M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z"/></svg>
|
||||
|
After Width: | Height: | Size: 139 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#212121;}.cls-2{fill:#3bb44a;}</style></defs><title>connected_active_server_16x16</title><path class="cls-1" d="M1.29.07V16h9.59a3.31,3.31,0,0,1-1.94-1H2.29V11h6a3.31,3.31,0,0,1,.54-.8A1.81,1.81,0,0,1,9,10H2.29v-9h8.53v8a3.68,3.68,0,0,1,.58,0l.39,0h0v-9Z"/><path class="cls-1" d="M3.3,1.8V4.25H5.75V1.8Zm2,2H3.8V2.3H5.25Z"/><circle class="cls-2" cx="11.24" cy="12.52" r="3.47"/></svg>
|
||||
|
After Width: | Height: | Size: 502 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#3bb44a;}</style></defs><title>connected_active_server_inverse_16x16</title><path class="cls-1" d="M1.29.07V16h9.59a3.31,3.31,0,0,1-1.94-1H2.29V11h6a3.31,3.31,0,0,1,.54-.8A1.81,1.81,0,0,1,9,10H2.29v-9h8.53v8a3.68,3.68,0,0,1,.58,0l.39,0h0v-9Z"/><path class="cls-1" d="M3.3,1.8V4.25H5.75V1.8Zm2,2H3.8V2.3H5.25Z"/><circle class="cls-2" cx="11.24" cy="12.52" r="3.47"/></svg>
|
||||
|
After Width: | Height: | Size: 507 B |
@@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* --- Registered servers tree viewlet --- */
|
||||
.server-explorer-viewlet .monaco-tree .monaco-tree-row .content .server-group {
|
||||
cursor: default;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Bold font style does not go well with CJK fonts */
|
||||
.server-explorer-viewlet:lang(zh-Hans) .monaco-tree .monaco-tree-row .server-group,
|
||||
.server-explorer-viewlet:lang(zh-Hant) .monaco-tree .monaco-tree-row .server-group,
|
||||
.server-explorer-viewlet:lang(ja) .monaco-tree .monaco-tree-row .server-group,
|
||||
.server-explorer-viewlet:lang(ko) .monaco-tree .monaco-tree-row .server-group { font-weight: normal; }
|
||||
|
||||
/* High Contrast Theming */
|
||||
.hc-black .monaco-workbench .server-explorer-viewlet .server-group {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar .monaco-action-bar .action-label.serverTree {
|
||||
background-size: 22px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% !important;
|
||||
}
|
||||
|
||||
.server-explorer-viewlet .object-explorer-view {
|
||||
height: calc(100% - 36px);
|
||||
}
|
||||
|
||||
.server-explorer-viewlet .server-group {
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.server-explorer-viewlet .monaco-action-bar .action-label {
|
||||
margin-right: 0.3em;
|
||||
margin-left: 0.3em;
|
||||
line-height: 15px;
|
||||
width: 10px !important;
|
||||
height: 10px !important;
|
||||
}
|
||||
|
||||
/* Add space beneath the button */
|
||||
.new-connection .monaco-text-button {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
/* display action buttons on hover */
|
||||
.server-explorer-viewlet .monaco-tree .monaco-tree-row > .content {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* Added to display the tree in connection dialog */
|
||||
.server-explorer-viewlet {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.explorer-servers {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* search box */
|
||||
.server-explorer-viewlet .search-box {
|
||||
padding-bottom: 4px;
|
||||
margin: auto;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
/* OE and connection element group */
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile,
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .object-element-group {
|
||||
padding: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* OE and connection label */
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .label,
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .object-element-group > .label {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* OE and connection icon */
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon,
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .object-element-group > .icon {
|
||||
float: left;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon.server-page.connected {
|
||||
background: url('connected_active_server.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon.server-page.connected,
|
||||
.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon.server-page.connected{
|
||||
background: url('connected_active_server_inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon.server-page.disconnected {
|
||||
background: url('disconnected_server.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon.server-page.disconnected,
|
||||
.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon.server-page.disconnected{
|
||||
background: url('disconnected_server_inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
/* loading for OE node */
|
||||
.server-explorer-viewlet .monaco-tree .monaco-tree-rows > .monaco-tree-row > .codicon.in-progress .connection-tile:before,
|
||||
.server-explorer-viewlet .monaco-tree .monaco-tree-rows > .monaco-tree-row > .codicon.in-progress .object-element-group:before {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 36px;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: -35px;
|
||||
}
|
||||
|
||||
.monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.expanded.has-children > .content.server-group:before {
|
||||
background: url('expanded-dark.svg') 50% 50% no-repeat;
|
||||
}
|
||||
|
||||
.monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.has-children > .content.server-group:before {
|
||||
background: url('collapsed-dark.svg') 50% 50% no-repeat;
|
||||
}
|
||||
|
||||
/* Add connection button */
|
||||
.server-explorer-viewlet .button-section {
|
||||
padding: 20px;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#212121;}.cls-2{fill:#d02e00;}</style></defs><title>disconnected_server_16x16</title><path class="cls-1" d="M1.42.06V16H11a3.31,3.31,0,0,1-1.94-1H2.42V11h6a3.31,3.31,0,0,1,.54-.8,1.81,1.81,0,0,1,.19-.2H2.42v-9H11v8a3.68,3.68,0,0,1,.58,0l.39,0h0v-9Z"/><path class="cls-1" d="M3.43,1.79V4.24H5.89V1.79Zm2,2H3.93V2.29H5.39Z"/><path class="cls-2" d="M11.08,16a2.22,2.22,0,0,0,.45,0,2.59,2.59,0,0,0,.4,0Z"/><path class="cls-2" d="M12,9.08h0l-.39,0a3.68,3.68,0,0,0-.58,0A3.41,3.41,0,0,0,9.14,10a1.81,1.81,0,0,0-.19.2,3.46,3.46,0,0,0-.89,2.3,3.4,3.4,0,0,0,.85,2.26,1.29,1.29,0,0,0,.16.17A3.31,3.31,0,0,0,11,16H12a3.46,3.46,0,0,0,2.17-1.13,3.41,3.41,0,0,0,.88-2.3A3.47,3.47,0,0,0,12,9.08Zm0,5.72a1.72,1.72,0,0,1-.39,0,2.23,2.23,0,0,1-.77-.14,2.29,2.29,0,0,1-1.54-2.17A2.22,2.22,0,0,1,9.79,11a2.29,2.29,0,0,1,1-.67,2.23,2.23,0,0,1,.77-.14,1.72,1.72,0,0,1,.39,0h0a2.3,2.3,0,0,1,0,4.53Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1002 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#d02e00;}</style></defs><title>disconnected_server_inverse_16x16</title><path class="cls-1" d="M1.42.06V16H11a3.31,3.31,0,0,1-1.94-1H2.42V11h6a3.31,3.31,0,0,1,.54-.8,1.81,1.81,0,0,1,.19-.2H2.42v-9H11v8a3.68,3.68,0,0,1,.58,0l.39,0h0v-9Z"/><path class="cls-1" d="M3.43,1.79V4.24H5.89V1.79Zm2,2H3.93V2.29H5.39Z"/><path class="cls-2" d="M11.08,16a2.22,2.22,0,0,0,.45,0,2.59,2.59,0,0,0,.4,0Z"/><path class="cls-2" d="M12,9.08h0l-.39,0a3.68,3.68,0,0,0-.58,0A3.41,3.41,0,0,0,9.14,10a1.81,1.81,0,0,0-.19.2,3.46,3.46,0,0,0-.89,2.3,3.4,3.4,0,0,0,.85,2.26,1.29,1.29,0,0,0,.16.17A3.31,3.31,0,0,0,11,16H12a3.46,3.46,0,0,0,2.17-1.13,3.41,3.41,0,0,0,.88-2.3A3.47,3.47,0,0,0,12,9.08Zm0,5.72a1.72,1.72,0,0,1-.39,0,2.23,2.23,0,0,1-.77-.14,2.29,2.29,0,0,1-1.54-2.17A2.22,2.22,0,0,1,9.79,11a2.29,2.29,0,0,1,1-.67,2.23,2.23,0,0,1,.77-.14,1.72,1.72,0,0,1,.39,0h0a2.3,2.3,0,0,1,0,4.53Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1007 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#E8E8E8" d="M11 10H5.344L11 4.414V10z"/></svg>
|
||||
|
After Width: | Height: | Size: 118 B |
@@ -0,0 +1,136 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { DefaultController, ICancelableEvent } from 'vs/base/parts/tree/browser/treeDefaults';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { ClearSingleRecentConnectionAction } from 'sql/workbench/contrib/connection/browser/connectionActions';
|
||||
import { ContributableActionProvider } from 'vs/workbench/browser/actions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import mouse = require('vs/base/browser/mouseEvent');
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
|
||||
export class RecentConnectionActionsProvider extends ContributableActionProvider {
|
||||
private _onRecentConnectionRemoved = new Emitter<void>();
|
||||
public onRecentConnectionRemoved: Event<void> = this._onRecentConnectionRemoved.event;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private _instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
private getRecentConnectionActions(tree: ITree, element: any): IAction[] {
|
||||
let actions: IAction[] = [];
|
||||
let clearSingleConnectionAction = this._instantiationService.createInstance(ClearSingleRecentConnectionAction, ClearSingleRecentConnectionAction.ID,
|
||||
ClearSingleRecentConnectionAction.LABEL, <IConnectionProfile>element);
|
||||
clearSingleConnectionAction.onRecentConnectionRemoved(() => this._onRecentConnectionRemoved.fire());
|
||||
actions.push(clearSingleConnectionAction);
|
||||
return actions;
|
||||
}
|
||||
|
||||
public hasActions(tree: ITree, element: any): boolean {
|
||||
return element instanceof ConnectionProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return actions given an element in the tree
|
||||
*/
|
||||
public getActions(tree: ITree, element: any): IAction[] {
|
||||
if (element instanceof ConnectionProfile) {
|
||||
return this.getRecentConnectionActions(tree, element);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export class RecentConnectionsActionsContext {
|
||||
public connectionProfile: ConnectionProfile;
|
||||
public container: HTMLElement;
|
||||
public tree: ITree;
|
||||
}
|
||||
|
||||
export class RecentConnectionTreeController extends DefaultController {
|
||||
|
||||
private _onRecentConnectionRemoved = new Emitter<void>();
|
||||
public onRecentConnectionRemoved: Event<void> = this._onRecentConnectionRemoved.event;
|
||||
|
||||
constructor(
|
||||
private clickcb: (element: any, eventish: ICancelableEvent, origin: string) => void,
|
||||
private actionProvider: RecentConnectionActionsProvider,
|
||||
private _connectionManagementService: IConnectionManagementService,
|
||||
@IContextMenuService private _contextMenuService: IContextMenuService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected onLeftClick(tree: ITree, element: any, eventish: ICancelableEvent, origin: string = 'mouse'): boolean {
|
||||
this.clickcb(element, eventish, origin);
|
||||
return super.onLeftClick(tree, element, eventish, origin);
|
||||
}
|
||||
|
||||
protected onEnter(tree: ITree, event: IKeyboardEvent): boolean {
|
||||
super.onEnter(tree, event);
|
||||
this.clickcb(tree.getSelection()[0], event, 'keyboard');
|
||||
return true;
|
||||
}
|
||||
|
||||
protected onRightClick(tree: ITree, element: any, eventish: ICancelableEvent, origin: string = 'mouse'): boolean {
|
||||
this.clickcb(element, eventish, origin);
|
||||
this.showContextMenu(tree, element, eventish);
|
||||
return true;
|
||||
}
|
||||
|
||||
public onMouseDown(tree: ITree, element: any, event: mouse.IMouseEvent, origin: string = 'mouse'): boolean {
|
||||
if (event.leftButton || event.middleButton) {
|
||||
return this.onLeftClick(tree, element, event, origin);
|
||||
} else {
|
||||
return this.onRightClick(tree, element, event);
|
||||
}
|
||||
}
|
||||
|
||||
public onKeyDown(tree: ITree, event: IKeyboardEvent): boolean {
|
||||
if (event.keyCode === 20) {
|
||||
let element = tree.getFocus();
|
||||
if (element instanceof ConnectionProfile) {
|
||||
this._connectionManagementService.clearRecentConnection(element);
|
||||
this._onRecentConnectionRemoved.fire();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onKeyDown(tree, event);
|
||||
}
|
||||
|
||||
public showContextMenu(tree: ITree, element: any, event: any): boolean {
|
||||
let actionContext: any;
|
||||
|
||||
if (element instanceof ConnectionProfile) {
|
||||
actionContext = new RecentConnectionsActionsContext();
|
||||
actionContext.container = event.target;
|
||||
actionContext.connectionProfile = <ConnectionProfile>element;
|
||||
actionContext.tree = tree;
|
||||
} else {
|
||||
actionContext = element;
|
||||
}
|
||||
|
||||
let anchor = { x: event.x + 1, y: event.y };
|
||||
this._contextMenuService.showContextMenu({
|
||||
getAnchor: () => anchor,
|
||||
getActions: () => this.actionProvider.getActions(tree, element),
|
||||
onHide: (wasCancelled?: boolean) => {
|
||||
if (wasCancelled) {
|
||||
tree.domFocus();
|
||||
}
|
||||
},
|
||||
getActionsContext: () => (actionContext)
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { DefaultController, ICancelableEvent } from 'vs/base/parts/tree/browser/treeDefaults';
|
||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
|
||||
export class SavedConnectionTreeController extends DefaultController {
|
||||
constructor(private clickcb: (element: any, eventish: ICancelableEvent, origin: string) => void) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected onLeftClick(tree: ITree, element: any, eventish: ICancelableEvent, origin: string = 'mouse'): boolean {
|
||||
this.clickcb(element, eventish, origin);
|
||||
return super.onLeftClick(tree, element, eventish, origin);
|
||||
}
|
||||
|
||||
protected onEnter(tree: ITree, event: IKeyboardEvent): boolean {
|
||||
super.onEnter(tree, event);
|
||||
|
||||
// grab the current selection for use later
|
||||
let selection = tree.getSelection();
|
||||
|
||||
this.clickcb(selection[0], event, 'keyboard');
|
||||
tree.toggleExpansion(selection[0]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user