← back to Commercialrealestate
CRCP list view: add Broker phone column + relabel agent phone
838f589edf6e420a83ce7feeab982f1d8fb6e367 · 2026-08-25 11:04:59 -0700 · Steve
Adds a 'Broker phone' field (firm/broker-of-record line) alongside the
existing agent phone, both as list columns. Resolver prefers the resolved
usre firm_phone, then broker-history current_broker.phone, then the raw
broker_phone, then a firm-tier agent line. Relabels the existing 'phone'
field 'Agent phone' for clarity; both are ALWAYS_ON. List/table only
(card view already shows broker phone via the Current-broker line).
Files touched
Diff
commit 838f589edf6e420a83ce7feeab982f1d8fb6e367
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Aug 25 11:04:59 2026 -0700
CRCP list view: add Broker phone column + relabel agent phone
Adds a 'Broker phone' field (firm/broker-of-record line) alongside the
existing agent phone, both as list columns. Resolver prefers the resolved
usre firm_phone, then broker-history current_broker.phone, then the raw
broker_phone, then a firm-tier agent line. Relabels the existing 'phone'
field 'Agent phone' for clarity; both are ALWAYS_ON. List/table only
(card view already shows broker phone via the Current-broker line).
---
public/index.html | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/public/index.html b/public/index.html
index 24593b4..596b7a9 100644
--- a/public/index.html
+++ b/public/index.html
@@ -866,7 +866,7 @@ const FIELDS = [
{k:'score', label:'Investment score', card:1, col:1, def:1},
{k:'deal', label:'Deal score', card:1, col:1, def:1},
{k:'agent', label:'Agent · contact', card:1, col:1, def:1},
- {k:'phone', label:'Phone', card:1, col:1, def:1},
+ {k:'phone', label:'Agent phone', card:1, col:1, def:1},
{k:'email', label:'Email', card:1, col:1, def:0},
{k:'firmweb', label:'Firm website', card:1, col:1, def:0},
{k:'firm', label:'Listing firm', card:1, col:1, def:1},
@@ -889,6 +889,7 @@ const FIELDS = [
{k:'brokerflag', label:'Prior-broker flag', card:1, col:0, def:1},
{k:'txhist', label:'Transaction history',card:1,col:0, def:0},
{k:'brokerline', label:'Current broker', card:1, col:1, def:1},
+ {k:'brokerPhone',label:'Broker phone', card:0, col:1, def:1},
{k:'coc', label:'Cash-on-cash', card:1, col:1, def:1},
{k:'dscr', label:'DSCR', card:1, col:1, def:1},
{k:'noi', label:'Est. NOI', card:1, col:1, def:1},
@@ -914,7 +915,7 @@ const FIELDS = [
];
// Steve (2026-08-20): ALWAYS show agent · contact, phone, listing firm, current broker — never hideable,
// override any persisted localStorage off-state (a prior toggle-off used to hide them forever despite def:1).
-const ALWAYS_ON = ['agent','phone','firm','brokerline','broker'];
+const ALWAYS_ON = ['agent','phone','brokerPhone','firm','brokerline','broker'];
const VIS = (function(){ let s={}; try{ s=JSON.parse(localStorage.getItem('cre_fields')||'{}'); }catch(e){} const o={}; FIELDS.forEach(f=>o[f.k]=ALWAYS_ON.includes(f.k)?true:((f.k in s)?!!s[f.k]:!!f.def)); return o; })();
function vis(k){ return !!VIS[k]; }
function saveVis(){ ALWAYS_ON.forEach(k=>VIS[k]=true); try{ localStorage.setItem('cre_fields', JSON.stringify(VIS)); }catch(e){} }
@@ -1040,6 +1041,8 @@ function colCell(k,p){ const f=p.finance||{};
const tier=a.phoneTier==='firm'?' <span class="tierb" title="Firm branch line'+(a.phoneCity?' — '+esc(a.phoneCity)+' office':'')+'">firm</span>':'';
return `<span class="ain"><a href="${telHref(a.phone)}" title="Call ${esc(a.phone)}">📞 ${esc(a.phone)}</a>${tier} <button class="copyb" data-copyval="${esc(a.phone)}" title="Copy phone">⧉</button></span>`; }
case 'email': { const a=agentInfo(p); return a.email?`<span class="ain"><a href="mailto:${esc(a.email)}" title="Email ${esc(a.email)}">✉ ${esc(a.email)}</a> <button class="copyb" data-copyval="${esc(a.email)}" title="Copy email">⧉</button></span>`:'—'; }
+ case 'brokerPhone': { const bp=brokerPhoneOf(p); if(!bp) return '—';
+ return `<span class="ain"><a href="${telHref(bp)}" title="Call broker ${esc(bp)}">📞 ${esc(bp)}</a> <button class="copyb" data-copyval="${esc(bp)}" title="Copy broker phone">⧉</button></span>`; }
case 'firmweb': { const a=agentInfo(p); const w=a.firmWebsite; if(!w) return '—';
const disp=String(w).replace(/^https?:\/\//,'').replace(/\/$/,''); const href=/^https?:\/\//.test(w)?w:'https://'+w;
return `<a class="ain" href="${esc(href)}" target="_blank" rel="noopener noreferrer" title="Open the listing firm’s website">🔗 ${esc(disp)}</a>`; }
@@ -1111,6 +1114,7 @@ function fieldVal(p,k){ const f=p.finance||{};
case 'addr': return p.address; case 'score': return p.composite; case 'deal': return p.deal&&p.deal.score;
case 'agent': { const a=agentInfo(p); return a.name||('~'); } // contactless rows sort last (~ > letters)
case 'phone': { const a=agentInfo(p); return a.phone||'~'; } // rows without a resolved phone sort last
+ case 'brokerPhone': { const bp=brokerPhoneOf(p); return bp||'~'; }
case 'email': { const a=agentInfo(p); return a.email||'~'; }
case 'firmweb': { const a=agentInfo(p); return a.firmWebsite||'~'; }
case 'firm': return firmLabel(p); case 'type': return p.type; case 'units': return p.units; case 'price': return p.price;
@@ -1298,6 +1302,18 @@ function agentInfo(p){
firmWebsite:rv.firm_website||'', firmPhone:(rv.firm_phone && !isNat(rv.firm_phone))?rv.firm_phone:'', firmAddress:rv.firm_address||'',
contacted_at:c.contacted_at||null, notes:c.notes||'', letters:(c.letters||[]) };
}
+// Broker (listing broker of record) phone — the enriched current-broker line, distinct from the
+// agent/contact phone in agentInfo (which folds in the scraped row's broker_phone). Steve 2026-08-25:
+// "add broker and agent phone numbers to the fields."
+function brokerPhoneOf(p){
+ const a=agentInfo(p);
+ const bh=window.BROKER_HIST[p.id]||window.BROKER_HIST_ADDR[(p.address||'').toLowerCase().trim()];
+ const chist=(bh&&bh.current_broker&&bh.current_broker.phone)||'';
+ // Prefer a DISTINCT firm/broker-of-record line (resolved usre firm_phone or broker-history), then the
+ // raw row, then — if the agent's own resolved line IS a firm/branch line — use that (it's the broker
+ // office number). Keeps "Broker phone" the firm-of-record line, distinct from the agent-direct phone.
+ return a.firmPhone || chist || p.broker_phone || (a.phoneTier==='firm' ? a.phone : '') || '';
+}
function gsearch(q){ return 'https://www.google.com/search?q='+encodeURIComponent(q); } // retained; no longer linked out
function safeUrl(u){ u=String(u==null?'':u); return /^https?:\/\//i.test(u)?u:'#'; }
// "↗ View property" — a link OUT to the real listing on whichever service it's on (Crexi / LoopNet /
← f700567 auto-data-snapshot: 2026-08-25T09:32:22 (2 data files) — dat
·
back to Commercialrealestate
·
chore: v0.24.0 (session close) — broker-phone list column [l 71519a5 →