Weave 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

A Symfony bundle for building customizable dashboards with widgets. Generate widgets via maker, control visibility with roles, configure caching and Twig templates, and store widget data with Doctrine migrations. Includes setup and troubleshooting recipes.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require 2lenet/dashboard2-bundle
    

    Add to config/routes.yaml:

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

    Run migrations:

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

    php bin/console make:widget
    

    Follow prompts (e.g., MyFirstWidget). This creates:

    • A widget class (src/Widget/MyFirstWidget.php) extending AbstractWidget.
    • A Twig template (templates/widget/my_first_widget.html.twig).
  3. Render the Dashboard: Add a route to your routes.yaml:

    dashboard:
        path: /dashboard
        controller: Lle\DashboardBundle\Controller\DashboardController::index
    

    Visit /dashboard to see your widget.


Implementation Patterns

Core Workflow

  1. Widget Creation:

    • Use make:widget for CRUD widgets or make:workflow-widget for workflow-specific widgets.
    • Manually extend AbstractWidget if needed (e.g., for custom logic).
  2. Rendering:

    • Override render() to return HTML (e.g., via twig() helper):
      public function render()
      {
          return $this->twig('widget/my_first_widget.html.twig', [
              'data' => $this->fetchData(),
          ]);
      }
      
    • Use Twig blocks to customize the Bootstrap 5 card layout (e.g., widget_class, widget_header).
  3. Configuration:

    • Define a form type (e.g., MyWidgetConfigType) and use createForm():
      public function render()
      {
          $form = $this->createForm(MyWidgetConfigType::class);
          return $this->twig('widget/my_first_widget.html.twig', [
              'config_form' => $form->createView(),
          ]);
      }
      
    • Access config values via getConfig('key').
  4. Static Dashboard:

    • Implement StaticWidgetProviderInterface to define a fixed widget layout:
      public function getMyWidgets(): array
      {
          return [
              'stats' => $this->buildWidget(StatsWidget::class, ['title' => 'System Stats']),
          ];
      }
      
    • Route to StaticDashboardController::staticDashboard.
  5. Chart Integration:

    • Implement ChartProviderInterface for dynamic charts:
      public function getChartList(): array
      {
          return ['daily_metrics', 'monthly_trends'];
      }
      public function getChart(string $key): Chart
      {
          return $this->chartBuilder->createChart(Chart::TYPE_LINE)->setData(...);
      }
      

Integration Tips

  • Dependencies:

    • Use Symfony UX Chart for charts (symfony/ux-chartjs).
    • For PDF exports, ensure dompdf/dompdf is installed.
  • Security:

    • Restrict widget visibility via supports() (e.g., role checks):
      public function supports(): bool
      {
          return $this->security->isGranted('ROLE_ADMIN');
      }
      
  • Performance:

    • Leverage caching with getCacheKey() and getCacheTimeout():
      public function getCacheKey(): string
      {
          return md5($this->getConfig('cache_dependency'));
      }
      
  • Testing:

    • Mock WidgetTypeInterface in unit tests:
      $widget = $this->createMock(AbstractWidget::class);
      $widget->method('render')->willReturn('<div>Test</div>');
      

Gotchas and Tips

Pitfalls

  1. Missing Routes:

    • Forgetting to add dashboard_widgets routes causes 404s. Verify with:
      php bin/console debug:router | grep dashboard
      
  2. Widget Not Appearing:

    • Check:
      • Roles: Override supports() or verify user roles (e.g., ROLE_DASHBOARD_WIDGET_NAME).
      • Network Tab: Look for 500 errors in the browser console.
      • Cache: Clear with php bin/console cache:clear.
  3. Static Dashboard Issues:

    • Widget Not Found: Ensure the provider’s getWidget() returns the correct instance by static_index.
    • Configuration Overrides: Cloning widgets in StaticWidgetProvider prevents shared state issues.
  4. Twig Template Errors:

    • Extend @LleDashboard/widget/base_widget.html.twig explicitly. Missing blocks (e.g., widget_class) may break styling.
  5. Form Submission:

    • Config forms must return JSON-serializable data. Avoid complex objects in getConfig().

Debugging

  • Widget Cache:

    • Disable caching temporarily by returning 0 from getCacheTimeout().
    • Log cache keys to verify updates:
      public function getCacheKey(): string
      {
          $key = $this->getId() . "_" . md5($this->config);
          error_log("Cache key: $key");
          return $key;
      }
      
  • Static Dashboard:

    • Test the provider in isolation:
      $provider = new StaticWidgetProvider($widgetTypes);
      dump($provider->getMyWidgets());
      

Extension Points

  1. Custom Widget Types:

    • Extend AbstractWidget to add shared logic (e.g., BaseDataWidget with fetchData()).
  2. Dynamic Roles:

    • Override role generation by implementing a voter:
      public function supports(): bool
      {
          return $this->security->isGranted('ROLE_CUSTOM');
      }
      
  3. Asset Management:

    • Use asset() in Twig for static assets (e.g., charts). Run php bin/console asset:install if stylesheets are missing.
  4. Event Listeners:

    • Hook into widget events (e.g., WidgetEvent::POST_RENDER) via Symfony’s event dispatcher:
      $this->eventDispatcher->dispatch(new WidgetEvent($this, 'post_render'));
      

Pro Tips

  • Widget Organization:

    • Group widgets by domain (e.g., src/Widget/Admin/, src/Widget/User/).
  • Reusable Components:

    • Create base templates for common layouts (e.g., widget/base_chart.html.twig).
  • Performance:

    • For heavy widgets, use getCacheTimeout(86400) (1 day) and invalidate cache on data changes:
      $this->cache->delete($this->getCacheKey());
      
  • Localization:

    • Translate widget names/titles via translation files (e.g., messages.en.yaml):
      widget.my_first_widget.name: "My First Widget"
      
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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package