From b3aaddfddc8db2c06102a36e58057fc5587fcb13 Mon Sep 17 00:00:00 2001 From: Awais Date: Wed, 20 Mar 2024 13:12:37 +0500 Subject: [PATCH 01/22] 2.x - Added Tailwind css - if layout not exists, install s using `laravel/breeze` or `laravel/ui` --- .gitignore | 3 +- composer.json | 7 +- composer.lock | 6 +- src/Commands/CrudGenerator.php | 33 +-- src/Commands/GeneratorCommand.php | 250 ++++++++++-------- src/stubs/Controller.stub | 31 +-- src/stubs/Model.stub | 6 +- src/stubs/layouts/app.stub | 80 ------ src/stubs/views/{ => bootstrap}/create.stub | 0 src/stubs/views/{ => bootstrap}/edit.stub | 0 .../views/{ => bootstrap}/form-field.stub | 0 src/stubs/views/{ => bootstrap}/form.stub | 0 src/stubs/views/{ => bootstrap}/index.stub | 14 +- src/stubs/views/{ => bootstrap}/show.stub | 0 src/stubs/views/bootstrap/view-field.stub | 4 + src/stubs/views/livewire/create.stub | 37 +++ src/stubs/views/livewire/edit.stub | 37 +++ src/stubs/views/livewire/form-field.stub | 5 + src/stubs/views/livewire/form.stub | 6 + src/stubs/views/livewire/index.stub | 62 +++++ src/stubs/views/livewire/show.stub | 37 +++ src/stubs/views/livewire/view-field.stub | 4 + src/stubs/views/react/create.stub | 37 +++ src/stubs/views/react/edit.stub | 37 +++ src/stubs/views/react/form-field.stub | 5 + src/stubs/views/react/form.stub | 6 + src/stubs/views/react/index.stub | 62 +++++ src/stubs/views/react/show.stub | 37 +++ src/stubs/views/react/view-field.stub | 4 + src/stubs/views/tailwind/create.stub | 37 +++ src/stubs/views/tailwind/edit.stub | 37 +++ src/stubs/views/tailwind/form-field.stub | 5 + src/stubs/views/tailwind/form.stub | 6 + src/stubs/views/tailwind/index.stub | 62 +++++ src/stubs/views/tailwind/show.stub | 37 +++ src/stubs/views/tailwind/view-field.stub | 4 + src/stubs/views/view-field.stub | 4 - src/stubs/views/vue/create.stub | 37 +++ src/stubs/views/vue/edit.stub | 37 +++ src/stubs/views/vue/form-field.stub | 5 + src/stubs/views/vue/form.stub | 6 + src/stubs/views/vue/index.stub | 62 +++++ src/stubs/views/vue/show.stub | 37 +++ src/stubs/views/vue/view-field.stub | 4 + 44 files changed, 942 insertions(+), 248 deletions(-) delete mode 100644 src/stubs/layouts/app.stub rename src/stubs/views/{ => bootstrap}/create.stub (100%) rename src/stubs/views/{ => bootstrap}/edit.stub (100%) rename src/stubs/views/{ => bootstrap}/form-field.stub (100%) rename src/stubs/views/{ => bootstrap}/form.stub (100%) rename src/stubs/views/{ => bootstrap}/index.stub (78%) rename src/stubs/views/{ => bootstrap}/show.stub (100%) create mode 100644 src/stubs/views/bootstrap/view-field.stub create mode 100644 src/stubs/views/livewire/create.stub create mode 100644 src/stubs/views/livewire/edit.stub create mode 100644 src/stubs/views/livewire/form-field.stub create mode 100644 src/stubs/views/livewire/form.stub create mode 100644 src/stubs/views/livewire/index.stub create mode 100644 src/stubs/views/livewire/show.stub create mode 100644 src/stubs/views/livewire/view-field.stub create mode 100644 src/stubs/views/react/create.stub create mode 100644 src/stubs/views/react/edit.stub create mode 100644 src/stubs/views/react/form-field.stub create mode 100644 src/stubs/views/react/form.stub create mode 100644 src/stubs/views/react/index.stub create mode 100644 src/stubs/views/react/show.stub create mode 100644 src/stubs/views/react/view-field.stub create mode 100644 src/stubs/views/tailwind/create.stub create mode 100644 src/stubs/views/tailwind/edit.stub create mode 100644 src/stubs/views/tailwind/form-field.stub create mode 100644 src/stubs/views/tailwind/form.stub create mode 100644 src/stubs/views/tailwind/index.stub create mode 100644 src/stubs/views/tailwind/show.stub create mode 100644 src/stubs/views/tailwind/view-field.stub delete mode 100644 src/stubs/views/view-field.stub create mode 100644 src/stubs/views/vue/create.stub create mode 100644 src/stubs/views/vue/edit.stub create mode 100644 src/stubs/views/vue/form-field.stub create mode 100644 src/stubs/views/vue/form.stub create mode 100644 src/stubs/views/vue/index.stub create mode 100644 src/stubs/views/vue/show.stub create mode 100644 src/stubs/views/vue/view-field.stub diff --git a/.gitignore b/.gitignore index cc46c69..20f89c6 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ npm-debug.log yarn-error.log .env .phpunit.result.cache -test/ \ No newline at end of file +test/ +*.DS_Store \ No newline at end of file diff --git a/composer.json b/composer.json index d31ae09..a367708 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "ibex/crud-generator", - "description": "Laravel Crud Generator", + "description": "Laravel CRUD Generator", "license": "MIT", "authors": [ { @@ -8,9 +8,10 @@ "email": "asargodha@gmail.com" } ], - "keywords": ["laravel", "crud", "crud generator", "laravel crud generator", "laravel package", "bootstrap css"], + "keywords": ["laravel", "crud", "crud generator", "laravel crud generator", "laravel package", "bootstrap css", "tailwind css", "alpine js"], "require": { - "laravel/framework": "^5.5|^6.20.42|^7.0|^8.0|^9.0|^10.0|^11.0" + "php": "^8.2", + "laravel/framework": "^10.30|^11.0" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 905207d..ddeedb3 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": "d947cdacb67217d64d866032e853c610", + "content-hash": "9666b203521c978396596a4847f5f633", "packages": [ { "name": "brick/math", @@ -5487,7 +5487,9 @@ "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, - "platform": [], + "platform": { + "php": "^8.2" + }, "platform-dev": [], "plugin-api-version": "2.3.0" } diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index fddd41b..9df6aa1 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -2,6 +2,8 @@ namespace Ibex\CrudGenerator\Commands; +use Exception; +use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Support\Str; /** @@ -18,21 +20,20 @@ class CrudGenerator extends GeneratorCommand */ protected $signature = 'make:crud {name : Table name} - {--route= : Custom route name}'; + {--route= : Custom route name} + {--stack= : The development stack that should be installed (blade,tailwind,livewire,livewire-functional,react,vue)'; /** * The console command description. * * @var string */ - protected $description = 'Create bootstrap Laravel CRUD operations'; + protected $description = 'Create Laravel CRUD operations'; /** * Execute the console command. * - * @return bool|null - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException - * + * @throws FileNotFoundException */ public function handle() { @@ -42,7 +43,7 @@ public function handle() // If table not exist in DB return if (!$this->tableExists()) { - $this->error("`{$this->table}` table not exist"); + $this->error("`$this->table` table not exist"); return false; } @@ -70,10 +71,10 @@ public function handle() * Build the Controller Class and save in app/Http/Controllers. * * @return $this - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + * @throws FileNotFoundException * */ - protected function buildController() + protected function buildController(): static { $controllerPath = $this->_getControllerPath($this->name); @@ -96,10 +97,10 @@ protected function buildController() /** * @return $this - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + * @throws FileNotFoundException * */ - protected function buildModel() + protected function buildModel(): static { $modelPath = $this->_getModelPath($this->name); @@ -134,11 +135,11 @@ protected function buildModel() /** * @return $this - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + * @throws FileNotFoundException * - * @throws \Exception + * @throws Exception */ - protected function buildViews() + protected function buildViews(): static { $this->info('Creating Views ...'); @@ -153,7 +154,7 @@ protected function buildViews() $tableHead .= $this->getHead($title); $tableBody .= $this->getBody($column); $viewRows .= $this->getField($title, $column, 'view-field'); - $form .= $this->getField($title, $column, 'form-field'); + $form .= $this->getField($title, $column); } $replace = array_merge($this->buildReplacements(), [ @@ -167,7 +168,7 @@ protected function buildViews() foreach (['index', 'create', 'edit', 'form', 'show'] as $view) { $viewTemplate = str_replace( - array_keys($replace), array_values($replace), $this->getStub("views/{$view}") + array_keys($replace), array_values($replace), $this->getStub("views/{$this->options['stack']}/$view") ); $this->write($this->_getViewPath($view), $viewTemplate); @@ -181,7 +182,7 @@ protected function buildViews() * * @return string */ - private function _buildClassName() + private function _buildClassName(): string { return Str::studly(Str::singular($this->table)); } diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index f541833..6cbb4d1 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -2,32 +2,31 @@ namespace Ibex\CrudGenerator\Commands; +use Exception; use Ibex\CrudGenerator\ModelGenerator; use Illuminate\Console\Command; +use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Str; +use RuntimeException; use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Process\Process; /** * Class GeneratorCommand. */ abstract class GeneratorCommand extends Command { - /** - * The filesystem instance. - * - * @var \Illuminate\Filesystem\Filesystem - */ - protected $files; + protected Filesystem $files; /** * Do not make these columns fillable in Model or views. * * @var array */ - protected $unwantedColumns = [ + protected array $unwantedColumns = [ 'id', 'uuid', 'ulid', @@ -39,66 +38,31 @@ abstract class GeneratorCommand extends Command 'deleted_at', ]; - /** - * Table name from argument. - * - * @var string - */ - protected $table = null; + protected ?string $table = null; /** * Formatted Class name from Table. * - * @var string + * @var null|string */ protected $name = null; - /** - * Store the DB table columns. - * - * @var array - */ - private $tableColumns = null; + private ?array $tableColumns = null; - /** - * Model Namespace. - * - * @var string - */ - protected $modelNamespace = 'App\Models'; + protected string $modelNamespace = 'App\Models'; - /** - * Controller Namespace. - * - * @var string - */ - protected $controllerNamespace = 'App\Http\Controllers'; + protected string $controllerNamespace = 'App\Http\Controllers'; - /** - * Request Namespace. - * - * @var string - */ - protected $requestNamespace = 'App\Http\Requests'; + protected string $requestNamespace = 'App\Http\Requests'; - /** - * Application Layout - * - * @var string - */ - protected $layout = 'layouts.app'; + protected string $layout = 'layouts.app'; - /** - * Custom Options name - * - * @var array - */ - protected $options = []; + protected array $options = []; /** * Create a new controller creator command instance. * - * @param \Illuminate\Filesystem\Filesystem $files + * @param Filesystem $files * * @return void */ @@ -118,21 +82,21 @@ public function __construct(Filesystem $files) * * @return $this */ - abstract protected function buildController(); + abstract protected function buildController(): static; /** * Generate the Model. * * @return $this */ - abstract protected function buildModel(); + abstract protected function buildModel(): static; /** * Generate the views. * * @return $this */ - abstract protected function buildViews(); + abstract protected function buildViews(): static; /** * Build the directory if necessary. @@ -141,7 +105,7 @@ abstract protected function buildViews(); * * @return string */ - protected function makeDirectory($path) + protected function makeDirectory(string $path): string { if (! $this->files->isDirectory(dirname($path))) { $this->files->makeDirectory(dirname($path), 0777, true, true); @@ -156,13 +120,9 @@ protected function makeDirectory($path) * @param $path * @param $content */ - protected function write($path, $content) + protected function write($path, $content): void { - $directory = $this->files->dirname($path); - - if (! $this->files->isDirectory($directory)) { - $this->files->makeDirectory($directory, 0755, true); - } + $this->makeDirectory($path); $this->files->put($path, $content); } @@ -174,17 +134,17 @@ protected function write($path, $content) * @param boolean $content * * @return string - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException - * + * @throws FileNotFoundException */ - protected function getStub($type, $content = true) + protected function getStub(string $type, bool $content = true): string { $stub_path = config('crud.stub_path', 'default'); + if ($stub_path == 'default') { $stub_path = __DIR__.'/../stubs/'; } - $path = Str::finish($stub_path, '/')."{$type}.stub"; + $path = Str::finish($stub_path, '/')."$type.stub"; if (! $content) { return $path; @@ -194,18 +154,13 @@ protected function getStub($type, $content = true) } /** - * @param $no + * @param int $no * * @return string */ - private function _getSpace($no = 1) + private function _getSpace(int $no = 1): string { - $tabs = ''; - for ($i = 0; $i < $no; $i++) { - $tabs .= "\t"; - } - - return $tabs; + return str_repeat("\t", $no); } /** @@ -213,7 +168,7 @@ private function _getSpace($no = 1) * * @return string */ - protected function _getControllerPath($name) + protected function _getControllerPath($name): string { return app_path($this->_getNamespacePath($this->controllerNamespace)."{$name}Controller.php"); } @@ -223,7 +178,7 @@ protected function _getControllerPath($name) * * @return string */ - protected function _getRequestPath($name) + protected function _getRequestPath($name): string { return app_path($this->_getNamespacePath($this->requestNamespace)."{$name}Request.php"); } @@ -233,9 +188,9 @@ protected function _getRequestPath($name) * * @return string */ - protected function _getModelPath($name) + protected function _getModelPath($name): string { - return $this->makeDirectory(app_path($this->_getNamespacePath($this->modelNamespace)."{$name}.php")); + return $this->makeDirectory(app_path($this->_getNamespacePath($this->modelNamespace)."$name.php")); } /** @@ -245,7 +200,7 @@ protected function _getModelPath($name) * * @return string */ - private function _getNamespacePath($namespace) + private function _getNamespacePath($namespace): string { $str = Str::start(Str::finish(Str::after($namespace, 'App'), '\\'), '\\'); @@ -257,7 +212,7 @@ private function _getNamespacePath($namespace) * * @return string */ - private function _getLayoutPath() + private function _getLayoutPath(): string { return $this->makeDirectory(resource_path("/views/layouts/app.blade.php")); } @@ -267,11 +222,11 @@ private function _getLayoutPath() * * @return string */ - protected function _getViewPath($view) + protected function _getViewPath($view): string { $name = Str::kebab($this->name); - return $this->makeDirectory(resource_path("/views/{$name}/{$view}.blade.php")); + return $this->makeDirectory(resource_path("/views/$name/$view.blade.php")); } /** @@ -279,12 +234,13 @@ protected function _getViewPath($view) * * @return array */ - protected function buildReplacements() + protected function buildReplacements(): array { return [ '{{layout}}' => $this->layout, '{{modelName}}' => $this->name, '{{modelTitle}}' => Str::title(Str::snake($this->name, ' ')), + '{{modelTitlePlural}}' => Str::title(Str::snake(Str::plural($this->name), ' ')), '{{modelNamespace}}' => $this->modelNamespace, '{{controllerNamespace}}' => $this->controllerNamespace, '{{requestNamespace}}' => $this->requestNamespace, @@ -308,11 +264,11 @@ protected function _getRoute() * @param $column * @param string $type * - * @return mixed - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + * @return string + * @throws FileNotFoundException * */ - protected function getField($title, $column, $type = 'form-field') + protected function getField($title, $column, string $type = 'form-field'): string { $replace = array_merge($this->buildReplacements(), [ '{{title}}' => $title, @@ -321,50 +277,60 @@ protected function getField($title, $column, $type = 'form-field') ]); return str_replace( - array_keys($replace), array_values($replace), $this->getStub("views/{$type}") + array_keys($replace), array_values($replace), $this->getStub("views/{$this->options['stack']}/$type") ); } /** * @param $title * - * @return mixed + * @return string */ - protected function getHead($title) + protected function getHead($title): string { $replace = array_merge($this->buildReplacements(), [ '{{title}}' => $title, ]); + $attr = match ($this->options['stack']) { + 'tailwind' => 'scope="col" class="py-3 pl-4 pr-3 text-left text-xs font-semibold uppercase tracking-wide text-gray-500"', + default => '' + }; + return str_replace( array_keys($replace), array_values($replace), - $this->_getSpace(10).'{{title}}'."\n" + $this->_getSpace(10).'{{title}}'."\n" ); } /** * @param $column * - * @return mixed + * @return string */ - protected function getBody($column) + protected function getBody($column): string { $replace = array_merge($this->buildReplacements(), [ '{{column}}' => $column, ]); + $attr = match ($this->options['stack']) { + 'tailwind' => 'class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"', + default => '' + }; + return str_replace( array_keys($replace), array_values($replace), - $this->_getSpace(11).'{{ ${{modelNameLowerCase}}->{{column}} }}'."\n" + $this->_getSpace(11).'{{ ${{modelNameLowerCase}}->{{column}} }}'."\n" ); } /** * Make layout if not exists. * - * @throws \Exception + * @throws Exception */ protected function buildLayout(): void { @@ -372,20 +338,33 @@ protected function buildLayout(): void $this->info('Creating Layout ...'); - if ($this->layout == 'layouts.app') { - $this->files->copy($this->getStub('layouts/app', false), $this->_getLayoutPath()); - } else { - throw new \Exception("{$this->layout} layout not found!"); + $uiPackage = match ($this->options['stack']) { + 'tailwind', 'livewire', 'react', 'vue' => 'laravel/breeze', + default => 'laravel/ui' + }; + + if (! $this->requireComposerPackages([$uiPackage], true)) { + throw new Exception("Unable to install $uiPackage. Please install it manually"); } + + $uiCommand = match ($this->options['stack']) { + 'tailwind' => 'php artisan breeze:install blade', + 'livewire' => 'php artisan breeze:install livewire', + 'react' => 'php artisan breeze:install react', + 'vue' => 'php artisan breeze:install vue', + default => 'php artisan ui bootstrap --auth' + }; + + $this->runCommands([$uiCommand]); } } /** * Get the DB Table columns. * - * @return array + * @return array|null */ - protected function getColumns() + protected function getColumns(): ?array { if (empty($this->tableColumns)) { $this->tableColumns = Schema::getColumns($this->table); @@ -397,7 +376,7 @@ protected function getColumns() /** * @return array */ - protected function getFilteredColumns() + protected function getFilteredColumns(): array { $unwanted = $this->unwantedColumns; $columns = []; @@ -416,7 +395,7 @@ protected function getFilteredColumns() * * @return array */ - protected function modelReplacements() + protected function modelReplacements(): array { $properties = '*'; $rulesArray = []; @@ -453,7 +432,7 @@ protected function modelReplacements() $rulesArray = Arr::except($rulesArray, $this->unwantedColumns); // Make rulesArray foreach ($rulesArray as $col => $rule) { - $rules .= "\n\t\t\t'{$col}' => '".implode('|', $rule)."',"; + $rules .= "\n\t\t\t'$col' => '".implode('|', $rule)."',"; } return $rules; @@ -461,7 +440,6 @@ protected function modelReplacements() $fillable = function () { - /** @var array $filterColumns Exclude the unwanted columns */ $filterColumns = $this->getFilteredColumns(); // Add quotes to the unwanted columns for fillable @@ -492,7 +470,7 @@ protected function modelReplacements() * * @return string */ - protected function getNameInput() + protected function getNameInput(): string { return trim($this->argument('name')); } @@ -500,15 +478,15 @@ protected function getNameInput() /** * Build the options * - * @return $this|array + * @return $this */ - protected function buildOptions() + protected function buildOptions(): static { - $route = $this->option('route'); - - if (! empty($route)) { - $this->options['route'] = $route; - } + $this->options['route'] = null; + $this->options['stack'] = match ($this->option('stack')) { + 'tailwind' => 'tailwind', + default => 'bootstrap', + }; return $this; } @@ -518,20 +496,60 @@ protected function buildOptions() * * @return array */ - protected function getArguments() + protected function getArguments(): array { return [ ['name', InputArgument::REQUIRED, 'The name of the table'], ]; } + protected function tableExists(): bool + { + return Schema::hasTable($this->table); + } + /** - * Is Table exist in DB. + * Installs the given Composer Packages into the application. * - * @return mixed + * @param array $packages + * @param bool $asDev + * @return bool */ - protected function tableExists() + protected function requireComposerPackages(array $packages, bool $asDev = false): bool { - return Schema::hasTable($this->table); + $command = array_merge( + ['composer', 'require'], + $packages, + $asDev ? ['--dev'] : [], + ); + + return (new Process($command, base_path(), ['COMPOSER_MEMORY_LIMIT' => '-1'])) + ->setTimeout(null) + ->run(function ($type, $output) { + $this->output->write($output); + }) === 0; + } + + /** + * Run the given commands. + * + * @param array $commands + * @return void + */ + protected function runCommands(array $commands): void + { + $process = Process::fromShellCommandline(implode(' && ', $commands), null, null, null, null); + + if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) { + try { + $process->setTty(true); + } catch (RuntimeException $e) { + $this->output->writeln(' WARN '.$e->getMessage().PHP_EOL); + } + } + + $process->run(function ($type, $line) { + $this->output->write(' '.$line); + }); } } diff --git a/src/stubs/Controller.stub b/src/stubs/Controller.stub index cc524c5..8b4d222 100644 --- a/src/stubs/Controller.stub +++ b/src/stubs/Controller.stub @@ -3,49 +3,50 @@ namespace {{controllerNamespace}}; use {{modelNamespace}}\{{modelName}}; +use Illuminate\Http\RedirectResponse; +use Illuminate\Http\Request; use {{requestNamespace}}\{{modelName}}Request; +use Illuminate\Support\Facades\Redirect; +use Illuminate\View\View; -/** - * Class {{modelName}}Controller - * @package App\Http\Controllers - */ class {{modelName}}Controller extends Controller { /** * Display a listing of the resource. */ - public function index() + public function index(Request $request): View { ${{modelNamePluralLowerCase}} = {{modelName}}::paginate(); return view('{{modelView}}.index', compact('{{modelNamePluralLowerCase}}')) - ->with('i', (request()->input('page', 1) - 1) * ${{modelNamePluralLowerCase}}->perPage()); + ->with('i', ($request->input('page', 1) - 1) * ${{modelNamePluralLowerCase}}->perPage()); } /** * Show the form for creating a new resource. */ - public function create() + public function create(): View { ${{modelNameLowerCase}} = new {{modelName}}(); + return view('{{modelView}}.create', compact('{{modelNameLowerCase}}')); } /** * Store a newly created resource in storage. */ - public function store({{modelName}}Request $request) + public function store({{modelName}}Request $request): RedirectResponse { {{modelName}}::create($request->validated()); - return redirect()->route('{{modelRoute}}.index') + return Redirect::route('{{modelRoute}}.index') ->with('success', '{{modelName}} created successfully.'); } /** * Display the specified resource. */ - public function show($id) + public function show($id): View { ${{modelNameLowerCase}} = {{modelName}}::find($id); @@ -55,7 +56,7 @@ class {{modelName}}Controller extends Controller /** * Show the form for editing the specified resource. */ - public function edit($id) + public function edit($id): View { ${{modelNameLowerCase}} = {{modelName}}::find($id); @@ -65,19 +66,19 @@ class {{modelName}}Controller extends Controller /** * Update the specified resource in storage. */ - public function update({{modelName}}Request $request, {{modelName}} ${{modelNameLowerCase}}) + public function update({{modelName}}Request $request, {{modelName}} ${{modelNameLowerCase}}): RedirectResponse { ${{modelNameLowerCase}}->update($request->validated()); - return redirect()->route('{{modelRoute}}.index') + return Redirect::route('{{modelRoute}}.index') ->with('success', '{{modelName}} updated successfully'); } - public function destroy($id) + public function destroy($id): RedirectResponse { {{modelName}}::find($id)->delete(); - return redirect()->route('{{modelRoute}}.index') + return Redirect::route('{{modelRoute}}.index') ->with('success', '{{modelName}} deleted successfully'); } } diff --git a/src/stubs/Model.stub b/src/stubs/Model.stub index 12d2a3f..9626075 100644 --- a/src/stubs/Model.stub +++ b/src/stubs/Model.stub @@ -13,16 +13,14 @@ use Illuminate\Database\Eloquent\Model; class {{modelName}} extends Model { {{softDeletes}} - protected $perPage = 20; /** - * Attributes that should be mass-assignable. + * The attributes that are mass assignable. * - * @var array + * @var array */ protected $fillable = [{{fillable}}]; {{relations}} - } diff --git a/src/stubs/layouts/app.stub b/src/stubs/layouts/app.stub deleted file mode 100644 index 17f3d41..0000000 --- a/src/stubs/layouts/app.stub +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - @if (trim($__env->yieldContent('template_title'))) @yield('template_title') | @endif {{ config('app.name', 'Laravel') }} - - - - - - - - - - - - -
- - -
- @yield('content') -
-
- - diff --git a/src/stubs/views/create.stub b/src/stubs/views/bootstrap/create.stub similarity index 100% rename from src/stubs/views/create.stub rename to src/stubs/views/bootstrap/create.stub diff --git a/src/stubs/views/edit.stub b/src/stubs/views/bootstrap/edit.stub similarity index 100% rename from src/stubs/views/edit.stub rename to src/stubs/views/bootstrap/edit.stub diff --git a/src/stubs/views/form-field.stub b/src/stubs/views/bootstrap/form-field.stub similarity index 100% rename from src/stubs/views/form-field.stub rename to src/stubs/views/bootstrap/form-field.stub diff --git a/src/stubs/views/form.stub b/src/stubs/views/bootstrap/form.stub similarity index 100% rename from src/stubs/views/form.stub rename to src/stubs/views/bootstrap/form.stub diff --git a/src/stubs/views/index.stub b/src/stubs/views/bootstrap/index.stub similarity index 78% rename from src/stubs/views/index.stub rename to src/stubs/views/bootstrap/index.stub index b38a148..7818892 100644 --- a/src/stubs/views/index.stub +++ b/src/stubs/views/bootstrap/index.stub @@ -1,7 +1,7 @@ @extends('{{layout}}') @section('template_title') - {{modelTitle}} + {{modelTitlePlural}} @endsection @section('content') @@ -13,7 +13,7 @@
- {{ __('{{modelTitle}}') }} + {{ __('{{modelTitlePlural}}') }}
@@ -45,12 +45,12 @@ {{ ++$i }} {{tableBody}} -
- {{ __('Show') }} - {{ __('Edit') }} + + {{ __('Show') }} + {{ __('Edit') }} @csrf @method('DELETE') - +
@@ -60,7 +60,7 @@
- {!! ${{modelNamePluralLowerCase}}->links() !!} + {!! ${{modelNamePluralLowerCase}}->withQueryString()->links() !!} diff --git a/src/stubs/views/show.stub b/src/stubs/views/bootstrap/show.stub similarity index 100% rename from src/stubs/views/show.stub rename to src/stubs/views/bootstrap/show.stub diff --git a/src/stubs/views/bootstrap/view-field.stub b/src/stubs/views/bootstrap/view-field.stub new file mode 100644 index 0000000..727571e --- /dev/null +++ b/src/stubs/views/bootstrap/view-field.stub @@ -0,0 +1,4 @@ +
+ {{title}}: + {{ ${{modelNameLowerCase}}->{{column}} }} +
diff --git a/src/stubs/views/livewire/create.stub b/src/stubs/views/livewire/create.stub new file mode 100644 index 0000000..cda6e43 --- /dev/null +++ b/src/stubs/views/livewire/create.stub @@ -0,0 +1,37 @@ + + +

+ {{ __('Create') }} {{modelTitle}} +

+
+ +
+
+
+
+
+
+

{{ __('Create') }} {{modelTitle}}

+

Add a new {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+ @csrf + + @include('{{modelView}}.form') +
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/livewire/edit.stub b/src/stubs/views/livewire/edit.stub new file mode 100644 index 0000000..8c488bb --- /dev/null +++ b/src/stubs/views/livewire/edit.stub @@ -0,0 +1,37 @@ + + +

+ {{ __('Update') }} {{modelTitle}} +

+
+ +
+
+
+
+
+
+

{{ __('Update') }} {{modelTitle}}

+

Update existing {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+ {{ method_field('PATCH') }} + @csrf + @include('{{modelView}}.form') +
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/livewire/form-field.stub b/src/stubs/views/livewire/form-field.stub new file mode 100644 index 0000000..e65450d --- /dev/null +++ b/src/stubs/views/livewire/form-field.stub @@ -0,0 +1,5 @@ +
+ + + +
diff --git a/src/stubs/views/livewire/form.stub b/src/stubs/views/livewire/form.stub new file mode 100644 index 0000000..35efa04 --- /dev/null +++ b/src/stubs/views/livewire/form.stub @@ -0,0 +1,6 @@ +
+ {{form}} +
+ Submit +
+
\ No newline at end of file diff --git a/src/stubs/views/livewire/index.stub b/src/stubs/views/livewire/index.stub new file mode 100644 index 0000000..cf39a0d --- /dev/null +++ b/src/stubs/views/livewire/index.stub @@ -0,0 +1,62 @@ + + +

+ {{ __('{{modelTitlePlural}}') }} +

+
+ +
+
+
+
+
+
+

{{ __('{{modelTitlePlural}}') }}

+

A list of all the {{ __('{{modelTitlePlural}}') }}.

+
+
+ Add new +
+
+ +
+
+
+ + + + + {{tableHeader}} + + + + + @foreach (${{modelNamePluralLowerCase}} as ${{modelNameLowerCase}}) + + + {{tableBody}} + + + @endforeach + +
No
{{ ++$i }} +
+ {{ __('Show') }} + {{ __('Edit') }} + @csrf + @method('DELETE') + {{ __('Delete') }} +
+
+ +
+ {!! ${{modelNamePluralLowerCase}}->withQueryString()->links() !!} +
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/stubs/views/livewire/show.stub b/src/stubs/views/livewire/show.stub new file mode 100644 index 0000000..4257207 --- /dev/null +++ b/src/stubs/views/livewire/show.stub @@ -0,0 +1,37 @@ + + +

+ {{ ${{modelNameLowerCase}}->name ?? __('Show') . " " . __('{{modelTitle}}') }} +

+
+ +
+
+
+
+
+
+

{{ __('Show') }} {{modelTitle}}

+

Details of {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+
+ {{viewRows}} +
+
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/livewire/view-field.stub b/src/stubs/views/livewire/view-field.stub new file mode 100644 index 0000000..4045b1a --- /dev/null +++ b/src/stubs/views/livewire/view-field.stub @@ -0,0 +1,4 @@ +
+
{{title}}
+
{{ ${{modelNameLowerCase}}->{{column}} }}
+
diff --git a/src/stubs/views/react/create.stub b/src/stubs/views/react/create.stub new file mode 100644 index 0000000..cda6e43 --- /dev/null +++ b/src/stubs/views/react/create.stub @@ -0,0 +1,37 @@ + + +

+ {{ __('Create') }} {{modelTitle}} +

+
+ +
+
+
+
+
+
+

{{ __('Create') }} {{modelTitle}}

+

Add a new {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+ @csrf + + @include('{{modelView}}.form') +
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/react/edit.stub b/src/stubs/views/react/edit.stub new file mode 100644 index 0000000..8c488bb --- /dev/null +++ b/src/stubs/views/react/edit.stub @@ -0,0 +1,37 @@ + + +

+ {{ __('Update') }} {{modelTitle}} +

+
+ +
+
+
+
+
+
+

{{ __('Update') }} {{modelTitle}}

+

Update existing {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+ {{ method_field('PATCH') }} + @csrf + @include('{{modelView}}.form') +
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/react/form-field.stub b/src/stubs/views/react/form-field.stub new file mode 100644 index 0000000..e65450d --- /dev/null +++ b/src/stubs/views/react/form-field.stub @@ -0,0 +1,5 @@ +
+ + + +
diff --git a/src/stubs/views/react/form.stub b/src/stubs/views/react/form.stub new file mode 100644 index 0000000..35efa04 --- /dev/null +++ b/src/stubs/views/react/form.stub @@ -0,0 +1,6 @@ +
+ {{form}} +
+ Submit +
+
\ No newline at end of file diff --git a/src/stubs/views/react/index.stub b/src/stubs/views/react/index.stub new file mode 100644 index 0000000..cf39a0d --- /dev/null +++ b/src/stubs/views/react/index.stub @@ -0,0 +1,62 @@ + + +

+ {{ __('{{modelTitlePlural}}') }} +

+
+ +
+
+
+
+
+
+

{{ __('{{modelTitlePlural}}') }}

+

A list of all the {{ __('{{modelTitlePlural}}') }}.

+
+
+ Add new +
+
+ +
+
+
+ + + + + {{tableHeader}} + + + + + @foreach (${{modelNamePluralLowerCase}} as ${{modelNameLowerCase}}) + + + {{tableBody}} + + + @endforeach + +
No
{{ ++$i }} +
+ {{ __('Show') }} + {{ __('Edit') }} + @csrf + @method('DELETE') + {{ __('Delete') }} +
+
+ +
+ {!! ${{modelNamePluralLowerCase}}->withQueryString()->links() !!} +
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/stubs/views/react/show.stub b/src/stubs/views/react/show.stub new file mode 100644 index 0000000..4257207 --- /dev/null +++ b/src/stubs/views/react/show.stub @@ -0,0 +1,37 @@ + + +

+ {{ ${{modelNameLowerCase}}->name ?? __('Show') . " " . __('{{modelTitle}}') }} +

+
+ +
+
+
+
+
+
+

{{ __('Show') }} {{modelTitle}}

+

Details of {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+
+ {{viewRows}} +
+
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/react/view-field.stub b/src/stubs/views/react/view-field.stub new file mode 100644 index 0000000..4045b1a --- /dev/null +++ b/src/stubs/views/react/view-field.stub @@ -0,0 +1,4 @@ +
+
{{title}}
+
{{ ${{modelNameLowerCase}}->{{column}} }}
+
diff --git a/src/stubs/views/tailwind/create.stub b/src/stubs/views/tailwind/create.stub new file mode 100644 index 0000000..cda6e43 --- /dev/null +++ b/src/stubs/views/tailwind/create.stub @@ -0,0 +1,37 @@ + + +

+ {{ __('Create') }} {{modelTitle}} +

+
+ +
+
+
+
+
+
+

{{ __('Create') }} {{modelTitle}}

+

Add a new {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+ @csrf + + @include('{{modelView}}.form') +
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/tailwind/edit.stub b/src/stubs/views/tailwind/edit.stub new file mode 100644 index 0000000..8c488bb --- /dev/null +++ b/src/stubs/views/tailwind/edit.stub @@ -0,0 +1,37 @@ + + +

+ {{ __('Update') }} {{modelTitle}} +

+
+ +
+
+
+
+
+
+

{{ __('Update') }} {{modelTitle}}

+

Update existing {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+ {{ method_field('PATCH') }} + @csrf + @include('{{modelView}}.form') +
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/tailwind/form-field.stub b/src/stubs/views/tailwind/form-field.stub new file mode 100644 index 0000000..e65450d --- /dev/null +++ b/src/stubs/views/tailwind/form-field.stub @@ -0,0 +1,5 @@ +
+ + + +
diff --git a/src/stubs/views/tailwind/form.stub b/src/stubs/views/tailwind/form.stub new file mode 100644 index 0000000..35efa04 --- /dev/null +++ b/src/stubs/views/tailwind/form.stub @@ -0,0 +1,6 @@ +
+ {{form}} +
+ Submit +
+
\ No newline at end of file diff --git a/src/stubs/views/tailwind/index.stub b/src/stubs/views/tailwind/index.stub new file mode 100644 index 0000000..cf39a0d --- /dev/null +++ b/src/stubs/views/tailwind/index.stub @@ -0,0 +1,62 @@ + + +

+ {{ __('{{modelTitlePlural}}') }} +

+
+ +
+
+
+
+
+
+

{{ __('{{modelTitlePlural}}') }}

+

A list of all the {{ __('{{modelTitlePlural}}') }}.

+
+
+ Add new +
+
+ +
+
+
+ + + + + {{tableHeader}} + + + + + @foreach (${{modelNamePluralLowerCase}} as ${{modelNameLowerCase}}) + + + {{tableBody}} + + + @endforeach + +
No
{{ ++$i }} +
+ {{ __('Show') }} + {{ __('Edit') }} + @csrf + @method('DELETE') + {{ __('Delete') }} +
+
+ +
+ {!! ${{modelNamePluralLowerCase}}->withQueryString()->links() !!} +
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/stubs/views/tailwind/show.stub b/src/stubs/views/tailwind/show.stub new file mode 100644 index 0000000..4257207 --- /dev/null +++ b/src/stubs/views/tailwind/show.stub @@ -0,0 +1,37 @@ + + +

+ {{ ${{modelNameLowerCase}}->name ?? __('Show') . " " . __('{{modelTitle}}') }} +

+
+ +
+
+
+
+
+
+

{{ __('Show') }} {{modelTitle}}

+

Details of {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+
+ {{viewRows}} +
+
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/tailwind/view-field.stub b/src/stubs/views/tailwind/view-field.stub new file mode 100644 index 0000000..4045b1a --- /dev/null +++ b/src/stubs/views/tailwind/view-field.stub @@ -0,0 +1,4 @@ +
+
{{title}}
+
{{ ${{modelNameLowerCase}}->{{column}} }}
+
diff --git a/src/stubs/views/view-field.stub b/src/stubs/views/view-field.stub deleted file mode 100644 index c7fe634..0000000 --- a/src/stubs/views/view-field.stub +++ /dev/null @@ -1,4 +0,0 @@ -
- {{title}}: - {{ ${{modelNameLowerCase}}->{{column}} }} -
diff --git a/src/stubs/views/vue/create.stub b/src/stubs/views/vue/create.stub new file mode 100644 index 0000000..cda6e43 --- /dev/null +++ b/src/stubs/views/vue/create.stub @@ -0,0 +1,37 @@ + + +

+ {{ __('Create') }} {{modelTitle}} +

+
+ +
+
+
+
+
+
+

{{ __('Create') }} {{modelTitle}}

+

Add a new {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+ @csrf + + @include('{{modelView}}.form') +
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/vue/edit.stub b/src/stubs/views/vue/edit.stub new file mode 100644 index 0000000..8c488bb --- /dev/null +++ b/src/stubs/views/vue/edit.stub @@ -0,0 +1,37 @@ + + +

+ {{ __('Update') }} {{modelTitle}} +

+
+ +
+
+
+
+
+
+

{{ __('Update') }} {{modelTitle}}

+

Update existing {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+ {{ method_field('PATCH') }} + @csrf + @include('{{modelView}}.form') +
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/vue/form-field.stub b/src/stubs/views/vue/form-field.stub new file mode 100644 index 0000000..e65450d --- /dev/null +++ b/src/stubs/views/vue/form-field.stub @@ -0,0 +1,5 @@ +
+ + + +
diff --git a/src/stubs/views/vue/form.stub b/src/stubs/views/vue/form.stub new file mode 100644 index 0000000..35efa04 --- /dev/null +++ b/src/stubs/views/vue/form.stub @@ -0,0 +1,6 @@ +
+ {{form}} +
+ Submit +
+
\ No newline at end of file diff --git a/src/stubs/views/vue/index.stub b/src/stubs/views/vue/index.stub new file mode 100644 index 0000000..cf39a0d --- /dev/null +++ b/src/stubs/views/vue/index.stub @@ -0,0 +1,62 @@ + + +

+ {{ __('{{modelTitlePlural}}') }} +

+
+ +
+
+
+
+
+
+

{{ __('{{modelTitlePlural}}') }}

+

A list of all the {{ __('{{modelTitlePlural}}') }}.

+
+
+ Add new +
+
+ +
+
+
+ + + + + {{tableHeader}} + + + + + @foreach (${{modelNamePluralLowerCase}} as ${{modelNameLowerCase}}) + + + {{tableBody}} + + + @endforeach + +
No
{{ ++$i }} +
+ {{ __('Show') }} + {{ __('Edit') }} + @csrf + @method('DELETE') + {{ __('Delete') }} +
+
+ +
+ {!! ${{modelNamePluralLowerCase}}->withQueryString()->links() !!} +
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/stubs/views/vue/show.stub b/src/stubs/views/vue/show.stub new file mode 100644 index 0000000..4257207 --- /dev/null +++ b/src/stubs/views/vue/show.stub @@ -0,0 +1,37 @@ + + +

+ {{ ${{modelNameLowerCase}}->name ?? __('Show') . " " . __('{{modelTitle}}') }} +

+
+ +
+
+
+
+
+
+

{{ __('Show') }} {{modelTitle}}

+

Details of {{ __('{{modelTitle}}') }}.

+
+
+ Back +
+
+ +
+
+
+
+
+ {{viewRows}} +
+
+
+
+
+
+
+
+
+
diff --git a/src/stubs/views/vue/view-field.stub b/src/stubs/views/vue/view-field.stub new file mode 100644 index 0000000..4045b1a --- /dev/null +++ b/src/stubs/views/vue/view-field.stub @@ -0,0 +1,4 @@ +
+
{{title}}
+
{{ ${{modelNameLowerCase}}->{{column}} }}
+
From 24b23a554fe738cff51ebd2353bc5d6b9a1acab3 Mon Sep 17 00:00:00 2001 From: Awais Date: Tue, 2 Apr 2024 09:10:57 +0500 Subject: [PATCH 02/22] 2.x - Added Tailwind css - if layout not exists, install s using `laravel/breeze` or `laravel/ui` --- src/Commands/CrudGenerator.php | 2 +- src/Commands/GeneratorCommand.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index 9df6aa1..f9f614e 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -21,7 +21,7 @@ class CrudGenerator extends GeneratorCommand protected $signature = 'make:crud {name : Table name} {--route= : Custom route name} - {--stack= : The development stack that should be installed (blade,tailwind,livewire,livewire-functional,react,vue)'; + {--stack= : The development stack that should be installed (blade,tailwind,livewire,livewire-functional,react,vue)}'; /** * The console command description. diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 6cbb4d1..a6c1345 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -485,6 +485,9 @@ protected function buildOptions(): static $this->options['route'] = null; $this->options['stack'] = match ($this->option('stack')) { 'tailwind' => 'tailwind', + 'livewire' => 'livewire', + 'react' => 'react', + 'vue' => 'vue', default => 'bootstrap', }; From db17773cb7074e4b6a19cb3f3ecf5cd4513e465a Mon Sep 17 00:00:00 2001 From: Awais Date: Thu, 4 Apr 2024 10:34:36 +0500 Subject: [PATCH 03/22] 2.x - Added Tailwind Livewire `laravel/breeze` --- src/Commands/CrudGenerator.php | 39 ++++++++- src/Commands/GeneratorCommand.php | 24 +++++- src/stubs/livewire/Create.stub | 31 +++++++ src/stubs/livewire/Edit.stub | 31 +++++++ src/stubs/livewire/Form.stub | 38 +++++++++ src/stubs/livewire/Index.stub | 30 +++++++ src/stubs/livewire/Show.stub | 24 ++++++ src/stubs/views/livewire/create.stub | 53 ++++++------ src/stubs/views/livewire/edit.stub | 54 ++++++------ src/stubs/views/livewire/form-field.stub | 6 +- src/stubs/views/livewire/index.stub | 101 ++++++++++++----------- src/stubs/views/livewire/show.stub | 52 ++++++------ src/stubs/views/livewire/view-field.stub | 8 +- 13 files changed, 347 insertions(+), 144 deletions(-) create mode 100644 src/stubs/livewire/Create.stub create mode 100644 src/stubs/livewire/Edit.stub create mode 100644 src/stubs/livewire/Form.stub create mode 100644 src/stubs/livewire/Index.stub create mode 100644 src/stubs/livewire/Show.stub diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index f9f614e..ba5c40a 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -21,7 +21,7 @@ class CrudGenerator extends GeneratorCommand protected $signature = 'make:crud {name : Table name} {--route= : Custom route name} - {--stack= : The development stack that should be installed (blade,tailwind,livewire,livewire-functional,react,vue)}'; + {--stack= : The development stack that should be installed (blade,tailwind,livewire,react,vue)}'; /** * The console command description. @@ -42,7 +42,7 @@ public function handle() $this->table = $this->getNameInput(); // If table not exist in DB return - if (!$this->tableExists()) { + if (! $this->tableExists()) { $this->error("`$this->table` table not exist"); return false; @@ -72,10 +72,15 @@ public function handle() * * @return $this * @throws FileNotFoundException - * */ protected function buildController(): static { + if ($this->options['stack'] == 'livewire') { + $this->buildLivewire(); + + return $this; + } + $controllerPath = $this->_getControllerPath($this->name); if ($this->files->exists($controllerPath) && $this->ask('Already exist Controller. Do you want overwrite (y/n)?', 'y') == 'n') { @@ -95,6 +100,34 @@ protected function buildController(): static return $this; } + protected function buildLivewire(): void + { + $this->info('Creating Livewire Component ...'); + + $folder = ucfirst(Str::plural($this->name)); + $model = Str::camel($this->name); + $replace = array_merge($this->buildReplacements(), $this->modelReplacements()); + + foreach (['Index', 'Show', 'Edit', 'Create'] as $component) { + $componentPath = $this->_getLivewirePath($folder.'/'.$component); + + $componentTemplate = str_replace( + array_keys($replace), array_values($replace), $this->getStub('livewire/'.$component) + ); + + $this->write($componentPath, $componentTemplate); + } + + // Form + $formPath = $this->_getLivewirePath('Forms/'.$model.'Form'); + + $componentTemplate = str_replace( + array_keys($replace), array_values($replace), $this->getStub('livewire/Form') + ); + + $this->write($formPath, $componentTemplate); + } + /** * @return $this * @throws FileNotFoundException diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index a6c1345..1be45ff 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -53,6 +53,8 @@ abstract class GeneratorCommand extends Command protected string $controllerNamespace = 'App\Http\Controllers'; + protected string $livewireNamespace = 'App\Livewire'; + protected string $requestNamespace = 'App\Http\Requests'; protected string $layout = 'layouts.app'; @@ -173,6 +175,16 @@ protected function _getControllerPath($name): string return app_path($this->_getNamespacePath($this->controllerNamespace)."{$name}Controller.php"); } + /** + * @param $name + * + * @return string + */ + protected function _getLivewirePath($name): string + { + return app_path($this->_getNamespacePath($this->livewireNamespace)."{$name}.php"); + } + /** * @param $name * @@ -244,6 +256,7 @@ protected function buildReplacements(): array '{{modelNamespace}}' => $this->modelNamespace, '{{controllerNamespace}}' => $this->controllerNamespace, '{{requestNamespace}}' => $this->requestNamespace, + '{{livewireNamespace}}' => $this->livewireNamespace, '{{modelNamePluralLowerCase}}' => Str::camel(Str::plural($this->name)), '{{modelNamePluralUpperCase}}' => ucfirst(Str::plural($this->name)), '{{modelNameLowerCase}}' => Str::camel($this->name), @@ -293,7 +306,7 @@ protected function getHead($title): string ]); $attr = match ($this->options['stack']) { - 'tailwind' => 'scope="col" class="py-3 pl-4 pr-3 text-left text-xs font-semibold uppercase tracking-wide text-gray-500"', + 'tailwind', 'livewire' => 'scope="col" class="py-3 pl-4 pr-3 text-left text-xs font-semibold uppercase tracking-wide text-gray-500"', default => '' }; @@ -316,7 +329,7 @@ protected function getBody($column): string ]); $attr = match ($this->options['stack']) { - 'tailwind' => 'class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"', + 'tailwind', 'livewire' => 'class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"', default => '' }; @@ -398,11 +411,16 @@ protected function getFilteredColumns(): array protected function modelReplacements(): array { $properties = '*'; + $livewireFormProperties = ''; + $livewireFormSetValues = ''; $rulesArray = []; $softDeletesNamespace = $softDeletes = ''; + $modelName = Str::camel($this->name); foreach ($this->getColumns() as $column) { $properties .= "\n * @property \${$column['name']}"; + $livewireFormProperties .= "\n public \${$column['name']} = '';"; + $livewireFormSetValues .= "\n \$this->{$column['name']} = \$this->{$modelName}Model->{$column['name']};"; if (! $column['nullable']) { $rulesArray[$column['name']] = ['required']; @@ -462,6 +480,8 @@ protected function modelReplacements(): array '{{properties}}' => $properties, '{{softDeletesNamespace}}' => $softDeletesNamespace, '{{softDeletes}}' => $softDeletes, + '{{livewireFormProperties}}' => $livewireFormProperties, + '{{livewireFormSetValues}}' => $livewireFormSetValues, ]; } diff --git a/src/stubs/livewire/Create.stub b/src/stubs/livewire/Create.stub new file mode 100644 index 0000000..e74aa16 --- /dev/null +++ b/src/stubs/livewire/Create.stub @@ -0,0 +1,31 @@ +form->set{{modelName}}Model(${{modelNameLowerCase}}); + } + + public function save() + { + $this->form->store(); + + return $this->redirectRoute('{{modelNamePluralLowerCase}}.index', navigate: true); + } + + #[Layout('{{layout}}')] + public function render() + { + return view('livewire.{{modelNamePluralLowerCase}}.create'); + } +} diff --git a/src/stubs/livewire/Edit.stub b/src/stubs/livewire/Edit.stub new file mode 100644 index 0000000..e735e34 --- /dev/null +++ b/src/stubs/livewire/Edit.stub @@ -0,0 +1,31 @@ +form->set{{modelName}}Model(${{modelNameLowerCase}}); + } + + public function save() + { + $this->form->update(); + + return $this->redirectRoute('{{modelNamePluralLowerCase}}.index', navigate: true); + } + + #[Layout('{{layout}}')] + public function render() + { + return view('livewire.{{modelNamePluralLowerCase}}.edit'); + } +} diff --git a/src/stubs/livewire/Form.stub b/src/stubs/livewire/Form.stub new file mode 100644 index 0000000..bda0868 --- /dev/null +++ b/src/stubs/livewire/Form.stub @@ -0,0 +1,38 @@ +{{modelNameLowerCase}}Model = ${{modelNameLowerCase}}Model; + {{livewireFormSetValues}} + } + + public function store(): void + { + $this->{{modelNameLowerCase}}Model->create($this->validate()); + + $this->reset(); + } + + public function update(): void + { + $this->{{modelNameLowerCase}}Model->update($this->validate()); + + $this->reset(); + } +} diff --git a/src/stubs/livewire/Index.stub b/src/stubs/livewire/Index.stub new file mode 100644 index 0000000..3c723e4 --- /dev/null +++ b/src/stubs/livewire/Index.stub @@ -0,0 +1,30 @@ +with('i', $this->getPage() * ${{modelNamePluralLowerCase}}->perPage()); + } + + public function delete({{modelName}} ${{modelNameLowerCase}}) + { + ${{modelNameLowerCase}}->delete(); + + return $this->redirectRoute('{{modelNamePluralLowerCase}}.index', navigate: true); + } +} diff --git a/src/stubs/livewire/Show.stub b/src/stubs/livewire/Show.stub new file mode 100644 index 0000000..dfd783e --- /dev/null +++ b/src/stubs/livewire/Show.stub @@ -0,0 +1,24 @@ +form->set{{modelName}}Model(${{modelNameLowerCase}}); + } + + #[Layout('{{layouts}}')] + public function render() + { + return view('livewire.{{modelNamePluralLowerCase}}.show', ['{{modelNameLowerCase}}' => $this->form->{{modelNameLowerCase}}Model]); + } +} diff --git a/src/stubs/views/livewire/create.stub b/src/stubs/views/livewire/create.stub index cda6e43..0468c45 100644 --- a/src/stubs/views/livewire/create.stub +++ b/src/stubs/views/livewire/create.stub @@ -1,37 +1,34 @@ - - -

- {{ __('Create') }} {{modelTitle}} -

-
+ +

+ {{ __('Create') }} {{modelTitle}} +

+
-
-
-
-
-
-
-

{{ __('Create') }} {{modelTitle}}

-

Add a new {{ __('{{modelTitle}}') }}.

-
-
- Back -
+
+
+
+
+
+
+

{{ __('Create') }} {{modelTitle}}

+

Add a new {{ __('{{modelTitle}}') }}.

+
+ Back +
+
-
-
-
-
- @csrf - - @include('{{modelView}}.form') -
-
+
+
+
+
+ @csrf + @include('{{modelView}}.form') +
- +
diff --git a/src/stubs/views/livewire/edit.stub b/src/stubs/views/livewire/edit.stub index 8c488bb..2445673 100644 --- a/src/stubs/views/livewire/edit.stub +++ b/src/stubs/views/livewire/edit.stub @@ -1,37 +1,35 @@ - - -

- {{ __('Update') }} {{modelTitle}} -

-
+ +

+ {{ __('Update') }} {{modelTitle}} +

+
-
-
-
-
-
-
-

{{ __('Update') }} {{modelTitle}}

-

Update existing {{ __('{{modelTitle}}') }}.

-
-
- Back -
+
+
+
+
+
+
+

{{ __('Update') }} {{modelTitle}}

+

Update existing {{ __('{{modelTitle}}') }}.

+
+ Back +
+
-
-
-
-
- {{ method_field('PATCH') }} - @csrf - @include('{{modelView}}.form') -
-
+
+
+
+
+ {{ method_field('PATCH') }} + @csrf + @include('{{modelView}}.form') +
- +
diff --git a/src/stubs/views/livewire/form-field.stub b/src/stubs/views/livewire/form-field.stub index e65450d..719a82f 100644 --- a/src/stubs/views/livewire/form-field.stub +++ b/src/stubs/views/livewire/form-field.stub @@ -1,5 +1,7 @@
- - + + @error('form.{{column}}') + + @enderror
diff --git a/src/stubs/views/livewire/index.stub b/src/stubs/views/livewire/index.stub index cf39a0d..1324c6e 100644 --- a/src/stubs/views/livewire/index.stub +++ b/src/stubs/views/livewire/index.stub @@ -1,57 +1,58 @@ - - -

- {{ __('{{modelTitlePlural}}') }} -

-
+ +

+ {{ __('{{modelTitlePlural}}') }} +

+
-
-
-
-
-
-
-

{{ __('{{modelTitlePlural}}') }}

-

A list of all the {{ __('{{modelTitlePlural}}') }}.

-
-
- Add new -
+
+
+
+
+
+
+

{{ __('{{modelTitlePlural}}') }}

+

A list of all the {{ __('{{modelTitlePlural}}') }}.

+
+ Add new +
+
-
-
-
- - - - - {{tableHeader}} - +
+
+
+
No
+ + + + {{tableHeader}} + + + + + @foreach (${{modelNamePluralLowerCase}} as ${{modelNameLowerCase}}) + + + {{tableBody}} + - - - @foreach (${{modelNamePluralLowerCase}} as ${{modelNameLowerCase}}) - - - {{tableBody}} - - - @endforeach - -
No
{{ ++$i }} + {{ __('Show') }} + {{ __('Edit') }} + +
{{ ++$i }} -
- {{ __('Show') }} - {{ __('Edit') }} - @csrf - @method('DELETE') - {{ __('Delete') }} -
-
+ @endforeach + + -
- {!! ${{modelNamePluralLowerCase}}->withQueryString()->links() !!} -
+
+ {!! ${{modelNamePluralLowerCase}}->withQueryString()->links() !!}
@@ -59,4 +60,4 @@
- \ No newline at end of file +
\ No newline at end of file diff --git a/src/stubs/views/livewire/show.stub b/src/stubs/views/livewire/show.stub index 4257207..042ebfa 100644 --- a/src/stubs/views/livewire/show.stub +++ b/src/stubs/views/livewire/show.stub @@ -1,32 +1,30 @@ - - -

- {{ ${{modelNameLowerCase}}->name ?? __('Show') . " " . __('{{modelTitle}}') }} -

-
+ +

+ {{ ${{modelNameLowerCase}}->name ?? __('Show') . " " . __('{{modelTitle}}') }} +

+
-
-
-
-
-
-
-

{{ __('Show') }} {{modelTitle}}

-

Details of {{ __('{{modelTitle}}') }}.

-
-
- Back -
+
+
+
+
+
+
+

{{ __('Show') }} {{modelTitle}}

+

Details of {{ __('{{modelTitle}}') }}.

+
+ Back +
+
-
-
-
-
-
- {{viewRows}} -
-
+
+
+
+
+
+ {{viewRows}} +
@@ -34,4 +32,4 @@
- +
diff --git a/src/stubs/views/livewire/view-field.stub b/src/stubs/views/livewire/view-field.stub index 4045b1a..bf56e78 100644 --- a/src/stubs/views/livewire/view-field.stub +++ b/src/stubs/views/livewire/view-field.stub @@ -1,4 +1,4 @@ -
-
{{title}}
-
{{ ${{modelNameLowerCase}}->{{column}} }}
-
+
+
{{title}}
+
{{ ${{modelNameLowerCase}}->{{column}} }}
+
From a01ece023c15a412539c9c61278e83dcf66e3c4f Mon Sep 17 00:00:00 2001 From: Awais Date: Thu, 4 Apr 2024 10:51:01 +0500 Subject: [PATCH 04/22] 2.x - Added Tailwind Livewire `laravel/breeze` --- src/Commands/CrudGenerator.php | 3 +-- src/Commands/GeneratorCommand.php | 16 +++++++++------- src/stubs/livewire/Create.stub | 2 +- src/stubs/livewire/Edit.stub | 2 +- src/stubs/livewire/Form.stub | 2 +- src/stubs/livewire/Index.stub | 2 +- src/stubs/livewire/Show.stub | 2 +- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index ba5c40a..4b1e2fb 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -105,7 +105,6 @@ protected function buildLivewire(): void $this->info('Creating Livewire Component ...'); $folder = ucfirst(Str::plural($this->name)); - $model = Str::camel($this->name); $replace = array_merge($this->buildReplacements(), $this->modelReplacements()); foreach (['Index', 'Show', 'Edit', 'Create'] as $component) { @@ -119,7 +118,7 @@ protected function buildLivewire(): void } // Form - $formPath = $this->_getLivewirePath('Forms/'.$model.'Form'); + $formPath = $this->_getLivewirePath('Forms/'.$this->name.'Form'); $componentTemplate = str_replace( array_keys($replace), array_values($replace), $this->getStub('livewire/Form') diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 1be45ff..412c3d9 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -313,7 +313,7 @@ protected function getHead($title): string return str_replace( array_keys($replace), array_values($replace), - $this->_getSpace(10).'{{title}}'."\n" + $this->_getSpace(9).'{{title}}'."\n" ); } @@ -336,7 +336,7 @@ protected function getBody($column): string return str_replace( array_keys($replace), array_values($replace), - $this->_getSpace(11).'{{ ${{modelNameLowerCase}}->{{column}} }}'."\n" + $this->_getSpace(10).'{{ ${{modelNameLowerCase}}->{{column}} }}'."\n" ); } @@ -416,11 +416,10 @@ protected function modelReplacements(): array $rulesArray = []; $softDeletesNamespace = $softDeletes = ''; $modelName = Str::camel($this->name); + $filterColumns = $this->getFilteredColumns(); foreach ($this->getColumns() as $column) { $properties .= "\n * @property \${$column['name']}"; - $livewireFormProperties .= "\n public \${$column['name']} = '';"; - $livewireFormSetValues .= "\n \$this->{$column['name']} = \$this->{$modelName}Model->{$column['name']};"; if (! $column['nullable']) { $rulesArray[$column['name']] = ['required']; @@ -456,9 +455,7 @@ protected function modelReplacements(): array return $rules; }; - $fillable = function () { - - $filterColumns = $this->getFilteredColumns(); + $fillable = function () use ($filterColumns) { // Add quotes to the unwanted columns for fillable array_walk($filterColumns, function (&$value) { @@ -473,6 +470,11 @@ protected function modelReplacements(): array [$relations, $properties] = (new ModelGenerator($this->table, $properties, $this->modelNamespace))->getEloquentRelations(); + foreach ($filterColumns as $column) { + $livewireFormProperties .= "\n public \${$column['name']} = '';"; + $livewireFormSetValues .= "\n \$this->{$column['name']} = \$this->{$modelName}Model->{$column['name']};"; + } + return [ '{{fillable}}' => $fillable(), '{{rules}}' => $rules(), diff --git a/src/stubs/livewire/Create.stub b/src/stubs/livewire/Create.stub index e74aa16..090cf5c 100644 --- a/src/stubs/livewire/Create.stub +++ b/src/stubs/livewire/Create.stub @@ -1,6 +1,6 @@ Date: Thu, 4 Apr 2024 10:57:58 +0500 Subject: [PATCH 05/22] 2.x - Added Tailwind Livewire `laravel/breeze` --- src/Commands/GeneratorCommand.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 412c3d9..b36e5b8 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -416,11 +416,15 @@ protected function modelReplacements(): array $rulesArray = []; $softDeletesNamespace = $softDeletes = ''; $modelName = Str::camel($this->name); - $filterColumns = $this->getFilteredColumns(); foreach ($this->getColumns() as $column) { $properties .= "\n * @property \${$column['name']}"; + if (! in_array($column['name'], $this->unwantedColumns)) { + $livewireFormProperties .= "\n public \${$column['name']} = '';"; + $livewireFormSetValues .= "\n \$this->{$column['name']} = \$this->{$modelName}Model->{$column['name']};"; + } + if (! $column['nullable']) { $rulesArray[$column['name']] = ['required']; } @@ -455,7 +459,9 @@ protected function modelReplacements(): array return $rules; }; - $fillable = function () use ($filterColumns) { + $fillable = function () { + + $filterColumns = $this->getFilteredColumns(); // Add quotes to the unwanted columns for fillable array_walk($filterColumns, function (&$value) { @@ -470,11 +476,6 @@ protected function modelReplacements(): array [$relations, $properties] = (new ModelGenerator($this->table, $properties, $this->modelNamespace))->getEloquentRelations(); - foreach ($filterColumns as $column) { - $livewireFormProperties .= "\n public \${$column['name']} = '';"; - $livewireFormSetValues .= "\n \$this->{$column['name']} = \$this->{$modelName}Model->{$column['name']};"; - } - return [ '{{fillable}}' => $fillable(), '{{rules}}' => $rules(), From 265d481fbd488102af257fbaa77376637ea382a6 Mon Sep 17 00:00:00 2001 From: Awais Date: Thu, 4 Apr 2024 11:02:32 +0500 Subject: [PATCH 06/22] 2.x - Added Tailwind Livewire `laravel/breeze` --- src/stubs/livewire/Form.stub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stubs/livewire/Form.stub b/src/stubs/livewire/Form.stub index 65fdfa7..f663054 100644 --- a/src/stubs/livewire/Form.stub +++ b/src/stubs/livewire/Form.stub @@ -5,7 +5,7 @@ namespace {{livewireNamespace}}\Forms; use {{modelNamespace}}\{{modelName}}; use Livewire\Form; -class Form extends Form +class {{modelName}}Form extends Form { public ?{{modelName}} ${{modelNameLowerCase}}Model; {{livewireFormProperties}} From f95d6c6ce22b96eae322014f804112828c98ae1b Mon Sep 17 00:00:00 2001 From: Awais Date: Thu, 4 Apr 2024 11:04:27 +0500 Subject: [PATCH 07/22] 2.x - Added Tailwind Livewire `laravel/breeze` --- src/stubs/livewire/Form.stub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stubs/livewire/Form.stub b/src/stubs/livewire/Form.stub index f663054..3ba1265 100644 --- a/src/stubs/livewire/Form.stub +++ b/src/stubs/livewire/Form.stub @@ -16,7 +16,7 @@ class {{modelName}}Form extends Form ]; } - public function setFlightModel({{modelName}} ${{modelNameLowerCase}}Model): void + public function set{{modelName}}Model({{modelName}} ${{modelNameLowerCase}}Model): void { $this->{{modelNameLowerCase}}Model = ${{modelNameLowerCase}}Model; {{livewireFormSetValues}} From e6584114886b8bf37ff66bd2c185dbdf9026f59b Mon Sep 17 00:00:00 2001 From: Awais Date: Thu, 4 Apr 2024 12:13:10 +0500 Subject: [PATCH 08/22] 2.x - Added Tailwind Livewire `laravel/breeze` --- src/Commands/GeneratorCommand.php | 6 +++++- src/stubs/livewire/Create.stub | 2 +- src/stubs/livewire/Edit.stub | 2 +- src/stubs/livewire/Index.stub | 2 +- src/stubs/livewire/Show.stub | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index b36e5b8..a9f96bb 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -237,8 +237,12 @@ private function _getLayoutPath(): string protected function _getViewPath($view): string { $name = Str::kebab($this->name); + $path = match ($this->options['stack']) { + 'livewire' => "/views/livewire/$name/$view.blade.php", + default => "/views/$name/$view.blade.php" + }; - return $this->makeDirectory(resource_path("/views/$name/$view.blade.php")); + return $this->makeDirectory(resource_path($path)); } /** diff --git a/src/stubs/livewire/Create.stub b/src/stubs/livewire/Create.stub index 090cf5c..88e9c43 100644 --- a/src/stubs/livewire/Create.stub +++ b/src/stubs/livewire/Create.stub @@ -26,6 +26,6 @@ class Create extends Component #[Layout('{{layout}}')] public function render() { - return view('livewire.{{modelNamePluralLowerCase}}.create'); + return view('livewire.{{modelNameLowerCase}}.create'); } } diff --git a/src/stubs/livewire/Edit.stub b/src/stubs/livewire/Edit.stub index 6ae0b38..8036520 100644 --- a/src/stubs/livewire/Edit.stub +++ b/src/stubs/livewire/Edit.stub @@ -26,6 +26,6 @@ class Edit extends Component #[Layout('{{layout}}')] public function render() { - return view('livewire.{{modelNamePluralLowerCase}}.edit'); + return view('livewire.{{modelNameLowerCase}}.edit'); } } diff --git a/src/stubs/livewire/Index.stub b/src/stubs/livewire/Index.stub index 5dd670b..0a70d04 100644 --- a/src/stubs/livewire/Index.stub +++ b/src/stubs/livewire/Index.stub @@ -17,7 +17,7 @@ class Index extends Component { ${{modelNamePluralLowerCase}} = {{modelName}}::paginate(); - return view('livewire.{{modelNamePluralLowerCase}}.index', compact('{{modelNamePluralLowerCase}}')) + return view('livewire.{{modelNameLowerCase}}.index', compact('{{modelNamePluralLowerCase}}')) ->with('i', $this->getPage() * ${{modelNamePluralLowerCase}}->perPage()); } diff --git a/src/stubs/livewire/Show.stub b/src/stubs/livewire/Show.stub index 82ea87a..562ba21 100644 --- a/src/stubs/livewire/Show.stub +++ b/src/stubs/livewire/Show.stub @@ -19,6 +19,6 @@ class Show extends Component #[Layout('{{layouts}}')] public function render() { - return view('livewire.{{modelNamePluralLowerCase}}.show', ['{{modelNameLowerCase}}' => $this->form->{{modelNameLowerCase}}Model]); + return view('livewire.{{modelNameLowerCase}}.show', ['{{modelNameLowerCase}}' => $this->form->{{modelNameLowerCase}}Model]); } } From 5ffb0f8d65dfe45782ff750e4c80022986b8abae Mon Sep 17 00:00:00 2001 From: Awais Date: Thu, 4 Apr 2024 12:56:22 +0500 Subject: [PATCH 09/22] 2.x - Added Tailwind Livewire `laravel/breeze` --- src/Commands/CrudGenerator.php | 33 ++++++++++++++++++++++++---- src/stubs/livewire/Show.stub | 2 +- src/stubs/views/livewire/create.stub | 2 +- src/stubs/views/livewire/edit.stub | 2 +- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index 4b1e2fb..4c1660f 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -55,16 +55,41 @@ public function handle() $this->buildOptions() ->buildController() ->buildModel() - ->buildViews(); + ->buildViews() + ->writeRoute(); + + $this->info('Created Successfully.'); + + return true; + } + + protected function writeRoute(): static + { + $replacements = $this->buildReplacements(); $this->info('Please add route below:'); $this->info(''); - $this->info("Route::resource('".$this->_getRoute()."', {$this->name}Controller::class);"); + + $lines = match ($this->options['stack']) { + 'livewire' => [ + "Route::get('/{$this->_getRoute()}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Index::class)->name('{$this->_getRoute()}.index');", + "Route::get('/{$this->_getRoute()}/create', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Create::class)->name('{$this->_getRoute()}.create');", + "Route::get('/{$this->_getRoute()}/show/\\{$replacements['modelNameLowerCase']}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Show::class)->name('{$this->_getRoute()}.show');", + "Route::get('/{$this->_getRoute()}/update/\\{{$replacements['modelNameLowerCase']}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Edit::class)->name('{$this->_getRoute()}.edit');", + ], + default => [ + "Route::resource('".$this->_getRoute()."', {$this->name}Controller::class);", + ] + }; + + foreach ($lines as $line) { + $this->info(''.$line.''); + } + $this->info(''); - $this->info('Created Successfully.'); - return true; + return $this; } /** diff --git a/src/stubs/livewire/Show.stub b/src/stubs/livewire/Show.stub index 562ba21..b492466 100644 --- a/src/stubs/livewire/Show.stub +++ b/src/stubs/livewire/Show.stub @@ -16,7 +16,7 @@ class Show extends Component $this->form->set{{modelName}}Model(${{modelNameLowerCase}}); } - #[Layout('{{layouts}}')] + #[Layout('{{layout}}')] public function render() { return view('livewire.{{modelNameLowerCase}}.show', ['{{modelNameLowerCase}}' => $this->form->{{modelNameLowerCase}}Model]); diff --git a/src/stubs/views/livewire/create.stub b/src/stubs/views/livewire/create.stub index 0468c45..28bfb0e 100644 --- a/src/stubs/views/livewire/create.stub +++ b/src/stubs/views/livewire/create.stub @@ -23,7 +23,7 @@
@csrf - @include('{{modelView}}.form') + @include('livewire.{{modelView}}.form')
diff --git a/src/stubs/views/livewire/edit.stub b/src/stubs/views/livewire/edit.stub index 2445673..25c0387 100644 --- a/src/stubs/views/livewire/edit.stub +++ b/src/stubs/views/livewire/edit.stub @@ -24,7 +24,7 @@
{{ method_field('PATCH') }} @csrf - @include('{{modelView}}.form') + @include('livewire.{{modelView}}.form')
From 0d9d3cfbc3455d44c84e9140fefcec5b08efc79b Mon Sep 17 00:00:00 2001 From: Awais Date: Thu, 4 Apr 2024 12:58:02 +0500 Subject: [PATCH 10/22] 2.x - Added Tailwind Livewire `laravel/breeze` --- src/Commands/CrudGenerator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index 4c1660f..104a0eb 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -75,8 +75,8 @@ protected function writeRoute(): static 'livewire' => [ "Route::get('/{$this->_getRoute()}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Index::class)->name('{$this->_getRoute()}.index');", "Route::get('/{$this->_getRoute()}/create', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Create::class)->name('{$this->_getRoute()}.create');", - "Route::get('/{$this->_getRoute()}/show/\\{$replacements['modelNameLowerCase']}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Show::class)->name('{$this->_getRoute()}.show');", - "Route::get('/{$this->_getRoute()}/update/\\{{$replacements['modelNameLowerCase']}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Edit::class)->name('{$this->_getRoute()}.edit');", + "Route::get('/{$this->_getRoute()}/show/\\{$replacements['{{modelNameLowerCase}}']}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Show::class)->name('{$this->_getRoute()}.show');", + "Route::get('/{$this->_getRoute()}/update/\\{{$replacements['{{modelNameLowerCase}}']}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Edit::class)->name('{$this->_getRoute()}.edit');", ], default => [ "Route::resource('".$this->_getRoute()."', {$this->name}Controller::class);", From 39733b8664dd5e473f7bb13a314895ffa834b72d Mon Sep 17 00:00:00 2001 From: Awais Date: Thu, 4 Apr 2024 13:09:46 +0500 Subject: [PATCH 11/22] 2.x - Added Tailwind Livewire `laravel/breeze` --- src/Commands/CrudGenerator.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index 104a0eb..57198f7 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -67,16 +67,16 @@ protected function writeRoute(): static { $replacements = $this->buildReplacements(); - $this->info('Please add route below:'); + $this->info('Please add route below: i:e; web.php'); $this->info(''); $lines = match ($this->options['stack']) { 'livewire' => [ - "Route::get('/{$this->_getRoute()}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Index::class)->name('{$this->_getRoute()}.index');", - "Route::get('/{$this->_getRoute()}/create', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Create::class)->name('{$this->_getRoute()}.create');", - "Route::get('/{$this->_getRoute()}/show/\\{$replacements['{{modelNameLowerCase}}']}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Show::class)->name('{$this->_getRoute()}.show');", - "Route::get('/{$this->_getRoute()}/update/\\{{$replacements['{{modelNameLowerCase}}']}', \{$this->livewireNamespace}\\{$replacements['{{modelNamePluralUpperCase}}']}\Edit::class)->name('{$this->_getRoute()}.edit');", + "Route::get('/{$this->_getRoute()}', \\$this->livewireNamespace\\{$replacements['{{modelNamePluralUpperCase}}']}\Index::class)->name('{$this->_getRoute()}.index');", + "Route::get('/{$this->_getRoute()}/create', \\$this->livewireNamespace\\{$replacements['{{modelNamePluralUpperCase}}']}\Create::class)->name('{$this->_getRoute()}.create');", + "Route::get('/{$this->_getRoute()}/show/{{$replacements['{{modelNameLowerCase}}']}}', \\$this->livewireNamespace\\{$replacements['{{modelNamePluralUpperCase}}']}\Show::class)->name('{$this->_getRoute()}.show');", + "Route::get('/{$this->_getRoute()}/update/{{$replacements['{{modelNameLowerCase}}']}}', \\$this->livewireNamespace\\{$replacements['{{modelNamePluralUpperCase}}']}\Edit::class)->name('{$this->_getRoute()}.edit');", ], default => [ "Route::resource('".$this->_getRoute()."', {$this->name}Controller::class);", @@ -84,7 +84,7 @@ protected function writeRoute(): static }; foreach ($lines as $line) { - $this->info(''.$line.''); + $this->info(''.$line.''); } $this->info(''); From 64688316ae17c55f62273d26007364c050cb3cd2 Mon Sep 17 00:00:00 2001 From: Awais Date: Thu, 4 Apr 2024 14:51:49 +0500 Subject: [PATCH 12/22] 2.x - Added Tailwind Livewire `laravel/breeze` view --- src/stubs/livewire/Create.stub | 4 ++-- src/stubs/livewire/Edit.stub | 4 ++-- src/stubs/livewire/Index.stub | 4 ++-- src/stubs/livewire/Show.stub | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/stubs/livewire/Create.stub b/src/stubs/livewire/Create.stub index 88e9c43..feb29d7 100644 --- a/src/stubs/livewire/Create.stub +++ b/src/stubs/livewire/Create.stub @@ -20,12 +20,12 @@ class Create extends Component { $this->form->store(); - return $this->redirectRoute('{{modelNamePluralLowerCase}}.index', navigate: true); + return $this->redirectRoute('{{modelRoute}}.index', navigate: true); } #[Layout('{{layout}}')] public function render() { - return view('livewire.{{modelNameLowerCase}}.create'); + return view('livewire.{{modelView}}.create'); } } diff --git a/src/stubs/livewire/Edit.stub b/src/stubs/livewire/Edit.stub index 8036520..0dfbbe2 100644 --- a/src/stubs/livewire/Edit.stub +++ b/src/stubs/livewire/Edit.stub @@ -20,12 +20,12 @@ class Edit extends Component { $this->form->update(); - return $this->redirectRoute('{{modelNamePluralLowerCase}}.index', navigate: true); + return $this->redirectRoute('{{modelRoute}}.index', navigate: true); } #[Layout('{{layout}}')] public function render() { - return view('livewire.{{modelNameLowerCase}}.edit'); + return view('livewire.{{modelView}}.edit'); } } diff --git a/src/stubs/livewire/Index.stub b/src/stubs/livewire/Index.stub index 0a70d04..3c067f3 100644 --- a/src/stubs/livewire/Index.stub +++ b/src/stubs/livewire/Index.stub @@ -17,7 +17,7 @@ class Index extends Component { ${{modelNamePluralLowerCase}} = {{modelName}}::paginate(); - return view('livewire.{{modelNameLowerCase}}.index', compact('{{modelNamePluralLowerCase}}')) + return view('livewire.{{modelView}}.index', compact('{{modelNamePluralLowerCase}}')) ->with('i', $this->getPage() * ${{modelNamePluralLowerCase}}->perPage()); } @@ -25,6 +25,6 @@ class Index extends Component { ${{modelNameLowerCase}}->delete(); - return $this->redirectRoute('{{modelNamePluralLowerCase}}.index', navigate: true); + return $this->redirectRoute('{{modelRoute}}.index', navigate: true); } } diff --git a/src/stubs/livewire/Show.stub b/src/stubs/livewire/Show.stub index b492466..8cfb791 100644 --- a/src/stubs/livewire/Show.stub +++ b/src/stubs/livewire/Show.stub @@ -19,6 +19,6 @@ class Show extends Component #[Layout('{{layout}}')] public function render() { - return view('livewire.{{modelNameLowerCase}}.show', ['{{modelNameLowerCase}}' => $this->form->{{modelNameLowerCase}}Model]); + return view('livewire.{{modelView}}.show', ['{{modelNameLowerCase}}' => $this->form->{{modelNameLowerCase}}Model]); } } From 032a8bcc8b992a1bf37542348838ccdc95a81ba6 Mon Sep 17 00:00:00 2001 From: Muhammad Awais Date: Thu, 4 Apr 2024 16:43:07 +0500 Subject: [PATCH 13/22] Update README.md --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a0ae9c0..581325b 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,23 @@ ![Laravel Crud Generator](https://banners.beyondco.de/Laravel%20CRUD.png?theme=dark&packageManager=composer+require&packageName=ibex%2Fcrud-generator&pattern=architect&style=style_1&description=Laravel+CRUD+Generator&md=1&showWatermark=0&fontSize=100px&images=gift) -![Packagist](https://img.shields.io/badge/Packagist-v1.3.2-green.svg?style=flat-square) +![Packagist](https://img.shields.io/badge/Packagist-v2-green.svg?style=flat-square) ![Licence](https://img.shields.io/badge/Licence-MIT-green.svg?style=flat-square) ![StyleCI](https://img.shields.io/badge/StyleCI-pass-green.svg?style=flat-square) -This Laravel Generator package provides and generates Controller, Model (with eloquent relations), and Views in **Bootstrap** for your development of your applications with a single command. +This Laravel CRUD Generator v2.x package provides and generates Controller, Model (with eloquent relations), and Views in **Bootstrap**/**Tailwind CSS** for the development of your applications with a single command. This new `v2.x` will have `--stack` options like `bootstrap`, `tailwind`, and `livewire`. (Livewire views will be generated in **Tailwind** css) - Will create **Model** with Eloquent relations - Will create **Controller** with all resources -- Will create **views** in Bootstrap +- Will create **Component** with all resources for Livewire +- Will create **views** in Bootstrap/Tailwind + +This is the best crud generator for a blank Laravel project installation too. This will auto install the starter kit [laravel/breeze](https://github.com/laravel/breeze) or [laravel/ui](https://github.com/laravel/ui) (for bootstrap 5) for blank Laravel installation. ## Requirements - Laravel >= 5.5 - PHP >= 7.1 + Laravel >= 10.x + PHP >= 8.1 ## Installation 1 - Install @@ -26,6 +29,12 @@ composer require ibex/crud-generator --dev php artisan vendor:publish --tag=crud ``` + +**For older Laravel(<10.x) versions please use [v1.x](https://github.com/awais-vteams/laravel-crud-generator/tree/v1.6)** +``` +composer require ibex/crud-generator:1.6 --dev +``` + ## Usage ``` php artisan make:crud {table_name} @@ -37,15 +46,31 @@ Add a route in `web.php` ``` Route::resource('banks', BankController::class); ``` + +For `Livewire` add routes below +``` +Route::get('/banks', \App\Livewire\Banks\Index::class)->name('banks.index'); +Route::get('/banks/create', \App\Livewire\Banks\Create::class)->name('banks.create'); +Route::get('/banks/show/{bank}', \App\Livewire\Banks\Show::class)->name('banks.show'); +Route::get('/banks/update/{bank}', \App\Livewire\Banks\Edit::class)->name('banks.edit'); +``` Route name in plural slug case. #### Options +- Tech Stack +``` +php artisan make:crud {table_name} --stack={bootstrap,tailwind,livewire} + +php artisan make:crud banks --stack=bootstrap //This will create views in Bootstrap 5 using Blade +php artisan make:crud banks --stack=tailwind //This will create views in Tailwind css using Blade +php artisan make:crud banks --stack=livewire //This will create views in Tailwind css with Livewire components +``` - Custom Route ``` php artisan make:crud {table_name} --route={route_name} ``` -## Example +## Examples *Model* image @@ -54,12 +79,23 @@ php artisan make:crud {table_name} --route={route_name} *Controller* image +*Livewire component* +image + -*Listing* +*Tailwind CSS* +image + + +*Bootstrap* ![Listing](https://i.imgur.com/UH5XGuw.png) -*Form* +*Tailwind Form* + +image + +*Bootstrap Form* ![Form](https://i.imgur.com/poRiZRO.png) From dcf7cb50e85f46d9cd030da57407f9833e05ba0a Mon Sep 17 00:00:00 2001 From: Awais Date: Sat, 20 Apr 2024 07:48:30 +0500 Subject: [PATCH 14/22] 2.x - Added API stack only --- src/Commands/CrudGenerator.php | 42 +++++++++++++++++- src/Commands/GeneratorCommand.php | 18 ++++++++ src/stubs/api/Controller.stub | 54 +++++++++++++++++++++++ src/stubs/api/Resource.stub | 19 ++++++++ src/stubs/views/react/create.stub | 37 ---------------- src/stubs/views/react/edit.stub | 37 ---------------- src/stubs/views/react/form-field.stub | 5 --- src/stubs/views/react/form.stub | 6 --- src/stubs/views/react/index.stub | 62 --------------------------- src/stubs/views/react/show.stub | 37 ---------------- src/stubs/views/react/view-field.stub | 4 -- src/stubs/views/vue/create.stub | 37 ---------------- src/stubs/views/vue/edit.stub | 37 ---------------- src/stubs/views/vue/form-field.stub | 5 --- src/stubs/views/vue/form.stub | 6 --- src/stubs/views/vue/index.stub | 62 --------------------------- src/stubs/views/vue/show.stub | 37 ---------------- src/stubs/views/vue/view-field.stub | 4 -- 18 files changed, 131 insertions(+), 378 deletions(-) create mode 100644 src/stubs/api/Controller.stub create mode 100644 src/stubs/api/Resource.stub delete mode 100644 src/stubs/views/react/create.stub delete mode 100644 src/stubs/views/react/edit.stub delete mode 100644 src/stubs/views/react/form-field.stub delete mode 100644 src/stubs/views/react/form.stub delete mode 100644 src/stubs/views/react/index.stub delete mode 100644 src/stubs/views/react/show.stub delete mode 100644 src/stubs/views/react/view-field.stub delete mode 100644 src/stubs/views/vue/create.stub delete mode 100644 src/stubs/views/vue/edit.stub delete mode 100644 src/stubs/views/vue/form-field.stub delete mode 100644 src/stubs/views/vue/form.stub delete mode 100644 src/stubs/views/vue/index.stub delete mode 100644 src/stubs/views/vue/show.stub delete mode 100644 src/stubs/views/vue/view-field.stub diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index 57198f7..e8769c0 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -5,6 +5,7 @@ use Exception; use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Support\Str; +use function Laravel\Prompts\select; /** * Class CrudGenerator. @@ -21,7 +22,7 @@ class CrudGenerator extends GeneratorCommand protected $signature = 'make:crud {name : Table name} {--route= : Custom route name} - {--stack= : The development stack that should be installed (blade,tailwind,livewire,react,vue)}'; + {--stack= : The development stack that should be installed (blade,tailwind,livewire,api)}'; /** * The console command description. @@ -63,6 +64,22 @@ public function handle() return true; } + protected function promptForMissingArguments(): array + { + return [ + 'stack' => fn() => select( + label: 'Which stack would you like to install?', + options: [ + 'blade' => 'Blade with Bootstrap css', + 'tailwind' => 'Blade with Tailwind css', + 'livewire' => 'Livewire with Tailwind css', + 'api' => 'API only', + ], + scroll: 4, + ), + ]; + } + protected function writeRoute(): static { $replacements = $this->buildReplacements(); @@ -104,6 +121,8 @@ protected function buildController(): static $this->buildLivewire(); return $this; + } elseif ($this->options['stack'] == 'api') { + $this->setControllerNamespace('App\Http\Controllers\Api'); } $controllerPath = $this->_getControllerPath($this->name); @@ -116,12 +135,27 @@ protected function buildController(): static $replace = $this->buildReplacements(); + $stubFolder = match ($this->options['stack']) { + 'api' => 'api/', + default => '' + }; + $controllerTemplate = str_replace( - array_keys($replace), array_values($replace), $this->getStub('Controller') + array_keys($replace), array_values($replace), $this->getStub($stubFolder.'Controller') ); $this->write($controllerPath, $controllerTemplate); + if ($this->options['stack'] == 'api') { + $resourcePath = $this->_getResourcePath($this->name); + + $resourceTemplate = str_replace( + array_keys($replace), array_values($replace), $this->getStub($stubFolder.'Resource') + ); + + $this->write($resourcePath, $resourceTemplate); + } + return $this; } @@ -198,6 +232,10 @@ protected function buildModel(): static */ protected function buildViews(): static { + if ($this->options['stack'] == 'api') { + return $this; + } + $this->info('Creating Views ...'); $tableHead = "\n"; diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index a9f96bb..4fdcdd2 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -53,6 +53,8 @@ abstract class GeneratorCommand extends Command protected string $controllerNamespace = 'App\Http\Controllers'; + protected string $resourceNamespace = 'App\Http\Resources'; + protected string $livewireNamespace = 'App\Livewire'; protected string $requestNamespace = 'App\Http\Requests'; @@ -175,6 +177,16 @@ protected function _getControllerPath($name): string return app_path($this->_getNamespacePath($this->controllerNamespace)."{$name}Controller.php"); } + /** + * @param $name + * + * @return string + */ + protected function _getResourcePath($name): string + { + return app_path($this->_getNamespacePath($this->resourceNamespace)."{$name}Resource.php"); + } + /** * @param $name * @@ -259,6 +271,7 @@ protected function buildReplacements(): array '{{modelTitlePlural}}' => Str::title(Str::snake(Str::plural($this->name), ' ')), '{{modelNamespace}}' => $this->modelNamespace, '{{controllerNamespace}}' => $this->controllerNamespace, + '{{resourceNamespace}}' => $this->resourceNamespace, '{{requestNamespace}}' => $this->requestNamespace, '{{livewireNamespace}}' => $this->livewireNamespace, '{{modelNamePluralLowerCase}}' => Str::camel(Str::plural($this->name)), @@ -582,4 +595,9 @@ protected function runCommands(array $commands): void $this->output->write(' '.$line); }); } + + protected function setControllerNamespace(string $controllerNamespace): void + { + $this->controllerNamespace = $controllerNamespace; + } } diff --git a/src/stubs/api/Controller.stub b/src/stubs/api/Controller.stub new file mode 100644 index 0000000..419e9f2 --- /dev/null +++ b/src/stubs/api/Controller.stub @@ -0,0 +1,54 @@ +validated()); + } + + /** + * Display the specified resource. + */ + public function show({{modelName}} ${{modelNameLowerCase}}): {{modelName}} + { + return ${{modelNameLowerCase}}; + } + + /** + * Update the specified resource in storage. + */ + public function update({{modelName}}Request $request, {{modelName}} ${{modelNameLowerCase}}): {{modelName}} + { + ${{modelNameLowerCase}}->update($request->validated()); + + return ${{modelNameLowerCase}}; + } + + public function destroy({{modelName}} ${{modelNameLowerCase}}): Response + { + ${{modelNameLowerCase}}->delete(); + + return response()->noContent(); + } +} diff --git a/src/stubs/api/Resource.stub b/src/stubs/api/Resource.stub new file mode 100644 index 0000000..f8a9dba --- /dev/null +++ b/src/stubs/api/Resource.stub @@ -0,0 +1,19 @@ + + */ + public function toArray(Request $request): array + { + return parent::toArray($request); + } +} diff --git a/src/stubs/views/react/create.stub b/src/stubs/views/react/create.stub deleted file mode 100644 index cda6e43..0000000 --- a/src/stubs/views/react/create.stub +++ /dev/null @@ -1,37 +0,0 @@ - - -

- {{ __('Create') }} {{modelTitle}} -

-
- -
-
-
-
-
-
-

{{ __('Create') }} {{modelTitle}}

-

Add a new {{ __('{{modelTitle}}') }}.

-
-
- Back -
-
- -
-
-
-
- @csrf - - @include('{{modelView}}.form') -
-
-
-
-
-
-
-
-
diff --git a/src/stubs/views/react/edit.stub b/src/stubs/views/react/edit.stub deleted file mode 100644 index 8c488bb..0000000 --- a/src/stubs/views/react/edit.stub +++ /dev/null @@ -1,37 +0,0 @@ - - -

- {{ __('Update') }} {{modelTitle}} -

-
- -
-
-
-
-
-
-

{{ __('Update') }} {{modelTitle}}

-

Update existing {{ __('{{modelTitle}}') }}.

-
-
- Back -
-
- -
-
-
-
- {{ method_field('PATCH') }} - @csrf - @include('{{modelView}}.form') -
-
-
-
-
-
-
-
-
diff --git a/src/stubs/views/react/form-field.stub b/src/stubs/views/react/form-field.stub deleted file mode 100644 index e65450d..0000000 --- a/src/stubs/views/react/form-field.stub +++ /dev/null @@ -1,5 +0,0 @@ -
- - - -
diff --git a/src/stubs/views/react/form.stub b/src/stubs/views/react/form.stub deleted file mode 100644 index 35efa04..0000000 --- a/src/stubs/views/react/form.stub +++ /dev/null @@ -1,6 +0,0 @@ -
- {{form}} -
- Submit -
-
\ No newline at end of file diff --git a/src/stubs/views/react/index.stub b/src/stubs/views/react/index.stub deleted file mode 100644 index cf39a0d..0000000 --- a/src/stubs/views/react/index.stub +++ /dev/null @@ -1,62 +0,0 @@ - - -

- {{ __('{{modelTitlePlural}}') }} -

-
- -
-
-
-
-
-
-

{{ __('{{modelTitlePlural}}') }}

-

A list of all the {{ __('{{modelTitlePlural}}') }}.

-
-
- Add new -
-
- -
-
-
- - - - - {{tableHeader}} - - - - - @foreach (${{modelNamePluralLowerCase}} as ${{modelNameLowerCase}}) - - - {{tableBody}} - - - @endforeach - -
No
{{ ++$i }} -
- {{ __('Show') }} - {{ __('Edit') }} - @csrf - @method('DELETE') - {{ __('Delete') }} -
-
- -
- {!! ${{modelNamePluralLowerCase}}->withQueryString()->links() !!} -
-
-
-
-
-
-
-
-
\ No newline at end of file diff --git a/src/stubs/views/react/show.stub b/src/stubs/views/react/show.stub deleted file mode 100644 index 4257207..0000000 --- a/src/stubs/views/react/show.stub +++ /dev/null @@ -1,37 +0,0 @@ - - -

- {{ ${{modelNameLowerCase}}->name ?? __('Show') . " " . __('{{modelTitle}}') }} -

-
- -
-
-
-
-
-
-

{{ __('Show') }} {{modelTitle}}

-

Details of {{ __('{{modelTitle}}') }}.

-
-
- Back -
-
- -
-
-
-
-
- {{viewRows}} -
-
-
-
-
-
-
-
-
-
diff --git a/src/stubs/views/react/view-field.stub b/src/stubs/views/react/view-field.stub deleted file mode 100644 index 4045b1a..0000000 --- a/src/stubs/views/react/view-field.stub +++ /dev/null @@ -1,4 +0,0 @@ -
-
{{title}}
-
{{ ${{modelNameLowerCase}}->{{column}} }}
-
diff --git a/src/stubs/views/vue/create.stub b/src/stubs/views/vue/create.stub deleted file mode 100644 index cda6e43..0000000 --- a/src/stubs/views/vue/create.stub +++ /dev/null @@ -1,37 +0,0 @@ - - -

- {{ __('Create') }} {{modelTitle}} -

-
- -
-
-
-
-
-
-

{{ __('Create') }} {{modelTitle}}

-

Add a new {{ __('{{modelTitle}}') }}.

-
-
- Back -
-
- -
-
-
-
- @csrf - - @include('{{modelView}}.form') -
-
-
-
-
-
-
-
-
diff --git a/src/stubs/views/vue/edit.stub b/src/stubs/views/vue/edit.stub deleted file mode 100644 index 8c488bb..0000000 --- a/src/stubs/views/vue/edit.stub +++ /dev/null @@ -1,37 +0,0 @@ - - -

- {{ __('Update') }} {{modelTitle}} -

-
- -
-
-
-
-
-
-

{{ __('Update') }} {{modelTitle}}

-

Update existing {{ __('{{modelTitle}}') }}.

-
-
- Back -
-
- -
-
-
-
- {{ method_field('PATCH') }} - @csrf - @include('{{modelView}}.form') -
-
-
-
-
-
-
-
-
diff --git a/src/stubs/views/vue/form-field.stub b/src/stubs/views/vue/form-field.stub deleted file mode 100644 index e65450d..0000000 --- a/src/stubs/views/vue/form-field.stub +++ /dev/null @@ -1,5 +0,0 @@ -
- - - -
diff --git a/src/stubs/views/vue/form.stub b/src/stubs/views/vue/form.stub deleted file mode 100644 index 35efa04..0000000 --- a/src/stubs/views/vue/form.stub +++ /dev/null @@ -1,6 +0,0 @@ -
- {{form}} -
- Submit -
-
\ No newline at end of file diff --git a/src/stubs/views/vue/index.stub b/src/stubs/views/vue/index.stub deleted file mode 100644 index cf39a0d..0000000 --- a/src/stubs/views/vue/index.stub +++ /dev/null @@ -1,62 +0,0 @@ - - -

- {{ __('{{modelTitlePlural}}') }} -

-
- -
-
-
-
-
-
-

{{ __('{{modelTitlePlural}}') }}

-

A list of all the {{ __('{{modelTitlePlural}}') }}.

-
-
- Add new -
-
- -
-
-
- - - - - {{tableHeader}} - - - - - @foreach (${{modelNamePluralLowerCase}} as ${{modelNameLowerCase}}) - - - {{tableBody}} - - - @endforeach - -
No
{{ ++$i }} -
- {{ __('Show') }} - {{ __('Edit') }} - @csrf - @method('DELETE') - {{ __('Delete') }} -
-
- -
- {!! ${{modelNamePluralLowerCase}}->withQueryString()->links() !!} -
-
-
-
-
-
-
-
-
\ No newline at end of file diff --git a/src/stubs/views/vue/show.stub b/src/stubs/views/vue/show.stub deleted file mode 100644 index 4257207..0000000 --- a/src/stubs/views/vue/show.stub +++ /dev/null @@ -1,37 +0,0 @@ - - -

- {{ ${{modelNameLowerCase}}->name ?? __('Show') . " " . __('{{modelTitle}}') }} -

-
- -
-
-
-
-
-
-

{{ __('Show') }} {{modelTitle}}

-

Details of {{ __('{{modelTitle}}') }}.

-
-
- Back -
-
- -
-
-
-
-
- {{viewRows}} -
-
-
-
-
-
-
-
-
-
diff --git a/src/stubs/views/vue/view-field.stub b/src/stubs/views/vue/view-field.stub deleted file mode 100644 index 4045b1a..0000000 --- a/src/stubs/views/vue/view-field.stub +++ /dev/null @@ -1,4 +0,0 @@ -
-
{{title}}
-
{{ ${{modelNameLowerCase}}->{{column}} }}
-
From aabba17f28c3eb3392c7b668082a23e4a47c8284 Mon Sep 17 00:00:00 2001 From: Awais Date: Sat, 20 Apr 2024 07:52:17 +0500 Subject: [PATCH 15/22] 2.x - Added API stack only --- src/Commands/GeneratorCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 4fdcdd2..b7a19c0 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -5,6 +5,7 @@ use Exception; use Ibex\CrudGenerator\ModelGenerator; use Illuminate\Console\Command; +use Illuminate\Contracts\Console\PromptsForMissingInput; use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Arr; @@ -17,7 +18,7 @@ /** * Class GeneratorCommand. */ -abstract class GeneratorCommand extends Command +abstract class GeneratorCommand extends Command implements PromptsForMissingInput { protected Filesystem $files; From 4bfc589c053b9b38414c554a7fbeebc3a851422d Mon Sep 17 00:00:00 2001 From: Awais Date: Sat, 20 Apr 2024 07:54:09 +0500 Subject: [PATCH 16/22] 2.x - Added API stack only --- src/Commands/CrudGenerator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index e8769c0..32ec161 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -64,7 +64,7 @@ public function handle() return true; } - protected function promptForMissingArguments(): array + protected function promptForMissingArgumentsUsing(): array { return [ 'stack' => fn() => select( From f2ba7e7b604fdb455239d1cc1fc9ea40b6cb59d3 Mon Sep 17 00:00:00 2001 From: Awais Date: Sat, 20 Apr 2024 07:59:19 +0500 Subject: [PATCH 17/22] 2.x - Added API stack only --- src/Commands/CrudGenerator.php | 4 ++-- src/Commands/GeneratorCommand.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index 32ec161..ce8ea63 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -21,8 +21,8 @@ class CrudGenerator extends GeneratorCommand */ protected $signature = 'make:crud {name : Table name} - {--route= : Custom route name} - {--stack= : The development stack that should be installed (blade,tailwind,livewire,api)}'; + {stack : The development stack that should be installed (blade,tailwind,livewire,api)} + {--route= : Custom route name}'; /** * The console command description. diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index b7a19c0..edc972e 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -524,7 +524,7 @@ protected function getNameInput(): string protected function buildOptions(): static { $this->options['route'] = null; - $this->options['stack'] = match ($this->option('stack')) { + $this->options['stack'] = match ($this->argument('stack')) { 'tailwind' => 'tailwind', 'livewire' => 'livewire', 'react' => 'react', From 5076f0e5476b536007ba0963b6db3cd9b11e7754 Mon Sep 17 00:00:00 2001 From: Awais Date: Sat, 20 Apr 2024 08:17:59 +0500 Subject: [PATCH 18/22] 2.x - Added API stack only --- src/Commands/CrudGenerator.php | 13 +++++++++++++ src/Commands/GeneratorCommand.php | 7 ------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index ce8ea63..9b5978c 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -5,6 +5,8 @@ use Exception; use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Support\Str; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; use function Laravel\Prompts\select; /** @@ -80,6 +82,17 @@ protected function promptForMissingArgumentsUsing(): array ]; } + protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output): void + { + $this->options['stack'] = match ($input->getArgument('stack')) { + 'tailwind' => 'tailwind', + 'livewire' => 'livewire', + 'react' => 'react', + 'vue' => 'vue', + default => 'bootstrap', + }; + } + protected function writeRoute(): static { $replacements = $this->buildReplacements(); diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index edc972e..d0aac21 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -524,13 +524,6 @@ protected function getNameInput(): string protected function buildOptions(): static { $this->options['route'] = null; - $this->options['stack'] = match ($this->argument('stack')) { - 'tailwind' => 'tailwind', - 'livewire' => 'livewire', - 'react' => 'react', - 'vue' => 'vue', - default => 'bootstrap', - }; return $this; } From c98ec0c32a49eb855af0916b3161a78de5737140 Mon Sep 17 00:00:00 2001 From: Awais Date: Sat, 20 Apr 2024 15:27:20 +0500 Subject: [PATCH 19/22] 2.x - Added API stack only --- src/Commands/CrudGenerator.php | 5 ++++- src/Commands/GeneratorCommand.php | 1 + src/stubs/api/Controller.stub | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index 9b5978c..02a221a 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -97,7 +97,7 @@ protected function writeRoute(): static { $replacements = $this->buildReplacements(); - $this->info('Please add route below: i:e; web.php'); + $this->info('Please add route below: i:e; web.php or api.php'); $this->info(''); @@ -108,6 +108,9 @@ protected function writeRoute(): static "Route::get('/{$this->_getRoute()}/show/{{$replacements['{{modelNameLowerCase}}']}}', \\$this->livewireNamespace\\{$replacements['{{modelNamePluralUpperCase}}']}\Show::class)->name('{$this->_getRoute()}.show');", "Route::get('/{$this->_getRoute()}/update/{{$replacements['{{modelNameLowerCase}}']}}', \\$this->livewireNamespace\\{$replacements['{{modelNamePluralUpperCase}}']}\Edit::class)->name('{$this->_getRoute()}.edit');", ], + 'api' => [ + "Route::apiResource('".$this->_getRoute()."', {$this->name}Controller::class);", + ], default => [ "Route::resource('".$this->_getRoute()."', {$this->name}Controller::class);", ] diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index d0aac21..9312c78 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -524,6 +524,7 @@ protected function getNameInput(): string protected function buildOptions(): static { $this->options['route'] = null; + $this->options['stack'] = $this->argument('stack'); return $this; } diff --git a/src/stubs/api/Controller.stub b/src/stubs/api/Controller.stub index 419e9f2..deb99d0 100644 --- a/src/stubs/api/Controller.stub +++ b/src/stubs/api/Controller.stub @@ -6,6 +6,8 @@ use {{modelNamespace}}\{{modelName}}; use Illuminate\Http\Request; use {{requestNamespace}}\{{modelName}}Request; use Illuminate\Http\Response; +use {{controllerNamespace}}\Controller; +use {{resourceNamespace}}\{{modelName}}Resource; class {{modelName}}Controller extends Controller { From 9f53fd81d94c54060bc21d69eb4f33533b590e6c Mon Sep 17 00:00:00 2001 From: Awais Date: Sat, 20 Apr 2024 15:41:56 +0500 Subject: [PATCH 20/22] 2.x - Added API stack only --- src/Commands/CrudGenerator.php | 6 +++--- src/Commands/GeneratorCommand.php | 18 +++++++++++++----- src/stubs/api/Controller.stub | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Commands/CrudGenerator.php b/src/Commands/CrudGenerator.php index 02a221a..0e4c662 100644 --- a/src/Commands/CrudGenerator.php +++ b/src/Commands/CrudGenerator.php @@ -137,11 +137,11 @@ protected function buildController(): static $this->buildLivewire(); return $this; - } elseif ($this->options['stack'] == 'api') { - $this->setControllerNamespace('App\Http\Controllers\Api'); } - $controllerPath = $this->_getControllerPath($this->name); + $controllerPath = $this->options['stack'] == 'api' + ? $this->_getApiControllerPath($this->name) + : $this->_getControllerPath($this->name); if ($this->files->exists($controllerPath) && $this->ask('Already exist Controller. Do you want overwrite (y/n)?', 'y') == 'n') { return $this; diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 9312c78..a08cbe2 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -54,6 +54,8 @@ abstract class GeneratorCommand extends Command implements PromptsForMissingInpu protected string $controllerNamespace = 'App\Http\Controllers'; + protected string $apiControllerNamespace = 'App\Http\Controllers\Api'; + protected string $resourceNamespace = 'App\Http\Resources'; protected string $livewireNamespace = 'App\Livewire'; @@ -178,6 +180,16 @@ protected function _getControllerPath($name): string return app_path($this->_getNamespacePath($this->controllerNamespace)."{$name}Controller.php"); } + /** + * @param $name + * + * @return string + */ + protected function _getApiControllerPath($name): string + { + return app_path($this->_getNamespacePath($this->apiControllerNamespace)."{$name}Controller.php"); + } + /** * @param $name * @@ -272,6 +284,7 @@ protected function buildReplacements(): array '{{modelTitlePlural}}' => Str::title(Str::snake(Str::plural($this->name), ' ')), '{{modelNamespace}}' => $this->modelNamespace, '{{controllerNamespace}}' => $this->controllerNamespace, + '{{apiControllerNamespace}}' => $this->apiControllerNamespace, '{{resourceNamespace}}' => $this->resourceNamespace, '{{requestNamespace}}' => $this->requestNamespace, '{{livewireNamespace}}' => $this->livewireNamespace, @@ -590,9 +603,4 @@ protected function runCommands(array $commands): void $this->output->write(' '.$line); }); } - - protected function setControllerNamespace(string $controllerNamespace): void - { - $this->controllerNamespace = $controllerNamespace; - } } diff --git a/src/stubs/api/Controller.stub b/src/stubs/api/Controller.stub index deb99d0..f183c2d 100644 --- a/src/stubs/api/Controller.stub +++ b/src/stubs/api/Controller.stub @@ -1,6 +1,6 @@ Date: Sun, 21 Apr 2024 07:31:08 +0500 Subject: [PATCH 21/22] Update README.md --- README.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 581325b..da700e4 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,11 @@ ![StyleCI](https://img.shields.io/badge/StyleCI-pass-green.svg?style=flat-square) -This Laravel CRUD Generator v2.x package provides and generates Controller, Model (with eloquent relations), and Views in **Bootstrap**/**Tailwind CSS** for the development of your applications with a single command. This new `v2.x` will have `--stack` options like `bootstrap`, `tailwind`, and `livewire`. (Livewire views will be generated in **Tailwind** css) +This Laravel CRUD Generator v2.x package provides and generates Controller, Model (with eloquent relations), and Views in **Bootstrap**/**Tailwind CSS** for the development of your applications with a single command. This new `v2.x` will have `--stack` options like `bootstrap`, `tailwind`, `livewire`(Livewire views will be generated in **Tailwind** CSS), and `API` only. - Will create **Model** with Eloquent relations - Will create **Controller** with all resources +- Will create **API Controllers** with all requests - Will create **Component** with all resources for Livewire - Will create **views** in Bootstrap/Tailwind @@ -54,22 +55,32 @@ Route::get('/banks/create', \App\Livewire\Banks\Create::class)->name('banks.crea Route::get('/banks/show/{bank}', \App\Livewire\Banks\Show::class)->name('banks.show'); Route::get('/banks/update/{bank}', \App\Livewire\Banks\Edit::class)->name('banks.edit'); ``` + +For `api` add routes below +``` +Route::apiResource('banks', BankController::class); +``` + Route name in plural slug case. #### Options - Tech Stack + + image ``` -php artisan make:crud {table_name} --stack={bootstrap,tailwind,livewire} +php artisan make:crud {table_name} --stack={bootstrap,tailwind,livewire,api} php artisan make:crud banks --stack=bootstrap //This will create views in Bootstrap 5 using Blade php artisan make:crud banks --stack=tailwind //This will create views in Tailwind css using Blade php artisan make:crud banks --stack=livewire //This will create views in Tailwind css with Livewire components +php artisan make:crud banks --stack=api //This will create API only controllers ``` - Custom Route ``` php artisan make:crud {table_name} --route={route_name} ``` + ## Examples *Model* @@ -82,6 +93,10 @@ php artisan make:crud {table_name} --route={route_name} *Livewire component* image +*API only controller* + +image + *Tailwind CSS* image From c19d7189b9ef9af4a91bba043d6476256c283a4c Mon Sep 17 00:00:00 2001 From: Muhammad Awais Date: Sun, 21 Apr 2024 19:37:59 +0500 Subject: [PATCH 22/22] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index da700e4..ea217b7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ![StyleCI](https://img.shields.io/badge/StyleCI-pass-green.svg?style=flat-square) -This Laravel CRUD Generator v2.x package provides and generates Controller, Model (with eloquent relations), and Views in **Bootstrap**/**Tailwind CSS** for the development of your applications with a single command. This new `v2.x` will have `--stack` options like `bootstrap`, `tailwind`, `livewire`(Livewire views will be generated in **Tailwind** CSS), and `API` only. +This Laravel CRUD Generator v2.x package provides and generates Controller, Model (with eloquent relations), and Views in **Bootstrap**/**Tailwind CSS** for the development of your applications with a single command. This new `v2.x` will have stack options like `bootstrap`, `tailwind`, `livewire`(Livewire views will be generated in **Tailwind** CSS), and `API` only. - Will create **Model** with Eloquent relations - Will create **Controller** with all resources @@ -68,12 +68,12 @@ Route name in plural slug case. image ``` -php artisan make:crud {table_name} --stack={bootstrap,tailwind,livewire,api} +php artisan make:crud {table_name} {bootstrap,tailwind,livewire,api} -php artisan make:crud banks --stack=bootstrap //This will create views in Bootstrap 5 using Blade -php artisan make:crud banks --stack=tailwind //This will create views in Tailwind css using Blade -php artisan make:crud banks --stack=livewire //This will create views in Tailwind css with Livewire components -php artisan make:crud banks --stack=api //This will create API only controllers +php artisan make:crud banks bootstrap //This will create views in Bootstrap 5 using Blade +php artisan make:crud banks tailwind //This will create views in Tailwind css using Blade +php artisan make:crud banks livewire //This will create views in Tailwind css with Livewire components +php artisan make:crud banks api //This will create API only controllers ``` - Custom Route ```