From 52bbb60defe8f6857f2a7b88f0f05d2bfcdde5ab Mon Sep 17 00:00:00 2001 From: Alex Ma Date: Wed, 11 Oct 2023 14:27:25 -0700 Subject: [PATCH] Add tooltips with advanced options on hover for editor tabs (#24486) * Added WIP table designer input change * added test details to tableDesigner * added connection name to details * wip restoration of nonDefaultOptions * added Verbosity todo for getTitle * added updated info * added fix for mainController * fixed assignment * added update to description * restore title parts to old names * added clarifying message * added title to dashboard and profilerinput * added advanced titles for edit data and query editor input * added changes based on feedback * added additional description * Added some changes to tableDesigner input * fixed comments * removed erroneous import * added updated titles and tooltips * added small corrections * added profiler XEL title feature * added session name to profiler input tooltip * added small tooltip rework * remove unavailable session name * added update to config.json --- extensions/mssql/config.json | 2 +- .../mssql/src/tableDesigner/tableDesigner.ts | 13 ++++-- src/sql/azdata.proposed.d.ts | 15 +++++- .../connection/common/connectionManagement.ts | 7 +++ .../common/testConnectionManagementService.ts | 4 ++ .../browser/mainThreadConnectionManagement.ts | 5 ++ .../api/common/extHostConnectionManagement.ts | 4 ++ .../api/common/sqlExtHost.api.impl.ts | 3 ++ .../api/common/sqlExtHost.protocol.ts | 1 + .../browser/editData/editDataInput.ts | 42 ++++++++++++++++- .../browser/editor/profiler/dashboardInput.ts | 22 +++++++++ .../browser/editor/profiler/profilerInput.ts | 44 +++++++++++++++++- .../tableDesigner/tableDesignerInput.ts | 20 ++++++-- .../common/editor/query/queryEditorInput.ts | 46 ++++++++++++++++--- .../browser/connectionManagementService.ts | 6 +++ 15 files changed, 214 insertions(+), 20 deletions(-) diff --git a/extensions/mssql/config.json b/extensions/mssql/config.json index 781c730e72..a012f15637 100644 --- a/extensions/mssql/config.json +++ b/extensions/mssql/config.json @@ -1,6 +1,6 @@ { "downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/{#version#}/microsoft.sqltools.servicelayer-{#fileName#}", - "version": "4.10.0.15", + "version": "4.10.0.16", "downloadFileNames": { "Windows_86": "win-x86-net7.0.zip", "Windows_64": "win-x64-net7.0.zip", diff --git a/extensions/mssql/src/tableDesigner/tableDesigner.ts b/extensions/mssql/src/tableDesigner/tableDesigner.ts index b955651ac2..88bc4cdc05 100644 --- a/extensions/mssql/src/tableDesigner/tableDesigner.ts +++ b/extensions/mssql/src/tableDesigner/tableDesigner.ts @@ -28,16 +28,18 @@ export function registerTableDesignerCommands(appContext: AppContext) { } const tableIcon = context.nodeInfo!.nodeSubType as azdata.designers.TableIcon; const telemetryInfo = await getTelemetryInfo(context, tableIcon); + let nonDefaultOptions = await azdata.connection.getNonDefaultOptions(context.connectionProfile); await azdata.designers.openTableDesigner(sqlProviderName, { title: NewTableText, - tooltip: `${context.connectionProfile!.serverName} - ${context.connectionProfile!.databaseName} - ${NewTableText}`, + tooltip: context.connectionProfile!.connectionName ? `${context.connectionProfile!.connectionName} - ${NewTableText}` : `${context.connectionProfile!.serverName} - ${context.connectionProfile!.databaseName} - ${NewTableText}`, server: context.connectionProfile!.serverName, database: context.connectionProfile!.databaseName, isNewTable: true, id: generateUuid(), connectionString: connectionString, accessToken: context.connectionProfile!.options.azureAccountToken as string, - tableIcon: tableIcon + tableIcon: tableIcon, + additionalInfo: `${context.connectionProfile!.serverName + ' - ' + context.connectionProfile!.databaseName}${nonDefaultOptions}` }, telemetryInfo, context); } catch (error) { console.error(error); @@ -48,6 +50,7 @@ export function registerTableDesignerCommands(appContext: AppContext) { appContext.extensionContext.subscriptions.push(vscode.commands.registerCommand('mssql.designTable', async (context: azdata.ObjectExplorerContext) => { try { void showPreloadDbModelSettingPrompt(appContext); + const connName = context.connectionProfile!.connectionName; const server = context.connectionProfile!.serverName; const database = context.connectionProfile!.databaseName; const schema = context.nodeInfo!.metadata!.schema; @@ -58,9 +61,10 @@ export function registerTableDesignerCommands(appContext: AppContext) { } const tableIcon = context.nodeInfo!.nodeSubType as azdata.designers.TableIcon; const telemetryInfo = await getTelemetryInfo(context, tableIcon); + let nonDefaultOptions = await azdata.connection.getNonDefaultOptions(context.connectionProfile); await azdata.designers.openTableDesigner(sqlProviderName, { title: `${schema}.${name}`, - tooltip: `${server} - ${database} - ${schema}.${name}`, + tooltip: connName ? `${connName} - ${schema}.${name}` : `${server} - ${database} - ${schema}.${name}`, server: server, database: database, isNewTable: false, @@ -69,7 +73,8 @@ export function registerTableDesignerCommands(appContext: AppContext) { id: `${sqlProviderName}|${server}|${database}|${schema}|${name}`, connectionString: connectionString, accessToken: context.connectionProfile!.options.azureAccountToken as string, - tableIcon: tableIcon + tableIcon: tableIcon, + additionalInfo: `${server + ' - ' + database}${nonDefaultOptions}` }, telemetryInfo, context); } catch (error) { console.error(error); diff --git a/src/sql/azdata.proposed.d.ts b/src/sql/azdata.proposed.d.ts index 74b748ed64..f66493b4e7 100644 --- a/src/sql/azdata.proposed.d.ts +++ b/src/sql/azdata.proposed.d.ts @@ -508,6 +508,13 @@ declare module 'azdata' { * @returns The new password that is returned from the operation or undefined if unsuccessful. */ export function openChangePasswordDialog(profile: IConnectionProfile): Thenable; + + /** + * Gets the non default options of the connection profile. + * @param profile The connection profile to get the options for. + * @returns The string key containing the non default options (if any) for the profile. + */ + export function getNonDefaultOptions(profile: IConnectionProfile): Thenable; } /* @@ -968,11 +975,11 @@ declare module 'azdata' { */ export interface TableInfo { /** - * Used as the table designer editor's tab header text. + * Used as the table designer editor's tab header text (as well as the base value of the tooltip). */ title: string; /** - * Used as the table designer editor's tab header hover text. + * Used as the table designer editor's tab header name text. */ tooltip: string; /** @@ -992,6 +999,10 @@ declare module 'azdata' { * table icon. */ tableIcon?: TableIcon; + /** + * Additional information for tooltip on hover displaying the full information of the connection. + */ + additionalInfo?: string; } /** diff --git a/src/sql/platform/connection/common/connectionManagement.ts b/src/sql/platform/connection/common/connectionManagement.ts index 0061ba5ee6..2937162595 100644 --- a/src/sql/platform/connection/common/connectionManagement.ts +++ b/src/sql/platform/connection/common/connectionManagement.ts @@ -381,6 +381,13 @@ export interface IConnectionManagementService { * @returns the new valid password that is entered, or undefined if cancelled or errored. */ openChangePasswordDialog(profile: IConnectionProfile): Promise; + + /** + * Launches the password change dialog. + * @param profile The connection profile to retrieve the non default connection options from + * @returns a string key containing the options that aren't default values. + */ + getNonDefaultOptions(profile: IConnectionProfile): string; } export enum RunQueryOnConnectionMode { diff --git a/src/sql/platform/connection/test/common/testConnectionManagementService.ts b/src/sql/platform/connection/test/common/testConnectionManagementService.ts index b91e7850bc..81f633b01e 100644 --- a/src/sql/platform/connection/test/common/testConnectionManagementService.ts +++ b/src/sql/platform/connection/test/common/testConnectionManagementService.ts @@ -355,6 +355,10 @@ export class TestConnectionManagementService implements IConnectionManagementSer return undefined; } + getNonDefaultOptions(profile: IConnectionProfile): string { + return undefined!; + } + openCustomErrorDialog(options: azdata.window.IErrorDialogOptions): Promise { return undefined; } diff --git a/src/sql/workbench/api/browser/mainThreadConnectionManagement.ts b/src/sql/workbench/api/browser/mainThreadConnectionManagement.ts index 2e0e371439..f3f78a0b0c 100644 --- a/src/sql/workbench/api/browser/mainThreadConnectionManagement.ts +++ b/src/sql/workbench/api/browser/mainThreadConnectionManagement.ts @@ -185,6 +185,11 @@ export class MainThreadConnectionManagement extends Disposable implements MainTh return this._connectionManagementService.openChangePasswordDialog(convertedProfile); } + public $getNonDefaultOptions(profile: azdata.IConnectionProfile): Thenable { + let convertedProfile = new ConnectionProfile(this._capabilitiesService, profile); + return Promise.resolve(this._connectionManagementService.getNonDefaultOptions(convertedProfile)); + } + public async $listDatabases(connectionId: string): Promise { let connectionUri = await this.$getUriForConnection(connectionId); let result = await this._connectionManagementService.listDatabases(connectionUri); diff --git a/src/sql/workbench/api/common/extHostConnectionManagement.ts b/src/sql/workbench/api/common/extHostConnectionManagement.ts index 56f27dbc8f..f704f12ecc 100644 --- a/src/sql/workbench/api/common/extHostConnectionManagement.ts +++ b/src/sql/workbench/api/common/extHostConnectionManagement.ts @@ -78,6 +78,10 @@ export class ExtHostConnectionManagement extends ExtHostConnectionManagementShap return this._proxy.$openChangePasswordDialog(profile); } + $getNonDefaultOptions(profile: azdata.IConnectionProfile): Thenable { + return this._proxy.$getNonDefaultOptions(profile); + } + public $listDatabases(connectionId: string): Thenable { return this._proxy.$listDatabases(connectionId); } diff --git a/src/sql/workbench/api/common/sqlExtHost.api.impl.ts b/src/sql/workbench/api/common/sqlExtHost.api.impl.ts index 3dacbb650d..1394137834 100644 --- a/src/sql/workbench/api/common/sqlExtHost.api.impl.ts +++ b/src/sql/workbench/api/common/sqlExtHost.api.impl.ts @@ -143,6 +143,9 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp openChangePasswordDialog(profile: azdata.IConnectionProfile): Thenable { return extHostConnectionManagement.$openChangePasswordDialog(profile); }, + getNonDefaultOptions(profile: azdata.IConnectionProfile): Thenable { + return extHostConnectionManagement.$getNonDefaultOptions(profile); + }, listDatabases(connectionId: string): Thenable { return extHostConnectionManagement.$listDatabases(connectionId); }, diff --git a/src/sql/workbench/api/common/sqlExtHost.protocol.ts b/src/sql/workbench/api/common/sqlExtHost.protocol.ts index 38cf4f15c5..5ad27a6969 100644 --- a/src/sql/workbench/api/common/sqlExtHost.protocol.ts +++ b/src/sql/workbench/api/common/sqlExtHost.protocol.ts @@ -734,6 +734,7 @@ export interface MainThreadConnectionManagementShape extends IDisposable { $getServerInfo(connectedId: string): Thenable; $openConnectionDialog(providers: string[], initialConnectionProfile?: azdata.IConnectionProfile, connectionCompletionOptions?: azdata.IConnectionCompletionOptions): Thenable; $openChangePasswordDialog(profile: azdata.IConnectionProfile): Thenable; + $getNonDefaultOptions(profile: azdata.IConnectionProfile): Thenable; $listDatabases(connectionId: string): Thenable; $getConnectionString(connectionId: string, includePassword: boolean): Thenable; $getUriForConnection(connectionId: string): Thenable; diff --git a/src/sql/workbench/browser/editData/editDataInput.ts b/src/sql/workbench/browser/editData/editDataInput.ts index 29e2843db7..26377ae659 100644 --- a/src/sql/workbench/browser/editData/editDataInput.ts +++ b/src/sql/workbench/browser/editData/editDataInput.ts @@ -18,6 +18,7 @@ import { UntitledTextEditorModel } from 'vs/workbench/services/untitled/common/u import { EncodingMode } from 'vs/workbench/services/textfile/common/textfiles'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IEditorModel, IEditorOptions } from 'vs/platform/editor/common/editor'; +import { Verbosity } from 'vs/workbench/common/editor'; /** * Input for the EditDataEditor. @@ -223,7 +224,46 @@ export class EditDataInput extends EditorInput implements IConnectableInput { } public getEncoding(): string | undefined { return this._sql.getEncoding(); } - public override getName(): string { return this._sql.getName(); } + public override getName(): string { + let profile = this._connectionManagementService.getConnectionProfile(this.uri); + let title = this._sql.getName(); + if (profile) { + if (profile.connectionName) { + title += ` - ${profile.connectionName}`; + } + else { + title += ` - ${profile.serverName}`; + if (profile.databaseName) { + title += `.${profile.databaseName}`; + } + title += ` (${profile.userName || profile.authenticationType})`; + } + } + return title; + } + public override getTitle(verbosity?: Verbosity): string { + let fullTitle = this._sql.getName(); + let profile = this._connectionManagementService.getConnectionProfile(this.uri); + if (profile) { + fullTitle += ` - ${profile.serverName}`; + if (profile.databaseName) { + fullTitle += `.${profile.databaseName}`; + } + fullTitle += ` (${profile.userName || profile.authenticationType})`; + let nonDefaultOptions = this._connectionManagementService.getNonDefaultOptions(profile); + fullTitle += nonDefaultOptions; + } + switch (verbosity) { + case Verbosity.LONG: + // Used by tabsTitleControl as the tooltip hover. + return fullTitle; + default: + case Verbosity.SHORT: + case Verbosity.MEDIUM: + // Used for header title by tabsTitleControl. + return this.getName(); + } + } public get hasAssociatedFilePath(): boolean { return this._sql.model.hasAssociatedFilePath; } public setEncoding(encoding: string, mode: EncodingMode /* ignored, we only have Encode */): void { diff --git a/src/sql/workbench/browser/editor/profiler/dashboardInput.ts b/src/sql/workbench/browser/editor/profiler/dashboardInput.ts index 06a001c46f..6a0334a69e 100644 --- a/src/sql/workbench/browser/editor/profiler/dashboardInput.ts +++ b/src/sql/workbench/browser/editor/profiler/dashboardInput.ts @@ -12,6 +12,7 @@ import { IConnectionManagementService } from 'sql/platform/connection/common/con import { mssqlProviderName } from 'sql/platform/connection/common/constants'; import { IModelService } from 'vs/editor/common/services/model'; import { ILanguageService } from 'vs/editor/common/languages/language'; +import { Verbosity } from 'vs/workbench/common/editor'; export class DashboardInput extends EditorInput { @@ -93,6 +94,27 @@ export class DashboardInput extends EditorInput { return name; } + public override getTitle(verbosity?: Verbosity): string { + let baseName = this.connectionProfile.serverName; + if (this.connectionProfile.databaseName && !this.isMasterMssql()) { + // Only add DB name if this is a non-default, non-master connection and if there is no user set profile name. + baseName = baseName + ':' + this.connectionProfile.databaseName; + } + let advancedOptions = this._connectionService.getNonDefaultOptions(this.connectionProfile); + let fullTitle = baseName + advancedOptions; + + switch (verbosity) { + case Verbosity.LONG: + // Used by tabsTitleControl as the tooltip hover. + return fullTitle; + default: + case Verbosity.SHORT: + case Verbosity.MEDIUM: + // Used for header title by tabsTitleControl. + return this.getName(); + } + } + private isMasterMssql(): boolean { return this.connectionProfile.providerName === mssqlProviderName && this.connectionProfile.databaseName?.toLowerCase() === 'master'; diff --git a/src/sql/workbench/browser/editor/profiler/profilerInput.ts b/src/sql/workbench/browser/editor/profiler/profilerInput.ts index a0547d6f60..771afe3d62 100644 --- a/src/sql/workbench/browser/editor/profiler/profilerInput.ts +++ b/src/sql/workbench/browser/editor/profiler/profilerInput.ts @@ -7,6 +7,7 @@ import { TableDataView } from 'sql/base/browser/ui/table/tableDataView'; import { IProfilerSession, IProfilerService, ProfilerSessionID, IProfilerViewTemplate, ProfilerFilter } from 'sql/workbench/services/profiler/browser/interfaces'; import { ProfilerState } from 'sql/workbench/common/editor/profiler/profilerState'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import * as azdata from 'azdata'; import * as nls from 'vs/nls'; @@ -17,8 +18,10 @@ import { Event, Emitter } from 'vs/base/common/event'; import { generateUuid } from 'vs/base/common/uuid'; import * as types from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; +import * as path from 'vs/base/common/path'; import { FilterData } from 'sql/workbench/services/profiler/browser/profilerFilter'; import { uriPrefixes } from 'sql/platform/connection/common/utils'; +import { Verbosity } from 'vs/workbench/common/editor'; export interface ColumnDefinition extends Slick.Column { name: string; @@ -26,6 +29,7 @@ export interface ColumnDefinition extends Slick.Column { export class ProfilerInput extends EditorInput implements IProfilerSession { + private static PROFILERNAME: string = nls.localize('profilerInput.profiler', "Profiler"); public static ID: string = 'workbench.editorinputs.profilerinputs'; public static SCHEMA: string = 'profiler'; private _data: TableDataView; @@ -48,6 +52,7 @@ export class ProfilerInput extends EditorInput implements IProfilerSession { constructor( public connection: IConnectionProfile | undefined, public fileURI: URI | undefined, + @IConnectionManagementService private _connectionService: IConnectionManagementService, @IProfilerService private _profilerService: IProfilerService, @INotificationService private _notificationService: INotificationService ) { @@ -114,6 +119,7 @@ export class ProfilerInput extends EditorInput implements IProfilerSession { public setSessionName(name: string) { if (!this.state.isRunning || !this.state.isPaused) { this._sessionName = name; + this._onDidChangeLabel.fire(); } } @@ -126,14 +132,48 @@ export class ProfilerInput extends EditorInput implements IProfilerSession { } public override getName(): string { - let name: string = nls.localize('profilerInput.profiler', "Profiler"); + let name: string = ProfilerInput.PROFILERNAME; if (!this.connection) { + if (this.isFileSession) { + name += ': ' + path.basename(this.fileURI.fsPath); + } return name; } - name += ': ' + this.connection.serverName.substring(0, 20); + if (this.connection.connectionName) { + name += ': ' + this.connection.connectionName.substring(0, 20); + } + else { + name += ': ' + this.connection.serverName.substring(0, 20); + } return name; } + public override getTitle(verbosity?: Verbosity): string { + let fullTitle = ProfilerInput.PROFILERNAME; + if (this.connection) { + if (this.sessionName) { + fullTitle += nls.localize('profilerInput.sessionName', ': Session Name: {0}\n', this.sessionName); + } + let baseName = this.connection.serverName + ':' + this.connection.databaseName; + let advancedOptions = this._connectionService.getNonDefaultOptions(this.connection); + fullTitle = fullTitle + nls.localize('profilerInput.connDetails', 'Connection Details: ') + baseName + advancedOptions; + } + else if (this.isFileSession) { + fullTitle += ': ' + path.basename(this.fileURI.fsPath); + } + + switch (verbosity) { + case Verbosity.LONG: + // Used by tabsTitleControl as the tooltip hover. + return fullTitle; + default: + case Verbosity.SHORT: + case Verbosity.MEDIUM: + // Used for header title by tabsTitleControl. + return this.getName(); + } + } + public getResource(): URI { return URI.from({ scheme: ProfilerInput.SCHEMA, diff --git a/src/sql/workbench/browser/editor/tableDesigner/tableDesignerInput.ts b/src/sql/workbench/browser/editor/tableDesigner/tableDesignerInput.ts index 59d1d1d1c1..78fcbd97d6 100644 --- a/src/sql/workbench/browser/editor/tableDesigner/tableDesignerInput.ts +++ b/src/sql/workbench/browser/editor/tableDesigner/tableDesignerInput.ts @@ -9,7 +9,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { TableDesignerComponentInput } from 'sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput'; import { TableDesignerProvider } from 'sql/workbench/services/tableDesigner/common/interface'; import * as azdata from 'azdata'; -import { GroupIdentifier, IRevertOptions, ISaveOptions } from 'vs/workbench/common/editor'; +import { GroupIdentifier, IRevertOptions, ISaveOptions, Verbosity } from 'vs/workbench/common/editor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Schemas } from 'sql/base/common/schemas'; @@ -25,6 +25,7 @@ export class TableDesignerInput extends EditorInput { public static ID: string = 'workbench.editorinputs.tableDesignerInput'; private _designerComponentInput: TableDesignerComponentInput; private _title: string; + private _additionalDetails: string = ''; private _name: string; private _tableIcon: azdata.designers.TableIcon; private _tableIconMap: Map = new Map([ @@ -80,8 +81,17 @@ export class TableDesignerInput extends EditorInput { return this._name; } - override getTitle(): string { - return this._title; + override getTitle(verbosity?: Verbosity): string { + switch (verbosity) { + case Verbosity.LONG: + // Used by tabsTitleControl as the tooltip hover. + return this._additionalDetails + this._title.substring(this._title.lastIndexOf(' - ')); + default: + case Verbosity.SHORT: + case Verbosity.MEDIUM: + // Used for header title by tabsTitleControl. + return this._title; + } } override isDirty(): boolean { @@ -119,6 +129,10 @@ export class TableDesignerInput extends EditorInput { private setEditorLabel(): void { this._name = this._designerComponentInput.tableInfo.title; this._title = this._designerComponentInput.tableInfo.tooltip; + let addlDetails = this._designerComponentInput.tableInfo.additionalInfo + if (addlDetails) { + this._additionalDetails = addlDetails; + } this._onDidChangeLabel.fire(); } } diff --git a/src/sql/workbench/common/editor/query/queryEditorInput.ts b/src/sql/workbench/common/editor/query/queryEditorInput.ts index c521a9ba13..c74e6780bc 100644 --- a/src/sql/workbench/common/editor/query/queryEditorInput.ts +++ b/src/sql/workbench/common/editor/query/queryEditorInput.ts @@ -7,7 +7,7 @@ import { localize } from 'vs/nls'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { Emitter } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; -import { GroupIdentifier, IRevertOptions, ISaveOptions, EditorInputCapabilities, IUntypedEditorInput } from 'vs/workbench/common/editor'; +import { GroupIdentifier, IRevertOptions, ISaveOptions, EditorInputCapabilities, IUntypedEditorInput, Verbosity } from 'vs/workbench/common/editor'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConnectionManagementService, IConnectableInput, INewConnectionParams, RunQueryOnConnectionMode } from 'sql/platform/connection/common/connectionManagement'; @@ -245,11 +245,16 @@ export abstract class QueryEditorInput extends EditorInput implements IConnectab title = this._description + ' '; } if (profile) { - title += `${profile.serverName}`; - if (profile.databaseName) { - title += `.${profile.databaseName}`; + if (profile.connectionName) { + title += `${profile.connectionName}`; + } + else { + title += `${profile.serverName}`; + if (profile.databaseName) { + title += `.${profile.databaseName}`; + } + title += ` (${profile.userName || profile.authenticationType})`; } - title += ` (${profile.userName || profile.authenticationType})`; } else { title += localize('disconnected', "disconnected"); } @@ -264,8 +269,35 @@ export abstract class QueryEditorInput extends EditorInput implements IConnectab } // Called to get the tooltip of the tab - public override getTitle(): string { - return this.getName(true); + public override getTitle(verbosity?: Verbosity): string { + let profile = this.connectionManagementService.getConnectionProfile(this.uri); + let fullTitle = ''; + if (profile) { + let additionalOptions = this.connectionManagementService.getNonDefaultOptions(profile); + if (this._description && this._description !== '') { + fullTitle = this._description + ' '; + } + fullTitle += `${profile.serverName}`; + if (profile.databaseName) { + fullTitle += `.${profile.databaseName}`; + } + fullTitle += ` (${profile.userName || profile.authenticationType})`; + + fullTitle += additionalOptions; + } + else { + fullTitle = this.getName(true); + } + switch (verbosity) { + case Verbosity.LONG: + // Used by tabsTitleControl as the tooltip hover. + return fullTitle; + default: + case Verbosity.SHORT: + case Verbosity.MEDIUM: + // Used for header title by tabsTitleControl. + return this.getName(true); + } } // State update funtions diff --git a/src/sql/workbench/services/connection/browser/connectionManagementService.ts b/src/sql/workbench/services/connection/browser/connectionManagementService.ts index bb35ddec01..d3423f5d6d 100644 --- a/src/sql/workbench/services/connection/browser/connectionManagementService.ts +++ b/src/sql/workbench/services/connection/browser/connectionManagementService.ts @@ -728,6 +728,12 @@ export class ConnectionManagementService extends Disposable implements IConnecti return result; } + public getNonDefaultOptions(profile: interfaces.IConnectionProfile): string { + let convProfile = new ConnectionProfile(this._capabilitiesService, profile); + let nonDefOptions = convProfile.getNonDefaultOptionsString(); + return nonDefOptions.replace('(', '[').replace(')', ']'); + } + private doActionsAfterConnectionComplete(uri: string, options: IConnectionCompletionOptions): void { let connectionManagementInfo = this._connectionStatusManager.findConnection(uri); if (!connectionManagementInfo) {