[object Object]

← back to Ffepurchasing

viewer standard: add Grid/List toggle + per-field on/off menu to internal record-grid viewer

e2119b7d7d92433db839223f2f2df171f9ea19ec · 2026-08-12 08:53:18 -0700 · Steve

Files touched

Diff

commit e2119b7d7d92433db839223f2f2df171f9ea19ec
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Aug 12 08:53:18 2026 -0700

    viewer standard: add Grid/List toggle + per-field on/off menu to internal record-grid viewer
---
 public/index.html | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/public/index.html b/public/index.html
index 17a4aef..01a5b95 100644
--- a/public/index.html
+++ b/public/index.html
@@ -192,6 +192,27 @@ table.products .tven { font-size:10px; letter-spacing:0.18em; text-transform:upp
 table.products .tact { padding:6px 12px; background:var(--paper); color:var(--bg); border:0; font-family:inherit; font-size:10px; letter-spacing:0.22em; text-transform:uppercase; font-weight:700; cursor:pointer }
 table.products .tact:hover { background:var(--accent); color:#fff }
 
+/* ===== Fields ▾ popover (admin field toggles) ===== */
+.ffe-fieldmenu { position:relative }
+.ffe-fbtn { background:transparent; border:1px solid var(--line); color:var(--muted); font-family:inherit; font-size:11px; letter-spacing:.22em; text-transform:uppercase; font-weight:700; padding:6px 12px; cursor:pointer; border-radius:2px; white-space:nowrap }
+.ffe-fbtn:hover { border-color:var(--paper); color:var(--paper) }
+.ffe-fpop { position:absolute; top:calc(100% + 8px); left:0; background:var(--bg); border:1px solid var(--line); border-radius:2px; box-shadow:0 14px 34px rgba(16,16,16,.18); padding:8px 4px; z-index:30; min-width:200px }
+html[data-theme="dark"] .ffe-fpop { background:var(--bg-soft) }
+.ffe-fpop[hidden] { display:none }
+.ffe-fpop label { display:flex; align-items:center; gap:10px; padding:7px 14px; font-size:12px; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); cursor:pointer; white-space:nowrap }
+.ffe-fpop label:hover { background:var(--bg-soft); color:var(--paper) }
+.ffe-fpop input { accent-color:var(--accent); margin:0 }
+/* per-field hide rules — card overlay children */
+body.ffehf-pat    .card .pat   { display:none }
+body.ffehf-aes    .card .pat-aes { display:none }
+body.ffehf-sku    .card .trade .row:first-child { display:none }
+body.ffehf-net30  .card .trade .row:nth-child(2) { display:none }
+body.ffehf-moq    .card .trade .row:nth-child(3), body.ffehf-moq .card .trade .moq-soft { display:none }
+body.ffehf-sample .card .actions { display:none }
+/* table view field toggles */
+body.ffehf-sku    table.products .tsku { display:none }
+body.ffehf-net30  table.products .tprice { display:none }
+body.ffehf-moq    table.products .tmoq { display:none }
 /* ===== WCAG 2.4.7 — keyboard focus indicators ===== */
 /* Strictly :focus-visible so mouse clicks do NOT show the ring */
 a:focus-visible,
@@ -489,6 +510,17 @@ textarea:focus-visible,
     <label class="dens-only">Grid</label>
     <input type="range" id="densitySlider" min="4" max="12" step="1" value="6" aria-label="Grid columns">
     <span class="ct" id="densityLabel">6 cols</span>
+    <div class="ffe-fieldmenu">
+      <button class="ffe-fbtn" id="ffe-fieldbtn" aria-haspopup="true" aria-expanded="false">Fields ▾</button>
+      <div class="ffe-fpop" id="ffe-fpop" hidden role="menu">
+        <label><input type="checkbox" data-ffef="pat" checked> Pattern name</label>
+        <label><input type="checkbox" data-ffef="aes" checked> Aesthetic tag</label>
+        <label><input type="checkbox" data-ffef="sku" checked> SKU</label>
+        <label><input type="checkbox" data-ffef="net30" checked> NET30 price</label>
+        <label><input type="checkbox" data-ffef="moq" checked> MOQ</label>
+        <label><input type="checkbox" data-ffef="sample" checked> Sample button</label>
+      </div>
+    </div>
     <div class="search">
       <svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="M21 21l-5.5-5.5"/></svg>
       <input type="text" id="searchInput" placeholder="Search by pattern, color, SKU…" autocomplete="off">
@@ -888,6 +920,31 @@ tb.addEventListener('click', () => setTheme(document.documentElement.dataset.the
 sfReadURL();          // deep-link: hydrate facet/q/sort from the URL before first load
 loadFacets();
 loadGridPage();
+
+// ── FIELDS MENU ───────────────────────────────────────────────────
+const FFE_F_DEF = { pat:true, aes:true, sku:true, net30:true, moq:true, sample:true };
+let FFE_F = Object.assign({}, FFE_F_DEF);
+try { const _s = localStorage.getItem('ffe_fields'); if (_s) FFE_F = Object.assign({}, FFE_F_DEF, JSON.parse(_s)); } catch(_) {}
+function applyFfeFields() {
+  for (const k of Object.keys(FFE_F_DEF)) document.body.classList.toggle('ffehf-'+k, !FFE_F[k]);
+  document.querySelectorAll('#ffe-fpop input[data-ffef]').forEach(cb => { cb.checked = !!FFE_F[cb.dataset.ffef]; });
+  try { localStorage.setItem('ffe_fields', JSON.stringify(FFE_F)); } catch(_) {}
+}
+document.querySelectorAll('#ffe-fpop input[data-ffef]').forEach(cb => {
+  cb.addEventListener('change', () => { FFE_F[cb.dataset.ffef] = cb.checked; applyFfeFields(); });
+});
+applyFfeFields();
+const ffeFBtn = document.getElementById('ffe-fieldbtn');
+const ffeFPop = document.getElementById('ffe-fpop');
+if (ffeFBtn) ffeFBtn.addEventListener('click', e => {
+  e.stopPropagation();
+  const open = ffeFPop.hidden;
+  ffeFPop.hidden = !open;
+  ffeFBtn.setAttribute('aria-expanded', open ? 'true' : 'false');
+});
+document.addEventListener('click', e => {
+  if (!e.target.closest('.ffe-fieldmenu')) { if (ffeFPop) ffeFPop.hidden = true; }
+});
 </script>
 <!-- ============================================================
      DW UNIVERSAL CONTACT MODULE — fashion-house UX

← 57ecf40 fix: take infinite-scroll .loading indicator out of flow (ki  ·  back to Ffepurchasing  ·  auto-data-snapshot: 2026-08-22T11:19:22 (1 data files) — dat 07a1be4 →