← back to Nationalrealestate
nav-agent: v1.1 merge-mode asset refresh
27b936f85e3e95e8467989ab20576bc5f1d3f4e7 · 2026-08-13 08:18:48 -0700 · Steve Abrams
Files touched
M public/nav-agent/nav-agent.cssM public/nav-agent/nav-agent.js
Diff
commit 27b936f85e3e95e8467989ab20576bc5f1d3f4e7
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Aug 13 08:18:48 2026 -0700
nav-agent: v1.1 merge-mode asset refresh
---
public/nav-agent/nav-agent.css | 7 ++++++
public/nav-agent/nav-agent.js | 51 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/public/nav-agent/nav-agent.css b/public/nav-agent/nav-agent.css
index 702094c..844d787 100644
--- a/public/nav-agent/nav-agent.css
+++ b/public/nav-agent/nav-agent.css
@@ -90,4 +90,11 @@ table .na-group-h td{padding:8px 6px;color:var(--na-acc);font-weight:600;border-
border-radius:6px;padding:6px 10px;font-size:12px;cursor:pointer}
.na-restorebar button:hover{border-color:var(--na-acc)}
+/* ---- merged mode: folded INTO an existing house panel ----------------- */
+.na-merge{border-top:1px dashed var(--na-line);margin-top:12px;padding-top:10px}
+.na-merge .na-mh{display:flex;align-items:center;gap:6px;font-weight:600;color:var(--na-acc);
+ text-transform:uppercase;font-size:11px;letter-spacing:.6px;margin-bottom:8px}
+.na-merge .na-row label{color:var(--na-mut);min-width:48px}
+.na-merge select{background:var(--na-bg2);border:1px solid var(--na-line);color:var(--na-fg);border-radius:6px;padding:6px 8px;font-size:13px;flex:1}
+
@media (max-width:640px){.na-panel{width:86vw}}
diff --git a/public/nav-agent/nav-agent.js b/public/nav-agent/nav-agent.js
index 89119e2..991a82f 100644
--- a/public/nav-agent/nav-agent.js
+++ b/public/nav-agent/nav-agent.js
@@ -364,6 +364,47 @@
if (g.removed) { wrap.classList.add('na-removed'); addRestore(); }
}
+ /* -- merged mode: fold into an existing house panel ("2 into 1") ------- */
+ function findHousePanel(target) {
+ var asides = [].slice.call(document.querySelectorAll('aside, .sidebar, .panel-left, [data-house-panel]'));
+ for (var i = 0; i < asides.length; i++) {
+ var a = asides[i];
+ if (a.classList.contains('na-panel')) continue;
+ if (a.contains(target)) continue; // a real control sidebar won't contain the grid
+ if (a.querySelector('input, select, details, .toggle, .chip')) return a; // has controls
+ }
+ return null;
+ }
+
+ function buildMergeSection(agent, house, opt) {
+ var M = agent.model, st = agent.state;
+ var old = house.querySelector('.na-merge'); if (old) old.remove();
+ var box = el('div', 'na-merge');
+ box.appendChild(el('div', 'na-mh', '⚙ Nav Agent'));
+ if (M.fields && M.fields.length) {
+ // sort ANY field (superset of the house's fixed sort options)
+ var srow = el('div', 'na-row', '<label>Sort</label>');
+ var ssel = el('select'); ssel.appendChild(new Option('— none —', ''));
+ M.fields.forEach(function (f) { ssel.appendChild(new Option(f.label, f.key)); });
+ ssel.value = st.sort || ''; srow.appendChild(ssel); box.appendChild(srow);
+ var dir = el('div', 'na-mini', '<button data-asc>▲ Asc</button><button data-desc>▼ Desc</button>');
+ function markDir() { dir.querySelector('[data-asc]').classList.toggle('on', st.dir !== 'desc'); dir.querySelector('[data-desc]').classList.toggle('on', st.dir === 'desc'); }
+ ssel.onchange = function () { st.sort = ssel.value; agent.save(); agent.applySort(); };
+ dir.querySelector('[data-asc]').onclick = function () { st.dir = 'asc'; agent.save(); agent.applySort(); markDir(); };
+ dir.querySelector('[data-desc]').onclick = function () { st.dir = 'desc'; agent.save(); agent.applySort(); markDir(); };
+ markDir(); box.appendChild(dir);
+ // group ANY field
+ var grow = el('div', 'na-row', '<label>Group</label>');
+ var gsel = el('select'); gsel.appendChild(new Option('— none —', ''));
+ M.fields.forEach(function (f) { gsel.appendChild(new Option(f.label, f.key)); });
+ gsel.value = st.group || ''; gsel.onchange = function () { st.group = gsel.value; agent.save(); agent.applyGroup(); };
+ grow.appendChild(gsel); box.appendChild(grow);
+ }
+ box.appendChild(el('div', 'na-note', 'Drag the grid’s ▤ bar to float · ▁ collapse · ⤢ maximize · ✕ remove.'));
+ house.appendChild(box);
+ return box;
+ }
+
/* -- public mount ------------------------------------------------------ */
var API = {
instances: [],
@@ -378,20 +419,24 @@
else target.setAttribute('data-na-sel', target.id ? '#' + target.id : '.' + (target.className.split(/\s+/)[0] || 'grid'));
var agent = Agent(target, opt);
target.__naAgent = agent;
- // (re)build the panel — called again by the observer when fields change
+ // "2 into 1": if the page already has a house control panel, fold into it
+ var house = opt.merge === false ? null : findHousePanel(target);
+ // (re)build the controls — called again by the observer when fields change
function makePanel() {
+ if (house) { agent._merge = buildMergeSection(agent, house, opt); return; }
var wasOpen = agent._panel && agent._panel.classList.contains('open');
if (agent._panel) agent._panel.remove();
agent._panel = buildPanel(agent, opt);
if (wasOpen) agent._panel.classList.add('open');
}
agent.onFields = makePanel;
+ agent.merged = !!house;
makePanel();
chrome(agent, opt);
agent.applyAll();
- // single launcher toggles every panel on the page
- if (!document.querySelector('.na-launch')) {
+ // standalone launcher only when NOT merged into a house panel
+ if (!house && !document.querySelector('.na-launch')) {
var b = el('button', 'na-launch', '⚙'); b.title = 'View controls';
b.onclick = function () {
var anyOpen = document.querySelector('.na-panel.open');
← 7b50153 usre: commercial-feed.html Recorded Activity gets grid/list/
·
back to Nationalrealestate
·
deals/contractors/feed: make every displayed table column so e36e0ec →