import { useCallback, useEffect, useRef } from 'react'; import { PractitionerWithRoles, useAuthServiceContext, usePractitionerServiceContext } from '../services'; import { useRereadOnJoinRecovery } from './useRereadOnJoinRecovery'; const listsThisPractice = (entries: PractitionerWithRoles[], organizationId: string | undefined) => !!organizationId && entries.some((entry) => entry.roles?.some((role) => role.organization?.reference === `Organization/${organizationId}`)); /** * Who a staff member can message: the staff directory when their role may read it and it is this * practice's, otherwise the colleague list every staff role may read, loaded for the current user and * practice. Messaging screens use this; screens that manage staff keep the directory and its denial. * `refreshOnMount` reads the colleague list once more when the caller mounts, keeping the held one meanwhile; * once that answer lands it is the list, since a held staff directory may predate a colleague who joined. */ // `enabled` false is a reader with no staff messaging (a patient, or a helper in somebody's record): it asks for // nothing, its retry and a recovered join cannot start a read, and it holds no staff rows. export const useColleagueDirectory = ( { refreshOnMount = false, enabled = true }: { refreshOnMount?: boolean; enabled?: boolean } = {}, ) => { const { practitionersList, colleagues, loadColleagues } = usePractitionerServiceContext(); const { currentUser, wpOrganization, joinRecovery } = useAuthServiceContext(); const organizationId = wpOrganization?.current?.id; const key = `${currentUser?.fhir?.id ?? ''}|${organizationId ?? ''}`; const current = colleagues?.key === key ? colleagues : undefined; const askedOnMount = useRef(false); const heldAtMountAsk = useRef(null); useEffect(() => { if (!enabled || !organizationId) return; const mountAsk = refreshOnMount && !askedOnMount.current; askedOnMount.current = true; if (mountAsk) heldAtMountAsk.current = current; if (!current || mountAsk) void loadColleagues(key); }, [enabled, organizationId, key, current, loadColleagues, refreshOnMount]); const retry = useCallback(() => { if (enabled) void loadColleagues(key); }, [enabled, key, loadColleagues]); useRereadOnJoinRecovery(joinRecovery, retry); if (!enabled) return { list: [] as PractitionerWithRoles[], status: 'ready' as const, retry }; const answeredSinceMount = heldAtMountAsk.current !== null && current?.status === 'ready' && current !== heldAtMountAsk.current; if (answeredSinceMount) { return { list: current.list, status: 'ready' as const, retry }; } if (listsThisPractice(practitionersList, organizationId)) { return { list: practitionersList, status: 'ready' as const, retry }; } return { list: current?.status === 'ready' ? current.list : [], status: current?.status ?? ('loading' as const), retry, }; };