Compare commits

..

14 Commits

Author SHA1 Message Date
adriano 0a031bd9a8 fix issues for websocket merge 2024-08-29 18:09:00 -03:00
adriano 1f8d5eb29b Merge branch 'websocket' of https://github.com/AdrianoRobson/projeto-hit into merge-socket 2024-08-22 16:53:27 -03:00
adriano 125e758a18 firt commit 2024-08-22 16:51:31 -03:00
adriano 83d197f240 feat: remoteTickesControll listeners 2024-05-23 17:39:42 -03:00
adriano 435a577bed fix: listener para ticket deletado 2024-05-22 12:51:11 -03:00
adriano fce5554681 fix: update message ack 2024-05-22 09:51:10 -03:00
adriano 3ced558b18 fix: getSettingValue quebrando a app 2024-05-21 10:15:59 -03:00
adriano 7bb73cfa19 fix: bugs de atualizacao dos tickets tempo real 2024-05-20 17:24:06 -03:00
adriano 62f137d884 feat: load balance 2024-05-20 10:00:45 -03:00
willian-pessoa eb1d0f2303 feat: verificar ticket id antes de atualizar lista de msgs 2024-05-09 16:01:21 -03:00
willian-pessoa dac57f9d48 refactor: restantes das conexoes para a conexao ws global 2024-05-09 15:59:02 -03:00
willian-pessoa 5981f9dd5e refactor: mais 7 conexoes movidas para conexao ws global 2024-05-09 15:31:30 -03:00
willian-pessoa 4d3cab5333 refactor: mais tres ws connecoes movidas para conecao global 2024-05-09 09:01:21 -03:00
willian-pessoa a5d3f19e1a refactor: criado conexao web socket global e movido alguns listeners para ela 2024-05-08 18:02:31 -03:00
31 changed files with 515 additions and 338 deletions

View File

@ -17,6 +17,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@sentry/node": "^5.29.2", "@sentry/node": "^5.29.2",
"@socket.io/redis-adapter": "^7.2.0",
"@types/fluent-ffmpeg": "^2.1.21", "@types/fluent-ffmpeg": "^2.1.21",
"@types/pino": "^6.3.4", "@types/pino": "^6.3.4",
"axios": "^1.2.3", "axios": "^1.2.3",
@ -41,18 +42,20 @@
"pino": "^6.9.0", "pino": "^6.9.0",
"pino-pretty": "^9.1.1", "pino-pretty": "^9.1.1",
"qrcode-terminal": "^0.12.0", "qrcode-terminal": "^0.12.0",
"redis": "^4.6.13",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"sequelize": "^5.22.3", "sequelize": "^5.22.3",
"sequelize-cli": "^5.5.1", "sequelize-cli": "^5.5.1",
"sequelize-typescript": "^1.1.0", "sequelize-typescript": "^1.1.0",
"sharp": "^0.32.5", "sharp": "^0.32.5",
"socket.io": "^3.0.5", "socket.io": "^4.7.5",
"socket.io-client": "^4.5.4", "socket.io-client": "^4.5.4",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"whatsapp-web.js": "github:pedroslopez/whatsapp-web.js", "whatsapp-web.js": "github:pedroslopez/whatsapp-web.js",
"yup": "^0.32.8" "yup": "^0.32.8"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash": "4.14",
"@types/bcryptjs": "^2.4.2", "@types/bcryptjs": "^2.4.2",
"@types/bluebird": "^3.5.32", "@types/bluebird": "^3.5.32",
"@types/cookie-parser": "^1.4.2", "@types/cookie-parser": "^1.4.2",

View File

@ -3,6 +3,9 @@ import { Server } from "http";
import AppError from "../errors/AppError"; import AppError from "../errors/AppError";
import { logger } from "../utils/logger"; import { logger } from "../utils/logger";
import { createAdapter } from "@socket.io/redis-adapter";
import { createClient } from 'redis';
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import ListUserParamiterService from "../services/UserServices/ListUserParamiterService"; import ListUserParamiterService from "../services/UserServices/ListUserParamiterService";
import { import {
@ -27,6 +30,7 @@ import {
} from "../services/WbotServices/wbotMessageListener"; } from "../services/WbotServices/wbotMessageListener";
import { join } from "path"; import { join } from "path";
import Whatsapp from "../models/Whatsapp"; import Whatsapp from "../models/Whatsapp";
import { get } from "../helpers/RedisClient"
let count: number = 0; let count: number = 0;
let listOnline: any[] = []; let listOnline: any[] = [];
@ -42,16 +46,32 @@ let dateTime = splitDateTime(
new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR })) new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
); );
export const initIO = (httpServer: Server): SocketIO => {
const pubClient = createClient({ url: 'redis://172.31.187.29:6379' });
const subClient = pubClient.duplicate();
pubClient.connect().catch(console.error);
subClient.connect().catch(console.error);
export const initIO = (httpServer: Server): SocketIO => {
io = new SocketIO(httpServer, { io = new SocketIO(httpServer, {
cors: { cors: {
origin: process.env.FRONTEND_URL origin: process.env.FRONTEND_URL,
//allowedHeaders: ["my-custom-header"],
//credentials: true
}, },
maxHttpBufferSize: 1e8 maxHttpBufferSize: 1e8,
}); // pingInterval: 25000,
// pingTimeout: 60000,
// adapter: createAdapter(pubClient, subClient)
});
io.on("connection", socket => { io.on("connection", socket => {
logger.info("Client Connected"); logger.info("Client Connected");
socket.on("joinWhatsSession", (whatsappId: string) => { socket.on("joinWhatsSession", (whatsappId: string) => {
logger.info(`A client joined a joinWhatsSession channel: ${whatsappId}`); logger.info(`A client joined a joinWhatsSession channel: ${whatsappId}`);
@ -107,6 +127,7 @@ export const initIO = (httpServer: Server): SocketIO => {
socket.on("online", (userId: any) => { socket.on("online", (userId: any) => {
// console.log('userId: ', userId) // console.log('userId: ', userId)
return
obj.uuid = uuidv4(); obj.uuid = uuidv4();
if (userId.logoutUserId) { if (userId.logoutUserId) {
@ -233,13 +254,18 @@ export const initIO = (httpServer: Server): SocketIO => {
if (rooms && rooms.size == 2 && ![...rooms][1].startsWith("session_")) if (rooms && rooms.size == 2 && ![...rooms][1].startsWith("session_"))
return; return;
let whatsappIds: any = await Whatsapp.findAll({ let whatsappIds = await get({
attributes: ["id"], key: "whatsapp:*",
raw: true parse: true
}); });
// let whatsappIds: any = await Whatsapp.findAll({
// attributes: ["id"],
// raw: true
// });
if (whatsappIds && whatsappIds.length > 0) { if (whatsappIds && whatsappIds.length > 0) {
whatsappIds = whatsappIds.map((e: any) => `${e.id}`); // whatsappIds = whatsappIds.map((e: any) => `${e.id}`);
console.log( console.log(
"whatsappIds whatsappIds whatsappIds whatsappIds whatsappIds: ", "whatsappIds whatsappIds whatsappIds whatsappIds whatsappIds: ",

View File

@ -43,7 +43,7 @@
"yup": "^0.32.8" "yup": "^0.32.8"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "PORT=3331 react-scripts start",
"build": "react-scripts build", "build": "react-scripts build",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject" "eject": "react-scripts eject"

View File

@ -1,7 +1,9 @@
import React, { useContext, useState, useEffect, useReducer, useRef } from "react" import React, { useContext, useState, useEffect, useReducer, useRef } from "react"
import { isSameDay, parseISO, format } from "date-fns" import { isSameDay, parseISO, format } from "date-fns"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import clsx from "clsx" import clsx from "clsx"
import { AuthContext } from "../../context/Auth/AuthContext" import { AuthContext } from "../../context/Auth/AuthContext"
@ -34,7 +36,7 @@ import whatsBackground from "../../assets/wa-background.png"
import api from "../../services/api" import api from "../../services/api"
import toastError from "../../errors/toastError" import toastError from "../../errors/toastError"
import { countTicketMsgContext } from "../../context/CountTicketMsgProvider/CountTicketMsgProvider" import { countTicketMsgContext } from "../../context/CountTicketMsgProvider/CountTicketMsgProvider"
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
messagesListWrapper: { messagesListWrapper: {
@ -438,11 +440,18 @@ const MessagesList = ({ ticketId, isGroup }) => {
}, [pageNumber, ticketId]) }, [pageNumber, ticketId])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("connect", () => socket.emit("joinChatBox", ticketId)) const onConnectMessagesList = () => {
socket.emit("joinChatBox", ticketId)
}
socket.on("appMessage", (data) => { onConnectMessagesList()
socket.on("connect", onConnectMessagesList)
const onAppMessageMessagesList = (data) => {
if (+data.message.ticketId !== +ticketId) return
if (data.action === "create") { if (data.action === "create") {
@ -454,10 +463,14 @@ const MessagesList = ({ ticketId, isGroup }) => {
if (data.action === "update") { if (data.action === "update") {
dispatch({ type: "UPDATE_MESSAGE", payload: data.message }) dispatch({ type: "UPDATE_MESSAGE", payload: data.message })
} }
}) }
socket.on("appMessage", onAppMessageMessagesList)
return () => { return () => {
socket.disconnect() socket.emit("leaveChatBox", ticketId)
socket.off("connect", onConnectMessagesList)
socket.off("appMessage", onAppMessageMessagesList)
} }
}, [ticketId]) }, [ticketId])
@ -949,4 +962,4 @@ const MessagesList = ({ ticketId, isGroup }) => {
) )
} }
export default MessagesList export default MessagesList

View File

@ -2,7 +2,8 @@ import React, { useState, useRef, useEffect, useContext } from "react"
import { useHistory } from "react-router-dom" import { useHistory } from "react-router-dom"
import { format } from "date-fns" import { format } from "date-fns"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import useSound from "use-sound" import useSound from "use-sound"
import Popover from "@material-ui/core/Popover" import Popover from "@material-ui/core/Popover"
@ -115,24 +116,24 @@ const NotificationsPopOver = () => {
useEffect(() => { useEffect(() => {
const fetchSession = async () => { const fetchSession = async () => {
try { try {
const { data } = await api.get('/settings') const { data } = await api.get('/settings')
setSettings(data.settings) setSettings(data.settings)
} catch (err) { } catch (err) {
toastError(err) toastError(err)
} }
} }
fetchSession() fetchSession()
}, []) }, [])
const getSettingValue = (key) => { const getSettingValue = (key) => {
const { value } = settings.find((s) => s.key === key) const { value } = settings.find((s) => s.key === key)
return value return value
} }
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("reload_page", (data) => { socket.on("reload_page", (data) => {
@ -193,7 +194,8 @@ const NotificationsPopOver = () => {
return () => { return () => {
socket.disconnect() socket.removeAllListeners('reload_page');
socket.removeAllListeners('onlineStatus');
} }
}, [user.id, handleLogout, user.profile]) }, [user.id, handleLogout, user.profile])
@ -201,12 +203,17 @@ const NotificationsPopOver = () => {
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("connect", () => socket.emit("joinNotification")) const onConnectNotifications = () => {
socket.emit("joinNotification")
}
onConnectNotifications()
socket.on("ticket", data => { socket.on("connect", onConnectNotifications)
const onTicketNotifications = data => {
if (data.action === "updateUnread" || data.action === "delete") { if (data.action === "updateUnread" || data.action === "delete") {
@ -232,25 +239,18 @@ const NotificationsPopOver = () => {
return prevState return prevState
}) })
} }
}) }
socket.on("appMessage", data => {
socket.on("ticket", onTicketNotifications)
const onAppMessageNotifications = data => {
if ( if (
data.action === "create" && data.action === "create" &&
!data.message.read && !data.message.read &&
(data.ticket.userId === user?.id || !data.ticket.userId) (data.ticket.userId === user?.id || !data.ticket.userId)
) { ) {
setNotifications(prevState => { setNotifications(prevState => {
// prevState.forEach((e)=>{ // prevState.forEach((e)=>{
// //
// }) // })
@ -265,8 +265,6 @@ const NotificationsPopOver = () => {
return [data.ticket, ...prevState] return [data.ticket, ...prevState]
}) })
const shouldNotNotificate = (data.message.ticketId === ticketIdRef.current && document.visibilityState === "visible") || const shouldNotNotificate = (data.message.ticketId === ticketIdRef.current && document.visibilityState === "visible") ||
(data.ticket.userId && data.ticket.userId !== user?.id) || (data.ticket.userId && data.ticket.userId !== user?.id) ||
data.ticket.isGroup || !data.ticket.userId data.ticket.isGroup || !data.ticket.userId
@ -275,20 +273,25 @@ const NotificationsPopOver = () => {
handleNotifications(data) handleNotifications(data)
} }
}) }
socket.on('notifyPeding', data =>{ socket.on("appMessage", onAppMessageNotifications)
if(settings?.length > 0 && getSettingValue('notificationTransferQueue') === 'enabled') handleNotifications("", data);
socket.on('notifyPeding', data => {
if (settings?.length > 0 && getSettingValue('notificationTransferQueue') === 'enabled') handleNotifications("", data);
}); });
return () => { return () => {
socket.disconnect() socket.off('connect', onConnectNotifications);
socket.off('ticket', onTicketNotifications);
socket.off('appMessage', onAppMessageNotifications);
socket.removeAllListeners('notifyPeding');
} }
}, [user, settings]) }, [user, settings])
const handleNotifications = (data, notify) => { const handleNotifications = (data, notify) => {
let isQueue = false; let isQueue = false;
if(!notify){ if (!notify) {
const { message, contact, ticket } = data const { message, contact, ticket } = data
const options = { const options = {
@ -301,14 +304,14 @@ const NotificationsPopOver = () => {
const notification = new Notification( const notification = new Notification(
`${i18n.t("tickets.notification.message")} ${contact.name}`, `${i18n.t("tickets.notification.message")} ${contact.name}`,
options options
) )
notification.onclick = e => { notification.onclick = e => {
e.preventDefault() e.preventDefault()
window.focus() window.focus()
historyRef.current.push(`/tickets/${ticket.id}`) historyRef.current.push(`/tickets/${ticket.id}`)
} }
setDesktopNotifications(prevState => { setDesktopNotifications(prevState => {
const notfiticationIndex = prevState.findIndex( const notfiticationIndex = prevState.findIndex(
n => n.tag === notification.tag n => n.tag === notification.tag
@ -319,15 +322,15 @@ const NotificationsPopOver = () => {
} }
return [notification, ...prevState] return [notification, ...prevState]
}) })
}else{ } else {
user.queues.forEach(queue =>{ user.queues.forEach(queue => {
if(queue.id === notify.data?.queue?.id){ if (queue.id === notify.data?.queue?.id) {
isQueue = true; isQueue = true;
} }
}) })
if(!isQueue){ if (!isQueue) {
return; return;
}else { } else {
const notification = new Notification(`${i18n.t("tickets.notification.messagePeding")} ${notify.data?.queue?.name}`); const notification = new Notification(`${i18n.t("tickets.notification.messagePeding")} ${notify.data?.queue?.name}`);
notification.onclick = e => { notification.onclick = e => {
e.preventDefault() e.preventDefault()
@ -346,7 +349,7 @@ const NotificationsPopOver = () => {
return [notification, ...prevState] return [notification, ...prevState]
}) })
} }
} }
soundAlertRef.current() soundAlertRef.current()
} }

View File

@ -3,7 +3,8 @@ import React, { useState, useEffect, useRef, useContext } from "react"
import * as Yup from "yup" import * as Yup from "yup"
import { Formik, Form, Field } from "formik" import { Formik, Form, Field } from "formik"
import { toast } from "react-toastify" import { toast } from "react-toastify"
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from "../../services/socket"
import { import {
makeStyles, makeStyles,
@ -50,8 +51,8 @@ const useStyles = makeStyles((theme) => ({
})) }))
const PositionSchema = Yup.object().shape({ const PositionSchema = Yup.object().shape({
name: Yup.string() name: Yup.string()
.required("Required"), .required("Required"),
}) })
const PositionModal = ({ const PositionModal = ({
@ -65,14 +66,14 @@ const PositionModal = ({
const isMounted = useRef(true) const isMounted = useRef(true)
const initialState = { const initialState = {
name: "", name: "",
} }
const [position, setPosition] = useState(initialState) const [position, setPosition] = useState(initialState)
// const [selectedQueueIds, setSelectedQueueIds] = useState([]) // const [selectedQueueIds, setSelectedQueueIds] = useState([])
const { setting } = useContext(AuthContext) const { setting } = useContext(AuthContext)
const [settings, setSettings] = useState(setting) const [settings, setSettings] = useState(setting)
useEffect(() => { useEffect(() => {
return () => { return () => {
@ -86,9 +87,9 @@ const PositionModal = ({
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('settings', (data) => { const onSettingsPosition = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -97,10 +98,12 @@ const PositionModal = ({
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsPosition)
return () => { return () => {
socket.disconnect() socket.off("settings", onSettingsPosition)
} }
}, []) }, [])
@ -140,7 +143,7 @@ const PositionModal = ({
const handleSavePosition = async (values) => { const handleSavePosition = async (values) => {
try { try {
if (positionId) { if (positionId) {
await api.put(`/positions/${positionId}`, values) await api.put(`/positions/${positionId}`, values)
handleClose() handleClose()
@ -153,7 +156,7 @@ const PositionModal = ({
handleClose() handleClose()
toast.success("Cargo salvo com sucesso") toast.success("Cargo salvo com sucesso")
} }
} catch (err) { } catch (err) {
toastError(err) toastError(err)
} }
@ -200,7 +203,7 @@ const PositionModal = ({
className={classes.textField} className={classes.textField}
fullWidth fullWidth
/> />
</div> </div>
{/* <div> {/* <div>
{ {
((settings && getSettingValue('quickAnswerByQueue') === 'enabled')) && ( ((settings && getSettingValue('quickAnswerByQueue') === 'enabled')) && (

View File

@ -1,6 +1,8 @@
import React, { useEffect, useState, useContext } from "react"; import React, { useEffect, useState, useContext } from "react";
import QRCode from "qrcode.react"; import QRCode from "qrcode.react";
import openSocket from "socket.io-client"; //import openSocket from "socket.io-client";
import { socket } from "../../services/socket";
import toastError from "../../errors/toastError"; import toastError from "../../errors/toastError";
import { Dialog, DialogContent, Paper, Typography } from "@material-ui/core"; import { Dialog, DialogContent, Paper, Typography } from "@material-ui/core";
@ -31,9 +33,9 @@ const QrcodeModal = ({ open, onClose, whatsAppId }) => {
useEffect(() => { useEffect(() => {
if (!whatsAppId) return; if (!whatsAppId) return;
const socket = openSocket(process.env.REACT_APP_BACKEND_URL); //const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
socket.on("whatsappSession", data => { const onWhatsAppSessionQrCode = data => {
if (data.action === "update" && data.session.id === whatsAppId) { if (data.action === "update" && data.session.id === whatsAppId) {
setQrCode(data.session.qrcode); setQrCode(data.session.qrcode);
} }
@ -42,21 +44,23 @@ const QrcodeModal = ({ open, onClose, whatsAppId }) => {
onClose(); onClose();
} }
if (data.action === "error") { if (data.action === "error") {
console.log('user.profile: ', user.profile) console.log('user.profile: ', user.profile)
if(user.profile === 'master'){ if (user.profile === 'master') {
alert(data.msg) alert(data.msg)
} }
} }
}); }
socket.on("whatsappSession", onWhatsAppSessionQrCode);
return () => { return () => {
socket.disconnect(); socket.off("whatsappSession", onWhatsAppSessionQrCode);
}; };
}, [whatsAppId, onClose, user.profile]); }, [whatsAppId, onClose, user.profile]);

View File

@ -23,8 +23,8 @@ import { IconButton, InputAdornment } from "@material-ui/core"
import { Colorize } from "@material-ui/icons" import { Colorize } from "@material-ui/icons"
import { AuthContext } from '../../context/Auth/AuthContext' import { AuthContext } from '../../context/Auth/AuthContext'
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from "../../services/socket"
const useStyles = makeStyles(theme => ({ const useStyles = makeStyles(theme => ({
@ -92,9 +92,9 @@ const QueueModal = ({ open, onClose, queueId }) => {
}, [setting]) }, [setting])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('settings', (data) => { const onSettingsQueueModal = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -103,10 +103,12 @@ const QueueModal = ({ open, onClose, queueId }) => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsQueueModal)
return () => { return () => {
socket.disconnect() socket.off("settings", onSettingsQueueModal)
} }
}, []) }, [])

View File

@ -3,8 +3,8 @@ import React, { useState, useEffect, useRef, useContext } from "react"
import * as Yup from "yup" import * as Yup from "yup"
import { Formik, Form, Field } from "formik" import { Formik, Form, Field } from "formik"
import { toast } from "react-toastify" import { toast } from "react-toastify"
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from "../../services/socket"
import { import {
makeStyles, makeStyles,
@ -79,7 +79,7 @@ const QuickAnswersModal = ({
const [quickAnswer, setQuickAnswer] = useState(initialState) const [quickAnswer, setQuickAnswer] = useState(initialState)
const [selectedQueueIds, setSelectedQueueIds] = useState([]) const [selectedQueueIds, setSelectedQueueIds] = useState([])
const { user, setting, getSettingValue } = useContext(AuthContext) const { user, setting, getSettingValue } = useContext(AuthContext)
const [settings, setSettings] = useState(setting) const [settings, setSettings] = useState(setting)
useEffect(() => { useEffect(() => {
return () => { return () => {
@ -92,18 +92,18 @@ const QuickAnswersModal = ({
}, [setting]) }, [setting])
useEffect(() => { useEffect(() => {
setSelectedQueueIds([]) setSelectedQueueIds([])
if (open && selectedQueueIds.length === 0 && !quickAnswerId) { if (open && selectedQueueIds.length === 0 && !quickAnswerId) {
setSelectedQueueIds(user.queues.map(q => q.id)) setSelectedQueueIds(user.queues.map(q => q.id))
} }
}, [open,]) }, [open,])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('settings', (data) => { const onSettingsQuickAnswersModal = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -112,14 +112,16 @@ const QuickAnswersModal = ({
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsQuickAnswersModal)
return () => { return () => {
socket.disconnect() socket.off("settings", onSettingsQuickAnswersModal)
} }
}, []) }, [])
useEffect(() => { useEffect(() => {
// setSelectedQueueIds([]) // setSelectedQueueIds([])
@ -139,7 +141,7 @@ const QuickAnswersModal = ({
if (isMounted.current) { if (isMounted.current) {
setQuickAnswer(data) setQuickAnswer(data)
if (data?.queues) { if (data?.queues) {
const quickQueueIds = data.queues?.map((queue) => queue.id) const quickQueueIds = data.queues?.map((queue) => queue.id)
setSelectedQueueIds(quickQueueIds) setSelectedQueueIds(quickQueueIds)
} }

View File

@ -3,8 +3,8 @@ import React, { useState, useEffect, useRef, useContext } from "react"
import * as Yup from "yup" import * as Yup from "yup"
import { Formik, Form, Field } from "formik" import { Formik, Form, Field } from "formik"
import { toast } from "react-toastify" import { toast } from "react-toastify"
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from "../../services/socket"
import { import {
makeStyles, makeStyles,
@ -91,9 +91,9 @@ const StatusChatEndModal = ({
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('settings', (data) => { const onSettingsStatusChatEndModal = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -102,10 +102,12 @@ const StatusChatEndModal = ({
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsStatusChatEndModal)
return () => { return () => {
socket.disconnect() socket.off("settings", onSettingsStatusChatEndModal)
} }
}, []) }, [])

View File

@ -2,7 +2,9 @@ import React, { useState, useEffect } from "react"
import { useParams, useHistory } from "react-router-dom" import { useParams, useHistory } from "react-router-dom"
import { toast } from "react-toastify" import { toast } from "react-toastify"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import clsx from "clsx" import clsx from "clsx"
import { Paper, makeStyles } from "@material-ui/core" import { Paper, makeStyles } from "@material-ui/core"
@ -132,22 +134,32 @@ const Ticket = () => {
}, []) }, [])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("connect", () => socket.emit("joinChatBox", ticketId)) const onConnectTicket = () => socket.emit("joinChatBox", ticketId)
onConnectTicket()
socket.on("connect", onConnectTicket)
const onTicketTicket = (data) => {
const isSameTicket = +data?.ticket?.id === +ticketId || +data.ticketId === +ticketId
if (!isSameTicket) return
socket.on("ticket", (data) => {
if (data.action === "update") { if (data.action === "update") {
setTicket(data.ticket) setTicket(data.ticket)
} }
if (data.action === "delete") { if (data.action === "deleteForever") {
console.log('delete forever')
toast.success("Ticket deleted sucessfully.") toast.success("Ticket deleted sucessfully.")
history.push("/tickets") history.push("/tickets")
} }
}) }
socket.on("contact", (data) => { socket.on("ticket", onTicketTicket)
const onContactTicket = (data) => {
if (data.action === "update") { if (data.action === "update") {
setContact((prevState) => { setContact((prevState) => {
if (prevState.id === data.contact?.id) { if (prevState.id === data.contact?.id) {
@ -156,9 +168,11 @@ const Ticket = () => {
return prevState return prevState
}) })
} }
}) }
socket.on("remoteTickesControllIdleOpen", (data) => { socket.on("contact", onContactTicket)
const onRemoteTicketsControllIdleOpenTicket = (data) => {
if (data.action === "update") { if (data.action === "update") {
let url_ticketId let url_ticketId
try { try {
@ -175,10 +189,15 @@ const Ticket = () => {
console.log('error on try do the send seen: ', error) console.log('error on try do the send seen: ', error)
} }
} }
}) }
socket.on("remoteTickesControllIdleOpen", onRemoteTicketsControllIdleOpenTicket)
return () => { return () => {
socket.disconnect() socket.off("connect", onConnectTicket)
socket.off("ticket", onTicketTicket)
socket.off("contact", onContactTicket)
socket.off("remoteTickesControllIdleOpen", onRemoteTicketsControllIdleOpenTicket)
} }
}, [ticketId, history]) }, [ticketId, history])

View File

@ -22,7 +22,8 @@ import MarkdownWrapper from "../MarkdownWrapper"
import { Tooltip } from "@material-ui/core" import { Tooltip } from "@material-ui/core"
import { AuthContext } from "../../context/Auth/AuthContext" import { AuthContext } from "../../context/Auth/AuthContext"
import toastError from "../../errors/toastError" import toastError from "../../errors/toastError"
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from "../../services/socket"
const useStyles = makeStyles(theme => ({ const useStyles = makeStyles(theme => ({
ticket: { ticket: {
@ -151,17 +152,18 @@ const TicketListItem = ({ ticket, remoteTicketsControll, settings }) => {
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('remoteTickesControll', (data) => { const onRemoteTickesControllTicketListItem = (data) => {
console.log('REMOTE TICKETS CONTROLL UPDATE2: ', data.tickets) console.log('REMOTE TICKETS CONTROLL UPDATE2: ', data.tickets)
if (data.action === 'update') { if (data.action === 'update') {
setRemoteTicketsControll(data.tickets) setRemoteTicketsControll(data.tickets)
} }
}) }
socket.on('remoteTickesControll', onRemoteTickesControllTicketListItem)
socket.on('settings', (data) => { const onSettingsTicketListItem = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -170,11 +172,13 @@ const TicketListItem = ({ ticket, remoteTicketsControll, settings }) => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsTicketListItem)
return () => { return () => {
socket.disconnect() socket.off('remoteTickesControll', onRemoteTickesControllTicketListItem);
socket.off('settings', onSettingsTicketListItem);
} }
}, []) }, [])

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect, useReducer, useContext } from "react" import React, { useState, useEffect, useReducer, useContext } from "react"
//import openSocket from "socket.io-client"
import openSocket from "socket.io-client" import { socket } from "../../services/socket"
import { makeStyles } from "@material-ui/core/styles" import { makeStyles } from "@material-ui/core/styles"
import List from "@material-ui/core/List" import List from "@material-ui/core/List"
@ -243,27 +243,29 @@ const TicketsList = (props) => {
// if (tab=='search')return // if (tab=='search')return
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
const shouldUpdateTicket = ticket => const shouldUpdateTicket = ticket =>
(status === ticket.status) &&
(!ticket.userId || ticket.userId === user?.id || showAll) && (!ticket.userId || ticket.userId === user?.id || showAll) &&
(!ticket.queueId || selectedQueueIds.indexOf(ticket.queueId) > -1) (!ticket.queueId || selectedQueueIds.indexOf(ticket.queueId) > -1)
const notBelongsToUserQueues = ticket => const notBelongsToUserQueues = ticket =>
ticket.queueId && selectedQueueIds.indexOf(ticket.queueId) === -1 ticket.queueId && selectedQueueIds.indexOf(ticket.queueId) === -1
socket.on("connect", () => { const onConnectTicketList = () => {
if (status) { if (status) {
socket.emit("joinTickets", status) socket.emit("joinTickets", status)
} else { } else {
socket.emit("joinNotification") socket.emit("joinNotification")
} }
}
}) onConnectTicketList()
socket.on("connect", onConnectTicketList)
const onTicketTicketList = data => {
socket.on("ticket", data => {
if (data.action === "updateUnread") { if (data.action === "updateUnread") {
@ -292,10 +294,11 @@ const TicketsList = (props) => {
if (data.action === "delete") { if (data.action === "delete") {
dispatch({ type: "DELETE_TICKET", payload: data.ticketId }) dispatch({ type: "DELETE_TICKET", payload: data.ticketId })
} }
}) }
socket.on("ticket", onTicketTicketList)
socket.on("appMessage", data => { const onAppMessageTicketList = data => {
if (data.action === "create" && shouldUpdateTicket(data.ticket)) { if (data.action === "create" && shouldUpdateTicket(data.ticket)) {
@ -307,7 +310,9 @@ const TicketsList = (props) => {
payload: data, payload: data,
}) })
} }
}) }
socket.on("appMessage", onAppMessageTicketList)
socket.on("contact", data => { socket.on("contact", data => {
if (data.action === "update") { if (data.action === "update") {
@ -318,16 +323,16 @@ const TicketsList = (props) => {
} }
}) })
const onRemoteTickesControllTicketList = (data) => {
socket.on('remoteTickesControll', (data) => {
console.log('REMOTE TICKETS CONTROLL UPDATE 1: ', data.tickets) console.log('REMOTE TICKETS CONTROLL UPDATE 1: ', data.tickets)
if (data.action === 'update') { if (data.action === 'update') {
setRemoteTicketsControll(data.tickets) setRemoteTicketsControll(data.tickets)
} }
}) }
socket.on('remoteTickesControll', onRemoteTickesControllTicketList)
socket.on('settings', (data) => { const onSettingsTicketList = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -336,11 +341,17 @@ const TicketsList = (props) => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsTicketList)
return () => { return () => {
socket.disconnect() socket.off("ticket", onTicketTicketList)
socket.off('appMessage', onAppMessageTicketList);
socket.removeAllListeners("contact")
socket.off('connect', onConnectTicketList);
socket.off('settings', onSettingsTicketList);
socket.off('remoteTickesControll', onRemoteTickesControllTicketList);
} }
}, [status, showAll, user, selectedQueueIds, tab]) }, [status, showAll, user, selectedQueueIds, tab])
@ -349,7 +360,7 @@ const TicketsList = (props) => {
if (typeof updateCount === "function") { if (typeof updateCount === "function") {
updateCount(ticketsList.length) updateCount(ticketsList.length)
} }
if (ticketsList && status === "pending"){ if (ticketsList && status === "pending") {
setTickets(ticketsList) setTickets(ticketsList)
} }
// else{ // else{

View File

@ -19,7 +19,6 @@ import FindInPageIcon from '@material-ui/icons/FindInPage'
import FormControlLabel from "@material-ui/core/FormControlLabel" import FormControlLabel from "@material-ui/core/FormControlLabel"
import Switch from "@material-ui/core/Switch" import Switch from "@material-ui/core/Switch"
import openSocket from "socket.io-client"
import NewTicketModal from "../NewTicketModal" import NewTicketModal from "../NewTicketModal"
import TicketsList from "../TicketsList" import TicketsList from "../TicketsList"
@ -153,7 +152,7 @@ const TicketsManager = () => {
const [openCount, setOpenCount] = useState(0) const [openCount, setOpenCount] = useState(0)
const [pendingCount, setPendingCount] = useState(0) const [pendingCount, setPendingCount] = useState(0)
const userQueueIds = user.queues.map((q) => q.id) const userQueueIds = user?.queues?.map((q) => q?.id)
const [selectedQueueIds, setSelectedQueueIds] = useState(userQueueIds || []) const [selectedQueueIds, setSelectedQueueIds] = useState(userQueueIds || [])
const [showContentSearch, setShowContentSearch] = useState(false) const [showContentSearch, setShowContentSearch] = useState(false)
@ -178,9 +177,9 @@ const TicketsManager = () => {
}, [setting]) }, [setting])
useEffect(() => { useEffect(() => {
if (user.profile.toUpperCase() === "ADMIN" || if (user?.profile?.toUpperCase() === "ADMIN" ||
user.profile.toUpperCase() === "SUPERVISOR" || user?.profile?.toUpperCase() === "SUPERVISOR" ||
user.profile.toUpperCase() === "MASTER") { user?.profile?.toUpperCase() === "MASTER") {
setShowAllTickets(true) setShowAllTickets(true)
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
@ -193,21 +192,21 @@ const TicketsManager = () => {
setTabOption(tab) setTabOption(tab)
}, [tab, setTabOption]) }, [tab, setTabOption])
useEffect(() => { useEffect(() => {
if (settings?.length > 0 && getSettingValue('waitingTimeTickets') !== 'enabled') return if (settings?.length > 0 && getSettingValue('waitingTimeTickets') !== 'enabled') return
const calculateAverageTime = () => { const calculateAverageTime = () => {
if (tickets.length > 0) { if (tickets.length > 0) {
const now = new Date() const now = new Date()
const differenceTime = tickets?.map(ticket => { const differenceTime = tickets?.map(ticket => {
const createdAt = new Date(ticket.createdAt) const createdAt = new Date(ticket?.createdAt)
const difference = now - createdAt const difference = now - createdAt
return difference return difference
}) })
const sumDifferences = differenceTime.reduce((total, difference) => total + difference, 0) const sumDifferences = differenceTime?.reduce((total, difference) => total + difference, 0)
const averageTimeMilliseconds = sumDifferences / tickets?.length const averageTimeMilliseconds = sumDifferences / tickets?.length
let hours = Math.floor(averageTimeMilliseconds / 3600000) let hours = Math.floor(averageTimeMilliseconds / 3600000)
const minutes = Math.floor((averageTimeMilliseconds % 3600000) / 60000) const minutes = Math.floor((averageTimeMilliseconds % 3600000) / 60000)
@ -222,10 +221,10 @@ const TicketsManager = () => {
} else return '00:00' } else return '00:00'
} }
setWaitingTime(calculateAverageTime()) setWaitingTime(calculateAverageTime())
const intervalId = setInterval(() => { const intervalId = setInterval(() => {
setWaitingTime(calculateAverageTime()) setWaitingTime(calculateAverageTime())
}, 10000) }, 10000)
return () => clearInterval(intervalId) return () => clearInterval(intervalId)

View File

@ -1,6 +1,7 @@
import React, { useState, useContext, useMemo, useEffect } from "react" import React, { useState, useContext, useMemo, useEffect } from "react"
import { useHistory } from "react-router-dom" import { useHistory } from "react-router-dom"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import Button from "@material-ui/core/Button" import Button from "@material-ui/core/Button"
import Dialog from "@material-ui/core/Dialog" import Dialog from "@material-ui/core/Dialog"
@ -110,9 +111,9 @@ const TransferTicketModal = ({ modalOpen, onClose, ticketid }) => {
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('settings', (data) => { const onSettingsTransferTicketModal = (data) => {
console.log('settings updated ----------------------------xxxxxxxxxxxx') console.log('settings updated ----------------------------xxxxxxxxxxxx')
if (data.action === 'update') { if (data.action === 'update') {
@ -123,10 +124,12 @@ const TransferTicketModal = ({ modalOpen, onClose, ticketid }) => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsTransferTicketModal)
return () => { return () => {
socket.disconnect() socket.off("settings", onSettingsTransferTicketModal)
} }
}, []) }, [])
@ -194,7 +197,7 @@ const TransferTicketModal = ({ modalOpen, onClose, ticketid }) => {
const { data } = await api.get(`/users/all`, { const { data } = await api.get(`/users/all`, {
params: { userId: user.id }, params: { userId: user.id },
}) })
setUsers(data.users) setUsers(data.users)
setQueuesByWhats(data.queues) setQueuesByWhats(data.queues)
setQueues(data.queues) setQueues(data.queues)
@ -228,7 +231,7 @@ const TransferTicketModal = ({ modalOpen, onClose, ticketid }) => {
{i18n.t("transferTicketModal.title")} {i18n.t("transferTicketModal.title")}
</DialogTitle> </DialogTitle>
<DialogContent dividers > <DialogContent dividers >
<FormControl variant="outlined" className={classes.maxWidth} style={{marginBottom: '8px'}}> <FormControl variant="outlined" className={classes.maxWidth} style={{ marginBottom: '8px' }}>
{/* <InputLabel>{i18n.t("transferTicketModal.fieldQueueLabel")}</InputLabel> */} {/* <InputLabel>{i18n.t("transferTicketModal.fieldQueueLabel")}</InputLabel> */}
<InputLabel>{'Usuário'}</InputLabel> <InputLabel>{'Usuário'}</InputLabel>
@ -247,7 +250,7 @@ const TransferTicketModal = ({ modalOpen, onClose, ticketid }) => {
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
</FormControl> </FormControl>
<FormControl variant="outlined" className={classes.maxWidth}> <FormControl variant="outlined" className={classes.maxWidth}>
<InputLabel>{i18n.t("transferTicketModal.fieldQueuePlaceholder")}</InputLabel> <InputLabel>{i18n.t("transferTicketModal.fieldQueuePlaceholder")}</InputLabel>
@ -259,7 +262,7 @@ const TransferTicketModal = ({ modalOpen, onClose, ticketid }) => {
required required
> >
<MenuItem style={{ background: "white", }} value={''}>&nbsp;</MenuItem> <MenuItem style={{ background: "white", }} value={''}>&nbsp;</MenuItem>
{queues.map((queue) => ( {queues?.map((queue) => (
<MenuItem <MenuItem
key={queue.id} key={queue.id}
value={queue.id} value={queue.id}

View File

@ -1,6 +1,7 @@
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import { useHistory } from 'react-router-dom' import { useHistory } from 'react-router-dom'
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from '../../services/socket'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
@ -62,19 +63,19 @@ const useAuth = () => {
useEffect(() => { useEffect(() => {
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
;(async () => { ; (async () => {
if (token) { if (token) {
try { try {
const { data } = await api.post('/auth/refresh_token') const { data } = await api.post('/auth/refresh_token')
api.defaults.headers.Authorization = `Bearer ${data.token}` api.defaults.headers.Authorization = `Bearer ${data.token}`
setIsAuth(true) setIsAuth(true)
setUser(data.user) setUser(data.user)
} catch (err) { } catch (err) {
toastError(err) toastError(err)
}
} }
} setLoading(false)
setLoading(false) })()
})()
}, []) }, [])
useEffect(() => { useEffect(() => {
@ -90,7 +91,7 @@ const useAuth = () => {
}, []) }, [])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('user', (data) => { socket.on('user', (data) => {
if (data.action === 'update' && data.user.id === user.id) { if (data.action === 'update' && data.user.id === user.id) {
@ -98,7 +99,7 @@ const useAuth = () => {
} }
}) })
socket.on('settings', (data) => { const onSettingsAuth = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSetting((prevState) => { setSetting((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -107,10 +108,13 @@ const useAuth = () => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsAuth)
return () => { return () => {
socket.disconnect() socket.removeAllListeners('user');
socket.off('settings', onSettingsAuth);
} }
}, [user]) }, [user])
@ -135,7 +139,7 @@ const useAuth = () => {
const handleLogout = async () => { const handleLogout = async () => {
setLoading(true) setLoading(true)
try { try {
await api.delete(`/auth/logout/${user.id}`); await api.delete(`/auth/logout/${user.id}`);
setIsAuth(false) setIsAuth(false)

View File

@ -1,5 +1,7 @@
import { useState, useEffect, useReducer } from "react"; import { useState, useEffect, useReducer } from "react";
import openSocket from "socket.io-client"; //import openSocket from "socket.io-client";
import { socket } from "../../services/socket";
import toastError from "../../errors/toastError"; import toastError from "../../errors/toastError";
@ -30,7 +32,7 @@ const reducer = (state, action) => {
if (whatsAppIndex !== -1) { if (whatsAppIndex !== -1) {
if ('disabled' in whatsApp) { if ('disabled' in whatsApp) {
state[whatsAppIndex].disabled = whatsApp.disabled state[whatsAppIndex].disabled = whatsApp.disabled
} }
else { else {
@ -126,7 +128,7 @@ const useWhatsApps = () => {
}, []); }, []);
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL); //const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
socket.on("whatsapp", data => { socket.on("whatsapp", data => {
if (data.action === "update") { if (data.action === "update") {
@ -158,7 +160,9 @@ const useWhatsApps = () => {
return () => { return () => {
socket.disconnect(); socket.removeAllListeners('whatsapp');
socket.removeAllListeners('whatsappSession');
socket.removeAllListeners('whatsappSessionMonit');
}; };
}, []); }, []);

View File

@ -31,7 +31,8 @@ import { i18n } from '../translate/i18n'
import { WhatsAppsContext } from '../context/WhatsApp/WhatsAppsContext' import { WhatsAppsContext } from '../context/WhatsApp/WhatsAppsContext'
import { AuthContext } from '../context/Auth/AuthContext' import { AuthContext } from '../context/Auth/AuthContext'
import { Can } from '../components/Can' import { Can } from '../components/Can'
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from '../services/socket'
import api from '../services/api' import api from '../services/api'
@ -118,9 +119,9 @@ const MainListItems = (props) => {
} }
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('settings', (data) => { const onSettingsMainListItem = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -129,10 +130,12 @@ const MainListItems = (props) => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsMainListItem)
return () => { return () => {
socket.disconnect() socket.off('settings', onSettingsMainListItem);
} }
}, []) }, [])

View File

@ -1,7 +1,8 @@
import React, { useState, useCallback, useEffect, useReducer, useContext } from 'react' import React, { useState, useCallback, useEffect, useReducer, useContext } from 'react'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from '../../services/socket'
import { makeStyles } from '@material-ui/core/styles' import { makeStyles } from '@material-ui/core/styles'
import { green } from '@material-ui/core/colors' import { green } from '@material-ui/core/colors'
@ -13,11 +14,11 @@ import {
IconButton, IconButton,
Table, Table,
TableHead, TableHead,
Paper, Paper,
} from '@material-ui/core' } from '@material-ui/core'
import { import {
Edit, Edit,
DeleteOutline, DeleteOutline,
// Restore // Restore
} from '@material-ui/icons' } from '@material-ui/icons'
@ -26,7 +27,7 @@ import MainHeader from '../../components/MainHeader'
import MainHeaderButtonsWrapper from '../../components/MainHeaderButtonsWrapper' import MainHeaderButtonsWrapper from '../../components/MainHeaderButtonsWrapper'
import Title from '../../components/Title' import Title from '../../components/Title'
import TableRowSkeleton from '../../components/TableRowSkeleton' import TableRowSkeleton from '../../components/TableRowSkeleton'
import CampaignModal from '../../components/CampaignModal' import CampaignModal from '../../components/CampaignModal'
import ConfirmationModal from '../../components/ConfirmationModal' import ConfirmationModal from '../../components/ConfirmationModal'
import QrcodeModal from '../../components/QrcodeModal' import QrcodeModal from '../../components/QrcodeModal'
@ -51,7 +52,7 @@ const reducer = (state, action) => {
const campaigns = action.payload const campaigns = action.payload
return [...state, ...campaigns] return [...state, ...campaigns]
} }
if (action.type === "UPDATE_CAMPAIGNS") { if (action.type === "UPDATE_CAMPAIGNS") {
const campaign = action.payload const campaign = action.payload
const campaignIndex = state.findIndex((c) => c.id === campaign.id) const campaignIndex = state.findIndex((c) => c.id === campaign.id)
@ -109,7 +110,7 @@ const useStyles = makeStyles((theme) => ({
buttonProgress: { buttonProgress: {
color: green[500], color: green[500],
}, },
})) }))
const Campaign = () => { const Campaign = () => {
//-------- //--------
@ -124,7 +125,7 @@ const Campaign = () => {
const [qrModalOpen, setQrModalOpen] = useState(false) const [qrModalOpen, setQrModalOpen] = useState(false)
const [selectedCampaign, setSelectedCampaign] = useState(null) const [selectedCampaign, setSelectedCampaign] = useState(null)
const [confirmModalOpen, setConfirmModalOpen] = useState(false) const [confirmModalOpen, setConfirmModalOpen] = useState(false)
const [campaigns, dispatch] = useReducer(reducer, []) const [campaigns, dispatch] = useReducer(reducer, [])
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
@ -152,7 +153,7 @@ const Campaign = () => {
const delayDebounceFn = setTimeout(() => { const delayDebounceFn = setTimeout(() => {
const fetchContacts = async () => { const fetchContacts = async () => {
try { try {
const { data } = await apiBroker.get('/campaign', { const { data } = await apiBroker.get('/campaign', {
params: { params: {
@ -160,7 +161,7 @@ const Campaign = () => {
baseURL: process.env.REACT_APP_BACKEND_URL_PRIVATE, baseURL: process.env.REACT_APP_BACKEND_URL_PRIVATE,
identifier: 'campaign' identifier: 'campaign'
} }
}) })
dispatch({ type: "LOAD_CAMPAIGNS", payload: data.campaign }) dispatch({ type: "LOAD_CAMPAIGNS", payload: data.campaign })
setLoading(false) setLoading(false)
@ -174,7 +175,7 @@ const Campaign = () => {
}, 500) }, 500)
return () => clearTimeout(delayDebounceFn) return () => clearTimeout(delayDebounceFn)
}, [user.id]) }, [user.id])
const handleOpenCampaignModal = () => { const handleOpenCampaignModal = () => {
setSelectedCampaign(null) setSelectedCampaign(null)
@ -184,12 +185,12 @@ const Campaign = () => {
const handleCloseCampaignModal = useCallback(() => { const handleCloseCampaignModal = useCallback(() => {
setCampaignModalOpen(false) setCampaignModalOpen(false)
setSelectedCampaign(null) setSelectedCampaign(null)
}, [setSelectedCampaign, setCampaignModalOpen]) }, [setSelectedCampaign, setCampaignModalOpen])
const handleStart = async (campaign) => { const handleStart = async (campaign) => {
try { try {
const { data } = await apiBroker.post(`/campaign/start/${campaign.id}`) const { data } = await apiBroker.post(`/campaign/start/${campaign.id}`)
dispatch({ type: "UPDATE_CAMPAIGNS", payload: data.campaign }) dispatch({ type: "UPDATE_CAMPAIGNS", payload: data.campaign })
@ -200,10 +201,10 @@ const Campaign = () => {
} }
} }
const handleStop = async (campaign) => { const handleStop = async (campaign) => {
try { try {
const { data } = await apiBroker.post(`/campaign/stop/${campaign.id}`) const { data } = await apiBroker.post(`/campaign/stop/${campaign.id}`)
dispatch({ type: "UPDATE_CAMPAIGNS", payload: data.campaign }) dispatch({ type: "UPDATE_CAMPAIGNS", payload: data.campaign })
@ -245,7 +246,7 @@ const Campaign = () => {
setConfirmModalOpen(true) setConfirmModalOpen(true)
} }
const handleSubmitConfirmationModal = async () => { const handleSubmitConfirmationModal = async () => {
if (confirmModalInfo.action === 'delete') { if (confirmModalInfo.action === 'delete') {
try { try {
@ -293,13 +294,12 @@ const Campaign = () => {
)} )}
</> </>
) )
} }
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
const onContactsBulkCampaing = (data) => {
socket.on("contactsBulkInsertOnQueueStatus", (data) => {
if (data.action === 'update') { if (data.action === 'update') {
if (String(data.insertOnQueue.adminId) === String(user.id)) { if (String(data.insertOnQueue.adminId) === String(user.id)) {
@ -312,19 +312,24 @@ const Campaign = () => {
} }
} }
}) }
socket.on('campaign', (data) => { socket.on("contactsBulkInsertOnQueueStatus", onContactsBulkCampaing)
const onCampaignCampaign = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
dispatch({ type: "UPDATE_CAMPAIGNS", payload: data.campaign }) dispatch({ type: "UPDATE_CAMPAIGNS", payload: data.campaign })
} }
}) }
socket.on('campaign', onCampaignCampaign)
return () => { return () => {
socket.disconnect() socket.off("campaign", onCampaignCampaign)
socket.off("contactsBulkInsertOnQueueStatus", onContactsBulkCampaing)
} }
}, [user.id]) }, [user.id])

View File

@ -2,7 +2,8 @@ import React, { useState, useCallback, useEffect, useContext } from 'react'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import { format, parseISO } from 'date-fns' import { format, parseISO } from 'date-fns'
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from '../../services/socket'
import { makeStyles } from '@material-ui/core/styles' import { makeStyles } from '@material-ui/core/styles'
import { green, red, yellow, grey } from '@material-ui/core/colors' import { green, red, yellow, grey } from '@material-ui/core/colors'
@ -144,7 +145,7 @@ const Connections = () => {
const [selectedWhatsApp, setSelectedWhatsApp] = useState(null) const [selectedWhatsApp, setSelectedWhatsApp] = useState(null)
const [confirmModalOpen, setConfirmModalOpen] = useState(false) const [confirmModalOpen, setConfirmModalOpen] = useState(false)
const [diskSpaceInfo, setDiskSpaceInfo] = useState({}) const [diskSpaceInfo, setDiskSpaceInfo] = useState({})
const [settings, setSettings] = useState([]) const [settings, setSettings] = useState([])
@ -388,7 +389,7 @@ const Connections = () => {
getSettingValue('whatsaAppCloudApi') === 'disabled') && ( getSettingValue('whatsaAppCloudApi') === 'disabled') && (
<CustomToolTip title={'Whatsapp Cloud API está desativado'}> <CustomToolTip title={'Whatsapp Cloud API está desativado'}>
<FiberManualRecord style={{ color: grey[500] }} /> <FiberManualRecord style={{ color: grey[500] }} />
</CustomToolTip> </CustomToolTip>
)} )}
{whatsApp.status === 'OPENING' && !whatsApp.isOfficial && ( {whatsApp.status === 'OPENING' && !whatsApp.isOfficial && (
<CircularProgress size={24} className={classes.buttonProgress} /> <CircularProgress size={24} className={classes.buttonProgress} />
@ -433,7 +434,7 @@ const Connections = () => {
try { try {
await api.post(`/restartwhatsappsession/0`, { await api.post(`/restartwhatsappsession/0`, {
params: { status: 'status' }, params: { status: 'status' },
}) })
setClicks((buttons) => setClicks((buttons) =>
buttons.map((e) => { buttons.map((e) => {
@ -451,15 +452,17 @@ const Connections = () => {
}, []) }, [])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('diskSpaceMonit', (data) => { const onDiskSpaceMonitConnections = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setDiskSpaceInfo(data.diskSpace) setDiskSpaceInfo(data.diskSpace)
} }
}) }
socket.on('settings', (data) => { socket.on('diskSpaceMonit', onDiskSpaceMonitConnections)
const onSettingsConnections = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -468,10 +471,13 @@ const Connections = () => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsConnections)
return () => { return () => {
socket.disconnect() socket.off("settings", onSettingsConnections)
socket.off("diskSpaceMonit", onDiskSpaceMonitConnections)
} }
}, []) }, [])

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect, useReducer, useCallback, useContext } from "react" import React, { useState, useEffect, useReducer, useCallback, useContext } from "react"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import { toast } from "react-toastify" import { toast } from "react-toastify"
import { useHistory } from "react-router-dom" import { useHistory } from "react-router-dom"
@ -260,9 +261,9 @@ const Contacts = () => {
}, [searchParam, pageNumber]) }, [searchParam, pageNumber])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("contactsBulkInsertOnQueueStatus", (data) => { const onContactsBulkContacts = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
if (String(data.insertOnQueue.adminId) === String(user.id)) { if (String(data.insertOnQueue.adminId) === String(user.id)) {
@ -278,9 +279,11 @@ const Contacts = () => {
} }
} }
}) }
socket.on("contact", (data) => { socket.on("contactsBulkInsertOnQueueStatus", onContactsBulkContacts)
const onContactContacts = (data) => {
if (data.action === "update" || data.action === "create") { if (data.action === "update" || data.action === "create") {
dispatch({ type: "UPDATE_CONTACTS", payload: data.contact }) dispatch({ type: "UPDATE_CONTACTS", payload: data.contact })
} }
@ -288,10 +291,13 @@ const Contacts = () => {
if (data.action === "delete") { if (data.action === "delete") {
dispatch({ type: "DELETE_CONTACT", payload: +data.contactId }) dispatch({ type: "DELETE_CONTACT", payload: +data.contactId })
} }
}) }
socket.on("contact", onContactContacts)
return () => { return () => {
socket.disconnect() socket.off("contact", onContactContacts)
socket.off("contactsBulkInsertOnQueueStatus", onContactsBulkContacts)
} }
}, [user, history]) }, [user, history])
@ -536,7 +542,7 @@ const Contacts = () => {
open={contactModalOpen} open={contactModalOpen}
onClose={handleCloseContactModal} onClose={handleCloseContactModal}
aria-labelledby="form-dialog-title" aria-labelledby="form-dialog-title"
contactId={selectedContactId} contactId={selectedContactId}
></ContactModal> ></ContactModal>
<ContactCreateTicketModal <ContactCreateTicketModal
modalOpen={isCreateTicketModalOpen} modalOpen={isCreateTicketModalOpen}

View File

@ -17,7 +17,8 @@ import { AuthContext } from "../../context/Auth/AuthContext"
import { i18n } from "../../translate/i18n"; import { i18n } from "../../translate/i18n";
import Chart from "./Chart" import Chart from "./Chart"
import PieChart from "./PieChart" import PieChart from "./PieChart"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import api from "../../services/api" import api from "../../services/api"
import { Can } from "../../components/Can" import { Can } from "../../components/Can"
@ -291,7 +292,7 @@ const Dashboard = () => {
const { data } = await api.get("/reports/user/services", { const { data } = await api.get("/reports/user/services", {
params: { userId: null, startDate: dateToday, endDate: dateToday, userQueues: selectedQueue }, params: { userId: null, startDate: dateToday, endDate: dateToday, userQueues: selectedQueue },
}) })
dispatch({ type: "RESET" }) dispatch({ type: "RESET" })
dispatch({ type: "LOAD_QUERY", payload: data.usersProfile }) dispatch({ type: "LOAD_QUERY", payload: data.usersProfile })
@ -301,7 +302,7 @@ const Dashboard = () => {
}) })
setTicketStatusChatEnd(ticketStatusChatEndData.reportStatusChatEnd) setTicketStatusChatEnd(ticketStatusChatEndData.reportStatusChatEnd)
} catch (err) { } catch (err) {
} }
@ -356,46 +357,54 @@ const Dashboard = () => {
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("ticketStatus", (data) => { const onTicketsStatusDashboard = (data) => {
if (data.action === "update") { if (data.action === "update") {
setStatus("") setStatus("")
setStatus(data.ticketStatus.status) setStatus(data.ticketStatus.status)
} }
}) }
socket.on("onlineStatus", (data) => { socket.on("ticketStatus", onTicketsStatusDashboard)
const onOnlineStatusDashboard = (data) => {
if (data.action === "logout" || data.action === "update") { if (data.action === "logout" || data.action === "update") {
dispatch({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime }) dispatch({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime })
} else if (data.action === "delete") { } else if (data.action === "delete") {
dispatch({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime }) dispatch({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime })
} }
}) }
socket.on("user", (data) => { socket.on("onlineStatus", onOnlineStatusDashboard)
const onUserDashboard = (data) => {
if (data.action === "delete") { if (data.action === "delete") {
dispatch({ type: "DELETE_USER", payload: +data.userId }) dispatch({ type: "DELETE_USER", payload: +data.userId })
} }
}) }
socket.on("user", onUserDashboard)
return () => { return () => {
socket.disconnect() socket.off("user", onUserDashboard)
socket.off("onlineStatus", onOnlineStatusDashboard)
socket.off("ticketStatus", onTicketsStatusDashboard)
} }
}, []) }, [])
const handleSelectedQueue = useCallback((queueSelected) => { const handleSelectedQueue = useCallback((queueSelected) => {
if(queueSelected !== 'All'){ if (queueSelected !== 'All') {
const queueIndex = user?.queues?.findIndex((q) => q.id === parseInt(queueSelected)); const queueIndex = user?.queues?.findIndex((q) => q.id === parseInt(queueSelected));
const queueIds = [] const queueIds = []
queueIds.push(user?.queues[queueIndex]?.id); queueIds.push(user?.queues[queueIndex]?.id);
setSelectedQueue(queueIds); setSelectedQueue(queueIds);
}else{ } else {
const queueIds = user?.queues?.map((queue) => queue.id); const queueIds = user?.queues?.map((queue) => queue.id);
setSelectedQueue(queueIds); setSelectedQueue(queueIds);
} }
},[user, setSelectedQueue]) }, [user, setSelectedQueue])
useEffect(() => { useEffect(() => {
if (ticketStatusChange === "") return if (ticketStatusChange === "") return
@ -532,7 +541,7 @@ const Dashboard = () => {
<Grid item container spacing={3}> <Grid item container spacing={3}>
<Grid item xs={12} sm={12} md={6} lg={6}> <Grid item xs={12} sm={12} md={6} lg={6}>
<Paper className={classes.fixedHeightPaper} variant="outlined"> <Paper className={classes.fixedHeightPaper} variant="outlined">
<Chart allTickets={usersOnlineInfo} selectedQueue = {selectedQueue}/> <Chart allTickets={usersOnlineInfo} selectedQueue={selectedQueue} />
</Paper> </Paper>
</Grid> </Grid>
<Grid item xs={12} sm={12} md={6} lg={6}> <Grid item xs={12} sm={12} md={6} lg={6}>

View File

@ -1,5 +1,6 @@
import React, { useState, useContext, useEffect, useReducer } from "react" import React, { useState, useContext, useEffect, useReducer } from "react"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import { import {
Button, Button,
@ -125,9 +126,9 @@ const Position = () => {
}, [searchParam, pageNumber]) }, [searchParam, pageNumber])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("position", (data) => { const onPositionPosition = (data) => {
if (data.action === "update" || data.action === "create") { if (data.action === "update" || data.action === "create") {
dispatch({ type: "UPDATE_POSITIONS", payload: data.position }) dispatch({ type: "UPDATE_POSITIONS", payload: data.position })
} }
@ -138,10 +139,12 @@ const Position = () => {
payload: +data.positionId, payload: +data.positionId,
}) })
} }
}) }
socket.on("position", onPositionPosition)
return () => { return () => {
socket.disconnect() socket.off("position", onPositionPosition)
} }
}, []) }, [])

View File

@ -1,6 +1,7 @@
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 { socket } from '../../services/socket'
import { import {
Button, Button,
@ -91,7 +92,7 @@ const reducer = (state, action) => {
const Queues = () => { const Queues = () => {
const classes = useStyles() const classes = useStyles()
const { user, setting, getSettingValue } = useContext(AuthContext) const { user, setting, getSettingValue } = useContext(AuthContext)
const [queues, dispatch] = useReducer(reducer, []) const [queues, dispatch] = useReducer(reducer, [])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
@ -120,12 +121,12 @@ const Queues = () => {
setLoading(false) setLoading(false)
} }
})() })()
}, []) }, [])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('queue', (data) => { const onQueueQueues = (data) => {
if (data.action === 'update' || data.action === 'create') { if (data.action === 'update' || data.action === 'create') {
dispatch({ type: 'UPDATE_QUEUES', payload: data.queue }) dispatch({ type: 'UPDATE_QUEUES', payload: data.queue })
} }
@ -133,9 +134,11 @@ const Queues = () => {
if (data.action === 'delete') { if (data.action === 'delete') {
dispatch({ type: 'DELETE_QUEUE', payload: data.queueId }) dispatch({ type: 'DELETE_QUEUE', payload: data.queueId })
} }
}) }
socket.on('settings', (data) => { socket.on('queue', onQueueQueues)
const onSettingsQueues = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -144,10 +147,13 @@ const Queues = () => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsQueues)
return () => { return () => {
socket.disconnect() socket.off("settings", onSettingsQueues)
socket.off("queue", onQueueQueues)
} }
}, []) }, [])

View File

@ -1,5 +1,6 @@
import React, { useState, useContext, useEffect, useReducer } from "react" import React, { useState, useContext, useEffect, useReducer } from "react"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import { import {
Button, Button,
@ -125,9 +126,9 @@ const QuickAnswers = () => {
}, [searchParam, pageNumber]) }, [searchParam, pageNumber])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("quickAnswer", (data) => { const onQuickAnswerQuickAnswers = (data) => {
if (data.action === "update" || data.action === "create") { if (data.action === "update" || data.action === "create") {
dispatch({ type: "UPDATE_QUICK_ANSWERS", payload: data.quickAnswer }) dispatch({ type: "UPDATE_QUICK_ANSWERS", payload: data.quickAnswer })
} }
@ -138,10 +139,11 @@ const QuickAnswers = () => {
payload: +data.quickAnswerId, payload: +data.quickAnswerId,
}) })
} }
}) }
socket.on("quickAnswer", onQuickAnswerQuickAnswers)
return () => { return () => {
socket.disconnect() socket.off("quickAnswer", onQuickAnswerQuickAnswers)
} }
}, []) }, [])

View File

@ -18,7 +18,8 @@ import MaterialTable from 'material-table'
import LogoutIcon from '@material-ui/icons/CancelOutlined' import LogoutIcon from '@material-ui/icons/CancelOutlined'
import apiBroker from "../../services/apiBroker" import apiBroker from "../../services/apiBroker"
import fileDownload from 'js-file-download' import fileDownload from 'js-file-download'
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import { i18n } from "../../translate/i18n" import { i18n } from "../../translate/i18n"
import Switch from '@mui/material/Switch' import Switch from '@mui/material/Switch'
@ -239,7 +240,7 @@ let columnsData = [
{ title: `Espera`, field: 'waiting_time' }, { title: `Espera`, field: 'waiting_time' },
{ title: `Mensagens`, field: 'messagesToFilter', searchable: true, hidden: true }, { title: `Mensagens`, field: 'messagesToFilter', searchable: true, hidden: true },
{ title: `Link`, field: 'link', searchable: false, hidden: true, export: true }, { title: `Link`, field: 'link', searchable: false, hidden: true, export: true },
] ]
let columnsDataSuper = [ let columnsDataSuper = [
{ title: `Tipo`, field: 'isRemote' }, { title: `Tipo`, field: 'isRemote' },
@ -381,10 +382,10 @@ const Report = () => {
const tickets = data.tickets.map(ticket => { const tickets = data.tickets.map(ticket => {
ticket.isRemote = ticket.isRemote ? 'Remoto' : 'Comum'; ticket.isRemote = ticket.isRemote ? 'Remoto' : 'Comum';
return ({ return ({
...ticket, ...ticket,
messagesToFilter: ticket.messages.map(message => message.body).join(' '), messagesToFilter: ticket.messages.map(message => message.body).join(' '),
link: `${process.env.REACT_APP_FRONTEND_URL}/tickets/${ticket.id}` link: `${process.env.REACT_APP_FRONTEND_URL}/tickets/${ticket.id}`
}) })
}) })
dispatchQ({ type: "LOAD_QUERY", payload: tickets }) dispatchQ({ type: "LOAD_QUERY", payload: tickets })
setHasMore(data.hasMore) setHasMore(data.hasMore)
@ -591,9 +592,9 @@ const Report = () => {
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("queryOnQueueStatus", (data) => { const onQueryOnQueueStatusReport = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
if (String(data.queryOnQueue.adminId) === String(userA.id)) { if (String(data.queryOnQueue.adminId) === String(userA.id)) {
@ -604,35 +605,39 @@ const Report = () => {
} }
} }
}) }
socket.on("queryOnQueueStatus", onQueryOnQueueStatusReport)
const onOnlineStatusReport = (data) => {
let date = new Date().toLocaleDateString('pt-BR').split('/')
let dateToday = `${date[2]}-${date[1]}-${date[0]}`
if (data.action === "logout" || (data.action === "update" &&
((`${startDate}` === `${endDate}`) && (`${endDate}` === `${dateToday}`) && (`${startDate}` === `${dateToday}`)))) {
dispatchQ({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime })
}
else if (data.action === "delete") {
dispatchQ({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime })
}
}
const onUserReport = (data) => {
if (data.action === "delete") {
dispatch({ type: "DELETE_USER", payload: +data.userId })
}
}
if (reportOption === '2') { if (reportOption === '2') {
socket.on("onlineStatus", onOnlineStatusReport)
socket.on("onlineStatus", (data) => { socket.on("user", onUserReport)
let date = new Date().toLocaleDateString('pt-BR').split('/')
let dateToday = `${date[2]}-${date[1]}-${date[0]}`
if (data.action === "logout" || (data.action === "update" &&
((`${startDate}` === `${endDate}`) && (`${endDate}` === `${dateToday}`) && (`${startDate}` === `${dateToday}`)))) {
dispatchQ({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime })
}
else if (data.action === "delete") {
dispatchQ({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime })
}
})
socket.on("user", (data) => {
if (data.action === "delete") {
dispatch({ type: "DELETE_USER", payload: +data.userId })
}
})
} }
else if (reportOption === "1") { else if (reportOption === "1") {
@ -641,7 +646,9 @@ const Report = () => {
} }
return () => { return () => {
socket.disconnect() socket.off("onlineStatus", onOnlineStatusReport)
socket.off("user", onUserReport)
socket.off("queryOnQueueStatus", onQueryOnQueueStatusReport)
} }
@ -687,7 +694,7 @@ const Report = () => {
const renderSwitch = (param) => { const renderSwitch = (param) => {
if(userA.profile !== 'supervisor'){ if (userA.profile !== 'supervisor') {
switch (param) { switch (param) {
case 'empty': case 'empty':
return ( return (
@ -880,7 +887,7 @@ const Report = () => {
<> <>
<MTable data={query} <MTable data={query}
columns={userA.profile !== 'supervisor' ? columnsData : columnsDataSuper} columns={userA.profile !== 'supervisor' ? columnsData : columnsDataSuper}
hasChild={userA.profile !== 'supervisor' ? true :false} hasChild={userA.profile !== 'supervisor' ? true : false}
removeClickRow={false} removeClickRow={false}
handleScroll={handleScroll} handleScroll={handleScroll}

View File

@ -28,8 +28,8 @@ import { render } from '@testing-library/react'
// import Modal from "../../../..ChatEnd/ModalChatEnd"; // import Modal from "../../../..ChatEnd/ModalChatEnd";
import Modal from "../../components/ModalUpdateScheduleReminder" import Modal from "../../components/ModalUpdateScheduleReminder"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
@ -204,11 +204,9 @@ const SchedulesReminder = () => {
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("schedulingNotify", (data) => {
const onSchedulingNotifySchedulesRemider = (data) => {
setLoading(true) setLoading(true)
@ -228,10 +226,12 @@ const SchedulesReminder = () => {
setLoading(false) setLoading(false)
}) }
socket.on("schedulingNotify", onSchedulingNotifySchedulesRemider)
return () => { return () => {
socket.disconnect() socket.off("schedulingNotify", onSchedulingNotifySchedulesRemider)
} }
}, []) }, [])
@ -300,9 +300,9 @@ const SchedulesReminder = () => {
useEffect(() => { useEffect(() => {
if (!loading) { if (!loading) {
setData(query.map(({ scheduleReminder, ...others }) => ( setData(query.map(({ scheduleReminder, ...others }) => (
{ {

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect, useContext } from 'react' import React, { useState, useEffect, useContext } from 'react'
import openSocket from 'socket.io-client' //import openSocket from 'socket.io-client'
import { socket } from '../../services/socket.js'
import { makeStyles } from '@material-ui/core/styles' import { makeStyles } from '@material-ui/core/styles'
import Paper from '@material-ui/core/Paper' import Paper from '@material-ui/core/Paper'
@ -124,9 +125,9 @@ const Settings = () => {
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('settings', (data) => { const onSettingsSettings = (data) => {
console.log('settings updated ----------------------------') console.log('settings updated ----------------------------')
if (data.action === 'update') { if (data.action === 'update') {
@ -137,10 +138,12 @@ const Settings = () => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsSettings)
return () => { return () => {
socket.disconnect() socket.off("settings", onSettingsSettings)
} }
}, []) }, [])
@ -179,7 +182,11 @@ const Settings = () => {
} }
const getSettingValue = (key, _obj = false) => { const getSettingValue = (key, _obj = false) => {
const { value, obj } = settings.find((s) => s.key === key) //const { value, obj } = settings.find((s) => s.key === key)
const setting = settings.find((s) => s.key === key)
const value = setting?.value || ""
const obj = setting?.obj || null
if (_obj) if (_obj)
return obj return obj
@ -641,7 +648,7 @@ const Settings = () => {
</Select> </Select>
</Paper> </Paper>
</Container> </Container>
</div> </div>
</div> </div>
)} )}
/> />

View File

@ -1,5 +1,6 @@
import React, { useState, useContext, useEffect, useReducer } from "react" import React, { useState, useContext, useEffect, useReducer } from "react"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import { import {
Button, Button,
@ -115,7 +116,7 @@ const StatusChatEnd = () => {
const { data } = await api.get("/statusChatEnd", { const { data } = await api.get("/statusChatEnd", {
params: { searchParam, pageNumber }, params: { searchParam, pageNumber },
}) })
setChecked(data?.statusChatEnd?.map(s => s.isDefault ? true : false)) setChecked(data?.statusChatEnd?.map(s => s.isDefault ? true : false))
dispatch({ type: "LOAD_STATUS_CHAT_END", payload: data.statusChatEnd }) dispatch({ type: "LOAD_STATUS_CHAT_END", payload: data.statusChatEnd })
@ -131,9 +132,9 @@ const StatusChatEnd = () => {
}, [searchParam, pageNumber]) }, [searchParam, pageNumber])
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("statusChatEnd", (data) => { const onStatusChatEndStatusChatEnd = (data) => {
if (data.action === "update" || data.action === "create") { if (data.action === "update" || data.action === "create") {
dispatch({ type: "UPDATE_STATUS_CHAT_END", payload: data.statusChatEnd }) dispatch({ type: "UPDATE_STATUS_CHAT_END", payload: data.statusChatEnd })
} }
@ -144,10 +145,12 @@ const StatusChatEnd = () => {
payload: +data.statusChatEndId, payload: +data.statusChatEndId,
}) })
} }
}) }
socket.on("statusChatEnd", onStatusChatEndStatusChatEnd)
return () => { return () => {
socket.disconnect() socket.off("statusChatEnd", onStatusChatEndStatusChatEnd)
} }
}, []) }, [])
@ -187,14 +190,14 @@ const StatusChatEnd = () => {
} }
const handleChange = async (event, statusChatEnd, index) => { const handleChange = async (event, statusChatEnd, index) => {
const newChecked = new Array(statusChatEnds.length).fill(false) const newChecked = new Array(statusChatEnds.length).fill(false)
newChecked[index] = event.target.checked newChecked[index] = event.target.checked
setChecked(newChecked) setChecked(newChecked)
try { try {
const { id } = statusChatEnd const { id } = statusChatEnd
await api.put(`/statusChatEnd/${id}`, { isDefault: event.target.checked }) await api.put(`/statusChatEnd/${id}`, { isDefault: event.target.checked })
toast.success("Status de encerramento padrão salvo com sucesso") toast.success("Status de encerramento padrão salvo com sucesso")
} catch (error) { } catch (error) {

View File

@ -1,6 +1,7 @@
import React, { useState, useEffect, useReducer, useContext } from "react" import React, { useState, useEffect, useReducer, useContext } from "react"
import { toast } from "react-toastify" import { toast } from "react-toastify"
import openSocket from "socket.io-client" //import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
import { makeStyles } from "@material-ui/core/styles" import { makeStyles } from "@material-ui/core/styles"
import Paper from "@material-ui/core/Paper" import Paper from "@material-ui/core/Paper"
@ -165,9 +166,9 @@ const Users = () => {
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL) //const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on("user", (data) => { const onUserUsers = (data) => {
if (data.action === "update" || data.action === "create") { if (data.action === "update" || data.action === "create") {
dispatch({ type: "UPDATE_USERS", payload: data.user }) dispatch({ type: "UPDATE_USERS", payload: data.user })
} }
@ -175,10 +176,11 @@ const Users = () => {
if (data.action === "delete") { if (data.action === "delete") {
dispatch({ type: "DELETE_USER", payload: +data.userId }) dispatch({ type: "DELETE_USER", payload: +data.userId })
} }
}) }
socket.on("user", onUserUsers)
socket.on('settings', (data) => { const onSettingsUsers = (data) => {
if (data.action === 'update') { if (data.action === 'update') {
setSettings((prevState) => { setSettings((prevState) => {
const aux = [...prevState] const aux = [...prevState]
@ -187,10 +189,12 @@ const Users = () => {
return aux return aux
}) })
} }
}) }
socket.on('settings', onSettingsUsers)
return () => { return () => {
socket.disconnect() socket.off("settings", onSettingsUsers)
socket.off("user", onUserUsers)
} }
}, []) }, [])

View File

@ -0,0 +1,14 @@
import { io } from 'socket.io-client';
// "undefined" means the URL will be computed from the `window.location` object
const URL = process.env.REACT_APP_BACKEND_URL
export const socket = io(URL,
//{
// withCredentials: true,
// extraHeaders: {
// "my-custom-header": "abcd"
// },
// transports: ['websocket', 'polling']
//}
);