diff --git a/README.md b/README.md index cb5d1cf..08f6dff 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,23 @@ The plugin automatically adds navigation items under "Resource Library": - **Created by Me** - Items you created - **Favorites** - Items you've marked as favorites +To hide those links for some users (for example roles that may enter the panel but should not see the library), use `navigationVisibleUsing()`: + +```php +use Tapp\FilamentLibrary\FilamentLibraryPlugin; + +public function panel(Panel $panel): Panel +{ + return $panel + ->plugins([ + FilamentLibraryPlugin::make() + ->navigationVisibleUsing(fn (): bool => auth()->user()?->can('view-any library-item') ?? false), + ]); +} +``` + +When unset, navigation items remain visible (backward compatible). Direct library URLs are still authorized by your library item policies. + ## Permissions System The plugin features a sophisticated permissions system inspired by Google Drive. diff --git a/src/FilamentLibraryPlugin.php b/src/FilamentLibraryPlugin.php index d431687..5b6796f 100644 --- a/src/FilamentLibraryPlugin.php +++ b/src/FilamentLibraryPlugin.php @@ -3,6 +3,7 @@ namespace Tapp\FilamentLibrary; use App\Models\User; +use Closure; use Filament\Contracts\Plugin; use Filament\Navigation\NavigationItem; use Filament\Panel; @@ -18,6 +19,11 @@ class FilamentLibraryPlugin implements Plugin protected static bool $personalFolderListenerRegistered = false; + /** + * @var (Closure(): bool)|bool|null + */ + protected Closure | bool | null $navigationVisibleUsing = null; + /** * @var array */ @@ -32,6 +38,20 @@ public function getId(): string return 'filament-library'; } + /** + * Control whether Resource Library navigation items are shown. + * + * Defaults to always visible when unset (backward compatible). + * + * @param (Closure(): bool)|bool $condition + */ + public function navigationVisibleUsing(Closure | bool $condition): static + { + $this->navigationVisibleUsing = $condition; + + return $this; + } + /** * Set a custom callback to determine if a user is a library admin. * @@ -147,7 +167,7 @@ public function register(Panel $panel): void LibraryItemResource::class, ])), ) - ->navigationItems([ + ->navigationItems($this->applyNavigationVisibility([ NavigationItem::make('Library') ->url(fn () => $libraryItemResourceClass::getUrl('index')) ->icon('heroicon-o-building-library') @@ -179,7 +199,7 @@ public function register(Panel $panel): void ->group('Resource Library') ->sort(6) ->isActiveWhen(fn () => request()->routeIs("filament.{$panelId}.resources.library.favorites")), - ]); + ])); } public function boot(Panel $panel): void @@ -225,6 +245,31 @@ protected static function sharedWithMeNavigationItem(string $panelId, string $li ]; } + public function isNavigationVisible(): bool + { + if ($this->navigationVisibleUsing === null) { + return true; + } + + if (is_bool($this->navigationVisibleUsing)) { + return $this->navigationVisibleUsing; + } + + return (bool) ($this->navigationVisibleUsing)(); + } + + /** + * @param list $items + * @return list + */ + protected function applyNavigationVisibility(array $items): array + { + return array_map( + fn (NavigationItem $item): NavigationItem => $item->visible(fn (): bool => $this->isNavigationVisible()), + $items, + ); + } + public static function make(): static { return app(static::class); diff --git a/tests/Unit/FilamentLibraryPluginTest.php b/tests/Unit/FilamentLibraryPluginTest.php index 90d6a56..0b90967 100644 --- a/tests/Unit/FilamentLibraryPluginTest.php +++ b/tests/Unit/FilamentLibraryPluginTest.php @@ -25,4 +25,32 @@ expect(LibraryItemResource::getModel())->toBe(CustomLibraryItemStub::class); }); +test('navigation is visible by default', function (): void { + $plugin = FilamentLibraryPlugin::make(); + + expect($plugin->isNavigationVisible())->toBeTrue(); +}); + +test('navigationVisibleUsing accepts a boolean', function (): void { + $plugin = FilamentLibraryPlugin::make() + ->navigationVisibleUsing(false); + + expect($plugin->isNavigationVisible())->toBeFalse(); +}); + +test('navigationVisibleUsing accepts a closure', function (): void { + $visible = false; + + $plugin = FilamentLibraryPlugin::make() + ->navigationVisibleUsing(function () use (&$visible): bool { + return $visible; + }); + + expect($plugin->isNavigationVisible())->toBeFalse(); + + $visible = true; + + expect($plugin->isNavigationVisible())->toBeTrue(); +}); + final class CustomLibraryItemStub extends LibraryItem {}