5.2 KiB · text History 7bac2a7
{% extends "root.html" %}

{% block inner %}
<div class="space-y-6 text-left">

  {# Queue depth — single line per kind, "messages / consumers, dlq=N". #}
  {% if depths %}
  {% set total_dlq = depths|map(attribute="dlq_messages")|sum %}
  <div>
    <div class="flex items-center justify-between mb-2">
      <h3 class="text-lg font-bold text-accent">Queue depth</h3>
      {% if total_dlq > 0 %}
      <form method="post" action="/failed/dlq/requeue" class="m-0">
        <button type="submit" class="btn btn-warning btn-xs">
          <i class="fas fa-rotate-left"></i> Requeue all DLQs ({{ total_dlq }})
        </button>
      </form>
      {% endif %}
    </div>
    <div class="overflow-x-auto">
      <table class="table table-sm">
        <thead>
          <tr>
            <th>Kind</th>
            <th class="text-right">Pending</th>
            <th class="text-right">Consumers</th>
            <th class="text-right">DLQ</th>
            <th class="text-right">Actions</th>
          </tr>
        </thead>
        <tbody>
          {% for q in depths %}
          <tr>
            <td><span class="badge badge-ghost">{{ q.kind }}</span></td>
            <td class="text-right font-mono">{{ q.messages }}</td>
            <td class="text-right font-mono">{{ q.consumers }}</td>
            <td class="text-right font-mono {% if q.dlq_messages > 0 %}text-error{% endif %}">{{ q.dlq_messages }}</td>
            <td class="text-right">
              {% if q.dlq_messages > 0 %}
              <form method="post" action="/failed/dlq/{{ q.kind }}/requeue" class="inline m-0">
                <button type="submit" class="btn btn-ghost btn-xs">
                  <i class="fas fa-rotate-left"></i> Requeue
                </button>
              </form>
              {% else %}
              <span class="opacity-30">—</span>
              {% endif %}
            </td>
          </tr>
          {% endfor %}
        </tbody>
      </table>
    </div>
  </div>
  {% endif %}

  {# Recent completions per kind. #}
  {% if recent %}
  <div>
    <h3 class="text-lg font-bold text-accent mb-2">Last 3 completed per queue</h3>
    <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
      {% for kind, jobs in recent|items %}
      <div class="border border-base-300 rounded-box p-3">
        <div class="flex items-center justify-between mb-2">
          <span class="badge badge-ghost">{{ kind }}</span>
          <span class="text-xs opacity-60">{{ jobs|length }} shown</span>
        </div>
        {% if not jobs %}
        <div class="text-xs opacity-60">— none yet —</div>
        {% else %}
        <ul class="space-y-1">
          {% for j in jobs %}
          <li class="text-xs font-mono truncate">
            <a href="/uploads/{{ j.upload_id }}" class="link link-hover">
              {{ j.file_name_original }}
            </a>
            <span class="opacity-60"> — {{ j.completed_at }}</span>
          </li>
          {% endfor %}
        </ul>
        {% endif %}
      </div>
      {% endfor %}
    </div>
  </div>
  {% endif %}

  <div class="flex justify-between items-center mb-4">
    <h2 class="text-2xl font-bold text-accent">Failed jobs ({{ rows|length }})</h2>
    {# DB-tracked failed jobs (per-user) — distinct from the DLQ table above,
       which holds broker-level dead-lettered messages across all users. #}
    {% if rows %}
    <form method="post" action="/failed/retry" class="m-0">
      <button type="submit" class="btn btn-warning btn-sm">
        <i class="fas fa-rotate-right"></i> Retry all
      </button>
    </form>
    {% endif %}
  </div>

  {% if request and request.query.notice %}
  <div class="alert alert-success">
    <i class="fas fa-circle-check"></i>
    <span>{{ request.query.notice }}</span>
  </div>
  {% endif %}

  {% if not rows %}
  <div class="alert alert-info">
    <i class="fas fa-circle-info"></i>
    <span>Nothing to retry — no failed jobs.</span>
  </div>
  {% else %}
  <div class="overflow-x-auto">
    <table class="table table-zebra table-sm">
      <thead>
        <tr>
          <th>Upload</th>
          <th>Kind</th>
          <th>Attempts</th>
          <th>Error</th>
          <th>Last attempt</th>
          <th class="text-right">Actions</th>
        </tr>
      </thead>
      <tbody>
        {% for r in rows %}
        <tr>
          <td>
            <a href="/uploads/{{ r.upload_id }}" class="link link-hover font-mono text-xs">
              {{ r.file_name_original }}
            </a>
          </td>
          <td><span class="badge badge-ghost">{{ r.kind }}</span></td>
          <td>{{ r.attempts }}</td>
          <td class="font-mono text-xs max-w-md truncate" title="{{ r.error or '' }}">
            {{ r.error or '—' }}
          </td>
          <td class="font-mono text-xs">{{ r.updated_at }}</td>
          <td class="text-right">
            <form method="post"
                  action="/uploads/{{ r.upload_id }}/jobs/{{ r.kind }}/retry"
                  class="inline m-0">
              <button type="submit" class="btn btn-ghost btn-xs">
                <i class="fas fa-rotate-right"></i> Retry
              </button>
            </form>
          </td>
        </tr>
        {% endfor %}
      </tbody>
    </table>
  </div>
  {% endif %}
</div>
{% endblock %}