Files
meetletacbfree/amd/src/settings_registration.js
T
mrxzamani be252e49e2 Address Moodle Marketplace review for mod_meetletacbfree 1.1.3.
Migrate legacy ajax/JS to external services and AMD, enable TLS verification, scope admin CSS with RTLCSS-safe rules, and fix README/lang/boilerplate gaps.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-20 12:41:47 +03:30

337 lines
12 KiB
JavaScript

// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @module mod_meetletacbfree/settings_registration
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['core/ajax', 'mod_meetletacbfree/meetlet_modal_scroll'], function(Ajax, MeetletModalScroll) {
'use strict';
function byId(id) {
return document.getElementById(id);
}
function setFlash(el, ok, message) {
if (!el) {
return;
}
el.className = 'alert mt-3 ' + (ok ? 'alert-success' : 'alert-danger');
el.textContent = message || '';
el.classList.toggle('d-none', !message);
}
function setActiveUi(active) {
var inactive = byId('meetlet-registration-actions-inactive');
var activeEl = byId('meetlet-registration-actions-active');
var product = byId('meetlet-registration-product');
if (inactive) {
inactive.classList.toggle('d-none', !!active);
}
if (activeEl) {
activeEl.classList.toggle('d-none', !active);
}
if (product) {
product.classList.toggle('d-none', !active);
}
}
function renderSummary(summary) {
if (!summary) {
return;
}
var badge = byId('meetlet-registration-status-badge');
var cfg = byId('meetlet-registration-config');
if (badge) {
badge.className = 'badge meetlet-license-badge '
+ (summary.active ? 'meetlet-license-badge--active' : 'meetlet-license-badge--inactive');
badge.textContent = summary.status_label
|| (summary.active
? (cfg && cfg.dataset.labelActive) || 'Active'
: (cfg && cfg.dataset.labelInactive) || 'Inactive');
}
var domain = byId('meetlet-registration-domain');
if (domain && cfg && cfg.dataset.labelDomain) {
domain.textContent = cfg.dataset.labelDomain.replace('__V__', summary.domain || '—');
}
var installation = byId('meetlet-registration-installation');
if (installation && cfg && cfg.dataset.labelInstallation) {
installation.textContent = cfg.dataset.labelInstallation.replace('__V__', summary.installation_id || '—');
}
var product = byId('meetlet-registration-product');
if (product) {
product.textContent = summary.product_label || '';
}
var err = byId('meetlet-registration-error');
if (err) {
if (summary.error) {
err.textContent = summary.error;
err.classList.remove('d-none');
} else {
err.textContent = '';
err.classList.add('d-none');
}
}
setActiveUi(!!summary.active);
}
function currentApiUrl(cfg) {
var input = cfg && cfg.dataset.apiInput ? document.getElementById(cfg.dataset.apiInput) : null;
if (input && input.value) {
return input.value.trim();
}
return '';
}
var modalState = {
open: false,
resolve: null,
lastFocus: null,
onKey: null,
};
function ensureModalOnBody(modal) {
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
return modal;
}
function modalScroll() {
return MeetletModalScroll;
}
function closeRegistrationModal(result) {
var modal = byId('meetlet-registration-modal');
if (!modal) {
return;
}
modal.setAttribute('hidden', 'hidden');
modal.style.display = 'none';
modalScroll().unlock();
if (modalState.onKey) {
document.removeEventListener('keydown', modalState.onKey, true);
modalState.onKey = null;
}
modalState.open = false;
var resolve = modalState.resolve;
modalState.resolve = null;
if (modalState.lastFocus) {
modalScroll().focusNoScroll(modalState.lastFocus);
}
modalState.lastFocus = null;
if (typeof resolve === 'function') {
resolve(!!result);
}
}
function openRegistrationModal(opts) {
var modal = ensureModalOnBody(byId('meetlet-registration-modal'));
var cfg = byId('meetlet-registration-config');
if (!modal) {
return Promise.resolve(false);
}
if (modalState.open) {
closeRegistrationModal(false);
}
var title = byId('meetlet-registration-modal-title');
var body = byId('meetlet-registration-modal-body');
var confirmBtn = byId('meetlet-registration-modal-confirm');
var tpl = opts.templateId ? document.getElementById(opts.templateId) : null;
if (!title || !body || !confirmBtn) {
return Promise.resolve(false);
}
title.textContent = opts.title || '';
if (tpl) {
body.innerHTML = '';
if (tpl.content && tpl.content.cloneNode) {
body.appendChild(tpl.content.cloneNode(true));
} else {
body.innerHTML = tpl.innerHTML;
}
} else {
body.innerHTML = '';
}
confirmBtn.textContent = opts.confirmLabel || '';
confirmBtn.className = 'btn ' + (opts.danger ? 'btn-outline-danger' : 'btn-primary');
modalState.lastFocus = document.activeElement;
modalScroll().lock();
modal.removeAttribute('hidden');
modal.style.display = 'flex';
modalState.open = true;
modalState.onKey = function (e) {
if (!modalState.open) {
return;
}
if (e.key === 'Escape') {
e.preventDefault();
e.stopPropagation();
closeRegistrationModal(false);
return;
}
if (e.key !== 'Tab') {
return;
}
var focusable = modal.querySelectorAll(
'button:not([disabled]), [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
if (!focusable.length) {
return;
}
var first = focusable[0];
var last = focusable[focusable.length - 1];
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
modalScroll().focusNoScroll(last);
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
modalScroll().focusNoScroll(first);
}
};
document.addEventListener('keydown', modalState.onKey, true);
window.setTimeout(function () {
modalScroll().focusNoScroll(confirmBtn);
}, 20);
return new Promise(function (resolve) {
modalState.resolve = resolve;
});
}
function postAction(action) {
var cfg = byId('meetlet-registration-config');
var flash = byId('meetlet-registration-flash');
if (!cfg) {
return;
}
setFlash(flash, true, '…');
Ajax.call([{
methodname: 'mod_meetletacbfree_registration_action',
args: {
action: action,
registration_api_url: currentApiUrl(cfg)
}
}])[0].then(function(data) {
data.summary = {
active: !!data.active,
status: data.status,
status_label: data.status_label,
product_label: data.product_label,
domain: data.domain,
installation_id: data.installation_id,
can_deactivate: !!data.can_deactivate
};
if (data.summary) {
renderSummary(data.summary);
}
if (data.success) {
setFlash(flash, true, data.message);
if (action === 'activate' || action === 'deactivate') {
window.setTimeout(function() {
window.location.reload();
}, 600);
}
} else {
setFlash(flash, false, data.error || 'Request failed');
}
}).catch(function(err) {
setFlash(flash, false, err && err.message ? err.message : 'Request failed');
});
}
function bindModalChrome() {
var modal = byId('meetlet-registration-modal');
if (!modal || modal.dataset.bound === '1') {
return;
}
modal.dataset.bound = '1';
modal.addEventListener('click', function (e) {
if (e.target.closest('[data-meetlet-modal-dismiss]')) {
e.preventDefault();
closeRegistrationModal(false);
}
});
var confirmBtn = byId('meetlet-registration-modal-confirm');
if (confirmBtn) {
confirmBtn.addEventListener('click', function (e) {
e.preventDefault();
closeRegistrationModal(true);
});
}
}
function bindDeactivateButton(btn) {
if (!btn || btn.dataset.bound === '1') {
return;
}
var cfg = byId('meetlet-registration-config');
btn.dataset.bound = '1';
btn.addEventListener('click', function () {
openRegistrationModal({
title: (cfg && cfg.dataset.confirmDeactivateTitle) || '',
templateId: 'meetlet-registration-tpl-deactivate',
confirmLabel: (cfg && cfg.dataset.confirmDeactivateOk) || '',
danger: true,
}).then(function (ok) {
if (ok) {
postAction('deactivate');
}
});
});
}
function bind() {
var activate = byId('meetlet-registration-activate');
var recheck = byId('meetlet-registration-recheck');
var deactivate = byId('meetlet-registration-deactivate');
var cfg = byId('meetlet-registration-config');
if ((!activate && !recheck) || (activate && activate.dataset.bound === '1')) {
return;
}
bindModalChrome();
if (activate) {
activate.dataset.bound = '1';
activate.addEventListener('click', function () {
openRegistrationModal({
title: (cfg && cfg.dataset.confirmActivateTitle) || '',
templateId: 'meetlet-registration-tpl-activate',
confirmLabel: (cfg && cfg.dataset.confirmActivateOk) || '',
danger: false,
}).then(function (ok) {
if (ok) {
postAction('activate');
}
});
});
}
if (recheck) {
recheck.dataset.bound = '1';
recheck.addEventListener('click', function () {
postAction('recheck');
});
}
bindDeactivateButton(deactivate);
}
return {init: bind};
});