mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 17:22:42 -05:00
177 lines
6.4 KiB
TypeScript
177 lines
6.4 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import * as vscode from 'vscode';
|
|
import * as path from 'path';
|
|
import * as constants from '../common/constants';
|
|
import { directoryExist, showInfoMessageWithLearnMoreLink } from '../common/utils';
|
|
import { defaultProjectSaveLocation } from '../common/projectLocationHelper';
|
|
import { WorkspaceService } from '../services/workspaceService';
|
|
|
|
/**
|
|
* Create flow for a New Project using only VS Code-native APIs such as QuickPick
|
|
*/
|
|
export async function createNewProjectWithQuickpick(workspaceService: WorkspaceService): Promise<void> {
|
|
// Refresh list of project types
|
|
const projectTypes = (await workspaceService.getAllProjectTypes()).map(projType => {
|
|
return {
|
|
label: projType.displayName,
|
|
description: projType.description,
|
|
id: projType.id,
|
|
targetPlatforms: projType.targetPlatforms,
|
|
defaultTargetPlatform: projType.defaultTargetPlatform,
|
|
sdkOption: projType.sdkStyleOption,
|
|
sdkLearnMoreUrl: projType.sdkStyleLearnMoreUrl,
|
|
learnMoreUrl: projType.learnMoreUrl
|
|
} as vscode.QuickPickItem & { id: string, sdkOption?: boolean, targetPlatforms?: string[], defaultTargetPlatform?: string, sdkLearnMoreUrl?: string, learnMoreUrl?: string };
|
|
});
|
|
|
|
// 1. Prompt for project type
|
|
const projectType = await vscode.window.showQuickPick(projectTypes, { title: constants.SelectProjectType, ignoreFocusOut: true });
|
|
if (!projectType) {
|
|
return;
|
|
}
|
|
|
|
// 2. Prompt for project name
|
|
const projectName = await vscode.window.showInputBox(
|
|
{
|
|
title: constants.EnterProjectName,
|
|
validateInput: (value) => {
|
|
return value ? undefined : constants.NameCannotBeEmpty;
|
|
},
|
|
ignoreFocusOut: true
|
|
});
|
|
if (!projectName) {
|
|
return;
|
|
}
|
|
|
|
const defaultProjectSaveLoc = defaultProjectSaveLocation();
|
|
const browseProjectLocationOptions = [constants.BrowseEllipsisWithIcon];
|
|
if (defaultProjectSaveLoc) {
|
|
browseProjectLocationOptions.unshift(defaultProjectSaveLoc.fsPath);
|
|
}
|
|
// 3. Prompt for Project location
|
|
// We validate that the folder doesn't already exist, and if it does keep prompting them to pick a new one
|
|
let projectLocation = '';
|
|
let browseProjectLocationTitle = constants.SelectProjectLocation;
|
|
while (true) {
|
|
const browseProjectLocation = await vscode.window.showQuickPick(
|
|
browseProjectLocationOptions,
|
|
{ title: browseProjectLocationTitle, ignoreFocusOut: true });
|
|
if (!browseProjectLocation) {
|
|
// User cancelled
|
|
return undefined;
|
|
}
|
|
if (browseProjectLocation === constants.BrowseEllipsisWithIcon) {
|
|
const locations = await vscode.window.showOpenDialog({
|
|
canSelectFiles: false,
|
|
canSelectFolders: true,
|
|
canSelectMany: false,
|
|
openLabel: constants.Select,
|
|
title: constants.SelectProjectLocation,
|
|
defaultUri: defaultProjectSaveLoc
|
|
});
|
|
if (!locations) {
|
|
// User cancelled out of open dialog - let them choose location again
|
|
browseProjectLocationTitle = constants.SelectProjectLocation;
|
|
continue;
|
|
}
|
|
projectLocation = locations[0].fsPath;
|
|
} else {
|
|
projectLocation = browseProjectLocation;
|
|
}
|
|
const locationExists = await directoryExist(path.join(projectLocation, projectName));
|
|
if (!locationExists) {
|
|
// Have a valid location so exit out now
|
|
break;
|
|
}
|
|
// Otherwise show the browse quick pick again with the title updated with the error
|
|
browseProjectLocationTitle = constants.ProjectDirectoryAlreadyExistErrorShort(projectName);
|
|
continue;
|
|
}
|
|
|
|
let targetPlatform;
|
|
if (projectType.targetPlatforms) {
|
|
// 4. Target platform of the project
|
|
let targetPlatforms: vscode.QuickPickItem[] = projectType.targetPlatforms.map(targetPlatform => { return { label: targetPlatform }; });
|
|
|
|
if (projectType.defaultTargetPlatform) {
|
|
// move the default target platform to be the first one in the list
|
|
const defaultIndex = targetPlatforms.findIndex(i => i.label === projectType.defaultTargetPlatform);
|
|
if (defaultIndex > -1) {
|
|
targetPlatforms.splice(defaultIndex, 1);
|
|
}
|
|
|
|
// add default next to the default target platform
|
|
targetPlatforms.unshift({ label: projectType.defaultTargetPlatform, description: constants.Default });
|
|
}
|
|
|
|
const selectedTargetPlatform = await vscode.window.showQuickPick(targetPlatforms, { title: constants.SelectTargetPlatform, ignoreFocusOut: true });
|
|
if (!selectedTargetPlatform) {
|
|
// User cancelled
|
|
return;
|
|
}
|
|
|
|
targetPlatform = selectedTargetPlatform.label;
|
|
}
|
|
|
|
let sdkStyle;
|
|
if (projectType.sdkOption) {
|
|
// 5. SDK-style project or not
|
|
const sdkLearnMoreButton: vscode.QuickInputButton = {
|
|
iconPath: new vscode.ThemeIcon('link-external'),
|
|
tooltip: constants.LearnMore
|
|
};
|
|
const quickPick = vscode.window.createQuickPick();
|
|
quickPick.items = [{ label: constants.YesRecommended }, { label: constants.No }];
|
|
quickPick.title = constants.SdkStyleProject;
|
|
quickPick.ignoreFocusOut = true;
|
|
const disposables: vscode.Disposable[] = [];
|
|
|
|
try {
|
|
if (projectType.sdkLearnMoreUrl) {
|
|
// add button to open sdkLearnMoreUrl if it was provided
|
|
quickPick.buttons = [sdkLearnMoreButton];
|
|
quickPick.placeholder = constants.SdkLearnMorePlaceholder;
|
|
}
|
|
|
|
let sdkStylePromise = new Promise<boolean | undefined>((resolve) => {
|
|
disposables.push(
|
|
quickPick.onDidHide(() => {
|
|
resolve(undefined);
|
|
}),
|
|
quickPick.onDidChangeSelection((item) => {
|
|
resolve(item[0].label === constants.YesRecommended);
|
|
}));
|
|
|
|
if (projectType.sdkLearnMoreUrl) {
|
|
disposables.push(quickPick.onDidTriggerButton(async () => {
|
|
await vscode.env.openExternal(vscode.Uri.parse(projectType.sdkLearnMoreUrl!));
|
|
}));
|
|
}
|
|
});
|
|
|
|
quickPick.show();
|
|
sdkStyle = await sdkStylePromise;
|
|
quickPick.hide();
|
|
} finally {
|
|
disposables.forEach(d => d.dispose());
|
|
}
|
|
|
|
if (sdkStyle === undefined) {
|
|
// User cancelled
|
|
return;
|
|
}
|
|
}
|
|
|
|
await workspaceService.createProject(projectName, vscode.Uri.file(projectLocation), projectType.id, targetPlatform, sdkStyle);
|
|
|
|
// Add info message with 'learn more' button if project type has a link
|
|
// for user to learn more about the project type
|
|
if (projectType.learnMoreUrl && projectType.defaultTargetPlatform) {
|
|
void showInfoMessageWithLearnMoreLink(constants.LocalDevInfo(projectType.defaultTargetPlatform), projectType.learnMoreUrl);
|
|
}
|
|
}
|