Redesign BP tracker with lightweight views and unobtrusive save confirmations

This commit is contained in:
Peter Stockings
2026-09-08 15:07:57 +10:00
parent 25d1774e53
commit 87b60aac9b
40 changed files with 2693 additions and 2553 deletions
+23 -68
View File
@@ -1,68 +1,23 @@
document.addEventListener('click', async (e) => {
const link = e.target.closest('a');
if (!link) return;
const url = link.getAttribute('href');
if (!url || url.startsWith('#') || url.startsWith('javascript:')) return;
// Only intercept same-origin links
if (link.origin !== window.location.origin) return;
// Ignore links that open in a new tab, download, or modifier keys
if (link.target === '_blank' || link.hasAttribute('download')) return;
if (e.ctrlKey || e.shiftKey || e.metaKey || e.altKey) return;
// Optional: add a "data-turbo='false'" attribute check to disable it on specific links
if (link.getAttribute('data-turbo') === 'false') return;
e.preventDefault();
document.body.style.cursor = 'wait';
try {
const response = await fetch(url);
if (!response.ok) throw new Error('Fetch failed');
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
document.title = doc.title;
document.body.innerHTML = doc.body.innerHTML;
// Carry over classes on the body if they changed
document.body.className = doc.body.className;
document.body.style.cursor = 'default';
window.history.pushState({}, '', url);
window.scrollTo(0, 0);
// Dispatch a custom event so other scripts can re-initialize if necessary
document.dispatchEvent(new Event('diy-turbo:load'));
} catch (error) {
console.error('DIY Turbo navigation error:', error);
window.location.href = url; // fallback
}
});
window.addEventListener('popstate', async () => {
document.body.style.cursor = 'wait';
try {
const response = await fetch(window.location.href);
if (!response.ok) throw new Error('Fetch failed');
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
document.title = doc.title;
document.body.innerHTML = doc.body.innerHTML;
document.body.className = doc.body.className;
document.body.style.cursor = 'default';
document.dispatchEvent(new Event('diy-turbo:load'));
} catch (error) {
console.error('DIY Turbo popstate error:', error);
window.location.reload(); // fallback
}
});
// Core flows use native links and forms. These enhancements are optional.
document.addEventListener('click', (event) => {
const close = event.target.closest('[data-dismiss]');
if (close) {
const notice = close.closest('.notice');
const next = document.querySelector('.add-action, .entry-form input:not([type=hidden]), #main');
notice.remove();
next?.focus();
}
if (event.target.closest('[data-print]')) window.print();
document.querySelectorAll('.account-menu[open]').forEach((menu) => {
if (!menu.contains(event.target)) menu.open = false;
});
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
document.querySelectorAll('.account-menu[open]').forEach((menu) => {
menu.open = false;
menu.querySelector('summary').focus();
});
}
});
document.querySelectorAll('[data-print]').forEach((button) => { button.hidden = false; });
+1 -1
View File
@@ -1 +1 @@
document.addEventListener("click",async t=>{const e=t.target.closest("a");if(!e)return;const o=e.getAttribute("href");if(o&&!o.startsWith("#")&&!o.startsWith("javascript:")&&e.origin===window.location.origin&&!("_blank"===e.target||e.hasAttribute("download")||t.ctrlKey||t.shiftKey||t.metaKey||t.altKey||"false"===e.getAttribute("data-turbo"))){t.preventDefault(),document.body.style.cursor="wait";try{const t=await fetch(o);if(!t.ok)throw new Error("Fetch failed");const e=await t.text(),r=(new DOMParser).parseFromString(e,"text/html");document.title=r.title,document.body.innerHTML=r.body.innerHTML,document.body.className=r.body.className,document.body.style.cursor="default",window.history.pushState({},"",o),window.scrollTo(0,0),document.dispatchEvent(new Event("diy-turbo:load"))}catch(t){console.error("DIY Turbo navigation error:",t),window.location.href=o}}}),window.addEventListener("popstate",async()=>{document.body.style.cursor="wait";try{const t=await fetch(window.location.href);if(!t.ok)throw new Error("Fetch failed");const e=await t.text(),o=(new DOMParser).parseFromString(e,"text/html");document.title=o.title,document.body.innerHTML=o.body.innerHTML,document.body.className=o.body.className,document.body.style.cursor="default",document.dispatchEvent(new Event("diy-turbo:load"))}catch(t){console.error("DIY Turbo popstate error:",t),window.location.reload()}});
document.addEventListener("click",e=>{const t=e.target.closest("[data-dismiss]");if(t){const e=t.closest(".notice"),n=document.querySelector(".add-action, .entry-form input:not([type=hidden]), #main");e.remove(),n?.focus()}e.target.closest("[data-print]")&&window.print(),document.querySelectorAll(".account-menu[open]").forEach(t=>{t.contains(e.target)||(t.open=!1)})}),document.addEventListener("keydown",e=>{"Escape"===e.key&&document.querySelectorAll(".account-menu[open]").forEach(e=>{e.open=!1,e.querySelector("summary").focus()})}),document.querySelectorAll("[data-print]").forEach(e=>{e.hidden=!1});