From add24a557d1124a1ef728daf2b03bc0cef4e0375 Mon Sep 17 00:00:00 2001 From: Nick Rogers Date: Thu, 21 Mar 2024 09:47:09 +1030 Subject: [PATCH] feature: resource lock (config not applied for permissions) feature: use virtual column for display_name; works better with filament feature: spotlight feature: add user form feature: logger (uses policy for permissions, needs solve) fix: add $recordTitleAttribute to support spotlight --- composer.json | 5 +- composer.lock | 375 +++++++++++++++++- config/resource-lock.php | 129 ++++++ database/Seeders/RoleAndPermissionSeeder.php | 1 + ...2024_02_09_300000_create_authors_table.php | 4 +- src/Filament/Resources/AuthorResource.php | 19 +- src/Filament/Resources/PermissionResource.php | 2 + src/Filament/Resources/RoleResource.php | 2 + src/Filament/Resources/TaxonomyResource.php | 34 +- src/Filament/Resources/UserResource.php | 14 +- src/Models/Author.php | 9 - src/Providers/FilaCmsAdminPanelProvider.php | 12 +- 12 files changed, 566 insertions(+), 40 deletions(-) create mode 100644 config/resource-lock.php diff --git a/composer.json b/composer.json index fada9d56..3ad86113 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,10 @@ "spatie/laravel-permission": "^6.3", "laravel/framework": "^10.0", "mansoor/filament-versionable": "^0.0.6", - "ralphjsmit/laravel-filament-components": "^2.1" + "ralphjsmit/laravel-filament-components": "^2.1", + "kenepa/resource-lock": "^2.0", + "z3d0x/filament-logger": "^0.7.0", + "pxlrbt/filament-spotlight": "*" }, "require-dev": { "laravel/sanctum": "^3.3", diff --git a/composer.lock b/composer.lock index 3ab585a0..3b92f967 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ec0cc50ce7680d832a3b0afb04c38a40", + "content-hash": "49fc426f994ac92b0579f6b0e01e86a6", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -2182,6 +2182,74 @@ ], "time": "2023-05-21T07:57:08+00:00" }, + { + "name": "kenepa/resource-lock", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/kenepa/resource-lock.git", + "reference": "43278f1d1421684c6a42152f92a64e83f602f31e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kenepa/resource-lock/zipball/43278f1d1421684c6a42152f92a64e83f602f31e", + "reference": "43278f1d1421684c6a42152f92a64e83f602f31e", + "shasum": "" + }, + "require": { + "filament/filament": "^3.0", + "illuminate/contracts": "^9.0|^10.0|^11.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.15.0" + }, + "require-dev": { + "laravel/pint": "^1.0", + "nunomaduro/collision": "^7.0|^8.1", + "nunomaduro/larastan": "^2.0.1", + "orchestra/testbench": "^7.0|^8.0|^9.0", + "pestphp/pest": "^2.0", + "pestphp/pest-plugin-laravel": "^2.0", + "pestphp/pest-plugin-livewire": "^2.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/laravel-ray": "^1.26", + "tightenco/duster": "^1.1" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Kenepa\\ResourceLock\\ResourceLockServiceProvider" + ], + "aliases": { + "ResourceLock": "Kenepa\\ResourceLock\\Facades\\ResourceLock" + } + } + }, + "autoload": { + "psr-4": { + "Kenepa\\ResourceLock\\": "src", + "Kenepa\\ResourceLock\\Database\\Factories\\": "database/factories" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Filament Resource Lock is a Filament plugin that adds resource locking functionality to your site.", + "homepage": "https://github.com/kenepa/resource-lock", + "keywords": [ + "Kenepa", + "laravel", + "resource-lock" + ], + "support": { + "issues": "https://github.com/kenepa/resource-lock/issues", + "source": "https://github.com/kenepa/resource-lock/tree/2.0.8" + }, + "time": "2024-03-13T08:04:34+00:00" + }, { "name": "kirschbaum-development/eloquent-power-joins", "version": "3.5.2", @@ -4806,6 +4874,72 @@ }, "time": "2021-10-29T13:26:27+00:00" }, + { + "name": "pxlrbt/filament-spotlight", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/pxlrbt/filament-spotlight.git", + "reference": "138f1cf15ba72a2b4316f10fdaa4d00cd0cbda19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pxlrbt/filament-spotlight/zipball/138f1cf15ba72a2b4316f10fdaa4d00cd0cbda19", + "reference": "138f1cf15ba72a2b4316f10fdaa4d00cd0cbda19", + "shasum": "" + }, + "require": { + "filament/filament": "^3.0.0-stable", + "php": "^8.0", + "wire-elements/spotlight": "^2.0" + }, + "require-dev": { + "laravel/pint": "^1.10" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "pxlrbt\\FilamentSpotlight\\SpotlightServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "pxlrbt\\FilamentSpotlight\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dennis Koch", + "email": "info@pixelarbeit.de" + } + ], + "description": "Spotlight for Filament Admin", + "keywords": [ + "alfred", + "filament", + "laravel", + "laravel-filament", + "spotlight", + "wire-elements" + ], + "support": { + "issues": "https://github.com/pxlrbt/filament-spotlight/issues", + "source": "https://github.com/pxlrbt/filament-spotlight/tree/v1.2.1" + }, + "funding": [ + { + "url": "https://github.com/pxlrbt", + "type": "github" + } + ], + "time": "2024-02-22T07:12:14+00:00" + }, { "name": "ralphjsmit/laravel-filament-components", "version": "2.1.0", @@ -5334,6 +5468,97 @@ ], "time": "2023-07-19T18:55:36+00:00" }, + { + "name": "spatie/laravel-activitylog", + "version": "4.8.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-activitylog.git", + "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/eb6f37dd40af950ce10cf5280f0acfa3e08c3bff", + "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff", + "shasum": "" + }, + "require": { + "illuminate/config": "^8.0 || ^9.0 || ^10.0 || ^11.0", + "illuminate/database": "^8.69 || ^9.27 || ^10.0 || ^11.0", + "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.6.3" + }, + "require-dev": { + "ext-json": "*", + "orchestra/testbench": "^6.23 || ^7.0 || ^8.0 || ^9.0", + "pestphp/pest": "^1.20 || ^2.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Activitylog\\ActivitylogServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Activitylog\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Tom Witkowski", + "email": "dev.gummibeer@gmail.com", + "homepage": "https://gummibeer.de", + "role": "Developer" + } + ], + "description": "A very simple activity logger to monitor the users of your website or application", + "homepage": "https://github.com/spatie/activitylog", + "keywords": [ + "activity", + "laravel", + "log", + "spatie", + "user" + ], + "support": { + "issues": "https://github.com/spatie/laravel-activitylog/issues", + "source": "https://github.com/spatie/laravel-activitylog/tree/4.8.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-03-08T22:28:17+00:00" + }, { "name": "spatie/laravel-package-tools", "version": "1.16.4", @@ -8239,6 +8464,154 @@ "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "wire-elements/spotlight", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/wire-elements/spotlight.git", + "reference": "1d64ebdc9ea56761f6be0e5554765ce498fb16a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wire-elements/spotlight/zipball/1d64ebdc9ea56761f6be0e5554765ce498fb16a8", + "reference": "1d64ebdc9ea56761f6be0e5554765ce498fb16a8", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0", + "livewire/livewire": "^3.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.4.3" + }, + "require-dev": { + "brianium/paratest": "^6.2|^7.4", + "nunomaduro/collision": "^5.3|^8.0", + "orchestra/testbench": "^6.15|^7.0|^8.0|^9.0", + "phpunit/phpunit": "^9.3|^10.5", + "vimeo/psalm": "^4.4|^5.22" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "LivewireUI\\Spotlight\\SpotlightServiceProvider" + ], + "aliases": { + "Spotlight": "LivewireUI\\Spotlight\\SpotlightFacade" + } + } + }, + "autoload": { + "psr-4": { + "LivewireUI\\Spotlight\\": "src", + "LivewireUI\\Spotlight\\Database\\Factories\\": "database/factories" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Philo Hermans", + "email": "support@wire-elements.dev", + "role": "Developer" + } + ], + "description": "Livewire component that provides Spotlight/Alfred-like functionality to your Laravel application.", + "homepage": "https://github.com/wire-elements/spotlight", + "keywords": [ + "laravel", + "livewire-ui", + "spotlight" + ], + "support": { + "issues": "https://github.com/wire-elements/spotlight/issues", + "source": "https://github.com/wire-elements/spotlight/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/livewire-ui", + "type": "github" + } + ], + "time": "2024-03-02T12:10:01+00:00" + }, + { + "name": "z3d0x/filament-logger", + "version": "v0.7.0", + "source": { + "type": "git", + "url": "https://github.com/Z3d0X/filament-logger.git", + "reference": "b98c5e3877eb519d24e75843922407d327ecc1a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Z3d0X/filament-logger/zipball/b98c5e3877eb519d24e75843922407d327ecc1a8", + "reference": "b98c5e3877eb519d24e75843922407d327ecc1a8", + "shasum": "" + }, + "require": { + "filament/filament": "^3.0", + "illuminate/contracts": "^8.0 | ^9.0 | ^10.0 | ^11.0", + "php": "^8.0 | ^8.1", + "spatie/laravel-activitylog": "^4.5", + "spatie/laravel-package-tools": "^1.13.5" + }, + "require-dev": { + "nunomaduro/collision": "^6.0 | ^8.0", + "nunomaduro/larastan": "^2.0.1", + "orchestra/testbench": "^7.0 | ^9.0", + "pestphp/pest": "^1.21 | ^2.34", + "pestphp/pest-plugin-laravel": "^1.1 | ^2.3", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5 | ^10.5", + "spatie/laravel-ray": "^1.26" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Z3d0X\\FilamentLogger\\FilamentLoggerServiceProvider" + ], + "aliases": { + "FilamentLogger": "Z3d0X\\FilamentLogger\\Facades\\FilamentLogger" + } + } + }, + "autoload": { + "psr-4": { + "Z3d0X\\FilamentLogger\\": "src", + "Z3d0X\\FilamentLogger\\Database\\Factories\\": "database/factories" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ziyaan Hassan", + "email": "ziyaan2010@gmail.com", + "role": "Developer" + } + ], + "description": "Activity logger for filament", + "homepage": "https://github.com/z3d0x/filament-logger", + "keywords": [ + "Z3d0X", + "filament-logger", + "laravel" + ], + "support": { + "issues": "https://github.com/Z3d0X/filament-logger/issues", + "source": "https://github.com/Z3d0X/filament-logger/tree/v0.7.0" + }, + "time": "2024-03-12T17:04:40+00:00" } ], "packages-dev": [ diff --git a/config/resource-lock.php b/config/resource-lock.php new file mode 100644 index 00000000..84a36cf2 --- /dev/null +++ b/config/resource-lock.php @@ -0,0 +1,129 @@ + [ + 'User' => \App\Models\User::class, + // 'ResourceLock' => null, + ], + + /* + |-------------------------------------------------------------------------- + | Filament Resource + |-------------------------------------------------------------------------- + | + | The resource lock filament resource displays all the current locks in place. + | You are able to replace the resource Lock with your own resource class. + | + */ + 'resource' => [ + 'class' => \Kenepa\ResourceLock\Resources\ResourceLockResource::class, + ], + + /* + |-------------------------------------------------------------------------- + | Resource Unlocker Button + |-------------------------------------------------------------------------- + | + | The unlocker configuration specifies whether limited access is enabled for + | the resource unlock button. If limited access is enabled, only specific + | users or roles will be able to unlock locked resources directly from + | the modal. + | + */ + + 'unlocker' => [ + 'limited_access' => true, + 'gate' => 'unlock', + ], + + /* + |-------------------------------------------------------------------------- + | Lock Notice + |-------------------------------------------------------------------------- + | + | The lock notice contains several configuration options for the modal + | that is display when a resource is locked. + | + */ + + 'lock_notice' => [ + 'display_resource_lock_owner' => false, + ], + + /* + |-------------------------------------------------------------------------- + | Resource Lock Manager + |-------------------------------------------------------------------------- + | + | The resource lock manager provides a simple way to view all resource locks + | of your application. It provides several ways to quickly unlock all or + | specific resources within your app. + | + */ + + 'manager' => [ + 'navigation_badge' => false, + 'navigation_icon' => 'heroicon-o-lock-closed', + 'navigation_label' => 'Resource Lock Manager', + 'plural_label' => 'Resource Locksz', + 'navigation_group' => 'Settings', + 'navigation_sort' => 1, + 'limited_access' => true, + 'gate' => 'unlock' + ], + + /* + |-------------------------------------------------------------------------- + | Lock timeout (in minutes) + |-------------------------------------------------------------------------- + | + | The lock_timeout configuration specifies the time interval, in minutes, + | after which a lock on a resource will expire if it has not been manually + | unlocked or released by the user. + | + */ + + 'lock_timeout' => 10, + + /* + |-------------------------------------------------------------------------- + | Check Locks before saving + |-------------------------------------------------------------------------- + | + | The check_locks_before_saving configuration specifies whether a lock of a resource will be checked + | before saving a resource if a tech-savvy user is able to bypass the locked + | resource modal and attempt to save the resource. In some cases you may want to turns this off. + | It's recommended to keep this on. + | + */ + + 'check_locks_before_saving' => true, + + /* + |-------------------------------------------------------------------------- + | Actions + |-------------------------------------------------------------------------- + | + | Action classes are simple classes that execute some logic within the package. + | If you want to add your own custom logic you are able to extend your own + | class with class your overwriting. + | Learn more about action classes: https://freek.dev/2442-strategies-for-making-laravel-packages-customizable + | + */ + + 'actions' => [ + 'get_resource_lock_owner_action' => \Kenepa\ResourceLock\Actions\GetResourceLockOwnerAction::class, + ], +]; diff --git a/database/Seeders/RoleAndPermissionSeeder.php b/database/Seeders/RoleAndPermissionSeeder.php index 85167736..01092cda 100644 --- a/database/Seeders/RoleAndPermissionSeeder.php +++ b/database/Seeders/RoleAndPermissionSeeder.php @@ -40,6 +40,7 @@ public function run() ['name' => 'manage taxonomies'], ['name' => 'view pages'], ['name' => 'manage pages'], + ['name' => 'unlock'], ]; foreach ($permissions as $permission) { diff --git a/database/migrations/2024_02_09_300000_create_authors_table.php b/database/migrations/2024_02_09_300000_create_authors_table.php index 3f58bd08..5b24e4d5 100644 --- a/database/migrations/2024_02_09_300000_create_authors_table.php +++ b/database/migrations/2024_02_09_300000_create_authors_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration +{ /** * Run the migrations. */ @@ -19,6 +20,7 @@ public function up(): void $table->index('first_name'); $table->index('last_name'); $table->index('is_individual'); + $table->string('display_name')->virtualAs('if(is_individual, concat(first_name, " ", last_name), first_name)'); }); } diff --git a/src/Filament/Resources/AuthorResource.php b/src/Filament/Resources/AuthorResource.php index 60ecf8db..5124a5d5 100644 --- a/src/Filament/Resources/AuthorResource.php +++ b/src/Filament/Resources/AuthorResource.php @@ -23,10 +23,17 @@ class AuthorResource extends AbstractResource protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; + protected static ?string $recordTitleAttribute = 'display_name'; + public static function form(Form $form): Form { return $form ->schema([ + Toggle::make('is_individual') + ->onIcon('heroicon-m-user') + ->offIcon('heroicon-m-user-group') + ->default(true) + ->live(), Fieldset::make() ->schema([ TextInput::make('first_name') @@ -38,11 +45,6 @@ public static function form(Form $form): Form ->visible(fn (Get $get) => $get('is_individual') ? true : false), ]) ->columns(2), - Toggle::make('is_individual') - ->onIcon('heroicon-m-user') - ->offIcon('heroicon-m-user-group') - ->default(true) - ->live(), ]); } @@ -52,11 +54,10 @@ public static function table(Table $table): Table ->columns([ TextColumn::make('display_name')->sortable(), IconColumn::make('is_individual')->label('Category') - ->icon(fn (bool $state) => $state ? 'heroicon-m-user' : 'heroicon-m-user-group'), - ]) - ->filters([ - + ->icon(fn (bool $state) => $state ? 'heroicon-m-user' : 'heroicon-m-user-group') + ->tooltip(fn (bool $state) => $state ? 'Individual' : 'Organization'), ]) + ->filters([]) ->actions([ Tables\Actions\EditAction::make(), ]) diff --git a/src/Filament/Resources/PermissionResource.php b/src/Filament/Resources/PermissionResource.php index 611e69c8..73bfe4ce 100644 --- a/src/Filament/Resources/PermissionResource.php +++ b/src/Filament/Resources/PermissionResource.php @@ -21,6 +21,8 @@ class PermissionResource extends AbstractResource protected static ?string $navigationGroup = 'Security'; + protected static ?string $recordTitleAttribute = 'name'; + public static function form(Form $form): Form { return $form diff --git a/src/Filament/Resources/RoleResource.php b/src/Filament/Resources/RoleResource.php index 4fadc63f..5c47a647 100644 --- a/src/Filament/Resources/RoleResource.php +++ b/src/Filament/Resources/RoleResource.php @@ -22,6 +22,8 @@ class RoleResource extends AbstractResource protected static ?string $navigationGroup = 'Security'; + protected static ?string $recordTitleAttribute = 'name'; + public static function form(Form $form): Form { return $form diff --git a/src/Filament/Resources/TaxonomyResource.php b/src/Filament/Resources/TaxonomyResource.php index 1797031a..1a8ff920 100644 --- a/src/Filament/Resources/TaxonomyResource.php +++ b/src/Filament/Resources/TaxonomyResource.php @@ -24,6 +24,8 @@ class TaxonomyResource extends AbstractResource protected static ?string $navigationGroup = 'Taxonomies'; + protected static ?string $recordTitleAttribute = 'name'; + /** * @return array */ @@ -33,32 +35,30 @@ public static function getNavigationItems(): array foreach (Taxonomy::all() as $taxonomy) { $navItems[] = NavigationItem::make($taxonomy->name) - ->group(static::getNavigationGroup()) - ->parentItem(static::getNavigationParentItem()) - ->icon(static::getNavigationIcon()) - ->activeIcon(static::getActiveNavigationIcon()) - ->isActiveWhen(fn () => request()->routeIs(route(static::getRouteBaseName().'.edit', $taxonomy))) - ->badge(static::getNavigationBadge(), color: static::getNavigationBadgeColor()) - ->badgeTooltip(static::getNavigationBadgeTooltip()) - ->sort(static::getNavigationSort()) - ->url(route(static::getRouteBaseName().'.edit', $taxonomy)); - - } - - $navItems[] = - NavigationItem::make('Create') ->group(static::getNavigationGroup()) ->parentItem(static::getNavigationParentItem()) ->icon(static::getNavigationIcon()) ->activeIcon(static::getActiveNavigationIcon()) - ->isActiveWhen(fn () => request()->routeIs(static::getRouteBaseName().'.create')) + ->isActiveWhen(fn () => request()->routeIs(route(static::getRouteBaseName() . '.edit', $taxonomy))) ->badge(static::getNavigationBadge(), color: static::getNavigationBadgeColor()) ->badgeTooltip(static::getNavigationBadgeTooltip()) ->sort(static::getNavigationSort()) - ->url(route(static::getRouteBaseName().'.create')); + ->url(route(static::getRouteBaseName() . '.edit', $taxonomy)); + } - return $navItems; + $navItems[] = + NavigationItem::make('Create') + ->group(static::getNavigationGroup()) + ->parentItem(static::getNavigationParentItem()) + ->icon(static::getNavigationIcon()) + ->activeIcon(static::getActiveNavigationIcon()) + ->isActiveWhen(fn () => request()->routeIs(static::getRouteBaseName() . '.create')) + ->badge(static::getNavigationBadge(), color: static::getNavigationBadgeColor()) + ->badgeTooltip(static::getNavigationBadgeTooltip()) + ->sort(static::getNavigationSort()) + ->url(route(static::getRouteBaseName() . '.create')); + return $navItems; } public static function form(Form $form): Form diff --git a/src/Filament/Resources/UserResource.php b/src/Filament/Resources/UserResource.php index 544ba05c..be01c901 100644 --- a/src/Filament/Resources/UserResource.php +++ b/src/Filament/Resources/UserResource.php @@ -3,6 +3,7 @@ namespace Portable\FilaCms\Filament\Resources; use Filament\Forms\Form; +use Filament\Forms; use Filament\Tables; use Filament\Tables\Table; use Portable\FilaCms\Filament\Resources\UserResource\Pages; @@ -20,11 +21,22 @@ class UserResource extends AbstractConfigurableResource protected static ?string $navigationGroup = 'Security'; + protected static ?string $recordTitleAttribute = 'name'; + public static function form(Form $form): Form { return $form ->schema([ - // + Forms\Components\TextInput::make('name') + ->required(), + Forms\Components\TextInput::make('email') + ->email() + ->prefixIcon('heroicon-m-envelope') + ->required(), + Forms\Components\Select::make('roles') + ->relationship('roles', 'name') + ->multiple() + ->preload(), ]); } diff --git a/src/Models/Author.php b/src/Models/Author.php index 5e81fac3..af14f7b9 100644 --- a/src/Models/Author.php +++ b/src/Models/Author.php @@ -19,13 +19,4 @@ class Author extends Model protected $casts = [ 'is_individual' => 'boolean', ]; - - protected $appends = ['display_name']; - - public function displayName(): Attribute - { - return Attribute::make( - get: fn (mixed $value, array $attributes) => $attributes['is_individual'] ? $attributes['first_name'].' '.$attributes['last_name'] : $attributes['first_name'] - ); - } } diff --git a/src/Providers/FilaCmsAdminPanelProvider.php b/src/Providers/FilaCmsAdminPanelProvider.php index 29bf218c..e50ea3c3 100644 --- a/src/Providers/FilaCmsAdminPanelProvider.php +++ b/src/Providers/FilaCmsAdminPanelProvider.php @@ -17,7 +17,9 @@ use Illuminate\Session\Middleware\AuthenticateSession; use Illuminate\Session\Middleware\StartSession; use Illuminate\View\Middleware\ShareErrorsFromSession; +use Kenepa\ResourceLock\ResourceLockPlugin; use Portable\FilaCms\Http\Middleware\FilaCmsAuthenticate; +use pxlrbt\FilamentSpotlight\SpotlightPlugin; class FilaCmsAdminPanelProvider extends PanelProvider { @@ -27,11 +29,19 @@ public function panel(Panel $panel): Panel ->default() ->id('admin') ->path('admin') + ->unsavedChangesAlerts() ->login() ->colors([ 'primary' => Color::Amber, ]) - ->plugins($this->getPlugins()) + ->plugins([ + SpotlightPlugin::make(), + ResourceLockPlugin::make(), + ...$this->getPlugins() + ]) + ->resources([ + config('filament-logger.activity_resource'), + ]) ->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources') ->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages') ->pages([