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>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# MeetLet Adobe Connect Bridge — Marketplace Edition
|
# MeetLet Adobe Connect Bridge — Marketplace Edition
|
||||||
|
|
||||||
**Component:** `mod_meetletacbfree`
|
**Component:** `mod_meetletacbfree`
|
||||||
**Release:** 1.0.9-marketplace
|
**Release:** 1.1.3
|
||||||
**License:** [GNU GPL v3 or later](COPYING.txt)
|
**License:** [GNU GPL v3 or later](COPYING.txt)
|
||||||
|
|
||||||
Connect Moodle to Adobe Connect for live classes, single sign-on (SSO), recordings, and shared meeting content — without a separate Windows agent or commercial license.
|
Connect Moodle to Adobe Connect for live classes, single sign-on (SSO), recordings, and shared meeting content — without a separate Windows agent or commercial license.
|
||||||
@@ -34,7 +34,7 @@ This edition is free to install and use. It includes the core classroom workflow
|
|||||||
| **Activity defaults** | Site-wide meeting language, wait-for-host, and tab visibility with per-activity overrides |
|
| **Activity defaults** | Site-wide meeting language, wait-for-host, and tab visibility with per-activity overrides |
|
||||||
| **Backup & restore** | Standard Moodle 2 backup API support for course copies and restores |
|
| **Backup & restore** | Standard Moodle 2 backup API support for course copies and restores |
|
||||||
| **Privacy API** | GDPR-ready privacy provider for exported and deleted user data |
|
| **Privacy API** | GDPR-ready privacy provider for exported and deleted user data |
|
||||||
| **Optional site registration** | Transparent opt-in registration with MeetLet for update notices and support statistics (plugin works fully without it) |
|
| **Plugin activation** | Voluntary administrator action with MeetLet; required to unlock meeting features (SSO join, recordings, content, and related tools) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
// 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/>.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ajax endpoint: run one Adobe Connect connection-test step.
|
|
||||||
*
|
|
||||||
* @package mod_meetletacbfree
|
|
||||||
* @copyright 2026 MeetLet
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
define('AJAX_SCRIPT', true);
|
|
||||||
|
|
||||||
require_once('../../../config.php');
|
|
||||||
|
|
||||||
use mod_meetletacbfree\local\conntest_runner;
|
|
||||||
|
|
||||||
require_login();
|
|
||||||
require_capability('moodle/site:config', context_system::instance());
|
|
||||||
require_sesskey();
|
|
||||||
|
|
||||||
\mod_meetletacbfree\registration\manager::require_registered();
|
|
||||||
|
|
||||||
$step = required_param('step', PARAM_ALPHA);
|
|
||||||
$result = conntest_runner::run_step($step);
|
|
||||||
|
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
echo json_encode($result);
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
<?php
|
|
||||||
// This file is part of Moodle - http://moodle.org/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ajax endpoint: activate / recheck / deactivate MeetLet site registration.
|
|
||||||
*
|
|
||||||
* @package mod_meetletacbfree
|
|
||||||
* @copyright 2026 MeetLet
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
define('AJAX_SCRIPT', true);
|
|
||||||
|
|
||||||
require_once('../../../config.php');
|
|
||||||
|
|
||||||
use mod_meetletacbfree\registration\error_mapper;
|
|
||||||
use mod_meetletacbfree\registration\manager;
|
|
||||||
use mod_meetletacbfree\registration\registration_exception;
|
|
||||||
|
|
||||||
require_login();
|
|
||||||
require_capability('moodle/site:config', context_system::instance());
|
|
||||||
require_sesskey();
|
|
||||||
|
|
||||||
$action = required_param('action', PARAM_ALPHA);
|
|
||||||
$apiurl = optional_param('registration_api_url', '', PARAM_URL);
|
|
||||||
|
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
|
|
||||||
try {
|
|
||||||
if ($apiurl !== '') {
|
|
||||||
set_config(manager::CONFIG_API_URL, rtrim($apiurl, '/'), 'meetletacbfree');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($action === 'activate') {
|
|
||||||
manager::activate();
|
|
||||||
echo json_encode([
|
|
||||||
'success' => true,
|
|
||||||
'message' => get_string('registration_activated', 'meetletacbfree'),
|
|
||||||
'summary' => manager::status_summary(),
|
|
||||||
]);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($action === 'recheck' || $action === 'refresh' || $action === 'validate') {
|
|
||||||
manager::recheck(true);
|
|
||||||
echo json_encode([
|
|
||||||
'success' => true,
|
|
||||||
'message' => get_string('registration_rechecked', 'meetletacbfree'),
|
|
||||||
'summary' => manager::status_summary(),
|
|
||||||
]);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($action === 'deactivate') {
|
|
||||||
manager::deactivate();
|
|
||||||
echo json_encode([
|
|
||||||
'success' => true,
|
|
||||||
'message' => get_string('registration_deactivated', 'meetletacbfree'),
|
|
||||||
'summary' => manager::status_summary(),
|
|
||||||
]);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($action === 'status') {
|
|
||||||
echo json_encode([
|
|
||||||
'success' => true,
|
|
||||||
'summary' => manager::status_summary(),
|
|
||||||
]);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new moodle_exception('invalidparameter');
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
$ex = registration_exception::from_throwable($e);
|
|
||||||
$mapped = error_mapper::from_exception($ex);
|
|
||||||
echo json_encode([
|
|
||||||
'success' => false,
|
|
||||||
'error' => $mapped['message'] ?? $ex->get_api_message(),
|
|
||||||
'error_code' => $ex->get_error_code(),
|
|
||||||
'request_id' => $ex->get_request_id(),
|
|
||||||
'summary' => manager::status_summary(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
<?php
|
|
||||||
// This file is part of Moodle - http://moodle.org/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset site access settings (role mapping or feature matrix) to built-in defaults.
|
|
||||||
*
|
|
||||||
* @package mod_meetletacbfree
|
|
||||||
* @copyright 2026 MeetLet
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
define('AJAX_SCRIPT', true);
|
|
||||||
|
|
||||||
require_once('../../../config.php');
|
|
||||||
|
|
||||||
use mod_meetletacbfree\local\featureaccess;
|
|
||||||
use mod_meetletacbfree\local\roles;
|
|
||||||
|
|
||||||
require_login();
|
|
||||||
require_capability('moodle/site:config', context_system::instance());
|
|
||||||
require_sesskey();
|
|
||||||
|
|
||||||
\mod_meetletacbfree\registration\manager::require_registered();
|
|
||||||
|
|
||||||
$section = required_param('section', PARAM_ALPHA);
|
|
||||||
|
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
|
|
||||||
try {
|
|
||||||
if ($section === 'rolemapping') {
|
|
||||||
$rules = roles::builtin_site_defaults();
|
|
||||||
$json = json_encode($rules, JSON_UNESCAPED_UNICODE);
|
|
||||||
set_config('default_participants', $json, 'meetletacbfree');
|
|
||||||
echo json_encode([
|
|
||||||
'success' => true,
|
|
||||||
'section' => 'rolemapping',
|
|
||||||
'matrix' => roles::matrix_from_rules($rules),
|
|
||||||
'message' => get_string('reset_success_rolemapping', 'meetletacbfree'),
|
|
||||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($section === 'featureaccess') {
|
|
||||||
$matrix = featureaccess::builtin_defaults();
|
|
||||||
$json = json_encode($matrix, JSON_UNESCAPED_UNICODE);
|
|
||||||
set_config('featureaccess', $json, 'meetletacbfree');
|
|
||||||
echo json_encode([
|
|
||||||
'success' => true,
|
|
||||||
'section' => 'featureaccess',
|
|
||||||
'matrix' => $matrix,
|
|
||||||
'message' => get_string('reset_success_featureaccess', 'meetletacbfree'),
|
|
||||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new moodle_exception('invalidparameter');
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
$error = $e->getMessage();
|
|
||||||
if ($e instanceof moodle_exception) {
|
|
||||||
$info = get_exception_info($e);
|
|
||||||
if (!empty($info->message)) {
|
|
||||||
$error = (string)$info->message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo json_encode([
|
|
||||||
'success' => false,
|
|
||||||
'error' => $error !== '' ? $error : get_string('reset_error', 'meetletacbfree'),
|
|
||||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,25 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MeetLet feature-access matrix: row/column "select all" toggles.
|
* @module mod_meetletacbfree/featureaccess_matrix
|
||||||
* Page-local (admin settings + mod form). Not AMD.
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
*/
|
*/
|
||||||
(function() {
|
|
||||||
|
define([], function() {
|
||||||
const bindMatrix = (matrix) => {
|
const bindMatrix = (matrix) => {
|
||||||
if (!matrix || matrix.getAttribute('data-access-bound') === '1') {
|
if (!matrix || matrix.getAttribute('data-access-bound') === '1') {
|
||||||
return;
|
return;
|
||||||
@@ -46,9 +63,5 @@
|
|||||||
document.querySelectorAll('[data-meetlet-access-matrix]').forEach(bindMatrix);
|
document.querySelectorAll('[data-meetlet-access-matrix]').forEach(bindMatrix);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
return {init: init};
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
});
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
@@ -1,19 +1,32 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared scroll lock for MeetLet modals.
|
* @module mod_meetletacbfree/meetlet_modal_scroll
|
||||||
* Uses body overflow + scroll guards — no position:fixed on body (avoids white-page flash).
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
*
|
|
||||||
* @package mod_meetletacbfree
|
|
||||||
* @copyright 2026 MeetLet
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
*/
|
*/
|
||||||
(function (global) {
|
|
||||||
|
define([], function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var scrollLockY = 0;
|
var scrollLockY = 0;
|
||||||
var guardsActive = false;
|
var guardsActive = false;
|
||||||
|
|
||||||
function scrollbarWidth() {
|
function scrollbarWidth() {
|
||||||
return Math.max(0, global.innerWidth - document.documentElement.clientWidth);
|
return Math.max(0, window.innerWidth - document.documentElement.clientWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
function focusNoScroll(el) {
|
function focusNoScroll(el) {
|
||||||
@@ -29,13 +42,13 @@
|
|||||||
|
|
||||||
function restoreScroll() {
|
function restoreScroll() {
|
||||||
if (scrollLockY > 0) {
|
if (scrollLockY > 0) {
|
||||||
global.scrollTo(0, scrollLockY);
|
window.scrollTo(0, scrollLockY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onScrollGuard() {
|
function onScrollGuard() {
|
||||||
if (scrollLockY && global.scrollY !== scrollLockY) {
|
if (scrollLockY && window.scrollY !== scrollLockY) {
|
||||||
global.scrollTo(0, scrollLockY);
|
window.scrollTo(0, scrollLockY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,9 +64,9 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
guardsActive = true;
|
guardsActive = true;
|
||||||
global.addEventListener('scroll', onScrollGuard, true);
|
window.addEventListener('scroll', onScrollGuard, true);
|
||||||
global.addEventListener('wheel', onMoveGuard, {passive: false, capture: true});
|
window.addEventListener('wheel', onMoveGuard, {passive: false, capture: true});
|
||||||
global.addEventListener('touchmove', onMoveGuard, {passive: false, capture: true});
|
window.addEventListener('touchmove', onMoveGuard, {passive: false, capture: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
function unbindGuards() {
|
function unbindGuards() {
|
||||||
@@ -61,24 +74,24 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
guardsActive = false;
|
guardsActive = false;
|
||||||
global.removeEventListener('scroll', onScrollGuard, true);
|
window.removeEventListener('scroll', onScrollGuard, true);
|
||||||
global.removeEventListener('wheel', onMoveGuard, true);
|
window.removeEventListener('wheel', onMoveGuard, true);
|
||||||
global.removeEventListener('touchmove', onMoveGuard, true);
|
window.removeEventListener('touchmove', onMoveGuard, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function lockPageScroll() {
|
function lockPageScroll() {
|
||||||
if (document.documentElement.classList.contains('meetlet-modal-open')) {
|
if (document.documentElement.classList.contains('meetlet-modal-open')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scrollLockY = global.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0;
|
scrollLockY = window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0;
|
||||||
var pad = scrollbarWidth();
|
var pad = scrollbarWidth();
|
||||||
if (pad > 0) {
|
if (pad > 0) {
|
||||||
document.body.style.paddingRight = pad + 'px';
|
document.body.style.paddingRight = pad + 'px';
|
||||||
}
|
}
|
||||||
document.documentElement.classList.add('meetlet-modal-open');
|
document.documentElement.classList.add('meetlet-modal-open');
|
||||||
restoreScroll();
|
restoreScroll();
|
||||||
if (typeof global.requestAnimationFrame === 'function') {
|
if (typeof window.requestAnimationFrame === 'function') {
|
||||||
global.requestAnimationFrame(restoreScroll);
|
window.requestAnimationFrame(restoreScroll);
|
||||||
}
|
}
|
||||||
bindGuards();
|
bindGuards();
|
||||||
}
|
}
|
||||||
@@ -93,18 +106,19 @@
|
|||||||
document.body.style.paddingRight = '';
|
document.body.style.paddingRight = '';
|
||||||
scrollLockY = 0;
|
scrollLockY = 0;
|
||||||
if (y) {
|
if (y) {
|
||||||
global.scrollTo(0, y);
|
window.scrollTo(0, y);
|
||||||
if (typeof global.requestAnimationFrame === 'function') {
|
if (typeof window.requestAnimationFrame === 'function') {
|
||||||
global.requestAnimationFrame(function () {
|
window.requestAnimationFrame(function() {
|
||||||
global.scrollTo(0, y);
|
window.scrollTo(0, y);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
global.MeetletModalScroll = {
|
return {
|
||||||
|
init: function() {},
|
||||||
lock: lockPageScroll,
|
lock: lockPageScroll,
|
||||||
unlock: unlockPageScroll,
|
unlock: unlockPageScroll,
|
||||||
focusNoScroll: focusNoScroll,
|
focusNoScroll: focusNoScroll
|
||||||
};
|
};
|
||||||
}(typeof window !== 'undefined' ? window : this));
|
});
|
||||||
@@ -1,7 +1,26 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MeetLet mod form participants — page-local only (not AMD).
|
* @module mod_meetletacbfree/modform
|
||||||
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
*/
|
*/
|
||||||
require(['core/str', 'core/notification', 'core/templates', 'core/ajax'], function(Str, Notification, Templates, Ajax) {
|
|
||||||
|
define(['core/str', 'core/notification', 'core/templates', 'core/ajax'], function(Str, Notification, Templates, Ajax) {
|
||||||
|
function init() {
|
||||||
const ELEMENT_SELECTOR = {
|
const ELEMENT_SELECTOR = {
|
||||||
participantData: () => document.querySelector('[data-participant-data]'),
|
participantData: () => document.querySelector('[data-participant-data]'),
|
||||||
participantList: () => document.getElementsByName('participants')[0],
|
participantList: () => document.getElementsByName('participants')[0],
|
||||||
@@ -477,4 +496,9 @@ require(['core/str', 'core/notification', 'core/templates', 'core/ajax'], functi
|
|||||||
});
|
});
|
||||||
updateSelectionFromType(typeSelect);
|
updateSelectionFromType(typeSelect);
|
||||||
participantListInit();
|
participantListInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: init
|
||||||
|
};
|
||||||
});
|
});
|
||||||
@@ -1,14 +1,28 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset-to-default for site role mapping and feature-access matrix (admin settings).
|
* @module mod_meetletacbfree/settings_access_reset
|
||||||
*
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
* @package mod_meetletacbfree
|
|
||||||
* @copyright 2026 MeetLet
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
*/
|
*/
|
||||||
(function () {
|
|
||||||
|
define(['core/ajax', 'mod_meetletacbfree/meetlet_modal_scroll'], function(Ajax, MeetletModalScroll) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var modalState = {
|
var modalState = {
|
||||||
open: false,
|
open: false,
|
||||||
resolve: null,
|
resolve: null,
|
||||||
lastFocus: null,
|
lastFocus: null,
|
||||||
@@ -18,15 +32,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
function modalScroll() {
|
function modalScroll() {
|
||||||
return window.MeetletModalScroll || {
|
return MeetletModalScroll;
|
||||||
lock: function () {},
|
|
||||||
unlock: function () {},
|
|
||||||
focusNoScroll: function (el) {
|
|
||||||
if (el && typeof el.focus === 'function') {
|
|
||||||
el.focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function byId(id) {
|
function byId(id) {
|
||||||
@@ -292,22 +298,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function postReset(root, section, str) {
|
function postReset(root, section, str) {
|
||||||
var endpoint = root.getAttribute('data-endpoint') || '';
|
return Ajax.call([{
|
||||||
var sesskey = root.getAttribute('data-sesskey') || '';
|
methodname: 'mod_meetletacbfree_reset_access_settings',
|
||||||
if (!endpoint || !sesskey) {
|
args: {section: section}
|
||||||
return Promise.reject(new Error(str.error || 'Error'));
|
}])[0].then(function(data) {
|
||||||
}
|
if (data && data.matrixjson) {
|
||||||
var url = endpoint + (endpoint.indexOf('?') >= 0 ? '&' : '?') +
|
try {
|
||||||
'sesskey=' + encodeURIComponent(sesskey) +
|
data.matrix = JSON.parse(data.matrixjson);
|
||||||
'§ion=' + encodeURIComponent(section);
|
} catch (e) {
|
||||||
return fetch(url, {
|
data.matrix = null;
|
||||||
method: 'POST',
|
}
|
||||||
credentials: 'same-origin',
|
}
|
||||||
headers: {
|
return data;
|
||||||
'Accept': 'application/json',
|
|
||||||
},
|
|
||||||
}).then(function (resp) {
|
|
||||||
return resp.json();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,9 +414,5 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
return {init: init};
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
});
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
@@ -1,7 +1,28 @@
|
|||||||
(function () {
|
// 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_conntest
|
||||||
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
define(['core/ajax'], function(Ajax) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function ready(fn) {
|
function ready(fn) {
|
||||||
if (document.readyState !== 'loading') {
|
if (document.readyState !== 'loading') {
|
||||||
fn();
|
fn();
|
||||||
} else {
|
} else {
|
||||||
@@ -131,7 +152,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ready(function () {
|
function init() {
|
||||||
var SAVE_ICON = '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">'
|
var SAVE_ICON = '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">'
|
||||||
+ '<path fill="currentColor" d="M17 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7l-4-4zm-5 16a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm3-10H5V5h10v4z"/>'
|
+ '<path fill="currentColor" d="M17 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7l-4-4zm-5 16a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm3-10H5V5h10v4z"/>'
|
||||||
+ '</svg>';
|
+ '</svg>';
|
||||||
@@ -191,9 +212,6 @@
|
|||||||
if (!btn || !grid) {
|
if (!btn || !grid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var endpoint = root.getAttribute('data-endpoint');
|
|
||||||
var sesskey = root.getAttribute('data-sesskey');
|
|
||||||
var steps = (root.getAttribute('data-steps') || 'login,folders,user,sso,cleanup')
|
var steps = (root.getAttribute('data-steps') || 'login,folders,user,sso,cleanup')
|
||||||
.split(',')
|
.split(',')
|
||||||
.map(function (s) { return s.trim(); })
|
.map(function (s) { return s.trim(); })
|
||||||
@@ -250,15 +268,12 @@
|
|||||||
setCardState(card, 'running', strings, '');
|
setCardState(card, 'running', strings, '');
|
||||||
setProgress(root, completed, steps.length, strings);
|
setProgress(root, completed, steps.length, strings);
|
||||||
|
|
||||||
var url = endpoint +
|
var result = await new Promise(function(resolve, reject) {
|
||||||
(endpoint.indexOf('?') === -1 ? '?' : '&') +
|
Ajax.call([{
|
||||||
'step=' + encodeURIComponent(step) +
|
methodname: 'mod_meetletacbfree_run_conntest_step',
|
||||||
'&sesskey=' + encodeURIComponent(sesskey);
|
args: {step: step}
|
||||||
var response = await fetch(url, {
|
}])[0].then(resolve).catch(reject);
|
||||||
credentials: 'same-origin',
|
|
||||||
headers: { 'Accept': 'application/json' }
|
|
||||||
});
|
});
|
||||||
var result = await response.json();
|
|
||||||
setCardState(
|
setCardState(
|
||||||
card,
|
card,
|
||||||
result.ok ? 'ok' : 'fail',
|
result.ok ? 'ok' : 'fail',
|
||||||
@@ -303,5 +318,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
})();
|
|
||||||
|
return {init: init};
|
||||||
|
});
|
||||||
@@ -1,14 +1,28 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inline Ajax site registration on plugin settings tab (Marketplace free edition).
|
* @module mod_meetletacbfree/settings_registration
|
||||||
*
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
* @package mod_meetletacbfree
|
|
||||||
* @copyright 2026 MeetLet
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
*/
|
*/
|
||||||
(function () {
|
|
||||||
|
define(['core/ajax', 'mod_meetletacbfree/meetlet_modal_scroll'], function(Ajax, MeetletModalScroll) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function byId(id) {
|
function byId(id) {
|
||||||
return document.getElementById(id);
|
return document.getElementById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,15 +112,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function modalScroll() {
|
function modalScroll() {
|
||||||
return window.MeetletModalScroll || {
|
return MeetletModalScroll;
|
||||||
lock: function () {},
|
|
||||||
unlock: function () {},
|
|
||||||
focusNoScroll: function (el) {
|
|
||||||
if (el && typeof el.focus === 'function') {
|
|
||||||
el.focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeRegistrationModal(result) {
|
function closeRegistrationModal(result) {
|
||||||
@@ -217,39 +223,39 @@
|
|||||||
if (!cfg) {
|
if (!cfg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var body = new URLSearchParams();
|
|
||||||
body.set('action', action);
|
|
||||||
body.set('sesskey', cfg.dataset.sesskey || '');
|
|
||||||
body.set('registration_api_url', currentApiUrl(cfg));
|
|
||||||
|
|
||||||
setFlash(flash, true, '…');
|
setFlash(flash, true, '…');
|
||||||
fetch(cfg.dataset.ajaxurl, {
|
Ajax.call([{
|
||||||
method: 'POST',
|
methodname: 'mod_meetletacbfree_registration_action',
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
|
args: {
|
||||||
credentials: 'same-origin',
|
action: action,
|
||||||
body: body.toString(),
|
registration_api_url: currentApiUrl(cfg)
|
||||||
})
|
}
|
||||||
.then(function (res) {
|
}])[0].then(function(data) {
|
||||||
return res.json();
|
data.summary = {
|
||||||
})
|
active: !!data.active,
|
||||||
.then(function (data) {
|
status: data.status,
|
||||||
if (data.summary) {
|
status_label: data.status_label,
|
||||||
renderSummary(data.summary);
|
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);
|
||||||
}
|
}
|
||||||
if (data.success) {
|
} else {
|
||||||
setFlash(flash, true, data.message);
|
setFlash(flash, false, data.error || 'Request failed');
|
||||||
if (action === 'activate' || action === 'deactivate') {
|
}
|
||||||
window.setTimeout(function () {
|
}).catch(function(err) {
|
||||||
window.location.reload();
|
setFlash(flash, false, err && err.message ? err.message : 'Request failed');
|
||||||
}, 600);
|
});
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setFlash(flash, false, data.error || 'Request failed');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (err) {
|
|
||||||
setFlash(flash, false, err && err.message ? err.message : 'Request failed');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindModalChrome() {
|
function bindModalChrome() {
|
||||||
@@ -326,9 +332,5 @@
|
|||||||
bindDeactivateButton(deactivate);
|
bindDeactivateButton(deactivate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
return {init: bind};
|
||||||
document.addEventListener('DOMContentLoaded', bind);
|
});
|
||||||
} else {
|
|
||||||
bind();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
@@ -1,10 +1,28 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace Moodle checkboxes with MeetLet pill switches (check / cross).
|
* @module mod_meetletacbfree/settings_toggles
|
||||||
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
*/
|
*/
|
||||||
(function () {
|
|
||||||
|
define([], function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function enhanceInput(input) {
|
function enhanceInput(input) {
|
||||||
if (!input || input.getAttribute('data-meetlet-switch') === '1') {
|
if (!input || input.getAttribute('data-meetlet-switch') === '1') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -138,9 +156,5 @@
|
|||||||
syncHoursEnabled();
|
syncHoursEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
return {init: run};
|
||||||
document.addEventListener('DOMContentLoaded', run);
|
});
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
@@ -1,8 +1,26 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MeetLet activity view — page-local only (not AMD).
|
* @module mod_meetletacbfree/view
|
||||||
* Loaded only on mod/meetletacbfree/view.php via $PAGE->requires->js().
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
*/
|
*/
|
||||||
require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notification, Str) {
|
|
||||||
|
define(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notification, Str) {
|
||||||
|
function init() {
|
||||||
const SELECTORS = {
|
const SELECTORS = {
|
||||||
config: '[data-meetlet-config]',
|
config: '[data-meetlet-config]',
|
||||||
app: '.meetlet-app',
|
app: '.meetlet-app',
|
||||||
@@ -1026,4 +1044,9 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
|
|||||||
|
|
||||||
startStatusTicker();
|
startStatusTicker();
|
||||||
loadTab('details', false);
|
loadTab('details', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: init
|
||||||
|
};
|
||||||
});
|
});
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
namespace mod_meetletacbfree\admin;
|
namespace mod_meetletacbfree\admin;
|
||||||
|
|
||||||
use mod_meetletacbfree\local\icons;
|
use mod_meetletacbfree\local\icons;
|
||||||
use moodle_url;
|
|
||||||
|
|
||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
@@ -65,7 +64,7 @@ class access_reset_ui {
|
|||||||
/**
|
/**
|
||||||
* Modal + config root (render once on the access settings tab).
|
* Modal + config root (render once on the access settings tab).
|
||||||
*/
|
*/
|
||||||
public static function page_assets(moodle_url $ajaxurl): string {
|
public static function page_assets(): string {
|
||||||
if (self::$assetsrendered) {
|
if (self::$assetsrendered) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -75,8 +74,6 @@ class access_reset_ui {
|
|||||||
$html = \html_writer::div('', '', [
|
$html = \html_writer::div('', '', [
|
||||||
'id' => 'meetlet-access-reset-root',
|
'id' => 'meetlet-access-reset-root',
|
||||||
'hidden' => 'hidden',
|
'hidden' => 'hidden',
|
||||||
'data-endpoint' => $ajaxurl->out(false),
|
|
||||||
'data-sesskey' => sesskey(),
|
|
||||||
'data-strings' => json_encode($strings, JSON_UNESCAPED_UNICODE),
|
'data-strings' => json_encode($strings, JSON_UNESCAPED_UNICODE),
|
||||||
]);
|
]);
|
||||||
$html .= self::modal_html();
|
$html .= self::modal_html();
|
||||||
|
|||||||
@@ -45,16 +45,9 @@ class setting_registration extends admin_setting {
|
|||||||
$summary = manager::status_summary();
|
$summary = manager::status_summary();
|
||||||
$active = !empty($summary['active']);
|
$active = !empty($summary['active']);
|
||||||
$candeactivate = !empty($summary['can_deactivate']);
|
$candeactivate = !empty($summary['can_deactivate']);
|
||||||
$ajaxurl = new \moodle_url('/mod/meetletacbfree/ajax/registration.php');
|
|
||||||
$scrolljsurl = new \moodle_url('/mod/meetletacbfree/javascript/meetlet_modal_scroll.js', [
|
|
||||||
'v' => '2026090146',
|
|
||||||
]);
|
|
||||||
$jsurl = new \moodle_url('/mod/meetletacbfree/javascript/settings_registration.js', [
|
|
||||||
'v' => '2026090146',
|
|
||||||
]);
|
|
||||||
$privacytaburl = manager::privacy_tab_url();
|
$privacytaburl = manager::privacy_tab_url();
|
||||||
$PAGE->requires->js($scrolljsurl);
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/meetlet_modal_scroll', 'init');
|
||||||
$PAGE->requires->js($jsurl);
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/settings_registration', 'init');
|
||||||
|
|
||||||
$statusbadge = \html_writer::span(
|
$statusbadge = \html_writer::span(
|
||||||
s($summary['status_label'] ?? ($active
|
s($summary['status_label'] ?? ($active
|
||||||
@@ -169,8 +162,6 @@ class setting_registration extends admin_setting {
|
|||||||
\html_writer::div('', 'mt-3 d-none', ['id' => 'meetlet-registration-flash']) .
|
\html_writer::div('', 'mt-3 d-none', ['id' => 'meetlet-registration-flash']) .
|
||||||
\html_writer::div('', '', [
|
\html_writer::div('', '', [
|
||||||
'id' => 'meetlet-registration-config',
|
'id' => 'meetlet-registration-config',
|
||||||
'data-ajaxurl' => $ajaxurl->out(false),
|
|
||||||
'data-sesskey' => sesskey(),
|
|
||||||
'data-api-input' => 'id_s_meetletacbfree_registration_api_url',
|
'data-api-input' => 'id_s_meetletacbfree_registration_api_url',
|
||||||
'data-label-active' => get_string('registration_status_active', 'meetletacbfree'),
|
'data-label-active' => get_string('registration_status_active', 'meetletacbfree'),
|
||||||
'data-label-inactive' => get_string('registration_status_inactive', 'meetletacbfree'),
|
'data-label-inactive' => get_string('registration_status_inactive', 'meetletacbfree'),
|
||||||
|
|||||||
@@ -44,6 +44,22 @@ class settingspage_tabs extends \theme_boost_admin_settingspage_tabs {
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function output_html() {
|
public function output_html() {
|
||||||
return $this->herohtml . parent::output_html();
|
global $PAGE;
|
||||||
|
if ($PAGE) {
|
||||||
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/meetlet_modal_scroll', 'init');
|
||||||
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/settings_registration', 'init');
|
||||||
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/settings_conntest', 'init');
|
||||||
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/settings_toggles', 'init');
|
||||||
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/featureaccess_matrix', 'init');
|
||||||
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/settings_access_reset', 'init');
|
||||||
|
}
|
||||||
|
// Scope MeetLet admin CSS under this root (Marketplace CSS guideline).
|
||||||
|
// dir attribute is not processed by Moodle RTLCSS (unlike styles.css values).
|
||||||
|
$attrs = right_to_left() ? ['dir' => 'rtl'] : [];
|
||||||
|
return \html_writer::div(
|
||||||
|
$this->herohtml . parent::output_html(),
|
||||||
|
'meetlet-admin-settings',
|
||||||
|
$attrs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ class client {
|
|||||||
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
|
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
|
||||||
}
|
}
|
||||||
if ($this->https) {
|
if ($this->https) {
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
||||||
}
|
}
|
||||||
if (!empty($CFG->proxyhost)) {
|
if (!empty($CFG->proxyhost)) {
|
||||||
@@ -363,7 +363,7 @@ class client {
|
|||||||
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
|
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
|
||||||
}
|
}
|
||||||
if ($this->https) {
|
if ($this->https) {
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
||||||
}
|
}
|
||||||
if (!empty($CFG->proxyhost)) {
|
if (!empty($CFG->proxyhost)) {
|
||||||
|
|||||||
@@ -1386,7 +1386,8 @@ class service {
|
|||||||
CURLOPT_RETURNTRANSFER => true,
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
CURLOPT_HEADER => true,
|
CURLOPT_HEADER => true,
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
CURLOPT_FOLLOWLOCATION => true,
|
||||||
CURLOPT_SSL_VERIFYPEER => false,
|
CURLOPT_SSL_VERIFYPEER => true,
|
||||||
|
CURLOPT_SSL_VERIFYHOST => 2,
|
||||||
CURLOPT_TIMEOUT => 12,
|
CURLOPT_TIMEOUT => 12,
|
||||||
CURLOPT_COOKIE => $cookie !== '' ? ('BREEZESESSION=' . $cookie) : '',
|
CURLOPT_COOKIE => $cookie !== '' ? ('BREEZESESSION=' . $cookie) : '',
|
||||||
]);
|
]);
|
||||||
|
|||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* External: activate / recheck / deactivate MeetLet site registration.
|
||||||
|
*
|
||||||
|
* @package mod_meetletacbfree
|
||||||
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace mod_meetletacbfree\external;
|
||||||
|
|
||||||
|
use core_external\external_api;
|
||||||
|
use core_external\external_function_parameters;
|
||||||
|
use core_external\external_single_structure;
|
||||||
|
use core_external\external_value;
|
||||||
|
use mod_meetletacbfree\registration\error_mapper;
|
||||||
|
use mod_meetletacbfree\registration\manager;
|
||||||
|
use mod_meetletacbfree\registration\registration_exception;
|
||||||
|
|
||||||
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajax-capable registration actions for admin settings.
|
||||||
|
*/
|
||||||
|
class registration_action extends external_api {
|
||||||
|
public static function execute_parameters(): external_function_parameters {
|
||||||
|
return new external_function_parameters([
|
||||||
|
'action' => new external_value(PARAM_ALPHA, 'activate|recheck|deactivate|status'),
|
||||||
|
'registration_api_url' => new external_value(PARAM_URL, 'Optional API base URL', VALUE_DEFAULT, ''),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function execute(string $action, string $registrationapiurl = ''): array {
|
||||||
|
$params = self::validate_parameters(self::execute_parameters(), [
|
||||||
|
'action' => $action,
|
||||||
|
'registration_api_url' => $registrationapiurl,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$context = \context_system::instance();
|
||||||
|
self::validate_context($context);
|
||||||
|
require_capability('moodle/site:config', $context);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($params['registration_api_url'] !== '') {
|
||||||
|
set_config(manager::CONFIG_API_URL, rtrim($params['registration_api_url'], '/'), 'meetletacbfree');
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = '';
|
||||||
|
if ($params['action'] === 'activate') {
|
||||||
|
manager::activate();
|
||||||
|
$message = get_string('registration_activated', 'meetletacbfree');
|
||||||
|
} else if (in_array($params['action'], ['recheck', 'refresh', 'validate'], true)) {
|
||||||
|
manager::recheck(true);
|
||||||
|
$message = get_string('registration_rechecked', 'meetletacbfree');
|
||||||
|
} else if ($params['action'] === 'deactivate') {
|
||||||
|
manager::deactivate();
|
||||||
|
$message = get_string('registration_deactivated', 'meetletacbfree');
|
||||||
|
} else if ($params['action'] === 'status') {
|
||||||
|
$message = '';
|
||||||
|
} else {
|
||||||
|
throw new \moodle_exception('invalidparameter');
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::pack_response(true, $message, '');
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
$ex = registration_exception::from_throwable($e);
|
||||||
|
$mapped = error_mapper::from_exception($ex);
|
||||||
|
return self::pack_response(
|
||||||
|
false,
|
||||||
|
'',
|
||||||
|
(string)($mapped['message'] ?? $ex->get_api_message())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,mixed>
|
||||||
|
*/
|
||||||
|
protected static function pack_response(bool $success, string $message, string $error): array {
|
||||||
|
$summary = manager::status_summary();
|
||||||
|
return [
|
||||||
|
'success' => $success,
|
||||||
|
'message' => $message,
|
||||||
|
'error' => $error,
|
||||||
|
'active' => !empty($summary['active']),
|
||||||
|
'status' => (string)($summary['status'] ?? ''),
|
||||||
|
'status_label' => (string)($summary['status_label'] ?? ''),
|
||||||
|
'product_label' => (string)($summary['product_label'] ?? ''),
|
||||||
|
'domain' => (string)($summary['domain'] ?? ''),
|
||||||
|
'installation_id' => (string)($summary['installation_id'] ?? ''),
|
||||||
|
'can_deactivate' => !empty($summary['can_deactivate']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function execute_returns(): external_single_structure {
|
||||||
|
return new external_single_structure([
|
||||||
|
'success' => new external_value(PARAM_BOOL, 'Whether the action succeeded'),
|
||||||
|
'message' => new external_value(PARAM_TEXT, 'Success message'),
|
||||||
|
'error' => new external_value(PARAM_TEXT, 'Error message when unsuccessful'),
|
||||||
|
'active' => new external_value(PARAM_BOOL, 'Whether activation is active'),
|
||||||
|
'status' => new external_value(PARAM_ALPHANUMEXT, 'Raw status code'),
|
||||||
|
'status_label' => new external_value(PARAM_TEXT, 'Human status label'),
|
||||||
|
'product_label' => new external_value(PARAM_TEXT, 'Product label'),
|
||||||
|
'domain' => new external_value(PARAM_TEXT, 'Site domain'),
|
||||||
|
'installation_id' => new external_value(PARAM_TEXT, 'Installation id'),
|
||||||
|
'can_deactivate' => new external_value(PARAM_BOOL, 'Whether deactivate is allowed'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* External: reset site role mapping or feature-access matrix to defaults.
|
||||||
|
*
|
||||||
|
* @package mod_meetletacbfree
|
||||||
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace mod_meetletacbfree\external;
|
||||||
|
|
||||||
|
use core_external\external_api;
|
||||||
|
use core_external\external_function_parameters;
|
||||||
|
use core_external\external_single_structure;
|
||||||
|
use core_external\external_value;
|
||||||
|
use mod_meetletacbfree\local\featureaccess;
|
||||||
|
use mod_meetletacbfree\local\roles;
|
||||||
|
|
||||||
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajax-capable reset of access settings defaults.
|
||||||
|
*/
|
||||||
|
class reset_access_settings extends external_api {
|
||||||
|
public static function execute_parameters(): external_function_parameters {
|
||||||
|
return new external_function_parameters([
|
||||||
|
'section' => new external_value(PARAM_ALPHA, 'Section: rolemapping or featureaccess'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function execute(string $section): array {
|
||||||
|
$params = self::validate_parameters(self::execute_parameters(), ['section' => $section]);
|
||||||
|
$context = \context_system::instance();
|
||||||
|
self::validate_context($context);
|
||||||
|
require_capability('moodle/site:config', $context);
|
||||||
|
|
||||||
|
\mod_meetletacbfree\registration\manager::require_registered();
|
||||||
|
|
||||||
|
if ($params['section'] === 'rolemapping') {
|
||||||
|
$rules = roles::builtin_site_defaults();
|
||||||
|
$json = json_encode($rules, JSON_UNESCAPED_UNICODE);
|
||||||
|
set_config('default_participants', $json, 'meetletacbfree');
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'section' => 'rolemapping',
|
||||||
|
'matrixjson' => json_encode(roles::matrix_from_rules($rules), JSON_UNESCAPED_UNICODE),
|
||||||
|
'message' => get_string('reset_success_rolemapping', 'meetletacbfree'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($params['section'] === 'featureaccess') {
|
||||||
|
$matrix = featureaccess::builtin_defaults();
|
||||||
|
$json = json_encode($matrix, JSON_UNESCAPED_UNICODE);
|
||||||
|
set_config('featureaccess', $json, 'meetletacbfree');
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'section' => 'featureaccess',
|
||||||
|
'matrixjson' => json_encode($matrix, JSON_UNESCAPED_UNICODE),
|
||||||
|
'message' => get_string('reset_success_featureaccess', 'meetletacbfree'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \moodle_exception('invalidparameter');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function execute_returns(): external_single_structure {
|
||||||
|
return new external_single_structure([
|
||||||
|
'success' => new external_value(PARAM_BOOL, 'Whether reset succeeded'),
|
||||||
|
'section' => new external_value(PARAM_ALPHA, 'Section that was reset'),
|
||||||
|
'matrixjson' => new external_value(PARAM_RAW, 'JSON-encoded matrix payload'),
|
||||||
|
'message' => new external_value(PARAM_TEXT, 'Success message'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* External: run one Adobe Connect connection-test step.
|
||||||
|
*
|
||||||
|
* @package mod_meetletacbfree
|
||||||
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace mod_meetletacbfree\external;
|
||||||
|
|
||||||
|
use core_external\external_api;
|
||||||
|
use core_external\external_function_parameters;
|
||||||
|
use core_external\external_multiple_structure;
|
||||||
|
use core_external\external_single_structure;
|
||||||
|
use core_external\external_value;
|
||||||
|
use mod_meetletacbfree\local\conntest_runner;
|
||||||
|
|
||||||
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajax-capable connection test step runner for admin settings.
|
||||||
|
*/
|
||||||
|
class run_conntest_step extends external_api {
|
||||||
|
public static function execute_parameters(): external_function_parameters {
|
||||||
|
return new external_function_parameters([
|
||||||
|
'step' => new external_value(PARAM_ALPHA, 'Connection test step name'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function execute(string $step): array {
|
||||||
|
$params = self::validate_parameters(self::execute_parameters(), ['step' => $step]);
|
||||||
|
$context = \context_system::instance();
|
||||||
|
self::validate_context($context);
|
||||||
|
require_capability('moodle/site:config', $context);
|
||||||
|
|
||||||
|
\mod_meetletacbfree\registration\manager::require_registered();
|
||||||
|
|
||||||
|
$result = conntest_runner::run_step($params['step']);
|
||||||
|
$subresults = [];
|
||||||
|
if (!empty($result['subresults']) && is_array($result['subresults'])) {
|
||||||
|
foreach ($result['subresults'] as $sub) {
|
||||||
|
$subresults[] = [
|
||||||
|
'label' => (string)($sub['label'] ?? ''),
|
||||||
|
'ok' => !empty($sub['ok']),
|
||||||
|
'detail' => (string)($sub['detail'] ?? ''),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'step' => (string)($result['step'] ?? $params['step']),
|
||||||
|
'label' => (string)($result['label'] ?? ''),
|
||||||
|
'ok' => !empty($result['ok']),
|
||||||
|
'detail' => (string)($result['detail'] ?? ''),
|
||||||
|
'done' => !empty($result['done']),
|
||||||
|
'abort' => !empty($result['abort']),
|
||||||
|
'subresults' => $subresults,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function execute_returns(): external_single_structure {
|
||||||
|
return new external_single_structure([
|
||||||
|
'step' => new external_value(PARAM_ALPHANUMEXT, 'Step id'),
|
||||||
|
'label' => new external_value(PARAM_TEXT, 'Step label'),
|
||||||
|
'ok' => new external_value(PARAM_BOOL, 'Whether the step passed'),
|
||||||
|
'detail' => new external_value(PARAM_RAW, 'Detail message'),
|
||||||
|
'done' => new external_value(PARAM_BOOL, 'Whether the run is finished'),
|
||||||
|
'abort' => new external_value(PARAM_BOOL, 'Whether remaining steps should abort'),
|
||||||
|
'subresults' => new external_multiple_structure(
|
||||||
|
new external_single_structure([
|
||||||
|
'label' => new external_value(PARAM_TEXT, 'Sub-step label'),
|
||||||
|
'ok' => new external_value(PARAM_BOOL, 'Sub-step ok'),
|
||||||
|
'detail' => new external_value(PARAM_RAW, 'Sub-step detail'),
|
||||||
|
]),
|
||||||
|
'Optional nested results',
|
||||||
|
VALUE_DEFAULT,
|
||||||
|
[]
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -161,7 +161,8 @@ class content {
|
|||||||
curl_setopt_array($ch, [
|
curl_setopt_array($ch, [
|
||||||
CURLOPT_FILE => $fp,
|
CURLOPT_FILE => $fp,
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
CURLOPT_FOLLOWLOCATION => true,
|
||||||
CURLOPT_SSL_VERIFYPEER => false,
|
CURLOPT_SSL_VERIFYPEER => true,
|
||||||
|
CURLOPT_SSL_VERIFYHOST => 2,
|
||||||
CURLOPT_TIMEOUT => 300,
|
CURLOPT_TIMEOUT => 300,
|
||||||
CURLOPT_COOKIE => $session !== '' ? ('BREEZESESSION=' . $session) : '',
|
CURLOPT_COOKIE => $session !== '' ? ('BREEZESESSION=' . $session) : '',
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -1,11 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
// This file is part of Moodle - http://moodle.org/
|
// 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/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structured registration API / local client exception.
|
* Structured registration API / local client exception.
|
||||||
*
|
*
|
||||||
* @package mod_meetletacbfree
|
* @package mod_meetletacbfree
|
||||||
* @copyright 2026 MeetLet
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
+21
-1
@@ -1,5 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
// This file is part of Moodle - http://moodle.org/
|
// 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/>.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standalone Adobe Connect connection test page.
|
||||||
|
*
|
||||||
|
* @package mod_meetletacbfree
|
||||||
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
require_once('../../config.php');
|
require_once('../../config.php');
|
||||||
|
|
||||||
@@ -15,7 +36,6 @@ $PAGE->set_context(context_system::instance());
|
|||||||
$PAGE->set_url(new moodle_url('/mod/meetletacbfree/conntest.php'));
|
$PAGE->set_url(new moodle_url('/mod/meetletacbfree/conntest.php'));
|
||||||
$PAGE->set_title(get_string('conntesttitle', 'meetletacbfree'));
|
$PAGE->set_title(get_string('conntesttitle', 'meetletacbfree'));
|
||||||
$PAGE->set_pagelayout('admin');
|
$PAGE->set_pagelayout('admin');
|
||||||
$PAGE->requires->css(new moodle_url('/mod/meetletacbfree/styles.css', ['v' => '2026081415']));
|
|
||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
$push = static function(string $label, bool $ok, string $detail = '') use (&$results): void {
|
$push = static function(string $label, bool $ok, string $detail = '') use (&$results): void {
|
||||||
|
|||||||
@@ -81,4 +81,28 @@ $functions = [
|
|||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'mod/meetletacbfree:host',
|
'capabilities' => 'mod/meetletacbfree:host',
|
||||||
],
|
],
|
||||||
|
'mod_meetletacbfree_run_conntest_step' => [
|
||||||
|
'classname' => 'mod_meetletacbfree\external\run_conntest_step',
|
||||||
|
'methodname' => 'execute',
|
||||||
|
'description' => 'Run one Adobe Connect connection-test step (admin)',
|
||||||
|
'type' => 'write',
|
||||||
|
'ajax' => true,
|
||||||
|
'capabilities' => 'moodle/site:config',
|
||||||
|
],
|
||||||
|
'mod_meetletacbfree_reset_access_settings' => [
|
||||||
|
'classname' => 'mod_meetletacbfree\external\reset_access_settings',
|
||||||
|
'methodname' => 'execute',
|
||||||
|
'description' => 'Reset site role mapping or feature-access matrix to defaults (admin)',
|
||||||
|
'type' => 'write',
|
||||||
|
'ajax' => true,
|
||||||
|
'capabilities' => 'moodle/site:config',
|
||||||
|
],
|
||||||
|
'mod_meetletacbfree_registration_action' => [
|
||||||
|
'classname' => 'mod_meetletacbfree\external\registration_action',
|
||||||
|
'methodname' => 'execute',
|
||||||
|
'description' => 'Activate, recheck, or deactivate MeetLet plugin registration (admin)',
|
||||||
|
'type' => 'write',
|
||||||
|
'ajax' => true,
|
||||||
|
'capabilities' => 'moodle/site:config',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -176,6 +176,9 @@ $string['testsso'] = 'Single sign-on (SSO)';
|
|||||||
$string['testsso_adminok'] = 'Admin SSO succeeded';
|
$string['testsso_adminok'] = 'Admin SSO succeeded';
|
||||||
$string['testsso_userok'] = 'Test-user SSO succeeded';
|
$string['testsso_userok'] = 'Test-user SSO succeeded';
|
||||||
$string['testsso_userwarn'] = 'Test-user SSO warned (admin SSO infrastructure is healthy)';
|
$string['testsso_userwarn'] = 'Test-user SSO warned (admin SSO infrastructure is healthy)';
|
||||||
|
$string['testsso_direct_ok'] = 'Admin SSO from Moodle server succeeded';
|
||||||
|
$string['testsso_direct_fail'] = 'Direct HTTP SSO from Moodle failed — {$a}';
|
||||||
|
$string['testmeeting'] = 'Create and remove test meeting';
|
||||||
|
|
||||||
$string['tabinfo'] = 'Overview';
|
$string['tabinfo'] = 'Overview';
|
||||||
$string['tabdetails'] = 'Session details';
|
$string['tabdetails'] = 'Session details';
|
||||||
@@ -334,6 +337,7 @@ $string['emptytab'] = 'Nothing to show';
|
|||||||
$string['cachedef_folders'] = 'Adobe Connect folder sco-ids';
|
$string['cachedef_folders'] = 'Adobe Connect folder sco-ids';
|
||||||
$string['cachedef_meetinginfo'] = 'Adobe Connect meeting info';
|
$string['cachedef_meetinginfo'] = 'Adobe Connect meeting info';
|
||||||
$string['cachedef_templates'] = 'Adobe Connect meeting templates';
|
$string['cachedef_templates'] = 'Adobe Connect meeting templates';
|
||||||
|
$string['cachedef_license_webhook_nonces'] = 'MeetLet license webhook nonce cache';
|
||||||
$string['tasksync'] = 'Sync MeetLet recordings';
|
$string['tasksync'] = 'Sync MeetLet recordings';
|
||||||
$string['brand'] = 'MeetLet';
|
$string['brand'] = 'MeetLet';
|
||||||
$string['subtitle'] = 'Adobe Connect';
|
$string['subtitle'] = 'Adobe Connect';
|
||||||
@@ -352,6 +356,10 @@ $string['enable_contenttab_desc'] = 'Master switch for the content tab. Roles st
|
|||||||
$string['allow_override_contenttab'] = 'Allow per-activity content tab setting';
|
$string['allow_override_contenttab'] = 'Allow per-activity content tab setting';
|
||||||
$string['allow_override_contenttab_desc'] = 'Teachers may enable/disable the content tab for each activity.';
|
$string['allow_override_contenttab_desc'] = 'Teachers may enable/disable the content tab for each activity.';
|
||||||
$string['showrecordingstab'] = 'Show recordings tab';
|
$string['showrecordingstab'] = 'Show recordings tab';
|
||||||
|
$string['offlinesettings'] = 'Offline session video';
|
||||||
|
$string['autooffline'] = 'Automatically create offline video after the Adobe Connect class ends';
|
||||||
|
$string['autooffline_help'] = 'When this class’s Adobe Connect room had people in it and then becomes empty, recordings are sent for MP4 creation. This is independent of the optional Moodle end time (which only blocks joining).';
|
||||||
|
$string['showzip_help'] = 'When ZIP links are enabled in site settings, use this to turn the ZIP link on or off for this activity only.';
|
||||||
$string['showcontenttab'] = 'Show content tab';
|
$string['showcontenttab'] = 'Show content tab';
|
||||||
$string['activityfeatures'] = 'Links and tabs visibility';
|
$string['activityfeatures'] = 'Links and tabs visibility';
|
||||||
$string['featuredisabled'] = 'This section has been disabled by the site administrator.';
|
$string['featuredisabled'] = 'This section has been disabled by the site administrator.';
|
||||||
@@ -551,6 +559,7 @@ $string['registration_err_misconfigured'] = 'Activation request misconfigured.';
|
|||||||
$string['registration_err_bad_signature'] = 'Invalid authorization signature from MeetLet.';
|
$string['registration_err_bad_signature'] = 'Invalid authorization signature from MeetLet.';
|
||||||
$string['registration_err_network'] = 'Could not reach the MeetLet activation server.';
|
$string['registration_err_network'] = 'Could not reach the MeetLet activation server.';
|
||||||
$string['registration_err_unknown'] = 'An unknown activation error occurred.';
|
$string['registration_err_unknown'] = 'An unknown activation error occurred.';
|
||||||
|
$string['registration_api_error'] = 'MeetLet activation API error: {$a}';
|
||||||
$string['registration_crypto_error'] = 'Activation cryptography error.';
|
$string['registration_crypto_error'] = 'Activation cryptography error.';
|
||||||
$string['registration_sodium_required'] = 'PHP sodium extension is required for plugin activation.';
|
$string['registration_sodium_required'] = 'PHP sodium extension is required for plugin activation.';
|
||||||
$string['task_registration_heartbeat'] = 'MeetLet plugin activation heartbeat';
|
$string['task_registration_heartbeat'] = 'MeetLet plugin activation heartbeat';
|
||||||
|
|||||||
@@ -176,6 +176,9 @@ $string['testsso'] = 'ورود یکپارچه (SSO)';
|
|||||||
$string['testsso_adminok'] = 'SSO مدیر موفق بود';
|
$string['testsso_adminok'] = 'SSO مدیر موفق بود';
|
||||||
$string['testsso_userok'] = 'SSO کاربر آزمایشی موفق بود';
|
$string['testsso_userok'] = 'SSO کاربر آزمایشی موفق بود';
|
||||||
$string['testsso_userwarn'] = 'SSO کاربر آزمایشی هشدار داد (زیرساخت SSO مدیر سالم است)';
|
$string['testsso_userwarn'] = 'SSO کاربر آزمایشی هشدار داد (زیرساخت SSO مدیر سالم است)';
|
||||||
|
$string['testsso_direct_ok'] = 'SSO مدیر از سرور مودل موفق بود';
|
||||||
|
$string['testsso_direct_fail'] = 'SSO مستقیم HTTP از مودل ناموفق بود — {$a}';
|
||||||
|
$string['testmeeting'] = 'ایجاد و حذف جلسه آزمایشی';
|
||||||
|
|
||||||
$string['tabinfo'] = 'نمای کلی';
|
$string['tabinfo'] = 'نمای کلی';
|
||||||
$string['tabdetails'] = 'توضیحات جلسه';
|
$string['tabdetails'] = 'توضیحات جلسه';
|
||||||
@@ -336,6 +339,7 @@ $string['emptytab'] = 'موردی برای نمایش نیست';
|
|||||||
$string['cachedef_folders'] = 'شناسه پوشههای Adobe Connect';
|
$string['cachedef_folders'] = 'شناسه پوشههای Adobe Connect';
|
||||||
$string['cachedef_meetinginfo'] = 'اطلاعات جلسه Adobe Connect';
|
$string['cachedef_meetinginfo'] = 'اطلاعات جلسه Adobe Connect';
|
||||||
$string['cachedef_templates'] = 'قالبهای جلسه Adobe Connect';
|
$string['cachedef_templates'] = 'قالبهای جلسه Adobe Connect';
|
||||||
|
$string['cachedef_license_webhook_nonces'] = 'کش nonce وبهوک لایسنس MeetLet';
|
||||||
$string['tasksync'] = 'همگامسازی ضبطهای MeetLet';
|
$string['tasksync'] = 'همگامسازی ضبطهای MeetLet';
|
||||||
$string['brand'] = 'MeetLet';
|
$string['brand'] = 'MeetLet';
|
||||||
$string['subtitle'] = 'Adobe Connect';
|
$string['subtitle'] = 'Adobe Connect';
|
||||||
@@ -354,6 +358,10 @@ $string['enable_contenttab_desc'] = 'کلید اصلی تب محتوا. نقش
|
|||||||
$string['allow_override_contenttab'] = 'اجازه تنظیم تب محتوا در هر فعالیت';
|
$string['allow_override_contenttab'] = 'اجازه تنظیم تب محتوا در هر فعالیت';
|
||||||
$string['allow_override_contenttab_desc'] = 'مدرس بتواند برای هر جلسه نمایش تب محتوا را جداگانه کنترل کند.';
|
$string['allow_override_contenttab_desc'] = 'مدرس بتواند برای هر جلسه نمایش تب محتوا را جداگانه کنترل کند.';
|
||||||
$string['showrecordingstab'] = 'نمایش تب ضبطها';
|
$string['showrecordingstab'] = 'نمایش تب ضبطها';
|
||||||
|
$string['offlinesettings'] = 'ویدیوی آفلاین جلسه';
|
||||||
|
$string['autooffline'] = 'ساخت خودکار ویدیوی آفلاین پس از پایان کلاس Adobe Connect';
|
||||||
|
$string['autooffline_help'] = 'وقتی اتاق Adobe Connect این کلاس خالی شود (پس از حضور شرکتکنندگان)، ضبطها برای ساخت MP4 ارسال میشوند. این مستقل از زمان پایان اختیاری در مودل است.';
|
||||||
|
$string['showzip_help'] = 'اگر لینک ZIP در تنظیمات سایت فعال باشد، با این گزینه میتوانید لینک ZIP را فقط برای این فعالیت روشن یا خاموش کنید.';
|
||||||
$string['showcontenttab'] = 'نمایش تب محتوا';
|
$string['showcontenttab'] = 'نمایش تب محتوا';
|
||||||
$string['activityfeatures'] = 'نمایش لینکها و تبها';
|
$string['activityfeatures'] = 'نمایش لینکها و تبها';
|
||||||
$string['featuredisabled'] = 'این بخش توسط مدیر سایت غیرفعال شده است.';
|
$string['featuredisabled'] = 'این بخش توسط مدیر سایت غیرفعال شده است.';
|
||||||
@@ -553,6 +561,7 @@ $string['registration_err_misconfigured'] = 'درخواست فعالسازی
|
|||||||
$string['registration_err_bad_signature'] = 'امضای مجوز از MeetLet نامعتبر است.';
|
$string['registration_err_bad_signature'] = 'امضای مجوز از MeetLet نامعتبر است.';
|
||||||
$string['registration_err_network'] = 'اتصال به سرور فعالسازی MeetLet برقرار نشد.';
|
$string['registration_err_network'] = 'اتصال به سرور فعالسازی MeetLet برقرار نشد.';
|
||||||
$string['registration_err_unknown'] = 'خطای ناشناخته در فعالسازی رخ داد.';
|
$string['registration_err_unknown'] = 'خطای ناشناخته در فعالسازی رخ داد.';
|
||||||
|
$string['registration_api_error'] = 'خطای API فعالسازی MeetLet: {$a}';
|
||||||
$string['registration_crypto_error'] = 'خطای رمزنگاری فعالسازی.';
|
$string['registration_crypto_error'] = 'خطای رمزنگاری فعالسازی.';
|
||||||
$string['registration_sodium_required'] = 'افزونه sodium در PHP برای فعالسازی پلاگین لازم است.';
|
$string['registration_sodium_required'] = 'افزونه sodium در PHP برای فعالسازی پلاگین لازم است.';
|
||||||
$string['task_registration_heartbeat'] = 'بررسی روزانه فعالسازی پلاگین MeetLet';
|
$string['task_registration_heartbeat'] = 'بررسی روزانه فعالسازی پلاگین MeetLet';
|
||||||
|
|||||||
+25
-8
@@ -1,5 +1,27 @@
|
|||||||
<?php
|
<?php
|
||||||
// This file is part of Moodle - http://moodle.org/
|
// 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/>.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MeetLet activity module form.
|
||||||
|
*
|
||||||
|
* @package mod_meetletacbfree
|
||||||
|
* @copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
require_once($CFG->dirroot . '/course/moodleform_mod.php');
|
require_once($CFG->dirroot . '/course/moodleform_mod.php');
|
||||||
@@ -12,10 +34,6 @@ use mod_meetletacbfree\registration\manager as registration_manager;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* MeetLet mod form.
|
* MeetLet mod form.
|
||||||
*
|
|
||||||
* @package mod_meetletacbfree
|
|
||||||
* @copyright 2026 MeetLet
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
*/
|
||||||
class mod_meetletacbfree_mod_form extends moodleform_mod {
|
class mod_meetletacbfree_mod_form extends moodleform_mod {
|
||||||
public function definition() {
|
public function definition() {
|
||||||
@@ -34,10 +52,9 @@ class mod_meetletacbfree_mod_form extends moodleform_mod {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/modform.js'));
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/modform', 'init');
|
||||||
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/featureaccess_matrix.js'));
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/featureaccess_matrix', 'init');
|
||||||
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/settings_toggles.js'));
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/settings_toggles', 'init');
|
||||||
$PAGE->requires->css(new moodle_url('/mod/meetletacbfree/styles.css', ['v' => '2026081913']));
|
|
||||||
|
|
||||||
$mform->addElement('header', 'general', get_string('general', 'form'));
|
$mform->addElement('header', 'general', get_string('general', 'form'));
|
||||||
$mform->addElement('text', 'name', get_string('meetingname', 'meetletacbfree'), ['size' => '64']);
|
$mform->addElement('text', 'name', get_string('meetingname', 'meetletacbfree'), ['size' => '64']);
|
||||||
|
|||||||
+2
-618
@@ -46,620 +46,6 @@ if ($ADMIN->fulltree) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$logo = $OUTPUT->image_url('adobeconnect', 'meetletacbfree');
|
$logo = $OUTPUT->image_url('adobeconnect', 'meetletacbfree');
|
||||||
$stylesurl = new moodle_url('/mod/meetletacbfree/styles.css', ['v' => '2026090146']);
|
|
||||||
$jsurl = new moodle_url('/mod/meetletacbfree/javascript/settings_conntest.js', ['v' => '2026082135']);
|
|
||||||
$togglejsurl = new moodle_url('/mod/meetletacbfree/javascript/settings_toggles.js', ['v' => '2026081907']);
|
|
||||||
$matrixjsurl = new moodle_url('/mod/meetletacbfree/javascript/featureaccess_matrix.js');
|
|
||||||
$accessresetjsurl = new moodle_url('/mod/meetletacbfree/javascript/settings_access_reset.js', ['v' => '2026090115']);
|
|
||||||
$resetajaxurl = new moodle_url('/mod/meetletacbfree/ajax/settings_reset.php');
|
|
||||||
$modalscrolljsurl = new moodle_url('/mod/meetletacbfree/javascript/meetlet_modal_scroll.js', ['v' => '2026082239']);
|
|
||||||
$registrationjsurl = new moodle_url('/mod/meetletacbfree/javascript/settings_registration.js', ['v' => '2026090144']);
|
|
||||||
$cronjsurl = null;
|
|
||||||
$ajaxurl = new moodle_url('/mod/meetletacbfree/ajax/conntest.php');
|
|
||||||
|
|
||||||
// Load styles.css explicitly on admin tabs (theme concatenate alone is not enough for switch CSS).
|
|
||||||
$styles = '
|
|
||||||
<link rel="stylesheet" href="' . s($stylesurl->out(false)) . '">
|
|
||||||
<style>
|
|
||||||
.path-admin #adminsettings .settingsform > h2 {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-settings-hero {
|
|
||||||
display:flex; gap:1rem; align-items:center;
|
|
||||||
padding:1.15rem 1.25rem; margin:0 0 1rem;
|
|
||||||
border-radius:16px;
|
|
||||||
background:
|
|
||||||
radial-gradient(700px 180px at 100% 0%, rgba(82,204,163,.22), transparent 55%),
|
|
||||||
linear-gradient(135deg, #00261a 0%, #0a3d2e 60%, #145c45 100%);
|
|
||||||
color:#fff;
|
|
||||||
border:1px solid rgba(82,204,163,.25);
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-settings-hero img {
|
|
||||||
width:56px; height:56px; object-fit:contain;
|
|
||||||
background:rgba(255,255,255,.95); border-radius:12px; padding:6px;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-settings-hero h3 {
|
|
||||||
margin:0 0 .2rem; font-size:1.2rem; font-weight:700; color:#fff;
|
|
||||||
display:flex; flex-wrap:wrap; align-items:center; gap:.45rem .55rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-settings-hero .meetlet-settings-version {
|
|
||||||
display:inline-block;
|
|
||||||
flex:0 0 auto;
|
|
||||||
align-self:center;
|
|
||||||
margin-inline-start:auto;
|
|
||||||
padding:.12rem .55rem;
|
|
||||||
font-size:.72rem; font-weight:650; line-height:1.35;
|
|
||||||
letter-spacing:.02em;
|
|
||||||
border-radius:999px;
|
|
||||||
background:rgba(82,204,163,.18);
|
|
||||||
border:1px solid rgba(82,204,163,.35);
|
|
||||||
color:#b8f5df;
|
|
||||||
white-space:nowrap;
|
|
||||||
direction:ltr;
|
|
||||||
unicode-bidi:isolate;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-settings-hero p {
|
|
||||||
margin:0; opacity:.85; color:#e6faf3;
|
|
||||||
white-space:nowrap;
|
|
||||||
max-width:none;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-settings-copy {
|
|
||||||
min-width:0; flex:1 1 auto;
|
|
||||||
}
|
|
||||||
@media (max-width: 900px) {
|
|
||||||
.path-admin .meetlet-settings-hero p {
|
|
||||||
white-space:normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.path-admin #adminsettings .nav-tabs {
|
|
||||||
border-bottom:2px solid #cfe8de;
|
|
||||||
gap:.2rem;
|
|
||||||
}
|
|
||||||
.path-admin #adminsettings .nav-tabs .nav-link {
|
|
||||||
border:0 !important;
|
|
||||||
border-radius:6px !important;
|
|
||||||
padding:.45rem .9rem;
|
|
||||||
color:#00261a;
|
|
||||||
font-weight:650;
|
|
||||||
box-shadow:none !important;
|
|
||||||
outline:none !important;
|
|
||||||
}
|
|
||||||
.path-admin #adminsettings .nav-tabs .nav-link:hover {
|
|
||||||
background:#e6faf3; color:#00261a;
|
|
||||||
}
|
|
||||||
.path-admin #adminsettings .nav-tabs .nav-link.active {
|
|
||||||
background:#52cca3; color:#00261a;
|
|
||||||
}
|
|
||||||
.path-admin #adminsettings .nav-tabs .nav-link:focus,
|
|
||||||
.path-admin #adminsettings .nav-tabs .nav-link:focus-visible,
|
|
||||||
.path-admin #adminsettings .nav-tabs .nav-link:active {
|
|
||||||
outline:none !important;
|
|
||||||
box-shadow:none !important;
|
|
||||||
border:0 !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-feature-group {
|
|
||||||
margin:1rem 0 .35rem;
|
|
||||||
padding:1rem 1.1rem .35rem;
|
|
||||||
border:1px solid #cfe8de;
|
|
||||||
border-radius:12px;
|
|
||||||
background:linear-gradient(180deg, #f3fbf8 0%, #ffffff 55%);
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-feature-group h4 {
|
|
||||||
margin:0 0 .25rem; color:#00261a; font-size:1.02rem; font-weight:700;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-feature-group p {
|
|
||||||
margin:0 0 .5rem; color:#4a6b5f; font-size:.9rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-settings-card {
|
|
||||||
background:#fff; border:1px solid #cfe8de; border-radius:14px;
|
|
||||||
padding:1rem 1.15rem; margin:.35rem 0 1rem;
|
|
||||||
}
|
|
||||||
.meetlet-license-badge {
|
|
||||||
font-weight: 700;
|
|
||||||
border-radius: 999px;
|
|
||||||
padding: .35rem .65rem;
|
|
||||||
}
|
|
||||||
.meetlet-license-badge--active {
|
|
||||||
background: var(--ml-green, #52cca3);
|
|
||||||
color: var(--ml-green-deep, #00261a);
|
|
||||||
}
|
|
||||||
.meetlet-license-badge--inactive {
|
|
||||||
background: #fff4d6;
|
|
||||||
color: #5a4700;
|
|
||||||
}
|
|
||||||
.path-admin #meetlet-license-modal.meetlet-modal,
|
|
||||||
.path-admin #meetlet-registration-modal.meetlet-modal,
|
|
||||||
.path-admin #meetlet-cronmon-modal.meetlet-modal,
|
|
||||||
.path-admin #meetlet-access-reset-modal.meetlet-modal {
|
|
||||||
z-index: 20000 !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-access-reset-toolbar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin: 0 0 .65rem;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin .meetlet-access-reset-toolbar {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
/* Cron videos ops cell: no extra cell/wrapper border (icon buttons keep theirs). */
|
|
||||||
.path-admin .meetlet-cronmon__table td.meetlet-cronmon__dl {
|
|
||||||
border-left: 0 !important;
|
|
||||||
border-right: 0 !important;
|
|
||||||
border-top: 0 !important;
|
|
||||||
background: transparent !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-cronmon__dl .meetlet-iconactions {
|
|
||||||
border: 0 !important;
|
|
||||||
background: transparent !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal--confirm .meetlet-modal__dialog {
|
|
||||||
width: min(480px, 100%);
|
|
||||||
max-height: min(86vh, 640px);
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal--confirm .meetlet-modal__head {
|
|
||||||
padding: 1.2rem 1.15rem 1rem;
|
|
||||||
border-radius: 18px 18px 0 0;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__lead {
|
|
||||||
margin: 0 0 .85rem;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 650;
|
|
||||||
line-height: 1.65;
|
|
||||||
color: #00261a;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__callout {
|
|
||||||
margin: 0 0 .9rem;
|
|
||||||
padding: .85rem 1rem .7rem;
|
|
||||||
border-radius: 12px;
|
|
||||||
border: 1px solid #e6c56a;
|
|
||||||
background: #fff8e6;
|
|
||||||
color: #5a4700;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__callout-title {
|
|
||||||
margin: 0 0 .4rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__limits {
|
|
||||||
margin: 0 0 .55rem;
|
|
||||||
padding-inline-start: 1.2rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__keep {
|
|
||||||
margin: 0;
|
|
||||||
color: #334942;
|
|
||||||
line-height: 1.65;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__foot {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
gap: .6rem;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding: .9rem 1.15rem 1.05rem;
|
|
||||||
border-top: 1px solid #cfe8de;
|
|
||||||
background: linear-gradient(180deg, #f7fcfa 0%, #ffffff 70%);
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__foot .btn {
|
|
||||||
border-radius: 10px;
|
|
||||||
font-weight: 700;
|
|
||||||
padding: .5rem 1.15rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__foot .btn-success {
|
|
||||||
background: #52cca3 !important;
|
|
||||||
border-color: #3db892 !important;
|
|
||||||
color: #00261a !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__foot .btn-outline-danger {
|
|
||||||
color: #a33b3b !important;
|
|
||||||
border-color: #d9a0a0 !important;
|
|
||||||
background: #fff !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-modal__foot .btn-outline-danger:hover,
|
|
||||||
.path-admin .meetlet-modal__foot .btn-outline-danger:focus {
|
|
||||||
color: #fff !important;
|
|
||||||
background: #c0392b !important;
|
|
||||||
border-color: #c0392b !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-about {
|
|
||||||
display:grid; gap:1.1rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-about__brand {
|
|
||||||
display:flex; justify-content:center; align-items:center;
|
|
||||||
padding:1.35rem 1.2rem;
|
|
||||||
border-radius:14px;
|
|
||||||
background:#f0f2f4;
|
|
||||||
border:1px solid #e2e6ea;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-about__brand img {
|
|
||||||
max-width:240px; width:100%; height:auto; display:block; margin:0 auto;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-about h4 { margin:0 0 .55rem; color:#00261a; }
|
|
||||||
.path-admin .meetlet-about p {
|
|
||||||
margin:0 0 .85rem; color:#334942; line-height:1.75; text-align:justify;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide { display:grid; gap:1rem; }
|
|
||||||
.path-admin .meetlet-guide__heading { margin:0; color:#00261a; font-size:1.15rem; }
|
|
||||||
.path-admin .meetlet-guide__intro {
|
|
||||||
margin:0; color:#334942; line-height:1.7;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__callout {
|
|
||||||
padding:.85rem 1rem; border-radius:10px; line-height:1.65;
|
|
||||||
border:1px solid #e6c56a; background:#fff8e6; color:#5a4700;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__section {
|
|
||||||
padding:1rem 1.05rem; border-radius:12px;
|
|
||||||
border:1px solid #cfe8de; background:#f7fcfa;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__section--current { background:#fff; }
|
|
||||||
.path-admin .meetlet-guide__section h4 {
|
|
||||||
margin:0 0 .55rem; color:#00261a; font-size:1.02rem; font-weight:700;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__section h5 {
|
|
||||||
margin:.85rem 0 .35rem; color:#0a3d2e; font-size:.95rem; font-weight:700;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__body,
|
|
||||||
.path-admin .meetlet-guide__body p,
|
|
||||||
.path-admin .meetlet-guide__body li {
|
|
||||||
color:#334942; line-height:1.7;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__body p { margin:0 0 .55rem; }
|
|
||||||
.path-admin .meetlet-guide__body ol,
|
|
||||||
.path-admin .meetlet-guide__body ul { margin:0 0 .35rem; padding-inline-start:1.25rem; }
|
|
||||||
.path-admin .meetlet-guide__body li { margin:0 0 .35rem; }
|
|
||||||
.path-admin .meetlet-guide__body code,
|
|
||||||
.path-admin .meetlet-guide__table code {
|
|
||||||
font-size:.88em; padding:.05rem .3rem; border-radius:4px;
|
|
||||||
background:#e6faf3; color:#00261a;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__table {
|
|
||||||
width:100%; margin:.35rem 0 0; border-collapse:collapse;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__table th,
|
|
||||||
.path-admin .meetlet-guide__table td {
|
|
||||||
padding:.45rem .55rem; border:1px solid #cfe8de; vertical-align:top;
|
|
||||||
text-align:start;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__table thead th,
|
|
||||||
.path-admin .meetlet-guide__table tbody th {
|
|
||||||
background:#e6faf3; color:#00261a; font-weight:650;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__code {
|
|
||||||
margin:.35rem 0 0; padding:.75rem .9rem; overflow-x:auto;
|
|
||||||
border-radius:10px; border:1px solid #cfe8de;
|
|
||||||
background:#0a3d2e; color:#e6faf3;
|
|
||||||
font-size:.82rem; line-height:1.45; direction:ltr; text-align:left;
|
|
||||||
white-space:pre;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__code-cell code {
|
|
||||||
font-weight:800; letter-spacing:.02em; direction:ltr; unicode-bidi:isolate;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__table td ol,
|
|
||||||
.path-admin .meetlet-guide__table td ul {
|
|
||||||
margin:.15rem 0 0; padding-inline-start:1.15rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-guide__table td li { margin:0 0 .25rem; }
|
|
||||||
.path-admin .meetlet-hourpicker { max-width: 42rem; }
|
|
||||||
.path-admin .meetlet-hourpicker.is-dimmed,
|
|
||||||
.path-admin #adminsettings .form-item.is-dimmed {
|
|
||||||
opacity: .45;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-hourpicker__tz {
|
|
||||||
margin: 0 0 .55rem; color:#4a6b5f; font-size:.88rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-hourpresets {
|
|
||||||
display:flex; flex-wrap:wrap; gap:.4rem; margin:0 0 .65rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-hourpreset {
|
|
||||||
border:1px solid #9fdcc4; background:#fff; color:#00261a;
|
|
||||||
border-radius:999px; padding:.28rem .7rem; font-size:.8rem; font-weight:650;
|
|
||||||
cursor:pointer;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-hourpreset:hover { background:#e6faf3; }
|
|
||||||
.path-admin .meetlet-hourpreset--ghost { border-color:#cfe8de; color:#4a6b5f; }
|
|
||||||
.path-admin .meetlet-hourgrid {
|
|
||||||
display:grid; grid-template-columns:repeat(8, minmax(0,1fr)); gap:.35rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-hourchip {
|
|
||||||
border:1px solid #cfe8de; background:#f7fcfa; color:#00261a;
|
|
||||||
border-radius:10px; padding:.45rem 0; font-size:.82rem; font-weight:750;
|
|
||||||
cursor:pointer;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-hourchip.is-on {
|
|
||||||
background:#52cca3; border-color:#0d9f6e; color:#00261a;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-hourchip.is-now { box-shadow:0 0 0 2px rgba(13,159,110,.35); }
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
.path-admin .meetlet-hourgrid { grid-template-columns:repeat(6, minmax(0,1fr)); }
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-about__cta-wrap {
|
|
||||||
display:flex; justify-content:center; margin-top:.35rem; padding-top:.35rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-about__cta {
|
|
||||||
display:inline-flex; align-items:center; justify-content:center;
|
|
||||||
min-width:220px; padding:.7rem 1.35rem; border-radius:10px;
|
|
||||||
background:#52cca3; color:#00261a !important;
|
|
||||||
text-decoration:none !important; font-weight:700;
|
|
||||||
border:1px solid #3db892;
|
|
||||||
box-shadow:0 6px 16px rgba(0,38,26,.08);
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-about__cta:hover {
|
|
||||||
background:#6fd9b5; color:#00261a !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-settings-btn {
|
|
||||||
display:inline-flex; align-items:center; justify-content:center; gap:.45rem;
|
|
||||||
padding:.6rem 1.15rem; border-radius:10px; border:0; cursor:pointer;
|
|
||||||
background:#52cca3; color:#00261a !important;
|
|
||||||
text-decoration:none !important; font-weight:700;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-settings-btn:hover { background:#6fd9b5; color:#00261a !important; }
|
|
||||||
.path-admin .meetlet-settings-btn:disabled { opacity:.65; cursor:wait; }
|
|
||||||
.path-admin .meetlet-settings-btn svg {
|
|
||||||
width:1.1rem; height:1.1rem; flex:0 0 auto; display:block;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-license-actions {
|
|
||||||
display:flex; flex-wrap:wrap; gap:.55rem; align-items:center;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-license-actions .btn {
|
|
||||||
display:inline-flex; align-items:center; justify-content:center; gap:.45rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-license-actions .btn svg {
|
|
||||||
width:1.05rem; height:1.05rem; flex:0 0 auto; display:block;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-license-btn--free {
|
|
||||||
background: linear-gradient(180deg, #e6faf3 0%, #d4f5ea 100%) !important;
|
|
||||||
border: 2px solid #52cca3 !important;
|
|
||||||
color: #00261a !important;
|
|
||||||
border-radius: 10px !important;
|
|
||||||
font-weight: 700 !important;
|
|
||||||
padding: .6rem 1.15rem !important;
|
|
||||||
box-shadow: 0 4px 12px rgba(82, 204, 163, 0.18) !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-license-btn--free:hover,
|
|
||||||
.path-admin .meetlet-license-btn--free:focus {
|
|
||||||
background: linear-gradient(180deg, #6fd9b5 0%, #52cca3 100%) !important;
|
|
||||||
border-color: #3db892 !important;
|
|
||||||
color: #00261a !important;
|
|
||||||
box-shadow: 0 6px 16px rgba(82, 204, 163, 0.28) !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest { max-width:none; margin:0; }
|
|
||||||
.path-admin .meetlet-conntest__actions {
|
|
||||||
display:flex; flex-wrap:wrap; gap:.75rem; align-items:center;
|
|
||||||
margin:.85rem 0 1rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__status { color:#4a6b5f; font-size:.9rem; }
|
|
||||||
.path-admin .meetlet-conntest__progress {
|
|
||||||
margin:0 0 1rem; padding:.85rem 1rem;
|
|
||||||
border:1px solid #cfe8de; border-radius:12px; background:#f7fcfa;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__progress-label {
|
|
||||||
display:flex; justify-content:space-between; gap:.75rem;
|
|
||||||
margin:0 0 .45rem; color:#00261a; font-weight:650; font-size:.92rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__progress-track {
|
|
||||||
height:10px; border-radius:999px; background:#d9eee5; overflow:hidden;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__progress-fill {
|
|
||||||
height:100%; width:0; border-radius:999px;
|
|
||||||
background:linear-gradient(90deg, #2f9f7a, #52cca3);
|
|
||||||
transition:width .28s ease;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__num {
|
|
||||||
min-width:1.7rem; height:1.7rem; border-radius:8px;
|
|
||||||
display:inline-flex; align-items:center; justify-content:center;
|
|
||||||
background:#e6faf3; color:#00261a; font-weight:750; font-size:.85rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__card--pending { opacity:.78; background:#fbfefe; }
|
|
||||||
.path-admin .meetlet-conntest__card--running {
|
|
||||||
border-color:#e6b422;
|
|
||||||
box-shadow:0 0 0 2px rgba(230,180,34,.22);
|
|
||||||
background:#fff8e6;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__card--running .meetlet-conntest__num {
|
|
||||||
background:#ffe08a; color:#5c4700;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__card--ok {
|
|
||||||
border-color:#9fdcc4; background:#f3fbf8;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__card--fail {
|
|
||||||
border-color:#ead3d0; background:#fff8f7;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-conntest__card--skipped { opacity:.55; }
|
|
||||||
.path-admin .meetlet-dot--pending { background:#9bb7ac; box-shadow:0 0 0 4px rgba(155,183,172,.18); }
|
|
||||||
.path-admin .meetlet-dot--running {
|
|
||||||
background:#e6b422; box-shadow:0 0 0 4px rgba(230,180,34,.28);
|
|
||||||
animation:meetletPulse 1s ease-in-out infinite;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-dot--skipped { background:#b7c4be; box-shadow:none; }
|
|
||||||
.path-admin .meetlet-pill--pending { background:#e8efec; color:#456257; }
|
|
||||||
.path-admin .meetlet-pill--running { background:#ffe08a; color:#5c4700; }
|
|
||||||
.path-admin .meetlet-pill--skipped { background:#eef1f0; color:#667a72; }
|
|
||||||
@keyframes meetletPulse {
|
|
||||||
0%, 100% { transform:scale(1); opacity:1; }
|
|
||||||
50% { transform:scale(1.15); opacity:.75; }
|
|
||||||
}
|
|
||||||
.path-admin #adminsettings form.settingsform {
|
|
||||||
padding-bottom:1rem;
|
|
||||||
}
|
|
||||||
/* Single save row: spacing only — no stacked border/gradient bands. */
|
|
||||||
.path-admin #adminsettings .settingsform > .row:has(.btn-primary),
|
|
||||||
.path-admin #adminsettings .form-buttons,
|
|
||||||
.path-admin #adminsettings .btns-group {
|
|
||||||
margin-top:1.25rem !important;
|
|
||||||
padding:0;
|
|
||||||
border:0;
|
|
||||||
background:transparent;
|
|
||||||
border-radius:0;
|
|
||||||
}
|
|
||||||
.path-admin #adminsettings .meetlet-savebar {
|
|
||||||
margin-top: 1.25rem !important;
|
|
||||||
margin-right: 0 !important;
|
|
||||||
margin-left: 0 !important;
|
|
||||||
margin-inline: 0 !important;
|
|
||||||
flex: 0 0 100% !important;
|
|
||||||
max-width: 100% !important;
|
|
||||||
width: 100% !important;
|
|
||||||
padding: .35rem 0 !important;
|
|
||||||
border: 0 !important;
|
|
||||||
background: transparent !important;
|
|
||||||
border-radius: 0 !important;
|
|
||||||
}
|
|
||||||
@media (min-width: 576px) {
|
|
||||||
.path-admin #adminsettings .meetlet-savebar.offset-sm-3,
|
|
||||||
.path-admin #adminsettings .meetlet-savebar {
|
|
||||||
margin-right: 0 !important;
|
|
||||||
margin-left: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.path-admin #adminsettings .btn-primary,
|
|
||||||
.path-admin #adminsettings input[type="submit"].btn-primary,
|
|
||||||
.path-admin #adminsettings button[type="submit"].btn-primary,
|
|
||||||
.path-admin #adminsettings .meetlet-btn-with-icon.btn-primary {
|
|
||||||
background:#52cca3 !important;
|
|
||||||
border-color:#3db892 !important;
|
|
||||||
color:#00261a !important;
|
|
||||||
font-weight:700 !important;
|
|
||||||
border-radius:10px !important;
|
|
||||||
padding:.55rem 1.35rem !important;
|
|
||||||
box-shadow:none !important;
|
|
||||||
}
|
|
||||||
.path-admin #adminsettings .btn-primary:hover,
|
|
||||||
.path-admin #adminsettings input[type="submit"].btn-primary:hover,
|
|
||||||
.path-admin #adminsettings button[type="submit"].btn-primary:hover {
|
|
||||||
background:#6fd9b5 !important;
|
|
||||||
border-color:#52cca3 !important;
|
|
||||||
color:#00261a !important;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-btn-with-icon {
|
|
||||||
display:inline-flex !important;
|
|
||||||
align-items:center;
|
|
||||||
justify-content:center;
|
|
||||||
gap:.45rem;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-btn-with-icon svg {
|
|
||||||
width:1.1rem;
|
|
||||||
height:1.1rem;
|
|
||||||
flex:0 0 auto;
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-btn-with-icon__label {
|
|
||||||
line-height:1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.path-admin .meetlet-server-group {
|
|
||||||
margin:1.1rem 0 .4rem; padding:1rem 1.1rem .2rem;
|
|
||||||
border:1px solid #cfe8de; border-radius:12px;
|
|
||||||
background:linear-gradient(180deg, #f3fbf8 0%, #ffffff 60%);
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-server-group h4 {
|
|
||||||
margin:0 0 .25rem; color:#00261a; font-size:1.02rem; font-weight:700;
|
|
||||||
}
|
|
||||||
.path-admin .meetlet-server-group p {
|
|
||||||
margin:0 0 .55rem; color:#4a6b5f; font-size:.9rem; line-height:1.55;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RTL alignment for Persian/Arabic admin settings */
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .settingsform,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .tab-content,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item {
|
|
||||||
direction: rtl;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label.label,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label > label,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label .form-shortname,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-description,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-defaultinfo,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting .form-check,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting .checkbox,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting label,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings h3.main,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label.text-sm-end,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label.text-end {
|
|
||||||
text-align: right !important;
|
|
||||||
direction: rtl;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-feature-group,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-feature-group h4,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-feature-group p,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-settings-card,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-about,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-about p,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-about h4,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-privacy,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-privacy p,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-privacy h3,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-privacy h4,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest__intro,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest__title,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest__status,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest__progress-label,
|
|
||||||
html[dir="rtl"] .path-admin .meetlet-settings-hero,
|
|
||||||
html[dir="rtl"] .path-admin .meetlet-settings-hero h3,
|
|
||||||
html[dir="rtl"] .path-admin .meetlet-settings-hero .meetlet-settings-version,
|
|
||||||
html[dir="rtl"] .path-admin .meetlet-settings-hero p,
|
|
||||||
html[dir="rtl"] .path-admin .meetlet-settings-copy {
|
|
||||||
direction: rtl;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin .meetlet-settings-hero {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .nav-tabs {
|
|
||||||
direction: rtl;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting input[type="text"],
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting input[type="password"],
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting input[type="url"],
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting input[type="number"],
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting select,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting textarea {
|
|
||||||
direction: ltr;
|
|
||||||
text-align: left;
|
|
||||||
unicode-bidi: isolate;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting .form-check,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting .checkbox,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting .form-checkbox {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
gap: .5rem;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label .form-shortname {
|
|
||||||
direction: ltr;
|
|
||||||
unicode-bidi: isolate;
|
|
||||||
text-align: right !important;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting .form-checkbox {
|
|
||||||
direction: rtl;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-setting .defaultsnext {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .meetlet-savebar,
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-buttons {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script src="' . s($modalscrolljsurl->out(false)) . '" defer></script>
|
|
||||||
<script src="' . s($registrationjsurl->out(false)) . '" defer></script>
|
|
||||||
<script src="' . s($jsurl->out(false)) . '" defer></script>
|
|
||||||
<script src="' . s($togglejsurl->out(false)) . '" defer></script>
|
|
||||||
<script src="' . s($matrixjsurl->out(false)) . '" defer></script>
|
|
||||||
<script src="' . s($accessresetjsurl->out(false)) . '" defer></script>';
|
|
||||||
|
|
||||||
$plugin = new stdClass();
|
$plugin = new stdClass();
|
||||||
include(__DIR__ . '/version.php');
|
include(__DIR__ . '/version.php');
|
||||||
@@ -673,7 +59,7 @@ html[dir="rtl"] .path-admin #adminsettings .form-buttons {
|
|||||||
$versionbadge = $release !== ''
|
$versionbadge = $release !== ''
|
||||||
? html_writer::span(get_string('settingsversion', 'meetletacbfree', $release), 'meetlet-settings-version')
|
? html_writer::span(get_string('settingsversion', 'meetletacbfree', $release), 'meetlet-settings-version')
|
||||||
: '';
|
: '';
|
||||||
$hero = $styles . html_writer::div(
|
$hero = html_writer::div(
|
||||||
html_writer::img($logo, 'Adobe Connect', ['alt' => 'Adobe Connect']) .
|
html_writer::img($logo, 'Adobe Connect', ['alt' => 'Adobe Connect']) .
|
||||||
html_writer::div(
|
html_writer::div(
|
||||||
html_writer::tag('h3', get_string('pluginname', 'meetletacbfree')) .
|
html_writer::tag('h3', get_string('pluginname', 'meetletacbfree')) .
|
||||||
@@ -828,8 +214,6 @@ html[dir="rtl"] .path-admin #adminsettings .form-buttons {
|
|||||||
'meetlet-conntest',
|
'meetlet-conntest',
|
||||||
[
|
[
|
||||||
'id' => 'meetlet-acb-conntest',
|
'id' => 'meetlet-acb-conntest',
|
||||||
'data-endpoint' => $ajaxurl->out(false),
|
|
||||||
'data-sesskey' => sesskey(),
|
|
||||||
'data-steps' => implode(',', conntest_runner::STEPS),
|
'data-steps' => implode(',', conntest_runner::STEPS),
|
||||||
'data-step-labels' => json_encode($steplabels, JSON_UNESCAPED_UNICODE),
|
'data-step-labels' => json_encode($steplabels, JSON_UNESCAPED_UNICODE),
|
||||||
'data-str-ok' => get_string('testok', 'meetletacbfree'),
|
'data-str-ok' => get_string('testok', 'meetletacbfree'),
|
||||||
@@ -923,7 +307,7 @@ html[dir="rtl"] .path-admin #adminsettings .form-buttons {
|
|||||||
$page->add(new admin_setting_heading(
|
$page->add(new admin_setting_heading(
|
||||||
'meetletacbfree/accessresetassets',
|
'meetletacbfree/accessresetassets',
|
||||||
'',
|
'',
|
||||||
\mod_meetletacbfree\admin\access_reset_ui::page_assets($resetajaxurl)
|
\mod_meetletacbfree\admin\access_reset_ui::page_assets()
|
||||||
));
|
));
|
||||||
$settings->add($page);
|
$settings->add($page);
|
||||||
|
|
||||||
|
|||||||
+537
-22
@@ -1185,11 +1185,13 @@
|
|||||||
background: #c0392b;
|
background: #c0392b;
|
||||||
border-color: #c0392b;
|
border-color: #c0392b;
|
||||||
}
|
}
|
||||||
|
/* rtl:begin:ignore */
|
||||||
html[dir="rtl"] .meetlet-modal--confirm .meetlet-modal__title,
|
html[dir="rtl"] .meetlet-modal--confirm .meetlet-modal__title,
|
||||||
html[dir="rtl"] .meetlet-modal--confirm .meetlet-modal__body,
|
html[dir="rtl"] .meetlet-modal--confirm .meetlet-modal__body,
|
||||||
html[dir="rtl"] .meetlet-modal--confirm .meetlet-modal__lead {
|
html[dir="rtl"] .meetlet-modal--confirm .meetlet-modal__lead {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
/* rtl:end:ignore */
|
||||||
/* Marker class on html; lock scroll on body only — overflow+height on html resets scroll position. */
|
/* Marker class on html; lock scroll on body only — overflow+height on html resets scroll position. */
|
||||||
html.meetlet-modal-open body {
|
html.meetlet-modal-open body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -1349,7 +1351,7 @@ html.meetlet-modal-open body {
|
|||||||
transition: background .18s ease;
|
transition: background .18s ease;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
direction: ltr; /* Keep thumb travel physical LTR; icons stay readable. */
|
/* rtl:ignore */ direction: ltr; /* Keep thumb travel physical LTR; icons stay readable. */
|
||||||
}
|
}
|
||||||
.meetlet-switch__thumb {
|
.meetlet-switch__thumb {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -1405,20 +1407,20 @@ html.meetlet-modal-open body {
|
|||||||
.meetlet-access-cell .meetlet-switch {
|
.meetlet-access-cell .meetlet-switch {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.path-admin #adminsettings .form-item:has(.meetlet-switch) {
|
.meetlet-admin-settings .form-item:has(.meetlet-switch) {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
.path-admin #adminsettings .form-item:has(.meetlet-switch) > .form-setting {
|
.meetlet-admin-settings .form-item:has(.meetlet-switch) > .form-setting {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
/* Toward the label column: left in LTR, right in RTL. */
|
/* Toward the label column: left in LTR, right in RTL. */
|
||||||
align-items: start;
|
align-items: start;
|
||||||
}
|
}
|
||||||
.path-admin #adminsettings .form-item:has(.meetlet-switch) > .form-label,
|
.meetlet-admin-settings .form-item:has(.meetlet-switch) > .form-label,
|
||||||
.path-admin #adminsettings .form-item:has(.meetlet-switch) > .form-setting {
|
.meetlet-admin-settings .form-item:has(.meetlet-switch) > .form-setting {
|
||||||
padding-top: .4rem;
|
padding-top: .4rem;
|
||||||
}
|
}
|
||||||
.path-admin #adminsettings .form-item:has(.meetlet-switch) .form-label > label {
|
.meetlet-admin-settings .form-item:has(.meetlet-switch) .form-label > label {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
@@ -1426,9 +1428,9 @@ html.meetlet-modal-open body {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: 22px;
|
min-height: 22px;
|
||||||
}
|
}
|
||||||
.path-admin #adminsettings .form-item:has(.meetlet-switch) .form-check,
|
.meetlet-admin-settings .form-item:has(.meetlet-switch) .form-check,
|
||||||
.path-admin #adminsettings .form-item:has(.meetlet-switch) .checkbox,
|
.meetlet-admin-settings .form-item:has(.meetlet-switch) .checkbox,
|
||||||
.path-admin #adminsettings .form-item:has(.meetlet-switch) .form-checkbox {
|
.meetlet-admin-settings .form-item:has(.meetlet-switch) .form-checkbox {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -1441,14 +1443,16 @@ html.meetlet-modal-open body {
|
|||||||
width: auto;
|
width: auto;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item:has(.meetlet-switch) .form-check,
|
/* rtl:begin:ignore */
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item:has(.meetlet-switch) .checkbox,
|
html[dir="rtl"] .meetlet-admin-settings .form-item:has(.meetlet-switch) .form-check,
|
||||||
html[dir="rtl"] .path-admin #adminsettings .form-item:has(.meetlet-switch) .form-checkbox {
|
html[dir="rtl"] .meetlet-admin-settings .form-item:has(.meetlet-switch) .checkbox,
|
||||||
|
html[dir="rtl"] .meetlet-admin-settings .form-item:has(.meetlet-switch) .form-checkbox {
|
||||||
/* Keep switch on the label side (visual right), same as pre-compact layout. */
|
/* Keep switch on the label side (visual right), same as pre-compact layout. */
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
/* rtl:end:ignore */
|
||||||
|
|
||||||
/* Site admin: Moodle role → Adobe Connect role mapping (chip radios). */
|
/* Site admin: Moodle role → Adobe Connect role mapping (chip radios). */
|
||||||
.meetlet-rolemapping-table .meetlet-rolemapping-cell {
|
.meetlet-rolemapping-table .meetlet-rolemapping-cell {
|
||||||
@@ -1637,19 +1641,19 @@ html[dir="rtl"] .path-admin #adminsettings .form-item:has(.meetlet-switch) .form
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Cron & video-delivery dashboard (plugin settings) */
|
/* Cron & video-delivery dashboard (plugin settings) */
|
||||||
.path-admin #adminsettings .form-item:has(#meetlet-cronmon) {
|
.meetlet-admin-settings .form-item:has(#meetlet-cronmon) {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
.path-admin #adminsettings .form-item:has(#meetlet-cronmon) > .form-label,
|
.meetlet-admin-settings .form-item:has(#meetlet-cronmon) > .form-label,
|
||||||
.path-admin #adminsettings .form-item:has(#meetlet-cronmon) .form-description,
|
.meetlet-admin-settings .form-item:has(#meetlet-cronmon) .form-description,
|
||||||
.path-admin #adminsettings .form-item:has(#meetlet-cronmon) .form-defaultinfo,
|
.meetlet-admin-settings .form-item:has(#meetlet-cronmon) .form-defaultinfo,
|
||||||
.path-admin #adminsettings .form-item:has(#meetlet-cronmon) .form-setting > .form-shortname {
|
.meetlet-admin-settings .form-item:has(#meetlet-cronmon) .form-setting > .form-shortname {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
.path-admin #adminsettings .form-item:has(#meetlet-cronmon) > .form-setting {
|
.meetlet-admin-settings .form-item:has(#meetlet-cronmon) > .form-setting {
|
||||||
max-width: none;
|
max-width: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
float: none;
|
float: none;
|
||||||
@@ -2049,20 +2053,26 @@ html[dir="rtl"] .path-admin #adminsettings .form-item:has(.meetlet-switch) .form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html[dir="rtl"] .path-admin #adminsettings #id_s_meetletacbfree_agent_dispatch,
|
/* rtl:begin:ignore */
|
||||||
html[dir="rtl"] .path-admin #adminsettings select[name="s_meetletacbfree_agent_dispatch"] {
|
html[dir="rtl"] .meetlet-admin-settings #id_s_meetletacbfree_agent_dispatch,
|
||||||
|
html[dir="rtl"] .meetlet-admin-settings select[name="s_meetletacbfree_agent_dispatch"] {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
html[dir="rtl"] .path-admin #adminsettings #id_s_meetletacbfree_agent_dispatch option,
|
/* rtl:end:ignore */
|
||||||
html[dir="rtl"] .path-admin #adminsettings select[name="s_meetletacbfree_agent_dispatch"] option {
|
/* rtl:begin:ignore */
|
||||||
|
html[dir="rtl"] .meetlet-admin-settings #id_s_meetletacbfree_agent_dispatch option,
|
||||||
|
html[dir="rtl"] .meetlet-admin-settings select[name="s_meetletacbfree_agent_dispatch"] option {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
/* rtl:end:ignore */
|
||||||
|
/* rtl:begin:ignore */
|
||||||
html[dir="rtl"] .path-admin .meetlet-hourpicker,
|
html[dir="rtl"] .path-admin .meetlet-hourpicker,
|
||||||
html[dir="rtl"] .path-admin .meetlet-hourpresets {
|
html[dir="rtl"] .path-admin .meetlet-hourpresets {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
}
|
}
|
||||||
|
/* rtl:end:ignore */
|
||||||
|
|
||||||
.meetlet-gate-msg {
|
.meetlet-gate-msg {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
@@ -2200,3 +2210,508 @@ html[dir="rtl"] .path-admin .meetlet-hourpresets {
|
|||||||
.activityiconcontainer .activityicon[src*="mod/meetletacbfree"] {
|
.activityiconcontainer .activityicon[src*="mod/meetletacbfree"] {
|
||||||
filter: none !important;
|
filter: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== MeetLet admin settings (scoped under .meetlet-admin-settings) ===== */
|
||||||
|
.meetlet-admin-settings .settingsform > h2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-settings-hero {
|
||||||
|
display:flex; gap:1rem; align-items:center;
|
||||||
|
padding:1.15rem 1.25rem; margin:0 0 1rem;
|
||||||
|
border-radius:16px;
|
||||||
|
background:
|
||||||
|
radial-gradient(700px 180px at 100% 0%, rgba(82,204,163,.22), transparent 55%),
|
||||||
|
linear-gradient(135deg, #00261a 0%, #0a3d2e 60%, #145c45 100%);
|
||||||
|
color:#fff;
|
||||||
|
border:1px solid rgba(82,204,163,.25);
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-settings-hero img {
|
||||||
|
width:56px; height:56px; object-fit:contain;
|
||||||
|
background:rgba(255,255,255,.95); border-radius:12px; padding:6px;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-settings-hero h3 {
|
||||||
|
margin:0 0 .2rem; font-size:1.2rem; font-weight:700; color:#fff;
|
||||||
|
display:flex; flex-wrap:wrap; align-items:center; gap:.45rem .55rem;
|
||||||
|
}
|
||||||
|
/* rtl:begin:ignore */
|
||||||
|
.meetlet-admin-settings .meetlet-settings-hero .meetlet-settings-version {
|
||||||
|
display:inline-block;
|
||||||
|
flex:0 0 auto;
|
||||||
|
align-self:center;
|
||||||
|
margin-inline-start:auto;
|
||||||
|
padding:.12rem .55rem;
|
||||||
|
font-size:.72rem; font-weight:650; line-height:1.35;
|
||||||
|
letter-spacing:.02em;
|
||||||
|
border-radius:999px;
|
||||||
|
background:rgba(82,204,163,.18);
|
||||||
|
border:1px solid rgba(82,204,163,.35);
|
||||||
|
color:#b8f5df;
|
||||||
|
white-space:nowrap;
|
||||||
|
direction:ltr;
|
||||||
|
unicode-bidi:isolate;
|
||||||
|
}
|
||||||
|
/* rtl:end:ignore */
|
||||||
|
.meetlet-admin-settings .meetlet-settings-hero p {
|
||||||
|
margin:0; opacity:.85; color:#e6faf3;
|
||||||
|
white-space:nowrap;
|
||||||
|
max-width:none;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-settings-copy {
|
||||||
|
min-width:0; flex:1 1 auto;
|
||||||
|
}
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.meetlet-admin-settings .meetlet-settings-hero p {
|
||||||
|
white-space:normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .nav-tabs {
|
||||||
|
border-bottom:2px solid #cfe8de;
|
||||||
|
gap:.2rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .nav-tabs .nav-link {
|
||||||
|
border:0 !important;
|
||||||
|
border-radius:6px !important;
|
||||||
|
padding:.45rem .9rem;
|
||||||
|
color:#00261a;
|
||||||
|
font-weight:650;
|
||||||
|
box-shadow:none !important;
|
||||||
|
outline:none !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .nav-tabs .nav-link:hover {
|
||||||
|
background:#e6faf3; color:#00261a;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .nav-tabs .nav-link.active {
|
||||||
|
background:#52cca3; color:#00261a;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .nav-tabs .nav-link:focus,
|
||||||
|
.meetlet-admin-settings .nav-tabs .nav-link:focus-visible,
|
||||||
|
.meetlet-admin-settings .nav-tabs .nav-link:active {
|
||||||
|
outline:none !important;
|
||||||
|
box-shadow:none !important;
|
||||||
|
border:0 !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-feature-group {
|
||||||
|
margin:1rem 0 .35rem;
|
||||||
|
padding:1rem 1.1rem .35rem;
|
||||||
|
border:1px solid #cfe8de;
|
||||||
|
border-radius:12px;
|
||||||
|
background:linear-gradient(180deg, #f3fbf8 0%, #ffffff 55%);
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-feature-group h4 {
|
||||||
|
margin:0 0 .25rem; color:#00261a; font-size:1.02rem; font-weight:700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-feature-group p {
|
||||||
|
margin:0 0 .5rem; color:#4a6b5f; font-size:.9rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-settings-card {
|
||||||
|
background:#fff; border:1px solid #cfe8de; border-radius:14px;
|
||||||
|
padding:1rem 1.15rem; margin:.35rem 0 1rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-license-badge {
|
||||||
|
font-weight: 700;
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: .35rem .65rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-license-badge--active {
|
||||||
|
background: var(--ml-green, #52cca3);
|
||||||
|
color: var(--ml-green-deep, #00261a);
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-license-badge--inactive {
|
||||||
|
background: #fff4d6;
|
||||||
|
color: #5a4700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings #meetlet-license-modal.meetlet-modal,
|
||||||
|
.meetlet-admin-settings #meetlet-registration-modal.meetlet-modal,
|
||||||
|
.meetlet-admin-settings #meetlet-cronmon-modal.meetlet-modal,
|
||||||
|
.meetlet-admin-settings #meetlet-access-reset-modal.meetlet-modal {
|
||||||
|
z-index: 20000 !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-access-reset-toolbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin: 0 0 .65rem;
|
||||||
|
}
|
||||||
|
/* Cron videos ops cell: no extra cell/wrapper border (icon buttons keep theirs). */
|
||||||
|
.meetlet-admin-settings .meetlet-cronmon__table td.meetlet-cronmon__dl {
|
||||||
|
border-left: 0 !important;
|
||||||
|
border-right: 0 !important;
|
||||||
|
border-top: 0 !important;
|
||||||
|
background: transparent !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-cronmon__dl .meetlet-iconactions {
|
||||||
|
border: 0 !important;
|
||||||
|
background: transparent !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal--confirm .meetlet-modal__dialog {
|
||||||
|
width: min(480px, 100%);
|
||||||
|
max-height: min(86vh, 640px);
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal--confirm .meetlet-modal__head {
|
||||||
|
padding: 1.2rem 1.15rem 1rem;
|
||||||
|
border-radius: 18px 18px 0 0;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__lead {
|
||||||
|
margin: 0 0 .85rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: 1.65;
|
||||||
|
color: #00261a;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__callout {
|
||||||
|
margin: 0 0 .9rem;
|
||||||
|
padding: .85rem 1rem .7rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid #e6c56a;
|
||||||
|
background: #fff8e6;
|
||||||
|
color: #5a4700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__callout-title {
|
||||||
|
margin: 0 0 .4rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__limits {
|
||||||
|
margin: 0 0 .55rem;
|
||||||
|
padding-inline-start: 1.2rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__keep {
|
||||||
|
margin: 0;
|
||||||
|
color: #334942;
|
||||||
|
line-height: 1.65;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__foot {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
gap: .6rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: .9rem 1.15rem 1.05rem;
|
||||||
|
border-top: 1px solid #cfe8de;
|
||||||
|
background: linear-gradient(180deg, #f7fcfa 0%, #ffffff 70%);
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__foot .btn {
|
||||||
|
border-radius: 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: .5rem 1.15rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__foot .btn-success {
|
||||||
|
background: #52cca3 !important;
|
||||||
|
border-color: #3db892 !important;
|
||||||
|
color: #00261a !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__foot .btn-outline-danger {
|
||||||
|
color: #a33b3b !important;
|
||||||
|
border-color: #d9a0a0 !important;
|
||||||
|
background: #fff !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-modal__foot .btn-outline-danger:hover,
|
||||||
|
.meetlet-admin-settings .meetlet-modal__foot .btn-outline-danger:focus {
|
||||||
|
color: #fff !important;
|
||||||
|
background: #c0392b !important;
|
||||||
|
border-color: #c0392b !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-about {
|
||||||
|
display:grid; gap:1.1rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-about__brand {
|
||||||
|
display:flex; justify-content:center; align-items:center;
|
||||||
|
padding:1.35rem 1.2rem;
|
||||||
|
border-radius:14px;
|
||||||
|
background:#f0f2f4;
|
||||||
|
border:1px solid #e2e6ea;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-about__brand img {
|
||||||
|
max-width:240px; width:100%; height:auto; display:block; margin:0 auto;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-about h4 { margin:0 0 .55rem; color:#00261a; }
|
||||||
|
.meetlet-admin-settings .meetlet-about p {
|
||||||
|
margin:0 0 .85rem; color:#334942; line-height:1.75; text-align:start;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide { display:grid; gap:1rem; }
|
||||||
|
.meetlet-admin-settings .meetlet-guide__heading { margin:0; color:#00261a; font-size:1.15rem; }
|
||||||
|
.meetlet-admin-settings .meetlet-guide__intro {
|
||||||
|
margin:0; color:#334942; line-height:1.7;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__callout {
|
||||||
|
padding:.85rem 1rem; border-radius:10px; line-height:1.65;
|
||||||
|
border:1px solid #e6c56a; background:#fff8e6; color:#5a4700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__section {
|
||||||
|
padding:1rem 1.05rem; border-radius:12px;
|
||||||
|
border:1px solid #cfe8de; background:#f7fcfa;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__section--current { background:#fff; }
|
||||||
|
.meetlet-admin-settings .meetlet-guide__section h4 {
|
||||||
|
margin:0 0 .55rem; color:#00261a; font-size:1.02rem; font-weight:700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__section h5 {
|
||||||
|
margin:.85rem 0 .35rem; color:#0a3d2e; font-size:.95rem; font-weight:700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__body,
|
||||||
|
.meetlet-admin-settings .meetlet-guide__body p,
|
||||||
|
.meetlet-admin-settings .meetlet-guide__body li {
|
||||||
|
color:#334942; line-height:1.7;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__body p { margin:0 0 .55rem; }
|
||||||
|
.meetlet-admin-settings .meetlet-guide__body ol,
|
||||||
|
.meetlet-admin-settings .meetlet-guide__body ul { margin:0 0 .35rem; padding-inline-start:1.25rem; }
|
||||||
|
.meetlet-admin-settings .meetlet-guide__body li { margin:0 0 .35rem; }
|
||||||
|
.meetlet-admin-settings .meetlet-guide__body code,
|
||||||
|
.meetlet-admin-settings .meetlet-guide__table code {
|
||||||
|
font-size:.88em; padding:.05rem .3rem; border-radius:4px;
|
||||||
|
background:#e6faf3; color:#00261a;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__table {
|
||||||
|
width:100%; margin:.35rem 0 0; border-collapse:collapse;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__table th,
|
||||||
|
.meetlet-admin-settings .meetlet-guide__table td {
|
||||||
|
padding:.45rem .55rem; border:1px solid #cfe8de; vertical-align:top;
|
||||||
|
text-align:start;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__table thead th,
|
||||||
|
.meetlet-admin-settings .meetlet-guide__table tbody th {
|
||||||
|
background:#e6faf3; color:#00261a; font-weight:650;
|
||||||
|
}
|
||||||
|
/* rtl:begin:ignore */
|
||||||
|
.meetlet-admin-settings .meetlet-guide__code {
|
||||||
|
margin:.35rem 0 0; padding:.75rem .9rem; overflow-x:auto;
|
||||||
|
border-radius:10px; border:1px solid #cfe8de;
|
||||||
|
background:#0a3d2e; color:#e6faf3;
|
||||||
|
font-size:.82rem; line-height:1.45; direction:ltr; text-align:left;
|
||||||
|
white-space:pre;
|
||||||
|
}
|
||||||
|
/* rtl:end:ignore */
|
||||||
|
.meetlet-admin-settings .meetlet-guide__code-cell code {
|
||||||
|
font-weight:800; letter-spacing:.02em; direction:ltr; unicode-bidi:isolate;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__table td ol,
|
||||||
|
.meetlet-admin-settings .meetlet-guide__table td ul {
|
||||||
|
margin:.15rem 0 0; padding-inline-start:1.15rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-guide__table td li { margin:0 0 .25rem; }
|
||||||
|
.meetlet-admin-settings .meetlet-hourpicker { max-width: 42rem; }
|
||||||
|
.meetlet-admin-settings .meetlet-hourpicker.is-dimmed,
|
||||||
|
.meetlet-admin-settings .form-item.is-dimmed {
|
||||||
|
opacity: .45;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-hourpicker__tz {
|
||||||
|
margin: 0 0 .55rem; color:#4a6b5f; font-size:.88rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-hourpresets {
|
||||||
|
display:flex; flex-wrap:wrap; gap:.4rem; margin:0 0 .65rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-hourpreset {
|
||||||
|
border:1px solid #9fdcc4; background:#fff; color:#00261a;
|
||||||
|
border-radius:999px; padding:.28rem .7rem; font-size:.8rem; font-weight:650;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-hourpreset:hover { background:#e6faf3; }
|
||||||
|
.meetlet-admin-settings .meetlet-hourpreset--ghost { border-color:#cfe8de; color:#4a6b5f; }
|
||||||
|
.meetlet-admin-settings .meetlet-hourgrid {
|
||||||
|
display:grid; grid-template-columns:repeat(8, minmax(0,1fr)); gap:.35rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-hourchip {
|
||||||
|
border:1px solid #cfe8de; background:#f7fcfa; color:#00261a;
|
||||||
|
border-radius:10px; padding:.45rem 0; font-size:.82rem; font-weight:750;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-hourchip.is-on {
|
||||||
|
background:#52cca3; border-color:#0d9f6e; color:#00261a;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-hourchip.is-now { box-shadow:0 0 0 2px rgba(13,159,110,.35); }
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.meetlet-admin-settings .meetlet-hourgrid { grid-template-columns:repeat(6, minmax(0,1fr)); }
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-about__cta-wrap {
|
||||||
|
display:flex; justify-content:center; margin-top:.35rem; padding-top:.35rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-about__cta {
|
||||||
|
display:inline-flex; align-items:center; justify-content:center;
|
||||||
|
min-width:220px; padding:.7rem 1.35rem; border-radius:10px;
|
||||||
|
background:#52cca3; color:#00261a !important;
|
||||||
|
text-decoration:none !important; font-weight:700;
|
||||||
|
border:1px solid #3db892;
|
||||||
|
box-shadow:0 6px 16px rgba(0,38,26,.08);
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-about__cta:hover {
|
||||||
|
background:#6fd9b5; color:#00261a !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-settings-btn {
|
||||||
|
display:inline-flex; align-items:center; justify-content:center; gap:.45rem;
|
||||||
|
padding:.6rem 1.15rem; border-radius:10px; border:0; cursor:pointer;
|
||||||
|
background:#52cca3; color:#00261a !important;
|
||||||
|
text-decoration:none !important; font-weight:700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-settings-btn:hover { background:#6fd9b5; color:#00261a !important; }
|
||||||
|
.meetlet-admin-settings .meetlet-settings-btn:disabled { opacity:.65; cursor:wait; }
|
||||||
|
.meetlet-admin-settings .meetlet-settings-btn svg {
|
||||||
|
width:1.1rem; height:1.1rem; flex:0 0 auto; display:block;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-license-actions {
|
||||||
|
display:flex; flex-wrap:wrap; gap:.55rem; align-items:center;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-license-actions .btn {
|
||||||
|
display:inline-flex; align-items:center; justify-content:center; gap:.45rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-license-actions .btn svg {
|
||||||
|
width:1.05rem; height:1.05rem; flex:0 0 auto; display:block;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-license-btn--free {
|
||||||
|
background: linear-gradient(180deg, #e6faf3 0%, #d4f5ea 100%) !important;
|
||||||
|
border: 2px solid #52cca3 !important;
|
||||||
|
color: #00261a !important;
|
||||||
|
border-radius: 10px !important;
|
||||||
|
font-weight: 700 !important;
|
||||||
|
padding: .6rem 1.15rem !important;
|
||||||
|
box-shadow: 0 4px 12px rgba(82, 204, 163, 0.18) !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-license-btn--free:hover,
|
||||||
|
.meetlet-admin-settings .meetlet-license-btn--free:focus {
|
||||||
|
background: linear-gradient(180deg, #6fd9b5 0%, #52cca3 100%) !important;
|
||||||
|
border-color: #3db892 !important;
|
||||||
|
color: #00261a !important;
|
||||||
|
box-shadow: 0 6px 16px rgba(82, 204, 163, 0.28) !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest { max-width:none; margin:0; }
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__actions {
|
||||||
|
display:flex; flex-wrap:wrap; gap:.75rem; align-items:center;
|
||||||
|
margin:.85rem 0 1rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__status { color:#4a6b5f; font-size:.9rem; }
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__progress {
|
||||||
|
margin:0 0 1rem; padding:.85rem 1rem;
|
||||||
|
border:1px solid #cfe8de; border-radius:12px; background:#f7fcfa;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__progress-label {
|
||||||
|
display:flex; justify-content:space-between; gap:.75rem;
|
||||||
|
margin:0 0 .45rem; color:#00261a; font-weight:650; font-size:.92rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__progress-track {
|
||||||
|
height:10px; border-radius:999px; background:#d9eee5; overflow:hidden;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__progress-fill {
|
||||||
|
height:100%; width:0; border-radius:999px;
|
||||||
|
background:linear-gradient(90deg, #2f9f7a, #52cca3);
|
||||||
|
transition:width .28s ease;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__num {
|
||||||
|
min-width:1.7rem; height:1.7rem; border-radius:8px;
|
||||||
|
display:inline-flex; align-items:center; justify-content:center;
|
||||||
|
background:#e6faf3; color:#00261a; font-weight:750; font-size:.85rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__card--pending { opacity:.78; background:#fbfefe; }
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__card--running {
|
||||||
|
border-color:#e6b422;
|
||||||
|
box-shadow:0 0 0 2px rgba(230,180,34,.22);
|
||||||
|
background:#fff8e6;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__card--running .meetlet-conntest__num {
|
||||||
|
background:#ffe08a; color:#5c4700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__card--ok {
|
||||||
|
border-color:#9fdcc4; background:#f3fbf8;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__card--fail {
|
||||||
|
border-color:#ead3d0; background:#fff8f7;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-conntest__card--skipped { opacity:.55; }
|
||||||
|
.meetlet-admin-settings .meetlet-dot--pending { background:#9bb7ac; box-shadow:0 0 0 4px rgba(155,183,172,.18); }
|
||||||
|
.meetlet-admin-settings .meetlet-dot--running {
|
||||||
|
background:#e6b422; box-shadow:0 0 0 4px rgba(230,180,34,.28);
|
||||||
|
animation:meetletPulse 1s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-dot--skipped { background:#b7c4be; box-shadow:none; }
|
||||||
|
.meetlet-admin-settings .meetlet-pill--pending { background:#e8efec; color:#456257; }
|
||||||
|
.meetlet-admin-settings .meetlet-pill--running { background:#ffe08a; color:#5c4700; }
|
||||||
|
.meetlet-admin-settings .meetlet-pill--skipped { background:#eef1f0; color:#667a72; }
|
||||||
|
@keyframes meetletPulse {
|
||||||
|
0%, 100% { transform:scale(1); opacity:1; }
|
||||||
|
50% { transform:scale(1.15); opacity:.75; }
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings form.settingsform {
|
||||||
|
padding-bottom:1rem;
|
||||||
|
}
|
||||||
|
/* Single save row: spacing only — no stacked border/gradient bands. */
|
||||||
|
.meetlet-admin-settings .settingsform > .row:has(.btn-primary),
|
||||||
|
.meetlet-admin-settings .form-buttons,
|
||||||
|
.meetlet-admin-settings .btns-group {
|
||||||
|
margin-top:1.25rem !important;
|
||||||
|
padding:0;
|
||||||
|
border:0;
|
||||||
|
background:transparent;
|
||||||
|
border-radius:0;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-savebar {
|
||||||
|
margin-top: 1.25rem !important;
|
||||||
|
margin-right: 0 !important;
|
||||||
|
margin-left: 0 !important;
|
||||||
|
margin-inline: 0 !important;
|
||||||
|
flex: 0 0 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: 100% !important;
|
||||||
|
padding: .35rem 0 !important;
|
||||||
|
border: 0 !important;
|
||||||
|
background: transparent !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
@media (min-width: 576px) {
|
||||||
|
.meetlet-admin-settings .meetlet-savebar.offset-sm-3,
|
||||||
|
.meetlet-admin-settings .meetlet-savebar {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .btn-primary,
|
||||||
|
.meetlet-admin-settings input[type="submit"].btn-primary,
|
||||||
|
.meetlet-admin-settings button[type="submit"].btn-primary,
|
||||||
|
.meetlet-admin-settings .meetlet-btn-with-icon.btn-primary {
|
||||||
|
background:#52cca3 !important;
|
||||||
|
border-color:#3db892 !important;
|
||||||
|
color:#00261a !important;
|
||||||
|
font-weight:700 !important;
|
||||||
|
border-radius:10px !important;
|
||||||
|
padding:.55rem 1.35rem !important;
|
||||||
|
box-shadow:none !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .btn-primary:hover,
|
||||||
|
.meetlet-admin-settings input[type="submit"].btn-primary:hover,
|
||||||
|
.meetlet-admin-settings button[type="submit"].btn-primary:hover {
|
||||||
|
background:#6fd9b5 !important;
|
||||||
|
border-color:#52cca3 !important;
|
||||||
|
color:#00261a !important;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-btn-with-icon {
|
||||||
|
display:inline-flex !important;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:center;
|
||||||
|
gap:.45rem;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-btn-with-icon svg {
|
||||||
|
width:1.1rem;
|
||||||
|
height:1.1rem;
|
||||||
|
flex:0 0 auto;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-btn-with-icon__label {
|
||||||
|
line-height:1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meetlet-admin-settings .meetlet-server-group {
|
||||||
|
margin:1.1rem 0 .4rem; padding:1rem 1.1rem .2rem;
|
||||||
|
border:1px solid #cfe8de; border-radius:12px;
|
||||||
|
background:linear-gradient(180deg, #f3fbf8 0%, #ffffff 60%);
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-server-group h4 {
|
||||||
|
margin:0 0 .25rem; color:#00261a; font-size:1.02rem; font-weight:700;
|
||||||
|
}
|
||||||
|
.meetlet-admin-settings .meetlet-server-group p {
|
||||||
|
margin:0 0 .55rem; color:#4a6b5f; font-size:.9rem; line-height:1.55;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,23 @@
|
|||||||
|
{{!
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
@template mod_meetletacbfree/participant_form_add
|
||||||
|
@copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
@license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
}}
|
||||||
<tr id="participant_list_tr_{{selectiontypevalue}}-{{selectionvalue}}">
|
<tr id="participant_list_tr_{{selectiontypevalue}}-{{selectionvalue}}">
|
||||||
<td class="participant_list_c0"><b><i>{{participanttype}}</i></b></td>
|
<td class="participant_list_c0"><b><i>{{participanttype}}</i></b></td>
|
||||||
<td class="participant_list_c1">{{participantvalue}}</td>
|
<td class="participant_list_c1">{{participantvalue}}</td>
|
||||||
|
|||||||
@@ -1,3 +1,23 @@
|
|||||||
|
{{!
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
@template mod_meetletacbfree/participant_single_select
|
||||||
|
@copyright 2026 MeetLet <info@meetlet.net>
|
||||||
|
@license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
}}
|
||||||
<div class="{{classes}} d-inline-block">
|
<div class="{{classes}} d-inline-block">
|
||||||
{{#label}}
|
{{#label}}
|
||||||
<label for="{{id}}"{{#labelattributes}} {{name}}="{{value}}"{{/labelattributes}}>
|
<label for="{{id}}"{{#labelattributes}} {{name}}="{{value}}"{{/labelattributes}}>
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@
|
|||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
$plugin->component = 'mod_meetletacbfree';
|
$plugin->component = 'mod_meetletacbfree';
|
||||||
$plugin->version = 2026090153;
|
$plugin->version = 2026092002;
|
||||||
$plugin->requires = 2024100700; // Moodle 4.5+.
|
$plugin->requires = 2024100700; // Moodle 4.5+.
|
||||||
$plugin->supported = [405, 502]; // 4.5 LTS through 5.2.
|
$plugin->supported = [405, 502]; // 4.5 LTS through 5.2.
|
||||||
$plugin->maturity = MATURITY_STABLE;
|
$plugin->maturity = MATURITY_STABLE;
|
||||||
|
|||||||
@@ -48,9 +48,8 @@ $PAGE->set_title(format_string($meetlet->name));
|
|||||||
$PAGE->set_heading(format_string($course->fullname));
|
$PAGE->set_heading(format_string($course->fullname));
|
||||||
$PAGE->set_context($context);
|
$PAGE->set_context($context);
|
||||||
$PAGE->activityheader->disable();
|
$PAGE->activityheader->disable();
|
||||||
$PAGE->requires->css(new moodle_url('/mod/meetletacbfree/styles.css', ['v' => '2026082250']));
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/meetlet_modal_scroll', 'init');
|
||||||
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/meetlet_modal_scroll.js', ['v' => '2026082250']));
|
$PAGE->requires->js_call_amd('mod_meetletacbfree/view', 'init');
|
||||||
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/view.js', ['v' => '2026082250']));
|
|
||||||
|
|
||||||
if ($cm->groupmode) {
|
if ($cm->groupmode) {
|
||||||
$groupid = groups_get_activity_group($cm, true) ?: $groupid;
|
$groupid = groups_get_activity_group($cm, true) ?: $groupid;
|
||||||
|
|||||||
Reference in New Issue
Block a user