IO-2924-Refactor-Production-board-to-use-Socket-Provider: rough in split logic / production-board-kanban.container.jsx logic

Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
Dave Richer
2024-09-25 17:44:53 -04:00
parent 50fe588949
commit 3b647dfd37

View File

@@ -1,15 +1,18 @@
import React, { useEffect, useMemo, useRef } from "react";
import { useQuery, useSubscription } from "@apollo/client";
import React, { useEffect, useMemo, useRef, useContext } from "react";
import { useQuery, useSubscription, useApolloClient, gql } from "@apollo/client";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import {
QUERY_JOBS_IN_PRODUCTION,
SUBSCRIPTION_JOBS_IN_PRODUCTION,
SUBSCRIPTION_JOBS_IN_PRODUCTION_VIEW
SUBSCRIPTION_JOBS_IN_PRODUCTION_VIEW,
GET_JOB_BY_PK
} from "../../graphql/jobs.queries";
import { QUERY_KANBAN_SETTINGS } from "../../graphql/user.queries";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import ProductionBoardKanbanComponent from "./production-board-kanban.component";
import { useSplitTreatments } from "@splitsoftware/splitio-react";
import SocketContext from "../../contexts/SocketIO/socketContext.jsx";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -17,7 +20,17 @@ const mapStateToProps = createStructuredSelector({
});
function ProductionBoardKanbanContainer({ bodyshop, currentUser, subscriptionType = "direct" }) {
const fired = useRef(false); // useRef to keep track of whether the subscription fired
const fired = useRef(false);
const client = useApolloClient();
const { socket } = useContext(SocketContext); // Get the socket from context
const {
treatments: { Websocket_Production }
} = useSplitTreatments({
attributes: {},
names: ["Websocket_Production"],
splitKey: bodyshop && bodyshop.imexshopid
});
const combinedStatuses = useMemo(
() => [
@@ -34,9 +47,12 @@ function ProductionBoardKanbanContainer({ bodyshop, currentUser, subscriptionTyp
onError: (error) => console.error(`Error fetching jobs in production: ${error.message}`)
});
const subscriptionEnabled = Websocket_Production?.treatment === "on";
const { data: updatedJobs } = useSubscription(
subscriptionType === "view" ? SUBSCRIPTION_JOBS_IN_PRODUCTION_VIEW : SUBSCRIPTION_JOBS_IN_PRODUCTION,
{
skip: !subscriptionEnabled,
onError: (error) => console.error(`Error subscribing to jobs in production: ${error.message}`)
}
);
@@ -46,22 +62,67 @@ function ProductionBoardKanbanContainer({ bodyshop, currentUser, subscriptionTyp
onError: (error) => console.error(`Error fetching Kanban settings: ${error.message}`)
});
// const currentReducerData = useSelector((state) => (state.trello.lanes ? state.trello : {}));
useEffect(() => {
if (!updatedJobs) {
if (subscriptionEnabled) {
if (!updatedJobs) {
return;
}
if (!fired.current) {
fired.current = true;
return;
}
refetch().catch((err) => console.error(`Error re-fetching jobs in production: ${err.message}`));
}
}, [updatedJobs, refetch, subscriptionEnabled]);
// Socket.IO implementation for users with Split treatment "off"
useEffect(() => {
if (subscriptionEnabled || !socket || !bodyshop || !bodyshop.id) {
return;
}
if (!fired.current) {
fired.current = true;
return;
}
refetch().catch((err) => console.error(`Error re-fetching jobs in production: ${err.message}`));
}, [updatedJobs, refetch]);
const handleJobChanged = async (jobChangedData) => {
const jobId = jobChangedData.jobId;
const existingJob = data?.jobs.find((job) => job.id === jobId);
if (existingJob) {
try {
const { data: jobData } = await client.query({
query: GET_JOB_BY_PK,
variables: { id: jobId },
fetchPolicy: "network-only"
});
client.writeFragment({
id: client.cache.identify({ __typename: "Job", id: jobId }),
fragment: gql`
fragment UpdatedJob on Job {
id
status
updatedAt
# ... include other fields you need to update
}
`,
data: jobData.job
});
} catch (error) {
console.error(`Error fetching job ${jobId}: ${error.message}`);
}
}
};
// Listen for 'job-changed' events
socket.on("job-changed", handleJobChanged);
// Clean up on unmount or when dependencies change
return () => {
socket.off("job-changed", handleJobChanged);
};
}, [subscriptionEnabled, socket, bodyshop, data, client]);
const filteredAssociationSettings = useMemo(() => {
return associationSettings?.associations[0] || null;
}, [associationSettings]);
}, [associationSettings?.associations]);
return (
<ProductionBoardKanbanComponent