Home
NexoPOS

Intercetta l’azione di CRUD con JavaScript

Quando si estende un CRUD con azioni personalizzate, la logica non sempre deve essere gestita sul backend: a volte è meglio gestirla sul frontend, soprattutto per le interazioni dell’interfaccia utente.

Ad esempio, immagina di aggiungere un’azione “Trasferisci stock” per spostare unità specifiche di un prodotto in un magazzino. Invece di elaborare questa operazione direttamente, puoi attivare una finestra pop-up quando l’azione viene cliccata, consentendoti di caricare e visualizzare un componente Vue personalizzato per gestire il trasferimento.

Inserisci un piè di pagina su un’istanza CRUD

Ora, dobbiamo iniettare in modo condizionale un footer personalizzato su un’istanza di Crud che vogliamo estendere. Questo significa che, quando viene utilizzata solo un’istanza di ProductCrud, ad esempio. Per fare ciò, dobbiamo prima registrare un filtro.


<?php
namespace Modules\MyModuleNamespace\Providers;

use Illuminate\Support\ServiceProvider;
use App\Classes\Hook;
use App\Classes\Output;

class MyModuleProvider extends ServiceProvider
{
    public function register()
    {        
        Hook::addFilter( 'ns-crud-footer', function( Output $output, $namespace ) {
            if ( $namespace === 'ns-products' ) {
                $output->addView( 'MyModuleNamespace::footer' );
            }
          
            return $output;
        });
    }
}

Qui abbiamo inserito una vista nel footer dell’istanza CRUD che elaborerà “prodotti”.

Nota che “ns-products” qui si riferisce a un identificatore (in precedenza namespace) del componente CRUD ProductCrud (disponibile su App\Crud\ProductCrud). Ciò significa che, per iniettare una Vue in un determinato componente CRUD, dobbiamo prima avere l’identificatore.

Registrare un’azione di riga personalizzata

Ora dobbiamo registrare un’azione personalizzata di riga con l’identificatore "my-product-transfer".

<?php
namespace Modules\MyModuleNamespace\Providers;

use Illuminate\Support\ServiceProvider;
use App\Classes\Hook;
use App\Services\CrudEntry;

class MyModuleProvider extends ServiceProvider
{
    public function register()
    {
        $namespace  = 'ns.products';
        
        Hook::addAction( Product::method( 'setActions' ), function( CrudEntry $row ) {
            $row->action( 
                label: __( 'Transfer Product' ),
                identifier: 'my-product-transfer'
            );

            return $row;
        });
    }
}

Catturare l’azione da JavaScript

Ora dobbiamo intercettare quell’azione poiché non abbiamo definito alcun tipo specifico noto.

<script>
nsEvent.subject().subscribe( event => {
    if ( event.identifier === 'ns-table-row-action' && event.value.action.identifier === 'my-product-transfer' ) {
        // Display you action here. "event.value.row" contains the actual clicked row. 
    }
});
</script>

Prima, verifichiamo se l’evento è “ns-table-row-action”, quindi controlliamo se lo spazio dei nomi dell’azione è “my-product-transfer”. A questo punto possiamo eseguire il nostro componente. Successivamente, dovremo usare un oggetto “Popup” per creare un pop-up per il nostro componente specifico. Assumeremo che tu abbia registrato correttamente il tuo componente Vue e che desideri aprirlo quando viene cliccata un’azione. Useremo l’esempio precedente qui.

<script>
nsEvent.subject().subscribe( event => {
    if ( event.identifier === 'ns-table-row-action' && event.value.action.identifier === 'my-product-transfer' ) {
        const row   = event.value.row;
        Popup.show( MyModulePopup, { row });
    }
});
</script>

Da ora in poi, dovremmo essere in grado di vedere comparire una finestra popup.