ENH UI updated for versioned objects and all its relations
This commit is contained in:
parent
6c69d32367
commit
c188ac72f3
|
@ -319,6 +319,10 @@ class GridField extends FormField
|
|||
$this->config->addComponent(GridState_Component::create());
|
||||
}
|
||||
|
||||
if (!$this->config->getComponentByType(GridFieldVersionTag::class)) {
|
||||
$this->config->addComponent(GridFieldVersionTag::create());
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ use SilverStripe\Control\HTTPResponse;
|
|||
use SilverStripe\Control\RequestHandler;
|
||||
use SilverStripe\Core\Convert;
|
||||
use SilverStripe\Core\ClassInfo;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Forms\CompositeField;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
use SilverStripe\Forms\Form;
|
||||
|
@ -19,6 +20,7 @@ use SilverStripe\Forms\LiteralField;
|
|||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\DataObjectInterface;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||
use SilverStripe\ORM\HasManyList;
|
||||
use SilverStripe\ORM\ManyManyList;
|
||||
|
@ -27,6 +29,7 @@ use SilverStripe\ORM\RelationList;
|
|||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\ValidationException;
|
||||
use SilverStripe\ORM\ValidationResult;
|
||||
use SilverStripe\Versioned\RecursiveStagesInterface;
|
||||
use SilverStripe\View\ArrayData;
|
||||
use SilverStripe\View\HTML;
|
||||
use SilverStripe\View\SSViewer;
|
||||
|
@ -417,7 +420,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||
throw new LogicException(get_class($this->record) . ' must implement ' . DataObjectInterface::class);
|
||||
}
|
||||
|
||||
$noChangesClasses = 'btn-outline-primary font-icon-tick';
|
||||
$noChangesClasses = $this->stagesDifferRecursive() ? 'btn-primary font-icon-save' : 'btn-outline-primary font-icon-tick';
|
||||
$majorActions->push(FormAction::create('doSave', _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.Save', 'Save'))
|
||||
->addExtraClass($noChangesClasses)
|
||||
->setAttribute('data-btn-alternate-add', 'btn-primary font-icon-save')
|
||||
|
@ -936,6 +939,25 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||
}
|
||||
}
|
||||
|
||||
$status = $this->getRecordStatus();
|
||||
$badge = null;
|
||||
if ($status) {
|
||||
// Generate badge
|
||||
$badge = DBField::create_field('HTMLFragment', sprintf(
|
||||
'<span class="badge version-status version-status--%s">%s</span>',
|
||||
$status['class'],
|
||||
$status['title']
|
||||
));
|
||||
}
|
||||
|
||||
$this->extend('updateBadge', $badge);
|
||||
|
||||
if ($badge) {
|
||||
/** @var ArrayData $lastItem */
|
||||
$lastItem = $items->last();
|
||||
$lastItem->setField('Extra', $badge);
|
||||
}
|
||||
|
||||
$this->extend('updateBreadcrumbs', $items);
|
||||
return $items;
|
||||
}
|
||||
|
@ -947,4 +969,25 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||
}
|
||||
return ClassInfo::shortName($this->record);
|
||||
}
|
||||
|
||||
private function getRecordStatus(): ?array
|
||||
{
|
||||
if ($this->stagesDifferRecursive()) {
|
||||
return [
|
||||
'class' => 'modified',
|
||||
'title' => _t(__CLASS__ . '.MODIFIED', 'Modified')
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private function stagesDifferRecursive(): bool
|
||||
{
|
||||
/** @var RecursiveStagesInterface $service */
|
||||
$service = Injector::inst()->get(RecursiveStagesInterface::class);
|
||||
|
||||
return $service->stagesDifferRecursive($this->record);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
namespace SilverStripe\Forms\GridField;
|
||||
|
||||
use SilverStripe\Forms\GridField\GridField;
|
||||
use SilverStripe\Forms\GridField\GridField_ColumnProvider;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\Versioned\Versioned;
|
||||
use SilverStripe\Core\Convert;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Versioned\RecursiveStagesInterface;
|
||||
use SilverStripe\Versioned\VersionedGridFieldState\VersionedGridFieldState;
|
||||
use SilverStripe\View\HTML;
|
||||
|
||||
class GridFieldVersionTag extends AbstractGridFieldComponent implements GridField_ColumnProvider
|
||||
{
|
||||
protected ?string $column = null;
|
||||
|
||||
protected array $versionedLabelFields = [];
|
||||
|
||||
public function __construct($versionedLabelFields = ['Name', 'Title'])
|
||||
{
|
||||
$this->setVersionedLabelFields($versionedLabelFields);
|
||||
}
|
||||
|
||||
public function getColumn(): ?string
|
||||
{
|
||||
return $this->column;
|
||||
}
|
||||
|
||||
public function setColumn(string $column): static
|
||||
{
|
||||
$this->column = $column;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVersionedLabelFields(): array
|
||||
{
|
||||
return $this->versionedLabelFields;
|
||||
}
|
||||
|
||||
public function setVersionedLabelFields(array $versionedLabelFields): static
|
||||
{
|
||||
$this->versionedLabelFields = $versionedLabelFields;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the list of columns displayed in the table.
|
||||
*
|
||||
* @see {@link GridFieldDataColumns->getDisplayFields()}
|
||||
* @see {@link GridFieldDataColumns}.
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param array $columns List reference of all column names.
|
||||
*/
|
||||
public function augmentColumns($gridField, &$columns): void
|
||||
{
|
||||
// Skip if not versioned, or column already set
|
||||
if ($this->getColumn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$matchedVersionedFields = array_intersect(
|
||||
$columns ?? [],
|
||||
$this->versionedLabelFields
|
||||
);
|
||||
|
||||
if (count($matchedVersionedFields ?? []) > 0) {
|
||||
// Get first matched column
|
||||
$this->setColumn(reset($matchedVersionedFields));
|
||||
} elseif ($columns) {
|
||||
// Use first column if none of preferred matches
|
||||
$this->setColumn(reset($columns));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Names of all columns which are affected by this component.
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnsHandled($gridField): array
|
||||
{
|
||||
return $this->getColumn() ? [$this->getColumn()] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML for the column, content of the <td> element.
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param DataObject $record Record displayed in this row
|
||||
* @param string $columnName
|
||||
* @return string HTML for the column.
|
||||
*/
|
||||
public function getColumnContent($gridField, $record, $columnName): string
|
||||
{
|
||||
$flagContent = '';
|
||||
$flags = $this->getStatusFlags($record);
|
||||
foreach ($flags as $class => $data) {
|
||||
$flagAttributes = [
|
||||
'class' => "ss-gridfield-badge badge status-{$class}",
|
||||
];
|
||||
if (isset($data['title'])) {
|
||||
$flagAttributes['title'] = $data['title'];
|
||||
}
|
||||
$flagContent .= ' ' . HTML::createTag('span', $flagAttributes, Convert::raw2xml($data['text']));
|
||||
}
|
||||
return $flagContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attributes for the column
|
||||
*/
|
||||
public function getColumnAttributes($gridField, $record, $columnName): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata for the column
|
||||
*/
|
||||
public function getColumnMetadata($gridField, $columnName): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status flags for a given record
|
||||
*/
|
||||
private function getStatusFlags(DataObject $record): array
|
||||
{
|
||||
if ($record->hasExtension(Versioned::class)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($this->stagesDifferRecursive($record)) {
|
||||
return [
|
||||
'modified' => [
|
||||
'text' => _t(__CLASS__ . '.MODIFIEDONDRAFTSHORT', 'Modified'),
|
||||
'title' => _t(__CLASS__ . '.MODIFIEDONDRAFTHELP', 'Item has unpublished changes'),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if stages differ for a given record and all its relations
|
||||
*/
|
||||
private function stagesDifferRecursive(DataObject $record): bool
|
||||
{
|
||||
/** @var RecursiveStagesInterface $service */
|
||||
$service = Injector::inst()->get(RecursiveStagesInterface::class);
|
||||
|
||||
return $service->stagesDifferRecursive($record);
|
||||
}
|
||||
}
|
|
@ -4,18 +4,37 @@ namespace SilverStripe\Forms\Tests\GridField;
|
|||
|
||||
use LogicException;
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Admin\LeftAndMain;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
use SilverStripe\Forms\Form;
|
||||
use SilverStripe\Forms\GridField\GridField;
|
||||
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
|
||||
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
||||
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Team;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\View\ArrayData;
|
||||
use SilverStripe\Versioned\Versioned;
|
||||
|
||||
class GridFieldDetailForm_ItemRequestTest extends SapphireTest
|
||||
{
|
||||
protected $usesDatabase = false;
|
||||
|
||||
protected static $fixture_file = 'GridFieldDetailForm_ItemRequestTest.yml';
|
||||
|
||||
protected static $extra_dataobjects = [
|
||||
Cheerleader::class,
|
||||
Team::class,
|
||||
];
|
||||
|
||||
protected static $required_extensions = [
|
||||
Cheerleader::class => [
|
||||
Versioned::class,
|
||||
],
|
||||
];
|
||||
|
||||
public function testItemEditFormThrowsException()
|
||||
{
|
||||
$gridField = new GridField('dummy', 'dummy', new ArrayList(), new GridFieldConfig_Base());
|
||||
|
@ -31,4 +50,24 @@ class GridFieldDetailForm_ItemRequestTest extends SapphireTest
|
|||
|
||||
$itemRequest->ItemEditForm();
|
||||
}
|
||||
|
||||
public function testBreadcrumbs()
|
||||
{
|
||||
$team = Team::get();
|
||||
$cheerleader = Cheerleader::get()->first();
|
||||
$form = new Form(null, 'Form', new FieldList(), new FieldList());
|
||||
$gridField = new GridField('TestGridField', 'TestGridFields', $team);
|
||||
$gridField->setForm($form);
|
||||
|
||||
$itemRequest = new GridFieldDetailForm_ItemRequest(
|
||||
$gridField,
|
||||
new GridFieldDetailForm(),
|
||||
$team->first(),
|
||||
new LeftandMain(),
|
||||
'',
|
||||
);
|
||||
|
||||
$item = $itemRequest->Breadcrumbs()->last()->toMap();
|
||||
$this->assertTrue(array_key_exists('Extra', $item));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
SilverStripe\Forms\Tests\GridField\GridFieldTest\Team:
|
||||
team1:
|
||||
Name: Team 1
|
||||
City: Cologne
|
||||
SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader:
|
||||
cheerleader1_team1:
|
||||
Name: Heather
|
||||
Team: =>SilverStripe\Forms\Tests\GridField\GridFieldTest\Team.team1
|
|
@ -24,6 +24,7 @@ use SilverStripe\Forms\GridField\GridFieldToolbarHeader;
|
|||
use SilverStripe\Forms\GridField\GridState;
|
||||
use SilverStripe\Forms\GridField\GridState_Component;
|
||||
use SilverStripe\Forms\GridField\GridState_Data;
|
||||
use SilverStripe\Forms\GridField\GridFieldVersionTag;
|
||||
use SilverStripe\Forms\RequiredFields;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Component;
|
||||
|
@ -96,6 +97,7 @@ class GridFieldTest extends SapphireTest
|
|||
new GridFieldPageCount('toolbar-header-right'),
|
||||
$pagination = new GridFieldPaginator(),
|
||||
new GridState_Component(),
|
||||
new GridFieldVersionTag(),
|
||||
]);
|
||||
$sort->setThrowExceptionOnBadDataType(false);
|
||||
$filter->setThrowExceptionOnBadDataType(false);
|
||||
|
@ -122,6 +124,7 @@ class GridFieldTest extends SapphireTest
|
|||
0 => new GridFieldSortableHeader,
|
||||
1 => new GridFieldDataColumns,
|
||||
2 => new GridState_Component,
|
||||
3 => new GridFieldVersionTag,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@ class Team extends DataObject implements TestOnly
|
|||
'Players' => Player::class
|
||||
];
|
||||
|
||||
private static $owns = [
|
||||
'Cheerleaders'
|
||||
];
|
||||
|
||||
private static $has_many = [
|
||||
'Cheerleaders' => Cheerleader::class
|
||||
];
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace SilverStripe\Forms\Tests\GridField;
|
||||
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\GridField\GridField;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Team;
|
||||
use SilverStripe\Versioned\Versioned;
|
||||
use SilverStripe\Forms\GridField\GridFieldVersionTag;
|
||||
|
||||
class GridFieldVersionTagTest extends SapphireTest
|
||||
{
|
||||
protected static $fixture_file = 'GridFieldVersionTagTest.yml';
|
||||
|
||||
protected static $extra_dataobjects = [
|
||||
Cheerleader::class,
|
||||
Team::class,
|
||||
];
|
||||
|
||||
protected static $required_extensions = [
|
||||
Cheerleader::class => [
|
||||
Versioned::class,
|
||||
],
|
||||
];
|
||||
|
||||
public function testGetColumnContent()
|
||||
{
|
||||
$team = Team::get();
|
||||
$cheerleader = Cheerleader::get()->first();
|
||||
$gridField = new GridField('TestGridField', 'TestGridFields', $team);
|
||||
|
||||
$columns = $gridField->getConfig()->getComponentByType(GridFieldVersionTag::class);
|
||||
$nameColumn = $columns->getColumnContent($gridField, $team->first(), 'Name');
|
||||
$this->assertEquals(
|
||||
$nameColumn,
|
||||
' <span class="ss-gridfield-badge badge status-modified" title="Item has unpublished changes">Modified</span>'
|
||||
);
|
||||
|
||||
$cheerleader->publishRecursive();
|
||||
$nameColumn = $columns->getColumnContent($gridField, $team->first(), 'Name');
|
||||
|
||||
$this->assertEquals($nameColumn, '');
|
||||
}
|
||||
|
||||
public function testAugmentColumns()
|
||||
{
|
||||
$team = Team::get();
|
||||
$cheerleader = Cheerleader::get()->first();
|
||||
$gridField = new GridField('TestGridField', 'TestGridFields', $team);
|
||||
|
||||
$columns = $gridField->getConfig()->getComponentByType(GridFieldVersionTag::class);
|
||||
|
||||
$columns->setVersionedLabelFields(['Title']);
|
||||
$column = $columns->getVersionedLabelFields();
|
||||
|
||||
$this->assertEquals($column, ['Title']);
|
||||
|
||||
$augmentColumns = ['Name', 'Title', 'ID'];
|
||||
|
||||
$columns->augmentColumns($gridField, $augmentColumns);
|
||||
$nameColumn = $columns->getColumn();
|
||||
|
||||
$this->assertEquals($nameColumn, 'Title');
|
||||
|
||||
$columns->setVersionedLabelFields(['Non-Title']);
|
||||
$column = $columns->getVersionedLabelFields();
|
||||
|
||||
$this->assertEquals($column, ['Non-Title']);
|
||||
|
||||
$columns->augmentColumns($gridField, $augmentColumns);
|
||||
$nameColumn = $columns->getColumn();
|
||||
|
||||
$this->assertNotEquals($nameColumn, 'Non-Title');
|
||||
$this->assertEquals($nameColumn, 'Title');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
SilverStripe\Forms\Tests\GridField\GridFieldTest\Team:
|
||||
team1:
|
||||
Name: Team 1
|
||||
City: Cologne
|
||||
SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader:
|
||||
cheerleader1_team1:
|
||||
Name: Heather
|
||||
Team: =>SilverStripe\Forms\Tests\GridField\GridFieldTest\Team.team1
|
Loading…
Reference in New Issue