Fixes #1856 Object Explorer needs Icons field for nodes separate from… (#1901)

* Fixes #1856 Object Explorer needs Icons field for nodes separate from type/subtype
- Adds in the concept of a themeable icon path which matches VSCode's implementation. This should help support theme-based overrides in the future
This commit is contained in:
Kevin Cunnane
2018-07-11 11:24:35 -07:00
committed by GitHub
parent 0ddb326e44
commit e99101447e
9 changed files with 281 additions and 55 deletions

View File

@@ -95,3 +95,7 @@ export class NodeType {
public static ColumnMasterKey = 'ColumnMasterKey';
public static ColumnEncryptionKey = 'ColumnEncryptionKey';
}
export interface SqlThemeIcon {
readonly id: string;
}

View File

@@ -5,7 +5,7 @@
'use strict';
import { NodeType } from 'sql/parts/objectExplorer/common/nodeType';
import { TreeNode, TreeItemCollapsibleState, ObjectExplorerCallbacks } from 'sql/parts/objectExplorer/common/treeNode';
import { TreeNode, TreeItemCollapsibleState } from 'sql/parts/objectExplorer/common/treeNode';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
@@ -20,7 +20,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { warn, error } from 'sql/base/common/log';
import { ServerTreeView } from 'sql/parts/objectExplorer/viewlet/serverTreeView';
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
import * as vscode from 'vscode';
export const SERVICE_ID = 'ObjectExplorerService';
@@ -402,7 +401,7 @@ export class ObjectExplorerService implements IObjectExplorerService {
}
return new TreeNode(nodeInfo.nodeType, nodeInfo.label, isLeaf, nodeInfo.nodePath,
nodeInfo.nodeSubType, nodeInfo.nodeStatus, parent, nodeInfo.metadata, {
nodeInfo.nodeSubType, nodeInfo.nodeStatus, parent, nodeInfo.metadata, nodeInfo.iconType, {
getChildren: treeNode => this.getChildren(treeNode),
isExpanded: treeNode => this.isExpanded(treeNode),
setNodeExpandedState: (treeNode, expandedState) => this.setNodeExpandedState(treeNode, expandedState),

View File

@@ -6,7 +6,7 @@
'use strict';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { NodeType } from 'sql/parts/objectExplorer/common/nodeType';
import { NodeType, SqlThemeIcon } from 'sql/parts/objectExplorer/common/nodeType';
import * as sqlops from 'sqlops';
import * as UUID from 'vs/base/common/uuid';
@@ -83,6 +83,23 @@ export class TreeNode {
public metadata: sqlops.ObjectMetadata;
public iconType: string | SqlThemeIcon;
constructor(nodeTypeId: string, label: string, isAlwaysLeaf: boolean, nodePath: string,
nodeSubType: string, nodeStatus: string, parent: TreeNode, metadata: sqlops.ObjectMetadata,
iconType: string | SqlThemeIcon,
private _objectExplorerCallbacks: ObjectExplorerCallbacks) {
this.nodeTypeId = nodeTypeId;
this.label = label;
this.isAlwaysLeaf = isAlwaysLeaf;
this.nodePath = nodePath;
this.parent = parent;
this.metadata = metadata;
this.iconType = iconType;
this.id = UUID.generateUuid();
this.nodeSubType = nodeSubType;
this.nodeStatus = nodeStatus;
}
public getConnectionProfile(): ConnectionProfile {
var currentNode: TreeNode = this;
while (!currentNode.connection && currentNode.parent) {
@@ -149,18 +166,4 @@ export class TreeNode {
public setSelected(selected: boolean, clearOtherSelections?: boolean): Thenable<void> {
return this._objectExplorerCallbacks.setNodeSelected(this, selected, clearOtherSelections);
}
constructor(nodeTypeId: string, label: string, isAlwaysLeaf: boolean, nodePath: string,
nodeSubType: string, nodeStatus: string, parent: TreeNode, metadata: sqlops.ObjectMetadata,
private _objectExplorerCallbacks: ObjectExplorerCallbacks) {
this.nodeTypeId = nodeTypeId;
this.label = label;
this.isAlwaysLeaf = isAlwaysLeaf;
this.nodePath = nodePath;
this.parent = parent;
this.metadata = metadata;
this.id = UUID.generateUuid();
this.nodeSubType = nodeSubType;
this.nodeStatus = nodeStatus;
}
}

View File

@@ -105,38 +105,45 @@ export class ServerTreeRenderer implements IRenderer {
*/
public renderElement(tree: ITree, element: any, templateId: string, templateData: any): void {
if (templateId === ServerTreeRenderer.CONNECTION_TEMPLATE_ID) {
this.renderConnection(tree, element, templateData);
this.renderConnection(element, templateData);
} else if (templateId === ServerTreeRenderer.CONNECTION_GROUP_TEMPLATE_ID) {
this.renderConnectionProfileGroup(tree, element, templateData);
this.renderConnectionProfileGroup(element, templateData);
} else {
this.renderObjectExplorer(tree, element, templateData);
this.renderObjectExplorer(element, templateData);
}
}
private renderObjectExplorer(tree: ITree, treeNode: TreeNode, templateData: IObjectExplorerTemplateData): void {
var iconName = treeNode.nodeTypeId;
if (treeNode.nodeStatus) {
iconName = treeNode.nodeTypeId + '_' + treeNode.nodeStatus;
}
if (treeNode.nodeSubType) {
iconName = treeNode.nodeTypeId + '_' + treeNode.nodeSubType;
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;
if (treeNode.iconType) {
iconName = (typeof treeNode.iconType === 'string') ? treeNode.iconType : treeNode.iconType.id;
} else {
iconName = treeNode.nodeTypeId;
if (treeNode.nodeStatus) {
iconName = treeNode.nodeTypeId + '_' + treeNode.nodeStatus;
}
if (treeNode.nodeSubType) {
iconName = treeNode.nodeTypeId + '_' + treeNode.nodeSubType;
}
}
let tokens: string[] = [];
for (var index = 1; index < templateData.icon.classList.length; index++) {
for (let index = 1; index < templateData.icon.classList.length; index++) {
tokens.push(templateData.icon.classList.item(index));
}
templateData.icon.classList.remove(...tokens);
templateData.icon.classList.add('icon');
let iconLoweCaseName = iconName.toLocaleLowerCase();
templateData.icon.classList.add(iconLoweCaseName);
let iconLowerCaseName = iconName.toLocaleLowerCase();
templateData.icon.classList.add(iconLowerCaseName);
templateData.label.textContent = treeNode.label;
templateData.root.title = treeNode.label;
}
private renderConnection(tree: ITree, connection: ConnectionProfile, templateData: IConnectionTemplateData): void {
private renderConnection(connection: ConnectionProfile, templateData: IConnectionTemplateData): void {
if (!this._isCompact) {
if (this._connectionManagementService.isConnected(undefined, connection)) {
templateData.icon.classList.remove('disconnected');
@@ -157,9 +164,9 @@ export class ServerTreeRenderer implements IRenderer {
templateData.connectionProfile = connection;
}
private renderConnectionProfileGroup(tree: ITree, connectionProfileGroup: ConnectionProfileGroup, templateData: IConnectionProfileGroupTemplateData): void {
private renderConnectionProfileGroup(connectionProfileGroup: ConnectionProfileGroup, templateData: IConnectionProfileGroupTemplateData): void {
var rowElement = this.findParentElement(templateData.root, 'monaco-tree-row');
let rowElement = this.findParentElement(templateData.root, 'monaco-tree-row');
if (rowElement) {
if (connectionProfileGroup.color) {
rowElement.style.background = connectionProfileGroup.color;
@@ -179,7 +186,7 @@ export class ServerTreeRenderer implements IRenderer {
* Returns the first parent which contains the className
*/
private findParentElement(container: HTMLElement, className: string): HTMLElement {
var currentElement = container;
let currentElement = container;
while (currentElement) {
if (currentElement.className.includes(className)) {
break;

114
src/sql/sqlops.d.ts vendored
View File

@@ -928,6 +928,10 @@ declare module 'sqlops' {
subset: EditRow[];
}
/**
* A NodeInfo object represents an element in the Object Explorer tree under
* a connection.
*/
export interface NodeInfo {
nodePath: string;
nodeType: string;
@@ -937,6 +941,116 @@ declare module 'sqlops' {
isLeaf: boolean;
metadata: ObjectMetadata;
errorMessage: string;
/**
* Optional iconType for the object in the tree. Currently this only supports
* an icon name or SqlThemeIcon name, rather than a path to an icon.
* If not defined, the nodeType + nodeStatus / nodeSubType values
* will be used instead.
*/
iconType?: string | SqlThemeIcon;
}
/**
* A reference to a named icon. Currently only a subset of the SQL icons are available.
* Using a theme icon is preferred over a custom icon as it gives theme authors the possibility to change the icons.
*/
export class SqlThemeIcon {
static readonly Folder: SqlThemeIcon;
static readonly Root: SqlThemeIcon;
static readonly Database: SqlThemeIcon;
static readonly Server: SqlThemeIcon;
static readonly ScalarValuedFunction: SqlThemeIcon;
static readonly TableValuedFunction: SqlThemeIcon;
static readonly AggregateFunction: SqlThemeIcon;
static readonly FileGroup: SqlThemeIcon;
static readonly StoredProcedure: SqlThemeIcon;
static readonly UserDefinedTableType: SqlThemeIcon;
static readonly View: SqlThemeIcon;
static readonly Table: SqlThemeIcon;
static readonly HistoryTable: SqlThemeIcon;
static readonly ServerLevelLinkedServerLogin: SqlThemeIcon;
static readonly ServerLevelServerAudit: SqlThemeIcon;
static readonly ServerLevelCryptographicProvider: SqlThemeIcon;
static readonly ServerLevelCredential: SqlThemeIcon;
static readonly ServerLevelServerRole: SqlThemeIcon;
static readonly ServerLevelLogin: SqlThemeIcon;
static readonly ServerLevelServerAuditSpecification: SqlThemeIcon;
static readonly ServerLevelServerTrigger: SqlThemeIcon;
static readonly ServerLevelLinkedServer: SqlThemeIcon;
static readonly ServerLevelEndpoint: SqlThemeIcon;
static readonly Synonym: SqlThemeIcon;
static readonly DatabaseTrigger: SqlThemeIcon;
static readonly Assembly: SqlThemeIcon;
static readonly MessageType: SqlThemeIcon;
static readonly Contract: SqlThemeIcon;
static readonly Queue: SqlThemeIcon;
static readonly Service: SqlThemeIcon;
static readonly Route: SqlThemeIcon;
static readonly DatabaseAndQueueEventNotification: SqlThemeIcon;
static readonly RemoteServiceBinding: SqlThemeIcon;
static readonly BrokerPriority: SqlThemeIcon;
static readonly FullTextCatalog: SqlThemeIcon;
static readonly FullTextStopList: SqlThemeIcon;
static readonly SqlLogFile: SqlThemeIcon;
static readonly PartitionFunction: SqlThemeIcon;
static readonly PartitionScheme: SqlThemeIcon;
static readonly SearchPropertyList: SqlThemeIcon;
static readonly User: SqlThemeIcon;
static readonly Schema: SqlThemeIcon;
static readonly AsymmetricKey: SqlThemeIcon;
static readonly Certificate: SqlThemeIcon;
static readonly SymmetricKey: SqlThemeIcon;
static readonly DatabaseEncryptionKey: SqlThemeIcon;
static readonly MasterKey: SqlThemeIcon;
static readonly DatabaseAuditSpecification: SqlThemeIcon;
static readonly Column: SqlThemeIcon;
static readonly Key: SqlThemeIcon;
static readonly Constraint: SqlThemeIcon;
static readonly Trigger: SqlThemeIcon;
static readonly Index: SqlThemeIcon;
static readonly Statistic: SqlThemeIcon;
static readonly UserDefinedDataType: SqlThemeIcon;
static readonly UserDefinedType: SqlThemeIcon;
static readonly XmlSchemaCollection: SqlThemeIcon;
static readonly SystemExactNumeric: SqlThemeIcon;
static readonly SystemApproximateNumeric: SqlThemeIcon;
static readonly SystemDateAndTime: SqlThemeIcon;
static readonly SystemCharacterString: SqlThemeIcon;
static readonly SystemUnicodeCharacterString: SqlThemeIcon;
static readonly SystemBinaryString: SqlThemeIcon;
static readonly SystemOtherDataType: SqlThemeIcon;
static readonly SystemClrDataType: SqlThemeIcon;
static readonly SystemSpatialDataType: SqlThemeIcon;
static readonly UserDefinedTableTypeColumn: SqlThemeIcon;
static readonly UserDefinedTableTypeKey: SqlThemeIcon;
static readonly UserDefinedTableTypeConstraint: SqlThemeIcon;
static readonly StoredProcedureParameter: SqlThemeIcon;
static readonly TableValuedFunctionParameter: SqlThemeIcon;
static readonly ScalarValuedFunctionParameter: SqlThemeIcon;
static readonly AggregateFunctionParameter: SqlThemeIcon;
static readonly DatabaseRole: SqlThemeIcon;
static readonly ApplicationRole: SqlThemeIcon;
static readonly FileGroupFile: SqlThemeIcon;
static readonly SystemMessageType: SqlThemeIcon;
static readonly SystemContract: SqlThemeIcon;
static readonly SystemService: SqlThemeIcon;
static readonly SystemQueue: SqlThemeIcon;
static readonly Sequence: SqlThemeIcon;
static readonly SecurityPolicy: SqlThemeIcon;
static readonly DatabaseScopedCredential: SqlThemeIcon;
static readonly ExternalResource: SqlThemeIcon;
static readonly ExternalDataSource: SqlThemeIcon;
static readonly ExternalFileFormat: SqlThemeIcon;
static readonly ExternalTable: SqlThemeIcon;
static readonly ColumnMasterKey: SqlThemeIcon;
static readonly ColumnEncryptionKey: SqlThemeIcon;
private constructor(id: string);
/**
* Gets the ID for the theme icon for help in cases where string comparison is needed
*/
public readonly id: string;
}
// Object Explorer interfaces -----------------------------------------------------------------------

View File

@@ -277,4 +277,102 @@ export enum DeclarativeDataType {
export enum CardType {
VerticalButton = 'VerticalButton',
Details = 'Details'
}
}
export class SqlThemeIcon {
static readonly Folder = new SqlThemeIcon('Folder');
static readonly Root = new SqlThemeIcon('root');
static readonly Database = new SqlThemeIcon('Database');
static readonly Server = new SqlThemeIcon('Server');
static readonly ScalarValuedFunction = new SqlThemeIcon('ScalarValuedFunction');
static readonly TableValuedFunction = new SqlThemeIcon('TableValuedFunction');
static readonly AggregateFunction = new SqlThemeIcon('AggregateFunction');
static readonly FileGroup = new SqlThemeIcon('FileGroup');
static readonly StoredProcedure = new SqlThemeIcon('StoredProcedure');
static readonly UserDefinedTableType = new SqlThemeIcon('UserDefinedTableType');
static readonly View = new SqlThemeIcon('View');
static readonly Table = new SqlThemeIcon('Table');
static readonly HistoryTable = new SqlThemeIcon('HistoryTable');
static readonly ServerLevelLinkedServerLogin = new SqlThemeIcon('ServerLevelLinkedServerLogin');
static readonly ServerLevelServerAudit = new SqlThemeIcon('ServerLevelServerAudit');
static readonly ServerLevelCryptographicProvider = new SqlThemeIcon('ServerLevelCryptographicProvider');
static readonly ServerLevelCredential = new SqlThemeIcon('ServerLevelCredential');
static readonly ServerLevelServerRole = new SqlThemeIcon('ServerLevelServerRole');
static readonly ServerLevelLogin = new SqlThemeIcon('ServerLevelLogin');
static readonly ServerLevelServerAuditSpecification = new SqlThemeIcon('ServerLevelServerAuditSpecification');
static readonly ServerLevelServerTrigger = new SqlThemeIcon('ServerLevelServerTrigger');
static readonly ServerLevelLinkedServer = new SqlThemeIcon('ServerLevelLinkedServer');
static readonly ServerLevelEndpoint = new SqlThemeIcon('ServerLevelEndpoint');
static readonly Synonym = new SqlThemeIcon('Synonym');
static readonly DatabaseTrigger = new SqlThemeIcon('DatabaseTrigger');
static readonly Assembly = new SqlThemeIcon('Assembly');
static readonly MessageType = new SqlThemeIcon('MessageType');
static readonly Contract = new SqlThemeIcon('Contract');
static readonly Queue = new SqlThemeIcon('Queue');
static readonly Service = new SqlThemeIcon('Service');
static readonly Route = new SqlThemeIcon('Route');
static readonly DatabaseAndQueueEventNotification = new SqlThemeIcon('DatabaseAndQueueEventNotification');
static readonly RemoteServiceBinding = new SqlThemeIcon('RemoteServiceBinding');
static readonly BrokerPriority = new SqlThemeIcon('BrokerPriority');
static readonly FullTextCatalog = new SqlThemeIcon('FullTextCatalog');
static readonly FullTextStopList = new SqlThemeIcon('FullTextStopList');
static readonly SqlLogFile = new SqlThemeIcon('SqlLogFile');
static readonly PartitionFunction = new SqlThemeIcon('PartitionFunction');
static readonly PartitionScheme = new SqlThemeIcon('PartitionScheme');
static readonly SearchPropertyList = new SqlThemeIcon('SearchPropertyList');
static readonly User = new SqlThemeIcon('User');
static readonly Schema = new SqlThemeIcon('Schema');
static readonly AsymmetricKey = new SqlThemeIcon('AsymmetricKey');
static readonly Certificate = new SqlThemeIcon('Certificate');
static readonly SymmetricKey = new SqlThemeIcon('SymmetricKey');
static readonly DatabaseEncryptionKey = new SqlThemeIcon('DatabaseEncryptionKey');
static readonly MasterKey = new SqlThemeIcon('MasterKey');
static readonly DatabaseAuditSpecification = new SqlThemeIcon('DatabaseAuditSpecification');
static readonly Column = new SqlThemeIcon('Column');
static readonly Key = new SqlThemeIcon('Key');
static readonly Constraint = new SqlThemeIcon('Constraint');
static readonly Trigger = new SqlThemeIcon('Trigger');
static readonly Index = new SqlThemeIcon('Index');
static readonly Statistic = new SqlThemeIcon('Statistic');
static readonly UserDefinedDataType = new SqlThemeIcon('UserDefinedDataType');
static readonly UserDefinedType = new SqlThemeIcon('UserDefinedType');
static readonly XmlSchemaCollection = new SqlThemeIcon('XmlSchemaCollection');
static readonly SystemExactNumeric = new SqlThemeIcon('SystemExactNumeric');
static readonly SystemApproximateNumeric = new SqlThemeIcon('SystemApproximateNumeric');
static readonly SystemDateAndTime = new SqlThemeIcon('SystemDateAndTime');
static readonly SystemCharacterString = new SqlThemeIcon('SystemCharacterString');
static readonly SystemUnicodeCharacterString = new SqlThemeIcon('SystemUnicodeCharacterString');
static readonly SystemBinaryString = new SqlThemeIcon('SystemBinaryString');
static readonly SystemOtherDataType = new SqlThemeIcon('SystemOtherDataType');
static readonly SystemClrDataType = new SqlThemeIcon('SystemClrDataType');
static readonly SystemSpatialDataType = new SqlThemeIcon('SystemSpatialDataType');
static readonly UserDefinedTableTypeColumn = new SqlThemeIcon('UserDefinedTableTypeColumn');
static readonly UserDefinedTableTypeKey = new SqlThemeIcon('UserDefinedTableTypeKey');
static readonly UserDefinedTableTypeConstraint = new SqlThemeIcon('UserDefinedTableTypeConstraint');
static readonly StoredProcedureParameter = new SqlThemeIcon('StoredProcedureParameter');
static readonly TableValuedFunctionParameter = new SqlThemeIcon('TableValuedFunctionParameter');
static readonly ScalarValuedFunctionParameter = new SqlThemeIcon('ScalarValuedFunctionParameter');
static readonly AggregateFunctionParameter = new SqlThemeIcon('AggregateFunctionParameter');
static readonly DatabaseRole = new SqlThemeIcon('DatabaseRole');
static readonly ApplicationRole = new SqlThemeIcon('ApplicationRole');
static readonly FileGroupFile = new SqlThemeIcon('FileGroupFile');
static readonly SystemMessageType = new SqlThemeIcon('SystemMessageType');
static readonly SystemContract = new SqlThemeIcon('SystemContract');
static readonly SystemService = new SqlThemeIcon('SystemService');
static readonly SystemQueue = new SqlThemeIcon('SystemQueue');
static readonly Sequence = new SqlThemeIcon('Sequence');
static readonly SecurityPolicy = new SqlThemeIcon('SecurityPolicy');
static readonly DatabaseScopedCredential = new SqlThemeIcon('DatabaseScopedCredential');
static readonly ExternalResource = new SqlThemeIcon('ExternalResource');
static readonly ExternalDataSource = new SqlThemeIcon('ExternalDataSource');
static readonly ExternalFileFormat = new SqlThemeIcon('ExternalFileFormat');
static readonly ExternalTable = new SqlThemeIcon('ExternalTable');
static readonly ColumnMasterKey = new SqlThemeIcon('ColumnMasterKey');
static readonly ColumnEncryptionKey = new SqlThemeIcon('ColumnEncryptionKey');
public readonly id: string;
private constructor(id: string) {
this.id = id;
}
}

View File

@@ -400,7 +400,8 @@ export function createApiFactory(
queryeditor: queryEditor,
ui: ui,
StatusIndicator: sqlExtHostTypes.StatusIndicator,
CardType: sqlExtHostTypes.CardType
CardType: sqlExtHostTypes.CardType,
SqlThemeIcon: sqlExtHostTypes.SqlThemeIcon
};
}
};