projeto-hit/frontend/src/pages/Queues/index.js

355 lines
10 KiB
JavaScript
Raw Normal View History

2023-07-20 15:30:26 +00:00
import React, { useEffect, useReducer, useState, useContext } from 'react'
2023-07-20 15:30:26 +00:00
import openSocket from 'socket.io-client'
import {
Button,
IconButton,
makeStyles,
Paper,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Typography,
2023-07-20 15:30:26 +00:00
} from '@material-ui/core'
import MainContainer from '../../components/MainContainer'
import MainHeader from '../../components/MainHeader'
import MainHeaderButtonsWrapper from '../../components/MainHeaderButtonsWrapper'
import TableRowSkeleton from '../../components/TableRowSkeleton'
import Title from '../../components/Title'
import { i18n } from '../../translate/i18n'
import toastError from '../../errors/toastError'
import api from '../../services/api'
import { DeleteOutline, Edit } from '@material-ui/icons'
import QueueModal from '../../components/QueueModal'
import { toast } from 'react-toastify'
import ConfirmationModal from '../../components/ConfirmationModal'
import { AuthContext } from '../../context/Auth/AuthContext'
import { Can } from '../../components/Can'
const useStyles = makeStyles((theme) => ({
mainPaper: {
flex: 1,
padding: theme.spacing(1),
2023-07-20 15:30:26 +00:00
overflowY: 'scroll',
...theme.scrollbarStyles,
},
customTableCell: {
2023-07-20 15:30:26 +00:00
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
2023-07-20 15:30:26 +00:00
}))
const reducer = (state, action) => {
2023-07-20 15:30:26 +00:00
if (action.type === 'LOAD_QUEUES') {
const queues = action.payload
const newQueues = []
queues.forEach((queue) => {
2023-07-20 15:30:26 +00:00
const queueIndex = state.findIndex((q) => q.id === queue.id)
if (queueIndex !== -1) {
2023-07-20 15:30:26 +00:00
state[queueIndex] = queue
} else {
2023-07-20 15:30:26 +00:00
newQueues.push(queue)
}
2023-07-20 15:30:26 +00:00
})
2023-07-20 15:30:26 +00:00
return [...state, ...newQueues]
}
2023-07-20 15:30:26 +00:00
if (action.type === 'UPDATE_QUEUES') {
const queue = action.payload
const queueIndex = state.findIndex((u) => u.id === queue.id)
if (queueIndex !== -1) {
2023-07-20 15:30:26 +00:00
state[queueIndex] = queue
return [...state]
} else {
2023-07-20 15:30:26 +00:00
return [queue, ...state]
}
}
2023-07-20 15:30:26 +00:00
if (action.type === 'DELETE_QUEUE') {
const queueId = action.payload
const queueIndex = state.findIndex((q) => q.id === queueId)
if (queueIndex !== -1) {
2023-07-20 15:30:26 +00:00
state.splice(queueIndex, 1)
}
2023-07-20 15:30:26 +00:00
return [...state]
}
2023-07-20 15:30:26 +00:00
if (action.type === 'RESET') {
return []
}
2023-07-20 15:30:26 +00:00
}
const Queues = () => {
2023-07-20 15:30:26 +00:00
const classes = useStyles()
2023-07-20 15:30:26 +00:00
const { user } = useContext(AuthContext)
2023-07-20 15:30:26 +00:00
const [queues, dispatch] = useReducer(reducer, [])
const [loading, setLoading] = useState(false)
2023-07-20 15:30:26 +00:00
const [queueModalOpen, setQueueModalOpen] = useState(false)
const [selectedQueue, setSelectedQueue] = useState(null)
const [confirmModalOpen, setConfirmModalOpen] = useState(false)
const [settings, setSettings] = useState([])
useEffect(() => {
2023-07-20 15:30:26 +00:00
;(async () => {
setLoading(true)
try {
2023-07-20 15:30:26 +00:00
const { data } = await api.get('/queue')
dispatch({ type: 'LOAD_QUEUES', payload: data })
2023-07-20 15:30:26 +00:00
setLoading(false)
} catch (err) {
2023-07-20 15:30:26 +00:00
toastError(err)
setLoading(false)
}
2023-07-20 15:30:26 +00:00
})()
}, [])
useEffect(() => {
2023-07-20 15:30:26 +00:00
const fetchSession = async () => {
try {
const { data } = await api.get('/settings')
setSettings(data)
} catch (err) {
toastError(err)
}
}
fetchSession()
}, [])
const getSettingValue = (key) => {
const { value } = settings.find((s) => s.key === key)
return value
}
2023-07-20 15:30:26 +00:00
useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
socket.on('queue', (data) => {
if (data.action === 'update' || data.action === 'create') {
dispatch({ type: 'UPDATE_QUEUES', payload: data.queue })
}
2023-07-20 15:30:26 +00:00
if (data.action === 'delete') {
dispatch({ type: 'DELETE_QUEUE', payload: data.queueId })
}
2023-07-20 15:30:26 +00:00
})
socket.on('settings', (data) => {
if (data.action === 'update') {
setSettings((prevState) => {
const aux = [...prevState]
const settingIndex = aux.findIndex((s) => s.key === data.setting.key)
aux[settingIndex].value = data.setting.value
return aux
})
}
})
return () => {
2023-07-20 15:30:26 +00:00
socket.disconnect()
}
}, [])
const handleOpenQueueModal = () => {
2023-07-20 15:30:26 +00:00
setQueueModalOpen(true)
setSelectedQueue(null)
}
const handleCloseQueueModal = () => {
2023-07-20 15:30:26 +00:00
setQueueModalOpen(false)
setSelectedQueue(null)
}
const handleEditQueue = (queue) => {
2023-07-20 15:30:26 +00:00
setSelectedQueue(queue)
setQueueModalOpen(true)
}
const handleCloseConfirmationModal = () => {
2023-07-20 15:30:26 +00:00
setConfirmModalOpen(false)
setSelectedQueue(null)
}
const handleDeleteQueue = async (queueId) => {
try {
2023-07-20 15:30:26 +00:00
await api.delete(`/queue/${queueId}`)
toast.success(i18n.t('Queue deleted successfully!'))
} catch (err) {
2023-07-20 15:30:26 +00:00
toastError(err)
}
2023-07-20 15:30:26 +00:00
setSelectedQueue(null)
}
return (
<Can
role={user.profile}
perform="queues-view:show"
yes={() => (
<MainContainer>
<ConfirmationModal
title={
selectedQueue &&
2023-07-20 15:30:26 +00:00
`${i18n.t('queues.confirmationModal.deleteTitle')} ${
selectedQueue.name
}?`
}
open={confirmModalOpen}
onClose={handleCloseConfirmationModal}
onConfirm={() => handleDeleteQueue(selectedQueue.id)}
>
2023-07-20 15:30:26 +00:00
{i18n.t('queues.confirmationModal.deleteMessage')}
</ConfirmationModal>
<QueueModal
open={queueModalOpen}
onClose={handleCloseQueueModal}
queueId={selectedQueue?.id}
/>
<MainHeader>
2023-07-20 15:30:26 +00:00
<Title>{i18n.t('queues.title')}</Title>
<Can
role={user.profile}
perform="show-icon-add-queue"
yes={() => (
<MainHeaderButtonsWrapper>
<Button
variant="contained"
color="primary"
onClick={handleOpenQueueModal}
>
2023-07-20 15:30:26 +00:00
{i18n.t('queues.buttons.add')}
</Button>
</MainHeaderButtonsWrapper>
)}
/>
</MainHeader>
<Paper className={classes.mainPaper} variant="outlined">
<Table size="small">
<TableHead>
<TableRow>
<TableCell align="center">
2023-07-20 15:30:26 +00:00
{i18n.t('queues.table.name')}
</TableCell>
<TableCell align="center">
2023-07-20 15:30:26 +00:00
{i18n.t('queues.table.color')}
</TableCell>
<TableCell align="center">
2023-07-20 15:30:26 +00:00
{i18n.t('queues.table.greeting')}
</TableCell>
<TableCell align="center">
2023-07-20 15:30:26 +00:00
{i18n.t('queues.table.actions')}
</TableCell>
</TableRow>
</TableHead>
<TableBody>
<>
{queues.map((queue) => (
<TableRow key={queue.id}>
<TableCell align="center">{queue.name}</TableCell>
<TableCell align="center">
<div className={classes.customTableCell}>
<span
style={{
backgroundColor: queue.color,
width: 60,
height: 20,
2023-07-20 15:30:26 +00:00
alignSelf: 'center',
}}
/>
</div>
</TableCell>
<TableCell align="center">
<div className={classes.customTableCell}>
<Typography
2023-07-20 15:30:26 +00:00
style={{ width: 300, align: 'center' }}
noWrap
variant="body2"
>
{queue.greetingMessage}
</Typography>
</div>
</TableCell>
<TableCell align="center">
<Can
role={user.profile}
perform="show-icon-edit-queue"
yes={() => (
2023-07-20 15:30:26 +00:00
<div
style={{
margin: 0,
padding: 0,
border: 'none',
display: 'inline',
}}
>
2023-07-20 15:30:26 +00:00
{(settings &&
settings.length > 0 &&
getSettingValue('editQueue') &&
getSettingValue('editQueue') === 'enabled') |
(user.profile === 'master') ? (
<IconButton
size="small"
onClick={() => handleEditQueue(queue)}
>
<Edit />
</IconButton>
) : (
<div></div>
)}
</div>
// <IconButton
// size="small"
// onClick={() => handleEditQueue(queue)}
// >
// <Edit />
// </IconButton>
)}
/>
<Can
role={user.profile}
perform="show-icon-delete-queue"
yes={() => (
<IconButton
size="small"
onClick={() => {
2023-07-20 15:30:26 +00:00
setSelectedQueue(queue)
setConfirmModalOpen(true)
}}
>
<DeleteOutline />
</IconButton>
)}
/>
</TableCell>
</TableRow>
))}
{loading && <TableRowSkeleton columns={4} />}
</>
</TableBody>
</Table>
</Paper>
</MainContainer>
)}
/>
2023-07-20 15:30:26 +00:00
)
}
2023-07-20 15:30:26 +00:00
export default Queues