feat(simplify): simplified logs view

Default to showing problem orders (ERROR/SKIPPED) first. Imported
orders collapsed behind "X comenzi importate cu succes" toggle.
Reduces noise for operators scanning for issues.

Cache-bust: logs.js?v=14, style.css?v=23

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-03-27 12:42:29 +00:00
parent bd4524707e
commit d3d1905b18
4 changed files with 87 additions and 6 deletions

View File

@@ -141,7 +141,11 @@ async function loadRunOrders(runId, statusFilter, page) {
if (orders.length === 0) {
tbody.innerHTML = '<tr><td colspan="9" class="text-center text-muted py-3">Nicio comanda</td></tr>';
} else {
tbody.innerHTML = orders.map((o, i) => {
const problemOrders = orders.filter(o => ['ERROR', 'SKIPPED'].includes(o.status));
const okOrders = orders.filter(o => ['IMPORTED', 'ALREADY_IMPORTED'].includes(o.status));
const otherOrders = orders.filter(o => !['ERROR', 'SKIPPED', 'IMPORTED', 'ALREADY_IMPORTED'].includes(o.status));
function orderRow(o, i) {
const dateStr = fmtDate(o.order_date);
const orderTotal = o.order_total != null ? Number(o.order_total).toFixed(2) : '-';
return `<tr style="cursor:pointer" onclick="openOrderDetail('${esc(o.order_number)}')">
@@ -155,7 +159,31 @@ async function loadRunOrders(runId, statusFilter, page) {
<td class="text-end text-muted">${fmtCost(o.discount_total)}</td>
<td class="text-end fw-bold">${orderTotal}</td>
</tr>`;
}).join('');
}
let html = '';
// Show problem orders first (always visible)
problemOrders.forEach((o, i) => { html += orderRow(o, i); });
otherOrders.forEach((o, i) => { html += orderRow(o, problemOrders.length + i); });
// Collapsible OK orders
if (okOrders.length > 0) {
const toggleId = 'okOrdersCollapse_' + Date.now();
html += `<tr><td colspan="9" class="p-0">
<div class="log-ok-toggle" onclick="this.nextElementSibling.classList.toggle('d-none')">
${okOrders.length} comenzi importate cu succes
</div>
<div class="d-none">
<table class="table mb-0">
<tbody>
${okOrders.map((o, i) => orderRow(o, problemOrders.length + otherOrders.length + i)).join('')}
</tbody>
</table>
</div>
</td></tr>`;
}
tbody.innerHTML = html;
}
// Mobile flat rows
@@ -164,7 +192,11 @@ async function loadRunOrders(runId, statusFilter, page) {
if (orders.length === 0) {
mobileList.innerHTML = '<div class="flat-row text-muted py-3 justify-content-center">Nicio comanda</div>';
} else {
mobileList.innerHTML = orders.map(o => {
const problemOrders = orders.filter(o => ['ERROR', 'SKIPPED'].includes(o.status));
const okOrders = orders.filter(o => ['IMPORTED', 'ALREADY_IMPORTED'].includes(o.status));
const otherOrders = orders.filter(o => !['ERROR', 'SKIPPED', 'IMPORTED', 'ALREADY_IMPORTED'].includes(o.status));
function mobileRow(o) {
const d = o.order_date || '';
let dateFmt = '-';
if (d.length >= 10) {
@@ -178,7 +210,22 @@ async function loadRunOrders(runId, statusFilter, page) {
<span class="grow truncate fw-bold">${esc(o.customer_name || '—')}</span>
<span class="text-nowrap">x${o.items_count || 0}${totalStr ? ' · <strong>' + totalStr + '</strong>' : ''}</span>
</div>`;
}).join('');
}
let mobileHtml = '';
problemOrders.forEach(o => { mobileHtml += mobileRow(o); });
otherOrders.forEach(o => { mobileHtml += mobileRow(o); });
if (okOrders.length > 0) {
mobileHtml += `<div class="log-ok-toggle" onclick="this.nextElementSibling.classList.toggle('d-none')">
${okOrders.length} comenzi importate cu succes
</div>
<div class="d-none">
${okOrders.map(o => mobileRow(o)).join('')}
</div>`;
}
mobileList.innerHTML = mobileHtml;
}
}