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:
+13
-1
@@ -529,7 +529,19 @@ function updateTicketStatus() {
|
||||
`);
|
||||
const modal = document.getElementById(modalId);
|
||||
lt.modal.open(modalId);
|
||||
const cleanup = (ok) => { lt.modal.close(modalId); setTimeout(() => modal.remove(), 300); if (!ok) statusSelect.selectedIndex = 0; };
|
||||
let settled = false;
|
||||
const cleanup = (ok) => {
|
||||
if (settled) return; // lt.modal.close() below re-enters via lt:modalclose
|
||||
settled = true;
|
||||
lt.modal.close(modalId);
|
||||
setTimeout(() => modal.remove(), 300);
|
||||
if (!ok) statusSelect.selectedIndex = 0;
|
||||
};
|
||||
// Backdrop click and Escape close the overlay through base.js's global
|
||||
// handlers. Without this the dropdown kept displaying the new status
|
||||
// while the server was never called, so the ticket looked closed until
|
||||
// a reload revealed it was still open.
|
||||
modal.addEventListener('lt:modalclose', () => cleanup(false));
|
||||
modal.querySelector('[data-modal-close]').addEventListener('click', () => cleanup(false));
|
||||
document.getElementById(`${modalId}_cancel`).addEventListener('click', () => cleanup(false));
|
||||
document.getElementById(`${modalId}_confirm`).addEventListener('click', () => {
|
||||
|
||||
Reference in New Issue
Block a user