From fbc6ce7141954d460817b3be171724992d1b74f5 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Sun, 24 Nov 2024 18:15:29 +0000 Subject: [PATCH] Generate Table Livewire components --- ...ommand.php => MakeLivewireFormCommand.php} | 2 +- packages/forms/src/FormsServiceProvider.php | 2 +- .../Concerns/CanGenerateResourceTables.php | 154 +---------- .../src/Commands/MakeResourceCommand.php | 4 +- packages/support/src/CliManager.php | 21 ++ .../Concerns/CanAskForComponentLocation.php | 2 +- .../CanAskForLivewireComponentLocation.php | 57 ++++ packages/support/src/Facades/FilamentCli.php | 4 +- .../Concerns/CanGenerateTables.php | 126 +++++---- .../LivewireTableClassGenerator.php | 172 ++++++++++++ .../tables/src/Commands/MakeColumnCommand.php | 4 +- .../src/Commands/MakeLivewireTableCommand.php | 246 ++++++++++++++++++ .../tables/src/Commands/MakeTableCommand.php | 102 -------- packages/tables/src/TablesServiceProvider.php | 2 +- ...{TableView.stub => LivewireTableView.stub} | 0 packages/tables/stubs/Table.stub | 46 ---- .../Legacy/LegacyMakePageCommandTest.php | 14 +- .../LegacyMakeRelationManagerCommandTest.php | 4 +- .../Legacy/LegacyMakeResourceCommandTest.php | 32 +-- .../Panels/Commands/MakePageCommandTest.php | 14 +- .../MakeRelationManagerCommandTest.php | 4 +- .../Commands/MakeResourceCommandTest.php | 94 +++---- 22 files changed, 667 insertions(+), 439 deletions(-) rename packages/forms/src/Commands/{MakeFormCommand.php => MakeLivewireFormCommand.php} (98%) create mode 100644 packages/support/src/Commands/Concerns/CanAskForLivewireComponentLocation.php rename packages/tables/src/Commands/{ => FileGenerators}/Concerns/CanGenerateTables.php (57%) create mode 100644 packages/tables/src/Commands/FileGenerators/LivewireTableClassGenerator.php create mode 100644 packages/tables/src/Commands/MakeLivewireTableCommand.php delete mode 100644 packages/tables/src/Commands/MakeTableCommand.php rename packages/tables/stubs/{TableView.stub => LivewireTableView.stub} (100%) delete mode 100644 packages/tables/stubs/Table.stub diff --git a/packages/forms/src/Commands/MakeFormCommand.php b/packages/forms/src/Commands/MakeLivewireFormCommand.php similarity index 98% rename from packages/forms/src/Commands/MakeFormCommand.php rename to packages/forms/src/Commands/MakeLivewireFormCommand.php index 353bf4097a..181660d03a 100644 --- a/packages/forms/src/Commands/MakeFormCommand.php +++ b/packages/forms/src/Commands/MakeLivewireFormCommand.php @@ -16,7 +16,7 @@ use function Laravel\Prompts\text; #[AsCommand(name: 'make:filament-livewire-form', aliases: [ 'make:livewire-form', ])] -class MakeFormCommand extends Command +class MakeLivewireFormCommand extends Command { use CanGenerateForms; use CanIndentStrings; diff --git a/packages/forms/src/FormsServiceProvider.php b/packages/forms/src/FormsServiceProvider.php index 59a0cf460c..5e5c835371 100644 --- a/packages/forms/src/FormsServiceProvider.php +++ b/packages/forms/src/FormsServiceProvider.php @@ -20,7 +20,7 @@ class FormsServiceProvider extends PackageServiceProvider ->name('filament-forms') ->hasCommands([ Commands\MakeFieldCommand::class, - Commands\MakeFormCommand::class, + Commands\MakeLivewireFormCommand::class, ]) ->hasTranslations() ->hasViews(); diff --git a/packages/panels/src/Commands/FileGenerators/Resources/Concerns/CanGenerateResourceTables.php b/packages/panels/src/Commands/FileGenerators/Resources/Concerns/CanGenerateResourceTables.php index 79671bb400..ea25a6c6ff 100644 --- a/packages/panels/src/Commands/FileGenerators/Resources/Concerns/CanGenerateResourceTables.php +++ b/packages/panels/src/Commands/FileGenerators/Resources/Concerns/CanGenerateResourceTables.php @@ -19,19 +19,19 @@ use Filament\Actions\ForceDeleteBulkAction; use Filament\Actions\RestoreAction; use Filament\Actions\RestoreBulkAction; use Filament\Actions\ViewAction; -use Filament\Tables\Columns\IconColumn; -use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\TextColumn; +use Filament\Tables\Commands\FileGenerators\Concerns\CanGenerateTables; use Filament\Tables\Filters\BaseFilter; use Filament\Tables\Filters\TrashedFilter; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletingScope; -use Illuminate\Support\Str; use Nette\PhpGenerator\Literal; trait CanGenerateResourceTables { + use CanGenerateTables; + /** * @param ?class-string $model */ @@ -91,154 +91,6 @@ trait CanGenerateResourceTables PHP; } - /** - * @param ?class-string $model - * @return array - */ - public function getTableColumns(?string $model = null): array - { - if (! $this->isGenerated()) { - return []; - } - - if (blank($model)) { - return []; - } - - if (! class_exists($model)) { - return []; - } - - $schema = $this->getModelSchema($model); - $table = $this->getModelTable($model); - - $columns = []; - - foreach ($schema->getColumns($table) as $column) { - if ($column['auto_increment']) { - continue; - } - - $type = $this->parseColumnType($column); - - if (in_array($type['name'], [ - 'json', - 'text', - ])) { - continue; - } - - $columnName = $column['name']; - - if (str($columnName)->endsWith([ - '_token', - ])) { - continue; - } - - if (str($columnName)->contains([ - 'password', - ])) { - continue; - } - - if (str($columnName)->endsWith('_id')) { - $guessedRelationshipName = $this->guessBelongsToRelationshipName($columnName, $model); - - if (filled($guessedRelationshipName)) { - $guessedRelationshipTitleColumnName = $this->guessBelongsToRelationshipTitleColumnName($columnName, app($model)->{$guessedRelationshipName}()->getModel()::class); - - $columnName = "{$guessedRelationshipName}.{$guessedRelationshipTitleColumnName}"; - } - } - - $columnData = []; - - if (in_array($columnName, [ - 'id', - 'sku', - 'uuid', - ])) { - $columnData['label'] = [Str::upper($columnName)]; - } - - if ($type['name'] === 'boolean') { - $columnData['type'] = IconColumn::class; - $columnData['boolean'] = []; - } else { - $columnData['type'] = match (true) { - $columnName === 'image', str($columnName)->startsWith('image_'), str($columnName)->contains('_image_'), str($columnName)->endsWith('_image') => ImageColumn::class, - default => TextColumn::class, - }; - - if (in_array($type['name'], [ - 'string', - 'char', - ]) && ($columnData['type'] === TextColumn::class)) { - $columnData['searchable'] = []; - } - - if (in_array($type['name'], [ - 'date', - ])) { - $columnData['date'] = []; - $columnData['sortable'] = []; - } - - if (in_array($type['name'], [ - 'datetime', - 'timestamp', - ])) { - $columnData['dateTime'] = []; - $columnData['sortable'] = []; - } - - if (in_array($type['name'], [ - 'integer', - 'decimal', - 'float', - 'double', - 'money', - ])) { - $columnData[in_array($columnName, [ - 'cost', - 'money', - 'price', - ]) || $type['name'] === 'money' ? 'money' : 'numeric'] = []; - $columnData['sortable'] = []; - } - } - - if (in_array($columnName, [ - 'created_at', - 'updated_at', - 'deleted_at', - ])) { - $columnData['toggleable'] = ['isToggledHiddenByDefault' => true]; - } - - $this->importUnlessPartial($columnData['type']); - - $columns[$columnName] = $columnData; - } - - return array_map( - function (array $columnData, string $columnName): string { - $column = (string) new Literal("{$this->simplifyFqn($columnData['type'])}::make(?)", [$columnName]); - - unset($columnData['type']); - - foreach ($columnData as $methodName => $parameters) { - $column .= new Literal(PHP_EOL . " ->{$methodName}(...?:)", [$parameters]); - } - - return "{$column},"; - }, - $columns, - array_keys($columns), - ); - } - /** * @param ?class-string $model */ diff --git a/packages/panels/src/Commands/MakeResourceCommand.php b/packages/panels/src/Commands/MakeResourceCommand.php index bd8f387d34..ea3244e159 100644 --- a/packages/panels/src/Commands/MakeResourceCommand.php +++ b/packages/panels/src/Commands/MakeResourceCommand.php @@ -116,7 +116,7 @@ class MakeResourceCommand extends Command { return [ new InputArgument( - name: 'name', + name: 'model', mode: InputArgument::OPTIONAL, description: 'The name of the model to generate the resource for, optionally prefixed with directories', ), @@ -275,7 +275,7 @@ class MakeResourceCommand extends Command ->map(fn (string $class): string => str($class)->after("{$modelNamespace}\\")) ->all(); - $this->modelFqnEnd = (string) str($this->argument('name') ?? suggest( + $this->modelFqnEnd = (string) str($this->argument('model') ?? suggest( label: 'What is the model name?', options: function (string $search) use ($modelFqns): array { $search = str($search)->trim()->replace(['\\', '/'], ''); diff --git a/packages/support/src/CliManager.php b/packages/support/src/CliManager.php index b0a797198f..3af6869922 100644 --- a/packages/support/src/CliManager.php +++ b/packages/support/src/CliManager.php @@ -9,6 +9,11 @@ class CliManager */ protected array $componentLocations = []; + /** + * @var array + */ + protected array $livewireComponentLocations = []; + public function registerComponentLocation(string $path, string $namespace, ?string $viewNamespace): void { $this->componentLocations[$namespace] = [ @@ -24,4 +29,20 @@ class CliManager { return $this->componentLocations; } + + public function registerLivewireComponentLocation(string $path, string $namespace, ?string $viewNamespace): void + { + $this->livewireComponentLocations[$namespace] = [ + 'path' => $path, + 'viewNamespace' => $viewNamespace, + ]; + } + + /** + * @return array + */ + public function getLivewireComponentLocations(): array + { + return $this->livewireComponentLocations; + } } diff --git a/packages/support/src/Commands/Concerns/CanAskForComponentLocation.php b/packages/support/src/Commands/Concerns/CanAskForComponentLocation.php index edbc25fb9d..35445e10e0 100644 --- a/packages/support/src/Commands/Concerns/CanAskForComponentLocation.php +++ b/packages/support/src/Commands/Concerns/CanAskForComponentLocation.php @@ -25,7 +25,7 @@ trait CanAskForComponentLocation return [ "App\\{$pathNamespace}", app_path($path), - null, + '', ]; } diff --git a/packages/support/src/Commands/Concerns/CanAskForLivewireComponentLocation.php b/packages/support/src/Commands/Concerns/CanAskForLivewireComponentLocation.php new file mode 100644 index 0000000000..b8ce0e923a --- /dev/null +++ b/packages/support/src/Commands/Concerns/CanAskForLivewireComponentLocation.php @@ -0,0 +1,57 @@ + 'App\\Livewire', + ...array_combine( + array_keys($locations), + array_keys($locations), + ), + ]; + + $namespace = select( + label: $question, + options: $options, + ); + + if (blank($namespace)) { + return [ + 'App\\Livewire', + app_path('Livewire'), + '', + ]; + } + + return [ + $namespace, + $locations[$namespace]['path'], + $locations[$namespace]['viewNamespace'] ?? null, + ]; + } +} diff --git a/packages/support/src/Facades/FilamentCli.php b/packages/support/src/Facades/FilamentCli.php index f10ab7879e..8864cf3316 100644 --- a/packages/support/src/Facades/FilamentCli.php +++ b/packages/support/src/Facades/FilamentCli.php @@ -6,8 +6,10 @@ use Filament\Support\CliManager; use Illuminate\Support\Facades\Facade; /** - * @method static void registerComponentLocation(string $directory, string $namespace, ?string $viewNamespace = null) * @method static array getComponentLocations() + * @method static array getLivewireComponentLocations() + * @method static void registerComponentLocation(string $directory, string $namespace, ?string $viewNamespace = null) + * @method static void registerLivewireComponentLocation(string $directory, string $namespace, ?string $viewNamespace = null) * * @see CliManager */ diff --git a/packages/tables/src/Commands/Concerns/CanGenerateTables.php b/packages/tables/src/Commands/FileGenerators/Concerns/CanGenerateTables.php similarity index 57% rename from packages/tables/src/Commands/Concerns/CanGenerateTables.php rename to packages/tables/src/Commands/FileGenerators/Concerns/CanGenerateTables.php index 14af36bab7..904a3bdad2 100644 --- a/packages/tables/src/Commands/Concerns/CanGenerateTables.php +++ b/packages/tables/src/Commands/FileGenerators/Concerns/CanGenerateTables.php @@ -1,22 +1,64 @@ $model + * @param ?class-string $model */ - protected function getResourceTableColumns(string $model): string + public function generateTableMethodBody(?string $model = null): string { - $model = $this->parseModel($model); + $this->importUnlessPartial(BulkActionGroup::class); + + return <<query(fn (): {$this->simplifyFqn(Builder::class)} => {$this->simplifyFqn($model)}::query()) + ->columns([ + {$this->outputTableColumns($model)} + ]) + ->filters([ + // + ]) + ->headerActions([ + // + ]) + ->actions([ + // + ]) + ->bulkActions([ + {$this->simplifyFqn(BulkActionGroup::class)}::make([ + // + ]), + ]); + PHP; + } + + /** + * @param ?class-string $model + * @return array + */ + public function getTableColumns(?string $model = null): array + { + if (! $this->isGenerated()) { + return []; + } if (blank($model)) { - return '//'; + return []; + } + + if (! class_exists($model)) { + return []; } $schema = $this->getModelSchema($model); @@ -73,18 +115,18 @@ trait CanGenerateTables } if ($type['name'] === 'boolean') { - $columnData['type'] = Tables\Columns\IconColumn::class; + $columnData['type'] = IconColumn::class; $columnData['boolean'] = []; } else { $columnData['type'] = match (true) { - $columnName === 'image', str($columnName)->startsWith('image_'), str($columnName)->contains('_image_'), str($columnName)->endsWith('_image') => Tables\Columns\ImageColumn::class, - default => Tables\Columns\TextColumn::class, + $columnName === 'image', str($columnName)->startsWith('image_'), str($columnName)->contains('_image_'), str($columnName)->endsWith('_image') => ImageColumn::class, + default => TextColumn::class, }; if (in_array($type['name'], [ 'string', 'char', - ]) && ($columnData['type'] === Tables\Columns\TextColumn::class)) { + ]) && ($columnData['type'] === TextColumn::class)) { $columnData['searchable'] = []; } @@ -127,55 +169,39 @@ trait CanGenerateTables $columnData['toggleable'] = ['isToggledHiddenByDefault' => true]; } + $this->importUnlessPartial($columnData['type']); + $columns[$columnName] = $columnData; } - $output = count($columns) ? '' : '//'; + return array_map( + function (array $columnData, string $columnName): string { + $column = (string) new Literal("{$this->simplifyFqn($columnData['type'])}::make(?)", [$columnName]); - foreach ($columns as $columnName => $columnData) { - // Constructor - $output .= (string) str($columnData['type'])->after('Filament\\'); - $output .= '::make(\''; - $output .= $columnName; - $output .= '\')'; + unset($columnData['type']); - unset($columnData['type']); + foreach ($columnData as $methodName => $parameters) { + $column .= new Literal(PHP_EOL . " ->{$methodName}(...?:)", [$parameters]); + } - // Configuration - foreach ($columnData as $methodName => $parameters) { - $output .= PHP_EOL; - $output .= ' ->'; - $output .= $methodName; - $output .= '('; - $output .= collect($parameters) - ->map(function (mixed $parameterValue, int | string $parameterName): string { - $parameterValue = match (true) { - /** @phpstan-ignore-next-line */ - is_bool($parameterValue) => $parameterValue ? 'true' : 'false', - /** @phpstan-ignore-next-line */ - is_null($parameterValue) => 'null', - is_numeric($parameterValue) => $parameterValue, - default => "'{$parameterValue}'", - }; + return "{$column},"; + }, + $columns, + array_keys($columns), + ); + } - if (is_numeric($parameterName)) { - return $parameterValue; - } + /** + * @param ?class-string $model + */ + public function outputTableColumns(?string $model = null): string + { + $columns = $this->getTableColumns($model); - return "{$parameterName}: {$parameterValue}"; - }) - ->implode(', '); - $output .= ')'; - } - - // Termination - $output .= ','; - - if (! (array_key_last($columns) === $columnName)) { - $output .= PHP_EOL; - } + if (empty($columns)) { + return '//'; } - return $output; + return implode(PHP_EOL . ' ', $columns); } } diff --git a/packages/tables/src/Commands/FileGenerators/LivewireTableClassGenerator.php b/packages/tables/src/Commands/FileGenerators/LivewireTableClassGenerator.php new file mode 100644 index 0000000000..0932ee89f9 --- /dev/null +++ b/packages/tables/src/Commands/FileGenerators/LivewireTableClassGenerator.php @@ -0,0 +1,172 @@ + $modelFqn + */ + final public function __construct( + protected string $fqn, + protected string $modelFqn, + protected bool $isGenerated, + protected string $view, + ) {} + + public function getNamespace(): string + { + return $this->extractNamespace($this->getFqn()); + } + + /** + * @return array + */ + public function getImports(): array + { + return [ + $this->getExtends(), + ...$this->getImplements(), + InteractsWithActions::class, + InteractsWithTable::class, + InteractsWithSchemas::class, + Table::class, + ...($this->hasPartialImports() ? ['Filament\Tables'] : []), + Builder::class, + $this->getModelFqn(), + View::class, + ]; + } + + public function getBasename(): string + { + return class_basename($this->getFqn()); + } + + public function getExtends(): string + { + return Component::class; + } + + /** + * @return array + */ + public function getImplements(): array + { + return [ + HasActions::class, + HasSchemas::class, + HasTable::class, + ]; + } + + protected function addTraitsToClass(ClassType $class): void + { + $this->addInteractsWithActionsTraitToClass($class); + $this->addInteractsWithTableTraitToClass($class); + $this->addInteractsWithSchemasTraitToClass($class); + } + + protected function addMethodsToClass(ClassType $class): void + { + $this->addTableMethodToClass($class); + $this->addRenderMethodToClass($class); + } + + protected function addInteractsWithActionsTraitToClass(ClassType $class): void + { + $trait = $class->addTrait(InteractsWithActions::class); + $this->configureInteractsWithActionsTrait($trait); + } + + protected function configureInteractsWithActionsTrait(TraitUse $trait): void {} + + protected function addInteractsWithTableTraitToClass(ClassType $class): void + { + $trait = $class->addTrait(InteractsWithTable::class); + $this->configureInteractsWithTableTrait($trait); + } + + protected function configureInteractsWithTableTrait(TraitUse $trait): void {} + + protected function addInteractsWithSchemasTraitToClass(ClassType $class): void + { + $trait = $class->addTrait(InteractsWithSchemas::class); + $this->configureInteractsWithSchemasTrait($trait); + } + + protected function configureInteractsWithSchemasTrait(TraitUse $trait): void {} + + protected function addTableMethodToClass(ClassType $class): void + { + $method = $class->addMethod('table') + ->setPublic() + ->setReturnType(Table::class) + ->setBody($this->generateTableMethodBody($this->getModelFqn())); + $method->addParameter('table') + ->setType(Table::class); + + $this->configureTableMethod($method); + } + + protected function configureTableMethod(Method $method): void {} + + protected function addRenderMethodToClass(ClassType $class): void + { + $method = $class->addMethod('render') + ->setPublic() + ->setReturnType(View::class) + ->setBody(new Literal(<<<'PHP' + return view(?); + PHP, [$this->getView()])); + + $this->configureRenderMethod($method); + } + + protected function configureRenderMethod(Method $method): void {} + + public function getFqn(): string + { + return $this->fqn; + } + + /** + * @return ?class-string + */ + public function getModelFqn(): ?string + { + return $this->modelFqn; + } + + public function isGenerated(): bool + { + return $this->isGenerated; + } + + public function getView(): string + { + return $this->view; + } +} diff --git a/packages/tables/src/Commands/MakeColumnCommand.php b/packages/tables/src/Commands/MakeColumnCommand.php index 84bb922154..89e2bb1ef9 100644 --- a/packages/tables/src/Commands/MakeColumnCommand.php +++ b/packages/tables/src/Commands/MakeColumnCommand.php @@ -154,8 +154,8 @@ class MakeColumnCommand extends Command $this->viewPath, ] = $this->askForViewLocation( str($this->fqn) - ->afterLast('Filament\\Tables\\Columns') - ->prepend('Filament\\Tables\\Columns') + ->afterLast('\\Filament\\Tables\\Columns\\') + ->prepend('Filament\\Tables\\Columns\\') ->replace('\\', '/') ->explode('/') ->map(Str::kebab(...)) diff --git a/packages/tables/src/Commands/MakeLivewireTableCommand.php b/packages/tables/src/Commands/MakeLivewireTableCommand.php new file mode 100644 index 0000000000..da855b6d9a --- /dev/null +++ b/packages/tables/src/Commands/MakeLivewireTableCommand.php @@ -0,0 +1,246 @@ + + */ + protected $aliases = [ + 'make:livewire-table', + ]; + + /** + * @var class-string + */ + protected string $fqn; + + protected string $fqnEnd; + + protected string $path; + + /** + * @var class-string + */ + protected string $modelFqn; + + protected string $modelFqnEnd; + + protected bool $isGenerated; + + protected ?string $view = null; + + protected ?string $viewPath = null; + + /** + * @return array + */ + protected function getArguments(): array + { + return [ + new InputArgument( + name: 'name', + mode: InputArgument::OPTIONAL, + description: 'The name of the Livewire component to generate, optionally prefixed with directories', + ), + new InputArgument( + name: 'model', + mode: InputArgument::OPTIONAL, + description: 'The name of the model to generate the table for, optionally prefixed with directories', + ), + ]; + } + + /** + * @return array + */ + protected function getOptions(): array + { + return [ + new InputOption( + name: 'generate', + shortcut: 'G', + mode: InputOption::VALUE_NONE, + description: 'Generate the table columns based on the attributes of a model', + ), + new InputOption( + name: 'model-namespace', + shortcut: null, + mode: InputOption::VALUE_REQUIRED, + description: 'The namespace of the model class, [App\\Models] by default', + ), + new InputOption( + name: 'force', + shortcut: 'F', + mode: InputOption::VALUE_NONE, + description: 'Overwrite the contents of the files if they already exist', + ), + ]; + } + + public function handle(): int + { + try { + $this->configureFqnEnd(); + $this->configureModel(); + $this->configureIsGenerated(); + + $this->configureLocation(); + + $this->createLivewireComponent(); + $this->createView(); + } catch (InvalidCommandOutput) { + return static::INVALID; + } + + $this->components->info("Livewire component [{$this->fqn}] created successfully."); + + return static::SUCCESS; + } + + protected function configureFqnEnd(): void + { + $this->fqnEnd = (string) str($this->argument('name') ?? text( + label: 'What is the Livewire component name?', + placeholder: 'BlogPostsTable', + required: true, + )) + ->trim('/') + ->trim('\\') + ->trim(' ') + ->studly() + ->replace('/', '\\'); + } + + protected function configureModel(): void + { + $modelNamespace = $this->option('model-namespace') ?? 'App\\Models'; + + $modelFqns = collect(get_declared_classes()) + ->filter(fn (string $class): bool => is_subclass_of($class, Model::class) && + str($class)->startsWith("{$modelNamespace}\\")) + ->map(fn (string $class): string => str($class)->after("{$modelNamespace}\\")) + ->all(); + + $this->modelFqnEnd = (string) str($this->argument('model') ?? suggest( + label: 'What is the model name?', + options: function (string $search) use ($modelFqns): array { + $search = str($search)->trim()->replace(['\\', '/'], ''); + + if (blank($search)) { + return $modelFqns; + } + + return array_filter( + $modelFqns, + fn (string $class): bool => str($class)->replace(['\\', '/'], '')->contains($search, ignoreCase: true), + ); + }, + placeholder: 'BlogPost', + )) + ->trim('/') + ->trim('\\') + ->trim(' ') + ->studly() + ->replace('/', '\\'); + + if (blank($this->modelFqnEnd)) { + $this->modelFqnEnd = 'Resource'; + } + + $this->modelFqn = "{$modelNamespace}\\{$this->modelFqnEnd}"; + } + + protected function configureIsGenerated(): void + { + $this->isGenerated = $this->option('generate') || confirm( + label: 'Would you like to generate the table columns based on the attributes of the model?', + default: false, + ); + } + + protected function configureLocation(): void + { + [ + $namespace, + $path, + $viewNamespace, + ] = $this->askForLivewireComponentLocation( + question: 'Where would you like to create the table?', + ); + + $this->fqn = "{$namespace}\\{$this->fqnEnd}"; + $this->path = (string) str("{$path}\\{$this->fqnEnd}.php") + ->replace('\\', '/') + ->replace('//', '/'); + + [ + $this->view, + $this->viewPath, + ] = $this->askForViewLocation( + str($this->fqn) + ->afterLast('\\Livewire\\') + ->prepend('Livewire\\') + ->replace('\\', '/') + ->explode('/') + ->map(Str::kebab(...)) + ->implode('.'), + defaultNamespace: $viewNamespace, + ); + } + + protected function createLivewireComponent(): void + { + if (! $this->option('force') && $this->checkForCollision($this->path)) { + throw new InvalidCommandOutput; + } + + $this->writeFile($this->path, app(LivewireTableClassGenerator::class, [ + 'fqn' => $this->fqn, + 'modelFqn' => $this->modelFqn, + 'isGenerated' => $this->isGenerated, + 'view' => $this->view, + ])); + } + + protected function createView(): void + { + if (blank($this->view)) { + return; + } + + if (! $this->option('force') && $this->checkForCollision($this->viewPath)) { + throw new InvalidCommandOutput; + } + + $this->copyStubToApp('LivewireTableView', $this->viewPath); + } +} diff --git a/packages/tables/src/Commands/MakeTableCommand.php b/packages/tables/src/Commands/MakeTableCommand.php deleted file mode 100644 index 6d17bb0bdd..0000000000 --- a/packages/tables/src/Commands/MakeTableCommand.php +++ /dev/null @@ -1,102 +0,0 @@ - - */ - protected $aliases = [ - 'make:livewire-table', - ]; - - public function handle(): int - { - $component = (string) str($this->argument('name') ?? text( - label: 'What is the table name?', - placeholder: 'Products/ListProducts', - required: true, - )) - ->trim('/') - ->trim('\\') - ->trim(' ') - ->replace('/', '\\'); - $componentClass = (string) str($component)->classBasename(); - $componentNamespace = str($component)->contains('\\') ? - (string) str($component)->beforeLast('\\') : - ''; - - $view = str($component) - ->replace('\\', '/') - ->prepend('Livewire/') - ->explode('/') - ->map(fn ($segment) => Str::lower(Str::kebab($segment))) - ->implode('.'); - - $model = (string) str($this->argument('model') ?? text( - label: 'What is the model name?', - placeholder: 'Product', - required: true, - )) - ->replace('/', '\\'); - $modelClass = (string) str($model)->classBasename(); - - $path = (string) str($component) - ->prepend('/') - ->prepend(app_path('Livewire/')) - ->replace('\\', '/') - ->replace('//', '/') - ->append('.php'); - - $viewPath = resource_path( - (string) str($view) - ->replace('.', '/') - ->prepend('views/') - ->append('.blade.php'), - ); - - if ((! $this->option('force')) && $this->checkForCollision([$path, $viewPath])) { - return static::INVALID; - } - - $this->copyStubToApp('Table', $path, [ - 'class' => $componentClass, - 'columns' => $this->indentString($this->option('generate') ? $this->getResourceTableColumns( - 'App\\Models\\' . $model, - ) : '//', 4), - 'model' => $model, - 'modelClass' => $modelClass, - 'namespace' => 'App\\Livewire' . ($componentNamespace !== '' ? "\\{$componentNamespace}" : ''), - 'view' => $view, - ]); - - $this->copyStubToApp('TableView', $viewPath); - - $this->components->info("Filament table [{$path}] created successfully."); - - return static::SUCCESS; - } -} diff --git a/packages/tables/src/TablesServiceProvider.php b/packages/tables/src/TablesServiceProvider.php index ed58c5d460..b9351e3030 100644 --- a/packages/tables/src/TablesServiceProvider.php +++ b/packages/tables/src/TablesServiceProvider.php @@ -23,7 +23,7 @@ class TablesServiceProvider extends PackageServiceProvider ->name('filament-tables') ->hasCommands([ Commands\MakeColumnCommand::class, - Commands\MakeTableCommand::class, + Commands\MakeLivewireTableCommand::class, ]) ->hasTranslations() ->hasViews(); diff --git a/packages/tables/stubs/TableView.stub b/packages/tables/stubs/LivewireTableView.stub similarity index 100% rename from packages/tables/stubs/TableView.stub rename to packages/tables/stubs/LivewireTableView.stub diff --git a/packages/tables/stubs/Table.stub b/packages/tables/stubs/Table.stub deleted file mode 100644 index de237f2631..0000000000 --- a/packages/tables/stubs/Table.stub +++ /dev/null @@ -1,46 +0,0 @@ -query({{ modelClass }}::query()) - ->columns([ -{{ columns }} - ]) - ->filters([ - // - ]) - ->actions([ - // - ]) - ->bulkActions([ - Actions\BulkActionGroup::make([ - // - ]), - ]); - } - - public function render(): View - { - return view('{{ view }}'); - } -} diff --git a/tests/src/Panels/Commands/Legacy/LegacyMakePageCommandTest.php b/tests/src/Panels/Commands/Legacy/LegacyMakePageCommandTest.php index b5b747c0e5..bb55432224 100644 --- a/tests/src/Panels/Commands/Legacy/LegacyMakePageCommandTest.php +++ b/tests/src/Panels/Commands/Legacy/LegacyMakePageCommandTest.php @@ -133,7 +133,7 @@ it('can generate a page class in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -165,7 +165,7 @@ it('can generate a page view in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -197,7 +197,7 @@ it('can generate a create page class in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -231,7 +231,7 @@ it('can generate an edit page class in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -265,7 +265,7 @@ it('can generate a view page class in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -297,7 +297,7 @@ it('can generate a view page class in a resource', function () { $runGenerateManageRelatedRecordsPageCommand = function (TestCase $testCase): PendingCommand { $testCase->artisan('make:filament-resource', [ - 'name' => 'Team', + 'model' => 'Team', '--view' => true, '--panel' => 'admin', '--no-interaction' => true, @@ -306,7 +306,7 @@ $runGenerateManageRelatedRecordsPageCommand = function (TestCase $testCase): Pen ->expectsQuestion('Does the model use soft deletes?', false); $testCase->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]) diff --git a/tests/src/Panels/Commands/Legacy/LegacyMakeRelationManagerCommandTest.php b/tests/src/Panels/Commands/Legacy/LegacyMakeRelationManagerCommandTest.php index 50601c9c66..094258fcc5 100644 --- a/tests/src/Panels/Commands/Legacy/LegacyMakeRelationManagerCommandTest.php +++ b/tests/src/Panels/Commands/Legacy/LegacyMakeRelationManagerCommandTest.php @@ -21,7 +21,7 @@ beforeEach(function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'Team', + 'model' => 'Team', '--model-namespace' => 'Filament\\Tests\\Models', '--view' => true, '--panel' => 'admin', @@ -29,7 +29,7 @@ beforeEach(function () { ]); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); diff --git a/tests/src/Panels/Commands/Legacy/LegacyMakeResourceCommandTest.php b/tests/src/Panels/Commands/Legacy/LegacyMakeResourceCommandTest.php index 01475a05cf..7400a1c52b 100644 --- a/tests/src/Panels/Commands/Legacy/LegacyMakeResourceCommandTest.php +++ b/tests/src/Panels/Commands/Legacy/LegacyMakeResourceCommandTest.php @@ -25,7 +25,7 @@ beforeEach(function () { it('can generate a resource class', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -39,7 +39,7 @@ it('can generate a resource class', function () { it('can generate a resource list page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -52,7 +52,7 @@ it('can generate a resource list page', function () { it('can generate a resource create page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -65,7 +65,7 @@ it('can generate a resource create page', function () { it('can generate a resource edit page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -78,7 +78,7 @@ it('can generate a resource edit page', function () { it('can generate a resource view page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--view' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -92,7 +92,7 @@ it('can generate a resource view page', function () { it('can generate the form and table of a resource class', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--generate' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -106,7 +106,7 @@ it('can generate the form and table of a resource class', function () { it('can generate a resource class with soft deletes', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--soft-deletes' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -120,7 +120,7 @@ it('can generate a resource class with soft deletes', function () { it('can generate a resource edit page with soft deletes', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--soft-deletes' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -134,7 +134,7 @@ it('can generate a resource edit page with soft deletes', function () { it('can generate a simple resource class', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--simple' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -148,7 +148,7 @@ it('can generate a simple resource class', function () { it('can generate a simple resource manage page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--simple' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -162,7 +162,7 @@ it('can generate a simple resource manage page', function () { it('can generate a resource class in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -175,7 +175,7 @@ it('can generate a resource class in a nested directory', function () { it('can generate a resource list page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -188,7 +188,7 @@ it('can generate a resource list page in a nested directory', function () { it('can generate a resource create page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -201,7 +201,7 @@ it('can generate a resource create page in a nested directory', function () { it('can generate a resource edit page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -214,7 +214,7 @@ it('can generate a resource edit page in a nested directory', function () { it('can generate a resource view page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--view' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -228,7 +228,7 @@ it('can generate a resource view page in a nested directory', function () { it('can generate a simple resource manage page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--simple' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', diff --git a/tests/src/Panels/Commands/MakePageCommandTest.php b/tests/src/Panels/Commands/MakePageCommandTest.php index a4d633dbf0..093db7b7cf 100644 --- a/tests/src/Panels/Commands/MakePageCommandTest.php +++ b/tests/src/Panels/Commands/MakePageCommandTest.php @@ -124,7 +124,7 @@ it('can generate a page class in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -156,7 +156,7 @@ it('can generate a page view in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -188,7 +188,7 @@ it('can generate a create page class in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -222,7 +222,7 @@ it('can generate an edit page class in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -256,7 +256,7 @@ it('can generate a view page class in a resource', function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -288,7 +288,7 @@ it('can generate a view page class in a resource', function () { $runGenerateManageRelatedRecordsPageCommand = function (TestCase $testCase): PendingCommand { $testCase->artisan('make:filament-resource', [ - 'name' => 'Team', + 'model' => 'Team', '--view' => true, '--panel' => 'admin', '--no-interaction' => true, @@ -297,7 +297,7 @@ $runGenerateManageRelatedRecordsPageCommand = function (TestCase $testCase): Pen ->expectsQuestion('Does the model use soft deletes?', false); $testCase->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]) diff --git a/tests/src/Panels/Commands/MakeRelationManagerCommandTest.php b/tests/src/Panels/Commands/MakeRelationManagerCommandTest.php index 4383d01493..9c87d944b5 100644 --- a/tests/src/Panels/Commands/MakeRelationManagerCommandTest.php +++ b/tests/src/Panels/Commands/MakeRelationManagerCommandTest.php @@ -13,7 +13,7 @@ beforeEach(function () { $this->withoutMockingConsoleOutput(); $this->artisan('make:filament-resource', [ - 'name' => 'Team', + 'model' => 'Team', '--model-namespace' => 'Filament\\Tests\\Models', '--view' => true, '--panel' => 'admin', @@ -21,7 +21,7 @@ beforeEach(function () { ]); $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); diff --git a/tests/src/Panels/Commands/MakeResourceCommandTest.php b/tests/src/Panels/Commands/MakeResourceCommandTest.php index 8d62141aca..45b62c1fc1 100644 --- a/tests/src/Panels/Commands/MakeResourceCommandTest.php +++ b/tests/src/Panels/Commands/MakeResourceCommandTest.php @@ -19,7 +19,7 @@ beforeEach(function () { it('can generate a resource class', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -32,7 +32,7 @@ it('can generate a resource class', function () { it('can generate a resource form', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -45,7 +45,7 @@ it('can generate a resource form', function () { it('can generate a resource infolist', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--view' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -59,7 +59,7 @@ it('can generate a resource infolist', function () { it('can generate a resource table', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -72,7 +72,7 @@ it('can generate a resource table', function () { it('can generate a resource list page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -85,7 +85,7 @@ it('can generate a resource list page', function () { it('can generate a resource create page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -98,7 +98,7 @@ it('can generate a resource create page', function () { it('can generate a resource edit page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -111,7 +111,7 @@ it('can generate a resource edit page', function () { it('can generate a resource view page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--view' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -125,7 +125,7 @@ it('can generate a resource view page', function () { it('can generate a resource class with embedded form', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--embed-schemas' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -139,7 +139,7 @@ it('can generate a resource class with embedded form', function () { it('can generate a resource class with embedded infolist', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--embed-schemas' => true, '--view' => true, '--model-namespace' => 'Filament\Tests\Models', @@ -154,7 +154,7 @@ it('can generate a resource class with embedded infolist', function () { it('can generate a resource class with embedded table', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--embed-table' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -168,7 +168,7 @@ it('can generate a resource class with embedded table', function () { it('can generate the resource form content', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--generate' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -182,7 +182,7 @@ it('can generate the resource form content', function () { it('can generate the resource table content', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--generate' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -196,7 +196,7 @@ it('can generate the resource table content', function () { it('can generate the form and table content embedded in a resource class', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--embed-schemas' => true, '--embed-table' => true, '--generate' => true, @@ -212,7 +212,7 @@ it('can generate the form and table content embedded in a resource class', funct it('can generate a resource class with soft deletes', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--soft-deletes' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -226,7 +226,7 @@ it('can generate a resource class with soft deletes', function () { it('can generate a resource table with soft deletes', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--soft-deletes' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -240,7 +240,7 @@ it('can generate a resource table with soft deletes', function () { it('can generate a resource edit page with soft deletes', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--soft-deletes' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -266,7 +266,7 @@ it('can generate a simple resource class', function () { } $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--simple' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -284,7 +284,7 @@ it('can generate a simple resource class', function () { it('can generate a simple resource manage page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--simple' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -298,7 +298,7 @@ it('can generate a simple resource manage page', function () { it('can generate a simple resource class without embedded schemas and table', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--not-embedded' => true, '--simple' => true, '--view' => true, @@ -314,7 +314,7 @@ it('can generate a simple resource class without embedded schemas and table', fu it('can generate a resource class in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -327,7 +327,7 @@ it('can generate a resource class in a nested directory', function () { it('can generate a resource form in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -340,7 +340,7 @@ it('can generate a resource form in a nested directory', function () { it('can generate a resource infolist in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--view' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -354,7 +354,7 @@ it('can generate a resource infolist in a nested directory', function () { it('can generate a resource table in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -367,7 +367,7 @@ it('can generate a resource table in a nested directory', function () { it('can generate a resource list page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -380,7 +380,7 @@ it('can generate a resource list page in a nested directory', function () { it('can generate a resource create page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -393,7 +393,7 @@ it('can generate a resource create page in a nested directory', function () { it('can generate a resource edit page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', '--no-interaction' => true, @@ -406,7 +406,7 @@ it('can generate a resource edit page in a nested directory', function () { it('can generate a resource view page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--view' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -420,7 +420,7 @@ it('can generate a resource view page in a nested directory', function () { it('can generate a simple resource manage page in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--simple' => true, '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -434,7 +434,7 @@ it('can generate a simple resource manage page in a nested directory', function it('can generate a nested resource class', function () { $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -450,7 +450,7 @@ it('can generate a nested resource class', function () { ]; $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--nested' => 'Users', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -464,7 +464,7 @@ it('can generate a nested resource class', function () { it('can generate a nested resource class with a plural parent resource name', function () { $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -480,7 +480,7 @@ it('can generate a nested resource class with a plural parent resource name', fu ]; $this->artisan('make:filament-resource', [ - 'name' => 'Posts', + 'model' => 'Post', '--nested' => 'Users', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -494,7 +494,7 @@ it('can generate a nested resource class with a plural parent resource name', fu it('can generate a nested resource class with a parent resource name with `Resource` at the end', function () { $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -510,7 +510,7 @@ it('can generate a nested resource class with a parent resource name with `Resou ]; $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--nested' => 'UserResource', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -524,7 +524,7 @@ it('can generate a nested resource class with a parent resource name with `Resou it('can generate a nested resource form', function () { $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -540,7 +540,7 @@ it('can generate a nested resource form', function () { ]; $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--nested' => 'Users', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -554,7 +554,7 @@ it('can generate a nested resource form', function () { it('can generate a nested resource infolist', function () { $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -570,7 +570,7 @@ it('can generate a nested resource infolist', function () { ]; $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--nested' => 'Users', '--view' => true, '--model-namespace' => 'Filament\Tests\Models', @@ -585,7 +585,7 @@ it('can generate a nested resource infolist', function () { it('can generate a nested resource create page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -601,7 +601,7 @@ it('can generate a nested resource create page', function () { ]; $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--nested' => 'Users', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -615,7 +615,7 @@ it('can generate a nested resource create page', function () { it('can generate a nested resource edit page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -631,7 +631,7 @@ it('can generate a nested resource edit page', function () { ]; $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--nested' => 'Users', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin', @@ -645,7 +645,7 @@ it('can generate a nested resource edit page', function () { it('can generate a nested resource view page', function () { $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -661,7 +661,7 @@ it('can generate a nested resource view page', function () { ]; $this->artisan('make:filament-resource', [ - 'name' => 'Post', + 'model' => 'Post', '--nested' => 'Users', '--view' => true, '--model-namespace' => 'Filament\Tests\Models', @@ -676,7 +676,7 @@ it('can generate a nested resource view page', function () { it('can generate a nested resource class in a nested directory', function () { $this->artisan('make:filament-resource', [ - 'name' => 'User', + 'model' => 'User', '--panel' => 'admin', '--no-interaction' => true, ]); @@ -692,7 +692,7 @@ it('can generate a nested resource class in a nested directory', function () { ]; $this->artisan('make:filament-resource', [ - 'name' => 'Blog/Post', + 'model' => 'Blog/Post', '--nested' => 'Users', '--model-namespace' => 'Filament\Tests\Models', '--panel' => 'admin',