Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NEW: Advanced jobs admin UI.
Browse files Browse the repository at this point in the history
mfendeksilverstripe committed Aug 31, 2020
1 parent 5175489 commit 0cae034
Showing 4 changed files with 221 additions and 8 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -819,6 +819,17 @@ As a consequence, the work might end up being very fragmented and each chunk may

Some projects do not mind this however, so this solution may still be quite suitable.

## Enabling extended admin UI

In case your project has many jobs to search through and the basic UI is not enough, you can use the advanced jobs admin UI option.
This option requires the `silverstripe-terraformers/gridfield-rich-filter-header` module, though.
To enable the advanced UI simply add this config to your project.

```yaml
Symbiote\QueuedJobs\Controllers\QueuedJobsAdmin:
advanced_admin_ui: true
```
## Contributing
### Translations
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -37,6 +37,9 @@
"replace": {
"silverstripe/queuedjobs": "self.version"
},
"suggest": {
"silverstripe-terraformers/gridfield-rich-filter-header": "Required for advanced admin UI"
},
"autoload": {
"psr-4": {
"Symbiote\\QueuedJobs\\": "src/",
178 changes: 178 additions & 0 deletions src/Controllers/QueuedJobsAdmin.php
Original file line number Diff line number Diff line change
@@ -15,23 +15,30 @@
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
use SilverStripe\Forms\GridField\GridFieldFilterHeader;
use SilverStripe\Forms\GridField\GridFieldPageCount;
use SilverStripe\Forms\GridField\GridFieldToolbarHeader;
use SilverStripe\Forms\TextareaField;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
use Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor;
use Symbiote\QueuedJobs\Forms\GridFieldQueuedJobExecute;
use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
use Symbiote\QueuedJobs\Services\QueuedJob;
use Symbiote\QueuedJobs\Services\QueuedJobService;
use Terraformers\RichFilterHeader\Form\GridField\RichFilterHeader;

/**
* @author Marcus Nyeholt <[email protected]>
* @license BSD http://silverstripe.org/bsd-license/
*/
class QueuedJobsAdmin extends ModelAdmin
{
const SCHEDULED_FILTER_FUTURE = 'future';
const SCHEDULED_FILTER_PAST = 'past';

/**
* @var string
*/
@@ -74,6 +81,16 @@ class QueuedJobsAdmin extends ModelAdmin
*/
private static $date_format_european = 'dd/MM/yyyy';

/**
* Enables advanced admin UI
* This requires the optional module
* silverstripe-terraformers/gridfield-rich-filter-header
*
* @config
* @var bool
*/
private static $advanced_admin_ui = false;

/**
* @var QueuedJobService
*/
@@ -167,6 +184,10 @@ public function getEditForm($id = null, $fields = null)
);
}

if ($this->config()->get('advanced_admin_ui')) {
$this->enableAdvancedAdminUi($grid);
}

$this->extend('updateEditForm', $form);

return $form;
@@ -213,4 +234,161 @@ public function createjob($data, Form $form)
}
return $this->redirectBack();
}

/**
* @param GridField $gridField
*/
private function enableAdvancedAdminUi(GridField $gridField)
{
if (!class_exists(RichFilterHeader::class)) {
return;
}

$config = $gridField->getConfig();

/** @var GridFieldDataColumns $gridFieldColumns */
$gridFieldColumns = $config->getComponentByType(GridFieldDataColumns::class);

$gridFieldColumns->setDisplayFields([
'getTrimmedImplementation' => _t(__CLASS__ . '.SUMMARY_TYPE', 'Type'),
'JobTypeString' => _t(__CLASS__ . '.SUMMARY_QUEUE', 'Queue'),
'JobStatus' => _t(__CLASS__ . '.SUMMARY_STATUS', 'Status'),
'JobTitle' => _t(__CLASS__ . '.SUMMARY_DESCRIPTION', 'Description'),
'Created' => _t(__CLASS__ . '.SUMMARY_ADDED', 'Added'),
'StartAfter' => _t(__CLASS__ . '.SUMMARY_SCHEDULED', 'Scheduled'),
'JobFinished' => _t(__CLASS__ . '.SUMMARY_FINISHED', 'Finished'),
]);

$config->removeComponentsByType(GridFieldFilterHeader::class);

$filter = new RichFilterHeader();
$filter
->setFilterConfig([
'getTrimmedImplementation' => 'Implementation',
'Description' => 'JobTitle',
'Status' => [
'title' => 'JobStatus',
'filter' => 'ExactMatchFilter',
],
'JobTypeString' => [
'title' => 'JobType',
'filter' => 'ExactMatchFilter',
],
'Created' => 'Added',
'StartAfter' => 'Scheduled',
])
->setFilterFields([
'JobType' => $queueType = DropdownField::create(
'',
'',
$this->getQueueTypes()
),
'JobStatus' => $jobStatus = DropdownField::create(
'',
'',
$this->getJobStatuses()
),
'Added' => $added = DropdownField::create(
'',
'',
$this->getAddedDates()
),
'Scheduled' => $scheduled = DropdownField::create(
'',
'',
[
self::SCHEDULED_FILTER_FUTURE => self::SCHEDULED_FILTER_FUTURE,
self::SCHEDULED_FILTER_PAST => self::SCHEDULED_FILTER_PAST,
]
),
])
->setFilterMethods([
'Added' => static function (DataList $list, $name, $value) {
if ($value) {
$added = DBDatetime::now()->modify($value);

return $list->filter(['Created:LessThanOrEqual' => $added->Rfc2822()]);
}

return $list;
},
'Scheduled' => static function (DataList $list, $name, $value) {
if ($value === static::SCHEDULED_FILTER_FUTURE) {
return $list->filter([
'StartAfter:GreaterThan' => DBDatetime::now()->Rfc2822(),
]);
}

if ($value === static::SCHEDULED_FILTER_PAST) {
return $list->filter([
'StartAfter:LessThanOrEqual' => DBDatetime::now()->Rfc2822(),
]);
}

return $list;
},
]);

foreach ([$jobStatus, $queueType, $added, $scheduled] as $dropDownField) {
/** @var DropdownField $dropDownField */
$dropDownField->setEmptyString('-- select --');
}

$config->addComponent($filter, GridFieldPaginator::class);
}

/**
* Queue types options for drop down field
*
* @return array
*/
private function getQueueTypes()
{
/** @var QueuedJobDescriptor $job */
$job = QueuedJobDescriptor::singleton();
$map = $job->getJobTypeValues();
$values = array_values($map);
$keys = [];

foreach (array_keys($map) as $key) {
$keys[] = (int) $key;
}

return array_combine($keys, $values);
}

/**
* All possible job statuses (this list is not exposed by the module)
* intended to be used in a drop down field
*
* @return array
*/
private function getJobStatuses()
{
/** @var QueuedJobDescriptor $job */
$job = QueuedJobDescriptor::singleton();
$statuses = $job->getJobStatusValues();

sort($statuses, SORT_STRING);

$statuses = array_combine($statuses, $statuses);

return $statuses;
}

/**
* Date options for added dates drop down field
*
* @return array
*/
private function getAddedDates()
{
return [
'-1 day' => '1 day or older',
'-3 day' => '3 days or older',
'-7 day' => '7 days or older',
'-14 day' => '14 days or older',
'-1 month' => '1 month or older',
];
}
}
37 changes: 29 additions & 8 deletions src/DataObjects/QueuedJobDescriptor.php
Original file line number Diff line number Diff line change
@@ -310,6 +310,19 @@ public function getJobTypeString()
return isset($map[$this->JobType]) ? $map[$this->JobType] : '(Unknown)';
}

/**
* @return string
*/
public function getTrimmedImplementation()
{
$segments = explode('\\', $this->Implementation);

while (count($segments) > 2) {
array_shift($segments);
}

return implode('\\', $segments);
}

/**
* Return a map of numeric JobType values to localisable string representations.
@@ -325,16 +338,11 @@ public function getJobTypeValues()
}

/**
* @return FieldList
* @return array
*/
public function getCMSFields()
public function getJobStatusValues()
{
$fields = parent::getCMSFields();
$fields->replaceField(
'JobType',
new DropdownField('JobType', $this->fieldLabel('JobType'), $this->getJobTypeValues())
);
$statuses = [
return [
QueuedJob::STATUS_NEW,
QueuedJob::STATUS_INIT,
QueuedJob::STATUS_RUN,
@@ -344,6 +352,19 @@ public function getCMSFields()
QueuedJob::STATUS_CANCELLED,
QueuedJob::STATUS_BROKEN,
];
}

/**
* @return FieldList
*/
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->replaceField(
'JobType',
new DropdownField('JobType', $this->fieldLabel('JobType'), $this->getJobTypeValues())
);
$statuses = $this->getJobStatusValues();
$fields->replaceField(
'JobStatus',
DropdownField::create('JobStatus', $this->fieldLabel('JobStatus'), array_combine($statuses, $statuses))

0 comments on commit 0cae034

Please sign in to comment.