Feat: Added 'New ticket" option on ticket list

This commit is contained in:
canove
2020-07-28 08:38:22 -03:00
parent 725adfaf6a
commit 915ee712dc
3 changed files with 92 additions and 81 deletions

View File

@@ -48,8 +48,18 @@ exports.index = async (req, res) => {
}; };
exports.store = async (req, res) => { exports.store = async (req, res) => {
const io = getIO();
const ticket = await Ticket.create(req.body); const ticket = await Ticket.create(req.body);
const contact = await ticket.getContact();
const serializaedTicket = { ...ticket.dataValues, contact: contact };
io.to("notification").emit("ticket", {
action: "create",
ticket: serializaedTicket,
});
res.status(200).json(ticket); res.status(200).json(ticket);
}; };

View File

@@ -7,11 +7,9 @@ import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions"; import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent"; import DialogContent from "@material-ui/core/DialogContent";
import DialogTitle from "@material-ui/core/DialogTitle"; import DialogTitle from "@material-ui/core/DialogTitle";
import Typography from "@material-ui/core/Typography";
import IconButton from "@material-ui/core/IconButton";
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
import Autocomplete from "@material-ui/lab/Autocomplete"; import Autocomplete from "@material-ui/lab/Autocomplete";
import CircularProgress from "@material-ui/core/CircularProgress"; import CircularProgress from "@material-ui/core/CircularProgress";
import FormControl from "@material-ui/core/FormControl";
import { green } from "@material-ui/core/colors"; import { green } from "@material-ui/core/colors";
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
@@ -23,18 +21,6 @@ const useStyles = makeStyles(theme => ({
display: "flex", display: "flex",
flexWrap: "wrap", flexWrap: "wrap",
}, },
textField: {
// marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
// width: "25ch",
flex: 1,
},
extraAttr: {
display: "flex",
justifyContent: "center",
alignItems: "center",
},
btnWrapper: { btnWrapper: {
// margin: theme.spacing(1), // margin: theme.spacing(1),
@@ -53,11 +39,14 @@ const useStyles = makeStyles(theme => ({
const NewTicketModal = ({ modalOpen, onClose, contactId }) => { const NewTicketModal = ({ modalOpen, onClose, contactId }) => {
const classes = useStyles(); const classes = useStyles();
const userId = +localStorage.getItem("userId");
const [options, setOptions] = React.useState([]); const [options, setOptions] = useState([]);
const [loading, setLoading] = React.useState(false); const [loading, setLoading] = useState(false);
const [selectedContact, setSelectedContact] = useState(null);
useEffect(() => { useEffect(() => {
setLoading(true);
const fetchContacts = async () => { const fetchContacts = async () => {
try { try {
const res = await api.get("contacts"); const res = await api.get("contacts");
@@ -68,21 +57,29 @@ const NewTicketModal = ({ modalOpen, onClose, contactId }) => {
}; };
fetchContacts(); fetchContacts();
setLoading(false);
}, []); }, []);
const handleClose = () => { const handleClose = () => {
onClose(); onClose();
// setTicket(initialState); setSelectedContact(null);
}; };
const handleSaveTicket = async selected => { const handleSaveTicket = async e => {
console.log(selected.id); e.preventDefault();
if (!selectedContact) return;
setLoading(true);
try { try {
await api.post("/tickets", { contactId: selected.id }); await api.post("/tickets", {
contactId: selectedContact.id,
userId: userId,
status: "open",
});
} catch (err) { } catch (err) {
alert(err); alert(err);
} }
// handleClose(); setLoading(false);
handleClose();
}; };
return ( return (
@@ -92,61 +89,67 @@ const NewTicketModal = ({ modalOpen, onClose, contactId }) => {
onClose={handleClose} onClose={handleClose}
maxWidth="lg" maxWidth="lg"
scroll="paper" scroll="paper"
className={classes.modal}
> >
<DialogTitle id="form-dialog-title">Criar Ticket</DialogTitle> <form onSubmit={handleSaveTicket}>
<DialogContent dividers> <DialogTitle id="form-dialog-title">Criar Ticket</DialogTitle>
<Autocomplete <DialogContent dividers>
id="asynchronous-demo" <Autocomplete
style={{ width: 300 }} id="asynchronous-demo"
getOptionLabel={option => option.name} style={{ width: 300 }}
onChange={(e, newValue) => { getOptionLabel={option => option.name}
handleSaveTicket(newValue); onChange={(e, newValue) => {
}} setSelectedContact(newValue);
options={options} }}
loading={loading} options={options}
renderInput={params => ( loading={loading}
<TextField renderInput={params => (
{...params} <TextField
label="Selecione o contato" {...params}
variant="outlined" label="Selecione o contato"
InputProps={{ variant="outlined"
...params.InputProps, required
endAdornment: ( id="my-input"
<React.Fragment> InputProps={{
{loading ? ( ...params.InputProps,
<CircularProgress color="inherit" size={20} /> endAdornment: (
) : null} <React.Fragment>
{params.InputProps.endAdornment} {loading ? (
</React.Fragment> <CircularProgress color="inherit" size={20} />
), ) : null}
}} {params.InputProps.endAdornment}
/> </React.Fragment>
)} ),
/> }}
</DialogContent> />
<DialogActions> )}
<Button />
onClick={handleClose} </DialogContent>
color="secondary" <DialogActions>
// disabled={isSubmitting} <Button
variant="outlined" onClick={handleClose}
> color="secondary"
Cancelar disabled={loading}
</Button> variant="outlined"
<Button >
onClick={handleSaveTicket} Cancelar
color="primary" </Button>
// disabled={isSubmitting} <Button
variant="contained" type="submit"
className={classes.btnWrapper} color="primary"
> disabled={loading}
Salvar variant="contained"
{loading && ( className={classes.btnWrapper}
<CircularProgress size={24} className={classes.buttonProgress} /> >
)} Salvar
</Button> {loading && (
</DialogActions> <CircularProgress
size={24}
className={classes.buttonProgress}
/>
)}
</Button>
</DialogActions>
</form>
</Dialog> </Dialog>
</div> </div>
); );

View File

@@ -250,8 +250,8 @@ const TicketsList = () => {
if (data.action === "updateUnread") { if (data.action === "updateUnread") {
resetUnreadMessages(data.ticketId); resetUnreadMessages(data.ticketId);
} }
if (data.action === "updateStatus") { if (data.action === "updateStatus" || data.action === "create") {
updateTicketStatus(data); updateTickets(data);
} }
}); });
@@ -293,7 +293,7 @@ const TicketsList = () => {
}); });
}; };
const updateTicketStatus = data => { const updateTickets = data => {
setTickets(prevState => { setTickets(prevState => {
const ticketIndex = prevState.findIndex( const ticketIndex = prevState.findIndex(
ticket => ticket.id === data.ticket.id ticket => ticket.id === data.ticket.id
@@ -358,8 +358,6 @@ const TicketsList = () => {
history.push(`/chat/${ticketId}`); history.push(`/chat/${ticketId}`);
}; };
const handleOpenNewTicketModal = () => {};
const countTickets = (status, userId) => { const countTickets = (status, userId) => {
const ticketsFound = tickets.filter( const ticketsFound = tickets.filter(
t => t.status === status && t.userId === userId t => t.status === status && t.userId === userId