This commit is contained in:
Sabina Talipova 2024-04-21 05:30:32 +12:00 committed by GitHub
commit 470ec0ae1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 347 additions and 1 deletions

View File

@ -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;
}

View File

@ -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;
@ -416,7 +419,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')
@ -934,6 +937,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;
}
@ -945,4 +967,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);
}
}

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -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

View File

@ -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,
]
);

View File

@ -18,6 +18,10 @@ class Team extends DataObject implements TestOnly
'Players' => Player::class
];
private static $owns = [
'Cheerleaders'
];
private static $has_many = [
'Cheerleaders' => Cheerleader::class
];

View File

@ -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');
}
}

View File

@ -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