Skip to content

Commit 8d6376b

Browse files
authored
Merge pull request #6193 from WoltLab/6.2-cronjob-to-grid-view
Migrate `CronjobListPage`to grid view
2 parents 01a2c45 + c3cc6b8 commit 8d6376b

File tree

14 files changed

+493
-257
lines changed

14 files changed

+493
-257
lines changed

wcfsetup/install/files/acp/js/WCF.ACP.js

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -16,110 +16,6 @@ WCF.ACP = { };
1616
*/
1717
WCF.ACP.Application = { };
1818

19-
/**
20-
* Namespace for ACP cronjob management.
21-
*/
22-
WCF.ACP.Cronjob = { };
23-
24-
/**
25-
* Handles the manual execution of cronjobs.
26-
*/
27-
WCF.ACP.Cronjob.ExecutionHandler = Class.extend({
28-
/**
29-
* notification object
30-
* @var WCF.System.Notification
31-
*/
32-
_notification: null,
33-
34-
/**
35-
* action proxy
36-
* @var WCF.Action.Proxy
37-
*/
38-
_proxy: null,
39-
40-
/**
41-
* Initializes WCF.ACP.Cronjob.ExecutionHandler object.
42-
*/
43-
init: function() {
44-
this._proxy = new WCF.Action.Proxy({
45-
success: $.proxy(this._success, this)
46-
});
47-
48-
$('.jsCronjobRow .jsExecuteButton').click($.proxy(this._click, this));
49-
50-
this._notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success'), 'success');
51-
},
52-
53-
/**
54-
* Handles a click on an execute button.
55-
*
56-
* @param object event
57-
*/
58-
_click: function(event) {
59-
this._proxy.setOption('data', {
60-
actionName: 'execute',
61-
className: 'wcf\\data\\cronjob\\CronjobAction',
62-
objectIDs: [ $(event.target).data('objectID') ]
63-
});
64-
65-
this._proxy.sendRequest();
66-
},
67-
68-
/**
69-
* Handles successful cronjob execution.
70-
*
71-
* @param object data
72-
* @param string textStatus
73-
* @param jQuery jqXHR
74-
*/
75-
_success: function(data, textStatus, jqXHR) {
76-
$('.jsCronjobRow').each($.proxy(function(index, row) {
77-
var $button = $(row).find('.jsExecuteButton');
78-
var $objectID = ($button).data('objectID');
79-
80-
if (WCF.inArray($objectID, data.objectIDs)) {
81-
if (data.returnValues[$objectID]) {
82-
// insert feedback here
83-
$(row).find('td.columnNextExec').html(data.returnValues[$objectID].formatted);
84-
$(row).wcfHighlight();
85-
}
86-
87-
this._notification.show();
88-
89-
return false;
90-
}
91-
}, this));
92-
}
93-
});
94-
95-
/**
96-
* Handles the cronjob log list.
97-
*/
98-
WCF.ACP.Cronjob.LogList = Class.extend({
99-
/**
100-
* Initializes WCF.ACP.Cronjob.LogList object.
101-
*/
102-
init: function() {
103-
// bind event listener to delete cronjob log button
104-
$('.jsCronjobLogDelete').click(function() {
105-
WCF.System.Confirmation.show(WCF.Language.get('wcf.acp.cronjob.log.clear.confirm'), function(action) {
106-
if (action == 'confirm') {
107-
new WCF.Action.Proxy({
108-
autoSend: true,
109-
data: {
110-
actionName: 'clearAll',
111-
className: 'wcf\\data\\cronjob\\log\\CronjobLogAction'
112-
},
113-
success: function() {
114-
window.location.reload();
115-
}
116-
});
117-
}
118-
});
119-
});
120-
}
121-
});
122-
12319
/**
12420
* Namespace for ACP package management.
12521
*/
Lines changed: 4 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
{include file='header' pageTitle='wcf.acp.cronjob.list'}
22

3-
<script data-relocate="true">
4-
$(function() {
5-
new WCF.ACP.Cronjob.ExecutionHandler();
6-
});
7-
</script>
8-
93
<header class="contentHeader">
104
<div class="contentHeaderTitle">
11-
<h1 class="contentTitle">{lang}wcf.acp.cronjob.list{/lang} <span class="badge badgeInverse">{#$items}</span></h1>
5+
<h1 class="contentTitle">{lang}wcf.acp.cronjob.list{/lang}</h1>
126
<p class="contentHeaderDescription">{lang}wcf.acp.cronjob.subtitle{/lang}</p>
137
</div>
148

@@ -21,112 +15,8 @@
2115
</nav>
2216
</header>
2317

24-
{hascontent}
25-
<div class="paginationTop">
26-
{content}{pages print=true assign=pagesLinks controller="CronjobList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}{/content}
27-
</div>
28-
{/hascontent}
29-
30-
{hascontent}
31-
<div class="section tabularBox">
32-
<table class="table jsObjectActionContainer" data-object-action-class-name="wcf\data\cronjob\CronjobAction">
33-
<thead>
34-
<tr>
35-
<th class="columnID columnCronjobID{if $sortField == 'cronjobID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='CronjobList'}pageNo={@$pageNo}&sortField=cronjobID&sortOrder={if $sortField == 'cronjobID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
36-
<th class="columnText columnExpression"><span>{lang}wcf.acp.cronjob.expression{/lang}</span></th>
37-
<th class="columnText columnDescription{if $sortField == 'descriptionI18n'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobList'}pageNo={@$pageNo}&sortField=descriptionI18n&sortOrder={if $sortField == 'descriptionI18n' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.description{/lang}</a></th>
38-
<th class="columnText columnPackage{if $sortField == 'packageID'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobList'}pageNo={@$pageNo}&sortField=packageID&sortOrder={if $sortField == 'packageID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.package.name{/lang}</a></th>
39-
<th class="columnDate columnNextExec{if $sortField == 'nextExec'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobList'}pageNo={@$pageNo}&sortField=nextExec&sortOrder={if $sortField == 'nextExec' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.nextExec{/lang}</a></th>
40-
41-
{event name='columnHeads'}
42-
</tr>
43-
</thead>
44-
45-
<tbody class="jsReloadPageWhenEmpty">
46-
{content}
47-
{foreach from=$objects item=cronjob}
48-
<tr class="jsCronjobRow jsObjectActionObject" data-object-id="{@$cronjob->getObjectID()}">
49-
<td class="columnIcon">
50-
<button type="button" class="jsExecuteButton jsTooltip" title="{lang}wcf.acp.cronjob.execute{/lang}" data-object-id="{@$cronjob->cronjobID}">
51-
{icon name='play'}
52-
</button>
53-
54-
{if $cronjob->canBeDisabled()}
55-
{objectAction action="toggle" isDisabled=$cronjob->isDisabled}
56-
{else}
57-
{if !$cronjob->isDisabled}
58-
<span class="disabled" title="{lang}wcf.global.button.disable{/lang}">
59-
{icon name='square-check'}
60-
</span>
61-
{else}
62-
<span class="disabled" title="{lang}wcf.global.button.enable{/lang}">
63-
{icon name='square'}
64-
</span>
65-
{/if}
66-
{/if}
67-
68-
{if $cronjob->isEditable()}
69-
<a href="{link controller='CronjobEdit' id=$cronjob->cronjobID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip">{icon name='pencil'}</a>
70-
{else}
71-
<span class="disabled" title="{lang}wcf.global.button.edit{/lang}">
72-
{icon name='pencil'}
73-
</span>
74-
{/if}
75-
{if $cronjob->isDeletable()}
76-
{objectAction action="delete" objectTitle=$cronjob->getDescription()}
77-
{else}
78-
<span class="disabled" title="{lang}wcf.global.button.delete{/lang}">
79-
{icon name='xmark'}
80-
</span>
81-
{/if}
82-
83-
{event name='rowButtons'}
84-
</td>
85-
<td class="columnID">{@$cronjob->cronjobID}</td>
86-
<td class="columnText columnExpression">
87-
<kbd>{$cronjob->getExpression()}</kbd>
88-
</td>
89-
<td class="columnText columnDescription">
90-
{if $cronjob->isEditable()}
91-
<a title="{lang}wcf.acp.cronjob.edit{/lang}" href="{link controller='CronjobEdit' id=$cronjob->cronjobID}{/link}">{$cronjob->getDescription()}</a>
92-
{else}
93-
{$cronjob->getDescription()}
94-
{/if}
95-
</td>
96-
<td class="columnText columnPackage">
97-
{$cronjob->getPackage()}
98-
</td>
99-
<td class="columnDate columnNextExec">
100-
{if !$cronjob->isDisabled && $cronjob->nextExec != 1}
101-
{@$cronjob->nextExec|plainTime}
102-
{/if}
103-
</td>
104-
105-
{event name='columns'}
106-
</tr>
107-
{/foreach}
108-
{/content}
109-
</tbody>
110-
</table>
111-
</div>
112-
{hascontentelse}
113-
<woltlab-core-notice type="info">{lang}wcf.global.noItems{/lang}</woltlab-core-notice>
114-
{/hascontent}
115-
116-
<footer class="contentFooter">
117-
{hascontent}
118-
<div class="paginationBottom">
119-
{content}{@$pagesLinks}{/content}
120-
</div>
121-
{/hascontent}
122-
123-
<nav class="contentFooterNavigation">
124-
<ul>
125-
<li><a href="{link controller='CronjobAdd'}{/link}" class="button">{icon name='plus'} <span>{lang}wcf.acp.cronjob.add{/lang}</span></a></li>
126-
127-
{event name='contentFooterNavigation'}
128-
</ul>
129-
</nav>
130-
</footer>
18+
<div class="section">
19+
{unsafe:$gridView->render()}
20+
</div>
13121

13222
{include file='footer'}

wcfsetup/install/files/lib/acp/page/CronjobListPage.class.php

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22

33
namespace wcf\acp\page;
44

5-
use wcf\data\cronjob\I18nCronjobList;
6-
use wcf\page\SortablePage;
5+
use wcf\page\AbstractGridViewPage;
6+
use wcf\system\gridView\AbstractGridView;
7+
use wcf\system\gridView\admin\CronjobGridView;
78

89
/**
910
* Shows information about configured cron jobs.
1011
*
11-
* @author Alexander Ebert
12-
* @copyright 2001-2019 WoltLab GmbH
13-
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
12+
* @author Olaf Braun, Alexander Ebert
13+
* @copyright 2001-2025 WoltLab GmbH
14+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
1415
*
15-
* @property I18nCronjobList $objectList
16+
* @property CronjobGridView $gridView
1617
*/
17-
class CronjobListPage extends SortablePage
18+
class CronjobListPage extends AbstractGridViewPage
1819
{
1920
/**
2021
* @inheritDoc
@@ -26,38 +27,9 @@ class CronjobListPage extends SortablePage
2627
*/
2728
public $neededPermissions = ['admin.management.canManageCronjob'];
2829

29-
/**
30-
* @inheritDoc
31-
*/
32-
public $defaultSortField = 'descriptionI18n';
33-
34-
/**
35-
* @inheritDoc
36-
*/
37-
public $itemsPerPage = 100;
38-
39-
/**
40-
* @inheritDoc
41-
*/
42-
public $validSortFields = [
43-
'cronjobID',
44-
'nextExec',
45-
'descriptionI18n',
46-
'packageID',
47-
];
48-
49-
/**
50-
* @inheritDoc
51-
*/
52-
public $objectListClassName = I18nCronjobList::class;
53-
54-
/**
55-
* @inheritDoc
56-
*/
57-
public function initObjectList()
30+
#[\Override]
31+
protected function createGridViewController(): AbstractGridView
5832
{
59-
parent::initObjectList();
60-
61-
$this->sqlOrderBy = "cronjob." . $this->sortField . " " . $this->sortOrder;
33+
return new CronjobGridView();
6234
}
6335
}

wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ static function (\wcf\event\endpoint\ControllerCollecting $event) {
162162
$event->register(new \wcf\system\endpoint\controller\core\articles\PublishArticle());
163163
$event->register(new \wcf\system\endpoint\controller\core\articles\UnpublishArticle());
164164
$event->register(new \wcf\system\endpoint\controller\core\attachments\DeleteAttachment());
165+
$event->register(new \wcf\system\endpoint\controller\core\cronjobs\EnableCronjob());
166+
$event->register(new \wcf\system\endpoint\controller\core\cronjobs\DisableCronjob());
167+
$event->register(new \wcf\system\endpoint\controller\core\cronjobs\DeleteCronjob());
168+
$event->register(new \wcf\system\endpoint\controller\core\cronjobs\ExecuteCronjob());
165169
}
166170
);
167171

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace wcf\event\gridView\admin;
4+
5+
use wcf\event\IPsr14Event;
6+
use wcf\system\gridView\admin\CronjobGridView;
7+
8+
/**
9+
* Indicates that the cronjob grid view has been initialized.
10+
*
11+
* @author Olaf Braun
12+
* @copyright 2001-2025 WoltLab GmbH
13+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14+
* @since 6.2
15+
*/
16+
final class CronjobGridViewInitialized implements IPsr14Event
17+
{
18+
public function __construct(public readonly CronjobGridView $gridView)
19+
{
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace wcf\event\interaction\admin;
4+
5+
use wcf\event\IPsr14Event;
6+
use wcf\system\interaction\admin\CronjobInteractions;
7+
8+
/**
9+
* Indicates that the provider for cronjob interactions is collecting interactions.
10+
*
11+
* @author Olaf Braun
12+
* @copyright 2001-2025 WoltLab GmbH
13+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14+
* @since 6.2
15+
*/
16+
final class CronjobInteractionCollecting implements IPsr14Event
17+
{
18+
public function __construct(public readonly CronjobInteractions $provider)
19+
{
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace wcf\event\interaction\bulk\admin;
4+
5+
use wcf\event\IPsr14Event;
6+
use wcf\system\interaction\bulk\admin\CronjobBulkInteractions;
7+
8+
/**
9+
* Indicates that the provider for cronjob bulk interactions is collecting interactions.
10+
*
11+
* @author Olaf Braun
12+
* @copyright 2001-2025 WoltLab GmbH
13+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14+
* @since 6.2
15+
*/
16+
final class CronjobBulkInteractionCollecting implements IPsr14Event
17+
{
18+
public function __construct(public readonly CronjobBulkInteractions $provider)
19+
{
20+
}
21+
}

0 commit comments

Comments
 (0)