diff --git a/src/sql/parts/dashboard/widgets/tasks/tasksWidget.component.ts b/src/sql/parts/dashboard/widgets/tasks/tasksWidget.component.ts
index c77b6ba701..5bb88a043b 100644
--- a/src/sql/parts/dashboard/widgets/tasks/tasksWidget.component.ts
+++ b/src/sql/parts/dashboard/widgets/tasks/tasksWidget.component.ts
@@ -52,6 +52,7 @@ export class TasksWidget extends DashboardWidget implements IDashboardWidget, On
private _profile: IConnectionProfile;
private _scrollableElement: ScrollableElement;
private $container: Builder;
+ static readonly ICON_PATH_TO_CSS_RULES: Map = new Map();
private _inited = false;
@@ -131,9 +132,9 @@ export class TasksWidget extends DashboardWidget implements IDashboardWidget, On
let tile = $('div.task-tile').style('height', this._size + 'px').style('width', this._size + 'px');
let innerTile = $('div');
- // @SQLTODO - iconPath shouldn't be used as a CSS class
- if (action.iconPath && action.iconPath.dark) {
- let icon = $('span.icon').addClass(action.iconPath.dark);
+ let iconClassName = TaskRegistry.getOrCreateTaskIconClassName(action);
+ if (iconClassName) {
+ let icon = $('span.icon').addClass(iconClassName);
innerTile.append(icon);
}
innerTile.append(label);
diff --git a/src/sql/parts/profiler/contrib/profilerActions.ts b/src/sql/parts/profiler/contrib/profilerActions.ts
index 1a208e32fa..31f6b52dcc 100644
--- a/src/sql/parts/profiler/contrib/profilerActions.ts
+++ b/src/sql/parts/profiler/contrib/profilerActions.ts
@@ -238,7 +238,8 @@ export class NewProfilerAction extends Task {
super({
id: NewProfilerAction.ID,
title: NewProfilerAction.LABEL,
- iconPath: { dark: NewProfilerAction.ICON, light: NewProfilerAction.ICON }
+ iconPath: { dark: NewProfilerAction.ICON, light: NewProfilerAction.ICON },
+ iconClass: NewProfilerAction.ICON
});
}
diff --git a/src/sql/platform/tasks/common/tasks.ts b/src/sql/platform/tasks/common/tasks.ts
index 49aab3cc57..0ac784f7fe 100644
--- a/src/sql/platform/tasks/common/tasks.ts
+++ b/src/sql/platform/tasks/common/tasks.ts
@@ -2,6 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
+import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import * as types from 'vs/base/common/types';
import { TPromise } from 'vs/base/common/winjs.base';
@@ -14,9 +15,10 @@ import { ILocalizedString, IMenuItem, MenuRegistry, ICommandAction } from 'vs/pl
import Event, { Emitter } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
-import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { LinkedList } from 'vs/base/common/linkedList';
-
+import { IdGenerator } from 'vs/base/common/idGenerator';
+import { createCSSRule } from 'vs/base/browser/dom';
+import URI from 'vs/base/common/uri';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
export interface ITaskOptions {
@@ -24,6 +26,7 @@ export interface ITaskOptions {
title: string;
iconPath: { dark: string; light: string; };
description?: ITaskHandlerDescription;
+ iconClass?: string;
}
export abstract class Task {
@@ -31,12 +34,14 @@ export abstract class Task {
public readonly title: string;
public readonly iconPathDark: string;
public readonly iconPath: { dark: string; light: string; };
+ private readonly _iconClass: string;
private readonly _description: ITaskHandlerDescription;
constructor(opts: ITaskOptions) {
this.id = opts.id;
this.title = opts.title;
this.iconPath = opts.iconPath;
+ this._iconClass = opts.iconClass;
this._description = opts.description;
}
@@ -44,7 +49,8 @@ export abstract class Task {
return {
id: this.id,
handler: (accessor, profile, args) => this.runTask(accessor, profile, args),
- description: this._description
+ description: this._description,
+ iconClass: this._iconClass
};
}
@@ -91,20 +97,25 @@ export interface ITask {
handler: ITaskHandler;
precondition?: ContextKeyExpr;
description?: ITaskHandlerDescription;
+ iconClass?: string;
}
export interface ITaskRegistry {
registerTask(id: string, command: ITaskHandler): IDisposable;
registerTask(command: ITask): IDisposable;
getTasks(): string[];
+ getOrCreateTaskIconClassName(item: ICommandAction): string;
onTaskRegistered: Event;
}
+const ids = new IdGenerator('task-icon-');
+
export const TaskRegistry: ITaskRegistry = new class implements ITaskRegistry {
private _tasks = new Array();
private _onTaskRegistered = new Emitter();
public readonly onTaskRegistered: Event = this._onTaskRegistered.event;
+ private taskIdToIconClassNameMap: Map = new Map();
registerTask(idOrTask: string | ITask, handler?: ITaskHandler): IDisposable {
let disposable: IDisposable;
@@ -113,6 +124,9 @@ export const TaskRegistry: ITaskRegistry = new class implements ITaskRegistry {
disposable = CommandsRegistry.registerCommand(idOrTask, handler);
id = idOrTask;
} else {
+ if (idOrTask.iconClass) {
+ this.taskIdToIconClassNameMap.set(idOrTask.id, idOrTask.iconClass);
+ }
disposable = CommandsRegistry.registerCommand(idOrTask);
id = idOrTask.id;
}
@@ -131,6 +145,19 @@ export const TaskRegistry: ITaskRegistry = new class implements ITaskRegistry {
};
}
+ getOrCreateTaskIconClassName(item: ICommandAction): string {
+ let iconClass = null;
+ if (this.taskIdToIconClassNameMap.has(item.id)) {
+ iconClass = this.taskIdToIconClassNameMap.get(item.id);
+ } else if (item.iconPath) {
+ iconClass = ids.nextId();
+ createCSSRule(`.icon.${iconClass}`, `background-image: url("${URI.file(item.iconPath.light || item.iconPath.dark).toString()}")`);
+ createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: url("${URI.file(item.iconPath.dark).toString()}")`);
+ this.taskIdToIconClassNameMap.set(item.id, iconClass);
+ }
+ return iconClass;
+ }
+
getTasks(): string[] {
return this._tasks.slice(0);
}
diff --git a/src/sql/workbench/common/actions.ts b/src/sql/workbench/common/actions.ts
index b98a2f905c..f65cff0ef6 100644
--- a/src/sql/workbench/common/actions.ts
+++ b/src/sql/workbench/common/actions.ts
@@ -51,7 +51,8 @@ export class NewQueryAction extends Task {
super({
id: NewQueryAction.ID,
title: NewQueryAction.LABEL,
- iconPath: { dark: NewQueryAction.ICON, light: NewQueryAction.ICON }
+ iconPath: { dark: NewQueryAction.ICON, light: NewQueryAction.ICON },
+ iconClass: NewQueryAction.ICON
});
}
@@ -292,7 +293,8 @@ export class BackupAction extends Task {
super({
id: BackupAction.ID,
title: BackupAction.LABEL,
- iconPath: { dark: BackupAction.ICON, light: BackupAction.ICON }
+ iconPath: { dark: BackupAction.ICON, light: BackupAction.ICON },
+ iconClass: BackupAction.ICON
});
}
@@ -322,7 +324,8 @@ export class RestoreAction extends Task {
super({
id: RestoreAction.ID,
title: RestoreAction.LABEL,
- iconPath: { dark: RestoreAction.ICON, light: RestoreAction.ICON }
+ iconPath: { dark: RestoreAction.ICON, light: RestoreAction.ICON },
+ iconClass: RestoreAction.ICON
});
}
@@ -421,7 +424,8 @@ export class ConfigureDashboardAction extends Task {
super({
id: ConfigureDashboardAction.ID,
title: ConfigureDashboardAction.LABEL,
- iconPath: { dark: ConfigureDashboardAction.ICON, light: ConfigureDashboardAction.ICON }
+ iconPath: { dark: ConfigureDashboardAction.ICON, light: ConfigureDashboardAction.ICON },
+ iconClass: ConfigureDashboardAction.ICON
});
}