easyadminfriends/easyadmindashboard-bundle
Installation
composer require easyadminfriends/easyadmindashboard-bundle:3.x
Ensure your project meets requirements: PHP 8.4+, Symfony 6.4+, and EasyAdmin 4.2+.
Configure the Bundle
Add to config/packages/easy_admin_dashboard.yaml:
easy_admin_dashboard:
title: "Admin Dashboard"
blocks: []
Extend DashboardController
Override index() in your custom DashboardController:
use EasyAdminFriends\EasyAdminDashboardBundle\Service\EasyAdminDashboard;
class DashboardController extends AbstractDashboardController
{
public function __construct(private EasyAdminDashboard $dashboard) {}
public function index(): Response
{
return $this->render('@EasyAdminDashboard/Default/index.html.twig', [
'dashboard' => $this->dashboard->getDashboard(),
]);
}
}
Register the Controller
Update config/packages/easy_admin.yaml:
easy_admin:
dashboard:
controller: App\Controller\Admin\DashboardController
First Use Case
Add a simple block to easy_admin_dashboard.yaml:
blocks:
stats:
label: "System Stats"
size: 6
css_class: "info"
items:
- { label: "Total Users", value: 100, icon: "users" }
Define Blocks in Config
Use config/packages/easy_admin_dashboard.yaml to structure blocks (e.g., cards, charts, or lists). Example:
blocks:
recent_orders:
label: "Recent Orders"
size: 4
css_class: "warning"
items:
- { label: "Order #123", value: "$100.00", icon: "shopping-cart" }
Dynamic Data Injection
Extend EasyAdminDashboard service to fetch real-time data (e.g., from repositories):
// src/Service/CustomDashboardService.php
use EasyAdminFriends\EasyAdminDashboardBundle\Service\EasyAdminDashboard;
class CustomDashboardService extends EasyAdminDashboard
{
public function __construct(
private EntityManagerInterface $em,
array $config
) {
parent::__construct($config);
}
public function getDashboard(): array
{
$dashboard = parent::getDashboard();
$dashboard['blocks']['stats']['items'][0]['value'] = $this->em->getRepository(User::class)->count([]);
return $dashboard;
}
}
Bind the service in services.yaml:
services:
EasyAdminFriends\EasyAdminDashboardBundle\Service\EasyAdminDashboard:
alias: App\Service\CustomDashboardService
Reusable Block Templates
Override Twig templates in templates/EasyAdminDashboard/Default/ to customize rendering (e.g., add charts with Chart.js):
{# templates/EasyAdminDashboard/Default/block.html.twig #}
<div class="card {{ css_class }}">
<div class="card-header">{{ label }}</div>
<div class="card-body">
{% for item in items %}
<div class="d-flex align-items-center">
<i class="fas fa-{{ item.icon }} me-2"></i>
<span>{{ item.label }}: {{ item.value }}</span>
</div>
{% endfor %}
</div>
</div>
Permission-Based Blocks
Filter blocks by user roles in getDashboard():
public function getDashboard(): array
{
$dashboard = parent::getDashboard();
if (!$this->isGranted('ROLE_ADMIN')) {
unset($dashboard['blocks']['admin_only']);
}
return $dashboard;
}
Integration with EasyAdmin CRUD Link blocks to CRUD actions:
blocks:
user_management:
label: "Users"
size: 3
css_class: "primary"
items:
- { label: "View All", url: "/admin/user", icon: "user-friends" }
Configuration Overrides
easy_admin_dashboard.yaml may not reflect immediately.php bin/console cache:clear
dumpenv to debug config:
php bin/console debug:config easy_admin_dashboard
Template Caching
config/packages/dev/twig.yaml:
twig:
cache: false
Service Binding Conflicts
EasyAdminDashboard service not injected.services.yaml (see Implementation Patterns).Icon Dependencies
{# templates/base.html.twig #}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
Performance with Large Datasets
getDashboard().public function getDashboard(): array
{
$dashboard = parent::getDashboard();
$dashboard['blocks']['stats']['items'][0]['value'] =
$this->userRepository->getUserCountLazy()->getValue();
return $dashboard;
}
public function getDashboard(): array
{
$dashboard = parent::getDashboard();
$this->logger->debug('Dashboard Data:', $dashboard);
return $dashboard;
}
php bin/console debug:config-validator easy_admin_dashboard
Custom Block Types
Create a new Twig template (e.g., chart_block.html.twig) and reference it in config:
blocks:
sales_chart:
type: "chart"
template: "EasyAdminDashboard/Default/chart_block.html.twig"
data: { /* chart config */ }
Dynamic Block Loading Load blocks via AJAX for large datasets:
// assets/js/dashboard.js
document.addEventListener('DOMContentLoaded', () => {
fetch('/admin/dashboard/load-more')
.then(response => response.json())
.then(data => {
document.getElementById('dynamic-blocks').innerHTML = data.html;
});
});
Event Listeners Trigger actions on dashboard load:
// src/EventListener/DashboardListener.php
use EasyAdminFriends\EasyAdminDashboardBundle\Event\DashboardEvent;
class DashboardListener
{
public function onDashboardBuild(DashboardEvent $event)
{
$event->getDashboard()['blocks']['stats']['items'][] = [
'label' => 'New Alert',
'value' => 'Critical',
'icon' => 'exclamation-triangle',
];
}
}
Register in services.yaml:
services:
App\EventListener\DashboardListener:
tags:
- { name: kernel.event_listener, event: easy_admin_dashboard.build, method: onDashboardBuild }
Internationalization (i18n)
Use Twig’s trans filter for labels:
blocks:
stats:
label: "%dashboard.stats.label%" # Key for translation
Define translations in translations/messages.en.yaml:
dashboard:
stats:
label: "System Statistics"
How can I help you explore Laravel packages today?