feature/IO-3096-GlobalNotifications - Checkpoint - Notification Center

This commit is contained in:
Dave Richer
2025-02-24 18:04:15 -05:00
parent b395839b37
commit 4f1c0b9996
9 changed files with 275 additions and 48 deletions

View File

@@ -4,7 +4,8 @@ import { auth } from "../../firebase/firebase.utils";
import { store } from "../../redux/store";
import { addAlerts, setWssStatus } from "../../redux/application/application.actions";
import client from "../../utils/GraphQLClient";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { useNotification } from "../Notifications/notificationContext.jsx";
import { gql } from "@apollo/client";
const useSocket = (bodyshop) => {
const socketRef = useRef(null);
@@ -79,39 +80,88 @@ const useSocket = (bodyshop) => {
};
const handleNotification = (data) => {
const { jobId, bodyShopId, notifications, notificationId } = data;
console.log("handleNotification - Received", { jobId, bodyShopId, notificationId, notifications });
const { jobId, bodyShopId, notificationId, associationId, notifications } = data; // Changed to associationId (capital I)
console.log("handleNotification - Received", {
jobId,
bodyShopId,
notificationId,
associationId,
notifications
});
// Construct the notification object to match the cache/database format
const newNotification = {
__typename: "notifications",
id: notificationId,
jobid: jobId,
associationid: null,
scenario_text: notifications.map((notif) => notif.body),
associationid: associationId || null, // Use associationId from socket, default to null if missing
scenario_text: JSON.stringify(notifications.map((notif) => notif.body)), // Stringify as in the cache
fcm_text: notifications.map((notif) => notif.body).join(". ") + ".",
scenario_meta: notifications.map((notif) => notif.variables || {}),
scenario_meta: JSON.stringify(notifications.map((notif) => notif.variables || {})), // Stringify as in the cache
created_at: new Date(notifications[0].timestamp).toISOString(),
read: null,
__typename: "notifications"
read: null // Assume unread unless specified otherwise
};
try {
// Use writeQuery to add the new notification to the cache, ensuring normalization and broadcasting
client.cache.writeQuery({
query: gql`
query GetNotifications {
notifications(order_by: { created_at: desc }) {
__typename
id
jobid
associationid
scenario_text
fcm_text
scenario_meta
created_at
read
}
}
`,
data: {
notifications: [
newNotification,
...(
client.cache.readQuery({
query: gql`
query GetNotifications {
notifications(order_by: { created_at: desc }) {
__typename
id
jobid
associationid
scenario_text
fcm_text
scenario_meta
created_at
read
}
}
`
})?.notifications || []
).filter((n) => n.id !== newNotification.id)
].sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) // Sort by created_at desc
},
broadcast: true // Notify dependent queries of the cache update
});
console.log("Cache updated with new notification:", newNotification);
// Update notifications_aggregate for unread count
client.cache.modify({
id: "ROOT_QUERY",
fields: {
notifications(existing = []) {
if (existing.some((n) => n.id === newNotification.id)) return existing;
console.log("Adding to cache", newNotification);
return [newNotification, ...existing];
},
notifications_aggregate(existing = { aggregate: { count: 0 } }) {
// Fallback if aggregate isnt in schema yet
if (!existing) return existing;
console.log("Updating unread count", existing.aggregate.count + 1);
const isUnread = newNotification.read === null;
const countChange = isUnread ? 1 : 0;
console.log("Updating unread count from socket:", existing.aggregate.count + countChange);
return {
...existing,
aggregate: {
...existing.aggregate,
count: existing.aggregate.count + 1
count: existing.aggregate.count + countChange
}
};
}
@@ -183,7 +233,7 @@ const useSocket = (bodyshop) => {
socketRef.current = null;
}
};
}, [bodyshop, client.cache]);
}, [bodyshop, notification]);
return { socket: socketRef.current, clientId };
};