Merge pull request #10 from AdrianoRobson/features

Features
pull/17/head
Renato Di Giacomo 2022-08-08 14:45:53 -03:00 committed by GitHub
commit ba475d3957
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 1304 additions and 533 deletions

View File

@ -10,7 +10,7 @@ import User from "../models/User";
import Queue from "../models/Queue"; import Queue from "../models/Queue";
import UserOnlineTime from "../models/UserOnlineTime"; import UserOnlineTime from "../models/UserOnlineTime";
import { Op, Sequelize,literal } from "sequelize"; import { Op, Sequelize, literal } from "sequelize";
import format from 'date-fns/format'; import format from 'date-fns/format';
import ptBR from 'date-fns/locale/pt-BR'; import ptBR from 'date-fns/locale/pt-BR';
import { splitDateTime } from "../helpers/SplitDateTime"; import { splitDateTime } from "../helpers/SplitDateTime";
@ -19,88 +19,203 @@ import ListUserParamiterService from "../services/UserServices/ListUserParamiter
import ShowUserServiceReport from "../services/UserServices/ShowUserServiceReport"; import ShowUserServiceReport from "../services/UserServices/ShowUserServiceReport";
import CountTicketsByUserQueue from "../services/UserServices/CountTicketsByUserQueue";
import ShowQueuesByUser from "../services/UserServices/ShowQueuesByUser";
import { filter } from "bluebird";
type IndexQuery = { type IndexQuery = {
userId: string; userId: string;
startDate: string; startDate: string;
endDate: string; endDate: string;
}; pageNumber: string;
};
export const reportUserByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => { export const reportUserByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => {
if (req.user.profile !== "master" && req.user.profile !== "admin") { if (req.user.profile !== "master" && req.user.profile !== "admin") {
throw new AppError("ERR_NO_PERMISSION", 403); throw new AppError("ERR_NO_PERMISSION", 403);
} }
const { userId, startDate, endDate } = req.query as IndexQuery const { userId, startDate, endDate, pageNumber } = req.query as IndexQuery
const data_query = await ShowTicketReport(userId, startDate, endDate); console.log('PAGE NUMBER: ', pageNumber)
return res.status(200).json(data_query);
const { tickets, count, hasMore } = await ShowTicketReport({ userId, startDate, endDate, pageNumber });
// return res.status(200).json(data_query);
return res.status(200).json({ tickets, count, hasMore });
}; };
export const reportUserService= async (req: Request, res: Response): Promise<Response> => { export const reportUserService = async (req: Request, res: Response): Promise<Response> => {
if (req.user.profile !== "master" && req.user.profile !== "admin") {
throw new AppError("ERR_NO_PERMISSION", 403);
}
const { userId, startDate, endDate } = req.query as IndexQuery
let usersProfile = await ListUserParamiterService({ profile: 'user' })
const sumUserOlineTime = await ShowUserServiceReport({ startDate, endDate, userId });
const closedByUser = await ShowUserServiceReport({ startDate, endDate, ticketStatus: 'closed', userId });
const openByUser = await ShowUserServiceReport({ startDate, endDate, ticketStatus: 'open', userId });
let dateTime = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR })))
const onlineUsers = await ListUserOnlineOffline({ date: dateTime.fullDate })
const openByUserOnQueue = await CountTicketsByUserQueue({ startDate: startDate, endDate: endDate, status: 'open', clientChatStart: true })
const openByUserOutQueue = await CountTicketsByUserQueue({ startDate: startDate, endDate: endDate, status: 'open', clientChatStart: false })
const closedByUserOnQueue = await CountTicketsByUserQueue({ startDate: startDate, endDate: endDate, status: 'closed', clientChatStart: true })
const closedUserOutQueue = await CountTicketsByUserQueue({ startDate: startDate, endDate: endDate, status: 'closed', clientChatStart: false })
// let openQueueInOut = openByUserOnQueue.concat(openByUserOutQueue)
// let closedQueueInOut = closedByUserOnQueue.concat(closedUserOutQueue)
const queuesByUser = await ShowQueuesByUser({ profile: 'user' })
let openCloseOnQueue = openByUserOnQueue.concat(closedByUserOnQueue)
let openCloseOutQueue = openByUserOutQueue.concat(closedUserOutQueue)
for (let i = 0; i < queuesByUser.length; i++) {
queuesByUser[i].countOpen = 0
queuesByUser[i].countClosed = 0
for (let x = 0; x < openCloseOnQueue.length; x++) {
if ((queuesByUser[i].userId == openCloseOnQueue[x].userId) &&
(queuesByUser[i].queueId == openCloseOnQueue[x].queueId && openCloseOnQueue[x].status == 'open')) {
queuesByUser[i].countOpen = openCloseOnQueue[x].totAttendance
}
else if ((queuesByUser[i].userId == openCloseOnQueue[x].userId) &&
(queuesByUser[i].queueId == openCloseOnQueue[x].queueId && openCloseOnQueue[x].status == 'closed')) {
queuesByUser[i].countClosed = openCloseOnQueue[x].totAttendance
}
if (req.user.profile !== "master" && req.user.profile !== "admin") {
throw new AppError("ERR_NO_PERMISSION", 403);
} }
const { userId, startDate, endDate } = req.query as IndexQuery }
let usersProfile = await ListUserParamiterService({profile: 'user'}) // console.log('queuesByUser: ', queuesByUser)
const sumUserOlineTime = await ShowUserServiceReport({startDate, endDate, userId});
const closedByUser = await ShowUserServiceReport({startDate, endDate, ticketStatus: 'closed', userId});
const openByUser = await ShowUserServiceReport({startDate, endDate, ticketStatus: 'open', userId});
let dateTime = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR })))
const onlineUsers = await ListUserOnlineOffline({ date: dateTime.fullDate })
usersProfile.map((user:any) => {
let index = sumUserOlineTime.findIndex((e:any) => e.userId == user.id) // console.log('queuesByUser: ',queuesByUser)
// console.log()
if (index != -1) { // console.log('CLIENT START TRUE openByUserOnQueue: ', openByUserOnQueue)
user.sumOnlineTime = sumUserOlineTime[index]; // console.log()
} // console.log('CLIENT START FALSE openByUserOutQueue: ', openByUserOutQueue)
// console.log()
index = closedByUser.findIndex((e:any) => e.userId == user.id) // console.log('CLIENT START TRUE closedByUserOnQueue: ', closedByUserOnQueue)
// console.log()
if (index != -1) { // console.log('CLIENT START FALSE closedUserOutQueue: ', closedUserOutQueue)
user.sumClosed = closedByUser[index];
}
index = openByUser.findIndex((e:any) => e.userId == user.id)
if (index != -1) {
user.sumOpen = openByUser[index]
}
index = onlineUsers.findIndex((e:any) => e.userId == user.id) usersProfile.map((user: any) => {
if (index != -1) { let index = sumUserOlineTime.findIndex((e: any) => e.userId == user.id)
user.statusOnline = onlineUsers[index]
}
if(startDate.length>0 && startDate.split('-').length == 3){ if (index != -1) {
let date = startDate.split('-') user.sumOnlineTime = sumUserOlineTime[index];
user.startDate = `${date[2]}/${date[1]}/${date[0]}` }
}
if(endDate.length>0 && endDate.split('-').length == 3){ index = closedByUser.findIndex((e: any) => e.userId == user.id)
let date = endDate.split('-')
user.endDate = `${date[2]}/${date[1]}/${date[0]}`
}
}) if (index != -1) {
user.sumClosed = closedByUser[index];
}
return res.status(200).json(usersProfile); index = openByUser.findIndex((e: any) => e.userId == user.id)
if (index != -1) {
user.sumOpen = openByUser[index]
}
// let openByUserOut = openQueueInOut.filter((e: any) => e.userId == user.id && !e.queueName)
// let openByUserIn = openQueueInOut.filter((e: any) => e.userId == user.id && e.queueName)
// if (openByUserOut && openByUserOut.length > 0) {
// user.openTicketByUserOut = openByUserOut
// }
// if (openByUserIn && openByUserIn.length > 0) {
// user.openTicketByUserIn = openByUserIn
// }
// let closedByUserOut = closedQueueInOut.filter((e: any) => e.userId == user.id && !e.queueName)
// let closedByUserIn = closedQueueInOut.filter((e: any) => e.userId == user.id && e.queueName)
// if (closedByUserOut && closedByUserOut.length > 0) {
// user.closedTicketByUserOut = closedByUserOut
// }
// if (closedByUserIn && closedByUserIn.length > 0) {
// user.closedTicketByUserIn = closedByUserIn
// }
// OPEN, CLOSED TICKETS STARTED BY USERS
let openClosedOutQueue = {}
let open = openCloseOutQueue.filter((e) => e.userId == user.id && e.status == 'open')
let closed = openCloseOutQueue.filter((e) => e.userId == user.id && e.status == 'closed')
openClosedOutQueue = {
...openClosedOutQueue,
userId: user.id,
countOpen: open && open.length > 0 ? open[0].totAttendance : 0,
countClosed: closed && closed.length > 0 ? closed[0].totAttendance : 0
}
user.openClosedOutQueue = openClosedOutQueue
// OPEN, CLOSED TICKETS STARTED BY CLIENTS
let openClosedInQueue = queuesByUser.filter((e) => e.userId == user.id)
if (openClosedInQueue && openClosedInQueue.length > 0) {
user.openClosedInQueue = openClosedInQueue
}
index = onlineUsers.findIndex((e: any) => e.userId == user.id)
if (index != -1) {
user.statusOnline = onlineUsers[index]
}
if (startDate.length > 0 && startDate.split('-').length == 3) {
let date = startDate.split('-')
user.startDate = `${date[2]}/${date[1]}/${date[0]}`
}
if (endDate.length > 0 && endDate.split('-').length == 3) {
let date = endDate.split('-')
user.endDate = `${date[2]}/${date[1]}/${date[0]}`
}
})
return res.status(200).json(usersProfile);
}; };
@ -108,15 +223,15 @@ export const reportUserService= async (req: Request, res: Response): Promise<Res
export const reportMessagesUserByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => { export const reportMessagesUserByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => {
if (req.user.profile !== "master" && req.user.profile !== "admin") { if (req.user.profile !== "master" && req.user.profile !== "admin") {
throw new AppError("ERR_NO_PERMISSION", 403); throw new AppError("ERR_NO_PERMISSION", 403);
} }
const { userId, startDate, endDate } = req.query as IndexQuery const { userId, startDate, endDate } = req.query as IndexQuery
const data_query_messages = await ShowMessageReport(userId, startDate, endDate); const data_query_messages = await ShowMessageReport(userId, startDate, endDate);
return res.status(200).json(data_query_messages); return res.status(200).json(data_query_messages);
}; };
@ -124,4 +239,3 @@ export const reportMessagesUserByDateStartDateEnd = async (req: Request, res: Re

View File

@ -21,6 +21,8 @@ import format from 'date-fns/format';
type IndexQuery = { type IndexQuery = {
searchParam: string; searchParam: string;
pageNumber: string; pageNumber: string;
@ -44,8 +46,12 @@ import ListStatusChatEndService from "../services/StatusChatEndService/ListStatu
import Ticket from "../models/Ticket"; import Ticket from "../models/Ticket";
import ShowUserServiceReport from "../services/UserServices/ShowUserServiceReport"; import ShowUserServiceReport from "../services/UserServices/ShowUserServiceReport";
import TicketEmiterSumOpenClosedByUser from "../helpers/OnlineReporEmiterInfoByUser"; import TicketEmiterSumOpenClosedByUser from "../helpers/OnlineReporEmiterInfoByUser";
import CountTicketService from "../services/TicketServices/CountTicketService";
import CountTicketsByUserQueue from "../services/UserServices/CountTicketsByUserQueue";
import ShowUserService from "../services/UserServices/ShowUserService";
export const index = async (req: Request, res: Response): Promise<Response> => { export const index = async (req: Request, res: Response): Promise<Response> => {
const { const {
pageNumber, pageNumber,
status, status,
@ -58,7 +64,6 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
} = req.query as IndexQuery; } = req.query as IndexQuery;
const userId = req.user.id; const userId = req.user.id;
let queueIds: number[] = []; let queueIds: number[] = [];
@ -138,6 +143,17 @@ export const show = async (req: Request, res: Response): Promise<Response> => {
}; };
export const count = async (req: Request, res: Response): Promise<Response> => {
type indexQ = { status: string; date?: string; };
const {status, date} = req.query as IndexQuery
const ticketCount = await CountTicketService(status, date);
return res.status(200).json(ticketCount);
};
@ -221,12 +237,15 @@ export const update = async (req: Request, res: Response): Promise<Response> =>
ticketId ticketId
}); });
const dateToday = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR })))
TicketEmiterSumOpenClosedByUser(ticketData.userId.toString(), dateToday.fullDate, dateToday.fullDate)
ticket2 = ticket ticket2 = ticket
} }
// test del
if (userOldInfo) { if (userOldInfo) {
@ -234,12 +253,15 @@ export const update = async (req: Request, res: Response): Promise<Response> =>
if (userOldInfo.userId) { if (userOldInfo.userId) {
// console.log('FECHOU...')
TicketEmiterSumOpenClosedByUser(userOldInfo.userId.toString(), dateToday.fullDate, dateToday.fullDate) TicketEmiterSumOpenClosedByUser(userOldInfo.userId.toString(), dateToday.fullDate, dateToday.fullDate)
} }
} }
//
return res.status(200).json(ticket2); return res.status(200).json(ticket2);
}; };
@ -248,7 +270,6 @@ export const update = async (req: Request, res: Response): Promise<Response> =>
// export const update = async ( // export const update = async (
// req: Request, // req: Request,
// res: Response // res: Response

View File

@ -6,7 +6,7 @@ module.exports = {
"StatusChatEnds", "StatusChatEnds",
[ [
{ {
name: "SEM RETORNO DO CLIENTE", name: "FINALIZADO",
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date() updatedAt: new Date()
}, },

View File

@ -3,14 +3,64 @@ import { splitDateTime } from "../helpers/SplitDateTime";
import format from 'date-fns/format'; import format from 'date-fns/format';
import ShowUserServiceReport from '../services/UserServices/ShowUserServiceReport'; import ShowUserServiceReport from '../services/UserServices/ShowUserServiceReport';
import { getIO } from "../libs/socket"; import { getIO } from "../libs/socket";
import CountTicketsByUserQueue from "../services/UserServices/CountTicketsByUserQueue";
import ShowQueuesByUser from '../services/UserServices/ShowQueuesByUser';
// import CountTicketsByUserQueue from "../services/UserServices/CountTicketsByUserQueue";
const TicketEmiterSumOpenClosedByUser = async (userId: string, startDate: string, endDate: string) => { const TicketEmiterSumOpenClosedByUser = async (userId: string, startDate: string, endDate: string) => {
const openByUser: any[] = await ShowUserServiceReport({ startDate: startDate, endDate:endDate, ticketStatus: 'open', userId: userId.toString() }); const openByUser: any[] = await ShowUserServiceReport({ startDate: startDate, endDate: endDate, ticketStatus: 'open', userId: userId.toString() });
const closedByUser: any[] = await ShowUserServiceReport({ startDate: endDate, endDate:endDate, ticketStatus: 'closed', userId: userId.toString() }); const closedByUser: any[] = await ShowUserServiceReport({ startDate: endDate, endDate: endDate, ticketStatus: 'closed', userId: userId.toString() });
const openByUserOnQueue: any[] = await CountTicketsByUserQueue({ startDate: startDate, endDate: endDate, status: 'open', clientChatStart: true, userId: userId })
const openByUserOutQueue: any[] = await CountTicketsByUserQueue({ startDate: startDate, endDate: endDate, status: 'open', clientChatStart: false, userId: userId })
const closedByUserOnQueue: any[] = await CountTicketsByUserQueue({ startDate: startDate, endDate: endDate, status: 'closed', clientChatStart: true, userId: userId })
const closedUserOutQueue: any[] = await CountTicketsByUserQueue({ startDate: startDate, endDate: endDate, status: 'closed', clientChatStart: false, userId: userId })
const queuesByUser = await ShowQueuesByUser({ profile: 'user', userId: userId })
let openCloseOnQueue = openByUserOnQueue.concat(closedByUserOnQueue)
let openCloseOutQueue = openByUserOutQueue.concat(closedUserOutQueue)
// OPEN, CLOSED TICKETS STARTED BY CLIENTS
for (let i = 0; i < queuesByUser.length; i++) {
queuesByUser[i].countOpen = 0
queuesByUser[i].countClosed = 0
for (let x = 0; x < openCloseOnQueue.length; x++) {
if ((queuesByUser[i].userId == openCloseOnQueue[x].userId) &&
(queuesByUser[i].queueId == openCloseOnQueue[x].queueId && openCloseOnQueue[x].status == 'open')) {
queuesByUser[i].countOpen = openCloseOnQueue[x].totAttendance
}
else if ((queuesByUser[i].userId == openCloseOnQueue[x].userId) &&
(queuesByUser[i].queueId == openCloseOnQueue[x].queueId && openCloseOnQueue[x].status == 'closed')) {
queuesByUser[i].countClosed = openCloseOnQueue[x].totAttendance
}
}
}
// OPEN, CLOSED TICKETS STARTED BY USERS
let openClosedOutQueue = {}
let open = openCloseOutQueue.filter((e) => e.status == 'open')
let closed = openCloseOutQueue.filter((e) => e.status == 'closed')
openClosedOutQueue = {
...openClosedOutQueue,
userId: userId,
countOpen: open && open.length > 0 ? open[0].totAttendance : 0,
countClosed: closed && closed.length > 0 ? closed[0].totAttendance : 0
}
//openByUser : [ { id: 13, status: 'online' } ]
const io = getIO(); const io = getIO();
io.emit("onlineStatus", { io.emit("onlineStatus", {
@ -18,6 +68,11 @@ const TicketEmiterSumOpenClosedByUser = async (userId: string, startDate: string
userOnlineTime: { userOnlineTime: {
sumOpen: openByUser.length > 0 ? openByUser[0] : { userId: userId, count: '' }, sumOpen: openByUser.length > 0 ? openByUser[0] : { userId: userId, count: '' },
sumClosed: closedByUser.length > 0 ? closedByUser[0] : { userId: userId, count: '' }, sumClosed: closedByUser.length > 0 ? closedByUser[0] : { userId: userId, count: '' },
openClosedOutQueue: openClosedOutQueue,
openClosedInQueue: queuesByUser
} }
}); });

View File

@ -13,6 +13,8 @@ const fastFolderSize = require('fast-folder-size')
const { promisify } = require('util') const { promisify } = require('util')
const fs = require('fs') const fs = require('fs')
const { exec } = require("child_process");
let scheduler_monitor: any; let scheduler_monitor: any;
let timeInterval = 5 let timeInterval = 5
@ -53,6 +55,35 @@ const monitor = async () => {
} }
exec("df -h /", (error: any, stdout: any, stderr: any) => {
if (error) {
console.log(`exec error: ${error.message}`);
return;
}
if (stderr) {
console.log(`exec stderr: ${stderr}`);
return;
}
stdout = stdout.split(/\r?\n/)
stdout = stdout[1].trim().split(/\s+/)
// DISK SPACE MONITORING
const io = getIO();
io.emit("diskSpaceMonit", {
action: "update",
diskSpace: {
size: stdout[1],
used: stdout[2],
available: stdout[3],
use: stdout[4]
}
});
});
// WHATS SESSION SIZE MONITORING // WHATS SESSION SIZE MONITORING
const whatsapps = await ListWhatsAppsService(); const whatsapps = await ListWhatsAppsService();

View File

@ -6,6 +6,8 @@ import * as TicketController from "../controllers/TicketController";
const ticketRoutes = express.Router(); const ticketRoutes = express.Router();
ticketRoutes.get("/tickets/count", isAuth, TicketController.count);
ticketRoutes.get("/tickets", isAuth, TicketController.index); ticketRoutes.get("/tickets", isAuth, TicketController.index);
ticketRoutes.get("/tickets/:ticketId", isAuth, TicketController.show); ticketRoutes.get("/tickets/:ticketId", isAuth, TicketController.show);

View File

@ -16,4 +16,4 @@ StartAllWhatsAppsSessions();
gracefulShutdown(server); gracefulShutdown(server);
startSchedulingMonitor(5000) startSchedulingMonitor(5000)
startWhoIsOnlineMonitor(5000) startWhoIsOnlineMonitor(2000)

View File

@ -0,0 +1,50 @@
import Ticket from "../../models/Ticket";
import AppError from "../../errors/AppError";
import { Op, where } from "sequelize";
import { Sequelize } from "sequelize";
import { format } from "date-fns";
import ptBR from 'date-fns/locale/pt-BR';
import { splitDateTime } from "../../helpers/SplitDateTime";
const dateToday = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR })))
const CountTicketService = async (status: string, date?: string): Promise<any> => {
let where_clause = {}
if (date) {
where_clause = {
createdAt: {
[Op.gte]: date + ' 00:00:00.000000',
[Op.lte]: date + ' 23:59:59.999999'
}
}
}
else {
// where_clause = {
// createdAt: {
// [Op.gte]: dateToday.fullDate + ' 00:00:00.000000',
// [Op.lte]: dateToday.fullDate + ' 23:59:59.999999'
// }
// }
}
where_clause = { ...where_clause, status: status }
const ticket = await Ticket.findAll({
where: where_clause,
raw: true,
attributes: [[Sequelize.fn("COUNT", Sequelize.col("Ticket.status")), "count"]],
});
if (!ticket) {
throw new AppError("ERR_NO_TICKET_FOUND", 404);
}
return ticket[0];
};
export default CountTicketService;

View File

@ -39,7 +39,7 @@ const ListTicketsService = async ({
showAll, showAll,
userId, userId,
withUnreadMessages, withUnreadMessages,
unlimited='false' unlimited = 'false'
}: Request): Promise<Response> => { }: Request): Promise<Response> => {
let whereCondition: Filterable["where"] = { let whereCondition: Filterable["where"] = {
[Op.or]: [{ userId }, { status: "pending" }], [Op.or]: [{ userId }, { status: "pending" }],
@ -47,6 +47,8 @@ const ListTicketsService = async ({
}; };
let includeCondition: Includeable[]; let includeCondition: Includeable[];
includeCondition = [ includeCondition = [
{ {
model: Contact, model: Contact,
@ -65,20 +67,21 @@ const ListTicketsService = async ({
} }
if (status) { if (status) {
whereCondition = {
...whereCondition,
status
};
// if (unlimited) { whereCondition = { ...whereCondition, status };
// whereCondition = {
// ...whereCondition, // console.log('TEST unlimited: ', unlimited)
// createdAt: {
// [Op.gte]: dateToday.fullDate + ' 00:00:00.000000', if (unlimited === 'true' && status !== 'pending') {
// [Op.lte]: dateToday.fullDate + ' 23:59:59.999999'
// } whereCondition = {
// } ...whereCondition,
// } createdAt: {
[Op.gte]: dateToday.fullDate + ' 00:00:00.000000',
[Op.lte]: dateToday.fullDate + ' 23:59:59.999999'
}
}
}
} }
@ -92,11 +95,7 @@ const ListTicketsService = async ({
as: "messages", as: "messages",
attributes: ["id", "body"], attributes: ["id", "body"],
where: { where: {
body: where( body: where(fn("LOWER", col("body")), "LIKE", `%${sanitizedSearchParam}%`)
fn("LOWER", col("body")),
"LIKE",
`%${sanitizedSearchParam}%`
)
}, },
required: false, required: false,
duplicating: false duplicating: false
@ -107,19 +106,13 @@ const ListTicketsService = async ({
...whereCondition, ...whereCondition,
[Op.or]: [ [Op.or]: [
{ {
"$contact.name$": where( "$contact.name$": where(fn("LOWER", col("contact.name")), "LIKE", `%${sanitizedSearchParam}%`)
fn("LOWER", col("contact.name")),
"LIKE",
`%${sanitizedSearchParam}%`
)
}, },
{ "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } }, { "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } },
{ {
"$message.body$": where( "$message.body$": where(fn("LOWER", col("body")), "LIKE", `%${sanitizedSearchParam}%`)
fn("LOWER", col("body")),
"LIKE",
`%${sanitizedSearchParam}%`
)
} }
] ]
}; };

View File

@ -16,12 +16,31 @@ import { startOfDay, endOfDay, parseISO, getDate} from "date-fns";
import { string } from "yup/lib/locale"; import { string } from "yup/lib/locale";
import Whatsapp from "../../models/Whatsapp"; import Whatsapp from "../../models/Whatsapp";
interface Request {
userId: string | number;
startDate: string;
endDate: string;
pageNumber?: string;
}
interface Response {
tickets: Ticket[];
count: number;
hasMore: boolean;
}
//Report by user, startDate, endDate //Report by user, startDate, endDate
const ShowTicketReport = async (id: string | number, startDate: string, endDate: string): Promise<Ticket[]> => { const ShowTicketReport = async ({
userId,
startDate,
endDate,
pageNumber = "1"
}: Request): Promise<Response> => {
let where_clause = {} let where_clause = {}
if(id=='0'){ if(userId=='0'){
where_clause = { where_clause = {
createdAt: { createdAt: {
[Op.gte]: startDate+' 00:00:00.000000', [Op.gte]: startDate+' 00:00:00.000000',
@ -31,7 +50,7 @@ const ShowTicketReport = async (id: string | number, startDate: string, endDate:
} }
else{ else{
where_clause = { where_clause = {
userid: id, userid: userId,
createdAt: { createdAt: {
[Op.gte]: startDate+' 00:00:00.000000', [Op.gte]: startDate+' 00:00:00.000000',
[Op.lte]: endDate +' 23:59:59.999999' [Op.lte]: endDate +' 23:59:59.999999'
@ -40,11 +59,14 @@ const ShowTicketReport = async (id: string | number, startDate: string, endDate:
} }
const limit = 40;
const offset = limit * (+pageNumber - 1);
const {count, rows: tickets} = await Ticket.findAndCountAll({
const ticket = await Ticket.findAll({
where: where_clause , where: where_clause ,
limit,
offset,
//attributes: ['id', 'status', 'createdAt', 'updatedAt'], //attributes: ['id', 'status', 'createdAt', 'updatedAt'],
attributes: ['id', 'status', 'statusChatEnd', [Sequelize.fn("DATE_FORMAT",Sequelize.col("Ticket.createdAt"),"%d/%m/%Y %H:%i:%s"),"createdAt"], attributes: ['id', 'status', 'statusChatEnd', [Sequelize.fn("DATE_FORMAT",Sequelize.col("Ticket.createdAt"),"%d/%m/%Y %H:%i:%s"),"createdAt"],
@ -82,14 +104,20 @@ const ShowTicketReport = async (id: string | number, startDate: string, endDate:
}, },
], ],
order: [
['id', 'ASC']
]
}); });
const hasMore = count > offset + tickets.length;
if (!ticket) {
if (!tickets) {
throw new AppError("ERR_NO_TICKET_FOUND", 404); throw new AppError("ERR_NO_TICKET_FOUND", 404);
} }
return ticket; return {tickets, count, hasMore};
}; };
export default ShowTicketReport; export default ShowTicketReport;

View File

@ -0,0 +1,73 @@
import { Sequelize, } from "sequelize";
const dbConfig = require("../../config/database");
const sequelize = new Sequelize(dbConfig);
const { QueryTypes } = require('sequelize');
interface Request {
startDate: string;
endDate: string;
status: string;
clientChatStart: boolean;
userId?: string | number;
}
const CountTicketsByUserQueue = async ({ startDate, endDate, status, clientChatStart, userId }: Request): Promise<any[]> => {
let usersQueueInfo = []
if (clientChatStart) {
if (userId) {
// CONSULTANDO POR CONVERSAS INICIADAS PELO CLIENTE
usersQueueInfo = await sequelize.query(`select Users.id as userId, Tickets.status, Queues.id as queueId, Queues.name as queueName, \
(select count(id) from Tickets where userId = Users.id and Tickets.status = '${status}' and Tickets.queueId = Queues.id \
and (date(Tickets.createdAt) BETWEEN '${startDate} 00:00:00.000000' AND '${endDate} 23:59:59.999999')) as totAttendance \
from Tickets inner join Users inner join Queues on Tickets.queueId = Queues.id and Tickets.userId = Users.id and Tickets.status = '${status}' \
and (date(Tickets.createdAt) BETWEEN '${startDate} 00:00:00.000000' AND '${endDate} 23:59:59.999999') and Users.id = '${userId}' group by Users.email, Queues.name;`, { type: QueryTypes.SELECT });
} else {
// CONSULTANDO POR CONVERSAS INICIADAS PELO CLIENTE
usersQueueInfo = await sequelize.query(`select Users.id as userId, Tickets.status, Queues.id as queueId, Queues.name as queueName, \
(select count(id) from Tickets where userId = Users.id and Tickets.status = '${status}' and Tickets.queueId = Queues.id \
and (date(Tickets.createdAt) BETWEEN '${startDate} 00:00:00.000000' AND '${endDate} 23:59:59.999999')) as totAttendance \
from Tickets inner join Users inner join Queues on Tickets.queueId = Queues.id and Tickets.userId = Users.id and Tickets.status = '${status}' \
and (date(Tickets.createdAt) BETWEEN '${startDate} 00:00:00.000000' AND '${endDate} 23:59:59.999999') group by Users.email, Queues.name;`, { type: QueryTypes.SELECT });
}
}
else {
if (userId) {
// CONSULTANDO POR CONVERSAS INICIADAS PELO ATENDENTE
usersQueueInfo = await sequelize.query(`select Users.id as userId, Tickets.status, \
(select count(id) from Tickets where userId = Users.id and Tickets.status = '${status}' and Tickets.queueId is null \
and (date(Tickets.createdAt) BETWEEN '${startDate} 00:00:00.000000' AND '${endDate} 23:59:59.999999')) as totAttendance \
from Tickets inner join Users on \
Tickets.queueId is null and Tickets.userId = Users.id and Tickets.status = '${status}' \
and (date(Tickets.createdAt) BETWEEN '${startDate} 00:00:00.000000' AND '${endDate} 23:59:59.999999') and Users.id = '${userId}' group by Users.email;`, { type: QueryTypes.SELECT });
}
else {
// CONSULTANDO POR CONVERSAS INICIADAS PELO ATENDENTE
usersQueueInfo = await sequelize.query(`select Users.id as userId, Tickets.status, \
(select count(id) from Tickets where userId = Users.id and Tickets.status = '${status}' and Tickets.queueId is null \
and (date(Tickets.createdAt) BETWEEN '${startDate} 00:00:00.000000' AND '${endDate} 23:59:59.999999')) as totAttendance \
from Tickets inner join Users on \
Tickets.queueId is null and Tickets.userId = Users.id and Tickets.status = '${status}' \
and (date(Tickets.createdAt) BETWEEN '${startDate} 00:00:00.000000' AND '${endDate} 23:59:59.999999') group by Users.email;`, { type: QueryTypes.SELECT });
}
}
return usersQueueInfo;
};
export default CountTicketsByUserQueue;

View File

@ -118,6 +118,7 @@ const CreateOrUpdateUserOnlineTime = async ({
console.log('UpdatedAt string: ', updatedAtString) console.log('UpdatedAt string: ', updatedAtString)
// //
io.emit("onlineStatus", { io.emit("onlineStatus", {
action: "update", action: "update",
userOnlineTime: { userOnlineTime: {

View File

@ -1,44 +1,62 @@
import { Op, Sequelize } from "sequelize"; import { Op, Sequelize } from "sequelize";
import Queue from "../../models/Queue";
import User from "../../models/User"; import User from "../../models/User";
import UserQueue from "../../models/UserQueue";
interface Request { interface Request {
userId?: string | number; userId?: string | number;
profile?: string; profile?: string;
}
const ListUser = async ({ profile, userId }: Request): Promise<User[]> => {
let where_clause = {}
if (userId && profile) {
where_clause = {
[Op.and]: [
{ userId: userId },
{ profile: profile }
]
}
} }
else if (userId) {
where_clause = {
const ListUser = async ({profile, userId}: Request): Promise<User[]> => { [Op.and]: [
{ userId: userId },
let where_clause = {} ]
if(userId && profile){
where_clause = {
[Op.and]: [
{userId: userId},
{profile: profile}
]
}
} }
else if(userId){ }
where_clause = { else if (profile) {
[Op.and]: [ where_clause = {
{userId: userId}, profile: profile
]
}
}
else if(profile){
where_clause = {
profile: profile
}
} }
}
const users = await User.findAll({ const users = await User.findAll({
where: where_clause, where: where_clause,
raw:true, raw: true,
attributes: ['id', 'name', 'email'], attributes: ['id', 'name', 'email'],
// include: [
// {
// model: UserQueue,
// separate: true,
// attributes: ['id',],
// order: [
// ['createdAt', 'ASC']
// ]
// },
// ],
order: [["id", "ASC"]], order: [["id", "ASC"]],
}) })
@ -51,4 +69,3 @@ export default ListUser;

View File

@ -61,7 +61,7 @@ const ListUserOnlineOffline = async ({date, userId, status}: Request): Promise<U
attributes: ['id', 'userId', 'status', attributes: ['id', 'userId', 'status',
[Sequelize.fn("DATE_FORMAT",Sequelize.col("UserOnlineTime.onlineTime"),"%Y-%m-%d %H:%i:%s"),"onlineTime"], [Sequelize.fn("DATE_FORMAT",Sequelize.col("UserOnlineTime.onlineTime"),"%Y-%m-%d %H:%i:%s"),"onlineTime"],
[Sequelize.fn("DATE_FORMAT",Sequelize.col("UserOnlineTime.createdAt"),"%Y-%m-%d %H:%i:%s"),"createdAt"], [Sequelize.fn("DATE_FORMAT",Sequelize.col("UserOnlineTime.createdAt"),"%Y-%m-%d %H:%i:%s"),"createdAt"],
[Sequelize.fn("DATE_FORMAT",Sequelize.col("UserOnlineTime.updatedAt"),"%Y-%m-%d %H:%i:%s"),"updatedAt"]], [Sequelize.fn("DATE_FORMAT",Sequelize.col("UserOnlineTime.updatedAt"),"%Y-%m-%d %H:%i:%s"),"updatedAt"]],
order: [["id", "ASC"]], order: [["id", "ASC"]],

View File

@ -0,0 +1,40 @@
import { Sequelize, } from "sequelize";
const dbConfig = require("../../config/database");
const sequelize = new Sequelize(dbConfig);
const { QueryTypes } = require('sequelize');
interface Request {
profile: string;
userId?: string | number;
}
const QueuesByUser = async ({ profile, userId }: Request): Promise<any[]> => {
let queueByUsersInfo = []
if (userId) {
// CONSULTANDO FILAS PELO ID DO USUARIO
queueByUsersInfo = await sequelize.query(`select UserQueues.userId, UserQueues.queueId, Users.name,
Queues.name, Queues.color from UserQueues inner join Users inner join Queues on
UserQueues.queueId = Queues.id and UserQueues.userId = Users.id and Users.id = '${userId}' and Users.profile = '${profile}' order by userId, queueId;`, { type: QueryTypes.SELECT });
} else {
// CONSULTANDO FILAS PELO USUARIO
queueByUsersInfo = await sequelize.query(`select UserQueues.userId, UserQueues.queueId, Users.name,
Queues.name, Queues.color from UserQueues inner join Users inner join Queues on
UserQueues.queueId = Queues.id and UserQueues.userId = Users.id and Users.profile = '${profile}' order by userId, queueId;`, { type: QueryTypes.SELECT });
}
return queueByUsersInfo;
};
export default QueuesByUser;

View File

@ -106,6 +106,8 @@ const ShowUserServiceReport = async ({
} }
// console.log('>>>>>>>>>>>>>> objQuery: ', objQuery)
if (!objQuery) { if (!objQuery) {

View File

@ -825,6 +825,7 @@ const handleMsgAck = async (msg: WbotMessage, ack: MessageAck) => {
action: "update", action: "update",
message: messageToUpdate message: messageToUpdate
}); });
} catch (err) { } catch (err) {
Sentry.captureException(err); Sentry.captureException(err);
logger.error(`Error handling message ack. Err: ${err}`); logger.error(`Error handling message ack. Err: ${err}`);

View File

@ -362,15 +362,17 @@ const MessagesList = ({ ticketId, isGroup }) => {
socket.on("connect", () => socket.emit("joinChatBox", ticketId)); socket.on("connect", () => socket.emit("joinChatBox", ticketId));
socket.on("appMessage", (data) => { socket.on("appMessage", (data) => {
if (data.action === "create") { if (data.action === "create") {
dispatch({ type: "ADD_MESSAGE", payload: data.message }); dispatch({ type: "ADD_MESSAGE", payload: data.message });
// console.log('* NOVA MENSAGEM CAP: ', data.message)
scrollToBottom(); scrollToBottom();
} }
if (data.action === "update") { if (data.action === "update") {
console.log('2 THIS IS THE DATA: ', data)
dispatch({ type: "UPDATE_MESSAGE", payload: data.message }); dispatch({ type: "UPDATE_MESSAGE", payload: data.message });
} }
}); });

View File

@ -4,82 +4,154 @@ import MaterialTable from 'material-table';
import Modal from '../Modal' import Modal from '../Modal'
import { render } from '@testing-library/react'; import { render } from '@testing-library/react';
import chat from '@material-ui/icons/Chat';
// import Button from "@material-ui/core/Button";
import React from 'react'; import React from 'react';
const MTable = (props) => { const MTable = (props) => {
const [selectedRow, setSelectedRow] = useState(null); const tableRef = React.useRef();
const openInNewTab = url => {
window.open(url, '_blank', 'noopener,noreferrer');
};
const [selectedRow, setSelectedRow] = useState(null);
//const dataLoad = props.data.map((dt) => { return { ...dt }}); //const dataLoad = props.data.map((dt) => { return { ...dt }});
const dataLoad = props.data.map(({ user, ...others }) => ({ ...others, 'user': user ? user : { name: 'Aguardando atendente', email: '' } })); const dataLoad = props.data.map(({ user, ...others }) => ({ ...others, 'user': user ? user : { name: 'Aguardando atendente', email: '' } }));
const columnsLoad = props.columns.map((column) => { return { ...column } }); const columnsLoad = props.columns.map((column) => { return { ...column } });
useEffect(() => { useEffect(() => {
console.log(`You have clicked the button ${selectedRow} times`) console.log(`You have clicked the button ${selectedRow} times`)
// console.log('TABLE REF: ', tableRef)
}, [selectedRow]); }, [selectedRow]);
useEffect(() => {
if (!tableRef.current) return
const element = tableRef.current.tableContainerDiv.current;
element.addEventListener('scroll', props.handleScroll);
return () => {
element.removeEventListener('scroll', props.handleScroll);
};
}, [props]);
return ( return (
<MaterialTable <>
title={props.table_title} {/* <Button onClick={handleTest}>Toggle</Button> */}
columns={columnsLoad}
data={dataLoad}
maxWidth={true} {/* <CircularProgress /> */}
onRowClick={(evt, selectedRow) => { <MaterialTable
title={props.table_title}
columns={columnsLoad}
data={dataLoad}
maxWidth={true}
if(props.removeClickRow){ tableRef={tableRef}
return
localization={{ header: { actions: props.hasChild ? 'Ticket' : null },}}
onRowClick={(evt, selectedRow) => {
if (props.removeClickRow) {
return
}
console.log(selectedRow.tableData.id);
console.log(selectedRow);
console.log(selectedRow.messages);
setSelectedRow(selectedRow.tableData.id)
if (props.hasChild) {
render(<Modal data={selectedRow.messages}
hasChild={false}
modal_header={'Chat do atendimento pelo Whatsapp'}
user={selectedRow.user.name}
clientContactNumber={selectedRow.contact.number} />)
}
console.log('props.hasChild: ', props.hasChild)
//evt.stopPropagation()
}
} }
console.log(selectedRow.tableData.id);
console.log(selectedRow);
console.log(selectedRow.messages);
setSelectedRow(selectedRow.tableData.id)
if (props.hasChild) { actions={[
render(<Modal data={selectedRow.messages} (rowData) => {
hasChild={false}
modal_header={'Chat do atendimento pelo Whatsapp'}
user={selectedRow.user.name}
clientContactNumber={selectedRow.contact.number} />)
}
console.log('props.hasChild: ', props.hasChild) if(props.hasChild){
return {
icon: chat,
tooltip: `Ticket id ${rowData.id}`,
disable: false,
onClick: (event, rowData) => {
//evt.stopPropagation() openInNewTab(`/tickets/${rowData.id}`)
}
}
options={{ }
search: true, }
selection: false, }
paging: false, }
padding: 'dense', ]}
sorting: true ? props.hasChild : false,
//loadingType: 'linear', options={{
searchFieldStyle: { search: true,
width: 300, selection: false,
}, paging: false,
padding: 'dense',
exportButton: props.hasChild ? true : null,
exportAllData: true,
sorting: true ? props.hasChild : false,
// loadingType: 'circular',
searchFieldStyle: {
width: 300,
},
pageSize: 20,
headerStyle: {
position: "sticky",
top: "0"
},
maxBodyHeight: "400px",
// minBodyHeight: "85vh", //FIXME to calculate dynamic height, needed for correct scroll position identification
// maxBodyHeight: "85vh",
rowStyle: rowData => ({
fontSize: 12,
backgroundColor: selectedRow === rowData.tableData.id ? '#ec5114' : '#FFF'
})
}}
/>
</>
pageSize: 20,
headerStyle: {
position: "sticky",
top: "0"
},
maxBodyHeight: "400px",
rowStyle: rowData => ({
fontSize: 12,
backgroundColor: selectedRow === rowData.tableData.id ? '#ec5114' : '#FFF'
})
}}
/>
); );
}; };

View File

@ -12,6 +12,7 @@ import useTickets from "../../hooks/useTickets";
import { i18n } from "../../translate/i18n"; import { i18n } from "../../translate/i18n";
import { AuthContext } from "../../context/Auth/AuthContext"; import { AuthContext } from "../../context/Auth/AuthContext";
const useStyles = makeStyles(theme => ({ const useStyles = makeStyles(theme => ({
ticketsListWrapper: { ticketsListWrapper: {
position: "relative", position: "relative",
@ -108,7 +109,7 @@ const reducer = (state, action) => {
if (action.type === "UPDATE_TICKET") { if (action.type === "UPDATE_TICKET") {
const ticket = action.payload; const ticket = action.payload;
// console.log('++++++++++++ UPDATE_TICKET: ',ticket) // console.log('++++++++++++ UPDATE_TICKET: ',ticket)
const ticketIndex = state.findIndex(t => t.id === ticket.id); const ticketIndex = state.findIndex(t => t.id === ticket.id);
if (ticketIndex !== -1) { if (ticketIndex !== -1) {
@ -134,8 +135,8 @@ const reducer = (state, action) => {
// console.log('&&&&&&& UPDATE_TICKET_UNREAD_MESSAGES ticket: ',ticket, ' |\n MESSAGE: ', message) // console.log('&&&&&&& UPDATE_TICKET_UNREAD_MESSAGES ticket: ',ticket, ' |\n MESSAGE: ', message)
if(!message.fromMe){ if (!message.fromMe) {
ticket.unreadMessages +=1 ticket.unreadMessages += 1
} }
state[ticketIndex] = ticket; state[ticketIndex] = ticket;
@ -195,6 +196,9 @@ const TicketsList = (props) => {
useEffect(() => { useEffect(() => {
if (!status && !searchParam) return; if (!status && !searchParam) return;
// console.log('lllllllllllllllllllllllllllllllll')
dispatch({ dispatch({
type: "LOAD_TICKETS", type: "LOAD_TICKETS",
payload: tickets, payload: tickets,
@ -221,6 +225,7 @@ const TicketsList = (props) => {
}); });
socket.on("ticket", data => { socket.on("ticket", data => {
if (data.action === "updateUnread") { if (data.action === "updateUnread") {
dispatch({ dispatch({
type: "RESET_UNREAD", type: "RESET_UNREAD",
@ -286,6 +291,7 @@ const TicketsList = (props) => {
}; };
const handleScroll = e => { const handleScroll = e => {
if (!hasMore || loading) return; if (!hasMore || loading) return;
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget; const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;

View File

@ -125,7 +125,6 @@ const TicketsManager = () => {
const handleSearch = (e) => { const handleSearch = (e) => {
const searchedTerm = e.target.value.toLowerCase().trim(); const searchedTerm = e.target.value.toLowerCase().trim();
console.log(searchedTerm)
clearTimeout(searchTimeout); clearTimeout(searchTimeout);

View File

@ -39,6 +39,19 @@ const reducer = (state, action) => {
} }
// if (action.type === "UPDATE_DISK_SPACE_MONIT") {
// const whatsApp = action.payload;
// const whatsAppIndex = state.findIndex(s => s.id === whatsApp.id);
// if (whatsAppIndex !== -1) {
// state[whatsAppIndex].sessionSize = whatsApp.sessionSize;
// return [...state];
// } else {
// return [whatsApp, ...state];
// }
// }
if (action.type === "UPDATE_WHATSAPPS_SESSION_MONIT") { if (action.type === "UPDATE_WHATSAPPS_SESSION_MONIT") {
const whatsApp = action.payload; const whatsApp = action.payload;
const whatsAppIndex = state.findIndex(s => s.id === whatsApp.id); const whatsAppIndex = state.findIndex(s => s.id === whatsApp.id);
@ -108,10 +121,6 @@ const useWhatsApps = () => {
} }
}); });
//test del
socket.on("whatsappSessionMonit", data => { socket.on("whatsappSessionMonit", data => {
if (data.action === "update") { if (data.action === "update") {
@ -121,7 +130,7 @@ const useWhatsApps = () => {
} }
}); });
//
return () => { return () => {
socket.disconnect(); socket.disconnect();

View File

@ -1,7 +1,9 @@
import React, { useState, useCallback, useContext } from "react"; 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 { 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";
import { import {
@ -111,6 +113,8 @@ 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({});
@ -324,6 +328,23 @@ const Connections = () => {
); );
}; };
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 ( return (
<Can <Can
@ -355,7 +376,10 @@ const Connections = () => {
/> />
<MainHeader> <MainHeader>
<Title>{i18n.t("connections.title")}</Title> <Title>{i18n.t("connections.title")}</Title>
<MainHeaderButtonsWrapper> <MainHeaderButtonsWrapper>
<Can <Can
role={user.profile} role={user.profile}
@ -370,193 +394,236 @@ const Connections = () => {
)} )}
/> />
</MainHeaderButtonsWrapper> </MainHeaderButtonsWrapper>
</MainHeader> </MainHeader>
<Paper className={classes.mainPaper} variant="outlined"> <Paper className={classes.mainPaper} variant="outlined">
<Table size="small"> <>
<TableHead>
<TableRow>
<TableCell align="center"> <Can
{i18n.t("connections.table.name")} role={user.profile}
</TableCell> perform="space-disk-info:show"
yes={() => (
<TableCell align="center">
{i18n.t("connections.table.status")}
</TableCell>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
{i18n.t("connections.table.session")}
</TableCell>
)}
/>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
Restore
</TableCell>
)}
/>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
Session MB
</TableCell>
)}
/>
<TableCell align="center">
{i18n.t("connections.table.lastUpdate")}
</TableCell>
<TableCell align="center">
{i18n.t("connections.table.default")}
</TableCell>
<TableCell align="center">
{i18n.t("connections.table.actions")}
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{loading ? (
<TableRowSkeleton />
) : (
<> <>
{whatsApps?.length > 0 && <Table size="small">
whatsApps.map(whatsApp => ( <TableHead>
<TableRow key={whatsApp.id}> <TableRow>
<TableCell align="center">{whatsApp.name}</TableCell> <TableCell align="center">
Size
</TableCell>
<TableCell align="center">
Used
</TableCell>
<TableCell align="center">
Available
</TableCell>
<TableCell align="center">
Use%
</TableCell>
</TableRow>
</TableHead>
<TableCell align="center"> <TableBody>
{renderStatusToolTips(whatsApp)} <TableRow>
</TableCell> <TableCell align="center">{diskSpaceInfo.size}</TableCell>
<TableCell align="center">{diskSpaceInfo.used}</TableCell>
<Can <TableCell align="center">{diskSpaceInfo.available}</TableCell>
role={user.profile} <TableCell align="center">{diskSpaceInfo.use}</TableCell>
perform="connection-button:show" </TableRow>
yes={() => ( </TableBody>
<TableCell align="center"> </Table>
{renderActionButtons(whatsApp)} <br />
</TableCell> </>
)}
/>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
<Button
size="small"
variant="contained"
color="primary"
onClick={() => handleRestartWhatsAppSession(whatsApp.id)}
>
Restore
</Button>
</TableCell>
)}
/>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
<CustomToolTip
title={'Informação da sessão em Megabytes'}
content={'Tamanho do diretorio da sessão atualizado a cada 5 segundos'}
>
<div>{whatsApp.sessionSize}</div>
</CustomToolTip>
</TableCell>
)}
/>
<TableCell align="center">
{format(parseISO(whatsApp.updatedAt), "dd/MM/yy HH:mm")}
</TableCell>
<TableCell align="center">
{whatsApp.isDefault && (
<div className={classes.customTableCell}>
<CheckCircle style={{ color: green[500] }} />
</div>
)}
</TableCell>
<TableCell align="center">
<Can
role={user.profile}
perform="show-icon-edit-whatsapp"
yes={() => (
<IconButton
size="small"
onClick={() => handleEditWhatsApp(whatsApp)}
>
<Edit />
</IconButton>
)}
/>
<Can
role={user.profile}
perform="btn-remove-whatsapp"
yes={() => (
<IconButton
size="small"
onClick={e => {
handleOpenConfirmationModal("delete", whatsApp.id);
}}
>
<DeleteOutline />
</IconButton>
)}
/>
</TableCell>
</TableRow>
))}
</>
)} )}
</TableBody> />
</Table>
<Table size="small">
<TableHead>
<TableRow>
<TableCell align="center">
{i18n.t("connections.table.name")}
</TableCell>
<TableCell align="center">
{i18n.t("connections.table.status")}
</TableCell>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
{i18n.t("connections.table.session")}
</TableCell>
)}
/>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
Restore
</TableCell>
)}
/>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
Session MB
</TableCell>
)}
/>
<TableCell align="center">
{i18n.t("connections.table.lastUpdate")}
</TableCell>
<TableCell align="center">
{i18n.t("connections.table.default")}
</TableCell>
<TableCell align="center">
{i18n.t("connections.table.actions")}
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{loading ? (
<TableRowSkeleton />
) : (
<>
{whatsApps?.length > 0 &&
whatsApps.map(whatsApp => (
<TableRow key={whatsApp.id}>
<TableCell align="center">{whatsApp.name}</TableCell>
<TableCell align="center">
{renderStatusToolTips(whatsApp)}
</TableCell>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
{renderActionButtons(whatsApp)}
</TableCell>
)}
/>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
<Button
size="small"
variant="contained"
color="primary"
onClick={() => handleRestartWhatsAppSession(whatsApp.id)}
>
Restore
</Button>
</TableCell>
)}
/>
<Can
role={user.profile}
perform="connection-button:show"
yes={() => (
<TableCell align="center">
<CustomToolTip
title={'Informação da sessão em Megabytes'}
content={'Tamanho do diretorio da sessão atualizado a cada 5 segundos'}
>
<div>{whatsApp.sessionSize}</div>
</CustomToolTip>
</TableCell>
)}
/>
<TableCell align="center">
{format(parseISO(whatsApp.updatedAt), "dd/MM/yy HH:mm")}
</TableCell>
<TableCell align="center">
{whatsApp.isDefault && (
<div className={classes.customTableCell}>
<CheckCircle style={{ color: green[500] }} />
</div>
)}
</TableCell>
<TableCell align="center">
<Can
role={user.profile}
perform="show-icon-edit-whatsapp"
yes={() => (
<IconButton
size="small"
onClick={() => handleEditWhatsApp(whatsApp)}
>
<Edit />
</IconButton>
)}
/>
<Can
role={user.profile}
perform="btn-remove-whatsapp"
yes={() => (
<IconButton
size="small"
onClick={e => {
handleOpenConfirmationModal("delete", whatsApp.id);
}}
>
<DeleteOutline />
</IconButton>
)}
/>
</TableCell>
</TableRow>
))}
</>
)}
</TableBody>
</Table>
</>
</Paper> </Paper>
</MainContainer> </MainContainer>
)} )}

View File

@ -36,17 +36,23 @@ import { AuthContext } from "../../context/Auth/AuthContext";
import { Can } from "../../components/Can"; import { Can } from "../../components/Can";
const reducer = (state, action) => { const reducer = (state, action) => {
if (action.type === "LOAD_CONTACTS") { if (action.type === "LOAD_CONTACTS") {
const contacts = action.payload; const contacts = action.payload;
const newContacts = []; const newContacts = [];
contacts.forEach((contact) => { contacts.forEach((contact) => {
const contactIndex = state.findIndex((c) => c.id === contact.id); const contactIndex = state.findIndex((c) => c.id === contact.id);
if (contactIndex !== -1) { if (contactIndex !== -1) {
state[contactIndex] = contact; state[contactIndex] = contact;
} else { } else {
newContacts.push(contact); newContacts.push(contact);
} }
}); });
return [...state, ...newContacts]; return [...state, ...newContacts];
@ -210,6 +216,9 @@ const Contacts = () => {
const handleScroll = (e) => { const handleScroll = (e) => {
if (!hasMore || loading) return; if (!hasMore || loading) return;
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget; const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
// console.log('scrollTop: ', scrollTop, ' | scrollHeight: ', scrollHeight, ' | clientHeight: ', clientHeight)
if (scrollHeight - (scrollTop + 100) < clientHeight) { if (scrollHeight - (scrollTop + 100) < clientHeight) {
loadMore(); loadMore();
} }

View File

@ -16,11 +16,18 @@ import { i18n } from "../../translate/i18n";
import Title from "./Title"; import Title from "./Title";
import useTickets from "../../hooks/useTickets"; import useTickets from "../../hooks/useTickets";
const Chart = () => { const Chart = (props) => {
const theme = useTheme(); const theme = useTheme();
const date = useRef(new Date().toISOString()); const date = useRef(new Date().toISOString());
const { tickets } = useTickets({ date: date.current }); const { tickets } = useTickets({ date: date.current, unlimited: "true" });
// useEffect(()=>{
// console.log('kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk')
// },[props.change])
const [chartData, setChartData] = useState([ const [chartData, setChartData] = useState([
{ time: "08:00", amount: 0 }, { time: "08:00", amount: 0 },
@ -42,10 +49,7 @@ const Chart = () => {
let aux = [...prevState]; let aux = [...prevState];
aux.forEach(a => { aux.forEach(a => {
tickets.forEach(ticket => { tickets.forEach(ticket => { format(startOfHour(parseISO(ticket.createdAt)), "HH:mm") === a.time && a.amount++; });
format(startOfHour(parseISO(ticket.createdAt)), "HH:mm") === a.time &&
a.amount++;
});
}); });
return aux; return aux;
@ -54,9 +58,8 @@ const Chart = () => {
return ( return (
<React.Fragment> <React.Fragment>
<Title>{`${i18n.t("dashboard.charts.perDay.title")}${ <Title>{`${i18n.t("dashboard.charts.perDay.title")}${tickets.length
tickets.length }`}</Title>
}`}</Title>
<ResponsiveContainer> <ResponsiveContainer>
<BarChart <BarChart
data={chartData} data={chartData}

View File

@ -22,6 +22,10 @@ import openSocket from "socket.io-client";
import api from "../../services/api"; import api from "../../services/api";
import openSocket from "socket.io-client";
import api from "../../services/api";
import { Can } from "../../components/Can"; import { Can } from "../../components/Can";
import CardUser from "../../components/DashboardUser/CardUser"; import CardUser from "../../components/DashboardUser/CardUser";
import TableUser from "../../components/DashboardUser/TableUser"; import TableUser from "../../components/DashboardUser/TableUser";
@ -197,6 +201,152 @@ const reducer = (state, action) => {
} }
}; };
const reducer = (state, action) => {
if (action.type === "DELETE_USER_STATUS") {
const userId = action.payload;
const userIndex = state.findIndex((u) => `${u.id}` === `${userId}`);
if (userIndex !== -1) {
state.splice(userIndex, 1);
}
return [...state];
}
if (action.type === 'LOAD_QUERY') {
const queries = action.payload
const newQueries = []
queries.forEach((query) => {
const queryIndex = state.findIndex((q) => q.id === query.id)
if (queryIndex !== -1) {
state[queryIndex] = query
}
else {
newQueries.push(query)
}
})
return [...state, ...newQueries]
}
if (action.type === "UPDATE_STATUS_ONLINE") {
let onlineUser = action.payload
let index = -1
let onlySumOpenClosed = false
if (onlineUser.sumOpen || onlineUser.sumClosed) {
index = state.findIndex((e) => ((onlineUser.sumOpen && e.id === onlineUser.sumOpen.userId) || (onlineUser.sumClosed && e.id === onlineUser.sumClosed.userId)))
onlySumOpenClosed = true
}
else {
index = state.findIndex((e) => `${e.id}` === `${onlineUser.userId}`)
}
if (index !== -1) {
if (!onlySumOpenClosed) {
if (!("statusOnline" in state[index])) {
state[index].statusOnline = onlineUser
}
else if ("statusOnline" in state[index]) {
state[index].statusOnline['status'] = onlineUser.status
}
}
if ("onlineTime" in onlineUser) {
if ("sumOnlineTime" in state[index]) {
state[index].sumOnlineTime['sum'] = (onlineUser.onlineTime).split(" ")[1]
}
else if (!("sumOnlineTime" in state[index])) {
state[index].sumOnlineTime = { userId: onlineUser.userId, sum: (onlineUser.onlineTime).split(" ")[1] }
}
}
if (onlineUser.sumOpen) {
if ("sumOpen" in state[index]) {
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1 | state[index].sumOpen["count"]: ', state[index].sumOpen['count'], ' | onlineUser.sumOpen.count: ', onlineUser.sumOpen.count)
state[index].sumOpen['count'] = onlineUser.sumOpen.count
} else if (!("sumOpen" in state[index])) {
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1')
state[index].sumOpen = onlineUser.sumOpen
}
}
if (onlineUser.sumClosed) {
if ("sumClosed" in state[index]) {
// console.log(' >>>>>>>>>>>>>>>>>> sumClosed 1 | state[index].sumClosed["count"]: ', state[index].sumClosed['count'], ' | onlineUser.sumClosed.count: ', onlineUser.sumClosed.count)
state[index].sumClosed['count'] = onlineUser.sumClosed.count
} else if (!("sumClosed" in state[index])) {
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1')
state[index].sumClosed = onlineUser.sumClosed
}
}
if(onlineUser.openClosedInQueue){
state[index].openClosedInQueue = onlineUser.openClosedInQueue
}
if(onlineUser.openClosedOutQueue){
state[index].openClosedOutQueue = onlineUser.openClosedOutQueue
}
// if(onlineUser.closedTicketByUserIn){
// state[index].closedTicketByUserIn = onlineUser.closedTicketByUserIn
// }
// if(onlineUser.closedTicketByUserOut){
// state[index].closedTicketByUserOut = onlineUser.closedTicketByUserOut
// }
// if(onlineUser.openTicketByUserIn){
// state[index].openTicketByUserIn = onlineUser.openTicketByUserIn
// }
// if(onlineUser.openTicketByUserOut){
// state[index].openTicketByUserOut = onlineUser.openTicketByUserOut
// }
}
return [...state]
}
if (action.type === "RESET") {
return [];
}
}
const Dashboard = () => { const Dashboard = () => {
const classes = useStyles(); const classes = useStyles();
const [usersOnlineInfo, dispatch] = useReducer(reducer, []); const [usersOnlineInfo, dispatch] = useReducer(reducer, []);

View File

@ -18,8 +18,11 @@ import MaterialTable from 'material-table';
import LogoutIcon from '@material-ui/icons/CancelOutlined'; import LogoutIcon from '@material-ui/icons/CancelOutlined';
import { CSVLink } from "react-csv"; import { CSVLink } from "react-csv";
// import CircularProgress from '@mui/material/CircularProgress';
import openSocket from "socket.io-client"; import openSocket from "socket.io-client";
@ -104,7 +107,7 @@ const reducerQ = (state, action) => {
const userIndex = state.findIndex((u) => `${u.id}` === `${userId}`); const userIndex = state.findIndex((u) => `${u.id}` === `${userId}`);
// console.log('>>>>>>>>>>>>>>>>>>>>> userIndex: ', userIndex) // console.log('>>>>>>>>>>>>>>>>>>>>> userIndex: ', userIndex)
if (userIndex !== -1) { if (userIndex !== -1) {
state.splice(userIndex, 1); state.splice(userIndex, 1);
@ -117,7 +120,6 @@ const reducerQ = (state, action) => {
if (action.type === 'LOAD_QUERY') { if (action.type === 'LOAD_QUERY') {
const queries = action.payload const queries = action.payload
const newQueries = [] const newQueries = []
@ -143,7 +145,7 @@ const reducerQ = (state, action) => {
let onlineUser = action.payload let onlineUser = action.payload
let index = -1 let index = -1
// console.log('sssssssssstate: ', state, ' | ONLINE USERS: onlineUser.userId ', onlineUser.userId) // console.log('sssssssssstate: ', state, ' | ONLINE USERS: onlineUser.userId ', onlineUser.userId)
if (onlineUser.sumOpen || onlineUser.sumClosed) { if (onlineUser.sumOpen || onlineUser.sumClosed) {
index = state.findIndex((e) => ((onlineUser.sumOpen && e.id === onlineUser.sumOpen.userId) || (onlineUser.sumClosed && e.id === onlineUser.sumClosed.userId))) index = state.findIndex((e) => ((onlineUser.sumOpen && e.id === onlineUser.sumOpen.userId) || (onlineUser.sumClosed && e.id === onlineUser.sumClosed.userId)))
@ -152,13 +154,13 @@ const reducerQ = (state, action) => {
index = state.findIndex((e) => `${e.id}` === `${onlineUser.userId}`) index = state.findIndex((e) => `${e.id}` === `${onlineUser.userId}`)
} }
//console.log(' *********************** index: ', index) //console.log(' *********************** index: ', index)
if (index !== -1) { if (index !== -1) {
// console.log('ENTROU NO INDEX') // console.log('ENTROU NO INDEX')
if (!("statusOnline" in state[index])) { if (!("statusOnline" in state[index])) {
@ -183,10 +185,10 @@ const reducerQ = (state, action) => {
if (onlineUser.sumOpen) { if (onlineUser.sumOpen) {
if ("sumOpen" in state[index]) { if ("sumOpen" in state[index]) {
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1 | state[index].sumOpen["count"]: ', state[index].sumOpen['count'], ' | onlineUser.sumOpen.count: ', onlineUser.sumOpen.count) // console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1 | state[index].sumOpen["count"]: ', state[index].sumOpen['count'], ' | onlineUser.sumOpen.count: ', onlineUser.sumOpen.count)
state[index].sumOpen['count'] = onlineUser.sumOpen.count state[index].sumOpen['count'] = onlineUser.sumOpen.count
} else if (!("sumOpen" in state[index])) { } else if (!("sumOpen" in state[index])) {
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1') // console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1')
state[index].sumOpen = onlineUser.sumOpen state[index].sumOpen = onlineUser.sumOpen
} }
@ -195,10 +197,10 @@ const reducerQ = (state, action) => {
if (onlineUser.sumClosed) { if (onlineUser.sumClosed) {
if ("sumClosed" in state[index]) { if ("sumClosed" in state[index]) {
// console.log(' >>>>>>>>>>>>>>>>>> sumClosed 1 | state[index].sumClosed["count"]: ', state[index].sumClosed['count'], ' | onlineUser.sumClosed.count: ', onlineUser.sumClosed.count) // console.log(' >>>>>>>>>>>>>>>>>> sumClosed 1 | state[index].sumClosed["count"]: ', state[index].sumClosed['count'], ' | onlineUser.sumClosed.count: ', onlineUser.sumClosed.count)
state[index].sumClosed['count'] = onlineUser.sumClosed.count state[index].sumClosed['count'] = onlineUser.sumClosed.count
} else if (!("sumClosed" in state[index])) { } else if (!("sumClosed" in state[index])) {
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1') // console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1')
state[index].sumClosed = onlineUser.sumClosed state[index].sumClosed = onlineUser.sumClosed
} }
@ -301,19 +303,26 @@ let columnsData = [
{ title: 'Criado', field: 'createdAt' }, { title: 'Criado', field: 'createdAt' },
//{title: 'Atualizado', field: 'updatedAt'}, //{title: 'Atualizado', field: 'updatedAt'},
{title: 'Status de encerramento', field: 'statusChatEnd'}]; { title: 'Status de encerramento', field: 'statusChatEnd' }];
const Report = () => { const Report = () => {
const csvLink = useRef() const csvLink = useRef()
const { user: userA } = useContext(AuthContext); const { user: userA } = useContext(AuthContext);
//-------- //--------
const [searchParam] = useState(""); const [searchParam] = useState("");
//const [loading, setLoading] = useState(false);
//const [hasMore, setHasMore] = useState(false); const [loading, setLoading] = useState(false);
const [hasMore, setHasMore] = useState(false);
const [pageNumberTickets, setTicketsPageNumber] = useState(1);
const [totalCountTickets, setTotalCountTickets] = useState(0);
const [pageNumber, setPageNumber] = useState(1); const [pageNumber, setPageNumber] = useState(1);
const [users, dispatch] = useReducer(reducer, []); const [users, dispatch] = useReducer(reducer, []);
//const [columns, setColums] = useState([]) //const [columns, setColums] = useState([])
@ -336,7 +345,7 @@ const Report = () => {
useEffect(() => { useEffect(() => {
dispatch({ type: "RESET" }); dispatch({ type: "RESET" });
dispatchQ({ type: "RESET" }) dispatchQ({ type: "RESET" })
setTicketsPageNumber(1)
setPageNumber(1); setPageNumber(1);
}, [searchParam, profile]); }, [searchParam, profile]);
@ -380,20 +389,24 @@ const Report = () => {
const delayDebounceFn = setTimeout(() => { const delayDebounceFn = setTimeout(() => {
setLoading(true);
const fetchQueries = async () => { const fetchQueries = async () => {
try { try {
if (reportOption === '1') { if (reportOption === '1') {
const dataQuery = await api.get("/reports/", { params: { userId, startDate, endDate }, }); const { data } = await api.get("/reports/", { params: { userId, startDate, endDate, pageNumber: pageNumberTickets }, });
dispatchQ({ type: "RESET" })
dispatchQ({ type: "LOAD_QUERY", payload: dataQuery.data });
//setLoading(false); // console.log('dataQuery: ', data)
// console.log('pageNumberTickets: ', pageNumberTickets)
// console.log('dataQuery: ', dataQuery.data) // dispatchQ({ type: "RESET" })
dispatchQ({ type: "LOAD_QUERY", payload: data.tickets });
setHasMore(data.hasMore);
setTotalCountTickets(data.count)
setLoading(false);
// console.log()
} }
else if (reportOption === '2') { else if (reportOption === '2') {
@ -404,7 +417,7 @@ const Report = () => {
//setLoading(false); //setLoading(false);
// console.log('REPORT 2 dataQuery : ', dataQuery.data) console.log('REPORT 2 dataQuery : ', dataQuery.data)
//console.log() //console.log()
@ -420,7 +433,7 @@ const Report = () => {
}, 500); }, 500);
return () => clearTimeout(delayDebounceFn); return () => clearTimeout(delayDebounceFn);
}, [userId, startDate, endDate, reportOption]); }, [userId, startDate, endDate, reportOption, pageNumberTickets, totalCountTickets]);
// Get from child 1 // Get from child 1
@ -449,7 +462,7 @@ const Report = () => {
setReport(data) setReport(data)
// console.log(' data: ', data) // console.log(' data: ', data)
} }
useEffect(() => { useEffect(() => {
@ -464,27 +477,15 @@ const Report = () => {
}, [reportOption]) }, [reportOption])
// useEffect(() => {
// console.log('>>>>>>>>>>>>>>>>>> New query: ', query)
// }, [query])
// test del
const handleCSVMessages = () => { const handleCSVMessages = () => {
// setLoading(true);
const fetchQueries = async () => { const fetchQueries = async () => {
try { try {
const dataQuery = await api.get("/reports/messages", { params: { userId, startDate, endDate }, }); const dataQuery = await api.get("/reports/messages", { params: { userId, startDate, endDate }, });
// console.log('dataQuery messages: ', dataQuery.data) console.log('dataQuery messages: ', dataQuery.data)
if (dataQuery.data.length > 0) { if (dataQuery.data.length > 0) {
@ -499,15 +500,10 @@ const Report = () => {
} }
} }
// console.log('dataCSVFormat: ', dataCSVFormat)
setDataCSV(dataCSVFormat) setDataCSV(dataCSVFormat)
setIsMount(false); setIsMount(false);
// setDataCSV(dataQuery.data)
} }
// setLoading(false);
} catch (err) { } catch (err) {
console.log(err); console.log(err);
} }
@ -542,16 +538,9 @@ const Report = () => {
socket.on("onlineStatus", (data) => { socket.on("onlineStatus", (data) => {
// setLoading(true);
let date = new Date().toLocaleDateString('pt-BR').split('/') let date = new Date().toLocaleDateString('pt-BR').split('/')
let dateToday = `${date[2]}-${date[1]}-${date[0]}` let dateToday = `${date[2]}-${date[1]}-${date[0]}`
// console.log('date: ', new Date(startDate).toLocaleDateString('pt-BR'))
// console.log('date2: ', startDate)
if (data.action === "logout" || (data.action === "update" && if (data.action === "logout" || (data.action === "update" &&
((`${startDate}` === `${endDate}`) && (`${endDate}` === `${dateToday}`) && (`${startDate}` === `${dateToday}`)))) { ((`${startDate}` === `${endDate}`) && (`${endDate}` === `${dateToday}`) && (`${startDate}` === `${dateToday}`)))) {
@ -564,14 +553,12 @@ const Report = () => {
dispatchQ({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime }); dispatchQ({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime });
} }
// setLoading(false);
}); });
socket.on("user", (data) => { socket.on("user", (data) => {
if (data.action === "delete") { if (data.action === "delete") {
// console.log(' entrou no delete user: ', data) // console.log(' entrou no delete user: ', data)
dispatch({ type: "DELETE_USER", payload: +data.userId }); dispatch({ type: "DELETE_USER", payload: +data.userId });
} }
}); });
@ -581,9 +568,13 @@ const Report = () => {
}; };
} }
else if (reportOption === "1") {
dispatchQ({ type: "RESET" })
setTicketsPageNumber(1)
}
}, [reportOption, startDate, endDate]); }, [reportOption, startDate, endDate, userId]);
// const handleDeleteRows = (id) => { // const handleDeleteRows = (id) => {
@ -610,6 +601,7 @@ const Report = () => {
setData(query.map((column) => { return { ...column } })) setData(query.map((column) => { return { ...column } }))
}, [query]) }, [query])
const handleLogouOnlineUser = async (userId) => { const handleLogouOnlineUser = async (userId) => {
@ -625,6 +617,30 @@ const Report = () => {
}; };
const loadMore = () => {
setTicketsPageNumber((prevState) => prevState + 1);
};
const handleScroll = (e) => {
if (!hasMore || loading) return;
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
// console.log('scrollTop: ', scrollTop,
// ' | scrollHeight: ', scrollHeight,
// ' | clientHeight: ', clientHeight,
// ' | scrollHeight - (scrollTop + 1): ', scrollHeight - (scrollTop + 1))
if (scrollHeight - (scrollTop + 1) < clientHeight) {
loadMore();
// e.currentTarget.scrollTo(0, 200);
}
};
return ( return (
<Can <Can
@ -639,7 +655,7 @@ const Report = () => {
return { 'value': obj.id, 'label': obj.name } return { 'value': obj.id, 'label': obj.name }
})} /></Item> })} /></Item>
<Item><DatePicker1 func={datePicker1Value} minDate={true} startEmpty={false} title={'Data inicio'} /></Item> <Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={false} title={'Data inicio'} /></Item>
<Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={'Data fim'} /></Item> <Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={'Data fim'} /></Item>
<Item sx={{ display: 'grid', gridColumn: '4 / 5', }}> <Item sx={{ display: 'grid', gridColumn: '4 / 5', }}>
@ -651,13 +667,15 @@ const Report = () => {
{reportOption === '1' && {reportOption === '1' &&
<div> <div>
{/* <Button <Button style={{display: "none"}}
variant="contained" variant="contained"
color="primary" color="primary"
onClick={(e) => handleCSVMessages()} onClick={(e) => {
handleCSVMessages()
}}
> >
{"CSV ALL"} {"CSV ALL"}
</Button> */} </Button>
<div> <div>
<CSVLink <CSVLink
@ -674,10 +692,6 @@ const Report = () => {
</Item> </Item>
</Box> </Box>
<Box sx={{ <Box sx={{
@ -688,11 +702,22 @@ const Report = () => {
{reportOption === '1' && {reportOption === '1' &&
<MTable data={query} // <div onScroll={handleScroll} style={{ height: 400, overflowY: "scroll" }}>
columns={columnsData} // </div>
hasChild={true}
removeClickRow={false} <>
table_title={'Atendimento por atendentes'} />
<MTable data={query}
columns={columnsData}
hasChild={true}
removeClickRow={false}
handleScroll={handleScroll}
table_title={'Atendimento por atendentes'} />
</>
} }
{reportOption === '2' && {reportOption === '2' &&
@ -711,7 +736,7 @@ const Report = () => {
[ [
// { title: 'Foto', field: 'ticket.contact.profilePicUrl', render: rowData => <img src={rowData['ticket.contact.profilePicUrl']} alt="imagem de perfil do whatsapp" style={{ width: 40, borderRadius: '50%' }} /> }, // { title: 'Foto', field: 'ticket.contact.profilePicUrl', render: rowData => <img src={rowData['ticket.contact.profilePicUrl']} alt="imagem de perfil do whatsapp" style={{ width: 40, borderRadius: '50%' }} /> },
{ title: 'Nome', field: 'name', cellStyle: {whiteSpace: 'nowrap'}, }, { title: 'Nome', field: 'name', cellStyle: { whiteSpace: 'nowrap' }, },
{ {
title: 'Status', field: 'statusOnline.status', title: 'Status', field: 'statusOnline.status',
@ -765,7 +790,7 @@ const Report = () => {
disable: false, disable: false,
onClick: (event, rowData) => { onClick: (event, rowData) => {
// console.log(' ROW DATA INFO: ', rowData, ' | rowData: ', rowData.id) // console.log(' ROW DATA INFO: ', rowData, ' | rowData: ', rowData.id)
handleLogouOnlineUser(rowData.id) handleLogouOnlineUser(rowData.id)
} }
} }

View File

@ -29,6 +29,7 @@ const rules = {
"show-icon-add-queue", "show-icon-add-queue",
"show-icon-edit-queue", "show-icon-edit-queue",
"show-icon-delete-queue", "show-icon-delete-queue",
"space-disk-info:show",
"drawer-admin-items:view", "drawer-admin-items:view",