33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6- import { AzureWizardPromptStep , type IAzureQuickPickItem , type IWizardOptions } from '@microsoft/vscode-azext-utils' ;
6+ import { AzureWizardPromptStep , type IActionContext , type IAzureQuickPickItem , type IAzureQuickPickOptions , type IWizardOptions } from '@microsoft/vscode-azext-utils' ;
77import * as escape from 'escape-string-regexp' ;
88import { type FuncVersion } from '../../FuncVersion' ;
9- import { JavaBuildTool , ProjectLanguage } from '../../constants' ;
9+ import { JavaBuildTool , ProjectLanguage , TemplateFilter , templateFilterSetting } from '../../constants' ;
1010import { ext } from '../../extensionVariables' ;
1111import { localize } from '../../localize' ;
1212import { type FunctionTemplateBase , type IFunctionTemplate } from '../../templates/IFunctionTemplate' ;
1313import { TemplateSchemaVersion } from '../../templates/TemplateProviderBase' ;
1414import { durableUtils } from '../../utils/durableUtils' ;
1515import { nonNullProp } from '../../utils/nonNull' ;
1616import { isNodeV4Plus , isPythonV2Plus , nodeV4Suffix } from '../../utils/programmingModelUtils' ;
17- import { getWorkspaceSetting } from '../../vsCodeConfig/settings' ;
17+ import { getWorkspaceSetting , updateWorkspaceSetting } from '../../vsCodeConfig/settings' ;
1818import { FunctionSubWizard } from './FunctionSubWizard' ;
1919import { type IFunctionWizardContext } from './IFunctionWizardContext' ;
2020import { JobsListStep } from './JobsListStep' ;
@@ -39,7 +39,7 @@ export class FunctionListStep extends AzureWizardPromptStep<IFunctionWizardConte
3939 const language : ProjectLanguage = nonNullProp ( context , 'language' ) ;
4040 const version : FuncVersion = nonNullProp ( context , 'version' ) ;
4141 const templateProvider = ext . templateProvider . get ( context ) ;
42- const templates : FunctionTemplateBase [ ] = await templateProvider . getFunctionTemplates ( context , context . projectPath , language , context . languageModel , version , context . projectTemplateKey ) ;
42+ const templates : FunctionTemplateBase [ ] = await templateProvider . getFunctionTemplates ( context , context . projectPath , language , context . languageModel , version , TemplateFilter . All , context . projectTemplateKey ) ;
4343 const foundTemplate : FunctionTemplateBase | undefined = templates . find ( ( t : FunctionTemplateBase ) => {
4444 if ( this . _options . templateId ) {
4545 const actualId : string = t . id . toLowerCase ( ) ;
@@ -83,6 +83,10 @@ export class FunctionListStep extends AzureWizardPromptStep<IFunctionWizardConte
8383 }
8484
8585 public async prompt ( context : IFunctionWizardContext ) : Promise < void > {
86+ /* v2 schema doesn't have a template filter setting */
87+ let templateFilter : TemplateFilter = context . templateSchemaVersion === TemplateSchemaVersion . v2 ? TemplateFilter . All :
88+ getWorkspaceSetting < TemplateFilter > ( templateFilterSetting , context . projectPath ) || TemplateFilter . Verified ;
89+
8690 const templateProvider = ext . templateProvider . get ( context ) ;
8791 while ( ! context . functionTemplate ) {
8892 let placeHolder : string = this . _isProjectWizard ?
@@ -93,13 +97,17 @@ export class FunctionListStep extends AzureWizardPromptStep<IFunctionWizardConte
9397 placeHolder += localize ( 'templateSource' , ' (Template source: "{0}")' , templateProvider . templateSource )
9498 }
9599
96- const result : FunctionTemplateBase | TemplatePromptResult =
97- ( await context . ui . showQuickPick ( this . getPicks ( context ) ,
98- { placeHolder, enableGrouping : true } ) ) . data ;
99-
100+ const result : FunctionTemplateBase | TemplatePromptResult = ( await context . ui . showQuickPick ( this . getPicks ( context , templateFilter ) , { placeHolder } ) ) . data ;
100101 if ( result === 'skipForNow' ) {
101102 context . telemetry . properties . templateId = 'skipForNow' ;
102103 break ;
104+ } else if ( result === 'changeFilter' ) {
105+ templateFilter = await promptForTemplateFilter ( context ) ;
106+ // can only update setting if it's open in a workspace
107+ if ( ! this . _isProjectWizard || context . openBehavior === 'AlreadyOpen' ) {
108+ await updateWorkspaceSetting ( templateFilterSetting , templateFilter , context . projectPath ) ;
109+ }
110+ context . telemetry . properties . changedFilter = 'true' ;
103111 } else if ( result === 'openAPI' ) {
104112 context . generateFromOpenAPI = true ;
105113 break ;
@@ -109,6 +117,8 @@ export class FunctionListStep extends AzureWizardPromptStep<IFunctionWizardConte
109117 } else {
110118 context . functionTemplate = result ;
111119 }
120+
121+ context . telemetry . properties . templateFilter = templateFilter ;
112122 }
113123 }
114124
@@ -118,18 +128,18 @@ export class FunctionListStep extends AzureWizardPromptStep<IFunctionWizardConte
118128 context . language !== ProjectLanguage . SelfHostedMCPServer ;
119129 }
120130
121- private async getPicks ( context : IFunctionWizardContext ) : Promise < IAzureQuickPickItem < FunctionTemplateBase | TemplatePromptResult > [ ] > {
131+ private async getPicks ( context : IFunctionWizardContext , templateFilter : TemplateFilter ) : Promise < IAzureQuickPickItem < FunctionTemplateBase | TemplatePromptResult > [ ] > {
122132 const language : ProjectLanguage = nonNullProp ( context , 'language' ) ;
123133 const languageModel = context . languageModel ;
124134 const version : FuncVersion = nonNullProp ( context , 'version' ) ;
125135 const templateProvider = ext . templateProvider . get ( context ) ;
126136
127- const templates : FunctionTemplateBase [ ] = await templateProvider . getFunctionTemplates ( context , context . projectPath , language , context . languageModel , version , context . projectTemplateKey ) ;
137+ const templates : FunctionTemplateBase [ ] = await templateProvider . getFunctionTemplates ( context , context . projectPath , language , context . languageModel , version , templateFilter , context . projectTemplateKey ) ;
128138 context . telemetry . measurements . templateCount = templates . length ;
129139 const picks : IAzureQuickPickItem < FunctionTemplateBase | TemplatePromptResult > [ ] = templates
130140 . filter ( ( t ) => ! ( doesTemplateRequireExistingStorageSetup ( t . id , language ) && ! context . hasDurableStorage ) )
131- . sort ( ( a , b ) => sortTemplates ( a , b ) )
132- . map ( t => { return { label : t . name , data : t , group : t . templateFilter } ; } ) ;
141+ . sort ( ( a , b ) => sortTemplates ( a , b , templateFilter ) )
142+ . map ( t => { return { label : t . name , data : t } ; } ) ;
133143
134144 if ( this . _isProjectWizard ) {
135145 picks . unshift ( {
@@ -157,6 +167,15 @@ export class FunctionListStep extends AzureWizardPromptStep<IFunctionWizardConte
157167 suppressPersistence : true
158168 } ) ;
159169 }
170+ if ( context . templateSchemaVersion !== TemplateSchemaVersion . v2 ) {
171+ // don't offer template filter for v2 schema
172+ picks . push ( {
173+ label : localize ( 'selectFilter' , '$(gear) Change template filter' ) ,
174+ description : localize ( 'currentFilter' , 'Current: {0}' , templateFilter ) ,
175+ data : 'changeFilter' ,
176+ suppressPersistence : true
177+ } ) ;
178+ }
160179
161180 if ( getWorkspaceSetting < boolean > ( 'showReloadTemplates' ) ) {
162181 picks . push ( {
@@ -176,7 +195,18 @@ interface IFunctionListStepOptions {
176195 functionSettings : { [ key : string ] : string | undefined } | undefined ;
177196}
178197
179- type TemplatePromptResult = 'skipForNow' | 'openAPI' | 'reloadTemplates' ;
198+ type TemplatePromptResult = 'changeFilter' | 'skipForNow' | 'openAPI' | 'reloadTemplates' ;
199+
200+ async function promptForTemplateFilter ( context : IActionContext ) : Promise < TemplateFilter > {
201+ const picks : IAzureQuickPickItem < TemplateFilter > [ ] = [
202+ { label : TemplateFilter . Verified , description : localize ( 'verifiedDescription' , '(Subset of "Core" that has been verified in VS Code)' ) , data : TemplateFilter . Verified } ,
203+ { label : TemplateFilter . Core , data : TemplateFilter . Core } ,
204+ { label : TemplateFilter . All , data : TemplateFilter . All }
205+ ] ;
206+
207+ const options : IAzureQuickPickOptions = { suppressPersistence : true , placeHolder : localize ( 'selectFilter' , 'Select a template filter' ) } ;
208+ return ( await context . ui . showQuickPick ( picks , options ) ) . data ;
209+ }
180210
181211// Todo: https://github.com/microsoft/vscode-azurefunctions/issues/3529
182212// Identify and filter out Durable Function templates requiring a pre-existing storage setup
@@ -198,17 +228,21 @@ function doesTemplateRequireExistingStorageSetup(templateId: string, language?:
198228 * If templateFilter is verified, puts HttpTrigger/TimerTrigger at the top since they're the most popular
199229 * Otherwise sort alphabetically
200230 */
201- function sortTemplates ( a : FunctionTemplateBase , b : FunctionTemplateBase ) : number {
202- function getPriority ( id : string ) : number {
203- if ( / \b h t t p t r i g g e r \b / i. test ( id ) ) { // Plain http trigger
204- return 1 ;
205- } else if ( / \b h t t p t r i g g e r / i. test ( id ) ) { // Http trigger with any extra pizazz
206- return 2 ;
207- } else if ( / \b t i m e r t r i g g e r \b / i. test ( id ) ) {
208- return 3 ;
209- } else {
210- return a . name . localeCompare ( b . name ) === - 1 ? 4 : 5 ;
231+ function sortTemplates ( a : FunctionTemplateBase , b : FunctionTemplateBase , templateFilter : TemplateFilter ) : number {
232+ if ( templateFilter === TemplateFilter . Verified ) {
233+ function getPriority ( id : string ) : number {
234+ if ( / \b h t t p t r i g g e r \b / i. test ( id ) ) { // Plain http trigger
235+ return 1 ;
236+ } else if ( / \b h t t p t r i g g e r / i. test ( id ) ) { // Http trigger with any extra pizazz
237+ return 2 ;
238+ } else if ( / \b t i m e r t r i g g e r \b / i. test ( id ) ) {
239+ return 3 ;
240+ } else {
241+ return 4 ;
242+ }
211243 }
244+ return getPriority ( a . id ) - getPriority ( b . id ) ;
212245 }
213- return getPriority ( a . id ) - getPriority ( b . id ) ;
246+
247+ return a . name . localeCompare ( b . name ) ;
214248}
0 commit comments