{% load i18n %}

{% trans "Data Table" %}

{% trans "Card-wrapped table with four named zones: " %}{% trans "header" %}{% trans " (title + badge + subtitle + right meta), " %}{% trans "controls" %}{% trans " (search + filters, subtle bg), " %}{% trans "table body" %}{% trans ", and " %}{% trans "pagination" %}{% trans ". All zones are optional - use only what you need. Add " %}dcr-data-table__header--subtle{% trans " to tint the header, and " %}dcr-data-table__title-icon{% trans " on an SVG to place an icon before the title text." %}

{% trans "Workers" %} 2 ONLINE

{% trans "Hostname" %} {% trans "Pool" %} {% trans "Conc." %} {% trans "Active" %} {% trans "Uptime" %}
celery@worker-1.prod prefork 8 3 12d 4h
celery@worker-3.prod gevent 50 0 -

{% trans "Usage" %}

<div class="dcr-data-table">
  <div class="dcr-data-table__header dcr-data-table__header--subtle">
    <div class="dcr-data-table__header-info">
      <h3 class="dcr-data-table__title">
        <svg class="dcr-data-table__title-icon" ...></svg>
        Workers <span class="dcr-badge dcr-badge--success">2 ONLINE</span>
      </h3>
    </div>
  </div>
  <table>…</table>
</div>
{% trans "App" %} {% trans "Label" %} {% trans "Models" %} {% trans "Migrations" %}
django.contrib.auth auth 4 up to date
django.contrib.contenttypes contenttypes 1 up to date
myapp.billing billing 6 1 pending

{% trans "Usage" %}

<!-- No-stripe modifier removes alternating row color -->
<div class="dcr-data-table dcr-data-table--no-stripe">
  <table>…</table>
</div>

{% trans "Key Browser" %} 12 TOTAL

{% trans "Browse every key across all databases on this Redis instance." %}

{% trans "Showing 12 of 12" %} {% trans "Updated just now" %}
{% trans "Key" %} {% trans "Type" %} {% trans "DB" %} {% trans "Size" %} {% trans "TTL" %}
user:42:profile hash db0 412 B 1h
session:s9k2lq string db1 1.2 KB 14d
queue:default list db0 8.2 KB never
{% trans "Showing" %} 1–3 {% trans "of" %} 12
{% trans "Previous" %} 1 2 3 {% trans "Next" %}

{% trans "Usage" %}

<div class="dcr-data-table">

  <!-- Zone 1: header -->
  <div class="dcr-data-table__header">
    <div class="dcr-data-table__header-info">
      <h3 class="dcr-data-table__title">Key Browser <span class="dcr-badge">12 TOTAL</span></h3>
      <p class="dcr-data-table__subtitle">Browse every key across all databases.</p>
    </div>
    <div class="dcr-data-table__meta">
      <div class="dcr-data-table__meta-info">
        <span>Showing 8 of 12</span>
        <span>Updated just now</span>
      </div>
      <button type="button" class="dcr-btn dcr-btn--ghost dcr-btn--sm">
        <svg class="dcr-btn__icon" …></svg> CLEAR
      </button>
    </div>
  </div>

  <!-- Zone 2: controls (optional) -->
  <div class="dcr-data-table__controls">
    <form class="dcr-form">…</form>
  </div>

  <!-- Zone 3: table body -->
  <table>…</table>

  <!-- Zone 4: pagination (optional) -->
  <div class="dcr-pagination">…</div>

</div>

{% trans "Expandable Rows" %}

{% trans "Add a " %}dcr-col--expand{% trans " column with a " %}dcr-data-table__expand-btn{% trans " toggle. Each row pairs with a hidden " %}dcr-data-table__expand-row{% trans " sibling. Toggle " %}is-open{% trans " and " %}aria-expanded{% trans " via JS." %}

{% trans "Receiver" %} {% trans "Sender" %} {% trans "Module" %} {% trans "Flags" %}
create_profile auth.User profiles.signals uid
{% trans "SOURCE" %} profiles/signals.py:14
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
send_order_email orders.Order notifications.signals weak
{% trans "SOURCE" %} notifications/signals.py:22
@receiver(post_save, sender=Order, weak=False)
def send_order_email(sender, instance, created, **kwargs):
    if created:
        send_confirmation.delay(instance.pk)
reindex_post blog.Post search.signals uid
{% trans "SOURCE" %} search/signals.py:9
@receiver(post_save, sender=Post, dispatch_uid="search.reindex_post")
def reindex_post(sender, instance, created, **kwargs):
    reindex(instance)

{% trans "Usage" %}

<div class="dcr-data-table dcr-data-table--no-stripe">
  <table>
    <thead>
      <tr>
        <th class="dcr-col--expand"></th>
        <th>Receiver</th>
        ...
      </tr>
    </thead>
    <tbody>
      <!-- data row -->
      <tr>
        <td class="dcr-col--expand">
          <button class="dcr-data-table__expand-btn"
                  aria-expanded="false"
                  aria-controls="row-1">
            <svg ...></svg>
          </button>
        </td>
        <td>create_profile</td>
        ...
      </tr>
      <!-- expand content row (hidden until toggled) -->
      <tr class="dcr-data-table__expand-row" id="row-1">
        <td colspan="5">
          <div class="dcr-code-viewer">…</div>
        </td>
      </tr>
    </tbody>
  </table>
</div>

<script>
document.querySelectorAll('.dcr-data-table__expand-btn').forEach(function (btn) {
  btn.addEventListener('click', function () {
    var row = document.getElementById(btn.getAttribute('aria-controls'));
    var open = btn.getAttribute('aria-expanded') === 'true';
    btn.setAttribute('aria-expanded', !open);
    row.classList.toggle('is-open', !open);
  });
});
</script>

{% trans "Pagination" %}

{% trans "Placed inside a " %}dcr-data-table{% trans " card, after the " %}<table>{% trans ". Supports numbered pages and cursor-only (prev / next) modes. Use " %}<a>{% trans " for active controls, " %}<span aria-disabled>{% trans " for disabled ones." %}

{# Page-based pagination #}

{% trans "Results" %}

847 keys
{% trans "Key" %}{% trans "TTL" %}{% trans "Size" %}
views.homepage300s1.2 KB
views.product_42600s4.7 KB
{% trans "Showing" %} 1–20 {% trans "of" %} 847
{% trans "Previous" %} 1 2 3 43 {% trans "Next" %}

{% trans "Usage" %}

<div class="dcr-pagination">
  <div class="dcr-pagination__per-page">
    <span class="dcr-pagination__summary">Showing <strong>1–20</strong> of <strong>847</strong></span>
    <label>Per page <select class="dcr-pagination__per-page-select">…</select></label>
  </div>
  <div class="dcr-pagination__controls">
    <span class="dcr-pagination__btn dcr-pagination__btn--prev" aria-disabled="true">Previous</span>
    <span class="dcr-pagination__page dcr-pagination__page--active">1</span>
    <a href="?page=2" class="dcr-pagination__page">2</a>
    <span class="dcr-pagination__ellipsis">…</span>
    <a href="?page=43" class="dcr-pagination__page">43</a>
    <a href="?page=2" class="dcr-pagination__btn dcr-pagination__btn--next">Next</a>
  </div>
</div>
{# Cursor-based pagination #}

{% trans "Keys" %}

{% trans "Key" %}{% trans "Type" %}
session:user_4821string
session:cart_5518hash
{% trans "Cursor scan - page 2" %}

{% trans "Usage" %}

<!-- Cursor-based: no page numbers, just prev/next -->
<div class="dcr-pagination">
  <span class="dcr-pagination__summary">Cursor scan - page 2</span>
  <div class="dcr-pagination__controls">
    <a href="?cursor=prev" class="dcr-pagination__btn dcr-pagination__btn--prev">Previous</a>
    <a href="?cursor=next" class="dcr-pagination__btn dcr-pagination__btn--next">Next</a>
  </div>
</div>

{% trans "Empty Results" %}

{% trans "Place " %}dcr-empty{% trans " inside a " %}<tbody>{% trans " cell spanning all columns so the table headers remain visible. Two patterns: no data at all, and no results matching active filters." %}

{% trans "Error Groups" %}

{% trans "Title" %} {% trans "Occurrences" %} {% trans "Last seen" %} {% trans "Status" %}

{% trans "No errors recorded" %}

{% trans "Errors captured from your views, middleware, and Celery tasks will appear here." %}

{% trans "Usage" %}

<div class="dcr-data-table dcr-data-table--no-hover">
  <div class="dcr-data-table__header">
    <h3 class="dcr-data-table__title">Error Groups</h3>
  </div>
  <table>
    <thead>
      <tr>
        <th>Title</th>
        <th>Occurrences</th>
        <th>Last seen</th>
        <th>Status</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td colspan="4">
          <div class="dcr-empty">
            <div class="dcr-empty__icon">...</div>
            <p class="dcr-empty__title">No errors recorded</p>
            <p class="dcr-empty__body">Errors captured from your views, middleware, and Celery tasks will appear here.</p>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</div>

{% trans "Ability Matrix" %}

{% trans "Tabular display of what a backend supports. Use on overview pages that manage multiple backends." %}

{% trans "Backend Capabilities" %}

{% trans "Backend" %} {% trans "Key listing" %} {% trans "TTL support" %} {% trans "Flush" %} {% trans "Inline edit" %}
LocMemCache
RedisCache

{% trans "Usage" %}

<div class="dcr-data-table">
  <div class="dcr-data-table__header">
    <h3 class="dcr-data-table__title">Backend Capabilities</h3>
  </div>
  <table>
    <thead>
      <tr><th>Backend</th><th>Key listing</th><th>TTL support</th></tr>
    </thead>
    <tbody>
      <tr>
        <td><code class="dcr-code">RedisCache</code></td>
        <td><span class="dcr-ability-indicator dcr-ability-indicator--yes">✓</span></td>
        <td><span class="dcr-ability-indicator dcr-ability-indicator--no">–</span></td>
      </tr>
    </tbody>
  </table>
</div>