Skip to content

Commit b9abec9

Browse files
authored
Show updated activity children output for createContainerApp (#756)
1 parent b4689c0 commit b9abec9

File tree

8 files changed

+128
-46
lines changed

8 files changed

+128
-46
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { activityFailContext, activityFailIcon, activityProgressContext, activityProgressIcon, activitySuccessContext, activitySuccessIcon, AzureWizardExecuteStep, createUniversallyUniqueContextValue, GenericParentTreeItem, GenericTreeItem, nonNullValue, type ExecuteActivityOutput, type IActionContext } from "@microsoft/vscode-azext-utils";
7+
8+
interface ActivityOutputCreateOptions {
9+
stepName: string;
10+
treeItemLabel: string;
11+
outputLogMessage?: string;
12+
activityStatus: 'Success' | 'Fail' | 'Progress';
13+
}
14+
15+
export abstract class AzureWizardActivityOutputExecuteStep<T extends IActionContext> extends AzureWizardExecuteStep<T> {
16+
abstract stepName: string;
17+
protected abstract getSuccessString(context: T): string;
18+
protected abstract getFailString(context: T): string;
19+
20+
protected getProgressString?(context: T): string;
21+
/**
22+
* Optional; define this if you want a special, custom label to be assigned to each tree item
23+
* that is different than the required success or fail strings
24+
*/
25+
protected getTreeItemLabel?(context: T): string;
26+
27+
public createSuccessOutput(context: T): ExecuteActivityOutput {
28+
const success: string = this.getSuccessString(context);
29+
30+
return createExecuteActivityOutput(context, {
31+
activityStatus: 'Success',
32+
stepName: this.stepName,
33+
treeItemLabel: this.getTreeItemLabel ? this.getTreeItemLabel(context) : success,
34+
outputLogMessage: success,
35+
});
36+
}
37+
38+
public createProgressOutput(context: T): ExecuteActivityOutput {
39+
const progress: string | undefined = this.getProgressString?.(context);
40+
41+
return createExecuteActivityOutput(context, {
42+
activityStatus: 'Progress',
43+
stepName: this.stepName,
44+
treeItemLabel: this.getTreeItemLabel ? this.getTreeItemLabel(context) : nonNullValue(progress),
45+
outputLogMessage: progress,
46+
});
47+
}
48+
49+
public createFailOutput(context: T): ExecuteActivityOutput {
50+
const fail: string = this.getFailString(context);
51+
52+
return createExecuteActivityOutput(context, {
53+
activityStatus: 'Fail',
54+
stepName: this.stepName,
55+
treeItemLabel: this.getTreeItemLabel ? this.getTreeItemLabel(context) : fail,
56+
outputLogMessage: fail,
57+
});
58+
}
59+
}
60+
61+
function createExecuteActivityOutput(_: IActionContext, options: ActivityOutputCreateOptions): ExecuteActivityOutput {
62+
const activityContext = options.activityStatus === 'Success' ? activitySuccessContext : options.activityStatus === 'Fail' ? activityFailContext : activityProgressContext;
63+
const contextValue = createUniversallyUniqueContextValue([`${options.stepName}${options.activityStatus}Item`, activityContext]);
64+
const label = options.treeItemLabel;
65+
const iconPath = options.activityStatus === 'Success' ? activitySuccessIcon : options.activityStatus === 'Fail' ? activityFailIcon : activityProgressIcon;
66+
67+
const item = options.activityStatus === 'Fail' ?
68+
// Logic is in place to automatically attach an error item as child if thrown during a registered execute step -- therefore, return fails with a parent tree item
69+
new GenericParentTreeItem(undefined, {
70+
contextValue,
71+
label,
72+
iconPath
73+
}) :
74+
new GenericTreeItem(undefined, {
75+
contextValue,
76+
label,
77+
iconPath
78+
});
79+
80+
return {
81+
item,
82+
message: options.outputLogMessage,
83+
}
84+
}

src/commands/EXECUTE_PRIORITY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ When creating or updating resources, execute steps should occupy certain priorit
6868

6969
#### Steps
7070

71+
- QuickStartImageConfigureStep: 610
7172
- ContainerAppCreateStep: 620
7273
- ContainerAppUpdateStep: 650
7374

src/commands/createContainerApp/ContainerAppCreateStep.ts

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,24 @@
55

66
import { KnownActiveRevisionsMode, type ContainerAppsAPIClient, type Ingress } from "@azure/arm-appcontainers";
77
import { LocationListStep } from "@microsoft/vscode-azext-azureutils";
8-
import { AzureWizardExecuteStep, GenericParentTreeItem, GenericTreeItem, activityFailContext, activityFailIcon, activitySuccessContext, activitySuccessIcon, createUniversallyUniqueContextValue, nonNullProp, nonNullValueAndProp, type ExecuteActivityOutput } from "@microsoft/vscode-azext-utils";
8+
import { nonNullProp, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
99
import { type Progress } from "vscode";
1010
import { containerAppsWebProvider } from "../../constants";
1111
import { ContainerAppItem } from "../../tree/ContainerAppItem";
1212
import { createContainerAppsAPIClient } from "../../utils/azureClients";
1313
import { localize } from "../../utils/localize";
14+
import { AzureWizardActivityOutputExecuteStep } from "../AzureWizardActivityOutputExecuteStep";
1415
import { getContainerNameForImage } from "../image/imageSource/containerRegistry/getContainerNameForImage";
1516
import { type ContainerAppCreateContext } from "./ContainerAppCreateContext";
1617

17-
export class ContainerAppCreateStep extends AzureWizardExecuteStep<ContainerAppCreateContext> {
18+
export class ContainerAppCreateStep<T extends ContainerAppCreateContext> extends AzureWizardActivityOutputExecuteStep<T> {
1819
public priority: number = 620;
20+
public stepName: string = 'containerAppCreateStep';
21+
protected getSuccessString = (context: T) => localize('createContainerAppSuccess', 'Created container app "{0}"', context.newContainerAppName);
22+
protected getFailString = (context: T) => localize('createContainerAppFail', 'Failed to create container app "{0}"', context.newContainerAppName);
23+
protected getTreeItemLabel = (context: T) => localize('createContainerAppLabel', 'Create container app "{0}"', context.newContainerAppName);
1924

20-
public async execute(context: ContainerAppCreateContext, progress: Progress<{ message?: string | undefined; increment?: number | undefined }>): Promise<void> {
25+
public async execute(context: T, progress: Progress<{ message?: string | undefined; increment?: number | undefined }>): Promise<void> {
2126
const appClient: ContainerAppsAPIClient = await createContainerAppsAPIClient(context);
2227

2328
const resourceGroupName: string = nonNullValueAndProp(context.resourceGroup, 'name');
@@ -60,29 +65,7 @@ export class ContainerAppCreateStep extends AzureWizardExecuteStep<ContainerAppC
6065
}));
6166
}
6267

63-
public shouldExecute(context: ContainerAppCreateContext): boolean {
68+
public shouldExecute(context: T): boolean {
6469
return !context.containerApp;
6570
}
66-
67-
public createSuccessOutput(context: ContainerAppCreateContext): ExecuteActivityOutput {
68-
return {
69-
item: new GenericTreeItem(undefined, {
70-
contextValue: createUniversallyUniqueContextValue(['containerAppCreateStepSuccessItem', activitySuccessContext]),
71-
label: localize('createContainerApp', 'Create container app "{0}"', context.newContainerAppName),
72-
iconPath: activitySuccessIcon
73-
}),
74-
message: localize('createContainerAppSuccess', 'Created container app "{0}".', context.newContainerAppName)
75-
};
76-
}
77-
78-
public createFailOutput(context: ContainerAppCreateContext): ExecuteActivityOutput {
79-
return {
80-
item: new GenericParentTreeItem(undefined, {
81-
contextValue: createUniversallyUniqueContextValue(['containerAppCreateStepFailItem', activityFailContext]),
82-
label: localize('createContainerApp', 'Create container app "{0}"', context.newContainerAppName),
83-
iconPath: activityFailIcon
84-
}),
85-
message: localize('createContainerAppFail', 'Failed to create container app "{0}".', context.newContainerAppName)
86-
};
87-
}
8871
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { ImageSource, quickStartImageName } from "../../constants";
7+
import { localize } from "../../utils/localize";
8+
import { AzureWizardActivityOutputExecuteStep } from "../AzureWizardActivityOutputExecuteStep";
9+
import { type ImageSourceContext } from "../image/imageSource/ImageSourceContext";
10+
import { type ContainerAppCreateContext } from "./ContainerAppCreateContext";
11+
12+
export class QuickStartImageConfigureStep<T extends ContainerAppCreateContext & ImageSourceContext> extends AzureWizardActivityOutputExecuteStep<T> {
13+
public priority: number = 610;
14+
public stepName: string = 'quickStartImageConfigureStep';
15+
protected getSuccessString = () => localize('quickStartImageSuccess', 'Successfully configured quick start image.');
16+
protected getFailString = () => localize('quickStartImageFail', 'Failed to configure quick start image.');
17+
protected getTreeItemLabel = () => localize('quickStartImageLabel', 'Configure quick start image');
18+
19+
public async execute(context: T): Promise<void> {
20+
context.image = quickStartImageName;
21+
context.enableIngress = true;
22+
context.enableExternal = true;
23+
context.targetPort = 80;
24+
}
25+
26+
public shouldExecute(context: T): boolean {
27+
return !context.image && context.imageSource === ImageSource.QuickstartImage;
28+
}
29+
}

src/commands/createContainerApp/createContainerApp.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { getVerifyProvidersStep } from "../../utils/getVerifyProvidersStep";
1616
import { localize } from "../../utils/localize";
1717
import { pickEnvironment } from "../../utils/pickItem/pickEnvironment";
1818
import { ImageSourceListStep } from "../image/imageSource/ImageSourceListStep";
19-
import { IngressPromptStep } from "../ingress/IngressPromptStep";
2019
import { type ContainerAppCreateContext } from "./ContainerAppCreateContext";
2120
import { ContainerAppCreateStep } from "./ContainerAppCreateStep";
2221
import { ContainerAppNameStep } from "./ContainerAppNameStep";
@@ -33,7 +32,7 @@ export async function createContainerApp(context: IActionContext, node?: Managed
3332
const wizardContext: ContainerAppCreateContext = {
3433
...context,
3534
...createSubscriptionContext(node.subscription),
36-
...await createActivityContext(),
35+
...await createActivityContext(true),
3736
subscription: node.subscription,
3837
managedEnvironment: node.managedEnvironment,
3938
imageSource: ImageSource.QuickstartImage,
@@ -55,7 +54,6 @@ export async function createContainerApp(context: IActionContext, node?: Managed
5554
promptSteps: [
5655
new ContainerAppNameStep(),
5756
new ImageSourceListStep(),
58-
new IngressPromptStep(),
5957
],
6058
executeSteps: [
6159
getVerifyProvidersStep<ContainerAppCreateContext>(),

src/commands/createContainerApp/setQuickStartImage.ts

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/commands/image/imageSource/ImageSourceListStep.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { AzureWizardPromptStep, type AzureWizardExecuteStep, type IAzureQuickPic
77
import { UIKind, env, workspace } from "vscode";
88
import { ImageSource } from "../../../constants";
99
import { localize } from "../../../utils/localize";
10-
import { setQuickStartImage } from "../../createContainerApp/setQuickStartImage";
10+
import { QuickStartImageConfigureStep } from "../../createContainerApp/QuickStartImageConfigureStep";
1111
import { RegistryCredentialsAddConfigurationListStep } from "../../registryCredentials/RegistryCredentialsAddConfigurationListStep";
1212
import { EnvironmentVariablesListStep } from "./EnvironmentVariablesListStep";
1313
import { type ImageSourceContext } from "./ImageSourceContext";
@@ -65,7 +65,7 @@ export class ImageSourceListStep extends AzureWizardPromptStep<ImageSourceContex
6565

6666
switch (context.imageSource) {
6767
case ImageSource.QuickstartImage:
68-
setQuickStartImage(context);
68+
executeSteps.push(new QuickStartImageConfigureStep());
6969
context.telemetry.properties.imageSource = ImageSource.QuickstartImage;
7070
break;
7171
case ImageSource.ContainerRegistry:

src/utils/activityUtils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import { type AzureResourcesExtensionApiWithActivity } from "@microsoft/vscode-a
88
import { ext } from "../extensionVariables";
99
import { settingUtils } from "./settingUtils";
1010

11-
export async function createActivityContext(): Promise<ExecuteActivityContext> {
11+
export async function createActivityContext(withChildren?: boolean): Promise<ExecuteActivityContext> {
1212
return {
1313
registerActivity: async (activity) => (ext.rgApiV2 as AzureResourcesExtensionApiWithActivity).activity.registerActivity(activity),
1414
suppressNotification: await settingUtils.getSetting('suppressActivityNotifications', undefined, 'azureResourceGroups'),
15+
activityChildren: withChildren ? [] : undefined,
1516
};
1617
}

0 commit comments

Comments
 (0)