1{% extends "base.html" %}
2
3{% block title %}td — {{ project_name }}{% endblock %}
4
5{% block content %}
6<nav aria-label="Breadcrumb">
7 <ol class="unstyled hstack">
8 <li><a href="/" class="unstyled">Projects</a></li>
9 <li aria-hidden="true">/</li>
10 <li><a href="/projects/{{ project_name }}" class="unstyled" aria-current="page"><strong>{{ project_name }}</strong></a></li>
11 </ol>
12</nav>
13
14<h1>{{ project_name }}</h1>
15
16<div class="container">
17 <div class="row">
18 <article class="card col-4">
19 <h2>Open</h2>
20 <p><strong>{{ stats_open }}</strong></p>
21 </article>
22 <article class="card col-4">
23 <h2>In progress</h2>
24 <p><strong>{{ stats_in_progress }}</strong></p>
25 </article>
26 <article class="card col-4">
27 <h2>Closed</h2>
28 <p><strong>{{ stats_closed }}</strong></p>
29 </article>
30 </div>
31</div>
32
33{% if !next_up.is_empty() %}
34<details open class="mt-4">
35 <summary><h2>Next up</h2></summary>
36 <div class="table">
37 <table>
38 <caption class="sr-only">Top scored tasks recommended to work on next</caption>
39 <thead>
40 <tr>
41 <th scope="col">#</th>
42 <th scope="col">ID</th>
43 <th scope="col">Score</th>
44 <th scope="col">Title</th>
45 </tr>
46 </thead>
47 <tbody>
48 {% for (i, s) in next_up.iter().enumerate() %}
49 <tr>
50 <td>{{ i + 1 }}</td>
51 <td><a href="/projects/{{ project_name }}/tasks/{{ s.id }}"><code>{{ s.short_id }}</code></a></td>
52 <td>{{ s.score }}</td>
53 <td>{{ s.title }}</td>
54 </tr>
55 {% endfor %}
56 </tbody>
57 </table>
58 </div>
59</details>
60{% endif %}
61
62<details open class="mt-4">
63 <summary><h2>Tasks</h2></summary>
64
65 <form method="get" action="/projects/{{ project_name }}" class="hstack gap-2 mt-2 mb-4">
66 <div data-field>
67 <label for="filter-status">Status</label>
68 <select id="filter-status" name="status" aria-label="Filter by status">
69 <option value="">All</option>
70 <option value="open"{% if filter_status.as_deref() == Some("open") %} selected{% endif %}>Open</option>
71 <option value="in_progress"{% if filter_status.as_deref() == Some("in_progress") %} selected{% endif %}>In progress</option>
72 <option value="closed"{% if filter_status.as_deref() == Some("closed") %} selected{% endif %}>Closed</option>
73 </select>
74 </div>
75 <div data-field>
76 <label for="filter-priority">Priority</label>
77 <select id="filter-priority" name="priority" aria-label="Filter by priority">
78 <option value="">All</option>
79 <option value="high"{% if filter_priority.as_deref() == Some("high") %} selected{% endif %}>High</option>
80 <option value="medium"{% if filter_priority.as_deref() == Some("medium") %} selected{% endif %}>Medium</option>
81 <option value="low"{% if filter_priority.as_deref() == Some("low") %} selected{% endif %}>Low</option>
82 </select>
83 </div>
84 <div data-field>
85 <label for="filter-effort">Effort</label>
86 <select id="filter-effort" name="effort" aria-label="Filter by effort">
87 <option value="">All</option>
88 <option value="low"{% if filter_effort.as_deref() == Some("low") %} selected{% endif %}>Low</option>
89 <option value="medium"{% if filter_effort.as_deref() == Some("medium") %} selected{% endif %}>Medium</option>
90 <option value="high"{% if filter_effort.as_deref() == Some("high") %} selected{% endif %}>High</option>
91 </select>
92 </div>
93 <div data-field>
94 <label for="filter-label">Label</label>
95 <select id="filter-label" name="label" aria-label="Filter by label">
96 <option value="">All</option>
97 {% for l in all_labels %}
98 <option value="{{ l }}"{% if filter_label.as_deref() == Some(l.as_str()) %} selected{% endif %}>{{ l }}</option>
99 {% endfor %}
100 </select>
101 </div>
102 <div data-field>
103 <label for="filter-search">Search</label>
104 <input type="text" id="filter-search" name="q" value="{{ filter_search }}" placeholder="Search titles…" aria-label="Search tasks by title">
105 </div>
106 <button type="submit" class="outline">Filter</button>
107 </form>
108
109 {% if page_tasks.is_empty() %}
110 <p class="text-light">No tasks match the current filters.</p>
111 {% else %}
112 <div class="table">
113 <table>
114 <caption class="sr-only">Task list for project {{ project_name }}</caption>
115 <thead>
116 <tr>
117 <th scope="col">ID</th>
118 <th scope="col">Status</th>
119 <th scope="col">Priority</th>
120 <th scope="col">Effort</th>
121 <th scope="col">Title</th>
122 </tr>
123 </thead>
124 <tbody>
125 {% for t in page_tasks %}
126 <tr>
127 <td><a href="/projects/{{ project_name }}/tasks/{{ t.full_id }}"><code>{{ t.short_id }}</code></a></td>
128 <td><span class="badge{% if t.status == "closed" %} success{% elif t.status == "in_progress" %} secondary{% endif %}">{{ t.status }}</span></td>
129 <td>{{ t.priority }}</td>
130 <td>{{ t.effort }}</td>
131 <td>{{ t.title }}</td>
132 </tr>
133 {% endfor %}
134 </tbody>
135 </table>
136 </div>
137
138 {% if total_pages > 1 %}
139 <nav aria-label="Task list pagination" class="mt-4">
140 <menu class="buttons">
141 {% if page > 1 %}
142 {% let prev = page - 1 %}
143 <li><a href="{{ self.pagination_href(prev) }}" class="button outline small">← Previous</a></li>
144 {% endif %}
145 {% for p in pagination_pages %}
146 <li>
147 {% if *p == page %}
148 <a href="{{ self.pagination_href(p) }}" class="button small" aria-current="page">{{ p }}</a>
149 {% else %}
150 <a href="{{ self.pagination_href(p) }}" class="button outline small">{{ p }}</a>
151 {% endif %}
152 </li>
153 {% endfor %}
154 {% if page < total_pages %}
155 {% let next = page + 1 %}
156 <li><a href="{{ self.pagination_href(next) }}" class="button outline small">Next →</a></li>
157 {% endif %}
158 </menu>
159 </nav>
160 {% endif %}
161 {% endif %}
162</details>
163{% endblock %}