From ea36694976e97becbbd5737cf4c9a1efe7ab6210 Mon Sep 17 00:00:00 2001 From: Oliver Bartsch <bo@cedev.de> Date: Mon, 3 Jul 2023 19:20:56 +0200 Subject: [PATCH] [BUGFIX] Make parallel execution checkbox in scheduler working The markup is adjusted to make the "parallel execution" checkbox in the scheduler module edit view working again. Additionally, the checkbox is only displayed for recuring tasks, because it's always set to FALSE for tasks with single execution. Resolves: #101146 Releases: main, 12.4 Change-Id: I0bc595683565ab099ca2a78f7a0aaf1480255a8f Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/79674 Tested-by: Oliver Bartsch <bo@cedev.de> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Oliver Bartsch <bo@cedev.de> --- Build/Sources/TypeScript/scheduler/scheduler.ts | 1 + .../Classes/Controller/SchedulerModuleController.php | 2 +- .../Resources/Private/Partials/AddEditMultipleField.html | 4 ++-- .../sysext/scheduler/Resources/Public/JavaScript/scheduler.js | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Build/Sources/TypeScript/scheduler/scheduler.ts b/Build/Sources/TypeScript/scheduler/scheduler.ts index 74b899d19975..60b18791d907 100644 --- a/Build/Sources/TypeScript/scheduler/scheduler.ts +++ b/Build/Sources/TypeScript/scheduler/scheduler.ts @@ -162,6 +162,7 @@ class Scheduler { taskType = parseInt(taskType + '', 10); $('#task_end_col').toggle(taskType === 2); $('#task_frequency_row').toggle(taskType === 2); + $('#task_multiple_row').toggle(taskType === 2); } /** diff --git a/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php b/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php index 76ecf487a229..8b6836d4d063 100644 --- a/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php +++ b/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php @@ -448,7 +448,7 @@ class SchedulerModuleController 'end' => $parsedBody['end'] ?? ($taskType === AbstractTask::TYPE_RECURRING ? $taskExecution->getEnd() : 0), // Find current frequency field value depending on task type and interval vs. cron command 'frequency' => $parsedBody['frequency'] ?? ($taskType === AbstractTask::TYPE_RECURRING ? ($taskExecution->getInterval() ?: $taskExecution->getCronCmd()) : ''), - 'multiple' => (bool)($parsedBody['multiple'] ?? $taskExecution->getMultiple()), + 'multiple' => !($taskType === AbstractTask::TYPE_SINGLE) && (bool)($parsedBody['multiple'] ?? $taskExecution->getMultiple()), 'description' => $parsedBody['description'] ?? $task->getDescription(), ]; diff --git a/typo3/sysext/scheduler/Resources/Private/Partials/AddEditMultipleField.html b/typo3/sysext/scheduler/Resources/Private/Partials/AddEditMultipleField.html index de459da0f364..e269c8de0430 100644 --- a/typo3/sysext/scheduler/Resources/Private/Partials/AddEditMultipleField.html +++ b/typo3/sysext/scheduler/Resources/Private/Partials/AddEditMultipleField.html @@ -3,16 +3,16 @@ data-namespace-typo3-fluid="true" > -<div class="row"> +<div class="row" id="task_multiple_row"> <div class="form-group"> <label class="form-label" for="task_multiple"><f:translate key="LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.parallel.long"/></label> <div class="formengine-field-item"> <div class="form-wizards-wrap"> <div class="form-wizards-element"> + <input type="hidden" name="tx_scheduler[multiple]" value="0"> <div class="form-check form-switch"> <input class="form-check-input" type="checkbox" name="tx_scheduler[multiple]" value="1" id="task_multiple" {f:if(condition:currentData.multiple,then:'checked="checked"')}> </div> - <input type="hidden" name="tx_scheduler[multiple]" value="0"> </div> </div> </div> diff --git a/typo3/sysext/scheduler/Resources/Public/JavaScript/scheduler.js b/typo3/sysext/scheduler/Resources/Public/JavaScript/scheduler.js index 4f02b70bc814..046a4cce6bfb 100644 --- a/typo3/sysext/scheduler/Resources/Public/JavaScript/scheduler.js +++ b/typo3/sysext/scheduler/Resources/Public/JavaScript/scheduler.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import $ from"jquery";import SortableTable from"@typo3/backend/sortable-table.js";import DocumentSaveActions from"@typo3/backend/document-save-actions.js";import RegularEvent from"@typo3/core/event/regular-event.js";import Modal from"@typo3/backend/modal.js";import Icons from"@typo3/backend/icons.js";import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import PersistentStorage from"@typo3/backend/storage/persistent.js";import DateTimePicker from"@typo3/backend/date-time-picker.js";import{MultiRecordSelectionSelectors}from"@typo3/backend/multi-record-selection.js";import Severity from"@typo3/backend/severity.js";class Scheduler{constructor(){this.initializeEvents(),this.initializeDefaultStates(),this.initializeCloseConfirm(),DocumentSaveActions.getInstance().addPreSubmitCallback((()=>{let e=$("#task_class").val();e=e.toLowerCase().replace(/\\/g,"-"),$(".extraFields").appendTo($("#extraFieldsHidden")),$(".extra_fields_"+e).appendTo($("#extraFieldsSection"))}))}static updateClearableInputs(){const e=document.querySelectorAll(".t3js-clearable");e.length>0&&import("@typo3/backend/input/clearable.js").then((function(){e.forEach((e=>e.clearable()))}))}static updateElementBrowserTriggers(){document.querySelectorAll(".t3js-element-browser").forEach((e=>{const t=document.getElementById(e.dataset.triggerFor);e.dataset.params=t.name+"|||pages"}))}static resolveDefaultNumberOfDays(){const e=document.getElementById("task_tableGarbageCollection_numberOfDays");return null===e||void 0===e.dataset.defaultNumberOfDays?null:JSON.parse(e.dataset.defaultNumberOfDays)}static storeCollapseState(e,t){let a={};PersistentStorage.isset("moduleData.scheduler_manage")&&(a=PersistentStorage.get("moduleData.scheduler_manage"));const l={};l[e]=t?1:0,$.extend(a,l),PersistentStorage.set("moduleData.scheduler_manage",a)}actOnChangedTaskClass(e){let t=e.val();t=t.toLowerCase().replace(/\\/g,"-"),$(".extraFields").hide(),$(".extra_fields_"+t).show()}actOnChangedTaskType(e){this.toggleFieldsByTaskType($(e.currentTarget).val())}actOnChangeSchedulerTableGarbageCollectionAllTables(e){const t=$("#task_tableGarbageCollection_numberOfDays"),a=$("#task_tableGarbageCollection_table");if(e.prop("checked"))a.prop("disabled",!0),t.prop("disabled",!0);else{let e=parseInt(t.val(),10);if(e<1){const t=a.val(),l=Scheduler.resolveDefaultNumberOfDays();null!==l&&(e=l[t])}a.prop("disabled",!1),e>0&&t.prop("disabled",!1)}}actOnChangeSchedulerTableGarbageCollectionTable(e){const t=$("#task_tableGarbageCollection_numberOfDays"),a=Scheduler.resolveDefaultNumberOfDays();null!==a&&a[e.val()]>0?(t.prop("disabled",!1),t.val(a[e.val()])):(t.prop("disabled",!0),t.val(0))}toggleFieldsByTaskType(e){e=parseInt(e+"",10),$("#task_end_col").toggle(2===e),$("#task_frequency_row").toggle(2===e)}initializeEvents(){$("#task_class").on("change",(e=>{this.actOnChangedTaskClass($(e.currentTarget))})),$("#task_type").on("change",this.actOnChangedTaskType.bind(this)),$("#task_tableGarbageCollection_allTables").on("change",(e=>{this.actOnChangeSchedulerTableGarbageCollectionAllTables($(e.currentTarget))})),$("#task_tableGarbageCollection_table").on("change",(e=>{this.actOnChangeSchedulerTableGarbageCollectionTable($(e.currentTarget))})),$("[data-update-task-frequency]").on("change",(e=>{const t=$(e.currentTarget);$("#task_frequency").val(t.val()),t.val(t.attr("value")).trigger("blur")})),document.querySelectorAll("[data-scheduler-table]").forEach((e=>{new SortableTable(e)})),document.querySelectorAll("#tx_scheduler_form .t3js-datetimepicker").forEach((e=>DateTimePicker.initialize(e))),$(document).on("click",".t3js-element-browser",(e=>{e.preventDefault();const t=e.currentTarget;Modal.advanced({type:Modal.types.iframe,content:t.href+"&mode="+t.dataset.mode+"&bparams="+t.dataset.params,size:Modal.sizes.large})})),new RegularEvent("show.bs.collapse",this.toggleCollapseIcon.bind(this)).bindTo(document),new RegularEvent("hide.bs.collapse",this.toggleCollapseIcon.bind(this)).bindTo(document),new RegularEvent("multiRecordSelection:action:go",this.executeTasks.bind(this)).bindTo(document),new RegularEvent("multiRecordSelection:action:go_cron",this.executeTasks.bind(this)).bindTo(document),window.addEventListener("message",this.listenOnElementBrowser.bind(this))}initializeDefaultStates(){const e=$("#task_type");e.length&&this.toggleFieldsByTaskType(e.val());const t=$("#task_class");t.length&&(this.actOnChangedTaskClass(t),Scheduler.updateClearableInputs(),Scheduler.updateElementBrowserTriggers())}listenOnElementBrowser(e){if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;if("typo3:elementBrowser:elementAdded"===e.data.actionName){if(void 0===e.data.fieldName)throw"fieldName not defined in message";if(void 0===e.data.value)throw"value not defined in message";document.querySelector('input[name="'+e.data.fieldName+'"]').value=e.data.value.split("_").pop()}}toggleCollapseIcon(e){const t="hide.bs.collapse"===e.type,a=document.querySelector('.t3js-toggle-table[data-bs-target="#'+e.target.id+'"] .collapseIcon');null!==a&&Icons.getIcon(t?"actions-view-list-expand":"actions-view-list-collapse",Icons.sizes.small).then((e=>{a.innerHTML=e})),Scheduler.storeCollapseState($(e.target).data("table"),t)}executeTasks(e){const t=document.querySelector("#tx_scheduler_form");if(null===t)return;const a=[];if(e.detail.checkboxes.forEach((e=>{const t=e.closest(MultiRecordSelectionSelectors.elementSelector);null!==t&&t.dataset.taskId&&a.push(t.dataset.taskId)})),a.length){if("multiRecordSelection:action:go_cron"===e.type){const e=document.createElement("input");e.setAttribute("type","hidden"),e.setAttribute("name","scheduleCron"),e.setAttribute("value",a.join(",")),t.append(e)}else{const e=document.createElement("input");e.setAttribute("type","hidden"),e.setAttribute("name","execute"),e.setAttribute("value",a.join(",")),t.append(e)}t.submit()}}initializeCloseConfirm(){const e=document.querySelector("form[name=tx_scheduler_form]");if(!e)return;const t=new FormData(e);document.querySelector(".t3js-scheduler-close").addEventListener("click",(a=>{const l=new FormData(e),n=Object.fromEntries(t.entries()),s=Object.fromEntries(l.entries());if(JSON.stringify(n)!==JSON.stringify(s)||e.querySelector('input[value="add"]')){a.preventDefault();const t=a.target.href;Modal.confirm(TYPO3.lang["label.confirm.close_without_save.title"]||"Do you want to close without saving?",TYPO3.lang["label.confirm.close_without_save.content"]||"You currently have unsaved changes. Are you sure you want to discard these changes?",Severity.warning,[{text:TYPO3.lang["buttons.confirm.close_without_save.no"]||"No, I will continue editing",btnClass:"btn-default",name:"no",trigger:()=>Modal.dismiss()},{text:TYPO3.lang["buttons.confirm.close_without_save.yes"]||"Yes, discard my changes",btnClass:"btn-default",name:"yes",trigger:()=>{Modal.dismiss(),window.location.href=t}},{text:TYPO3.lang["buttons.confirm.save_and_close"]||"Save and close",btnClass:"btn-primary",name:"save",active:!0,trigger:()=>{Modal.dismiss();const t=document.createElement("input");t.type="hidden",t.value="saveclose",t.name="CMD",e.append(t),e.submit()}}])}}))}}export default new Scheduler; \ No newline at end of file +import $ from"jquery";import SortableTable from"@typo3/backend/sortable-table.js";import DocumentSaveActions from"@typo3/backend/document-save-actions.js";import RegularEvent from"@typo3/core/event/regular-event.js";import Modal from"@typo3/backend/modal.js";import Icons from"@typo3/backend/icons.js";import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import PersistentStorage from"@typo3/backend/storage/persistent.js";import DateTimePicker from"@typo3/backend/date-time-picker.js";import{MultiRecordSelectionSelectors}from"@typo3/backend/multi-record-selection.js";import Severity from"@typo3/backend/severity.js";class Scheduler{constructor(){this.initializeEvents(),this.initializeDefaultStates(),this.initializeCloseConfirm(),DocumentSaveActions.getInstance().addPreSubmitCallback((()=>{let e=$("#task_class").val();e=e.toLowerCase().replace(/\\/g,"-"),$(".extraFields").appendTo($("#extraFieldsHidden")),$(".extra_fields_"+e).appendTo($("#extraFieldsSection"))}))}static updateClearableInputs(){const e=document.querySelectorAll(".t3js-clearable");e.length>0&&import("@typo3/backend/input/clearable.js").then((function(){e.forEach((e=>e.clearable()))}))}static updateElementBrowserTriggers(){document.querySelectorAll(".t3js-element-browser").forEach((e=>{const t=document.getElementById(e.dataset.triggerFor);e.dataset.params=t.name+"|||pages"}))}static resolveDefaultNumberOfDays(){const e=document.getElementById("task_tableGarbageCollection_numberOfDays");return null===e||void 0===e.dataset.defaultNumberOfDays?null:JSON.parse(e.dataset.defaultNumberOfDays)}static storeCollapseState(e,t){let a={};PersistentStorage.isset("moduleData.scheduler_manage")&&(a=PersistentStorage.get("moduleData.scheduler_manage"));const l={};l[e]=t?1:0,$.extend(a,l),PersistentStorage.set("moduleData.scheduler_manage",a)}actOnChangedTaskClass(e){let t=e.val();t=t.toLowerCase().replace(/\\/g,"-"),$(".extraFields").hide(),$(".extra_fields_"+t).show()}actOnChangedTaskType(e){this.toggleFieldsByTaskType($(e.currentTarget).val())}actOnChangeSchedulerTableGarbageCollectionAllTables(e){const t=$("#task_tableGarbageCollection_numberOfDays"),a=$("#task_tableGarbageCollection_table");if(e.prop("checked"))a.prop("disabled",!0),t.prop("disabled",!0);else{let e=parseInt(t.val(),10);if(e<1){const t=a.val(),l=Scheduler.resolveDefaultNumberOfDays();null!==l&&(e=l[t])}a.prop("disabled",!1),e>0&&t.prop("disabled",!1)}}actOnChangeSchedulerTableGarbageCollectionTable(e){const t=$("#task_tableGarbageCollection_numberOfDays"),a=Scheduler.resolveDefaultNumberOfDays();null!==a&&a[e.val()]>0?(t.prop("disabled",!1),t.val(a[e.val()])):(t.prop("disabled",!0),t.val(0))}toggleFieldsByTaskType(e){e=parseInt(e+"",10),$("#task_end_col").toggle(2===e),$("#task_frequency_row").toggle(2===e),$("#task_multiple_row").toggle(2===e)}initializeEvents(){$("#task_class").on("change",(e=>{this.actOnChangedTaskClass($(e.currentTarget))})),$("#task_type").on("change",this.actOnChangedTaskType.bind(this)),$("#task_tableGarbageCollection_allTables").on("change",(e=>{this.actOnChangeSchedulerTableGarbageCollectionAllTables($(e.currentTarget))})),$("#task_tableGarbageCollection_table").on("change",(e=>{this.actOnChangeSchedulerTableGarbageCollectionTable($(e.currentTarget))})),$("[data-update-task-frequency]").on("change",(e=>{const t=$(e.currentTarget);$("#task_frequency").val(t.val()),t.val(t.attr("value")).trigger("blur")})),document.querySelectorAll("[data-scheduler-table]").forEach((e=>{new SortableTable(e)})),document.querySelectorAll("#tx_scheduler_form .t3js-datetimepicker").forEach((e=>DateTimePicker.initialize(e))),$(document).on("click",".t3js-element-browser",(e=>{e.preventDefault();const t=e.currentTarget;Modal.advanced({type:Modal.types.iframe,content:t.href+"&mode="+t.dataset.mode+"&bparams="+t.dataset.params,size:Modal.sizes.large})})),new RegularEvent("show.bs.collapse",this.toggleCollapseIcon.bind(this)).bindTo(document),new RegularEvent("hide.bs.collapse",this.toggleCollapseIcon.bind(this)).bindTo(document),new RegularEvent("multiRecordSelection:action:go",this.executeTasks.bind(this)).bindTo(document),new RegularEvent("multiRecordSelection:action:go_cron",this.executeTasks.bind(this)).bindTo(document),window.addEventListener("message",this.listenOnElementBrowser.bind(this))}initializeDefaultStates(){const e=$("#task_type");e.length&&this.toggleFieldsByTaskType(e.val());const t=$("#task_class");t.length&&(this.actOnChangedTaskClass(t),Scheduler.updateClearableInputs(),Scheduler.updateElementBrowserTriggers())}listenOnElementBrowser(e){if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;if("typo3:elementBrowser:elementAdded"===e.data.actionName){if(void 0===e.data.fieldName)throw"fieldName not defined in message";if(void 0===e.data.value)throw"value not defined in message";document.querySelector('input[name="'+e.data.fieldName+'"]').value=e.data.value.split("_").pop()}}toggleCollapseIcon(e){const t="hide.bs.collapse"===e.type,a=document.querySelector('.t3js-toggle-table[data-bs-target="#'+e.target.id+'"] .collapseIcon');null!==a&&Icons.getIcon(t?"actions-view-list-expand":"actions-view-list-collapse",Icons.sizes.small).then((e=>{a.innerHTML=e})),Scheduler.storeCollapseState($(e.target).data("table"),t)}executeTasks(e){const t=document.querySelector("#tx_scheduler_form");if(null===t)return;const a=[];if(e.detail.checkboxes.forEach((e=>{const t=e.closest(MultiRecordSelectionSelectors.elementSelector);null!==t&&t.dataset.taskId&&a.push(t.dataset.taskId)})),a.length){if("multiRecordSelection:action:go_cron"===e.type){const e=document.createElement("input");e.setAttribute("type","hidden"),e.setAttribute("name","scheduleCron"),e.setAttribute("value",a.join(",")),t.append(e)}else{const e=document.createElement("input");e.setAttribute("type","hidden"),e.setAttribute("name","execute"),e.setAttribute("value",a.join(",")),t.append(e)}t.submit()}}initializeCloseConfirm(){const e=document.querySelector("form[name=tx_scheduler_form]");if(!e)return;const t=new FormData(e);document.querySelector(".t3js-scheduler-close").addEventListener("click",(a=>{const l=new FormData(e),n=Object.fromEntries(t.entries()),s=Object.fromEntries(l.entries());if(JSON.stringify(n)!==JSON.stringify(s)||e.querySelector('input[value="add"]')){a.preventDefault();const t=a.target.href;Modal.confirm(TYPO3.lang["label.confirm.close_without_save.title"]||"Do you want to close without saving?",TYPO3.lang["label.confirm.close_without_save.content"]||"You currently have unsaved changes. Are you sure you want to discard these changes?",Severity.warning,[{text:TYPO3.lang["buttons.confirm.close_without_save.no"]||"No, I will continue editing",btnClass:"btn-default",name:"no",trigger:()=>Modal.dismiss()},{text:TYPO3.lang["buttons.confirm.close_without_save.yes"]||"Yes, discard my changes",btnClass:"btn-default",name:"yes",trigger:()=>{Modal.dismiss(),window.location.href=t}},{text:TYPO3.lang["buttons.confirm.save_and_close"]||"Save and close",btnClass:"btn-primary",name:"save",active:!0,trigger:()=>{Modal.dismiss();const t=document.createElement("input");t.type="hidden",t.value="saveclose",t.name="CMD",e.append(t),e.submit()}}])}}))}}export default new Scheduler; \ No newline at end of file -- GitLab