@medplum/dosespot-react
Version:
Medplum DoseSpot React SDK
8 lines (7 loc) • 8.05 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/common.ts", "../../src/useDoseSpotIFrame.ts", "../../src/useDoseSpotNotifications.ts"],
"sourcesContent": ["// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors\n// SPDX-License-Identifier: Apache-2.0\nimport { Identifier } from '@medplum/fhirtypes';\n\nexport const MEDPLUM_BOT_SYSTEM = 'https://www.medplum.com/bots';\n\nexport const DOSESPOT_PATIENT_ID_SYSTEM = 'https://dosespot.com/patient-id';\n\nexport const DOSESPOT_PATIENT_SYNC_BOT: Identifier = { system: MEDPLUM_BOT_SYSTEM, value: 'dosespot-patient-sync-bot' };\n\nexport const DOSESPOT_IFRAME_BOT: Identifier = { system: MEDPLUM_BOT_SYSTEM, value: 'dosespot-iframe-bot' };\n\nexport const DOSESPOT_MEDICATION_HISTORY_BOT: Identifier = {\n system: MEDPLUM_BOT_SYSTEM,\n value: 'dosespot-medication-history-bot',\n};\n\nexport const DOSESPOT_PRESCRIPTIONS_SYNC_BOT: Identifier = {\n system: MEDPLUM_BOT_SYSTEM,\n value: 'dosespot-prescriptions-sync-bot',\n};\n\nexport const DOSESPOT_NOTIFICATION_COUNTS_BOT: Identifier = {\n system: MEDPLUM_BOT_SYSTEM,\n value: 'dosespot-notification-counts-bot',\n};\n\nexport interface DoseSpotNotificationCountsResponse {\n PendingPrescriptionsCount: number;\n PendingRxChangeCount: number;\n RefillRequestsCount: number;\n TransactionErrorsCount: number;\n}\n", "// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors\n// SPDX-License-Identifier: Apache-2.0\nimport { useMedplum } from '@medplum/react-hooks';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { DOSESPOT_IFRAME_BOT, DOSESPOT_PATIENT_SYNC_BOT } from './common';\n\nexport interface DoseSpotIFrameOptions {\n readonly patientId?: string;\n readonly onPatientSyncSuccess?: () => void;\n readonly onIframeSuccess?: (url: string) => void;\n readonly onError?: (err: unknown) => void;\n}\n\nexport function useDoseSpotIFrame(options: DoseSpotIFrameOptions): string | undefined {\n const medplum = useMedplum();\n const { patientId, onPatientSyncSuccess, onIframeSuccess, onError } = options;\n const initializingRef = useRef<boolean>(false);\n const [iframeUrl, setIframeUrl] = useState<string | undefined>(undefined);\n\n const onPatientSyncSuccessRef = useRef(onPatientSyncSuccess);\n onPatientSyncSuccessRef.current = onPatientSyncSuccess;\n\n const onIframeSuccessRef = useRef(onIframeSuccess);\n onIframeSuccessRef.current = onIframeSuccess;\n\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n const initPage = useCallback(async () => {\n if (initializingRef.current) {\n return;\n }\n\n initializingRef.current = true;\n try {\n if (patientId) {\n await medplum.executeBot(DOSESPOT_PATIENT_SYNC_BOT, { patientId });\n onPatientSyncSuccessRef.current?.();\n }\n const result = await medplum.executeBot(DOSESPOT_IFRAME_BOT, { patientId });\n if (result.url) {\n setIframeUrl(result.url);\n onIframeSuccessRef.current?.(result.url);\n }\n } catch (err: unknown) {\n onErrorRef.current?.(err);\n }\n }, [medplum, patientId]);\n\n useEffect(() => {\n initPage().catch(console.error);\n }, [initPage]);\n\n return iframeUrl;\n}\n", "// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors\n// SPDX-License-Identifier: Apache-2.0\nimport { useMedplum } from '@medplum/react-hooks';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { DOSESPOT_NOTIFICATION_COUNTS_BOT, DoseSpotNotificationCountsResponse } from './common';\n\nexport interface DoseSpotNotificationsOptions {\n readonly refreshIntervalMilliseconds?: number;\n readonly onChange?: (count: number) => void;\n readonly onError?: (err: unknown) => void;\n}\n\nconst DEFAULT_REFRESH_INTERVAL_MILLISECONDS = 10000;\n\nexport function useDoseSpotNotifications(options?: DoseSpotNotificationsOptions): number | undefined {\n const medplum = useMedplum();\n const { onChange, onError } = options ?? {};\n const hasDoseSpot = medplum.getProjectMembership()?.identifier?.some((i) => i.system?.includes('dosespot'));\n const refreshInterval = options?.refreshIntervalMilliseconds ?? DEFAULT_REFRESH_INTERVAL_MILLISECONDS;\n const timerRef = useRef<NodeJS.Timeout | undefined>(undefined);\n const [unreadCount, setUnreadCount] = useState<number | undefined>(undefined);\n\n const stopTimer = useCallback(() => {\n const timerId = timerRef.current;\n if (timerId) {\n clearInterval(timerId);\n }\n }, []);\n\n const updateCount = useCallback(async () => {\n try {\n const result = (await medplum.executeBot(\n DOSESPOT_NOTIFICATION_COUNTS_BOT,\n {}\n )) as DoseSpotNotificationCountsResponse;\n\n let newCount = 0;\n if (result.PendingPrescriptionsCount) {\n newCount += result.PendingPrescriptionsCount;\n }\n if (result.PendingRxChangeCount) {\n newCount += result.PendingRxChangeCount;\n }\n if (result.RefillRequestsCount) {\n newCount += result.RefillRequestsCount;\n }\n if (result.TransactionErrorsCount) {\n newCount += result.TransactionErrorsCount;\n }\n if (newCount !== unreadCount) {\n setUnreadCount(newCount);\n onChange?.(newCount);\n }\n } catch (err: unknown) {\n onError?.(err);\n stopTimer();\n }\n }, [medplum, unreadCount, onChange, onError, stopTimer]);\n\n const startTimer = useCallback(() => {\n timerRef.current = setInterval(() => {\n updateCount().catch(console.error);\n }, refreshInterval);\n }, [updateCount, refreshInterval]);\n\n useEffect(() => {\n // Start an interval timer to update the count every 5 seconds\n if (hasDoseSpot) {\n startTimer();\n }\n\n // Clear the interval timer when the component is unmounted\n return stopTimer;\n }, [hasDoseSpot, startTimer, stopTimer]);\n\n return unreadCount;\n}\n"],
"mappings": "AAIO,IAAM,mBAAqB,+BAErB,2BAA6B,kCAE7B,0BAAwC,CAAE,OAAQ,mBAAoB,MAAO,2BAA4B,EAEzG,oBAAkC,CAAE,OAAQ,mBAAoB,MAAO,qBAAsB,EAE7F,gCAA8C,CACzD,OAAQ,mBACR,MAAO,iCACT,EAEa,gCAA8C,CACzD,OAAQ,mBACR,MAAO,iCACT,EAEa,iCAA+C,CAC1D,OAAQ,mBACR,MAAO,kCACT,ECvBA,OAAS,eAAkB,uBAC3B,OAAS,YAAa,UAAW,OAAQ,aAAgB,QAUlD,SAAS,kBAAkB,QAAoD,CACpF,IAAM,QAAU,WAAW,EACrB,CAAE,UAAW,qBAAsB,gBAAiB,OAAQ,EAAI,QAChE,gBAAkB,OAAgB,EAAK,EACvC,CAAC,UAAW,YAAY,EAAI,SAA6B,MAAS,EAElE,wBAA0B,OAAO,oBAAoB,EAC3D,wBAAwB,QAAU,qBAElC,IAAM,mBAAqB,OAAO,eAAe,EACjD,mBAAmB,QAAU,gBAE7B,IAAM,WAAa,OAAO,OAAO,EACjC,WAAW,QAAU,QAErB,IAAM,SAAW,YAAY,SAAY,CACvC,GAAI,iBAAgB,QAIpB,iBAAgB,QAAU,GAC1B,GAAI,CACE,YACF,MAAM,QAAQ,WAAW,0BAA2B,CAAE,SAAU,CAAC,EACjE,wBAAwB,UAAU,GAEpC,IAAM,OAAS,MAAM,QAAQ,WAAW,oBAAqB,CAAE,SAAU,CAAC,EACtE,OAAO,MACT,aAAa,OAAO,GAAG,EACvB,mBAAmB,UAAU,OAAO,GAAG,EAE3C,OAAS,IAAc,CACrB,WAAW,UAAU,GAAG,CAC1B,EACF,EAAG,CAAC,QAAS,SAAS,CAAC,EAEvB,iBAAU,IAAM,CACd,SAAS,EAAE,MAAM,QAAQ,KAAK,CAChC,EAAG,CAAC,QAAQ,CAAC,EAEN,SACT,CCpDA,OAAS,cAAAA,gBAAkB,uBAC3B,OAAS,eAAAC,aAAa,aAAAC,WAAW,UAAAC,QAAQ,YAAAC,cAAgB,QASzD,IAAM,sCAAwC,IAEvC,SAAS,yBAAyB,QAA4D,CACnG,IAAM,QAAUC,YAAW,EACrB,CAAE,SAAU,OAAQ,EAAI,SAAW,CAAC,EACpC,YAAc,QAAQ,qBAAqB,GAAG,YAAY,KAAM,GAAM,EAAE,QAAQ,SAAS,UAAU,CAAC,EACpG,gBAAkB,SAAS,6BAA+B,sCAC1D,SAAWC,QAAmC,MAAS,EACvD,CAAC,YAAa,cAAc,EAAIC,UAA6B,MAAS,EAEtE,UAAYC,aAAY,IAAM,CAClC,IAAM,QAAU,SAAS,QACrB,SACF,cAAc,OAAO,CAEzB,EAAG,CAAC,CAAC,EAEC,YAAcA,aAAY,SAAY,CAC1C,GAAI,CACF,IAAM,OAAU,MAAM,QAAQ,WAC5B,iCACA,CAAC,CACH,EAEI,SAAW,EACX,OAAO,4BACT,UAAY,OAAO,2BAEjB,OAAO,uBACT,UAAY,OAAO,sBAEjB,OAAO,sBACT,UAAY,OAAO,qBAEjB,OAAO,yBACT,UAAY,OAAO,wBAEjB,WAAa,cACf,eAAe,QAAQ,EACvB,WAAW,QAAQ,EAEvB,OAAS,IAAc,CACrB,UAAU,GAAG,EACb,UAAU,CACZ,CACF,EAAG,CAAC,QAAS,YAAa,SAAU,QAAS,SAAS,CAAC,EAEjD,WAAaA,aAAY,IAAM,CACnC,SAAS,QAAU,YAAY,IAAM,CACnC,YAAY,EAAE,MAAM,QAAQ,KAAK,CACnC,EAAG,eAAe,CACpB,EAAG,CAAC,YAAa,eAAe,CAAC,EAEjC,OAAAC,WAAU,KAEJ,aACF,WAAW,EAIN,WACN,CAAC,YAAa,WAAY,SAAS,CAAC,EAEhC,WACT",
"names": ["useMedplum", "useCallback", "useEffect", "useRef", "useState", "useMedplum", "useRef", "useState", "useCallback", "useEffect"]
}