feat:chat modules

This commit is contained in:
amazuecos
2024-09-25 17:42:55 +00:00
parent 2fc9af9db4
commit c651db61ff
16 changed files with 808 additions and 382 deletions

View File

@ -742,6 +742,8 @@ $routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($route
$routes->get('department/presupuesto/(:num)/(:num)', 'ChatController::get_chat_presupuesto/$1/$2', ['as' => 'getChatPresupuesto']); $routes->get('department/presupuesto/(:num)/(:num)', 'ChatController::get_chat_presupuesto/$1/$2', ['as' => 'getChatPresupuesto']);
$routes->get('department/pedido/(:num)/(:num)', 'ChatController::get_chat_pedido/$1/$2', ['as' => 'getChatPedido']); $routes->get('department/pedido/(:num)/(:num)', 'ChatController::get_chat_pedido/$1/$2', ['as' => 'getChatPedido']);
$routes->get('department/factura/(:num)/(:num)', 'ChatController::get_chat_factura/$1/$2', ['as' => 'getChatFactura']); $routes->get('department/factura/(:num)/(:num)', 'ChatController::get_chat_factura/$1/$2', ['as' => 'getChatFactura']);
$routes->get('department/(:num)/users', 'ChatController::get_chat_department_users/$1', ['as' => 'getChatDepartmentUsers']);
$routes->get('(:num)', 'ChatController::get_chat/$1', ['as' => 'getChat']); $routes->get('(:num)', 'ChatController::get_chat/$1', ['as' => 'getChat']);
$routes->post('message/presupuesto', 'ChatController::store_chat_message_presupuesto', ['as' => 'storeChatMessagePresupuesto']); $routes->post('message/presupuesto', 'ChatController::store_chat_message_presupuesto', ['as' => 'storeChatMessagePresupuesto']);
@ -751,6 +753,8 @@ $routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($route
$routes->get('contacts', 'ChatController::get_chat_internal_contacts', ['as' => 'getChatInternalContacts']); $routes->get('contacts', 'ChatController::get_chat_internal_contacts', ['as' => 'getChatInternalContacts']);
$routes->get('contacts/(:num)', 'ChatController::get_chat_internal_contact/$1', ['as' => 'getChatInternalContact']); $routes->get('contacts/(:num)', 'ChatController::get_chat_internal_contact/$1', ['as' => 'getChatInternalContact']);
$routes->get('contact/(:num)/messages', 'ChatController::get_chat_internal_messages/$1', ['as' => 'getChatInternalMessages']); $routes->get('contact/(:num)/messages', 'ChatController::get_chat_internal_messages/$1', ['as' => 'getChatInternalMessages']);
$routes->get('notifications', 'ChatController::get_chat_cliente/$1', ['as' => 'getChatCliente']);

View File

@ -7,6 +7,7 @@ use App\Models\Chat\ChatDeparmentModel;
use App\Models\Chat\ChatDeparmentUserModel; use App\Models\Chat\ChatDeparmentUserModel;
use App\Models\Chat\ChatMessageModel; use App\Models\Chat\ChatMessageModel;
use App\Models\Chat\ChatModel; use App\Models\Chat\ChatModel;
use App\Models\Clientes\ClienteModel;
use App\Models\Usuarios\UserModel; use App\Models\Usuarios\UserModel;
use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\RequestInterface;
@ -20,6 +21,8 @@ class ChatController extends BaseController
protected ChatModel $chatModel; protected ChatModel $chatModel;
protected ChatMessageModel $chatMessageModel; protected ChatMessageModel $chatMessageModel;
protected UserModel $userModel; protected UserModel $userModel;
protected ClienteModel $clienteModel;
@ -36,6 +39,8 @@ class ChatController extends BaseController
$this->chatModel = model(ChatModel::class); $this->chatModel = model(ChatModel::class);
$this->chatMessageModel = model(ChatMessageModel::class); $this->chatMessageModel = model(ChatMessageModel::class);
$this->userModel = model(UserModel::class); $this->userModel = model(UserModel::class);
$this->clienteModel = model(ClienteModel::class);
} }
public function index() {} public function index() {}
public function get_chat_departments() public function get_chat_departments()
@ -161,6 +166,9 @@ class ChatController extends BaseController
} }
public function get_chat_internal_contacts() public function get_chat_internal_contacts()
{ {
if(auth()->user()->cliente_id){
return $this->response->setJSON([]);
}
$users = $this->userModel->builder() $users = $this->userModel->builder()
->where("cliente_id", null) ->where("cliente_id", null)
->whereNotIn("id", [auth()->user()->id]) ->whereNotIn("id", [auth()->user()->id])
@ -173,6 +181,9 @@ class ChatController extends BaseController
} }
public function get_chat_internal_contact(int $user_id) public function get_chat_internal_contact(int $user_id)
{ {
if(auth()->user()->cliente_id){
return $this->response->setJSON([]);
}
$users = $this->userModel->builder() $users = $this->userModel->builder()
->where("cliente_id", null) ->where("cliente_id", null)
->where("deleted_at", null) ->where("deleted_at", null)
@ -186,4 +197,23 @@ class ChatController extends BaseController
$conversation = $this->chatMessageModel->get_chat_contact_messages($user_id); $conversation = $this->chatMessageModel->get_chat_contact_messages($user_id);
return $this->response->setJSON($conversation); return $this->response->setJSON($conversation);
} }
public function get_chat_cliente()
{
$cliente_id = auth()->user()->cliente_id;
$response = [];
if($cliente_id){
$data = $this->clienteModel->getClienteDataPresupuestoPedidoFactura($cliente_id);
$response["chatFacturas"] = $this->chatModel->getClienteChatFacturas($data["facturas"]);
$response["chatPresupuestos"] = $this->chatModel->getClienteChatPresupuestos($data["presupuestos"]);
$response["chatPedidos"] = $this->chatModel->getClienteChatPedidos($data["pedidos"]);
$response["data"] = $data;
}
return $this->response->setJSON($response);
}
public function get_chat_department_users(int $chat_department_id)
{
$data = $this->chatDeparmentModel->getChatDepartmentUsers($chat_department_id);
return $this->response->setJSON($data);
}
} }

View File

@ -1,8 +1,8 @@
<?php namespace App\Controllers\Configuracion; <?php namespace App\Controllers\Configuracion;
use App\Entities\Usuarios\UserEntity; use App\Entities\Usuarios\UserEntity;
use App\Models\Chat\ChatDeparmentModel;
use App\Models\Chat\ChatDeparmentUserModel;
use App\Models\Usuarios\GroupModel; use App\Models\Usuarios\GroupModel;
use App\Models\UserModel; use App\Models\UserModel;
@ -16,6 +16,9 @@ class Users extends \App\Controllers\GoBaseController
private $group_model; private $group_model;
private $group_user_model; private $group_user_model;
private $user_model; private $user_model;
private ChatDeparmentModel $chat_department_model;
private ChatDeparmentUserModel $chat_department_user_model;
use \CodeIgniter\API\ResponseTrait; use \CodeIgniter\API\ResponseTrait;
@ -38,6 +41,9 @@ class Users extends \App\Controllers\GoBaseController
$this->group_model = new GroupModel(); $this->group_model = new GroupModel();
$this->group_user_model = new GroupsUsersModel(); $this->group_user_model = new GroupsUsersModel();
$this->user_model = new UserModel(); $this->user_model = new UserModel();
$this->chat_department_model = model(ChatDeparmentModel::class);
$this->chat_department_user_model = model(ChatDeparmentUserModel::class);
$this->viewData['pageTitle'] = lang('Users.moduleTitle'); $this->viewData['pageTitle'] = lang('Users.moduleTitle');
@ -76,7 +82,10 @@ class Users extends \App\Controllers\GoBaseController
} }
// Obtener los grupos a los que pertenece // Obtener los grupos a los que pertenece
$currentGroups = $postData['group'] ?? []; $currentGroups = $postData['group'] ?? [];
$chatDepartments = $postData['chatDepartments'] ?? [];
unset($postData['group']); unset($postData['group']);
unset($postData['chatDepartments']);
// Generar el nombre de usuario // Generar el nombre de usuario
$postData['username'] = strstr($postData['email'], '@', true); $postData['username'] = strstr($postData['email'], '@', true);
$sanitizedData = $this->sanitized($postData, true); $sanitizedData = $this->sanitized($postData, true);
@ -128,6 +137,14 @@ class Users extends \App\Controllers\GoBaseController
]; ];
$this->group_user_model->insert($group_user_data); $this->group_user_model->insert($group_user_data);
} }
$this->chat_department_user_model->where("user_id",$id)->delete();
foreach($chatDepartments as $chatDepartment)
{
$this->chat_department_user_model->insert([
"user_id" => $id,
"chat_department_id" => $this->chat_department_model->where("name",$chatDepartment)->first()["id"]
]);
}
$message = lang('Basic.global.saveSuccess', [mb_strtolower(lang('Users.user'))]) . '.'; $message = lang('Basic.global.saveSuccess', [mb_strtolower(lang('Users.user'))]) . '.';
$message = ucfirst(str_replace("'", "\'", $message)); $message = ucfirst(str_replace("'", "\'", $message));
@ -150,6 +167,7 @@ class Users extends \App\Controllers\GoBaseController
$this->viewData['clienteList'] = $this->getClienteListItems(); $this->viewData['clienteList'] = $this->getClienteListItems();
$this->viewData['formAction'] = route_to('createUser'); $this->viewData['formAction'] = route_to('createUser');
$this->viewData['groups'] = $this->group_model->select('keyword, title')->findAll(); $this->viewData['groups'] = $this->group_model->select('keyword, title')->findAll();
$this->viewData['chatDepartments'] = $this->chat_department_model->findAll();
$this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Users.user') . ' ' . lang('Basic.global.addNewSuffix'); $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Users.user') . ' ' . lang('Basic.global.addNewSuffix');
@ -176,7 +194,10 @@ class Users extends \App\Controllers\GoBaseController
$postData = $this->request->getPost(); $postData = $this->request->getPost();
$currentGroups = $postData['group'] ?? []; $currentGroups = $postData['group'] ?? [];
$chatDepartments = $postData['chatDepartments'] ?? [];
unset($postData['group']); unset($postData['group']);
unset($postData['chatDepartments']);
// Obtener contraseña nueva si se ha introducido en texto plano // Obtener contraseña nueva si se ha introducido en texto plano
// Obtener contraseña nueva si se ha introducido en texto plano // Obtener contraseña nueva si se ha introducido en texto plano
@ -233,7 +254,14 @@ class Users extends \App\Controllers\GoBaseController
]; ];
$this->group_user_model->insert($group_user_data); $this->group_user_model->insert($group_user_data);
} }
$this->chat_department_user_model->where("user_id",$id)->delete();
foreach($chatDepartments as $chatDepartment)
{
$this->chat_department_user_model->insert([
"user_id" => $id,
"chat_department_id" => $this->chat_department_model->where("name",$chatDepartment)->first()["id"]
]);
}
$id = $user->id ?? $id; $id = $user->id ?? $id;
$message = lang('Basic.global.updateSuccess', [mb_strtolower(lang('Users.user'))]) . '.'; $message = lang('Basic.global.updateSuccess', [mb_strtolower(lang('Users.user'))]) . '.';
$message = ucfirst(str_replace("'", "\'", $message)); $message = ucfirst(str_replace("'", "\'", $message));
@ -256,6 +284,8 @@ class Users extends \App\Controllers\GoBaseController
$this->viewData['formAction'] = route_to('updateUser', $id); $this->viewData['formAction'] = route_to('updateUser', $id);
$this->viewData['selectedGroups'] = $this->group_model->getUsersRoles($requestedId); $this->viewData['selectedGroups'] = $this->group_model->getUsersRoles($requestedId);
$this->viewData['groups'] = $this->group_model->select('keyword, title')->findAll(); $this->viewData['groups'] = $this->group_model->select('keyword, title')->findAll();
$this->viewData['chatDepartments'] = $this->chat_department_model->select(["display","name","id as chatDepartmentId"])->findAll();
$this->viewData['chatDepartmentUser'] = $this->chat_department_user_model->getChatDepartmentUser($user->id);
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Users.user') . ' ' . lang('Basic.global.edit3'); $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Users.user') . ' ' . lang('Basic.global.edit3');
return $this->displayForm(__METHOD__, $id); return $this->displayForm(__METHOD__, $id);

View File

@ -18,6 +18,7 @@ return [
'emailConfirmed' => 'Email Confirmado', 'emailConfirmed' => 'Email Confirmado',
'firstName' => 'Nombre', 'firstName' => 'Nombre',
'group' => 'Rol', 'group' => 'Rol',
'chatDepartments' => 'Chat departamento',
'idUser' => 'ID Usuario', 'idUser' => 'ID Usuario',
'language' => 'Idioma', 'language' => 'Idioma',
'lastAccess' => 'Último acceso', 'lastAccess' => 'Último acceso',

View File

@ -98,4 +98,26 @@ class ChatDeparmentModel extends Model
} }
return $departments; return $departments;
} }
public function getChatDepartmentUsers(int $chat_deparment_id)
{
$result = $this->db->table('chat_departments')
->select(
[
"users.*"
]
)
->join(
"chat_department_users",
"chat_department_users.chat_department_id = chat_departments.id",
'left'
)
->join(
"users",
"chat_department_users.user_id = users.id",
'left'
)->where("chat_departments.id",$chat_deparment_id)
->get()->getResultObject();
return $result;
}
} }

View File

@ -47,4 +47,12 @@ class ChatDeparmentUserModel extends Model
protected $afterFind = []; protected $afterFind = [];
protected $beforeDelete = []; protected $beforeDelete = [];
protected $afterDelete = []; protected $afterDelete = [];
public function getChatDepartmentUser(int $user_id)
{
return $this->db->table($this->table." t1")
->select("chat_departments.*")
->join("chat_departments","t1.chat_department_id = chat_departments.id","left")
->where("t1.user_id",$user_id)->get()->getResultObject();
}
} }

View File

@ -2,7 +2,7 @@
namespace App\Models\Chat; namespace App\Models\Chat;
use App\Models\Usuarios\UserModel;
use CodeIgniter\Model; use CodeIgniter\Model;
use stdClass; use stdClass;
@ -192,5 +192,74 @@ class ChatModel extends Model
->get()->getResultObject(); ->get()->getResultObject();
return $query; return $query;
} }
public function getClienteChatPedidos(array $pedidos) : array
{
$results = $this->db->table("chats")
->select([
"chats.id as chatId",
"chats.pedido_id as pedidoId",
"chats.chat_department_id as chatDepartmentId",
"chat_departments.display as chatDisplay",
"pedidos.id as title"
])
->join("chat_departments","chat_departments.id = chats.chat_department_id","left")
->join("pedidos","pedidos.id = chats.pedido_id","left")
->join("chat_messages","pedidos.id = chats.pedido_id","left")
->whereNotIn("chat_messages.sender_id",[auth()->user()->id])
->whereIn("pedidos.id",$pedidos)
->get()->getResultObject();
$chatMessageModel = model(ChatMessageModel::class);
foreach ($results as $row) {
$row->messages = $chatMessageModel->get_chat_messages($row->chatId);
}
return $results;
}
public function getClienteChatFacturas(array $facturas) : array
{
$results = $this->db->table("chats")
->select([
"chats.id as chatId",
"chats.factura_id as facturaId",
"chats.chat_department_id as chatDepartmentId",
"chat_departments.display as chatDisplay",
"facturas.numero as title"
])
->join("chat_departments","chat_departments.id = chats.chat_department_id","left")
->join("facturas","facturas.id = chats.factura_id","left")
->join("chat_messages","chats.id = chat_messages.chat_id","left")
->whereNotIn("chat_messages.sender_id",[auth()->user()->id])
->whereIn("facturas.id",$facturas)
->get()->getResultObject();
$chatMessageModel = model(ChatMessageModel::class);
foreach ($results as $row) {
$row->messages = $chatMessageModel->get_chat_messages($row->chatId);
}
return $results;
}
public function getClienteChatPresupuestos(array $presupuestos) : array
{
$results = $this->db->table("chats")
->select([
"chats.id as chatId",
"chats.presupuesto_id as presupuestoId",
"chats.chat_department_id as chatDepartmentId",
"chat_departments.display as chatDisplay",
"presupuestos.titulo as title"
])
->join("chat_departments","chat_departments.id = chats.chat_department_id","left")
->join("presupuestos","presupuestos.id = chats.presupuesto_id","left")
->join("chat_messages","chats.id = chat_messages.chat_id","left")
->whereNotIn("chat_messages.sender_id",[auth()->user()->id])
->whereIn("presupuestos.id",$presupuestos)
->get()->getResultObject();
$chatMessageModel = model(ChatMessageModel::class);
foreach ($results as $row) {
$row->messages = $chatMessageModel->get_chat_messages($row->chatId);
}
return $results;
}
} }

View File

@ -332,4 +332,39 @@ class ClienteModel extends \App\Models\BaseModel
return $builder->get()->getResultArray(); return $builder->get()->getResultArray();
} }
public function getClienteDataPresupuestoPedidoFactura(int $cliente_id) : array
{
$query = $this->db
->table($this->table." t1")
->select([
"t1.id as clienteId",
"presupuestos.id as presupuestoId",
"pedidos.id as pedidoId",
"presupuesto_estados.estado as presupuestoEstado",
"facturas_pedidos_lineas.factura_id as facturaId",
])
->join("presupuestos","t1.id = presupuestos.cliente_id","left")
->join("presupuesto_estados","presupuestos.estado_id = presupuesto_estados.id","left")
->join("pedidos_linea","presupuestos.id = pedidos_linea.presupuesto_id","left")
->join("pedidos","pedidos.id = pedidos_linea.pedido_id","left")
->join("facturas_pedidos_lineas","facturas_pedidos_lineas.pedido_linea_id = pedidos_linea.id","left")
->where("t1.id",$cliente_id);
$data = $query->get()->getResultObject();
$facturas = [];
$presupuestos = [];
$pedidos = [];
$result = [];
foreach ($data as $row) {
$facturas[] = $row->facturaId;
$presupuestos[] = $row->presupuestoId;
$pedidos[] = $row->pedidoId;
}
$result["facturas"] = array_unique(array_filter($facturas));
$result["presupuestos"] = array_unique(array_filter($presupuestos));
$result["pedidos"] = array_unique(array_filter($pedidos));
return $result;
}
} }

View File

@ -75,26 +75,23 @@
class="avatar-initial rounded-circle bg-label-primary">P</span> class="avatar-initial rounded-circle bg-label-primary">P</span>
</div> </div>
<div class="chat-contact-info flex-grow-1 ms-2"> <div class="chat-contact-info flex-grow-1 ms-2">
<h6 class="m-0">Departamento Producción</h6> <h6 class="m-0"></h6>
<small class="user-status text-muted">Consulta sobre el presupuesto <small class="user-status text-muted"></small>
P001</small>
</div> </div>
</div> </div>
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<div class="dropdown d-flex align-self-center"> <div class="dropdown d-flex align-self-center ml-2 px-2 d-none" id="chat-header-dropdown-users">
<button class="btn p-0" type="button" id="chat-header-actions" <button type="button" class="btn btn-primary btn-icon rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
data-bs-toggle="dropdown" aria-haspopup="true" <i class="ti ti-users"></i>
aria-expanded="false">
<i class="ti ti-dots-vertical"></i>
</button> </button>
<div class="dropdown-menu dropdown-menu-end d-none" <div class="dropdown-menu dropdown-menu-end" id="chat-header-users"
aria-labelledby="chat-header-actions"> aria-labelledby="chat-header-users">
<a class="dropdown-item" href="javascript:void(0);">Silenciar
Conversacion</a>
<a class="dropdown-item" href="javascript:void(0);">Limpiar
Conversacion</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -78,22 +78,20 @@
<h6 class="m-0"></h6> <h6 class="m-0"></h6>
<small class="user-status text-muted"></small> <small class="user-status text-muted"></small>
</div> </div>
</div> </div>
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<div class="dropdown d-flex align-self-center"> <div class="dropdown d-flex align-self-center ml-2 px-2 d-none" id="chat-header-dropdown-users">
<button class="btn p-0" type="button" id="chat-header-actions" <button type="button" class="btn btn-primary btn-icon rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
data-bs-toggle="dropdown" aria-haspopup="true" <i class="ti ti-users"></i>
aria-expanded="false">
<i class="ti ti-dots-vertical"></i>
</button> </button>
<div class="dropdown-menu dropdown-menu-end" <div class="dropdown-menu dropdown-menu-end" id="chat-header-users"
aria-labelledby="chat-header-actions"> aria-labelledby="chat-header-users">
<a class="dropdown-item" href="javascript:void(0);">Silenciar
Conversacion</a>
<a class="dropdown-item" href="javascript:void(0);">Limpiar
Conversacion</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,13 +1,13 @@
<div class="accordion accordion-bordered mt-3" id="accordionChatPresupuesto"> <div class="accordion accordion-bordered mt-3" id="accordionChatPresupuesto">
<div class="card accordion-item active"> <div class="card accordion-item">
<h2 class="accordion-header" id="headingChatPresupuesto"> <h2 class="accordion-header" id="headingChatPresupuesto">
<button type="button" class="accordion-button" data-bs-toggle="collapse" <button type="button" class="accordion-button collapsed" data-bs-toggle="collapse"
data-bs-target="#accordionChatPresupuestoTip" aria-expanded="false" data-bs-target="#accordionChatPresupuestoTip" aria-expanded="false"
aria-controls="accordionChatPresupuestoTip"> aria-controls="accordionChatPresupuestoTip">
<h3><?= lang("Chat.chat") ?></h3> <h3><?= lang("Chat.chat") ?></h3>
</button> </button>
</h2> </h2>
<div id="accordionChatPresupuestoTip" class="accordion-collapse collapse show" <div id="accordionChatPresupuestoTip" class="accordion-collapse collapse"
data-bs-parent="#accordionChatPresupuesto"> data-bs-parent="#accordionChatPresupuesto">
<div class="accordion-body"> <div class="accordion-body">
<div class="container-xxl flex-grow-1" id="chat-presupuesto" data-id="<?= $modelId ?>"> <div class="container-xxl flex-grow-1" id="chat-presupuesto" data-id="<?= $modelId ?>">
@ -77,26 +77,23 @@
class="avatar-initial rounded-circle bg-label-primary">P</span> class="avatar-initial rounded-circle bg-label-primary">P</span>
</div> </div>
<div class="chat-contact-info flex-grow-1 ms-2"> <div class="chat-contact-info flex-grow-1 ms-2">
<h6 class="m-0">Departamento Producción</h6> <h6 class="m-0"></h6>
<small class="user-status text-muted">Consulta sobre el presupuesto <small class="user-status text-muted"></small>
P001</small>
</div> </div>
</div> </div>
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<div class="dropdown d-flex align-self-center"> <div class="dropdown d-flex align-self-center ml-2 px-2 d-none" id="chat-header-dropdown-users">
<button class="btn p-0" type="button" id="chat-header-actions" <button type="button" class="btn btn-primary btn-icon rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
data-bs-toggle="dropdown" aria-haspopup="true" <i class="ti ti-users"></i>
aria-expanded="false">
<i class="ti ti-dots-vertical"></i>
</button> </button>
<div class="dropdown-menu dropdown-menu-end" <div class="dropdown-menu dropdown-menu-end" id="chat-header-users"
aria-labelledby="chat-header-actions"> aria-labelledby="chat-header-users">
<a class="dropdown-item" href="javascript:void(0);">Silenciar
Conversacion</a>
<a class="dropdown-item" href="javascript:void(0);">Limpiar
Conversacion</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -52,6 +52,25 @@
</select> </select>
</div> </div>
</div> </div>
<div class="mb-3">
<div class="form-group">
<label for="chat_departments" class="form-label"> <?= lang('Users.chatDepartments') ?></label>
<select tabindex="11" name="chatDepartments[]" id="chat_departments" multiple="multiple"
class="form-control select2 form-select">
<?php
$selectedChatDepartments = isset($chatDepartmentUser) && is_array($chatDepartmentUser) ? $chatDepartmentUser : [];
$selectedKeywords = array_map(fn($chatDepartment) => $chatDepartment->name, $selectedChatDepartments);
foreach ($chatDepartments as $item) :
$isSelected = in_array($item["name"], $selectedKeywords) ? 'selected' : '';
?>
<option value="<?= $item["name"] ?>"
data-select2-id=<?= $item["name"] ?> <?= $isSelected ?>>
<?= $item["display"] ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="mb-3"> <div class="mb-3">
<label for="cliente_id" class="form-label"> <label for="cliente_id" class="form-label">
<?= lang('Presupuestos.clienteId') ?> <?= lang('Presupuestos.clienteId') ?>

View File

@ -11,23 +11,21 @@ $picture = "/assets/img/default-user.png";
dir="ltr" dir="ltr"
data-theme="theme-default" data-theme="theme-default"
data-assets-path="<?= site_url('themes/vuexy/') ?>" data-assets-path="<?= site_url('themes/vuexy/') ?>"
data-template="vertical-menu-template-no-customizer" data-template="vertical-menu-template-no-customizer">
>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta <meta
name="viewport" name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
/>
<title><?= config('Safekat')->appName ?></title> <title><?= config('Safekat')->appName ?></title>
<meta name="description" content=""/> <meta name="description" content="" />
<!-- Favicon --> <!-- Favicon -->
<link rel="icon" type="image/x-icon" href="<?= site_url('themes/vuexy/img/favicon/favicon.ico') ?>"/> <link rel="icon" type="image/x-icon" href="<?= site_url('themes/vuexy/img/favicon/favicon.ico') ?>" />
<link rel="apple-touch-icon" sizes="57x57" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-57x57.png') ?>"> <link rel="apple-touch-icon" sizes="57x57" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-57x57.png') ?>">
<link rel="apple-touch-icon" sizes="60x60" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-60x60.png') ?>"> <link rel="apple-touch-icon" sizes="60x60" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-60x60.png') ?>">
<link rel="apple-touch-icon" sizes="72x72" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-72x72.png') ?>"> <link rel="apple-touch-icon" sizes="72x72" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-72x72.png') ?>">
@ -53,31 +51,32 @@ $picture = "/assets/img/default-user.png";
<link rel="manifest" href="<?= site_url('themes/vuexy/img/favicon/manifest.json') ?>"> <link rel="manifest" href="<?= site_url('themes/vuexy/img/favicon/manifest.json') ?>">
<!-- Fonts --> <!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com"/> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link <link
href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap" href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap"
rel="stylesheet" rel="stylesheet" />
/>
<!-- Icons --> <!-- Icons -->
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/fonts/fontawesome.css') ?>"/> <link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/fonts/fontawesome.css') ?>" />
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/fonts/tabler-icons.css') ?>"/> <link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/fonts/tabler-icons.css') ?>" />
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/fonts/flag-icons.css') ?>"/> <link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/fonts/flag-icons.css') ?>" />
<!-- Core CSS --> <!-- Core CSS -->
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/rtl/core.css') ?>"/> <link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/rtl/core.css') ?>" />
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/rtl/theme-semi-dark.css') ?>"/> <link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/rtl/theme-semi-dark.css') ?>" />
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/safekat.css') ?>"/> <link rel="stylesheet" href="<?= site_url('themes/vuexy/css/safekat.css') ?>" />
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/pages/app-chat.css') ?>">
<!-- Vendors CSS --> <!-- Vendors CSS -->
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.css') ?>"/> <link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.css') ?>" />
<!-- Page CSS --> <!-- Page CSS -->
<?= $this->renderSection('css') ?> <?= $this->renderSection('css') ?>
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/safekat.css') ?>"/> <link rel="stylesheet" href="<?= site_url('themes/vuexy/css/safekat.css') ?>" />
<!-- Helpers --> <!-- Helpers -->
<script src="<?= site_url('themes/vuexy/vendor/js/helpers.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/js/helpers.js') ?>"></script>
@ -87,8 +86,8 @@ $picture = "/assets/img/default-user.png";
<body> <body>
<!-- Layout wrapper --> <!-- Layout wrapper -->
<div class="layout-wrapper layout-content-navbar"> <div class="layout-wrapper layout-content-navbar">
<div class="layout-container"> <div class="layout-container">
<?php include "selector_menu.php" ?> <?php include "selector_menu.php" ?>
@ -99,18 +98,50 @@ $picture = "/assets/img/default-user.png";
<!-- Navbar --> <!-- Navbar -->
<nav <nav
class="layout-navbar container-fluid navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme" class="layout-navbar container-fluid navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
id="layout-navbar" id="layout-navbar">
>
<div class="layout-menu-toggle navbar-nav align-items-xl-center me-3 me-xl-0 d-xl-none"> <div class="layout-menu-toggle navbar-nav align-items-xl-center me-3 me-xl-0 d-xl-none">
<a class="nav-item nav-link px-0 me-xl-4" href="javascript:void(0)"> <a class="nav-item nav-link px-0 me-xl-4" href="javascript:void(0)">
<i class="ti ti-menu-2 ti-sm"></i> <i class="ti ti-menu-2 ti-sm"></i>
</a> </a>
</div> </div>
<div class="navbar-nav-right d-flex align-items-center" id="navbar-collapse"> <div class="navbar-nav-right d-flex align-items-center" id="navbar-collapse">
<ul class="navbar-nav flex-row align-items-center ms-auto"> <ul class="navbar-nav flex-row align-items-center ms-auto">
<li class="nav-item dropdown-shortcuts navbar-dropdown dropdown me-2 me-xl-0">
<a
class="nav-link dropdown-toggle hide-arrow"
href="javascript:void(0);"
data-bs-toggle="dropdown"
data-bs-auto-close="outside"
aria-expanded="false">
<span class="tf-icons ti-md ti ti-message-circle"></span>
<span id="chat-notification-number" class="badge bg-danger text-white badge-notifications"></span>
</a>
<div class="dropdown-menu dropdown-menu-end py-0">
<div class="dropdown-menu-header border-bottom">
<div class="dropdown-header d-flex align-items-center py-3">
<h5 class="text-body mb-0 me-auto">Chats</h5>
</div>
</div>
<div class="dropdown-shortcuts-list scrollable-container">
<!-- Chat & Contacts -->
<div class="container">
<div class="col app-chat-contacts app-sidebar flex-grow-0 overflow-hidden"
id="app-chat-contacts">
<div class="container-m-nx m-2">
<div class="sidebar-body">
<!-- Contacts -->
<ul class="list-unstyled chat-contact-list mb-0" id="chat-notification-list">
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</li>
<!-- Notification --> <!-- Notification -->
<li class="nav-item dropdown-notifications navbar-dropdown dropdown me-3 me-xl-1"> <li class="nav-item dropdown-notifications navbar-dropdown dropdown me-3 me-xl-1">
<a <a
@ -118,9 +149,9 @@ $picture = "/assets/img/default-user.png";
href="javascript:void(0);" href="javascript:void(0);"
data-bs-toggle="dropdown" data-bs-toggle="dropdown"
data-bs-auto-close="outside" data-bs-auto-close="outside"
aria-expanded="false" aria-expanded="false">
>
<i class="ti ti-bell ti-md"></i> <i class="ti ti-bell ti-md"></i>
</a> </a>
</li> </li>
<!--/ Notification --> <!--/ Notification -->
@ -130,8 +161,7 @@ $picture = "/assets/img/default-user.png";
<a <a
class="nav-link hide-arrow" class="nav-link hide-arrow"
href="<?= site_url('presupuestos/buscador'); ?>" href="<?= site_url('presupuestos/buscador'); ?>"
title="Acceso directo a buscador de presupuestos" title="Acceso directo a buscador de presupuestos">
>
<i class="ti ti-report-search ti-md"></i> <i class="ti ti-report-search ti-md"></i>
</a> </a>
</li> </li>
@ -147,8 +177,7 @@ $picture = "/assets/img/default-user.png";
href="javascript:void(0);" href="javascript:void(0);"
data-bs-toggle="dropdown" data-bs-toggle="dropdown"
data-bs-auto-close="outside" data-bs-auto-close="outside"
aria-expanded="false" aria-expanded="false">
>
<i class="ti ti-building ti-md"></i> <i class="ti ti-building ti-md"></i>
</a> </a>
<div class="dropdown-menu dropdown-menu-end py-0"> <div class="dropdown-menu dropdown-menu-end py-0">
@ -224,7 +253,7 @@ $picture = "/assets/img/default-user.png";
<a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);" <a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);"
data-bs-toggle="dropdown"> data-bs-toggle="dropdown">
<div class="avatar"> <div class="avatar">
<img src="<?= $picture ?? '' ?>" alt class="h-auto rounded-circle"/> <img src="<?= $picture ?? '' ?>" alt class="h-auto rounded-circle" />
</div> </div>
</a> </a>
<ul class="dropdown-menu dropdown-menu-end"> <ul class="dropdown-menu dropdown-menu-end">
@ -233,7 +262,7 @@ $picture = "/assets/img/default-user.png";
<div class="d-flex"> <div class="d-flex">
<div class="flex-shrink-0 me-3"> <div class="flex-shrink-0 me-3">
<div class="avatar avatar"> <div class="avatar avatar">
<img src="<?= $picture ?? '' ?>" alt class="h-auto rounded-circle"/> <img src="<?= $picture ?? '' ?>" alt class="h-auto rounded-circle" />
</div> </div>
</div> </div>
<div class="flex-grow-1"> <div class="flex-grow-1">
@ -311,47 +340,48 @@ $picture = "/assets/img/default-user.png";
<!-- Drag Target Area To SlideIn Menu On Small Screens --> <!-- Drag Target Area To SlideIn Menu On Small Screens -->
<div class="drag-target"></div> <div class="drag-target"></div>
</div> </div>
<!-- / Layout wrapper --> <!-- / Layout wrapper -->
<?= $this->renderSection('footerAdditions') ?> <?= $this->renderSection('footerAdditions') ?>
<!-- Core JS --> <!-- Core JS -->
<!-- build:js assets/vendor/js/core.js --> <!-- build:js assets/vendor/js/core.js -->
<script src="<?= site_url('themes/vuexy/vendor/libs/jquery/jquery.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/libs/jquery/jquery.js') ?>"></script>
<script src="<?= site_url('themes/vuexy/vendor/libs/popper/popper.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/libs/popper/popper.js') ?>"></script>
<script src="<?= site_url('themes/vuexy/vendor/js/bootstrap.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/js/bootstrap.js') ?>"></script>
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
<script src="<?= site_url('themes/vuexy/vendor/libs/hammer/hammer.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/libs/hammer/hammer.js') ?>"></script>
<script src="<?= site_url('themes/vuexy/vendor/js/menu.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/js/menu.js') ?>"></script>
<!-- endbuild --> <script type="module" src="<?= site_url('assets/js/safekat/pages/chatNotification.js') ?>"></script>
<!-- Vendors JS --> <!-- endbuild -->
<?= $this->renderSection('additionalExternalJs') ?>
<!-- Main JS --> <!-- Vendors JS -->
<script src="<?= site_url('themes/vuexy/js/main.js') ?>"></script> <?= $this->renderSection('additionalExternalJs') ?>
<!-- Page JS --> <!-- Main JS -->
<?= sweetAlert() ?> <script src="<?= site_url('themes/vuexy/js/main.js') ?>"></script>
<?php <!-- Page JS -->
if (isset($global_js_variables)) { <?= sweetAlert() ?>
<?php
if (isset($global_js_variables)) {
echo "<script>\n"; echo "<script>\n";
foreach ($global_js_variables as $name => $value): foreach ($global_js_variables as $name => $value):
echo "\t" . "var $name = $value;" . "\n"; echo "\t" . "var $name = $value;" . "\n";
endforeach; endforeach;
echo "</script>\n"; echo "</script>\n";
} }
?> ?>
<script type="text/javascript"> <script type="text/javascript">
<?= $this->renderSection('globalJsFunctions') ?> <?= $this->renderSection('globalJsFunctions') ?>
var theTable; var theTable;
var <?=csrf_token() ?? 'token'?>v = '<?= csrf_hash() ?>'; var <?= csrf_token() ?? 'token' ?>v = '<?= csrf_hash() ?>';
function yeniden(andac = null) { function yeniden(andac = null) {
if (andac == null) { if (andac == null) {
@ -362,12 +392,15 @@ if (isset($global_js_variables)) {
$('input[name="<?= csrf_token() ?>"]').val(andac); $('input[name="<?= csrf_token() ?>"]').val(andac);
$('meta[name="<?= config('Security')->tokenName ?>"]').attr('content', andac) $('meta[name="<?= config('Security')->tokenName ?>"]').attr('content', andac)
$.ajaxSetup({ $.ajaxSetup({
headers: {'<?= config('Security')->headerName ?>': andac, 'X-Requested-With': 'XMLHttpRequest'}, headers: {
<?=csrf_token()?>: andac '<?= config('Security')->headerName ?>': andac,
'X-Requested-With': 'XMLHttpRequest'
},
<?= csrf_token() ?>: andac
}); });
} }
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function() {
function adjustSidebar4ContentWrapper() { function adjustSidebar4ContentWrapper() {
if ($('#sidebar').hasClass('d-none') && $(window).width() <= 768) { if ($('#sidebar').hasClass('d-none') && $(window).width() <= 768) {
@ -381,7 +414,7 @@ if (isset($global_js_variables)) {
adjustSidebar4ContentWrapper(); adjustSidebar4ContentWrapper();
$('#sidebarCollapse').on('click', function () { $('#sidebarCollapse').on('click', function() {
if ($('#sidebar').hasClass('d-none') && $(window).width() <= 768) { if ($('#sidebar').hasClass('d-none') && $(window).width() <= 768) {
$('#sidebar').removeClass('d-none d-sm-none d-md-block'); $('#sidebar').removeClass('d-none d-sm-none d-md-block');
@ -396,17 +429,15 @@ if (isset($global_js_variables)) {
}); });
$(window).resize(function () { $(window).resize(function() {
adjustSidebar4ContentWrapper(); adjustSidebar4ContentWrapper();
}); });
<?= $this->renderSection('additionalInlineJs') ?> <?= $this->renderSection('additionalInlineJs') ?>
}); });
</script>
</script>
</body> </body>
</html>
</html>

View File

@ -8,34 +8,58 @@ class Chat {
this.chatList = this.domItem.find("#chat-list") this.chatList = this.domItem.find("#chat-list")
this.chatHistory = this.domItem.find("#chat-conversation") this.chatHistory = this.domItem.find("#chat-conversation")
this.modelId = this.domItem.data("id") this.modelId = this.domItem.data("id")
this.chatHistoryBody = document.querySelector(".chat-history-body") this.chatHistoryBody = this.domItem.find(".chat-history-body")
this.sendBtnMessageDepartment = this.domItem.find("#send-msg-btn-deparment") this.sendBtnMessageDepartment = this.domItem.find("#send-msg-btn-deparment")
this.sendBtnMessageInternal= this.domItem.find("#send-msg-btn-internal") this.sendBtnMessageInternal = this.domItem.find("#send-msg-btn-internal")
this.chatSidebarLeftUserAbout = this.domItem.find('.chat-sidebar-left-user-about'),
this.messageInput = this.domItem.find(".message-input") this.messageInput = this.domItem.find(".message-input")
this.sideBar = this.domItem.find(".sidebar-body") this.sideBar = this.domItem.find(".sidebar-body")
this.chatDeparmentId = undefined this.chatDeparmentId = undefined
this.searchInput = this.domItem.find(".chat-search-input")
this.headers = {} this.headers = {}
this.chatContactsBody = document.querySelector('.app-chat-contacts .sidebar-body') this.chatContactsBody = this.domItem.find('.app-chat-contacts .sidebar-body')
this.chatContactListItems = [].slice.call( this.chatContactListItems = [].slice.call(
document.querySelectorAll('.chat-contact-list-item:not(.chat-contact-list-item-title)') document.querySelectorAll('.chat-contact-list-item:not(.chat-contact-list-item-title)')
) )
} }
init() { init() {
// Inicializar PerfectScrollbar
if (this.searchInput.length) {
this.searchInput.on('keyup', () => {
const searchValue = this.searchInput.val(),
chatListItem0 = this.domItem.find('.chat-list-item-0'),
contactListItem0 = this.domItem.find('.contact-list-item-0'),
searchChatListItems = this.domItem.find('#chat-list li:not(.chat-contact-list-item-title)'),
searchContactListItems = this.domItem.find('#contact-list li:not(.chat-contact-list-item-title)');
// Buscar en chats
const chatListItemsCount = this._searchChatContacts(searchChatListItems, searchValue);
// Mostrar u ocultar mensaje de "No se encontraron resultados" en chats
if (chatListItem0.length) {
chatListItem0.toggleClass('d-none', chatListItemsCount === 0);
}
// Buscar en contactos
const contactListItemsCount = this._searchChatContacts(searchContactListItems, searchValue);
// Mostrar u ocultar mensaje de "No se encontraron resultados" en contactos
if (contactListItem0.length) {
contactListItem0.toggleClass('d-none', contactListItemsCount === 0);
}
});
}
this.sendBtnMessageDepartment.addClass("d-none") this.sendBtnMessageDepartment.addClass("d-none")
this.sendBtnMessageInternal.addClass("d-none") this.sendBtnMessageInternal.addClass("d-none")
if (this.chatContactsBody) { if (this.chatContactsBody[0]) {
this.scrollbarContacts = new PerfectScrollbar(this.chatContactsBody, { this.scrollbarContacts = new PerfectScrollbar(this.chatContactsBody[0], {
wheelPropagation: false, wheelPropagation: false,
suppressScrollX: true suppressScrollX: true
}); });
} }
if (this.chatHistoryBody) { if (this.chatHistoryBody[0]) {
this.scrollbarChatHistory = new PerfectScrollbar(this.chatHistoryBody, { this.scrollbarChatHistory = new PerfectScrollbar(this.chatHistoryBody[0], {
wheelPropagation: false, wheelPropagation: false,
suppressScrollX: true suppressScrollX: true
}); });
@ -69,13 +93,28 @@ class Chat {
this.chatType = "internal" this.chatType = "internal"
} }
_setBtnInternal()
{ _searchChatContacts(searchListItems, searchValue) {
let searchListItemsCount = 0;
searchListItems.each(function () {
const searchListItemText = $(this).text().toLowerCase();
const matchesSearch = searchListItemText.indexOf(searchValue) !== -1;
$(this).toggleClass('d-flex', matchesSearch);
$(this).toggleClass('d-none', !matchesSearch);
if (matchesSearch) {
searchListItemsCount++;
}
});
return searchListItemsCount;
}
_setBtnInternal() {
this.sendBtnMessageInternal.removeClass("d-none") this.sendBtnMessageInternal.removeClass("d-none")
this.sendBtnMessageDepartment.addClass("d-none") this.sendBtnMessageDepartment.addClass("d-none")
} }
_setBtnDeparment() _setBtnDeparment() {
{
this.sendBtnMessageDepartment.removeClass("d-none") this.sendBtnMessageDepartment.removeClass("d-none")
this.sendBtnMessageInternal.addClass("d-none") this.sendBtnMessageInternal.addClass("d-none")
} }
@ -98,10 +137,13 @@ class Chat {
Object.values(data).map(row => { Object.values(data).map(row => {
this.chatList.append(this._getContact(row)) this.chatList.append(this._getContact(row))
this.chatList.find(`#chat_${row.name}`).on("click", (event) => { this.chatList.find(`#chat_${row.name}`).on("click", (event) => {
let chatDeparmentId = this.chatList.find(`#chat_${row.name}`).data("id") $(".chat-contact-list-item").removeClass("active")
$(event.currentTarget).parent().addClass("active")
this.chatDeparmentId = this.chatList.find(`#chat_${row.name}`).data("id")
this.domItem.find(".chat-history-header div.chat-contact-info h6").text(row.display) this.domItem.find(".chat-history-header div.chat-contact-info h6").text(row.display)
this.domItem.find(".chat-history-header div.chat-contact-info small.user-status").text(row.display) this.domItem.find(".chat-history-header div.chat-contact-info small.user-status").text(row.display)
this._getChatMessage(chatDeparmentId) this._getChatMessage()
this._getChatDeparmentUsers()
}) })
}) })
@ -110,6 +152,48 @@ class Chat {
_handleGetChatListError(error) { _handleGetChatListError(error) {
console.error(error) console.error(error)
} }
_getChatDeparmentUsers() {
this.domItem.find("#chat-header-users").empty()
this.domItem.find("#chat-header-dropdown-users").removeClass("d-none")
let ajax = new Ajax(
`/chat/department/${this.chatDeparmentId}/users`,
null,
null,
this._getChatDeparmentUsersSuccess.bind(this),
this._getChatDeparmentUsersError.bind(this),
)
ajax.get()
}
_getChatDeparmentUsersSuccess(deparmentUsers) {
deparmentUsers.map((user) => {
this.domItem.find("#chat-header-users").append(
`
<li class="chat-contact-list-item p-1">
<a class="d-flex align-items-center py-1"
id="chat-contact-list-item-${user.id}">
<div class="avatar d-block flex-shrink-0">
<span class="avatar-initial rounded-circle bg-label-primary">
${user?.first_name?.charAt(0) ?? "?"
+ user?.last_name?.charAt(0) ?? "?"}</span>
</div>
<div class="chat-contact-info flex-grow-1 ms-2">
<h6 class="chat-contact-name text-truncate m-0">${user?.first_name ?? "" + " " +
user?.last_name ?? ""}</h6>
<p class="chat-contact-status text-muted text-truncate mb-0">
${user.username}
</p>
</div>
</a>
</li>
`
)
})
}
_getChatDeparmentUsersError(err) { }
_getContact(row) { _getContact(row) {
let chat = ` let chat = `
<li class="chat-contact-list-item"> <li class="chat-contact-list-item">
@ -128,8 +212,7 @@ class Chat {
` `
return chat return chat
} }
_getChatMessage(chatDeparmentId) { _getChatMessage() {
this.chatDeparmentId = chatDeparmentId
let ajax = new Ajax( let ajax = new Ajax(
`/chat/department/${this.chatType}/${this.chatDeparmentId}/${this.modelId}`, `/chat/department/${this.chatType}/${this.chatDeparmentId}/${this.modelId}`,
null, null,
@ -213,7 +296,7 @@ class Chat {
} }
_handleListContacts() { _handleListContacts() {
this.sideBar.find("#contact-list").removeClass("d-none") this.sideBar.find("#contact-list").removeClass("d-none")
this.sendBtnMessageInternal.on("click",this._sendMessageInternal.bind(this)) this.sendBtnMessageInternal.on("click", this._sendMessageInternal.bind(this))
let ajax = new Ajax( let ajax = new Ajax(
"/chat/contacts", "/chat/contacts",
null, null,
@ -234,7 +317,11 @@ class Chat {
this.sideBar.find("#contact-list").removeClass("d-none") this.sideBar.find("#contact-list").removeClass("d-none")
} }
this.sideBar.find(".contact-chat").on("click", (e) => { this.sideBar.find(".contact-chat").on("click", (e) => {
$(".contact-chat").parent().removeClass("active")
$(".chat-contact-list-item").removeClass("active")
this.domItem.find("#chat-header-dropdown-users").addClass("d-none")
let userId = $(e.currentTarget).data("id") let userId = $(e.currentTarget).data("id")
$(e.currentTarget).parent().addClass('active')
this.receiverId = userId this.receiverId = userId
this._handleGetSingleContact(userId) this._handleGetSingleContact(userId)
this._setBtnInternal() this._setBtnInternal()
@ -324,7 +411,8 @@ class Chat {
${contact.username} ${contact.username}
</p> </p>
</div> </div>
${contact.unreadMessages ? `<span class="badge badge-center rounded-pill bg-primary">${contact.unreadMessages}</span>` : ""} ${contact.unreadMessages ? `<span
class="badge badge-center rounded-pill bg-primary">${contact.unreadMessages}</span>` : ""}
</a> </a>
</li> </li>
` `
@ -339,6 +427,100 @@ class Chat {
}
export const showNotificationMessages = (dom) => {
let ajax = new Ajax(
'/chat/notifications',
null,
null,
(data) => {
let totalMessages = 0
data?.chatPresupuestos?.map((e) => {
console.log(e)
let numberOfMessages = 0
e.messages.forEach(m => {
m.viewed == "1" ? numberOfMessages++ : null
});
totalMessages+= numberOfMessages
if(numberOfMessages > 0){
dom.append(
`
<li class="">
<a href="/presupuestos/cosidotapablanda/edit/${e.presupuestoId}" class="d-flex align-items-center flex-grow">
<div class="avatar d-block flex-shrink-0">
<span class="avatar-initial rounded-circle bg-label-primary">${e.presupuestoId}</span>
</div>
<div class="chat-contact-info flex-grow-1 ms-2">
<h6 class="chat-contact-name text-truncate m-0">[${e.title}] ${e.chatDisplay}</h6>
</div>
<span class="badge badge-center rounded-pill bg-primary">${numberOfMessages}</span>
</a>
</li>
`
)
}
})
data?.chatFacturas?.map((e) => {
console.log(e)
let numberOfMessages = 0
e.messages.forEach(m => {
m.viewed == "1" ? numberOfMessages++ : null
});
totalMessages+= numberOfMessages
if(numberOfMessages > 0){
dom.append(
`
<li class="">
<a href="/presupuestos/cosidotapablanda/edit/${e.facturaId}" class="d-flex align-items-center flex-grow">
<div class="avatar d-block flex-shrink-0">
<span class="avatar-initial rounded-circle bg-label-primary">${e.facturaId}</span>
</div>
<div class="chat-contact-info flex-grow-1 ms-2">
<h6 class="chat-contact-name text-truncate m-0">[${e.title}] ${e.chatDisplay}</h6>
</div>
<span class="badge badge-center rounded-pill bg-primary">${numberOfMessages}</span>
</a>
</li>
`
)
}
})
data?.chatPedidos?.map((e) => {
console.log(e)
let numberOfMessages = 0
e.messages.forEach(m => {
m.viewed == "1" ? numberOfMessages++ : null
});
$("#chat-notification-number").text(numberOfMessages)
totalMessages+= numberOfMessages
if(numberOfMessages > 0){
dom.append(
`
<li class="">
<a href="/presupuestos/cosidotapablanda/edit/${e.pedidoId}" class="d-flex align-items-center flex-grow">
<div class="avatar d-block flex-shrink-0">
<span class="avatar-initial rounded-circle bg-label-primary">${e.pedidoId}</span>
</div>
<div class="chat-contact-info flex-grow-1 ms-2">
<h6 class="chat-contact-name text-truncate m-0">[${e.title}] ${e.chatDisplay}</h6>
</div>
<span class="badge badge-center rounded-pill bg-primary">${numberOfMessages}</span>
</a>
</li>
`
)
}
})
$("#chat-notification-number").text(totalMessages)
},
(err) => { }
)
ajax.get()
} }
export default Chat export default Chat

View File

@ -0,0 +1,3 @@
import {showNotificationMessages} from "../components/chat.js";
showNotificationMessages($("#chat-notification-list"))