messages departments section

This commit is contained in:
amazuecos
2025-03-20 08:20:50 +01:00
parent d417db18e2
commit 6e96beeec8
26 changed files with 1045 additions and 306 deletions

View File

@ -12,6 +12,7 @@ class Chat {
this.modelId = this.domItem.data("id")
this.chatHistoryBody = this.domItem.find(".chat-history-body")
this.sendBtnMessageDepartment = this.domItem.find("#send-msg-btn-deparment")
this.sendBtnMessageDepartmentClient = this.domItem.find("#send-msg-btn-deparment-client")
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")
@ -126,11 +127,15 @@ class Chat {
this.chatType = "general"
this._handleGetChatList()
this.sendBtnMessageDepartment.on("click", this._sendMessage.bind(this))
this.sendBtnMessageDepartmentClient.on("click", this._sendMessage.bind(this))
}
initPresupuesto() {
this.chatType = "presupuesto"
this._handleGetChatList()
this.sendBtnMessageDepartment.on("click", this._sendMessage.bind(this))
this.sendBtnMessageDepartmentClient.on("click", this._sendMessage.bind(this))
this.messageInput.on("keypress", this._sendMessagePressKey.bind(this))
this.initSelectClient()
@ -141,6 +146,7 @@ class Chat {
this.chatType = "pedido"
this._handleGetChatList()
this.sendBtnMessageDepartment.on("click", this._sendMessage.bind(this))
this.sendBtnMessageDepartmentClient.on("click", this._sendMessage.bind(this))
this.messageInput.on("keypress", this._sendMessagePressKey.bind(this))
this.initSelectClient()
@ -150,6 +156,7 @@ class Chat {
this.chatType = "factura"
this._handleGetChatList()
this.sendBtnMessageDepartment.on("click", this._sendMessage.bind(this))
this.sendBtnMessageDepartmentClient.on("click", this._sendMessage.bind(this))
this.messageInput.on("keypress", this._sendMessagePressKey.bind(this))
this.initSelectClient()
@ -215,10 +222,14 @@ class Chat {
this._getChatMessage()
this._getChatTotalMessages(row.name)
this._getChatDeparmentUsers()
})
})
this.chatList.find(`#chat__produccion`).trigger("click");
if (Object.values(data)) {
const firstDepartment = Object.values(data)[0]
this.chatList.find(`#chat_${firstDepartment.name}`).trigger("click");
}
}
_handleGetChatListError(error) {
console.error(error)
@ -356,10 +367,9 @@ class Chat {
</div>
<div class="text-${chatMessage?.pos == "left" ? "start" : "end"} text-muted mt-1">
<div class="text-${chatMessage?.pos == "left" ? "start" : "end"} text-muted mt-1">
<i class="ti me-1"></i>
<small>${chatMessage?.user?.first_name + " " + chatMessage?.user?.last_name}</small>
</div>
<i class="ti ${chatMessage?.viewed ? "ti-checks" : "ti-check"} ti-xs me-1 text-success"></i>
<i class="ti ${chatMessage?.viewed == 1 ? "ti-checks" : "ti-check"} ti-xs me-1 text-success"></i>
<small>${chatMessage.created_at}</small>
</div>
@ -426,7 +436,7 @@ class Chat {
message: messageText,
chat_department_id: this.chatDeparmentId,
user: this.userId,
client: this.selectClientUser.getVal(),
client: this.selectClientUser.getVal() ?? null,
model_id: this.modelId
}
if (messageText) {
@ -745,7 +755,7 @@ class Chat {
_handleRequestExitChatDeparment() {
const ajax = new Ajax('/chat/department/user/' + this.chatDeparmentId,
{
model_fk: this.chatType,
model_fk: this.chatType + "_id",
model_id_fk: this.modelId
},
null,
@ -768,7 +778,7 @@ class Chat {
const ajax = new Ajax('/chat/department/user',
{
chat_department_id: this.chatDeparmentId,
model_fk: this.chatType,
model_fk: this.chatType + "_id",
model_id_fk: this.modelId
},
null,

View File

@ -0,0 +1,160 @@
import Ajax from "../ajax.js";
import { alertConfirmationDelete, alertSuccess, alertError, alertConfirmAction } from '../alerts/sweetAlert.js'
export class ChatDepartmentDatatable {
constructor(domItem) {
this.item = domItem
this.chatDepartmentDisplay = $("#chat-department-display")
this.btnStoreChatDepartment = $("#btn-add-new-chat-department")
this.datatableColumns = [
{ data: 'id', searchable: false, sortable: true },
{ data: 'display', searchable: true, sortable: true },
{ data: 'description', searchable: true, sortable: true },
{
data: 'action', searchable: false, sortable: false,
render: (d, t) => {
return `<div class="btn-group btn-group-sm">
<a href="/chat/department/edit/${d}" class="chat-department-edit" ><i class="ti ti-eye ti-sm mx-2"></i></a>
<a href="javascript:void(0);" class="chat-department-delete" data-id="${d}" ><i class="ti ti-trash ti-sm mx-2"></i></a>
</div>`
}
}
]
}
init() {
this.btnStoreChatDepartment.on('click', this.storeNewChatDepartment.bind(this))
this.item.on('click', '.chat-department-delete', this.deleteChatDepartment.bind(this))
this.datatable = this.item.DataTable({
processing: true,
order: [[0, 'asc']],
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
serverSide: true,
pageLength: 10,
language: {
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
},
columns: this.datatableColumns,
ajax: '/chat/department/datatable'
});
}
deleteChatDepartment(event) {
const ajax = new Ajax(
`/chat/department/${$(event.currentTarget).data("id")}`,
null,
null,
this.deleteChatDepartmentSuccess.bind(this),
this.deleteChatDepartmentError.bind(this)
)
alertConfirmationDelete().then(result => {
if (result.isConfirmed) {
ajax.delete()
}
})
}
deleteChatDepartmentSuccess(response) {
this.datatable.ajax.reload()
alertSuccess(response.message).fire()
}
deleteChatDepartmentError(response) {
alertError(response.message).fire()
}
storeNewChatDepartment() {
this.btnStoreChatDepartment.attr("disabled")
const ajax = new Ajax("/chat/department", {
display: this.chatDepartmentDisplay.val()
},
null,
this.storeNewChatDepartmentSuccess.bind(this),
this.storeNewChatDepartmentError.bind(this)
)
if (this.chatDepartmentDisplay.val()) {
alertConfirmAction().then(result => {
if (result.isConfirmed) {
ajax.post()
}
})
} else {
this.btnStoreChatDepartment.removeAttr("disabled")
}
}
storeNewChatDepartmentSuccess(response) {
this.datatable.ajax.reload()
alertSuccess(response.message).fire()
}
storeNewChatDepartmentError(response) {
console.log(response)
alertError(response.message).fire()
}
}
export class ChatDepartmentUserDatatable {
constructor(domItem) {
this.item = domItem
this.datatableColumns = [
{ data: 'userFullName', searchable: true, sortable: true },
{ data: 'username', searchable: true, sortable: true },
{
data: 'action', searchable: false, sortable: false,
render: (d, t) => {
return `<div class="btn-group btn-group-sm">
<a type="button" href="javascript:void(0);" data-id="${d}" class="chat-department-user-delete"><i class="ti ti-trash ti-sm mx-2"></i></a>
</div>`
}
}
]
}
init() {
this.actions()
this.datatable = this.item.DataTable({
processing: true,
order: [[0, 'desc']],
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
serverSide: true,
pageLength: 10,
language: {
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
},
columns: this.datatableColumns,
ajax: '/chat/department/users/datatable/' + this.item.data('id')
});
}
actions() {
this.item.on("click", ".chat-department-user-delete", this.deleteRow.bind(this))
}
deleteRow(event) {
const ajax = new Ajax(`/chat/department/admin/user/${this.item.data('id')}/${$(event.currentTarget).data("id")}`,
null,
null,
this.deleteRowSuccess.bind(this),
this.deleteRowError.bind(this),
)
alertConfirmationDelete().then(result => {
if (result.isConfirmed) {
ajax.delete()
}
})
}
deleteRowSuccess(response) {
this.datatable.ajax.reload();
alertSuccess(response.message).fire()
}
deleteRowError(response) {
alertError(response?.message).fire()
}
}

View File

@ -134,33 +134,49 @@ class MessagesDatatable {
}
handleDropUpSuccess(response) {
const chatId = response.chat_id
const users = response.data
if (users.length > 0) {
const unviewedNotifications = response.data.unviewedNotifications
const viewedNotifications = response.data.viewedNotifications
users.forEach(user => {
const viewed = (user.notification_count - user.viewed_count) == 0
if (unviewedNotifications.length > 0) {
unviewedNotifications.forEach(user => {
if (user.userFullName || user.userName) {
$(`#dropdown-viewed-${chatId}`)
.append(`
<li >
<a class="d-flex flex-row justify-content-start align-items-center dropdown-item px-2 gap-2" href="javascript:void(0);" >
<span> ${user.userFullName ?? user.userName} </span>
<span class="badge badge-center rounded-pill text-bg-secondary">
<i class="ti ti-xs ti-${viewed ? "eye-check" : "eye-off"} "></i>
</span>
</a>
</li>
`)
.append(this.addDropUpItem(user))
}
});
} else {
$(`#dropdown-viewed-${chatId}`).append(`<li><a class="dropdown-item" href="javascript:void(0);" >Visto</a></li>`)
}
if (viewedNotifications.length > 0) {
viewedNotifications.forEach(user => {
if (user.userFullName || user.userName) {
$(`#dropdown-viewed-${chatId}`)
.append(this.addDropUpItem(user))
}
});
}
}
handleDropUpError() { }
addDropUpItem(user)
{
return `
<li >
<a type="button" class="d-flex flex-row justify-content-between align-items-center dropdown-item px-2 gap-2" href="javascript:void(0);" >
<span> ${user.userFullName ?? user.userName} </span>
<span class="badge badge-center rounded-pill text-bg-${
user.viewed == 1 ? 'success' : 'danger'
}">
<i class="ti ti-xs ti-${
user.viewed == 1 ? 'eye-check' : 'eye-off'
} "></i>
</span>
</a>
</li>`;
}
}

View File

@ -0,0 +1,91 @@
import ClassSelect from "../select2.js"
import { ChatDepartmentUserDatatable } from '../datatables/ChatDepartmentDatatable.js'
import Ajax from "../ajax.js"
import { alertConfirmAction, alertError, alertSuccess } from "../alerts/sweetAlert.js"
class ChatDepartmentForm {
constructor(domItem) {
this.item = domItem
this.chatDepartmentId = this.item.data("id")
this.btnAddUserToDepartment = this.item.find("#add-user-admin-chat-department")
this.btnUpdate = this.item.find("#btn-chat-department-update")
this.chatDepartmentUsersDatatable = new ChatDepartmentUserDatatable($("#tableChatDepartmentUsers"))
this.seletChatDepartmentUserItem = this.item.find("#selectChatDepartmentUser")
this.seletChatDepartmentUser = new ClassSelect(
this.seletChatDepartmentUserItem,
`/chat/department/users/select/add/${this.chatDepartmentId}`
)
}
init() {
this.seletChatDepartmentUser.init()
this.chatDepartmentUsersDatatable.init()
this.btnAddUserToDepartment.on('click', this._handleUserToDepartment.bind(this))
this.btnUpdate.on("click", this._handleUpdateDepartment.bind(this))
}
getFormData() {
return {
display: this.item.find("#chat-department-display").val(),
description: this.item.find("#chat-department-description").val()
}
}
updateFormData(data) {
this.item.find("#chat-department-display").val(data.display)
this.item.find("#chat-department-description").val(data.description)
}
_handleUserToDepartment() {
this.btnAddUserToDepartment.attr("disabled", "disabled")
const ajax = new Ajax("/chat/department/subscribe/admin/user",
{
user_id: this.seletChatDepartmentUser.getVal(),
chat_department_id: this.chatDepartmentId
},
null,
this._handleUserToDepartmentSuccess.bind(this),
this._handleUserToDepartmentError.bind(this)
)
if (this.seletChatDepartmentUser.getVal()) {
ajax.post();
} else {
this.btnAddUserToDepartment.removeAttr("disabled")
}
}
_handleUserToDepartmentSuccess(response) {
this.btnAddUserToDepartment.removeAttr("disabled")
this.chatDepartmentUsersDatatable.datatable.ajax.reload()
alertSuccess(response.message).fire()
this.seletChatDepartmentUser.reset()
}
_handleUserToDepartmentError(response) {
alertError(response.message ?? "").fire()
this.btnAddUserToDepartment.removeAttr("disabled")
}
_handleUpdateDepartment() {
this.btnUpdate.attr("disabled")
const ajax = new Ajax("/chat/department/update/" + this.chatDepartmentId,
this.getFormData(),
null,
this._handleUserToDepartmentSuccess.bind(this),
this._handleUserToDepartmentError.bind(this)
)
if (this.getFormData()) {
ajax.post();
} else {
this.btnUpdate.removeAttr("disabled")
}
}
__handleUpdateDepartmentSuccess(response) {
this.btnUpdate.removeAttr("disabled")
alertSuccess(response.message).fire()
this.updateFormData(response.data)
}
_handleUpdateDepartmentError(response) {
this.btnUpdate.removeAttr("disabled")
alertError(response.message ?? "").fire()
}
}
export default ChatDepartmentForm

View File

@ -5,97 +5,96 @@
* @param {String} placeholder
*/
let ClassSelect = function (domItem, url, placeholder, allowClear = false, params = {}, dropdownParent = "", hideSearch = false) {
this.url = url;
this.item = domItem;
this.params = params;
this.dropdownParent = dropdownParent;
this.hideSearch = hideSearch;
this.url = url;
this.item = domItem;
this.params = params;
this.dropdownParent = dropdownParent;
this.hideSearch = hideSearch;
this.config = {
placeholder: placeholder,
allowClear: allowClear,
dropdownParent: dropdownParent!=""?dropdownParent:domItem.parent(),
language: "es",
ajax: {
url: () => {
return this.url;
},
data: (params) => {
let q = $.trim(params.term);
let d = {
q: q,
page: params.page || 1,
};
for (let key in this.params) {
d[key] = this.params[key];
}
return d;
},
processResults: function (data) {
return {
results: $.map(data, function (obj) {
return {
id: obj.id,
text: obj.nombre ?? obj.name,
desc: obj.description,
};
}),
};
},
cache: true,
this.config = {
placeholder: placeholder,
allowClear: allowClear,
dropdownParent: dropdownParent != "" ? dropdownParent : domItem.parent(),
language: "es",
ajax: {
url: () => {
return this.url;
},
};
this.init = function () {
if (this.item.length) {
data: (params) => {
let q = $.trim(params.term);
let d = {
q: q,
page: params.page || 1,
};
if(this.hideSearch){
this.config.minimumResultsForSearch = -1;
for (let key in this.params) {
d[key] = this.params[key];
}
this.item = this.item.select2(this.config);
// $.fn.modal.Constructor.prototype.enforceFocus = function () {};
}
};
this.setOption = function (id, nombre) {
var newOption = new Option(nombre , id, false, false);
this.item.append(newOption);
this.item.val(id).trigger("change");
};
this.reset = function () {
this.item.val(null).trigger("change");
};
this.setParams = function(params){
this.params = params;
};
this.getVal = function () {
return this.item.val();
};
this.setVal = function (val) {
return this.item.val(val).trigger("change");
};
this.empty = function () {
return this.item.empty().trigger("change");
};
this.readOnly = function () {
this.item.enable(false);
};
this.enable = () => {
this.item.enable(true);
};
this.fixWithScroll = function () {};
this.getText = () => {
return this.item.find(":selected").text();
};
this.onChange = function(callback) {
this.item.on('change', callback);
};
this.offChange = function() {
this.item.off('change');
};
return d;
},
processResults: function (data) {
return {
results: $.map(data, function (obj) {
return {
id: obj.id,
text: obj.nombre ?? obj.name,
desc: obj.description,
};
}),
};
},
cache: true,
},
};
this.init = function () {
if (this.item.length) {
if (this.hideSearch) {
this.config.minimumResultsForSearch = -1;
}
this.item = this.item.select2(this.config);
// $.fn.modal.Constructor.prototype.enforceFocus = function () {};
}
};
this.setOption = function (id, nombre) {
var newOption = new Option(nombre, id, false, false);
this.item.append(newOption);
this.item.val(id).trigger("change");
};
this.reset = function () {
this.item.val(null).trigger("change");
};
this.setParams = function (params) {
this.params = params;
};
this.getVal = function () {
return this.item.val();
};
this.setVal = function (val) {
return this.item.val(val).trigger("change");
};
this.empty = function () {
return this.item.empty().trigger("change");
};
this.readOnly = function () {
this.item.enable(false);
};
this.enable = () => {
this.item.enable(true);
};
this.fixWithScroll = function () { };
this.getText = () => {
return this.item.find(":selected").text();
};
this.onChange = function (callback) {
this.item.on('change', callback);
};
this.offChange = function () {
this.item.off('change');
};
};
export default ClassSelect;

View File

@ -0,0 +1,13 @@
import Ajax from '../../../components/ajax.js'
import { ChatDepartmentDatatable } from '../../../components/datatables/ChatDepartmentDatatable.js'
$(() => {
const chatDepartmentDatatable = new ChatDepartmentDatatable($("#tableChatDepartments"))
chatDepartmentDatatable.init()
})

View File

@ -0,0 +1,8 @@
import ChatDepartmentForm from '../../../components/forms/chatDepartmentForm.js'
$(() => {
const chatDepartmentForm = new ChatDepartmentForm($("#chatDepartmentForm"))
chatDepartmentForm.init()
})