From 67ad73a8bdb1b6966ea343696ec9ce68f0a0ab86 Mon Sep 17 00:00:00 2001 From: Ricardo Paes Date: Wed, 23 Feb 2022 11:06:31 -0300 Subject: [PATCH 01/12] :sparkles: add user association with whatsapps --- .../20220223095932-add-whatsapp-to-user.ts | 17 +++++++++++++++++ backend/src/models/User.ts | 12 +++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 backend/src/database/migrations/20220223095932-add-whatsapp-to-user.ts diff --git a/backend/src/database/migrations/20220223095932-add-whatsapp-to-user.ts b/backend/src/database/migrations/20220223095932-add-whatsapp-to-user.ts new file mode 100644 index 0000000..fc53178 --- /dev/null +++ b/backend/src/database/migrations/20220223095932-add-whatsapp-to-user.ts @@ -0,0 +1,17 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Users", "whatsappId", { + type: DataTypes.INTEGER, + references: { model: "Whatsapps", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL", + allowNull: true + },); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Users", "whatsappId"); + } +}; diff --git a/backend/src/models/User.ts b/backend/src/models/User.ts index 9be664b..73edff4 100644 --- a/backend/src/models/User.ts +++ b/backend/src/models/User.ts @@ -11,12 +11,15 @@ import { AutoIncrement, Default, HasMany, - BelongsToMany + BelongsToMany, + ForeignKey, + BelongsTo } from "sequelize-typescript"; import { hash, compare } from "bcryptjs"; import Ticket from "./Ticket"; import Queue from "./Queue"; import UserQueue from "./UserQueue"; +import Whatsapp from "./Whatsapp"; @Table class User extends Model { @@ -45,6 +48,13 @@ class User extends Model { @Column profile: string; + @ForeignKey(() => Whatsapp) + @Column + whatsappId: number; + + @BelongsTo(() => Whatsapp) + whatsapp: Whatsapp; + @CreatedAt createdAt: Date; From a6a63a04085d782457db06360daf6908cbd082c0 Mon Sep 17 00:00:00 2001 From: Ricardo Paes Date: Wed, 23 Feb 2022 11:13:50 -0300 Subject: [PATCH 02/12] :sparkles: create functions to check if the user has a link with whatsapp --- backend/src/helpers/GetDefaultWhatsApp.ts | 12 +++++++++++- .../src/helpers/GetDefaultWhatsAppByUser.ts | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 backend/src/helpers/GetDefaultWhatsAppByUser.ts diff --git a/backend/src/helpers/GetDefaultWhatsApp.ts b/backend/src/helpers/GetDefaultWhatsApp.ts index afcb362..ef74cda 100644 --- a/backend/src/helpers/GetDefaultWhatsApp.ts +++ b/backend/src/helpers/GetDefaultWhatsApp.ts @@ -1,7 +1,17 @@ import AppError from "../errors/AppError"; import Whatsapp from "../models/Whatsapp"; +import GetDefaultWhatsAppByUser from "./GetDefaultWhatsAppByUser"; + +const GetDefaultWhatsApp = async ( + userId?: number +): Promise => { + if(userId) { + const whatsappByUser = await GetDefaultWhatsAppByUser(userId); + if(whatsappByUser !== null) { + return whatsappByUser; + } + } -const GetDefaultWhatsApp = async (): Promise => { const defaultWhatsapp = await Whatsapp.findOne({ where: { isDefault: true } }); diff --git a/backend/src/helpers/GetDefaultWhatsAppByUser.ts b/backend/src/helpers/GetDefaultWhatsAppByUser.ts new file mode 100644 index 0000000..f9d6aac --- /dev/null +++ b/backend/src/helpers/GetDefaultWhatsAppByUser.ts @@ -0,0 +1,18 @@ +import User from "../models/User"; +import Whatsapp from "../models/Whatsapp"; +import { logger } from "../utils/logger"; + +const GetDefaultWhatsAppByUser = async ( + userId: number +): Promise => { + const user = await User.findByPk(userId, {include: ["whatsapp"]}); + if( user === null ) { + return null; + } + + logger.info(`Found whatsapp linked to user '${user.name}' is '${user.whatsapp.name}'.`); + + return user.whatsapp; +}; + +export default GetDefaultWhatsAppByUser; From afb5d68602f40fb22cfb397566d404495afff12a Mon Sep 17 00:00:00 2001 From: Ricardo Paes Date: Wed, 23 Feb 2022 11:19:36 -0300 Subject: [PATCH 03/12] :sparkles: searching default whatsapp using user link --- backend/src/controllers/ApiController.ts | 10 +++++++--- .../src/controllers/ImportPhoneContactsController.ts | 3 ++- backend/src/helpers/GetTicketWbot.ts | 2 +- .../src/services/TicketServices/CreateTicketService.ts | 2 +- .../src/services/WbotServices/ImportContactsService.ts | 4 ++-- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/backend/src/controllers/ApiController.ts b/backend/src/controllers/ApiController.ts index 33fb7df..2c553b8 100644 --- a/backend/src/controllers/ApiController.ts +++ b/backend/src/controllers/ApiController.ts @@ -24,7 +24,10 @@ interface ContactData { number: string; } -const createContact = async (newContact: string) => { +const createContact = async ( + userId: number, + newContact: string +) => { await CheckIsValidContact(newContact); const validNumber: any = await CheckContactNumber(newContact); @@ -42,7 +45,7 @@ const createContact = async (newContact: string) => { const contact = await CreateOrUpdateContactService(contactData); - const defaultWhatsapp = await GetDefaultWhatsApp(); + const defaultWhatsapp = await GetDefaultWhatsApp(userId); const createTicket = await FindOrCreateTicketService( contact, @@ -76,7 +79,8 @@ export const index = async (req: Request, res: Response): Promise => { throw new AppError(err.message); } - const contactAndTicket = await createContact(newContact.number); + const userId:number = parseInt(req.user.id); + const contactAndTicket = await createContact(userId, newContact.number); if (medias) { await Promise.all( diff --git a/backend/src/controllers/ImportPhoneContactsController.ts b/backend/src/controllers/ImportPhoneContactsController.ts index 01f1cfc..2b19890 100644 --- a/backend/src/controllers/ImportPhoneContactsController.ts +++ b/backend/src/controllers/ImportPhoneContactsController.ts @@ -2,7 +2,8 @@ import { Request, Response } from "express"; import ImportContactsService from "../services/WbotServices/ImportContactsService"; export const store = async (req: Request, res: Response): Promise => { - await ImportContactsService(); + const userId:number = parseInt(req.user.id); + await ImportContactsService(userId); return res.status(200).json({ message: "contacts imported" }); }; diff --git a/backend/src/helpers/GetTicketWbot.ts b/backend/src/helpers/GetTicketWbot.ts index 0caa6b0..802e8e9 100644 --- a/backend/src/helpers/GetTicketWbot.ts +++ b/backend/src/helpers/GetTicketWbot.ts @@ -5,7 +5,7 @@ import Ticket from "../models/Ticket"; const GetTicketWbot = async (ticket: Ticket): Promise => { if (!ticket.whatsappId) { - const defaultWhatsapp = await GetDefaultWhatsApp(); + const defaultWhatsapp = await GetDefaultWhatsApp(ticket.user.id); await ticket.$set("whatsapp", defaultWhatsapp); } diff --git a/backend/src/services/TicketServices/CreateTicketService.ts b/backend/src/services/TicketServices/CreateTicketService.ts index 4ea16cf..276d5e5 100644 --- a/backend/src/services/TicketServices/CreateTicketService.ts +++ b/backend/src/services/TicketServices/CreateTicketService.ts @@ -15,7 +15,7 @@ const CreateTicketService = async ({ status, userId }: Request): Promise => { - const defaultWhatsapp = await GetDefaultWhatsApp(); + const defaultWhatsapp = await GetDefaultWhatsApp(userId); await CheckContactOpenTickets(contactId); diff --git a/backend/src/services/WbotServices/ImportContactsService.ts b/backend/src/services/WbotServices/ImportContactsService.ts index ee6fd1f..531fff5 100644 --- a/backend/src/services/WbotServices/ImportContactsService.ts +++ b/backend/src/services/WbotServices/ImportContactsService.ts @@ -3,8 +3,8 @@ import { getWbot } from "../../libs/wbot"; import Contact from "../../models/Contact"; import { logger } from "../../utils/logger"; -const ImportContactsService = async (): Promise => { - const defaultWhatsapp = await GetDefaultWhatsApp(); +const ImportContactsService = async (userId:number): Promise => { + const defaultWhatsapp = await GetDefaultWhatsApp(userId); const wbot = getWbot(defaultWhatsapp.id); From acd628028e487df51995da68130b415bda2cf551 Mon Sep 17 00:00:00 2001 From: Ricardo Paes Date: Wed, 23 Feb 2022 11:21:11 -0300 Subject: [PATCH 04/12] :sparkles: open more than one ticket per user as long as it is using another whatsapp --- backend/src/helpers/CheckContactOpenTickets.ts | 7 +++++-- .../src/services/TicketServices/CreateTicketService.ts | 2 +- .../services/TicketServices/FindOrCreateTicketService.ts | 9 ++++++--- .../src/services/TicketServices/UpdateTicketService.ts | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/backend/src/helpers/CheckContactOpenTickets.ts b/backend/src/helpers/CheckContactOpenTickets.ts index 3437cce..71de597 100644 --- a/backend/src/helpers/CheckContactOpenTickets.ts +++ b/backend/src/helpers/CheckContactOpenTickets.ts @@ -2,9 +2,12 @@ import { Op } from "sequelize"; import AppError from "../errors/AppError"; import Ticket from "../models/Ticket"; -const CheckContactOpenTickets = async (contactId: number): Promise => { +const CheckContactOpenTickets = async ( + contactId: number, + whatsappId: number +): Promise => { const ticket = await Ticket.findOne({ - where: { contactId, status: { [Op.or]: ["open", "pending"] } } + where: { contactId, whatsappId, status: { [Op.or]: ["open", "pending"] } } }); if (ticket) { diff --git a/backend/src/services/TicketServices/CreateTicketService.ts b/backend/src/services/TicketServices/CreateTicketService.ts index 276d5e5..890c0f9 100644 --- a/backend/src/services/TicketServices/CreateTicketService.ts +++ b/backend/src/services/TicketServices/CreateTicketService.ts @@ -17,7 +17,7 @@ const CreateTicketService = async ({ }: Request): Promise => { const defaultWhatsapp = await GetDefaultWhatsApp(userId); - await CheckContactOpenTickets(contactId); + await CheckContactOpenTickets(contactId, defaultWhatsapp.id); const { isGroup } = await ShowContactService(contactId); diff --git a/backend/src/services/TicketServices/FindOrCreateTicketService.ts b/backend/src/services/TicketServices/FindOrCreateTicketService.ts index bf4c2b0..702f59c 100644 --- a/backend/src/services/TicketServices/FindOrCreateTicketService.ts +++ b/backend/src/services/TicketServices/FindOrCreateTicketService.ts @@ -15,7 +15,8 @@ const FindOrCreateTicketService = async ( status: { [Op.or]: ["open", "pending"] }, - contactId: groupContact ? groupContact.id : contact.id + contactId: groupContact ? groupContact.id : contact.id, + whatsappId: whatsappId } }); @@ -26,7 +27,8 @@ const FindOrCreateTicketService = async ( if (!ticket && groupContact) { ticket = await Ticket.findOne({ where: { - contactId: groupContact.id + contactId: groupContact.id, + whatsappId: whatsappId }, order: [["updatedAt", "DESC"]] }); @@ -46,7 +48,8 @@ const FindOrCreateTicketService = async ( updatedAt: { [Op.between]: [+subHours(new Date(), 2), +new Date()] }, - contactId: contact.id + contactId: contact.id, + whatsappId: whatsappId }, order: [["updatedAt", "DESC"]] }); diff --git a/backend/src/services/TicketServices/UpdateTicketService.ts b/backend/src/services/TicketServices/UpdateTicketService.ts index 3efc5db..eaaadb9 100644 --- a/backend/src/services/TicketServices/UpdateTicketService.ts +++ b/backend/src/services/TicketServices/UpdateTicketService.ts @@ -36,7 +36,7 @@ const UpdateTicketService = async ({ const oldUserId = ticket.user?.id; if (oldStatus === "closed") { - await CheckContactOpenTickets(ticket.contact.id); + await CheckContactOpenTickets(ticket.contact.id, ticket.whatsappId); } await ticket.update({ From a9739f3a650d6adbfffe35e711f731d6a1b688ef Mon Sep 17 00:00:00 2001 From: Ricardo Paes Date: Wed, 23 Feb 2022 11:29:19 -0300 Subject: [PATCH 05/12] :sparkles: api update whatsapp id too --- .../src/services/TicketServices/UpdateTicketService.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/src/services/TicketServices/UpdateTicketService.ts b/backend/src/services/TicketServices/UpdateTicketService.ts index eaaadb9..950cf20 100644 --- a/backend/src/services/TicketServices/UpdateTicketService.ts +++ b/backend/src/services/TicketServices/UpdateTicketService.ts @@ -10,6 +10,7 @@ interface TicketData { status?: string; userId?: number; queueId?: number; + whatsappId?: number; } interface Request { @@ -27,7 +28,7 @@ const UpdateTicketService = async ({ ticketData, ticketId }: Request): Promise => { - const { status, userId, queueId } = ticketData; + const { status, userId, queueId, whatsappId } = ticketData; const ticket = await ShowTicketService(ticketId); await SetTicketMessagesAsRead(ticket); @@ -46,6 +47,11 @@ const UpdateTicketService = async ({ }); + if(whatsappId) { + await ticket.update({ + whatsappId + }); + } await ticket.reload(); From e7252c1273dee61c8ec9dda77cada11e32b9bb33 Mon Sep 17 00:00:00 2001 From: Ricardo Paes Date: Thu, 24 Feb 2022 08:07:24 -0300 Subject: [PATCH 06/12] :sparkles: When starting ticket set queue automatically if user is only one linked --- .../services/TicketServices/CreateTicketService.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/backend/src/services/TicketServices/CreateTicketService.ts b/backend/src/services/TicketServices/CreateTicketService.ts index 890c0f9..bfda479 100644 --- a/backend/src/services/TicketServices/CreateTicketService.ts +++ b/backend/src/services/TicketServices/CreateTicketService.ts @@ -2,18 +2,21 @@ import AppError from "../../errors/AppError"; import CheckContactOpenTickets from "../../helpers/CheckContactOpenTickets"; import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp"; import Ticket from "../../models/Ticket"; +import User from "../../models/User"; import ShowContactService from "../ContactServices/ShowContactService"; interface Request { contactId: number; status: string; userId: number; + queueId ?: number; } const CreateTicketService = async ({ contactId, status, - userId + userId, + queueId }: Request): Promise => { const defaultWhatsapp = await GetDefaultWhatsApp(userId); @@ -21,11 +24,17 @@ const CreateTicketService = async ({ const { isGroup } = await ShowContactService(contactId); + if(queueId === undefined) { + const user = await User.findByPk(userId, { include: ["queues"]}); + queueId = user?.queues.length === 1 ? user.queues[0].id : undefined; + } + const { id }: Ticket = await defaultWhatsapp.$create("ticket", { contactId, status, isGroup, - userId + userId, + queueId }); const ticket = await Ticket.findByPk(id, { include: ["contact"] }); From a837e555a0930376923adc810c1c80aa0e6ae129 Mon Sep 17 00:00:00 2001 From: Ricardo Paes Date: Thu, 24 Feb 2022 08:43:56 -0300 Subject: [PATCH 07/12] :bug: fixing `Cannot read property 'name' of null` --- backend/src/helpers/GetDefaultWhatsAppByUser.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/src/helpers/GetDefaultWhatsAppByUser.ts b/backend/src/helpers/GetDefaultWhatsAppByUser.ts index f9d6aac..e651777 100644 --- a/backend/src/helpers/GetDefaultWhatsAppByUser.ts +++ b/backend/src/helpers/GetDefaultWhatsAppByUser.ts @@ -10,7 +10,9 @@ const GetDefaultWhatsAppByUser = async ( return null; } - logger.info(`Found whatsapp linked to user '${user.name}' is '${user.whatsapp.name}'.`); + if(user.whatsapp !== null) { + logger.info(`Found whatsapp linked to user '${user.name}' is '${user.whatsapp.name}'.`); + } return user.whatsapp; }; From 61df7c8bc0a55cf0087ebbf315ba3807ce1fdd09 Mon Sep 17 00:00:00 2001 From: Ricardo Paes Date: Thu, 24 Feb 2022 23:55:54 -0300 Subject: [PATCH 08/12] :sparkles: Add parameter `whatsappId` in `api/messages/send` to choose --- backend/src/controllers/ApiController.ts | 25 +++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/backend/src/controllers/ApiController.ts b/backend/src/controllers/ApiController.ts index 2c553b8..66d72f1 100644 --- a/backend/src/controllers/ApiController.ts +++ b/backend/src/controllers/ApiController.ts @@ -4,6 +4,7 @@ import AppError from "../errors/AppError"; import GetDefaultWhatsApp from "../helpers/GetDefaultWhatsApp"; import SetTicketMessagesAsRead from "../helpers/SetTicketMessagesAsRead"; import Message from "../models/Message"; +import Whatsapp from "../models/Whatsapp"; import CreateOrUpdateContactService from "../services/ContactServices/CreateOrUpdateContactService"; import FindOrCreateTicketService from "../services/TicketServices/FindOrCreateTicketService"; import ShowTicketService from "../services/TicketServices/ShowTicketService"; @@ -13,6 +14,10 @@ import GetProfilePicUrl from "../services/WbotServices/GetProfilePicUrl"; import SendWhatsAppMedia from "../services/WbotServices/SendWhatsAppMedia"; import SendWhatsAppMessage from "../services/WbotServices/SendWhatsAppMessage"; +type WhatsappData = { + whatsappId: number; +} + type MessageData = { body: string; fromMe: boolean; @@ -25,7 +30,7 @@ interface ContactData { } const createContact = async ( - userId: number, + whatsappId: number | undefined, newContact: string ) => { await CheckIsValidContact(newContact); @@ -45,11 +50,21 @@ const createContact = async ( const contact = await CreateOrUpdateContactService(contactData); - const defaultWhatsapp = await GetDefaultWhatsApp(userId); + let whatsapp:Whatsapp | null; + + if(whatsappId === undefined) { + whatsapp = await GetDefaultWhatsApp(); + } else { + whatsapp = await Whatsapp.findByPk(whatsappId); + + if(whatsapp === null) { + throw new AppError(`whatsapp #${whatsappId} not found`); + } + } const createTicket = await FindOrCreateTicketService( contact, - defaultWhatsapp.id, + whatsapp.id, 1 ); @@ -62,6 +77,7 @@ const createContact = async ( export const index = async (req: Request, res: Response): Promise => { const newContact: ContactData = req.body; + const { whatsappId }: WhatsappData = req.body; const { body, quotedMsg }: MessageData = req.body; const medias = req.files as Express.Multer.File[]; @@ -79,8 +95,7 @@ export const index = async (req: Request, res: Response): Promise => { throw new AppError(err.message); } - const userId:number = parseInt(req.user.id); - const contactAndTicket = await createContact(userId, newContact.number); + const contactAndTicket = await createContact(whatsappId, newContact.number); if (medias) { await Promise.all( From 84bbe3afaa8adb328c71c097eb2489409a5a8e02 Mon Sep 17 00:00:00 2001 From: Ricardo Paes Date: Fri, 25 Feb 2022 08:18:57 -0300 Subject: [PATCH 09/12] :sparkles: In user registration add standard whatsapp field --- backend/src/controllers/UserController.ts | 5 ++-- backend/src/helpers/SerializeUser.ts | 5 +++- .../UserServices/CreateUserService.ts | 9 ++++-- .../services/UserServices/ListUsersService.ts | 4 ++- .../services/UserServices/ShowUserService.ts | 6 ++-- .../UserServices/UpdateUserService.ts | 15 ++++------ frontend/src/components/UserModal/index.js | 29 +++++++++++++++++-- frontend/src/pages/Users/index.js | 4 +++ frontend/src/translate/languages/en.js | 2 ++ frontend/src/translate/languages/es.js | 2 ++ frontend/src/translate/languages/pt.js | 2 ++ 11 files changed, 62 insertions(+), 21 deletions(-) diff --git a/backend/src/controllers/UserController.ts b/backend/src/controllers/UserController.ts index 06d329d..001d97b 100644 --- a/backend/src/controllers/UserController.ts +++ b/backend/src/controllers/UserController.ts @@ -27,7 +27,7 @@ export const index = async (req: Request, res: Response): Promise => { }; export const store = async (req: Request, res: Response): Promise => { - const { email, password, name, profile, queueIds } = req.body; + const { email, password, name, profile, queueIds, whatsappId } = req.body; if ( req.url === "/signup" && @@ -43,7 +43,8 @@ export const store = async (req: Request, res: Response): Promise => { password, name, profile, - queueIds + queueIds, + whatsappId }); const io = getIO(); diff --git a/backend/src/helpers/SerializeUser.ts b/backend/src/helpers/SerializeUser.ts index 3802500..928f75b 100644 --- a/backend/src/helpers/SerializeUser.ts +++ b/backend/src/helpers/SerializeUser.ts @@ -1,5 +1,6 @@ import Queue from "../models/Queue"; import User from "../models/User"; +import Whatsapp from "../models/Whatsapp"; interface SerializedUser { id: number; @@ -7,6 +8,7 @@ interface SerializedUser { email: string; profile: string; queues: Queue[]; + whatsapp: Whatsapp; } export const SerializeUser = (user: User): SerializedUser => { @@ -15,6 +17,7 @@ export const SerializeUser = (user: User): SerializedUser => { name: user.name, email: user.email, profile: user.profile, - queues: user.queues + queues: user.queues, + whatsapp: user.whatsapp }; }; diff --git a/backend/src/services/UserServices/CreateUserService.ts b/backend/src/services/UserServices/CreateUserService.ts index 098846b..83aa987 100644 --- a/backend/src/services/UserServices/CreateUserService.ts +++ b/backend/src/services/UserServices/CreateUserService.ts @@ -10,6 +10,7 @@ interface Request { name: string; queueIds?: number[]; profile?: string; + whatsappId?: number; } interface Response { @@ -24,7 +25,8 @@ const CreateUserService = async ({ password, name, queueIds = [], - profile = "admin" + profile = "admin", + whatsappId }: Request): Promise => { const schema = Yup.object().shape({ name: Yup.string().required().min(2), @@ -56,9 +58,10 @@ const CreateUserService = async ({ email, password, name, - profile + profile, + whatsappId: whatsappId ? whatsappId : null }, - { include: ["queues"] } + { include: ["queues", "whatsapp"] } ); await user.$set("queues", queueIds); diff --git a/backend/src/services/UserServices/ListUsersService.ts b/backend/src/services/UserServices/ListUsersService.ts index fb8a202..200ce05 100644 --- a/backend/src/services/UserServices/ListUsersService.ts +++ b/backend/src/services/UserServices/ListUsersService.ts @@ -1,6 +1,7 @@ import { Sequelize, Op } from "sequelize"; import Queue from "../../models/Queue"; import User from "../../models/User"; +import Whatsapp from "../../models/Whatsapp"; interface Request { searchParam?: string; @@ -39,7 +40,8 @@ const ListUsersService = async ({ offset, order: [["createdAt", "DESC"]], include: [ - { model: Queue, as: "queues", attributes: ["id", "name", "color"] } + { model: Queue, as: "queues", attributes: ["id", "name", "color"] }, + { model: Whatsapp, as: "whatsapp", attributes: ["id", "name"] }, ] }); diff --git a/backend/src/services/UserServices/ShowUserService.ts b/backend/src/services/UserServices/ShowUserService.ts index 03ecab4..d98a8c0 100644 --- a/backend/src/services/UserServices/ShowUserService.ts +++ b/backend/src/services/UserServices/ShowUserService.ts @@ -1,12 +1,14 @@ import User from "../../models/User"; import AppError from "../../errors/AppError"; import Queue from "../../models/Queue"; +import Whatsapp from "../../models/Whatsapp"; const ShowUserService = async (id: string | number): Promise => { const user = await User.findByPk(id, { - attributes: ["name", "id", "email", "profile", "tokenVersion"], + attributes: ["name", "id", "email", "profile", "tokenVersion", "whatsappId"], include: [ - { model: Queue, as: "queues", attributes: ["id", "name", "color"] } + { model: Queue, as: "queues", attributes: ["id", "name", "color"] }, + { model: Whatsapp, as: "whatsapp", attributes: ["id", "name"] }, ], order: [ [ { model: Queue, as: "queues"}, 'name', 'asc' ] ] }); diff --git a/backend/src/services/UserServices/UpdateUserService.ts b/backend/src/services/UserServices/UpdateUserService.ts index 114d557..b429ca9 100644 --- a/backend/src/services/UserServices/UpdateUserService.ts +++ b/backend/src/services/UserServices/UpdateUserService.ts @@ -1,6 +1,7 @@ import * as Yup from "yup"; import AppError from "../../errors/AppError"; +import { SerializeUser } from "../../helpers/SerializeUser"; import ShowUserService from "./ShowUserService"; interface UserData { @@ -9,6 +10,7 @@ interface UserData { name?: string; profile?: string; queueIds?: number[]; + whatsappId?: number; } interface Request { @@ -36,7 +38,7 @@ const UpdateUserService = async ({ password: Yup.string() }); - const { email, password, profile, name, queueIds = [] } = userData; + const { email, password, profile, name, queueIds = [], whatsappId } = userData; try { await schema.validate({ email, password, profile, name }); @@ -48,20 +50,15 @@ const UpdateUserService = async ({ email, password, profile, - name + name, + whatsappId: whatsappId ? whatsappId : null }); await user.$set("queues", queueIds); await user.reload(); - const serializedUser = { - id: user.id, - name: user.name, - email: user.email, - profile: user.profile, - queues: user.queues - }; + const serializedUser = SerializeUser(user); return serializedUser; }; diff --git a/frontend/src/components/UserModal/index.js b/frontend/src/components/UserModal/index.js index 1d27a44..d7da0fb 100644 --- a/frontend/src/components/UserModal/index.js +++ b/frontend/src/components/UserModal/index.js @@ -32,6 +32,7 @@ import toastError from "../../errors/toastError"; import QueueSelect from "../QueueSelect"; import { AuthContext } from "../../context/Auth/AuthContext"; import { Can } from "../Can"; +import useWhatsApps from "../../hooks/useWhatsApps"; const useStyles = makeStyles(theme => ({ root: { @@ -79,7 +80,7 @@ const UserModal = ({ open, onClose, userId }) => { name: "", email: "", password: "", - profile: "user", + profile: "user" }; const { user: loggedInUser } = useContext(AuthContext); @@ -87,7 +88,8 @@ const UserModal = ({ open, onClose, userId }) => { const [user, setUser] = useState(initialState); const [selectedQueueIds, setSelectedQueueIds] = useState([]); const [showPassword, setShowPassword] = useState(false); - + const [whatsappId, setWhatsappId] = useState(false); + const {loading, whatsApps} = useWhatsApps(); useEffect(() => { const fetchUser = async () => { @@ -99,6 +101,7 @@ const UserModal = ({ open, onClose, userId }) => { }); const userQueueIds = data.queues?.map(queue => queue.id); setSelectedQueueIds(userQueueIds); + setWhatsappId(data.whatsappId ? data.whatsappId : ''); } catch (err) { toastError(err); } @@ -113,7 +116,7 @@ const UserModal = ({ open, onClose, userId }) => { }; const handleSaveUser = async values => { - const userData = { ...values, queueIds: selectedQueueIds }; + const userData = { ...values, whatsappId, queueIds: selectedQueueIds }; try { if (userId) { await api.put(`/users/${userId}`, userData); @@ -242,6 +245,26 @@ const UserModal = ({ open, onClose, userId }) => { /> )} /> + ( + + {i18n.t("userModal.form.whatsapp")} + setWhatsappId(e.target.value)} + label={i18n.t("userModal.form.whatsapp")} + > +   + {whatsApps.map((whatsapp) => ( + {whatsapp.name} + ))} + + + )} + />