diff --git a/ui/src/context/LiveUpdatesProvider.tsx b/ui/src/context/LiveUpdatesProvider.tsx index d262691e..6a1403af 100644 --- a/ui/src/context/LiveUpdatesProvider.tsx +++ b/ui/src/context/LiveUpdatesProvider.tsx @@ -227,6 +227,29 @@ function buildActivityToast( }; } +function buildJoinRequestToast( + payload: Record, +): ToastInput | null { + const entityType = readString(payload.entityType); + const action = readString(payload.action); + const entityId = readString(payload.entityId); + const details = readRecord(payload.details); + + if (entityType !== "join_request" || !action || !entityId) return null; + if (action !== "join.requested" && action !== "join.request_replayed") return null; + + const requestType = readString(details?.requestType); + const label = requestType === "agent" ? "Agent" : "Someone"; + + return { + title: `${label} wants to join`, + body: "A new join request is waiting for approval.", + tone: "info", + action: { label: "View inbox", href: "/inbox/new" }, + dedupeKey: `join-request:${entityId}`, + }; +} + function buildAgentStatusToast( payload: Record, nameOf: (id: string) => string | null, @@ -461,7 +484,9 @@ function handleLiveEvent( if (event.type === "activity.logged") { invalidateActivityQueries(queryClient, expectedCompanyId, payload); const action = readString(payload.action); - const toast = buildActivityToast(queryClient, expectedCompanyId, payload); + const toast = + buildActivityToast(queryClient, expectedCompanyId, payload) ?? + buildJoinRequestToast(payload); if (toast) gatedPushToast(gate, pushToast, `activity:${action ?? "unknown"}`, toast); } }