Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dashboard2 Bundle Laravel Package

2lenet/dashboard2-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require 2lenet/dashboard2-bundle
    

    Add routes in config/routes.yaml:

    dashboard_widgets:
        resource: "@LleDashboardBundle/Resources/config/routes.yaml"
    
  2. Database Setup

    php bin/console make:migration
    php bin/console doctrine:migrations:migrate
    
  3. First Widget Generate a widget using the maker:

    php bin/console make:widget
    

    Provide a short name (e.g., user_stats), and the bundle generates a class and template.

  4. Verify Widget Visibility Ensure the widget appears in the dashboard. If not, check:

    • Roles (default: ROLE_DASHBOARD_<WIDGET_NAME>).
    • Network tab for 500 errors.
    • Clear cache (php bin/console cache:clear).

Implementation Patterns

Core Workflow

  1. Widget Creation Extend AbstractWidget and implement render(), getName(), and optionally supports(). Example:

    use Lle\DashboardBundle\Widgets\AbstractWidget;
    
    class UserStatsWidget extends AbstractWidget {
        public function render() {
            return $this->twig("widget/user_stats.html.twig", [
                "users" => $this->getUserService()->getActiveUsers()
            ]);
        }
    
        public function getName() {
            return "user_stats.title"; // Translatable
        }
    }
    
  2. Templating Extend @LleDashboard/widget/base_widget.html.twig:

    {% extends '@LleDashboard/widget/base_widget.html.twig' %}
    {% block widget_content %}
        <div>{{ users|length }} active users</div>
    {% endblock %}
    
  3. Dynamic Data Fetching Use dependency injection (e.g., UserService) in the widget constructor:

    public function __construct(private UserService $userService) {}
    
  4. Configuration Add a form for user-configurable settings:

    public function render() {
        $form = $this->createForm(UserStatsType::class);
        return $this->twig("widget/user_stats.html.twig", [
            "config_form" => $form->createView(),
            "users" => $this->userService->getUsers($this->getConfig("filter"))
        ]);
    }
    
  5. Caching Override getCacheKey() and getCacheTimeout() for performance:

    public function getCacheKey() {
        return $this->getId() . "_" . md5($this->getConfig("filter"));
    }
    
    public function getCacheTimeout() {
        return 300; // 5 minutes
    }
    
  6. Static Dashboard Implement StaticWidgetProviderInterface for fixed layouts:

    public function getMyWidgets(): array {
        return [
            "users" => $this->buildWidget(UserStatsWidget::class, ["title" => "Active Users"])
        ];
    }
    

Integration Tips

  • ChartJS Integration Implement ChartProviderInterface for dynamic charts:

    public function getChartList(): array {
        return ["daily_active_users", "monthly_signups"];
    }
    
    public function getChart(string $confKey): Chart {
        $data = $this->fetchChartData($confKey);
        return $this->chartBuilder->createChart(Chart::TYPE_LINE)
            ->setData($data)
            ->setOptions(["responsive" => true]);
    }
    
  • Role-Based Access Override supports() to restrict visibility:

    public function supports(): bool {
        return $this->security->isGranted('ROLE_ADMIN');
    }
    
  • PDF Export Customize export settings in render():

    return $this->twig("widget/report.html.twig", [
        "exportable" => ["orientation" => "landscape", "format" => "a4"]
    ]);
    

Gotchas and Tips

Pitfalls

  1. Widget Not Appearing?

    • Check Roles: Default role is ROLE_DASHBOARD_<WIDGET_NAME>. Ensure users have this role.
    • 500 Errors: Inspect the network tab for failed AJAX requests. Common causes:
      • Missing dependencies (e.g., symfony/ux-chartjs for charts).
      • Unhandled exceptions in render().
    • Cache Issues: Clear cache after changes:
      php bin/console cache:clear
      php bin/console asset:install
      
  2. Static Dashboard 404s

    • Ensure the route is correctly configured in config/routes.yaml:
      home:
          path: /
          controller: Lle\DashboardBundle\Controller\StaticDashboardController::staticDashboard
      
  3. Widget Configuration Not Saving

    • Verify the form type is properly bound to the widget’s config structure. Use getConfig() to retrieve values:
      $filter = $this->getConfig("filter", "all"); // Default to "all"
      
  4. ChartJS Not Rendering

    • Ensure symfony/ux-chartjs is installed and the widget implements ChartProviderInterface.
    • Check the browser console for JavaScript errors (e.g., missing Chart.js library).
  5. Migration Failures

    • Always verify the generated migration file for the widgets table before running migrate. Example schema:
      $table->id();
      $table->string('type');
      $table->json('config')->nullable();
      $table->integer('position');
      $table->string('user_id')->nullable();
      

Debugging Tips

  • Log Widget Data Add debug logs in render() to inspect data:

    $this->logger->debug("Widget data:", ["config" => $this->config]);
    
  • Override Base Template To debug rendering issues, override the base template and add {{ dump(widget) }}:

    {% extends '@LleDashboard/widget/base_widget.html.twig' %}
    {% block widget_content %}
        {{ dump(widget) }}
        <!-- Your content -->
    {% endblock %}
    
  • Disable Cache Temporarily Set getCacheTimeout() to 0 to bypass caching during development:

    public function getCacheTimeout() { return 0; }
    

Extension Points

  1. Custom Widget Types Create a custom maker command by extending make:widget:

    php bin/console make:command CustomWidgetMaker
    

    Override configure() to generate specialized widgets.

  2. Dynamic Widget Loading Use Symfony’s autowiring to lazy-load widgets:

    public function __construct(private iterable $widgetTypes) {}
    

    Filter widgets by interface or trait (e.g., ChartProviderInterface).

  3. Widget Events Dispatch events for cross-cutting concerns (e.g., logging, analytics):

    $this->eventDispatcher->dispatch(new WidgetRenderEvent($this));
    
  4. Static Dashboard Extensions Add a refresh button by extending the static dashboard template:

    <button onclick="refreshStaticDashboard('{index}')">Refresh</button>
    

    Implement AJAX endpoint in StaticDashboardController.

  5. Widget Testing Test widgets in isolation using WidgetTestCase:

    use Lle\DashboardBundle\Tests\WidgetTestCase;
    
    class UserStatsWidgetTest extends WidgetTestCase {
        public function testRender() {
            $widget = new UserStatsWidget($this->security);
            $html = $widget->render();
            $this->assertStringContainsString("Active Users", $html);
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui