feat(sidebar) : expose GET /api/sidebar filtered by active modules

This commit is contained in:
Matthieu
2026-06-19 14:35:17 +02:00
parent 748289b61a
commit 52399b35d9
6 changed files with 239 additions and 0 deletions
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace App\Shared\Domain\Sidebar;
final class SidebarFilter
{
/**
* @param list<array{label:string, icon:string, items: list<array{label:string, to:string, icon:string, module?:string}>}> $sections
* @param list<string> $activeModuleIds
*
* @return array{sections: list<array{label:string, icon:string, items: list<array{label:string, to:string, icon:string}>}>, disabledRoutes: list<string>}
*/
public static function filter(array $sections, array $activeModuleIds): array
{
$outSections = [];
$disabledRoutes = [];
foreach ($sections as $section) {
$items = [];
foreach ($section['items'] as $item) {
$module = $item['module'] ?? null;
if (null !== $module && !in_array($module, $activeModuleIds, true)) {
$disabledRoutes[] = $item['to'];
continue;
}
$items[] = ['label' => $item['label'], 'to' => $item['to'], 'icon' => $item['icon']];
}
if ([] !== $items) {
$outSections[] = ['label' => $section['label'], 'icon' => $section['icon'], 'items' => $items];
}
}
return ['sections' => $outSections, 'disabledRoutes' => $disabledRoutes];
}
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace App\Shared\Infrastructure\ApiPlatform\Resource;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use App\Shared\Infrastructure\ApiPlatform\State\SidebarProvider;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new Get(
uriTemplate: '/sidebar',
normalizationContext: ['groups' => ['sidebar:read']],
provider: SidebarProvider::class,
),
],
)]
final class SidebarResource
{
/**
* @var list<array{label:string, icon:string, items: list<array{label:string, to:string, icon:string}>}>
*/
#[Groups(['sidebar:read'])]
public array $sections = [];
/**
* @var list<string>
*/
#[Groups(['sidebar:read'])]
public array $disabledRoutes = [];
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace App\Shared\Infrastructure\ApiPlatform\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Shared\Domain\Module\ModuleRegistry;
use App\Shared\Domain\Sidebar\SidebarFilter;
use App\Shared\Infrastructure\ApiPlatform\Resource\SidebarResource;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
final readonly class SidebarProvider implements ProviderInterface
{
public function __construct(
#[Autowire('%kernel.project_dir%')]
private string $projectDir,
) {}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): SidebarResource
{
/** @var list<class-string> $moduleClasses */
$moduleClasses = require $this->projectDir.'/config/modules.php';
/** @var list<array{label:string, icon:string, items: list<array{label:string, to:string, icon:string, module?:string}>}> $sidebar */
$sidebar = require $this->projectDir.'/config/sidebar.php';
$filtered = SidebarFilter::filter($sidebar, ModuleRegistry::ids($moduleClasses));
$dto = new SidebarResource();
$dto->sections = $filtered['sections'];
$dto->disabledRoutes = $filtered['disabledRoutes'];
return $dto;
}
}