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

Dashboard Module Laravel Package

anomaly/dashboard-module

A dashboard module for the Anomaly CMS/Streams platform for Laravel, providing a ready-made administrative dashboard interface to display widgets, panels, and key information within your application's control panel.

View on GitHub
Deep Wiki
Context7

Getting Started

The Dashboard module is an addon for the Streams Platform (the framework under PyroCMS 3.x), not a standalone Laravel package. It gives the control panel an admin/dashboard landing page plus the widget container that other addons drop cards into. With 3 stars and no dependents, treat it as an internal ecosystem component: it assumes you are already running a Streams-powered app and that the platform's addon loader is doing the wiring.

Prerequisites before you composer require anything

  • A Laravel app bootstrapped with anomaly/streams-platform (or PyroCMS 3.x), with the AddonServiceProvider discovery running.
  • A Laravel version that matches the platform release you're on. This package tracks the platform's own Laravel constraint, so pin both together rather than upgrading Laravel independently.
  • Familiarity with Streams addons: every addon is a Composer package with a module class + a service provider, discovered from vendor/ and addons/.

Minimal steps

composer require anomaly/dashboard-module
php artisan addon:install anomaly/dashboard-module
php artisan addon:publish anomaly/dashboard-module   # only if you intend to override views/config
php artisan view:clear && php artisan assets:clear

Then hit /admin/dashboard while authenticated as an admin. If the nav item or the page is missing, the install step is almost always the culprit — the addon registers routes and sections at boot, but its tables and seeded widget records come from the install migrations.

Where to look first, in this order

  1. src/DashboardModuleServiceProvider.php — this is the real API surface. Read the $routes, $sections, $buttons, $widgets, $assets, and $bindings properties; everything the module exposes is declared there.
  2. src/Widget/ — the widget contract/model/repository. This is what you'll extend day-to-day.
  3. resources/views/ — the dashboard shell and per-widget partials. Views here are Twig (via TwigBridge), so expect .twig, not .blade.php.
  4. migrations/ — tells you whether per-user layout persistence exists (a dashboard_widgets-style table) or whether the layout is static.

Do not assume class names from any README; open src/ and confirm. The repository has essentially no external users, so there is no community-vetted documentation to fall back on.

First real use case: replace one of the stock cards with a card showing your data — e.g. "unread support tickets" or "revenue today". That exercises the whole loop: a widget registration in your own addon, a view, and a data provider. If that works, everything else in this module is variation on the same theme.

Implementation Patterns

Pattern 1: Register your own widget from an existing addon

The dashboard is a widget host. You almost never edit this package; you register widgets into it from your project addon's service provider.

// addons/default/example/support-module/src/SupportModuleServiceProvider.php
protected $widgets = [
    \Example\SupportModule\Widget\OpenTicketsWidget::class,
];

The widget class typically extends the module's widget extension/model and declares a title, a view, and a render()/getData() hook. Keep the widget class thin — resolve a repository in the method body rather than injecting via constructor, because Streams instantiates some addon classes through its own container conventions and constructor injection is inconsistently respected across platform versions.

Pattern 2: Dashboard-as-a-section of your own admin surface

If you're building a custom panel and want the same dashboard shell without installing this addon as your landing page, mirror what the service provider does: declare a section in your module class and point it at the dashboard route.

// src/YourModule.php
protected $sections = [
    'dashboard' => [
        'buttons' => [
            'dashboard' => ['href' => 'admin/dashboard', 'text' => 'Dashboard'],
        ],
    ],
];

This is the highest-leverage pattern: the module's value is really the section/route/asset registration, not the specific cards it ships.

Pattern 3: Override the layout without forking

Streams resolves addon views through a publish/override chain. Publishing puts the views under resources/{addon-slug}/ in your app, where they win over the vendor copy.

php artisan addon:publish anomaly/dashboard-module

Then edit the published Twig partials (index.twig, the widget wrapper). Prefer this over editing vendor/ — Composer will silently wipe vendor edits on the next update, and this package gets infrequent releases, so a "temporary" vendor patch can survive for months and then vanish at the worst time.

Pattern 4: Route and middleware overrides

If you need auth/role gating beyond the platform default, add middleware in your app rather than editing the addon's $routes:

// app/Http/Kernel.php or a route group in a service provider
Route::middleware(['web', 'auth', 'can:access-admin'])
    ->group(base_path('vendor/anomaly/dashboard-module/resources/routes.php'));

Cleaner alternative: leave the addon's routes alone, and gate the section/button visibility so unauthorized users never see the nav entry.

Pattern 5: Widget data providers

Standard shape used across the ecosystem — a widget's render method returns a view with data, and the view handles presentation:

public function render()
{
    return view('example/support_module::widgets/open_tickets', [
        'count' => $this->tickets->open()->count(),
    ]);
}

Cache anything expensive here. The dashboard has no built-in caching layer, and a dashboard page is the single most-loaded admin URL in most applications — five widgets each running three uncached queries is the classic first-month performance regression.

Workflow tips

  • Keep this module unmodified and put all customization in a project-level addon. Streams' override chain is good enough that forking buys you nothing and costs you upgrades.
  • Add the widget registration to your own addon's service provider so dashboard cards are versioned with the feature they summarize.
  • If you're on PyroCMS 3, prefer the PyroCMS dashboard conventions over this package's, and check whether the CMS already bundles an equivalent before adding a second dashboard surface.
  • Pin the version in composer.json with an explicit constraint and commit the lockfile. There is no release cadence to rely on here.

Gotchas and Tips

The install step is not optional and not idempotent-looking. Streams addons need addon:install to run their migrations and seed their registries. Skipping it produces a route that resolves to a blank page or a 404 with no error — the least helpful failure mode. If the dashboard renders empty, re-run install and check the addons table's installed flag before debugging anything else.

Twig, not Blade. Views are Twig. If you drop a .blade.php file into an override path, it will be silently ignored and you'll chase a "my change isn't showing up" bug. The view:clear command clears Streams' own compiled view cache too, but asset caches are separate (assets:clear).

Namespace and slug collisions. The addon slug (dashboard) is used for view namespaces, config keys, and translation keys. Naming your own addon dashboard-anything risks the same namespace prefix and produces confusing override resolution where your views win unexpectedly.

Class names in examples and blog posts are unreliable. Because the package has essentially no user base, any tutorial you find may reference pre-rename classes from an older platform version. Always confirm against src/ in the version you installed. This is the single biggest time sink with low-star Anomaly packages.

Upgrades are coupled. The dashboard's service provider implements Streams' addon contracts directly, so a platform minor bump can change method signatures the module overrides. Before any platform upgrade, run the dashboard route and every custom widget in a staging environment. There is no test suite of consequence in this repo to catch it for you.

Watch the Laravel/Streams constraint, not the package version. composer require anomaly/dashboard-module will happily resolve against an old platform if the constraint allows. Start from the platform version you actually run, then constrain the addon.

Debugging order that actually works: (1) php artisan route:list | grep dashboard — is the route registered at all? (2) Is the addon in the addons table as installed and enabled? (3) Does the service provider boot — php artisan tinker and check the container for the module class. (4) Only then look at views. Ninety percent of "the dashboard is broken" reports resolve at step 1 or 2.

Extension points, ranked by risk: registering widgets (safe), publishing and overriding views (safe, upgrade-friendly), overriding routes via your own group (safe), extending the widget model/repository (moderate — couples you to internal schema), editing vendor/ (avoid). If you find yourself needing to modify the module class itself, that's a signal your requirement belongs in a separate section of your own addon instead.

Consider whether you need this at all. If you're on a current PyroCMS release, the CMS ships its own control panel dashboard. For a plain Laravel/Streams app, a single route + Blade view in your own addon reproduces the useful part of this package in about 40 lines, without inheriting an unmaintained dependency whose only dependents are zero. Adopt it because you want the Streams-native widget contract and section registration, not because you want "a dashboard."

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle