Modificações para exibir informaçãos em tempo real no dasboard
parent
2d95bfe20d
commit
71d69990e2
|
@ -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,13 +19,19 @@ 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;
|
pageNumber: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const reportUserByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => {
|
export const reportUserByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
@ -40,7 +46,7 @@ export const reportUserByDateStartDateEnd = async (req: Request, res: Response):
|
||||||
console.log('PAGE NUMBER: ', pageNumber)
|
console.log('PAGE NUMBER: ', pageNumber)
|
||||||
|
|
||||||
|
|
||||||
const { tickets, count, hasMore } = await ShowTicketReport({userId, startDate, endDate, pageNumber});
|
const { tickets, count, hasMore } = await ShowTicketReport({ userId, startDate, endDate, pageNumber });
|
||||||
|
|
||||||
// return res.status(200).json(data_query);
|
// return res.status(200).json(data_query);
|
||||||
|
|
||||||
|
@ -48,7 +54,7 @@ export const reportUserByDateStartDateEnd = async (req: Request, res: Response):
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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") {
|
if (req.user.profile !== "master" && req.user.profile !== "admin") {
|
||||||
throw new AppError("ERR_NO_PERMISSION", 403);
|
throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
|
@ -56,49 +62,153 @@ export const reportUserService= async (req: Request, res: Response): Promise<Res
|
||||||
const { userId, startDate, endDate } = req.query as IndexQuery
|
const { userId, startDate, endDate } = req.query as IndexQuery
|
||||||
|
|
||||||
|
|
||||||
let usersProfile = await ListUserParamiterService({profile: 'user'})
|
let usersProfile = await ListUserParamiterService({ profile: 'user' })
|
||||||
|
|
||||||
const sumUserOlineTime = await ShowUserServiceReport({startDate, endDate, userId});
|
const sumUserOlineTime = await ShowUserServiceReport({ startDate, endDate, userId });
|
||||||
const closedByUser = await ShowUserServiceReport({startDate, endDate, ticketStatus: 'closed', userId});
|
const closedByUser = await ShowUserServiceReport({ startDate, endDate, ticketStatus: 'closed', userId });
|
||||||
const openByUser = await ShowUserServiceReport({startDate, endDate, ticketStatus: 'open', 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 })))
|
let dateTime = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR })))
|
||||||
const onlineUsers = await ListUserOnlineOffline({ date: dateTime.fullDate })
|
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 })
|
||||||
|
|
||||||
usersProfile.map((user:any) => {
|
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 index = sumUserOlineTime.findIndex((e:any) => e.userId == user.id)
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// console.log('queuesByUser: ', queuesByUser)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// console.log('queuesByUser: ',queuesByUser)
|
||||||
|
// console.log()
|
||||||
|
// console.log('CLIENT START TRUE openByUserOnQueue: ', openByUserOnQueue)
|
||||||
|
// console.log()
|
||||||
|
// console.log('CLIENT START FALSE openByUserOutQueue: ', openByUserOutQueue)
|
||||||
|
// console.log()
|
||||||
|
// console.log('CLIENT START TRUE closedByUserOnQueue: ', closedByUserOnQueue)
|
||||||
|
// console.log()
|
||||||
|
// console.log('CLIENT START FALSE closedUserOutQueue: ', closedUserOutQueue)
|
||||||
|
|
||||||
|
|
||||||
|
usersProfile.map((user: any) => {
|
||||||
|
|
||||||
|
let index = sumUserOlineTime.findIndex((e: any) => e.userId == user.id)
|
||||||
|
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
user.sumOnlineTime = sumUserOlineTime[index];
|
user.sumOnlineTime = sumUserOlineTime[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
index = closedByUser.findIndex((e:any) => e.userId == user.id)
|
index = closedByUser.findIndex((e: any) => e.userId == user.id)
|
||||||
|
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
user.sumClosed = closedByUser[index];
|
user.sumClosed = closedByUser[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
index = openByUser.findIndex((e:any) => e.userId == user.id)
|
index = openByUser.findIndex((e: any) => e.userId == user.id)
|
||||||
|
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
user.sumOpen = openByUser[index]
|
user.sumOpen = openByUser[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
index = onlineUsers.findIndex((e:any) => e.userId == user.id)
|
|
||||||
|
|
||||||
|
|
||||||
|
// 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) {
|
if (index != -1) {
|
||||||
user.statusOnline = onlineUsers[index]
|
user.statusOnline = onlineUsers[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
if(startDate.length>0 && startDate.split('-').length == 3){
|
if (startDate.length > 0 && startDate.split('-').length == 3) {
|
||||||
let date = startDate.split('-')
|
let date = startDate.split('-')
|
||||||
user.startDate = `${date[2]}/${date[1]}/${date[0]}`
|
user.startDate = `${date[2]}/${date[1]}/${date[0]}`
|
||||||
}
|
}
|
||||||
|
|
||||||
if(endDate.length>0 && endDate.split('-').length == 3){
|
if (endDate.length > 0 && endDate.split('-').length == 3) {
|
||||||
let date = endDate.split('-')
|
let date = endDate.split('-')
|
||||||
user.endDate = `${date[2]}/${date[1]}/${date[0]}`
|
user.endDate = `${date[2]}/${date[1]}/${date[0]}`
|
||||||
}
|
}
|
||||||
|
@ -129,4 +239,3 @@ export const reportMessagesUserByDateStartDateEnd = async (req: Request, res: Re
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -16,4 +16,4 @@ StartAllWhatsAppsSessions();
|
||||||
gracefulShutdown(server);
|
gracefulShutdown(server);
|
||||||
|
|
||||||
startSchedulingMonitor(5000)
|
startSchedulingMonitor(5000)
|
||||||
startWhoIsOnlineMonitor(5000)
|
startWhoIsOnlineMonitor(2000)
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -1,33 +1,35 @@
|
||||||
|
|
||||||
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[]> => {
|
const ListUser = async ({ profile, userId }: Request): Promise<User[]> => {
|
||||||
|
|
||||||
let where_clause = {}
|
let where_clause = {}
|
||||||
|
|
||||||
if(userId && profile){
|
if (userId && profile) {
|
||||||
where_clause = {
|
where_clause = {
|
||||||
[Op.and]: [
|
[Op.and]: [
|
||||||
{userId: userId},
|
{ userId: userId },
|
||||||
{profile: profile}
|
{ profile: profile }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(userId){
|
else if (userId) {
|
||||||
where_clause = {
|
where_clause = {
|
||||||
[Op.and]: [
|
[Op.and]: [
|
||||||
{userId: userId},
|
{ userId: userId },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(profile){
|
else if (profile) {
|
||||||
where_clause = {
|
where_clause = {
|
||||||
profile: profile
|
profile: profile
|
||||||
}
|
}
|
||||||
|
@ -36,9 +38,25 @@ const ListUser = async ({profile, userId}: Request): Promise<User[]> => {
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,8 @@ const ShowUserServiceReport = async ({
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// console.log('>>>>>>>>>>>>>> objQuery: ', objQuery)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!objQuery) {
|
if (!objQuery) {
|
||||||
|
|
|
@ -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",
|
||||||
|
@ -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;
|
||||||
|
@ -224,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",
|
||||||
|
|
|
@ -16,12 +16,19 @@ 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, unlimited: "true" });
|
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 },
|
||||||
{ time: "09:00", amount: 0 },
|
{ time: "09: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,8 +58,7 @@ 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
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useContext } from "react"
|
import React, { useContext, useReducer, useEffect, useState } from "react"
|
||||||
|
|
||||||
import Paper from "@material-ui/core/Paper"
|
import Paper from "@material-ui/core/Paper"
|
||||||
import Container from "@material-ui/core/Container"
|
import Container from "@material-ui/core/Container"
|
||||||
|
@ -6,7 +6,7 @@ import Grid from "@material-ui/core/Grid"
|
||||||
import { makeStyles } from "@material-ui/core/styles"
|
import { makeStyles } from "@material-ui/core/styles"
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
|
|
||||||
import useTickets from "../../hooks/useTickets"
|
// import useTickets from "../../hooks/useTickets"
|
||||||
|
|
||||||
import { AuthContext } from "../../context/Auth/AuthContext";
|
import { AuthContext } from "../../context/Auth/AuthContext";
|
||||||
|
|
||||||
|
@ -14,8 +14,14 @@ import { i18n } from "../../translate/i18n";
|
||||||
|
|
||||||
import Chart from "./Chart"
|
import Chart from "./Chart"
|
||||||
|
|
||||||
|
import openSocket from "socket.io-client";
|
||||||
|
|
||||||
|
import api from "../../services/api";
|
||||||
|
|
||||||
import { Can } from "../../components/Can";
|
import { Can } from "../../components/Can";
|
||||||
|
|
||||||
|
import { Button } from "@material-ui/core";
|
||||||
|
|
||||||
const useStyles = makeStyles(theme => ({
|
const useStyles = makeStyles(theme => ({
|
||||||
container: {
|
container: {
|
||||||
paddingTop: theme.spacing(4),
|
paddingTop: theme.spacing(4),
|
||||||
|
@ -44,27 +50,312 @@ const useStyles = makeStyles(theme => ({
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 [open, setOpen] = useState(0)
|
||||||
|
const [closed, setClosed] = useState(0)
|
||||||
|
const [pending, setPending] = useState(0)
|
||||||
|
|
||||||
const { user } = useContext(AuthContext);
|
const { user } = useContext(AuthContext);
|
||||||
var userQueueIds = [];
|
// var userQueueIds = [];
|
||||||
|
|
||||||
if (user.queues && user.queues.length > 0) {
|
// if (user.queues && user.queues.length > 0) {
|
||||||
userQueueIds = user.queues.map(q => q.id);
|
// userQueueIds = user.queues.map(q => q.id);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const GetTickets = (status, showAll, withUnreadMessages, unlimited) => {
|
||||||
|
|
||||||
|
// const { tickets } = useTickets({
|
||||||
|
// status: status,
|
||||||
|
// showAll: showAll,
|
||||||
|
// withUnreadMessages: withUnreadMessages,
|
||||||
|
// queueIds: JSON.stringify(userQueueIds),
|
||||||
|
// unlimited: unlimited
|
||||||
|
// });
|
||||||
|
// return tickets.length;
|
||||||
|
// }
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
dispatch({ type: "RESET" });
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleLogouOnlineUser = async (userId) => {
|
||||||
|
try {
|
||||||
|
await api.get(`/users/logout/${userId}`);
|
||||||
|
//toast.success(("Desloged!"));
|
||||||
|
//handleDeleteRows(scheduleId)
|
||||||
|
} catch (err) {
|
||||||
|
// toastError(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetTickets = (status, showAll, withUnreadMessages, unlimited) => {
|
|
||||||
|
|
||||||
const { tickets } = useTickets({
|
};
|
||||||
status: status,
|
|
||||||
showAll: showAll,
|
|
||||||
withUnreadMessages: withUnreadMessages,
|
useEffect(() => {
|
||||||
queueIds: JSON.stringify(userQueueIds),
|
|
||||||
unlimited: unlimited
|
//setLoading(true);
|
||||||
|
|
||||||
|
const delayDebounceFn = setTimeout(() => {
|
||||||
|
|
||||||
|
// setLoading(true);
|
||||||
|
const fetchQueries = async () => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
let date = new Date().toLocaleDateString('pt-BR').split('/')
|
||||||
|
let dateToday = `${date[2]}-${date[1]}-${date[0]}`
|
||||||
|
|
||||||
|
const dataQuery = await api.get("/reports/user/services", { params: { userId: null, startDate: dateToday, endDate: dateToday }, });
|
||||||
|
dispatch({ type: "RESET" })
|
||||||
|
dispatch({ type: "LOAD_QUERY", payload: dataQuery.data });
|
||||||
|
|
||||||
|
console.log('xxx REPORT 2 dataQuery : ', dataQuery.data)
|
||||||
|
|
||||||
|
//console.log()
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchQueries();
|
||||||
|
|
||||||
|
}, 500);
|
||||||
|
return () => clearTimeout(delayDebounceFn);
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
||||||
|
|
||||||
|
// socket.on("ticket", (data) => {
|
||||||
|
// console.log('OK')
|
||||||
|
// });
|
||||||
|
|
||||||
|
socket.on("onlineStatus", (data) => {
|
||||||
|
|
||||||
|
if (data.action === "logout" || (data.action === "update")) {
|
||||||
|
|
||||||
|
// console.log('>>>>>>> data.userOnlineTime: ', data.userOnlineTime)
|
||||||
|
|
||||||
|
|
||||||
|
dispatch({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime });
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (data.action === "delete") {
|
||||||
|
dispatch({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime });
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
return tickets.length;
|
|
||||||
|
socket.on("user", (data) => {
|
||||||
|
|
||||||
|
if (data.action === "delete") {
|
||||||
|
// console.log(' entrou no delete user: ', data)
|
||||||
|
dispatch({ type: "DELETE_USER", payload: +data.userId });
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
socket.disconnect();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
const delayDebounceFn = setTimeout(() => {
|
||||||
|
|
||||||
|
const fetchQueries = async () => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
let date = new Date().toLocaleDateString('pt-BR').split('/')
|
||||||
|
let dateToday = `${date[2]}-${date[1]}-${date[0]}`
|
||||||
|
|
||||||
|
const _open = await api.get("/tickets/count", { params: { status: 'open', date: dateToday } });
|
||||||
|
const _closed = await api.get("/tickets/count", { params: { status: 'closed', date: dateToday } });
|
||||||
|
const _pending = await api.get("/tickets/count", { params: { status: 'pending', date: dateToday } });
|
||||||
|
|
||||||
|
setOpen(_open.data.count)
|
||||||
|
setClosed(_closed.data.count)
|
||||||
|
setPending(_pending.data.count)
|
||||||
|
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchQueries();
|
||||||
|
|
||||||
|
}, 500);
|
||||||
|
return () => clearTimeout(delayDebounceFn);
|
||||||
|
|
||||||
|
}, [usersOnlineInfo]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
@ -83,7 +374,8 @@ const Dashboard = () => {
|
||||||
</Typography>
|
</Typography>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Typography component="h1" variant="h4">
|
<Typography component="h1" variant="h4">
|
||||||
{GetTickets("open", "true", "false", "true")}
|
{/* {GetTickets("open", "true", "false", "true")} */}
|
||||||
|
{open}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
@ -95,7 +387,8 @@ const Dashboard = () => {
|
||||||
</Typography>
|
</Typography>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Typography component="h1" variant="h4">
|
<Typography component="h1" variant="h4">
|
||||||
{GetTickets("pending", "true", "false", "true")}
|
{/* {GetTickets("pending", "true", "false", "true")} */}
|
||||||
|
{pending}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
@ -107,21 +400,171 @@ const Dashboard = () => {
|
||||||
</Typography>
|
</Typography>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Typography component="h1" variant="h4">
|
<Typography component="h1" variant="h4">
|
||||||
{GetTickets("closed", "true", "false", "true")}
|
{/* {GetTickets("closed", "true", "false", "true")} */}
|
||||||
|
{closed}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<Grid item sm={6}>
|
||||||
|
<Paper style={{ padding: "15px", }}>
|
||||||
|
<Typography component="h3" color="primary" paragraph>
|
||||||
|
{'Total online'}
|
||||||
|
</Typography>
|
||||||
|
<Grid item>
|
||||||
|
<Typography component="h1" paragraph>
|
||||||
|
{usersOnlineInfo &&
|
||||||
|
usersOnlineInfo.filter((user) => user.statusOnline && user.statusOnline.status === 'online').length
|
||||||
|
}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
<Grid item sm={6}>
|
||||||
|
<Paper style={{ padding: "15px", }}>
|
||||||
|
<Typography component="h3" color="primary" paragraph>
|
||||||
|
{'Total offline'}
|
||||||
|
</Typography>
|
||||||
|
<Grid item>
|
||||||
|
<Typography component="h1" paragraph>
|
||||||
|
{usersOnlineInfo &&
|
||||||
|
usersOnlineInfo.filter((user) => !user.statusOnline || user.statusOnline.status === 'offline').length
|
||||||
|
}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Paper className={classes.fixedHeightPaper}>
|
<Paper className={classes.fixedHeightPaper}>
|
||||||
<Chart />
|
<Chart />
|
||||||
</Paper>
|
</Paper>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</Grid>
|
|
||||||
</Container>
|
|
||||||
|
{usersOnlineInfo &&
|
||||||
|
|
||||||
|
usersOnlineInfo.map((userInfo, index) => (
|
||||||
|
|
||||||
|
// <MenuItem key={index} value={option.value}> {option.label} </MenuItem>
|
||||||
|
|
||||||
|
|
||||||
|
<>
|
||||||
|
{userInfo.statusOnline &&
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<Grid item sm={3} key={index} style={{ margin: "25px" }}>
|
||||||
|
<Paper style={{ height: "480px", width: "300px", padding: "5px", overflow: "hidden" }}>
|
||||||
|
<Typography component="h3" color="primary">
|
||||||
|
{userInfo.name}
|
||||||
|
</Typography>
|
||||||
|
<Grid item>
|
||||||
|
|
||||||
|
<Typography component="h1">
|
||||||
|
{userInfo.statusOnline &&
|
||||||
|
userInfo.statusOnline.status
|
||||||
|
}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography component="h1">
|
||||||
|
Em atendimento: {userInfo.sumOpen && userInfo.sumOpen.count}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography component="h1">
|
||||||
|
Finalizado: {userInfo.sumClosed && userInfo.sumClosed.count}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography component="h1">
|
||||||
|
Tempo online: {userInfo.sumOnlineTime && userInfo.sumOnlineTime.sum}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
|
||||||
|
<div style={{ border: 'dotted', margin: '3px', padding: '2px' }}>
|
||||||
|
|
||||||
|
<div>Em atendimento(open/closed) por fila, conversas iniciadas pelos clientes:</div>
|
||||||
|
|
||||||
|
|
||||||
|
{userInfo.openClosedInQueue &&
|
||||||
|
|
||||||
|
userInfo.openClosedInQueue.map((info, index) => (
|
||||||
|
<>
|
||||||
|
<Typography component="h1" key={index}>
|
||||||
|
{info.name}: OPEN {info.countOpen} | CLOSED {info.countClosed}
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style={{ border: 'dotted', margin: '3px', padding: '2px' }}>
|
||||||
|
|
||||||
|
<div>Em atendimento(open/closed) sem fila, conversas iniciadas por atendentes:</div>
|
||||||
|
|
||||||
|
{userInfo.openClosedOutQueue &&
|
||||||
|
|
||||||
|
<Typography component="h1" key={index}>
|
||||||
|
SEM FILA: OPEN {userInfo.openClosedOutQueue.countOpen} | CLOSED {userInfo.openClosedOutQueue.countClosed}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{userInfo.statusOnline && userInfo.statusOnline.status === "online" &&
|
||||||
|
|
||||||
|
userInfo.statusOnline &&
|
||||||
|
|
||||||
|
<Typography component="h1">
|
||||||
|
|
||||||
|
<Button style={{ display: "block" }}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={(e) => {
|
||||||
|
// handleCSVMessages()
|
||||||
|
handleLogouOnlineUser(userInfo.id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{"Deslogar"}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
|
||||||
|
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Container >
|
||||||
|
</div >
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -417,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()
|
||||||
|
|
||||||
|
@ -538,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}`)))) {
|
||||||
|
|
||||||
|
@ -560,8 +553,6 @@ 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) => {
|
||||||
|
@ -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) => {
|
||||||
|
|
Loading…
Reference in New Issue