feat(tickets): center the overview, remove its filter row
The INC/CRQ overview is now a centered "today" snapshot — header + metric tiles centered. Removed the overview filter row (Cluster/Status/Window/Apply/refresh): the Ticket explorer below carries the ad-hoc filtering, so it was redundant. incQs() is fixed to window=today; dropped initIncDropdowns + the removed listeners. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
e58195073d
commit
9fb39aa992
1 changed files with 15 additions and 67 deletions
|
|
@ -225,8 +225,8 @@
|
|||
}
|
||||
|
||||
/* INC metric strip */
|
||||
.metric-row { display: flex; flex-wrap: wrap; gap: 26px; }
|
||||
.metric { display: flex; flex-direction: column; min-width: 96px; }
|
||||
.metric-row { display: flex; flex-wrap: wrap; gap: 26px; justify-content: center; }
|
||||
.metric { display: flex; flex-direction: column; align-items: center; text-align: center; min-width: 96px; }
|
||||
.metric b { font-size: 22px; line-height: 1.1; font-variant-numeric: tabular-nums; }
|
||||
.metric b.accent { color: var(--accent); }
|
||||
.metric .lbl { font-size: 9.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; margin-top: 3px; }
|
||||
|
|
@ -238,9 +238,7 @@
|
|||
.sla-unknown { color: var(--muted); }
|
||||
|
||||
/* INC overview row: metric tiles (left) + filters (right) on one balanced row */
|
||||
.tk-overview-row { display: flex; align-items: center; justify-content: space-between; gap: 16px 28px; flex-wrap: wrap; }
|
||||
.tk-overview-metrics { min-width: 0; }
|
||||
.tk-filters { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-left: auto; }
|
||||
.tk-overview-metrics { min-width: 0; text-align: center; }
|
||||
.tk-filters .ff select, .tk-filters .ff input { min-width: 130px; }
|
||||
|
||||
/* Live vehicle DOM marker (ported from FleetNow) */
|
||||
|
|
@ -411,35 +409,10 @@
|
|||
</div>
|
||||
<main id="tk-main">
|
||||
<div class="card span12">
|
||||
<div class="tk-overview-row">
|
||||
<div class="tk-overview-metrics">
|
||||
<h2><span id="tk-ds-ov">INC</span> overview <span class="count" id="tk-fresh"></span></h2>
|
||||
<div class="metric-row" id="tk-metrics"><div class="empty">Loading…</div></div>
|
||||
</div>
|
||||
<div class="tk-filters">
|
||||
<div class="ff">
|
||||
<label for="tk-cluster">Cluster</label>
|
||||
<select id="tk-cluster"><option value="">All clusters</option></select>
|
||||
</div>
|
||||
<div class="ff">
|
||||
<label for="tk-status">Status</label>
|
||||
<select id="tk-status"><option value="">All statuses</option></select>
|
||||
</div>
|
||||
<div class="ff">
|
||||
<label for="tk-window">Window</label>
|
||||
<select id="tk-window">
|
||||
<option value="today" selected>Today</option>
|
||||
<option value="week">This week</option>
|
||||
<option value="month">This month</option>
|
||||
<option value="custom">Custom range</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="ff custom" id="tk-ff-start"><label for="tk-start">Start</label><input type="date" id="tk-start"></div>
|
||||
<div class="ff custom" id="tk-ff-end"><label for="tk-end">End</label><input type="date" id="tk-end"></div>
|
||||
<button class="btn" id="tk-apply" type="button">Apply</button>
|
||||
<button class="btn ghost" id="tk-refresh" type="button" title="Reload">↻</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card span12">
|
||||
|
|
@ -929,9 +902,9 @@ function setDataset(ds) {
|
|||
const U = ds.toUpperCase();
|
||||
$('tk-ds-ov').textContent = U;
|
||||
$('tk-ds-map').textContent = U;
|
||||
// per-dataset dropdowns + explorer results are stale → clear and re-init
|
||||
incDropdownsInit = false; incFilterOptionsInit = false;
|
||||
['tk-cluster', 'tk-status', 'tk-x-eng', 'tk-x-cluster'].forEach(resetSelect);
|
||||
// per-dataset explorer dropdowns + results are stale → clear and re-init
|
||||
incFilterOptionsInit = false;
|
||||
['tk-x-eng', 'tk-x-cluster'].forEach(resetSelect);
|
||||
$('tk-x-id').value = ''; $('tk-x-id-list').innerHTML = '';
|
||||
$('tk-x-count').textContent = '';
|
||||
$('tk-x-wrap').innerHTML = '<div class="empty">Search by ticket id, engineer, cluster, state and time.</div>';
|
||||
|
|
@ -1009,7 +982,7 @@ let tkMap = null, tkPopup = null, tkLivePoll = null, tkClosureChart = null;
|
|||
const tkMarkers = new Map(); // imei → maplibregl.Marker
|
||||
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 incData = null, vehCount = 0;
|
||||
let DS = 'inc'; // active Tickets dataset (inc | crq) — drives /webhook/${DS}-* endpoints + labels
|
||||
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' });
|
||||
|
|
@ -1023,18 +996,10 @@ function eatShort(iso) {
|
|||
}
|
||||
function addDay(ymd) { const [y, m, d] = ymd.split('-').map(Number); return new Date(Date.UTC(y, m - 1, d + 1)).toISOString().slice(0, 10); }
|
||||
|
||||
// The overview is a fixed "today" snapshot now that its filter row is removed —
|
||||
// ad-hoc cluster / status / time filtering lives in the Ticket explorer below.
|
||||
function incQs() {
|
||||
const p = new URLSearchParams();
|
||||
if ($('tk-cluster').value) p.set('cluster', $('tk-cluster').value);
|
||||
if ($('tk-status').value) p.set('status', $('tk-status').value);
|
||||
const w = $('tk-window').value;
|
||||
if (w === 'custom') {
|
||||
if ($('tk-start').value) p.set('from', $('tk-start').value + 'T00:00:00+03:00');
|
||||
if ($('tk-end').value) p.set('to', addDay($('tk-end').value) + 'T00:00:00+03:00'); // inclusive end
|
||||
} else {
|
||||
p.set('window', w);
|
||||
}
|
||||
return p.toString();
|
||||
return 'window=today';
|
||||
}
|
||||
|
||||
// Squircle + bolt map marker: a rounded squircle tapering to a bottom point (anchors on
|
||||
|
|
@ -1125,14 +1090,8 @@ function renderIncMap() {
|
|||
function initIncMap() {
|
||||
if (tkMap) { tkMap.resize(); return; } // already built — just fix sizing
|
||||
|
||||
// Filter / control listeners (attached once, with the map).
|
||||
$('tk-window').addEventListener('change', () => {
|
||||
const custom = $('tk-window').value === 'custom';
|
||||
$('tk-ff-start').classList.toggle('show', custom);
|
||||
$('tk-ff-end').classList.toggle('show', custom);
|
||||
});
|
||||
$('tk-apply').addEventListener('click', loadInc);
|
||||
$('tk-refresh').addEventListener('click', loadInc);
|
||||
// Control listeners (attached once, with the map). The overview filter row was
|
||||
// removed (it's a fixed "today" snapshot); the explorer carries its own filters.
|
||||
$('tk-layers-toggle').addEventListener('click', () => $('tk-layers').classList.toggle('collapsed'));
|
||||
|
||||
// Ticket explorer controls
|
||||
|
|
@ -1327,23 +1286,12 @@ async function loadIncSearch() {
|
|||
}
|
||||
}
|
||||
|
||||
// Populate the Cluster / Status filters from the first unfiltered response.
|
||||
function initIncDropdowns(m) {
|
||||
const fill = (id, obj) => {
|
||||
const el = $(id);
|
||||
Object.keys(obj || {}).filter(k => k !== '').sort().forEach(k => el.add(new Option(k, k)));
|
||||
};
|
||||
fill('tk-cluster', m.by_cluster);
|
||||
fill('tk-status', m.by_status);
|
||||
}
|
||||
|
||||
async function loadInc() {
|
||||
$('tk-main').classList.add('loading');
|
||||
try {
|
||||
const j = await api(`/webhook/${DS}-dashboard?${incQs()}`);
|
||||
incData = j;
|
||||
tkLoadedDay = eatDay();
|
||||
if (!incDropdownsInit && j.metrics) { initIncDropdowns(j.metrics); incDropdownsInit = true; }
|
||||
renderIncMetrics(j.metrics, j.freshness);
|
||||
renderIncMap(); // fan out co-located pins so open (vivid) + closed (faded) both show
|
||||
buildIncLayers();
|
||||
|
|
|
|||
Loading…
Reference in a new issue