mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
Strict null scripting (#12126)
* strict null scripting * fix compile * fix tests * fix icon
This commit is contained in:
6
src/sql/azdata.d.ts
vendored
6
src/sql/azdata.d.ts
vendored
@@ -322,7 +322,7 @@ declare module 'azdata' {
|
||||
export interface IConnectionProfile extends ConnectionInfo {
|
||||
connectionName?: string;
|
||||
serverName: string;
|
||||
databaseName: string;
|
||||
databaseName?: string;
|
||||
userName: string;
|
||||
password: string;
|
||||
authenticationType: string;
|
||||
@@ -413,7 +413,7 @@ declare module 'azdata' {
|
||||
/**
|
||||
* database name
|
||||
*/
|
||||
databaseName: string;
|
||||
databaseName?: string;
|
||||
/**
|
||||
* user name
|
||||
*/
|
||||
@@ -749,7 +749,7 @@ declare module 'azdata' {
|
||||
}
|
||||
|
||||
export interface ScriptingParamDetails {
|
||||
filePath: string;
|
||||
filePath?: string;
|
||||
scriptCompatibilityOption: string;
|
||||
targetDatabaseEngineEdition: string;
|
||||
targetDatabaseEngineType: string;
|
||||
|
||||
@@ -8,6 +8,8 @@ import * as azdata from 'azdata';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import type { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IconPath } from 'sql/platform/connection/common/connectionProfile';
|
||||
|
||||
export const SERVICE_ID = 'capabilitiesService';
|
||||
export const HOST_NAME = 'azdata';
|
||||
@@ -20,6 +22,7 @@ export const clientCapabilities = {
|
||||
|
||||
export interface ConnectionProviderProperties {
|
||||
providerId: string;
|
||||
iconPath?: URI | IconPath | { id: string, path: IconPath }[]
|
||||
displayName: string;
|
||||
notebookKernelAlias?: string;
|
||||
azureResource?: string;
|
||||
|
||||
@@ -13,7 +13,13 @@ import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilit
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { deepClone } from 'vs/base/common/objects';
|
||||
import * as Constants from 'sql/platform/connection/common/constants';
|
||||
import { find } from 'vs/base/common/arrays';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export interface IconPath {
|
||||
light: URI;
|
||||
dark: URI;
|
||||
}
|
||||
|
||||
|
||||
// Concrete implementation of the IConnectionProfile interface
|
||||
|
||||
@@ -29,6 +35,8 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
public groupId?: string;
|
||||
public saveProfile: boolean;
|
||||
|
||||
public iconPath?: IconPath;
|
||||
|
||||
public isDisconnecting: boolean = false;
|
||||
|
||||
public constructor(
|
||||
@@ -49,7 +57,7 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
let capabilities = this.capabilitiesService.getCapabilities(model.providerName);
|
||||
if (capabilities && capabilities.connection && capabilities.connection.connectionOptions) {
|
||||
const options = capabilities.connection.connectionOptions;
|
||||
let appNameOption = find(options, option => option.specialValueType === interfaces.ConnectionOptionSpecialType.appName);
|
||||
let appNameOption = options.find(option => option.specialValueType === interfaces.ConnectionOptionSpecialType.appName);
|
||||
if (appNameOption) {
|
||||
let appNameKey = appNameOption.name;
|
||||
this.options[appNameKey] = Constants.applicationName;
|
||||
@@ -87,9 +95,13 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
|
||||
}
|
||||
|
||||
private static nullCheckEqualsIgnoreCase(a: string, b: string) {
|
||||
let bothNull: boolean = !a && !b;
|
||||
return bothNull ? bothNull : equalsIgnoreCase(a, b);
|
||||
private static nullCheckEqualsIgnoreCase(a?: string, b?: string) {
|
||||
if (a && !b || b && !a) {
|
||||
return false;
|
||||
} else {
|
||||
let bothNull: boolean = !a && !b;
|
||||
return bothNull ? bothNull : equalsIgnoreCase(a!, b!);
|
||||
}
|
||||
}
|
||||
|
||||
public generateNewId() {
|
||||
|
||||
@@ -152,7 +152,7 @@ export class ConnectionStatusManager {
|
||||
//Check if the existing connection database name is different the one in the summary
|
||||
if (connection.connectionProfile.databaseName !== summary.connectionSummary.databaseName) {
|
||||
//Add the ownerUri with database name to the map if not already exists
|
||||
connection.connectionProfile.databaseName = summary.connectionSummary.databaseName;
|
||||
connection.connectionProfile.databaseName = summary.connectionSummary.databaseName!;
|
||||
let prefix = Utils.getUriPrefix(summary.ownerUri);
|
||||
let ownerUriWithDbName = Utils.generateUriWithPrefix(connection.connectionProfile, prefix);
|
||||
if (!(ownerUriWithDbName in this._connections)) {
|
||||
@@ -186,7 +186,7 @@ export class ConnectionStatusManager {
|
||||
let connection = this._connections[changedConnInfo.connectionUri];
|
||||
if (connection && connection.connectionProfile) {
|
||||
connection.connectionProfile.serverName = changedConnInfo.connection.serverName;
|
||||
connection.connectionProfile.databaseName = changedConnInfo.connection.databaseName;
|
||||
connection.connectionProfile.databaseName = changedConnInfo.connection.databaseName!;
|
||||
connection.connectionProfile.userName = changedConnInfo.connection.userName;
|
||||
return connection.connectionProfile;
|
||||
}
|
||||
|
||||
@@ -137,6 +137,6 @@ export function findProfileInGroup(og: IConnectionProfile, groups: ConnectionPro
|
||||
export function isMaster(profile: IConnectionProfile): boolean {
|
||||
// TODO: the connection profile should have a property to indicate whether the connection is a server connection or database connection
|
||||
// created issue to track the problem: https://github.com/Microsoft/azuredatastudio/issues/5193.
|
||||
return (profile.providerName === mssqlProviderName && profile.databaseName.toLowerCase() === 'master')
|
||||
|| (profile.providerName.toLowerCase() === 'pgsql' && profile.databaseName.toLowerCase() === 'postgres');
|
||||
return (profile.providerName === mssqlProviderName && profile.databaseName?.toLowerCase() === 'master')
|
||||
|| (profile.providerName.toLowerCase() === 'pgsql' && profile.databaseName?.toLowerCase() === 'postgres');
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ suite('SQL ConnectionProfileInfo tests', () => {
|
||||
assert.equal(conn.serverName, undefined);
|
||||
conn.connectionName = connectionProfile.connectionName!;
|
||||
conn.serverName = connectionProfile.serverName;
|
||||
conn.databaseName = connectionProfile.databaseName;
|
||||
conn.databaseName = connectionProfile.databaseName!;
|
||||
conn.authenticationType = connectionProfile.authenticationType;
|
||||
conn.password = connectionProfile.password;
|
||||
conn.userName = connectionProfile.userName;
|
||||
|
||||
@@ -141,7 +141,7 @@ suite('SQL ProviderConnectionInfo tests', () => {
|
||||
assert.equal(conn.serverName, undefined);
|
||||
conn.connectionName = connectionProfile.connectionName!;
|
||||
conn.serverName = connectionProfile.serverName;
|
||||
conn.databaseName = connectionProfile.databaseName;
|
||||
conn.databaseName = connectionProfile.databaseName!;
|
||||
conn.authenticationType = connectionProfile.authenticationType;
|
||||
conn.password = connectionProfile.password;
|
||||
conn.userName = connectionProfile.userName;
|
||||
@@ -157,7 +157,7 @@ suite('SQL ProviderConnectionInfo tests', () => {
|
||||
let conn = new ProviderConnectionInfo(capabilitiesService, mssqlProviderName);
|
||||
assert.equal(conn.serverName, undefined);
|
||||
conn.serverName = connectionProfile.serverName;
|
||||
conn.databaseName = connectionProfile.databaseName;
|
||||
conn.databaseName = connectionProfile.databaseName!;
|
||||
conn.authenticationType = connectionProfile.authenticationType;
|
||||
conn.password = connectionProfile.password;
|
||||
conn.userName = connectionProfile.userName;
|
||||
|
||||
@@ -95,7 +95,7 @@ export class DashboardInput extends EditorInput {
|
||||
|
||||
private isMasterMssql(): boolean {
|
||||
return this.connectionProfile.providerName === mssqlProviderName
|
||||
&& this.connectionProfile.databaseName.toLowerCase() === 'master';
|
||||
&& this.connectionProfile.databaseName?.toLowerCase() === 'master';
|
||||
}
|
||||
|
||||
public get uri(): string | undefined {
|
||||
|
||||
@@ -27,8 +27,8 @@ export class ScriptSelectAction extends Action {
|
||||
|
||||
public async run(actionContext: BaseActionContext): Promise<boolean> {
|
||||
return scriptSelect(
|
||||
actionContext.profile,
|
||||
actionContext.object,
|
||||
actionContext.profile!,
|
||||
actionContext.object!,
|
||||
this._connectionManagementService,
|
||||
this._queryEditorService,
|
||||
this._scriptingService
|
||||
@@ -52,8 +52,8 @@ export class ScriptExecuteAction extends Action {
|
||||
|
||||
public async run(actionContext: BaseActionContext): Promise<boolean> {
|
||||
return script(
|
||||
actionContext.profile,
|
||||
actionContext.object,
|
||||
actionContext.profile!,
|
||||
actionContext.object!,
|
||||
this._connectionManagementService,
|
||||
this._queryEditorService,
|
||||
this._scriptingService,
|
||||
@@ -79,8 +79,8 @@ export class ScriptAlterAction extends Action {
|
||||
|
||||
public async run(actionContext: BaseActionContext): Promise<boolean> {
|
||||
return script(
|
||||
actionContext.profile,
|
||||
actionContext.object,
|
||||
actionContext.profile!,
|
||||
actionContext.object!,
|
||||
this._connectionManagementService,
|
||||
this._queryEditorService,
|
||||
this._scriptingService,
|
||||
@@ -105,8 +105,8 @@ export class EditDataAction extends Action {
|
||||
|
||||
public async run(actionContext: BaseActionContext): Promise<boolean> {
|
||||
return scriptEditSelect(
|
||||
actionContext.profile,
|
||||
actionContext.object,
|
||||
actionContext.profile!,
|
||||
actionContext.object!,
|
||||
this._connectionManagementService,
|
||||
this._queryEditorService,
|
||||
this._scriptingService
|
||||
@@ -130,8 +130,8 @@ export class ScriptCreateAction extends Action {
|
||||
|
||||
public async run(actionContext: BaseActionContext): Promise<boolean> {
|
||||
return script(
|
||||
actionContext.profile,
|
||||
actionContext.object,
|
||||
actionContext.profile!,
|
||||
actionContext.object!,
|
||||
this._connectionManagementService,
|
||||
this._queryEditorService,
|
||||
this._scriptingService,
|
||||
@@ -157,8 +157,8 @@ export class ScriptDeleteAction extends Action {
|
||||
|
||||
public async run(actionContext: BaseActionContext): Promise<boolean> {
|
||||
return script(
|
||||
actionContext.profile,
|
||||
actionContext.object,
|
||||
actionContext.profile!,
|
||||
actionContext.object!,
|
||||
this._connectionManagementService,
|
||||
this._queryEditorService,
|
||||
this._scriptingService,
|
||||
|
||||
@@ -42,7 +42,7 @@ const targetDatabaseEngineEditionMap = {
|
||||
*/
|
||||
export async function scriptSelect(connectionProfile: IConnectionProfile, metadata: azdata.ObjectMetadata, connectionService: IConnectionManagementService, queryEditorService: IQueryEditorService, scriptingService: IScriptingService): Promise<boolean> {
|
||||
const connectionResult = await connectionService.connectIfNotConnected(connectionProfile);
|
||||
let paramDetails: azdata.ScriptingParamDetails = getScriptingParamDetails(connectionService, connectionResult, metadata);
|
||||
let paramDetails = getScriptingParamDetails(connectionService, connectionResult, metadata)!;
|
||||
const result = await scriptingService.script(connectionResult, metadata, ScriptOperation.Select, paramDetails);
|
||||
if (result && result.script) {
|
||||
const owner = await queryEditorService.newSqlEditor({ initalContent: result.script }, connectionProfile?.providerName);
|
||||
@@ -68,8 +68,8 @@ export async function scriptSelect(connectionProfile: IConnectionProfile, metada
|
||||
*/
|
||||
export async function scriptEditSelect(connectionProfile: IConnectionProfile, metadata: azdata.ObjectMetadata, connectionService: IConnectionManagementService, queryEditorService: IQueryEditorService, scriptingService: IScriptingService): Promise<boolean> {
|
||||
const connectionResult = await connectionService.connectIfNotConnected(connectionProfile);
|
||||
let paramDetails: azdata.ScriptingParamDetails = getScriptingParamDetails(connectionService, connectionResult, metadata);
|
||||
const result = await scriptingService.script(connectionResult, metadata, ScriptOperation.Select, paramDetails);
|
||||
let paramDetails = getScriptingParamDetails(connectionService, connectionResult, metadata);
|
||||
const result = await scriptingService.script(connectionResult, metadata, ScriptOperation.Select, paramDetails!);
|
||||
if (result && result.script) {
|
||||
const owner = await queryEditorService.newEditDataEditor(metadata.schema, metadata.name, result.script);
|
||||
// Connect our editor
|
||||
@@ -120,7 +120,7 @@ export async function script(connectionProfile: IConnectionProfile, metadata: az
|
||||
operation: ScriptOperation,
|
||||
errorMessageService: IErrorMessageService): Promise<boolean> {
|
||||
const connectionResult = await connectionService.connectIfNotConnected(connectionProfile);
|
||||
let paramDetails = getScriptingParamDetails(connectionService, connectionResult, metadata);
|
||||
let paramDetails = getScriptingParamDetails(connectionService, connectionResult, metadata)!;
|
||||
const result = await scriptingService.script(connectionResult, metadata, operation, paramDetails);
|
||||
if (result) {
|
||||
let script: string = result.script;
|
||||
@@ -160,18 +160,21 @@ export async function script(connectionProfile: IConnectionProfile, metadata: az
|
||||
}
|
||||
}
|
||||
|
||||
function getScriptingParamDetails(connectionService: IConnectionManagementService, ownerUri: string, metadata: azdata.ObjectMetadata): azdata.ScriptingParamDetails {
|
||||
let serverInfo: azdata.ServerInfo = getServerInfo(connectionService, ownerUri);
|
||||
let paramDetails: azdata.ScriptingParamDetails = {
|
||||
filePath: undefined,
|
||||
scriptCompatibilityOption: scriptCompatibilityOptionMap[serverInfo.serverMajorVersion],
|
||||
targetDatabaseEngineEdition: targetDatabaseEngineEditionMap[serverInfo.engineEditionId],
|
||||
targetDatabaseEngineType: serverInfo.isCloud ? 'SqlAzure' : 'SingleInstance'
|
||||
};
|
||||
return paramDetails;
|
||||
function getScriptingParamDetails(connectionService: IConnectionManagementService, ownerUri: string, metadata: azdata.ObjectMetadata): azdata.ScriptingParamDetails | undefined {
|
||||
let serverInfo: azdata.ServerInfo | undefined = getServerInfo(connectionService, ownerUri);
|
||||
if (serverInfo) {
|
||||
let paramDetails: azdata.ScriptingParamDetails = {
|
||||
filePath: undefined,
|
||||
scriptCompatibilityOption: scriptCompatibilityOptionMap[serverInfo.serverMajorVersion as keyof typeof scriptCompatibilityOptionMap],
|
||||
targetDatabaseEngineEdition: targetDatabaseEngineEditionMap[serverInfo.engineEditionId as keyof typeof targetDatabaseEngineEditionMap],
|
||||
targetDatabaseEngineType: serverInfo.isCloud ? 'SqlAzure' : 'SingleInstance'
|
||||
};
|
||||
return paramDetails;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getServerInfo(connectionService: IConnectionManagementService, ownerUri: string): azdata.ServerInfo {
|
||||
function getServerInfo(connectionService: IConnectionManagementService, ownerUri: string): azdata.ServerInfo | undefined {
|
||||
let connection: ConnectionManagementInfo = connectionService.getConnectionInfo(ownerUri);
|
||||
return connection.serverInfo;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ export class ConnectionViewletPanel extends ViewPane {
|
||||
|
||||
public static readonly ID = 'dataExplorer.servers';
|
||||
|
||||
private _root: HTMLElement;
|
||||
private _root?: HTMLElement;
|
||||
private _serverTreeView: ServerTreeView;
|
||||
private _addServerAction: IAction;
|
||||
private _addServerGroupAction: IAction;
|
||||
@@ -89,7 +89,7 @@ export class ConnectionViewletPanel extends ViewPane {
|
||||
|
||||
layoutBody(size: number): void {
|
||||
this._serverTreeView.layout(size);
|
||||
DOM.toggleClass(this._root, 'narrow', this._root.clientWidth < 300);
|
||||
DOM.toggleClass(this._root!, 'narrow', this._root!.clientWidth < 300);
|
||||
}
|
||||
|
||||
show(): void {
|
||||
|
||||
@@ -87,9 +87,9 @@ export class DataExplorerViewlet extends Viewlet {
|
||||
}
|
||||
|
||||
export class DataExplorerViewPaneContainer extends ViewPaneContainer {
|
||||
private root: HTMLElement;
|
||||
private root?: HTMLElement;
|
||||
|
||||
private dataSourcesBox: HTMLElement;
|
||||
private dataSourcesBox?: HTMLElement;
|
||||
|
||||
constructor(
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@@ -125,7 +125,7 @@ export class DataExplorerViewPaneContainer extends ViewPaneContainer {
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): void {
|
||||
toggleClass(this.root, 'narrow', dimension.width <= 300);
|
||||
toggleClass(this.root!, 'narrow', dimension.width <= 300);
|
||||
super.layout(new Dimension(dimension.width, dimension.height));
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ export class DataExplorerViewPaneContainer extends ViewPaneContainer {
|
||||
|
||||
getSecondaryActions(): IAction[] {
|
||||
let menu = this.menuService.createMenu(MenuId.DataExplorerAction, this.contextKeyService);
|
||||
let actions = [];
|
||||
let actions: IAction[] = [];
|
||||
menu.getActions({}).forEach(group => {
|
||||
if (group[0] === 'secondary') {
|
||||
actions.push(...group[1]);
|
||||
|
||||
@@ -9,7 +9,7 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { attachListStyler } from 'vs/platform/theme/common/styler';
|
||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { ISelectionEvent, ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -29,31 +29,30 @@ import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { Button } from 'sql/base/browser/ui/button/button';
|
||||
import { attachButtonStyler } from 'sql/platform/theme/common/styler';
|
||||
import { TreeNode, TreeItemCollapsibleState } from 'sql/workbench/services/objectExplorer/common/treeNode';
|
||||
import { SERVER_GROUP_AUTOEXPAND_CONFIG } from 'sql/workbench/contrib/objectExplorer/common/serverGroup.contribution';
|
||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||
import { ServerTreeActionProvider } from 'sql/workbench/services/objectExplorer/browser/serverTreeActionProvider';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { isHidden } from 'sql/base/browser/dom';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { startsWith } from 'vs/base/common/strings';
|
||||
import { SERVER_GROUP_CONFIG } from 'sql/workbench/services/serverGroup/common/interfaces';
|
||||
import { horizontalScrollingKey } from 'vs/platform/list/browser/listService';
|
||||
import { ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ITreeContextMenuEvent, ITreeEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ObjectExplorerActionsContext } from 'sql/workbench/services/objectExplorer/browser/objectExplorerActions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
|
||||
/**
|
||||
* ServerTreeview implements the dynamic tree view.
|
||||
*/
|
||||
export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
|
||||
public messages: HTMLElement;
|
||||
private _buttonSection: HTMLElement;
|
||||
public messages?: HTMLElement;
|
||||
private _buttonSection?: HTMLElement;
|
||||
private _treeSelectionHandler: TreeSelectionHandler;
|
||||
private _activeConnectionsFilterAction: ActiveConnectionsFilterAction;
|
||||
private _tree: ITree | AsyncServerTree;
|
||||
private _tree?: ITree | AsyncServerTree;
|
||||
private _onSelectionOrFocusChange: Emitter<void>;
|
||||
private _actionProvider: ServerTreeActionProvider;
|
||||
|
||||
@@ -81,7 +80,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
// Refresh the tree input now that the capabilities are registered so that we can
|
||||
// get the full ConnectionProfiles with the server info updated properly
|
||||
const treeInput = TreeUpdateUtils.getTreeInput(this._connectionManagementService);
|
||||
const treeInput = TreeUpdateUtils.getTreeInput(this._connectionManagementService)!;
|
||||
await this._tree.setInput(treeInput);
|
||||
this._treeSelectionHandler.onTreeActionStateChange(false);
|
||||
} else {
|
||||
@@ -113,7 +112,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
}
|
||||
|
||||
public get tree(): ITree | AsyncServerTree {
|
||||
return this._tree;
|
||||
return this._tree!;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,14 +158,14 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
|
||||
const horizontalScrollEnabled: boolean = this._configurationService.getValue(horizontalScrollingKey) || false;
|
||||
this._tree = this._register(TreeCreationUtils.createServersTree(container, this._instantiationService, this._configurationService, horizontalScrollEnabled));
|
||||
this._register(this._tree.onDidChangeSelection((event) => this.onSelected(event)));
|
||||
this._register(this._tree.onDidChangeSelection((event: ISelectionEvent | ITreeEvent<ServerTreeElement>) => this.onSelected(event)));
|
||||
this._register(this._tree.onDidBlur(() => this._onSelectionOrFocusChange.fire()));
|
||||
this._register(this._tree.onDidChangeFocus(() => this._onSelectionOrFocusChange.fire()));
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
this._register(this._tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
this._register(this._tree.onMouseDblClick(e => {
|
||||
// Open dashboard on double click for server and database nodes
|
||||
let connectionProfile: ConnectionProfile;
|
||||
let connectionProfile: ConnectionProfile | undefined;
|
||||
if (e.element instanceof ConnectionProfile) {
|
||||
connectionProfile = e.element;
|
||||
} else if (e.element instanceof TreeNode) {
|
||||
@@ -212,16 +211,16 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
|
||||
return new Promise<void>(async (resolve, reject) => {
|
||||
await this.refreshTree();
|
||||
const root = <ConnectionProfileGroup>this._tree.getInput();
|
||||
const root = <ConnectionProfileGroup>this._tree!.getInput();
|
||||
|
||||
const expandGroups: boolean = this._configurationService.getValue(SERVER_GROUP_CONFIG)[SERVER_GROUP_AUTOEXPAND_CONFIG];
|
||||
const expandGroups = this._configurationService.getValue<{ autoExpand: boolean }>(SERVER_GROUP_CONFIG).autoExpand;
|
||||
if (expandGroups) {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
await Promise.all(ConnectionProfileGroup.getSubgroups(root).map(subgroup => {
|
||||
return this._tree.expand(subgroup);
|
||||
return this._tree!.expand(subgroup);
|
||||
}));
|
||||
} else {
|
||||
await this._tree.expandAll(ConnectionProfileGroup.getSubgroups(root));
|
||||
await this._tree!.expandAll(ConnectionProfileGroup.getSubgroups(root));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -238,7 +237,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
public isObjectExplorerConnectionUri(uri: string): boolean {
|
||||
let isBackupRestoreUri: boolean = uri.indexOf(ConnectionUtils.ConnectionUriBackupIdAttributeName) >= 0 ||
|
||||
uri.indexOf(ConnectionUtils.ConnectionUriRestoreIdAttributeName) >= 0;
|
||||
return uri && startsWith(uri, ConnectionUtils.uriPrefixes.default) && !isBackupRestoreUri;
|
||||
return !!uri && uri.startsWith(ConnectionUtils.uriPrefixes.default) && !isBackupRestoreUri;
|
||||
}
|
||||
|
||||
private async handleAddConnectionProfile(newProfile?: IConnectionProfile): Promise<void> {
|
||||
@@ -277,16 +276,16 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
}
|
||||
}
|
||||
|
||||
const currentSelections = this._tree.getSelection();
|
||||
const currentSelections = this._tree!.getSelection();
|
||||
const currentSelectedElement = currentSelections && currentSelections.length >= 1 ? currentSelections[0] : undefined;
|
||||
const newProfileIsSelected = currentSelectedElement && newProfile ? currentSelectedElement.id === newProfile.id : false;
|
||||
if (newProfile && currentSelectedElement && !newProfileIsSelected) {
|
||||
this._tree.clearSelection();
|
||||
this._tree!.clearSelection();
|
||||
}
|
||||
await this.refreshTree();
|
||||
if (newProfile && !newProfileIsSelected) {
|
||||
await this._tree.reveal(newProfile);
|
||||
this._tree.select(newProfile);
|
||||
await this._tree!.reveal(newProfile);
|
||||
this._tree!.select(newProfile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,11 +303,11 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
*/
|
||||
private getConnectionInTreeInput(connectionId: string): ConnectionProfile | undefined {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
const root = this._tree.getInput();
|
||||
const root = this._tree.getInput()!;
|
||||
const connections = ConnectionProfileGroup.getConnectionsInGroup(root);
|
||||
return connections.find(conn => conn.id === connectionId);
|
||||
} else {
|
||||
const root = TreeUpdateUtils.getTreeInput(this._connectionManagementService);
|
||||
const root = TreeUpdateUtils.getTreeInput(this._connectionManagementService)!;
|
||||
const connections = ConnectionProfileGroup.getConnectionsInGroup(root);
|
||||
const results = connections.filter(con => {
|
||||
if (connectionId === con.id) {
|
||||
@@ -330,16 +329,16 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
this._tree.rerender(element);
|
||||
} else {
|
||||
await this._tree.refresh(element);
|
||||
await this._tree!.refresh(element);
|
||||
}
|
||||
await this._tree.expand(element);
|
||||
await this._tree.reveal(element, 0.5);
|
||||
await this._tree!.expand(element);
|
||||
await this._tree!.reveal(element, 0.5);
|
||||
this._treeSelectionHandler.onTreeActionStateChange(false);
|
||||
}
|
||||
}
|
||||
|
||||
public addObjectExplorerNodeAndRefreshTree(connection: IConnectionProfile): void {
|
||||
hide(this.messages);
|
||||
hide(this.messages!);
|
||||
if (!this._objectExplorerService.getObjectExplorerNode(connection)) {
|
||||
this._objectExplorerService.updateObjectExplorerNodes(connection).catch(e => errors.onUnexpectedError(e));
|
||||
}
|
||||
@@ -356,35 +355,35 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
this._tree.collapse(conn);
|
||||
await this.refreshTree();
|
||||
} else {
|
||||
await this._tree.collapse(conn);
|
||||
return this._tree.refresh(conn);
|
||||
await this._tree!.collapse(conn);
|
||||
return this._tree!.refresh(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async refreshTree(): Promise<void> {
|
||||
hide(this.messages);
|
||||
hide(this.messages!);
|
||||
this.clearOtherActions();
|
||||
return TreeUpdateUtils.registeredServerUpdate(this._tree, this._connectionManagementService);
|
||||
return TreeUpdateUtils.registeredServerUpdate(this._tree!, this._connectionManagementService);
|
||||
}
|
||||
|
||||
public async refreshElement(element: ServerTreeElement): Promise<void> {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
return this._tree.updateChildren(element);
|
||||
} else {
|
||||
return this._tree.refresh(element);
|
||||
return this._tree!.refresh(element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter connections based on view (recent/active)
|
||||
*/
|
||||
private filterConnections(treeInput: ConnectionProfileGroup[], view: string): ConnectionProfileGroup[] {
|
||||
private filterConnections(treeInput: ConnectionProfileGroup[] | undefined, view: string): ConnectionProfileGroup[] | undefined {
|
||||
if (!treeInput || treeInput.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const result = treeInput.map(group => {
|
||||
const result = coalesce(treeInput.map(group => {
|
||||
// Keep active/recent connections and remove the rest
|
||||
if (group.connections) {
|
||||
group.connections = group.connections.filter(con => {
|
||||
@@ -408,7 +407,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
return group;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -416,35 +415,35 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
* Set tree elements based on the view (recent/active)
|
||||
*/
|
||||
public showFilteredTree(view: string): void {
|
||||
hide(this.messages);
|
||||
hide(this.messages!);
|
||||
// Clear other action views if user switched between two views
|
||||
this.clearOtherActions(view);
|
||||
const root = TreeUpdateUtils.getTreeInput(this._connectionManagementService);
|
||||
let treeInput: ConnectionProfileGroup = null;
|
||||
let treeInput: ConnectionProfileGroup | undefined = undefined;
|
||||
if (root) {
|
||||
// Filter results based on view
|
||||
const filteredResults = this.filterConnections([root], view);
|
||||
if (!filteredResults || !filteredResults[0]) {
|
||||
show(this.messages);
|
||||
this.messages.focus();
|
||||
show(this.messages!);
|
||||
this.messages!.focus();
|
||||
} else {
|
||||
treeInput = filteredResults[0];
|
||||
}
|
||||
this._tree.setInput(treeInput).then(async () => {
|
||||
if (isHidden(this.messages)) {
|
||||
this._tree.getFocus();
|
||||
this._tree!.setInput(treeInput!).then(async () => {
|
||||
if (isHidden(this.messages!)) {
|
||||
this._tree!.getFocus();
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
await Promise.all(ConnectionProfileGroup.getSubgroups(treeInput).map(subgroup => {
|
||||
this._tree.expand(subgroup);
|
||||
await Promise.all(ConnectionProfileGroup.getSubgroups(treeInput!).map(subgroup => {
|
||||
this._tree!.expand(subgroup);
|
||||
}));
|
||||
} else {
|
||||
await this._tree.expandAll(ConnectionProfileGroup.getSubgroups(treeInput));
|
||||
await this._tree!.expandAll(ConnectionProfileGroup.getSubgroups(treeInput!));
|
||||
}
|
||||
} else {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
this._tree.setFocus([]);
|
||||
} else {
|
||||
this._tree.clearFocus();
|
||||
this._tree!.clearFocus();
|
||||
}
|
||||
}
|
||||
}, errors.onUnexpectedError);
|
||||
@@ -460,33 +459,33 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
if (!searchString) {
|
||||
return;
|
||||
}
|
||||
hide(this.messages);
|
||||
hide(this.messages!);
|
||||
// Clear other actions if user searched during other views
|
||||
this.clearOtherActions();
|
||||
// Filter connections based on search
|
||||
const filteredResults = this.searchConnections(searchString);
|
||||
if (!filteredResults || filteredResults.length === 0) {
|
||||
show(this.messages);
|
||||
this.messages.focus();
|
||||
show(this.messages!);
|
||||
this.messages!.focus();
|
||||
}
|
||||
// Add all connections to tree root and set tree input
|
||||
const treeInput = new ConnectionProfileGroup('searchroot', undefined, 'searchroot', undefined, undefined);
|
||||
treeInput.addConnections(filteredResults);
|
||||
this._tree.setInput(treeInput).then(async () => {
|
||||
if (isHidden(this.messages)) {
|
||||
this._tree.getFocus();
|
||||
this._tree!.setInput(treeInput).then(async () => {
|
||||
if (isHidden(this.messages!)) {
|
||||
this._tree!.getFocus();
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
await Promise.all(ConnectionProfileGroup.getSubgroups(treeInput).map(subgroup => {
|
||||
this._tree.expand(subgroup);
|
||||
this._tree!.expand(subgroup);
|
||||
}));
|
||||
} else {
|
||||
await this._tree.expandAll(ConnectionProfileGroup.getSubgroups(treeInput));
|
||||
await this._tree!.expandAll(ConnectionProfileGroup.getSubgroups(treeInput));
|
||||
}
|
||||
} else {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
this._tree.setFocus([]);
|
||||
} else {
|
||||
this._tree.clearFocus();
|
||||
this._tree!.clearFocus();
|
||||
}
|
||||
}
|
||||
}, errors.onUnexpectedError);
|
||||
@@ -497,7 +496,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
*/
|
||||
private searchConnections(searchString: string): ConnectionProfile[] {
|
||||
|
||||
const root = TreeUpdateUtils.getTreeInput(this._connectionManagementService);
|
||||
const root = TreeUpdateUtils.getTreeInput(this._connectionManagementService)!;
|
||||
const connections = ConnectionProfileGroup.getConnectionsInGroup(root);
|
||||
const results = connections.filter(con => {
|
||||
if (searchString && (searchString.length > 0)) {
|
||||
@@ -542,7 +541,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
}
|
||||
|
||||
private onSelected(event: any): void {
|
||||
this._treeSelectionHandler.onTreeSelect(event, this._tree, this._connectionManagementService, this._objectExplorerService, () => this._onSelectionOrFocusChange.fire());
|
||||
this._treeSelectionHandler.onTreeSelect(event, this._tree!, this._connectionManagementService, this._objectExplorerService, () => this._onSelectionOrFocusChange.fire());
|
||||
this._onSelectionOrFocusChange.fire();
|
||||
}
|
||||
|
||||
@@ -550,21 +549,21 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
* set the layout of the view
|
||||
*/
|
||||
public layout(height: number): void {
|
||||
this._tree.layout(height);
|
||||
this._tree!.layout(height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of selected nodes in the tree
|
||||
*/
|
||||
public getSelection(): any[] {
|
||||
return this._tree.getSelection();
|
||||
return this._tree!.getSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the tree view currently has focus
|
||||
*/
|
||||
public isFocused(): boolean {
|
||||
return this._tree.getHTMLElement() === document.activeElement;
|
||||
return this._tree!.getHTMLElement() === document.activeElement;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -572,9 +571,9 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
*/
|
||||
public async setExpandedState(element: ServerTreeElement, expandedState?: TreeItemCollapsibleState): Promise<void> {
|
||||
if (expandedState === TreeItemCollapsibleState.Collapsed) {
|
||||
return this._tree.collapse(element);
|
||||
return this._tree!.collapse(element);
|
||||
} else if (expandedState === TreeItemCollapsibleState.Expanded) {
|
||||
return this._tree.expand(element);
|
||||
return this._tree!.expand(element);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,7 +581,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
* Reveal the given element in the tree
|
||||
*/
|
||||
public async reveal(element: ServerTreeElement): Promise<void> {
|
||||
return this._tree.reveal(element);
|
||||
return this._tree!.reveal(element);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -593,7 +592,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
this._tree.setSelection([]);
|
||||
} else {
|
||||
this._tree.clearSelection();
|
||||
this._tree!.clearSelection();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -602,14 +601,14 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
this._tree.setSelection(this._tree.getSelection().concat(element));
|
||||
this._tree.reveal(element);
|
||||
} else {
|
||||
this._tree.select(element);
|
||||
return this._tree.reveal(element);
|
||||
this._tree!.select(element);
|
||||
return this._tree!.reveal(element);
|
||||
}
|
||||
} else {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
this._tree.setSelection(this._tree.getSelection().filter(item => item !== element));
|
||||
} else {
|
||||
this._tree.deselect(element);
|
||||
this._tree!.deselect(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,7 +620,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
if (this._tree instanceof AsyncServerTree) {
|
||||
return !this._tree.getNode(element).collapsed;
|
||||
} else {
|
||||
return this._tree.isExpanded(element);
|
||||
return this._tree!.isExpanded(element);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -630,42 +629,45 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
|
||||
* Return actions in the context menu
|
||||
*/
|
||||
private onContextMenu(e: ITreeContextMenuEvent<ServerTreeElement>): boolean {
|
||||
e.browserEvent.preventDefault();
|
||||
e.browserEvent.stopPropagation();
|
||||
this._tree.setSelection([e.element]);
|
||||
if (e.element) {
|
||||
e.browserEvent.preventDefault();
|
||||
e.browserEvent.stopPropagation();
|
||||
this._tree!.setSelection([e.element]);
|
||||
|
||||
let actionContext: any;
|
||||
if (e.element instanceof TreeNode) {
|
||||
let context = new ObjectExplorerActionsContext();
|
||||
context.nodeInfo = e.element.toNodeInfo();
|
||||
// Note: getting DB name before, but intentionally not using treeUpdateUtils.getConnectionProfile as it replaces
|
||||
// the connection ID with a new one. This breaks a number of internal tasks
|
||||
context.connectionProfile = e.element.getConnectionProfile().toIConnectionProfile();
|
||||
context.connectionProfile.databaseName = e.element.getDatabaseName();
|
||||
actionContext = context;
|
||||
} else if (e.element instanceof ConnectionProfile) {
|
||||
let context = new ObjectExplorerActionsContext();
|
||||
context.connectionProfile = e.element.toIConnectionProfile();
|
||||
context.isConnectionNode = true;
|
||||
actionContext = context;
|
||||
} else {
|
||||
// TODO: because the connection group is used as a context object and isn't serializable,
|
||||
// the Group-level context menu is not currently extensible
|
||||
actionContext = e.element;
|
||||
let actionContext: any;
|
||||
if (e.element instanceof TreeNode) {
|
||||
let context = new ObjectExplorerActionsContext();
|
||||
context.nodeInfo = e.element.toNodeInfo();
|
||||
// Note: getting DB name before, but intentionally not using treeUpdateUtils.getConnectionProfile as it replaces
|
||||
// the connection ID with a new one. This breaks a number of internal tasks
|
||||
context.connectionProfile = e.element.getConnectionProfile()!.toIConnectionProfile();
|
||||
context.connectionProfile.databaseName = e.element.getDatabaseName();
|
||||
actionContext = context;
|
||||
} else if (e.element instanceof ConnectionProfile) {
|
||||
let context = new ObjectExplorerActionsContext();
|
||||
context.connectionProfile = e.element.toIConnectionProfile();
|
||||
context.isConnectionNode = true;
|
||||
actionContext = context;
|
||||
} else {
|
||||
// TODO: because the connection group is used as a context object and isn't serializable,
|
||||
// the Group-level context menu is not currently extensible
|
||||
actionContext = e.element;
|
||||
}
|
||||
|
||||
this._contextMenuService.showContextMenu({
|
||||
getAnchor: () => e.anchor,
|
||||
getActions: () => this._actionProvider.getActions(this._tree!, e.element!),
|
||||
getKeyBinding: (action) => this._keybindingService.lookupKeybinding(action.id),
|
||||
onHide: (wasCancelled?: boolean) => {
|
||||
if (wasCancelled) {
|
||||
this._tree!.domFocus();
|
||||
}
|
||||
},
|
||||
getActionsContext: () => (actionContext)
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
this._contextMenuService.showContextMenu({
|
||||
getAnchor: () => e.anchor,
|
||||
getActions: () => this._actionProvider.getActions(this._tree, e.element),
|
||||
getKeyBinding: (action) => this._keybindingService.lookupKeybinding(action.id),
|
||||
onHide: (wasCancelled?: boolean) => {
|
||||
if (wasCancelled) {
|
||||
this._tree.domFocus();
|
||||
}
|
||||
},
|
||||
getActionsContext: () => (actionContext)
|
||||
});
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,130 +40,148 @@ export const EDIT_DATA_COMMAND_ID = 'dataExplorer.scriptAsEdit';
|
||||
// Script as Create
|
||||
CommandsRegistry.registerCommand({
|
||||
id: SCRIPT_AS_CREATE_COMMAND_ID,
|
||||
handler: async (accessor, args: TreeViewItemHandleArg) => {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const errorMessageService = accessor.get(IErrorMessageService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata
|
||||
};
|
||||
const scriptCreateAction = new ScriptCreateAction(ScriptCreateAction.ID, ScriptCreateAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService, errorMessageService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptCreateAction.run(baseContext));
|
||||
handler: async (accessor, args: TreeViewItemHandleArg): Promise<boolean | undefined> => {
|
||||
if (args.$treeItem?.payload) {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const errorMessageService = accessor.get(IErrorMessageService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem)!.metadata
|
||||
};
|
||||
const scriptCreateAction = new ScriptCreateAction(ScriptCreateAction.ID, ScriptCreateAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService, errorMessageService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptCreateAction.run(baseContext));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
// Script as Delete
|
||||
CommandsRegistry.registerCommand({
|
||||
id: SCRIPT_AS_DELETE_COMMAND_ID,
|
||||
handler: async (accessor, args: TreeViewItemHandleArg) => {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const errorMessageService = accessor.get(IErrorMessageService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata
|
||||
};
|
||||
const scriptDeleteAction = new ScriptDeleteAction(ScriptDeleteAction.ID, ScriptDeleteAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService, errorMessageService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptDeleteAction.run(baseContext));
|
||||
handler: async (accessor, args: TreeViewItemHandleArg): Promise<boolean | undefined> => {
|
||||
if (args.$treeItem?.payload) {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const errorMessageService = accessor.get(IErrorMessageService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem)!.metadata
|
||||
};
|
||||
const scriptDeleteAction = new ScriptDeleteAction(ScriptDeleteAction.ID, ScriptDeleteAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService, errorMessageService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptDeleteAction.run(baseContext));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
// Script as Select
|
||||
CommandsRegistry.registerCommand({
|
||||
id: SCRIPT_AS_SELECT_COMMAND_ID,
|
||||
handler: async (accessor, args: TreeViewItemHandleArg) => {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata
|
||||
};
|
||||
const scriptSelectAction = new ScriptSelectAction(ScriptSelectAction.ID, ScriptSelectAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptSelectAction.run(baseContext));
|
||||
handler: async (accessor, args: TreeViewItemHandleArg): Promise<boolean | undefined> => {
|
||||
if (args.$treeItem?.payload) {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem)!.metadata
|
||||
};
|
||||
const scriptSelectAction = new ScriptSelectAction(ScriptSelectAction.ID, ScriptSelectAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptSelectAction.run(baseContext));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
// Script as Execute
|
||||
CommandsRegistry.registerCommand({
|
||||
id: SCRIPT_AS_EXECUTE_COMMAND_ID,
|
||||
handler: async (accessor, args: TreeViewItemHandleArg) => {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const errorMessageService = accessor.get(IErrorMessageService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata
|
||||
};
|
||||
const scriptExecuteAction = new ScriptExecuteAction(ScriptExecuteAction.ID, ScriptExecuteAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService, errorMessageService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptExecuteAction.run(baseContext));
|
||||
handler: async (accessor, args: TreeViewItemHandleArg): Promise<boolean | undefined> => {
|
||||
if (args.$treeItem?.payload) {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const errorMessageService = accessor.get(IErrorMessageService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem)!.metadata
|
||||
};
|
||||
const scriptExecuteAction = new ScriptExecuteAction(ScriptExecuteAction.ID, ScriptExecuteAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService, errorMessageService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptExecuteAction.run(baseContext));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
// Script as Alter
|
||||
CommandsRegistry.registerCommand({
|
||||
id: SCRIPT_AS_ALTER_COMMAND_ID,
|
||||
handler: async (accessor, args: TreeViewItemHandleArg) => {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const errorMessageService = accessor.get(IErrorMessageService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata
|
||||
};
|
||||
const scriptAlterAction = new ScriptAlterAction(ScriptAlterAction.ID, ScriptAlterAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService, errorMessageService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptAlterAction.run(baseContext));
|
||||
handler: async (accessor, args: TreeViewItemHandleArg): Promise<boolean | undefined> => {
|
||||
if (args.$treeItem?.payload) {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const errorMessageService = accessor.get(IErrorMessageService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem)!.metadata
|
||||
};
|
||||
const scriptAlterAction = new ScriptAlterAction(ScriptAlterAction.ID, ScriptAlterAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService, errorMessageService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => scriptAlterAction.run(baseContext));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
// Edit Data
|
||||
CommandsRegistry.registerCommand({
|
||||
id: EDIT_DATA_COMMAND_ID,
|
||||
handler: async (accessor, args: TreeViewItemHandleArg) => {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata
|
||||
};
|
||||
const editDataAction = new EditDataAction(EditDataAction.ID, EditDataAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => editDataAction.run(baseContext));
|
||||
handler: async (accessor, args: TreeViewItemHandleArg): Promise<boolean | undefined> => {
|
||||
if (args.$treeItem?.payload) {
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const queryEditorService = accessor.get(IQueryEditorService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const scriptingService = accessor.get(IScriptingService);
|
||||
const progressService = accessor.get(IProgressService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
const baseContext: BaseActionContext = {
|
||||
profile: profile,
|
||||
object: oeShimService.getNodeInfoForTreeItem(args.$treeItem)!.metadata
|
||||
};
|
||||
const editDataAction = new EditDataAction(EditDataAction.ID, EditDataAction.LABEL,
|
||||
queryEditorService, connectionManagementService, scriptingService);
|
||||
return progressService.withProgress({ location: VIEWLET_ID }, () => editDataAction.run(baseContext));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
@@ -186,9 +204,9 @@ CommandsRegistry.registerCommand({
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const objectExplorerService = accessor.get(IObjectExplorerService);
|
||||
const selectionHandler = instantiationService.createInstance(TreeSelectionHandler);
|
||||
const node = await getTreeNode(args, objectExplorerService);
|
||||
const node = (await getTreeNode(args, objectExplorerService))!;
|
||||
selectionHandler.onTreeActionStateChange(true);
|
||||
let connectionProfile = TreeUpdateUtils.getConnectionProfile(node);
|
||||
let connectionProfile = TreeUpdateUtils.getConnectionProfile(node)!;
|
||||
let ownerUri = connectionManagementService.getConnectionUri(connectionProfile);
|
||||
ownerUri = connectionManagementService.getFormattedUri(ownerUri, connectionProfile);
|
||||
let metadata = node.metadata;
|
||||
@@ -207,7 +225,7 @@ CommandsRegistry.registerCommand({
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const objectExplorerService = accessor.get(IObjectExplorerService);
|
||||
const selectionHandler = instantiationService.createInstance(TreeSelectionHandler);
|
||||
const node = await getTreeNode(args, objectExplorerService);
|
||||
const node = (await getTreeNode(args, objectExplorerService))!;
|
||||
selectionHandler.onTreeActionStateChange(true);
|
||||
let connectionProfile = TreeUpdateUtils.getConnectionProfile(node);
|
||||
let metadata = node.metadata;
|
||||
@@ -227,9 +245,9 @@ CommandsRegistry.registerCommand({
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const objectExplorerService = accessor.get(IObjectExplorerService);
|
||||
const selectionHandler = instantiationService.createInstance(TreeSelectionHandler);
|
||||
const node = await getTreeNode(args, objectExplorerService);
|
||||
const node = (await getTreeNode(args, objectExplorerService))!;
|
||||
selectionHandler.onTreeActionStateChange(true);
|
||||
let connectionProfile = TreeUpdateUtils.getConnectionProfile(node);
|
||||
let connectionProfile = TreeUpdateUtils.getConnectionProfile(node)!;
|
||||
let metadata = node.metadata;
|
||||
let ownerUri = connectionManagementService.getConnectionUri(connectionProfile);
|
||||
ownerUri = connectionManagementService.getFormattedUri(ownerUri, connectionProfile);
|
||||
@@ -249,9 +267,9 @@ CommandsRegistry.registerCommand({
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const objectExplorerService = accessor.get(IObjectExplorerService);
|
||||
const selectionHandler = instantiationService.createInstance(TreeSelectionHandler);
|
||||
const node = await getTreeNode(args, objectExplorerService);
|
||||
const node = (await getTreeNode(args, objectExplorerService))!;
|
||||
selectionHandler.onTreeActionStateChange(true);
|
||||
let connectionProfile = TreeUpdateUtils.getConnectionProfile(node);
|
||||
let connectionProfile = TreeUpdateUtils.getConnectionProfile(node)!;
|
||||
let metadata = node.metadata;
|
||||
let ownerUri = connectionManagementService.getConnectionUri(connectionProfile);
|
||||
ownerUri = connectionManagementService.getFormattedUri(ownerUri, connectionProfile);
|
||||
@@ -271,9 +289,9 @@ CommandsRegistry.registerCommand({
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const objectExplorerService = accessor.get(IObjectExplorerService);
|
||||
const selectionHandler = instantiationService.createInstance(TreeSelectionHandler);
|
||||
const node = await getTreeNode(args, objectExplorerService);
|
||||
const node = (await getTreeNode(args, objectExplorerService))!;
|
||||
selectionHandler.onTreeActionStateChange(true);
|
||||
let connectionProfile = TreeUpdateUtils.getConnectionProfile(node);
|
||||
let connectionProfile = TreeUpdateUtils.getConnectionProfile(node)!;
|
||||
let metadata = node.metadata;
|
||||
let ownerUri = connectionManagementService.getConnectionUri(connectionProfile);
|
||||
ownerUri = connectionManagementService.getFormattedUri(ownerUri, connectionProfile);
|
||||
@@ -297,8 +315,8 @@ CommandsRegistry.registerCommand({
|
||||
//set objectExplorerTreeNode for context menu clicks
|
||||
const node = await getTreeNode(args, objectExplorerService);
|
||||
selectionHandler.onTreeActionStateChange(true);
|
||||
const connectionProfile = TreeUpdateUtils.getConnectionProfile(<TreeNode>node);
|
||||
const metadata = node.metadata;
|
||||
const connectionProfile = TreeUpdateUtils.getConnectionProfile(<TreeNode>node)!;
|
||||
const metadata = node!.metadata;
|
||||
let ownerUri = connectionManagementService.getConnectionUri(connectionProfile);
|
||||
ownerUri = connectionManagementService.getFormattedUri(ownerUri, connectionProfile);
|
||||
|
||||
@@ -320,9 +338,9 @@ export async function handleOeRefreshCommand(accessor: ServicesAccessor, args: O
|
||||
const logService = accessor.get(ILogService);
|
||||
const notificationService = accessor.get(INotificationService);
|
||||
const treeNode = await getTreeNode(args, objectExplorerService);
|
||||
const tree = objectExplorerService.getServerTreeView().tree;
|
||||
const tree = objectExplorerService.getServerTreeView()!.tree;
|
||||
try {
|
||||
await objectExplorerService.refreshTreeNode(treeNode.getSession(), treeNode);
|
||||
await objectExplorerService.refreshTreeNode(treeNode!.getSession()!, treeNode!);
|
||||
if (tree instanceof AsyncServerTree) {
|
||||
await tree.updateChildren(treeNode);
|
||||
} else {
|
||||
@@ -330,7 +348,7 @@ export async function handleOeRefreshCommand(accessor: ServicesAccessor, args: O
|
||||
}
|
||||
} catch (err) {
|
||||
// Display message to the user but also log the entire error to the console for the stack trace
|
||||
notificationService.error(localize('refreshError', "An error occurred refreshing node '{0}': {1}", args.nodeInfo.label, getErrorMessage(err)));
|
||||
notificationService.error(localize('refreshError', "An error occurred refreshing node '{0}': {1}", args.nodeInfo?.label, getErrorMessage(err)));
|
||||
logService.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import { NodeType } from 'sql/workbench/services/objectExplorer/common/nodeType'
|
||||
import { ServerTreeView } from 'sql/workbench/contrib/objectExplorer/browser/serverTreeView';
|
||||
import { createObjectExplorerServiceMock } from 'sql/workbench/services/objectExplorer/test/browser/testObjectExplorerService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { TestTree } from 'sql/workbench/test/treeMock';
|
||||
import { TestConnectionManagementService } from 'sql/platform/connection/test/common/testConnectionManagementService';
|
||||
|
||||
@@ -56,7 +55,7 @@ const oeActionArgs: ObjectExplorerActionsContext = { connectionProfile: connecti
|
||||
|
||||
let instantiationService: IInstantiationService;
|
||||
let logServiceMock: TypeMoq.Mock<ILogService>;
|
||||
let treeMock: TypeMoq.Mock<ITree>;
|
||||
let treeMock: TypeMoq.Mock<TestTree>;
|
||||
|
||||
suite('Scripting Actions', () => {
|
||||
|
||||
@@ -68,7 +67,7 @@ suite('Scripting Actions', () => {
|
||||
const serverTreeViewMock = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Loose, connectionManagementServiceMock.object, instantiationService, undefined, undefined, undefined, undefined, capabilitiesService);
|
||||
treeMock = TypeMoq.Mock.ofType(TestTree);
|
||||
serverTreeViewMock.setup(x => x.tree).returns(() => treeMock.object);
|
||||
collection.set(IObjectExplorerService, createObjectExplorerServiceMock({ serverTreeView: serverTreeViewMock.object, treeNode: treeNode }).object);
|
||||
collection.set(IObjectExplorerService, createObjectExplorerServiceMock({ serverTreeView: serverTreeViewMock.object, treeNode: treeNode }));
|
||||
logServiceMock = TypeMoq.Mock.ofInstance(new NullLogService());
|
||||
collection.set(ILogService, logServiceMock.object);
|
||||
collection.set(INotificationService, new TestNotificationService());
|
||||
|
||||
@@ -18,7 +18,7 @@ export class ConnectionContextKey implements IContextKey<IConnectionProfile> {
|
||||
|
||||
private _providerKey: IContextKey<string>;
|
||||
private _serverKey: IContextKey<string>;
|
||||
private _databaseKey: IContextKey<string>;
|
||||
private _databaseKey: IContextKey<string | undefined>;
|
||||
private _connectionKey: IContextKey<IConnectionProfile>;
|
||||
private _isQueryProviderKey: IContextKey<boolean>;
|
||||
private _canOpenInAzurePortal: IContextKey<boolean>;
|
||||
|
||||
@@ -52,7 +52,7 @@ export class AsyncServerTreeDataSource implements IAsyncDataSource<ConnectionPro
|
||||
if (element.children) {
|
||||
return element.children;
|
||||
} else {
|
||||
return await this._objectExplorerService.resolveTreeNodeChildren(element.getSession(), element);
|
||||
return await this._objectExplorerService.resolveTreeNodeChildren(element.getSession()!, element);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -37,15 +37,15 @@ export class AsyncServerTreeDragAndDrop implements ITreeDragAndDrop<ServerTreeEl
|
||||
* Returns a uri if the given element should be allowed to drag.
|
||||
* Returns null, otherwise.
|
||||
*/
|
||||
public getDragURI(element: ServerTreeElement): string {
|
||||
return this._dragAndDrop.getDragURI(this._tree, element);
|
||||
public getDragURI(element: ServerTreeElement): string | null {
|
||||
return this._dragAndDrop.getDragURI(this._tree!, element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a label(name) to display when dragging the element.
|
||||
*/
|
||||
public getDragLabel(elements: ServerTreeElement[]): string {
|
||||
return this._dragAndDrop.getDragLabel(this._tree, elements);
|
||||
return this._dragAndDrop.getDragLabel(this._tree!, elements);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,17 +54,17 @@ export class AsyncServerTreeDragAndDrop implements ITreeDragAndDrop<ServerTreeEl
|
||||
public onDragStart(dragAndDropData: IDragAndDropData, originalEvent: DragEvent): void {
|
||||
// Force the event cast while in preview - we don't use any of the mouse properties on the
|
||||
// implementation so this is fine for now
|
||||
return this._dragAndDrop.onDragStart(this._tree, dragAndDropData, <any>originalEvent);
|
||||
return this._dragAndDrop.onDragStart(this._tree!, dragAndDropData, <any>originalEvent);
|
||||
}
|
||||
|
||||
public onDragOver(data: IDragAndDropData, targetElement: ServerTreeElement, targetIndex: number, originalEvent: DragEvent): boolean | ITreeDragOverReaction {
|
||||
public onDragOver(data: IDragAndDropData, targetElement: ServerTreeElement | undefined, targetIndex: number, originalEvent: DragEvent): boolean | ITreeDragOverReaction {
|
||||
// Dropping onto an empty space (undefined targetElement) we treat as wanting to move into the root connection group
|
||||
if (!targetElement) {
|
||||
targetElement = this._tree?.getInput();
|
||||
}
|
||||
// Force the event cast while in preview - we don't use any of the mouse properties on the
|
||||
// implementation so this is fine for now
|
||||
const canDragOver = this._dragAndDrop.onDragOver(this._tree, data, targetElement, <any>originalEvent);
|
||||
const canDragOver = this._dragAndDrop.onDragOver(this._tree!, data, targetElement, <any>originalEvent);
|
||||
|
||||
if (canDragOver.accept) {
|
||||
return TreeDragOverReactions.acceptBubbleDown(canDragOver.autoExpand);
|
||||
@@ -76,14 +76,14 @@ export class AsyncServerTreeDragAndDrop implements ITreeDragAndDrop<ServerTreeEl
|
||||
/**
|
||||
* Handle a drop in the server tree.
|
||||
*/
|
||||
public drop(data: IDragAndDropData, targetElement: ServerTreeElement, targetIndex: number, originalEvent: DragEvent): void {
|
||||
public drop(data: IDragAndDropData, targetElement: ServerTreeElement | undefined, targetIndex: number, originalEvent: DragEvent): void {
|
||||
// Dropping onto an empty space (undefined targetElement) we treat as wanting to move into the root connection group
|
||||
if (!targetElement) {
|
||||
targetElement = this._tree?.getInput();
|
||||
}
|
||||
// Force the event cast while in preview - we don't use any of the mouse properties on the
|
||||
// implementation so this is fine for now
|
||||
this._dragAndDrop.drop(this._tree, data, targetElement, <any>originalEvent);
|
||||
this._dragAndDrop.drop(this._tree!, data, targetElement, <any>originalEvent);
|
||||
}
|
||||
|
||||
public onDragEnd(originalEvent: DragEvent): void {
|
||||
@@ -102,7 +102,7 @@ export class AsyncRecentConnectionsDragAndDrop implements ITreeDragAndDrop<Serve
|
||||
return (<ConnectionProfile>element).id;
|
||||
}
|
||||
else if (element instanceof ConnectionProfileGroup) {
|
||||
return (<ConnectionProfileGroup>element).id;
|
||||
return (<ConnectionProfileGroup>element).id ?? null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ export class AsyncRecentConnectionsDragAndDrop implements ITreeDragAndDrop<Serve
|
||||
else if (elements[0] instanceof ConnectionProfileGroup) {
|
||||
return elements[0].name;
|
||||
}
|
||||
return undefined;
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,6 @@ import { ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser
|
||||
|
||||
export class AsyncServerTreeIdentityProvider implements IIdentityProvider<ServerTreeElement> {
|
||||
getId(element: ServerTreeElement): { toString(): string; } {
|
||||
return element.id;
|
||||
return element.id!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'vs/css!./media/objectTypes/objecttypes';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { ConnectionProfile, IconPath } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { TreeNode } from 'sql/workbench/services/objectExplorer/common/treeNode';
|
||||
import { iconRenderer } from 'sql/workbench/services/objectExplorer/browser/iconRenderer';
|
||||
@@ -22,6 +22,7 @@ import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { ServerTreeRenderer } from 'sql/workbench/services/objectExplorer/browser/serverTreeRenderer';
|
||||
import { ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree';
|
||||
import { DefaultServerGroupColor } from 'sql/workbench/services/serverGroup/common/serverGroupViewModel';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
class ConnectionProfileGroupTemplate extends Disposable {
|
||||
private _root: HTMLElement;
|
||||
@@ -31,7 +32,7 @@ class ConnectionProfileGroupTemplate extends Disposable {
|
||||
container: HTMLElement
|
||||
) {
|
||||
super();
|
||||
container.parentElement.classList.add('server-group');
|
||||
container.parentElement!.classList.add('server-group');
|
||||
container.classList.add('server-group');
|
||||
this._root = dom.append(container, dom.$('.server-group'));
|
||||
this._nameContainer = dom.append(this._root, dom.$('span.name'));
|
||||
@@ -89,7 +90,7 @@ class ConnectionProfileTemplate extends Disposable {
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService
|
||||
) {
|
||||
super();
|
||||
container.parentElement.classList.add('connection-profile');
|
||||
container.parentElement!.classList.add('connection-profile');
|
||||
this._root = dom.append(container, dom.$('.connection-tile'));
|
||||
this._icon = dom.append(this._root, dom.$('div.icon server-page'));
|
||||
this._connectionStatusBadge = dom.append(this._icon, dom.$('div.connection-status-badge'));
|
||||
@@ -98,16 +99,15 @@ class ConnectionProfileTemplate extends Disposable {
|
||||
|
||||
set(element: ConnectionProfile) {
|
||||
if (!this._isCompact) {
|
||||
let iconPath: IconPath = getIconPath(element, this._connectionManagementService);
|
||||
let iconPath: IconPath | undefined = getIconPath(element, this._connectionManagementService);
|
||||
if (this._connectionManagementService.isConnected(undefined, element)) {
|
||||
this._connectionStatusBadge.classList.remove('disconnected');
|
||||
this._connectionStatusBadge.classList.add('connected');
|
||||
renderServerIcon(this._icon, iconPath);
|
||||
} else {
|
||||
this._connectionStatusBadge.classList.remove('connected');
|
||||
this._connectionStatusBadge.classList.add('disconnected');
|
||||
renderServerIcon(this._icon, iconPath);
|
||||
}
|
||||
renderServerIcon(this._icon, iconPath);
|
||||
}
|
||||
|
||||
let label = element.title;
|
||||
@@ -156,7 +156,7 @@ class TreeNodeTemplate extends Disposable {
|
||||
set(element: TreeNode) {
|
||||
// Use an explicitly defined iconType first. If not defined, fall back to using nodeType and
|
||||
// other compount indicators instead.
|
||||
let iconName: string = undefined;
|
||||
let iconName: string | undefined = undefined;
|
||||
if (element.iconType) {
|
||||
iconName = (typeof element.iconType === 'string') ? element.iconType : element.iconType.id;
|
||||
} else {
|
||||
@@ -171,7 +171,7 @@ class TreeNodeTemplate extends Disposable {
|
||||
|
||||
let tokens: string[] = [];
|
||||
for (let index = 1; index < this._icon.classList.length; index++) {
|
||||
tokens.push(this._icon.classList.item(index));
|
||||
tokens.push(this._icon.classList.item(index)!);
|
||||
}
|
||||
this._icon.classList.remove(...tokens);
|
||||
this._icon.classList.add('icon');
|
||||
@@ -229,7 +229,7 @@ export class ServerTreeAccessibilityProvider implements IListAccessibilityProvid
|
||||
|
||||
getAriaLabel(element: ServerTreeElement): string | null {
|
||||
if (element instanceof ConnectionProfileGroup) {
|
||||
return element.fullName;
|
||||
return element.fullName ?? null;
|
||||
} else if (element instanceof ConnectionProfile) {
|
||||
return element.title;
|
||||
}
|
||||
@@ -240,22 +240,22 @@ export class ServerTreeAccessibilityProvider implements IListAccessibilityProvid
|
||||
/**
|
||||
* Returns the first parent which contains the className
|
||||
*/
|
||||
function findParentElement(container: HTMLElement, className: string): HTMLElement {
|
||||
let currentElement = container;
|
||||
function findParentElement(container: HTMLElement, className: string): HTMLElement | undefined {
|
||||
let currentElement: HTMLElement | null = container;
|
||||
while (currentElement) {
|
||||
if (currentElement.className.indexOf(className) > -1) {
|
||||
break;
|
||||
}
|
||||
currentElement = currentElement.parentElement;
|
||||
}
|
||||
return currentElement;
|
||||
return withNullAsUndefined(currentElement);
|
||||
}
|
||||
|
||||
function getIconPath(connection: ConnectionProfile, connectionManagementService: IConnectionManagementService): IconPath {
|
||||
function getIconPath(connection: ConnectionProfile, connectionManagementService: IConnectionManagementService): IconPath | undefined {
|
||||
if (!connection) { return undefined; }
|
||||
|
||||
if (connection['iconPath']) {
|
||||
return connection['iconPath'];
|
||||
if (connection.iconPath) {
|
||||
return connection.iconPath;
|
||||
}
|
||||
|
||||
let iconId = connectionManagementService.getConnectionIconId(connection.id);
|
||||
@@ -264,8 +264,8 @@ function getIconPath(connection: ConnectionProfile, connectionManagementService:
|
||||
let providerProperties = connectionManagementService.getProviderProperties(connection.providerName);
|
||||
if (!providerProperties) { return undefined; }
|
||||
|
||||
let iconPath: IconPath = undefined;
|
||||
let pathConfig: URI | IconPath | { id: string, path: IconPath }[] = providerProperties['iconPath'];
|
||||
let iconPath: IconPath | undefined = undefined;
|
||||
let pathConfig: URI | IconPath | { id: string, path: IconPath }[] | undefined = providerProperties['iconPath'];
|
||||
if (Array.isArray(pathConfig)) {
|
||||
for (const e of pathConfig) {
|
||||
if (!e.id || e.id === iconId) {
|
||||
@@ -274,25 +274,18 @@ function getIconPath(connection: ConnectionProfile, connectionManagementService:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (pathConfig['light']) {
|
||||
iconPath = pathConfig as IconPath;
|
||||
connection['iconPath'] = iconPath;
|
||||
} else if (URI.isUri(pathConfig)) {
|
||||
iconPath = { light: pathConfig, dark: pathConfig };
|
||||
connection.iconPath = iconPath;
|
||||
} else {
|
||||
let singlePath = pathConfig as URI;
|
||||
iconPath = { light: singlePath, dark: singlePath };
|
||||
connection['iconPath'] = iconPath;
|
||||
connection.iconPath = pathConfig;
|
||||
}
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
function renderServerIcon(element: HTMLElement, iconPath: IconPath): void {
|
||||
function renderServerIcon(element: HTMLElement, iconPath?: IconPath): void {
|
||||
if (!element) { return; }
|
||||
if (iconPath) {
|
||||
iconRenderer.putIcon(element, iconPath);
|
||||
}
|
||||
}
|
||||
|
||||
interface IconPath {
|
||||
light: URI;
|
||||
dark: URI;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ export function supportsFolderNodeNameDrop(nodeId: string, label: string): boole
|
||||
return false;
|
||||
}
|
||||
|
||||
function escapeString(input: string): string;
|
||||
function escapeString(input: undefined): undefined;
|
||||
function escapeString(input: string | undefined): string | undefined {
|
||||
return input?.replace(/]/g, ']]');
|
||||
}
|
||||
@@ -46,22 +48,22 @@ export class ServerTreeDragAndDrop implements IDragAndDrop {
|
||||
* Returns a uri if the given element should be allowed to drag.
|
||||
* Returns null, otherwise.
|
||||
*/
|
||||
public getDragURI(tree: AsyncServerTree | ITree, element: any): string {
|
||||
public getDragURI(tree: AsyncServerTree | ITree, element: any): string | null {
|
||||
if (element) {
|
||||
if (element instanceof ConnectionProfile) {
|
||||
return (<ConnectionProfile>element).id;
|
||||
return element.id;
|
||||
} else if (element instanceof ConnectionProfileGroup) {
|
||||
return (<ConnectionProfileGroup>element).id;
|
||||
return element.id ?? null;
|
||||
} else if (supportsNodeNameDrop(element.nodeTypeId)) {
|
||||
return (<TreeNode>element).id;
|
||||
} else if (supportsFolderNodeNameDrop(element.nodeTypeId, element.label) && element.children) {
|
||||
return (<TreeNode>element).id;
|
||||
} else {
|
||||
return undefined;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,11 +80,11 @@ export class ServerTreeDragAndDrop implements IDragAndDrop {
|
||||
return elements[0].label;
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +127,7 @@ export class ServerTreeDragAndDrop implements IDragAndDrop {
|
||||
return element.connection.providerName;
|
||||
}
|
||||
|
||||
return this.getProviderNameFromElement(element.parent);
|
||||
return this.getProviderNameFromElement(element.parent!);
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +135,7 @@ export class ServerTreeDragAndDrop implements IDragAndDrop {
|
||||
let canDragOver: boolean = true;
|
||||
|
||||
if (source instanceof ConnectionProfile) {
|
||||
if (!this._connectionManagementService.canChangeConnectionConfig(source, targetConnectionProfileGroup.id)) {
|
||||
if (!this._connectionManagementService.canChangeConnectionConfig(source, targetConnectionProfileGroup.id!)) {
|
||||
canDragOver = false;
|
||||
}
|
||||
} else if (source instanceof ConnectionProfileGroup) {
|
||||
@@ -158,7 +160,7 @@ export class ServerTreeDragAndDrop implements IDragAndDrop {
|
||||
// Verify if the connection can be moved to the target group
|
||||
const source = data.getData()[0];
|
||||
if (source instanceof ConnectionProfile) {
|
||||
if (!this._connectionManagementService.canChangeConnectionConfig(source, targetConnectionProfileGroup.id)) {
|
||||
if (!this._connectionManagementService.canChangeConnectionConfig(source, targetConnectionProfileGroup.id!)) {
|
||||
canDragOver = false;
|
||||
}
|
||||
} else if (source instanceof ConnectionProfileGroup) {
|
||||
@@ -201,7 +203,7 @@ export class ServerTreeDragAndDrop implements IDragAndDrop {
|
||||
|
||||
if (source instanceof ConnectionProfile) {
|
||||
// Change group id of profile
|
||||
this._connectionManagementService.changeGroupIdForConnection(source, targetConnectionProfileGroup.id).then(() => {
|
||||
this._connectionManagementService.changeGroupIdForConnection(source, targetConnectionProfileGroup.id!).then(() => {
|
||||
if (tree) {
|
||||
TreeUpdateUtils.registeredServerUpdate(tree, self._connectionManagementService, targetConnectionProfileGroup);
|
||||
}
|
||||
@@ -224,13 +226,13 @@ export class ServerTreeDragAndDrop implements IDragAndDrop {
|
||||
TreeUpdateUtils.isInDragAndDrop = false;
|
||||
}
|
||||
|
||||
private getTargetGroup(targetElement: any): ConnectionProfileGroup {
|
||||
private getTargetGroup(targetElement: ConnectionProfileGroup | ConnectionProfile): ConnectionProfileGroup {
|
||||
let targetConnectionProfileGroup: ConnectionProfileGroup;
|
||||
if (targetElement instanceof ConnectionProfile) {
|
||||
targetConnectionProfileGroup = (<ConnectionProfile>targetElement).getParent();
|
||||
targetConnectionProfileGroup = targetElement.getParent()!;
|
||||
}
|
||||
else {
|
||||
targetConnectionProfileGroup = <ConnectionProfileGroup>targetElement;
|
||||
targetConnectionProfileGroup = targetElement;
|
||||
}
|
||||
|
||||
return targetConnectionProfileGroup;
|
||||
@@ -256,12 +258,12 @@ export class RecentConnectionsDragAndDrop implements IDragAndDrop {
|
||||
* Returns a uri if the given element should be allowed to drag.
|
||||
* Returns null, otherwise.
|
||||
*/
|
||||
public getDragURI(tree: ITree, element: any): string {
|
||||
public getDragURI(tree: ITree, element: any): string | null {
|
||||
if (element instanceof ConnectionProfile) {
|
||||
return (<ConnectionProfile>element).id;
|
||||
}
|
||||
else if (element instanceof ConnectionProfileGroup) {
|
||||
return (<ConnectionProfileGroup>element).id;
|
||||
return (<ConnectionProfileGroup>element).id ?? null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -276,7 +278,7 @@ export class RecentConnectionsDragAndDrop implements IDragAndDrop {
|
||||
else if (elements[0] instanceof ConnectionProfileGroup) {
|
||||
return (<ConnectionProfileGroup>elements[0]).name;
|
||||
}
|
||||
return undefined;
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,11 +10,11 @@ import { URI } from 'vs/base/common/uri';
|
||||
class IconRenderer {
|
||||
private iconRegistered: Set<string> = new Set<string>();
|
||||
|
||||
public registerIcon(path: URI | IconPath): string {
|
||||
public registerIcon(path: URI | IconPath): string | undefined {
|
||||
if (!path) { return undefined; }
|
||||
let iconPath: IconPath = this.toIconPath(path);
|
||||
let iconUid: string = this.getIconUid(iconPath);
|
||||
if (!this.iconRegistered.has(iconUid)) {
|
||||
let iconUid: string | undefined = this.getIconUid(iconPath);
|
||||
if (iconUid && !this.iconRegistered.has(iconUid)) {
|
||||
createCSSRule(`.icon#${iconUid}`, `background: ${asCSSUrl(iconPath.light || iconPath.dark)} center center no-repeat`);
|
||||
createCSSRule(`.vs-dark .icon#${iconUid}, .hc-black .icon#${iconUid}`, `background: ${asCSSUrl(iconPath.dark)} center center no-repeat`);
|
||||
this.iconRegistered.add(iconUid);
|
||||
@@ -22,30 +22,30 @@ class IconRenderer {
|
||||
return iconUid;
|
||||
}
|
||||
|
||||
public getIconUid(path: URI | IconPath): string {
|
||||
public getIconUid(path: URI | IconPath): string | undefined {
|
||||
if (!path) { return undefined; }
|
||||
let iconPath: IconPath = this.toIconPath(path);
|
||||
return `icon${hash(iconPath.light.toString() + iconPath.dark.toString())}`;
|
||||
}
|
||||
|
||||
private toIconPath(path: URI | IconPath): IconPath {
|
||||
if (path['light']) {
|
||||
return path as IconPath;
|
||||
} else {
|
||||
let singlePath = path as URI;
|
||||
if (URI.isUri(path)) {
|
||||
let singlePath = path;
|
||||
return { light: singlePath, dark: singlePath };
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
public putIcon(element: HTMLElement, path: URI | IconPath): void {
|
||||
if (!element || !path) { return undefined; }
|
||||
let iconUid: string = this.registerIcon(path);
|
||||
element.id = iconUid;
|
||||
let iconUid: string | undefined = this.registerIcon(path);
|
||||
element.id = iconUid ?? '';
|
||||
}
|
||||
|
||||
public removeIcon(element: HTMLElement): void {
|
||||
if (!element) { return undefined; }
|
||||
element.id = undefined;
|
||||
element.id = '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,9 +117,9 @@ class BadgeRenderer {
|
||||
|
||||
public removeBadge(element: HTMLElement, badgeClass: string): void {
|
||||
let children: HTMLCollection = element.children;
|
||||
let current = children[0];
|
||||
let current: Element | null = children[0];
|
||||
while (current) {
|
||||
let next = current.nextElementSibling;
|
||||
let next: Element | null = current.nextElementSibling;
|
||||
if (current.classList.contains(badgeClass)) {
|
||||
current.remove();
|
||||
break;
|
||||
|
||||
@@ -19,10 +19,8 @@ export class RecentConnectionDataSource implements IDataSource {
|
||||
public getId(tree: ITree, element: any): string {
|
||||
if (element instanceof ConnectionProfile) {
|
||||
return (<ConnectionProfile>element).id;
|
||||
} else if (element instanceof ConnectionProfileGroup) {
|
||||
return (<ConnectionProfileGroup>element).id;
|
||||
} else {
|
||||
return undefined;
|
||||
return (<ConnectionProfileGroup>element).id!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,4 +61,4 @@ export class RecentConnectionDataSource implements IDataSource {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ export class ServerTreeController extends treedefaults.DefaultController {
|
||||
context.nodeInfo = element.toNodeInfo();
|
||||
// Note: getting DB name before, but intentionally not using treeUpdateUtils.getConnectionProfile as it replaces
|
||||
// the connection ID with a new one. This breaks a number of internal tasks
|
||||
context.connectionProfile = element.getConnectionProfile().toIConnectionProfile();
|
||||
context.connectionProfile = element.getConnectionProfile()!.toIConnectionProfile();
|
||||
context.connectionProfile.databaseName = element.getDatabaseName();
|
||||
actionContext = context;
|
||||
} else if (element instanceof ConnectionProfile) {
|
||||
|
||||
@@ -30,13 +30,7 @@ export class ServerTreeDataSource implements IDataSource {
|
||||
* No more than one element may use a given identifier.
|
||||
*/
|
||||
public getId(tree: ITree, element: any): string {
|
||||
if (element instanceof ConnectionProfile
|
||||
|| element instanceof ConnectionProfileGroup
|
||||
|| element instanceof TreeNode) {
|
||||
return element.id;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
return element.id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,7 +61,7 @@ export class ServerTreeDataSource implements IDataSource {
|
||||
return node.children;
|
||||
} else {
|
||||
try {
|
||||
return this._objectExplorerService.resolveTreeNodeChildren(node.getSession(), node);
|
||||
return this._objectExplorerService.resolveTreeNodeChildren(node.getSession()!, node);
|
||||
} catch (expandError) {
|
||||
await node.setExpandedState(TreeItemCollapsibleState.Collapsed);
|
||||
node.errorStateMessage = expandError;
|
||||
|
||||
@@ -16,6 +16,7 @@ import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { badgeRenderer, iconRenderer } from 'sql/workbench/services/objectExplorer/browser/iconRenderer';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { DefaultServerGroupColor } from 'sql/workbench/services/serverGroup/common/serverGroupViewModel';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
export interface IConnectionTemplateData {
|
||||
root: HTMLElement;
|
||||
@@ -132,7 +133,7 @@ export class ServerTreeRenderer implements IRenderer {
|
||||
private renderObjectExplorer(treeNode: TreeNode, templateData: IObjectExplorerTemplateData): void {
|
||||
// Use an explicitly defined iconType first. If not defined, fall back to using nodeType and
|
||||
// other compount indicators instead.
|
||||
let iconName: string = undefined;
|
||||
let iconName: string | undefined = undefined;
|
||||
if (treeNode.iconType) {
|
||||
iconName = (typeof treeNode.iconType === 'string') ? treeNode.iconType : treeNode.iconType.id;
|
||||
} else {
|
||||
@@ -147,7 +148,7 @@ export class ServerTreeRenderer implements IRenderer {
|
||||
|
||||
let tokens: string[] = [];
|
||||
for (let index = 1; index < templateData.icon.classList.length; index++) {
|
||||
tokens.push(templateData.icon.classList.item(index));
|
||||
tokens.push(templateData.icon.classList.item(index)!);
|
||||
}
|
||||
templateData.icon.classList.remove(...tokens);
|
||||
templateData.icon.classList.add('icon');
|
||||
@@ -162,11 +163,11 @@ export class ServerTreeRenderer implements IRenderer {
|
||||
templateData.root.title = treeNode.label;
|
||||
}
|
||||
|
||||
private getIconPath(connection: ConnectionProfile): IconPath {
|
||||
private getIconPath(connection: ConnectionProfile): IconPath | undefined {
|
||||
if (!connection) { return undefined; }
|
||||
|
||||
if (connection['iconPath']) {
|
||||
return connection['iconPath'];
|
||||
if (connection.iconPath) {
|
||||
return connection.iconPath;
|
||||
}
|
||||
|
||||
let iconId = this._connectionManagementService.getConnectionIconId(connection.id);
|
||||
@@ -175,8 +176,8 @@ export class ServerTreeRenderer implements IRenderer {
|
||||
let providerProperties = this._connectionManagementService.getProviderProperties(connection.providerName);
|
||||
if (!providerProperties) { return undefined; }
|
||||
|
||||
let iconPath: IconPath = undefined;
|
||||
let pathConfig: URI | IconPath | { id: string, path: IconPath }[] = providerProperties['iconPath'];
|
||||
let iconPath: IconPath | undefined = undefined;
|
||||
let pathConfig: URI | IconPath | { id: string, path: IconPath }[] | undefined = providerProperties.iconPath;
|
||||
if (Array.isArray(pathConfig)) {
|
||||
for (const e of pathConfig) {
|
||||
if (!e.id || e.id === iconId) {
|
||||
@@ -185,18 +186,18 @@ export class ServerTreeRenderer implements IRenderer {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (pathConfig['light']) {
|
||||
iconPath = pathConfig as IconPath;
|
||||
connection['iconPath'] = iconPath;
|
||||
} else {
|
||||
} else if (URI.isUri(pathConfig)) {
|
||||
let singlePath = pathConfig as URI;
|
||||
iconPath = { light: singlePath, dark: singlePath };
|
||||
connection['iconPath'] = iconPath;
|
||||
connection.iconPath = iconPath;
|
||||
} else {
|
||||
iconPath = pathConfig as IconPath;
|
||||
connection.iconPath = iconPath;
|
||||
}
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
private renderServerIcon(element: HTMLElement, iconPath: IconPath, isConnected: boolean): void {
|
||||
private renderServerIcon(element: HTMLElement, iconPath: IconPath | undefined, isConnected: boolean): void {
|
||||
if (!element) { return; }
|
||||
if (iconPath) {
|
||||
iconRenderer.putIcon(element, iconPath);
|
||||
@@ -209,7 +210,7 @@ export class ServerTreeRenderer implements IRenderer {
|
||||
|
||||
private renderConnection(connection: ConnectionProfile, templateData: IConnectionTemplateData): void {
|
||||
if (!this._isCompact) {
|
||||
let iconPath: IconPath = this.getIconPath(connection);
|
||||
let iconPath = this.getIconPath(connection);
|
||||
if (this._connectionManagementService.isConnected(undefined, connection)) {
|
||||
templateData.icon.classList.remove('disconnected');
|
||||
templateData.icon.classList.add('connected');
|
||||
@@ -252,15 +253,15 @@ export class ServerTreeRenderer implements IRenderer {
|
||||
/**
|
||||
* Returns the first parent which contains the className
|
||||
*/
|
||||
private findParentElement(container: HTMLElement, className: string): HTMLElement {
|
||||
let currentElement = container;
|
||||
private findParentElement(container: HTMLElement, className: string): HTMLElement | undefined {
|
||||
let currentElement: HTMLElement | null = container;
|
||||
while (currentElement) {
|
||||
if (currentElement.className.indexOf(className) > -1) {
|
||||
break;
|
||||
}
|
||||
currentElement = currentElement.parentElement;
|
||||
}
|
||||
return currentElement;
|
||||
return withNullAsUndefined(currentElement);
|
||||
}
|
||||
|
||||
public disposeTemplate(tree: ITree, templateId: string, templateData: any): void {
|
||||
|
||||
@@ -142,5 +142,5 @@ export class TreeCreationUtils {
|
||||
}
|
||||
|
||||
function useAsyncServerTree(configurationService: IConfigurationService): boolean {
|
||||
return configurationService.getValue('workbench.enablePreviewFeatures') && configurationService.getValue('serverTree.useAsyncServerTree');
|
||||
return configurationService.getValue<boolean>('workbench.enablePreviewFeatures') && configurationService.getValue<boolean>('serverTree.useAsyncServerTree');
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ suite('AsyncServerTreeDragAndDrop', () => {
|
||||
assert.equal(treeNodeArray[0].label, labelTreeNode);
|
||||
|
||||
let labelUndefined = serverTreeDragAndDrop.getDragLabel(undefined);
|
||||
assert.equal(undefined, labelUndefined);
|
||||
assert.equal('', labelUndefined);
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ suite('SQL Drag And Drop Controller tests', () => {
|
||||
assert.equal(treeNodeArray[0].label, labelTreeNode);
|
||||
|
||||
let labelUndefined = serverTreeDragAndDrop.getDragLabel(testTree, null);
|
||||
assert.equal(undefined, labelUndefined);
|
||||
assert.equal('', labelUndefined);
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -26,18 +26,18 @@ export type ObjectExplorerServiceMockOptions = {
|
||||
*
|
||||
* @param options Options to use for setting up functions on the mock to return various values
|
||||
*/
|
||||
export function createObjectExplorerServiceMock(options: ObjectExplorerServiceMockOptions): TypeMoq.Mock<IObjectExplorerService> {
|
||||
export function createObjectExplorerServiceMock(options: ObjectExplorerServiceMockOptions): IObjectExplorerService {
|
||||
const objectExplorerService = TypeMoq.Mock.ofType(TestObjectExplorerService);
|
||||
|
||||
if (options.treeNode) {
|
||||
objectExplorerService.setup(x => x.getTreeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(options.treeNode));
|
||||
objectExplorerService.setup(x => x.getTreeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(options.treeNode!));
|
||||
}
|
||||
|
||||
if (options.serverTreeView) {
|
||||
objectExplorerService.setup(x => x.getServerTreeView()).returns(() => options.serverTreeView);
|
||||
objectExplorerService.setup(x => x.getServerTreeView()).returns(() => options.serverTreeView!);
|
||||
}
|
||||
|
||||
return objectExplorerService;
|
||||
return objectExplorerService.object;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,13 +49,13 @@ export class TestObjectExplorerService implements IObjectExplorerService {
|
||||
|
||||
constructor() { }
|
||||
|
||||
public getSession(sessionId: string): azdata.ObjectExplorerSession { return undefined; }
|
||||
public getSession(sessionId: string): azdata.ObjectExplorerSession { throw new Error('Method not implemented'); }
|
||||
|
||||
public providerRegistered(providerId: string): boolean { return true; }
|
||||
|
||||
public get onUpdateObjectExplorerNodes(): Event<ObjectExplorerNodeEventArgs> { return undefined; }
|
||||
public get onUpdateObjectExplorerNodes(): Event<ObjectExplorerNodeEventArgs> { throw new Error('Method not implemented'); }
|
||||
|
||||
public get onSelectionOrFocusChange(): Event<void> { return undefined; }
|
||||
public get onSelectionOrFocusChange(): Event<void> { throw new Error('Method not implemented'); }
|
||||
|
||||
public async updateObjectExplorerNodes(connection: IConnectionProfile): Promise<void> { }
|
||||
|
||||
@@ -67,41 +67,41 @@ export class TestObjectExplorerService implements IObjectExplorerService {
|
||||
|
||||
public async onSessionDisconnected(handle: number, session: azdata.ObjectExplorerSession): Promise<void> { }
|
||||
|
||||
public getObjectExplorerNode(connection: IConnectionProfile): TreeNode { return undefined; }
|
||||
public getObjectExplorerNode(connection: IConnectionProfile): TreeNode { throw new Error('Method not implemented'); }
|
||||
|
||||
public async createNewSession(providerId: string, connection: ConnectionProfile): Promise<azdata.ObjectExplorerSessionResponse> { return undefined; }
|
||||
public async createNewSession(providerId: string, connection: ConnectionProfile): Promise<azdata.ObjectExplorerSessionResponse> { throw new Error('Method not implemented'); }
|
||||
|
||||
public async expandNode(providerId: string, session: azdata.ObjectExplorerSession, nodePath: string): Promise<azdata.ObjectExplorerExpandInfo> { return undefined; }
|
||||
public async expandNode(providerId: string, session: azdata.ObjectExplorerSession, nodePath: string): Promise<azdata.ObjectExplorerExpandInfo> { throw new Error('Method not implemented'); }
|
||||
|
||||
public async refreshNode(providerId: string, session: azdata.ObjectExplorerSession, nodePath: string): Promise<azdata.ObjectExplorerExpandInfo> { return undefined; }
|
||||
public async refreshNode(providerId: string, session: azdata.ObjectExplorerSession, nodePath: string): Promise<azdata.ObjectExplorerExpandInfo> { throw new Error('Method not implemented'); }
|
||||
|
||||
public async closeSession(providerId: string, session: azdata.ObjectExplorerSession): Promise<azdata.ObjectExplorerCloseSessionResponse> { return undefined; }
|
||||
public async closeSession(providerId: string, session: azdata.ObjectExplorerSession): Promise<azdata.ObjectExplorerCloseSessionResponse> { throw new Error('Method not implemented'); }
|
||||
|
||||
public registerProvider(providerId: string, provider: azdata.ObjectExplorerProvider): void { }
|
||||
|
||||
public registerNodeProvider(nodeProvider: azdata.ObjectExplorerNodeProvider): void { }
|
||||
|
||||
public async resolveTreeNodeChildren(session: azdata.ObjectExplorerSession, parentTree: TreeNode): Promise<TreeNode[]> { return undefined; }
|
||||
public async resolveTreeNodeChildren(session: azdata.ObjectExplorerSession, parentTree: TreeNode): Promise<TreeNode[]> { throw new Error('Method not implemented'); }
|
||||
|
||||
public async refreshTreeNode(session: azdata.ObjectExplorerSession, parentTree: TreeNode): Promise<TreeNode[]> { return undefined; }
|
||||
public async refreshTreeNode(session: azdata.ObjectExplorerSession, parentTree: TreeNode): Promise<TreeNode[]> { throw new Error('Method not implemented'); }
|
||||
|
||||
public registerServerTreeView(view: IServerTreeView): void { }
|
||||
|
||||
public getSelectedProfileAndDatabase(): { profile: ConnectionProfile, databaseName: string } { return undefined; }
|
||||
public getSelectedProfileAndDatabase(): { profile: ConnectionProfile, databaseName: string } | undefined { return undefined; }
|
||||
|
||||
public isFocused(): boolean { return true; }
|
||||
|
||||
public getServerTreeView(): IServerTreeView { return undefined; }
|
||||
public getServerTreeView(): IServerTreeView { throw new Error('Method not implemented'); }
|
||||
|
||||
public async findNodes(connectionId: string, type: string, schema: string, name: string, database: string, parentObjectNames?: string[]): Promise<azdata.NodeInfo[]> { return undefined; }
|
||||
public async findNodes(connectionId: string, type: string, schema: string, name: string, database: string, parentObjectNames?: string[]): Promise<azdata.NodeInfo[]> { throw new Error('Method not implemented'); }
|
||||
|
||||
public getActiveConnectionNodes(): TreeNode[] { return undefined; }
|
||||
public getActiveConnectionNodes(): TreeNode[] { throw new Error('Method not implemented'); }
|
||||
|
||||
public async getNodeActions(connectionId: string, nodePath: string): Promise<string[]> { return undefined; }
|
||||
public async getNodeActions(connectionId: string, nodePath: string): Promise<string[]> { throw new Error('Method not implemented'); }
|
||||
|
||||
public async refreshNodeInView(connectionId: string, nodePath: string): Promise<TreeNode> { return undefined; }
|
||||
public async refreshNodeInView(connectionId: string, nodePath: string): Promise<TreeNode> { throw new Error('Method not implemented'); }
|
||||
|
||||
public getSessionConnectionProfile(sessionId: string): azdata.IConnectionProfile { return undefined; }
|
||||
public getSessionConnectionProfile(sessionId: string): azdata.IConnectionProfile { throw new Error('Method not implemented'); }
|
||||
|
||||
public async getTreeNode(connectionId: string, nodePath: string): Promise<TreeNode> { return undefined; }
|
||||
public async getTreeNode(connectionId: string, nodePath: string): Promise<TreeNode> { throw new Error('Method not implemented'); }
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export class QueryHistoryInfo {
|
||||
public connectionProfile: IConnectionProfile,
|
||||
public startTime: Date,
|
||||
status?: QueryStatus) {
|
||||
this.database = connectionProfile ? connectionProfile.databaseName : '';
|
||||
this.database = connectionProfile?.databaseName ?? '';
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +319,7 @@ export class RestoreDialogController implements IRestoreDialogController {
|
||||
|
||||
if (this._currentProvider === ConnectionConstants.mssqlProviderName) {
|
||||
let restoreDialog = this._restoreDialogs[this._currentProvider] as RestoreDialog;
|
||||
restoreDialog.viewModel.resetRestoreOptions(connection.databaseName);
|
||||
restoreDialog.viewModel.resetRestoreOptions(connection.databaseName!);
|
||||
this.getMssqlRestoreConfigInfo().then(() => {
|
||||
restoreDialog.open(connection.serverName, this._ownerUri!);
|
||||
restoreDialog.validateRestore();
|
||||
|
||||
@@ -77,7 +77,7 @@ export class TaskService implements ITaskService {
|
||||
}
|
||||
|
||||
public createNewTask(taskInfo: azdata.TaskInfo) {
|
||||
let databaseName: string = taskInfo.databaseName;
|
||||
let databaseName: string | undefined = taskInfo.databaseName;
|
||||
let serverName: string = taskInfo.serverName;
|
||||
if (taskInfo && taskInfo.connection) {
|
||||
let connectionProfile = this.connectionManagementService.getConnectionProfile(taskInfo.connection.connectionId);
|
||||
|
||||
@@ -12,24 +12,24 @@ import { IItemExpandEvent, IItemCollapseEvent } from 'vs/base/parts/tree/browser
|
||||
*/
|
||||
export class TestTree implements ITree {
|
||||
|
||||
readonly onDidChangeFocus: Event<IFocusEvent>;
|
||||
readonly onDidChangeSelection: Event<ISelectionEvent>;
|
||||
readonly onDidChangeHighlight: Event<IHighlightEvent>;
|
||||
readonly onDidExpandItem: Event<IItemExpandEvent>;
|
||||
readonly onDidCollapseItem: Event<IItemCollapseEvent>;
|
||||
readonly onDidDispose: Event<void>;
|
||||
readonly onDidChangeFocus: Event<IFocusEvent> = Event.None;
|
||||
readonly onDidChangeSelection: Event<ISelectionEvent> = Event.None;
|
||||
readonly onDidChangeHighlight: Event<IHighlightEvent> = Event.None;
|
||||
readonly onDidExpandItem: Event<IItemExpandEvent> = Event.None;
|
||||
readonly onDidCollapseItem: Event<IItemCollapseEvent> = Event.None;
|
||||
readonly onDidDispose: Event<void> = Event.None;
|
||||
|
||||
constructor() { }
|
||||
|
||||
public style(styles: ITreeStyles): void { }
|
||||
|
||||
get onDidFocus(): Event<void> { return undefined; }
|
||||
get onDidFocus(): Event<void> { return Event.None; }
|
||||
|
||||
get onDidBlur(): Event<void> { return undefined; }
|
||||
get onDidBlur(): Event<void> { return Event.None; }
|
||||
|
||||
get onDidScroll(): Event<void> { return undefined; }
|
||||
get onDidScroll(): Event<void> { return Event.None; }
|
||||
|
||||
public getHTMLElement(): HTMLElement { return undefined; }
|
||||
public getHTMLElement(): HTMLElement { throw new Error('Method not implemented'); }
|
||||
|
||||
public layout(height?: number, width?: number): void { }
|
||||
|
||||
@@ -113,7 +113,7 @@ export class TestTree implements ITree {
|
||||
|
||||
public deselect(element: any, eventPayload?: any): void { }
|
||||
|
||||
getNavigator(fromElement?: any, subTreeOnly?: boolean): INavigator<any> { return undefined; }
|
||||
getNavigator(fromElement?: any, subTreeOnly?: boolean): INavigator<any> { throw new Error('Method not implemented'); }
|
||||
|
||||
public dispose(): void { }
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@
|
||||
"./sql/workbench/contrib/profiler/**/*.ts", // 100 errors
|
||||
"./sql/workbench/contrib/query/**/*.ts", // 3077 errors
|
||||
"./sql/workbench/contrib/queryHistory/**/*.ts", // 290 errors
|
||||
"./sql/workbench/contrib/scripting/**/*.ts", // 179 errors
|
||||
"./sql/workbench/contrib/welcome/**/*.ts", // 66 errors
|
||||
"./sql/workbench/services/connection/**/*.ts", // 3130 errors
|
||||
"./sql/workbench/services/dialog/**/*.ts", // 2995 errors
|
||||
|
||||
Reference in New Issue
Block a user