feat: added delete tickets option

This commit is contained in:
canove
2020-07-30 19:48:45 -03:00
parent 14fed6c4a0
commit 362c4c183c
5 changed files with 165 additions and 40 deletions

View File

@@ -120,3 +120,23 @@ exports.update = async (req, res) => {
res.status(200).json(ticket); res.status(200).json(ticket);
}; };
exports.delete = async (req, res) => {
const io = getIO();
const { ticketId } = req.params;
const ticket = await Ticket.findByPk(ticketId);
if (!ticket) {
return res.status(400).json({ error: "No ticket found with this ID" });
}
await ticket.destroy();
io.to("notification").emit("ticket", {
action: "delete",
ticketId: ticket.id,
});
res.status(200).json({ message: "ticket deleted" });
};

View File

@@ -11,4 +11,6 @@ routes.post("/tickets", isAuth, TicketController.store);
routes.put("/tickets/:ticketId", isAuth, TicketController.update); routes.put("/tickets/:ticketId", isAuth, TicketController.update);
routes.delete("/tickets/:ticketId", isAuth, TicketController.delete);
module.exports = routes; module.exports = routes;

View File

@@ -0,0 +1,73 @@
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import { toast } from "react-toastify";
import MenuItem from "@material-ui/core/MenuItem";
import Menu from "@material-ui/core/Menu";
import api from "../../services/api";
import ConfirmationModal from "../ConfirmationModal";
const TicketOptionsMenu = ({ ticket, menuOpen, handleClose, anchorEl }) => {
const history = useHistory();
const [confirmationOpen, setConfirmationOpen] = useState(false);
const handleDeleteTicket = async () => {
try {
await api.delete(`/tickets/${ticket.id}`);
toast.success("Ticket deletado com sucesso.");
history.push("/chat");
} catch (err) {
toast.error("Erro ao deletar o ticket");
}
console.log("deleted");
handleClose();
};
const handleTransferTicket = e => {
console.log("transfered");
handleClose();
};
const handleOpenConfirmationModal = e => {
setConfirmationOpen(true);
handleClose();
};
console.log(ticket);
return (
<>
<Menu
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
open={menuOpen}
onClose={handleClose}
>
<MenuItem onClick={handleOpenConfirmationModal}>Deletar</MenuItem>
<MenuItem onClick={handleTransferTicket}>Transferir</MenuItem>
</Menu>
<ConfirmationModal
title={`Deletar o ticket #${ticket.id} do contato ${ticket.contact.name}?`}
open={confirmationOpen}
setOpen={setConfirmationOpen}
onConfirm={handleDeleteTicket}
>
Atenção, todas as mensagens relacionadas a este ticket serão apagadas.
</ConfirmationModal>
</>
);
};
export default TicketOptionsMenu;

View File

@@ -20,12 +20,15 @@ import Button from "@material-ui/core/Button";
import Paper from "@material-ui/core/Paper"; import Paper from "@material-ui/core/Paper";
import { green } from "@material-ui/core/colors"; import { green } from "@material-ui/core/colors";
import Skeleton from "@material-ui/lab/Skeleton"; import Skeleton from "@material-ui/lab/Skeleton";
import IconButton from "@material-ui/core/IconButton";
import MoreVertIcon from "@material-ui/icons/MoreVert";
import api from "../../services/api"; import api from "../../services/api";
import ContactDrawer from "../ContactDrawer"; import ContactDrawer from "../ContactDrawer";
import whatsBackground from "../../assets/wa-background.png"; import whatsBackground from "../../assets/wa-background.png";
import LinkifyWithTargetBlank from "../LinkifyWithTargetBlank"; import LinkifyWithTargetBlank from "../LinkifyWithTargetBlank";
import MessageInput from "../MessageInput/"; import MessageInput from "../MessageInput/";
import TicketOptionsMenu from "./TicketOptionsMenu";
const drawerWidth = 320; const drawerWidth = 320;
@@ -65,7 +68,7 @@ const useStyles = makeStyles(theme => ({
messagesHeader: { messagesHeader: {
display: "flex", display: "flex",
cursor: "pointer", // cursor: "pointer",
backgroundColor: "#eee", backgroundColor: "#eee",
flex: "none", flex: "none",
borderBottom: "1px solid rgba(0, 0, 0, 0.12)", borderBottom: "1px solid rgba(0, 0, 0, 0.12)",
@@ -233,6 +236,9 @@ const MessagesList = () => {
const [drawerOpen, setDrawerOpen] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false);
const lastMessageRef = useRef(); const lastMessageRef = useRef();
const [anchorEl, setAnchorEl] = useState(null);
const moreMenuOpen = Boolean(anchorEl);
useEffect(() => { useEffect(() => {
setMessagesList([]); setMessagesList([]);
}, [searchParam]); }, [searchParam]);
@@ -366,9 +372,15 @@ const MessagesList = () => {
} }
}; };
const handleOpenTicketOptionsMenu = e => {
setAnchorEl(e.currentTarget);
};
const handleCloseTicketOptionsMenu = e => {
setAnchorEl(null);
};
const handleUpdateTicketStatus = async (e, status, userId) => { const handleUpdateTicketStatus = async (e, status, userId) => {
e.preventDefault();
e.stopPropagation();
try { try {
await api.put(`/tickets/${ticketId}`, { await api.put(`/tickets/${ticketId}`, {
status: status, status: status,
@@ -380,6 +392,14 @@ const MessagesList = () => {
history.push("/chat"); history.push("/chat");
}; };
const handleDrawerOpen = () => {
setDrawerOpen(true);
};
const handleDrawerClose = () => {
setDrawerOpen(false);
};
const renderMessageAck = message => { const renderMessageAck = message => {
if (message.ack === 0) { if (message.ack === 0) {
return <AccessTimeIcon fontSize="small" className={classes.ackIcons} />; return <AccessTimeIcon fontSize="small" className={classes.ackIcons} />;
@@ -480,13 +500,6 @@ const MessagesList = () => {
} }
}; };
const handleDrawerOpen = () => {
setDrawerOpen(true);
};
const handleDrawerClose = () => {
setDrawerOpen(false);
};
return ( return (
<div className={classes.root} id="drawer-container"> <div className={classes.root} id="drawer-container">
<Paper <Paper
@@ -496,12 +509,10 @@ const MessagesList = () => {
[classes.mainWrapperShift]: drawerOpen, [classes.mainWrapperShift]: drawerOpen,
})} })}
> >
<Card <Card square className={classes.messagesHeader}>
square
className={classes.messagesHeader}
onClick={handleDrawerOpen}
>
<CardHeader <CardHeader
onClick={handleDrawerOpen}
style={{ cursor: "pointer" }}
titleTypographyProps={{ noWrap: true }} titleTypographyProps={{ noWrap: true }}
subheaderTypographyProps={{ noWrap: true }} subheaderTypographyProps={{ noWrap: true }}
avatar={ avatar={
@@ -557,6 +568,15 @@ const MessagesList = () => {
</Button> </Button>
</> </>
)} )}
<IconButton onClick={handleOpenTicketOptionsMenu}>
<MoreVertIcon />
</IconButton>
<TicketOptionsMenu
ticket={ticket}
anchorEl={anchorEl}
menuOpen={moreMenuOpen}
handleClose={handleCloseTicketOptionsMenu}
/>
</div> </div>
)} )}
</Card> </Card>

View File

@@ -251,11 +251,14 @@ const TicketsList = () => {
socket.on("ticket", data => { socket.on("ticket", data => {
if (data.action === "updateUnread") { if (data.action === "updateUnread") {
resetUnreadMessages(data.ticketId); resetUnreadMessages(data);
} }
if (data.action === "updateStatus" || data.action === "create") { if (data.action === "updateStatus" || data.action === "create") {
updateTickets(data); updateTickets(data);
} }
if (data.action === "delete") {
deleteTicket(data);
}
}); });
socket.on("appMessage", data => { socket.on("appMessage", data => {
@@ -277,57 +280,64 @@ const TicketsList = () => {
}; };
}, [ticketId, userId]); }, [ticketId, userId]);
const updateUnreadMessagesCount = data => { const updateUnreadMessagesCount = ({ message, ticket }) => {
setTickets(prevState => { setTickets(prevState => {
const ticketIndex = prevState.findIndex( const ticketIndex = prevState.findIndex(t => t.id === message.ticketId);
ticket => ticket.id === data.message.ticketId
);
if (ticketIndex !== -1) { if (ticketIndex !== -1) {
let aux = [...prevState]; let aux = [...prevState];
if (!data.message.fromMe) { if (!message.fromMe) {
aux[ticketIndex].unreadMessages++; aux[ticketIndex].unreadMessages++;
} }
aux[ticketIndex].lastMessage = data.message.body; aux[ticketIndex].lastMessage = message.body;
aux[ticketIndex].status = data.ticket.status; aux[ticketIndex].status = ticket.status;
aux.unshift(aux.splice(ticketIndex, 1)[0]); aux.unshift(aux.splice(ticketIndex, 1)[0]);
return aux; return aux;
} else { } else {
return [data.ticket, ...prevState]; return [ticket, ...prevState];
} }
}); });
}; };
const updateTickets = data => { const updateTickets = ({ ticket }) => {
setTickets(prevState => { setTickets(prevState => {
const ticketIndex = prevState.findIndex( const ticketIndex = prevState.findIndex(t => t.id === ticket.id);
ticket => ticket.id === data.ticket.id
);
if (ticketIndex === -1) { if (ticketIndex === -1) {
return [data.ticket, ...prevState]; return [ticket, ...prevState];
} else { } else {
let aux = [...prevState]; let aux = [...prevState];
aux[ticketIndex] = data.ticket; aux[ticketIndex] = ticket;
return aux; return aux;
} }
}); });
}; };
const showDesktopNotification = data => { const deleteTicket = ({ ticketId }) => {
setTickets(prevState => {
const ticketIndex = prevState.findIndex(ticket => ticket.id === ticketId);
if (ticketIndex === -1) {
return prevState;
} else {
let aux = [...prevState];
aux.splice(ticketIndex, 1);
return aux;
}
});
};
const showDesktopNotification = ({ message, contact, ticket }) => {
const options = { const options = {
body: `${data.message.body} - ${format(new Date(), "HH:mm")}`, body: `${message.body} - ${format(new Date(), "HH:mm")}`,
icon: data.contact.profilePicUrl, icon: contact.profilePicUrl,
tag: data.ticket.id, tag: ticket.id,
}; };
let notification = new Notification( let notification = new Notification(`Mensagem de ${contact.name}`, options);
`Mensagem de ${data.contact.name}`,
options
);
notification.onclick = function (event) { notification.onclick = function (event) {
event.preventDefault(); // event.preventDefault(); //
window.open(`/chat/${data.ticket.id}`, "_self"); window.open(`/chat/${ticket.id}`, "_self");
}; };
document.addEventListener("visibilitychange", () => { document.addEventListener("visibilitychange", () => {
@@ -339,7 +349,7 @@ const TicketsList = () => {
document.getElementById("sound").play(); document.getElementById("sound").play();
}; };
const resetUnreadMessages = ticketId => { const resetUnreadMessages = ({ ticketId }) => {
setTickets(prevState => { setTickets(prevState => {
const ticketIndex = prevState.findIndex( const ticketIndex = prevState.findIndex(
ticket => ticket.id === +ticketId ticket => ticket.id === +ticketId