Prepare modules
This commit is contained in:
@ -1,115 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Koneko\VuexyAdmin\Livewire\Users;
|
||||
|
||||
use Spatie\Permission\Models\Role;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Koneko\VuexyAdmin\Models\User;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class UserIndex extends Component
|
||||
{
|
||||
public $statuses;
|
||||
public $status_options;
|
||||
|
||||
public $rows_roles = [];
|
||||
public $roles_options = [];
|
||||
public $roles_html_select;
|
||||
|
||||
public $total, $enabled, $disabled;
|
||||
|
||||
public $indexAlert;
|
||||
|
||||
public $userId, $name, $email, $password, $roles, $status, $photo, $src_photo;
|
||||
public $modalTitle;
|
||||
public $btnSubmitTxt;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->modalTitle = 'Crear usuario nuevo';
|
||||
$this->btnSubmitTxt = 'Crear usuario';
|
||||
|
||||
$this->statuses = [
|
||||
User::STATUS_ENABLED => ['title' => 'Activo', 'class' => 'badge bg-label-' . User::$statusListClass[User::STATUS_ENABLED]],
|
||||
User::STATUS_DISABLED => ['title' => 'Deshabilitado', 'class' => 'badge bg-label-' . User::$statusListClass[User::STATUS_DISABLED]],
|
||||
User::STATUS_REMOVED => ['title' => 'Eliminado', 'class' => 'badge bg-label-' . User::$statusListClass[User::STATUS_REMOVED]],
|
||||
];
|
||||
|
||||
$roles = Role::whereNotIn('name', ['Patient', 'Doctor'])->get();
|
||||
|
||||
$this->roles_html_select = "<select id=\"UserRole\" class=\"form-select text-capitalize\"><option value=\"\"> Selecciona un rol </option>";
|
||||
|
||||
foreach ($roles as $role) {
|
||||
$this->rows_roles[$role->name] = "<span class=\"badge bg-label-" . $role->style . " mx-1\">" . $role->name . "</span>";
|
||||
|
||||
if (Auth::user()->hasRole('SuperAdmin') || $role->name != 'SuperAdmin') {
|
||||
$this->roles_html_select .= "<option value=\"" . $role->name . "\" class=\"text-capitalize\">" . $role->name . "</option>";
|
||||
$this->roles_options[$role->name] = $role->name;
|
||||
}
|
||||
}
|
||||
|
||||
$this->roles_html_select .= "</select>";
|
||||
|
||||
$this->status_options = [
|
||||
User::STATUS_ENABLED => User::$statusList[User::STATUS_ENABLED],
|
||||
User::STATUS_DISABLED => User::$statusList[User::STATUS_DISABLED],
|
||||
];
|
||||
}
|
||||
|
||||
public function countUsers()
|
||||
{
|
||||
$this->total = User::count();
|
||||
$this->enabled = User::where('status', User::STATUS_ENABLED)->count();
|
||||
$this->disabled = User::where('status', User::STATUS_DISABLED)->count();
|
||||
}
|
||||
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
$this->indexAlert = '';
|
||||
$this->modalTitle = 'Editar usuario: ' . $id;
|
||||
$this->btnSubmitTxt = 'Guardar cambios';
|
||||
|
||||
$this->userId = $user->id;
|
||||
$this->name = $user->name;
|
||||
$this->email = $user->email;
|
||||
$this->password = '';
|
||||
$this->roles = $user->roles->pluck('name')->toArray();
|
||||
$this->src_photo = $user->profile_photo_url;
|
||||
$this->status = $user->status;
|
||||
|
||||
$this->dispatch('openModal');
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$user = User::find($id);
|
||||
|
||||
if ($user) {
|
||||
// Eliminar la imagen de perfil si existe
|
||||
if ($user->profile_photo_path)
|
||||
Storage::disk('public')->delete($user->profile_photo_path);
|
||||
|
||||
// Eliminar el usuario
|
||||
$user->delete();
|
||||
|
||||
$this->indexAlert = '<div class="alert alert-warning alert-dismissible" role="alert">Se eliminó correctamente el usuario.<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div>';
|
||||
|
||||
$this->dispatch('refreshUserCount');
|
||||
$this->dispatch('afterDelete');
|
||||
} else {
|
||||
$this->indexAlert = '<div class="alert alert-danger alert-dismissible" role="alert">Usuario no encontrado.<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div>';
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('vuexy-admin::livewire.users.index', [
|
||||
'users' => User::paginate(10),
|
||||
]);
|
||||
}
|
||||
}
|
@ -2,14 +2,8 @@
|
||||
|
||||
namespace Koneko\VuexyAdmin\Livewire\Users;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Koneko\VuexyAdmin\Livewire\Form\AbstractFormOffCanvasComponent;
|
||||
use Koneko\VuexyAdmin\Models\User;
|
||||
use Koneko\VuexyContacts\Services\{ContactCatalogService,ConstanciaFiscalService,FacturaXmlService};
|
||||
use Koneko\VuexyStoreManager\Services\StoreCatalogService;
|
||||
use Livewire\WithFileUploads;
|
||||
|
||||
/**
|
||||
* Class UserOffCanvasForm
|
||||
@ -22,40 +16,15 @@ use Livewire\WithFileUploads;
|
||||
*/
|
||||
class UserOffCanvasForm extends AbstractFormOffCanvasComponent
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public $doc_file;
|
||||
public $dropzoneVisible = true;
|
||||
|
||||
|
||||
/**
|
||||
* Propiedades del formulario relacionadas con el usuario.
|
||||
*/
|
||||
public $code,
|
||||
$parent_id,
|
||||
$name,
|
||||
$last_name,
|
||||
$email,
|
||||
$company,
|
||||
$rfc,
|
||||
$nombre_fiscal,
|
||||
$tipo_persona,
|
||||
$c_regimen_fiscal,
|
||||
$domicilio_fiscal,
|
||||
$is_partner,
|
||||
$is_employee,
|
||||
$is_prospect,
|
||||
$is_customer,
|
||||
$is_provider,
|
||||
$status;
|
||||
|
||||
/**
|
||||
* Listas de opciones para selects en el formulario.
|
||||
*/
|
||||
public $store_options = [],
|
||||
$work_center_options = [],
|
||||
$manager_options = [];
|
||||
|
||||
/**
|
||||
* Eventos de escucha de Livewire.
|
||||
*
|
||||
@ -85,28 +54,6 @@ class UserOffCanvasForm extends AbstractFormOffCanvasComponent
|
||||
return User::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define los campos del formulario.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
protected function fields(): array
|
||||
{
|
||||
return (new User())->getFillable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Valores por defecto para el formulario.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function defaults(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Campo que se debe enfocar cuando se abra el formulario.
|
||||
*
|
||||
@ -117,6 +64,8 @@ class UserOffCanvasForm extends AbstractFormOffCanvasComponent
|
||||
return 'name';
|
||||
}
|
||||
|
||||
// ===================== VALIDACIONES =====================
|
||||
|
||||
/**
|
||||
* Define reglas de validación dinámicas basadas en el modo actual.
|
||||
*
|
||||
@ -129,10 +78,8 @@ class UserOffCanvasForm extends AbstractFormOffCanvasComponent
|
||||
case 'create':
|
||||
case 'edit':
|
||||
return [
|
||||
'code' => ['required', 'string', 'max:16', Rule::unique('contact', 'code')->ignore($this->id)],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users,email'],
|
||||
'name' => ['required', 'string', 'max:96'],
|
||||
'notes' => ['nullable', 'string', 'max:1024'],
|
||||
'tel' => ['nullable', 'regex:/^[0-9+\-\s]+$/', 'max:20'],
|
||||
];
|
||||
|
||||
case 'delete':
|
||||
@ -145,8 +92,6 @@ class UserOffCanvasForm extends AbstractFormOffCanvasComponent
|
||||
}
|
||||
}
|
||||
|
||||
// ===================== VALIDACIONES =====================
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
@ -168,121 +113,10 @@ class UserOffCanvasForm extends AbstractFormOffCanvasComponent
|
||||
protected function messages(): array
|
||||
{
|
||||
return [
|
||||
'code.unique' => 'Este código ya está en uso por otro usuario.',
|
||||
'name.required' => 'El nombre del usuario es obligatorio.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Carga el formulario con datos del usuario y actualiza las opciones dinámicas.
|
||||
*
|
||||
* @param int $id
|
||||
*/
|
||||
public function loadFormModel($id): void
|
||||
{
|
||||
parent::loadFormModel($id);
|
||||
|
||||
$this->work_center_options = $this->store_id
|
||||
? DB::table('store_work_centers')
|
||||
->where('store_id', $this->store_id)
|
||||
->pluck('name', 'id')
|
||||
->toArray()
|
||||
: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Carga el formulario para eliminar un usuario, actualizando las opciones necesarias.
|
||||
*
|
||||
* @param int $id
|
||||
*/
|
||||
public function loadFormModelForDeletion($id): void
|
||||
{
|
||||
parent::loadFormModelForDeletion($id);
|
||||
|
||||
$this->work_center_options = DB::table('store_work_centers')
|
||||
->where('store_id', $this->store_id)
|
||||
->pluck('name', 'id')
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define las opciones de los selectores desplegables.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function options(): array
|
||||
{
|
||||
$storeCatalogService = app(StoreCatalogService::class);
|
||||
$contactCatalogService = app(ContactCatalogService::class);
|
||||
|
||||
return [
|
||||
'store_options' => $storeCatalogService->searchCatalog('stores', '', ['limit' => -1]),
|
||||
'manager_options' => $contactCatalogService->searchCatalog('users', '', ['limit' => -1]),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesa el documento recibido (CFDI XML o Constancia PDF).
|
||||
*/
|
||||
public function processDocument()
|
||||
{
|
||||
// Verificamos si el archivo es válido
|
||||
if (!$this->doc_file instanceof UploadedFile) {
|
||||
return $this->addError('doc_file', 'No se pudo recibir el archivo.');
|
||||
}
|
||||
|
||||
try {
|
||||
// Validar tipo de archivo
|
||||
$this->validate([
|
||||
'doc_file' => 'required|mimes:pdf,xml|max:2048'
|
||||
]);
|
||||
|
||||
|
||||
// **Detectar el tipo de documento**
|
||||
$extension = strtolower($this->doc_file->getClientOriginalExtension());
|
||||
|
||||
// **Procesar según el tipo de archivo**
|
||||
switch ($extension) {
|
||||
case 'xml':
|
||||
$service = new FacturaXmlService();
|
||||
$data = $service->processUploadedFile($this->doc_file);
|
||||
break;
|
||||
|
||||
case 'pdf':
|
||||
$service = new ConstanciaFiscalService();
|
||||
$data = $service->extractData($this->doc_file);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Formato de archivo no soportado.");
|
||||
}
|
||||
|
||||
dd($data);
|
||||
|
||||
// **Asignar los valores extraídos al formulario**
|
||||
$this->rfc = $data['rfc'] ?? null;
|
||||
$this->name = $data['name'] ?? null;
|
||||
$this->email = $data['email'] ?? null;
|
||||
$this->tel = $data['telefono'] ?? null;
|
||||
//$this->direccion = $data['domicilio_fiscal'] ?? null;
|
||||
|
||||
// Ocultar el Dropzone después de procesar
|
||||
$this->dropzoneVisible = false;
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
$this->handleValidationException($e);
|
||||
|
||||
} catch (QueryException $e) {
|
||||
$this->handleDatabaseException($e);
|
||||
|
||||
} catch (ModelNotFoundException $e) {
|
||||
$this->handleException('danger', 'Registro no encontrado.');
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->handleException('danger', 'Error al procesar el archivo: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruta de la vista asociada con este formulario.
|
||||
*
|
||||
|
@ -40,7 +40,6 @@ class UserShow extends Component
|
||||
$is_prospect,
|
||||
$is_customer,
|
||||
$is_provider,
|
||||
$is_user,
|
||||
$status;
|
||||
public $deleteUserImage;
|
||||
public $cuentaUsuarioAlert,
|
||||
@ -55,7 +54,6 @@ class UserShow extends Component
|
||||
'is_prospect' => 'nullable|boolean',
|
||||
'is_customer' => 'nullable|boolean',
|
||||
'is_provider' => 'nullable|boolean',
|
||||
'is_user' => 'nullable|boolean',
|
||||
'pricelist_id' => 'nullable|integer',
|
||||
'enable_credit' => 'nullable|boolean',
|
||||
'credit_days' => 'nullable|integer',
|
||||
@ -102,7 +100,6 @@ class UserShow extends Component
|
||||
$this->is_prospect = $this->user->is_prospect? true : false;
|
||||
$this->is_customer = $this->user->is_customer? true : false;
|
||||
$this->is_provider = $this->user->is_provider? true : false;
|
||||
$this->is_user = $this->user->is_user? true : false;
|
||||
$this->pricelist_id = $this->user->pricelist_id;
|
||||
$this->enable_credit = $this->user->enable_credit? true : false;
|
||||
$this->credit_days = $this->user->credit_days;
|
||||
@ -140,7 +137,6 @@ class UserShow extends Component
|
||||
$validatedData['is_prospect'] = $validatedData['is_prospect'] ? 1 : 0;
|
||||
$validatedData['is_customer'] = $validatedData['is_customer'] ? 1 : 0;
|
||||
$validatedData['is_provider'] = $validatedData['is_provider'] ? 1 : 0;
|
||||
$validatedData['is_user'] = $validatedData['is_user'] ? 1 : 0;
|
||||
$validatedData['pricelist_id'] = $validatedData['pricelist_id'] ?: null;
|
||||
$validatedData['enable_credit'] = $validatedData['enable_credit'] ? 1 : 0;
|
||||
$validatedData['credit_days'] = $validatedData['credit_days'] ?: null;
|
||||
@ -150,7 +146,6 @@ class UserShow extends Component
|
||||
$validatedData['cargo'] = null;
|
||||
$validatedData['is_prospect'] = null;
|
||||
$validatedData['is_provider'] = null;
|
||||
$validatedData['is_user'] = null;
|
||||
$validatedData['enable_credit'] = null;
|
||||
$validatedData['credit_days'] = null;
|
||||
$validatedData['credit_limit'] = null;
|
||||
|
@ -6,11 +6,11 @@ use Koneko\VuexyAdmin\Models\User;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class UserCount extends Component
|
||||
class UsersCount extends Component
|
||||
{
|
||||
public $total, $enabled, $disabled;
|
||||
|
||||
protected $listeners = ['refreshUserCount' => 'updateCounts'];
|
||||
protected $listeners = ['refreshUsersCount' => 'updateCounts'];
|
||||
|
||||
public function mount()
|
||||
{
|
@ -2,17 +2,11 @@
|
||||
|
||||
namespace Koneko\VuexyAdmin\Livewire\Users;
|
||||
|
||||
use Livewire\WithFileUploads;
|
||||
use Koneko\VuexyAdmin\Models\User;
|
||||
use Koneko\VuexyAdmin\Livewire\Table\AbstractIndexComponent;
|
||||
|
||||
class UserIndex extends AbstractIndexComponent
|
||||
class UsersIndex extends AbstractIndexComponent
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public $doc_file;
|
||||
public $dropzoneVisible = true;
|
||||
|
||||
/**
|
||||
* Almacena rutas útiles para la funcionalidad de edición o eliminación.
|
||||
*/
|
||||
@ -32,32 +26,14 @@ class UserIndex extends AbstractIndexComponent
|
||||
protected function columns(): array
|
||||
{
|
||||
return [
|
||||
'action' => 'Acciones',
|
||||
'code' => 'Código personal',
|
||||
'full_name' => 'Nombre Completo',
|
||||
'email' => 'Correo Electrónico',
|
||||
'parent_name' => 'Responsable',
|
||||
'parent_email' => 'Correo Responsable',
|
||||
'company' => 'Empresa',
|
||||
'birth_date' => 'Fecha de Nacimiento',
|
||||
'hire_date' => 'Fecha de Contratación',
|
||||
'curp' => 'CURP',
|
||||
'nss' => 'NSS',
|
||||
'job_title' => 'Puesto',
|
||||
'rfc' => 'RFC',
|
||||
'nombre_fiscal' => 'Nombre Fiscal',
|
||||
'profile_photo_path' => 'Foto de Perfil',
|
||||
'is_partner' => 'Socio',
|
||||
'is_employee' => 'Empleado',
|
||||
'is_prospect' => 'Prospecto',
|
||||
'is_customer' => 'Cliente',
|
||||
'is_provider' => 'Proveedor',
|
||||
'is_user' => 'Usuario',
|
||||
'status' => 'Estatus',
|
||||
'creator' => 'Creado Por',
|
||||
'creator_email' => 'Correo Creador',
|
||||
'created_at' => 'Fecha de Creación',
|
||||
'updated_at' => 'Última Modificación',
|
||||
'action' => 'Acciones',
|
||||
'full_name' => 'Nombre completo',
|
||||
'email' => 'Correo electrónico',
|
||||
'email_verified_at' => 'Correo verificado',
|
||||
'created_by' => 'Creado Por',
|
||||
'status' => 'Estatus',
|
||||
'created_at' => 'Fecha Creación',
|
||||
'updated_at' => 'Última Modificación',
|
||||
];
|
||||
}
|
||||
|
||||
@ -86,14 +62,27 @@ class UserIndex extends AbstractIndexComponent
|
||||
'formatter' => 'emailFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'parent_name' => [
|
||||
'formatter' => 'contactParentFormatter',
|
||||
'email_verified_at' => [
|
||||
'visible' => false,
|
||||
],
|
||||
'agent_name' => [
|
||||
'formatter' => 'agentFormatter',
|
||||
'parent_id' => [
|
||||
'formatter' => 'parentProfileFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'agent_id' => [
|
||||
'formatter' => 'agentProfileFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'phone' => [
|
||||
'formatter' => 'telFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'mobile' => [
|
||||
'formatter' => 'telFormatter',
|
||||
],
|
||||
'whatsapp' => [
|
||||
'formatter' => 'whatsappFormatter',
|
||||
],
|
||||
'company' => [
|
||||
'formatter' => 'textNowrapFormatter',
|
||||
],
|
||||
@ -103,10 +92,16 @@ class UserIndex extends AbstractIndexComponent
|
||||
'nss' => [
|
||||
'visible' => false,
|
||||
],
|
||||
'job_title' => [
|
||||
'license_number' => [
|
||||
'visible' => false,
|
||||
],
|
||||
'job_position' => [
|
||||
'formatter' => 'textNowrapFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'pais' => [
|
||||
'visible' => false,
|
||||
],
|
||||
'rfc' => [
|
||||
'visible' => false,
|
||||
],
|
||||
@ -114,6 +109,7 @@ class UserIndex extends AbstractIndexComponent
|
||||
'formatter' => 'textNowrapFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
|
||||
'domicilio_fiscal' => [
|
||||
'visible' => false,
|
||||
],
|
||||
@ -176,14 +172,14 @@ class UserIndex extends AbstractIndexComponent
|
||||
],
|
||||
'align' => 'center',
|
||||
],
|
||||
'is_provider' => [
|
||||
'is_supplier' => [
|
||||
'formatter' => [
|
||||
'name' => 'dynamicBooleanFormatter',
|
||||
'params' => ['tag' => 'checkSI'],
|
||||
],
|
||||
'align' => 'center',
|
||||
],
|
||||
'is_user' => [
|
||||
'is_carrier' => [
|
||||
'formatter' => [
|
||||
'name' => 'dynamicBooleanFormatter',
|
||||
'params' => ['tag' => 'checkSI'],
|
||||
@ -211,69 +207,6 @@ class UserIndex extends AbstractIndexComponent
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesa el documento recibido (CFDI XML o Constancia PDF).
|
||||
*/
|
||||
public function processDocument()
|
||||
{
|
||||
// Verificamos si el archivo es válido
|
||||
if (!$this->doc_file instanceof UploadedFile) {
|
||||
return $this->addError('doc_file', 'No se pudo recibir el archivo.');
|
||||
}
|
||||
|
||||
try {
|
||||
// Validar tipo de archivo
|
||||
$this->validate([
|
||||
'doc_file' => 'required|mimes:pdf,xml|max:2048'
|
||||
]);
|
||||
|
||||
|
||||
// **Detectar el tipo de documento**
|
||||
$extension = strtolower($this->doc_file->getClientOriginalExtension());
|
||||
|
||||
// **Procesar según el tipo de archivo**
|
||||
switch ($extension) {
|
||||
case 'xml':
|
||||
$service = new FacturaXmlService();
|
||||
$data = $service->processUploadedFile($this->doc_file);
|
||||
break;
|
||||
|
||||
case 'pdf':
|
||||
$service = new ConstanciaFiscalService();
|
||||
$data = $service->extractData($this->doc_file);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Formato de archivo no soportado.");
|
||||
}
|
||||
|
||||
dd($data);
|
||||
|
||||
// **Asignar los valores extraídos al formulario**
|
||||
$this->rfc = $data['rfc'] ?? null;
|
||||
$this->name = $data['name'] ?? null;
|
||||
$this->email = $data['email'] ?? null;
|
||||
$this->tel = $data['telefono'] ?? null;
|
||||
//$this->direccion = $data['domicilio_fiscal'] ?? null;
|
||||
|
||||
// Ocultar el Dropzone después de procesar
|
||||
$this->dropzoneVisible = false;
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
$this->handleValidationException($e);
|
||||
|
||||
} catch (QueryException $e) {
|
||||
$this->handleDatabaseException($e);
|
||||
|
||||
} catch (ModelNotFoundException $e) {
|
||||
$this->handleException('danger', 'Registro no encontrado.');
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->handleException('danger', 'Error al procesar el archivo: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Montamos el componente y llamamos al parent::mount() para configurar la tabla.
|
||||
*/
|
Reference in New Issue
Block a user