Dashboard cleanup: chart empty-state message, dead click-handler (#101)
Two small findings from the same dashboard audit pass: 1. Charts rendered a bare empty frame with no message when the filtered dataset was empty (fresh install, or a non-admin's visibility-filtered ticket set happening to be zero). makeDonut/ makeBar now show a "No data for current filters" message in the chart's place instead of silently doing nothing. 2. Stat cards had two independent, redundant click-handler implementations. lt.statsFilter.init() (base.js, shared web_template code) read each card's data-filter-key/data-filter-val attributes and called window.lt_onStatFilter(key, val) on click — but that global is never defined anywhere in this app, so it only toggled a cosmetic .active class with no functional effect. The actual navigation logic is the separate handler at ~line 1282 that ignores those attributes entirely. Both fired on the same click with no visible symptom, but the markup looked load-bearing and wasn't — a trap for a future edit that touches one implementation assuming it's the only one. Removed the dead lt.statsFilter.init() call and the now-unused data-filter-key/data-filter-val attributes from this app's DashboardView.php (left the shared lt.statsFilter module in base.js itself untouched, since other LotusGuild apps consuming the same shared template file may define their own lt_onStatFilter). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MGDKHiU5RJdo3dqQUDow3X
This commit is contained in:
+16
-7
@@ -120,7 +120,6 @@ include __DIR__ . '/layout_header.php';
|
||||
?>
|
||||
|
||||
<div class="lt-stat-card stat-open" role="button" tabindex="0"
|
||||
data-filter-key="status" data-filter-val="Open,Pending,In Progress"
|
||||
title="Click to filter by active tickets" aria-label="Open tickets">
|
||||
<div class="lt-stat-icon">[ # ]</div>
|
||||
<div class="lt-stat-info">
|
||||
@@ -133,7 +132,6 @@ include __DIR__ . '/layout_header.php';
|
||||
</div>
|
||||
|
||||
<div class="lt-stat-card stat-critical" role="button" tabindex="0"
|
||||
data-filter-key="priority" data-filter-val="1"
|
||||
title="Click to filter critical (P1) tickets" aria-label="Critical P1 tickets">
|
||||
<div class="lt-stat-icon lt-text-danger">[ ! ]</div>
|
||||
<div class="lt-stat-info">
|
||||
@@ -146,7 +144,6 @@ include __DIR__ . '/layout_header.php';
|
||||
</div>
|
||||
|
||||
<div class="lt-stat-card stat-unassigned" role="button" tabindex="0"
|
||||
data-filter-key="assigned_to" data-filter-val="unassigned"
|
||||
title="Click to filter unassigned tickets" aria-label="Unassigned tickets">
|
||||
<div class="lt-stat-icon lt-text-amber">[ @ ]</div>
|
||||
<div class="lt-stat-info">
|
||||
@@ -171,7 +168,6 @@ include __DIR__ . '/layout_header.php';
|
||||
</div>
|
||||
|
||||
<div class="lt-stat-card stat-resolved" role="button" tabindex="0"
|
||||
data-filter-key="status" data-filter-val="Closed"
|
||||
title="Click to filter closed tickets" aria-label="Closed tickets today">
|
||||
<div class="lt-stat-icon lt-text-muted">[ OK ]</div>
|
||||
<div class="lt-stat-info">
|
||||
@@ -334,7 +330,8 @@ include __DIR__ . '/layout_header.php';
|
||||
|
||||
function makeDonut(canvasId, data, colorMap) {
|
||||
var ctx = document.getElementById(canvasId);
|
||||
if (!ctx || !data.length) return;
|
||||
if (!ctx) return;
|
||||
if (!data.length) { showChartEmptyState(ctx); return; }
|
||||
ctx.title = 'Click a segment to filter the ticket list';
|
||||
return new Chart(ctx, {
|
||||
type: 'doughnut',
|
||||
@@ -365,9 +362,22 @@ include __DIR__ . '/layout_header.php';
|
||||
});
|
||||
}
|
||||
|
||||
function showChartEmptyState(canvas) {
|
||||
canvas.style.display = 'none';
|
||||
var wrap = canvas.parentElement;
|
||||
if (wrap && !wrap.querySelector('.lt-chart-empty')) {
|
||||
var msg = document.createElement('div');
|
||||
msg.className = 'lt-chart-empty';
|
||||
msg.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:0.75rem';
|
||||
msg.textContent = 'No data for current filters';
|
||||
wrap.appendChild(msg);
|
||||
}
|
||||
}
|
||||
|
||||
function makeBar(canvasId, data) {
|
||||
var ctx = document.getElementById(canvasId);
|
||||
if (!ctx || !data.length) return;
|
||||
if (!ctx) return;
|
||||
if (!data.length) { showChartEmptyState(ctx); return; }
|
||||
ctx.title = 'Click a bar to filter the ticket list';
|
||||
return new Chart(ctx, {
|
||||
type: 'bar',
|
||||
@@ -1226,7 +1236,6 @@ window.TICKET_STATUSES = <?= json_encode($GLOBALS['config']['TICKET_STATUSES'])
|
||||
if (window.lt) {
|
||||
lt.keys.initDefaults();
|
||||
lt.tableNav.init('tickets-table');
|
||||
lt.statsFilter.init();
|
||||
}
|
||||
|
||||
// Saved filter pills — load on page init
|
||||
|
||||
Reference in New Issue
Block a user