05/25 Improvement 1
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<div>
|
||||
<h2><i class="bi bi-patch-check text-info me-2"></i>Verification Queue</h2>
|
||||
<p class="text-muted mb-0">
|
||||
Issues awaiting supervisor sign-off before they are fully closed.
|
||||
Issues awaiting director sign-off before they are fully closed.
|
||||
</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
@@ -21,6 +21,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# ── Bulk-verify toolbar — shown when at least one issue is pending ── #}
|
||||
{% if grouped %}
|
||||
<form method="POST" action="{{ url_for('issues.bulk_verify') }}" id="bulkVerifyForm">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
{# Issue checkboxes are rendered inside the per-facility tables below;
|
||||
hidden inputs with their IDs are inserted here by JS on submission. #}
|
||||
<div class="card bg-light border-0 mb-3 p-2 d-flex flex-row align-items-center gap-3 flex-wrap" id="bulkToolbar">
|
||||
<div class="form-check mb-0">
|
||||
<input class="form-check-input" type="checkbox" id="selectAllIssues">
|
||||
<label class="form-check-label fw-semibold" for="selectAllIssues">Select all</label>
|
||||
</div>
|
||||
<span class="text-muted small" id="selectedCount">0 selected</span>
|
||||
<button type="submit" class="btn btn-success btn-sm" id="bulkVerifyBtn" disabled
|
||||
onclick="return injectBulkIds(this.form)">
|
||||
<i class="bi bi-patch-check-fill me-1"></i>Verify Selected
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% if not grouped %}
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body text-center py-5 text-muted">
|
||||
@@ -47,6 +67,7 @@
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="table-light" style="font-size:.82rem;">
|
||||
<tr>
|
||||
<th width="36"><span class="visually-hidden">Select</span></th>
|
||||
<th width="60">ID</th>
|
||||
<th width="90">Severity</th>
|
||||
<th>Area / Description</th>
|
||||
@@ -62,6 +83,12 @@
|
||||
{% set hrs = sla_hours_remaining(issue) %}
|
||||
<tr class="{{ 'table-danger' if sla == 'breached' else 'table-warning' if sla == 'at_risk' else '' }}">
|
||||
|
||||
{# Bulk-select checkbox #}
|
||||
<td class="align-middle text-center">
|
||||
<input class="form-check-input issue-checkbox" type="checkbox"
|
||||
value="{{ issue.id }}" aria-label="Select issue #{{ issue.id }}">
|
||||
</td>
|
||||
|
||||
{# ID #}
|
||||
<td class="text-muted small align-middle">
|
||||
<a href="{{ url_for('issues.view', issue_id=issue.id) }}"
|
||||
@@ -157,3 +184,53 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
// ── Bulk-verify checkbox management ─────────────────────────────────────────
|
||||
(function () {
|
||||
const selectAll = document.getElementById('selectAllIssues');
|
||||
const countEl = document.getElementById('selectedCount');
|
||||
const verifyBtn = document.getElementById('bulkVerifyBtn');
|
||||
|
||||
function updateToolbar() {
|
||||
const checked = document.querySelectorAll('.issue-checkbox:checked');
|
||||
const n = checked.length;
|
||||
if (countEl) countEl.textContent = n + ' selected';
|
||||
if (verifyBtn) verifyBtn.disabled = n === 0;
|
||||
if (selectAll) selectAll.indeterminate = n > 0 && n < document.querySelectorAll('.issue-checkbox').length;
|
||||
if (selectAll) selectAll.checked = n > 0 && n === document.querySelectorAll('.issue-checkbox').length;
|
||||
}
|
||||
|
||||
document.querySelectorAll('.issue-checkbox').forEach(cb => {
|
||||
cb.addEventListener('change', updateToolbar);
|
||||
});
|
||||
|
||||
if (selectAll) {
|
||||
selectAll.addEventListener('change', function () {
|
||||
document.querySelectorAll('.issue-checkbox').forEach(cb => { cb.checked = this.checked; });
|
||||
updateToolbar();
|
||||
});
|
||||
}
|
||||
|
||||
updateToolbar();
|
||||
}());
|
||||
|
||||
// ── Inject checked issue IDs into the bulk-verify form before submit ─────────
|
||||
function injectBulkIds(form) {
|
||||
// Remove any previously injected inputs
|
||||
form.querySelectorAll('input[name="issue_ids"]').forEach(el => el.remove());
|
||||
const checked = document.querySelectorAll('.issue-checkbox:checked');
|
||||
if (!checked.length) { alert('Please select at least one issue.'); return false; }
|
||||
if (!confirm('Verify and close ' + checked.length + ' selected issue(s)?')) return false;
|
||||
checked.forEach(cb => {
|
||||
const hidden = document.createElement('input');
|
||||
hidden.type = 'hidden';
|
||||
hidden.name = 'issue_ids';
|
||||
hidden.value = cb.value;
|
||||
form.appendChild(hidden);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user