From 7a8888f0735d36828ad75ca66b6bc5487cac31ce Mon Sep 17 00:00:00 2001 From: Kim Santiago <31145923+kisantia@users.noreply.github.com> Date: Fri, 24 Feb 2023 13:36:39 -0800 Subject: [PATCH] Show error if trying to create or open project when no project extension is installed (#22021) * show error if trying to create or open project when no project extensions are found * only check if project providers are available on startup and when extensions change * addressing comments * Update extensions/data-workspace/src/services/workspaceService.ts use some instead of find Co-authored-by: Charles Gagnon --------- Co-authored-by: Charles Gagnon --- extensions/data-workspace/src/common/constants.ts | 1 + .../src/common/dataWorkspaceExtension.ts | 5 +++++ extensions/data-workspace/src/main.ts | 15 +++++++++++++++ .../src/services/workspaceService.ts | 14 ++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/extensions/data-workspace/src/common/constants.ts b/extensions/data-workspace/src/common/constants.ts index 90d1f164b7..1b544e677b 100644 --- a/extensions/data-workspace/src/common/constants.ts +++ b/extensions/data-workspace/src/common/constants.ts @@ -23,6 +23,7 @@ export const gitCloneError = localize('gitCloneError', "Error during git clone. export const openedProjectsUndefinedAfterRefresh = localize('openedProjectsUndefinedAfterRefresh', "List of opened projects should not be undefined after refresh from disk."); export const dragAndDropNotSupported = localize('dragAndDropNotSupported', "This project type does not support drag and drop."); export const onlyMovingOneFileIsSupported = localize('onlyMovingOneFileIsSupported', "Only moving one file at a time is supported."); +export const noProjectProvidingExtensionsInstalled = localize('noProjectProvidingExtensionsInstalled', "No database project extensions are installed. Please install a database project extension to use this feature."); // UI export const OkButtonText = localize('dataworkspace.ok', "OK"); diff --git a/extensions/data-workspace/src/common/dataWorkspaceExtension.ts b/extensions/data-workspace/src/common/dataWorkspaceExtension.ts index bc6d384c55..103321002e 100644 --- a/extensions/data-workspace/src/common/dataWorkspaceExtension.ts +++ b/extensions/data-workspace/src/common/dataWorkspaceExtension.ts @@ -9,6 +9,7 @@ import { WorkspaceService } from '../services/workspaceService'; import { defaultProjectSaveLocation } from './projectLocationHelper'; import { openSpecificProjectNewProjectDialog } from '../dialogs/newProjectDialog'; import { isValidBasename, isValidBasenameErrorMessage, isValidFilenameCharacter, sanitizeStringForFilename } from './pathUtilsHelper'; +import { noProjectProvidingExtensionsInstalled } from './constants'; export class DataWorkspaceExtension implements IExtension { constructor(private workspaceService: WorkspaceService) { @@ -39,6 +40,10 @@ export class DataWorkspaceExtension implements IExtension { } openSpecificProjectNewProjectDialog(projectType: IProjectType): Promise { + if (!this.workspaceService.isProjectProviderAvailable) { + void vscode.window.showErrorMessage(noProjectProvidingExtensionsInstalled); + } + return openSpecificProjectNewProjectDialog(projectType, this.workspaceService); } diff --git a/extensions/data-workspace/src/main.ts b/extensions/data-workspace/src/main.ts index b2abd3335c..8e207b90b4 100644 --- a/extensions/data-workspace/src/main.ts +++ b/extensions/data-workspace/src/main.ts @@ -16,6 +16,7 @@ import { getAzdataApi } from './common/utils'; import { createNewProjectWithQuickpick } from './dialogs/newProjectQuickpick'; import Logger from './common/logger'; import { TelemetryReporter } from './common/telemetry'; +import { noProjectProvidingExtensionsInstalled } from './common/constants'; export async function activate(context: vscode.ExtensionContext): Promise { const startTime = new Date().getTime(); @@ -46,6 +47,11 @@ export async function activate(context: vscode.ExtensionContext): Promise { + workspaceService.updateIfProjectProviderAvailable(); + })); + const iconPathHelperTime = new Date().getTime(); IconPathHelper.setExtensionContext(context); Logger.log(`IconPathHelper took ${new Date().getTime() - iconPathHelperTime}ms`); diff --git a/extensions/data-workspace/src/services/workspaceService.ts b/extensions/data-workspace/src/services/workspaceService.ts index 6002b38e7c..f6d198f822 100644 --- a/extensions/data-workspace/src/services/workspaceService.ts +++ b/extensions/data-workspace/src/services/workspaceService.ts @@ -25,12 +25,26 @@ export class WorkspaceService implements IWorkspaceService { private openedProjects: vscode.Uri[] | undefined = undefined; private excludedProjects: string[] | undefined; + private _isProjectProviderAvailable: boolean = false; constructor() { Logger.log(`Calling getProjectsInWorkspace() from WorkspaceService constructor`); + this.updateIfProjectProviderAvailable(); this.getProjectsInWorkspace(undefined, true).catch(err => Logger.error(`Error initializing projects in workspace ${err}`)); } + get isProjectProviderAvailable(): boolean { + return this._isProjectProviderAvailable; + } + + public updateIfProjectProviderAvailable(): void { + Logger.log(`Checking ${vscode.extensions.all.length} extensions to see if there is a project provider is available`); + const startTime = new Date().getTime(); + + this._isProjectProviderAvailable = vscode.extensions.all.some(e => e.packageJSON.contributes?.projects?.length > 0); + Logger.log(`isProjectProviderAvailable is ${this._isProjectProviderAvailable}. Total time = ${new Date().getTime() - startTime}ms`); + } + /** * Verify that a workspace is open or that if one isn't and we're running in ADS, it's ok to create a workspace and restart ADS */