@@ -42,6 +42,7 @@ import { validateIp, validateIpNet } from '~/util/ip'
4242import { links } from '~/util/links'
4343import { capitalize } from '~/util/str'
4444
45+ import { type ActiveSubforms } from './firewall-rules-create'
4546import { type FirewallRuleValues } from './firewall-rules-util'
4647
4748/**
@@ -88,10 +89,12 @@ const TargetAndHostFilterSubform = ({
8889 sectionType,
8990 control,
9091 messageContent,
92+ updateSubformStates,
9193} : {
9294 sectionType : 'target' | 'host'
9395 control : Control < FirewallRuleValues >
9496 messageContent : ReactNode
97+ updateSubformStates : ( subform : keyof ActiveSubforms , value : boolean ) => void
9598} ) => {
9699 const { project, vpc } = useVpcSelector ( )
97100 // prefetchedApiQueries below are prefetched in firewall-rules-create and -edit
@@ -125,8 +128,11 @@ const TargetAndHostFilterSubform = ({
125128 // https://github.com/react-hook-form/react-hook-form/blob/9a497a70a/src/logic/createFormControl.ts#L1194-L1203
126129 const { isSubmitSuccessful : subformSubmitSuccessful } = subform . formState
127130 useEffect ( ( ) => {
128- if ( subformSubmitSuccessful ) subform . reset ( targetAndHostDefaultValues )
129- } , [ subformSubmitSuccessful , subform ] )
131+ if ( subformSubmitSuccessful ) {
132+ subform . reset ( targetAndHostDefaultValues )
133+ updateSubformStates ( sectionType , false )
134+ }
135+ } , [ subformSubmitSuccessful , subform , updateSubformStates , sectionType ] )
130136
131137 const [ valueType , value ] = subform . watch ( [ 'type' , 'value' ] )
132138 const sectionItems = {
@@ -143,9 +149,15 @@ const TargetAndHostFilterSubform = ({
143149 // back to validating on submit instead of change. Also resets readyToSubmit.
144150 const onTypeChange = ( ) => {
145151 subform . reset ( { type : subform . getValues ( 'type' ) , value : '' } )
152+ updateSubformStates ( sectionType , false )
146153 }
147154 const onInputChange = ( value : string ) => {
148155 subform . setValue ( 'value' , value )
156+ updateSubformStates ( sectionType , value . length > 0 )
157+ }
158+ const onClear = ( ) => {
159+ subform . reset ( )
160+ updateSubformStates ( sectionType , false )
149161 }
150162
151163 return (
@@ -178,6 +190,7 @@ const TargetAndHostFilterSubform = ({
178190 description = "Select an option or enter a custom value"
179191 control = { subformControl }
180192 onEnter = { submitSubform }
193+ onChange = { ( ) => updateSubformStates ( sectionType , true ) }
181194 onInputChange = { onInputChange }
182195 items = { items }
183196 allowArbitraryValues
@@ -212,7 +225,7 @@ const TargetAndHostFilterSubform = ({
212225 < MiniTable . ClearAndAddButtons
213226 addButtonCopy = { `Add ${ sectionType === 'host' ? 'host filter' : 'target' } ` }
214227 disabled = { ! value }
215- onClear = { ( ) => subform . reset ( ) }
228+ onClear = { onClear }
216229 onSubmit = { submitSubform }
217230 />
218231 { field . value . length > 0 && (
@@ -289,14 +302,20 @@ type CommonFieldsProps = {
289302 control : Control < FirewallRuleValues >
290303 nameTaken : ( name : string ) => boolean
291304 error : ApiError | null
305+ updateSubformStates : ( subform : keyof ActiveSubforms , value : boolean ) => void
292306}
293307
294308const targetAndHostDefaultValues : TargetAndHostFormValues = {
295309 type : 'vpc' ,
296310 value : '' ,
297311}
298312
299- export const CommonFields = ( { control, nameTaken, error } : CommonFieldsProps ) => {
313+ export const CommonFields = ( {
314+ control,
315+ nameTaken,
316+ error,
317+ updateSubformStates,
318+ } : CommonFieldsProps ) => {
300319 // Ports
301320 const portRangeForm = useForm ( { defaultValues : { portRange : '' } } )
302321 const ports = useController ( { name : 'ports' , control } ) . field
@@ -307,7 +326,11 @@ export const CommonFields = ({ control, nameTaken, error }: CommonFieldsProps) =
307326 // that it is not already in the list
308327 ports . onChange ( [ ...ports . value , portRangeValue ] )
309328 portRangeForm . reset ( )
329+ updateSubformStates ( 'port' , false )
310330 } )
331+ useEffect ( ( ) => {
332+ updateSubformStates ( 'port' , portValue . length > 0 )
333+ } , [ updateSubformStates , portValue ] )
311334
312335 return (
313336 < >
@@ -406,6 +429,7 @@ export const CommonFields = ({ control, nameTaken, error }: CommonFieldsProps) =
406429 </ p >
407430 </ >
408431 }
432+ updateSubformStates = { updateSubformStates }
409433 />
410434
411435 < FormDivider />
@@ -453,7 +477,10 @@ export const CommonFields = ({ control, nameTaken, error }: CommonFieldsProps) =
453477 < MiniTable . ClearAndAddButtons
454478 addButtonCopy = "Add port filter"
455479 disabled = { ! portValue }
456- onClear = { ( ) => portRangeForm . reset ( ) }
480+ onClear = { ( ) => {
481+ portRangeForm . reset ( )
482+ updateSubformStates ( 'port' , false )
483+ } }
457484 onSubmit = { submitPortRange }
458485 />
459486 </ div >
@@ -500,6 +527,7 @@ export const CommonFields = ({ control, nameTaken, error }: CommonFieldsProps) =
500527 traffic. For an outbound rule, they match the destination.
501528 </ >
502529 }
530+ updateSubformStates = { updateSubformStates }
503531 />
504532
505533 { error && (
0 commit comments