@@ -92,11 +92,21 @@ export default class WebhookRouterForm extends React.Component<
9292
9393 if ( this . state . method . value . value === Methods . FUNCTION && this . state . url . value ) {
9494 const functionName = this . state . url . value ;
95- const selectedOption = webhookOptions . find ( ( opt : any ) => opt . name === functionName ) ;
95+ let selectedOption = webhookOptions . find ( ( opt : any ) => opt . name === functionName ) ;
96+ if ( ! selectedOption ) {
97+ selectedOption = {
98+ value : 'custom' ,
99+ name : 'custom' ,
100+ label : 'Custom'
101+ } ;
102+ }
96103
97104 this . setState ( {
98105 webhookOptions,
99- webhookFunction : { value : selectedOption || null }
106+ webhookFunction : { value : selectedOption || null } ,
107+ url : {
108+ value : selectedOption . value === 'custom' ? this . state . url . value : selectedOption . name
109+ }
100110 } ) ;
101111 } else {
102112 this . setState ( { webhookOptions } ) ;
@@ -109,15 +119,18 @@ export default class WebhookRouterForm extends React.Component<
109119 }
110120
111121 private handleWebhookFunctionChanged ( selected : any ) : boolean {
122+ const isCustom = selected ?. value === 'custom' ;
112123 const prevFunction = this . state . webhookFunction ?. value ;
113124 const prevFunctionName = prevFunction ?. name || prevFunction ?. value ;
114125
115126 let updates : Partial < WebhookRouterFormState > = {
116127 webhookFunction : { value : selected } ,
117- url : { value : selected ? selected . name || selected . value : '' }
128+ url : {
129+ value : selected ? ( isCustom ? '' : selected . name || selected . value ) : ''
130+ }
118131 } ;
119132
120- if ( selected ) {
133+ if ( selected && ! isCustom ) {
121134 const backendDefaultBody = selected . body || '' ;
122135 const currentBody = this . state . body . value ;
123136
@@ -126,6 +139,8 @@ export default class WebhookRouterForm extends React.Component<
126139 updates . body = {
127140 value : shouldResetBody ? backendDefaultBody : currentBody
128141 } ;
142+ } else if ( isCustom ) {
143+ updates . body = { value : '{}' } ;
129144 } else {
130145 updates . body = { value : '' } ;
131146 }
@@ -308,7 +323,6 @@ export default class WebhookRouterForm extends React.Component<
308323
309324 if ( valid ) {
310325 const payload = stateToNode ( this . props . nodeSettings , this . state ) ;
311-
312326 this . props . updateRouter ( payload ) ;
313327
314328 this . props . onClose ( false ) ;
@@ -423,21 +437,41 @@ export default class WebhookRouterForm extends React.Component<
423437 </ div >
424438 < div className = { styles . url } >
425439 { method === 'FUNCTION' ? (
426- < TembaSelectElement
427- key = "webhook_function_select"
428- name = { i18n . t ( 'forms.function' , 'Function' ) }
429- placeholder = {
430- this . state . isLoading
431- ? 'Loading functions…'
432- : i18n . t ( 'forms.select_or_type' , 'Type to search or select' )
433- }
434- entry = { this . state . webhookFunction }
435- searchable = { true }
436- multi = { false }
437- expressions = { false }
438- onChange = { this . handleWebhookFunctionChanged }
439- options = { this . state . webhookOptions }
440- />
440+ < >
441+ { this . state . webhookFunction ?. value ?. value === 'custom' ? (
442+ < div className = { styles . custom_function_wrapper } >
443+ < TextInputElement
444+ name = { i18n . t ( 'forms.custom_function_label' , 'Function Name' ) }
445+ placeholder = { i18n . t ( 'forms.enter_label' , 'Enter function name' ) }
446+ entry = { this . state . url }
447+ onChange = { ( v : string ) => this . handleUpdate ( { url : v } ) }
448+ autocomplete = { true }
449+ />
450+ < div
451+ className = { styles . toggle_icon }
452+ onClick = { ( ) => this . handleWebhookFunctionChanged ( null ) }
453+ >
454+ ▾
455+ </ div >
456+ </ div >
457+ ) : (
458+ < TembaSelectElement
459+ key = "webhook_function_select"
460+ name = { i18n . t ( 'forms.function' , 'Function' ) }
461+ placeholder = {
462+ this . state . isLoading
463+ ? 'Loading functions…'
464+ : i18n . t ( 'forms.select_or_type' , 'Type to search or select' )
465+ }
466+ entry = { this . state . webhookFunction }
467+ searchable = { true }
468+ multi = { false }
469+ expressions = { false }
470+ onChange = { this . handleWebhookFunctionChanged }
471+ options = { this . state . webhookOptions }
472+ />
473+ ) }
474+ </ >
441475 ) : (
442476 < TextInputElement
443477 name = { i18n . t ( 'forms.url' , 'URL' ) }
0 commit comments