[object Object]

← back to Dw Pitch Followup

Expand sort to all fields incl Invoice total (merch_total); add sort control to One-list view (defaults to invoice-total desc)

53052462bd41ccd86e1e4c5584fd5976a8b143d4 · 2026-07-07 14:46:31 -0700 · Steve Abrams

Files touched

Diff

commit 53052462bd41ccd86e1e4c5584fd5976a8b143d4
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jul 7 14:46:31 2026 -0700

    Expand sort to all fields incl Invoice total (merch_total); add sort control to One-list view (defaults to invoice-total desc)
---
 public/index.html | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/public/index.html b/public/index.html
index ee6ec24..22de530 100644
--- a/public/index.html
+++ b/public/index.html
@@ -131,10 +131,12 @@ const META = {
   list3:{title:'Vendor Memos Overdue', tag:'Vendor Memo', defn:'Sample memos WE requested 8–180 days ago that still have not arrived.'},
 };
 const SORTS = {
-  list1:[['Newest sent','created_at:desc'],['Oldest sent','created_at:asc'],['Company A→Z','company:asc'],['Most samples','ordered:desc']],
-  list2:[['Newest invoiced','created_at:desc'],['Oldest invoiced','created_at:asc'],['Company A→Z','company:asc'],['Most invoices','invoice_count:desc']],
-  list3:[['Most overdue','days_overdue:desc'],['Least overdue','days_overdue:asc'],['Vendor A→Z','vendor:asc'],['Client A→Z','company:asc']],
+  list1:[['Invoice total ↓','merch_total:desc'],['Invoice total ↑','merch_total:asc'],['Newest sent','created_at:desc'],['Oldest sent','created_at:asc'],['Company A→Z','company:asc'],['Email A→Z','email:asc'],['Account #','account:asc'],['Most samples ordered','ordered:desc'],['Most sent','sent:desc'],['Most missing','missing:desc'],['% sent ↓','ratio:desc']],
+  list2:[['Invoice total ↓','merch_total:desc'],['Invoice total ↑','merch_total:asc'],['Newest invoiced','created_at:desc'],['Oldest invoiced','created_at:asc'],['Company A→Z','company:asc'],['Email A→Z','email:asc'],['Account #','account:asc'],['Most invoices','invoice_count:desc'],['Max invoice $ ↓','max_total:desc']],
+  list3:[['Most overdue','days_overdue:desc'],['Least overdue','days_overdue:asc'],['Vendor A→Z','vendor:asc'],['Client A→Z','company:asc'],['SKU A→Z','sku:asc'],['Pattern A→Z','pattern:asc'],['Account #','account:asc']],
 };
+// Flat (One list) view sorts across ALL merged rows — includes invoice total.
+const FLAT_SORTS=[['Invoice total ↓','merch_total:desc'],['Invoice total ↑','merch_total:asc'],['Newest','created_at:desc'],['Oldest','created_at:asc'],['Company A→Z','company:asc'],['Account #','account:asc']];
 let DATA=null;
 const VIEW = {};      // rows per container id
 const RENDERED = {};  // count rendered per container id
@@ -183,7 +185,10 @@ function flatRows(){
   let all=[];
   for(const list of buckets){ for(const r of (DATA[list]||[])) all.push({r,list}); }
   if(q) all = all.filter(x=>JSON.stringify(x.r).toLowerCase().includes(q));
-  all.sort((a,b)=>String(b.r.created_at||'').localeCompare(String(a.r.created_at||'')));
+  const [f,dir]=(LS('sort:flat','merch_total:desc')).split(':');
+  all.sort((a,b)=>{ let x=a.r[f],y=b.r[f];
+    if(f==='merch_total'||typeof x==='number'||typeof y==='number'){ x=+x||0;y=+y||0; return dir==='asc'?x-y:y-x; }
+    x=String(x||'');y=String(y||''); return dir==='asc'?x.localeCompare(y):y.localeCompare(x); });
   return all;
 }
 
@@ -363,8 +368,11 @@ function buildBoard(){
     LISTS.forEach(list=>{ const body=document.getElementById('body-'+list);
       body.addEventListener('scroll',()=>{ if(body.scrollTop+body.clientHeight >= body.scrollHeight-300) renderChunk(list,list); }); });
   } else {
+    const fsaved = LS('sort:flat','merch_total:desc');
+    const fopts = FLAT_SORTS.map(([t,v])=>`<option value="${v}" ${v===fsaved?'selected':''}>${t}</option>`).join('');
     board.innerHTML = `<section class="col">
-      <div class="col-head"><div class="col-title">All correspondence<span class="n" id="n-flat">0</span></div></div>
+      <div class="col-head"><div class="col-title">All correspondence<span class="n" id="n-flat">0</span></div>
+        <select class="col-sort" data-list="flat">${fopts}</select></div>
       <div class="col-body" id="body-flat"></div>
     </section>`;
     const body=document.getElementById('body-flat');
@@ -383,7 +391,11 @@ document.getElementById('layoutSeg').addEventListener('click',e=>{ const b=e.tar
 document.getElementById('bucket').addEventListener('change',e=>{ setLS('bucket',e.target.value); rerenderAll(); });
 document.getElementById('q').addEventListener('input',rerenderAll);
 document.getElementById('board').addEventListener('change',e=>{
-  if(e.target.matches('.col-sort')){ setLS('sort:'+e.target.dataset.list, e.target.value); rerenderContainer(e.target.dataset.list, filterSort(e.target.dataset.list), e.target.dataset.list); return; }
+  if(e.target.matches('.col-sort')){
+    const l=e.target.dataset.list; setLS('sort:'+l, e.target.value);
+    if(l==='flat') rerenderContainer('flat', flatRows(), null);
+    else rerenderContainer(l, filterSort(l), l);
+    return; }
   if(e.target.matches('[data-sel]')){
     const card=e.target.closest('.card'); const list=card.dataset.list; const k=card.dataset.k; const set=selSet(list);
     if(e.target.checked){ set.add(k); card.classList.add('sel'); } else { set.delete(k); card.classList.remove('sel'); }

← e3aa21c Revert invoice links to file-open (skip GotoInvoice deep-lin  ·  back to Dw Pitch Followup  ·  Right-panel detail view (context+last-corresponded on click+ a350bea →