Skip to content

Commit 3a70f29

Browse files
authored
Add activity log & draft support to editScaleRange (#466)
1 parent 415b41d commit 3a70f29

File tree

10 files changed

+163
-69
lines changed

10 files changed

+163
-69
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@
195195
"category": "Azure Container Apps"
196196
},
197197
{
198-
"command": "containerApps.editScalingRange",
199-
"title": "%containerApps.editScalingRange%",
198+
"command": "containerApps.editScaleRange",
199+
"title": "%containerApps.editScaleRange%",
200200
"category": "Azure Container Apps"
201201
},
202202
{
@@ -405,7 +405,7 @@
405405
"group": "2@1"
406406
},
407407
{
408-
"command": "containerApps.editScalingRange",
408+
"command": "containerApps.editScaleRange",
409409
"when": "view =~ /(azureResourceGroups|azureFocusView)/ && viewItem =~ /scaleItem/i",
410410
"group": "1@1"
411411
},

package.nls.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"containerApps.deleteConfirmation.ClickButton": "Prompts with a warning dialog where you click a button to delete.",
3636
"containerApps.openInPortal": "Open in Portal",
3737
"containerApps.openConsoleInPortal": "Open Console in Portal",
38-
"containerApps.editScalingRange": "Edit Scaling Range...",
38+
"containerApps.editScaleRange": "Edit Scaling Range...",
3939
"containerApps.addScaleRule": "Add Scale Rule...",
4040
"containerApps.deleteScaleRule": "Delete Scale Rule...",
4141
"containerApps.connectToGitHub": "Connect to GitHub Repository...",

src/commands/EXECUTE_PRIORITY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ Reserved
9393

9494
#### Steps
9595

96+
- ScaleRangeUpdateStep: 1110
9697
- AddScaleRuleStep: 1120
9798

9899
### 10. Unallocated Space

src/commands/registerCommands.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { createRevisionDraft } from './revisionDraft/createRevisionDraft';
3232
import { deployRevisionDraft } from './revisionDraft/deployRevisionDraft/deployRevisionDraft';
3333
import { discardRevisionDraft } from './revisionDraft/discardRevisionDraft';
3434
import { editRevisionDraft } from './revisionDraft/editRevisionDraft';
35-
import { editScalingRange } from './scaling/editScalingRange';
35+
import { editScaleRange } from './scaling/scaleRange/editScaleRange';
3636
import { addScaleRule } from './scaling/scaleRule/addScaleRule/addScaleRule';
3737
import { deleteScaleRule } from './scaling/scaleRule/deleteScaleRule/deleteScaleRule';
3838
import { addSecret } from './secret/addSecret/addSecret';
@@ -87,7 +87,7 @@ export function registerCommands(): void {
8787
registerCommandWithTreeNodeUnwrapping('containerApps.discardRevisionDraft', discardRevisionDraft);
8888

8989
// scaling
90-
registerCommandWithTreeNodeUnwrapping('containerApps.editScalingRange', editScalingRange);
90+
registerCommandWithTreeNodeUnwrapping('containerApps.editScaleRange', editScaleRange);
9191
registerCommandWithTreeNodeUnwrapping('containerApps.addScaleRule', addScaleRule);
9292
registerCommandWithTreeNodeUnwrapping('containerApps.deleteScaleRule', deleteScaleRule);
9393

src/commands/scaling/editScalingRange.ts

Lines changed: 0 additions & 62 deletions
This file was deleted.
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.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import type { ExecuteActivityContext } from "@microsoft/vscode-azext-utils";
7+
import type { IContainerAppContext } from "../../IContainerAppContext";
8+
9+
export interface ScaleRangeContext extends IContainerAppContext, ExecuteActivityContext {
10+
newMinRange?: number;
11+
newMaxRange?: number;
12+
13+
scaleMinRange: number;
14+
scaleMaxRange: number;
15+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 { AzureWizardPromptStep } from '@microsoft/vscode-azext-utils';
7+
import { localize } from '../../../utils/localize';
8+
import type { ScaleRangeContext } from './ScaleRangeContext';
9+
10+
export class ScaleRangePromptStep extends AzureWizardPromptStep<ScaleRangeContext> {
11+
public async prompt(context: ScaleRangeContext): Promise<void> {
12+
const scaleRange: string = (await context.ui.showInputBox({
13+
prompt: localize('editScalingRange', 'Set the range of application replicas that get created in response to a scale rule. Set any range within the minimum of 0 and the maximum of 10 replicas'),
14+
value: `${context.scaleMinRange}-${context.scaleMaxRange}`,
15+
validateInput: this.validateInput,
16+
})).trim();
17+
18+
const [min, max] = scaleRange.split('-').map(range => Number(range));
19+
context.newMinRange = min;
20+
context.newMaxRange = max;
21+
}
22+
23+
public shouldPrompt(context: ScaleRangeContext): boolean {
24+
return !context.newMinRange || !context.newMaxRange;
25+
}
26+
27+
private validateInput(range: string | undefined): string | undefined {
28+
const formatRegex = /^\d{1,2}-\d{1,2}$/;
29+
if (!range || !formatRegex.test(range)) {
30+
return localize('enterRange', 'Please enter the range in the following format "0-10"');
31+
}
32+
33+
const [min, max] = range.split('-').map(range => Number(range));
34+
if (min > 10 || max > 10) {
35+
return localize('maxRangeExceeded', 'The maximum number of replicas is 10.');
36+
} else if (min > max) {
37+
return localize('minHigherThanMax', 'The minimum range cannot be larger than the maximum range.');
38+
} else if (max === 0) {
39+
return localize('maxGreaterThan0', 'The maximum replicas must be greater than 0.');
40+
}
41+
42+
return undefined;
43+
}
44+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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 { nonNullProp } from "@microsoft/vscode-azext-utils";
7+
import { ext } from "../../../extensionVariables";
8+
import type { RevisionsItemModel } from "../../../tree/revisionManagement/RevisionItem";
9+
import { localize } from "../../../utils/localize";
10+
import { getParentResourceFromItem } from "../../../utils/revisionDraftUtils";
11+
import { RevisionDraftUpdateBaseStep } from "../../revisionDraft/RevisionDraftUpdateBaseStep";
12+
import type { ScaleRangeContext } from "./ScaleRangeContext";
13+
14+
export class ScaleRangeUpdateStep<T extends ScaleRangeContext> extends RevisionDraftUpdateBaseStep<T> {
15+
public priority: number = 1110;
16+
17+
constructor(baseItem: RevisionsItemModel) {
18+
super(baseItem);
19+
}
20+
21+
public async execute(context: ScaleRangeContext): Promise<void> {
22+
this.revisionDraftTemplate.scale ||= {};
23+
this.revisionDraftTemplate.scale.minReplicas = context.newMinRange;
24+
this.revisionDraftTemplate.scale.maxReplicas = context.newMaxRange;
25+
26+
this.updateRevisionDraftWithTemplate();
27+
28+
context.scaleMinRange = nonNullProp(context, 'newMinRange');
29+
context.scaleMaxRange = nonNullProp(context, 'newMaxRange');
30+
31+
const parentResourceName = getParentResourceFromItem(this.baseItem).name;
32+
ext.outputChannel.appendLog(localize('updatedScaleRange', 'Updated replica scaling range to {0}-{1} for "{2}".', context.newMinRange, context.newMaxRange, parentResourceName));
33+
}
34+
35+
public shouldExecute(context: ScaleRangeContext): boolean {
36+
return context.newMinRange !== undefined && context.newMaxRange !== undefined;
37+
}
38+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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 type { Revision, Scale } from "@azure/arm-appcontainers";
7+
import { AzureWizard, IActionContext, createSubscriptionContext, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
8+
import type { ContainerAppModel } from "../../../tree/ContainerAppItem";
9+
import type { ScaleItem } from "../../../tree/scaling/ScaleItem";
10+
import { createActivityContext } from "../../../utils/activityUtils";
11+
import { localize } from "../../../utils/localize";
12+
import { pickScale } from "../../../utils/pickItem/pickScale";
13+
import { getParentResource } from "../../../utils/revisionDraftUtils";
14+
import type { ScaleRangeContext } from "./ScaleRangeContext";
15+
import { ScaleRangePromptStep } from "./ScaleRangePromptStep";
16+
import { ScaleRangeUpdateStep } from "./ScaleRangeUpdateStep";
17+
18+
export async function editScaleRange(context: IActionContext, node?: ScaleItem): Promise<void> {
19+
const item: ScaleItem = node ?? await pickScale(context, { autoSelectDraft: true });
20+
const { containerApp, revision, subscription } = item;
21+
22+
const parentResource: ContainerAppModel | Revision = getParentResource(containerApp, revision);
23+
const scale: Scale = nonNullValueAndProp(parentResource.template, 'scale');
24+
25+
const wizardContext: ScaleRangeContext = {
26+
...context,
27+
...createSubscriptionContext(subscription),
28+
...await createActivityContext(),
29+
containerApp,
30+
subscription,
31+
scaleMinRange: scale.minReplicas ?? 0,
32+
scaleMaxRange: scale.maxReplicas ?? 0
33+
};
34+
35+
const wizard: AzureWizard<ScaleRangeContext> = new AzureWizard(wizardContext, {
36+
title: localize('editScaleRangePre', 'Update replica scaling range for "{0}" (draft)', parentResource.name),
37+
promptSteps: [new ScaleRangePromptStep()],
38+
executeSteps: [new ScaleRangeUpdateStep(item)],
39+
showLoadingPrompt: true
40+
});
41+
42+
await wizard.prompt();
43+
wizardContext.activityTitle = localize('editScaleRange', 'Update replica scaling range to "{0}-{1}" for "{2}" (draft)', wizardContext.newMinRange, wizardContext.newMaxRange, parentResource.name);
44+
await wizard.execute();
45+
}

src/utils/revisionDraftUtils.ts

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

66
import { KnownActiveRevisionsMode, Revision } from "@azure/arm-appcontainers";
7-
import { ContainerAppModel } from "../tree/ContainerAppItem";
7+
import { ContainerAppItem, ContainerAppModel } from "../tree/ContainerAppItem";
8+
import type { RevisionsItemModel } from "../tree/revisionManagement/RevisionItem";
89

910
/**
1011
* Use to always select the correct parent resource model
@@ -13,3 +14,15 @@ import { ContainerAppModel } from "../tree/ContainerAppItem";
1314
export function getParentResource(containerApp: ContainerAppModel, revision: Revision): ContainerAppModel | Revision {
1415
return containerApp.revisionsMode === KnownActiveRevisionsMode.Single ? containerApp : revision;
1516
}
17+
18+
/**
19+
* Use to always select the correct parent resource model from an item
20+
* https://github.com/microsoft/vscode-azurecontainerapps/blob/main/src/commands/revisionDraft/README.md
21+
*/
22+
export function getParentResourceFromItem(item: ContainerAppItem | RevisionsItemModel): ContainerAppModel | Revision {
23+
if (ContainerAppItem.isContainerAppItem(item) || item.containerApp.revisionsMode === KnownActiveRevisionsMode.Single) {
24+
return item.containerApp;
25+
} else {
26+
return item.revision;
27+
}
28+
}

0 commit comments

Comments
 (0)