Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UX: Change command labels, remove entry point for Create new project..., add Create Function App from deploy #4042

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 20 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,6 @@
"command": "azureFunctions.createNewProject",
"title": "%azureFunctions.createNewProject%",
"category": "Azure Functions",
"icon": {
"light": "resources/light/CreateNewProject.svg",
"dark": "resources/dark/CreateNewProject.svg"
},
"enablement": "!virtualWorkspace"
},
{
"command": "azureFunctions.createNewProjectWithDockerfile",
"title": "%azureFunctions.createNewProjectWithDockerfile%",
"category": "Azure Functions",
"enablement": "!virtualWorkspace"
},
{
Expand All @@ -207,6 +197,13 @@
"title": "%azureFunctions.deleteSlot%",
"category": "Azure Functions"
},
{
"command": "azureFunctions.deployProject",
"title": "%azureFunctions.deployProject%",
"category": "Azure Functions",
"icon": "$(cloud-upload)",
"enablement": "!virtualWorkspace"
},
{
"command": "azureFunctions.deploy",
"title": "%azureFunctions.deploy%",
Expand Down Expand Up @@ -375,24 +372,8 @@
"group": "1_projects@1"
},
{
"command": "azureFunctions.createNewProject",
"group": "1_projects@2"
},
{
"command": "azureFunctions.createNewProjectWithDockerfile",
"group": "1_projects@3"
},
{
"command": "azureFunctions.deploy",
"command": "azureFunctions.deployProject",
"group": "2_deploy@1"
},
{
"command": "azureFunctions.createFunctionApp",
"group": "3_create@1"
},
{
"command": "azureFunctions.createFunctionAppAdvanced",
"group": "3_create@2"
}
],
"view/title": [
Expand All @@ -403,6 +384,16 @@
}
],
"view/item/context": [
{
"command": "azureFunctions.createFunction",
"when": "view == azureWorkspace && viewItem =~ /azFunc.*ReadWrite;Functions;/i",
"group": "inline"
},
{
"command": "azureFunctions.createFunction",
"when": "view == azureWorkspace && viewItem =~ /azFunc.*ReadWrite;Functions;/i",
"group": "1@1"
},
{
"command": "azureFunctions.createFunctionApp",
"when": "view == azureResourceGroups && viewItem =~ /functionapp/i && viewItem =~ /azureResourceTypeGroup/i",
Expand Down Expand Up @@ -1104,7 +1095,7 @@
"id": "create",
"title": "%azureFunctions.walkthrough.functionsStart.create.title%",
"completionEvents": [
"onCommand:azureFunctions.createNewProject"
"onCommand:azureFunctions.createFunction"
],
"description": "%azureFunctions.walkthrough.functionsStart.create.description%",
"media": {
Expand Down Expand Up @@ -1194,7 +1185,7 @@
"@microsoft/vscode-azext-azureappsettings": "^0.2.1",
"@microsoft/vscode-azext-azureutils": "^3.0.0",
"@microsoft/vscode-azext-serviceconnector": "^0.1.3",
"@microsoft/vscode-azext-utils": "^2.3.1",
"@microsoft/vscode-azext-utils": "^2.5.0",
"@microsoft/vscode-azureresources-api": "^2.0.4",
"cross-fetch": "^4.0.0",
"escape-string-regexp": "^4.0.0",
Expand Down
4 changes: 2 additions & 2 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
"azureFunctions.configureDeploymentSource": "Configure Deployment Source...",
"azureFunctions.connectToGitHub": "Connect to GitHub Repository...",
"azureFunctions.copyFunctionUrl": "Copy Function Url",
"azureFunctions.createFunction": "Create Function...",
"azureFunctions.createFunction": "Create function locally...",
"azureFunctions.createFunctionApp": "Create Function App in Azure...",
"azureFunctions.createFunctionAppAdvanced": "Create Function App in Azure... (Advanced)",
"azureFunctions.createFunctionAppDetail": "For serverless, event driven apps and automation.",
"azureFunctions.createNewProject": "Create New Project...",
"azureFunctions.createNewProjectWithDockerfile": "Create New Containerized Project...",
"azureFunctions.createPythonVenv": "Create a virtual environment when creating a new Python project.",
"azureFunctions.createSlot": "Create Slot...",
"azureFunctions.deleteFunction": "Delete Function...",
"azureFunctions.deleteFunctionApp": "Delete Function App...",
"azureFunctions.deleteSlot": "Delete Slot...",
"azureFunctions.deployProject": "Deploy to Azure...",
"azureFunctions.deploy": "Deploy to Function App...",
"azureFunctions.deploySlot": "Deploy to Slot...",
"azureFunctions.deploySubpath": "The default subpath of a workspace folder to use when deploying. If set, you will not be prompted for the folder path when deploying.",
Expand Down
18 changes: 17 additions & 1 deletion src/LocalResourceProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { type AzExtParentTreeItem, type AzExtTreeItem } from "@microsoft/vscode-azext-utils";
import { GenericTreeItem, type AzExtParentTreeItem, type AzExtTreeItem } from "@microsoft/vscode-azext-utils";
import { type WorkspaceResourceProvider } from "@microsoft/vscode-azext-utils/hostapi";
import { Disposable } from "vscode";
import { localize } from "./localize";
import { InitLocalProjectTreeItem } from "./tree/localProject/InitLocalProjectTreeItem";
import { InvalidLocalProjectTreeItem } from "./tree/localProject/InvalidLocalProjectTreeItem";
import { LocalProjectTreeItem } from "./tree/localProject/LocalProjectTreeItem";
import { treeUtils } from "./utils/treeUtils";
import { listLocalProjects, type LocalProjectInternal } from "./workspace/listLocalProjects";

export class FunctionsLocalResourceProvider implements WorkspaceResourceProvider {
Expand All @@ -21,6 +23,7 @@ export class FunctionsLocalResourceProvider implements WorkspaceResourceProvider
this._projectDisposables = [];

const localProjects = await listLocalProjects();
let hasLocalProject = false;

for (const project of localProjects.initializedProjects) {
const treeItem: LocalProjectTreeItem = new LocalProjectTreeItem(parent, project as LocalProjectInternal);
Expand All @@ -29,13 +32,26 @@ export class FunctionsLocalResourceProvider implements WorkspaceResourceProvider
}

for (const unintializedProject of localProjects.unintializedProjects) {
hasLocalProject = true;
children.push(new InitLocalProjectTreeItem(parent, unintializedProject.projectPath, unintializedProject.workspaceFolder));
}

for (const invalidProject of localProjects.invalidProjects) {
hasLocalProject = true;
children.push(new InvalidLocalProjectTreeItem(parent, invalidProject.projectPath, invalidProject.error, invalidProject.workspaceFolder));
}

if (!hasLocalProject && children.length === 0) {
const ti: GenericTreeItem = new GenericTreeItem(parent, {
label: localize('createFunctionLocally', 'Create New Project...'),
commandId: 'azureFunctions.createNewProject',
contextValue: 'createNewProject',
iconPath: treeUtils.getThemedIconPath('CreateNewProject')
});
ti.commandArgs = [];
children.push(ti);
}

return children;
}
private _projectDisposables: Disposable[] = [];
Expand Down
4 changes: 2 additions & 2 deletions src/agent/agentIntegration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export async function getCommands(): Promise<(WizardCommandConfig | SimpleComman
{
type: "simple",
name: createFunctionProjectCommandName,
commandId: "azureFunctions.createNewProject",
displayName: "Create Function Project",
commandId: "azureFunctions.createFunction",
displayName: "Create Function Locally",
intentDescription: "This is best when users ask to create a new function project in VS Code. They may also refer to creating a function project by asking to create a project based upon a function project template.",
requiresAzureLogin: true,
},
Expand Down
41 changes: 41 additions & 0 deletions src/commands/SubscriptionListStep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { AzureWizardPromptStep, type IAzureQuickPickItem } from "@microsoft/vscode-azext-utils";
import { type AzureSubscription } from "@microsoft/vscode-azureresources-api";
import { l10n } from "vscode";
import { ext } from "../extensionVariables";
import { type IFuncDeployContext } from "./deploy/deploy";

export class SubscriptionListStep extends AzureWizardPromptStep<IFuncDeployContext> {
private _picks: IAzureQuickPickItem<AzureSubscription>[] = [];
private _oneSubscription: boolean = false;
public async prompt(context: IFuncDeployContext): Promise<void> {
context.subscription = (await context.ui.showQuickPick(this._picks, { placeHolder: l10n.t("Select a subscription") })).data;
}

public shouldPrompt(_: IFuncDeployContext): boolean {
return !this._oneSubscription;
}

public async configureBeforePrompt(context: IFuncDeployContext): Promise<void> {
this._picks = await this.getPicks(context);
// auto select if only one subscription
if (this._picks.length === 1) {
this._oneSubscription = true;
context.subscription = this._picks[0].data;
}
}

private async getPicks(_: IFuncDeployContext): Promise<IAzureQuickPickItem<AzureSubscription>[]> {
return (await ext.rgApi.getSubscriptions(true)).map(s => {
return { label: s.name, description: s.subscriptionId, data: s };
});
}
}
34 changes: 34 additions & 0 deletions src/commands/createFunctionApp/UniqueNamePromptStep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { type IAppServiceWizardContext } from "@microsoft/vscode-azext-azureappservice";
import { AzureWizardPromptStep } from "@microsoft/vscode-azext-utils";
import { localize } from "../../localize";
import { setConsumptionPlanProperties } from "./FunctionAppHostingPlanStep";
import { type IFunctionAppWizardContext } from "./IFunctionAppWizardContext";

export class ConfigureCommonNamesStep extends AzureWizardPromptStep<IAppServiceWizardContext> {
public async prompt(_context: IAppServiceWizardContext): Promise<void> {
// do nothing, will be handled in configuration
}

public shouldPrompt(_context: IAppServiceWizardContext): boolean {
// never prompt
return false;
}

public async configureBeforePrompt(context: IFunctionAppWizardContext): Promise<void> {
if (!context.advancedCreation) {
const newName: string | undefined = await context.relatedNameTask;
if (!newName) {
throw new Error(localize('noUniqueName', 'Failed to generate unique name for resources. Use advanced creation to manually enter resource names.'));
}
context.newResourceGroupName = context.newResourceGroupName || newName;
setConsumptionPlanProperties(context);
context.newStorageAccountName = newName;
context.newAppInsightsName = newName;
}
}
}
Loading
Loading