feat: centralize breadcrumbs in topbar and remove history navigation
Move breadcrumb rendering from individual page templates into the core topbar. Each page now sets $breadcrumbs in its action .php file; the topbar renders it automatically via the shared partial. - Remove global back/forward buttons and app-nav-history.js component - Remove Alt+Arrow keyboard shortcuts for history navigation - Render breadcrumb in topbar-left section (replaces button area) - Clean up breadcrumb CSS: context-neutral base (flex, no margin) - Recalculate sticky titlebar offset in details container - Migrate all 41 pages (core + helpdesk, audit, addressbook, api-docs) - Add missing breadcrumbs to addressbook detail view - Update architecture contract tests (nav-history references removed) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,6 @@ import { initFlashAutoDismiss } from './components/app-flash-auto-dismiss.js';
|
||||
import { initPasswordHints } from './components/app-password-hints.js';
|
||||
import { initBadgeCopy } from './components/app-copy-badge.js';
|
||||
import { initMultiSelectComponent } from './components/app-multiselect-init.js';
|
||||
import { initNavHistory } from './components/app-nav-history.js';
|
||||
import { initSidebarToggle } from './components/app-toggle-sidebar.js';
|
||||
import { initAsidePanels } from './components/app-toggle-aside-panels.js';
|
||||
import { initDetailsAsideToggle } from './components/app-toggle-details-aside.js';
|
||||
@@ -177,10 +176,6 @@ const bootRuntime = async () => {
|
||||
scope: 'global',
|
||||
configPath: 'components.multiSelect',
|
||||
});
|
||||
runtime.register('nav-history', initNavHistory, {
|
||||
selector: '[data-app-component="nav-history"]',
|
||||
configPath: 'components.navHistory',
|
||||
});
|
||||
runtime.register('details-state', initDetailsState, {
|
||||
scope: 'global',
|
||||
configPath: 'components.detailsState',
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/**
|
||||
* Browser history integration — handles back/forward navigation state.
|
||||
*/
|
||||
import { isEditableTarget } from '../core/app-form-utils.js';
|
||||
import { resolveHost } from '../core/app-dom.js';
|
||||
|
||||
export function initNavHistory(root = document, options = {}) {
|
||||
const {
|
||||
backSelector = '#global-back',
|
||||
forwardSelector = '#global-forward',
|
||||
} = options;
|
||||
const host = resolveHost(root);
|
||||
const back = host.querySelector(backSelector);
|
||||
const forward = host.querySelector(forwardSelector);
|
||||
if (!back && !forward) {
|
||||
return { destroy: () => {} };
|
||||
}
|
||||
|
||||
const setDisabledState = (link, disabled) => {
|
||||
link.setAttribute('aria-disabled', disabled ? 'true' : 'false');
|
||||
link.classList.toggle('is-disabled', disabled);
|
||||
if (disabled) {
|
||||
link.setAttribute('tabindex', '-1');
|
||||
} else {
|
||||
link.removeAttribute('tabindex');
|
||||
}
|
||||
};
|
||||
|
||||
const updateHistoryButtons = () => {
|
||||
const hasHistory = window.history.length > 1;
|
||||
if (back instanceof HTMLElement) {
|
||||
setDisabledState(back, !hasHistory);
|
||||
}
|
||||
if (forward instanceof HTMLElement) {
|
||||
setDisabledState(forward, !hasHistory);
|
||||
}
|
||||
};
|
||||
|
||||
const onKeyDown = (event) => {
|
||||
if (!event.altKey || event.metaKey || event.ctrlKey) {
|
||||
return;
|
||||
}
|
||||
if (isEditableTarget(event.target)) {
|
||||
return;
|
||||
}
|
||||
if (event.key === 'ArrowLeft') {
|
||||
if (window.history.length > 1) {
|
||||
event.preventDefault();
|
||||
window.history.back();
|
||||
}
|
||||
} else if (event.key === 'ArrowRight') {
|
||||
if (window.history.length > 1) {
|
||||
event.preventDefault();
|
||||
window.history.forward();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', onKeyDown);
|
||||
|
||||
const onBackClick = (event) => {
|
||||
event.preventDefault();
|
||||
if (window.history.length > 1) {
|
||||
window.history.back();
|
||||
}
|
||||
};
|
||||
if (back instanceof HTMLElement) {
|
||||
back.addEventListener('click', onBackClick);
|
||||
}
|
||||
|
||||
const onForwardClick = (event) => {
|
||||
event.preventDefault();
|
||||
if (window.history.length > 1) {
|
||||
window.history.forward();
|
||||
}
|
||||
};
|
||||
if (forward instanceof HTMLElement) {
|
||||
forward.addEventListener('click', onForwardClick);
|
||||
}
|
||||
|
||||
window.addEventListener('popstate', updateHistoryButtons);
|
||||
updateHistoryButtons();
|
||||
|
||||
const destroy = () => {
|
||||
document.removeEventListener('keydown', onKeyDown);
|
||||
if (back instanceof HTMLElement) {
|
||||
back.removeEventListener('click', onBackClick);
|
||||
}
|
||||
if (forward instanceof HTMLElement) {
|
||||
forward.removeEventListener('click', onForwardClick);
|
||||
}
|
||||
window.removeEventListener('popstate', updateHistoryButtons);
|
||||
};
|
||||
|
||||
return { destroy, update: updateHistoryButtons };
|
||||
}
|
||||
Reference in New Issue
Block a user