primo commit

This commit is contained in:
2024-12-17 17:34:10 +01:00
commit e650f8df99
16435 changed files with 2451012 additions and 0 deletions

View File

@ -0,0 +1,120 @@
import JoomlaDialog from 'joomla.dialog';
/**
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
/**
* Helper to create an element
*
* @param {String} nodeName
* @param {String} text
* @param {Array} classList
* @returns {HTMLElement}
*/
const createEl = (nodeName, text = '', classList = []) => {
const el = document.createElement(nodeName);
el.textContent = text;
if (classList && classList.length) {
el.classList.add(...classList);
}
return el;
};
/**
* Trigger the task through a GET request
*
* @param {String} url
* @param {HTMLElement} resultContainer
*/
const runTheTask = (url, resultContainer) => {
const statusHolder = resultContainer.querySelector('.scheduler-status');
const progressBar = resultContainer.querySelector('.progress-bar');
const complete = success => {
progressBar.style.width = '100%';
progressBar.classList.add(success ? 'bg-success' : 'bg-danger');
setTimeout(() => progressBar.classList.remove('progress-bar-animated'), 500);
};
progressBar.style.width = '15%';
fetch(url, {
headers: {
'X-CSRF-Token': Joomla.getOptions('csrf.token', '')
}
}).then(response => {
if (!response.ok) {
throw new Error(Joomla.Text._('JLIB_JS_AJAX_ERROR_OTHER').replace('%s', response.status).replace('%d', response.status));
}
return response.json();
}).then(output => {
if (!output.data) {
// The request was successful but the response is empty in some reason
throw new Error(Joomla.Text._('JLIB_JS_AJAX_ERROR_NO_CONTENT'));
}
statusHolder.textContent = Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_COMPLETED');
if (output.data.duration > 0) {
resultContainer.appendChild(createEl('div', Joomla.Text._('COM_SCHEDULER_TEST_RUN_DURATION').replace('%s', output.data.duration.toFixed(2))));
}
if (output.data.output) {
resultContainer.appendChild(createEl('div', Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', '').replace('<br>', '')));
resultContainer.appendChild(createEl('pre', output.data.output, ['bg-body', 'p-2']));
}
complete(true);
}).catch(error => {
complete(false);
statusHolder.textContent = Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED');
resultContainer.appendChild(createEl('div', error.message, ['text-danger']));
});
};
// Listen on click over a task button to run a task
document.addEventListener('click', event => {
const button = event.target.closest('button[data-scheduler-run]');
if (!button) return;
event.preventDefault();
// Get the task info from the button
const {
id,
title,
url
} = button.dataset;
// Prepare the initial popup content, by following template:
// <div class="p-3">
// <h4>Task: Task title</h4>
// <div class="mb-2 scheduler-status">Status: Task Status</div>
// <div class="progress mb-2"><div class="progress-bar progress-bar-striped bg-success"></div></div>
// </div>
const content = (() => {
const body = createEl('div', '', ['p-3']);
const progress = createEl('div', '', ['progress', 'mb-2']);
const progressBar = createEl('div', '', ['progress-bar', 'progress-bar-striped', 'progress-bar-animated']);
body.appendChild(createEl('h4', Joomla.Text._('COM_SCHEDULER_TEST_RUN_TASK').replace('%s', title)));
body.appendChild(createEl('div', Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_STARTED'), ['mb-2', 'scheduler-status']));
progress.appendChild(progressBar);
body.appendChild(progress);
progressBar.style.width = '0%';
return body;
})();
// Create dialog instance
const dialog = new JoomlaDialog({
popupType: 'inline',
textHeader: Joomla.Text._('COM_SCHEDULER_TEST_RUN_TITLE').replace('%d', id),
textClose: Joomla.Text._('JCLOSE'),
popupContent: content,
width: '800px',
height: 'fit-content'
});
// Run the task when dialog is ready
dialog.addEventListener('joomla-dialog:open', () => {
runTheTask(url, content);
});
// Reload the page when dialog is closed
dialog.addEventListener('joomla-dialog:close', () => {
window.location.reload();
});
dialog.show();
});

View File

@ -0,0 +1,4 @@
import i from"joomla.dialog";/**
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/const a=(r,t="",d=[])=>{const o=document.createElement(r);return o.textContent=t,d&&d.length&&o.classList.add(...d),o},c=(r,t)=>{const d=t.querySelector(".scheduler-status"),o=t.querySelector(".progress-bar"),s=e=>{o.style.width="100%",o.classList.add(e?"bg-success":"bg-danger"),setTimeout(()=>o.classList.remove("progress-bar-animated"),500)};o.style.width="15%",fetch(r,{headers:{"X-CSRF-Token":Joomla.getOptions("csrf.token","")}}).then(e=>{if(!e.ok)throw new Error(Joomla.Text._("JLIB_JS_AJAX_ERROR_OTHER").replace("%s",e.status).replace("%d",e.status));return e.json()}).then(e=>{if(!e.data)throw new Error(Joomla.Text._("JLIB_JS_AJAX_ERROR_NO_CONTENT"));d.textContent=Joomla.Text._("COM_SCHEDULER_TEST_RUN_STATUS_COMPLETED"),e.data.duration>0&&t.appendChild(a("div",Joomla.Text._("COM_SCHEDULER_TEST_RUN_DURATION").replace("%s",e.data.duration.toFixed(2)))),e.data.output&&(t.appendChild(a("div",Joomla.Text._("COM_SCHEDULER_TEST_RUN_OUTPUT").replace("%s","").replace("<br>",""))),t.appendChild(a("pre",e.data.output,["bg-body","p-2"]))),s(!0)}).catch(e=>{s(!1),d.textContent=Joomla.Text._("COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED"),t.appendChild(a("div",e.message,["text-danger"]))})};document.addEventListener("click",r=>{const t=r.target.closest("button[data-scheduler-run]");if(!t)return;r.preventDefault();const{id:d,title:o,url:s}=t.dataset,e=(()=>{const n=a("div","",["p-3"]),_=a("div","",["progress","mb-2"]),T=a("div","",["progress-bar","progress-bar-striped","progress-bar-animated"]);return n.appendChild(a("h4",Joomla.Text._("COM_SCHEDULER_TEST_RUN_TASK").replace("%s",o))),n.appendChild(a("div",Joomla.Text._("COM_SCHEDULER_TEST_RUN_STATUS_STARTED"),["mb-2","scheduler-status"])),_.appendChild(T),n.appendChild(_),T.style.width="0%",n})(),l=new i({popupType:"inline",textHeader:Joomla.Text._("COM_SCHEDULER_TEST_RUN_TITLE").replace("%d",d),textClose:Joomla.Text._("JCLOSE"),popupContent:e,width:"800px",height:"fit-content"});l.addEventListener("joomla-dialog:open",()=>{c(s,e)}),l.addEventListener("joomla-dialog:close",()=>{window.location.reload()}),l.show()});

View File

@ -0,0 +1,102 @@
/**
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
/**
* Add a keyboard event listener to the Select a Task Type search element.
*
* IMPORTANT! This script is meant to be loaded deferred. This means that a. it's non-blocking
* (the browser can load it whenever) and b. it doesn't need an on DOMContentLoaded event handler
* because the browser is guaranteed to execute it only after the DOM content has loaded, the
* whole point of it being deferred.
*
* The search box has a keyboard handler that fires every time you press a keyboard button or send
* a keypress with a touch / virtual keyboard. We then iterate all task type cards and check if
* the plain text (HTML stripped out) representation of the task title or description partially
* matches the text you entered in the search box. If it doesn't we add a Bootstrap class to hide
* the task.
*
* This way we limit the displayed tasks only to those searched.
*
* This feature follows progressive enhancement. The search box is hidden by default and only
* displayed when this JavaScript here executes. Furthermore, session storage is only used if it
* is available in the browser. That's a bit of a pain but makes sure things won't break in older
* browsers.
*
* Furthermore and to facilitate the user experience we auto-focus the search element which has a
* suitable title so that non-sighted users are not startled. This way we address both UX concerns
* and accessibility.
*
* Finally, the search string is saved into session storage on the assumption that the user is
* probably going to be creating multiple instances of the same task, one after another, as is
* typical when building a new Joomla! site.
*/
// Make sure the element exists i.e. a template override has not removed it.
const elSearch = document.getElementById('comSchedulerSelectSearch');
const elSearchContainer = document.getElementById('comSchedulerSelectSearchContainer');
const elSearchHeader = document.getElementById('comSchedulerSelectTypeHeader');
const elSearchResults = document.getElementById('comSchedulerSelectResultsContainer');
const alertElement = document.querySelector('.tasks-alert');
if (elSearch && elSearchContainer) {
// Add the keyboard event listener which performs the live search in the cards
elSearch.addEventListener('keyup', ({
target
}) => {
/** @type {KeyboardEvent} event */
const partialSearch = target.value;
let hasSearchResults = false; // Save the search string into session storage
if (typeof sessionStorage !== 'undefined') {
sessionStorage.setItem('Joomla.com_scheduler.new.search', partialSearch);
}
// Iterate over all the task cards
document.querySelectorAll('.comSchedulerSelectCard').forEach(card => {
// First remove the class which hide the task cards
card.classList.remove('d-none');
// An empty search string means that we should show everything
if (!partialSearch) {
return;
}
const cardHeader = card.querySelector('.new-task-title');
const cardBody = card.querySelector('.new-task-caption');
const title = cardHeader ? cardHeader.textContent : '';
const description = cardBody ? cardBody.textContent : '';
// If the task title and description dont match add a class to hide it.
if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) {
card.classList.add('d-none');
} else {
hasSearchResults = true;
}
});
if (hasSearchResults || !partialSearch) {
alertElement.classList.add('d-none');
elSearchHeader.classList.remove('d-none');
elSearchResults.classList.remove('d-none');
} else {
alertElement.classList.remove('d-none');
elSearchHeader.classList.add('d-none');
elSearchResults.classList.add('d-none');
}
});
// For reasons of progressive enhancement the search box is hidden by default.
elSearchContainer.classList.remove('d-none');
// Focus the just show element
elSearch.focus();
try {
if (typeof sessionStorage !== 'undefined') {
// Load the search string from session storage
elSearch.value = sessionStorage.getItem('Joomla.com_scheduler.new.search') || '';
// Trigger the keyboard handler event manually to initiate the search
elSearch.dispatchEvent(new KeyboardEvent('keyup'));
}
} catch (e) {
// This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :(
}
}

View File

@ -0,0 +1,4 @@
/**
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/const elSearch=document.getElementById("comSchedulerSelectSearch"),elSearchContainer=document.getElementById("comSchedulerSelectSearchContainer"),elSearchHeader=document.getElementById("comSchedulerSelectTypeHeader"),elSearchResults=document.getElementById("comSchedulerSelectResultsContainer"),alertElement=document.querySelector(".tasks-alert");if(elSearch&&elSearchContainer){elSearch.addEventListener("keyup",({target:s})=>{const e=s.value;let o=!1;typeof sessionStorage<"u"&&sessionStorage.setItem("Joomla.com_scheduler.new.search",e),document.querySelectorAll(".comSchedulerSelectCard").forEach(t=>{if(t.classList.remove("d-none"),!e)return;const n=t.querySelector(".new-task-title"),c=t.querySelector(".new-task-caption"),a=n?n.textContent:"",r=c?c.textContent:"";a&&!a.toLowerCase().includes(e.toLowerCase())&&r&&!r.toLowerCase().includes(e.toLowerCase())?t.classList.add("d-none"):o=!0}),o||!e?(alertElement.classList.add("d-none"),elSearchHeader.classList.remove("d-none"),elSearchResults.classList.remove("d-none")):(alertElement.classList.remove("d-none"),elSearchHeader.classList.add("d-none"),elSearchResults.classList.add("d-none"))}),elSearchContainer.classList.remove("d-none"),elSearch.focus();try{typeof sessionStorage<"u"&&(elSearch.value=sessionStorage.getItem("Joomla.com_scheduler.new.search")||"",elSearch.dispatchEvent(new KeyboardEvent("keyup")))}catch{}}

View File

@ -0,0 +1,54 @@
/**
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
if (!window.Joomla) {
throw new Error('Joomla API was not properly initialised!');
}
const copyToClipboardFallback = input => {
input.focus();
input.select();
try {
const copy = document.execCommand('copy');
if (copy) {
Joomla.renderMessages({
message: [Joomla.Text._('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS')]
});
} else {
Joomla.renderMessages({
error: [Joomla.Text._('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL')]
});
}
} catch (err) {
Joomla.renderMessages({
error: [err]
});
}
};
const copyToClipboard = () => {
const button = document.getElementById('link-copy');
button.addEventListener('click', ({
currentTarget
}) => {
const input = currentTarget.previousElementSibling;
if (!navigator.clipboard) {
copyToClipboardFallback(input);
return;
}
navigator.clipboard.writeText(input.value).then(() => {
Joomla.renderMessages({
message: [Joomla.Text._('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS')]
});
}, () => {
Joomla.renderMessages({
error: [Joomla.Text._('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL')]
});
});
});
};
const onBoot = () => {
copyToClipboard();
document.removeEventListener('DOMContentLoaded', onBoot);
};
document.addEventListener('DOMContentLoaded', onBoot);

View File

@ -0,0 +1,4 @@
/**
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/if(!window.Joomla)throw new Error("Joomla API was not properly initialised!");const copyToClipboardFallback=o=>{o.focus(),o.select();try{document.execCommand("copy")?Joomla.renderMessages({message:[Joomla.Text._("COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS")]}):Joomla.renderMessages({error:[Joomla.Text._("COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL")]})}catch(e){Joomla.renderMessages({error:[e]})}},copyToClipboard=()=>{document.getElementById("link-copy").addEventListener("click",({currentTarget:e})=>{const t=e.previousElementSibling;if(!navigator.clipboard){copyToClipboardFallback(t);return}navigator.clipboard.writeText(t.value).then(()=>{Joomla.renderMessages({message:[Joomla.Text._("COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS")]})},()=>{Joomla.renderMessages({error:[Joomla.Text._("COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL")]})})})},onBoot=()=>{copyToClipboard(),document.removeEventListener("DOMContentLoaded",onBoot)};document.addEventListener("DOMContentLoaded",onBoot);

Binary file not shown.