`;
+ }
+
+ public removeBadge(element: HTMLElement, badgeClass: string): void {
+ let children: HTMLCollection = element.children;
+ let current = children[0];
+ while (current) {
+ let next = current.nextElementSibling;
+ if (current.classList.contains(badgeClass)) {
+ current.remove();
+ break;
+ }
+ current = next;
+ }
+ }
+}
+
+export const badgeRenderer: BadgeRenderer = new BadgeRenderer();
+
+interface IconPath {
+ light: URI;
+ dark: URI;
+}
diff --git a/src/sql/workbench/parts/objectExplorer/browser/serverTreeRenderer.ts b/src/sql/workbench/parts/objectExplorer/browser/serverTreeRenderer.ts
index a4e309c329..e5c5312bd7 100644
--- a/src/sql/workbench/parts/objectExplorer/browser/serverTreeRenderer.ts
+++ b/src/sql/workbench/parts/objectExplorer/browser/serverTreeRenderer.ts
@@ -14,6 +14,9 @@ import { ITree, IRenderer } from 'vs/base/parts/tree/browser/tree';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { TreeNode } from 'sql/workbench/parts/objectExplorer/common/treeNode';
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
+import { badgeRenderer, iconRenderer } from 'sql/workbench/parts/objectExplorer/browser/iconRenderer';
+import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
+import { URI } from 'vs/base/common/uri';
export interface IConnectionTemplateData {
root: HTMLElement;
@@ -56,7 +59,8 @@ export class ServerTreeRenderer implements IRenderer {
constructor(
isCompact: boolean,
- @IConnectionManagementService private _connectionManagementService: IConnectionManagementService
+ @IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
+ @IContextKeyService private _contextKeyService: IContextKeyService
) {
// isCompact defaults to false unless explicitly set by instantiation call.
if (isCompact) {
@@ -152,19 +156,70 @@ export class ServerTreeRenderer implements IRenderer {
let iconLowerCaseName = iconName.toLocaleLowerCase();
templateData.icon.classList.add(iconLowerCaseName);
+ if (treeNode.iconPath) {
+ iconRenderer.putIcon(templateData.icon, treeNode.iconPath);
+ }
+
templateData.label.textContent = treeNode.label;
templateData.root.title = treeNode.label;
}
+ private getIconPath(connection: ConnectionProfile): IconPath {
+ if (!connection) { return undefined; }
+
+ if (connection['iconPath']) {
+ return connection['iconPath'];
+ }
+
+ let iconId = this._connectionManagementService.getConnectionIconId(connection.id);
+ if (!iconId) { return undefined; }
+
+ 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'];
+ if (Array.isArray(pathConfig)) {
+ for (const e of pathConfig) {
+ if (!e.id || e.id === iconId) {
+ iconPath = e.path;
+ connection['iconPath'] = iconPath;
+ break;
+ }
+ }
+ } else if (pathConfig['light']) {
+ iconPath = pathConfig as IconPath;
+ connection['iconPath'] = iconPath;
+ } else {
+ let singlePath = pathConfig as URI;
+ iconPath = { light: singlePath, dark: singlePath };
+ connection['iconPath'] = iconPath;
+ }
+ return iconPath;
+ }
+
+ private renderServerIcon(element: HTMLElement, iconPath: IconPath, isConnected: boolean): void {
+ if (!element) { return; }
+ if (iconPath) {
+ iconRenderer.putIcon(element, iconPath);
+ }
+ let badgeToRemove: string = isConnected ? badgeRenderer.serverDisconnected : badgeRenderer.serverConnected;
+ let badgeToAdd: string = isConnected ? badgeRenderer.serverConnected : badgeRenderer.serverDisconnected;
+ badgeRenderer.removeBadge(element, badgeToRemove);
+ badgeRenderer.addBadge(element, badgeToAdd);
+ }
private renderConnection(connection: ConnectionProfile, templateData: IConnectionTemplateData): void {
if (!this._isCompact) {
+ let iconPath: IconPath = this.getIconPath(connection);
if (this._connectionManagementService.isConnected(undefined, connection)) {
templateData.icon.classList.remove('disconnected');
templateData.icon.classList.add('connected');
+ this.renderServerIcon(templateData.icon, iconPath, true);
} else {
templateData.icon.classList.remove('connected');
templateData.icon.classList.add('disconnected');
+ this.renderServerIcon(templateData.icon, iconPath, false);
}
}
@@ -217,3 +272,7 @@ export class ServerTreeRenderer implements IRenderer {
}
}
+interface IconPath {
+ light: URI;
+ dark: URI;
+}
diff --git a/src/sql/workbench/parts/objectExplorer/common/treeNode.ts b/src/sql/workbench/parts/objectExplorer/common/treeNode.ts
index 833efc8fcd..58a863a8b8 100644
--- a/src/sql/workbench/parts/objectExplorer/common/treeNode.ts
+++ b/src/sql/workbench/parts/objectExplorer/common/treeNode.ts
@@ -8,6 +8,7 @@ import { NodeType, SqlThemeIcon } from 'sql/workbench/parts/objectExplorer/commo
import * as azdata from 'sqlops';
import * as UUID from 'vs/base/common/uuid';
+import { URI } from 'vs/base/common/uri';
export enum TreeItemCollapsibleState {
None = 0,
@@ -91,6 +92,8 @@ export class TreeNode {
public iconType: string | SqlThemeIcon;
+ public iconPath: URI | { light: URI, dark: URI };
+
constructor(nodeTypeId: string, label: string, isAlwaysLeaf: boolean, nodePath: string,
nodeSubType: string, nodeStatus: string, parent: TreeNode, metadata: azdata.ObjectMetadata,
iconType: string | SqlThemeIcon,
diff --git a/src/sqltest/stubs/connectionManagementService.test.ts b/src/sqltest/stubs/connectionManagementService.test.ts
index fdaf10752d..19effabca3 100644
--- a/src/sqltest/stubs/connectionManagementService.test.ts
+++ b/src/sqltest/stubs/connectionManagementService.test.ts
@@ -11,6 +11,8 @@ import { ConnectionProfile } from 'sql/platform/connection/common/connectionProf
import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo';
import * as azdata from 'azdata';
import { Event, Emitter } from 'vs/base/common/event';
+import { isUndefinedOrNull } from 'vs/base/common/types';
+import { ConnectionProviderProperties } from 'sql/workbench/parts/connection/common/connectionProviderExtension';
// Test stubs for commonly used objects
@@ -35,6 +37,10 @@ export class TestConnectionManagementService implements IConnectionManagementSer
}
+ registerIconProvider(providerId: string, provider: azdata.IconProvider): void {
+
+ }
+
showConnectionDialog(params?: INewConnectionParams, model?: IConnectionProfile, connectionResult?: IConnectionResult): Promise {
return undefined;
}
@@ -273,4 +279,12 @@ export class TestConnectionManagementService implements IConnectionManagementSer
getConnectionProfileById(profileId: string): IConnectionProfile {
return undefined;
}
+
+ getProviderProperties(providerName: string): ConnectionProviderProperties {
+ return undefined;
+ }
+
+ getConnectionIconId(connectionId: string): string {
+ return undefined;
+ }
}
\ No newline at end of file