@@ -6,8 +6,8 @@ public static class WizardTimeouts
66 /// <summary>Default per-step wizard request timeout.</summary>
77 public const int DefaultTimeoutMs = 30_000 ;
88
9- /// <summary>Extended timeout for steps that wait on external auth .</summary>
10- public const int AuthTimeoutMs = 300_000 ;
9+ /// <summary>Extended timeout for steps that wait on auth or external setup work .</summary>
10+ public const int SlowStepTimeoutMs = 300_000 ;
1111
1212 /// <summary>Polling delay for gateway progress/status wizard steps.</summary>
1313 public static readonly TimeSpan ProgressPollDelay = TimeSpan . FromSeconds ( 1 ) ;
@@ -24,16 +24,82 @@ public static class WizardTimeouts
2424 "browser" , "authenticate" , "verification" ,
2525 } ;
2626
27- /// <summary>Auth-style steps get <see cref="AuthTimeoutMs"/>; others get <see cref="DefaultTimeoutMs"/>.</summary>
28- public static int ForStep ( string ? title , string ? message )
27+ private static readonly string [ ] s_slowSetupHints =
2928 {
30- var text = $ "{ title } { message } ";
31- foreach ( var hint in s_authHints )
29+ "plugin" , "install" , "download" , "teams" ,
30+ } ;
31+
32+ /// <summary>
33+ /// Auth and external setup steps get <see cref="SlowStepTimeoutMs"/>; ordinary
34+ /// questions get <see cref="DefaultTimeoutMs"/>. Only selected option metadata
35+ /// is considered so an unselected slow integration does not extend every choice.
36+ /// </summary>
37+ public static int ForStep (
38+ string ? title ,
39+ string ? message ,
40+ string ? stepId = null ,
41+ IReadOnlyCollection < WizardOptionValue > ? selectedOptions = null )
42+ {
43+ var promptText = JoinText ( title , message ) ;
44+ if ( HasAnyHint ( promptText , s_authHints ) )
45+ return SlowStepTimeoutMs ;
46+
47+ // With a choice step, only the submitted option proves which operation
48+ // will run. This keeps "skip" and unrelated options on the short path.
49+ var slowText = selectedOptions is null
50+ ? JoinText ( title , message , stepId )
51+ : JoinOptionText ( selectedOptions ) ;
52+ if ( HasAnyHint ( slowText , s_slowSetupHints ) )
53+ return SlowStepTimeoutMs ;
54+
55+ return DefaultTimeoutMs ;
56+ }
57+
58+ internal static int ForGatewayStep (
59+ string ? title ,
60+ string ? message ,
61+ string ? stepId ,
62+ string ? stepType ,
63+ IReadOnlyList < WizardOptionValue > options ,
64+ string ? answer = null )
65+ {
66+ var category = WizardStepClassifier . Categorize ( stepType , options . Count > 0 ) ;
67+ IReadOnlyCollection < WizardOptionValue > ? selectedOptions =
68+ category == WizardStepCategory . RequiresAnswer && options . Count > 0 ? [ ] : null ;
69+
70+ if ( selectedOptions is not null && ! string . IsNullOrWhiteSpace ( answer ) )
3271 {
33- if ( text . Contains ( hint , StringComparison . OrdinalIgnoreCase ) )
34- return AuthTimeoutMs ;
72+ if ( string . Equals ( stepType , "multiselect" , StringComparison . OrdinalIgnoreCase )
73+ && WizardAnswerBuilder . TryResolveOptions ( options , answer , out var multiselectOptions ) )
74+ {
75+ selectedOptions = multiselectOptions ;
76+ }
77+ else if ( ! string . Equals ( stepType , "multiselect" , StringComparison . OrdinalIgnoreCase )
78+ && WizardAnswerBuilder . TryFindOption ( options , answer , out var selectedOption ) )
79+ {
80+ selectedOptions = [ selectedOption ] ;
81+ }
3582 }
3683
37- return DefaultTimeoutMs ;
84+ return ForStep ( title , message , stepId , selectedOptions ) ;
3885 }
86+
87+ private static string JoinOptionText ( IEnumerable < WizardOptionValue > options )
88+ {
89+ var parts = new List < string ? > ( ) ;
90+ foreach ( var option in options )
91+ {
92+ parts . Add ( option . Value ) ;
93+ parts . Add ( option . Label ) ;
94+ parts . Add ( option . Hint ) ;
95+ }
96+
97+ return JoinText ( parts . ToArray ( ) ) ;
98+ }
99+
100+ private static string JoinText ( params string ? [ ] parts ) =>
101+ string . Join ( ' ' , parts . Where ( part => ! string . IsNullOrWhiteSpace ( part ) ) ) ;
102+
103+ private static bool HasAnyHint ( string text , IEnumerable < string > hints ) =>
104+ hints . Any ( hint => text . Contains ( hint , StringComparison . OrdinalIgnoreCase ) ) ;
39105}
0 commit comments