finalização do recurso de encerramento de ticket automatico e expiração de ticket
parent
417f947263
commit
c8ea53a4bc
|
@ -5,6 +5,8 @@ import AppError from "../errors/AppError";
|
|||
|
||||
import UpdateSettingService from "../services/SettingServices/UpdateSettingService";
|
||||
import ListSettingsService from "../services/SettingServices/ListSettingsService";
|
||||
import updateSettingTicket from "../services/SettingServices/UpdateSettingTicket";
|
||||
import SettingTicket from "../models/SettingTicket";
|
||||
|
||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||
// if (req.user.profile !== "master") {
|
||||
|
@ -12,8 +14,37 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
|||
// }
|
||||
|
||||
const settings = await ListSettingsService();
|
||||
const outBusinessHours = await SettingTicket.findOne({
|
||||
where: { key: "outBusinessHours" }
|
||||
});
|
||||
const ticketExpiration = await SettingTicket.findOne({
|
||||
where: { key: "ticketExpiration" }
|
||||
});
|
||||
|
||||
return res.status(200).json(settings);
|
||||
return res.status(200).json({ settings, outBusinessHours, ticketExpiration });
|
||||
};
|
||||
|
||||
export const updateTicketSettings = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
const { outBusinessHours, ticketExpiration } = req.body;
|
||||
|
||||
if (outBusinessHours && Object.keys(outBusinessHours).length > 0) {
|
||||
await updateSettingTicket({
|
||||
...outBusinessHours,
|
||||
key: "outBusinessHours"
|
||||
});
|
||||
}
|
||||
|
||||
if (ticketExpiration && Object.keys(ticketExpiration).length > 0) {
|
||||
await updateSettingTicket({
|
||||
...ticketExpiration,
|
||||
key: "ticketExpiration"
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).json({ outBusinessHours, ticketExpiration });
|
||||
};
|
||||
|
||||
export const update = async (
|
||||
|
|
|
@ -14,6 +14,7 @@ import QuickAnswer from "../models/QuickAnswer";
|
|||
import SchedulingNotify from "../models/SchedulingNotify";
|
||||
import StatusChatEnd from "../models/StatusChatEnd";
|
||||
import UserOnlineTime from "../models/UserOnlineTime";
|
||||
import SettingTicket from "../models/SettingTicket";
|
||||
// eslint-disable-next-line
|
||||
const dbConfig = require("../config/database");
|
||||
// import dbConfig from "../config/database";
|
||||
|
@ -35,7 +36,8 @@ const models = [
|
|||
|
||||
SchedulingNotify,
|
||||
StatusChatEnd,
|
||||
UserOnlineTime,
|
||||
UserOnlineTime,
|
||||
SettingTicket
|
||||
];
|
||||
|
||||
sequelize.addModels(models);
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import { QueryInterface, DataTypes } from "sequelize"
|
||||
|
||||
module.exports = {
|
||||
up: (queryInterface: QueryInterface) => {
|
||||
return queryInterface.createTable("SettingTickets", {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
allowNull: false
|
||||
},
|
||||
message: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true
|
||||
},
|
||||
startTime: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true
|
||||
},
|
||||
endTime: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true
|
||||
},
|
||||
value: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
key: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
createdAt: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false
|
||||
},
|
||||
updatedAt: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
down: (queryInterface: QueryInterface) => {
|
||||
return queryInterface.dropTable("SettingTickets");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import { QueryInterface } from "sequelize";
|
||||
|
||||
module.exports = {
|
||||
up: (queryInterface: QueryInterface) => {
|
||||
return queryInterface.bulkInsert(
|
||||
"SettingTickets",
|
||||
[
|
||||
{
|
||||
message: "",
|
||||
startTime: new Date(),
|
||||
endTime: new Date(),
|
||||
value: "disabled",
|
||||
key: "outBusinessHours",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
},
|
||||
{
|
||||
message: "",
|
||||
startTime: new Date(),
|
||||
endTime: new Date(),
|
||||
value: "disabled",
|
||||
key: "ticketExpiration",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
}
|
||||
],
|
||||
{}
|
||||
);
|
||||
},
|
||||
|
||||
down: (queryInterface: QueryInterface) => {
|
||||
return queryInterface.bulkDelete("SettingTickets", {});
|
||||
}
|
||||
};
|
|
@ -0,0 +1,84 @@
|
|||
import SettingTicket from "../models/SettingTicket";
|
||||
import ListTicketTimeLife from "../services/TicketServices/ListTicketTimeLife";
|
||||
import UpdateTicketService from "../services/TicketServices/UpdateTicketService";
|
||||
import BotIsOnQueue from "./BotIsOnQueue";
|
||||
|
||||
import {
|
||||
format as _format,
|
||||
isWithinInterval,
|
||||
parse,
|
||||
subMinutes
|
||||
} from "date-fns";
|
||||
|
||||
import ptBR from "date-fns/locale/pt-BR";
|
||||
import { splitDateTime } from "./SplitDateTime";
|
||||
|
||||
const fsPromises = require("fs/promises");
|
||||
const fs = require("fs");
|
||||
|
||||
let timer: any;
|
||||
|
||||
const AutoCloseTickets = async () => {
|
||||
try {
|
||||
// const botInfo = await BotIsOnQueue('botqueue')
|
||||
|
||||
// if (!botInfo.userIdBot) return
|
||||
|
||||
const ticketExpiration = await SettingTicket.findOne({
|
||||
where: { key: "ticketExpiration" }
|
||||
});
|
||||
|
||||
if (ticketExpiration && ticketExpiration.value == "enabled") {
|
||||
const startTime = splitDateTime(
|
||||
new Date(
|
||||
_format(new Date(ticketExpiration.startTime), "yyyy-MM-dd HH:mm:ss", {
|
||||
locale: ptBR
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
const seconds = timeStringToSeconds(startTime.fullTime);
|
||||
|
||||
console.log("Ticket seconds: ", seconds);
|
||||
|
||||
let tickets: any = await ListTicketTimeLife({
|
||||
timeseconds: seconds,
|
||||
status: "open"
|
||||
});
|
||||
|
||||
console.log("tickets: ", tickets);
|
||||
|
||||
for (let i = 0; i < tickets.length; i++) {
|
||||
|
||||
await UpdateTicketService({
|
||||
ticketData: { status: "closed", statusChatEnd: "FINALIZADO" },
|
||||
ticketId: tickets[i].ticket_id,
|
||||
msg: ticketExpiration.message
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("There was an error on try close the bot tickets: ", error);
|
||||
}
|
||||
};
|
||||
|
||||
function timeStringToSeconds(timeString: any) {
|
||||
const [hours, minutes, seconds] = timeString.split(":").map(Number);
|
||||
return hours * 3600 + minutes * 60 + seconds;
|
||||
}
|
||||
|
||||
const schedule = async () => {
|
||||
try {
|
||||
clearInterval(timer);
|
||||
|
||||
await AutoCloseTickets();
|
||||
} catch (error) {
|
||||
console.log("error on schedule: ", error);
|
||||
} finally {
|
||||
timer = setInterval(schedule, 60000);
|
||||
}
|
||||
};
|
||||
|
||||
timer = setInterval(schedule, 60000);
|
||||
|
||||
export default schedule;
|
|
@ -0,0 +1,40 @@
|
|||
import {
|
||||
Table,
|
||||
Column,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Model,
|
||||
PrimaryKey,
|
||||
AutoIncrement
|
||||
} from "sequelize-typescript";
|
||||
|
||||
@Table
|
||||
class SettingTicket extends Model<SettingTicket> {
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
id: number;
|
||||
|
||||
@Column
|
||||
message: string;
|
||||
|
||||
@Column
|
||||
startTime: Date;
|
||||
|
||||
@Column
|
||||
endTime: Date;
|
||||
|
||||
@Column
|
||||
value: string;
|
||||
|
||||
@Column
|
||||
key: string;
|
||||
|
||||
@CreatedAt
|
||||
createdAt: Date;
|
||||
|
||||
@UpdatedAt
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export default SettingTicket;
|
|
@ -3,13 +3,21 @@ import isAuth from "../middleware/isAuth";
|
|||
|
||||
import * as SettingController from "../controllers/SettingController";
|
||||
|
||||
const settingRoutes = Router();
|
||||
const settingRoutes = Router();
|
||||
|
||||
settingRoutes.get("/settings", SettingController.index);
|
||||
|
||||
// routes.get("/settings/:settingKey", isAuth, SettingsController.show);
|
||||
|
||||
settingRoutes.put(
|
||||
"/settings/ticket",
|
||||
isAuth,
|
||||
SettingController.updateTicketSettings
|
||||
);
|
||||
|
||||
|
||||
// change setting key to key in future
|
||||
settingRoutes.put("/settings/:settingKey", isAuth, SettingController.update);
|
||||
|
||||
|
||||
export default settingRoutes;
|
||||
|
|
|
@ -10,6 +10,7 @@ import { cacheSize, flushCache, loadTicketsCache } from "./helpers/TicketCache";
|
|||
import { loadContactsCache } from "./helpers/ContactsCache";
|
||||
import { loadSchedulesCache } from "./helpers/SchedulingNotifyCache";
|
||||
import { delRestoreControllFile } from "./helpers/RestoreControll";
|
||||
import "./helpers/AutoCloseTickets";
|
||||
|
||||
import "./helpers/SchedulingNotifySendMessage"
|
||||
import axios from "axios";
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import AppError from "../../errors/AppError";
|
||||
import SettingTicket from "../../models/SettingTicket";
|
||||
|
||||
interface Request {
|
||||
key: string;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
value: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
const updateSettingTicket = async ({
|
||||
key,
|
||||
startTime,
|
||||
endTime,
|
||||
value,
|
||||
message
|
||||
}: Request): Promise<SettingTicket | undefined> => {
|
||||
try {
|
||||
const businessHours = await SettingTicket.findOne({ where: { key } });
|
||||
|
||||
if (!businessHours) {
|
||||
throw new AppError("ERR_NO_SETTING_FOUND", 404);
|
||||
}
|
||||
|
||||
await businessHours.update({ startTime, endTime, message, value });
|
||||
|
||||
return businessHours;
|
||||
} catch (error: any) {
|
||||
console.error("===> Error on UpdateSettingService.ts file: \n", error);
|
||||
throw new AppError(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
export default updateSettingTicket;
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
import { Sequelize, } from "sequelize";
|
||||
|
||||
const dbConfig = require("../../config/database");
|
||||
const sequelize = new Sequelize(dbConfig);
|
||||
const { QueryTypes } = require('sequelize');
|
||||
|
||||
import { splitDateTime } from "../../helpers/SplitDateTime";
|
||||
import format from 'date-fns/format';
|
||||
import ptBR from 'date-fns/locale/pt-BR';
|
||||
|
||||
|
||||
interface Request {
|
||||
timeseconds: string | number;
|
||||
status: string;
|
||||
userId?: string | number;
|
||||
}
|
||||
|
||||
const ListTicketTimeLife = async ({timeseconds, status, userId }: Request): Promise<any[]> => {
|
||||
|
||||
let tickets = []
|
||||
|
||||
let currentDate = format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR })
|
||||
|
||||
// console.log('------------------> currentDate: ', currentDate)
|
||||
|
||||
if (userId) {
|
||||
// CONSULTANDO FILAS PELO ID DO USUARIO
|
||||
tickets = await sequelize.query(`select user.id as user_id, user.name as user_name, t.id as ticket_id from Tickets as t inner join Users as user on
|
||||
t.userId = user.id and user.name = 'botqueue' and t.status='${status}' and (TIMESTAMPDIFF(SECOND, t.updatedAt, '${currentDate}')) >= ${timeseconds};`, { type: QueryTypes.SELECT });
|
||||
|
||||
} else {
|
||||
|
||||
// CONSULTANDO FILAS PELO USUARIO
|
||||
tickets = await sequelize.query(`select id as ticket_id from Tickets where status='${status}' and
|
||||
(TIMESTAMPDIFF(SECOND, updatedAt, '${currentDate}')) >= ${timeseconds};`, { type: QueryTypes.SELECT });
|
||||
|
||||
}
|
||||
|
||||
return tickets;
|
||||
};
|
||||
|
||||
export default ListTicketTimeLife;
|
||||
|
||||
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ const UpdateTicketService = async ({
|
|||
|
||||
await ticket.reload();
|
||||
|
||||
if (msg.length > 0) {
|
||||
if (msg?.trim().length > 0) {
|
||||
|
||||
setTimeout(async () => {
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,6 +20,7 @@
|
|||
"dotenv": "^16.0.1",
|
||||
"emoji-mart": "^3.0.1",
|
||||
"formik": "^2.2.0",
|
||||
"formik-material-ui-pickers": "^1.0.0-alpha.1",
|
||||
"i18next": "^19.8.2",
|
||||
"i18next-browser-languagedetector": "^6.0.1",
|
||||
"js-file-download": "^0.4.12",
|
||||
|
|
|
@ -0,0 +1,304 @@
|
|||
import React, { useState, useEffect, } from 'react'
|
||||
// import * as Yup from 'yup'
|
||||
import { Formik, Form, Field, } from 'formik'
|
||||
import { toast } from 'react-toastify'
|
||||
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { green } from '@material-ui/core/colors'
|
||||
|
||||
import { TimePicker } from 'formik-material-ui-pickers'
|
||||
|
||||
import DateFnsUtils from '@date-io/date-fns'
|
||||
|
||||
import ptBrLocale from "date-fns/locale/pt-BR"
|
||||
|
||||
|
||||
import {
|
||||
MuiPickersUtilsProvider,
|
||||
} from '@material-ui/pickers'
|
||||
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
Button,
|
||||
DialogActions,
|
||||
CircularProgress,
|
||||
TextField,
|
||||
Switch,
|
||||
FormControlLabel,
|
||||
} from '@material-ui/core'
|
||||
|
||||
import api from '../../services/api'
|
||||
import { i18n } from '../../translate/i18n'
|
||||
import toastError from '../../errors/toastError'
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
|
||||
multFieldLine: {
|
||||
display: 'flex',
|
||||
'& > *:not(:last-child)': {
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
},
|
||||
|
||||
btnWrapper: {
|
||||
position: 'relative',
|
||||
},
|
||||
|
||||
buttonProgress: {
|
||||
color: green[500],
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
marginTop: -12,
|
||||
marginLeft: -12,
|
||||
},
|
||||
}))
|
||||
|
||||
// const SessionSchema = Yup.object().shape({
|
||||
// name: Yup.string()
|
||||
// .min(2, 'Too Short!')
|
||||
// .max(100, 'Too Long!')
|
||||
// .required('Required'),
|
||||
// })
|
||||
|
||||
const ConfigModal = ({ open, onClose, change }) => {
|
||||
const classes = useStyles()
|
||||
const initialState = {
|
||||
startTimeBus: new Date(),
|
||||
endTimeBus: new Date(),
|
||||
messageBus: '',
|
||||
businessTimeEnalbe: false,
|
||||
ticketTimeExpiration: new Date(),
|
||||
ticketExpirationMsg: '',
|
||||
ticketExpirationEnable: false,
|
||||
}
|
||||
|
||||
const [config, setConfig] = useState(initialState)
|
||||
|
||||
useEffect(() => {
|
||||
const fetchSession = async () => {
|
||||
|
||||
try {
|
||||
const { data } = await api.get('/settings')
|
||||
|
||||
setConfig({
|
||||
startTimeBus: data.outBusinessHours.startTime,
|
||||
endTimeBus: data.outBusinessHours.endTime,
|
||||
messageBus: data.outBusinessHours.message,
|
||||
businessTimeEnalbe: data.outBusinessHours.value === 'enabled' ? true : false,
|
||||
ticketTimeExpiration: data.ticketExpiration.startTime,
|
||||
ticketExpirationMsg: data.ticketExpiration.message,
|
||||
ticketExpirationEnable: data.ticketExpiration.value === 'enabled' ? true : false
|
||||
})
|
||||
|
||||
} catch (err) {
|
||||
toastError(err)
|
||||
}
|
||||
}
|
||||
fetchSession()
|
||||
}, [change])
|
||||
|
||||
const handleSaveConfig = async (values) => {
|
||||
|
||||
values = {
|
||||
outBusinessHours: {
|
||||
startTime: values.startTimeBus,
|
||||
endTime: values.endTimeBus,
|
||||
message: values.messageBus,
|
||||
value: values.businessTimeEnalbe ? 'enabled' : 'disabled'
|
||||
},
|
||||
ticketExpiration: {
|
||||
startTime: values.ticketTimeExpiration,
|
||||
message: values.ticketExpirationMsg,
|
||||
value: values.ticketExpirationEnable ? 'enabled' : 'disabled'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
|
||||
await api.put(`/settings/ticket`, values)
|
||||
|
||||
toast.success('Atualização realizada com sucesso!')
|
||||
handleClose()
|
||||
|
||||
} catch (err) {
|
||||
toastError(err)
|
||||
}
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
onClose()
|
||||
// setConfig(initialState)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
maxWidth="sm"
|
||||
fullWidth
|
||||
scroll="paper"
|
||||
>
|
||||
<DialogTitle>
|
||||
Configurações
|
||||
</DialogTitle>
|
||||
|
||||
|
||||
<Formik
|
||||
initialValues={config}
|
||||
enableReinitialize={true}
|
||||
// validationSchema={SessionSchema}
|
||||
onSubmit={(values, actions) => {
|
||||
|
||||
setTimeout(() => {
|
||||
handleSaveConfig(values)
|
||||
actions.setSubmitting(false)
|
||||
}, 100)
|
||||
}}
|
||||
>
|
||||
{({ values, touched, errors, isSubmitting }) => (
|
||||
<MuiPickersUtilsProvider utils={DateFnsUtils} locale={ptBrLocale}>
|
||||
<Form>
|
||||
|
||||
<DialogContent dividers>
|
||||
|
||||
<div className={classes.multFieldLine}>
|
||||
<Field
|
||||
component={TimePicker}
|
||||
name="startTimeBus"
|
||||
label="Inicio atendimento"
|
||||
ampm={false}
|
||||
openTo="hours"
|
||||
views={['hours', 'minutes',]}
|
||||
format="HH:mm"
|
||||
/>
|
||||
{' '}
|
||||
<Field
|
||||
component={TimePicker}
|
||||
name="endTimeBus"
|
||||
label="Fim atendimento"
|
||||
ampm={false}
|
||||
openTo="hours"
|
||||
views={['hours', 'minutes',]}
|
||||
format="HH:mm"
|
||||
/>
|
||||
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Field
|
||||
as={Switch}
|
||||
color="primary"
|
||||
name="businessTimeEnalbe"
|
||||
checked={values.businessTimeEnalbe}
|
||||
/>
|
||||
}
|
||||
label={'Ativar/Desativar'} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Field
|
||||
as={TextField}
|
||||
label={'Mensagem fora do horário de atendimento'}
|
||||
type="messageBus"
|
||||
multiline
|
||||
rows={5}
|
||||
fullWidth
|
||||
name="messageBus"
|
||||
error={
|
||||
touched.messageBus && Boolean(errors.messageBus)
|
||||
}
|
||||
helperText={
|
||||
touched.messageBus && errors.messageBus
|
||||
}
|
||||
variant="outlined"
|
||||
margin="dense"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<div className={classes.multFieldLine}>
|
||||
<Field
|
||||
component={TimePicker}
|
||||
name="ticketTimeExpiration"
|
||||
label="Ticket expira em hh:mm"
|
||||
ampm={false}
|
||||
openTo="hours"
|
||||
views={['hours', 'minutes',]}
|
||||
format="HH:mm"
|
||||
/>
|
||||
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Field
|
||||
as={Switch}
|
||||
color="primary"
|
||||
name="ticketExpirationEnable"
|
||||
checked={values.ticketExpirationEnable}
|
||||
/>
|
||||
}
|
||||
label={'Ativar/Desativar'}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Field
|
||||
as={TextField}
|
||||
label={'Mensagem por falta de atividade no atendimento'}
|
||||
type="ticketExpirationMsg"
|
||||
multiline
|
||||
rows={5}
|
||||
fullWidth
|
||||
name="ticketExpirationMsg"
|
||||
error={
|
||||
touched.ticketExpirationMsg && Boolean(errors.ticketExpirationMsg)
|
||||
}
|
||||
helperText={
|
||||
touched.ticketExpirationMsg && errors.ticketExpirationMsg
|
||||
}
|
||||
variant="outlined"
|
||||
margin="dense"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={handleClose}
|
||||
color="secondary"
|
||||
disabled={isSubmitting}
|
||||
variant="outlined"
|
||||
>
|
||||
{i18n.t('whatsappModal.buttons.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
disabled={isSubmitting}
|
||||
variant="contained"
|
||||
className={classes.btnWrapper}
|
||||
>
|
||||
{isSubmitting ? (
|
||||
<CircularProgress
|
||||
size={24}
|
||||
className={classes.buttonProgress}
|
||||
/>
|
||||
) : 'Salvar'}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Form>
|
||||
</MuiPickersUtilsProvider>
|
||||
)}
|
||||
</Formik>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(ConfigModal)
|
|
@ -76,7 +76,7 @@ const useAuth = () => {
|
|||
const fetchSession = async () => {
|
||||
try {
|
||||
const { data } = await api.get('/settings')
|
||||
setSetting(data)
|
||||
setSetting(data.settings)
|
||||
} catch (err) {
|
||||
toastError(err)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ import openSocket from 'socket.io-client'
|
|||
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { green } from '@material-ui/core/colors'
|
||||
|
||||
import Settings from "@material-ui/icons/Settings";
|
||||
|
||||
import {
|
||||
Button,
|
||||
TableBody,
|
||||
|
@ -47,6 +50,7 @@ import toastError from '../../errors/toastError'
|
|||
//--------
|
||||
import { AuthContext } from '../../context/Auth/AuthContext'
|
||||
import { Can } from '../../components/Can'
|
||||
import ConfigModal from '../../components/ConfigModal'
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
mainPaper: {
|
||||
|
@ -107,6 +111,7 @@ const Connections = () => {
|
|||
|
||||
const { whatsApps, loading } = useContext(WhatsAppsContext)
|
||||
const [whatsAppModalOpen, setWhatsAppModalOpen] = useState(false)
|
||||
const [configModalOpen, setConfigModalOpen] = useState(false)
|
||||
const [qrModalOpen, setQrModalOpen] = useState(false)
|
||||
const [selectedWhatsApp, setSelectedWhatsApp] = useState(null)
|
||||
const [confirmModalOpen, setConfirmModalOpen] = useState(false)
|
||||
|
@ -134,7 +139,7 @@ const Connections = () => {
|
|||
const fetchSession = async () => {
|
||||
try {
|
||||
const { data } = await api.get('/settings')
|
||||
setSettings(data)
|
||||
setSettings(data.settings)
|
||||
} catch (err) {
|
||||
toastError(err)
|
||||
}
|
||||
|
@ -205,6 +210,13 @@ const Connections = () => {
|
|||
setWhatsAppModalOpen(true)
|
||||
}
|
||||
|
||||
const handleOpenConfigModal = () => {
|
||||
setConfigModalOpen(true)
|
||||
}
|
||||
|
||||
const handleCloseConfigModal = () => {
|
||||
setConfigModalOpen(false)
|
||||
}
|
||||
const handleCloseWhatsAppModal = useCallback(() => {
|
||||
setWhatsAppModalOpen(false)
|
||||
setSelectedWhatsApp(null)
|
||||
|
@ -307,17 +319,17 @@ const Connections = () => {
|
|||
{(whatsApp.status === 'CONNECTED' ||
|
||||
whatsApp.status === 'PAIRING' ||
|
||||
whatsApp.status === 'TIMEOUT') && (
|
||||
<Button
|
||||
size="small"
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => {
|
||||
handleOpenConfirmationModal('disconnect', whatsApp.id)
|
||||
}}
|
||||
>
|
||||
{i18n.t('connections.buttons.disconnect')}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
size="small"
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => {
|
||||
handleOpenConfirmationModal('disconnect', whatsApp.id)
|
||||
}}
|
||||
>
|
||||
{i18n.t('connections.buttons.disconnect')}
|
||||
</Button>
|
||||
)}
|
||||
{whatsApp.status === 'OPENING' && (
|
||||
<Button size="small" variant="outlined" disabled color="default">
|
||||
{i18n.t('connections.buttons.connecting')}
|
||||
|
@ -454,10 +466,24 @@ const Connections = () => {
|
|||
whatsAppId={!qrModalOpen && selectedWhatsApp?.id}
|
||||
/>
|
||||
|
||||
<ConfigModal
|
||||
open={configModalOpen}
|
||||
onClose={handleCloseConfigModal}
|
||||
change={configModalOpen}
|
||||
/>
|
||||
|
||||
<MainHeader>
|
||||
<Title>{i18n.t('connections.title')}</Title>
|
||||
|
||||
<MainHeaderButtonsWrapper>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleOpenConfigModal}
|
||||
>
|
||||
<Settings/>
|
||||
</Button>
|
||||
<Can
|
||||
role={user.profile}
|
||||
perform="btn-add-whatsapp"
|
||||
|
@ -664,8 +690,8 @@ const Connections = () => {
|
|||
settings.length > 0 &&
|
||||
getSettingValue('editURA') &&
|
||||
getSettingValue('editURA') ===
|
||||
'enabled') |
|
||||
(user.profile === 'master') ? (
|
||||
'enabled') |
|
||||
(user.profile === 'master') ? (
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() =>
|
||||
|
|
|
@ -121,7 +121,7 @@ const Queues = () => {
|
|||
const fetchSession = async () => {
|
||||
try {
|
||||
const { data } = await api.get('/settings')
|
||||
setSettings(data)
|
||||
setSettings(data.settings)
|
||||
} catch (err) {
|
||||
toastError(err)
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ const Settings = () => {
|
|||
const fetchSession = async () => {
|
||||
try {
|
||||
const { data } = await api.get('/settings')
|
||||
setSettings(data)
|
||||
setSettings(data.settings)
|
||||
} catch (err) {
|
||||
toastError(err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue