System hooks missing features like URL masking, Custom Template, Custom Headers
### About
System hooks do not use the same form that is [shared by group and project hooks](https://gitlab.com/gitlab-org/gitlab/-/blob/61cfd3475c458246eab94163c6899f44a740ced6/ee/app/views/groups/hooks/edit.html.haml#L11).
### Problem
Over time, this has meant that new features added for project and group webhooks are not available to system hooks. At time of writing these are:
- URL masking
- Custom headers
- Custom webhook template
### Proposal
Refactor system hooks to be able to share with group and project hooks these missing features.
---
## Implementation Plan
### Context
GitLab's system hooks (admin-level webhooks) are missing three features that project and group webhooks already have: URL masking, custom headers, and custom webhook templates.
The DB columns already exist on `web_hooks` (`encrypted_url_variables`, `encrypted_custom_headers`, `custom_webhook_template`). The `WebHooks::Hook` concern (which `SystemHook` inherits via `WebHook`) already provides the underlying logic. The gap is purely in the controller params and the UI.
### Implementation Steps
#### 1. Controller — `app/controllers/admin/hooks_controller.rb`
The admin controller overrides `hook_param_names` and excludes `custom_webhook_template` (the parent in `HookActions` already permits `url_variables` and `custom_headers` as arrays). Add the missing param:
```ruby
def hook_param_names
%i[enable_ssl_verification name description token url custom_webhook_template]
end
```
#### 2. JS Entry Point — `app/assets/javascripts/pages/admin/hooks/index.js`
The current file only calls `initHookTestDropdowns()`. Add the Vue form initializer:
```js
import initWebhookForm, { initHookTestDropdowns } from '~/webhooks';
initWebhookForm();
initHookTestDropdowns();
```
#### 3. Add `repositoryUpdateEvents` to TRIGGER_CONFIG — `app/assets/javascripts/webhooks/constants.js`
`repository_update_events` is a system-hook-only trigger not currently in `TRIGGER_CONFIG`. Add it (it should be filtered out for project/group hooks in step 4).
#### 4. Filter triggers by hook type — `app/assets/javascripts/webhooks/components/webhook_form_trigger_list.vue`
Currently the trigger list renders ALL `TRIGGER_CONFIG` entries regardless of hook type, meaning system hooks would see `noteEvents`, `issuesEvents`, etc. Add a computed property to filter by keys present in `initialTriggers`:
```js
computed: {
filteredTriggerConfig() {
const triggerKeys = Object.keys(this.triggers);
return this.$options.TRIGGER_CONFIG.filter(({ key }) => triggerKeys.includes(key));
},
},
```
**Backward compatibility**: `all_triggers(hook)` for `ProjectHook` passes all project trigger keys, so all project/group trigger items continue to render. For `SystemHook`, only `repositoryUpdateEvents`, `tagPushEvents`, and `mergeRequestsEvents` (plus `pushEvents` via `PushEvents` component) will show.
#### 5. Rewrite admin HAML form — `app/views/admin/hooks/_form.html.haml`
Replace the current pure-HAML form with one that mounts the Vue component (matching the pattern in `shared/web_hooks/_form.html.haml`) while preserving EE-specific content.
The Vue component handles: name, description, URL + URL masking (FormUrlApp), token, custom headers (FormCustomHeaders), and triggers (WebhookFormTriggerList). The HAML handles custom_webhook_template and SSL (matching the pattern in `shared/web_hooks/_form.html.haml`).
### Critical Files
| File | Change |
|---|---|
| `app/controllers/admin/hooks_controller.rb` | Add `custom_webhook_template` to `hook_param_names` |
| `app/assets/javascripts/pages/admin/hooks/index.js` | Call `initWebhookForm()` |
| `app/assets/javascripts/webhooks/constants.js` | Add `repositoryUpdateEvents` to `TRIGGER_CONFIG` |
| `app/assets/javascripts/webhooks/components/webhook_form_trigger_list.vue` | Filter config by `initialTriggers` keys |
| `app/views/admin/hooks/_form.html.haml` | Replace HAML form with Vue mount + HAML SSL/template fields |
| `app/views/admin/hooks/edit.html.haml` | Add `html: { class: 'js-webhook-form' }` |
| `spec/controllers/admin/hooks_controller_spec.rb` | Add tests for new params |
| `spec/frontend/webhooks/components/webhook_form_trigger_list_spec.js` | Add filtering tests |
issue