import * as signalR from "@microsoft/signalr"; import { cacheData, clearCacheKey, getCachedData, } from "../slices/apiDataManager"; import showToast from "./toastService"; import eventBus from "./eventBus"; import { useSelector } from "react-redux"; import { clearApiCacheKey } from "../slices/apiCacheSlice"; import { BASE_URL } from "../utils/constants"; import { queryClient } from "../layouts/AuthLayout"; const base_Url = BASE_URL; let connection = null; const targetPath = ""; export function startSignalR(loggedUser) { var jwtToken = localStorage.getItem("jwtToken"); connection = new signalR.HubConnectionBuilder() .withUrl(`${base_Url}/hubs/marco`, { accessTokenFactory: () => jwtToken, transport: signalR.HttpTransportType.LongPolling, withCredentials: false, }) // .withKeepAliveInterval(30000) // .withServerTimeout(30000) .withAutomaticReconnect() .build(); connection.serverTimeoutInMilliseconds = 30000; // 60 seconds const todayDate = new Date(); const today = new Date( Date.UTC(todayDate.getFullYear(), todayDate.getMonth(), todayDate.getDate()) ) .toISOString() .split("T")[0]; connection.on("NotificationEventHandler", (data) => { const { loggedInUserId, keyword, response, employeeList, numberOfImages } = data; const loggedInId = loggedUser?.employeeInfo?.id; if (loggedInUserId === loggedInId) return; // ---- Handlers for invalidate or remove ---- const queryInvalidators = { Payment_Request: () => { queryClient.invalidateQueries({ queryKey: ["paymentRequestList"] }), queryClient.invalidateQueries({ queryKey: ["paymentRequest"] }); }, Recurring_Payment: () => { queryClient.invalidateQueries({ queryKey: ["recurringExpenseList"] }), queryClient.invalidateQueries({ queryKey: ["recurringExpense"] }); }, Expanse: () => { queryClient.invalidateQueries({ queryKey: ["Expenses"] }), queryClient.invalidateQueries({ queryKey: ["Expense"] }); }, Create_Project: () => queryClient.invalidateQueries(["projectslist"]), Update_Project: () => queryClient.invalidateQueries(["projectslist"]), Infra: () => queryClient.removeQueries({ queryKey: ["ProjectInfra"] }), Task_Report: () => queryClient.invalidateQueries({ queryKey: ["Infra"] }), WorkItem: () => queryClient.invalidateQueries({ queryKey: ["WorkItems"] }), Directory_Notes: () => { queryClient.invalidateQueries({ queryKey: ["directoryNotes"] }); queryClient.invalidateQueries({ queryKey: ["Notes"] }); }, Directory_Buckets: () => { queryClient.invalidateQueries({ queryKey: ["bucketList"] }); }, Directory: () => { queryClient.invalidateQueries({ queryKey: ["contacts"] }); queryClient.invalidateQueries({ queryKey: ["Contact"] }); queryClient.invalidateQueries({ queryKey: ["ContactProfile"] }); }, }; // ---- Keyword based event emitters ---- const emitters = { employee: () => eventBus.emit("employee", data), project: () => eventBus.emit("project", data), infra: () => eventBus.emit("infra", data), assign_project_all: () => eventBus.emit("assign_project_all", data), image_gallery: () => eventBus.emit("image_gallery", data), }; // ---- Handle Attendance ---- if (keyword === "Attendance") { const checkIn = response.checkInTime.substring(0, 10); if (today === checkIn) eventBus.emit("attendance", data); const onlyDate = Number(checkIn.substring(8, 10)); const afterTwoDay = checkIn.substring(0, 8) + (onlyDate + 2).toString().padStart(2, "0"); if ( afterTwoDay <= today && (response.activity === 4 || response.activity === 5) ) { eventBus.emit("regularization", data); } eventBus.emit("attendance_log", data); } // ---- Invalidate/Remove cache by keywords ---- if (queryInvalidators[keyword]) { queryInvalidators[keyword](); } // ---- Project creation/update ---- if (keyword === "Create_Project" || keyword === "Update_Project") { emitters.project(); } // ---- Assign/deassign project ---- if (keyword === "Assign_Project") { if (employeeList?.includes(loggedInId)) { try { cacheData("hasReceived", false); eventBus.emit("assign_project_one", data); } catch {} } emitters.assign_project_all(); } // ---- Employee update ---- if (keyword === "Employee") { clearCacheKey("Attendance"); clearCacheKey("regularizedList"); clearCacheKey("AttendanceLogs"); queryClient.invalidateQueries(["allEmployee", true]); queryClient.invalidateQueries(["allEmployee", false]); queryClient.invalidateQueries(["employeeProfile", response?.employeeId]); queryClient.invalidateQueries(["employeeListByProject"]); emitters.employee(); } // ---- Image related events ---- if ( ["Task_Report", "Task_Comment"].includes(keyword) && numberOfImages > 0 ) { emitters.image_gallery(); } // --- Service Project ---------------- if (keyword === "Service_Project") { queryClient.invalidateQueries(["serviceProjects"]); queryClient.invalidateQueries(["serviceProject"]); } if (keyword === "Project_Branch") { queryClient.invalidateQueries(["branches"]); } if (keyword === "Service_Project_Allocation") { queryClient.invalidateQueries(["serviceProjectTeam"]); } if (keyword === "Job_Ticket") { queryClient.invalidateQueries(["serviceProjectJobs"]); queryClient.invalidateQueries(["service-job"]); } if (keyword === "Job_Ticket_Comment") { queryClient.invalidateQueries(["jobComments"]); } }); connection.start(); } export function stopSignalR() { if (connection) connection.stop(); }