-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #6599 Allow to compute action label dynamically with a callab…
…le (hhamon) This PR was merged into the 4.x branch. Discussion ---------- Allow to compute action label dynamically with a callable The goal of this MR is to allow computing dynamic label when adding new custom actions at the top of an entity page (i.e. edit, details, etc.). For instance, I have an entity model on which I can list and add internal notes. At the top of my entity model details page, I've configured a new custom action that points to another controller that enables to view and add internal notes. For a sake of improved user experience, I want the action label to display the number of related internal notes that have been added for the entity model I'm currently administrating. <img width="379" alt="Screenshot 2024-11-28 at 20 32 57" src="https://github.com/user-attachments/assets/55082738-92f9-4d9e-ac2d-767e977b9de7"> <img width="373" alt="Screenshot 2024-11-28 at 20 36 40" src="https://github.com/user-attachments/assets/6e9703cb-02d1-4c18-a6e5-826bcebb181b"> The current implementation only enables to define a static string label for an action. Using a similar approach to the `->displayIf()`, the `Action::new()` and `Action::setLabel()` methods now supports receiving a callable that will be evaluated later by the `ActionFactory` service. The callable receives the entity model instance and is evaluated only once. The computed label gets stored in the `ActionDto::$label` property automatically. The good part of using the callable is that the label can be dynamically computed thanks to: 1. The received entity model instance 2. Any extra parameters imported/used by the `Closure` object 3. Any injected service object that the `Closure` has access to within its scope WDYT? Commits ------- d1e8742 Allow to compute action label dynamically with a callable
- Loading branch information
Showing
6 changed files
with
233 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
namespace EasyCorp\Bundle\EasyAdminBundle\Tests\Dto; | ||
|
||
use EasyCorp\Bundle\EasyAdminBundle\Dto\ActionDto; | ||
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
final class ActionDtoTest extends TestCase | ||
{ | ||
public function testComputeLabelFromStaticLabel() | ||
{ | ||
$actionDto = new ActionDto(); | ||
$actionDto->setLabel('Edit'); | ||
|
||
$actionDto->computeLabel($this->getEntityDto('42')); | ||
|
||
$this->assertSame('Edit', $actionDto->getLabel()); | ||
} | ||
|
||
public function testComputeLabelFromDynamicLabelCallable() | ||
{ | ||
$actionDto = new ActionDto(); | ||
$actionDto->setLabel(static function (object $entity) { | ||
return sprintf('Edit %s', $entity); | ||
}); | ||
|
||
$actionDto->computeLabel($this->getEntityDto('1337')); | ||
|
||
$this->assertSame('Edit #1337', $actionDto->getLabel()); | ||
} | ||
|
||
public function testComputeLabelFailsWithInvalidCallableReturnValueType() | ||
{ | ||
$actionDto = new ActionDto(); | ||
$actionDto->setLabel(static function (object $entity) { | ||
return 12345; | ||
}); | ||
|
||
$this->expectException(\RuntimeException::class); | ||
$this->expectExceptionMessage('Action label callable must return a string or a Symfony\Contracts\Translation\TranslatableInterface instance but it returned a(n) "integer" value instead.'); | ||
|
||
$actionDto->computeLabel($this->getEntityDto('1337')); | ||
} | ||
|
||
private function getEntityDto(string $entityId): EntityDto | ||
{ | ||
$entityDtoMock = $this->createMock(EntityDto::class); | ||
$entityDtoMock | ||
->expects($this->any()) | ||
->method('getInstance') | ||
->willReturn( | ||
new class($entityId) { | ||
private $entityId; | ||
|
||
public function __construct(string $entityId) | ||
{ | ||
$this->entityId = $entityId; | ||
} | ||
|
||
public function __toString(): string | ||
{ | ||
return sprintf('#%s', $this->entityId); | ||
} | ||
} | ||
); | ||
|
||
return $entityDtoMock; | ||
} | ||
} |