Files
nextcloud/php/public/desec-modal.js
T
Simon L. 454905c852 feat(desec): run registration flow in a modal iframe
Move the deSEC "register a free domain" flow out of the inline containers
page form and into a modal backed by a dedicated /desec view loaded in an
iframe. The multi-step register -> verify -> domain process now re-renders
inside the modal, so the user can adjust the details and complete email
verification without reloading the whole page each step. Only once the
domain is fully registered does the view reload the parent containers page.

- add /desec route + desec.twig standalone view
- add desec-modal.js (open/close, backdrop + Escape) and desec-done.js
  (parent reload on completion)
- redirect register POST to the /desec view so steps stay in the modal
- drop the redundant <details> wrapper in desec-register.twig, add heading
- style the modal and let <button class="button"> pick up button styles
- drive the modal iframe in the Playwright specs and update the QA checklist

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-06-22 13:24:50 +02:00

51 lines
1.8 KiB
JavaScript

"use strict";
// Opens the deSEC registration flow (the /desec view) inside a modal iframe so the user can
// run the multi-step register -> verify -> domain process without leaving the containers
// page. The iframe re-navigates itself between steps; once a domain is registered, the
// /desec view reloads the parent window via desec-done.js, so this script only has to deal
// with opening and closing the modal.
(function () {
const modal = document.getElementById('desec-modal');
const frame = document.getElementById('desec-frame');
if (!modal || !frame) {
return;
}
function openModal() {
// Load (or reload) the flow each time the modal is opened so it always reflects the
// current registration state on the server.
frame.src = 'desec';
modal.hidden = false;
document.body.classList.add('modal-open');
}
function closeModal() {
modal.hidden = true;
document.body.classList.remove('modal-open');
// Drop the iframe content so credentials are not left rendered in the background.
frame.src = 'about:blank';
}
document.querySelectorAll('[data-desec-open]').forEach((el) => {
el.addEventListener('click', openModal);
});
document.querySelectorAll('[data-desec-close]').forEach((el) => {
el.addEventListener('click', closeModal);
});
// Close when clicking the dimmed backdrop (but not when clicking inside the dialog).
modal.addEventListener('click', (event) => {
if (event.target === modal) {
closeModal();
}
});
// Close on Escape for keyboard users.
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape' && !modal.hidden) {
closeModal();
}
});
})();