Es común las acciones de crear, editar y eliminar registros con el objetivo de facilitar estas acciones se cuenta la la opción de usar el siguiente trait en los componentes de livewire.
Para hacer uso del trait AccionesCrud debemos especificar en el componente de livewire.
use Livewire\Component;
use DevCucei\RocketmanComponents\Traits\Views\WithActionsCrud;
class Ejemplo extends Component
{
use WithActionsCrud;
}
Es necesario declarar las siguientes variable publicas en el componente de livewire para su uso posterior.
/**
* Variables para uso de crud
* @var
*/
public $formularioAttributes;
public $mode,$formulario;
Spatie permission nos permite asociar a nuestros usuarios roles y permisos. Para permitir realizar acciones de crud a los usuarios, se requiere especificar en el componente de livewire como un permiso que se aplicara a todas las acciones,
/**
* Indica permiso para acciones de crud
*/
public $permission = 'administrar.roles';
si es necesario mas de un permiso
/**
* Indica permisos para acciones de crud
*/
public $permission = 'administrar.roles|administrar.permisos';
o pemisos especificos para cada acción.
/**
* Indica permisos para acciones de crud
*/
public $permissionCreate = 'administrar.roles';
public $permissionDelete = 'administrar.roles';
public $permissionUpdate = 'administrar.roles';
Para usar los permisos crea un nuevo metodo en el modelo User.php que valide si el usuario cuenta con el permiso asignado atraves de un rol
public function getPermissionSession($permission){
$roles = $this->roles;
foreach($roles as $role){
if($role->hasPermissionTo($permission)){
return true;
}
}
return false;
}
{info} El uso del Trait no interviene con la estructura estándar de las validaciones en Livewire
protected $rules = [ 'name' => 'required|min:6', 'email' => 'required|email', ];
En ocasiones las funciones del Trait no serán suficientes por lo que podremos realizar la Sobreescritura nombrando en el componente de Livewire una función con el mismo nombre.
Si es neceaario agregar lineas de código para el uso funciones del trait podrás renombrar la función y llamarla de nuevo en el componente de Livewire.
/**
* Renombra función de trait para utilizar dos funciones
*/
use AccionesCrud{
save as traitSave;
}
public function save()
{
$this->traitSave(); //función save de Trait acciones crud
}
Los modales y notificaciones utilizados para los formularios son componentes de blade que deberan de ser incluidos en la vista del componente de livewire.
<div>
<!-- BEGIN: Funcionalidades CRUD-->
<x-acciones-crud.modal-crud/>
<x-acciones-crud.modal-delete/>
<!-- END: Funcionalidades CRUD -->
</div>
{info}Para dar estilos a los modales podra agrarlo como un attributo
<div>
<x-acciones-crud.modal-crud staticBackdrop="true"/>
</div>
Para hacer uso de las notificaciones agrege al achivo layout del proyecto
<body>
@include('partials.notifications')
<!---------- toastify-js ----------->
@include('snippets.toastify-js')
</body>
Si incluye mas de un componente de crud en una vista es necesario declarar una variable publica con el id del modal para que Livewire pueda acceder a ellos
/**
* @var int Indica id de modal crud y modal delete
*/
public $modalCrudName = 'modal-crud-giros';
public $modalDeleteName = 'modal-delete-giros';
Para activar el modal de crear podrás hace uso del componente <x-button-primary> en cualquier lugar de la vista del componete de livewire.
<x-button-primary
wire:click="create()"
icono="fa-solid fa-plus"
titulo="Agregar"
/>
{info} En caso de que se requiera especificar de otra manera en la vista recuerda agregar
wire:click="create()"para seguir haciendo uso de las funcionalidades del trait.
Para activar el modal de editar y eliminar podrás hace uso del componente <x-acciones-crud> o <x-acciones-crud-dropdown> en cualquier lugar de la vista del componete de livewire.
<x-acciones-crud id="{{$id}}"/>
<x-acciones-crud-dropdown id="{{$id}}"/>
Ejemplo utilizando trait de llistado
/**
* Indica las columnas del listado
* @var array
*/
public function getColumns(): array
{
return [
'Acciones' => [
'view' => [
'name'=>'Components.acciones-crud',
'attributes' => [
'id' => 'id',
],
],
],
];
}
{info} En caso de que se requiera especificar de otra manera en la vista recuerda agregar
wire:click="edit($id)"ywire:click="delete($id)"para seguir haciendo uso de las funcionalidades del trait.
Para crear el formulario los campos deberán de ser especificados en el componente de livewire a manera de arreglo dentro de la función publica getFormularioAttributes().
/**
* Indica los campos del formulario
* @var array
*/
public function getFormularioAttributes(): array
{
return [
];
}
Todos los campos cuentan con las misma estructura:
name = Nombre del input.
required = Indica si el input es requerido (true o false).
label = Texto que se mostrara en la etiqueta.
type = Tipo de input (text, textarea, select, date, datetime-local, switch, vertical-checkbox, horizontal-checkbox, vertical-radio, horizontal-radio)
middleware = Indica el permiso o rol para mostrar el campo en el formulario Opcional.
style = Indica el numero de columnas que tomara el input por defecto tomara todas las columnas Opcional.
placeholder = Indica el texto provisional para los inputs de tipo text y text-area Opcional.
value = Indica el valor provisional para los inputs de tipo date y datetime-local Opcional.
a excepción de los inputs con opciones multiples a los cuales se les debera especificar
options = Indica las opciones disponibles puede ser un arreglo o colección,
optionsValue = Indica el campo del arreglo o colección que sera utilizado como valor del input Opcional por default id
labelOptions = Indica el campo del arreglo o colección que sera utilizado como valor del label Opcional por default name
styleOptions = Indica el numero de columnas que tomara cada opción Opcional por default mt-2 mx-2 col-span-4 lg:col-span-4
'text' => [
'name' => 'formulario.name',
'label'=>'Permiso',
'type'=>'text',
'placeholder'=>'permiso',
'middleware' => 'Empresa',
'style' => 'col-span-6 lg:col-span-6 p-2',
],
'textarea' => [
'name' => 'formulario.name',
'label'=>'Permiso',
'type'=>'textarea',
'placeholder'=>'permiso',
'middleware' => 'Empresa',
'style' => 'col-span-6 lg:col-span-6 p-2',
],
'select' => [
'name' => 'roles',
'required' => false,
'label'=>'Roles',
'type'=>'select',
'options' => Role::all()->pluck('name','id'),
'selected-options' => Role::all()->pluck('name','id'),
'middleware' => 'Desarrollador',
'style' => 'col-span-6 lg:col-span-6 p-2',
],
'date' => [
'name' => 'formulario.name',
'label'=>'Permiso',
'type'=>'date',
'value'=>'10/02/2022',
'middleware' => 'Desarrollador',
'style' => 'col-span-6 lg:col-span-6 p-2'
],
'datetime-local' => [
'name' => 'formulario.name',
'label'=>'Permiso',
'type'=>'datetime-local',
'value'=>'10/02/2022',
'middleware' => 'Desarrollador',
'style' => 'col-span-6 lg:col-span-6 p-2'
],
'switch' => [
'name' => 'formulario.name',
'label'=>'switch',
'type'=>'switch',
'middleware' => 'Desarrollador',
'style' => 'col-span-6 lg:col-span-6 p-2'
],
'checkbox' => [
'name' => 'formulario.habilitado',
'label'=>'Habilitado',
'type'=>'checkbox',
'middleware' => 'Desarrollador',
'style' => 'col-span-6 lg:col-span-6 p-2'
],
'roles-check-vertical' => [
'name' => 'roles',
'label'=>'Roles',
'type'=>'vertical-checkbox',
'optionsValue' => 'name', //opcional por default name y id
'optionsLabel' => 'id',
'options' => Role::all(),
'middleware' => 'Desarrollador',
'style' => 'col-span-6 lg:col-span-6 p-2'
],
'roles-check-horizontal' => [
'name' => 'roles',
'label'=>'Roles',
'type'=>'horizontal-checkbox',
'optionsValue' => 'name', //opcional por default name y id
'optionsLabel' => 'id',
'options' => Role::all(),
'styleOptions' => 'mt-2 mx-2 col-span-2 lg:col-span-2',
'middleware' => 'Desarrollador',
'style' => 'col-span-6 lg:col-span-6 p-2'
],
'roles-radio-vertical' => [
'name' => 'roles',
'label'=>'Roles',
'type'=>'vertical-radio',
'optionsValue' => 'name', //opcional por default name y id
'optionsLabel' => 'id',
'options' => Role::all(),
'middleware' => 'Desarrollador',
'style' => 'col-span-6 lg:col-span-6 p-2'
],
'roles-radio-horizontal' => [
'name' => 'roleds',
'label'=>'Roles',
'type'=>'horizontal-radio',
'optionsValue' => 'name', //opcional por default name y id
'optionsLabel' => 'id',
'options' => Role::all(),
'styleOptions' => 'mt-2 mx-2 col-span-2 lg:col-span-2',
'middleware' => 'Desarrollador',
'style' => 'col-span-6 lg:col-span-6 p-2'
],
/**
* Carga los atributos del formulario.
*
* @return
*/
public function create()
{
$this->resetInput();
$this->mode = 'Crear';
$this->formularioAttributes = $this->getFormularioAttributes();
$this->dispatchBrowserEvent('open-modal', ['modal' => 'modal-crud']);
}
public function save()
{
$this->hasPermission($this->permissionCreate ?? $this->permission);
$this->validate();
$instance = $this->model::Create($this->formulario);
$instance->save();
$this->resetInput();
$this->dispatchBrowserEvent('close-modal', ['modal' => 'modal-crud']);
$this->dispatchBrowserEvent('success-notification-toggle');
}
/**
* Carga los atributos del formulario y el registro a editar.
*
* @return
*/
public function edit($id)
{
$this->resetInput();
$this->mode = 'Editar';
$this->formularioAttributes = $this->getFormularioAttributes();
$this->formulario = $this->model::findOrFail($id);
$this->dispatchBrowserEvent('open-modal', ['modal' => 'modal-crud']);
}
public function update()
{
$this->hasPermission($this->permissionUpdate ?? $this->permission);
$this->validate();
$this->formulario->save();
$this->resetInput();
$this->dispatchBrowserEvent('close-modal', ['modal' => 'modal-crud']);
$this->dispatchBrowserEvent('success-notification-toggle');
}
public function delete($id)
{
$this->hasPermission($this->permissionDelete ?? $this->permission);
$this->resetInput();
$this->mode = 'Eliminar';
$this->formulario = $this->model::findOrFail($id);
$this->dispatchBrowserEvent('open-modal', ['modal' => 'modal-delete']);
}
public function destroy()
{
$this->formulario->delete();
$this->resetInput();
$this->dispatchBrowserEvent('close-modal', ['modal' => 'modal-delete']);
$this->dispatchBrowserEvent('success-delete-notification-toggle');
}
public function hasPermission($permission)
{
if(!$this->user->can($permission)) abort(403);
}