mirror of
https://github.com/cheveguerra/whaticket-community.git
synced 2026-04-20 04:39:20 +00:00
Create custom field table and assocs
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
const Sequelize = require("sequelize");
|
const Sequelize = require("sequelize");
|
||||||
|
|
||||||
const Contact = require("../models/Contact");
|
const Contact = require("../models/Contact");
|
||||||
|
const ContactCustomField = require("../models/ContactCustomField");
|
||||||
|
|
||||||
// const Message = require("../models/Message");
|
// const Message = require("../models/Message");
|
||||||
// const Sequelize = require("sequelize");
|
// const Sequelize = require("sequelize");
|
||||||
// const { getIO } = require("../libs/socket");
|
// const { getIO } = require("../libs/socket");
|
||||||
@@ -50,3 +52,18 @@ exports.store = async (req, res) => {
|
|||||||
|
|
||||||
res.status(200).json({ number, name });
|
res.status(200).json({ number, name });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.show = async (req, res) => {
|
||||||
|
const { contactId } = req.params;
|
||||||
|
|
||||||
|
const { id, name, number, extraInfo } = await Contact.findByPk(contactId, {
|
||||||
|
include: [{ model: ContactCustomField, as: "extraInfo" }],
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
number,
|
||||||
|
extraInfo,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ const Contact = require("../models/Contact");
|
|||||||
const Ticket = require("../models/Ticket");
|
const Ticket = require("../models/Ticket");
|
||||||
const Message = require("../models/Message");
|
const Message = require("../models/Message");
|
||||||
const Whatsapp = require("../models/Whatsapp");
|
const Whatsapp = require("../models/Whatsapp");
|
||||||
|
const ContactCustomField = require("../models/ContactCustomField");
|
||||||
|
|
||||||
const models = [User, Contact, Ticket, Message, Whatsapp];
|
const models = [User, Contact, Ticket, Message, Whatsapp, ContactCustomField];
|
||||||
|
|
||||||
class Database {
|
class Database {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface, Sequelize) => {
|
||||||
|
return queryInterface.createTable("ContactCustomFields", {
|
||||||
|
id: {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
contactId: {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
references: { model: "Contacts", key: "id" },
|
||||||
|
onUpdate: "CASCADE",
|
||||||
|
onDelete: "CASCADE",
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: queryInterface => {
|
||||||
|
return queryInterface.dropTable("ContactCustomFields");
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -18,6 +18,10 @@ class Contact extends Sequelize.Model {
|
|||||||
|
|
||||||
static associate(models) {
|
static associate(models) {
|
||||||
this.hasMany(models.Ticket, { foreignKey: "contactId" });
|
this.hasMany(models.Ticket, { foreignKey: "contactId" });
|
||||||
|
this.hasMany(models.ContactCustomField, {
|
||||||
|
foreignKey: "contactId",
|
||||||
|
as: "extraInfo",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
backend/src/models/ContactCustomField.js
Normal file
26
backend/src/models/ContactCustomField.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
const Sequelize = require("sequelize");
|
||||||
|
|
||||||
|
class ContactCustomField extends Sequelize.Model {
|
||||||
|
static init(sequelize) {
|
||||||
|
super.init(
|
||||||
|
{
|
||||||
|
name: { type: Sequelize.STRING },
|
||||||
|
value: { type: Sequelize.STRING },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sequelize,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static associate(models) {
|
||||||
|
this.belongsTo(models.Contact, {
|
||||||
|
foreignKey: "contactId",
|
||||||
|
as: "extraInfo",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ContactCustomField;
|
||||||
@@ -7,6 +7,10 @@ const routes = express.Router();
|
|||||||
|
|
||||||
routes.get("/contacts", isAuth, ContactController.index);
|
routes.get("/contacts", isAuth, ContactController.index);
|
||||||
|
|
||||||
|
routes.get("/contacts/:contactId", isAuth, ContactController.show);
|
||||||
|
|
||||||
routes.post("/contacts", isAuth, ContactController.store);
|
routes.post("/contacts", isAuth, ContactController.store);
|
||||||
|
|
||||||
|
// routes.put("/contacts/contactId", isAuth, ContactController.index);
|
||||||
|
|
||||||
module.exports = routes;
|
module.exports = routes;
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
|
|||||||
|
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
|
|
||||||
|
import api from "../../util/api";
|
||||||
|
|
||||||
const useStyles = makeStyles(theme => ({
|
const useStyles = makeStyles(theme => ({
|
||||||
root: {
|
root: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -55,12 +57,34 @@ const AddContactModal = ({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchContact = async () => {
|
||||||
|
if (!contactId) return;
|
||||||
|
const res = await api.get(`/contacts/${contactId}`);
|
||||||
|
setContact(res.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchContact();
|
||||||
|
}, [contactId]);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setModalOpen(false);
|
setModalOpen(false);
|
||||||
|
setContact({
|
||||||
|
id: "",
|
||||||
|
name: "",
|
||||||
|
number: "",
|
||||||
|
email: "",
|
||||||
|
extraInfo: [
|
||||||
|
{
|
||||||
|
id: "",
|
||||||
|
name: "",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {}, [contactId]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<Dialog
|
<Dialog
|
||||||
@@ -74,6 +98,7 @@ const AddContactModal = ({
|
|||||||
>
|
>
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={contact}
|
initialValues={contact}
|
||||||
|
enableReinitialize={true}
|
||||||
onSubmit={(values, { setSubmitting }) => {
|
onSubmit={(values, { setSubmitting }) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
alert(JSON.stringify(values, null, 2));
|
alert(JSON.stringify(values, null, 2));
|
||||||
|
|||||||
@@ -75,8 +75,9 @@ const Contacts = () => {
|
|||||||
const [count, setCount] = useState(0);
|
const [count, setCount] = useState(0);
|
||||||
const [searchParam, setSearchParam] = useState("");
|
const [searchParam, setSearchParam] = useState("");
|
||||||
const [contacts, setContacts] = useState([]);
|
const [contacts, setContacts] = useState([]);
|
||||||
|
const [selectedContactId, setSelectedContactId] = useState(null);
|
||||||
|
|
||||||
const [modalOpen, setModalOpen] = useState(true);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -113,6 +114,7 @@ const Contacts = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleClickOpen = () => {
|
const handleClickOpen = () => {
|
||||||
|
setSelectedContactId(null);
|
||||||
setModalOpen(true);
|
setModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -120,6 +122,11 @@ const Contacts = () => {
|
|||||||
setModalOpen(false);
|
setModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hadleEditContact = contactId => {
|
||||||
|
setSelectedContactId(contactId);
|
||||||
|
setModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className={classes.mainContainer}>
|
<Container className={classes.mainContainer}>
|
||||||
<ContactModal
|
<ContactModal
|
||||||
@@ -127,6 +134,7 @@ const Contacts = () => {
|
|||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
setModalOpen={setModalOpen}
|
setModalOpen={setModalOpen}
|
||||||
aria-labelledby="form-dialog-title"
|
aria-labelledby="form-dialog-title"
|
||||||
|
contactId={selectedContactId}
|
||||||
></ContactModal>
|
></ContactModal>
|
||||||
<div className={classes.contactsHeader}>
|
<div className={classes.contactsHeader}>
|
||||||
<Typography variant="h5" gutterBottom>
|
<Typography variant="h5" gutterBottom>
|
||||||
@@ -176,7 +184,10 @@ const Contacts = () => {
|
|||||||
<TableCell>{contact.number}</TableCell>
|
<TableCell>{contact.number}</TableCell>
|
||||||
<TableCell>{contact.updatedAt}</TableCell>
|
<TableCell>{contact.updatedAt}</TableCell>
|
||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
<IconButton size="small">
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={() => hadleEditContact(contact.id)}
|
||||||
|
>
|
||||||
<EditIcon />
|
<EditIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton size="small">
|
<IconButton size="small">
|
||||||
|
|||||||
Reference in New Issue
Block a user