← back to Commercialrealestate
CRCP rent-rolls.html: add compact List view (Table/List/Cards)
ca33199d881ff250c9ea32b0b4c941b4492d67b1 · 2026-08-18 21:04:16 -0700 · Steve Abrams
Files touched
Diff
commit ca33199d881ff250c9ea32b0b4c941b4492d67b1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Aug 18 21:04:16 2026 -0700
CRCP rent-rolls.html: add compact List view (Table/List/Cards)
---
public/rent-rolls.html | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/public/rent-rolls.html b/public/rent-rolls.html
index 4c67d50..d66d47d 100644
--- a/public/rent-rolls.html
+++ b/public/rent-rolls.html
@@ -114,6 +114,14 @@
#modal{width:min(760px,96vw);position:relative;padding:0;}
#modal .x{position:absolute;top:12px;right:14px;background:none;border:0;color:var(--muted);font-size:22px;cursor:pointer;z-index:2;}
.hide{display:none;}
+/* compact List view (3rd view alongside Table + Cards) */
+.lst{padding:8px 0 40px;display:flex;flex-direction:column;}
+.lrow{display:flex;align-items:baseline;gap:16px;flex-wrap:wrap;padding:10px 16px;border-bottom:1px solid var(--line,rgba(255,255,255,.08));cursor:pointer;}
+.lrow:hover{background:var(--hover,rgba(120,160,255,.06));}
+.lnm{font-weight:700;min-width:200px;flex:0 0 auto;color:var(--ink,#e6edf3);}
+.lmeta{display:flex;flex-wrap:wrap;gap:5px 16px;flex:1 1 320px;min-width:0;}
+.lm{font-size:12.5px;white-space:nowrap;color:var(--ink,#e6edf3);}
+.lk{color:var(--mut,#8b949e);font-size:10px;text-transform:uppercase;letter-spacing:.5px;margin-right:5px;}
</style>
<link rel="stylesheet" href="/nav-agent/nav-agent.css"><!-- nav-agent -->
<link rel="stylesheet" href="/crcp-theme.css"><!-- CRCP day/night tokens: load LAST so html[data-theme] wins -->
@@ -127,7 +135,7 @@
<div class="toolbar" id="toolbar" style="display:none">
<input class="search" id="q" type="text" placeholder="search all fields — address, city, zip, source, units, NOI, rent… (space = AND)">
- <div class="toggle" id="view"><button data-v="table" class="on">▦ Table</button><button data-v="cards">▤ Cards</button></div>
+ <div class="toggle" id="view"><button data-v="table" class="on">▦ Table</button><button data-v="list">☰ List</button><button data-v="cards">▤ Cards</button></div>
<select id="sortsel" title="Sort rent rolls"></select>
<label class="dens" title="Card density — columns in Cards view">▦ <input type="range" id="cols" min="1" max="4" step="1" value="1"></label>
<div class="coldrop" id="coldrop">
@@ -138,6 +146,7 @@
</div>
<div id="tableView" class="tblwrap hide"><table class="g" data-no-sort><thead id="thead"></thead><tbody id="tbody"></tbody></table></div>
+ <div id="listView" class="lst hide"></div>
<div id="rolls"></div>
</div>
@@ -312,8 +321,9 @@ function filtered(){
function syncDensVis(){ const d=document.querySelector('.dens'); if(d) d.classList.toggle('hide', view!=='cards'); }
function render(){
syncDensVis();
+ const lv=$('#listView');
if(view==='table'){
- $('#tableView').classList.remove('hide'); $('#rolls').classList.add('hide');
+ $('#tableView').classList.remove('hide'); $('#rolls').classList.add('hide'); if(lv) lv.classList.add('hide');
const rows=filtered(); const cols=visCols();
$('#count').textContent=`${rows.length} of ${DATA.length} rent rolls`;
$('#thead').innerHTML='<tr>'+cols.map(c=>`<th data-k="${c.k}" draggable="true" title="Drag to reorder · click to sort" class="dragcol${sortKey===c.k?(sortDir>0?' asc':' desc'):''}">${esc(c.l)}</th>`).join('')+'</tr>';
@@ -321,8 +331,13 @@ function render(){
const csig=cols.map(c=>c.k).join(',');
if(csig!==lastColSig){ lastColSig=csig; reinitResize(); }
else if(window.ColResize && window.ColResize.reattach){ window.ColResize.reattach(document.querySelector('#tableView table.g')); } // resize handles survive sort/search re-render (TK-10089)
+ } else if(view==='list' && lv){
+ $('#tableView').classList.add('hide'); $('#rolls').classList.add('hide'); lv.classList.remove('hide');
+ const rows=filtered(); const cols=visCols();
+ $('#count').textContent=`${rows.length} of ${DATA.length} rent rolls`;
+ lv.innerHTML=rows.map(r=>`<div class="lrow rrow" data-id="${r.id}" style="cursor:pointer"><div class="lnm">${cell(r,cols[0])}</div><div class="lmeta">`+cols.slice(1).map(c=>`<span class="lm"><span class="lk">${esc(c.l)}</span>${cell(r,c)}</span>`).join('')+`</div></div>`).join('');
} else {
- $('#tableView').classList.add('hide'); $('#rolls').classList.remove('hide');
+ $('#tableView').classList.add('hide'); $('#rolls').classList.remove('hide'); if(lv) lv.classList.add('hide');
const rows=filtered();
$('#count').textContent=`${rows.length} of ${DATA.length} rent rolls`;
$('#rolls').innerHTML=rows.map((r,idx)=>rollHtml(r.__raw,idx)).join('');
@@ -429,7 +444,7 @@ fetch('/api/rent-rolls').then(r=>r.json()).then(d=>{
DATA=rolls.map(flatRow);
$('#sub').textContent=`${rolls.length} rent roll${rolls.length>1?'s':''} · document-grade NOI → DSCR · local · $0`;
// restore saved view + sort prefs
- const pv=localStorage.getItem('rentView'); if(pv==='grid'||pv==='table'||pv==='cards'){ view=(pv==='grid'?'cards':pv); }
+ const pv=localStorage.getItem('rentView'); if(pv==='grid'||pv==='table'||pv==='cards'||pv==='list'){ view=(pv==='grid'?'cards':pv); }
const sk=localStorage.getItem('rentSortKey'), sd=localStorage.getItem('rentSortDir');
if(sk&&COLS.some(c=>c.k===sk))sortKey=sk; if(sd==='1'||sd==='-1')sortDir=+sd;
buildSortSel(); buildColMenu();
← d5a0b83 crcp-theme: theme fleet custom SURFACE vars (--panel/--panel
·
back to Commercialrealestate
·
CRCP: generic BuildOut scraper (class-cracker) + auto-discov 284092d →