Skip to content

Commit b8ac537

Browse files
authored
Add Deploy to Container App with Copilot command (#965)
1 parent 19bb9ca commit b8ac537

File tree

11 files changed

+127
-12
lines changed

11 files changed

+127
-12
lines changed

package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@
9595
"title": "%containerApps.deployContainerApp%",
9696
"category": "Azure Container Apps"
9797
},
98+
{
99+
"command": "containerApps.deployContainerAppWithCopilot",
100+
"title": "%containerApps.deployContainerAppWithCopilot%",
101+
"category": "Azure Container Apps"
102+
},
98103
{
99104
"command": "containerApps.deleteContainerApp",
100105
"title": "%containerApps.deleteContainerApp%",
@@ -383,6 +388,11 @@
383388
"when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /containerAppItem(.*)revisionMode:single/i",
384389
"group": "2@1"
385390
},
391+
{
392+
"command": "containerApps.deployContainerAppWithCopilot",
393+
"when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /containerAppItem(.*)revisionMode:single/i",
394+
"group": "2@2"
395+
},
386396
{
387397
"command": "containerApps.deployRevisionDraft",
388398
"when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /containerAppItem(.*)revisionMode:single(.*)unsavedChanges:true/i",

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"containerApps.deployWorkspaceProject": "Deploy Project from Workspace...",
2626
"containerApps.deployWorkspaceProjectApi": "Deploy Project from Workspace (API)...",
2727
"containerApps.deployContainerApp": "Deploy to Container App...",
28+
"containerApps.deployContainerAppWithCopilot": "Deploy to Container App with Copilot...",
2829
"containerApps.deleteContainerApp": "Delete Container App...",
2930
"containerApps.disableIngress": "Disable Ingress for Container App",
3031
"containerApps.enableIngress": "Enable Ingress for Container App...",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.md in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { CopilotUserInput, type IActionContext } from "@microsoft/vscode-azext-utils";
7+
import * as vscode from 'vscode';
8+
import { type ContainerAppItem } from "../../tree/ContainerAppItem";
9+
import { SharedState } from "../../webviews/OpenConfirmationViewStep";
10+
import { deployContainerApp } from "../deployContainerApp/deployContainerApp";
11+
12+
export async function deployWithCopilot(context: IActionContext, node: ContainerAppItem): Promise<void> {
13+
context.ui = new CopilotUserInput(vscode, JSON.stringify(node.viewProperties), () => SharedState.currentPanel);
14+
await deployContainerApp(context, node);
15+
}

src/commands/deployContainerApp/deployContainerApp.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { KnownActiveRevisionsMode } from "@azure/arm-appcontainers";
7-
import { AzureWizard, createSubscriptionContext, nonNullProp, type IActionContext, type ISubscriptionActionContext, type ISubscriptionContext } from "@microsoft/vscode-azext-utils";
7+
import { AzureWizard, CopilotUserInput, createSubscriptionContext, nonNullProp, type AzureWizardPromptStep, type IActionContext, type ISubscriptionActionContext, type ISubscriptionContext } from "@microsoft/vscode-azext-utils";
88
import { ImageSource } from "../../constants";
99
import { type ContainerAppItem } from "../../tree/ContainerAppItem";
1010
import { createActivityContext } from "../../utils/activityUtils";
@@ -14,6 +14,7 @@ import { getVerifyProvidersStep } from "../../utils/getVerifyProvidersStep";
1414
import { localize } from "../../utils/localize";
1515
import { pickContainerApp } from "../../utils/pickItem/pickContainerApp";
1616
import { OpenConfirmationViewStep } from "../../webviews/OpenConfirmationViewStep";
17+
import { OpenLoadingViewStep } from "../../webviews/OpenLoadingViewStep";
1718
import { CommandAttributes } from "../CommandAttributes";
1819
import { ContainerAppOverwriteConfirmStep } from "../ContainerAppOverwriteConfirmStep";
1920
import { deployWorkspaceProject } from "../deployWorkspaceProject/deployWorkspaceProject";
@@ -60,18 +61,28 @@ export async function deployContainerApp(context: IActionContext, node?: Contain
6061
wizardContext.telemetry.properties.revisionMode = item.containerApp.revisionsMode;
6162

6263
const confirmationViewTitle: string = localize('summary', 'Summary');
63-
const confirmationViewDescription: string = localize('viewDescription', 'Please select an input you would like to change. Note: Any input proceeding the changed input may need to change as well');
64-
const confirmationViewTabTitle: string = localize('deployContainerAppTabTitle', 'Summary - Deploy Image to Container App');
65-
const title: string = localize('deployContainerAppTitle', 'Deploy image to container app');
64+
let confirmationViewDescription: string = localize('viewDescription', 'Please select an input you would like to change. Note: Any input proceeding the changed input will need to change as well');
65+
let confirmationViewTabTitle: string = localize('deployContainerAppTabTitle', 'Summary - Deploy Image to Container App');
66+
let title: string = localize('deployContainerAppTitle', 'Deploy image to container app');
67+
68+
const promptSteps: AzureWizardPromptStep<ContainerAppDeployContext>[] = []
69+
if (wizardContext.ui instanceof CopilotUserInput) {
70+
promptSteps.push(new OpenLoadingViewStep());
71+
confirmationViewDescription = localize('viewDescription', 'Please review AI generated inputs and select any you would like to modify. Note: Any input proceeding the modified input will need to change as well');
72+
confirmationViewTabTitle = localize('deployContainerAppTabTitle', 'Summary - Deploy Image to Container App using Copilot');
73+
title = localize('deployContainerAppWithCopilotTitle', 'Deploy image to container app using copilot');
74+
}
75+
76+
promptSteps.push(
77+
new ContainerAppDeployStartingResourcesLogStep(),
78+
new ImageSourceListStep(),
79+
new ContainerAppOverwriteConfirmStep(),
80+
new OpenConfirmationViewStep(confirmationViewTitle, confirmationViewTabTitle, confirmationViewDescription, title, () => wizard.confirmationViewProperties)
81+
);
6682

6783
const wizard: AzureWizard<ContainerAppDeployContext> = new AzureWizard(wizardContext, {
6884
title: title,
69-
promptSteps: [
70-
new ContainerAppDeployStartingResourcesLogStep(),
71-
new ImageSourceListStep(),
72-
new ContainerAppOverwriteConfirmStep(),
73-
new OpenConfirmationViewStep(confirmationViewTitle, confirmationViewTabTitle, confirmationViewDescription, title, () => wizard.confirmationViewProperties)
74-
],
85+
promptSteps: promptSteps,
7586
executeSteps: [
7687
getVerifyProvidersStep<ContainerAppDeployContext>(),
7788
new ContainerAppUpdateStep(),

src/commands/registerCommands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { registerCommand, registerCommandWithTreeNodeUnwrapping, registerErrorHa
77
import { type EnvironmentVariableItem } from '../tree/containers/EnvironmentVariableItem';
88
import { deployImageApiCompat } from './api/deployImageApi';
99
import { browseContainerAppNode } from './browseContainerApp';
10+
import { deployWithCopilot } from './copilot/deployWithCopilot';
1011
import { createContainerApp } from './createContainerApp/createContainerApp';
1112
import { createManagedEnvironment } from './createManagedEnvironment/createManagedEnvironment';
1213
import { deleteContainerApp } from './deleteContainerApp/deleteContainerApp';
@@ -87,6 +88,7 @@ export function registerCommands(): void {
8788
registerCommandWithTreeNodeUnwrapping('containerApps.deployRevisionDraft', deployRevisionDraft);
8889
registerCommandWithTreeNodeUnwrapping('containerApps.deployWorkspaceProject', deployWorkspaceProject);
8990
registerCommandWithTreeNodeUnwrapping('containerApps.deployContainerApp', deployContainerApp);
91+
registerCommandWithTreeNodeUnwrapping('containerApps.deployContainerAppWithCopilot', deployWithCopilot);
9092

9193
// github
9294
registerCommandWithTreeNodeUnwrapping('containerApps.connectToGitHub', connectToGitHub);

src/webviews/LoadingView.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
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 { Spinner } from "@fluentui/react-components";
7+
import './loadingView.scss';
8+
9+
export const LoadingView = () =>
10+
<div className='loadingView'>
11+
<Spinner labelPosition="below" label="Generating Copilot responses..." />
12+
</div>
13+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.md in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { ViewColumn } from "vscode";
7+
import { ext } from "../extensionVariables";
8+
import { WebviewController } from "./extension-server/WebviewController";
9+
10+
export type LoadingViewControllerType = {
11+
title: string;
12+
}
13+
14+
export class LoadingViewController extends WebviewController<LoadingViewControllerType> {
15+
constructor(viewConfiguration: LoadingViewControllerType) {
16+
super(ext.context, viewConfiguration.title, 'loadingView', viewConfiguration, ViewColumn.Active);
17+
}
18+
}

src/webviews/OpenConfirmationViewStep.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
* Licensed under the MIT License. See License.md in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { AzureWizardPromptStep, GoBackError, openUrl, UserCancelledError, type ConfirmationViewProperty, type IActionContext } from "@microsoft/vscode-azext-utils";
6+
import { AzExtUserInput, AzureWizardPromptStep, CopilotUserInput, GoBackError, openUrl, UserCancelledError, type ConfirmationViewProperty, type IActionContext } from "@microsoft/vscode-azext-utils";
77
import * as vscode from 'vscode';
8+
import { type WebviewPanel } from 'vscode';
89
import { localize } from "../utils/localize";
910
import { ConfirmationViewController } from "./ConfirmationViewController";
1011

@@ -13,6 +14,7 @@ export const SharedState = {
1314
cancelled: true,
1415
copilotClicked: false,
1516
editingPicks: false,
17+
currentPanel: undefined as WebviewPanel | undefined,
1618
};
1719

1820
export class OpenConfirmationViewStep<T extends IActionContext> extends AzureWizardPromptStep<T> {
@@ -32,6 +34,11 @@ export class OpenConfirmationViewStep<T extends IActionContext> extends AzureWiz
3234
}
3335

3436
public async prompt(context: T): Promise<void> {
37+
if (SharedState.currentPanel) {
38+
SharedState.currentPanel.dispose();
39+
SharedState.currentPanel = undefined;
40+
}
41+
3542
const confirmationView = new ConfirmationViewController({
3643
title: this.title,
3744
tabTitle: this.tabTitle,
@@ -48,6 +55,9 @@ export class OpenConfirmationViewStep<T extends IActionContext> extends AzureWiz
4855
if (SharedState.itemsToClear > 0) {
4956
context.telemetry.properties.editingPicks = 'true';
5057
SharedState.editingPicks = true;
58+
if (context.ui instanceof CopilotUserInput) {
59+
context.ui = new AzExtUserInput(context);
60+
}
5161
throw new GoBackError(SharedState.itemsToClear);
5262
}
5363

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.md in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { AzureWizardPromptStep, type IActionContext } from "@microsoft/vscode-azext-utils";
7+
import * as vscode from 'vscode';
8+
import { localize } from "../utils/localize";
9+
import { LoadingViewController } from "./LoadingViewController";
10+
import { SharedState } from "./OpenConfirmationViewStep";
11+
12+
export class OpenLoadingViewStep<T extends IActionContext> extends AzureWizardPromptStep<T> {
13+
public async prompt(): Promise<void> {
14+
const loadingView = new LoadingViewController({ title: localize('loadingViewTitle', 'Loading...') });
15+
loadingView.revealToForeground(vscode.ViewColumn.Active);
16+
SharedState.currentPanel = loadingView.panel;
17+
}
18+
19+
public shouldPrompt(): boolean {
20+
return true;
21+
}
22+
}

src/webviews/WebviewRegistry.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { ConfirmationView } from "./ConfirmationView";
7+
import { LoadingView } from "./LoadingView";
78

89
export const WebviewRegistry = {
9-
confirmationView: ConfirmationView
10+
confirmationView: ConfirmationView,
11+
loadingView: LoadingView
1012
} as const;

0 commit comments

Comments
 (0)