|
@@ -1,10 +1,14 @@
|
|
|
class Index extends App.ControllerSubContent
|
|
|
requiredPermission: 'admin.webhook'
|
|
|
header: __('Webhooks')
|
|
|
+
|
|
|
+ events:
|
|
|
+ 'click [data-type=predefined]': 'choosePreDefinedWebhook'
|
|
|
+
|
|
|
constructor: ->
|
|
|
super
|
|
|
|
|
|
- @genericController = new App.ControllerGenericIndex(
|
|
|
+ @genericController = new WebhookIndex(
|
|
|
el: @el
|
|
|
id: @id
|
|
|
genericObject: 'Webhook'
|
|
@@ -23,12 +27,20 @@ class Index extends App.ControllerSubContent
|
|
|
]
|
|
|
buttons: [
|
|
|
{ name: __('Example Payload'), 'data-type': 'payload', class: 'btn' }
|
|
|
- { name: __('New Webhook'), 'data-type': 'new', class: 'btn--success' }
|
|
|
+ {
|
|
|
+ name: __('New Webhook')
|
|
|
+ 'data-type': 'new'
|
|
|
+ class: 'btn--success'
|
|
|
+ menu: [
|
|
|
+ { name: __('Pre-defined Webhook'), 'data-type': 'predefined' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
]
|
|
|
logFacility: 'webhook'
|
|
|
payloadExampleUrl: '/api/v1/webhooks/preview'
|
|
|
container: @el.closest('.content')
|
|
|
veryLarge: true
|
|
|
+ handlers: [@customPayloadCollapseHandler]
|
|
|
validateOnSubmit: @validateOnSubmit
|
|
|
)
|
|
|
|
|
@@ -39,6 +51,35 @@ class Index extends App.ControllerSubContent
|
|
|
|
|
|
@genericController.paginate( @page || 1 )
|
|
|
|
|
|
+ disableSwitchCallback: ->
|
|
|
+ $(@).parents('form').find('[data-attribute-name="customized_payload"] label').css('pointer-events', 'none')
|
|
|
+
|
|
|
+ enableSwitchCallback: ->
|
|
|
+ $(@).parents('form').find('[data-attribute-name="customized_payload"] label').css('pointer-events', '')
|
|
|
+
|
|
|
+ customPayloadCollapseHandler: (params, attribute, attributes, classname, form, ui) =>
|
|
|
+ return if attribute.name isnt 'customized_payload'
|
|
|
+
|
|
|
+ customPayloadCollapseWidget = form.find('[data-attribute-name="custom_payload"] .panel-collapse')
|
|
|
+
|
|
|
+ # Prevent triggering duplicate events by disabling switch pointer events during collapsing.
|
|
|
+ customPayloadCollapseWidget
|
|
|
+ .off('show.bs.collapse hide.bs.collapse', @disableSwitchCallback)
|
|
|
+ .on('show.bs.collapse hide.bs.collapse', @disableSwitchCallback)
|
|
|
+
|
|
|
+ # Make sure the pointer events are re-enabled after collapsing.
|
|
|
+ customPayloadCollapseWidget
|
|
|
+ .off('shown.bs.collapse hidden.bs.collapse', @enableSwitchCallback)
|
|
|
+ .on('shown.bs.collapse hidden.bs.collapse', @enableSwitchCallback)
|
|
|
+
|
|
|
+ # Show or hide the custom payload widget depending on the switch value.
|
|
|
+ if params.customized_payload
|
|
|
+ customPayloadCollapseWidget.collapse('show')
|
|
|
+ form.find('[data-attribute-name="custom_payload"]').css('margin-bottom', '')
|
|
|
+ else
|
|
|
+ customPayloadCollapseWidget.collapse('hide')
|
|
|
+ form.find('[data-attribute-name="custom_payload"]').css('margin-bottom', '0')
|
|
|
+
|
|
|
validateOnSubmit: (params) ->
|
|
|
return if _.isEmpty(params['custom_payload'])
|
|
|
|
|
@@ -56,4 +97,142 @@ class Index extends App.ControllerSubContent
|
|
|
|
|
|
errors
|
|
|
|
|
|
+ choosePreDefinedWebhook: (e) =>
|
|
|
+ e.preventDefault()
|
|
|
+
|
|
|
+ new ChoosePreDefinedWebhook(
|
|
|
+ container: @el.closest('.content')
|
|
|
+ callback: @newPreDefinedWebhook
|
|
|
+ )
|
|
|
+
|
|
|
+ newPreDefinedWebhook: (webhook) =>
|
|
|
+ new NewPreDefinedWebhook(
|
|
|
+ genericObject: 'Webhook'
|
|
|
+ pageData:
|
|
|
+ object: __('Webhook')
|
|
|
+ container: @el.closest('.content')
|
|
|
+ veryLarge: true
|
|
|
+ handlers: [@customPayloadCollapseHandler]
|
|
|
+ validateOnSubmit: @validateOnSubmit
|
|
|
+ preDefinedWebhook: webhook
|
|
|
+ )
|
|
|
+
|
|
|
+class WebhookIndex extends App.ControllerGenericIndex
|
|
|
+ editControllerClass: -> EditWebhook
|
|
|
+
|
|
|
+class ChoosePreDefinedWebhook extends App.ControllerModal
|
|
|
+ buttonClose: true
|
|
|
+ buttonCancel: true
|
|
|
+ buttonSubmit: __('Next')
|
|
|
+ buttonClass: 'btn--primary'
|
|
|
+ head: __('Pre-defined Webhook')
|
|
|
+ veryLarge: true
|
|
|
+ shown: false
|
|
|
+
|
|
|
+ constructor: ->
|
|
|
+ super
|
|
|
+
|
|
|
+ App.PreDefinedWebhook.subscribe(@render, initFetch: true)
|
|
|
+
|
|
|
+ content: ->
|
|
|
+ content = $(App.view('pre_defined_webhook')())
|
|
|
+
|
|
|
+ preDefinedWebhooksSelection = (el) ->
|
|
|
+ selection = App.UiElement.select.render(
|
|
|
+ id: 'preDefinedWebhooks'
|
|
|
+ name: 'pre_defined_webhook_id'
|
|
|
+ multiple: false
|
|
|
+ limit: 100
|
|
|
+ null: false
|
|
|
+ relation: 'PreDefinedWebhook'
|
|
|
+ nulloption: false
|
|
|
+ )
|
|
|
+ el.html(selection)
|
|
|
+
|
|
|
+ preDefinedWebhooksSelection(content.find('.js-preDefinedWebhooks'))
|
|
|
+
|
|
|
+ content
|
|
|
+
|
|
|
+ onSubmit: (e) =>
|
|
|
+ @formDisable(e)
|
|
|
+ params = @formParam(e.target)
|
|
|
+ webhook = App.PreDefinedWebhook.find(params.pre_defined_webhook_id)
|
|
|
+ @close()
|
|
|
+ @callback(webhook)
|
|
|
+
|
|
|
+PreDefinedWebhookMixin =
|
|
|
+ field_prefix: 'preferences::pre_defined_webhook'
|
|
|
+
|
|
|
+ preDefinedWebhookAttributes: ->
|
|
|
+
|
|
|
+ # Make a deep clone of the pre-defined webhook field definition.
|
|
|
+ fields = $.extend(true, {}, @preDefinedWebhook.fields)
|
|
|
+
|
|
|
+ # Include pre-defined webhook type as a disabled field.
|
|
|
+ attrs = [
|
|
|
+ name: 'pre_defined_webhook_type'
|
|
|
+ display: __('Pre-defined Webhook')
|
|
|
+ null: true
|
|
|
+ tag: 'select'
|
|
|
+ relation: 'PreDefinedWebhook'
|
|
|
+ value: @preDefinedWebhook.id
|
|
|
+ disabled: true
|
|
|
+ ]
|
|
|
+
|
|
|
+ # Append preferences field prefix to all field names.
|
|
|
+ attrs = attrs.concat(
|
|
|
+ _.map fields,
|
|
|
+ (field) =>
|
|
|
+ field.name = "#{@field_prefix}::#{field.name}"
|
|
|
+ field
|
|
|
+ )
|
|
|
+
|
|
|
+ attrs
|
|
|
+
|
|
|
+ contentFormModel: ->
|
|
|
+
|
|
|
+ # Make a deep clone of the pre-defined webhook field definition.
|
|
|
+ attrs = $.extend(true, [], App[@genericObject].configure_attributes)
|
|
|
+
|
|
|
+ # Process edit forms conditionally, in case we are dealing with a pre-defined webhook.
|
|
|
+ if not @preDefinedWebhook and @item?.pre_defined_webhook_type
|
|
|
+ @preDefinedWebhook = App.PreDefinedWebhook.find(@item.pre_defined_webhook_type)
|
|
|
+
|
|
|
+ # Add pre-defined webhook fields as additional attributes.
|
|
|
+ if @preDefinedWebhook
|
|
|
+ customizedPayloadIndex = _.findIndex(attrs, (attr) -> attr.name is 'customized_payload')
|
|
|
+
|
|
|
+ # Inject the fields right above the regular `customized_payload` attribute.
|
|
|
+ if customizedPayloadIndex isnt -1
|
|
|
+ attrs.splice(customizedPayloadIndex, 0, @preDefinedWebhookAttributes()...)
|
|
|
+
|
|
|
+ # As a fallback, inject the fields to the end of the form.
|
|
|
+ else
|
|
|
+ attrs = attrs.concat @preDefinedWebhookAttributes()
|
|
|
+
|
|
|
+ { configure_attributes: attrs }
|
|
|
+
|
|
|
+class NewPreDefinedWebhook extends App.ControllerGenericNew
|
|
|
+ @include PreDefinedWebhookMixin
|
|
|
+
|
|
|
+ # Inject the pre-defined webhook data into the form.
|
|
|
+ contentFormParams: ->
|
|
|
+ name: App.i18n.translatePlain(@preDefinedWebhook.name)
|
|
|
+ custom_payload: @preDefinedWebhook.custom_payload
|
|
|
+ note: App.i18n.translatePlain('Pre-defined webhook for %s.', App.i18n.translatePlain(@preDefinedWebhook.name))
|
|
|
+
|
|
|
+class EditWebhook extends App.ControllerGenericEdit
|
|
|
+ shown: false
|
|
|
+
|
|
|
+ @include PreDefinedWebhookMixin
|
|
|
+
|
|
|
+ constructor: ->
|
|
|
+ super
|
|
|
+
|
|
|
+ App.PreDefinedWebhook.subscribe(@render, initFetch: true)
|
|
|
+
|
|
|
+ # Inject the pre-defined webhook data into the form.
|
|
|
+ contentFormParams: ->
|
|
|
+ $.extend(true, @item, { custom_payload: @preDefinedWebhook?.custom_payload if not @item.customized_payload })
|
|
|
+
|
|
|
App.Config.set('Webhook', { prio: 3350, name: __('Webhook'), parent: '#manage', target: '#manage/webhook', controller: Index, permission: ['admin.webhook'] }, 'NavBarAdmin')
|