diff --git a/backend/src/controllers/SettingController.ts b/backend/src/controllers/SettingController.ts index 10b7f8e..7144a89 100644 --- a/backend/src/controllers/SettingController.ts +++ b/backend/src/controllers/SettingController.ts @@ -7,9 +7,9 @@ import UpdateSettingService from "../services/SettingServices/UpdateSettingServi import ListSettingsService from "../services/SettingServices/ListSettingsService"; export const index = async (req: Request, res: Response): Promise => { - if (req.user.profile !== "master") { - throw new AppError("ERR_NO_PERMISSION", 403); - } + // if (req.user.profile !== "master") { + // throw new AppError("ERR_NO_PERMISSION", 403); + // } const settings = await ListSettingsService(); diff --git a/backend/src/database/seeds/20230719121844-add-edit-ura-settings.ts b/backend/src/database/seeds/20230719121844-add-edit-ura-settings.ts new file mode 100644 index 0000000..98c27f5 --- /dev/null +++ b/backend/src/database/seeds/20230719121844-add-edit-ura-settings.ts @@ -0,0 +1,22 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.bulkInsert( + "Settings", + [ + { + key: "editURA", + value: "enabled", + createdAt: new Date(), + updatedAt: new Date() + } + ], + {} + ); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.bulkDelete("Settings", {}); + } +}; diff --git a/backend/src/database/seeds/20230719184620-add-edit-queue-settings.ts b/backend/src/database/seeds/20230719184620-add-edit-queue-settings.ts new file mode 100644 index 0000000..71d598a --- /dev/null +++ b/backend/src/database/seeds/20230719184620-add-edit-queue-settings.ts @@ -0,0 +1,22 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.bulkInsert( + "Settings", + [ + { + key: "editQueue", + value: "enabled", + createdAt: new Date(), + updatedAt: new Date() + } + ], + {} + ); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.bulkDelete("Settings", {}); + } +}; diff --git a/backend/src/routes/settingRoutes.ts b/backend/src/routes/settingRoutes.ts index 5a1ffa0..7047a63 100644 --- a/backend/src/routes/settingRoutes.ts +++ b/backend/src/routes/settingRoutes.ts @@ -5,9 +5,7 @@ import * as SettingController from "../controllers/SettingController"; const settingRoutes = Router(); - - -settingRoutes.get("/settings", isAuth, SettingController.index); +settingRoutes.get("/settings", SettingController.index); // routes.get("/settings/:settingKey", isAuth, SettingsController.show); diff --git a/backend/src/services/StatusChatEndService/ShowStatusChatEndService.ts b/backend/src/services/StatusChatEndService/ShowStatusChatEndService.ts index 12c6aaf..085e591 100644 --- a/backend/src/services/StatusChatEndService/ShowStatusChatEndService.ts +++ b/backend/src/services/StatusChatEndService/ShowStatusChatEndService.ts @@ -1,8 +1,14 @@ import StatusChatEnd from "../../models/StatusChatEnd"; import AppError from "../../errors/AppError"; -const ShowStatusChatEndService = async (id: string | number): Promise => { - const status = await StatusChatEnd.findByPk(id, { attributes: ['id', 'name'], }); +const ShowStatusChatEndService = async ( + id: string | number +): Promise => { + const status = await StatusChatEnd.findByPk(id, { + attributes: ["id", "name"] + }); + + console.log(`---------------> statusChatEnd id: ${id}`); if (!status) { throw new AppError("ERR_NO_STATUS_FOUND", 404); @@ -11,4 +17,4 @@ const ShowStatusChatEndService = async (id: string | number): Promise => { - + console.log("========> queueId: ", queueId); try { - const defaultWhatsapp = await GetDefaultWhatsApp(userId); - if (!queueId) { - const user = await User.findByPk(userId, { raw: true, }) - const matchingQueue = await whatsappQueueMatchingUserQueue(userId, defaultWhatsapp, user?.profile); - queueId = matchingQueue ? matchingQueue.queueId : undefined + const user = await User.findByPk(userId, { raw: true }); + const matchingQueue = await whatsappQueueMatchingUserQueue( + userId, + defaultWhatsapp, + user?.profile + ); + queueId = matchingQueue ? matchingQueue.queueId : undefined; } await CheckContactOpenTickets(contactId); @@ -66,27 +65,32 @@ const CreateTicketService = async ({ // console.log('CONTACT ticket.id: ', ticket.id) - - // TEST DEL + // TEST DEL try { - - let jsonString = JSON.stringify(ticket); //convert to string to remove the sequelize specific meta data + let jsonString = JSON.stringify(ticket); //convert to string to remove the sequelize specific meta data let ticket_obj = JSON.parse(jsonString); //to make plain json - delete ticket_obj['contact']['extraInfo'] + delete ticket_obj["contact"]["extraInfo"]; - ticket_obj = flatten(ticket_obj) - - await createOrUpdateTicketCache(`ticket:${ticket.id}`, ticket_obj) + ticket_obj = flatten(ticket_obj); + await createOrUpdateTicketCache(`ticket:${ticket.id}`, ticket_obj); } catch (error) { - console.log('There was an error on UpdateTicketService.ts on createTicketCache from user: ', error) + console.log( + "There was an error on UpdateTicketService.ts on createTicketCache from user: ", + error + ); } // + const dateToday = splitDateTime( + new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR })) + ); - const dateToday = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }))) - - TicketEmiterSumOpenClosedByUser(userId.toString(), dateToday.fullDate, dateToday.fullDate) + TicketEmiterSumOpenClosedByUser( + userId.toString(), + dateToday.fullDate, + dateToday.fullDate + ); const io = getIO(); io.emit("ticketStatus", { @@ -94,14 +98,11 @@ const CreateTicketService = async ({ ticketStatus: { ticketId: ticket.id, status: ticket.status } }); - return ticket; - } catch (error: any) { - console.error('===> Error on CreateTicketService.ts file: \n', error) + console.error("===> Error on CreateTicketService.ts file: \n", error); throw new AppError(error.message); } - }; export default CreateTicketService; diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index dbb3ffa..4b2c774 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -5,12 +5,10 @@ import * as Sentry from "@sentry/node"; import { copyFolder } from "../../helpers/CopyFolder"; import { removeDir } from "../../helpers/DeleteDirectory"; -import path from 'path'; +import path from "path"; import { format } from "date-fns"; -import ptBR from 'date-fns/locale/pt-BR'; - - +import ptBR from "date-fns/locale/pt-BR"; import { Contact as WbotContact, @@ -36,19 +34,18 @@ import UpdateTicketService from "../TicketServices/UpdateTicketService"; import { date } from "faker"; import ShowQueueService from "../QueueService/ShowQueueService"; -import ShowTicketMessage from "../TicketServices/ShowTicketMessage" -import BotIsOnQueue from "../../helpers/BotIsOnQueue" +import ShowTicketMessage from "../TicketServices/ShowTicketMessage"; +import BotIsOnQueue from "../../helpers/BotIsOnQueue"; import Queue from "../../models/Queue"; -import fs from 'fs'; +import fs from "fs"; import { StartWhatsAppSession } from "../../services/WbotServices/StartWhatsAppSession"; -import { removeWbot } from '../../libs/wbot' +import { removeWbot } from "../../libs/wbot"; import { restartWhatsSession } from "../../helpers/RestartWhatsSession"; - -import data_ura from './ura' -import msg_client_transfer from './ura_msg_transfer' +import data_ura from "./ura"; +import msg_client_transfer from "./ura_msg_transfer"; import final_message from "./ura_final_message"; import SendWhatsAppMessage from "./SendWhatsAppMessage"; import Whatsapp from "../../models/Whatsapp"; @@ -56,19 +53,25 @@ import { splitDateTime } from "../../helpers/SplitDateTime"; import { queryDialogFlow } from "../DialogflowServices/QueryDialogflow"; import { createDialogflowSessionWithModel } from "../DialogflowServices/CreateSessionDialogflow"; -import bot_actions from './BotActions' +import bot_actions from "./BotActions"; import ShowTicketService from "../TicketServices/ShowTicketService"; -import { updateTicketCacheByTicketId } from '../../helpers/TicketCache' +import { updateTicketCacheByTicketId } from "../../helpers/TicketCache"; import endPointQuery from "../../helpers/EndpointQuery"; import { Console } from "console"; import ShowContactCustomFieldService from "../ContactServices/ShowContactCustomFieldsService"; -import { insertMessageContactCache, getLastId } from '../../helpers/LastMessageIdByContactCache' +import { + insertMessageContactCache, + getLastId +} from "../../helpers/LastMessageIdByContactCache"; import autoRestore from "../../helpers/AutoRestore"; import { _restore } from "../../helpers/RestoreControll"; import sendWhatsAppMessageSocket from "../../helpers/SendWhatsappMessageSocket"; -import { getWhatsappIds, setWhatsappId } from "../../helpers/WhatsappIdMultiSessionControl"; +import { + getWhatsappIds, + setWhatsappId +} from "../../helpers/WhatsappIdMultiSessionControl"; import SendWhatsAppMedia from "./SendWhatsAppMedia"; import AppError from "../../errors/AppError"; import { tr } from "date-fns/locale"; @@ -79,10 +82,7 @@ import FindOrCreateQueryItemService from "../SLM/FindOrCreateQueryItemService"; import ShowQueryItemService from "../SLM/ShowQueryItemService"; import QueryItem from "../../models/QueryItem"; - - -var lst: any[] = getWhatsappIds() - +var lst: any[] = getWhatsappIds(); interface Session extends Client { id?: number; @@ -130,7 +130,7 @@ const verifyMediaMessage = async ( ticket: Ticket, contact: Contact, media: any, - quotedMsg?: any, + quotedMsg?: any ): Promise => { // const quotedMsg = await verifyQuotedMessage(msg); @@ -140,12 +140,15 @@ const verifyMediaMessage = async ( throw new Error("ERR_WAPP_DOWNLOAD_MEDIA"); } - console.log('MEDIA.FILENAME: ', media.fileName, ' | msg.fromMe: ', msg.fromMe) + console.log( + "MEDIA.FILENAME: ", + media.fileName, + " | msg.fromMe: ", + msg.fromMe + ); if (!media.filename) { - - console.log('No file name -----------------------------------------') - + console.log("No file name -----------------------------------------"); const ext = media.mimetype.split("/")[1].split(";")[0]; media.filename = `${new Date().getTime()}.${ext}`; @@ -158,15 +161,13 @@ const verifyMediaMessage = async ( // "base64" // ); - console.log('FROM wbotMessageListener.ts media.filename: ', media.filename) - + console.log("FROM wbotMessageListener.ts media.filename: ", media.filename); await writeFileAsync( join(__dirname, "..", "..", "..", "..", "..", "public", media.filename), media.data, "base64" ); - } catch (err) { Sentry.captureException(err); logger.error(`There was an error: wbotMessageLitener.ts: ${err}`); @@ -195,11 +196,8 @@ const verifyMessage = async ( msg: WbotMessage, ticket: Ticket, contact: Contact, - quotedMsg?: any, + quotedMsg?: any ) => { - - - // const quotedMsg = await verifyQuotedMessage(msg); // const quotedMsg = await verifyQuotedMessage(msg); @@ -216,310 +214,303 @@ const verifyMessage = async ( // quotedMsgId: quotedMsg?.id }; - await ticket.update({ lastMessage: msg.body }); await CreateMessageService({ messageData }); }; - - const queryEndPointHit = async (centro_de_custo: string) => { + let msg_endpoint: any = []; - let msg_endpoint: any = [] - - let response2 = await endPointQuery('http://177.107.193.124:8095/labs/zabbix-frontend/api/api.php', 'post', { 'params[cod_web]': centro_de_custo.trim(), }) + let response2 = await endPointQuery( + "http://177.107.193.124:8095/labs/zabbix-frontend/api/api.php", + "post", + { "params[cod_web]": centro_de_custo.trim() } + ); if (response2 && response2.data.result) { - response2 = response2.data.result; - for (let i = 0; i < response2.length; i++) { - - let data = '' - let sub_data = '*Atualizações:*\n\n' + let data = ""; + let sub_data = "*Atualizações:*\n\n"; let properties: any = Object.entries(response2[i]); for (let x = 0; x < properties.length; x++) { - - if (typeof (properties[x][1]) != 'object') { - - if (properties[x][0] === 'n_chamado_web') { - properties[x][0] = 'Protocolo' - } - else if (properties[x][0] === 'nome_cliente') { - properties[x][0] = 'Nome do cliente' - } - else if (properties[x][0] === 'quando_inicio') { - properties[x][0] = 'Data de abertura' - } - else if (properties[x][0] === 'nome_filial') { - properties[x][0] = 'Nome da filial' - } - else if (properties[x][0] === 'cod_web') { - properties[x][0] = 'Codigo do cliente' - } - else if (properties[x][0] === 'id' || properties[x][0] === 'cliente_id') { - continue + if (typeof properties[x][1] != "object") { + if (properties[x][0] === "n_chamado_web") { + properties[x][0] = "Protocolo"; + } else if (properties[x][0] === "nome_cliente") { + properties[x][0] = "Nome do cliente"; + } else if (properties[x][0] === "quando_inicio") { + properties[x][0] = "Data de abertura"; + } else if (properties[x][0] === "nome_filial") { + properties[x][0] = "Nome da filial"; + } else if (properties[x][0] === "cod_web") { + properties[x][0] = "Codigo do cliente"; + } else if ( + properties[x][0] === "id" || + properties[x][0] === "cliente_id" + ) { + continue; } - - data += `*${properties[x][0]}*: ${properties[x][1].replace(/(\r\n|\n|\r)/gm, "")}\n` - - } - else if (typeof (properties[x][1]) == 'object') { - + data += `*${properties[x][0]}*: ${properties[x][1].replace( + /(\r\n|\n|\r)/gm, + "" + )}\n`; + } else if (typeof properties[x][1] == "object") { const sub_properties = properties[x][1]; for (let k = 0; k < sub_properties.length; k++) { - let inner_properties: any = Object.entries(sub_properties[k]); for (let y = 0; y < inner_properties.length; y++) { - - if (inner_properties[y][0] === 'texto') { - inner_properties[y][0] = 'Informação' - } - else if (inner_properties[y][0] === 'quando') { - inner_properties[y][0] = 'Data da Informação' - } - else if (inner_properties[y][0] === 'login') { - continue + if (inner_properties[y][0] === "texto") { + inner_properties[y][0] = "Informação"; + } else if (inner_properties[y][0] === "quando") { + inner_properties[y][0] = "Data da Informação"; + } else if (inner_properties[y][0] === "login") { + continue; } - sub_data += `*${inner_properties[y][0]}*: ${inner_properties[y][1].replace(/(\r\n|\n|\r)/gm, "")}\n` - + sub_data += `*${inner_properties[y][0]}*: ${inner_properties[ + y + ][1].replace(/(\r\n|\n|\r)/gm, "")}\n`; } - sub_data += '\n' - + sub_data += "\n"; } - } - } - msg_endpoint.push({ header: data, body: sub_data }) - + msg_endpoint.push({ header: data, body: sub_data }); } - - } - else { - msg_endpoint = null + } else { + msg_endpoint = null; } - return msg_endpoint - -} - - -const monitoramento_response2 = async (response: any | null, wbot: any, contact: any, ticket: any, centro_de_custo: any, final_message: string = '', send_empty_incident?: boolean) => { + return msg_endpoint; +}; +const monitoramento_response2 = async ( + response: any | null, + wbot: any, + contact: any, + ticket: any, + centro_de_custo: any, + final_message: string = "", + send_empty_incident?: boolean +) => { if (!response) { - // OLD // const msg = await wbot.sendMessage(`${contact.number}@c.us`, `Houve um erro ao tentar consultar o monitoramento da Operadora!${final_message}`); // await verifyMessage(msg, ticket, contact); // await new Promise(f => setTimeout(f, 1000)); - // NEW - await SendWhatsAppMessage({ body: `Houve um erro ao tentar consultar o monitoramento da Operadora!${final_message}`, ticket, number: `${contact.number}@c.us` }) - - } - else if (response.length > 0) { - + // NEW + await SendWhatsAppMessage({ + body: `Houve um erro ao tentar consultar o monitoramento da Operadora!${final_message}`, + ticket, + number: `${contact.number}@c.us` + }); + } else if (response.length > 0) { for (let i = 0; i < response.length; i++) { - // OLD // const msg = await wbot.sendMessage(`${contact.number}@c.us`, `*Situação do chamado na Operadora*\n\n*Incidente*:\n\n ${response[i].header}\n${response[i].body}${final_message}`); // await verifyMessage(msg, ticket, contact); // await new Promise(f => setTimeout(f, 1000)); // NEW - await SendWhatsAppMessage({ body: `*Situação do chamado na Operadora*\n\n*Incidente*:\n\n ${response[i].header}\n${response[i].body}${final_message}`, ticket, number: `${contact.number}@c.us` }) - - + await SendWhatsAppMessage({ + body: `*Situação do chamado na Operadora*\n\n*Incidente*:\n\n ${response[i].header}\n${response[i].body}${final_message}`, + ticket, + number: `${contact.number}@c.us` + }); } - - } - else if (send_empty_incident) { - + } else if (send_empty_incident) { // OLD // const msg = await wbot.sendMessage(`${contact.number}@c.us`, `Conforme Monitoramento a internet da unidade está operacional${final_message}`); // await verifyMessage(msg, ticket, contact); // await new Promise(f => setTimeout(f, 1000)); // NEW - await SendWhatsAppMessage({ body: `Conforme Monitoramento a internet da unidade está operacional${final_message}`, ticket, number: `${contact.number}@c.us` }) - + await SendWhatsAppMessage({ + body: `Conforme Monitoramento a internet da unidade está operacional${final_message}`, + ticket, + number: `${contact.number}@c.us` + }); } +}; -} +async function sendDelayedMessages( + wbot: any, + ticket: Ticket, + contact: Contact, + message: string, + _msg?: WbotMessage +) { + const body = message.replace(/\\n/g, "\n"); - - -async function sendDelayedMessages(wbot: any, ticket: Ticket, contact: Contact, message: string, _msg?: WbotMessage) { - const body = message.replace(/\\n/g, '\n'); - - if (body.search('dialog_actions') != -1) { - - let msgAction = botMsgActions(body) + if (body.search("dialog_actions") != -1) { + let msgAction = botMsgActions(body); // console.log('gggggggggggggggggggggggggggggggggg msgAction: ', msgAction) - if (msgAction.actions[0] == 'request_endpoint') { - - + if (msgAction.actions[0] == "request_endpoint") { // NEW - await SendWhatsAppMessage({ body: msgAction.msgBody, ticket, number: `${contact.number}@c.us` }) + await SendWhatsAppMessage({ + body: msgAction.msgBody, + ticket, + number: `${contact.number}@c.us` + }); - // const url = 'http://177.107.193.124:8095/labs/zabbix-frontend/api/api.php/99383' + // const url = 'http://177.107.193.124:8095/labs/zabbix-frontend/api/api.php/99383' - let aux = msgAction.actions[1].split('/') + let aux = msgAction.actions[1].split("/"); - let cod_web + let cod_web; if (aux && aux.length > 0) { - cod_web = aux[aux.length - 1] + cod_web = aux[aux.length - 1]; } - let params = msgAction.actions[1].split('api.php')[1].slice(1).split('/') + let params = msgAction.actions[1].split("api.php")[1].slice(1).split("/"); - let url = msgAction.actions[1].replace(/\.php.*/, '.php') + let url = msgAction.actions[1].replace(/\.php.*/, ".php"); - let response: any = '' - - if (params[0] === 'validate_n_chamado_web') { + let response: any = ""; + if (params[0] === "validate_n_chamado_web") { await FindOrCreateQueryItemService({ contactId: contact.id, queryItem: params[1].trim(), - name: 'n_chamado_web' - }) + name: "n_chamado_web" + }); let valid = await endPointQuery( - 'http://177.107.192.247:8095/labs/monitoramentohit/api/api.php', - 'post', + "http://177.107.192.247:8095/labs/monitoramentohit/api/api.php", + "post", { - 'params[n_chamado_web]': params[1], - 'method': 'omnihit.consultachamadostatus' - }) + "params[n_chamado_web]": params[1], + method: "omnihit.consultachamadostatus" + } + ); - - if (valid && valid.data.result == 'open') { - - botSendMessage(ticket, `✅ Protocolo validado, agora digite a informação que deseja adicionar.`) + if (valid && valid.data.result == "open") { + botSendMessage( + ticket, + `✅ Protocolo validado, agora digite a informação que deseja adicionar.` + ); FindOrCreateQueryItemService({ contactId: contact.id, - name: 'insert_protocol_info', - status: true, - }) - - } - else if (valid && valid.data.result == 'notfound') { - - botSendMessage(ticket, `Protocolo *${params[1]}* não encontrado!`) - - } - else if (valid && valid.data.result == 'close') { - + name: "insert_protocol_info", + status: true + }); + } else if (valid && valid.data.result == "notfound") { + botSendMessage(ticket, `Protocolo *${params[1]}* não encontrado!`); + } else if (valid && valid.data.result == "close") { botSendMessage( ticket, - `O protocolo *${params[1]}* foi encerrado. Não é mais possível adicionar informação. Se desejar consultar o historico digite *1*`) + `O protocolo *${params[1]}* foi encerrado. Não é mais possível adicionar informação. Se desejar consultar o historico digite *1*` + ); // - + } else { + botSendMessage( + ticket, + `Ops! Não foi possível validar seu protocolo devido a um erro na comunicação com o servidor.Tente novamente mais tarde.\n_Digite *0* para falar com a HIT._` + ); } - else { - - botSendMessage(ticket, `Ops! Não foi possível validar seu protocolo devido a um erro na comunicação com o servidor.Tente novamente mais tarde.\n_Digite *0* para falar com a HIT._`) - - } - } - if (params[0] === 'validate_n_chamado_web') return + if (params[0] === "validate_n_chamado_web") return; - if (params[0] === 'cod_web') { - - response = await endPointQuery('http://177.107.192.247:8095/labs/monitoramentohit/api/api.php', - 'post', { - 'params[cod_web]': params[1], - 'method': 'omnihit.consultachamado' - }) - - - } - else if (params[0] === 'n_chamado_web') { - - response = await endPointQuery('http://177.107.192.247:8095/labs/monitoramentohit/api/api.php', - 'post', + if (params[0] === "cod_web") { + response = await endPointQuery( + "http://177.107.192.247:8095/labs/monitoramentohit/api/api.php", + "post", { - 'params[n_chamado_web]': params[1], - 'method': 'omnihit.consultachamado', - }) - - + "params[cod_web]": params[1], + method: "omnihit.consultachamado" + } + ); + } else if (params[0] === "n_chamado_web") { + response = await endPointQuery( + "http://177.107.192.247:8095/labs/monitoramentohit/api/api.php", + "post", + { + "params[n_chamado_web]": params[1], + method: "omnihit.consultachamado" + } + ); } try { - if (response && response.data.result.trim().length > 0) { - response = response.data.result - } - else if (response && response.data.result.trim().length === 0) { - response = '' - } - else { - response = null + response = response.data.result; + } else if (response && response.data.result.trim().length === 0) { + response = ""; + } else { + response = null; } // response = response.data.result if (response.trim().length == 0) { - - botSendMessage(ticket, `Não existe nenhum chamado para essa operação!\n _Digite *0* para falar com a HIT._`) - - } - else if (response.trim().length > 0) { - + botSendMessage( + ticket, + `Não existe nenhum chamado para essa operação!\n _Digite *0* para falar com a HIT._` + ); + } else if (response.trim().length > 0) { await SendWhatsAppMessage({ body: response, ticket }); - } - } catch (error) { - botSendMessage(ticket, `Houve um erro ao realizar a consulta!\n _Digite *0* para falar com a HIT._`) + botSendMessage( + ticket, + `Houve um erro ao realizar a consulta!\n _Digite *0* para falar com a HIT._` + ); } + } else if (msgAction.actions[0] == "queue_transfer") { + console.log( + ">>>>>>>>>>>>>>> msgAction: ", + msgAction, + " | msgAction.actions[1]: ", + msgAction.actions[1] + ); - } else if (msgAction.actions[0] == 'queue_transfer') { + await SendWhatsAppMessage({ + body: msgAction.msgBody, + ticket, + number: `${contact.number}@c.us` + }); - console.log('>>>>>>>>>>>>>>> msgAction: ', msgAction, ' | msgAction.actions[1]: ', msgAction.actions[1]) - - await SendWhatsAppMessage({ body: msgAction.msgBody, ticket, number: `${contact.number}@c.us` }) - - await transferTicket(+msgAction.actions[1], wbot, ticket) - } - else if (msgAction.actions[0] == 'send_file') { - - const sourcePath = path.join(__dirname, `../../../public/bot`) + await transferTicket(+msgAction.actions[1], wbot, ticket); + } else if (msgAction.actions[0] == "send_file") { + const sourcePath = path.join(__dirname, `../../../public/bot`); // const msg = await wbot.sendMessage(`${contact.number}@c.us`, msgAction.msgBody); // await verifyMessage(msg, ticket, contact); // await new Promise(f => setTimeout(f, 1000)); // // NEW - await SendWhatsAppMessage({ body: msgAction.msgBody, ticket, number: `${contact.number}@c.us` }) - - - await botSendMedia(ticket, contact, wbot, sourcePath, msgAction.actions[1]) + await SendWhatsAppMessage({ + body: msgAction.msgBody, + ticket, + number: `${contact.number}@c.us` + }); + await botSendMedia( + ticket, + contact, + wbot, + sourcePath, + msgAction.actions[1] + ); } - - } - else { + } else { // const linesOfBody = body.split('\n'); // OLD @@ -528,27 +519,25 @@ async function sendDelayedMessages(wbot: any, ticket: Ticket, contact: Contact, // await new Promise(f => setTimeout(f, 1000)); // NEW - sendWhatsAppMessageSocket(ticket, body) - - + sendWhatsAppMessageSocket(ticket, body); // for(let message of linesOfBody) { // const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, message); // await verifyMessage(sentMessage, ticket, contact); // await new Promise(f => setTimeout(f, 1000)); - // } + // } } - - } - const extractCallCode = (str: string) => { - if (str.includes('*') && str.indexOf('*') < str.lastIndexOf('*')) { - return (str.substring(str.indexOf('*'), str.lastIndexOf('*') + 1)).split('*').join('') + if (str.includes("*") && str.indexOf("*") < str.lastIndexOf("*")) { + return str + .substring(str.indexOf("*"), str.lastIndexOf("*") + 1) + .split("*") + .join(""); } - return '' -} + return ""; +}; const sendDialogflowAwswer = async ( wbot: any, @@ -558,24 +547,30 @@ const sendDialogflowAwswer = async ( send: boolean = true // chat: Chat ) => { - - console.log('-----------> msg.from: ', msg.from) + console.log("-----------> msg.from: ", msg.from); // return - const session = await createDialogflowSessionWithModel(ticket.queue.dialogflow); + const session = await createDialogflowSessionWithModel( + ticket.queue.dialogflow + ); if (session === undefined) { return; } - - if (msg.type != 'chat') { - botSendMessage(ticket, `Desculpe, nao compreendi!\nEnvie apenas texto quando estiver interagindo com o bot!\n _Digite *0* para falar com a HIT._`) - return + if (msg.type != "chat") { + botSendMessage( + ticket, + `Desculpe, nao compreendi!\nEnvie apenas texto quando estiver interagindo com o bot!\n _Digite *0* para falar com a HIT._` + ); + return; } - if (msg.type == 'chat' && String(msg.body).length > 120) { - botSendMessage(ticket, `Desculpe, nao compreendi!\nTexto acima de 120 caracteres!\n _Digite *0* para falar com a HIT._`) - return + if (msg.type == "chat" && String(msg.body).length > 120) { + botSendMessage( + ticket, + `Desculpe, nao compreendi!\nTexto acima de 120 caracteres!\n _Digite *0* para falar com a HIT._` + ); + return; } let dialogFlowReply = await queryDialogFlow( @@ -589,19 +584,17 @@ const sendDialogflowAwswer = async ( return; } - if (!send) return + if (!send) return; // Make disponible later from session out - // chat.sendStateTyping(); + // chat.sendStateTyping(); await new Promise(f => setTimeout(f, 1000)); for (let message of dialogFlowReply) { await sendDelayedMessages(wbot, ticket, contact, message.text.text[0], msg); } -} - - +}; const verifyQueue = async ( wbot: any, @@ -609,7 +602,6 @@ const verifyQueue = async ( ticket: Ticket, contact: Contact ) => { - const { queues, greetingMessage } = await ShowWhatsAppService(wbot.id!); /*if (queues.length === 1) { @@ -620,45 +612,32 @@ const verifyQueue = async ( return; }*/ - - let selectedOption = null; - let choosenQueue = null + let choosenQueue = null; //Habilitar esse caso queira usar o bot - const botInfo = await BotIsOnQueue('botqueue') + const botInfo = await BotIsOnQueue("botqueue"); // const botInfo = { isOnQueue: false, botQueueId: 0, userIdBot: 0 } if (botInfo.isOnQueue) { - choosenQueue = await ShowQueueService(botInfo.botQueueId); - - } - - else if (queues.length === 1) { + } else if (queues.length === 1) { selectedOption = 1; choosenQueue = queues[+selectedOption - 1]; - } - else { - + } else { selectedOption = msg.body; //////////////// EXTRAIR APENAS O NÚMERO /////////////////// - selectedOption = selectedOption.replace(/[^1-9]/g, '') + selectedOption = selectedOption.replace(/[^1-9]/g, ""); /////////////////////////////////// choosenQueue = queues[+selectedOption - 1]; } - - if (choosenQueue) { - // Atualizando o status do ticket para mostrar notificação para o atendente da fila escolhida pelo usuário. De queueChoice para pending if (queues.length > 1 && !botInfo.isOnQueue) { - await ticket.update({ status: "pending" }); - } // @@ -667,48 +646,40 @@ const verifyQueue = async ( ticketId: ticket.id }); - - let botOptions = '' + let botOptions = ""; // O bot abre a mensagem na fila para atender o usuario if (botInfo.isOnQueue) { - await UpdateTicketService({ - ticketData: { status: 'open', userId: botInfo.userIdBot }, + ticketData: { status: "open", userId: botInfo.userIdBot }, ticketId: ticket.id }); const _ticket = await ShowTicketService(ticket.id); // const chat = wbot.chat await sendDialogflowAwswer(wbot, _ticket, msg, contact); - return - + return; } // - let body = '' + let body = ""; if (botOptions.length > 0) { body = `\u200e${choosenQueue.greetingMessage}\n\n${botOptions}\n${final_message.msg}`; - } - else { + } else { body = `\u200e${choosenQueue.greetingMessage}`; } - sendWhatsAppMessageSocket(ticket, body) - - } - else { - - const repet: any = await mostRepeatedPhrase(ticket.id) + sendWhatsAppMessageSocket(ticket, body); + } else { + const repet: any = await mostRepeatedPhrase(ticket.id); if (repet.occurrences > 4) { - - await UpdateTicketService({ ticketData: { status: 'pending', queueId: queues[0].id }, ticketId: ticket.id }); - - } - else { - + await UpdateTicketService({ + ticketData: { status: "pending", queueId: queues[0].id }, + ticketId: ticket.id + }); + } else { let options = ""; queues.forEach((queue, index) => { @@ -719,40 +690,38 @@ const verifyQueue = async ( const debouncedSentMessage = debounce( async () => { - - // const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, body); + // const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, body); // verifyMessage(sentMessage, ticket, contact); - sendWhatsAppMessageSocket(ticket, body) - - + sendWhatsAppMessageSocket(ticket, body); }, 3000, ticket.id ); debouncedSentMessage(); - } - - - } }; -const transferTicket = async (queueIndex: number, wbot: any, ticket: Ticket) => { +const transferTicket = async ( + queueIndex: number, + wbot: any, + ticket: Ticket +) => { + const botInfo = await BotIsOnQueue("botqueue"); - const botInfo = await BotIsOnQueue('botqueue') + const queuesWhatsGreetingMessage = await queuesOutBot( + wbot, + botInfo.botQueueId + ); - const queuesWhatsGreetingMessage = await queuesOutBot(wbot, botInfo.botQueueId) - - const queues = queuesWhatsGreetingMessage.queues + const queues = queuesWhatsGreetingMessage.queues; // console.log('queues ---> ', queues) - await botTransferTicket(queues[queueIndex], ticket) - -} + await botTransferTicket(queues[queueIndex], ticket); +}; // const botMsgActions = (params: string) => { @@ -765,19 +734,16 @@ const transferTicket = async (queueIndex: number, wbot: any, ticket: Ticket) => // return { msgBody: bodyMsg, 'actions': [actions[0].trim(), actions[1].trim()] }; // } - const botMsgActions = (params: string) => { + let lstActions = params.split("dialog_actions="); + let bodyMsg = lstActions[0].trim(); + let obj = {}; - let lstActions = params.split('dialog_actions=') - let bodyMsg = lstActions[0].trim() - let obj = {} - - console.log('lstActions: ', lstActions[1].split('=')) - let actions = lstActions[1].split('=') - - return { msgBody: bodyMsg, 'actions': actions }; -} + console.log("lstActions: ", lstActions[1].split("=")); + let actions = lstActions[1].split("="); + return { msgBody: bodyMsg, actions: actions }; +}; const isValidMsg = (msg: WbotMessage): boolean => { if (msg.from === "status@broadcast") return false; @@ -795,140 +761,129 @@ const isValidMsg = (msg: WbotMessage): boolean => { return false; }; - const queuesOutBot = async (wbot: any, botId: string | number) => { - const { queues, greetingMessage } = await ShowWhatsAppService(wbot.id!); - const indexQueue = queues.findIndex((q) => q.id == botId) + const indexQueue = queues.findIndex(q => q.id == botId); if (indexQueue != -1) { - queues.splice(indexQueue, 1) + queues.splice(indexQueue, 1); } - return { queues, greetingMessage } - -} + return { queues, greetingMessage }; +}; const botTransferTicket = async (queues: Queue, ticket: Ticket) => { - - console.log('>>>>>>>>>>>>>>>>> queues.id: ', queues.id) + console.log(">>>>>>>>>>>>>>>>> queues.id: ", queues.id); await ticket.update({ userId: null }); - await UpdateTicketService({ ticketData: { status: 'pending', queueId: queues.id }, ticketId: ticket.id }); - -} - -const botSendMedia = async (ticket: Ticket, contact: Contact, wbot: any, mediaPath: string, fileNameExtension: string) => { + await UpdateTicketService({ + ticketData: { status: "pending", queueId: queues.id }, + ticketId: ticket.id + }); +}; +const botSendMedia = async ( + ticket: Ticket, + contact: Contact, + wbot: any, + mediaPath: string, + fileNameExtension: string +) => { const debouncedSentMessage = debounce( - async () => { + const newMedia = MessageMedia.fromFilePath( + `${mediaPath}/${fileNameExtension}` + ); - const newMedia = MessageMedia.fromFilePath(`${mediaPath}/${fileNameExtension}`); - - const media = { path: `${mediaPath}/${fileNameExtension}` } + const media = { path: `${mediaPath}/${fileNameExtension}` }; // OLD // const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, newMedia, { caption: 'this is my caption' }); - // await ticket.update({ lastMessage: fileNameExtension }); + // await ticket.update({ lastMessage: fileNameExtension }); // verifyMessage(sentMessage, ticket, contact); // NEW - await SendWhatsAppMedia({ media: media.path, ticket }) - - + await SendWhatsAppMedia({ media: media.path, ticket }); }, 3000, ticket.id ); debouncedSentMessage(); - -} - +}; const botSendMessage = (ticket: Ticket, msg: string) => { - const debouncedSentMessage = debounce( - async () => { //OLD // const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, `${msg}`); // verifyMessage(sentMessage, ticket, contact); //NEW - await SendWhatsAppMessage({ body: msg, ticket }) + await SendWhatsAppMessage({ body: msg, ticket }); }, 3000, ticket.id ); debouncedSentMessage(); - -} +}; const _clear_lst = () => { + console.log("THE lst.length: ", lst.length); - console.log('THE lst.length: ', lst.length) + if (lst.length <= 199) return; - if (lst.length <= 199) return - - const chunk: any = Math.floor((lst.length / 2)) + const chunk: any = Math.floor(lst.length / 2); lst = lst.slice(chunk, chunk + lst.length); - let whatsappIdsSplited = lst.map((e) => `${e.id}`).toString() + let whatsappIdsSplited = lst.map(e => `${e.id}`).toString(); - setWhatsappId(whatsappIdsSplited, true) - -} - -const handleMessage = async ( - msg: any, - wbot: any -): Promise => { + setWhatsappId(whatsappIdsSplited, true); +}; +const handleMessage = async (msg: any, wbot: any): Promise => { if (!msg.fromMe) { + _clear_lst(); - _clear_lst() + let index = lst.findIndex((x: any) => x.id == msg.id.id); - let index = lst.findIndex((x: any) => x.id == msg.id.id) - - console.log('INDEX: ', index) + console.log("INDEX: ", index); if (index == -1) { - // console.log('-----------------> LST: ', lst):q - lst.push({ id: msg.id.id }) + lst.push({ id: msg.id.id }); - setWhatsappId(msg.id.id) + setWhatsappId(msg.id.id); + } else { + console.log("IGNORED ID: ", msg.id.id); - } - else { - console.log('IGNORED ID: ', msg.id.id) - - return + return; } // console.log('LIST OF ID MESSAGE lst: ', lst) - console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id) + console.log( + "PASSOU.................................FROM: ", + msg.from.split("@")[0], + " | ID: ", + msg.id.id + ); } - if (!isValidMsg(msg)) { return; } try { - let msgContact: any = wbot.msgContact + let msgContact: any = wbot.msgContact; // let groupContact: Contact | undefined; if (msg.fromMe) { - // console.log('FROM ME: ', msg.fromMe, ' | /\u200e/.test(msg.body[0]: ', (/\u200e/.test(msg.body[0]))) // messages sent automatically by wbot have a special character in front of it @@ -948,14 +903,12 @@ const handleMessage = async ( // console.log('1 --------------> msgContat: ', JSON.parse(JSON.stringify(msgContact))) // console.log(' # msg.type: ', msg.type ) - } else { - // msgContact = await msg.getContact(); // console.log('2 --------------> msgContat: ', JSON.parse(JSON.stringify(msgContact))) - // + // console.log(`\n <<<<<<<<<< RECEIVING MESSAGE: Parcial msg and msgContact info: msgContact.name: ${msgContact.name} @@ -966,12 +919,11 @@ const handleMessage = async ( msg.body: ${msg.body} msg.type: ${msg.type} msg.from: ${msg.from} - msg.to: ${msg.to}\n`) - + msg.to: ${msg.to}\n`); } // const chat = await msg.getChat(); - const chat = wbot.chat + const chat = wbot.chat; // if(chat.isGroup){ @@ -993,8 +945,6 @@ const handleMessage = async ( // groupContact = await verifyContact(msgGroupContact); // } - - const whatsapp = await ShowWhatsAppService(wbot.id!); // const whatsapp = await ShowWhatsAppService(46); @@ -1005,25 +955,28 @@ const handleMessage = async ( // console.log('----------> contact: ', JSON.parse(JSON.stringify(contact))) - if (unreadMessages === 0 && whatsapp.farewellMessage && whatsapp.farewellMessage === msg.body) return; + if ( + unreadMessages === 0 && + whatsapp.farewellMessage && + whatsapp.farewellMessage === msg.body + ) + return; - let ticket + let ticket; - const _botInfo = await BotIsOnQueue('botqueue') + const _botInfo = await BotIsOnQueue("botqueue"); if (_botInfo.isOnQueue) { - let ticket_obj: any = await FindOrCreateTicketServiceBot( contact, wbot.id!, - unreadMessages, + unreadMessages // groupContact ); - ticket = ticket_obj.ticket + ticket = ticket_obj.ticket; if (ticket_obj.created) { - let queue = await ShowQueueService(_botInfo.botQueueId); await UpdateTicketService({ @@ -1033,20 +986,15 @@ const handleMessage = async ( ticket = await ShowTicketService(ticket.id); } - - - } - else { + } else { ticket = await FindOrCreateTicketService( contact, wbot.id!, - unreadMessages, + unreadMessages // groupContact ); } - - // const ticket = await FindOrCreateTicketService( // contact, // wbot.id!, @@ -1054,39 +1002,39 @@ const handleMessage = async ( // // groupContact // ); - - - - // + // // await updateTicketCacheByTicketId(ticket.id, {'contact.profilePicUrl': ticket.contact.profilePicUrl}) // Para responder para o cliente pelo mesmo whatsapp que ele enviou a mensagen if (wbot.id != ticket.whatsappId) { - // console.log('PARA RESPONDER PELO MEMOS WHATSAPP wbot.id: ', wbot.id, ' | wbot.status: ', wbot.status) // console.log('WHATSAPP STATUS ticket.whatsappId: ', ticket.whatsappId) try { await ticket.update({ whatsappId: wbot.id }); } catch (error: any) { - console.error('===> Error on wbotMessageListener.ts into handleMessage fuction file: \n', error) + console.error( + "===> Error on wbotMessageListener.ts into handleMessage fuction file: \n", + error + ); throw new AppError(error.message); } - - - } - // + // if (msg.hasMedia) { - await verifyMediaMessage(msg, ticket, contact, wbot.media, wbot.quotedMsg); + await verifyMediaMessage( + msg, + ticket, + contact, + wbot.media, + wbot.quotedMsg + ); } else { - // console.log('>>>>>>> msg.fromMe: ',msg.fromMe ) await verifyMessage(msg, ticket, contact, wbot.quotedMsg); } - if ( !ticket.queue && !chat.isGroup && @@ -1100,123 +1048,118 @@ const handleMessage = async ( // O bot interage com o cliente e encaminha o atendimento para fila de atendende quando o usuário escolhe a opção falar com atendente //Habilitar esse caso queira usar o bot - const botInfo = await BotIsOnQueue('botqueue') + const botInfo = await BotIsOnQueue("botqueue"); // const botInfo = { isOnQueue: false, botQueueId: 0, userIdBot: 0 } - if (botInfo.isOnQueue && !msg.fromMe && ticket.userId == botInfo.userIdBot) { + if ( + botInfo.isOnQueue && + !msg.fromMe && + ticket.userId == botInfo.userIdBot + ) { + const repet: any = await mostRepeatedPhrase(ticket.id); - const repet: any = await mostRepeatedPhrase(ticket.id) - - console.log('repet.occurrences: ', repet.occurrences) + console.log("repet.occurrences: ", repet.occurrences); if (repet.occurrences > 4) { - - await transferTicket(0, wbot, ticket) + await transferTicket(0, wbot, ticket); await SendWhatsAppMessage({ body: `Seu atendimento foi transferido para um agente!\n\nPara voltar ao menu principal digite *0* - `, ticket, number: `${contact.number}@c.us` - }) - - } - else { - + `, + ticket, + number: `${contact.number}@c.us` + }); + } else { const _item = await ShowQueryItemService({ contactId: contact.id, - name: 'insert_protocol_info' - }) - + name: "insert_protocol_info" + }); // let last_messages = await ShowTicketMessage(ticket.id, 2, true) // if (last_messages.length > 0 && last_messages[0].body.includes('validado') && msg.body.trim() != '0') { + if (_item && _item?.status && msg.body.trim() != "0") { + _item.update({ status: false }); - if (_item && _item?.status && msg.body.trim() != '0') { - - _item.update({ status: false }) - - await SendWhatsAppMessage({ body: `Aguarde inserindo informação, em breve te atualizaremos`, ticket }) + await SendWhatsAppMessage({ + body: `Aguarde inserindo informação, em breve te atualizaremos`, + ticket + }); const item: QueryItem = await ShowQueryItemService({ contactId: contact.id, - name: 'n_chamado_web' - }) - + name: "n_chamado_web" + }); if (!item?.queryItem) { - - botSendMessage(ticket, `Ops! Houve um erro, tente novamente.`) - return + botSendMessage(ticket, `Ops! Houve um erro, tente novamente.`); + return; } - let response = await endPointQuery( - 'http://177.107.192.247:8095/labs/monitoramentohit/api/api.php', - 'post', + "http://177.107.192.247:8095/labs/monitoramentohit/api/api.php", + "post", { - 'params[n_chamado_web]': item?.queryItem, - 'method': 'omnihit.chamadoaddobs', - 'params[obs]': msg.body - }) + "params[n_chamado_web]": item?.queryItem, + method: "omnihit.chamadoaddobs", + "params[obs]": msg.body + } + ); if (response && response.data.result) { - // botSendMessage(ticket, `${response.data.result}`) - botSendMessage(ticket, `✅ A informação foi adicionada com sucesso e será armazenada no histórico do protocolo.`) - + botSendMessage( + ticket, + `✅ A informação foi adicionada com sucesso e será armazenada no histórico do protocolo.` + ); + } else { + botSendMessage( + ticket, + `Ops! Houve um erro ao tentar inserir sua informação devido a um erro na comunicação com o servidor.Tente novamente mais tarde.` + ); } - else { - - botSendMessage(ticket, `Ops! Houve um erro ao tentar inserir sua informação devido a um erro na comunicação com o servidor.Tente novamente mais tarde.`) - - } - - + } else { + await sendDialogflowAwswer(wbot, ticket, msg, contact); } - else { - - await sendDialogflowAwswer(wbot, ticket, msg, contact,); - - } - - } - } - else if (botInfo.isOnQueue && !msg.fromMe && msg.body == '0' && ticket.status == 'pending' && ticket.queueId) { - + } else if ( + botInfo.isOnQueue && + !msg.fromMe && + msg.body == "0" && + ticket.status == "pending" && + ticket.queueId + ) { let choosenQueue = await ShowQueueService(botInfo.botQueueId); await UpdateTicketService({ - ticketData: { status: 'open', userId: botInfo.userIdBot, queueId: choosenQueue.id }, + ticketData: { + status: "open", + userId: botInfo.userIdBot, + queueId: choosenQueue.id + }, ticketId: ticket.id }); const _ticket = await ShowTicketService(ticket.id); // const chat = await msg.getChat(); - const chat = wbot.chat + const chat = wbot.chat; - await sendDialogflowAwswer(wbot, _ticket, msg, contact,); - return + await sendDialogflowAwswer(wbot, _ticket, msg, contact); + return; } - - if (msg && !msg.fromMe && ticket.status == 'pending') { - - await setMessageAsRead(ticket) - + if (msg && !msg.fromMe && ticket.status == "pending") { + await setMessageAsRead(ticket); } - - } catch (err) { Sentry.captureException(err); - console.log('xxxxxxxxxxxxx err: ', err) + console.log("xxxxxxxxxxxxx err: ", err); logger.error(`Error handling whatsapp message: Err: ${err}`); } }; const handleMsgAck = async (msg_id: any, ack: any) => { - await new Promise(r => setTimeout(r, 4000)); const io = getIO(); @@ -1233,18 +1176,17 @@ const handleMsgAck = async (msg_id: any, ack: any) => { ] }); if (!messageToUpdate) { - console.log(`Not found the MESSAGE ID ${msg_id}to change the ACK into the Message table`) + console.log( + `Not found the MESSAGE ID ${msg_id}to change the ACK into the Message table` + ); return; } await messageToUpdate.update({ ack }); - // console.log('ACK messageToUpdate: ', JSON.parse(JSON.stringify(messageToUpdate))) - io.to(messageToUpdate.ticketId.toString()).emit("appMessage", { action: "update", message: messageToUpdate }); - } catch (err) { Sentry.captureException(err); logger.error(`Error handling message ack. Err: ${err}`); @@ -1252,7 +1194,6 @@ const handleMsgAck = async (msg_id: any, ack: any) => { }; const wbotMessageListener = (wbot: any): void => { - wbot.on("message_create", async (msg: any) => { handleMessage(msg, wbot); }); @@ -1266,4 +1207,11 @@ const wbotMessageListener = (wbot: any): void => { }); }; -export { wbotMessageListener, handleMessage, handleMsgAck, lst, verifyContact, sendDialogflowAwswer }; +export { + wbotMessageListener, + handleMessage, + handleMsgAck, + lst, + verifyContact, + sendDialogflowAwswer +}; diff --git a/frontend/src/App.js b/frontend/src/App.js index 854091e..5d99c17 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,57 +1,54 @@ -import React, { useState, useEffect } from "react"; -import Routes from "./routes"; -import "react-toastify/dist/ReactToastify.css"; +import React, { useState, useEffect } from 'react' +import Routes from './routes' +import 'react-toastify/dist/ReactToastify.css' -import { createTheme, ThemeProvider } from "@material-ui/core/styles"; -import { ptBR } from "@material-ui/core/locale"; +import { createTheme, ThemeProvider } from '@material-ui/core/styles' +import { ptBR } from '@material-ui/core/locale' -import { TabTicketProvider } from "../src/context/TabTicketHeaderOption/TabTicketHeaderOption"; +import { TabTicketProvider } from '../src/context/TabTicketHeaderOption/TabTicketHeaderOption' const App = () => { - const [locale, setLocale] = useState(); + const [locale, setLocale] = useState() const theme = createTheme( { scrollbarStyles: { - "&::-webkit-scrollbar": { - width: "8px", - height: "8px", + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', }, - "&::-webkit-scrollbar-thumb": { - boxShadow: "inset 0 0 6px rgba(0, 0, 0, 0.3)", + '&::-webkit-scrollbar-thumb': { + boxShadow: 'inset 0 0 6px rgba(0, 0, 0, 0.3)', - backgroundColor: "#e8e8e8", + backgroundColor: '#e8e8e8', }, }, palette: { //primary: { main: "#2576d2" }, - primary: { main: "#ec5114" }, + primary: { main: '#ec5114' }, }, }, locale - ); + ) useEffect(() => { - const i18nlocale = localStorage.getItem("i18nextLng"); + const i18nlocale = localStorage.getItem('i18nextLng') const browserLocale = - i18nlocale.substring(0, 2) + i18nlocale.substring(3, 5); + i18nlocale.substring(0, 2) + i18nlocale.substring(3, 5) - if (browserLocale === "ptBR") { - setLocale(ptBR); + if (browserLocale === 'ptBR') { + setLocale(ptBR) } - }, []); + }, []) return ( - {/*TabTicketProvider Context to manipulate the entire state of selected option from user click on tickets options header */} - - - ); -}; + ) +} -export default App; +export default App diff --git a/frontend/src/components/QueueModal/index.js b/frontend/src/components/QueueModal/index.js index e067b23..177cc82 100644 --- a/frontend/src/components/QueueModal/index.js +++ b/frontend/src/components/QueueModal/index.js @@ -302,4 +302,4 @@ const QueueModal = ({ open, onClose, queueId }) => { ); }; -export default QueueModal; +export default QueueModal; \ No newline at end of file diff --git a/frontend/src/components/WhatsAppModal/index.js b/frontend/src/components/WhatsAppModal/index.js index 57d0cd0..b2b8e40 100644 --- a/frontend/src/components/WhatsAppModal/index.js +++ b/frontend/src/components/WhatsAppModal/index.js @@ -1,290 +1,300 @@ -import React, { useState, useEffect } from "react"; -import * as Yup from "yup"; -import { Formik, Form, Field } from "formik"; -import { toast } from "react-toastify"; +import React, { useState, useEffect, useContext } from 'react' +import * as Yup from 'yup' +import { Formik, Form, Field } from 'formik' +import { toast } from 'react-toastify' -import { makeStyles } from "@material-ui/core/styles"; -import { green } from "@material-ui/core/colors"; +import { makeStyles } from '@material-ui/core/styles' +import { green } from '@material-ui/core/colors' + +import { AuthContext } from '../../context/Auth/AuthContext' +import { Can } from '../../components/Can' import { - Dialog, - DialogContent, - DialogTitle, - Button, - DialogActions, - CircularProgress, - TextField, - Switch, - FormControlLabel, -} from "@material-ui/core"; + Dialog, + DialogContent, + DialogTitle, + Button, + DialogActions, + CircularProgress, + TextField, + Switch, + FormControlLabel, +} from '@material-ui/core' -import api from "../../services/api"; -import { i18n } from "../../translate/i18n"; -import toastError from "../../errors/toastError"; -import QueueSelect from "../QueueSelect"; +import api from '../../services/api' +import { i18n } from '../../translate/i18n' +import toastError from '../../errors/toastError' +import QueueSelect from '../QueueSelect' -const useStyles = makeStyles(theme => ({ - root: { - display: "flex", - flexWrap: "wrap", - }, +const useStyles = makeStyles((theme) => ({ + root: { + display: 'flex', + flexWrap: 'wrap', + }, - multFieldLine: { - display: "flex", - "& > *:not(:last-child)": { - marginRight: theme.spacing(1), - }, - }, + multFieldLine: { + display: 'flex', + '& > *:not(:last-child)': { + marginRight: theme.spacing(1), + }, + }, - btnWrapper: { - position: "relative", - }, + btnWrapper: { + position: 'relative', + }, - buttonProgress: { - color: green[500], - position: "absolute", - top: "50%", - left: "50%", - marginTop: -12, - marginLeft: -12, - }, -})); + buttonProgress: { + color: green[500], + position: 'absolute', + top: '50%', + left: '50%', + marginTop: -12, + marginLeft: -12, + }, +})) const SessionSchema = Yup.object().shape({ - name: Yup.string() - .min(2, "Too Short!") - .max(100, "Too Long!") - .required("Required"), -}); + name: Yup.string() + .min(2, 'Too Short!') + .max(100, 'Too Long!') + .required('Required'), +}) const WhatsAppModal = ({ open, onClose, whatsAppId }) => { - const classes = useStyles(); - const initialState = { - name: "", - urlApi: "", - url: "", - greetingMessage: "", - farewellMessage: "", - isDefault: false, - }; - const [whatsApp, setWhatsApp] = useState(initialState); - const [selectedQueueIds, setSelectedQueueIds] = useState([]); + const classes = useStyles() + const initialState = { + name: '', + urlApi: '', + url: '', + greetingMessage: '', + farewellMessage: '', + isDefault: false, + } - useEffect(() => { - const fetchSession = async () => { - if (!whatsAppId) return; + const { user } = useContext(AuthContext) - try { - const { data } = await api.get(`whatsapp/${whatsAppId}`); - setWhatsApp(data); + const [whatsApp, setWhatsApp] = useState(initialState) + const [selectedQueueIds, setSelectedQueueIds] = useState([]) - const whatsQueueIds = data.queues?.map(queue => queue.id); - setSelectedQueueIds(whatsQueueIds); - } catch (err) { - toastError(err); - } - }; - fetchSession(); - }, [whatsAppId]); + useEffect(() => { + const fetchSession = async () => { + if (!whatsAppId) return - const handleSaveWhatsApp = async values => { - const whatsappData = { ...values, queueIds: selectedQueueIds }; + try { + const { data } = await api.get(`whatsapp/${whatsAppId}`) + setWhatsApp(data) - let response = null + const whatsQueueIds = data.queues?.map((queue) => queue.id) + setSelectedQueueIds(whatsQueueIds) + } catch (err) { + toastError(err) + } + } + fetchSession() + }, [whatsAppId]) - try { - if (whatsAppId) { - response = await api.put(`/whatsapp/${whatsAppId}`, whatsappData); - } else { - response = await api.post("/whatsapp", whatsappData); - } + const handleSaveWhatsApp = async (values) => { + const whatsappData = { ...values, queueIds: selectedQueueIds } - console.log('response: ', response.data.message) + let response = null - if(response && response.data.message === 'wrong_number_start'){ - alert('O numero contido no nome da conexão deve iniciar com o código do país!') - } - else if(response && response.data.message === 'invalid_phone_number'){ - alert('A quantidade de numeros digitados no nome do contato é invalida! Certifique-se de que você digitou o numero correto acompanhado pelo código do país!') - } - else if( response && response.data.message === 'no_phone_number'){ - alert('Para criar/editar uma sessão de Whatsapp é necessário que o numero do Whatsapp acompanhado pelo código do país esteja presente no nome da sessão!') - } - else{ - toast.success(i18n.t("whatsappModal.success")); - handleClose(); - } - - } catch (err) { - toastError(err); - } - }; + try { + if (whatsAppId) { + response = await api.put(`/whatsapp/${whatsAppId}`, whatsappData) + } else { + response = await api.post('/whatsapp', whatsappData) + } - const handleClose = () => { - onClose(); - setWhatsApp(initialState); - }; + console.log('response: ', response.data.message) - return ( -
- - - {whatsAppId - ? i18n.t("whatsappModal.title.edit") - : i18n.t("whatsappModal.title.add")} - - { - setTimeout(() => { - handleSaveWhatsApp(values); - actions.setSubmitting(false); - }, 400); - }} - > - {({ values, touched, errors, isSubmitting }) => ( -
- - -
- - - } - label={i18n.t("whatsappModal.form.default")} - /> -
+ if (response && response.data.message === 'wrong_number_start') { + alert( + 'O numero contido no nome da conexão deve iniciar com o código do país!' + ) + } else if (response && response.data.message === 'invalid_phone_number') { + alert( + 'A quantidade de numeros digitados no nome do contato é invalida! Certifique-se de que você digitou o numero correto acompanhado pelo código do país!' + ) + } else if (response && response.data.message === 'no_phone_number') { + alert( + 'Para criar/editar uma sessão de Whatsapp é necessário que o numero do Whatsapp acompanhado pelo código do país esteja presente no nome da sessão!' + ) + } else { + toast.success(i18n.t('whatsappModal.success')) + handleClose() + } + } catch (err) { + toastError(err) + } + } + const handleClose = () => { + onClose() + setWhatsApp(initialState) + } + return ( +
+ + + {whatsAppId + ? i18n.t('whatsappModal.title.edit') + : i18n.t('whatsappModal.title.add')} + + { + setTimeout(() => { + handleSaveWhatsApp(values) + actions.setSubmitting(false) + }, 400) + }} + > + {({ values, touched, errors, isSubmitting }) => ( + + + ( + <> +
+ + + } + label={i18n.t('whatsappModal.form.default')} + /> +
+
+ + +
+ + )} + /> -
- - -
+
+ +
+
+ +
+ setSelectedQueueIds(selectedIds)} + /> +
+ + + + + + )} +
+
+
+ ) +} -
- -
- - -
- -
- setSelectedQueueIds(selectedIds)} - /> -
- - - - - - )} -
-
-
- ); -}; - -export default React.memo(WhatsAppModal); +export default React.memo(WhatsAppModal) diff --git a/frontend/src/context/Auth/AuthContext.js b/frontend/src/context/Auth/AuthContext.js index d13b342..5368f33 100644 --- a/frontend/src/context/Auth/AuthContext.js +++ b/frontend/src/context/Auth/AuthContext.js @@ -1,21 +1,22 @@ -import React, { createContext } from "react"; +import React, { createContext } from 'react' -import useAuth from "../../hooks/useAuth.js"; +import useAuth from '../../hooks/useAuth.js' -const AuthContext = createContext(); +const AuthContext = createContext() const AuthProvider = ({ children }) => { - const { loading, user, isAuth, handleLogin, handleLogout } = useAuth(); + const { loading, user, isAuth, handleLogin, handleLogout, setSetting } = + useAuth() - //{ + //{ - return ( - - {children} - - ); -}; + return ( + + {children} + + ) +} -export { AuthContext, AuthProvider }; +export { AuthContext, AuthProvider } diff --git a/frontend/src/hooks/useAuth.js/index.js b/frontend/src/hooks/useAuth.js/index.js index dc5d3d3..70ffe21 100644 --- a/frontend/src/hooks/useAuth.js/index.js +++ b/frontend/src/hooks/useAuth.js/index.js @@ -1,125 +1,158 @@ -import { useState, useEffect } from "react"; -import { useHistory } from "react-router-dom"; -import openSocket from "socket.io-client"; +import { useState, useEffect } from 'react' +import { useHistory } from 'react-router-dom' +import openSocket from 'socket.io-client' -import { toast } from "react-toastify"; +import { toast } from 'react-toastify' -import { i18n } from "../../translate/i18n"; -import api from "../../services/api"; -import toastError from "../../errors/toastError"; +import { i18n } from '../../translate/i18n' +import api from '../../services/api' +import toastError from '../../errors/toastError' const useAuth = () => { - const history = useHistory(); - const [isAuth, setIsAuth] = useState(false); - const [loading, setLoading] = useState(true); - const [user, setUser] = useState({}); + const history = useHistory() + const [isAuth, setIsAuth] = useState(false) + const [loading, setLoading] = useState(true) + const [user, setUser] = useState({}) - api.interceptors.request.use( - config => { - const token = localStorage.getItem("token"); - if (token) { - config.headers["Authorization"] = `Bearer ${JSON.parse(token)}`; - setIsAuth(true); - } - return config; - }, - error => { - Promise.reject(error); - } - ); + const [setting, setSetting] = useState({}) - api.interceptors.response.use( - response => { - return response; - }, - async error => { - const originalRequest = error.config; - if (error?.response?.status === 403 && !originalRequest._retry) { - originalRequest._retry = true; + api.interceptors.request.use( + (config) => { + const token = localStorage.getItem('token') + if (token) { + config.headers['Authorization'] = `Bearer ${JSON.parse(token)}` + setIsAuth(true) + } + return config + }, + (error) => { + Promise.reject(error) + } + ) - const { data } = await api.post("/auth/refresh_token"); - if (data) { - localStorage.setItem("token", JSON.stringify(data.token)); - api.defaults.headers.Authorization = `Bearer ${data.token}`; - } - return api(originalRequest); - } - if (error?.response?.status === 401) { - localStorage.removeItem("token"); - api.defaults.headers.Authorization = undefined; - setIsAuth(false); - } - return Promise.reject(error); - } - ); + api.interceptors.response.use( + (response) => { + return response + }, + async (error) => { + const originalRequest = error.config + if (error?.response?.status === 403 && !originalRequest._retry) { + originalRequest._retry = true - useEffect(() => { - const token = localStorage.getItem("token"); - (async () => { - if (token) { - try { - const { data } = await api.post("/auth/refresh_token"); - api.defaults.headers.Authorization = `Bearer ${data.token}`; - setIsAuth(true); - setUser(data.user); - } catch (err) { - toastError(err); - } - } - setLoading(false); - })(); - }, []); + const { data } = await api.post('/auth/refresh_token') + if (data) { + localStorage.setItem('token', JSON.stringify(data.token)) + api.defaults.headers.Authorization = `Bearer ${data.token}` + } + return api(originalRequest) + } + if (error?.response?.status === 401) { + localStorage.removeItem('token') + api.defaults.headers.Authorization = undefined + setIsAuth(false) + } + return Promise.reject(error) + } + ) - useEffect(() => { - const socket = openSocket(process.env.REACT_APP_BACKEND_URL); + useEffect(() => { + const token = localStorage.getItem('token') + ;(async () => { + if (token) { + try { + const { data } = await api.post('/auth/refresh_token') + api.defaults.headers.Authorization = `Bearer ${data.token}` + setIsAuth(true) + setUser(data.user) + } catch (err) { + toastError(err) + } + } + setLoading(false) + })() + }, []) - socket.on("user", data => { - if (data.action === "update" && data.user.id === user.id) { - setUser(data.user); - } - }); + useEffect(() => { + const fetchSession = async () => { + try { + const { data } = await api.get('/settings') + setSetting(data) + } catch (err) { + toastError(err) + } + } + fetchSession() + }, []) - return () => { - socket.disconnect(); - }; - }, [user]); + useEffect(() => { + const socket = openSocket(process.env.REACT_APP_BACKEND_URL) - const handleLogin = async userData => { - setLoading(true); + socket.on('user', (data) => { + if (data.action === 'update' && data.user.id === user.id) { + setUser(data.user) + } + }) - try { - const { data } = await api.post("/auth/login", userData); - localStorage.setItem("token", JSON.stringify(data.token)); - api.defaults.headers.Authorization = `Bearer ${data.token}`; - setUser(data.user); - setIsAuth(true); - toast.success(i18n.t("auth.toasts.success")); - history.push("/tickets"); - setLoading(false); - } catch (err) { - toastError(err); - setLoading(false); - } - }; + socket.on('settings', (data) => { + if (data.action === 'update') { + setSetting((prevState) => { + const aux = [...prevState] + const settingIndex = aux.findIndex((s) => s.key === data.setting.key) + aux[settingIndex].value = data.setting.value + return aux + }) + } + }) - const handleLogout = async () => { - setLoading(true); + return () => { + socket.disconnect() + } + }, [user]) - try { - await api.delete("/auth/logout"); - setIsAuth(false); - setUser({}); - localStorage.removeItem("token"); - api.defaults.headers.Authorization = undefined; - setLoading(false); - history.push("/login"); - } catch (err) { - toastError(err); - setLoading(false); - } - }; + const handleLogin = async (userData) => { + setLoading(true) - return { isAuth, user, loading, handleLogin, handleLogout }; -}; + try { + const { data } = await api.post('/auth/login', userData) + localStorage.setItem('token', JSON.stringify(data.token)) + api.defaults.headers.Authorization = `Bearer ${data.token}` + setUser(data.user) + setIsAuth(true) + toast.success(i18n.t('auth.toasts.success')) + history.push('/tickets') + setLoading(false) + } catch (err) { + toastError(err) + setLoading(false) + } + } -export default useAuth; + const handleLogout = async () => { + setLoading(true) + + try { + await api.delete('/auth/logout') + setIsAuth(false) + setUser({}) + localStorage.removeItem('token') + api.defaults.headers.Authorization = undefined + setLoading(false) + history.push('/login') + } catch (err) { + toastError(err) + setLoading(false) + } + } + + return { + isAuth, + user, + loading, + handleLogin, + handleLogout, + setting, + setSetting, + } +} + +export default useAuth diff --git a/frontend/src/pages/Connections/index.js b/frontend/src/pages/Connections/index.js index aa04cc9..a8c5fe4 100644 --- a/frontend/src/pages/Connections/index.js +++ b/frontend/src/pages/Connections/index.js @@ -1,368 +1,371 @@ -import React, { useState, useCallback, useEffect, useContext } from "react"; -import { toast } from "react-toastify"; -import { format, parseISO } from "date-fns"; +import React, { useState, useCallback, useEffect, useContext } from 'react' +import { toast } from 'react-toastify' +import { format, parseISO } from 'date-fns' -import openSocket from "socket.io-client"; +import openSocket from 'socket.io-client' -import { makeStyles } from "@material-ui/core/styles"; -import { green } from "@material-ui/core/colors"; +import { makeStyles } from '@material-ui/core/styles' +import { green } from '@material-ui/core/colors' import { - Button, - TableBody, - TableRow, - TableCell, - IconButton, - Table, - TableHead, - Paper, - Tooltip, - Typography, - CircularProgress, -} from "@material-ui/core"; + Button, + TableBody, + TableRow, + TableCell, + IconButton, + Table, + TableHead, + Paper, + Tooltip, + Typography, + CircularProgress, +} from '@material-ui/core' import { - Edit, - CheckCircle, - SignalCellularConnectedNoInternet2Bar, - SignalCellularConnectedNoInternet0Bar, - SignalCellular4Bar, - CropFree, - DeleteOutline, - // Restore -} from "@material-ui/icons"; + Edit, + CheckCircle, + SignalCellularConnectedNoInternet2Bar, + SignalCellularConnectedNoInternet0Bar, + SignalCellular4Bar, + CropFree, + DeleteOutline, + // Restore +} from '@material-ui/icons' -import MainContainer from "../../components/MainContainer"; -import MainHeader from "../../components/MainHeader"; -import MainHeaderButtonsWrapper from "../../components/MainHeaderButtonsWrapper"; -import Title from "../../components/Title"; -import TableRowSkeleton from "../../components/TableRowSkeleton"; +import MainContainer from '../../components/MainContainer' +import MainHeader from '../../components/MainHeader' +import MainHeaderButtonsWrapper from '../../components/MainHeaderButtonsWrapper' +import Title from '../../components/Title' +import TableRowSkeleton from '../../components/TableRowSkeleton' -import api from "../../services/api"; -import WhatsAppModal from "../../components/WhatsAppModal"; -import ConfirmationModal from "../../components/ConfirmationModal"; -import QrcodeModal from "../../components/QrcodeModal"; -import { i18n } from "../../translate/i18n"; -import { WhatsAppsContext } from "../../context/WhatsApp/WhatsAppsContext"; -import toastError from "../../errors/toastError"; +import api from '../../services/api' +import WhatsAppModal from '../../components/WhatsAppModal' +import ConfirmationModal from '../../components/ConfirmationModal' +import QrcodeModal from '../../components/QrcodeModal' +import { i18n } from '../../translate/i18n' +import { WhatsAppsContext } from '../../context/WhatsApp/WhatsAppsContext' +import toastError from '../../errors/toastError' //-------- -import { AuthContext } from "../../context/Auth/AuthContext"; -import { Can } from "../../components/Can"; +import { AuthContext } from '../../context/Auth/AuthContext' +import { Can } from '../../components/Can' - -const useStyles = makeStyles(theme => ({ - mainPaper: { - flex: 1, - padding: theme.spacing(1), - overflowY: "scroll", - ...theme.scrollbarStyles, - }, - customTableCell: { - display: "flex", - alignItems: "center", - justifyContent: "center", - }, - tooltip: { - backgroundColor: "#f5f5f9", - color: "rgba(0, 0, 0, 0.87)", - fontSize: theme.typography.pxToRem(14), - border: "1px solid #dadde9", - maxWidth: 450, - }, - tooltipPopper: { - textAlign: "center", - }, - buttonProgress: { - color: green[500], - }, -})); +const useStyles = makeStyles((theme) => ({ + mainPaper: { + flex: 1, + padding: theme.spacing(1), + overflowY: 'scroll', + ...theme.scrollbarStyles, + }, + customTableCell: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + }, + tooltip: { + backgroundColor: '#f5f5f9', + color: 'rgba(0, 0, 0, 0.87)', + fontSize: theme.typography.pxToRem(14), + border: '1px solid #dadde9', + maxWidth: 450, + }, + tooltipPopper: { + textAlign: 'center', + }, + buttonProgress: { + color: green[500], + }, +})) const CustomToolTip = ({ title, content, children }) => { - const classes = useStyles(); + const classes = useStyles() - return ( - - - {title} - - {content && {content}} - - } - > - {children} - - ); -}; + return ( + + + {title} + + {content && {content}} + + } + > + {children} + + ) +} const Connections = () => { + //-------- + const { user } = useContext(AuthContext) - //-------- - const { user } = useContext(AuthContext); + const classes = useStyles() + const { whatsApps, loading } = useContext(WhatsAppsContext) + const [whatsAppModalOpen, setWhatsAppModalOpen] = useState(false) + const [qrModalOpen, setQrModalOpen] = useState(false) + const [selectedWhatsApp, setSelectedWhatsApp] = useState(null) + const [confirmModalOpen, setConfirmModalOpen] = useState(false) - const classes = useStyles(); + const [diskSpaceInfo, setDiskSpaceInfo] = useState({}) - const { whatsApps, loading } = useContext(WhatsAppsContext); - const [whatsAppModalOpen, setWhatsAppModalOpen] = useState(false); - const [qrModalOpen, setQrModalOpen] = useState(false); - const [selectedWhatsApp, setSelectedWhatsApp] = useState(null); - const [confirmModalOpen, setConfirmModalOpen] = useState(false); + const [disabled, setDisabled] = useState(true) - const [diskSpaceInfo, setDiskSpaceInfo] = useState({}); + const [settings, setSettings] = useState([]) - const [disabled, setDisabled] = useState(true); + const [buttons, setClicks] = useState([]) - const [buttons, setClicks] = useState([]) + const confirmationModalInitialState = { + action: '', + title: '', + message: '', + whatsAppId: '', + open: false, + } + const [confirmModalInfo, setConfirmModalInfo] = useState( + confirmationModalInitialState + ) + useEffect(() => { + const fetchSession = async () => { + try { + const { data } = await api.get('/settings') + setSettings(data) + } catch (err) { + toastError(err) + } + } + fetchSession() + }, []) - const confirmationModalInitialState = { - action: "", - title: "", - message: "", - whatsAppId: "", - open: false, - }; - const [confirmModalInfo, setConfirmModalInfo] = useState( - confirmationModalInitialState - ); + const getSettingValue = (key) => { + const { value } = settings.find((s) => s.key === key) - const handleStartWhatsAppSession = async whatsAppId => { - try { - await api.post(`/whatsappsession/${whatsAppId}`); - } catch (err) { - toastError(err); - } - }; + return value + } + const handleStartWhatsAppSession = async (whatsAppId) => { + try { + await api.post(`/whatsappsession/${whatsAppId}`) + } catch (err) { + toastError(err) + } + } + const handleRestartWhatsAppSession = async (whatsapp) => { + try { + whatsapp.disabled = true + setClicks([...buttons, whatsapp.id]) - const handleRestartWhatsAppSession = async whatsapp => { - try { + function enable_button(whatsappId) { + setClicks((buttons) => + buttons.filter((id) => { + return +id !== +whatsappId + }) + ) + } - whatsapp.disabled = true + setTimeout(enable_button, 25000, whatsapp.id) - setClicks([...buttons, whatsapp.id]) + await api.post(`/restartwhatsappsession/${whatsapp.id}`) + } catch (err) { + toastError(err) + } + } - function enable_button(whatsappId) { + useEffect(() => { + // whatsApps.map((e) => { + // if (buttons.includes(e.id)) { + // e.disabled = true + // } + // }) - setClicks(buttons => buttons.filter(id => { return +id !== +whatsappId }),); + for (let i = 0; i < whatsApps.length; i++) { + if (buttons.includes(whatsApps[i].id)) { + whatsApps[i].disabled = true + } + } + }, [whatsApps, buttons]) - } + const handleRequestNewQrCode = async (whatsAppId) => { + try { + await api.put(`/whatsappsession/${whatsAppId}`) + } catch (err) { + toastError(err) + } + } - setTimeout(enable_button, 25000, whatsapp.id) + const handleOpenWhatsAppModal = () => { + setSelectedWhatsApp(null) + setWhatsAppModalOpen(true) + } - await api.post(`/restartwhatsappsession/${whatsapp.id}`); + const handleCloseWhatsAppModal = useCallback(() => { + setWhatsAppModalOpen(false) + setSelectedWhatsApp(null) + }, [setSelectedWhatsApp, setWhatsAppModalOpen]) - } catch (err) { - toastError(err); - } - }; + const handleOpenQrModal = (whatsApp) => { + setSelectedWhatsApp(whatsApp) + setQrModalOpen(true) + } + const handleCloseQrModal = useCallback(() => { + setSelectedWhatsApp(null) + setQrModalOpen(false) + }, [setQrModalOpen, setSelectedWhatsApp]) - useEffect(() => { + const handleEditWhatsApp = (whatsApp) => { + setSelectedWhatsApp(whatsApp) + setWhatsAppModalOpen(true) + } - // whatsApps.map((e) => { - // if (buttons.includes(e.id)) { - // e.disabled = true - // } - // }) + const handleOpenConfirmationModal = (action, whatsAppId) => { + if (action === 'disconnect') { + setConfirmModalInfo({ + action: action, + title: i18n.t('connections.confirmationModal.disconnectTitle'), + message: i18n.t('connections.confirmationModal.disconnectMessage'), + whatsAppId: whatsAppId, + }) + } + if (action === 'delete') { + setConfirmModalInfo({ + action: action, + title: i18n.t('connections.confirmationModal.deleteTitle'), + message: i18n.t('connections.confirmationModal.deleteMessage'), + whatsAppId: whatsAppId, + }) + } + setConfirmModalOpen(true) + } - for (let i = 0; i < whatsApps.length; i++) { - if (buttons.includes(whatsApps[i].id)) { - whatsApps[i].disabled = true - } - } + const handleSubmitConfirmationModal = async () => { + if (confirmModalInfo.action === 'disconnect') { + try { + await api.delete(`/whatsappsession/${confirmModalInfo.whatsAppId}`) + } catch (err) { + toastError(err) + } + } - }, [whatsApps, buttons]) + if (confirmModalInfo.action === 'delete') { + try { + await api.delete(`/whatsapp/${confirmModalInfo.whatsAppId}`) + toast.success(i18n.t('connections.toasts.deleted')) + } catch (err) { + toastError(err) + } + } + setConfirmModalInfo(confirmationModalInitialState) + } - const handleRequestNewQrCode = async whatsAppId => { - try { - await api.put(`/whatsappsession/${whatsAppId}`); - } catch (err) { - toastError(err); - } - }; + const renderActionButtons = (whatsApp) => { + return ( + ( + <> + {whatsApp.status === 'qrcode' && ( + + )} + {whatsApp.status === 'DISCONNECTED' && ( + <> + {' '} + + + )} + {(whatsApp.status === 'CONNECTED' || + whatsApp.status === 'PAIRING' || + whatsApp.status === 'TIMEOUT') && ( + + )} + {whatsApp.status === 'OPENING' && ( + + )} + + )} + /> + ) + } - const handleOpenWhatsAppModal = () => { - setSelectedWhatsApp(null); - setWhatsAppModalOpen(true); - }; + const renderStatusToolTips = (whatsApp) => { + return ( +
+ {whatsApp.status === 'DISCONNECTED' && ( + + + + )} + {whatsApp.status === 'OPENING' && ( + + )} + {whatsApp.status === 'qrcode' && ( + + + + )} + {whatsApp.status === 'CONNECTED' && ( + + + + )} + {(whatsApp.status === 'TIMEOUT' || whatsApp.status === 'PAIRING') && ( + + + + )} - const handleCloseWhatsAppModal = useCallback(() => { - setWhatsAppModalOpen(false); - setSelectedWhatsApp(null); - }, [setSelectedWhatsApp, setWhatsAppModalOpen]); - - const handleOpenQrModal = whatsApp => { - setSelectedWhatsApp(whatsApp); - setQrModalOpen(true); - }; - - const handleCloseQrModal = useCallback(() => { - setSelectedWhatsApp(null); - setQrModalOpen(false); - }, [setQrModalOpen, setSelectedWhatsApp]); - - const handleEditWhatsApp = whatsApp => { - setSelectedWhatsApp(whatsApp); - setWhatsAppModalOpen(true); - }; - - const handleOpenConfirmationModal = (action, whatsAppId) => { - if (action === "disconnect") { - setConfirmModalInfo({ - action: action, - title: i18n.t("connections.confirmationModal.disconnectTitle"), - message: i18n.t("connections.confirmationModal.disconnectMessage"), - whatsAppId: whatsAppId, - }); - } - - if (action === "delete") { - setConfirmModalInfo({ - action: action, - title: i18n.t("connections.confirmationModal.deleteTitle"), - message: i18n.t("connections.confirmationModal.deleteMessage"), - whatsAppId: whatsAppId, - }); - } - setConfirmModalOpen(true); - }; - - const handleSubmitConfirmationModal = async () => { - if (confirmModalInfo.action === "disconnect") { - try { - await api.delete(`/whatsappsession/${confirmModalInfo.whatsAppId}`); - } catch (err) { - toastError(err); - } - } - - if (confirmModalInfo.action === "delete") { - try { - await api.delete(`/whatsapp/${confirmModalInfo.whatsAppId}`); - toast.success(i18n.t("connections.toasts.deleted")); - } catch (err) { - toastError(err); - } - } - - setConfirmModalInfo(confirmationModalInitialState); - }; - - const renderActionButtons = whatsApp => { - return ( - - ( - - <> - {whatsApp.status === "qrcode" && ( - - )} - {whatsApp.status === "DISCONNECTED" && ( - - <> - {" "} - - - )} - {(whatsApp.status === "CONNECTED" || - whatsApp.status === "PAIRING" || - whatsApp.status === "TIMEOUT") && ( - - )} - {whatsApp.status === "OPENING" && ( - - )} - - - )} - /> - - ); - }; - - const renderStatusToolTips = whatsApp => { - return ( -
- {whatsApp.status === "DISCONNECTED" && ( - - - - )} - {whatsApp.status === "OPENING" && ( - - )} - {whatsApp.status === "qrcode" && ( - - - - )} - {whatsApp.status === "CONNECTED" && ( - - - - )} - {(whatsApp.status === "TIMEOUT" || whatsApp.status === "PAIRING") && ( - - - - )} - - {/* {whatsApp.status === "RESTORING" && ( + {/* {whatsApp.status === "RESTORING" && ( { )} */} -
- ); - }; - - - - - useEffect(() => { - - const delayDebounceFn = setTimeout(() => { - - const fetchQueries = async () => { - try { - - await api.post(`/restartwhatsappsession/0`, { params: { status: 'status' }, }); - - setDisabled(false) - - setClicks(buttons => buttons.map((e) => { return { id: e.id, disabled: false } })) - - } catch (err) { - console.log(err); - } - }; - - fetchQueries(); - - }, 500); - return () => clearTimeout(delayDebounceFn); - - }, []); - - - useEffect(() => { - const socket = openSocket(process.env.REACT_APP_BACKEND_URL); - - socket.on("diskSpaceMonit", data => { - if (data.action === "update") { - - setDiskSpaceInfo(data.diskSpace) - - } - }); - - return () => { - socket.disconnect(); - }; - }, []); - - return ( - - ( - - - - {confirmModalInfo.message} - - - - - - - - - - - {i18n.t("connections.title")} - - - ( - - )} - /> - - - - - - - - <> - - ( - <> - - - - - Size - - - Used - - - Available - - - Use% - - - - - - - {diskSpaceInfo.size} - {diskSpaceInfo.used} - {diskSpaceInfo.available} - {diskSpaceInfo.use} - - -
-
- - )} - /> - - - - - - - {i18n.t("connections.table.name")} - - - - {i18n.t("connections.table.status")} - - - ( - - {i18n.t("connections.table.session")} - - )} - /> - - - - - ( - - Restore - - )} - /> - - - - ( - - Session MB - - )} - /> - - - - - - {i18n.t("connections.table.lastUpdate")} - - - {i18n.t("connections.table.default")} - - - {i18n.t("connections.table.actions")} - - - - - {loading ? ( - - ) : ( - <> - {whatsApps?.length > 0 && - whatsApps.map(whatsApp => ( - - {whatsApp.name} - - - {renderStatusToolTips(whatsApp)} - - - ( - - {renderActionButtons(whatsApp)} - - )} - /> - - - - - - - ( - - - - - - - )} - /> - - - - ( - - -
{whatsApp.sessionSize}
-
-
- )} - /> - - - - - - - {format(parseISO(whatsApp.updatedAt), "dd/MM/yy HH:mm")} - - - - - {whatsApp.isDefault && ( -
- -
- )} -
- - - - - ( - handleEditWhatsApp(whatsApp)} - > - - - )} - /> - - - ( - { - handleOpenConfirmationModal("delete", whatsApp.id); - }} - > - - - )} - /> - - -
- ))} - - )} -
-
- - -
-
- )} - /> - - ); -}; - -export default Connections; +
+ ) + } + + useEffect(() => { + const delayDebounceFn = setTimeout(() => { + const fetchQueries = async () => { + try { + await api.post(`/restartwhatsappsession/0`, { + params: { status: 'status' }, + }) + + setDisabled(false) + + setClicks((buttons) => + buttons.map((e) => { + return { id: e.id, disabled: false } + }) + ) + } catch (err) { + console.log(err) + } + } + + fetchQueries() + }, 500) + return () => clearTimeout(delayDebounceFn) + }, []) + + useEffect(() => { + const socket = openSocket(process.env.REACT_APP_BACKEND_URL) + + socket.on('diskSpaceMonit', (data) => { + if (data.action === 'update') { + setDiskSpaceInfo(data.diskSpace) + } + }) + + socket.on('settings', (data) => { + if (data.action === 'update') { + setSettings((prevState) => { + const aux = [...prevState] + const settingIndex = aux.findIndex((s) => s.key === data.setting.key) + aux[settingIndex].value = data.setting.value + return aux + }) + } + }) + + return () => { + socket.disconnect() + } + }, []) + + return ( + ( + + + {confirmModalInfo.message} + + + + + + + + {i18n.t('connections.title')} + + + ( + + )} + /> + + + + + <> + ( + <> + + + + Size + Used + Available + Use% + + + + + + + {diskSpaceInfo.size} + + + {diskSpaceInfo.used} + + + {diskSpaceInfo.available} + + + {diskSpaceInfo.use} + + + +
+
+ + )} + /> + + + + + + {i18n.t('connections.table.name')} + + + + {i18n.t('connections.table.status')} + + + ( + + {i18n.t('connections.table.session')} + + )} + /> + + Restore} + /> + + ( + Session MB + )} + /> + + + {i18n.t('connections.table.lastUpdate')} + + + {i18n.t('connections.table.default')} + + + {i18n.t('connections.table.actions')} + + + + + {loading ? ( + + ) : ( + <> + {whatsApps?.length > 0 && + whatsApps.map((whatsApp) => ( + + + {whatsApp.name} + + + + {renderStatusToolTips(whatsApp)} + + + ( + + {renderActionButtons(whatsApp)} + + )} + /> + + ( + + + + )} + /> + + ( + + +
{whatsApp.sessionSize}
+
+
+ )} + /> + + + {format( + parseISO(whatsApp.updatedAt), + 'dd/MM/yy HH:mm' + )} + + + + {whatsApp.isDefault && ( +
+ +
+ )} +
+ + + ( + // disabled={ + // whatsApp.disabled || disabled + // ? true + // : false + // } +
+ {(settings && + settings.length > 0 && + getSettingValue('editURA') && + getSettingValue('editURA') === + 'enabled') | + (user.profile === 'master') ? ( + + handleEditWhatsApp(whatsApp) + } + > + + + ) : ( +
+ )} +
+ )} + /> + + ( + { + handleOpenConfirmationModal( + 'delete', + whatsApp.id + ) + }} + > + + + )} + /> +
+
+ ))} + + )} +
+
+ +
+
+ )} + /> + ) +} + +export default Connections diff --git a/frontend/src/pages/Queues/index.js b/frontend/src/pages/Queues/index.js index 4df3e78..99b6eab 100644 --- a/frontend/src/pages/Queues/index.js +++ b/frontend/src/pages/Queues/index.js @@ -1,6 +1,6 @@ -import React, { useEffect, useReducer, useState, useContext } from "react"; +import React, { useEffect, useReducer, useState, useContext } from 'react' -import openSocket from "socket.io-client"; +import openSocket from 'socket.io-client' import { Button, @@ -13,155 +13,186 @@ import { TableHead, TableRow, Typography, -} from "@material-ui/core"; +} from '@material-ui/core' -import MainContainer from "../../components/MainContainer"; -import MainHeader from "../../components/MainHeader"; -import MainHeaderButtonsWrapper from "../../components/MainHeaderButtonsWrapper"; -import TableRowSkeleton from "../../components/TableRowSkeleton"; -import Title from "../../components/Title"; -import { i18n } from "../../translate/i18n"; -import toastError from "../../errors/toastError"; -import api from "../../services/api"; -import { DeleteOutline, Edit } from "@material-ui/icons"; -import QueueModal from "../../components/QueueModal"; -import { toast } from "react-toastify"; -import ConfirmationModal from "../../components/ConfirmationModal"; +import MainContainer from '../../components/MainContainer' +import MainHeader from '../../components/MainHeader' +import MainHeaderButtonsWrapper from '../../components/MainHeaderButtonsWrapper' +import TableRowSkeleton from '../../components/TableRowSkeleton' +import Title from '../../components/Title' +import { i18n } from '../../translate/i18n' +import toastError from '../../errors/toastError' +import api from '../../services/api' +import { DeleteOutline, Edit } from '@material-ui/icons' +import QueueModal from '../../components/QueueModal' +import { toast } from 'react-toastify' +import ConfirmationModal from '../../components/ConfirmationModal' -import { AuthContext } from "../../context/Auth/AuthContext"; -import { Can } from "../../components/Can"; +import { AuthContext } from '../../context/Auth/AuthContext' +import { Can } from '../../components/Can' const useStyles = makeStyles((theme) => ({ mainPaper: { flex: 1, padding: theme.spacing(1), - overflowY: "scroll", + overflowY: 'scroll', ...theme.scrollbarStyles, }, customTableCell: { - display: "flex", - alignItems: "center", - justifyContent: "center", + display: 'flex', + alignItems: 'center', + justifyContent: 'center', }, -})); +})) const reducer = (state, action) => { - if (action.type === "LOAD_QUEUES") { - const queues = action.payload; - const newQueues = []; + if (action.type === 'LOAD_QUEUES') { + const queues = action.payload + const newQueues = [] queues.forEach((queue) => { - const queueIndex = state.findIndex((q) => q.id === queue.id); + const queueIndex = state.findIndex((q) => q.id === queue.id) if (queueIndex !== -1) { - state[queueIndex] = queue; + state[queueIndex] = queue } else { - newQueues.push(queue); + newQueues.push(queue) } - }); + }) - return [...state, ...newQueues]; + return [...state, ...newQueues] } - if (action.type === "UPDATE_QUEUES") { - const queue = action.payload; - const queueIndex = state.findIndex((u) => u.id === queue.id); + if (action.type === 'UPDATE_QUEUES') { + const queue = action.payload + const queueIndex = state.findIndex((u) => u.id === queue.id) if (queueIndex !== -1) { - state[queueIndex] = queue; - return [...state]; + state[queueIndex] = queue + return [...state] } else { - return [queue, ...state]; + return [queue, ...state] } } - if (action.type === "DELETE_QUEUE") { - const queueId = action.payload; - const queueIndex = state.findIndex((q) => q.id === queueId); + if (action.type === 'DELETE_QUEUE') { + const queueId = action.payload + const queueIndex = state.findIndex((q) => q.id === queueId) if (queueIndex !== -1) { - state.splice(queueIndex, 1); + state.splice(queueIndex, 1) } - return [...state]; + return [...state] } - if (action.type === "RESET") { - return []; + if (action.type === 'RESET') { + return [] } -}; +} const Queues = () => { - const classes = useStyles(); + const classes = useStyles() - const { user } = useContext(AuthContext); + const { user } = useContext(AuthContext) - const [queues, dispatch] = useReducer(reducer, []); - const [loading, setLoading] = useState(false); + const [queues, dispatch] = useReducer(reducer, []) + const [loading, setLoading] = useState(false) - const [queueModalOpen, setQueueModalOpen] = useState(false); - const [selectedQueue, setSelectedQueue] = useState(null); - const [confirmModalOpen, setConfirmModalOpen] = useState(false); + const [queueModalOpen, setQueueModalOpen] = useState(false) + const [selectedQueue, setSelectedQueue] = useState(null) + const [confirmModalOpen, setConfirmModalOpen] = useState(false) + + const [settings, setSettings] = useState([]) useEffect(() => { - (async () => { - setLoading(true); + ;(async () => { + setLoading(true) try { - const { data } = await api.get("/queue"); - dispatch({ type: "LOAD_QUEUES", payload: data }); + const { data } = await api.get('/queue') + dispatch({ type: 'LOAD_QUEUES', payload: data }) - setLoading(false); + setLoading(false) } catch (err) { - toastError(err); - setLoading(false); + toastError(err) + setLoading(false) } - })(); - }, []); + })() + }, []) useEffect(() => { - const socket = openSocket(process.env.REACT_APP_BACKEND_URL); + const fetchSession = async () => { + try { + const { data } = await api.get('/settings') + setSettings(data) + } catch (err) { + toastError(err) + } + } + fetchSession() + }, []) - socket.on("queue", (data) => { - if (data.action === "update" || data.action === "create") { - dispatch({ type: "UPDATE_QUEUES", payload: data.queue }); + const getSettingValue = (key) => { + const { value } = settings.find((s) => s.key === key) + + return value + } + + useEffect(() => { + const socket = openSocket(process.env.REACT_APP_BACKEND_URL) + + socket.on('queue', (data) => { + if (data.action === 'update' || data.action === 'create') { + dispatch({ type: 'UPDATE_QUEUES', payload: data.queue }) } - if (data.action === "delete") { - dispatch({ type: "DELETE_QUEUE", payload: data.queueId }); + if (data.action === 'delete') { + dispatch({ type: 'DELETE_QUEUE', payload: data.queueId }) } - }); + }) + + socket.on('settings', (data) => { + if (data.action === 'update') { + setSettings((prevState) => { + const aux = [...prevState] + const settingIndex = aux.findIndex((s) => s.key === data.setting.key) + aux[settingIndex].value = data.setting.value + return aux + }) + } + }) return () => { - socket.disconnect(); - }; - }, []); + socket.disconnect() + } + }, []) const handleOpenQueueModal = () => { - setQueueModalOpen(true); - setSelectedQueue(null); - }; + setQueueModalOpen(true) + setSelectedQueue(null) + } const handleCloseQueueModal = () => { - setQueueModalOpen(false); - setSelectedQueue(null); - }; + setQueueModalOpen(false) + setSelectedQueue(null) + } const handleEditQueue = (queue) => { - setSelectedQueue(queue); - setQueueModalOpen(true); - }; + setSelectedQueue(queue) + setQueueModalOpen(true) + } const handleCloseConfirmationModal = () => { - setConfirmModalOpen(false); - setSelectedQueue(null); - }; + setConfirmModalOpen(false) + setSelectedQueue(null) + } const handleDeleteQueue = async (queueId) => { try { - await api.delete(`/queue/${queueId}`); - toast.success(i18n.t("Queue deleted successfully!")); + await api.delete(`/queue/${queueId}`) + toast.success(i18n.t('Queue deleted successfully!')) } catch (err) { - toastError(err); + toastError(err) } - setSelectedQueue(null); - }; + setSelectedQueue(null) + } return ( { handleDeleteQueue(selectedQueue.id)} > - {i18n.t("queues.confirmationModal.deleteMessage")} + {i18n.t('queues.confirmationModal.deleteMessage')} { queueId={selectedQueue?.id} /> - {i18n.t("queues.title")} - + {i18n.t('queues.title')} { color="primary" onClick={handleOpenQueueModal} > - {i18n.t("queues.buttons.add")} + {i18n.t('queues.buttons.add')} )} /> - - - {i18n.t("queues.table.name")} + {i18n.t('queues.table.name')} - {i18n.t("queues.table.color")} + {i18n.t('queues.table.color')} - {i18n.t("queues.table.greeting")} + {i18n.t('queues.table.greeting')} - {i18n.t("queues.table.actions")} + {i18n.t('queues.table.actions')} @@ -238,7 +267,7 @@ const Queues = () => { backgroundColor: queue.color, width: 60, height: 20, - alignSelf: "center", + alignSelf: 'center', }} /> @@ -246,7 +275,7 @@ const Queues = () => {
@@ -255,25 +284,44 @@ const Queues = () => {
- - - - ( - handleEditQueue(queue)} +
- - + {(settings && + settings.length > 0 && + getSettingValue('editQueue') && + getSettingValue('editQueue') === 'enabled') | + (user.profile === 'master') ? ( + handleEditQueue(queue)} + > + + + ) : ( +
+ )} +
+ + // handleEditQueue(queue)} + // > + // + // )} /> - { { - setSelectedQueue(queue); - setConfirmModalOpen(true); + setSelectedQueue(queue) + setConfirmModalOpen(true) }} > )} /> -
))} @@ -301,7 +348,7 @@ const Queues = () => { )} /> - ); -}; + ) +} -export default Queues; +export default Queues diff --git a/frontend/src/pages/Settings/index.js b/frontend/src/pages/Settings/index.js index 2912d6d..ab79873 100644 --- a/frontend/src/pages/Settings/index.js +++ b/frontend/src/pages/Settings/index.js @@ -1,190 +1,207 @@ -import React, { useState, useEffect, useContext} from "react"; -import openSocket from "socket.io-client"; +import React, { useState, useEffect, useContext } from 'react' +import openSocket from 'socket.io-client' -import { makeStyles } from "@material-ui/core/styles"; -import Paper from "@material-ui/core/Paper"; -import Typography from "@material-ui/core/Typography"; -import Container from "@material-ui/core/Container"; -import Select from "@material-ui/core/Select"; -import { toast } from "react-toastify"; +import { makeStyles } from '@material-ui/core/styles' +import Paper from '@material-ui/core/Paper' +import Typography from '@material-ui/core/Typography' +import Container from '@material-ui/core/Container' +import Select from '@material-ui/core/Select' +import { toast } from 'react-toastify' -import api from "../../services/api"; -import { i18n } from "../../translate/i18n.js"; -import toastError from "../../errors/toastError"; +import api from '../../services/api' +import { i18n } from '../../translate/i18n.js' +import toastError from '../../errors/toastError' //-------- -import { AuthContext } from "../../context/Auth/AuthContext"; -import { Can } from "../../components/Can"; +import { AuthContext } from '../../context/Auth/AuthContext' + +import { Can } from '../../components/Can' // import Button from "@material-ui/core/Button"; -const useStyles = makeStyles(theme => ({ - root: { - display: "flex", - alignItems: "center", - padding: theme.spacing(4), - }, +const useStyles = makeStyles((theme) => ({ + root: { + display: 'flex', + alignItems: 'center', + padding: theme.spacing(4), + }, - paper: { - padding: theme.spacing(2), - display: "flex", - alignItems: "center", - }, + paper: { + padding: theme.spacing(2), + display: 'flex', + alignItems: 'center', + }, - settingOption: { - marginLeft: "auto", - }, - margin: { - margin: theme.spacing(1), - }, -})); + settingOption: { + marginLeft: 'auto', + }, + margin: { + margin: theme.spacing(1), + }, +})) const Settings = () => { - const classes = useStyles(); + const classes = useStyles() - //-------- - const { user } = useContext(AuthContext); + //-------- + const { user } = useContext(AuthContext) - const [settings, setSettings] = useState([]); + const [settings, setSettings] = useState([]) - useEffect(() => { - const fetchSession = async () => { - try { - const { data } = await api.get("/settings"); - setSettings(data); - } catch (err) { - toastError(err); - } - }; - fetchSession(); - }, []); + useEffect(() => { + const fetchSession = async () => { + try { + const { data } = await api.get('/settings') + setSettings(data) + } catch (err) { + toastError(err) + } + } + fetchSession() + }, []) - useEffect(() => { - const socket = openSocket(process.env.REACT_APP_BACKEND_URL); + useEffect(() => { + const socket = openSocket(process.env.REACT_APP_BACKEND_URL) - socket.on("settings", data => { - if (data.action === "update") { - setSettings(prevState => { - const aux = [...prevState]; - const settingIndex = aux.findIndex(s => s.key === data.setting.key); - aux[settingIndex].value = data.setting.value; - return aux; - }); - } - }); + socket.on('settings', (data) => { + console.log('settings updated ----------------------------') - return () => { - socket.disconnect(); - }; - }, []); + if (data.action === 'update') { + setSettings((prevState) => { + const aux = [...prevState] + const settingIndex = aux.findIndex((s) => s.key === data.setting.key) + aux[settingIndex].value = data.setting.value + return aux + }) + } + }) - const handleChangeSetting = async e => { - const selectedValue = e.target.value; - const settingKey = e.target.name; + return () => { + socket.disconnect() + } + }, []) - try { - await api.put(`/settings/${settingKey}`, { - value: selectedValue, - }); - toast.success(i18n.t("settings.success")); - } catch (err) { - toastError(err); - } - }; + useEffect(() => { + console.log('------> settings: ', settings) + }, [settings]) - const getSettingValue = key => { - const { value } = settings.find(s => s.key === key); - return value; - }; + const handleChangeSetting = async (e) => { + const selectedValue = e.target.value + const settingKey = e.target.name + try { + await api.put(`/settings/${settingKey}`, { + value: selectedValue, + }) + toast.success(i18n.t('settings.success')) + } catch (err) { + toastError(err) + } + } - // const handleEdit = () => { - - // - - // } + const getSettingValue = (key) => { + const { value } = settings.find((s) => s.key === key) - return ( + return value + } + return ( + ( +
+
+ + + {i18n.t('settings.title')} + - ( + + + {i18n.t('settings.settings.userCreation.name')} + -
+ + + +
-
- - - {i18n.t("settings.title")} - - - - - {i18n.t("settings.settings.userCreation.name")} - - - - - -
- +
+ + + Editar ura - {/*
- - - Application name - - - + + + +
- - Estudio Face - +
+ + + Editar fila + + + +
+
+ )} + /> + ) +} - - -
- -
-
*/} - -
- - )} - /> - - ); -}; - -export default Settings; +export default Settings diff --git a/frontend/src/rules.js b/frontend/src/rules.js index 2ea72e4..1b7c1ad 100644 --- a/frontend/src/rules.js +++ b/frontend/src/rules.js @@ -1,59 +1,58 @@ const rules = { - user: { - static: [], - }, + user: { + static: [], + }, - admin: { - static: [ - //"show-icon-edit-whatsapp", + admin: { + static: [ + 'show-icon-edit-whatsapp', + 'show-icon-edit-queue', - "drawer-admin-items:view", - "tickets-manager:showall", - "user-modal:editProfile", - "user-modal:editQueues", - "ticket-options:deleteTicket", - "contacts-page:deleteContact", - "contacts-page:import-csv-contacts", - "connections-view:show", - "dashboard-view:show", - "queues-view:show", - "user-view:show", - "ticket-report:show", - - ], - }, + 'drawer-admin-items:view', + 'tickets-manager:showall', + 'user-modal:editProfile', + 'user-modal:editQueues', + 'ticket-options:deleteTicket', + 'contacts-page:deleteContact', + 'contacts-page:import-csv-contacts', + 'connections-view:show', + 'dashboard-view:show', + 'queues-view:show', + 'user-view:show', + 'ticket-report:show', + ], + }, - master: { - static: [ + master: { + static: [ + 'url-remote-session:show', + 'show-icon-edit-whatsapp', + 'show-icon-add-queue', + 'show-icon-edit-queue', + 'show-icon-delete-queue', + 'space-disk-info:show', - "show-icon-edit-whatsapp", - "show-icon-add-queue", - "show-icon-edit-queue", - "show-icon-delete-queue", - "space-disk-info:show", - + 'drawer-admin-items:view', + 'tickets-manager:showall', + 'user-modal:editProfile', + 'user-modal:editQueues', + 'ticket-options:deleteTicket', + 'contacts-page:deleteContact', + 'contacts-page:import-contacts', + 'contacts-page:import-csv-contacts', + 'connections-view:show', + 'dashboard-view:show', + 'queues-view:show', + 'user-view:show', + 'settings-view:show', + 'btn-add-user', + 'icon-remove-user', + 'btn-add-whatsapp', + 'btn-remove-whatsapp', + 'ticket-report:show', + 'connection-button:show', + ], + }, +} - "drawer-admin-items:view", - "tickets-manager:showall", - "user-modal:editProfile", - "user-modal:editQueues", - "ticket-options:deleteTicket", - "contacts-page:deleteContact", - "contacts-page:import-contacts", - "contacts-page:import-csv-contacts", - "connections-view:show", - "dashboard-view:show", - "queues-view:show", - "user-view:show", - "settings-view:show", - "btn-add-user", - "icon-remove-user", - "btn-add-whatsapp", - "btn-remove-whatsapp", - "ticket-report:show", - "connection-button:show" - ], - }, -}; - -export default rules; +export default rules