fix(ui): no-cache static assets (stop stale CSS/JS after deploys); live nav-active sync; breadcrumb sized+themed to match back button
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -101,7 +101,15 @@ export function renderSidebar(root) {
|
||||
)
|
||||
);
|
||||
|
||||
renderSpaceTree(spacesContainer);
|
||||
// Sync the active highlight across ALL nav items (global links + space tree)
|
||||
// to the current hash. navItem only sets active at creation, so without this
|
||||
// the highlight stays stuck on the previously-selected tab until a refresh.
|
||||
function syncActive() {
|
||||
root.querySelectorAll('a.sb-item').forEach(a =>
|
||||
a.classList.toggle('active', a.getAttribute('href') === location.hash));
|
||||
}
|
||||
|
||||
renderSpaceTree(spacesContainer).then(syncActive);
|
||||
|
||||
// Pending-count badge wiring
|
||||
on('pending-count', (n) => {
|
||||
@@ -110,6 +118,10 @@ export function renderSidebar(root) {
|
||||
if (n > 0) inboxItem.appendChild(el('span', { class: 'badge' }, String(n)));
|
||||
});
|
||||
|
||||
// Refresh tree on hashchange (active highlight) and on space creation.
|
||||
window.addEventListener('hashchange', () => renderSpaceTree(spacesContainer));
|
||||
// On navigation: re-render the tree (lazy state) then re-sync the highlight.
|
||||
window.addEventListener('hashchange', async () => {
|
||||
await renderSpaceTree(spacesContainer);
|
||||
syncActive();
|
||||
});
|
||||
syncActive();
|
||||
}
|
||||
|
||||
@@ -166,12 +166,12 @@ button.ghost:hover { color: var(--text); border-color: var(--accent-dim); }
|
||||
.doc-head .back-btn { margin-bottom: 0; }
|
||||
.doc-head .exp-menu { margin-left: auto; }
|
||||
|
||||
/* Breadcrumb: Space › parent › current */
|
||||
.crumbs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px; }
|
||||
/* Breadcrumb: Space › parent › current — sized + themed to sit inline with the back button */
|
||||
.crumbs { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 13px; font-family: var(--font-ui); line-height: 1; }
|
||||
.crumb { color: var(--muted); text-decoration: none; }
|
||||
.crumb:hover { color: var(--accent); }
|
||||
.crumb.current { color: var(--text); }
|
||||
.crumb-sep { color: var(--accent-dim); }
|
||||
.crumb-sep { color: var(--accent-dim); font-size: 14px; }
|
||||
|
||||
/* Export dropdown */
|
||||
.exp-menu { position: relative; }
|
||||
|
||||
@@ -20,7 +20,11 @@ export function createApp() {
|
||||
limit: '10mb',
|
||||
verify: (req, _res, buf) => { req.rawBody = buf; }
|
||||
}));
|
||||
app.use(express.static('public'));
|
||||
// no-cache (not no-store): the browser may cache but must revalidate, so a
|
||||
// deploy's new CSS/JS takes effect immediately instead of serving stale assets.
|
||||
app.use(express.static('public', {
|
||||
setHeaders: (res) => res.setHeader('Cache-Control', 'no-cache')
|
||||
}));
|
||||
|
||||
// /api/ingest/* bypasses agentOrOwner — webhooks authenticate via HMAC
|
||||
// and need access to req.rawBody captured above.
|
||||
|
||||
Reference in New Issue
Block a user