customização para editar ura e filas
parent
92f7d8b4db
commit
21ce9e1825
|
@ -7,9 +7,9 @@ import UpdateSettingService from "../services/SettingServices/UpdateSettingServi
|
||||||
import ListSettingsService from "../services/SettingServices/ListSettingsService";
|
import ListSettingsService from "../services/SettingServices/ListSettingsService";
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
if (req.user.profile !== "master") {
|
// if (req.user.profile !== "master") {
|
||||||
throw new AppError("ERR_NO_PERMISSION", 403);
|
// throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
}
|
// }
|
||||||
|
|
||||||
const settings = await ListSettingsService();
|
const settings = await ListSettingsService();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "editURA",
|
||||||
|
value: "enabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "editQueue",
|
||||||
|
value: "enabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -5,9 +5,7 @@ import * as SettingController from "../controllers/SettingController";
|
||||||
|
|
||||||
const settingRoutes = Router();
|
const settingRoutes = Router();
|
||||||
|
|
||||||
|
settingRoutes.get("/settings", SettingController.index);
|
||||||
|
|
||||||
settingRoutes.get("/settings", isAuth, SettingController.index);
|
|
||||||
|
|
||||||
// routes.get("/settings/:settingKey", isAuth, SettingsController.show);
|
// routes.get("/settings/:settingKey", isAuth, SettingsController.show);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
import StatusChatEnd from "../../models/StatusChatEnd";
|
import StatusChatEnd from "../../models/StatusChatEnd";
|
||||||
import AppError from "../../errors/AppError";
|
import AppError from "../../errors/AppError";
|
||||||
|
|
||||||
const ShowStatusChatEndService = async (id: string | number): Promise<StatusChatEnd> => {
|
const ShowStatusChatEndService = async (
|
||||||
const status = await StatusChatEnd.findByPk(id, { attributes: ['id', 'name'], });
|
id: string | number
|
||||||
|
): Promise<StatusChatEnd> => {
|
||||||
|
const status = await StatusChatEnd.findByPk(id, {
|
||||||
|
attributes: ["id", "name"]
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`---------------> statusChatEnd id: ${id}`);
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
throw new AppError("ERR_NO_STATUS_FOUND", 404);
|
throw new AppError("ERR_NO_STATUS_FOUND", 404);
|
||||||
|
|
|
@ -1,57 +1,54 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from 'react'
|
||||||
import Routes from "./routes";
|
import Routes from './routes'
|
||||||
import "react-toastify/dist/ReactToastify.css";
|
import 'react-toastify/dist/ReactToastify.css'
|
||||||
|
|
||||||
import { createTheme, ThemeProvider } from "@material-ui/core/styles";
|
import { createTheme, ThemeProvider } from '@material-ui/core/styles'
|
||||||
import { ptBR } from "@material-ui/core/locale";
|
import { ptBR } from '@material-ui/core/locale'
|
||||||
|
|
||||||
import { TabTicketProvider } from "../src/context/TabTicketHeaderOption/TabTicketHeaderOption";
|
import { TabTicketProvider } from '../src/context/TabTicketHeaderOption/TabTicketHeaderOption'
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [locale, setLocale] = useState();
|
const [locale, setLocale] = useState()
|
||||||
|
|
||||||
const theme = createTheme(
|
const theme = createTheme(
|
||||||
{
|
{
|
||||||
scrollbarStyles: {
|
scrollbarStyles: {
|
||||||
"&::-webkit-scrollbar": {
|
'&::-webkit-scrollbar': {
|
||||||
width: "8px",
|
width: '8px',
|
||||||
height: "8px",
|
height: '8px',
|
||||||
},
|
},
|
||||||
"&::-webkit-scrollbar-thumb": {
|
'&::-webkit-scrollbar-thumb': {
|
||||||
boxShadow: "inset 0 0 6px rgba(0, 0, 0, 0.3)",
|
boxShadow: 'inset 0 0 6px rgba(0, 0, 0, 0.3)',
|
||||||
|
|
||||||
backgroundColor: "#e8e8e8",
|
backgroundColor: '#e8e8e8',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
palette: {
|
palette: {
|
||||||
//primary: { main: "#2576d2" },
|
//primary: { main: "#2576d2" },
|
||||||
primary: { main: "#ec5114" },
|
primary: { main: '#ec5114' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
locale
|
locale
|
||||||
);
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const i18nlocale = localStorage.getItem("i18nextLng");
|
const i18nlocale = localStorage.getItem('i18nextLng')
|
||||||
const browserLocale =
|
const browserLocale =
|
||||||
i18nlocale.substring(0, 2) + i18nlocale.substring(3, 5);
|
i18nlocale.substring(0, 2) + i18nlocale.substring(3, 5)
|
||||||
|
|
||||||
if (browserLocale === "ptBR") {
|
if (browserLocale === 'ptBR') {
|
||||||
setLocale(ptBR);
|
setLocale(ptBR)
|
||||||
}
|
}
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={theme}>
|
||||||
|
|
||||||
{/*TabTicketProvider Context to manipulate the entire state of selected option from user click on tickets options header */}
|
{/*TabTicketProvider Context to manipulate the entire state of selected option from user click on tickets options header */}
|
||||||
<TabTicketProvider>
|
<TabTicketProvider>
|
||||||
<Routes />
|
<Routes />
|
||||||
</TabTicketProvider>
|
</TabTicketProvider>
|
||||||
|
|
||||||
|
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
export default App;
|
export default App
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useContext } from 'react'
|
||||||
import * as Yup from "yup";
|
import * as Yup from 'yup'
|
||||||
import { Formik, Form, Field } from "formik";
|
import { Formik, Form, Field } from 'formik'
|
||||||
import { toast } from "react-toastify";
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import { green } from "@material-ui/core/colors";
|
import { green } from '@material-ui/core/colors'
|
||||||
|
|
||||||
|
import { AuthContext } from '../../context/Auth/AuthContext'
|
||||||
|
import { Can } from '../../components/Can'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
|
@ -16,114 +19,119 @@ import {
|
||||||
TextField,
|
TextField,
|
||||||
Switch,
|
Switch,
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
} from "@material-ui/core";
|
} from '@material-ui/core'
|
||||||
|
|
||||||
import api from "../../services/api";
|
import api from '../../services/api'
|
||||||
import { i18n } from "../../translate/i18n";
|
import { i18n } from '../../translate/i18n'
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from '../../errors/toastError'
|
||||||
import QueueSelect from "../QueueSelect";
|
import QueueSelect from '../QueueSelect'
|
||||||
|
|
||||||
const useStyles = makeStyles(theme => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
root: {
|
root: {
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
flexWrap: "wrap",
|
flexWrap: 'wrap',
|
||||||
},
|
},
|
||||||
|
|
||||||
multFieldLine: {
|
multFieldLine: {
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
"& > *:not(:last-child)": {
|
'& > *:not(:last-child)': {
|
||||||
marginRight: theme.spacing(1),
|
marginRight: theme.spacing(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
btnWrapper: {
|
btnWrapper: {
|
||||||
position: "relative",
|
position: 'relative',
|
||||||
},
|
},
|
||||||
|
|
||||||
buttonProgress: {
|
buttonProgress: {
|
||||||
color: green[500],
|
color: green[500],
|
||||||
position: "absolute",
|
position: 'absolute',
|
||||||
top: "50%",
|
top: '50%',
|
||||||
left: "50%",
|
left: '50%',
|
||||||
marginTop: -12,
|
marginTop: -12,
|
||||||
marginLeft: -12,
|
marginLeft: -12,
|
||||||
},
|
},
|
||||||
}));
|
}))
|
||||||
|
|
||||||
const SessionSchema = Yup.object().shape({
|
const SessionSchema = Yup.object().shape({
|
||||||
name: Yup.string()
|
name: Yup.string()
|
||||||
.min(2, "Too Short!")
|
.min(2, 'Too Short!')
|
||||||
.max(100, "Too Long!")
|
.max(100, 'Too Long!')
|
||||||
.required("Required"),
|
.required('Required'),
|
||||||
});
|
})
|
||||||
|
|
||||||
const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles()
|
||||||
const initialState = {
|
const initialState = {
|
||||||
name: "",
|
name: '',
|
||||||
urlApi: "",
|
urlApi: '',
|
||||||
url: "",
|
url: '',
|
||||||
greetingMessage: "",
|
greetingMessage: '',
|
||||||
farewellMessage: "",
|
farewellMessage: '',
|
||||||
isDefault: false,
|
isDefault: false,
|
||||||
};
|
}
|
||||||
const [whatsApp, setWhatsApp] = useState(initialState);
|
|
||||||
const [selectedQueueIds, setSelectedQueueIds] = useState([]);
|
const { user } = useContext(AuthContext)
|
||||||
|
|
||||||
|
const [whatsApp, setWhatsApp] = useState(initialState)
|
||||||
|
const [selectedQueueIds, setSelectedQueueIds] = useState([])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchSession = async () => {
|
const fetchSession = async () => {
|
||||||
if (!whatsAppId) return;
|
if (!whatsAppId) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get(`whatsapp/${whatsAppId}`);
|
const { data } = await api.get(`whatsapp/${whatsAppId}`)
|
||||||
setWhatsApp(data);
|
setWhatsApp(data)
|
||||||
|
|
||||||
const whatsQueueIds = data.queues?.map(queue => queue.id);
|
const whatsQueueIds = data.queues?.map((queue) => queue.id)
|
||||||
setSelectedQueueIds(whatsQueueIds);
|
setSelectedQueueIds(whatsQueueIds)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
fetchSession();
|
fetchSession()
|
||||||
}, [whatsAppId]);
|
}, [whatsAppId])
|
||||||
|
|
||||||
const handleSaveWhatsApp = async values => {
|
const handleSaveWhatsApp = async (values) => {
|
||||||
const whatsappData = { ...values, queueIds: selectedQueueIds };
|
const whatsappData = { ...values, queueIds: selectedQueueIds }
|
||||||
|
|
||||||
let response = null
|
let response = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (whatsAppId) {
|
if (whatsAppId) {
|
||||||
response = await api.put(`/whatsapp/${whatsAppId}`, whatsappData);
|
response = await api.put(`/whatsapp/${whatsAppId}`, whatsappData)
|
||||||
} else {
|
} else {
|
||||||
response = await api.post("/whatsapp", whatsappData);
|
response = await api.post('/whatsapp', whatsappData)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('response: ', response.data.message)
|
console.log('response: ', response.data.message)
|
||||||
|
|
||||||
if (response && response.data.message === 'wrong_number_start') {
|
if (response && response.data.message === 'wrong_number_start') {
|
||||||
alert('O numero contido no nome da conexão deve iniciar com o código do país!')
|
alert(
|
||||||
|
'O numero contido no nome da conexão deve iniciar com o código do país!'
|
||||||
|
)
|
||||||
|
} else if (response && response.data.message === 'invalid_phone_number') {
|
||||||
|
alert(
|
||||||
|
'A quantidade de numeros digitados no nome do contato é invalida! Certifique-se de que você digitou o numero correto acompanhado pelo código do país!'
|
||||||
|
)
|
||||||
|
} else if (response && response.data.message === 'no_phone_number') {
|
||||||
|
alert(
|
||||||
|
'Para criar/editar uma sessão de Whatsapp é necessário que o numero do Whatsapp acompanhado pelo código do país esteja presente no nome da sessão!'
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
toast.success(i18n.t('whatsappModal.success'))
|
||||||
|
handleClose()
|
||||||
}
|
}
|
||||||
else if(response && response.data.message === 'invalid_phone_number'){
|
|
||||||
alert('A quantidade de numeros digitados no nome do contato é invalida! Certifique-se de que você digitou o numero correto acompanhado pelo código do país!')
|
|
||||||
}
|
|
||||||
else if( response && response.data.message === 'no_phone_number'){
|
|
||||||
alert('Para criar/editar uma sessão de Whatsapp é necessário que o numero do Whatsapp acompanhado pelo código do país esteja presente no nome da sessão!')
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
toast.success(i18n.t("whatsappModal.success"));
|
|
||||||
handleClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
onClose();
|
onClose()
|
||||||
setWhatsApp(initialState);
|
setWhatsApp(initialState)
|
||||||
};
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
|
@ -136,8 +144,8 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
>
|
>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
{whatsAppId
|
{whatsAppId
|
||||||
? i18n.t("whatsappModal.title.edit")
|
? i18n.t('whatsappModal.title.edit')
|
||||||
: i18n.t("whatsappModal.title.add")}
|
: i18n.t('whatsappModal.title.add')}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={whatsApp}
|
initialValues={whatsApp}
|
||||||
|
@ -145,19 +153,23 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
validationSchema={SessionSchema}
|
validationSchema={SessionSchema}
|
||||||
onSubmit={(values, actions) => {
|
onSubmit={(values, actions) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
handleSaveWhatsApp(values);
|
handleSaveWhatsApp(values)
|
||||||
actions.setSubmitting(false);
|
actions.setSubmitting(false)
|
||||||
}, 400);
|
}, 400)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ values, touched, errors, isSubmitting }) => (
|
{({ values, touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<DialogContent dividers>
|
<DialogContent dividers>
|
||||||
|
<Can
|
||||||
|
role={user.profile}
|
||||||
|
perform="url-remote-session:show"
|
||||||
|
yes={() => (
|
||||||
|
<>
|
||||||
<div className={classes.multFieldLine}>
|
<div className={classes.multFieldLine}>
|
||||||
<Field
|
<Field
|
||||||
as={TextField}
|
as={TextField}
|
||||||
label={i18n.t("whatsappModal.form.name")}
|
label={i18n.t('whatsappModal.form.name')}
|
||||||
autoFocus
|
autoFocus
|
||||||
name="name"
|
name="name"
|
||||||
error={touched.name && Boolean(errors.name)}
|
error={touched.name && Boolean(errors.name)}
|
||||||
|
@ -175,16 +187,13 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
checked={values.isDefault}
|
checked={values.isDefault}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label={i18n.t("whatsappModal.form.default")}
|
label={i18n.t('whatsappModal.form.default')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div className={classes.multFieldLine}>
|
<div className={classes.multFieldLine}>
|
||||||
<Field
|
<Field
|
||||||
as={TextField}
|
as={TextField}
|
||||||
label='url API'
|
label="url API"
|
||||||
autoFocus
|
autoFocus
|
||||||
name="urlApi"
|
name="urlApi"
|
||||||
error={touched.name && Boolean(errors.name)}
|
error={touched.name && Boolean(errors.name)}
|
||||||
|
@ -195,7 +204,7 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
/>
|
/>
|
||||||
<Field
|
<Field
|
||||||
as={TextField}
|
as={TextField}
|
||||||
label='url session'
|
label="url session"
|
||||||
autoFocus
|
autoFocus
|
||||||
name="url"
|
name="url"
|
||||||
error={touched.name && Boolean(errors.name)}
|
error={touched.name && Boolean(errors.name)}
|
||||||
|
@ -205,12 +214,14 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
className={classes.textField}
|
className={classes.textField}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Field
|
<Field
|
||||||
as={TextField}
|
as={TextField}
|
||||||
label={i18n.t("queueModal.form.greetingMessage")}
|
label={i18n.t('queueModal.form.greetingMessage')}
|
||||||
type="greetingMessage"
|
type="greetingMessage"
|
||||||
multiline
|
multiline
|
||||||
rows={5}
|
rows={5}
|
||||||
|
@ -227,11 +238,10 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Field
|
<Field
|
||||||
as={TextField}
|
as={TextField}
|
||||||
label={i18n.t("whatsappModal.form.farewellMessage")}
|
label={i18n.t('whatsappModal.form.farewellMessage')}
|
||||||
type="farewellMessage"
|
type="farewellMessage"
|
||||||
multiline
|
multiline
|
||||||
rows={5}
|
rows={5}
|
||||||
|
@ -249,7 +259,7 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
</div>
|
</div>
|
||||||
<QueueSelect
|
<QueueSelect
|
||||||
selectedQueueIds={selectedQueueIds}
|
selectedQueueIds={selectedQueueIds}
|
||||||
onChange={selectedIds => setSelectedQueueIds(selectedIds)}
|
onChange={(selectedIds) => setSelectedQueueIds(selectedIds)}
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
|
@ -259,7 +269,7 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
>
|
>
|
||||||
{i18n.t("whatsappModal.buttons.cancel")}
|
{i18n.t('whatsappModal.buttons.cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
@ -269,8 +279,8 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
className={classes.btnWrapper}
|
className={classes.btnWrapper}
|
||||||
>
|
>
|
||||||
{whatsAppId
|
{whatsAppId
|
||||||
? i18n.t("whatsappModal.buttons.okEdit")
|
? i18n.t('whatsappModal.buttons.okEdit')
|
||||||
: i18n.t("whatsappModal.buttons.okAdd")}
|
: i18n.t('whatsappModal.buttons.okAdd')}
|
||||||
{isSubmitting && (
|
{isSubmitting && (
|
||||||
<CircularProgress
|
<CircularProgress
|
||||||
size={24}
|
size={24}
|
||||||
|
@ -284,7 +294,7 @@ const WhatsAppModal = ({ open, onClose, whatsAppId }) => {
|
||||||
</Formik>
|
</Formik>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
export default React.memo(WhatsAppModal);
|
export default React.memo(WhatsAppModal)
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
import React, { createContext } from "react";
|
import React, { createContext } from 'react'
|
||||||
|
|
||||||
import useAuth from "../../hooks/useAuth.js";
|
import useAuth from '../../hooks/useAuth.js'
|
||||||
|
|
||||||
const AuthContext = createContext();
|
const AuthContext = createContext()
|
||||||
|
|
||||||
const AuthProvider = ({ children }) => {
|
const AuthProvider = ({ children }) => {
|
||||||
const { loading, user, isAuth, handleLogin, handleLogout } = useAuth();
|
const { loading, user, isAuth, handleLogin, handleLogout, setSetting } =
|
||||||
|
useAuth()
|
||||||
|
|
||||||
//{
|
//{
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthContext.Provider
|
<AuthContext.Provider
|
||||||
value={{ loading, user, isAuth, handleLogin, handleLogout }}
|
value={{ loading, user, isAuth, handleLogin, handleLogout, setSetting }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</AuthContext.Provider>
|
</AuthContext.Provider>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
export { AuthContext, AuthProvider };
|
export { AuthContext, AuthProvider }
|
||||||
|
|
|
@ -1,125 +1,158 @@
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from 'react'
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from 'react-router-dom'
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from 'socket.io-client'
|
||||||
|
|
||||||
import { toast } from "react-toastify";
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
import { i18n } from "../../translate/i18n";
|
import { i18n } from '../../translate/i18n'
|
||||||
import api from "../../services/api";
|
import api from '../../services/api'
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from '../../errors/toastError'
|
||||||
|
|
||||||
const useAuth = () => {
|
const useAuth = () => {
|
||||||
const history = useHistory();
|
const history = useHistory()
|
||||||
const [isAuth, setIsAuth] = useState(false);
|
const [isAuth, setIsAuth] = useState(false)
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true)
|
||||||
const [user, setUser] = useState({});
|
const [user, setUser] = useState({})
|
||||||
|
|
||||||
|
const [setting, setSetting] = useState({})
|
||||||
|
|
||||||
api.interceptors.request.use(
|
api.interceptors.request.use(
|
||||||
config => {
|
(config) => {
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem('token')
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers["Authorization"] = `Bearer ${JSON.parse(token)}`;
|
config.headers['Authorization'] = `Bearer ${JSON.parse(token)}`
|
||||||
setIsAuth(true);
|
setIsAuth(true)
|
||||||
}
|
}
|
||||||
return config;
|
return config
|
||||||
},
|
},
|
||||||
error => {
|
(error) => {
|
||||||
Promise.reject(error);
|
Promise.reject(error)
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
|
|
||||||
api.interceptors.response.use(
|
api.interceptors.response.use(
|
||||||
response => {
|
(response) => {
|
||||||
return response;
|
return response
|
||||||
},
|
},
|
||||||
async error => {
|
async (error) => {
|
||||||
const originalRequest = error.config;
|
const originalRequest = error.config
|
||||||
if (error?.response?.status === 403 && !originalRequest._retry) {
|
if (error?.response?.status === 403 && !originalRequest._retry) {
|
||||||
originalRequest._retry = true;
|
originalRequest._retry = true
|
||||||
|
|
||||||
const { data } = await api.post("/auth/refresh_token");
|
const { data } = await api.post('/auth/refresh_token')
|
||||||
if (data) {
|
if (data) {
|
||||||
localStorage.setItem("token", JSON.stringify(data.token));
|
localStorage.setItem('token', JSON.stringify(data.token))
|
||||||
api.defaults.headers.Authorization = `Bearer ${data.token}`;
|
api.defaults.headers.Authorization = `Bearer ${data.token}`
|
||||||
}
|
}
|
||||||
return api(originalRequest);
|
return api(originalRequest)
|
||||||
}
|
}
|
||||||
if (error?.response?.status === 401) {
|
if (error?.response?.status === 401) {
|
||||||
localStorage.removeItem("token");
|
localStorage.removeItem('token')
|
||||||
api.defaults.headers.Authorization = undefined;
|
api.defaults.headers.Authorization = undefined
|
||||||
setIsAuth(false);
|
setIsAuth(false)
|
||||||
}
|
}
|
||||||
return Promise.reject(error);
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem('token')
|
||||||
(async () => {
|
;(async () => {
|
||||||
if (token) {
|
if (token) {
|
||||||
try {
|
try {
|
||||||
const { data } = await api.post("/auth/refresh_token");
|
const { data } = await api.post('/auth/refresh_token')
|
||||||
api.defaults.headers.Authorization = `Bearer ${data.token}`;
|
api.defaults.headers.Authorization = `Bearer ${data.token}`
|
||||||
setIsAuth(true);
|
setIsAuth(true)
|
||||||
setUser(data.user);
|
setUser(data.user)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setLoading(false);
|
setLoading(false)
|
||||||
})();
|
})()
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const fetchSession = async () => {
|
||||||
|
try {
|
||||||
socket.on("user", data => {
|
const { data } = await api.get('/settings')
|
||||||
if (data.action === "update" && data.user.id === user.id) {
|
setSetting(data)
|
||||||
setUser(data.user);
|
} catch (err) {
|
||||||
|
toastError(err)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
fetchSession()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
|
||||||
|
|
||||||
|
socket.on('user', (data) => {
|
||||||
|
if (data.action === 'update' && data.user.id === user.id) {
|
||||||
|
setUser(data.user)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.on('settings', (data) => {
|
||||||
|
if (data.action === 'update') {
|
||||||
|
setSetting((prevState) => {
|
||||||
|
const aux = [...prevState]
|
||||||
|
const settingIndex = aux.findIndex((s) => s.key === data.setting.key)
|
||||||
|
aux[settingIndex].value = data.setting.value
|
||||||
|
return aux
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.disconnect();
|
socket.disconnect()
|
||||||
};
|
}
|
||||||
}, [user]);
|
}, [user])
|
||||||
|
|
||||||
const handleLogin = async userData => {
|
const handleLogin = async (userData) => {
|
||||||
setLoading(true);
|
setLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data } = await api.post("/auth/login", userData);
|
const { data } = await api.post('/auth/login', userData)
|
||||||
localStorage.setItem("token", JSON.stringify(data.token));
|
localStorage.setItem('token', JSON.stringify(data.token))
|
||||||
api.defaults.headers.Authorization = `Bearer ${data.token}`;
|
api.defaults.headers.Authorization = `Bearer ${data.token}`
|
||||||
setUser(data.user);
|
setUser(data.user)
|
||||||
setIsAuth(true);
|
setIsAuth(true)
|
||||||
toast.success(i18n.t("auth.toasts.success"));
|
toast.success(i18n.t('auth.toasts.success'))
|
||||||
history.push("/tickets");
|
history.push('/tickets')
|
||||||
setLoading(false);
|
setLoading(false)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
setLoading(false);
|
setLoading(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
setLoading(true);
|
setLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.delete("/auth/logout");
|
await api.delete('/auth/logout')
|
||||||
setIsAuth(false);
|
setIsAuth(false)
|
||||||
setUser({});
|
setUser({})
|
||||||
localStorage.removeItem("token");
|
localStorage.removeItem('token')
|
||||||
api.defaults.headers.Authorization = undefined;
|
api.defaults.headers.Authorization = undefined
|
||||||
setLoading(false);
|
setLoading(false)
|
||||||
history.push("/login");
|
history.push('/login')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
setLoading(false);
|
setLoading(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
return { isAuth, user, loading, handleLogin, handleLogout };
|
return {
|
||||||
};
|
isAuth,
|
||||||
|
user,
|
||||||
|
loading,
|
||||||
|
handleLogin,
|
||||||
|
handleLogout,
|
||||||
|
setting,
|
||||||
|
setSetting,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default useAuth;
|
export default useAuth
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import React, { useState, useCallback, useEffect, useContext } from "react";
|
import React, { useState, useCallback, useEffect, useContext } from 'react'
|
||||||
import { toast } from "react-toastify";
|
import { toast } from 'react-toastify'
|
||||||
import { format, parseISO } from "date-fns";
|
import { format, parseISO } from 'date-fns'
|
||||||
|
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from 'socket.io-client'
|
||||||
|
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import { green } from "@material-ui/core/colors";
|
import { green } from '@material-ui/core/colors'
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
TableBody,
|
TableBody,
|
||||||
|
@ -18,7 +18,7 @@ import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
CircularProgress,
|
CircularProgress,
|
||||||
} from "@material-ui/core";
|
} from '@material-ui/core'
|
||||||
import {
|
import {
|
||||||
Edit,
|
Edit,
|
||||||
CheckCircle,
|
CheckCircle,
|
||||||
|
@ -28,56 +28,55 @@ import {
|
||||||
CropFree,
|
CropFree,
|
||||||
DeleteOutline,
|
DeleteOutline,
|
||||||
// Restore
|
// Restore
|
||||||
} from "@material-ui/icons";
|
} from '@material-ui/icons'
|
||||||
|
|
||||||
import MainContainer from "../../components/MainContainer";
|
import MainContainer from '../../components/MainContainer'
|
||||||
import MainHeader from "../../components/MainHeader";
|
import MainHeader from '../../components/MainHeader'
|
||||||
import MainHeaderButtonsWrapper from "../../components/MainHeaderButtonsWrapper";
|
import MainHeaderButtonsWrapper from '../../components/MainHeaderButtonsWrapper'
|
||||||
import Title from "../../components/Title";
|
import Title from '../../components/Title'
|
||||||
import TableRowSkeleton from "../../components/TableRowSkeleton";
|
import TableRowSkeleton from '../../components/TableRowSkeleton'
|
||||||
|
|
||||||
import api from "../../services/api";
|
import api from '../../services/api'
|
||||||
import WhatsAppModal from "../../components/WhatsAppModal";
|
import WhatsAppModal from '../../components/WhatsAppModal'
|
||||||
import ConfirmationModal from "../../components/ConfirmationModal";
|
import ConfirmationModal from '../../components/ConfirmationModal'
|
||||||
import QrcodeModal from "../../components/QrcodeModal";
|
import QrcodeModal from '../../components/QrcodeModal'
|
||||||
import { i18n } from "../../translate/i18n";
|
import { i18n } from '../../translate/i18n'
|
||||||
import { WhatsAppsContext } from "../../context/WhatsApp/WhatsAppsContext";
|
import { WhatsAppsContext } from '../../context/WhatsApp/WhatsAppsContext'
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from '../../errors/toastError'
|
||||||
|
|
||||||
//--------
|
//--------
|
||||||
import { AuthContext } from "../../context/Auth/AuthContext";
|
import { AuthContext } from '../../context/Auth/AuthContext'
|
||||||
import { Can } from "../../components/Can";
|
import { Can } from '../../components/Can'
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme) => ({
|
||||||
const useStyles = makeStyles(theme => ({
|
|
||||||
mainPaper: {
|
mainPaper: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
padding: theme.spacing(1),
|
padding: theme.spacing(1),
|
||||||
overflowY: "scroll",
|
overflowY: 'scroll',
|
||||||
...theme.scrollbarStyles,
|
...theme.scrollbarStyles,
|
||||||
},
|
},
|
||||||
customTableCell: {
|
customTableCell: {
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
justifyContent: "center",
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
backgroundColor: "#f5f5f9",
|
backgroundColor: '#f5f5f9',
|
||||||
color: "rgba(0, 0, 0, 0.87)",
|
color: 'rgba(0, 0, 0, 0.87)',
|
||||||
fontSize: theme.typography.pxToRem(14),
|
fontSize: theme.typography.pxToRem(14),
|
||||||
border: "1px solid #dadde9",
|
border: '1px solid #dadde9',
|
||||||
maxWidth: 450,
|
maxWidth: 450,
|
||||||
},
|
},
|
||||||
tooltipPopper: {
|
tooltipPopper: {
|
||||||
textAlign: "center",
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
buttonProgress: {
|
buttonProgress: {
|
||||||
color: green[500],
|
color: green[500],
|
||||||
},
|
},
|
||||||
}));
|
}))
|
||||||
|
|
||||||
const CustomToolTip = ({ title, content, children }) => {
|
const CustomToolTip = ({ title, content, children }) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
|
@ -97,189 +96,195 @@ const CustomToolTip = ({ title, content, children }) => {
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
const Connections = () => {
|
const Connections = () => {
|
||||||
|
|
||||||
//--------
|
//--------
|
||||||
const { user } = useContext(AuthContext);
|
const { user } = useContext(AuthContext)
|
||||||
|
|
||||||
|
const classes = useStyles()
|
||||||
|
|
||||||
const classes = useStyles();
|
const { whatsApps, loading } = useContext(WhatsAppsContext)
|
||||||
|
const [whatsAppModalOpen, setWhatsAppModalOpen] = useState(false)
|
||||||
|
const [qrModalOpen, setQrModalOpen] = useState(false)
|
||||||
|
const [selectedWhatsApp, setSelectedWhatsApp] = useState(null)
|
||||||
|
const [confirmModalOpen, setConfirmModalOpen] = useState(false)
|
||||||
|
|
||||||
const { whatsApps, loading } = useContext(WhatsAppsContext);
|
const [diskSpaceInfo, setDiskSpaceInfo] = useState({})
|
||||||
const [whatsAppModalOpen, setWhatsAppModalOpen] = useState(false);
|
|
||||||
const [qrModalOpen, setQrModalOpen] = useState(false);
|
|
||||||
const [selectedWhatsApp, setSelectedWhatsApp] = useState(null);
|
|
||||||
const [confirmModalOpen, setConfirmModalOpen] = useState(false);
|
|
||||||
|
|
||||||
const [diskSpaceInfo, setDiskSpaceInfo] = useState({});
|
const [disabled, setDisabled] = useState(true)
|
||||||
|
|
||||||
const [disabled, setDisabled] = useState(true);
|
const [settings, setSettings] = useState([])
|
||||||
|
|
||||||
const [buttons, setClicks] = useState([])
|
const [buttons, setClicks] = useState([])
|
||||||
|
|
||||||
|
|
||||||
const confirmationModalInitialState = {
|
const confirmationModalInitialState = {
|
||||||
action: "",
|
action: '',
|
||||||
title: "",
|
title: '',
|
||||||
message: "",
|
message: '',
|
||||||
whatsAppId: "",
|
whatsAppId: '',
|
||||||
open: false,
|
open: false,
|
||||||
};
|
}
|
||||||
const [confirmModalInfo, setConfirmModalInfo] = useState(
|
const [confirmModalInfo, setConfirmModalInfo] = useState(
|
||||||
confirmationModalInitialState
|
confirmationModalInitialState
|
||||||
);
|
)
|
||||||
|
|
||||||
const handleStartWhatsAppSession = async whatsAppId => {
|
useEffect(() => {
|
||||||
|
const fetchSession = async () => {
|
||||||
try {
|
try {
|
||||||
await api.post(`/whatsappsession/${whatsAppId}`);
|
const { data } = await api.get('/settings')
|
||||||
|
setSettings(data)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
fetchSession()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const getSettingValue = (key) => {
|
||||||
|
const { value } = settings.find((s) => s.key === key)
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleStartWhatsAppSession = async (whatsAppId) => {
|
||||||
const handleRestartWhatsAppSession = async whatsapp => {
|
|
||||||
try {
|
try {
|
||||||
|
await api.post(`/whatsappsession/${whatsAppId}`)
|
||||||
|
} catch (err) {
|
||||||
|
toastError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRestartWhatsAppSession = async (whatsapp) => {
|
||||||
|
try {
|
||||||
whatsapp.disabled = true
|
whatsapp.disabled = true
|
||||||
|
|
||||||
setClicks([...buttons, whatsapp.id])
|
setClicks([...buttons, whatsapp.id])
|
||||||
|
|
||||||
function enable_button(whatsappId) {
|
function enable_button(whatsappId) {
|
||||||
|
setClicks((buttons) =>
|
||||||
setClicks(buttons => buttons.filter(id => { return +id !== +whatsappId }),);
|
buttons.filter((id) => {
|
||||||
|
return +id !== +whatsappId
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(enable_button, 25000, whatsapp.id)
|
setTimeout(enable_button, 25000, whatsapp.id)
|
||||||
|
|
||||||
await api.post(`/restartwhatsappsession/${whatsapp.id}`);
|
await api.post(`/restartwhatsappsession/${whatsapp.id}`)
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
// whatsApps.map((e) => {
|
// whatsApps.map((e) => {
|
||||||
// if (buttons.includes(e.id)) {
|
// if (buttons.includes(e.id)) {
|
||||||
// e.disabled = true
|
// e.disabled = true
|
||||||
// }
|
// }
|
||||||
// })
|
// })
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < whatsApps.length; i++) {
|
for (let i = 0; i < whatsApps.length; i++) {
|
||||||
if (buttons.includes(whatsApps[i].id)) {
|
if (buttons.includes(whatsApps[i].id)) {
|
||||||
whatsApps[i].disabled = true
|
whatsApps[i].disabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}, [whatsApps, buttons])
|
}, [whatsApps, buttons])
|
||||||
|
|
||||||
|
const handleRequestNewQrCode = async (whatsAppId) => {
|
||||||
const handleRequestNewQrCode = async whatsAppId => {
|
|
||||||
try {
|
try {
|
||||||
await api.put(`/whatsappsession/${whatsAppId}`);
|
await api.put(`/whatsappsession/${whatsAppId}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const handleOpenWhatsAppModal = () => {
|
const handleOpenWhatsAppModal = () => {
|
||||||
setSelectedWhatsApp(null);
|
setSelectedWhatsApp(null)
|
||||||
setWhatsAppModalOpen(true);
|
setWhatsAppModalOpen(true)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleCloseWhatsAppModal = useCallback(() => {
|
const handleCloseWhatsAppModal = useCallback(() => {
|
||||||
setWhatsAppModalOpen(false);
|
setWhatsAppModalOpen(false)
|
||||||
setSelectedWhatsApp(null);
|
setSelectedWhatsApp(null)
|
||||||
}, [setSelectedWhatsApp, setWhatsAppModalOpen]);
|
}, [setSelectedWhatsApp, setWhatsAppModalOpen])
|
||||||
|
|
||||||
const handleOpenQrModal = whatsApp => {
|
const handleOpenQrModal = (whatsApp) => {
|
||||||
setSelectedWhatsApp(whatsApp);
|
setSelectedWhatsApp(whatsApp)
|
||||||
setQrModalOpen(true);
|
setQrModalOpen(true)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleCloseQrModal = useCallback(() => {
|
const handleCloseQrModal = useCallback(() => {
|
||||||
setSelectedWhatsApp(null);
|
setSelectedWhatsApp(null)
|
||||||
setQrModalOpen(false);
|
setQrModalOpen(false)
|
||||||
}, [setQrModalOpen, setSelectedWhatsApp]);
|
}, [setQrModalOpen, setSelectedWhatsApp])
|
||||||
|
|
||||||
const handleEditWhatsApp = whatsApp => {
|
const handleEditWhatsApp = (whatsApp) => {
|
||||||
setSelectedWhatsApp(whatsApp);
|
setSelectedWhatsApp(whatsApp)
|
||||||
setWhatsAppModalOpen(true);
|
setWhatsAppModalOpen(true)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleOpenConfirmationModal = (action, whatsAppId) => {
|
const handleOpenConfirmationModal = (action, whatsAppId) => {
|
||||||
if (action === "disconnect") {
|
if (action === 'disconnect') {
|
||||||
setConfirmModalInfo({
|
setConfirmModalInfo({
|
||||||
action: action,
|
action: action,
|
||||||
title: i18n.t("connections.confirmationModal.disconnectTitle"),
|
title: i18n.t('connections.confirmationModal.disconnectTitle'),
|
||||||
message: i18n.t("connections.confirmationModal.disconnectMessage"),
|
message: i18n.t('connections.confirmationModal.disconnectMessage'),
|
||||||
whatsAppId: whatsAppId,
|
whatsAppId: whatsAppId,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action === "delete") {
|
if (action === 'delete') {
|
||||||
setConfirmModalInfo({
|
setConfirmModalInfo({
|
||||||
action: action,
|
action: action,
|
||||||
title: i18n.t("connections.confirmationModal.deleteTitle"),
|
title: i18n.t('connections.confirmationModal.deleteTitle'),
|
||||||
message: i18n.t("connections.confirmationModal.deleteMessage"),
|
message: i18n.t('connections.confirmationModal.deleteMessage'),
|
||||||
whatsAppId: whatsAppId,
|
whatsAppId: whatsAppId,
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
setConfirmModalOpen(true)
|
||||||
}
|
}
|
||||||
setConfirmModalOpen(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmitConfirmationModal = async () => {
|
const handleSubmitConfirmationModal = async () => {
|
||||||
if (confirmModalInfo.action === "disconnect") {
|
if (confirmModalInfo.action === 'disconnect') {
|
||||||
try {
|
try {
|
||||||
await api.delete(`/whatsappsession/${confirmModalInfo.whatsAppId}`);
|
await api.delete(`/whatsappsession/${confirmModalInfo.whatsAppId}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (confirmModalInfo.action === "delete") {
|
if (confirmModalInfo.action === 'delete') {
|
||||||
try {
|
try {
|
||||||
await api.delete(`/whatsapp/${confirmModalInfo.whatsAppId}`);
|
await api.delete(`/whatsapp/${confirmModalInfo.whatsAppId}`)
|
||||||
toast.success(i18n.t("connections.toasts.deleted"));
|
toast.success(i18n.t('connections.toasts.deleted'))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setConfirmModalInfo(confirmationModalInitialState);
|
setConfirmModalInfo(confirmationModalInitialState)
|
||||||
};
|
}
|
||||||
|
|
||||||
const renderActionButtons = whatsApp => {
|
const renderActionButtons = (whatsApp) => {
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="connection-button:show"
|
perform="connection-button:show"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
|
|
||||||
<>
|
<>
|
||||||
{whatsApp.status === "qrcode" && (
|
{whatsApp.status === 'qrcode' && (
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => handleOpenQrModal(whatsApp)}
|
onClick={() => handleOpenQrModal(whatsApp)}
|
||||||
>
|
>
|
||||||
{i18n.t("connections.buttons.qrcode")}
|
{i18n.t('connections.buttons.qrcode')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{whatsApp.status === "DISCONNECTED" && (
|
{whatsApp.status === 'DISCONNECTED' && (
|
||||||
|
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
|
@ -287,76 +292,74 @@ const Connections = () => {
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => handleStartWhatsAppSession(whatsApp.id)}
|
onClick={() => handleStartWhatsAppSession(whatsApp.id)}
|
||||||
>
|
>
|
||||||
{i18n.t("connections.buttons.tryAgain")}
|
{i18n.t('connections.buttons.tryAgain')}
|
||||||
</Button>{" "}
|
</Button>{' '}
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
onClick={() => handleRequestNewQrCode(whatsApp.id)}
|
onClick={() => handleRequestNewQrCode(whatsApp.id)}
|
||||||
>
|
>
|
||||||
{i18n.t("connections.buttons.newQr")}
|
{i18n.t('connections.buttons.newQr')}
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{(whatsApp.status === "CONNECTED" ||
|
{(whatsApp.status === 'CONNECTED' ||
|
||||||
whatsApp.status === "PAIRING" ||
|
whatsApp.status === 'PAIRING' ||
|
||||||
whatsApp.status === "TIMEOUT") && (
|
whatsApp.status === 'TIMEOUT') && (
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleOpenConfirmationModal("disconnect", whatsApp.id);
|
handleOpenConfirmationModal('disconnect', whatsApp.id)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{i18n.t("connections.buttons.disconnect")}
|
{i18n.t('connections.buttons.disconnect')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{whatsApp.status === "OPENING" && (
|
{whatsApp.status === 'OPENING' && (
|
||||||
<Button size="small" variant="outlined" disabled color="default">
|
<Button size="small" variant="outlined" disabled color="default">
|
||||||
{i18n.t("connections.buttons.connecting")}
|
{i18n.t('connections.buttons.connecting')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
);
|
const renderStatusToolTips = (whatsApp) => {
|
||||||
};
|
|
||||||
|
|
||||||
const renderStatusToolTips = whatsApp => {
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.customTableCell}>
|
<div className={classes.customTableCell}>
|
||||||
{whatsApp.status === "DISCONNECTED" && (
|
{whatsApp.status === 'DISCONNECTED' && (
|
||||||
<CustomToolTip
|
<CustomToolTip
|
||||||
title={i18n.t("connections.toolTips.disconnected.title")}
|
title={i18n.t('connections.toolTips.disconnected.title')}
|
||||||
content={i18n.t("connections.toolTips.disconnected.content")}
|
content={i18n.t('connections.toolTips.disconnected.content')}
|
||||||
>
|
>
|
||||||
<SignalCellularConnectedNoInternet0Bar color="secondary" />
|
<SignalCellularConnectedNoInternet0Bar color="secondary" />
|
||||||
</CustomToolTip>
|
</CustomToolTip>
|
||||||
)}
|
)}
|
||||||
{whatsApp.status === "OPENING" && (
|
{whatsApp.status === 'OPENING' && (
|
||||||
<CircularProgress size={24} className={classes.buttonProgress} />
|
<CircularProgress size={24} className={classes.buttonProgress} />
|
||||||
)}
|
)}
|
||||||
{whatsApp.status === "qrcode" && (
|
{whatsApp.status === 'qrcode' && (
|
||||||
<CustomToolTip
|
<CustomToolTip
|
||||||
title={i18n.t("connections.toolTips.qrcode.title")}
|
title={i18n.t('connections.toolTips.qrcode.title')}
|
||||||
content={i18n.t("connections.toolTips.qrcode.content")}
|
content={i18n.t('connections.toolTips.qrcode.content')}
|
||||||
>
|
>
|
||||||
<CropFree />
|
<CropFree />
|
||||||
</CustomToolTip>
|
</CustomToolTip>
|
||||||
)}
|
)}
|
||||||
{whatsApp.status === "CONNECTED" && (
|
{whatsApp.status === 'CONNECTED' && (
|
||||||
<CustomToolTip title={i18n.t("connections.toolTips.connected.title")}>
|
<CustomToolTip title={i18n.t('connections.toolTips.connected.title')}>
|
||||||
<SignalCellular4Bar style={{ color: green[500] }} />
|
<SignalCellular4Bar style={{ color: green[500] }} />
|
||||||
</CustomToolTip>
|
</CustomToolTip>
|
||||||
)}
|
)}
|
||||||
{(whatsApp.status === "TIMEOUT" || whatsApp.status === "PAIRING") && (
|
{(whatsApp.status === 'TIMEOUT' || whatsApp.status === 'PAIRING') && (
|
||||||
<CustomToolTip
|
<CustomToolTip
|
||||||
title={i18n.t("connections.toolTips.timeout.title")}
|
title={i18n.t('connections.toolTips.timeout.title')}
|
||||||
content={i18n.t("connections.toolTips.timeout.content")}
|
content={i18n.t('connections.toolTips.timeout.content')}
|
||||||
>
|
>
|
||||||
<SignalCellularConnectedNoInternet2Bar color="secondary" />
|
<SignalCellularConnectedNoInternet2Bar color="secondary" />
|
||||||
</CustomToolTip>
|
</CustomToolTip>
|
||||||
|
@ -371,62 +374,65 @@ const Connections = () => {
|
||||||
</CustomToolTip>
|
</CustomToolTip>
|
||||||
)} */}
|
)} */}
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
const delayDebounceFn = setTimeout(() => {
|
const delayDebounceFn = setTimeout(() => {
|
||||||
|
|
||||||
const fetchQueries = async () => {
|
const fetchQueries = async () => {
|
||||||
try {
|
try {
|
||||||
|
await api.post(`/restartwhatsappsession/0`, {
|
||||||
await api.post(`/restartwhatsappsession/0`, { params: { status: 'status' }, });
|
params: { status: 'status' },
|
||||||
|
})
|
||||||
|
|
||||||
setDisabled(false)
|
setDisabled(false)
|
||||||
|
|
||||||
setClicks(buttons => buttons.map((e) => { return { id: e.id, disabled: false } }))
|
setClicks((buttons) =>
|
||||||
|
buttons.map((e) => {
|
||||||
|
return { id: e.id, disabled: false }
|
||||||
|
})
|
||||||
|
)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
fetchQueries();
|
|
||||||
|
|
||||||
}, 500);
|
|
||||||
return () => clearTimeout(delayDebounceFn);
|
|
||||||
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
|
fetchQueries()
|
||||||
|
}, 500)
|
||||||
|
return () => clearTimeout(delayDebounceFn)
|
||||||
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
|
||||||
|
|
||||||
socket.on("diskSpaceMonit", data => {
|
|
||||||
if (data.action === "update") {
|
|
||||||
|
|
||||||
|
socket.on('diskSpaceMonit', (data) => {
|
||||||
|
if (data.action === 'update') {
|
||||||
setDiskSpaceInfo(data.diskSpace)
|
setDiskSpaceInfo(data.diskSpace)
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
|
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 () => {
|
return () => {
|
||||||
socket.disconnect();
|
socket.disconnect()
|
||||||
};
|
}
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="connections-view:show"
|
perform="connections-view:show"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
<MainContainer>
|
<MainContainer>
|
||||||
|
|
||||||
<ConfirmationModal
|
<ConfirmationModal
|
||||||
title={confirmModalInfo.title}
|
title={confirmModalInfo.title}
|
||||||
open={confirmModalOpen}
|
open={confirmModalOpen}
|
||||||
|
@ -436,7 +442,6 @@ const Connections = () => {
|
||||||
{confirmModalInfo.message}
|
{confirmModalInfo.message}
|
||||||
</ConfirmationModal>
|
</ConfirmationModal>
|
||||||
|
|
||||||
|
|
||||||
<QrcodeModal
|
<QrcodeModal
|
||||||
open={qrModalOpen}
|
open={qrModalOpen}
|
||||||
onClose={handleCloseQrModal}
|
onClose={handleCloseQrModal}
|
||||||
|
@ -450,32 +455,28 @@ const Connections = () => {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MainHeader>
|
<MainHeader>
|
||||||
|
<Title>{i18n.t('connections.title')}</Title>
|
||||||
|
|
||||||
<Title>{i18n.t("connections.title")}</Title>
|
|
||||||
|
|
||||||
<MainHeaderButtonsWrapper>
|
<MainHeaderButtonsWrapper>
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="btn-add-whatsapp" updatedAt
|
perform="btn-add-whatsapp"
|
||||||
|
updatedAt
|
||||||
yes={() => (
|
yes={() => (
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={handleOpenWhatsAppModal}>
|
onClick={handleOpenWhatsAppModal}
|
||||||
{i18n.t("connections.buttons.add")}
|
>
|
||||||
|
{i18n.t('connections.buttons.add')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</MainHeaderButtonsWrapper>
|
</MainHeaderButtonsWrapper>
|
||||||
|
|
||||||
|
|
||||||
</MainHeader>
|
</MainHeader>
|
||||||
|
|
||||||
|
|
||||||
<Paper className={classes.mainPaper} variant="outlined">
|
<Paper className={classes.mainPaper} variant="outlined">
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="space-disk-info:show"
|
perform="space-disk-info:show"
|
||||||
|
@ -484,27 +485,27 @@ const Connections = () => {
|
||||||
<Table size="small">
|
<Table size="small">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell align="center">
|
<TableCell align="center">Size</TableCell>
|
||||||
Size
|
<TableCell align="center">Used</TableCell>
|
||||||
</TableCell>
|
<TableCell align="center">Available</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">Use%</TableCell>
|
||||||
Used
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="center">
|
|
||||||
Available
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="center">
|
|
||||||
Use%
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
||||||
<TableBody>
|
<TableBody>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell align="center">{diskSpaceInfo.size}</TableCell>
|
<TableCell align="center">
|
||||||
<TableCell align="center">{diskSpaceInfo.used}</TableCell>
|
{diskSpaceInfo.size}
|
||||||
<TableCell align="center">{diskSpaceInfo.available}</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">{diskSpaceInfo.use}</TableCell>
|
<TableCell align="center">
|
||||||
|
{diskSpaceInfo.used}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center">
|
||||||
|
{diskSpaceInfo.available}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center">
|
||||||
|
{diskSpaceInfo.use}
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
|
@ -516,13 +517,12 @@ const Connections = () => {
|
||||||
<Table size="small">
|
<Table size="small">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("connections.table.name")}
|
{i18n.t('connections.table.name')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("connections.table.status")}
|
{i18n.t('connections.table.status')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
|
@ -530,47 +530,33 @@ const Connections = () => {
|
||||||
perform="connection-button:show"
|
perform="connection-button:show"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("connections.table.session")}
|
{i18n.t('connections.table.session')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Can
|
||||||
|
role={user.profile}
|
||||||
|
perform="connection-button:show"
|
||||||
|
yes={() => <TableCell align="center">Restore</TableCell>}
|
||||||
|
/>
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="connection-button:show"
|
perform="connection-button:show"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
<TableCell align="center">
|
<TableCell align="center">Session MB</TableCell>
|
||||||
Restore
|
|
||||||
</TableCell>
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Can
|
|
||||||
role={user.profile}
|
|
||||||
perform="connection-button:show"
|
|
||||||
yes={() => (
|
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
Session MB
|
{i18n.t('connections.table.lastUpdate')}
|
||||||
</TableCell>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<TableCell align="center">
|
|
||||||
{i18n.t("connections.table.lastUpdate")}
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("connections.table.default")}
|
{i18n.t('connections.table.default')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("connections.table.actions")}
|
{i18n.t('connections.table.actions')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
@ -580,9 +566,11 @@ const Connections = () => {
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{whatsApps?.length > 0 &&
|
{whatsApps?.length > 0 &&
|
||||||
whatsApps.map(whatsApp => (
|
whatsApps.map((whatsApp) => (
|
||||||
<TableRow key={whatsApp.id}>
|
<TableRow key={whatsApp.id}>
|
||||||
<TableCell align="center">{whatsApp.name}</TableCell>
|
<TableCell align="center">
|
||||||
|
{whatsApp.name}
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{renderStatusToolTips(whatsApp)}
|
{renderStatusToolTips(whatsApp)}
|
||||||
|
@ -598,36 +586,30 @@ const Connections = () => {
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="connection-button:show"
|
perform="connection-button:show"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
|
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
disabled={whatsApp.disabled || disabled ? true : false}
|
disabled={
|
||||||
|
whatsApp.disabled || disabled
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
}
|
||||||
size="small"
|
size="small"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => handleRestartWhatsAppSession(whatsApp)}
|
onClick={() =>
|
||||||
|
handleRestartWhatsAppSession(whatsApp)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Restore
|
Restore
|
||||||
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="connection-button:show"
|
perform="connection-button:show"
|
||||||
|
@ -635,7 +617,9 @@ const Connections = () => {
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
<CustomToolTip
|
<CustomToolTip
|
||||||
title={'Informação da sessão em Megabytes'}
|
title={'Informação da sessão em Megabytes'}
|
||||||
content={'Tamanho do diretorio da sessão atualizado a cada 5 segundos'}
|
content={
|
||||||
|
'Tamanho do diretorio da sessão atualizado a cada 5 segundos'
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div>{whatsApp.sessionSize}</div>
|
<div>{whatsApp.sessionSize}</div>
|
||||||
</CustomToolTip>
|
</CustomToolTip>
|
||||||
|
@ -643,15 +627,13 @@ const Connections = () => {
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{format(parseISO(whatsApp.updatedAt), "dd/MM/yy HH:mm")}
|
{format(
|
||||||
|
parseISO(whatsApp.updatedAt),
|
||||||
|
'dd/MM/yy HH:mm'
|
||||||
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{whatsApp.isDefault && (
|
{whatsApp.isDefault && (
|
||||||
<div className={classes.customTableCell}>
|
<div className={classes.customTableCell}>
|
||||||
|
@ -660,38 +642,62 @@ const Connections = () => {
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="show-icon-edit-whatsapp"
|
perform="show-icon-edit-whatsapp"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
|
// disabled={
|
||||||
|
// whatsApp.disabled || disabled
|
||||||
|
// ? true
|
||||||
|
// : false
|
||||||
|
// }
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
margin: 0,
|
||||||
|
padding: 0,
|
||||||
|
border: 'none',
|
||||||
|
display: 'inline',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{(settings &&
|
||||||
|
settings.length > 0 &&
|
||||||
|
getSettingValue('editURA') &&
|
||||||
|
getSettingValue('editURA') ===
|
||||||
|
'enabled') |
|
||||||
|
(user.profile === 'master') ? (
|
||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => handleEditWhatsApp(whatsApp)}
|
onClick={() =>
|
||||||
|
handleEditWhatsApp(whatsApp)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Edit />
|
<Edit />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
) : (
|
||||||
|
<div></div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="btn-remove-whatsapp"
|
perform="btn-remove-whatsapp"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
onClick={e => {
|
onClick={(e) => {
|
||||||
handleOpenConfirmationModal("delete", whatsApp.id);
|
handleOpenConfirmationModal(
|
||||||
|
'delete',
|
||||||
|
whatsApp.id
|
||||||
|
)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DeleteOutline />
|
<DeleteOutline />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
@ -699,14 +705,12 @@ const Connections = () => {
|
||||||
)}
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
</Paper>
|
</Paper>
|
||||||
</MainContainer>
|
</MainContainer>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
);
|
export default Connections
|
||||||
};
|
|
||||||
|
|
||||||
export default Connections;
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useEffect, useReducer, useState, useContext } from "react";
|
import React, { useEffect, useReducer, useState, useContext } from 'react'
|
||||||
|
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from 'socket.io-client'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
@ -13,155 +13,186 @@ import {
|
||||||
TableHead,
|
TableHead,
|
||||||
TableRow,
|
TableRow,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from '@material-ui/core'
|
||||||
|
|
||||||
import MainContainer from "../../components/MainContainer";
|
import MainContainer from '../../components/MainContainer'
|
||||||
import MainHeader from "../../components/MainHeader";
|
import MainHeader from '../../components/MainHeader'
|
||||||
import MainHeaderButtonsWrapper from "../../components/MainHeaderButtonsWrapper";
|
import MainHeaderButtonsWrapper from '../../components/MainHeaderButtonsWrapper'
|
||||||
import TableRowSkeleton from "../../components/TableRowSkeleton";
|
import TableRowSkeleton from '../../components/TableRowSkeleton'
|
||||||
import Title from "../../components/Title";
|
import Title from '../../components/Title'
|
||||||
import { i18n } from "../../translate/i18n";
|
import { i18n } from '../../translate/i18n'
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from '../../errors/toastError'
|
||||||
import api from "../../services/api";
|
import api from '../../services/api'
|
||||||
import { DeleteOutline, Edit } from "@material-ui/icons";
|
import { DeleteOutline, Edit } from '@material-ui/icons'
|
||||||
import QueueModal from "../../components/QueueModal";
|
import QueueModal from '../../components/QueueModal'
|
||||||
import { toast } from "react-toastify";
|
import { toast } from 'react-toastify'
|
||||||
import ConfirmationModal from "../../components/ConfirmationModal";
|
import ConfirmationModal from '../../components/ConfirmationModal'
|
||||||
|
|
||||||
import { AuthContext } from "../../context/Auth/AuthContext";
|
import { AuthContext } from '../../context/Auth/AuthContext'
|
||||||
import { Can } from "../../components/Can";
|
import { Can } from '../../components/Can'
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
mainPaper: {
|
mainPaper: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
padding: theme.spacing(1),
|
padding: theme.spacing(1),
|
||||||
overflowY: "scroll",
|
overflowY: 'scroll',
|
||||||
...theme.scrollbarStyles,
|
...theme.scrollbarStyles,
|
||||||
},
|
},
|
||||||
customTableCell: {
|
customTableCell: {
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
justifyContent: "center",
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
}));
|
}))
|
||||||
|
|
||||||
const reducer = (state, action) => {
|
const reducer = (state, action) => {
|
||||||
if (action.type === "LOAD_QUEUES") {
|
if (action.type === 'LOAD_QUEUES') {
|
||||||
const queues = action.payload;
|
const queues = action.payload
|
||||||
const newQueues = [];
|
const newQueues = []
|
||||||
|
|
||||||
queues.forEach((queue) => {
|
queues.forEach((queue) => {
|
||||||
const queueIndex = state.findIndex((q) => q.id === queue.id);
|
const queueIndex = state.findIndex((q) => q.id === queue.id)
|
||||||
if (queueIndex !== -1) {
|
if (queueIndex !== -1) {
|
||||||
state[queueIndex] = queue;
|
state[queueIndex] = queue
|
||||||
} else {
|
} else {
|
||||||
newQueues.push(queue);
|
newQueues.push(queue)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
return [...state, ...newQueues];
|
return [...state, ...newQueues]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.type === "UPDATE_QUEUES") {
|
if (action.type === 'UPDATE_QUEUES') {
|
||||||
const queue = action.payload;
|
const queue = action.payload
|
||||||
const queueIndex = state.findIndex((u) => u.id === queue.id);
|
const queueIndex = state.findIndex((u) => u.id === queue.id)
|
||||||
|
|
||||||
if (queueIndex !== -1) {
|
if (queueIndex !== -1) {
|
||||||
state[queueIndex] = queue;
|
state[queueIndex] = queue
|
||||||
return [...state];
|
return [...state]
|
||||||
} else {
|
} else {
|
||||||
return [queue, ...state];
|
return [queue, ...state]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.type === "DELETE_QUEUE") {
|
if (action.type === 'DELETE_QUEUE') {
|
||||||
const queueId = action.payload;
|
const queueId = action.payload
|
||||||
const queueIndex = state.findIndex((q) => q.id === queueId);
|
const queueIndex = state.findIndex((q) => q.id === queueId)
|
||||||
if (queueIndex !== -1) {
|
if (queueIndex !== -1) {
|
||||||
state.splice(queueIndex, 1);
|
state.splice(queueIndex, 1)
|
||||||
}
|
}
|
||||||
return [...state];
|
return [...state]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.type === "RESET") {
|
if (action.type === 'RESET') {
|
||||||
return [];
|
return []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const Queues = () => {
|
const Queues = () => {
|
||||||
const classes = useStyles();
|
const classes = useStyles()
|
||||||
|
|
||||||
const { user } = useContext(AuthContext);
|
const { user } = useContext(AuthContext)
|
||||||
|
|
||||||
const [queues, dispatch] = useReducer(reducer, []);
|
const [queues, dispatch] = useReducer(reducer, [])
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
const [queueModalOpen, setQueueModalOpen] = useState(false);
|
const [queueModalOpen, setQueueModalOpen] = useState(false)
|
||||||
const [selectedQueue, setSelectedQueue] = useState(null);
|
const [selectedQueue, setSelectedQueue] = useState(null)
|
||||||
const [confirmModalOpen, setConfirmModalOpen] = useState(false);
|
const [confirmModalOpen, setConfirmModalOpen] = useState(false)
|
||||||
|
|
||||||
|
const [settings, setSettings] = useState([])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
;(async () => {
|
||||||
setLoading(true);
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get("/queue");
|
const { data } = await api.get('/queue')
|
||||||
dispatch({ type: "LOAD_QUEUES", payload: data });
|
dispatch({ type: 'LOAD_QUEUES', payload: data })
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
setLoading(false);
|
setLoading(false)
|
||||||
}
|
}
|
||||||
})();
|
})()
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const fetchSession = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await api.get('/settings')
|
||||||
|
setSettings(data)
|
||||||
|
} catch (err) {
|
||||||
|
toastError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fetchSession()
|
||||||
|
}, [])
|
||||||
|
|
||||||
socket.on("queue", (data) => {
|
const getSettingValue = (key) => {
|
||||||
if (data.action === "update" || data.action === "create") {
|
const { value } = settings.find((s) => s.key === key)
|
||||||
dispatch({ type: "UPDATE_QUEUES", payload: data.queue });
|
|
||||||
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.action === "delete") {
|
useEffect(() => {
|
||||||
dispatch({ type: "DELETE_QUEUE", payload: data.queueId });
|
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 })
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
if (data.action === 'delete') {
|
||||||
|
dispatch({ type: 'DELETE_QUEUE', payload: data.queueId })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
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 () => {
|
return () => {
|
||||||
socket.disconnect();
|
socket.disconnect()
|
||||||
};
|
}
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
const handleOpenQueueModal = () => {
|
const handleOpenQueueModal = () => {
|
||||||
setQueueModalOpen(true);
|
setQueueModalOpen(true)
|
||||||
setSelectedQueue(null);
|
setSelectedQueue(null)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleCloseQueueModal = () => {
|
const handleCloseQueueModal = () => {
|
||||||
setQueueModalOpen(false);
|
setQueueModalOpen(false)
|
||||||
setSelectedQueue(null);
|
setSelectedQueue(null)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleEditQueue = (queue) => {
|
const handleEditQueue = (queue) => {
|
||||||
setSelectedQueue(queue);
|
setSelectedQueue(queue)
|
||||||
setQueueModalOpen(true);
|
setQueueModalOpen(true)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleCloseConfirmationModal = () => {
|
const handleCloseConfirmationModal = () => {
|
||||||
setConfirmModalOpen(false);
|
setConfirmModalOpen(false)
|
||||||
setSelectedQueue(null);
|
setSelectedQueue(null)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleDeleteQueue = async (queueId) => {
|
const handleDeleteQueue = async (queueId) => {
|
||||||
try {
|
try {
|
||||||
await api.delete(`/queue/${queueId}`);
|
await api.delete(`/queue/${queueId}`)
|
||||||
toast.success(i18n.t("Queue deleted successfully!"));
|
toast.success(i18n.t('Queue deleted successfully!'))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
|
}
|
||||||
|
setSelectedQueue(null)
|
||||||
}
|
}
|
||||||
setSelectedQueue(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Can
|
<Can
|
||||||
|
@ -172,14 +203,15 @@ const Queues = () => {
|
||||||
<ConfirmationModal
|
<ConfirmationModal
|
||||||
title={
|
title={
|
||||||
selectedQueue &&
|
selectedQueue &&
|
||||||
`${i18n.t("queues.confirmationModal.deleteTitle")} ${selectedQueue.name
|
`${i18n.t('queues.confirmationModal.deleteTitle')} ${
|
||||||
|
selectedQueue.name
|
||||||
}?`
|
}?`
|
||||||
}
|
}
|
||||||
open={confirmModalOpen}
|
open={confirmModalOpen}
|
||||||
onClose={handleCloseConfirmationModal}
|
onClose={handleCloseConfirmationModal}
|
||||||
onConfirm={() => handleDeleteQueue(selectedQueue.id)}
|
onConfirm={() => handleDeleteQueue(selectedQueue.id)}
|
||||||
>
|
>
|
||||||
{i18n.t("queues.confirmationModal.deleteMessage")}
|
{i18n.t('queues.confirmationModal.deleteMessage')}
|
||||||
</ConfirmationModal>
|
</ConfirmationModal>
|
||||||
<QueueModal
|
<QueueModal
|
||||||
open={queueModalOpen}
|
open={queueModalOpen}
|
||||||
|
@ -187,8 +219,7 @@ const Queues = () => {
|
||||||
queueId={selectedQueue?.id}
|
queueId={selectedQueue?.id}
|
||||||
/>
|
/>
|
||||||
<MainHeader>
|
<MainHeader>
|
||||||
<Title>{i18n.t("queues.title")}</Title>
|
<Title>{i18n.t('queues.title')}</Title>
|
||||||
|
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
|
@ -200,29 +231,27 @@ const Queues = () => {
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={handleOpenQueueModal}
|
onClick={handleOpenQueueModal}
|
||||||
>
|
>
|
||||||
{i18n.t("queues.buttons.add")}
|
{i18n.t('queues.buttons.add')}
|
||||||
</Button>
|
</Button>
|
||||||
</MainHeaderButtonsWrapper>
|
</MainHeaderButtonsWrapper>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
</MainHeader>
|
</MainHeader>
|
||||||
<Paper className={classes.mainPaper} variant="outlined">
|
<Paper className={classes.mainPaper} variant="outlined">
|
||||||
<Table size="small">
|
<Table size="small">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("queues.table.name")}
|
{i18n.t('queues.table.name')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("queues.table.color")}
|
{i18n.t('queues.table.color')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("queues.table.greeting")}
|
{i18n.t('queues.table.greeting')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("queues.table.actions")}
|
{i18n.t('queues.table.actions')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
@ -238,7 +267,7 @@ const Queues = () => {
|
||||||
backgroundColor: queue.color,
|
backgroundColor: queue.color,
|
||||||
width: 60,
|
width: 60,
|
||||||
height: 20,
|
height: 20,
|
||||||
alignSelf: "center",
|
alignSelf: 'center',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -246,7 +275,7 @@ const Queues = () => {
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
<div className={classes.customTableCell}>
|
<div className={classes.customTableCell}>
|
||||||
<Typography
|
<Typography
|
||||||
style={{ width: 300, align: "center" }}
|
style={{ width: 300, align: 'center' }}
|
||||||
noWrap
|
noWrap
|
||||||
variant="body2"
|
variant="body2"
|
||||||
>
|
>
|
||||||
|
@ -255,25 +284,44 @@ const Queues = () => {
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
|
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="show-icon-edit-queue"
|
perform="show-icon-edit-queue"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
margin: 0,
|
||||||
|
padding: 0,
|
||||||
|
border: 'none',
|
||||||
|
display: 'inline',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{(settings &&
|
||||||
|
settings.length > 0 &&
|
||||||
|
getSettingValue('editQueue') &&
|
||||||
|
getSettingValue('editQueue') === 'enabled') |
|
||||||
|
(user.profile === 'master') ? (
|
||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => handleEditQueue(queue)}
|
onClick={() => handleEditQueue(queue)}
|
||||||
>
|
>
|
||||||
<Edit />
|
<Edit />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
) : (
|
||||||
|
<div></div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
// <IconButton
|
||||||
|
// size="small"
|
||||||
|
// onClick={() => handleEditQueue(queue)}
|
||||||
|
// >
|
||||||
|
// <Edit />
|
||||||
|
// </IconButton>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="show-icon-delete-queue"
|
perform="show-icon-delete-queue"
|
||||||
|
@ -281,15 +329,14 @@ const Queues = () => {
|
||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedQueue(queue);
|
setSelectedQueue(queue)
|
||||||
setConfirmModalOpen(true);
|
setConfirmModalOpen(true)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DeleteOutline />
|
<DeleteOutline />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
@ -301,7 +348,7 @@ const Queues = () => {
|
||||||
</MainContainer>
|
</MainContainer>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
export default Queues;
|
export default Queues
|
||||||
|
|
|
@ -1,128 +1,125 @@
|
||||||
import React, { useState, useEffect, useContext} from "react";
|
import React, { useState, useEffect, useContext } from 'react'
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from 'socket.io-client'
|
||||||
|
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import Paper from "@material-ui/core/Paper";
|
import Paper from '@material-ui/core/Paper'
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from '@material-ui/core/Typography'
|
||||||
import Container from "@material-ui/core/Container";
|
import Container from '@material-ui/core/Container'
|
||||||
import Select from "@material-ui/core/Select";
|
import Select from '@material-ui/core/Select'
|
||||||
import { toast } from "react-toastify";
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
import api from "../../services/api";
|
import api from '../../services/api'
|
||||||
import { i18n } from "../../translate/i18n.js";
|
import { i18n } from '../../translate/i18n.js'
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from '../../errors/toastError'
|
||||||
|
|
||||||
//--------
|
//--------
|
||||||
import { AuthContext } from "../../context/Auth/AuthContext";
|
import { AuthContext } from '../../context/Auth/AuthContext'
|
||||||
import { Can } from "../../components/Can";
|
|
||||||
|
import { Can } from '../../components/Can'
|
||||||
|
|
||||||
// import Button from "@material-ui/core/Button";
|
// import Button from "@material-ui/core/Button";
|
||||||
|
|
||||||
const useStyles = makeStyles(theme => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
root: {
|
root: {
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
padding: theme.spacing(4),
|
padding: theme.spacing(4),
|
||||||
},
|
},
|
||||||
|
|
||||||
paper: {
|
paper: {
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
|
|
||||||
settingOption: {
|
settingOption: {
|
||||||
marginLeft: "auto",
|
marginLeft: 'auto',
|
||||||
},
|
},
|
||||||
margin: {
|
margin: {
|
||||||
margin: theme.spacing(1),
|
margin: theme.spacing(1),
|
||||||
},
|
},
|
||||||
}));
|
}))
|
||||||
|
|
||||||
const Settings = () => {
|
const Settings = () => {
|
||||||
const classes = useStyles();
|
const classes = useStyles()
|
||||||
|
|
||||||
//--------
|
//--------
|
||||||
const { user } = useContext(AuthContext);
|
const { user } = useContext(AuthContext)
|
||||||
|
|
||||||
const [settings, setSettings] = useState([]);
|
const [settings, setSettings] = useState([])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchSession = async () => {
|
const fetchSession = async () => {
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get("/settings");
|
const { data } = await api.get('/settings')
|
||||||
setSettings(data);
|
setSettings(data)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
fetchSession();
|
fetchSession()
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
|
||||||
|
|
||||||
socket.on("settings", data => {
|
socket.on('settings', (data) => {
|
||||||
if (data.action === "update") {
|
console.log('settings updated ----------------------------')
|
||||||
setSettings(prevState => {
|
|
||||||
const aux = [...prevState];
|
if (data.action === 'update') {
|
||||||
const settingIndex = aux.findIndex(s => s.key === data.setting.key);
|
setSettings((prevState) => {
|
||||||
aux[settingIndex].value = data.setting.value;
|
const aux = [...prevState]
|
||||||
return aux;
|
const settingIndex = aux.findIndex((s) => s.key === data.setting.key)
|
||||||
});
|
aux[settingIndex].value = data.setting.value
|
||||||
|
return aux
|
||||||
|
})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.disconnect();
|
socket.disconnect()
|
||||||
};
|
}
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
const handleChangeSetting = async e => {
|
useEffect(() => {
|
||||||
const selectedValue = e.target.value;
|
console.log('------> settings: ', settings)
|
||||||
const settingKey = e.target.name;
|
}, [settings])
|
||||||
|
|
||||||
|
const handleChangeSetting = async (e) => {
|
||||||
|
const selectedValue = e.target.value
|
||||||
|
const settingKey = e.target.name
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.put(`/settings/${settingKey}`, {
|
await api.put(`/settings/${settingKey}`, {
|
||||||
value: selectedValue,
|
value: selectedValue,
|
||||||
});
|
})
|
||||||
toast.success(i18n.t("settings.success"));
|
toast.success(i18n.t('settings.success'))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const getSettingValue = key => {
|
const getSettingValue = (key) => {
|
||||||
const { value } = settings.find(s => s.key === key);
|
const { value } = settings.find((s) => s.key === key)
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
return value
|
||||||
// const handleEdit = () => {
|
}
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={user.profile}
|
role={user.profile}
|
||||||
perform="settings-view:show"
|
perform="settings-view:show"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<Container className={classes.container} maxWidth="sm">
|
<Container className={classes.container} maxWidth="sm">
|
||||||
<Typography variant="body2" gutterBottom>
|
<Typography variant="body2" gutterBottom>
|
||||||
{i18n.t("settings.title")}
|
{i18n.t('settings.title')}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Paper className={classes.paper}>
|
<Paper className={classes.paper}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1">
|
||||||
{i18n.t("settings.settings.userCreation.name")}
|
{i18n.t('settings.settings.userCreation.name')}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
|
@ -132,59 +129,79 @@ const Settings = () => {
|
||||||
id="userCreation-setting"
|
id="userCreation-setting"
|
||||||
name="userCreation"
|
name="userCreation"
|
||||||
value={
|
value={
|
||||||
settings && settings.length > 0 && getSettingValue("userCreation")
|
settings &&
|
||||||
|
settings.length > 0 &&
|
||||||
|
getSettingValue('userCreation')
|
||||||
}
|
}
|
||||||
className={classes.settingOption}
|
className={classes.settingOption}
|
||||||
onChange={handleChangeSetting}
|
onChange={handleChangeSetting}
|
||||||
>
|
>
|
||||||
<option value="enabled">
|
<option value="enabled">
|
||||||
{i18n.t("settings.settings.userCreation.options.enabled")}
|
{i18n.t('settings.settings.userCreation.options.enabled')}
|
||||||
</option>
|
</option>
|
||||||
<option value="disabled">
|
<option value="disabled">
|
||||||
{i18n.t("settings.settings.userCreation.options.disabled")}
|
{i18n.t('settings.settings.userCreation.options.disabled')}
|
||||||
</option>
|
</option>
|
||||||
</Select>
|
</Select>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={classes.root}>
|
||||||
{/* <div className={classes.root}>
|
|
||||||
<Container className={classes.container} maxWidth="sm">
|
<Container className={classes.container} maxWidth="sm">
|
||||||
<Typography variant="body2" gutterBottom>
|
|
||||||
Application name
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Paper className={classes.paper}>
|
<Paper className={classes.paper}>
|
||||||
|
<Typography variant="body1">Editar ura</Typography>
|
||||||
|
|
||||||
<Typography variant="body1">
|
<Select
|
||||||
Estudio Face
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
margin="dense"
|
margin="dense"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
id="applicationName-setting"
|
native
|
||||||
name="applicationName"
|
id="editURA-setting"
|
||||||
color="primary"
|
name="editURA"
|
||||||
onClick={(e) => handleEdit()}
|
value={
|
||||||
|
settings &&
|
||||||
|
settings.length > 0 &&
|
||||||
|
getSettingValue('editURA')
|
||||||
|
}
|
||||||
className={classes.settingOption}
|
className={classes.settingOption}
|
||||||
|
onChange={handleChangeSetting}
|
||||||
>
|
>
|
||||||
{"EDIT"}
|
<option value="enabled">Ativado</option>
|
||||||
</Button>
|
<option value="disabled">Desativado</option>
|
||||||
|
</Select>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
</Container>
|
</Container>
|
||||||
</div> */}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={classes.root}>
|
||||||
|
<Container className={classes.container} maxWidth="sm">
|
||||||
|
<Paper className={classes.paper}>
|
||||||
|
<Typography variant="body1">Editar fila</Typography>
|
||||||
|
|
||||||
|
<Select
|
||||||
|
margin="dense"
|
||||||
|
variant="outlined"
|
||||||
|
native
|
||||||
|
id="editQueue-setting"
|
||||||
|
name="editQueue"
|
||||||
|
value={
|
||||||
|
settings &&
|
||||||
|
settings.length > 0 &&
|
||||||
|
getSettingValue('editQueue')
|
||||||
|
}
|
||||||
|
className={classes.settingOption}
|
||||||
|
onChange={handleChangeSetting}
|
||||||
|
>
|
||||||
|
<option value="enabled">Ativado</option>
|
||||||
|
<option value="disabled">Desativado</option>
|
||||||
|
</Select>
|
||||||
|
</Paper>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
);
|
export default Settings
|
||||||
};
|
|
||||||
|
|
||||||
export default Settings;
|
|
||||||
|
|
|
@ -5,55 +5,54 @@ const rules = {
|
||||||
|
|
||||||
admin: {
|
admin: {
|
||||||
static: [
|
static: [
|
||||||
//"show-icon-edit-whatsapp",
|
'show-icon-edit-whatsapp',
|
||||||
|
'show-icon-edit-queue',
|
||||||
"drawer-admin-items:view",
|
|
||||||
"tickets-manager:showall",
|
|
||||||
"user-modal:editProfile",
|
|
||||||
"user-modal:editQueues",
|
|
||||||
"ticket-options:deleteTicket",
|
|
||||||
"contacts-page:deleteContact",
|
|
||||||
"contacts-page:import-csv-contacts",
|
|
||||||
"connections-view:show",
|
|
||||||
"dashboard-view:show",
|
|
||||||
"queues-view:show",
|
|
||||||
"user-view:show",
|
|
||||||
"ticket-report:show",
|
|
||||||
|
|
||||||
|
'drawer-admin-items:view',
|
||||||
|
'tickets-manager:showall',
|
||||||
|
'user-modal:editProfile',
|
||||||
|
'user-modal:editQueues',
|
||||||
|
'ticket-options:deleteTicket',
|
||||||
|
'contacts-page:deleteContact',
|
||||||
|
'contacts-page:import-csv-contacts',
|
||||||
|
'connections-view:show',
|
||||||
|
'dashboard-view:show',
|
||||||
|
'queues-view:show',
|
||||||
|
'user-view:show',
|
||||||
|
'ticket-report:show',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
master: {
|
master: {
|
||||||
static: [
|
static: [
|
||||||
|
'url-remote-session:show',
|
||||||
|
'show-icon-edit-whatsapp',
|
||||||
|
'show-icon-add-queue',
|
||||||
|
'show-icon-edit-queue',
|
||||||
|
'show-icon-delete-queue',
|
||||||
|
'space-disk-info:show',
|
||||||
|
|
||||||
"show-icon-edit-whatsapp",
|
'drawer-admin-items:view',
|
||||||
"show-icon-add-queue",
|
'tickets-manager:showall',
|
||||||
"show-icon-edit-queue",
|
'user-modal:editProfile',
|
||||||
"show-icon-delete-queue",
|
'user-modal:editQueues',
|
||||||
"space-disk-info:show",
|
'ticket-options:deleteTicket',
|
||||||
|
'contacts-page:deleteContact',
|
||||||
|
'contacts-page:import-contacts',
|
||||||
"drawer-admin-items:view",
|
'contacts-page:import-csv-contacts',
|
||||||
"tickets-manager:showall",
|
'connections-view:show',
|
||||||
"user-modal:editProfile",
|
'dashboard-view:show',
|
||||||
"user-modal:editQueues",
|
'queues-view:show',
|
||||||
"ticket-options:deleteTicket",
|
'user-view:show',
|
||||||
"contacts-page:deleteContact",
|
'settings-view:show',
|
||||||
"contacts-page:import-contacts",
|
'btn-add-user',
|
||||||
"contacts-page:import-csv-contacts",
|
'icon-remove-user',
|
||||||
"connections-view:show",
|
'btn-add-whatsapp',
|
||||||
"dashboard-view:show",
|
'btn-remove-whatsapp',
|
||||||
"queues-view:show",
|
'ticket-report:show',
|
||||||
"user-view:show",
|
'connection-button:show',
|
||||||
"settings-view:show",
|
|
||||||
"btn-add-user",
|
|
||||||
"icon-remove-user",
|
|
||||||
"btn-add-whatsapp",
|
|
||||||
"btn-remove-whatsapp",
|
|
||||||
"ticket-report:show",
|
|
||||||
"connection-button:show"
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
export default rules;
|
export default rules
|
||||||
|
|
Loading…
Reference in New Issue