From b8fd1f31516a4450e29f8af7845715c7c2f17e9d Mon Sep 17 00:00:00 2001 From: Nicolas Date: Mon, 30 Dec 2024 15:45:07 +0100 Subject: [PATCH] hook --- backend/src/server.ts | 26 +++++-------------- frontend/src/actions/consultantActions.ts | 3 +-- .../components/consultant/EditConsultant.tsx | 6 ++++- .../hooks/useEntityChangedToast.tsx | 17 ++++++++++++ .../src/components/project/EditProject.tsx | 12 ++------- .../src/components/socketio/SocketService.ts | 10 +++---- 6 files changed, 37 insertions(+), 37 deletions(-) create mode 100644 frontend/src/components/hooks/useEntityChangedToast.tsx diff --git a/backend/src/server.ts b/backend/src/server.ts index ba3562e8..91949459 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -4,7 +4,7 @@ import bodyParser from 'body-parser'; import sgMail from '@sendgrid/mail'; import {MongoClient} from 'mongodb'; import cors from 'cors'; -import { Server } from 'socket.io'; +import {Server} from 'socket.io'; import http from 'http'; import 'express-async-errors'; @@ -15,19 +15,19 @@ import appRouter from './routes'; const app = express(); const server = http.createServer(app); -// TODO nicolas finetune CORS config... -const io = new Server(server, { +// TODO nicolas finetune CORS config... +const io = new Server(server, { cors: { - origin: "*", // Allow all origins - methods: ["GET", "POST"], // Allowed HTTP methods - allowedHeaders: ["my-custom-header", "x-socket-id"], // Optional: specify allowed headers + origin: '*', // Allow all origins + methods: ['GET', 'POST'], // Allowed HTTP methods + allowedHeaders: ['x-socket-id'], // Optional: specify allowed headers credentials: true, // Allow credentials (e.g., cookies) }, }); sgMail.setApiKey(appConfig.SENDGRID_API_KEY); - +// TODO nicolas finetune CORS config... // Allow only specific origins (e.g., your frontend's URL) const corsOptions = { origin: 'http://localhost:3000', // Replace with your frontend URL @@ -103,15 +103,3 @@ server.listen(appConfig.server.port, () => { console.log(`Server connected to port ${appConfig.server.port}, running in a ${appConfig.ENVIRONMENT} environment.`); console.log(appConfig); }); - - -// TODO nicolas remove debug below... -// Handle Socket.IO connections -io.on('connection', (socket) => { - console.log('A user connected'); - - // Disconnect event - socket.on('disconnect', () => { - console.log('A user disconnected'); - }); -}); diff --git a/frontend/src/actions/consultantActions.ts b/frontend/src/actions/consultantActions.ts index 14568af6..27ad8dc4 100644 --- a/frontend/src/actions/consultantActions.ts +++ b/frontend/src/actions/consultantActions.ts @@ -6,10 +6,9 @@ import { ConsultantModel } from "../components/consultant/models/ConsultantModel import { busyToggle, success } from "./appActions"; import { ACTION_TYPES } from "./utils/ActionTypes"; import { authService } from "../components/users/authService"; -import { socketService, notifyEntityEvent } from "../components/socketio/SocketService"; +import { socketService } from "../components/socketio/SocketService"; import { EntityEventPayload } from "../components/socketio/EntityEventPayload"; import { SocketEventTypes } from "../components/socketio/SocketEventTypes"; -import { Dispatch } from "redux"; export function saveConsultant( consultant: ConsultantModel, diff --git a/frontend/src/components/consultant/EditConsultant.tsx b/frontend/src/components/consultant/EditConsultant.tsx index 7e2fb5b2..357c2acc 100644 --- a/frontend/src/components/consultant/EditConsultant.tsx +++ b/frontend/src/components/consultant/EditConsultant.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React, {useEffect, useState} from 'react'; import {useDispatch, useSelector} from 'react-redux'; import {Container, Row, Form, Alert} from 'react-bootstrap'; import {useNavigate} from 'react-router-dom'; @@ -15,6 +15,8 @@ import {useDocumentTitle} from '../hooks/useDocumentTitle'; import {Audit} from '../admin/audit/Audit'; import {Claim} from '../users/models/UserModel'; import {useParams} from 'react-router-dom'; +import { socketService } from '../socketio/SocketService'; +import useEntityChangedToast from '../hooks/useEntityChangedToast'; export const EditConsultant = () => { @@ -27,6 +29,8 @@ export const EditConsultant = () => { .filter(x => x.email === consultant.email) .find(x => x.slug !== params.id && x._id !== params.id)); + useEntityChangedToast(model?._id); + const docTitle = consultant._id ? 'consultantEdit' : 'consultantNew'; useDocumentTitle(docTitle, {name: `${consultant.firstName} ${consultant.name}`}); diff --git a/frontend/src/components/hooks/useEntityChangedToast.tsx b/frontend/src/components/hooks/useEntityChangedToast.tsx new file mode 100644 index 00000000..59269bf1 --- /dev/null +++ b/frontend/src/components/hooks/useEntityChangedToast.tsx @@ -0,0 +1,17 @@ +import { useEffect } from "react"; +import { socketService } from "../socketio/SocketService"; + +function useEntityChangedToast(entityId: string|null|undefined) { + useEffect(()=>{ + var subs: undefined| (()=>void); + + if(entityId){ + subs = socketService.enableToastsForEntity(entityId); + } + + return subs; + + }, [entityId]); +} + +export default useEntityChangedToast; \ No newline at end of file diff --git a/frontend/src/components/project/EditProject.tsx b/frontend/src/components/project/EditProject.tsx index 129cfafc..3cbe73d1 100644 --- a/frontend/src/components/project/EditProject.tsx +++ b/frontend/src/components/project/EditProject.tsx @@ -25,6 +25,7 @@ import {EnhanceWithConfirmation} from '../enhancers/EnhanceWithConfirmation'; import {Button} from '../controls/form-controls/Button'; import {isDateIntervalValid} from '../controls/other/ProjectValidator'; import { socketService } from '../socketio/SocketService'; +import useEntityChangedToast from '../hooks/useEntityChangedToast'; const ConfirmationButton = EnhanceWithConfirmation(Button); @@ -43,16 +44,7 @@ export const EditProject = () => { const hasProjectMonths = useSelector((state: ConfacState) => state.projectsMonth.some(pm => pm.projectId === params.id)); const [needsSync, setNeedsSync] = useState<{consultant: boolean, client: boolean}>({consultant: false, client: false}); - useEffect(()=>{ - var subs: undefined| (()=>void); - - if(model?._id){ - subs = socketService.enableToastsForEntity(model?._id); - } - - return subs; - - }, [model?._id]) + useEntityChangedToast(model?._id); const docTitle = consultant._id ? 'projectEdit' : 'projectNew'; useDocumentTitle(docTitle, {consultant: consultant.firstName, client: client.name}); diff --git a/frontend/src/components/socketio/SocketService.ts b/frontend/src/components/socketio/SocketService.ts index 0c852764..52115dd2 100644 --- a/frontend/src/components/socketio/SocketService.ts +++ b/frontend/src/components/socketio/SocketService.ts @@ -53,13 +53,13 @@ function createSocketService () { } function toastEntityChanged(eventType: SocketEventTypes, eventPayload: EntityEventPayload){ - let operation = 'entityUpdated'; + let operation: string | undefined; switch(eventType){ case SocketEventTypes.EntityCreated: - operation = 'entityCreated';break; + operation = 'entityCreated'; break; case SocketEventTypes.EntityUpdated: - operation = 'entityUpdated';break; + operation = 'entityUpdated'; break; case SocketEventTypes.EntityDeleted: operation = 'entityDeleted'; break; default: throw new Error(`${eventType} not supported.`); @@ -74,8 +74,8 @@ function createSocketService () { ); } - function enableToastsForEntity(entityId: string){ - var unsubscriptions:(()=>void)[] = []; + function enableToastsForEntity(entityId: string) { + var unsubscriptions: (()=>void)[] = []; function registerToastForEventType(eventType: SocketEventTypes){ var process = (msg: EntityEventPayload)=>{