Skip to content

Instantly share code, notes, and snippets.

@lucacastelnuovo
Last active January 20, 2025 16:50
Show Gist options
  • Save lucacastelnuovo/ae7d617c1c57c0047ac40804f2166c8e to your computer and use it in GitHub Desktop.
Save lucacastelnuovo/ae7d617c1c57c0047ac40804f2166c8e to your computer and use it in GitHub Desktop.
Filament V3 - Deeplink RelationManager
<?php
namespace App\Filament\AppPanel\Resources;
use App\Filament\AppPanel\Resources\ExampleResource\RelationManagers;
use Filament\Resources\Resource;
// ...
class ExampleResource extends Resource
{
// ...
public static function getRelations(): array
{
return [
BooksRelationManager::class,
CarsRelationManager::class,
];
}
}
<?php
namespace App\Filament\AppPanel\Resources\ExampleResource\Pages;
use App\Filament\AppPanel\Resources\ExampleResource;
use Filament\Resources\Pages\ViewRecord;
use Livewire\Attributes\On;
use Livewire\Attributes\Url;
class ViewExample extends ViewRecord
{
protected static string $resource = ExampleResource::class;
#[Url]
public string $deeplink = '';
public bool $deeplinkViewed = false;
#[On('parse-deeplink')]
public function parseDeeplink()
{
if ($this->deeplinkViewed) {
return;
}
$deeplink = explode('-', $this->deeplink, limit: 3);
if (3 === count($deeplink)) {
[$type, $action, $id] = $deeplink;
$types = [
'book' => '0',
'car' => '1',
];
/**
* This is not necessary but does add some security.
* Without this attackers could dispatch to any event starting with "deeplink-".
*/
if (!array_key_exists($type, $types)) {
return;
}
/**
* This code auto-switches to the correct relation manager.
* This is necessary because otherwise the actions cannot execute.
*/
$requiredRelationManagerId = $types[$type];
if ($this->activeRelationManager !== $requiredRelationManagerId) {
$this->activeRelationManager = $requiredRelationManagerId;
return;
}
$this->deeplinkViewed = true;
$this->dispatch("deeplink-{$type}", action: 'view', id: $id);
}
}
}
<?php
namespace App\Filament\Resources\ExampleResource\RelationManagers;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Table;
use Livewire\Attributes\On;
class BooksRelationManager extends RelationManager
{
protected static string $relationship = 'books';
public function mount(): void
{
parent::mount();
$this->dispatch('parse-deeplink');
}
#[On('deeplink-book')]
public function executeDeeplink(string $action, string $id)
{
$this->replaceMountedTableAction($action, $id);
}
public function table(Table $table): Table
{
return $table
// ...
->actions([
ViewAction::make(),
EditAction::make(),
]);
}
}
<?php
namespace App\Filament\Resources\ExampleResource\RelationManagers;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Table;
use Livewire\Attributes\On;
class CarsRelationManager extends RelationManager
{
protected static string $relationship = 'cars';
public function mount(): void
{
parent::mount();
$this->dispatch('parse-deeplink');
}
#[On('deeplink-car')]
public function executeDeeplink(string $action, string $id)
{
$this->replaceMountedTableAction($action, $id);
}
public function table(Table $table): Table
{
return $table
// ...
->actions([
ViewAction::make(),
EditAction::make(),
]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment