diff --git a/package-lock.json b/package-lock.json index 365b495..71b63e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dataverse-devtools", - "version": "2.2.5", + "version": "2.2.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dataverse-devtools", - "version": "2.2.5", + "version": "2.2.6", "dependencies": { "@azure/identity": "^3.0.0", "@azure/identity-vscode": "^1.0.0", diff --git a/package.json b/package.json index 4d2c219..278d0a4 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "Power Platform", "Dynamics 365", "Xrm", + "DVDT", "Dev Tools" ], "qna": "https://github.com/Power-Maverick/DataverseDevTools-VSCode/discussions", diff --git a/resources/toolIcons/cmt.png b/resources/toolIcons/dark/cmt.png similarity index 100% rename from resources/toolIcons/cmt.png rename to resources/toolIcons/dark/cmt.png diff --git a/resources/toolIcons/drb.png b/resources/toolIcons/dark/drb.png similarity index 100% rename from resources/toolIcons/drb.png rename to resources/toolIcons/dark/drb.png diff --git a/resources/toolIcons/dark/erd.svg b/resources/toolIcons/dark/erd.svg new file mode 100644 index 0000000..93f20a8 --- /dev/null +++ b/resources/toolIcons/dark/erd.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/toolIcons/dark/generic.svg b/resources/toolIcons/dark/generic.svg new file mode 100644 index 0000000..ae8f055 --- /dev/null +++ b/resources/toolIcons/dark/generic.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/resources/toolIcons/pd.png b/resources/toolIcons/dark/pd.png similarity index 100% rename from resources/toolIcons/pd.png rename to resources/toolIcons/dark/pd.png diff --git a/resources/toolIcons/prt.png b/resources/toolIcons/dark/prt.png similarity index 100% rename from resources/toolIcons/prt.png rename to resources/toolIcons/dark/prt.png diff --git a/resources/toolIcons/light/cmt.png b/resources/toolIcons/light/cmt.png new file mode 100644 index 0000000..a880dcf Binary files /dev/null and b/resources/toolIcons/light/cmt.png differ diff --git a/resources/toolIcons/light/drb.png b/resources/toolIcons/light/drb.png new file mode 100644 index 0000000..969330a Binary files /dev/null and b/resources/toolIcons/light/drb.png differ diff --git a/resources/toolIcons/light/erd.svg b/resources/toolIcons/light/erd.svg new file mode 100644 index 0000000..9c4044b --- /dev/null +++ b/resources/toolIcons/light/erd.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/toolIcons/light/generic.svg b/resources/toolIcons/light/generic.svg new file mode 100644 index 0000000..02919c7 --- /dev/null +++ b/resources/toolIcons/light/generic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/toolIcons/light/pd.png b/resources/toolIcons/light/pd.png new file mode 100644 index 0000000..d6fc124 Binary files /dev/null and b/resources/toolIcons/light/pd.png differ diff --git a/resources/toolIcons/light/prt.png b/resources/toolIcons/light/prt.png new file mode 100644 index 0000000..d6fc124 Binary files /dev/null and b/resources/toolIcons/light/prt.png differ diff --git a/src/commands/registerCommands.ts b/src/commands/registerCommands.ts index b6a1db3..522781e 100644 --- a/src/commands/registerCommands.ts +++ b/src/commands/registerCommands.ts @@ -3,9 +3,9 @@ import * as vscode from "vscode"; import { CliCommandTreeItem } from "../cliCommands/cliCommandsDataProvider"; import { CLIHelper } from "../helpers/cliHelper"; import { DataverseHelper } from "../helpers/dataverseHelper"; -import { DRBHelper } from "../helpers/drbHelper"; import { ErrorHandler } from "../helpers/errorHandler"; import { TemplateHelper } from "../helpers/templateHelper"; +import { ToolsHelper } from "../helpers/toolsHelper"; import { TypingsHelper } from "../helpers/typingsHelper"; import { WebResourceHelper } from "../helpers/webResourceHelper"; import { ToolsTreeItem } from "../tools/toolsDataProvider"; @@ -30,8 +30,8 @@ export async function registerCommands(vscontext: vscode.ExtensionContext, tr: T const templateHelper = new TemplateHelper(vscontext); const wrHelper = new WebResourceHelper(vscontext, dvHelper); const typingHelper = new TypingsHelper(vscontext, dvHelper); - const drbHelper = new DRBHelper(vscontext); const errorHandler = new ErrorHandler(tr); + const toolsHelper = new ToolsHelper(vscontext); dvStatusBarItem = vscode.window.createStatusBarItem(connectionStatusBarUniqueId, vscode.StatusBarAlignment.Left); vscontext.subscriptions.push(dvStatusBarItem); @@ -203,46 +203,6 @@ export async function registerCommands(vscontext: vscode.ExtensionContext, tr: T } }, }, - { - command: "dvdt.commands.openDRB", - callback: async () => { - try { - drbHelper.openDRB(views); - } catch (error) { - errorHandler.log(error, "openDRB"); - } - }, - }, - { - command: "dvdt.commands.launchPRT", - callback: async () => { - try { - cliHelper.launchPRT(); - } catch (error) { - errorHandler.log(error, "launchPRT"); - } - }, - }, - { - command: "dvdt.commands.launchCMT", - callback: async () => { - try { - cliHelper.launchCMT(); - } catch (error) { - errorHandler.log(error, "launchCMT"); - } - }, - }, - { - command: "dvdt.commands.launchPD", - callback: async () => { - try { - cliHelper.launchPD(); - } catch (error) { - errorHandler.log(error, "launchPD"); - } - }, - }, { command: "dvdt.explorer.webresources.linkExistingWebResource", callback: async (uri: vscode.Uri) => { @@ -257,22 +217,7 @@ export async function registerCommands(vscontext: vscode.ExtensionContext, tr: T command: "dvdt.explorer.tools.launchTool", callback: async (toolItem: ToolsTreeItem) => { try { - switch (toolItem.toolShortName) { - case "drb": - drbHelper.openDRB(views); - break; - case "prt": - cliHelper.launchPRT(); - break; - case "cmt": - cliHelper.launchCMT(); - break; - case "pd": - cliHelper.launchPD(); - break; - default: - break; - } + toolsHelper.openTool(toolItem); } catch (error) { errorHandler.log(error, "launchTool"); } diff --git a/src/commands/registerToolsCommands.ts b/src/commands/registerToolsCommands.ts new file mode 100644 index 0000000..30b425a --- /dev/null +++ b/src/commands/registerToolsCommands.ts @@ -0,0 +1,71 @@ +import TelemetryReporter from "@vscode/extension-telemetry"; +import * as vscode from "vscode"; +import { CLIHelper } from "../helpers/cliHelper"; +import { ErrorHandler } from "../helpers/errorHandler"; +import { ToolsHelper } from "../helpers/toolsHelper"; +import { ICommand } from "../utils/Interfaces"; +import { ViewBase } from "../views/ViewBase"; + +export async function registerToolsCommands(vscontext: vscode.ExtensionContext, tr: TelemetryReporter): Promise { + const toolHelper = new ToolsHelper(vscontext); + const views = new ViewBase(vscontext); + const errorHandler = new ErrorHandler(tr); + const cliHelper = new CLIHelper(vscontext); + + const cmds: Array = new Array( + { + command: "dvdt.commands.openDRB", + callback: async () => { + try { + toolHelper.openDRB(views); + } catch (error) { + errorHandler.log(error, "openDRB"); + } + }, + }, + // { + // command: "dvdt.commands.openERDGenerator", + // callback: async () => { + // try { + // toolHelper.openERDGenerator(); + // } catch (error) { + // errorHandler.log(error, "openERDGenerator"); + // } + // }, + // }, + { + command: "dvdt.commands.launchPRT", + callback: async () => { + try { + cliHelper.launchPRT(); + } catch (error) { + errorHandler.log(error, "launchPRT"); + } + }, + }, + { + command: "dvdt.commands.launchCMT", + callback: async () => { + try { + cliHelper.launchCMT(); + } catch (error) { + errorHandler.log(error, "launchCMT"); + } + }, + }, + { + command: "dvdt.commands.launchPD", + callback: async () => { + try { + cliHelper.launchPD(); + } catch (error) { + errorHandler.log(error, "launchPD"); + } + }, + }, + ); + + cmds.forEach((c) => { + vscontext.subscriptions.push(vscode.commands.registerCommand(c.command, c.callback)); + }); +} diff --git a/src/extension.ts b/src/extension.ts index 7ae5d89..85e7e34 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,6 +3,7 @@ import TelemetryReporter from "@vscode/extension-telemetry"; import * as vscode from "vscode"; import { registerCommands } from "./commands/registerCommands"; +import { registerToolsCommands } from "./commands/registerToolsCommands"; import { registerTreeDataProviders } from "./commands/registerTreeDataProviders"; import { DataverseHelper } from "./helpers/dataverseHelper"; import * as config from "./utils/Config"; @@ -32,6 +33,9 @@ export function activate(context: vscode.ExtensionContext) { registerTreeDataProviders(context, reporter); registerCommands(context, reporter); + registerToolsCommands(context, reporter); + + console.log(`Extension ${extensionId} v${extensionVersion} is now active!`); // Start periodic token expiration check startTokenExpirationCheck(context); @@ -59,20 +63,17 @@ export function deactivate() { */ function startTokenExpirationCheck(context: vscode.ExtensionContext) { let lastNotifiedExpiration = false; - + tokenExpirationTimer = setInterval(() => { const dvHelper = new DataverseHelper(context); const isExpired = dvHelper.isCurrentConnectionTokenExpired(); - + if (isExpired && !lastNotifiedExpiration) { // Get current connection to create tree item for reconnect const conn = dvHelper.getCurrentWorkspaceConnection(); - + // Show notification to user - vscode.window.showWarningMessage( - "Your Dataverse connection token has expired. Please reconnect to continue working.", - "Reconnect" - ).then(selection => { + vscode.window.showWarningMessage("Your Dataverse connection token has expired. Please reconnect to continue working.", "Reconnect").then((selection) => { if (selection === "Reconnect" && conn) { // Create a tree item with the connection name to pass to the command const connItem = { @@ -81,17 +82,17 @@ function startTokenExpirationCheck(context: vscode.ExtensionContext) { collapsibleState: vscode.TreeItemCollapsibleState.Collapsed, level: 2, current: true, - expired: true + expired: true, }; vscode.commands.executeCommand("dvdt.explorer.connections.connectDataverse", connItem); } }); - + lastNotifiedExpiration = true; - + // Refresh the connection tree to show expired icon vscode.commands.executeCommand("dvdt.explorer.connections.refreshConnection"); - + // Update status bar to show expired state if (conn) { vscode.commands.executeCommand("dvdt.explorer.connections.updateStatusBar", conn); diff --git a/src/helpers/drbHelper.ts b/src/helpers/drbHelper.ts deleted file mode 100644 index 86e2996..0000000 --- a/src/helpers/drbHelper.ts +++ /dev/null @@ -1,28 +0,0 @@ -import * as vscode from "vscode"; -import { connectionCurrentStoreKey } from "../utils/Constants"; -import { ErrorMessages } from "../utils/ErrorMessages"; -import { IConnection } from "../utils/Interfaces"; -import { State } from "../utils/State"; -import { DataverseRestBuilderView } from "../views/DataverseRestBuilderView"; -import { ViewBase } from "../views/ViewBase"; - -export class DRBHelper { - private vsstate: State; - - /** - * Initialization constructor for VS Code Context - */ - constructor(private vscontext: vscode.ExtensionContext) { - this.vsstate = new State(vscontext); - } - - public async openDRB(view: ViewBase): Promise { - const connFromWS: IConnection = this.vsstate.getFromWorkspace(connectionCurrentStoreKey); - if (connFromWS && connFromWS.currentAccessToken) { - const webview = await view.getWebView({ type: "openDRB", title: "Dataverse REST Builder" }); - new DataverseRestBuilderView(webview, this.vscontext, connFromWS.currentAccessToken); - } else { - vscode.window.showErrorMessage(ErrorMessages.drbConnectionError); - } - } -} diff --git a/src/helpers/toolsHelper.ts b/src/helpers/toolsHelper.ts new file mode 100644 index 0000000..2853281 --- /dev/null +++ b/src/helpers/toolsHelper.ts @@ -0,0 +1,64 @@ +import * as vscode from "vscode"; +import { ToolsTreeItem } from "../tools/toolsDataProvider"; +import { connectionCurrentStoreKey } from "../utils/Constants"; +import { ErrorMessages } from "../utils/ErrorMessages"; +import { IConnection } from "../utils/Interfaces"; +import { State } from "../utils/State"; +import { DataverseRestBuilderView } from "../views/DataverseRestBuilderView"; +import { ViewBase } from "../views/ViewBase"; +import { CLIHelper } from "./cliHelper"; + +export class ToolsHelper { + private vsstate: State; + + /** + * Initialization constructor for VS Code Context + */ + constructor(private vscontext: vscode.ExtensionContext) { + this.vsstate = new State(vscontext); + } + + public openTool(toolItem: ToolsTreeItem) { + const views = new ViewBase(this.vscontext); + const cliHelper = new CLIHelper(this.vscontext); + + switch (toolItem.toolShortName) { + case "drb": + this.openDRB(views); + break; + // case "erd": + // this.openERDGenerator(); + // break; + case "prt": + cliHelper.launchPRT(); + break; + case "cmt": + cliHelper.launchCMT(); + break; + case "pd": + cliHelper.launchPD(); + break; + default: + break; + } + } + + public async openDRB(view: ViewBase): Promise { + const connFromWS: IConnection = this.vsstate.getFromWorkspace(connectionCurrentStoreKey); + if (connFromWS && connFromWS.currentAccessToken) { + const webview = await view.getWebView({ type: "openDRB", title: "Dataverse REST Builder" }); + new DataverseRestBuilderView(webview, this.vscontext, connFromWS.currentAccessToken); + } else { + vscode.window.showErrorMessage(ErrorMessages.drbConnectionError); + } + } + + // public openERDGenerator(): void { + // const connFromWS: IConnection = this.vsstate.getFromWorkspace(connectionCurrentStoreKey); + // if (connFromWS && connFromWS.currentAccessToken) { + // showERDPanel(this.vscontext.extensionUri, connFromWS.environmentUrl, connFromWS.currentAccessToken); + // } else { + // vscode.window.showErrorMessage(ErrorMessages.commonToolsError); + // } + // } +} diff --git a/src/tools/tools.json b/src/tools/tools.json index 49e3778..af36cb3 100644 --- a/src/tools/tools.json +++ b/src/tools/tools.json @@ -1,8 +1,28 @@ { "tools": [ - { "toolName": "Dataverse REST Builder", "toolShortName": "drb", "toolAuthor": "Guido Preite" }, - { "toolName": "Plugin Registration", "toolShortName": "prt", "toolAuthor": "Microsoft" }, - { "toolName": "Configuration Migration", "toolShortName": "cmt", "toolAuthor": "Microsoft" }, - { "toolName": "Package Deployer", "toolShortName": "pd", "toolAuthor": "Microsoft" } + { + "name": "Dataverse REST Builder", + "shortName": "drb", + "author": "Guido Preite", + "icon": "drb.png" + }, + { + "name": "Plugin Registration", + "shortName": "prt", + "author": "Microsoft", + "icon": "prt.png" + }, + { + "name": "Configuration Migration", + "shortName": "cmt", + "author": "Microsoft", + "icon": "cmt.png" + }, + { + "name": "Package Deployer", + "shortName": "pd", + "author": "Microsoft", + "icon": "pd.png" + } ] -} +} \ No newline at end of file diff --git a/src/tools/toolsDataProvider.ts b/src/tools/toolsDataProvider.ts index 87ecda4..ab02f63 100644 --- a/src/tools/toolsDataProvider.ts +++ b/src/tools/toolsDataProvider.ts @@ -16,7 +16,7 @@ export class ToolsDataProvider implements vscode.TreeDataProvider let toolsTree: ToolsTreeItem[] = []; toolsArray.tools.map((tool) => { - toolsTree.push(new ToolsTreeItem(tool.toolName, tool.toolShortName, tool.toolAuthor, vscode.TreeItemCollapsibleState.None)); + toolsTree.push(new ToolsTreeItem(tool.name, tool.shortName, tool.author, vscode.TreeItemCollapsibleState.None, tool.icon)); }); return Promise.resolve(toolsTree); @@ -24,28 +24,18 @@ export class ToolsDataProvider implements vscode.TreeDataProvider } export class ToolsTreeItem extends ToolsItemBase { - constructor(public readonly toolName: string, public readonly toolShortName: string, public readonly authorName: string, public readonly collapsibleState: vscode.TreeItemCollapsibleState) { + constructor( + public readonly toolName: string, + public readonly toolShortName: string, + public readonly authorName: string, + public readonly collapsibleState: vscode.TreeItemCollapsibleState, + public readonly toolIcon?: string, + ) { super(toolName, authorName, collapsibleState); } iconPath = { - light: vscode.Uri.file( - path.join( - __filename, - "..", - "resources", - "toolIcons", - this.toolShortName === "drb" ? "drb.png" : this.toolShortName === "prt" ? "prt.png" : this.toolShortName === "cmt" ? "cmt.png" : this.toolShortName === "pd" ? "pd.png" : "generic.svg", - ), - ), - dark: vscode.Uri.file( - path.join( - __filename, - "..", - "resources", - "toolIcons", - this.toolShortName === "drb" ? "drb.png" : this.toolShortName === "prt" ? "prt.png" : this.toolShortName === "cmt" ? "cmt.png" : this.toolShortName === "pd" ? "pd.png" : "generic.svg", - ), - ), + light: vscode.Uri.file(path.join(__filename, "..", "resources", "toolIcons", "light", this.toolIcon ?? "generic.svg")), + dark: vscode.Uri.file(path.join(__filename, "..", "resources", "toolIcons", "dark", this.toolIcon ?? "generic.svg")), }; } diff --git a/src/utils/ErrorMessages.ts b/src/utils/ErrorMessages.ts index c4a0aa6..f1d1f2c 100644 --- a/src/utils/ErrorMessages.ts +++ b/src/utils/ErrorMessages.ts @@ -15,4 +15,5 @@ export class ErrorMessages { public static wrUploadError: string = "Failed to upload web resource. Please check your connection and try again."; public static drbConnectionError: string = "Connect to an environment before trying to load Dataverse REST Builder."; public static invalidLoginType: string = "Invalid Login Type."; + public static commonToolsError: string = "An error occurred while trying to open the tool. Please try again."; } diff --git a/src/utils/Interfaces.ts b/src/utils/Interfaces.ts index 7197155..3e5debc 100644 --- a/src/utils/Interfaces.ts +++ b/src/utils/Interfaces.ts @@ -294,9 +294,10 @@ export interface ITools { } export interface IToolDetails { - toolName: string; - toolShortName: string; - toolAuthor: string; + name: string; + shortName: string; + author: string; + icon?: string; } export interface ICliCommandList { commands: ICliCommand[];