diff --git a/backend/src/controllers/TicketController.ts b/backend/src/controllers/TicketController.ts index 0ae36da..ef30029 100644 --- a/backend/src/controllers/TicketController.ts +++ b/backend/src/controllers/TicketController.ts @@ -12,6 +12,7 @@ type IndexQuery = { status: string; date: string; showAll: string; + withUnreadMessages: string; }; interface TicketData { @@ -25,7 +26,8 @@ export const index = async (req: Request, res: Response): Promise => { status, date, searchParam, - showAll + showAll, + withUnreadMessages } = req.query as IndexQuery; const userId = req.user.id; @@ -36,7 +38,8 @@ export const index = async (req: Request, res: Response): Promise => { status, date, showAll, - userId + userId, + withUnreadMessages }); return res.status(200).json({ tickets, count, hasMore }); diff --git a/backend/src/services/TicketServices/ListTicketsService.ts b/backend/src/services/TicketServices/ListTicketsService.ts index 1368b06..e474339 100644 --- a/backend/src/services/TicketServices/ListTicketsService.ts +++ b/backend/src/services/TicketServices/ListTicketsService.ts @@ -12,6 +12,7 @@ interface Request { date?: string; showAll?: string; userId: string; + withUnreadMessages?: string; } interface Response { @@ -26,24 +27,24 @@ const ListTicketsService = async ({ status, date, showAll, - userId + userId, + withUnreadMessages }: Request): Promise => { - let whereCondition: Filterable["where"]; + let whereCondition: Filterable["where"] = { + [Op.or]: [{ userId }, { status: "pending" }] + }; let includeCondition: Includeable[]; includeCondition = [ { model: Contact, as: "contact", - attributes: ["id", "name", "number", "profilePicUrl"], - include: ["extraInfo"] + attributes: ["id", "name", "number", "profilePicUrl"] } ]; if (showAll === "true") { whereCondition = {}; - } else { - whereCondition = { userId }; } if (status) { @@ -102,6 +103,21 @@ const ListTicketsService = async ({ }; } + if (withUnreadMessages === "true") { + includeCondition = [ + ...includeCondition, + { + model: Message, + as: "messages", + attributes: [], + where: { + read: false, + fromMe: false + } + } + ]; + } + const limit = 20; const offset = limit * (+pageNumber - 1); diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index af352f4..8fc37e2 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -167,8 +167,6 @@ const wbotMessageListener = (whatsapp: Whatsapp): void => { const io = getIO(); wbot.on("message_create", async msg => { - console.log(msg.type); - if (!isValidMsg(msg)) { return; } diff --git a/frontend/src/components/NotificationsPopOver/index.js b/frontend/src/components/NotificationsPopOver/index.js index c5e3977..b1ee0d3 100644 --- a/frontend/src/components/NotificationsPopOver/index.js +++ b/frontend/src/components/NotificationsPopOver/index.js @@ -49,7 +49,7 @@ const NotificationsPopOver = () => { const ticketId = +history.location.pathname.split("/")[2]; const anchorEl = useRef(); const [isOpen, setIsOpen] = useState(false); - const [notifications, setNotifications] = useState([]); + // const [notifications, setNotifications] = useState([]); useEffect(() => { if (!("Notification" in window)) { @@ -81,30 +81,7 @@ const NotificationsPopOver = () => { }; }, [history, ticketId, userId]); - const { tickets: openTickets } = useTickets({ status: "open" }); - const { tickets: pendingTickets } = useTickets({ - status: "pending", - showAll: true, - }); - - useEffect(() => { - if (openTickets.length > 0 || pendingTickets.length > 0) { - let aux = []; - - openTickets.forEach(ticket => { - if (ticket.unreadMessages > 0) { - aux.push(ticket); - } - }); - pendingTickets.forEach(ticket => { - if (ticket.unreadMessages > 0) { - aux.push(ticket); - } - }); - - setNotifications(aux); - } - }, [openTickets, pendingTickets]); + const { tickets: notifications } = useTickets({ withUnreadMessages: "true" }); const showDesktopNotification = ({ message, contact, ticket }) => { const options = { @@ -176,6 +153,8 @@ const NotificationsPopOver = () => { No tickets with unread messages. ) : ( + notifications && + notifications.length > 0 && notifications.map(ticket => ( diff --git a/frontend/src/hooks/useTickets/index.js b/frontend/src/hooks/useTickets/index.js index 3c73da2..0090b6b 100644 --- a/frontend/src/hooks/useTickets/index.js +++ b/frontend/src/hooks/useTickets/index.js @@ -24,7 +24,7 @@ const reducer = (state, action) => { } if (action.type === "UPDATE_TICKETS") { - const { ticket, status, loggedUser } = action.payload; + const { ticket, status, loggedUser, withUnreadMessages } = action.payload; const ticketIndex = state.findIndex(t => t.id === ticket.id); if (ticketIndex !== -1) { @@ -41,6 +41,8 @@ const reducer = (state, action) => { ticket.status === "closed") ) { state.unshift(ticket); + } else if (withUnreadMessages) { + state.unshift(ticket); } return [...state]; } @@ -56,11 +58,14 @@ const reducer = (state, action) => { } if (action.type === "RESET_UNREAD") { - const ticketId = action.payload; + const { ticketId, withUnreadMessages } = action.payload; const ticketIndex = state.findIndex(t => t.id === ticketId); if (ticketIndex !== -1) { state[ticketIndex].unreadMessages = 0; + if (withUnreadMessages) { + state.splice(ticketIndex, 1); + } } return [...state]; } @@ -70,7 +75,14 @@ const reducer = (state, action) => { } }; -const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => { +const useTickets = ({ + searchParam, + pageNumber, + status, + date, + showAll, + withUnreadMessages, +}) => { const userId = +localStorage.getItem("userId"); const [loading, setLoading] = useState(true); const [hasMore, setHasMore] = useState(false); @@ -79,7 +91,6 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => { useEffect(() => { setLoading(true); const delayDebounceFn = setTimeout(() => { - console.log(showAll); const fetchTickets = async () => { try { const { data } = await api.get("/tickets", { @@ -89,6 +100,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => { status, date, showAll, + withUnreadMessages, }, }); dispatch({ @@ -107,7 +119,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => { fetchTickets(); }, 500); return () => clearTimeout(delayDebounceFn); - }, [searchParam, pageNumber, status, date, showAll]); + }, [searchParam, pageNumber, status, date, showAll, withUnreadMessages]); useEffect(() => { const socket = openSocket(process.env.REACT_APP_BACKEND_URL); @@ -115,7 +127,13 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => { socket.on("ticket", data => { if (data.action === "updateUnread") { - dispatch({ type: "RESET_UNREAD", payload: data.ticketId }); + dispatch({ + type: "RESET_UNREAD", + payload: { + ticketId: data.ticketId, + withUnreadMessages: withUnreadMessages, + }, + }); } if (data.action === "updateStatus" || data.action === "create") { @@ -141,6 +159,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => { payload: { ticket: data.ticket, status: status, + withUnreadMessages: withUnreadMessages, loggedUser: userId, }, }); @@ -150,7 +169,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => { return () => { socket.disconnect(); }; - }, [status, userId]); + }, [status, withUnreadMessages, userId]); return { loading, tickets, hasMore, dispatch }; };