corregida busqueda de usuarios. también el mail obligatorio y borrar los chat departaments con soft delete

This commit is contained in:
2024-12-09 19:44:44 +01:00
parent d9d3bd69c0
commit 719455567e
6 changed files with 257 additions and 32 deletions

View File

@ -105,6 +105,7 @@ $routes->group('users', ['namespace' => 'App\Controllers\Configuracion'], functi
$routes->get('delete/(:num)', 'Users::delete/$1', ['as' => 'deleteUser']);
$routes->post('allmenuitems', 'Users::allItemsSelect', ['as' => 'select2ItemsOfUsers']);
$routes->post('menuitems', 'Users::menuItems', ['as' => 'menuItemsOfUsers']);
$routes->post('datatable', 'Users::datatable', ['as' => 'datatableOfUsers']);
$routes->get('getMenuComerciales', 'Users::getMenuComerciales', ['as' => 'menuItemsComerciales']);
});
$routes->resource('users', ['namespace' => 'App\Controllers\Configuracion', 'controller' => 'Users', 'except' => 'show,new,create,update']);

View File

@ -7,6 +7,8 @@ use App\Models\Usuarios\GroupModel;
use App\Models\UserModel;
use App\Models\Usuarios\GroupsUsersModel;
use App\Models\Collection;
use CodeIgniter\Shield\Entities\User;
use function PHPUnit\Framework\isNull;
@ -22,7 +24,8 @@ class Users extends \App\Controllers\GoBaseController
use \CodeIgniter\API\ResponseTrait;
protected static $primaryModelName = 'App\Models\UserModel';
protected static $primaryModelName = UserModel::class;
protected $modelName = ClientePlantillaPreciosLineasModel::class;
protected static $singularObjectNameCc = 'user';
protected static $singularObjectName = 'User';
@ -58,10 +61,8 @@ class Users extends \App\Controllers\GoBaseController
public function index()
{
$this->viewData['usingClientSideDataTable'] = true;
$this->viewData['usingServerSideDataTable'] = true;
$this->viewData['pageSubTitle'] = lang('Basic.global.ManageAllRecords', [lang('Users.user')]);
$this->viewData['user_model'] = $this->user_model;
$this->viewData['userList2'] = auth()->getProvider()->findAll();
parent::index();
}
@ -313,8 +314,10 @@ class Users extends \App\Controllers\GoBaseController
return $this->redirect2listView('errorMessage', $message);
endif;
$this->chat_department_user_model->where("user_id", $id)->delete();
$users = auth()->getProvider();
$users->delete($user->id, true);
$users->delete($user->id);
$message = "Usuario eliminado correctamente";
return $this->redirect2listView('successMessage', $message);
@ -373,6 +376,43 @@ class Users extends \App\Controllers\GoBaseController
}
}
public function datatable(){
if($this->request->isAJAX()){
$reqData = $this->request->getPost();
if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
$errstr = 'No data available in response to this specific request.';
$response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
return $response;
}
$start = $reqData['start'] ?? 0;
$length = $reqData['length'] ?? 5;
$searchValues = get_filter_datatables_columns($reqData);
$requestedOrder = $reqData['order'] ?? [];
$resourceData = $this->model->getResource($searchValues);
foreach ($requestedOrder as $order) {
$column = $order['column'] ?? 0;
$dir = $order['dir'] ?? 'asc';
$orderColumn = UserModel::SORTABLE[$column] ?? null;
if ($orderColumn) {
$resourceData->orderBy($orderColumn, $dir);
}
}
$resourceData = $resourceData->limit($length, $start)->get()->getResultObject();
return $this->respond(Collection::datatable(
$resourceData,
$this->model->getResource([])->countAllResults(),
$this->model->getResource($searchValues)->countAllResults()
));
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function getMenuComerciales()
{
if ($this->request->isAJAX()) {

View File

@ -11,7 +11,7 @@ class ChatDeparmentUserModel extends Model
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $useSoftDeletes = true;
protected $protectFields = true;
protected $allowedFields = [
"chat_department_id",

View File

@ -22,6 +22,14 @@ class UserModel extends ShieldUserModel
];
}
const SORTABLE = [
0 => "t1.id",
1 => "t1.first_name",
2 => "t1.last_name",
3 => "t2.secret",
4 => "t1.last_active",
];
protected $returnType = UsersEntity::class;
protected $useSoftDeletes = true;
@ -33,6 +41,7 @@ class UserModel extends ShieldUserModel
protected $validationRules = [
"first_name" => "required|trim|max_length[150]",
"last_name" => "required|trim|max_length[150]",
"email" => "required|valid_email|max_length[150]",
'new_pwd' => 'permit_empty|min_length[8]',
'new_pwd_confirm' => 'permit_empty|required_with[new_pwd]|matches[new_pwd]',
"comments" => "permit_empty|trim|max_length[512]"
@ -56,9 +65,40 @@ class UserModel extends ShieldUserModel
'comments' => [
"max_length" => "Users.validation.last_name.max_length",
],
'email' => [
"required" => "Users.validation.email.required",
"valid_email" => "Users.validation.email.valid_email",
"max_length" => "Users.validation.email.max_length"
]
];
public function getResource($search = [])
{
$builder = $this->db
->table($this->table . " t1")
->select(
"t1.id as id, t1.first_name AS first_name, t1.last_name AS last_name,
t2.secret AS email, t1.last_active AS last_active"
);
$builder->join("auth_identities t2", "t1.id = t2.user_id", "left");
$builder->where('t1.deleted_at', null)->groupBy("t1.id");
if (empty($search))
return $builder;
else {
$builder->groupStart();
foreach ($search as $col_search) {
$builder->like(self::SORTABLE[$col_search[0]], $col_search[2]);
}
$builder->groupEnd();
return $builder;
}
}
public function getComerciales()
{

View File

@ -1,5 +1,6 @@
<?= $this->include('themes/_commonPartialsBs/datatables') ?>
<?=$this->include('themes/_commonPartialsBs/datatables') ?>
<?= $this->extend('themes/vuexy/main/defaultlayout') ?>
<?= $this->section('content'); ?>
<div class="row">
<div class="col-md-12">
@ -16,36 +17,15 @@
style="width: 100%;">
<thead>
<tr>
<th>ID</th>
<th><?= lang('Users.firstName') ?></th>
<th><?= lang('Users.lastName') ?></th>
<th><?= lang('Users.email') ?></th>
<th><?= lang('Users.lastAccess') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
<th class="noFilter"><?= lang('Users.lastAccess') ?></th>
<th class="noFilter text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($userList2 as $item) : ?>
<tr>
<td class="align-middle">
<?= empty($item->first_name) || strlen($item->first_name) < 51 ? esc($item->first_name) : character_limiter(esc($item->first_name), 50) ?>
</td>
<td class="align-middle">
<?= empty($item->last_name) || strlen($item->last_name) < 51 ? esc($item->last_name) : character_limiter(esc($item->last_name), 50) ?>
</td>
<td class="align-middle">
<?= empty(auth()->getProvider()->findById($item->id)->email) ? "" : character_limiter(esc(auth()->getProvider()->findById($item->id)->email), 50) ?>
</td>
<td class="align-middle text-nowrap">
<?= empty($item->last_active) ? '' : date('d/m/Y H:m:s', strtotime($item->last_active)) ?>
</td>
<td class="align-middle text-center text-nowrap">
<?= anchor(route_to('editUser', $item->id), "<i class='ti ti-pencil ti-sm mx-2'></i>", ['class' => 'text-body', 'data-id' => $item->id,]); ?>
<?= anchor('#confirm2delete', "<i class='ti ti-trash ti-sm mx-2'></i>", ['class' => 'text-body', 'data-href' => route_to('deleteUser', $item->id), 'data-bs-toggle' => 'modal', 'data-bs-target' => '#confirm2delete']); ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div><!--//.card-body -->
@ -56,4 +36,24 @@
</div><!--//.col -->
</div><!--//.row -->
<?= $this->endSection() ?>
<?= $this->endSection() ?>
<?=$this->section('css') ?>
<link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>">
<?=$this->endSection() ?>
<?= $this->section('additionalExternalJs') ?>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/dataTables.buttons.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.html5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.print.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/jszip/jszip.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script>
<script type="module" src="<?= site_url('assets/js/safekat/pages/users/list.js') ?>"></script>
<?=$this->endSection() ?>

View File

@ -0,0 +1,144 @@
import Table from '../../components/table.js';
import ConfirmDeleteModal from '../../components/ConfirmDeleteModal.js';
import Ajax from '../../components/ajax.js';
import { getToken } from '../../common/common.js';
class UserList {
constructor() {
this.domItem = $('.card-body');
this.csrf_token = getToken();
this.csrf_hash = $('#mainContainer').find('input[name="' + this.csrf_token + '"]').val();
this.tableUsers = null;
this.deleteModal = null;
}
init() {
const self = this;
this.headerSearcher();
this.deleteModal = new ConfirmDeleteModal('plantillasTarifasCliente');
this.deleteModal.init();
this.#initTable();
// Editar en linea la fila
this.tableUsers.table.on('click', '.btn-edit-' + this.tableUsers.getAlias(), function (e) {
const dataId = $(this).attr('data-id');
if (!Number.isNaN(Number(dataId))) {
window.location.href = '/users/edit/' + dataId;
}
});
// Eliminar la fila
this.tableUsers.table.on('click', '.btn-delete-' + this.tableUsers.getAlias(), function (e) {
const row = $(this).closest('tr')[0]._DT_RowIndex;
const dataId = $(this).attr('data-id');
self.deleteModal.setData($(this).attr('data-id'));
self.deleteModal.show(() => {
if (!Number.isNaN(Number(self.deleteModal.getData()))) {
new Ajax(
'/users/delete/' + dataId,
{
},
{},
(data, textStatus, jqXHR) => {
self.tableUsers.table.clearPipeline();
self.tableUsers.table.row($(row)).invalidate().draw();
popSuccessAlert(data.msg ?? jqXHR.statusText);
},
(error) => {
console.log(error);
}
).get();
self.deleteModal.hide();
}
});
});
}
#initTable() {
const self = this;
const columns = [
{ 'data': 'id' },
{ 'data': 'first_name' },
{ 'data': 'last_name' },
{ 'data': 'email' },
{ 'data': 'last_active' },
];
const actions = ['edit', 'delete'];
this.tableUsers = new Table(
$('#tableOfUsers'),
'users',
'/users/datatable',
columns,
[]
);
this.tableUsers.init({
actions: actions,
colVisibility: false,
buttonsExport: true,
});
this.tableUsers.table.on('init.dt', function () {
self.tableUsers.table.page.len(50).draw();
});
}
headerSearcher() {
const self = this;
$('#tableOfUsers thead tr').clone(false).appendTo('#tableOfUsers thead');
$('#tableOfUsers thead tr:eq(1) th').each(function (i) {
if (!$(this).hasClass("noFilter")) {
$(this).html('<input type="text" class="form-control " style="min-width:100px;max-width:500px;font-size:0.8rem !important;" />');
$('input', this).on('change clear', function () {
if (self.tableUsers.table.column(i).search() !== this.value) {
self.tableUsers.table
.column(i)
.search(this.value)
.draw();
}
});
}
else {
$(this).html('<span></span>');
}
});
}
}
document.addEventListener('DOMContentLoaded', function () {
new UserList().init();
});