From cc0370f9eec06b440d08341ed1bb7cf088aa4788 Mon Sep 17 00:00:00 2001 From: Adam Weston Date: Tue, 5 Nov 2024 14:02:59 -0500 Subject: [PATCH] Feat: support create another as optional --- README.md | 17 ++++ src/Components/QuickCreateMenu.php | 130 +++++++++++++++++------------ src/QuickCreatePlugin.php | 14 ++++ 3 files changed, 109 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index f8d723b..8140ccd 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,23 @@ public function panel(Panel $panel): Panel } ``` +### Create Another + +By default, the ability to create another record will respect the settings of your 'create record' or 'list records' create action. This can be overridden to either enable or disable it for all resources with the `createAnother()` method. + +```php +use Awcodes\FilamentQuickCreate\QuickCreatePlugin; + +public function panel(Panel $panel): Panel +{ + return $panel + ->plugins([ + QuickCreatePlugin::make() + ->createAnother(false), + ]) +} +``` + ### Appearance #### Rounded diff --git a/src/Components/QuickCreateMenu.php b/src/Components/QuickCreateMenu.php index a743a3e..4b952ef 100644 --- a/src/Components/QuickCreateMenu.php +++ b/src/Components/QuickCreateMenu.php @@ -76,75 +76,101 @@ protected function cacheActions(): void public function getActions(): array { - return collect($this->resources)->transform(function ($resource) { - $r = App::make($resource['resource_name']); - - return CreateAction::make($resource['action_name']) - ->authorize($r::canCreate()) - ->model($resource['model']) - ->slideOver(fn (): bool => QuickCreatePlugin::get()->shouldUseSlideOver()) - ->form(function ($arguments, $form) use ($r) { - return $r->form($form->operation('create')->columns()); - })->action(function (array $arguments, Form $form, CreateAction $action) use ($r): void { - $model = $action->getModel(); - - $record = $action->process(function (array $data, HasActions $livewire) use ($model, $action, $r): Model { - if ($translatableContentDriver = $livewire->makeFilamentTranslatableContentDriver()) { - $record = $translatableContentDriver->makeRecord($model, $data); - } else { - $record = new $model(); - $record->fill($data); + return collect($this->resources) + ->transform(function ($resource) { + $r = App::make($resource['resource_name']); + $canCreateAnother = QuickCreatePlugin::get()->canCreateAnother(); + + if ($canCreateAnother === null) { + if ($r->hasPage('create')) { + $canCreateAnother = App::make($r->getPages()['create']->getPage())::canCreateAnother(); + } else { + $page = isset($r->getPages()['index']) + ? $r->getPages()['index']->getPage() + : null; + + if ($page) { + $reflectionMethod = new \ReflectionMethod($page, 'getHeaderActions'); + $actions = $reflectionMethod->invoke(new $page()); + $createAction = collect($actions)->filter(function ($action) { + return $action instanceof CreateAction; + })->first(); + + if ($createAction) { + $canCreateAnother = $createAction->canCreateAnother(); + } } + } + } + + return CreateAction::make($resource['action_name']) + ->authorize($r::canCreate()) + ->model($resource['model']) + ->slideOver(fn (): bool => QuickCreatePlugin::get()->shouldUseSlideOver()) + ->form(function ($arguments, $form) use ($r) { + return $r->form($form->operation('create')->columns()); + }) + ->createAnother($canCreateAnother) + ->action(function (array $arguments, Form $form, CreateAction $action) use ($r): void { + $model = $action->getModel(); + + $record = $action->process(function (array $data, HasActions $livewire) use ($model, $action, $r): Model { + if ($translatableContentDriver = $livewire->makeFilamentTranslatableContentDriver()) { + $record = $translatableContentDriver->makeRecord($model, $data); + } else { + $record = new $model(); + $record->fill($data); + } - if ($relationship = $action->getRelationship()) { - /** @phpstan-ignore-next-line */ - $relationship->save($record); + if ($relationship = $action->getRelationship()) { + /** @phpstan-ignore-next-line */ + $relationship->save($record); - return $record; - } + return $record; + } - if ( - $r::isScopedToTenant() && - ($tenant = Filament::getTenant()) - ) { - $relationship = $r::getTenantRelationship($tenant); + if ( + $r::isScopedToTenant() && + ($tenant = Filament::getTenant()) + ) { + $relationship = $r::getTenantRelationship($tenant); - if ($relationship instanceof HasManyThrough) { - $record->save(); + if ($relationship instanceof HasManyThrough) { + $record->save(); - return $record; - } + return $record; + } - return $relationship->save($record); - } + return $relationship->save($record); + } - $record->save(); + $record->save(); - return $record; - }); + return $record; + }); - $action->record($record); - $form->model($record)->saveRelationships(); + $action->record($record); + $form->model($record)->saveRelationships(); - if ($arguments['another'] ?? false) { - $action->callAfter(); - $action->sendSuccessNotification(); + if ($arguments['another'] ?? false) { + $action->callAfter(); + $action->sendSuccessNotification(); - $action->record(null); + $action->record(null); - // Ensure that the form record is anonymized so that relationships aren't loaded. - $form->model($model); + // Ensure that the form record is anonymized so that relationships aren't loaded. + $form->model($model); - $form->fill(); + $form->fill(); - $action->halt(); + $action->halt(); - return; - } + return; + } - $action->success(); - }); - }) + $action->success(); + }); + }) ->values() ->toArray(); } diff --git a/src/QuickCreatePlugin.php b/src/QuickCreatePlugin.php index 6af00b9..67ae778 100644 --- a/src/QuickCreatePlugin.php +++ b/src/QuickCreatePlugin.php @@ -42,6 +42,8 @@ class QuickCreatePlugin implements Plugin protected string | array | Closure | null $keyBindings = null; + protected bool | Closure | null $createAnother = null; + public function boot(Panel $panel): void { Livewire::component('quick-create-menu', Components\QuickCreateMenu::class); @@ -261,4 +263,16 @@ public function getKeyBindings(): ?array { return collect($this->evaluate($this->keyBindings))->toArray(); } + + public function createAnother(bool | Closure $condition = true): static + { + $this->createAnother = $condition; + + return $this; + } + + public function canCreateAnother(): ?bool + { + return $this->evaluate($this->createAnother); + } }