mlsolutions/nova-dashboard

The missing dashboard for nova.

Maintainers

Package info

github.com/ml-solutions-ltda/nova-dashboard

pkg:composer/mlsolutions/nova-dashboard

Fund package maintenance!

milewski

Statistics

Installs: 6 062

Dependents: 0

Suggesters: 0

Stars: 1

v1.1.1 2026-06-22 03:10 UTC

This package is not auto-updated.

Last update: 2026-06-22 03:11:01 UTC


README

Latest Version on Packagist Total Downloads License

Laravel Nova Dashboard In Action

The missing dashboard for Laravel Nova!

Installation

You can install the package via composer:

composer require mlsolutions/nova-dashboard

List of current available widgets:

Usage

The dashboard itself is simply a standard Laravel Nova card, so you can use it either as a card on any resource or within the default Nova dashboard functionality.

use App\Models\User;
use MlSolutions\NovaDashboard\Card\NovaDashboard;
use MlSolutions\NovaDashboard\Card\View;
use MlSolutions\NovaDashboard\Filters;
use Laravel\Nova\Dashboards\Main as Dashboard;

class Main extends Dashboard
{
    public function cards(): array
    {
        return [
            NovaDashboard::make()
                ->addView('Website Performance', function (View $view) {
                    return $view
                        ->icon('window')
                        ->addWidgets([
                            BounceRate::make(),
                            ConversionRate::make(),
                            WebsiteTraffic::make(),
                            SessionDuration::make(),
                        ])
                        ->addFilters([
                            LocationFilter::make(),
                            UserTypeFilter::make(),
                            DateRangeFilter::make(),
                        ])
                        ->download(
                            resolver: function ($request, View $view, string $format, Filters $filters) {
                                return $filters
                                    ->applyToQueryBuilder(User::query())
                                    ->select('name', 'email', 'created_at');
                            },
                            label: 'Download Report',
                            filename: 'website-performance',
                            formats: ['csv', 'excel'],
                        );
                }),
        ];
    }
}

Static

By default, each widget is draggable, and the user is able to rearrange it to their liking. This behavior can be disabled by calling $view->static().

Widgets

The widgets are responsible for displaying your data on your views; they are essentially standard Nova cards. However, they respond to dashboard events and reload their data whenever the filters change.

Once you have a widget, they are usually configured like this:

class MyCustomWidget extends ValueWidget
{
    /**
     * Here you can configure your widget by calling whatever options are available for each widget
     */
    public function configure(NovaRequest $request): void
    {
        $this->icon('<svg>...</svg>');
        $this->title('Session Duration');
        $this->textColor('#f95738');
        $this->backgroundColor('#f957384f');
    }

    /**
     * This function is responsible for returning the actual data that will be shown on the widget,
     * each widget expects its own format, so please refer to the widget documentation 
     */
    public function value(Filters $filters): mixed
    {
        /**
         * $filters contain all the set values from the filters that were shown on the frontend. 
         * You can retrieve them and implement any custom logic you may have.
         */
        $filterValue = $filters->getFilterValue(LikesFilter::class);
        
        return 'example';
    }
}

All widgets have common methods to configure their size and position. The value is not in pixels but in grid units, ranging from 1 to 12 (corresponding to 12 columns).

$widget->layout(width: 2, height: 1, x: 0, y: 1);
$widget->minWidth(2);
$widget->minHeight(1);

Filters

Filters Preview

These are standard nova filter classes with 1 simple difference, the method ->apply() does not get called by default. Why?

use Illuminate\Http\Request;
use Laravel\Nova\Filters\BooleanFilter;

class ExampleFilter extends BooleanFilter
{
    public function apply(Request $request, $query, $value)
    {
        // this function is required however it is not used by the nova-dashboard
    }
}

Usually your widget ->value() function will receive an instance of MlSolutions\NovaDashboard\Filters this class contains a method for retrieving the value of any given filter, for example:

class SessionDuration extends ValueWidget
{
    public function value(Filters $filters): mixed
    {
        $filterA = $filters->getFilterValue(YourFilterClass::class);
        $filterB = $filters->getFilterValue(YourSecondFilterClass::class);
    }
}

However, if you want to reuse the logic that you have previously set on your filters or share existing filters with the dashboard you can call the method ->applyToQueryBuilder() to get the same behavior:

class SessionDuration extends ValueWidget
{
    public function value(Filters $filters): mixed
    {
        $result = $filters->applyToQueryBuilder(User::query())->get();    
    }
}

->applyToQueryBuilder() will run every filter through the default filter logic of nova.

Downloads

Views can expose a report download button that always uses the filters currently applied in the dashboard.

use App\Models\User;
use MlSolutions\NovaDashboard\Card\View;
use MlSolutions\NovaDashboard\Downloads\DownloadResult;
use MlSolutions\NovaDashboard\Filters;
use Laravel\Nova\Http\Requests\NovaRequest;

$view->download(
    resolver: function (Filters $filters, NovaRequest $request, View $view, string $format) {
        return $filters
            ->applyToQueryBuilder(User::query())
            ->select('name', 'email', 'created_at');
    },
    label: 'Download Users',
    filename: 'users-report',
    formats: ['csv', 'excel'],
);

The resolver receives the current dashboard filter state, not a prebuilt query result.

Available callback arguments:

  • NovaRequest $request: the active Nova request.
  • View $view: the current dashboard view.
  • string $format: either csv or excel.
  • Filters $filters: the same filter object used by widgets.
  • array $filterValues: all current filters serialized as class, name, and value.

This matches how dashboards are commonly built in real projects such as socialnexa-nova: widgets read filter values and then assemble the query or service call that produces the final dataset.

Accepted resolver return types:

  • Eloquent\Builder or Query\Builder: the package runs the query and exports the current result set.
  • Collection, array or any iterable list of rows: columns are inferred automatically.
  • DownloadResult: use it when you want full control over columns, row order or the exported filename.
  • An array with rows, optional columns, and optional filename.

Example with custom column order:

$view->download(
    resolver: function (Filters $filters, NovaRequest $request, View $view, string $format) {
        $rows = $filters
            ->applyToQueryBuilder(User::query())
            ->get()
            ->map(fn (User $user) => [
                'Name' => $user->name,
                'Email' => $user->email,
                'Joined At' => $user->created_at?->toDateString(),
            ]);

        return DownloadResult::make(
            columns: ['Name', 'Email', 'Joined At'],
            rows: $rows,
            filename: 'filtered-users',
        );
    },
);

Example using the raw serialized filter values:

$view->download(
    resolver: function (array $filterValues) {
        $dateRange = data_get($filterValues, App\Nova\Filters\CreateAtDateFilter::class . '.value');

        // Build your own query/service call from the active filter values.
        return [];
    },
);

excel exports a native Excel-compatible .xls file, while csv exports UTF-8 CSV with BOM for spreadsheet compatibility.

⭐️ Show Your Support

Please give a ⭐️ if this project helped you!

Other Packages You Might Like

License

The MIT License (MIT). Please see License File for more information.