[ kalizi.dev ]

Configura una Dashboard Admin Laravel con InfyOm in pochi minuti, anche su progetti esistenti

Photo by Carlos Muza on Unsplash

Hai passato le ultime X ore a costruire un sistema molto complesso, con tante interazioni e funzionalità complicate, hai scritto i test e ora tutto funziona. Ma non hai una Dashboard da cui monitorare i dettagli del tuo sistema ed eseguire operazioni CRUD sui suoi modelli, e non vuoi perdere troppo tempo a mettere in piedi una dashboard che non ti serve direttamente o che non userai direttamente, quindi?

Questo è, in breve, ciò che mi è capitato qualche giorno fa. Voglio darti un po' di contesto senza condizionare la tua opinione sull'intera idea di questo articolo. Dovevo costruire un sistema complesso in cui puoi eseguire una sola operazione, il sistema ha una sola funzionalità complessa: l'utente deve caricare dei file, scegliere una configurazione, inserire la sua email (sì, l'utente non ha login) e poi consegnare tutto al server che accoda un job; questo job lavora in background eseguendo ciò che deve fare e infine invia una email. È stato un sistema bellissimo da programmare (se ti piace programmare 💻 come a me), ho dovuto incollare Laravel con alcuni script bash, ho scritto i test, ho controllato le falle di sicurezza, ma... e se i manager volessero vedere lo stato attuale dei job e cosa fanno gli utenti? E ho iniziato a cercare il modo più veloce per costruire una bella dashboard con operazioni CRUD, con il minor codice da scrivere e il miglior risultato possibile, ed eccolo qui InfyOmLabs Laravel Generator!

🔧 Configurare tutto

Partirò da un progetto esistente, ma tutto ciò che vedi qui può essere replicato facilmente in qualunque progetto, anche uno nuovo.

Come detto prima, nel mio progetto non ho nessun modello utente (perché non ho login), quindi partirò dalla sua migration. Puoi tranquillamente prendere la migration integrata di Laravel e creare un utente programmaticamente via tinker o in qualche altro modo, metto il codice per tinker:

User::create([
    'name' => 'Kalizi',
    'email' => '****@******.***',
    'password' => \Hash::make('myBeautifulPassword'),
]);

Ora siamo pronti a costruire la dashboard con il generator, dobbiamo partire da composer.json :

"require": {
    // Your dependencies
    "infyomlabs/laravel-generator": "8.0.x-dev",
    "laravelcollective/html": "^6.2",
    "infyomlabs/adminlte-templates": "8.0.x-dev",
    "doctrine/dbal": "~2.3",
    "yajra/laravel-datatables": "^1.5",
    "yajra/laravel-datatables-buttons": "^4.10",
    "yajra/laravel-datatables-oracle": "~9.0"
},

Con questi package aggiungerai il generator, il generator HTML, adminlte-template per la dashboard, dbal per leggere gli schemi dal database e usarli nella generazione, i package yajra datatables per la generazione delle jQuery datatables e per rendere semplici le interazioni con il server. Se preferisci, puoi passare al template CoreUI usando "infyomlabs/coreui-templates": "8.0.x-dev" (al posto di adminlte). Ora basta un composer update .

Ora pubblica la config con php artisan vendor:publish --provider="InfyOm\Generator\InfyOmGeneratorServiceProvider" e siamo pronti!

Ora modifica config/infyom/laravel_generator.php editando:

  1. path: se vuoi mettere ogni contenuto generato in una cartella specifica, nel mio caso volevo tutto sotto una cartella admin, quindi ho aggiunto /admin come cartella dove necessario (views). Questo è particolarmente utile se vuoi separare la roba dell'admin dal codice del tuo sistema.
  2. 'templates' => 'your_template_here': puoi mettere adminlte-templates o coreui-templates.
  3. 'repository_pattern' => false nella chiave options, il pattern repository non mi piace molto, ma puoi tenerlo se preferisci
  4. 'prefixes' => [ 'route' => 'admin', 'path' => 'admin', 'views' => '', 'public' => '' ] questo aggiungerà ogni route come admin.? nel path /admin.
  5. 'datatables' => true se vuoi abilitare le datatables, personalmente le adoro.
  6. 'tests' => false è un generator e non farò modifiche particolari sui file generati, quindi non ho davvero bisogno dei test (sta a te decidere).

Ultimo ma non meno importante, dobbiamo pubblicare i file di default di infyom per la generazione con php artisan infyom:publish e con php artisan infyom.publish:layout (quest'ultimo comando genererà le views anche per l'autenticazione, se le hai già, chiederà se sovrascriverle). Se vuoi usare le datatables (con server-side rendering), devi anche pubblicare la roba delle datatables eseguendo php artisan vendor:publish --tag='datatables-button'.

Ora siamo pronti!

✏️ Il nostro primo CRUD️

Photo by Galymzhan Abdugalimov on Unsplash

InfyOm è pronto e ora possiamo generare il nostro CRUD via artisan, come? Vediamo quali comandi possiamo eseguire lanciando php artisan:

infyom
  infyom:api                  Create a full CRUD API for given model
  infyom:api_scaffold         Create a full CRUD API and Scaffold for given model
  infyom:migration            Create migration command
  infyom:model                Create model command
  infyom:publish              Publishes & init api routes, base controller, base test cases traits.
  infyom:repository           Create repository command
  infyom:rollback             Rollback a full CRUD API and Scaffold for given model
  infyom:scaffold             Create a full CRUD views for given model
 infyom.api
  infyom.api:controller       Create an api controller command
  infyom.api:requests         Create an api request command
  infyom.api:tests            Create tests command
 infyom.publish
  infyom.publish:layout       Publishes auth files
  infyom.publish:templates    Publishes api generator templates.
  infyom.publish:user         Publishes Users CRUD file
 infyom.scaffold
  infyom.scaffold:controller  Create controller command
  infyom.scaffold:requests    Create a full CRUD views for given model
  infyom.scaffold:views       Create views file command

Abbiamo tanti comandi che possiamo lanciare, e ogni comando ha tante opzioni. Non mi serve tutto, quindi mi concentrerò sul comando scaffold e approfondiremo le sue opzioni lanciando php artisan infyom:scaffold --help (ometterò le opzioni di default di Laravel come --help o -v|vv|vvv e mi concentrerò solo sulle opzioni del generator)

Description:
  Create a full CRUD views for given model
Usage:
  infyom:scaffold [options] [--] <model>
Arguments:
  model                                      Singular Model name
Options:
      --fieldsFile=FIELDSFILE                Fields input as json file
      --jsonFromGUI=JSONFROMGUI              Direct Json string while using GUI interface
      --plural=PLURAL                        Plural Model name
      --tableName=TABLENAME                  Table Name
      --fromTable                            Generate from existing table
      --ignoreFields=IGNOREFIELDS            Ignore fields while generating from table
      --save                                 Save model schema to file
      --primary=PRIMARY                      Custom primary key
      --prefix=PREFIX                        Prefix for all files
      --paginate=PAGINATE                    Pagination for index.blade.php
      --skip=SKIP                            Skip Specific Items to Generate (migration,model,controllers,api_controller,scaffold_controller,repository,requests,api_requests,scaffold_requests,routes,api_routes,scaffold_routes,views,tests,menu,dump-autoload)
      --datatables=DATATABLES                Override datatables settings
      --views=VIEWS                          Specify only the views you want generated: index,create,edit,show
      --relations                            Specify if you want to pass relationships for fields
      --softDelete                           Soft Delete Option
      --forceMigrate                         Specify if you want to run migration or not
      --factory                              To generate factory
      --seeder                               To generate seeder
      --localized                            Localize files.
      --repositoryPattern=REPOSITORYPATTERN  Repository Pattern
      --connection=CONNECTION                Specify connection name

Come puoi vedere, ci sono molte opzioni che puoi regolare e sfruttare per ottenere un CRUD il più velocemente possibile.

Ora devi concentrarti sul tuo database, il nome del mio modello è ProcessingSession (nome tabella: processing_sessions) che ha una relazione one-to-many con ProcessingFile (nome tabella: processing_files). Il comando che ho usato per impostare il primo CRUD è:

php artisan infyom:scaffold --fromTable --tableName=processing_sessions --factory --seeder --skip=model ProcessingSession

Dai un'occhiata a ogni opzione:

  • --fromTable --tableName=processing_sessionsqueste opzioni servono per ottenere i dati del modello dal database. Usando dbal, questo recupererà la struttura della tabella dal database e userà ogni dettaglio della struttura per la generazione.
  • --factory genererà una factory per il modello.
  • --seeder genererà un seeder per il modello.
  • --skip=model questo serve se hai già la tua implementazione del modello, se non hai nessun modello nel tuo progetto, questo genererà un file Model per la tua tabella.

L'output sarà qualcosa del genere:

Factory created:
ProcessingSessionFactory.php
Seeder created:
ProcessingSessionsTableSeeder.php
Create Request created:
CreateProcessingSessionRequest.php
Update Request created:
UpdateProcessingSessionRequest.php
DataTable created:
ProcessingSessionDataTable.php
Controller created:
ProcessingSessionController.php
Generating Views...
datatables_actions.blade.php created
table.blade.php created
index.blade.php created
field.blade.php created
create.blade.php created
edit.blade.php created
show_fields.blade.php created
show.blade.php created
Views created.
processingSessions routes added.
processingSessions menu added.
Schema File saved:
ProcessingSession.json
Generating autoload files

Cosa è successo dopo questo comando? Guarda le modifiche ai file:

New:
app/Http/Controllers/Admin/ProcessingSessionController.php
app/Http/Requests/Admin/CreateProcessingSessionRequest.php
app/Http/Requests/Admin/UpdateProcessingSessionRequest.php
database/factories/ProcessingSessionFactory.php
database/seeders/ProcessingSessionTableSeeder.php
resources/views/admin/processing_sessions/*.blade.php
Changed:
routes/web.php

InfyOm si limita a pubblicare la roba, non aggiunge il controllo dell'utente, quindi dobbiamo costruire un Middleware php artisan make:middleware AdminMiddleware e aggiungere la logica che preferisci.

Ora apri routes/web.php, sistema il Controller generato (se non funziona) e aggiungi il middleware:

use App\Http\Controllers\Admin\ProcessingSessionController;
Route::group(
    [
        'prefix' => 'admin', 
        'as' => 'admin.',
        'middleware' => \App\Http\Middleware\AdminMiddleware::class
    ], 
    function () {
        Route::resource('processingSessions', ProcessingSessionController::class);
    }
);

Ci servono ancora due ritocchi, apri il Controller, le Requests e la DataTable e correggi gli import del modello da App\Models\Admin\Model a App\Models\Model o a qualunque sia il namespace del tuo modello. L'altro è aggiungere le regole di validazione nel tuo modello come proprietà statica. Se guardi le tue classi request puoi vedere che nei metodi rules() InfyOm usa la proprietà statica Model::$rules che devi aggiungere al tuo modello.

E siamo pronti, se l'autenticazione funziona, puoi aprire admin/processingSessions ed ecco il CRUD!

CRUD di base costruito con InfyOm, pronto per la personalizzazione

Ogni altro crud sarà più o meno lo stesso. Ogni volta che generi un CRUD avrai i seguenti file:

┌── create.blade.php
├── datatables_actions.blade.php
├── edit.blade.php
├── fields.blade.php
├── index.blade.php
├── show.blade.php
├── show_fields.blade.php
└── table.blade.php

Se vuoi modificare un qualsiasi passo del processo CRUD, dovrai editare il file relativo (se vuoi mostrare le relazioni puoi modificare show.blade.php inserendo i loro modelli iniettandoli dal controller, se usi le relazioni di default di Eloquent puoi farlo facilmente). Attenzione: il file fields.blade.php è condiviso tra i passi Create e Update, usa la facade Form che inietterà automaticamente il modello. Nel passo Create però il modello non è definito, quindi se modifichi il file fai attenzione a non combinare guai usando l'istanza del modello senza che sia impostata e inizializzata, usando un semplice isset($modelName).

🧱 Costruire una dashboard

Il tuo template adminlte è già configurato, devi solo costruire una view per sfruttarlo. Parti con una view in views/admin/index.php che estende views/layouts/app.blade.php e sovrascrive la sezione content. Dopodiché, costruisci un Controller per gestirla php artisan make:controller Admin\DashboardController con una funzione index che renderizza la view precedente, da collegare a una route sotto il gruppo che abbiamo creato prima.

use App\Http\Controllers\Admin\DashboardController;
Route::group(
    [
        'prefix' => 'admin', 
        'as' => 'admin.',
        'middleware' => \App\Http\Middleware\AdminMiddleware::class
    ], 
    function () {
        Route::get('/', [DashboardController::class, 'index'])->name('index');
        // ... your other CRUDs
    }
);

Dovresti vedere una dashboard vuota:

Costruire la tua dashboard

Vogliamo modificare un paio di cose, apri views/layouts/app.blade.php, sostituisci il "logo InfyOm" con il tuo e con l'URL base dell'admin

<a href="{!! route('admin.index') !!}" class="logo">
    <img src="{!! asset('/img/your_logo.png') !!}" alt="Your Project Dashboard" />
</a>

Scorri fino al footer e modifica la sezione "Copyright"

<footer class="main-footer" style="max-height: 100px;text-align: center">
    <strong>Copyright © 2020 <a href="{!! url('/') !!}">Project</a>.</strong> All rights reserved.
</footer>

Tutto ciò che devi fare ora è comporre la tua dashboard usando i componenti AdminLTE dalla documentazione ufficiale, Laravel e i Blade Components.

🧠Vuoi di più?

Dai un'occhiata alle dipendenze di AdminLTE e importa i plugin nel tuo views/layouts/app.blade.php. Vuoi essere ancora più veloce? Puoi dare un'occhiata ad altri package di supporto come questo helper per Chart.js. Tutto ciò che devi fare è sfruttare la potenza di Laravel in combinazione con questo generator!

E questo è tutto! ✌🏻