app
Widget Registry
Public Made by Adomby adom
The reviewed registry of widgets renderable from plain markdown on any wiki page
← Commit history
adom-stock: show the wiki's cached numbers first; a refresh link spends a vendor lookup only on request
1 file changed
+13−2
widgets/stock-widget.js+13−2@@ -23,8 +23,19 @@ tr+tr td{border-top:1px solid var(--border)}td.num{font-variant-numeric:tabular- const inline = this.querySelector('script[type="application/json"]'); if (inline) { try { data = JSON.parse(inline.textContent); } catch (e) { err = 'bad inline data'; } } const src = this.getAttribute('src');- if (!data && src) { try { const r = await fetch(src, { credentials: 'include', headers: { 'X-Adom-Widget': 'stock' } }); data = await r.json(); if (!r.ok) err = data && data.error ? data.error : `stock route answered ${r.status}`; } catch (e) { err = 'could not load stock'; } }+ if (!data && src) ({ data, err } = await this.load(src, false));+ // Nothing cached yet: this reader asked, so spend the lookup now.+ if (!err && data && src && data.refresh === 'declined' && !Object.values(data.vendors || {}).some(Boolean)) ({ data, err } = await this.load(src, true)); this.render(data, err);+ this.shadowRoot.addEventListener('click', async (e) => {+ const a = e.target.closest && e.target.closest('a.refresh'); if (!a || !src) return;+ e.preventDefault(); a.textContent = 'checking'; const r = await this.load(src, true); this.render(r.data, r.err);+ });+ }+ // fresh=false reads the wiki's cache only; fresh=true lets the wiki spend a vendor lookup (counted against the daily budget).+ async load(src, fresh) {+ try { const r = await fetch(src, { credentials: 'include', headers: fresh ? { 'X-Adom-Widget': 'stock' } : {} }); const data = await r.json(); return { data, err: r.ok ? null : (data && data.error ? data.error : `stock route answered ${r.status}`) }; }+ catch (e) { return { data: null, err: 'could not load stock' }; } } render(d, err) { const root = this.shadowRoot, wrap = root.querySelector('.wrap'), when = root.querySelector('.when');@@ -40,7 +51,7 @@ tr+tr td{border-top:1px solid var(--border)}td.num{font-variant-numeric:tabular- const link = r.product_url ? `<a href="${esc(r.product_url)}" target="_blank" rel="noopener">open</a>` : ''; return `<tr><td>${esc(label)}<br><span class="pn">${esc(r.part || r.mpn || '')}</span></td><td class="num ${r.stock > 0 ? 'in' : 'out'}">${r.stock > 0 ? num(r.stock) + ' in stock' : 'out of stock'}</td><td class="num">${esc(r.unit_price || '')}</td><td class="num">${esc(r.price_100 || '')}</td><td>${link}</td></tr>`; });- when.textContent = (d.stale ? 'refreshing, ' : '') + ago(d.checked_at);+ when.innerHTML = esc(ago(d.checked_at)) + (d.checked_at ? ' <a class="refresh" href="#" title="Ask the distributors again (counts against the daily lookup budget)">refresh</a>' : ''); body.outerHTML = `<table><thead><tr><th>Distributor</th><th class="num">Stock</th><th class="num">Unit</th><th class="num">At 100</th><th></th></tr></thead><tbody>${rows.join('')}</tbody></table>`; } }