Skip to content

Commit

Permalink
Tags no Contato
Browse files Browse the repository at this point in the history
  • Loading branch information
rtenorioh committed Sep 27, 2022
1 parent aefcc3a commit 7c3357a
Show file tree
Hide file tree
Showing 36 changed files with 1,683 additions and 147 deletions.
3 changes: 2 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"license": "MIT",
"dependencies": {
"@sentry/node": "^5.29.2",
"@types/lodash": "^4.14.185",
"@types/pino": "^6.3.4",
"bcryptjs": "^2.4.3",
"cookie-parser": "^1.4.5",
Expand All @@ -27,6 +26,7 @@
"express-async-errors": "^3.1.1",
"http-graceful-shutdown": "^2.3.2",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.21",
"multer": "^1.4.2",
"mustache": "^4.2.0",
"mysql2": "^2.2.5",
Expand Down Expand Up @@ -54,6 +54,7 @@
"@types/faker": "^5.1.3",
"@types/jest": "^26.0.15",
"@types/jsonwebtoken": "^8.5.0",
"@types/lodash": "^4.14.185",
"@types/multer": "^1.4.4",
"@types/mustache": "^4.1.2",
"@types/node": "^14.11.8",
Expand Down
126 changes: 126 additions & 0 deletions backend/src/controllers/TagController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { Request, Response } from "express";
import { getIO } from "../libs/socket";

import AppError from "../errors/AppError";

import CreateService from "../services/TagServices/CreateService";
import ListService from "../services/TagServices/ListService";
import UpdateService from "../services/TagServices/UpdateService";
import ShowService from "../services/TagServices/ShowService";
import DeleteService from "../services/TagServices/DeleteService";
import SimpleListService from "../services/TagServices/SimpleListService";
import SyncTagService from "../services/TagServices/SyncTagsService";
import DeleteAllService from "../services/TagServices/DeleteAllService";

type IndexQuery = {
searchParam?: string;
pageNumber?: string | number;
};

export const index = async (req: Request, res: Response): Promise<Response> => {
const { pageNumber, searchParam } = req.query as IndexQuery;

const { tags, count, hasMore } = await ListService({
searchParam,
pageNumber
});

return res.json({ tags, count, hasMore });
};

export const store = async (req: Request, res: Response): Promise<Response> => {
const { name, color } = req.body;

const tag = await CreateService({
name,
color
});

const io = getIO();
io.emit("tag", {
action: "create",
tag
});

return res.status(200).json(tag);
};

export const show = async (req: Request, res: Response): Promise<Response> => {
const { tagId } = req.params;

const tag = await ShowService(tagId);

return res.status(200).json(tag);
};

export const update = async (
req: Request,
res: Response
): Promise<Response> => {
if (req.user.profile !== "admin") {
throw new AppError("ERR_NO_PERMISSION", 403);
}

const { tagId } = req.params;
const tagData = req.body;

const tag = await UpdateService({ tagData, id: tagId });

const io = getIO();
io.emit("tag", {
action: "update",
tag
});

return res.status(200).json(tag);
};

export const remove = async (
req: Request,
res: Response
): Promise<Response> => {
const { tagId } = req.params;

await DeleteService(tagId);

const io = getIO();
io.emit("tag", {
action: "delete",
tagId
});

return res.status(200).json({ message: "Tag deleted" });
};

export const removeAll = async (
req: Request,
res: Response
): Promise<Response> => {
const { tagId } = req.params;

await DeleteAllService();

return res.send();
};

export const list = async (req: Request, res: Response): Promise<Response> => {
const { searchParam } = req.query as IndexQuery;

const tags = await SimpleListService({ searchParam });

return res.json(tags);
};

export const syncTags = async (req: Request, res: Response): Promise<any> => {
const data = req.body;

try {
if (data) {
const tags = await SyncTagService(data);

return res.json(tags);
}
} catch (err) {
throw new AppError("ERR_SYNC_TAGS", 500);
}
};
6 changes: 5 additions & 1 deletion backend/src/database/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import Queue from "../models/Queue";
import WhatsappQueue from "../models/WhatsappQueue";
import UserQueue from "../models/UserQueue";
import QuickAnswer from "../models/QuickAnswer";
import Tag from "../models/Tag";
import ContactTag from "../models/ContactTag";

// eslint-disable-next-line
const dbConfig = require("../config/database");
Expand All @@ -28,7 +30,9 @@ const models = [
Queue,
WhatsappQueue,
UserQueue,
QuickAnswer
QuickAnswer,
Tag,
ContactTag
];

sequelize.addModels(models);
Expand Down
34 changes: 34 additions & 0 deletions backend/src/database/migrations/20220906150400-create-tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { QueryInterface, DataTypes } from "sequelize";

module.exports = {
up: (queryInterface: QueryInterface) => {
return queryInterface.createTable("Tags", {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: false
},
color: {
type: DataTypes.STRING,
allowNull: true
},
createdAt: {
type: DataTypes.DATE,
allowNull: false
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false
}
});
},

down: (queryInterface: QueryInterface) => {
return queryInterface.dropTable("Tags");
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { QueryInterface, DataTypes } from "sequelize";

module.exports = {
up: (queryInterface: QueryInterface) => {
return queryInterface.createTable("ContactTags", {
contactId: {
type: DataTypes.INTEGER,
references: { model: "Contacts", key: "id" },
onUpdate: "CASCADE",
onDelete: "CASCADE",
allowNull: false
},
tagId: {
type: DataTypes.INTEGER,
references: { model: "Tags", key: "id" },
onUpdate: "CASCADE",
onDelete: "CASCADE",
allowNull: false
},
createdAt: {
type: DataTypes.DATE,
allowNull: false
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false
}
});
},

down: (queryInterface: QueryInterface) => {
return queryInterface.dropTable("ContactTags");
}
};
21 changes: 15 additions & 6 deletions backend/src/models/Contact.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import {
Table,
AllowNull,
AutoIncrement,
BelongsToMany,
Column,
CreatedAt,
UpdatedAt,
Default,
HasMany,
Model,
PrimaryKey,
AutoIncrement,
AllowNull,
Table,
Unique,
Default,
HasMany
UpdatedAt
} from "sequelize-typescript";
import ContactCustomField from "./ContactCustomField";
import Ticket from "./Ticket";
import Tag from "./Tag";
import ContactTag from "./ContactTag";

@Table
class Contact extends Model<Contact> {
Expand Down Expand Up @@ -52,6 +55,12 @@ class Contact extends Model<Contact> {

@HasMany(() => ContactCustomField)
extraInfo: ContactCustomField[];

@HasMany(() => ContactTag)
contactTags: ContactTag[];

@BelongsToMany(() => Tag, () => ContactTag)
tags: Tag[];
}

export default Contact;
38 changes: 38 additions & 0 deletions backend/src/models/ContactTag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
Table,
Column,
CreatedAt,
UpdatedAt,
Model,
ForeignKey,
BelongsTo
} from "sequelize-typescript";
import Tag from "./Tag";
import Contact from "./Contact";

@Table({
tableName: "ContactTags"
})
class ContactTag extends Model<ContactTag> {
@ForeignKey(() => Contact)
@Column
contactId: number;

@ForeignKey(() => Tag)
@Column
tagId: number;

@CreatedAt
createdAt: Date;

@UpdatedAt
updatedAt: Date;

@BelongsTo(() => Contact)
contact: Contact;

@BelongsTo(() => Tag)
tag: Tag;
}

export default ContactTag;
37 changes: 37 additions & 0 deletions backend/src/models/Tag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
Table,
Column,
CreatedAt,
UpdatedAt,
Model,
PrimaryKey,
AutoIncrement,
BelongsToMany
} from "sequelize-typescript";
import Contact from "./Contact";
import ContactTag from "./ContactTag";

@Table
class Tag extends Model<Tag> {
@PrimaryKey
@AutoIncrement
@Column
id: number;

@Column
name: string;

@Column
color: string;

@BelongsToMany(() => Contact, () => ContactTag)
contacts: Contact[];

@CreatedAt
createdAt: Date;

@UpdatedAt
updatedAt: Date;
}

export default Tag;
2 changes: 2 additions & 0 deletions backend/src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import whatsappSessionRoutes from "./whatsappSessionRoutes";
import queueRoutes from "./queueRoutes";
import quickAnswerRoutes from "./quickAnswerRoutes";
import apiRoutes from "./apiRoutes";
import tagRoutes from "./tagRoutes";

const routes = Router();

Expand All @@ -25,5 +26,6 @@ routes.use(whatsappSessionRoutes);
routes.use(queueRoutes);
routes.use(quickAnswerRoutes);
routes.use("/api/messages", apiRoutes);
routes.use(tagRoutes);

export default routes;
17 changes: 17 additions & 0 deletions backend/src/routes/tagRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import express from "express";
import isAuth from "../middleware/isAuth";

import * as TagController from "../controllers/TagController";

const tagRoutes = express.Router();

tagRoutes.get("/tags/list", isAuth, TagController.list);
tagRoutes.get("/tags", isAuth, TagController.index);
tagRoutes.post("/tags", isAuth, TagController.store);
tagRoutes.put("/tags/:tagId", isAuth, TagController.update);
tagRoutes.get("/tags/:tagId", isAuth, TagController.show);
tagRoutes.delete("/tags/:tagId", isAuth, TagController.remove);
tagRoutes.delete("/tags", isAuth, TagController.removeAll);
tagRoutes.post("/tags/sync", isAuth, TagController.syncTags);

export default tagRoutes;
Loading

0 comments on commit 7c3357a

Please sign in to comment.