{% extends "base.html" %} {% block title %}Admin - craft-dashboard{% endblock %} {% block content %}
Live status and GitHub API budgets.
{{ next_expected_fetch | local_datetime("Unknown") }}
Polling every 10 minutes
{{ api_budget.core_remaining ~ " / " ~ api_budget.core_limit ~ " remaining" if api_budget else "Unknown" }}
{{ api_budget.graphql_remaining ~ " / " ~ api_budget.graphql_limit ~ " remaining" if api_budget else "Unknown" }}
Newest: {{ system_status.most_recent_full_refresh | local_datetime("Unknown") }}
Oldest (up next): {{ system_status.most_overdue_full_refresh | local_datetime("Unknown") }}
{% if system_status.full_refresh_failing_count %} {% else %}No projects currently failing
{% endif %}Collection run history. Click any row to see which issues were collected.
| Source | Started | Status | Projects | Issues | Duration | Errors |
|---|---|---|---|---|---|---|
| {{ run.source }} | {% if run.started_at %} {{ run.started_at | local_datetime }} {% else %}—{% endif %} | {% if run.status == "failed" %} {{ run.status }} {% elif run.status == "interrupted" %} {{ run.status }} {% elif run.status == "running" %} {{ run.status }} {% elif run.errors %} {{ run.status }} ⚠ {% else %} {{ run.status }} {% endif %} | {{ run.projects_processed }} | {{ run.issues_collected }} | {% if run.status == "running" and run.started_at %} running… {% else %} {{ run.duration_seconds | format_duration if run.duration_seconds is not none else "—" }} {% endif %} |
{% if run.errors %}
|
No recent collection runs.
{% endif %}Open issues refresh every 10 minutes. Each hour, the project that has gone longest without a full sync (open and closed issues) is refreshed. The top row is up next in the rotation. Failure counters track consecutive failures; projects with recent intermittent failures in the last 24 hours show a caution indicator.
| Project | Source | Last open poll | Last full refresh | Next full refresh | Consecutive failures |
|---|---|---|---|---|---|
| {{ entry.project }} | {{ entry.source }} | {% if entry.last_open_poll_at %} {{ entry.last_open_poll_at | local_datetime }} {% if entry.last_open_poll_issues_collected is not none %} ({{ entry.last_open_poll_issues_collected }} issues) {% endif %} {% else %} — {% endif %} | {% if entry.last_refreshed_at %} {% set h = entry.hours_since_last %} {{ entry.last_refreshed_at | local_datetime }} {% if h is not none and h == 0 %} (less than 1 hour ago) {% elif h is not none and h == 1 %} (1 hour ago) {% elif h is not none and h < 48 %} ({{ h }} hours ago) {% else %} ({{ entry.days_since_last }} days ago) {% endif %} {% if entry.last_full_refresh_issues_collected is not none %} • {{ entry.last_full_refresh_issues_collected }} issues {% endif %} {% if entry.last_full_refresh_duration_seconds is not none %} • {{ entry.last_full_refresh_duration_seconds | format_duration }} {% endif %} {% else %} never {% endif %} | {{ entry.next_refresh_at | local_datetime }} {% if loop.first %} (up next) {% elif entry.next_refresh_hours == 1 %} (in ~1 hour) {% else %} (in ~{{ entry.next_refresh_hours }} hours) {% endif %} | {% if entry.consecutive_failures > 0 or entry.open_poll_consecutive_failures > 0 %} {% if entry.consecutive_failures > 0 %} Full: {{ entry.consecutive_failures }} {% endif %} {% if entry.open_poll_consecutive_failures > 0 %} Poll: {{ entry.open_poll_consecutive_failures }} {% endif %} {% elif entry.recent_failures_24h > 0 %} 0 ({{ entry.recent_failures_24h }} in 24h ⚠) {% else %} 0 {% endif %} |
No refresh schedule data. Run a collection first.
{% endif %}Latest issue activity across tracked repositories.