feat(tickets map): auto midnight rollover + larger squircle markers

- Midnight reset for ALL today-windowed categories: the dashboard now refetches
  when the EAT calendar day changes (60s check), so closed pins/counts, the
  day-total, closures-daily and closures-by-engineer all reset for the new day
  even on a screen left open overnight (previously only reset on manual Refresh).
- Markers enlarged (open icon-size max 1.0 -> 1.25, closed 0.78 -> 1.0) — bigger
  than before but still more compact than the old teardrops.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
david kiania 2026-06-18 23:33:33 +03:00
parent 8a0e1304ab
commit 2d7cc98d4b

View file

@ -960,6 +960,8 @@ const tkMarkers = new Map(); // imei → maplibregl.M
const tkLayerState = { open: true, closed: true, vehicles: true };
let tkOwnerFilter = null; // when set, the closed layer is filtered to this engineer (drill-down)
let incData = null, incDropdownsInit = false, vehCount = 0;
let tkLoadedDay = null; // EAT calendar day of the last INC load — drives the midnight auto-rollover
const eatDay = () => new Date().toLocaleDateString('en-CA', { timeZone: 'Africa/Nairobi' });
// ── INC helpers ───────────────────────────────────────────────────────────
const mttrFmt = (min) => (min == null || isNaN(min)) ? '—' : num(min / 60, 1) + ' h';
@ -1101,7 +1103,7 @@ function initIncMap() {
visibility: tkLayerState.closed ? 'visible' : 'none',
'icon-image': ['match', ['get', 'sla_status'],
'Breached', 'pin-closed-breached', 'Compliant', 'pin-closed-ok', 'pin-closed-unknown'],
'icon-size': ['interpolate', ['linear'], ['zoom'], 6, 0.42, 11, 0.6, 16, 0.78],
'icon-size': ['interpolate', ['linear'], ['zoom'], 6, 0.52, 11, 0.74, 16, 1.0],
'icon-anchor': 'bottom', 'icon-allow-overlap': true, 'icon-ignore-placement': true,
},
paint: { 'icon-opacity': 0.9 },
@ -1114,7 +1116,7 @@ function initIncMap() {
visibility: tkLayerState.open ? 'visible' : 'none',
'icon-image': ['match', ['get', 'sla_state'],
'breached', 'pin-breached', 'at_risk', 'pin-at_risk', 'ok', 'pin-ok', 'pin-unknown'],
'icon-size': ['interpolate', ['linear'], ['zoom'], 6, 0.52, 11, 0.78, 16, 1],
'icon-size': ['interpolate', ['linear'], ['zoom'], 6, 0.64, 11, 0.92, 16, 1.25],
'icon-anchor': 'bottom', 'icon-allow-overlap': true, 'icon-ignore-placement': true,
},
});
@ -1127,6 +1129,10 @@ function initIncMap() {
if (incData) renderIncMap(); // INC data may have arrived before the basemap loaded
loadLive();
tkLivePoll = setInterval(loadLive, LIVE_POLL_MS);
// Auto roll over at EAT midnight: when the calendar day changes, refetch so EVERY
// today-windowed category (closed pins, closed counts, total, closures, by-engineer)
// resets for the new day — even on a dashboard left open overnight.
setInterval(() => { if (tkLoadedDay && eatDay() !== tkLoadedDay) loadInc(); }, 60000);
});
}
@ -1240,6 +1246,7 @@ async function loadInc() {
try {
const j = await api(`/webhook/inc-dashboard?${incQs()}`);
incData = j;
tkLoadedDay = eatDay();
if (!incDropdownsInit && j.metrics) { initIncDropdowns(j.metrics); incDropdownsInit = true; }
renderIncMetrics(j.metrics, j.freshness);
renderIncTables(j.metrics);