fix(dashboard): replace hover row-actions with kebab menu, fix modal button reset and delete color
- Bug 1: hover actions covered total column; replaced with kebab dropdown in dedicated 44px column - Bug 2: resync/delete buttons kept stale state across modal opens; reset in modal init block - Bug 3: delete success button was green (btn-success); changed to red (btn-danger) - Dropdown styled per DESIGN.md: warm shadow, 8px radius, dark mode tokens Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -393,19 +393,27 @@ input[type="checkbox"] {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
/* Dashboard row hover actions */
|
||||
#dashOrdersBody tr { position: relative; }
|
||||
#dashOrdersBody tr .row-actions {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
gap: 4px;
|
||||
z-index: 1;
|
||||
/* Dashboard kebab dropdown */
|
||||
.kebab-dropdown .btn { color: var(--text-muted); }
|
||||
.kebab-dropdown .btn:hover { color: var(--text-secondary); }
|
||||
.kebab-dropdown .dropdown-menu {
|
||||
box-shadow: var(--card-shadow);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
font-family: var(--font-body);
|
||||
font-size: 13px;
|
||||
min-width: 160px;
|
||||
}
|
||||
#dashOrdersBody tr:hover .row-actions {
|
||||
display: inline-flex;
|
||||
.kebab-dropdown .dropdown-item { font-size: 13px; padding: 6px 12px; }
|
||||
.kebab-dropdown .dropdown-item:hover { background: var(--surface-raised); }
|
||||
[data-theme="dark"] .kebab-dropdown .dropdown-menu {
|
||||
background: var(--surface);
|
||||
border-color: var(--border);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
[data-theme="dark"] .kebab-dropdown .dropdown-item:hover {
|
||||
background: var(--surface-raised);
|
||||
}
|
||||
|
||||
/* ── Forms ───────────────────────────────────────── */
|
||||
|
||||
@@ -360,7 +360,7 @@ async function loadDashOrders() {
|
||||
const orders = data.orders || [];
|
||||
|
||||
if (orders.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="9" class="text-center text-muted py-3">Nicio comanda</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="10" class="text-center text-muted py-3">Nicio comanda</td></tr>';
|
||||
} else {
|
||||
tbody.innerHTML = orders.map(o => {
|
||||
const dateStr = fmtDate(o.order_date);
|
||||
@@ -375,7 +375,8 @@ async function loadDashOrders() {
|
||||
<td>${o.items_count || 0}</td>
|
||||
<td class="text-end text-muted">${fmtCost(o.delivery_cost)}</td>
|
||||
<td class="text-end text-muted">${fmtCost(o.discount_total)}</td>
|
||||
<td class="text-end fw-bold" style="position:relative">${orderTotal}${(o.status === 'IMPORTED' || o.status === 'ALREADY_IMPORTED') && !(o.invoice && o.invoice.facturat) ? '<span class="row-actions"><button class="btn btn-xs btn-outline-warning" aria-label="Resync comanda" title="Resync" onclick="event.stopPropagation(); dashResyncOrder(\'' + esc(o.order_number) + '\', this)"><i class="bi bi-arrow-repeat"></i></button><button class="btn btn-xs btn-outline-danger" aria-label="Sterge din ROA" title="Sterge din ROA" onclick="event.stopPropagation(); dashDeleteOrder(\'' + esc(o.order_number) + '\', this)"><i class="bi bi-trash"></i></button></span>' : ''}</td>
|
||||
<td class="text-end fw-bold">${orderTotal}</td>
|
||||
<td class="kebab-dropdown" onclick="event.stopPropagation()">${(o.status === 'IMPORTED' || o.status === 'ALREADY_IMPORTED') && !(o.invoice && o.invoice.facturat) ? '<div class="dropdown"><button class="btn btn-sm border-0" aria-label="Actiuni comanda" data-bs-toggle="dropdown"><i class="bi bi-three-dots-vertical"></i></button><ul class="dropdown-menu dropdown-menu-end"><li><button class="dropdown-item" onclick="dashResyncOrder(\'' + esc(o.order_number) + '\', this)"><i class="bi bi-arrow-repeat me-2"></i>Resync</button></li><li><button class="dropdown-item text-danger" onclick="dashDeleteOrder(\'' + esc(o.order_number) + '\', this)"><i class="bi bi-trash me-2"></i>Sterge din ROA</button></li></ul></div>' : ''}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
}
|
||||
@@ -442,7 +443,7 @@ async function loadDashOrders() {
|
||||
});
|
||||
} catch (err) {
|
||||
document.getElementById('dashOrdersBody').innerHTML =
|
||||
`<tr><td colspan="9" class="text-center text-danger">${esc(err.message)}</td></tr>`;
|
||||
`<tr><td colspan="10" class="text-center text-danger">${esc(err.message)}</td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,7 +637,7 @@ function dashDeleteOrder(orderNumber, btn) {
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
b.innerHTML = '<i class="bi bi-check-circle"></i>';
|
||||
b.className = 'btn btn-xs btn-success';
|
||||
b.className = 'btn btn-xs btn-danger';
|
||||
setTimeout(() => loadDashOrders(), 1500);
|
||||
} else {
|
||||
b.innerHTML = '<i class="bi bi-exclamation-triangle"></i>';
|
||||
|
||||
@@ -507,6 +507,10 @@ async function renderOrderDetailModal(orderNumber, opts) {
|
||||
document.getElementById('detailError').style.display = 'none';
|
||||
const retryBtn = document.getElementById('detailRetryBtn');
|
||||
if (retryBtn) { retryBtn.style.display = 'none'; retryBtn.disabled = false; retryBtn.innerHTML = '<i class="bi bi-arrow-clockwise"></i> Reimporta'; retryBtn.className = 'btn btn-sm btn-outline-primary'; }
|
||||
const resyncBtn = document.getElementById('detailResyncBtn');
|
||||
if (resyncBtn) { resyncBtn.style.display = 'none'; resyncBtn.disabled = false; resyncBtn.innerHTML = '<i class="bi bi-arrow-repeat"></i> Resync'; resyncBtn.className = 'btn btn-sm btn-outline-warning'; }
|
||||
const deleteBtn = document.getElementById('detailDeleteBtn');
|
||||
if (deleteBtn) { deleteBtn.style.display = 'none'; deleteBtn.disabled = false; deleteBtn.innerHTML = '<i class="bi bi-trash"></i> Sterge din ROA'; deleteBtn.className = 'btn btn-sm btn-outline-danger'; }
|
||||
const receiptEl = document.getElementById('detailReceipt');
|
||||
if (receiptEl) receiptEl.innerHTML = '';
|
||||
const receiptMEl = document.getElementById('detailReceiptMobile');
|
||||
@@ -840,7 +844,7 @@ async function renderOrderDetailModal(orderNumber, opts) {
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
btn.innerHTML = '<i class="bi bi-check-circle"></i> Sters';
|
||||
btn.className = 'btn btn-sm btn-success';
|
||||
btn.className = 'btn btn-sm btn-danger';
|
||||
setTimeout(() => renderOrderDetailModal(orderNumber, opts), 1500);
|
||||
} else {
|
||||
btn.innerHTML = '<i class="bi bi-exclamation-triangle"></i> ' + (data.message || 'Eroare');
|
||||
|
||||
Reference in New Issue
Block a user