Skip to content

Commit

Permalink
NEW: Advanced jobs admin UI.
Browse files Browse the repository at this point in the history
  • Loading branch information
mfendeksilverstripe committed Oct 7, 2021
1 parent 89f00a3 commit a658779
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 0 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,17 @@ Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor:

This will add Job data and Messages raw tabs to the job descriptor edit form. Displayed information is read only.

## 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
Expand Down
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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/",
Expand Down
178 changes: 178 additions & 0 deletions src/Controllers/QueuedJobsAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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',
];
}
}
14 changes: 14 additions & 0 deletions src/DataObjects/QueuedJobDescriptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,20 @@ public function getMessagesRaw()
return $this->SavedJobMessages;
}

/**
* @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.
* @return array
Expand Down

0 comments on commit a658779

Please sign in to comment.