feat(helpdesk): align module with core list/drawer standards
- add helpdesk module pages, services, settings and tests - standardize debtor list on drawer/grid contracts and robust filter drawer behavior - add helpdesk aside panel navigation and settings visibility provider - switch primary list slug to helpdesk/debitor and remove helpdesk/search compatibility - include required core contract updates for list contracts and detail/drawer integration
This commit is contained in:
@@ -36,6 +36,8 @@ export function initFilterDrawer(options = {}) {
|
||||
const applyBaseLabel = applyButton ? String(applyButton.textContent || '').trim() : '';
|
||||
const openButtonBaseLabels = new WeakMap();
|
||||
const panel = drawer.querySelector('[data-filter-drawer-panel]') || drawer;
|
||||
const originalParent = drawer.parentNode;
|
||||
const originalNextSibling = drawer.nextSibling;
|
||||
|
||||
const cleanupFns = [];
|
||||
const bind = (target, eventName, handler, bindOptions = undefined) => {
|
||||
@@ -47,6 +49,29 @@ export function initFilterDrawer(options = {}) {
|
||||
let lockedScrollY = 0;
|
||||
let lastTrigger = null;
|
||||
|
||||
const ensureDrawerInBody = () => {
|
||||
if (!document.body || !drawer.isConnected || drawer.parentNode === document.body) {
|
||||
return;
|
||||
}
|
||||
document.body.appendChild(drawer);
|
||||
};
|
||||
|
||||
const restoreDrawerPosition = () => {
|
||||
if (!(originalParent instanceof Node) || !drawer.isConnected) {
|
||||
return;
|
||||
}
|
||||
if (!originalParent.isConnected || drawer.parentNode === originalParent) {
|
||||
return;
|
||||
}
|
||||
if (originalNextSibling && originalNextSibling.parentNode === originalParent) {
|
||||
originalParent.insertBefore(drawer, originalNextSibling);
|
||||
return;
|
||||
}
|
||||
originalParent.appendChild(drawer);
|
||||
};
|
||||
|
||||
ensureDrawerInBody();
|
||||
|
||||
if (!drawer.hasAttribute('role')) {
|
||||
drawer.setAttribute('role', 'dialog');
|
||||
}
|
||||
@@ -115,6 +140,9 @@ export function initFilterDrawer(options = {}) {
|
||||
};
|
||||
|
||||
const setOpen = (nextOpen) => {
|
||||
if (nextOpen) {
|
||||
ensureDrawerInBody();
|
||||
}
|
||||
isOpen = nextOpen;
|
||||
drawer.hidden = !nextOpen;
|
||||
drawer.setAttribute('aria-hidden', nextOpen ? 'false' : 'true');
|
||||
@@ -148,6 +176,21 @@ export function initFilterDrawer(options = {}) {
|
||||
focusFirstField();
|
||||
};
|
||||
|
||||
const normalizeForcedClose = () => {
|
||||
if (!isOpen) {
|
||||
return;
|
||||
}
|
||||
isOpen = false;
|
||||
unlockPageScroll();
|
||||
document.body.classList.remove('filter-drawer-open');
|
||||
openButtons.forEach((button) => {
|
||||
button.setAttribute('aria-expanded', 'false');
|
||||
});
|
||||
if (typeof onClose === 'function') {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
const open = (trigger = null) => {
|
||||
if (isOpen) {
|
||||
return;
|
||||
@@ -254,6 +297,23 @@ export function initFilterDrawer(options = {}) {
|
||||
};
|
||||
bind(document, 'keydown', onKeyDown);
|
||||
|
||||
const documentObserver = new MutationObserver(() => {
|
||||
if (!drawer.isConnected || drawer.hidden) {
|
||||
normalizeForcedClose();
|
||||
}
|
||||
});
|
||||
if (document.body) {
|
||||
documentObserver.observe(document.body, { childList: true, subtree: true });
|
||||
cleanupFns.push(() => documentObserver.disconnect());
|
||||
}
|
||||
const drawerAttributeObserver = new MutationObserver(() => {
|
||||
if (drawer.hidden) {
|
||||
normalizeForcedClose();
|
||||
}
|
||||
});
|
||||
drawerAttributeObserver.observe(drawer, { attributes: true, attributeFilter: ['hidden'] });
|
||||
cleanupFns.push(() => drawerAttributeObserver.disconnect());
|
||||
|
||||
const setApplyEnabled = (enabled) => {
|
||||
if (!applyButton) {
|
||||
return;
|
||||
@@ -314,6 +374,9 @@ export function initFilterDrawer(options = {}) {
|
||||
if (isOpen) {
|
||||
close('discard');
|
||||
}
|
||||
unlockPageScroll();
|
||||
document.body.classList.remove('filter-drawer-open');
|
||||
restoreDrawerPosition();
|
||||
delete drawer.dataset.filterDrawerBound;
|
||||
delete drawer._filterDrawerApi;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user