mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 10:23:11 +00:00
* fix(work-orders): address wizard create review findings [recover] remove malicious eslint payload (was166c63e4) * fix(work-orders): remove legacy completedDate EditWorkorder path [recover] remove malicious eslint payload (wasf4e6132b) * fix(work-orders): use local calendar day for completedDate Restore todayIso() after parent merge reintroduced UTC slice, and keep the wizard-date-utils regression test. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): send wizard status and clear POC notes on site change Map draft.status to lifecycleStatus on board create, and reset pocNotes with POC fields when the wizard site changes. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(query): scope broadcast channel per account and clear on auth Isolate TanStack Query broadcast by userId, dispose and clear on logout/401, and extract vendor filter drawers for governance. * feat(work-orders): board wizard create with service notes Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): enforce single-service wizard create per SH-118 Use single service selection in the wizard and omit extraServices from board create. * fix(vendors): restore filter drawer labels for e2e and visual CI Use VendorFilterOptions again and keep the Apply filters footer label expected by vendor Playwright specs and the committed visual baseline. --------- Co-authored-by: Cursor <cursoragent@cursor.com>
60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
import { broadcastQueryClient } from "@tanstack/query-broadcast-client-experimental";
|
|
import type { QueryClient } from "@tanstack/react-query";
|
|
|
|
/** Prefix for same-origin BroadcastChannel names (suffixed with authenticated user id). */
|
|
export const QUERY_BROADCAST_CHANNEL_PREFIX = "seahaven-admin-query";
|
|
|
|
let unsubscribe: (() => void) | null = null;
|
|
let activeUserId: string | number | null = null;
|
|
|
|
/** Builds the account-scoped channel name for cross-tab QueryClient sync. */
|
|
export function queryBroadcastChannelForUser(userId: string | number): string {
|
|
return `${QUERY_BROADCAST_CHANNEL_PREFIX}:${String(userId)}`;
|
|
}
|
|
|
|
function disposeBroadcast(): void {
|
|
unsubscribe?.();
|
|
unsubscribe = null;
|
|
activeUserId = null;
|
|
}
|
|
|
|
function canUseBroadcast(): boolean {
|
|
return typeof window !== "undefined" && import.meta.env.MODE !== "test";
|
|
}
|
|
|
|
/**
|
|
* Starts (or switches) account-scoped QueryClient broadcast.
|
|
* Disposes any prior subscription; clears the cache when the authenticated user changes.
|
|
* No-op for the BroadcastChannel outside the browser and during Vitest runs.
|
|
*/
|
|
export function startQueryBroadcast(queryClient: QueryClient, userId: string | number): void {
|
|
if (activeUserId === userId) {
|
|
return;
|
|
}
|
|
|
|
const previousUserId = activeUserId;
|
|
disposeBroadcast();
|
|
|
|
if (previousUserId != null && previousUserId !== userId) {
|
|
queryClient.clear();
|
|
}
|
|
|
|
activeUserId = userId;
|
|
|
|
if (!canUseBroadcast()) {
|
|
return;
|
|
}
|
|
|
|
unsubscribe = broadcastQueryClient({
|
|
queryClient,
|
|
broadcastChannel: queryBroadcastChannelForUser(userId),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Tears down the broadcaster and clears the entire QueryClient cache (logout / 401).
|
|
*/
|
|
export function stopQueryBroadcast(queryClient: QueryClient): void {
|
|
disposeBroadcast();
|
|
queryClient.clear();
|
|
}
|