Dismissing the required-comment modal no longer looks like a close (#20)
Lint / JS (eslint) (push) Successful in 15s
Lint / PHP requirements (version + extensions) (push) Successful in 41s
Security / PHP Security (semgrep) (push) Successful in 1m8s
Lint / PHP (phpcs PSR-12) (push) Successful in 18s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Successful in 2s
Lint / JS (eslint) (push) Successful in 15s
Lint / PHP requirements (version + extensions) (push) Successful in 41s
Security / PHP Security (semgrep) (push) Successful in 1m8s
Lint / PHP (phpcs PSR-12) (push) Successful in 18s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Successful in 2s
A modal can be dismissed four ways: the ✕ button, Cancel, a backdrop click, or
Escape. base.js handles the last two globally (a document click handler and
registerKey('escape', closeAllModals)), so the status-change modal — which wired
only the two buttons — never learned it had been dismissed. The status dropdown
kept displaying the new status even though update_ticket.php was never called,
so the ticket looked closed with no comment until a reload showed it still open.
The same gap left every dynamically-inserted modal in the DOM when dismissed
that way, so the next open inserted a duplicate id that shadowed the live one.
- base.js closeModal now dispatches a bubbling lt:modalclose event (synced to
web_template as bbec859), and _statusCommentModal treats it as "no comment".
- ticket.js reverts the dropdown on any dismissal, guarded against the re-entry
its own lt.modal.close() would otherwise cause.
- dashboard.js gains openModalWithDismiss() so all seven dynamic modals plus the
generic prompt modal tear down however they are dismissed.
Verified in headless chromium against all four dismissal routes plus a
confirm-with-comment control: 22/22. Against the pre-fix files the same test
fails 6 assertions — backdrop and Escape leave the dropdown on "Closed *" with
an orphaned overlay — so it reproduces the reported behaviour exactly.
This commit is contained in:
@@ -241,6 +241,11 @@
|
||||
trigger.focus();
|
||||
}
|
||||
}
|
||||
// Announce the close so whoever opened the modal can undo optimistic UI or
|
||||
// clean up a dynamically-inserted overlay. A modal can be dismissed four
|
||||
// ways — the ✕ button, a Cancel button, a backdrop click, and Escape — and
|
||||
// the last two are handled globally here, so button-only listeners miss them.
|
||||
el.dispatchEvent(new CustomEvent('lt:modalclose', { bubbles: true }));
|
||||
}
|
||||
|
||||
function closeAllModals() {
|
||||
@@ -2774,6 +2779,9 @@
|
||||
setTimeout(() => { if (modalEl && modalEl.parentNode) modalEl.remove(); }, 300);
|
||||
resolve(value);
|
||||
};
|
||||
// Any dismissal counts as "no comment given", including a backdrop click or
|
||||
// Escape, which close the overlay through the global handlers above.
|
||||
modalEl.addEventListener('lt:modalclose', () => finish(null));
|
||||
modalEl.querySelector('[data-modal-close]').addEventListener('click', () => finish(null));
|
||||
document.getElementById(modalId + '_cancel').addEventListener('click', () => finish(null));
|
||||
document.getElementById(modalId + '_confirm').addEventListener('click', () => {
|
||||
|
||||
Reference in New Issue
Block a user