milestone_rows.html
html
| 1 | {# milestone_rows.html — HTMX fragment: milestone list rows. |
| 2 | Included by milestones_list.html for initial SSR and returned bare for |
| 3 | HTMX tab/sort switches (HX-Request: true). |
| 4 | Context vars: milestones, base_url, state, sort #} |
| 5 | {% if milestones %} |
| 6 | {% for ms in milestones %} |
| 7 | {% set total = ms.open_issues + ms.closed_issues %} |
| 8 | {% set pct = ((ms.closed_issues / total) * 100) | int if total > 0 else 0 %} |
| 9 | <div class="milestone-row"> |
| 10 | <div class="milestone-title-row"> |
| 11 | <a href="{{ base_url }}/milestones/{{ ms.number }}" class="milestone-title-link">{{ ms.title }}</a> |
| 12 | <span class="badge {% if ms.state == 'open' %}badge-open{% else %}badge-closed{% endif %}">{{ ms.state }}</span> |
| 13 | </div> |
| 14 | |
| 15 | {% if ms.description %} |
| 16 | <p class="milestone-meta">{{ ms.description }}</p> |
| 17 | {% endif %} |
| 18 | |
| 19 | <div class="milestone-meta"> |
| 20 | {% if ms.due_on %} |
| 21 | <span class="milestone-due">📅 Due {{ ms.due_on.strftime('%b %-d, %Y') }}</span> • |
| 22 | {% endif %} |
| 23 | <span>{{ ms.open_issues }} open • {{ ms.closed_issues }} closed</span> |
| 24 | </div> |
| 25 | |
| 26 | <div class="milestone-progress-wrap"> |
| 27 | <div class="milestone-progress-bar-track"> |
| 28 | <div class="milestone-progress-bar-fill" style="width:{{ pct }}%"></div> |
| 29 | </div> |
| 30 | <span class="milestone-progress-label">{{ pct }}%</span> |
| 31 | </div> |
| 32 | </div> |
| 33 | {% endfor %} |
| 34 | {% else %} |
| 35 | <div class="milestone-empty"> |
| 36 | <p>🎯 No milestones</p> |
| 37 | <p style="font-size:13px">Create a milestone to track progress toward a goal.</p> |
| 38 | </div> |
| 39 | {% endif %} |