feature/IO-2924-Refactor-Production-Board-For-Sockets - Checkpoint
Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
@@ -58,17 +58,40 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
const updatedLanes = cloneDeep(prevBoardLanes.lanes);
|
const updatedLanes = cloneDeep(prevBoardLanes.lanes);
|
||||||
|
|
||||||
// Find the lane containing the card with the updated job ID
|
// Find the lane containing the card with the updated job ID
|
||||||
const sourceLane = updatedLanes.find((lane) => lane.cards.some((card) => card.id === updatedJob.id));
|
let sourceLane = updatedLanes.find((lane) => lane.cards.some((card) => card.id === updatedJob.id));
|
||||||
|
|
||||||
if (!sourceLane) {
|
if (!sourceLane) {
|
||||||
console.error("Source lane not found for the updated job.");
|
console.log("Card not found in any lane. Checking for valid status to add it.");
|
||||||
return prevBoardLanes; // Return the previous state if no source lane is found
|
|
||||||
|
// Find the target lane based on the new status if the card does not exist
|
||||||
|
const targetLane = updatedLanes.find((lane) => lane.id === updatedJob.status);
|
||||||
|
|
||||||
|
if (targetLane && updatedJob.isInProduction) {
|
||||||
|
// Check if job is in production and status is valid
|
||||||
|
console.log(`Adding card to lane ${targetLane.title}`);
|
||||||
|
|
||||||
|
// Add the new card to the target lane
|
||||||
|
const newCard = {
|
||||||
|
id: updatedJob.id,
|
||||||
|
metadata: { ...updatedJob }
|
||||||
|
};
|
||||||
|
targetLane.cards.push(newCard);
|
||||||
|
|
||||||
|
// Update the lane title with the new card count
|
||||||
|
targetLane.title = `${targetLane.title.split(" ")[0]} (${targetLane.cards.length})`;
|
||||||
|
|
||||||
|
return { lanes: updatedLanes }; // Return early since the card is added
|
||||||
|
} else {
|
||||||
|
console.error("No valid lane or status to add the job to.");
|
||||||
|
return prevBoardLanes; // Return the previous state if no valid status or lane
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the card in the source lane
|
// If the card exists, find it in the source lane
|
||||||
const cardIndex = sourceLane.cards.findIndex((card) => card.id === updatedJob.id);
|
const cardIndex = sourceLane.cards.findIndex((card) => card.id === updatedJob.id);
|
||||||
const currentCard = sourceLane.cards[cardIndex];
|
const currentCard = sourceLane.cards[cardIndex];
|
||||||
|
|
||||||
|
// If we somehow can't find the card, return
|
||||||
if (!currentCard) {
|
if (!currentCard) {
|
||||||
console.error("Card not found for the updated job.");
|
console.error("Card not found for the updated job.");
|
||||||
return prevBoardLanes; // Return the previous state if the card is not found
|
return prevBoardLanes; // Return the previous state if the card is not found
|
||||||
@@ -76,7 +99,6 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
|
|
||||||
// Iterate through the properties of updatedJob and update the corresponding values in currentCard.metadata
|
// Iterate through the properties of updatedJob and update the corresponding values in currentCard.metadata
|
||||||
Object.keys(updatedJob).forEach((key) => {
|
Object.keys(updatedJob).forEach((key) => {
|
||||||
// Ensure the field exists in currentCard.metadata before updating it
|
|
||||||
if (key in currentCard.metadata && currentCard.metadata[key] !== updatedJob[key]) {
|
if (key in currentCard.metadata && currentCard.metadata[key] !== updatedJob[key]) {
|
||||||
console.log(`Updating ${key} from ${currentCard.metadata[key]} to ${updatedJob[key]}`);
|
console.log(`Updating ${key} from ${currentCard.metadata[key]} to ${updatedJob[key]}`);
|
||||||
currentCard.metadata[key] = updatedJob[key];
|
currentCard.metadata[key] = updatedJob[key];
|
||||||
@@ -99,10 +121,7 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
// Find the target lane based on the new status
|
// Find the target lane based on the new status
|
||||||
const targetLane = updatedLanes.find((lane) => lane.id === updatedJob.status);
|
const targetLane = updatedLanes.find((lane) => lane.id === updatedJob.status);
|
||||||
if (targetLane) {
|
if (targetLane) {
|
||||||
// Move the card to the target lane and update its data
|
|
||||||
targetLane.cards.push({ ...cardToMove, metadata: { ...currentCard.metadata } });
|
targetLane.cards.push({ ...cardToMove, metadata: { ...currentCard.metadata } });
|
||||||
|
|
||||||
// Update the lane titles with the new card count
|
|
||||||
sourceLane.title = `${sourceLane.title.split(" ")[0]} (${sourceLane.cards.length})`;
|
sourceLane.title = `${sourceLane.title.split(" ")[0]} (${sourceLane.cards.length})`;
|
||||||
targetLane.title = `${targetLane.title.split(" ")[0]} (${targetLane.cards.length})`;
|
targetLane.title = `${targetLane.title.split(" ")[0]} (${targetLane.cards.length})`;
|
||||||
} else {
|
} else {
|
||||||
@@ -112,12 +131,8 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
// Case 2: Only data has changed
|
// Case 2: Only data has changed
|
||||||
else if (isDataChanged && !isLaneChanged) {
|
else if (isDataChanged && !isLaneChanged) {
|
||||||
console.log("Case 2: Only Data Changed");
|
console.log("Case 2: Only Data Changed");
|
||||||
|
|
||||||
// Update the card's metadata in place
|
|
||||||
sourceLane.cards[cardIndex] = { ...currentCard, metadata: { ...currentCard.metadata } };
|
sourceLane.cards[cardIndex] = { ...currentCard, metadata: { ...currentCard.metadata } };
|
||||||
|
// sourceLane.cards = [...sourceLane.cards]; // Force shallow change for re-render
|
||||||
// Force a shallow change in the source lane to trigger re-render
|
|
||||||
sourceLane.cards = [...sourceLane.cards];
|
|
||||||
}
|
}
|
||||||
// Case 3: Only the lane has changed
|
// Case 3: Only the lane has changed
|
||||||
else if (!isDataChanged && isLaneChanged) {
|
else if (!isDataChanged && isLaneChanged) {
|
||||||
@@ -129,10 +144,7 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
// Find the target lane based on the new status
|
// Find the target lane based on the new status
|
||||||
const targetLane = updatedLanes.find((lane) => lane.id === updatedJob.status);
|
const targetLane = updatedLanes.find((lane) => lane.id === updatedJob.status);
|
||||||
if (targetLane) {
|
if (targetLane) {
|
||||||
// Move the card to the new lane without changing its data
|
|
||||||
targetLane.cards.push(cardToMove);
|
targetLane.cards.push(cardToMove);
|
||||||
|
|
||||||
// Update the lane titles with the new card count
|
|
||||||
sourceLane.title = `${sourceLane.title.split(" ")[0]} (${sourceLane.cards.length})`;
|
sourceLane.title = `${sourceLane.title.split(" ")[0]} (${sourceLane.cards.length})`;
|
||||||
targetLane.title = `${targetLane.title.split(" ")[0]} (${targetLane.cards.length})`;
|
targetLane.title = `${targetLane.title.split(" ")[0]} (${targetLane.cards.length})`;
|
||||||
} else {
|
} else {
|
||||||
@@ -140,7 +152,6 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the updated lanes
|
|
||||||
return { lanes: updatedLanes };
|
return { lanes: updatedLanes };
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -28,20 +28,26 @@ const useSocket = (bodyshop) => {
|
|||||||
|
|
||||||
setSocket(socketInstance);
|
setSocket(socketInstance);
|
||||||
|
|
||||||
socketInstance.on("connect", () => {
|
// When the socket connects or reconnects, join the bodyshop room
|
||||||
|
const joinRoomOnConnect = () => {
|
||||||
console.log("Socket connected:", socketInstance.id);
|
console.log("Socket connected:", socketInstance.id);
|
||||||
setClientId(socketInstance.id);
|
setClientId(socketInstance.id);
|
||||||
|
|
||||||
if (bodyshop.id) {
|
if (bodyshop.id) {
|
||||||
socketInstance.on("bodyshop-message", handleBodyshopMessage);
|
|
||||||
socketInstance.emit("join-bodyshop-room", bodyshop.id);
|
socketInstance.emit("join-bodyshop-room", bodyshop.id);
|
||||||
|
console.log(`Joined bodyshop room: ${bodyshop.id}`);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
// Set up the necessary socket event handlers
|
||||||
|
socketInstance.on("connect", joinRoomOnConnect);
|
||||||
|
|
||||||
socketInstance.on("reconnect", (attempt) => {
|
socketInstance.on("reconnect", (attempt) => {
|
||||||
console.log(`Socket reconnected after ${attempt} attempts`);
|
console.log(`Socket reconnected after ${attempt} attempts`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socketInstance.on("bodyshop-message", handleBodyshopMessage);
|
||||||
|
|
||||||
socketInstance.on("connect_error", (err) => {
|
socketInstance.on("connect_error", (err) => {
|
||||||
console.error("Socket connection error:", err);
|
console.error("Socket connection error:", err);
|
||||||
});
|
});
|
||||||
@@ -50,15 +56,13 @@ const useSocket = (bodyshop) => {
|
|||||||
console.log("Socket disconnected");
|
console.log("Socket disconnected");
|
||||||
});
|
});
|
||||||
|
|
||||||
if (bodyshop?.id) {
|
// Clean up on component unmount or when bodyshop changes
|
||||||
return () => {
|
|
||||||
socketInstance.emit("leave-bodyshop-room", bodyshop.id);
|
|
||||||
socketInstance.off("bodyshop-message", handleBodyshopMessage);
|
|
||||||
socketInstance.disconnect();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
if (bodyshop?.id) {
|
||||||
|
socketInstance.emit("leave-bodyshop-room", bodyshop.id);
|
||||||
|
}
|
||||||
|
socketInstance.off("connect", joinRoomOnConnect);
|
||||||
|
socketInstance.off("bodyshop-message", handleBodyshopMessage);
|
||||||
socketInstance.disconnect();
|
socketInstance.disconnect();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -69,24 +73,3 @@ const useSocket = (bodyshop) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default useSocket;
|
export default useSocket;
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// if (socket && bodyshop && bodyshop.id) {
|
|
||||||
// const handleConnect = () => {
|
|
||||||
// socket.emit("join-bodyshop-room", bodyshop.id);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// const handleBodyshopMessage = (message) => {
|
|
||||||
// console.log(`Received message for bodyshop ${bodyshop.id}:`, message);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// socket.on("connect", handleConnect);
|
|
||||||
// socket.on("bodyshop-message", handleBodyshopMessage);
|
|
||||||
//
|
|
||||||
// return () => {
|
|
||||||
// socket.emit("leave-bodyshop-room", bodyshop.id);
|
|
||||||
// socket.off("connect", handleConnect);
|
|
||||||
// socket.off("bodyshop-message", handleBodyshopMessage);
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }, [socket, bodyshop]);
|
|
||||||
|
|||||||
@@ -210,7 +210,8 @@ const applyRedisHelpers = (pubClient, app) => {
|
|||||||
getMultipleSessionData,
|
getMultipleSessionData,
|
||||||
setMultipleFromArraySessionData,
|
setMultipleFromArraySessionData,
|
||||||
addItemToEndOfList,
|
addItemToEndOfList,
|
||||||
addItemToBeginningOfList
|
addItemToBeginningOfList,
|
||||||
|
pubClient
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
@@ -222,7 +223,8 @@ const applyRedisHelpers = (pubClient, app) => {
|
|||||||
getMultipleSessionData,
|
getMultipleSessionData,
|
||||||
setMultipleFromArraySessionData,
|
setMultipleFromArraySessionData,
|
||||||
addItemToEndOfList,
|
addItemToEndOfList,
|
||||||
addItemToBeginningOfList
|
addItemToBeginningOfList,
|
||||||
|
pubClient
|
||||||
};
|
};
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,14 @@ require("dotenv").config({
|
|||||||
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
||||||
});
|
});
|
||||||
|
|
||||||
const { io, setSessionData, clearSessionData, getMultipleSessionData, addItemToEndOfList } = require("../../server");
|
const {
|
||||||
|
io,
|
||||||
|
setSessionData,
|
||||||
|
clearSessionData,
|
||||||
|
getMultipleSessionData,
|
||||||
|
addItemToEndOfList,
|
||||||
|
pubClient
|
||||||
|
} = require("../../server");
|
||||||
|
|
||||||
const { admin } = require("../firebase/firebase-handler");
|
const { admin } = require("../firebase/firebase-handler");
|
||||||
const logger = require("../utils/logger");
|
const logger = require("../utils/logger");
|
||||||
@@ -130,15 +137,35 @@ function registerPbsApEvents(socket) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getRedisKeyForSocket = (socketId) => `socket:${socketId}:rooms`;
|
||||||
|
|
||||||
// Room management and broadcasting events
|
// Room management and broadcasting events
|
||||||
function registerRoomAndBroadcastEvents(socket) {
|
function registerRoomAndBroadcastEvents(socket) {
|
||||||
|
// Rejoin rooms on reconnect
|
||||||
|
pubClient.lRange(getRedisKeyForSocket(socket.id), 0, -1, (err, rooms) => {
|
||||||
|
if (rooms && rooms.length > 0) {
|
||||||
|
rooms.forEach((room) => {
|
||||||
|
socket.join(room);
|
||||||
|
createLogEvent(socket, "DEBUG", `Client rejoined bodyshop room: ${room}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
socket.on("join-bodyshop-room", async (bodyshopUUID) => {
|
socket.on("join-bodyshop-room", async (bodyshopUUID) => {
|
||||||
socket.join(bodyshopUUID);
|
socket.join(bodyshopUUID);
|
||||||
|
|
||||||
|
// Store room in Redis
|
||||||
|
pubClient.rPush(getRedisKeyForSocket(socket.id), bodyshopUUID);
|
||||||
|
|
||||||
await createLogEvent(socket, "DEBUG", `Client joined bodyshop room: ${bodyshopUUID}`);
|
await createLogEvent(socket, "DEBUG", `Client joined bodyshop room: ${bodyshopUUID}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("leave-bodyshop-room", async (bodyshopUUID) => {
|
socket.on("leave-bodyshop-room", async (bodyshopUUID) => {
|
||||||
socket.leave(bodyshopUUID);
|
socket.leave(bodyshopUUID);
|
||||||
|
|
||||||
|
// Remove room from Redis
|
||||||
|
pubClient.lRem(getRedisKeyForSocket(socket.id), 0, bodyshopUUID);
|
||||||
|
|
||||||
await createLogEvent(socket, "DEBUG", `Client left bodyshop room: ${bodyshopUUID}`);
|
await createLogEvent(socket, "DEBUG", `Client left bodyshop room: ${bodyshopUUID}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -146,8 +173,12 @@ function registerRoomAndBroadcastEvents(socket) {
|
|||||||
io.to(bodyshopUUID).emit("bodyshop-message", message);
|
io.to(bodyshopUUID).emit("bodyshop-message", message);
|
||||||
await createLogEvent(socket, "INFO", `Broadcast message to bodyshop ${bodyshopUUID}`);
|
await createLogEvent(socket, "INFO", `Broadcast message to bodyshop ${bodyshopUUID}`);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
socket.on("disconnect", () => {
|
||||||
|
// Optional: Cleanup Redis entry on disconnect if needed
|
||||||
|
createLogEvent(socket, "DEBUG", `Client disconnected: ${socket.id}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
// DMS session clearing event
|
// DMS session clearing event
|
||||||
function registerDmsClearSessionEvent(socket) {
|
function registerDmsClearSessionEvent(socket) {
|
||||||
socket.on("clear-dms-session", async () => {
|
socket.on("clear-dms-session", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user