Skip to content

Commit b5d0191

Browse files
authored
✨ Add Filter for Webhook Deliveries (#967)
1 parent 2ec21fb commit b5d0191

File tree

8 files changed

+84
-13
lines changed

8 files changed

+84
-13
lines changed

default_translations/de/messages.de.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,9 @@ settings:
543543
title: Zustellungen
544544
heading: Zustellungen
545545
subtitle: Kürzliche Webhook-Zustellungen
546+
filter:
547+
label: Status
548+
all: Alle
546549
table:
547550
id: ID
548551
event: Ereignis

default_translations/en/messages.en.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,9 @@ settings:
545545
title: Deliveries
546546
heading: Deliveries
547547
subtitle: Recent webhook deliveries
548+
filter:
549+
label: Status
550+
all: All
548551
table:
549552
id: ID
550553
event: Event

features/settings_webhook.feature

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ Feature: Settings
8484
And I should see "Delivered"
8585
And I should see "Failed"
8686

87+
When I am on "/settings/webhooks/1/deliveries?status=success"
88+
Then the response status code should be 200
89+
And I should not see "Retry"
90+
91+
When I am on "/settings/webhooks/1/deliveries?status=failed"
92+
Then the response status code should be 200
93+
And I should see "Retry"
94+
8795
@webhooks
8896
Scenario: Admin can view a delivery for a webhook
8997
Given the following WebhookEndpoint exists:

src/Controller/WebhookDeliveryController.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@ public function index(
2626
Request $request,
2727
): Response {
2828
$page = $request->query->getInt('page', 1);
29-
$pagination = $this->manager->findPaginatedByEndpoint($endpoint, $page);
29+
$status = $request->query->getString('status', '');
30+
$pagination = $this->manager->findPaginatedByEndpoint($endpoint, $page, $status);
3031

3132
return $this->render('Settings/Webhook/Delivery/index.html.twig', [
3233
'deliveries' => $pagination['items'],
3334
'endpoint' => $endpoint,
3435
'page' => $pagination['page'],
3536
'totalPages' => $pagination['totalPages'],
3637
'total' => $pagination['total'],
38+
'status' => $status,
3739
]);
3840
}
3941

src/Repository/WebhookDeliveryRepository.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,47 @@ public function countByEndpoint(WebhookEndpoint $endpoint): int
2828
->getQuery()
2929
->getSingleScalarResult();
3030
}
31+
32+
public function countByEndpointAndStatus(WebhookEndpoint $endpoint, string $status): int
33+
{
34+
$qb = $this->createQueryBuilder('d')
35+
->select('COUNT(d.id)')
36+
->where('d.endpoint = :endpoint')
37+
->setParameter('endpoint', $endpoint);
38+
39+
$this->applyStatusFilter($qb, $status);
40+
41+
return (int) $qb->getQuery()->getSingleScalarResult();
42+
}
43+
44+
/**
45+
* @return WebhookDelivery[]
46+
*/
47+
public function findByEndpointAndStatus(
48+
WebhookEndpoint $endpoint,
49+
string $status,
50+
int $limit,
51+
int $offset,
52+
): array {
53+
$qb = $this->createQueryBuilder('d')
54+
->where('d.endpoint = :endpoint')
55+
->setParameter('endpoint', $endpoint)
56+
->orderBy('d.id', 'DESC')
57+
->setMaxResults($limit)
58+
->setFirstResult($offset);
59+
60+
$this->applyStatusFilter($qb, $status);
61+
62+
return $qb->getQuery()->getResult();
63+
}
64+
65+
private function applyStatusFilter(\Doctrine\ORM\QueryBuilder $qb, string $status): void
66+
{
67+
match ($status) {
68+
'success' => $qb->andWhere('d.success = true'),
69+
'failed' => $qb->andWhere('d.error IS NOT NULL')->andWhere('d.success = false'),
70+
'pending' => $qb->andWhere('d.error IS NULL')->andWhere('d.success = false'),
71+
default => null,
72+
};
73+
}
3174
}

src/Service/WebhookDeliveryManager.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ public function __construct(
3030
public function findPaginatedByEndpoint(
3131
WebhookEndpoint $endpoint,
3232
int $page = 1,
33+
string $status = '',
3334
): array {
3435
$page = max(1, $page);
3536
$offset = ($page - 1) * self::PAGE_SIZE;
36-
$total = $this->repository->countByEndpoint($endpoint);
37-
$totalPages = (int) ceil($total / self::PAGE_SIZE);
38-
$items = $this->repository->findBy(
39-
['endpoint' => $endpoint],
40-
['id' => 'DESC'],
37+
$total = $this->repository->countByEndpointAndStatus($endpoint, $status);
38+
$totalPages = max(1, (int) ceil($total / self::PAGE_SIZE));
39+
$items = $this->repository->findByEndpointAndStatus(
40+
$endpoint,
41+
$status,
4142
self::PAGE_SIZE,
4243
$offset,
4344
);

templates/Settings/Webhook/Delivery/index.html.twig

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,22 @@
1616
<p class="text-sm text-gray-500 dark:text-gray-300 mt-1">{{ 'settings.webhook.deliveries.subtitle'|trans }}</p>
1717
</div>
1818
</div>
19-
<div class="mb-4">
19+
<div class="mb-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
2020
<a href="{{ path('settings_webhook_endpoint_index') }}"
2121
class="inline-flex items-center px-3 py-1.5 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-600">
2222
{{ ux_icon('heroicons:arrow-left', {class: 'w-4 h-4 mr-1'}) }} {{ 'settings.webhook.actions.back'|trans }}
2323
</a>
24+
<div class="flex items-center gap-2">
25+
<label for="status-filter" class="text-sm text-gray-600 dark:text-gray-400">{{ 'settings.webhook.deliveries.filter.label'|trans }}:</label>
26+
<select id="status-filter"
27+
onchange="window.location.href = this.value"
28+
class="px-3 py-1.5 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
29+
<option value="{{ path('settings_webhook_delivery_index', {id: endpoint.id}) }}"{% if status == '' %} selected{% endif %}>{{ 'settings.webhook.deliveries.filter.all'|trans }}</option>
30+
<option value="{{ path('settings_webhook_delivery_index', {id: endpoint.id, status: 'success'}) }}"{% if status == 'success' %} selected{% endif %}>{{ 'settings.webhook.deliveries.status.delivered'|trans }}</option>
31+
<option value="{{ path('settings_webhook_delivery_index', {id: endpoint.id, status: 'failed'}) }}"{% if status == 'failed' %} selected{% endif %}>{{ 'settings.webhook.deliveries.status.failed'|trans }}</option>
32+
<option value="{{ path('settings_webhook_delivery_index', {id: endpoint.id, status: 'pending'}) }}"{% if status == 'pending' %} selected{% endif %}>{{ 'settings.webhook.deliveries.status.pending'|trans }}</option>
33+
</select>
34+
</div>
2435
</div>
2536
<div class="overflow-hidden">
2637
<div class="overflow-x-auto">
@@ -88,7 +99,7 @@
8899
</div>
89100
<div class="flex gap-2">
90101
{% if page > 1 %}
91-
<a href="{{ path('settings_webhook_delivery_index', {id: endpoint.id, page: page - 1}) }}"
102+
<a href="{{ path('settings_webhook_delivery_index', {id: endpoint.id, page: page - 1, status: status}|filter(v => v)) }}"
92103
class="inline-flex items-center px-3 py-1.5 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-600">
93104
{{ ux_icon('heroicons:chevron-left', {class: 'w-4 h-4 mr-1'}) }} {{ 'settings.webhook.deliveries.pagination.newer'|trans }}
94105
</a>
@@ -97,7 +108,7 @@
97108
{{ 'settings.webhook.deliveries.pagination.page'|trans({'%page%': page, '%totalPages%': totalPages}) }}
98109
</span>
99110
{% if page < totalPages %}
100-
<a href="{{ path('settings_webhook_delivery_index', {id: endpoint.id, page: page + 1}) }}"
111+
<a href="{{ path('settings_webhook_delivery_index', {id: endpoint.id, page: page + 1, status: status}|filter(v => v)) }}"
101112
class="inline-flex items-center px-3 py-1.5 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-600">
102113
{{ 'settings.webhook.deliveries.pagination.older'|trans }} {{ ux_icon('heroicons:chevron-right', {class: 'w-4 h-4 ml-1'}) }}
103114
</a>

tests/Service/WebhookDeliveryManagerTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ public function testFindPaginatedByEndpointReturnsDeliveries(): void
2727

2828
$repo = $this->createMock(WebhookDeliveryRepository::class);
2929
$repo->expects($this->once())
30-
->method('countByEndpoint')
31-
->with($endpoint)
30+
->method('countByEndpointAndStatus')
31+
->with($endpoint, '')
3232
->willReturn(2);
3333
$repo->expects($this->once())
34-
->method('findBy')
35-
->with(['endpoint' => $endpoint], ['id' => 'DESC'], 20, 0)
34+
->method('findByEndpointAndStatus')
35+
->with($endpoint, '', 20, 0)
3636
->willReturn([$d2, $d1]);
3737

3838
$em = $this->createMock(EntityManagerInterface::class);

0 commit comments

Comments
 (0)