@@ -110,6 +110,7 @@ const EmailSenderModal = ({
110110 } ,
111111 variable : `#${ item . join ( '.' ) } #` ,
112112 value_selector : item ,
113+ required : true ,
113114 }
114115 } )
115116 const varInputs = variables . filter ( item => ! isENV ( item . value_selector ) && ! isOutput ( item . value_selector ) ) . map ( ( item ) => {
@@ -119,22 +120,22 @@ const EmailSenderModal = ({
119120 label : item . label || item . variable ,
120121 variable : item . variable ,
121122 type : InputVarType . textInput ,
122- required : false ,
123+ required : true ,
123124 value_selector : item . value_selector ,
124125 }
125126 }
126127 return {
127128 label : item . label || item . variable ,
128129 variable : item . variable ,
129130 type : originalVar . type === VarType . number ? InputVarType . number : InputVarType . textInput ,
130- required : false ,
131+ required : true ,
131132 }
132133 } )
133134 return varInputs
134135 } , [ availableNodes , config ?. body , formContent , formInputs , nodesOutputVars ] )
135136
136137 const [ inputs , setInputs ] = useState < Record < string , unknown > > ( { } )
137- const [ collapsed , setCollapsed ] = useState ( true )
138+ const [ collapsed , setCollapsed ] = useState ( ! ( generatedInputs . length > 0 ) )
138139 const [ sendingEmail , setSendingEmail ] = useState ( false )
139140 const [ done , setDone ] = useState ( false )
140141
@@ -145,7 +146,21 @@ const EmailSenderModal = ({
145146 } )
146147 }
147148
149+ const confirmChecked = useMemo ( ( ) => {
150+ for ( const variable of generatedInputs ) {
151+ if ( variable . required ) {
152+ const value = inputs [ variable . variable ]
153+ if ( value === undefined || value === null || value === '' ) {
154+ return false
155+ }
156+ }
157+ }
158+ return true
159+ } , [ generatedInputs , inputs ] )
160+
148161 const handleConfirm = useCallback ( async ( ) => {
162+ if ( ! confirmChecked )
163+ return
149164 setSendingEmail ( true )
150165 try {
151166 await testEmailSender ( {
@@ -159,7 +174,7 @@ const EmailSenderModal = ({
159174 finally {
160175 setSendingEmail ( false )
161176 }
162- } , [ testEmailSender , appDetail ?. id , nodeId , deliveryId , inputs ] )
177+ } , [ confirmChecked , testEmailSender , appDetail ?. id , nodeId , deliveryId , inputs ] )
163178
164179 if ( done ) {
165180 return (
@@ -303,39 +318,40 @@ const EmailSenderModal = ({
303318 </ >
304319 ) }
305320 { /* vars */ }
306- < >
307- < div className = "px-6" >
308- < Divider className = "!mb-2 !mt-4 !h-px !w-12 bg-divider-regular" />
309- </ div >
310- < div className = "px-6 py-2" >
311- < div className = "group flex h-6 cursor-pointer items-center" onClick = { ( ) => setCollapsed ( ! collapsed ) } >
312- < div className = "system-sm-semibold-uppercase mr-1 text-text-secondary" > { t ( `${ i18nPrefix } .deliveryMethod.emailSender.vars` , { ns : 'workflow' } ) } </ div >
313- < div className = "system-xs-regular text-text-tertiary" > { t ( `${ i18nPrefix } .deliveryMethod.emailSender.optional` , { ns : 'workflow' } ) } </ div >
314- < RiArrowRightSFill className = { cn ( 'h-4 w-4 text-text-quaternary group-hover:text-text-primary' , ! collapsed && 'rotate-90' ) } />
321+ { generatedInputs . length > 0 && (
322+ < >
323+ < div className = "px-6" >
324+ < Divider className = "!mb-2 !mt-4 !h-px !w-12 bg-divider-regular" />
315325 </ div >
316- < div className = "system-xs-regular text-text-tertiary" > { t ( `${ i18nPrefix } .deliveryMethod.emailSender.varsTip` , { ns : 'workflow' } ) } </ div >
317- { ! collapsed && (
318- < div className = "mt-3 space-y-4" >
319- { generatedInputs . map ( ( variable , index ) => (
320- < div
321- key = { variable . variable }
322- className = "mb-4 last-of-type:mb-0"
323- >
324- < FormItem
325- autoFocus = { index === 0 }
326- payload = { variable }
327- value = { inputs [ variable . variable ] }
328- onChange = { v => handleValueChange ( variable . variable , v ) }
329- />
330- </ div >
331- ) ) }
326+ < div className = "px-6 py-2" >
327+ < div className = "group flex h-6 cursor-pointer items-center" onClick = { ( ) => setCollapsed ( ! collapsed ) } >
328+ < div className = "system-sm-semibold-uppercase mr-1 text-text-secondary" > { t ( `${ i18nPrefix } .deliveryMethod.emailSender.vars` , { ns : 'workflow' } ) } </ div >
329+ < RiArrowRightSFill className = { cn ( 'h-4 w-4 text-text-quaternary group-hover:text-text-primary' , ! collapsed && 'rotate-90' ) } />
332330 </ div >
333- ) }
334- </ div >
335- </ >
331+ < div className = "system-xs-regular text-text-tertiary" > { t ( `${ i18nPrefix } .deliveryMethod.emailSender.varsTip` , { ns : 'workflow' } ) } </ div >
332+ { ! collapsed && (
333+ < div className = "mt-3 space-y-4" >
334+ { generatedInputs . map ( ( variable , index ) => (
335+ < div
336+ key = { variable . variable }
337+ className = "mb-4 last-of-type:mb-0"
338+ >
339+ < FormItem
340+ autoFocus = { index === 0 }
341+ payload = { variable }
342+ value = { inputs [ variable . variable ] }
343+ onChange = { v => handleValueChange ( variable . variable , v ) }
344+ />
345+ </ div >
346+ ) ) }
347+ </ div >
348+ ) }
349+ </ div >
350+ </ >
351+ ) }
336352 < div className = "flex flex-row-reverse gap-2 p-6 pt-5" >
337353 < Button
338- disabled = { sendingEmail }
354+ disabled = { sendingEmail || ! confirmChecked }
339355 loading = { sendingEmail }
340356 variant = "primary"
341357 onClick = { handleConfirm }
0 commit comments