gabelbart / nova-toolbar-tools
Adds toolbar tools and toolbar resources to laravel nova.
Requires
- php: >=7.4.0
- ext-json: *
README
Nova Toolbar Tools
A composer package for laravel nova. It enables you to globally select and persist resources.
Example use-cases:
- Base for developing your own toolbar-tools
- Select a model you want to filter for in some resources without applying the filter every time but only once every session
- Customize the menu based on the selection
- Hide or show resources
- Hide or show tools
- Customize tool behaviour based on global selection
Requirements
- Laravel Nova 3
Installation
composer require gabelbart/nova-toolbar-tools
Add the component to the Nova template
Copy vendor/laravel/nova/resources/views/layout.blade.php
to resources/views/vendor/nova/layout.blade.php
Add the following:
<toolbar-tool-list class="mx-3"></toolbar-tool-list>
To the top toolbar (body > #nova > .flex > .content > .flex:first-child
) on a position you like and adjust the margins. The result could look like this:
<!-- ... SNIP -->
<!-- Content -->
<div class="content">
<div class="flex items-center relative shadow h-header bg-white z-20 px-view">
<a v-if="@json(\Laravel\Nova\Nova::name() !== null)" href="{{ \Illuminate\Support\Facades\Config::get('nova.url') }}" class="no-underline dim font-bold text-90 mr-6">
{{ \Laravel\Nova\Nova::name() }}
</a>
@if (count(\Laravel\Nova\Nova::globallySearchableResources(request())) > 0)
<global-search dusk="global-search-component"></global-search>
@endif
<!-- TOOLS GO HERE: before the 'user-dropdown', auto-margin left, med margin right -->
<toolbar-tool-list class="ml-auto mr-3"></toolbar-tool-list>
<dropdown class="ml-3 h-9 flex items-center dropdown-right">
@include('nova::partials.user')
</dropdown>
</div>
<div data-testid="content" class="px-view py-view mx-auto">
@yield('content')
@include('nova::partials.footer')
</div>
</div>
<!-- SNIP ... -->
Add the middleware to the nova config
Add \Gabelbart\Laravel\Nova\ToolbarTools\Http\Middleware\BootToolbarTools::class
to the middleware
list in config/nova.php
Load tools in your \App\Providers\NovaServiceProvider
Add this method:
public function toolbarTools()
{
return [
];
}
Add these lines to the boot
method:
Nova::serving(function () {
\Gabelbart\Laravel\Nova\ToolbarTools\ToolbarTools::toolbarTools($this->toolbarTools());
});
If you already have a Nova::serving
block, you might just combine the contsnts.
Usage
Toolbar resources
Set up toolbar resource
Let's say you have a Resource \App\Nova\Publisher
, to create a toolbar-dropdown you need to creat an instance of \Gabelbart\Laravel\Nova\ToolbarTools\Tools\ToolbarResource
.
Add the following to the toolbarTools
method of your NovaServiceProvider
:
ToolbarResource::make(\App\Nova\Publisher::class)
It might look like this then:
public function toolbarTools()
{
return [
ToolbarResource::make(\App\Nova\Publisher::class)
];
}
Access the value
Anywhere in nova you can now access the value with the static sessionValueFor
method of \Gabelbart\Laravel\Nova\ToolbarTools\Tools\ToolbarResource
.
For example:
/** @var ?\App\Models\Publisher $publisher */
$publisher = ToolbarResource::sessionValueFor(\App\Nova\Publisher::class);
In addition, you can use the \Gabelbart\Laravel\Nova\ToolbarTools\Traits\HasToolbarSelection
trait.
This enables you to call the getToolbarSelection
and getToolbarSelectionOrFail
static methods of your resources.
class Publisher extends \Laravel\Nova\Resource
{
use \Gabelbart\Laravel\Nova\ToolbarTools\Traits\HasToolbarSelection;
}
/** @var ?\App\Models\Publisher $model */
$model = Publisher::getToolbarSelection();
Options
Label
By default the label of your nova-resource will be used, this can be customized:
ToolbarResource::make(\App\Nova\Publisher::class)
->withLabel(__('my_own_label'))
Searchable
By default all possible options will be displayed.
If you rather want the user to search you can use the searchable
option.
ToolbarResource::make(\App\Nova\Publisher::class)
->searchable()
Search - Hotkey
If you want to assign a hotkey to the search you can provide an Mousetrap option (https://craig.is/killing/mice). As second parameter you can optionally provide an alternative label.
ToolbarResource::make(\App\Nova\Publisher::class)
->withSearchHotkey('alt+p', '[Alt] + [p]')
Selection
By default the value from the session will be used, if you turned that off you might want to set the selected value yourself.
ToolbarResource::make(\App\Nova\Publisher::class)
->selection(\Auth::user()->favoritePublisher())
Saving to session
By default the value from the selection will be remembered within the session.
If you want to change that call the saveToSession
method with false
as parameter.
You might want to consider persisting the value and providing the selection yourself then,
have a look at selection
and onChange
.
ToolbarResource::make(\App\Nova\Publisher::class)
->saveToSession(false)
Reacting to selection
If you want to customize the behaviour for a selection change you can do this within a custom callback.
The request will have a parameter called id
containing the primary key of the selection.
ToolbarResource::make(\App\Nova\Publisher::class)
->onChange(fn (\Illuminate\Http\Request $request) => \App\Nova\Publisher::onChangeToolbarSelection($request))
Manipulating the index-query
Note: This will not work for the search option since it's using the global search of nova.
If you want to customize the list of available options you can use the withIndexQuery
method.
It receives the internal query builder as parameter.
However, you can return your own query builder instance if you want to replace the internal query builder.
ToolbarResource::make(\App\Nova\Book::class)
->withIndexQuery(fn (\Illuminate\Database\Eloquent\Builder $builder) => $builder->where('publisher_id', \Auth::user()->id))