diff --git a/Build/Sources/TypeScript/scheduler/Resources/Public/TypeScript/Scheduler.ts b/Build/Sources/TypeScript/scheduler/Resources/Public/TypeScript/Scheduler.ts index 4f636fc79948773676af5ed205fc530bdaa5f365..46b1fd5c4597568757dd22b9beddcda153e4a915 100644 --- a/Build/Sources/TypeScript/scheduler/Resources/Public/TypeScript/Scheduler.ts +++ b/Build/Sources/TypeScript/scheduler/Resources/Public/TypeScript/Scheduler.ts @@ -24,7 +24,6 @@ import PersistentStorage = require('TYPO3/CMS/Backend/Storage/Persistent'); interface TableNumberMapping { [s: string]: number; } -declare let defaultNumberOfDays: TableNumberMapping; /** * Module: TYPO3/CMS/Scheduler/Scheduler @@ -40,6 +39,14 @@ class Scheduler { }); } + private static resolveDefaultNumberOfDays(): TableNumberMapping|null { + const element = document.getElementById('task_tableGarbageCollection_numberOfDays'); + if (element === null || typeof element.dataset.defaultNumberOfDays === 'undefined') { + return null; + } + return JSON.parse(element.dataset.defaultNumberOfDays) as TableNumberMapping + } + /** * Store task group collapse state in UC */ @@ -74,7 +81,7 @@ class Scheduler { * This method reacts on changes to the task class * It switches on or off the relevant extra fields */ - public actOnChangedTaskClass = (theSelector: JQuery): void => { + public actOnChangedTaskClass(theSelector: JQuery): void { let taskClass: string = theSelector.val(); taskClass = taskClass.toLowerCase().replace(/\\/g, '-'); @@ -87,14 +94,14 @@ class Scheduler { /** * This method reacts on changes to the type of a task, i.e. single or recurring */ - public actOnChangedTaskType = (evt: JQueryEventObject): void => { + public actOnChangedTaskType(evt: JQueryEventObject): void { this.toggleFieldsByTaskType($(evt.currentTarget).val()); } /** * This method reacts on field changes of all table field for table garbage collection task */ - public actOnChangeSchedulerTableGarbageCollectionAllTables = (theCheckbox: JQuery): void => { + public actOnChangeSchedulerTableGarbageCollectionAllTables(theCheckbox: JQuery): void { let $numberOfDays = $('#task_tableGarbageCollection_numberOfDays'); let $taskTableGarbageCollectionTable = $('#task_tableGarbageCollection_table'); if (theCheckbox.prop('checked')) { @@ -105,7 +112,8 @@ class Scheduler { let numberOfDays = parseInt($numberOfDays.val(), 10); if (numberOfDays < 1) { let selectedTable = $taskTableGarbageCollectionTable.val(); - if (typeof(defaultNumberOfDays[selectedTable]) !== 'undefined') { + const defaultNumberOfDays = Scheduler.resolveDefaultNumberOfDays(); + if (defaultNumberOfDays !== null) { numberOfDays = defaultNumberOfDays[selectedTable]; } } @@ -121,9 +129,10 @@ class Scheduler { * This methods set the 'number of days' field to the default expire period * of the selected table */ - public actOnChangeSchedulerTableGarbageCollectionTable = (theSelector: JQuery): void => { + public actOnChangeSchedulerTableGarbageCollectionTable(theSelector: JQuery): void { let $numberOfDays = $('#task_tableGarbageCollection_numberOfDays'); - if (defaultNumberOfDays[theSelector.val()] > 0) { + const defaultNumberOfDays = Scheduler.resolveDefaultNumberOfDays(); + if (defaultNumberOfDays !== null && defaultNumberOfDays[theSelector.val()] > 0) { $numberOfDays.prop('disabled', false); $numberOfDays.val(defaultNumberOfDays[theSelector.val()]); } else { @@ -135,7 +144,7 @@ class Scheduler { /** * Toggle the relevant form fields by task type */ - public toggleFieldsByTaskType = (taskType: number): void => { + public toggleFieldsByTaskType(taskType: number): void { // Single task option = 1, Recurring task option = 2 taskType = parseInt(taskType + '', 10); $('#task_end_col').toggle(taskType === 2); @@ -145,12 +154,12 @@ class Scheduler { /** * Registers listeners */ - public initializeEvents = (): void => { + public initializeEvents(): void { $('#task_class').on('change', (evt: JQueryEventObject): void => { this.actOnChangedTaskClass($(evt.currentTarget)); }); - $('#task_type').on('change', this.actOnChangedTaskType); + $('#task_type').on('change', this.actOnChangedTaskType.bind(this)); $('#task_tableGarbageCollection_allTables').on('change', (evt: JQueryEventObject): void => { this.actOnChangeSchedulerTableGarbageCollectionAllTables($(evt.currentTarget)); @@ -183,18 +192,18 @@ class Scheduler { }); }); - new RegularEvent('show.bs.collapse', this.toggleCollapseIcon).bindTo(document); - new RegularEvent('hide.bs.collapse', this.toggleCollapseIcon).bindTo(document); - new RegularEvent('multiRecordSelection:action:go', this.executeTasks).bindTo(document); - new RegularEvent('multiRecordSelection:action:go_cron', this.executeTasks).bindTo(document); + 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); + window.addEventListener('message', this.listenOnElementBrowser.bind(this)); } /** * Initialize default states */ - public initializeDefaultStates = (): void => { + public initializeDefaultStates(): void { let $taskType = $('#task_type'); if ($taskType.length) { this.toggleFieldsByTaskType($taskType.val()); @@ -206,7 +215,7 @@ class Scheduler { } } - private listenOnElementBrowser = (e: MessageEvent): void => { + private listenOnElementBrowser(e: MessageEvent): void { if (!MessageUtility.verifyOrigin(e.origin)) { throw 'Denied message sent by ' + e.origin; } @@ -226,7 +235,7 @@ class Scheduler { } } - private toggleCollapseIcon (e: Event): void { + private toggleCollapseIcon(e: Event): void { const isCollapsed: boolean = e.type === 'hide.bs.collapse'; const collapseIcon: HTMLElement = document.querySelector('.t3js-toggle-table[data-bs-target="#' + (e.target as HTMLElement).id + '"] .collapseIcon'); if (collapseIcon !== null) { @@ -239,7 +248,7 @@ class Scheduler { Scheduler.storeCollapseState($(e.target).data('table'), isCollapsed); } - private executeTasks (e: CustomEvent): void { + private executeTasks(e: CustomEvent): void { const form: HTMLFormElement = document.querySelector('#tx_scheduler_form'); if (form === null) { return; @@ -268,7 +277,7 @@ class Scheduler { form.submit(); } - }; + } } export = new Scheduler(); diff --git a/typo3/sysext/scheduler/Classes/Task/TableGarbageCollectionAdditionalFieldProvider.php b/typo3/sysext/scheduler/Classes/Task/TableGarbageCollectionAdditionalFieldProvider.php index 867a0f8e1e27f18a53f3b660a82919b41b9d20be..69c945bc91f4d96d2dd913fbb1dae39902c18828 100644 --- a/typo3/sysext/scheduler/Classes/Task/TableGarbageCollectionAdditionalFieldProvider.php +++ b/typo3/sysext/scheduler/Classes/Task/TableGarbageCollectionAdditionalFieldProvider.php @@ -17,6 +17,7 @@ namespace TYPO3\CMS\Scheduler\Task; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Messaging\FlashMessage; +use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Scheduler\AbstractAdditionalFieldProvider; use TYPO3\CMS\Scheduler\Controller\SchedulerModuleController; use TYPO3\CMS\Scheduler\Task\Enumeration\Action; @@ -130,9 +131,6 @@ class TableGarbageCollectionAdditionalFieldProvider extends AbstractAdditionalFi // Add table drop down html $fieldHtml[] = '<select class="form-select" name="' . $fieldName . '"' . $disabled . ' id="' . $fieldId . '">' . implode(LF, $options) . '</select>'; // Add js array for default 'number of days' values - $fieldHtml[] = '<script>/*<![CDATA[*/<!--'; - $fieldHtml[] = 'var defaultNumberOfDays = ' . json_encode($this->defaultNumberOfDays) . ';'; - $fieldHtml[] = '// -->/*]]>*/</script>'; $fieldConfiguration = [ 'code' => implode(LF, $fieldHtml), 'label' => 'LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.tableGarbageCollection.table', @@ -167,12 +165,21 @@ class TableGarbageCollectionAdditionalFieldProvider extends AbstractAdditionalFi } } } - if ($task && $task->allTables === true) { - $disabled = ' disabled="disabled"'; - } $fieldName = 'tx_scheduler[scheduler_tableGarbageCollection_numberOfDays]'; $fieldId = 'task_tableGarbageCollection_numberOfDays'; - $fieldHtml = '<input class="form-control" type="text" name="' . $fieldName . '" id="' . $fieldId . '"' . $disabled . ' value="' . (int)$taskInfo['scheduler_tableGarbageCollection_numberOfDays'] . '" size="4">'; + $attrs = [ + 'class' => 'form-control', + 'type' => 'text', + 'name' => $fieldName, + 'id' => $fieldId, + 'size' => '4', + 'value' => (string)(int)$taskInfo['scheduler_tableGarbageCollection_numberOfDays'], + 'data-default-number-of-days' => GeneralUtility::jsonEncodeForHtmlAttribute($this->defaultNumberOfDays, false), + ]; + if ($task && $task->allTables === true) { + $attrs['disabled'] = 'disabled'; + } + $fieldHtml = '<input ' . GeneralUtility::implodeAttributes($attrs, true) . '>'; $fieldConfiguration = [ 'code' => $fieldHtml, 'label' => 'LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.tableGarbageCollection.numberOfDays', diff --git a/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js b/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js index e28451739eac7ba2df666da2ae7f116114f071c4..3d763dd8f644edc3d5dde7ac49a350d9cc83a14a 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! */ -var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};define(["require","exports","jquery","TYPO3/CMS/Backend/DocumentSaveActions","TYPO3/CMS/Core/Event/RegularEvent","TYPO3/CMS/Backend/Modal","TYPO3/CMS/Backend/Icons","TYPO3/CMS/Backend/Utility/MessageUtility","TYPO3/CMS/Backend/Storage/Persistent","tablesort"],(function(e,t,a,l,s,n,o,i,d){"use strict";a=__importDefault(a),s=__importDefault(s);class r{constructor(){this.actOnChangedTaskClass=e=>{let t=e.val();t=t.toLowerCase().replace(/\\/g,"-"),a.default(".extraFields").hide(),a.default(".extra_fields_"+t).show()},this.actOnChangedTaskType=e=>{this.toggleFieldsByTaskType(a.default(e.currentTarget).val())},this.actOnChangeSchedulerTableGarbageCollectionAllTables=e=>{let t=a.default("#task_tableGarbageCollection_numberOfDays"),l=a.default("#task_tableGarbageCollection_table");if(e.prop("checked"))l.prop("disabled",!0),t.prop("disabled",!0);else{let e=parseInt(t.val(),10);if(e<1){let t=l.val();void 0!==defaultNumberOfDays[t]&&(e=defaultNumberOfDays[t])}l.prop("disabled",!1),e>0&&t.prop("disabled",!1)}},this.actOnChangeSchedulerTableGarbageCollectionTable=e=>{let t=a.default("#task_tableGarbageCollection_numberOfDays");defaultNumberOfDays[e.val()]>0?(t.prop("disabled",!1),t.val(defaultNumberOfDays[e.val()])):(t.prop("disabled",!0),t.val(0))},this.toggleFieldsByTaskType=e=>{e=parseInt(e+"",10),a.default("#task_end_col").toggle(2===e),a.default("#task_frequency_row").toggle(2===e)},this.initializeEvents=()=>{a.default("#task_class").on("change",e=>{this.actOnChangedTaskClass(a.default(e.currentTarget))}),a.default("#task_type").on("change",this.actOnChangedTaskType),a.default("#task_tableGarbageCollection_allTables").on("change",e=>{this.actOnChangeSchedulerTableGarbageCollectionAllTables(a.default(e.currentTarget))}),a.default("#task_tableGarbageCollection_table").on("change",e=>{this.actOnChangeSchedulerTableGarbageCollectionTable(a.default(e.currentTarget))}),a.default("[data-update-task-frequency]").on("change",e=>{const t=a.default(e.currentTarget);a.default("#task_frequency").val(t.val()),t.val(t.attr("value")).trigger("blur")});const e=document.querySelector("table.taskGroup-table");null!==e&&new Tablesort(e),a.default(document).on("click",".t3js-element-browser",e=>{e.preventDefault();const t=e.currentTarget;n.advanced({type:n.types.iframe,content:t.href+"&mode="+t.dataset.mode+"&bparams="+t.dataset.params,size:n.sizes.large})}),new s.default("show.bs.collapse",this.toggleCollapseIcon).bindTo(document),new s.default("hide.bs.collapse",this.toggleCollapseIcon).bindTo(document),new s.default("multiRecordSelection:action:go",this.executeTasks).bindTo(document),new s.default("multiRecordSelection:action:go_cron",this.executeTasks).bindTo(document),window.addEventListener("message",this.listenOnElementBrowser)},this.initializeDefaultStates=()=>{let e=a.default("#task_type");e.length&&this.toggleFieldsByTaskType(e.val());let t=a.default("#task_class");t.length&&(this.actOnChangedTaskClass(t),r.updateElementBrowserTriggers())},this.listenOnElementBrowser=e=>{if(!i.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";const t=e.data.value.split("_");document.querySelector('input[name="'+e.data.fieldName+'"]').value=t[1]}},this.initializeEvents(),this.initializeDefaultStates(),l.getInstance().addPreSubmitCallback(()=>{let e=a.default("#task_class").val();e=e.toLowerCase().replace(/\\/g,"-"),a.default(".extraFields").appendTo(a.default("#extraFieldsHidden")),a.default(".extra_fields_"+e).appendTo(a.default("#extraFieldsSection"))})}static updateElementBrowserTriggers(){document.querySelectorAll(".t3js-element-browser").forEach(e=>{const t=document.getElementById(e.dataset.triggerFor);e.dataset.params=t.name+"|||pages"})}static storeCollapseState(e,t){let l={};d.isset("moduleData.scheduler")&&(l=d.get("moduleData.scheduler"));const s={};s[e]=t?1:0,a.default.extend(l,s),d.set("moduleData.scheduler",l)}toggleCollapseIcon(e){const t="hide.bs.collapse"===e.type,l=document.querySelector('.t3js-toggle-table[data-bs-target="#'+e.target.id+'"] .collapseIcon');null!==l&&o.getIcon(t?"actions-view-list-expand":"actions-view-list-collapse",o.sizes.small).done(e=>{l.innerHTML=e}),r.storeCollapseState(a.default(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("tr");null!==t&&t.dataset.taskId&&a.push(t.dataset.taskId)}),a.length){const l=document.createElement("input");if(l.setAttribute("type","hidden"),l.setAttribute("name","tx_scheduler[execute]"),l.setAttribute("value",a.join(",")),t.append(l),"multiRecordSelection:action:go_cron"===e.type){const e=document.createElement("input");e.setAttribute("type","hidden"),e.setAttribute("name","go_cron"),e.setAttribute("value","1"),t.append(e)}t.submit()}}}return new r})); \ No newline at end of file +var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};define(["require","exports","jquery","TYPO3/CMS/Backend/DocumentSaveActions","TYPO3/CMS/Core/Event/RegularEvent","TYPO3/CMS/Backend/Modal","TYPO3/CMS/Backend/Icons","TYPO3/CMS/Backend/Utility/MessageUtility","TYPO3/CMS/Backend/Storage/Persistent","tablesort"],(function(e,t,a,l,s,n,o,d,r){"use strict";a=__importDefault(a),s=__importDefault(s);class i{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 l={};r.isset("moduleData.scheduler")&&(l=r.get("moduleData.scheduler"));const s={};s[e]=t?1:0,a.default.extend(l,s),r.set("moduleData.scheduler",l)}constructor(){this.initializeEvents(),this.initializeDefaultStates(),l.getInstance().addPreSubmitCallback(()=>{let e=a.default("#task_class").val();e=e.toLowerCase().replace(/\\/g,"-"),a.default(".extraFields").appendTo(a.default("#extraFieldsHidden")),a.default(".extra_fields_"+e).appendTo(a.default("#extraFieldsSection"))})}actOnChangedTaskClass(e){let t=e.val();t=t.toLowerCase().replace(/\\/g,"-"),a.default(".extraFields").hide(),a.default(".extra_fields_"+t).show()}actOnChangedTaskType(e){this.toggleFieldsByTaskType(a.default(e.currentTarget).val())}actOnChangeSchedulerTableGarbageCollectionAllTables(e){let t=a.default("#task_tableGarbageCollection_numberOfDays"),l=a.default("#task_tableGarbageCollection_table");if(e.prop("checked"))l.prop("disabled",!0),t.prop("disabled",!0);else{let e=parseInt(t.val(),10);if(e<1){let t=l.val();const a=i.resolveDefaultNumberOfDays();null!==a&&(e=a[t])}l.prop("disabled",!1),e>0&&t.prop("disabled",!1)}}actOnChangeSchedulerTableGarbageCollectionTable(e){let t=a.default("#task_tableGarbageCollection_numberOfDays");const l=i.resolveDefaultNumberOfDays();null!==l&&l[e.val()]>0?(t.prop("disabled",!1),t.val(l[e.val()])):(t.prop("disabled",!0),t.val(0))}toggleFieldsByTaskType(e){e=parseInt(e+"",10),a.default("#task_end_col").toggle(2===e),a.default("#task_frequency_row").toggle(2===e)}initializeEvents(){a.default("#task_class").on("change",e=>{this.actOnChangedTaskClass(a.default(e.currentTarget))}),a.default("#task_type").on("change",this.actOnChangedTaskType.bind(this)),a.default("#task_tableGarbageCollection_allTables").on("change",e=>{this.actOnChangeSchedulerTableGarbageCollectionAllTables(a.default(e.currentTarget))}),a.default("#task_tableGarbageCollection_table").on("change",e=>{this.actOnChangeSchedulerTableGarbageCollectionTable(a.default(e.currentTarget))}),a.default("[data-update-task-frequency]").on("change",e=>{const t=a.default(e.currentTarget);a.default("#task_frequency").val(t.val()),t.val(t.attr("value")).trigger("blur")});const e=document.querySelector("table.taskGroup-table");null!==e&&new Tablesort(e),a.default(document).on("click",".t3js-element-browser",e=>{e.preventDefault();const t=e.currentTarget;n.advanced({type:n.types.iframe,content:t.href+"&mode="+t.dataset.mode+"&bparams="+t.dataset.params,size:n.sizes.large})}),new s.default("show.bs.collapse",this.toggleCollapseIcon.bind(this)).bindTo(document),new s.default("hide.bs.collapse",this.toggleCollapseIcon.bind(this)).bindTo(document),new s.default("multiRecordSelection:action:go",this.executeTasks.bind(this)).bindTo(document),new s.default("multiRecordSelection:action:go_cron",this.executeTasks.bind(this)).bindTo(document),window.addEventListener("message",this.listenOnElementBrowser.bind(this))}initializeDefaultStates(){let e=a.default("#task_type");e.length&&this.toggleFieldsByTaskType(e.val());let t=a.default("#task_class");t.length&&(this.actOnChangedTaskClass(t),i.updateElementBrowserTriggers())}listenOnElementBrowser(e){if(!d.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";const t=e.data.value.split("_");document.querySelector('input[name="'+e.data.fieldName+'"]').value=t[1]}}toggleCollapseIcon(e){const t="hide.bs.collapse"===e.type,l=document.querySelector('.t3js-toggle-table[data-bs-target="#'+e.target.id+'"] .collapseIcon');null!==l&&o.getIcon(t?"actions-view-list-expand":"actions-view-list-collapse",o.sizes.small).done(e=>{l.innerHTML=e}),i.storeCollapseState(a.default(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("tr");null!==t&&t.dataset.taskId&&a.push(t.dataset.taskId)}),a.length){const l=document.createElement("input");if(l.setAttribute("type","hidden"),l.setAttribute("name","tx_scheduler[execute]"),l.setAttribute("value",a.join(",")),t.append(l),"multiRecordSelection:action:go_cron"===e.type){const e=document.createElement("input");e.setAttribute("type","hidden"),e.setAttribute("name","go_cron"),e.setAttribute("value","1"),t.append(e)}t.submit()}}}return new i})); \ No newline at end of file