Inicio
NexoPOS

Capturar la acción de Crud con JavaScript

Al ampliar un CRUD con acciones personalizadas, la lógica no siempre pertenece al backend; a veces es mejor gestionarla en el frontend, especialmente para las interacciones de la interfaz de usuario.

Por ejemplo, imagina agregar una acción de “Transferir stock” para mover unidades específicas de un producto a un almacén. En lugar de procesarlo directamente, puedes activar una ventana emergente cuando se haga clic en la acción, lo que te permite cargar y mostrar un componente personalizado de Vue para gestionar la transferencia.

Inyectar el pie de página en una instancia CRUD

Ahora, necesitamos inyectar condicionalmente un pie de página personalizado en una instancia de Crud que queremos extender. Esto significa que, cuando solo se esté utilizando una instancia de ProductCrud, por ejemplo. Para ello, primero necesitamos registrar 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;
        });
    }
}

Aquí, hemos insertado una vista en el pie de página de la instancia de CRUD que procesará «productos».

Tenga en cuenta que “ns-products” aquí se refiere a un identificador (antes namespace) del componente CRUD ProductCrud (disponible en App\Crud\ProductCrud). Esto significa que, para inyectar un Vue en un componente CRUD específico, primero necesitamos tener el identificador.

Registrar una acción de fila personalizada

Ahora, necesitamos registrar una acción personalizada de fila con el identificador "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;
        });
    }
}

Capturando la acción desde JavaScript

Ahora necesitamos capturar esa acción, ya que no hemos definido ningún tipo conocido específico.

<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>

Primero, comprobamos si el evento es «ns-table-row-action»; luego comprobamos si el espacio de nombres de la acción es «my-product-transfer». Entonces podemos ejecutar nuestro componente. A continuación, necesitaremos usar un objeto «Popup» para crear un pop-up para nuestro componente específico. Supondremos que has registrado correctamente tu componente de Vue y que te gustaría abrirlo cuando se haga clic en una acción. Usaremos el ejemplo anterior aquí.

<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>

A partir de ahora, deberíamos poder ver que aparece una ventana emergente.