@@ -6,6 +6,9 @@ import { vscode } from "@src/utils/vscode"
66import { useExtensionState } from "@src/context/ExtensionStateContext"
77import { useAppTranslation } from "@src/i18n/TranslationContext"
88import { AutoApproveToggle , AutoApproveSetting , autoApproveSettingsConfig } from "../settings/AutoApproveToggle"
9+ import { StandardTooltip } from "@src/components/ui"
10+ import { useAutoApprovalState } from "@src/hooks/useAutoApprovalState"
11+ import { useAutoApprovalToggles } from "@src/hooks/useAutoApprovalToggles"
912
1013interface AutoApproveMenuProps {
1114 style ?: React . CSSProperties
@@ -17,16 +20,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
1720 const {
1821 autoApprovalEnabled,
1922 setAutoApprovalEnabled,
20- alwaysAllowReadOnly,
21- alwaysAllowWrite,
22- alwaysAllowExecute,
23- alwaysAllowBrowser,
24- alwaysAllowMcp,
25- alwaysAllowModeSwitch,
26- alwaysAllowSubtasks,
2723 alwaysApproveResubmit,
28- alwaysAllowFollowupQuestions,
29- alwaysAllowUpdateTodoList,
3024 allowedMaxRequests,
3125 setAlwaysAllowReadOnly,
3226 setAlwaysAllowWrite,
@@ -43,10 +37,24 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
4337
4438 const { t } = useAppTranslation ( )
4539
40+ const baseToggles = useAutoApprovalToggles ( )
41+
42+ // AutoApproveMenu needs alwaysApproveResubmit in addition to the base toggles
43+ const toggles = useMemo (
44+ ( ) => ( {
45+ ...baseToggles ,
46+ alwaysApproveResubmit : alwaysApproveResubmit ,
47+ } ) ,
48+ [ baseToggles , alwaysApproveResubmit ] ,
49+ )
50+
51+ const { hasEnabledOptions, effectiveAutoApprovalEnabled } = useAutoApprovalState ( toggles , autoApprovalEnabled )
52+
4653 const onAutoApproveToggle = useCallback (
4754 ( key : AutoApproveSetting , value : boolean ) => {
4855 vscode . postMessage ( { type : key , bool : value } )
4956
57+ // Update the specific toggle state
5058 switch ( key ) {
5159 case "alwaysAllowReadOnly" :
5260 setAlwaysAllowReadOnly ( value )
@@ -79,8 +87,30 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
7987 setAlwaysAllowUpdateTodoList ( value )
8088 break
8189 }
90+
91+ // Check if we need to update the master auto-approval state
92+ // Create a new toggles state with the updated value
93+ const updatedToggles = {
94+ ...toggles ,
95+ [ key ] : value ,
96+ }
97+
98+ const willHaveEnabledOptions = Object . values ( updatedToggles ) . some ( ( v ) => ! ! v )
99+
100+ // If enabling the first option, enable master auto-approval
101+ if ( value && ! hasEnabledOptions && willHaveEnabledOptions ) {
102+ setAutoApprovalEnabled ( true )
103+ vscode . postMessage ( { type : "autoApprovalEnabled" , bool : true } )
104+ }
105+ // If disabling the last option, disable master auto-approval
106+ else if ( ! value && hasEnabledOptions && ! willHaveEnabledOptions ) {
107+ setAutoApprovalEnabled ( false )
108+ vscode . postMessage ( { type : "autoApprovalEnabled" , bool : false } )
109+ }
82110 } ,
83111 [
112+ toggles ,
113+ hasEnabledOptions ,
84114 setAlwaysAllowReadOnly ,
85115 setAlwaysAllowWrite ,
86116 setAlwaysAllowExecute ,
@@ -91,43 +121,32 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
91121 setAlwaysApproveResubmit ,
92122 setAlwaysAllowFollowupQuestions ,
93123 setAlwaysAllowUpdateTodoList ,
124+ setAutoApprovalEnabled ,
94125 ] ,
95126 )
96127
97- const toggleExpanded = useCallback ( ( ) => setIsExpanded ( ( prev ) => ! prev ) , [ ] )
128+ const toggleExpanded = useCallback ( ( ) => {
129+ setIsExpanded ( ( prev ) => ! prev )
130+ } , [ ] )
98131
99- const toggles = useMemo (
100- ( ) => ( {
101- alwaysAllowReadOnly : alwaysAllowReadOnly ,
102- alwaysAllowWrite : alwaysAllowWrite ,
103- alwaysAllowExecute : alwaysAllowExecute ,
104- alwaysAllowBrowser : alwaysAllowBrowser ,
105- alwaysAllowMcp : alwaysAllowMcp ,
106- alwaysAllowModeSwitch : alwaysAllowModeSwitch ,
107- alwaysAllowSubtasks : alwaysAllowSubtasks ,
108- alwaysApproveResubmit : alwaysApproveResubmit ,
109- alwaysAllowFollowupQuestions : alwaysAllowFollowupQuestions ,
110- alwaysAllowUpdateTodoList : alwaysAllowUpdateTodoList ,
111- } ) ,
112- [
113- alwaysAllowReadOnly ,
114- alwaysAllowWrite ,
115- alwaysAllowExecute ,
116- alwaysAllowBrowser ,
117- alwaysAllowMcp ,
118- alwaysAllowModeSwitch ,
119- alwaysAllowSubtasks ,
120- alwaysApproveResubmit ,
121- alwaysAllowFollowupQuestions ,
122- alwaysAllowUpdateTodoList ,
123- ] ,
124- )
132+ // Disable main checkbox while menu is open or no options selected
133+ const isCheckboxDisabled = useMemo ( ( ) => {
134+ return ! hasEnabledOptions || isExpanded
135+ } , [ hasEnabledOptions , isExpanded ] )
125136
126137 const enabledActionsList = Object . entries ( toggles )
127138 . filter ( ( [ _key , value ] ) => ! ! value )
128139 . map ( ( [ key ] ) => t ( autoApproveSettingsConfig [ key as AutoApproveSetting ] . labelKey ) )
129140 . join ( ", " )
130141
142+ // Update displayed text logic
143+ const displayText = useMemo ( ( ) => {
144+ if ( ! effectiveAutoApprovalEnabled || ! hasEnabledOptions ) {
145+ return t ( "chat:autoApprove.none" )
146+ }
147+ return enabledActionsList || t ( "chat:autoApprove.none" )
148+ } , [ effectiveAutoApprovalEnabled , hasEnabledOptions , enabledActionsList , t ] )
149+
131150 const handleOpenSettings = useCallback (
132151 ( ) =>
133152 window . postMessage ( { type : "action" , action : "settingsButtonClicked" , values : { section : "autoApprove" } } ) ,
@@ -155,14 +174,26 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
155174 } }
156175 onClick = { toggleExpanded } >
157176 < div onClick = { ( e ) => e . stopPropagation ( ) } >
158- < VSCodeCheckbox
159- checked = { autoApprovalEnabled ?? false }
160- onChange = { ( ) => {
161- const newValue = ! ( autoApprovalEnabled ?? false )
162- setAutoApprovalEnabled ( newValue )
163- vscode . postMessage ( { type : "autoApprovalEnabled" , bool : newValue } )
164- } }
165- />
177+ < StandardTooltip
178+ content = { ! hasEnabledOptions ? t ( "chat:autoApprove.selectOptionsFirst" ) : undefined } >
179+ < VSCodeCheckbox
180+ checked = { effectiveAutoApprovalEnabled }
181+ disabled = { isCheckboxDisabled }
182+ aria-label = {
183+ hasEnabledOptions
184+ ? t ( "chat:autoApprove.toggleAriaLabel" )
185+ : t ( "chat:autoApprove.disabledAriaLabel" )
186+ }
187+ onChange = { ( ) => {
188+ if ( hasEnabledOptions ) {
189+ const newValue = ! ( autoApprovalEnabled ?? false )
190+ setAutoApprovalEnabled ( newValue )
191+ vscode . postMessage ( { type : "autoApprovalEnabled" , bool : newValue } )
192+ }
193+ // If no options enabled, do nothing
194+ } }
195+ />
196+ </ StandardTooltip >
166197 </ div >
167198 < div
168199 style = { {
@@ -188,7 +219,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
188219 flex : 1 ,
189220 minWidth : 0 ,
190221 } } >
191- { enabledActionsList || t ( "chat:autoApprove.none" ) }
222+ { displayText }
192223 </ span >
193224 < span
194225 className = { `codicon codicon-chevron-${ isExpanded ? "down" : "right" } ` }
0 commit comments