Fix notifications 500 (audit_id column), smart resolution time units

- notifications.php: audit_log PK is audit_id not log_id; alias all
  three queries with audit_id AS log_id to fix 500 error
- DashboardView: avg resolution time now picks best unit automatically
  (min < 1h, hr < 48h, days < 14d, wks otherwise) with full hours
  shown in title tooltip; adds lt-stat-unit CSS for the suffix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-05 11:32:02 -04:00
parent 5e04478586
commit bc88ba3612
3 changed files with 28 additions and 5 deletions
+3 -3
View File
@@ -45,7 +45,7 @@ $myUsername = $currentUser['username'] ?? '';
// Query 1: Tickets assigned to me (events from other users) // Query 1: Tickets assigned to me (events from other users)
$assignSql = "SELECT $assignSql = "SELECT
al.log_id, al.action_type, al.entity_type, al.entity_id, al.details, al.created_at, al.audit_id AS log_id, al.action_type, al.entity_type, al.entity_id, al.details, al.created_at,
COALESCE(u.display_name, u.username, 'System') AS actor_name COALESCE(u.display_name, u.username, 'System') AS actor_name
FROM audit_log al FROM audit_log al
LEFT JOIN users u ON al.user_id = u.user_id LEFT JOIN users u ON al.user_id = u.user_id
@@ -88,7 +88,7 @@ $stmt->close();
// Step B: fetch recent comment audit events not by the current user // Step B: fetch recent comment audit events not by the current user
$commentSql = "SELECT $commentSql = "SELECT
al.log_id, al.action_type, al.entity_type, al.entity_id, al.details, al.created_at, al.audit_id AS log_id, al.action_type, al.entity_type, al.entity_id, al.details, al.created_at,
COALESCE(u.display_name, u.username, 'System') AS actor_name COALESCE(u.display_name, u.username, 'System') AS actor_name
FROM audit_log al FROM audit_log al
LEFT JOIN users u ON al.user_id = u.user_id LEFT JOIN users u ON al.user_id = u.user_id
@@ -118,7 +118,7 @@ foreach ($rawCommentRows as $rawRow) {
// Query 3: Status changes on watched tickets (from other users) // Query 3: Status changes on watched tickets (from other users)
$statusSql = "SELECT DISTINCT $statusSql = "SELECT DISTINCT
al.log_id, al.action_type, al.entity_type, al.entity_id, al.details, al.created_at, al.audit_id AS log_id, al.action_type, al.entity_type, al.entity_id, al.details, al.created_at,
COALESCE(u.display_name, u.username, 'System') AS actor_name COALESCE(u.display_name, u.username, 'System') AS actor_name
FROM audit_log al FROM audit_log al
LEFT JOIN users u ON al.user_id = u.user_id LEFT JOIN users u ON al.user_id = u.user_id
+8
View File
@@ -8,6 +8,14 @@
margin-bottom: 1rem; margin-bottom: 1rem;
} }
/* Unit suffix on resolution time stat (smaller, muted) */
.lt-stat-unit {
font-size: 0.65em;
font-weight: 500;
margin-left: 0.15em;
opacity: 0.75;
}
/* Priority row highlights */ /* Priority row highlights */
.lt-row-critical td { .lt-row-critical td {
background: rgba(255, 77, 77, 0.04); background: rgba(255, 77, 77, 0.04);
+17 -2
View File
@@ -162,10 +162,25 @@ include __DIR__ . '/layout_header.php';
</div> </div>
</div> </div>
<div class="lt-stat-card stat-time" title="Average resolution time" aria-label="Avg resolution time"> <?php
$avgHours = $stats['avg_resolution_hours'] ?? 0;
if ($avgHours <= 0) {
$avgDisplay = '—'; $avgUnit = '';
} elseif ($avgHours < 1) {
$avgDisplay = (string)max(1, (int)round($avgHours * 60)); $avgUnit = 'min';
} elseif ($avgHours < 48) {
$avgDisplay = (string)(int)round($avgHours); $avgUnit = 'hr';
} elseif ($avgHours < 336) { // <14 days
$avgDisplay = number_format($avgHours / 24, 1); $avgUnit = 'days';
} else {
$avgDisplay = number_format($avgHours / 168, 1); $avgUnit = 'wks';
}
$avgTitle = $avgHours > 0 ? number_format($avgHours, 1) . ' hours' : 'No data';
?>
<div class="lt-stat-card stat-time" title="Average resolution time: <?= htmlspecialchars($avgTitle) ?>" aria-label="Avg resolution time">
<div class="lt-stat-icon lt-text-muted">&#x23F1;</div> <div class="lt-stat-icon lt-text-muted">&#x23F1;</div>
<div class="lt-stat-info"> <div class="lt-stat-info">
<div class="lt-stat-value"><?= htmlspecialchars($stats['avg_resolution_hours'] ?? '—') ?>h</div> <div class="lt-stat-value"><?= htmlspecialchars($avgDisplay) ?><span class="lt-stat-unit"><?= $avgUnit ?></span></div>
<div class="lt-stat-label">Avg Resolution</div> <div class="lt-stat-label">Avg Resolution</div>
</div> </div>
</div> </div>