aboutsummaryrefslogtreecommitdiff
path: root/webmentions_ssg/templates
diff options
context:
space:
mode:
authorDennis Fink2026-08-21 13:13:23 +0200
committerDennis Fink2026-08-21 13:13:23 +0200
commit75d22f618b22de6d26ed66bd9a15bf7a66e97af9 (patch)
treebe4b29d9c761b79d6ac476adda00dfb9f31b415e /webmentions_ssg/templates
parent66ad7fefff6edc1d993f5c347430a28d63727988 (diff)
downloadwebmentions-ssg-75d22f618b22de6d26ed66bd9a15bf7a66e97af9.tar.gz
webmentions-ssg-75d22f618b22de6d26ed66bd9a15bf7a66e97af9.zip
feat(sender): paginate sent webmention details
Load sent Webmentions with database-backed pagination instead of eagerly loading the full relationship for each source. Condense delivery, revision, and activity metadata in the source detail table and add pagination controls for large Webmention sets.
Diffstat (limited to 'webmentions_ssg/templates')
-rw-r--r--webmentions_ssg/templates/sent_source.html220
1 files changed, 114 insertions, 106 deletions
diff --git a/webmentions_ssg/templates/sent_source.html b/webmentions_ssg/templates/sent_source.html
index 77376b5..db8f898 100644
--- a/webmentions_ssg/templates/sent_source.html
+++ b/webmentions_ssg/templates/sent_source.html
@@ -4,6 +4,7 @@ SPDX-FileCopyrightText: 2026 Dennis Fink <me+coding@dennisfink.me>
SPDX-License-Identifier: BSD-3-Clause
-->
{% extends "base.html" %}
+{% from "bootstrap5/pagination.html" import render_pagination %}
{% block content %}
<div class="mb-3">
<a href="{{ url_for("root.sent") }}">&larr; Back to sources</a>
@@ -65,100 +66,102 @@ SPDX-License-Identifier: BSD-3-Clause
</div>
<div class="d-flex justify-content-between align-items-start mb-3">
<h2 class="mb-0">Sent Webmentions</h2>
- <span class="text-body-secondary">{{ webmentions | length }} webmentions</span>
+ <span class="text-body-secondary">{{ webmentions.item | length }} webmentions</span>
</div>
- {% if webmentions %}
- <div class="table-responsive">
- <table class="table table-bordered table-striped table-hover align-middle">
- <thead>
- <tr>
- <th scope="col">Target</th>
- <th scope="col">Status</th>
- <th scope="col">Active</th>
- <th scope="col">Desired revision</th>
- <th scope="col">Processed revision</th>
- <th scope="col">Sent revision</th>
- <th scope="col">Failure Reason</th>
- <th scope="col">Endpoint</th>
- <th scope="col">Response Status</th>
- <th scope="col">Status URL</th>
- <th scope="col">Last attempted at</th>
- <th scope="col">Last sent at</th>
- <th scope="col">Actions</th>
- </tr>
- </thead>
- <tbody>
- {% for webmention in webmentions %}
- {% if webmention.status is none %}
- {% set row_class = "table-info" %}
- {% set badge_class = "text-bg-info" %}
- {% elif webmention.status.value == "sent" %}
- {% set row_class = "table-success" %}
- {% set badge_class = "text-bg-success" %}
- {% elif webmention.status.value == "unsupported" %}
- {% set row_class = "table-warning" %}
- {% set badge_class = "text-bg-warning" %}
- {% elif webmention.status.value == "failed" %}
- {% set row_class = "table-danger" %}
- {% set badge_class = "text-bg-danger" %}
- {% else %}
- {% set row_class = "table-info" %}
- {% set badge_class = "text-bg-info" %}
- {% endif %}
- <tr class="{{ row_class }}">
- <td class="text-break">
- <a href="{{ webmention.target }}">{{ webmention.target }}</a>
- </td>
- <td>
- {% if webmention.status is none %}
- <span class="badge {{ badge_class }}">Pending</span>
- {% else %}
- <span class="badge {{ badge_class }}">{{ webmention.status.value.title() }}</span>
- {% endif %}
- </td>
- <td>
- {% if webmention.active %}
- <span class="badge text-bg-success">Active</span>
- {% else %}
- <span class="badge text-bg-danger">Removed</span>
- {% endif %}
- </td>
- <td>{{ webmention.desired_revision }}</td>
- <td>
+ {% if webmentions.items %}
+ <table class="table table-bordered table-striped table-hover align-middle">
+ <thead>
+ <tr>
+ <th scope="col" class="w-25">Target</th>
+ <th scope="col">Status</th>
+ <th scope="col">Active</th>
+ <th scope="col">Revisions</th>
+ <th scope="col">Delivery</th>
+ <th scope="col">Last activity</th>
+ <th scope="col">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for webmention in webmentions %}
+ {% if webmention.status is none %}
+ {% set row_class = "table-info" %}
+ {% set badge_class = "text-bg-info" %}
+ {% elif webmention.status.value == "sent" %}
+ {% set row_class = "table-success" %}
+ {% set badge_class = "text-bg-success" %}
+ {% elif webmention.status.value == "unsupported" %}
+ {% set row_class = "table-warning" %}
+ {% set badge_class = "text-bg-warning" %}
+ {% elif webmention.status.value == "failed" %}
+ {% set row_class = "table-danger" %}
+ {% set badge_class = "text-bg-danger" %}
+ {% else %}
+ {% set row_class = "table-info" %}
+ {% set badge_class = "text-bg-info" %}
+ {% endif %}
+ <tr class="{{ row_class }}">
+ <td class="text-break">
+ <a href="{{ webmention.target }}">{{ webmention.target }}</a>
+ </td>
+ <td>
+ {% if webmention.status is none %}
+ <span class="badge {{ badge_class }}">Pending</span>
+ {% else %}
+ <span class="badge {{ badge_class }}">{{ webmention.status.value.title() }}</span>
+ {% endif %}
+ {% if webmention.failure_reason is not none %}
+ <div class="small mt-2">{{ webmention.failure_reason }}</div>
+ {% endif %}
+ </td>
+ <td>
+ {% if webmention.active %}
+ <span class="badge text-bg-success">Active</span>
+ {% else %}
+ <span class="badge text-bg-danger">Removed</span>
+ {% endif %}
+ </td>
+ <td class="small text-nowrap">
+ <div>
+ <strong>Desired:</strong>
+ {{ webmention.desired_revision }}
+ </div>
+ <div>
+ <strong>Processed:</strong>
{{ webmention.processed_revision
if webmention.processed_revision is not none
else "—" }}
- </td>
- <td>
+ </div>
+ <div>
+ <strong>Sent:</strong>
{{ webmention.sent_revision
if webmention.sent_revision is not none
else "—" }}
- </td>
- <td>
- {{ webmention.failure_reason
- if webmention.failure_reason is not none
- else "—" }}
- </td>
- <td class="text-break">
- {% if webmention.endpoint is not none %}
- <a href="{{ webmention.endpoint }}">{{ webmention.endpoint }}</a>
- {% else %}
- —
- {% endif %}
- </td>
- <td>
- {{ webmention.response_status
- if webmention.response_status is not none
- else "—" }}
- </td>
- <td class="text-break">
- {% if webmention.status_url is not none %}
- <a href="{{ webmention.status_url }}">{{ webmention.status_url }}</a>
- {% else %}
- —
- {% endif %}
- </td>
- <td>
+ </div>
+ </td>
+ <td class="small">
+ {% if webmention.endpoint is not none %}
+ <div class="mb-1">
+ <strong>Endpoint:</strong>
+ <a href="{{ webmention.endpoint }}" class="text-break">{{ webmention.endpoint }}</a>
+ </div>
+ {% endif %}
+ {% if webmention.response_status is not none %}
+ <div class="mb-1">
+ <strong>HTTP:</strong>
+ {{ webmention.response_status }}
+ </div>
+ {% endif %}
+ {% if webmention.status_url is not none %}
+ <div>
+ <strong>Status:</strong>
+ <a href="{{ webmention.status_url }}" class="text-break">{{ webmention.status_url }}</a>
+ </div>
+ {% endif %}
+ </td>
+ <td class="small text-nowrap">
+ <div class="mb-1">
+ <strong>Attempted:</strong>
+ <br>
{% if webmention.last_attempted_at is not none %}
<time datetime="{{ webmention.last_attempted_at.isoformat() }}">
{{ webmention.last_attempted_at.strftime("%Y-%m-%d %H:%M:%S") }}
@@ -166,8 +169,10 @@ SPDX-License-Identifier: BSD-3-Clause
{% else %}
—
{% endif %}
- </td>
- <td>
+ </div>
+ <div>
+ <strong>Sent:</strong>
+ <br>
{% if webmention.last_sent_at is not none %}
<time datetime="{{ webmention.last_sent_at.isoformat() }}">
{{ webmention.last_sent_at.strftime("%Y-%m-%d %H:%M:%S") }}
@@ -175,23 +180,26 @@ SPDX-License-Identifier: BSD-3-Clause
{% else %}
—
{% endif %}
- </td>
- <td>
- <button type="button"
- class="btn btn-sm btn-primary"
- data-bs-toggle="modal"
- data-bs-target="#confirmation-modal"
- data-action="{{ url_for("root.resend_sent_webmention", source_identifier=source.uuid, webmention_identifier=webmention.uuid) }}"
- data-title="Resend Webmention?"
- data-message="This Webmention will be queued again for delivery to {{ webmention.target }}."
- data-confirm-label="Resend"
- data-confirm-class="btn-primary">Resend</button>
- </td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
- </div>
+ </div>
+ </td>
+ <td>
+ <button type="button"
+ class="btn btn-sm btn-primary"
+ data-bs-toggle="modal"
+ data-bs-target="#confirmation-modal"
+ data-action="{{ url_for("root.resend_sent_webmention", source_identifier=source.uuid, webmention_identifier=webmention.uuid) }}"
+ data-title="Resend Webmention?"
+ data-message="This Webmention will be queued again for delivery to {{ webmention.target }}."
+ data-confirm-label="Resend"
+ data-confirm-class="btn-primary">Resend</button>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% if webmentions.pages > 1 %}
+ <div class="mt-3">{{ render_pagination(webmentions) }}</div>
+ {% endif %}
{% include "includes/confirmation_modal.html" %}
{% else %}
<p class="text-body-secondary">No Webmentions have been discovered for this source.</p>