The Control Panel is accessible under /cp by default (configurable in config/waterhole/cp.php), and all routes are named with the waterhole.cp. prefix. To register your own routes with these attributes, use the cp method of the Routes extender:
use Illuminate\Support\Facades\Route;
use Waterhole\Extend;
Extend\CpRoutes::add(function () {
Route::get('my-route', MyController::class) // Path: /cp/my-route
->name('my-route'); // Name: waterhole.cp.my-route
});
The CpNav extender is a list of components that make up the CP navigation. You can add any component or view you want; typically you'll want to use a closure returning a NavLink component instance:
use Waterhole\Components\NavLink;
use Waterhole\Extend;
Extend\CpNav::add(
'resources',
fn() => new NavLink(
label: 'Resources',
icon: 'tabler-star',
route: 'waterhole.cp.resources',
)
);
To add styles or scripts to the Control Panel (without adding them to the global bundle), use the Stylesheet and Script extenders and specify cp as the bundle name.
use Waterhole\Extend;
Extend\Stylesheet::add(__DIR__.'/../resources/less/test.css', bundle: 'cp');
Extend\Script::add(__DIR__.'/../resources/dist/test.js', bundle: 'cp');
See Assets for more information about how Waterhole manages assets.
Widgets are just Blade components. So, to make a new widget available, define a new component:
namespace App\Widgets;
use Illuminate\View\Component;
class LatestResources extends Component
{
public function render()
{
return view('widgets.latest-resources');
}
}
Typically the widget view will contain a card beginning with a <h3> element:
Each Waterhole project can configure its widget layout in config/waterhole/cp.php – refer to the Dashboard customization documentation.
Any extra configuration options will be passed in when the widget is instantiated. For example, you could accept a limit configuration option (with a default value) like so:
class LatestResources extends Component
{
public function __construct(public int $limit = 3)
{
}
// ...
}
If your widget is a bit resource intensive – if it makes a HTTP request, or runs an expensive database query, for example – you can indicate that it should be loaded lazily, so as to not slow down the whole Dashboard loading.
Set a static $lazy property to true on your component, and Waterhole will take care of the rest:
class LatestResources extends Component
{
public static bool $lazy = true;
}