Check select-all, filtered total, deposit slip layout fixes
- Add select-all checkbox to checks table header; checks/unchecks all visible (filtered) rows; supports indeterminate state - Add summary bar below checks toolbar showing count and total amount of filtered checks - Deposit slip: output to full 8.5x11 letter page for trimming - Deposit slip: remove beige left strip fill (white background) - Deposit slip: remove vertical separator between depositor/bank info - Deposit slip: stack bank info below account info instead of side-by-side - Deposit slip: lower date underline position - Deposit slip left strip: flip text orientation to read tilt-left (rotate 90 instead of -90; reposition all strip element anchors) - Deposit slip left strip: center MICR and labels in strip width - Deposit slip total: include decimal point in rotated digit amount
This commit is contained in:
@@ -79,6 +79,14 @@ header {
|
||||
.toolbar-right { display: flex; align-items: center; gap: 8px; }
|
||||
.toolbar label { font-size: 12px; font-weight: 500; color: var(--text-muted); }
|
||||
|
||||
.checks-summary {
|
||||
padding: 3px 12px;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
flex-shrink: 0;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
select {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
|
||||
+3
-1
@@ -45,11 +45,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="checks-summary" class="checks-summary"></div>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table id="checks-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-select"></th>
|
||||
<th class="col-select"><input type="checkbox" id="select-all-checks" title="Select all"></th>
|
||||
<th class="col-no sortable" data-col="check_no"># <span class="sort-indicator"></span></th>
|
||||
<th class="col-date sortable" data-col="check_date">Date <span class="sort-indicator"></span></th>
|
||||
<th class="col-payee sortable" data-col="payee">Payee <span class="sort-indicator"></span></th>
|
||||
|
||||
@@ -97,11 +97,15 @@ function renderTable() {
|
||||
if (checks.length === 0) {
|
||||
tbody.innerHTML = '<tr class="empty-row"><td colspan="8">No checks found.</td></tr>';
|
||||
updateSortIndicators();
|
||||
updateSelectAll();
|
||||
updateChecksSummary();
|
||||
return;
|
||||
}
|
||||
|
||||
tbody.innerHTML = checks.map(renderRow).join('');
|
||||
updateSortIndicators();
|
||||
updateSelectAll();
|
||||
updateChecksSummary();
|
||||
|
||||
// Attach row-level event listeners
|
||||
tbody.querySelectorAll('input[type="checkbox"]').forEach(cb => {
|
||||
@@ -188,6 +192,36 @@ function updateSortIndicators() {
|
||||
});
|
||||
}
|
||||
|
||||
function updateSelectAll() {
|
||||
const selectAll = document.getElementById('select-all-checks');
|
||||
const checks = filteredAndSortedChecks();
|
||||
if (checks.length === 0) {
|
||||
selectAll.checked = false;
|
||||
selectAll.indeterminate = false;
|
||||
return;
|
||||
}
|
||||
const nSelected = checks.filter(c => state.selected.has(c.id)).length;
|
||||
selectAll.indeterminate = nSelected > 0 && nSelected < checks.length;
|
||||
selectAll.checked = nSelected === checks.length;
|
||||
}
|
||||
|
||||
function updateChecksSummary() {
|
||||
const el = document.getElementById('checks-summary');
|
||||
const filtered = filteredAndSortedChecks();
|
||||
const all = state.checks.length;
|
||||
const fmt = n => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(n);
|
||||
|
||||
if (all === 0) { el.textContent = ''; return; }
|
||||
|
||||
const filteredTotal = filtered.reduce((s, c) => s + (parseFloat(c.amount) || 0), 0);
|
||||
const isFiltered = filtered.length < all;
|
||||
if (isFiltered) {
|
||||
el.textContent = `${filtered.length} of ${all} checks · ${fmt(filteredTotal)}`;
|
||||
} else {
|
||||
el.textContent = `${all} check${all !== 1 ? 's' : ''} · ${fmt(filteredTotal)}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function refreshPdfButton() {
|
||||
const n = state.selected.size;
|
||||
@@ -206,6 +240,7 @@ function onCheckboxChange(cb) {
|
||||
state.selected.delete(id);
|
||||
}
|
||||
refreshPdfButton();
|
||||
updateSelectAll();
|
||||
}
|
||||
|
||||
// ── Slide-in panel ───────────────────────────────────────────────────────────
|
||||
@@ -916,6 +951,18 @@ function init() {
|
||||
renderTable();
|
||||
});
|
||||
|
||||
// Select-all checkbox
|
||||
document.getElementById('select-all-checks').addEventListener('change', e => {
|
||||
const checks = filteredAndSortedChecks();
|
||||
if (e.target.checked) {
|
||||
checks.forEach(c => state.selected.add(c.id));
|
||||
} else {
|
||||
checks.forEach(c => state.selected.delete(c.id));
|
||||
}
|
||||
renderTable();
|
||||
refreshPdfButton();
|
||||
});
|
||||
|
||||
// New check
|
||||
document.getElementById('btn-new-check').addEventListener('click', () => openPanel());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user