Feb 02 2026: implement issue unfollow badge on issue list
This commit is contained in:
+16
-2
@@ -56,10 +56,20 @@ def index():
|
|||||||
q = q.filter(Issue.status == status_filter)
|
q = q.filter(Issue.status == status_filter)
|
||||||
|
|
||||||
issues = q.paginate(page=page, per_page=25, error_out=False)
|
issues = q.paginate(page=page, per_page=25, error_out=False)
|
||||||
|
|
||||||
|
# Build a set of issue IDs the current user is following so the template
|
||||||
|
# can render the following badge and inline unfollow button without an
|
||||||
|
# additional query per row.
|
||||||
|
followed_ids = {
|
||||||
|
f.issue_id
|
||||||
|
for f in IssueFollower.query.filter_by(user_id=current_user.id).all()
|
||||||
|
}
|
||||||
|
|
||||||
return render_template('issues/list.html',
|
return render_template('issues/list.html',
|
||||||
issues=issues,
|
issues=issues,
|
||||||
severity_filter=severity_filter,
|
severity_filter=severity_filter,
|
||||||
status_filter=status_filter)
|
status_filter=status_filter,
|
||||||
|
followed_ids=followed_ids)
|
||||||
|
|
||||||
|
|
||||||
# ── View / Update ─────────────────────────────────────────────────────────────
|
# ── View / Update ─────────────────────────────────────────────────────────────
|
||||||
@@ -276,7 +286,11 @@ def unfollow(issue_id):
|
|||||||
flash('You have unfollowed this issue.', 'info')
|
flash('You have unfollowed this issue.', 'info')
|
||||||
else:
|
else:
|
||||||
flash('You are not following this issue.', 'info')
|
flash('You are not following this issue.', 'info')
|
||||||
return redirect(url_for('issues.view', issue_id=issue_id))
|
|
||||||
|
# Respect an explicit next URL (e.g. return to the list page).
|
||||||
|
# Fall back to the issue view if none is provided.
|
||||||
|
next_url = request.form.get('next') or url_for('issues.view', issue_id=issue_id)
|
||||||
|
return redirect(next_url)
|
||||||
|
|
||||||
|
|
||||||
# ── Standalone create ─────────────────────────────────────────────────────────
|
# ── Standalone create ─────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -45,11 +45,19 @@
|
|||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover mb-0">
|
<table class="table table-hover mb-0">
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
<tr><th>Reported</th><th>Severity</th><th>Facility / Area</th>
|
<tr>
|
||||||
<th>Description</th><th>Status</th><th>Assigned</th><th></th></tr>
|
<th>Reported</th>
|
||||||
|
<th>Severity</th>
|
||||||
|
<th>Facility / Area</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Assigned</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for issue in issues.items %}
|
{% for issue in issues.items %}
|
||||||
|
{% set is_following = issue.id in followed_ids %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><small>{{ issue.reported_at.strftime('%Y-%m-%d %H:%M') }}</small></td>
|
<td><small>{{ issue.reported_at.strftime('%Y-%m-%d %H:%M') }}</small></td>
|
||||||
<td>
|
<td>
|
||||||
@@ -71,8 +79,27 @@
|
|||||||
{% if issue.assigned_user %}{{ issue.assigned_user.username }}
|
{% if issue.assigned_user %}{{ issue.assigned_user.username }}
|
||||||
{% else %}<span class="text-muted">—</span>{% endif %}
|
{% else %}<span class="text-muted">—</span>{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="text-nowrap">
|
||||||
<a href="{{ url_for('issues.view', issue_id=issue.id) }}" class="btn btn-sm btn-outline-secondary">
|
{# Following badge + inline unfollow #}
|
||||||
|
{% if is_following %}
|
||||||
|
<span class="badge bg-primary me-1" title="You are following this issue">
|
||||||
|
<i class="bi bi-bell-fill"></i> Following
|
||||||
|
</span>
|
||||||
|
<form method="post"
|
||||||
|
action="{{ url_for('issues.unfollow', issue_id=issue.id) }}"
|
||||||
|
class="d-inline"
|
||||||
|
title="Unfollow this issue">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<input type="hidden" name="next" value="{{ url_for('issues.index', page=issues.page, severity=severity_filter, status=status_filter) }}">
|
||||||
|
<button type="submit" class="btn btn-sm btn-outline-primary p-0 px-1 me-1"
|
||||||
|
title="Unfollow">
|
||||||
|
<i class="bi bi-bell-slash" style="font-size:.75rem;"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<a href="{{ url_for('issues.view', issue_id=issue.id) }}"
|
||||||
|
class="btn btn-sm btn-outline-secondary">
|
||||||
{% if current_user.role in ['admin','supervisor'] or issue.assigned_to == current_user.id %}
|
{% if current_user.role in ['admin','supervisor'] or issue.assigned_to == current_user.id %}
|
||||||
<i class="bi bi-pencil"></i> Edit
|
<i class="bi bi-pencil"></i> Edit
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -85,19 +112,22 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if issues.pages > 1 %}
|
{% if issues.pages > 1 %}
|
||||||
<div class="d-flex justify-content-center py-3">
|
<div class="d-flex justify-content-center py-3">
|
||||||
<nav><ul class="pagination pagination-sm mb-0">
|
<nav><ul class="pagination pagination-sm mb-0">
|
||||||
{% for p in issues.iter_pages(left_edge=1,right_edge=1,left_current=2,right_current=2) %}
|
{% for p in issues.iter_pages(left_edge=1,right_edge=1,left_current=2,right_current=2) %}
|
||||||
{% if p %}
|
{% if p %}
|
||||||
<li class="page-item {{ 'active' if p == issues.page }}">
|
<li class="page-item {{ 'active' if p == issues.page }}">
|
||||||
<a class="page-link" href="{{ url_for('issues.index', page=p, severity=severity_filter, status=status_filter) }}">{{ p }}</a>
|
<a class="page-link"
|
||||||
|
href="{{ url_for('issues.index', page=p, severity=severity_filter, status=status_filter) }}">{{ p }}</a>
|
||||||
</li>
|
</li>
|
||||||
{% else %}<li class="page-item disabled"><span class="page-link">…</span></li>{% endif %}
|
{% else %}<li class="page-item disabled"><span class="page-link">…</span></li>{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul></nav>
|
</ul></nav>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="alert alert-info m-3"><i class="bi bi-info-circle"></i> No issues found.</div>
|
<div class="alert alert-info m-3"><i class="bi bi-info-circle"></i> No issues found.</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
Reference in New Issue
Block a user