feat: richer Webhooks tab — create, toggle, delete subscriptions (#454)

* feat: richer Webhooks tab — create, toggle, delete subscriptions

Adds full webhook subscription management matching the dashboard UI:
- Create subscription dialog (name, description, events, deliver, secret)
- Per-subscription enable/disable toggle via PUT endpoint
- Delete with confirmation dialog
- Enhanced subscription cards: description, event chips, delivery badge,
  secret indicator, URL display
- Search filtering across name, description, and events
- Updated Webhook.kt model with full API shape
- New HermesApiService endpoints for CRUD operations

Closes #447

* fix: remove double top padding on webhooks screen LazyColumn

* fix: use string resources in webhooks screen (sweep hardcoded strings)

* fix: resolve unresolved merge conflict in AchievementsScreen

Leftover <<<<<<< markers from a main merge broke compilation on the
webhooks-full-parity branch, cascading through ktlint/lint/tests.

---------

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-07-03 00:52:49 +03:00
1 parent f887146056
commit d875c8a040
6 files changed
+660 -161

No files matched your search

@@ -8,10 +8,38 @@ data class WebhooksResponse(
data class WebhookSubscription(
val name: String,
val url: String,
val description: String?,
val events: List<String>?,
val deliver: String?,
val deliver_only: Boolean?,
val prompt: String?,
val skills: List<String>?,
val created_at: String?,
val url: String,
val secret_set: Boolean?,
val enabled: Boolean?,
)
data class CreateWebhookRequest(
val name: String,
val description: String? = null,
val events: List<String>? = null,
val prompt: String? = null,
val skills: List<String>? = null,
val deliver: String? = null,
val deliver_only: Boolean? = null,
val deliver_chat_id: String? = null,
val secret: String? = null,
)
data class WebhooksToggleRequest(
val enabled: Boolean,
)
data class WebhookToggleSubscriptionRequest(
val enabled: Boolean,
)
data class DeleteWebhookResponse(
val ok: Boolean,
)