diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-45535-SortingForScheduler-list.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-45535-SortingForScheduler-list.rst new file mode 100644 index 0000000000000000000000000000000000000000..22aa46dead9be1ed030e30aa2147556720bcaafd --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-45535-SortingForScheduler-list.rst @@ -0,0 +1,20 @@ +.. include:: ../../Includes.txt + +============================================ +Feature: #45535 - Sorting for scheduler-list +============================================ + +See :issue:`45535` + +Description +=========== + +It is now possible to sort the scheduler-list according to the table headings. + + +Impact +====== + +The sorting of the scheduler-list table is done by using the jquery datatables plugin. + +.. index:: Backend, JavaScript \ No newline at end of file diff --git a/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php b/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php index 8915fece5602c40a65e309e76566320e6c02d57d..f4a9ce286d9d2129d2753ee6985ff1819c44e0d8 100644 --- a/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php +++ b/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php @@ -399,20 +399,6 @@ class SchedulerModuleController return $this->view->render(); } - /** - * Renders the task progress bar. - * - * @param float $progress Task progress - * @return string Progress bar markup - */ - protected function renderTaskProgressBar($progress) - { - $progressText = $this->getLanguageService()->getLL('status.progress') . ': ' . $progress . '%'; - return '<div class="progress">' - . '<div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="' . $progress . '" aria-valuemin="0" aria-valuemax="100" style="width: ' . $progress . '%;">' . $progressText . '</div>' - . '</div>'; - } - /** * Delete a task from the execution queue */ @@ -865,80 +851,23 @@ class SchedulerModuleController $this->getPageRenderer()->loadJquery(); $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Scheduler/Scheduler'); $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip'); - $table = []; - // Header row - $table[] = - '<thead><tr>' - . '<th><a class="btn btn-default" href="#" id="checkall" title="' . htmlspecialchars($this->getLanguageService()->getLL('label.checkAll')) . '">' . $this->moduleTemplate->getIconFactory()->getIcon('actions-document-select', Icon::SIZE_SMALL)->render() . '</a></th>' - . '<th>' . htmlspecialchars($this->getLanguageService()->getLL('label.id')) . '</th>' - . '<th>' . htmlspecialchars($this->getLanguageService()->getLL('task')) . '</th>' - . '<th>' . htmlspecialchars($this->getLanguageService()->getLL('label.type')) . '</th>' - . '<th>' . htmlspecialchars($this->getLanguageService()->getLL('label.frequency')) . '</th>' - . '<th>' . htmlspecialchars($this->getLanguageService()->getLL('label.parallel')) . '</th>' - . '<th>' . htmlspecialchars($this->getLanguageService()->getLL('label.lastExecution')) . '</th>' - . '<th>' . htmlspecialchars($this->getLanguageService()->getLL('label.nextExecution')) . '</th>' - . '<th></th>' - . '</tr></thead>'; + + $tasks = $temporaryResult; $registeredClasses = $this->getRegisteredClasses(); - $iconFactory = GeneralUtility::makeInstance(IconFactory::class); - $collapseIcon = $iconFactory->getIcon('actions-view-list-collapse', Icon::SIZE_SMALL)->render(); - $expandIcon = $iconFactory->getIcon('actions-view-list-expand', Icon::SIZE_SMALL)->render(); foreach ($temporaryResult as $taskIndex => $taskGroup) { - $collapseExpandIcons = '<span class="taskGroup_' . $taskIndex . '">' . $collapseIcon . '</span>' - . '<span class="taskGroup_' . $taskIndex . '" style="display: none;">' . $expandIcon . '</span>'; - if (!empty($taskGroup['groupName'])) { - $groupText = '<strong>' . htmlspecialchars($taskGroup['groupName']) . '</strong>'; - if (!empty($taskGroup['groupDescription'])) { - $groupText .= '<br>' . nl2br(htmlspecialchars($taskGroup['groupDescription'])); - } - $table[] = '<tr class="taskGroup" data-task-group-id="' . $taskIndex . '"><td colspan="8">' . $groupText . '</td><td style="text-align:right;">' . $collapseExpandIcons . '</td></tr>'; - } else { - if (count($temporaryResult) > 1) { - $table[] = '<tr class="taskGroup" data-task-group-id="0"><td colspan="8"><strong>' . htmlspecialchars($this->getLanguageService()->getLL('label.noGroup')) . '</strong></td><td style="text-align:right;">' . $collapseExpandIcons . '</td></tr>'; - } - } - - foreach ($taskGroup['tasks'] as $schedulerRecord) { - // Define action icons - $link = htmlspecialchars($this->moduleUri . '&CMD=edit&tx_scheduler[uid]=' . $schedulerRecord['uid']); - $editAction = '<a data-toggle="tooltip" data-container="body" class="btn btn-default" href="' . $link . '" title="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:edit')) . '">' . - $this->moduleTemplate->getIconFactory()->getIcon('actions-open', Icon::SIZE_SMALL)->render() . '</a>'; + foreach ($taskGroup['tasks'] as $recordIndex => $schedulerRecord) { if ((int)$schedulerRecord['disable'] === 1) { $translationKey = 'enable'; - $icon = $this->moduleTemplate->getIconFactory()->getIcon('actions-edit-unhide', Icon::SIZE_SMALL); } else { $translationKey = 'disable'; - $icon = $this->moduleTemplate->getIconFactory()->getIcon('actions-edit-hide', Icon::SIZE_SMALL); } - $toggleHiddenAction = '<a data-toggle="tooltip" data-container="body" class="btn btn-default" href="' . htmlspecialchars($this->moduleUri - . '&CMD=toggleHidden&tx_scheduler[uid]=' . $schedulerRecord['uid']) . '" title="' - . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:' . $translationKey)) - . '">' . $icon->render() . '</a>'; - $deleteAction = '<a data-toggle="tooltip" data-container="body" class="btn btn-default t3js-modal-trigger" href="' . htmlspecialchars($this->moduleUri . '&CMD=delete&tx_scheduler[uid]=' . $schedulerRecord['uid']) . '" ' - . ' data-severity="warning"' - . ' data-title="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:delete')) . '"' - . ' data-button-close-text="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:cancel')) . '"' - . ' data-content="' . htmlspecialchars($this->getLanguageService()->getLL('msg.delete')) . '"' - . ' title="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:delete')) . '">' . - $this->moduleTemplate->getIconFactory()->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render() . '</a>'; - $stopAction = '<a data-toggle="tooltip" data-container="body" class="btn btn-default t3js-modal-trigger" href="' . htmlspecialchars($this->moduleUri . '&CMD=stop&tx_scheduler[uid]=' . $schedulerRecord['uid']) . '" ' - . ' data-severity="warning"' - . ' data-title="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:stop')) . '"' - . ' data-button-close-text="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:cancel')) . '"' - . ' data-content="' . htmlspecialchars($this->getLanguageService()->getLL('msg.stop')) . '"' - . ' title="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:stop')) . '">' . - $this->moduleTemplate->getIconFactory()->getIcon('actions-close', Icon::SIZE_SMALL)->render() . '</a>'; - $runAction = '<a class="btn btn-default" data-toggle="tooltip" data-container="body" href="' . htmlspecialchars($this->moduleUri . '&tx_scheduler[execute][]=' . $schedulerRecord['uid']) . '" title="' . htmlspecialchars($this->getLanguageService()->getLL('action.run_task')) . '">' . - $this->moduleTemplate->getIconFactory()->getIcon('extensions-scheduler-run-task', Icon::SIZE_SMALL)->render() . '</a>'; - $runCronAction = '<a class="btn btn-default" data-toggle="tooltip" data-container="body" href="' . htmlspecialchars($this->moduleUri . '&CMD=setNextExecutionTime&tx_scheduler[uid]=' . $schedulerRecord['uid']) . '" title="' . htmlspecialchars($this->getLanguageService()->getLL('action.run_task_cron')) . '">' . - $this->moduleTemplate->getIconFactory()->getIcon('extensions-scheduler-run-task-cron', Icon::SIZE_SMALL)->render() . '</a>'; + $tasks[$taskIndex]['tasks'][$recordIndex]['translationKey'] = $translationKey; // Define some default values $lastExecution = '-'; $isRunning = false; $showAsDisabled = false; - $startExecutionElement = '<span class="btn btn-default disabled">' . $this->moduleTemplate->getIconFactory()->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>'; // Restore the serialized task and pass it a reference to the scheduler object /** @var $task \TYPO3\CMS\Scheduler\Task\AbstractTask|ProgressProviderInterface */ $task = unserialize($schedulerRecord['serialized_task_object']); @@ -946,6 +875,7 @@ class SchedulerModuleController if ($class === '__PHP_Incomplete_Class' && preg_match('/^O:[0-9]+:"(?P<classname>.+?)"/', $schedulerRecord['serialized_task_object'], $matches) === 1) { $class = $matches['classname']; } + $tasks[$taskIndex]['tasks'][$recordIndex]['class'] = $class; // Assemble information about last execution if (!empty($schedulerRecord['lastexecution_time'])) { $lastExecution = date($dateFormat, $schedulerRecord['lastexecution_time']); @@ -956,19 +886,20 @@ class SchedulerModuleController } $lastExecution .= ' (' . $context . ')'; } + $tasks[$taskIndex]['tasks'][$recordIndex]['lastExecution'] = $lastExecution; if (isset($registeredClasses[get_class($task)]) && $this->scheduler->isValidTaskObject($task)) { + $tasks[$taskIndex]['tasks'][$recordIndex]['validClass'] = true; // The task object is valid $labels = []; - $name = htmlspecialchars($registeredClasses[$class]['title'] . ' (' . $registeredClasses[$class]['extension'] . ')'); $additionalInformation = $task->getAdditionalInformation(); if ($task instanceof ProgressProviderInterface) { $progress = round((float)$task->getProgress(), 2); - $name .= $this->renderTaskProgressBar($progress); - } - if (!empty($additionalInformation)) { - $name .= '<div class="additional-information">' . nl2br(htmlspecialchars($additionalInformation)) . '</div>'; + $tasks[$taskIndex]['tasks'][$recordIndex]['progress'] = $progress; } + $tasks[$taskIndex]['tasks'][$recordIndex]['classTitle'] = $registeredClasses[$class]['title']; + $tasks[$taskIndex]['tasks'][$recordIndex]['classExtension'] = $registeredClasses[$class]['extension']; + $tasks[$taskIndex]['tasks'][$recordIndex]['additionalInformation'] = $additionalInformation; // Check if task currently has a running execution if (!empty($schedulerRecord['serialized_executions'])) { $labels[] = [ @@ -977,6 +908,7 @@ class SchedulerModuleController ]; $isRunning = true; } + $tasks[$taskIndex]['tasks'][$recordIndex]['isRunning'] = $isRunning; // Prepare display of next execution date // If task is currently running, date is not displayed (as next hasn't been calculated yet) @@ -995,6 +927,7 @@ class SchedulerModuleController ]; } } + $tasks[$taskIndex]['tasks'][$recordIndex]['nextDate'] = $nextDate; // Get execution type if ($task->getType() === AbstractTask::TYPE_SINGLE) { $execType = $this->getLanguageService()->getLL('label.type.single'); @@ -1007,17 +940,6 @@ class SchedulerModuleController $frequency = $task->getExecution()->getCronCmd(); } } - // Get multiple executions setting - if ($task->getExecution()->getMultiple()) { - $multiple = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:yes'); - } else { - $multiple = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:no'); - } - // Define checkbox - $startExecutionElement = '<label class="btn btn-default btn-checkbox"><input type="checkbox" name="tx_scheduler[execute][]" value="' . $schedulerRecord['uid'] . '" id="task_' . $schedulerRecord['uid'] . '"><span class="t3-icon fa"></span></label>'; - - $actions = '<div class="btn-group" role="group">' . $editAction . $toggleHiddenAction . $deleteAction . '</div>'; - // Check the disable status // Row is shown dimmed if task is disabled, unless it is still running if ($schedulerRecord['disable'] && !$isRunning) { @@ -1027,13 +949,15 @@ class SchedulerModuleController ]; $showAsDisabled = true; } - - // Show no action links (edit, delete) if task is running - if ($isRunning) { - $actions = '<div class="btn-group" role="group">' . $stopAction . '</div>'; + $tasks[$taskIndex]['tasks'][$recordIndex]['execType'] = $execType; + $tasks[$taskIndex]['tasks'][$recordIndex]['frequency'] = $frequency; + // Get multiple executions setting + if ($task->getExecution()->getMultiple()) { + $multiple = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:yes'); } else { - $actions .= ' <div class="btn-group" role="group">' . $runCronAction . $runAction . '</div>'; + $multiple = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:no'); } + $tasks[$taskIndex]['tasks'][$recordIndex]['multiple'] = $multiple; // Check if the last run failed if (!empty($schedulerRecord['lastexecution_failure'])) { @@ -1052,52 +976,16 @@ class SchedulerModuleController 'description' => $labelDescription ]; } - // Format the execution status, - // including failure feedback, if any - $taskDesc = ''; - if ($schedulerRecord['description'] !== '') { - $taskDesc = '<span class="description">' . nl2br(htmlspecialchars($schedulerRecord['description'])) . '</span>'; + $tasks[$taskIndex]['tasks'][$recordIndex]['labels'] = $labels; + if ($showAsDisabled) { + $tasks[$taskIndex]['tasks'][$recordIndex]['showAsDisabled'] = 'disabled'; } - $taskName = '<span class="name"><a href="' . $link . '">' . $name . '</a></span>'; - - $table[] = - '<tr class="' . ($showAsDisabled ? 'disabled' : '') . ' taskGroup_' . $taskIndex . '">' - . '<td><span class="t-span">' . $startExecutionElement . '</span></td>' - . '<td class="right"><span class="t-span">' . $schedulerRecord['uid'] . '</span></td>' - . '<td><span class="t-span">' . $this->makeStatusLabel($labels) . $taskName . $taskDesc . '</span></td>' - . '<td><span class="t-span">' . $execType . '</span></td>' - . '<td><span class="t-span">' . $frequency . '</span></td>' - . '<td><span class="t-span">' . $multiple . '</span></td>' - . '<td><span class="t-span">' . $lastExecution . '</span></td>' - . '<td><span class="t-span">' . $nextDate . '</span></td>' - . '<td class="nowrap"><span class="t-span">' . $actions . '</span></td>' - . '</tr>'; - } else { - // The task object is not valid - // Prepare to issue an error - $executionStatusOutput = '<span class="label label-danger">' - . htmlspecialchars(sprintf( - $this->getLanguageService()->getLL('msg.invalidTaskClass'), - $class - )) - . '</span>'; - $table[] = - '<tr>' - . '<td>' . $startExecutionElement . '</td>' - . '<td class="right">' . $schedulerRecord['uid'] . '</td>' - . '<td colspan="6">' . $executionStatusOutput . '</td>' - . '<td class="nowrap"><div class="btn-group" role="group">' - . '<span class="btn btn-default disabled">' . $this->moduleTemplate->getIconFactory()->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>' - . '<span class="btn btn-default disabled">' . $this->moduleTemplate->getIconFactory()->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>' - . $deleteAction - . '<span class="btn btn-default disabled">' . $this->moduleTemplate->getIconFactory()->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>' - . '</div></td>' - . '</tr>'; } } } - $this->view->assign('table', '<table class="table table-striped table-hover">' . implode(LF, $table) . '</table>'); + $this->view->assign('tasks', $tasks); + $this->view->assign('moduleUri', $this->moduleUri); $this->view->assign('now', $this->getServerTime()); return $this->view->render(); diff --git a/typo3/sysext/scheduler/Resources/Private/Partials/Backend/SchedulerModule/TaskList.html b/typo3/sysext/scheduler/Resources/Private/Partials/Backend/SchedulerModule/TaskList.html new file mode 100644 index 0000000000000000000000000000000000000000..c2a157f100eba379fa0d3b00068ab3d34febe636 --- /dev/null +++ b/typo3/sysext/scheduler/Resources/Private/Partials/Backend/SchedulerModule/TaskList.html @@ -0,0 +1,158 @@ +<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" + xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" + data-namespace-typo3-fluid="true"> + +<f:for each="{tasks}" as="taskGroup" iteration="groupIterator"> + + <div class="tx_scheduler_mod1_table"> + <f:if condition="{taskGroup.groupName} == ''"> + <f:then> + <f:if condition="{tasks -> f:count()}>1"> + <table class="table table-striped table-hover" style="margin-bottom: -2px;"> + <tr class="taskGroup" data-task-group-id="0"> + <td><strong><f:translate key="label.noGroup" /></strong> + </td><td style="text-align:right;"> + <span class="taskGroup_{groupIterator.index}"><core:icon identifier="actions-view-list-collapse" /></span> + <span class="taskGroup_{groupIterator.index}" style="display: none;"><core:icon identifier="actions-view-list-expand" /></span> + </td> + </tr> + </table> + </f:if> + </f:then> + <f:else> + <table class="table table-striped table-hover" style="margin-bottom: -2px;"> + <tr class="taskGroup" data-task-group-id="{groupIterator.index}"> + <td> + <strong>{taskGroup.groupName}</strong> + <f:if condition="{taskGroup.groupDescription} != ''"> + <f:format.nl2br>{taskGroup.groupDescription}</f:format.nl2br> + </f:if> + </td><td style="text-align:right;"> + <span class="taskGroup_{groupIterator.index}"><core:icon identifier="actions-view-list-collapse" /></span> + <span class="taskGroup_{groupIterator.index}" style="display: none;"><core:icon identifier="actions-view-list-expand" /></span> + </td> + </tr> + </table> + </f:else> + </f:if> + <table class="table table-striped table-hover display"> + <thead><tr class="taskGroup_{groupIterator.index}"> + <th><span class="t-span"><a class="btn btn-default checkall" href="#" id="checkall" title="{f:translate(key:'label.checkAll')}"><core:icon identifier="actions-document-select" /></a></span></th> + <th><span class="t-span"><f:translate key="label.id" /></span></th> + <th><span class="t-span"><f:translate key="task" /></span></th> + <th><span class="t-span"><f:translate key="label.type" /></span></th> + <th><span class="t-span"><f:translate key="label.frequency" /></span></th> + <th><span class="t-span"><f:translate key="label.parallel" /></span></th> + <th><span class="t-span"><f:translate key="label.lastExecution" /></span></th> + <th><span class="t-span"><f:translate key="label.nextExecution" /></span></th> + <th><span class="t-span"></span></th> + </tr></thead> + <f:for each="{taskGroup.tasks}" as="taskRecord" iteration="taskIterator"> + <f:if condition="{taskRecord.validClass}"> + <f:then> + <tr class="{taskRecord.showAsDisabled} taskGroup_{groupIterator.index}"> + <td><span class="t-span"><label class="btn btn-default btn-checkbox"><input type="checkbox" name="tx_scheduler[execute][]" value="{taskRecord.uid}" id="task_{taskRecord.uid}"><span class="t3-icon fa"></span></label></span></td> + <td class="right"><span class="t-span">{taskRecord.uid}</span></td> + <td><span class="t-span"> + <f:for each="{taskRecord.labels}" as="label"> + <f:if condition="{taskRecord.validClass}"> + <span class="label label-{label.class} pull-right" title="{label.desciption}">{label.text}</span> + </f:if> + </f:for> + <span class="name"> + <a href="{moduleUri}&CMD=edit&tx_scheduler[uid]={taskRecord.uid}">{taskRecord.classTitle} ({taskRecord.classExtension}) + <f:if condition="{taskRecord.progress}"> + <div class="progress"> + <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="{taskRecord.progress}" aria-valuemin="0" aria-valuemax="100" style="width: {taskRecord.progress}%;">{f:translate(key:'label.checkAll')}: {taskRecord.progress}%</div> + </div> + </f:if> + <f:if condition="{taskRecord.additionalInformation}"> + <div class="additional-information"><f:format.nl2br>{taskRecord.additionalInformation}</f:format.nl2br></div> + </f:if> + </a> + </span> + <f:if condition="{taskRecord.description} != ''"> + <span class="description"><f:format.nl2br>{taskRecord.description}</f:format.nl2br></span> + </f:if> + </span> + </td> + <td><span class="t-span">{taskRecord.execType}</span></td> + <td><span class="t-span">{taskRecord.frequency}</span></td> + <td><span class="t-span">{taskRecord.multiple}</span></td> + <td><span class="t-span">{taskRecord.lastExecution}</span></td> + <td><span class="t-span">{taskRecord.nextDate}</span></td> + <td class="nowrap"><span class="t-span"> + <f:if condition="{taskRecord.isRunning}"> + <f:then> + <div class="btn-group" role="group"> + <a data-toggle="tooltip" data-container="body" class="btn btn-default t3js-modal-trigger" href="{moduleUri}&CMD=stop&tx_scheduler[uid]={taskRecord.uid}" + data-severity="warning" + data-title="{f:translate(key:'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:stop')}" + data-button-close-text="{f:translate(key:'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:cancel')}" + data-content="{f:translate(key:'msg.stop')}" + title="{f:translate(key:'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:stop')}"> + <core:icon identifier="actions-close" /> + </a> + </div> + </f:then> + <f:else> + <div class="btn-group" role="group"> + <a data-toggle="tooltip" data-container="body" class="btn btn-default" href="{moduleUri}&CMD=edit&tx_scheduler[uid]={taskRecord.uid}" title="{f:translate(key:'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:edit')}"> + <core:icon identifier="actions-open" /> + </a> + <a data-toggle="tooltip" data-container="body" class="btn btn-default" href="{moduleUri}&CMD=toggleHidden&tx_scheduler[uid]={taskRecord.uid}" title="{f:translate(key:'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:{taskRecord.translationKey}')}"> + <f:if condition="{taskRecord.translationKey} == 'enable'"> + <f:then> + <core:icon identifier="actions-edit-unhide" /> + </f:then> + <f:else> + <core:icon identifier="actions-edit-hide" /> + </f:else> + </f:if> + </a> + <a data-toggle="tooltip" data-container="body" class="btn btn-default t3js-modal-trigger" href="{moduleUri}&CMD=delete&tx_scheduler[uid]={taskRecord.uid}" + data-severity="warning" + data-title="{f:translate(key:'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:delete')}" + data-button-close-text="{f:translate(key:'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:cancel')}" + data-content="{f:translate(key:'msg.delete')}" + title="{f:translate(key:'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:delete')}"> + <core:icon identifier="actions-edit-delete" /> + </a> + </div> + + <div class="btn-group" role="group"> + <a class="btn btn-default" data-toggle="tooltip" data-container="body" href="{moduleUri}&CMD=setNextExecutionTime&tx_scheduler[uid]={taskRecord.uid}" title="{f:translate(key:'action.run_task_cron')}"> + <core:icon identifier="extensions-scheduler-run-task-cron" /> + </a> + <a class="btn btn-default" data-toggle="tooltip" data-container="body" href="{moduleUri}&tx_scheduler[execute][]={taskRecord.uid}" title="{f:translate(key:'action.run_task')}"> + <core:icon identifier="extensions-scheduler-run-task" /> + </a> + </div> + </f:else> + </f:if> + </span> + </td> + </tr> + </f:then> + <f:else> + <tr> + <td><span class="btn btn-default disabled"><core:icon identifier="empty-empty" /></span></td> + <td class="right">{taskRecord.uid}</td> + <td colspan="6"><span class="label label-danger"><f:translate key="msg.invalidTaskClass" arguments="{0: '{taskRecord.class}'}" /></span></td> + <td class="nowrap"> + <div class="btn-group" role="group"> + <span class="btn btn-default disabled"><core:icon identifier="empty-empty" /></span> + <span class="btn btn-default disabled"><core:icon identifier="empty-empty" /></span> + $deleteAction + <span class="btn btn-default disabled"><core:icon identifier="empty-empty" /></span> + </div> + </td> + </tr> + </f:else> + </f:if> + </f:for> + </table> + </div> +</f:for> +<br /> +</html> diff --git a/typo3/sysext/scheduler/Resources/Private/Templates/Backend/SchedulerModule/ListTasks.html b/typo3/sysext/scheduler/Resources/Private/Templates/Backend/SchedulerModule/ListTasks.html index efc0e1971b817c3fc017eb671d3fdf21ac8c67bc..35fbc1c2a5ba9d062a0619d901a78978d171607d 100644 --- a/typo3/sysext/scheduler/Resources/Private/Templates/Backend/SchedulerModule/ListTasks.html +++ b/typo3/sysext/scheduler/Resources/Private/Templates/Backend/SchedulerModule/ListTasks.html @@ -1,4 +1,5 @@ -<f:format.raw>{table}</f:format.raw> +<f:render partial="TaskList" arguments="{tasks: tasks, moduleUri: moduleUri}" /> + <button class="btn btn-default" name="go_cron" id="scheduler_executeselected"> <core:icon identifier="extensions-scheduler-run-task-cron" /> <f:translate key="label.cronjobSelected" /> diff --git a/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js b/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js index 869391c3bc22b9397ae9fd7c75cf69101548ee63..e53373716251a1d553c89251c34663a9d6a60804 100644 --- a/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js +++ b/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js @@ -15,6 +15,7 @@ * Module: TYPO3/CMS/Scheduler/Scheduler */ define(['jquery', + 'datatables', 'TYPO3/CMS/Backend/SplitButtons' ], function($, SplitButtons) { @@ -23,7 +24,8 @@ define(['jquery', * @type {{}} * @exports TYPO3/CMS/Scheduler/Scheduler */ - var Scheduler = {}; + var Scheduler = { + }; var allCheckedStatus = false; @@ -102,7 +104,7 @@ define(['jquery', * @returns {Boolean} */ Scheduler.checkOrUncheckAllCheckboxes = function(theSelector) { - theSelector.parents('.tx_scheduler_mod1').find(':checkbox').prop('checked', !allCheckedStatus); + theSelector.parents('.tx_scheduler_mod1_table').find(':checkbox').prop('checked', !allCheckedStatus); allCheckedStatus = !allCheckedStatus; return false; }; @@ -125,7 +127,7 @@ define(['jquery', * @param {Object} theSelector */ Scheduler.toggleTaskGroups = function(theSelector) { - taskGroup = theSelector.data('task-group-id'); + var taskGroup = theSelector.data('task-group-id'); var taskGroupClass= '.taskGroup_' + taskGroup; $(taskGroupClass).toggleClass('taskGroup--close'); }; @@ -134,7 +136,7 @@ define(['jquery', * Registers listeners */ Scheduler.initializeEvents = function() { - $('#checkall').on('click', function() { + $('.checkall').on('click', function() { Scheduler.checkOrUncheckAllCheckboxes($(this)); }); @@ -155,6 +157,11 @@ define(['jquery', $('.taskGroup').on('click', function() { Scheduler.toggleTaskGroups($(this)); }); + + $('table.display').DataTable( { + "paging": false, + "searching": false + } ); }; /** @@ -166,7 +173,9 @@ define(['jquery', Scheduler.toggleFieldsByTaskType($taskType.val()); } var $taskClass = $('#task_class'); - Scheduler.actOnChangedTaskClass($taskClass); + if ($taskClass.length) { + Scheduler.actOnChangedTaskClass($taskClass); + } }; $(Scheduler.initializeEvents);