Skip to content

Commit

Permalink
feat: allow user to attach actions to properties in details
Browse files Browse the repository at this point in the history
  • Loading branch information
KDederichs committed Jan 15, 2025
1 parent 8dca478 commit eddd12d
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 6 deletions.
5 changes: 5 additions & 0 deletions assets/css/easyadmin-theme/detail-page.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@
min-inline-size: 66%;
}

.ea-detail .field-group .field-actions {
flex: 1;
min-inline-size: 66%;
}

.ea-detail .field-group.field-textarea .field-value,
.ea-detail .field-group.field-text_editor .field-value {
max-block-size: 350px;
Expand Down
10 changes: 7 additions & 3 deletions src/Config/Actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ public static function new(): self
return new self($dto);
}

public function add(string $pageName, Action|string $actionNameOrObject): self
public function add(string $pageName, Action|string $actionNameOrObject, ?string $property = null): self
{
return $this->doAddAction($pageName, $actionNameOrObject);
return $this->doAddAction($pageName, $actionNameOrObject, false, $property);
}

public function addBatchAction(Action|string $actionNameOrObject): self
Expand Down Expand Up @@ -220,7 +220,7 @@ private function createBuiltInAction(string $pageName, string $actionName): Acti
throw new \InvalidArgumentException(sprintf('The "%s" action is not a built-in action, so you can\'t add or configure it via its name. Either refer to one of the built-in actions or create a custom action called "%s".', $actionName, $actionName));
}

private function doAddAction(string $pageName, Action|string $actionNameOrObject, bool $isBatchAction = false): self
private function doAddAction(string $pageName, Action|string $actionNameOrObject, bool $isBatchAction = false, ?string $property = null): self
{
$actionName = \is_string($actionNameOrObject) ? $actionNameOrObject : (string) $actionNameOrObject;
$action = \is_string($actionNameOrObject) ? $this->createBuiltInAction($pageName, $actionNameOrObject) : $actionNameOrObject;
Expand All @@ -234,6 +234,10 @@ private function doAddAction(string $pageName, Action|string $actionNameOrObject
$actionDto->setType(Action::TYPE_BATCH);
}

if (Crud::PAGE_DETAIL === $pageName) {
$actionDto->setProperty($property);
}

if (Crud::PAGE_INDEX === $pageName && Action::DELETE === $actionName) {
$this->dto->prependAction($pageName, $actionDto);
} else {
Expand Down
11 changes: 11 additions & 0 deletions src/Dto/ActionDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ final class ActionDto
private $url;
private array $translationParameters = [];
private $displayCallable;
private ?string $property = null;

public function getType(): string
{
Expand Down Expand Up @@ -311,4 +312,14 @@ public function getAsConfigObject(): Action

return $action;
}

public function getProperty(): ?string
{
return $this->property;
}

public function setProperty(?string $property): void
{
$this->property = $property;
}
}
12 changes: 12 additions & 0 deletions src/Dto/FieldDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace EasyCorp\Bundle\EasyAdminBundle\Dto;

use EasyCorp\Bundle\EasyAdminBundle\Collection\ActionCollection;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore;
use EasyCorp\Bundle\EasyAdminBundle\Form\Type\EaFormFieldsetType;
Expand Down Expand Up @@ -56,6 +57,7 @@ final class FieldDto
private $uniqueId;
private KeyValueStore $displayedOn;
private array $htmlAttributes = [];
private ?ActionCollection $actions = null;

public function __construct()
{
Expand Down Expand Up @@ -517,4 +519,14 @@ public function setHtmlAttribute(string $attribute, mixed $value): self

return $this;
}

public function getActions(): ?ActionCollection
{
return $this->actions;
}

public function setActions(?ActionCollection $actions): void
{
$this->actions = $actions;
}
}
13 changes: 12 additions & 1 deletion src/Factory/ActionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public function processEntityActions(EntityDto $entityDto, ActionConfigDto $acti
{
$currentPage = $this->adminContextProvider->getContext()->getCrud()->getCurrentPage();
$entityActions = [];
$propertyActions = [];
foreach ($actionsDto->getActions()->all() as $actionDto) {
if (!$actionDto->isEntityAction()) {
continue;
Expand Down Expand Up @@ -65,10 +66,20 @@ public function processEntityActions(EntityDto $entityDto, ActionConfigDto $acti
$actionDto->setCssClass($actionDto->getCssClass().' '.$addedCssClass);
}

$entityActions[$actionDto->getName()] = $this->processAction($currentPage, $actionDto, $entityDto);
if (!$actionDto->getProperty()) {

Check failure on line 69 in src/Factory/ActionFactory.php

View workflow job for this annotation

GitHub Actions / phpstan

Only booleans are allowed in a negated boolean, string|null given.
$entityActions[$actionDto->getName()] = $this->processAction($currentPage, $actionDto, $entityDto);
} else {
if (!isset($propertyActions[$actionDto->getProperty()])) {
$propertyActions[$actionDto->getProperty()] = [];
}
$propertyActions[$actionDto->getProperty()][$actionDto->getName()] = $this->processAction($currentPage, $actionDto, $entityDto);
}
}

$entityDto->setActions(ActionCollection::new($entityActions));
foreach ($propertyActions as $property => $actions) {
$entityDto->getFields()->getByProperty($property)?->setActions(ActionCollection::new($actions));
}
}

public function processGlobalActions(?ActionConfigDto $actionsDto = null): ActionCollection
Expand Down
14 changes: 12 additions & 2 deletions templates/crud/detail.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,18 @@
</div>
{% endif %}

<div class="field-value">
{{ include(field.templatePath, { field: field, entity: entity }, with_context = false) }}
<div>
<div class="field-value">
{{ include(field.templatePath, { field: field, entity: entity }, with_context = false) }}
</div>

{% if field.actions is not null %}
<div class="field-actions">
{% for action in field.actions %}
{{ include(action.templatePath, { action: action }, with_context = false) }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
{% endmacro %}
Expand Down

0 comments on commit eddd12d

Please sign in to comment.