@medplum/react-hooks 5.1.26 → 5.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,11 +8,18 @@ import type { ExtractResource } from '@medplum/fhirtypes';
8
8
  import type { Identifier } from '@medplum/fhirtypes';
9
9
  import type { JSX } from 'react';
10
10
  import type { Medication } from '@medplum/fhirtypes';
11
+ import type { MedicationCartClearRequest } from '@medplum/core';
12
+ import type { MedicationCartManageResponse } from '@medplum/core';
13
+ import type { MedicationCartRemoveRequest } from '@medplum/core';
14
+ import type { MedicationCheckoutRequest } from '@medplum/core';
15
+ import type { MedicationCheckoutResponse } from '@medplum/core';
11
16
  import type { MedicationOrderRequest } from '@medplum/core';
12
17
  import type { MedicationOrderResponse } from '@medplum/core';
18
+ import type { MedicationRequest } from '@medplum/fhirtypes';
13
19
  import type { MedicationSearchParams } from '@medplum/core';
14
20
  import type { MedplumClient } from '@medplum/core';
15
21
  import type { OperationOutcome } from '@medplum/fhirtypes';
22
+ import type { OrderSetSyncResponse } from '@medplum/core';
16
23
  import type { Organization } from '@medplum/fhirtypes';
17
24
  import type { Patient } from '@medplum/fhirtypes';
18
25
  import type { PharmacySearchParams } from '@medplum/core';
@@ -30,6 +37,7 @@ import type { ReactNode } from 'react';
30
37
  import type { Reference } from '@medplum/fhirtypes';
31
38
  import type { Resource } from '@medplum/fhirtypes';
32
39
  import type { ResourceArray } from '@medplum/core';
40
+ import type { ResourceModifiedEvent } from '@medplum/core';
33
41
  import type { ResourceType } from '@medplum/fhirtypes';
34
42
  import type { SearchRequest } from '@medplum/core';
35
43
  import type { Signature } from '@medplum/fhirtypes';
@@ -37,6 +45,23 @@ import type { Subscription } from '@medplum/fhirtypes';
37
45
  import type { TypedValue } from '@medplum/core';
38
46
  import type { WithId } from '@medplum/core';
39
47
 
48
+ /**
49
+ * Applies the `questionnaire-optionExclusive` rule to an answer change.
50
+ *
51
+ * Given the previous and newly requested answers for an item, enforces that selecting an answer
52
+ * option marked exclusive clears every other answer, and selecting any other option clears a
53
+ * previously selected exclusive answer. Returns the new answers unchanged if the item has no
54
+ * exclusive options or the change only removed answers.
55
+ *
56
+ * See: https://hl7.org/fhir/extensions/StructureDefinition-questionnaire-optionExclusive.html
57
+ *
58
+ * @param item - The questionnaire item being answered.
59
+ * @param previousAnswers - The item's answers before the change.
60
+ * @param newAnswers - The answers requested by the change.
61
+ * @returns The reconciled answers.
62
+ */
63
+ export declare function applyOptionExclusive(item: QuestionnaireItem, previousAnswers: QuestionnaireResponseItemAnswer[] | undefined, newAnswers: QuestionnaireResponseItemAnswer[]): QuestionnaireResponseItemAnswer[];
64
+
40
65
  export declare function buildInitialResponse(questionnaire: Questionnaire, questionnaireResponse?: QuestionnaireResponse): QuestionnaireResponse;
41
66
 
42
67
  export declare function buildInitialResponseItem(item: QuestionnaireItem): QuestionnaireResponseItem;
@@ -106,8 +131,22 @@ export declare function isChoiceQuestion(item: QuestionnaireItem): boolean;
106
131
  */
107
132
  export declare function isQuestionEnabled(item: QuestionnaireItem, questionnaireResponse: QuestionnaireResponse | undefined): boolean;
108
133
 
134
+ /**
135
+ * Returns true if an error thrown while expanding a ValueSet means the value set itself is
136
+ * unavailable — a permanent 400/404 (e.g. "ValueSet not found"). Transient failures (429 rate
137
+ * limit, 401, 5xx, network) return false so a blip never disables a field.
138
+ * @param err - The error thrown by `valueSetExpand`.
139
+ * @returns True for a permanent 400/404, false for a transient failure.
140
+ */
141
+ export declare function isValueSetUnavailableError(err: unknown): boolean;
142
+
143
+ /** Thrown by {@link UseMedicationCartReturn.checkout} when an {@link UseMedicationCartReturn.addToCart} call is still in flight. */
144
+ export declare const MEDICATION_CART_ADD_IN_PROGRESS = "Cannot checkout while a medication is still being added to the cart";
145
+
109
146
  export declare interface MedicationIFrameOptions {
110
147
  readonly patientId?: string;
148
+ /** Selected practice location for multi-practice deployments. */
149
+ readonly organization?: Reference<Organization>;
111
150
  readonly onPatientSyncSuccess?: () => void;
112
151
  readonly onIframeSuccess?: (url: string) => void;
113
152
  readonly onError?: (err: unknown) => void;
@@ -154,6 +193,8 @@ export declare const QUESTIONNAIRE_HIDDEN_URL = "http://hl7.org/fhir/StructureDe
154
193
 
155
194
  export declare const QUESTIONNAIRE_ITEM_CONTROL_URL = "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl";
156
195
 
196
+ export declare const QUESTIONNAIRE_OPTION_EXCLUSIVE_URL = "http://hl7.org/fhir/StructureDefinition/questionnaire-optionExclusive";
197
+
157
198
  export declare const QUESTIONNAIRE_REFERENCE_FILTER_URL = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceFilter";
158
199
 
159
200
  export declare const QUESTIONNAIRE_REFERENCE_RESOURCE_URL = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource";
@@ -296,6 +337,53 @@ export declare function typedValueToResponseItem(item: QuestionnaireItem, value:
296
337
 
297
338
  export declare const useCachedBinaryUrl: (binaryUrl: string | undefined) => string | undefined;
298
339
 
340
+ /**
341
+ * Vendor-neutral hook for the full **medication cart** lifecycle: add a draft
342
+ * line (`createResource`), check out a set of drafts into the vendor's batch
343
+ * approval queue (`$checkout-medications`), and remove/clear cart lines
344
+ * (`$remove-cart-medication` / `$clear-cart`).
345
+ *
346
+ * Cart checkout / remove / clear hit project-scoped **FHIR custom operations**
347
+ * whose backing Bot is chosen at deploy time via an `OperationDefinition`
348
+ * carrying the `operationDefinition-implementation` extension — see
349
+ * [bot operations docs](https://www.medplum.com/docs/bots/custom-fhir-operations).
350
+ * The server's `tryCustomOperation` dispatch handles the OD → Bot lookup, so
351
+ * projects swap vendors by deploying a different bot under the same code.
352
+ *
353
+ * `addToCart` is plain FHIR `createResource` (no `$add-cart` operation): the
354
+ * Medplum-side cart is the set of draft `MedicationRequest`s. Vendor staging
355
+ * (e.g. ScriptSure MedCart) happens at checkout. Vendors without a batch
356
+ * approval queue (e.g. DoseSpot iframe-first) simply never call `checkout` /
357
+ * `removeFromCart` / `clearCart`.
358
+ *
359
+ * Requests for the custom operations are encoded as `Parameters` bodies and
360
+ * decoded by the matching `@medplum/core` helpers. Per-line outcomes arrive in
361
+ * `response.items`.
362
+ *
363
+ * @returns Cart add / checkout / remove / clear callbacks plus `adding` state.
364
+ */
365
+ export declare function useMedicationCart(): UseMedicationCartReturn;
366
+
367
+ export declare interface UseMedicationCartReturn {
368
+ /**
369
+ * Persist a draft `MedicationRequest` as a cart line via plain FHIR
370
+ * `createResource` (no custom operation). Vendor staging happens later at
371
+ * {@link UseMedicationCartReturn.checkout}.
372
+ */
373
+ addToCart: (medicationRequest: MedicationRequest) => Promise<MedicationRequest>;
374
+ /** True while one or more {@link UseMedicationCartReturn.addToCart} calls are in flight. */
375
+ adding: boolean;
376
+ /**
377
+ * Submit draft cart lines to the vendor's batch approval queue and return an
378
+ * embeddable approval-widget URL. Refuses while {@link UseMedicationCartReturn.adding} is true.
379
+ */
380
+ checkout: (input: MedicationCheckoutRequest) => Promise<MedicationCheckoutResponse>;
381
+ /** Remove a single draft `MedicationRequest` from the patient's vendor cart. */
382
+ removeFromCart: (input: MedicationCartRemoveRequest) => Promise<MedicationCartManageResponse>;
383
+ /** Remove every item from the patient's vendor cart. */
384
+ clearCart: (input: MedicationCartClearRequest) => Promise<MedicationCartManageResponse>;
385
+ }
386
+
299
387
  /**
300
388
  * Generic React hook that syncs a patient to a medication-order vendor and
301
389
  * returns the chart iframe URL.
@@ -379,6 +467,8 @@ export declare interface UseMedicationOrderSetOptions {
379
467
  /** Vendor-side order set id, when picked directly (escape hatch when no synced PD exists yet). */
380
468
  readonly vendorOrderSetId?: number | string;
381
469
  readonly appId?: string;
470
+ /** Selected practice location for multi-practice deployments. */
471
+ readonly organization?: Reference<Organization>;
382
472
  }
383
473
 
384
474
  export declare interface UseMedicationOrderSetReturn {
@@ -523,7 +613,6 @@ export declare interface UseResourceBoardProps<T extends Resource = Resource> {
523
613
  * without changing the search. Reloads in place — no skeleton — like `refresh()`.
524
614
  */
525
615
  readonly reloadKey?: unknown;
526
- readonly onSelectFirst?: (item: WithId<T>) => void;
527
616
  readonly onLoad?: (items: WithId<T>[], total: number | undefined) => void;
528
617
  readonly onError?: (error: unknown) => void;
529
618
  }
@@ -542,6 +631,30 @@ export declare interface UseResourceBoardResult<T extends Resource = Resource> {
542
631
  readonly refresh: () => Promise<void>;
543
632
  }
544
633
 
634
+ /**
635
+ * React hook for observing FHIR resource modifications made through the Medplum client.
636
+ *
637
+ * The callback is invoked whenever this client instance creates, updates, patches, or deletes
638
+ * a resource of one of the given types, including modifications announced with
639
+ * `MedplumClient.notifyResourceModified`. Use it to keep local component state in sync with
640
+ * mutations made elsewhere in the application. Subscribing to a single resource type narrows
641
+ * the event so `event.resource` is typed to that resource, no type guard required:
642
+ *
643
+ * ```tsx
644
+ * useResourceModified('Slot', (event) => {
645
+ * // event.resource is `WithId<Slot> | undefined`
646
+ * });
647
+ * useResourceModified(['Slot', 'Appointment'], () => refreshSchedule());
648
+ * ```
649
+ *
650
+ * Modifications made by other clients (or other users) are not observed;
651
+ * use `useSubscription` for server-side change notifications.
652
+ *
653
+ * @param resourceType - The resource type or types to observe.
654
+ * @param callback - Invoked with the event payload for each matching modification.
655
+ */
656
+ export declare function useResourceModified<K extends ResourceType>(resourceType: K | K[], callback: (event: ResourceModifiedEvent<ExtractResource<K>>) => void): void;
657
+
545
658
  /**
546
659
  * React hook for searching FHIR resources.
547
660
  *
@@ -615,13 +728,18 @@ export declare type UseSubscriptionOptions = {
615
728
  * to the configured e-prescribing vendor via the `$sync-orderset` custom FHIR operation
616
729
  * (`POST /fhir/R4/PlanDefinition/$sync-orderset`).
617
730
  *
618
- * Silently no-ops when the operation is not deployed (i.e. no e-prescribing vendor
619
- * is configured for the project), so callers do not need to guard against missing
620
- * integrations.
731
+ * Resolves with the decoded `OrderSetSyncResponse` so callers can surface
732
+ * per-action failures (`results[i].status === 'failed'` / `failedCount > 0`) —
733
+ * without this, an order set that only partially synced would silently apply
734
+ * with fewer meds than the PlanDefinition requested.
621
735
  *
622
- * @returns A stable `syncOrderSet(planDefinitionId)` callback.
736
+ * Resolves with `undefined` when the operation is not deployed (i.e. no
737
+ * e-prescribing vendor is configured for the project), so callers do not need to
738
+ * guard against missing integrations.
739
+ *
740
+ * @returns A stable `syncOrderSet(planDefinitionId, organization?)` callback.
623
741
  */
624
- export declare function useSyncOrderSet(): (planDefinitionId: string) => Promise<void>;
742
+ export declare function useSyncOrderSet(): (planDefinitionId: string, organization?: Reference<Organization>) => Promise<OrderSetSyncResponse | undefined>;
625
743
 
626
744
  export declare function useThreadInbox({ query, threadId }: UseThreadInboxOptions): UseThreadInboxReturn;
627
745
 
@@ -641,6 +759,30 @@ export declare interface UseThreadInboxReturn {
641
759
  refreshThreadMessages: () => Promise<void>;
642
760
  }
643
761
 
762
+ /**
763
+ * Probes a set of ValueSet URLs for availability, each with a filter-free, count-limited expansion.
764
+ *
765
+ * A filter-free probe means a 400/404 unambiguously describes the value set itself (unlike a
766
+ * user-typed search, whose 400 can be filter-specific), so the verdict is safe to act on. Repeated
767
+ * probes of the same URL are deduplicated by the `MedplumClient` request cache, which caches
768
+ * rejections too, so many fields bound to the same missing value set cost one request. Recovery
769
+ * after a value set is imported happens on the next mount (i.e. a page refresh) — there is no live
770
+ * subscription. Transient failures (429/5xx/network) resolve as available so a blip never disables
771
+ * a field; only a permanent 400/404 marks a URL unavailable.
772
+ * @param urls - The ValueSet URLs to probe. Falsy entries are ignored, and duplicates collapse to a
773
+ * single probe.
774
+ * @returns The availability verdict, with `loading` true until every requested URL has settled.
775
+ */
776
+ export declare function useValueSetAvailabilities(urls: readonly (string | undefined)[]): ValueSetAvailability;
777
+
778
+ /**
779
+ * Probes a single ValueSet's availability once on mount. A thin wrapper around
780
+ * {@link useValueSetAvailabilities} for the common single-value-set case.
781
+ * @param url - The ValueSet URL, or undefined for unbound inputs (always available).
782
+ * @returns undefined while the probe is in flight, true if available, false if unavailable.
783
+ */
784
+ export declare function useValueSetAvailability(url: string | undefined): boolean | undefined;
785
+
644
786
  export declare function useWhisper({ language, model, onTranscript, idleTimeoutMs, }: UseWhisperOptions): UseWhisperResult;
645
787
 
646
788
  export declare type UseWhisperOptions = {
@@ -666,6 +808,18 @@ export declare type UseWhisperResult = {
666
808
  setMuted: (value: boolean) => void;
667
809
  };
668
810
 
811
+ /**
812
+ * The result of probing one or more ValueSet URLs for availability.
813
+ */
814
+ export declare interface ValueSetAvailability {
815
+ /** True while at least one requested URL is still being probed. */
816
+ readonly loading: boolean;
817
+ /** The subset of requested URLs known to be available. */
818
+ readonly available: string[];
819
+ /** The subset of requested URLs known to be unavailable (a permanent 400/404). */
820
+ readonly unavailable: string[];
821
+ }
822
+
669
823
  export declare type WhisperStatus = 'idle' | 'requesting_microphone' | 'connecting' | 'connected' | 'listening' | 'speech_started' | 'speech_stopped' | 'disconnected' | 'error';
670
824
 
671
825
  export { }
@@ -8,11 +8,18 @@ import type { ExtractResource } from '@medplum/fhirtypes';
8
8
  import type { Identifier } from '@medplum/fhirtypes';
9
9
  import type { JSX } from 'react';
10
10
  import type { Medication } from '@medplum/fhirtypes';
11
+ import type { MedicationCartClearRequest } from '@medplum/core';
12
+ import type { MedicationCartManageResponse } from '@medplum/core';
13
+ import type { MedicationCartRemoveRequest } from '@medplum/core';
14
+ import type { MedicationCheckoutRequest } from '@medplum/core';
15
+ import type { MedicationCheckoutResponse } from '@medplum/core';
11
16
  import type { MedicationOrderRequest } from '@medplum/core';
12
17
  import type { MedicationOrderResponse } from '@medplum/core';
18
+ import type { MedicationRequest } from '@medplum/fhirtypes';
13
19
  import type { MedicationSearchParams } from '@medplum/core';
14
20
  import type { MedplumClient } from '@medplum/core';
15
21
  import type { OperationOutcome } from '@medplum/fhirtypes';
22
+ import type { OrderSetSyncResponse } from '@medplum/core';
16
23
  import type { Organization } from '@medplum/fhirtypes';
17
24
  import type { Patient } from '@medplum/fhirtypes';
18
25
  import type { PharmacySearchParams } from '@medplum/core';
@@ -30,6 +37,7 @@ import type { ReactNode } from 'react';
30
37
  import type { Reference } from '@medplum/fhirtypes';
31
38
  import type { Resource } from '@medplum/fhirtypes';
32
39
  import type { ResourceArray } from '@medplum/core';
40
+ import type { ResourceModifiedEvent } from '@medplum/core';
33
41
  import type { ResourceType } from '@medplum/fhirtypes';
34
42
  import type { SearchRequest } from '@medplum/core';
35
43
  import type { Signature } from '@medplum/fhirtypes';
@@ -37,6 +45,23 @@ import type { Subscription } from '@medplum/fhirtypes';
37
45
  import type { TypedValue } from '@medplum/core';
38
46
  import type { WithId } from '@medplum/core';
39
47
 
48
+ /**
49
+ * Applies the `questionnaire-optionExclusive` rule to an answer change.
50
+ *
51
+ * Given the previous and newly requested answers for an item, enforces that selecting an answer
52
+ * option marked exclusive clears every other answer, and selecting any other option clears a
53
+ * previously selected exclusive answer. Returns the new answers unchanged if the item has no
54
+ * exclusive options or the change only removed answers.
55
+ *
56
+ * See: https://hl7.org/fhir/extensions/StructureDefinition-questionnaire-optionExclusive.html
57
+ *
58
+ * @param item - The questionnaire item being answered.
59
+ * @param previousAnswers - The item's answers before the change.
60
+ * @param newAnswers - The answers requested by the change.
61
+ * @returns The reconciled answers.
62
+ */
63
+ export declare function applyOptionExclusive(item: QuestionnaireItem, previousAnswers: QuestionnaireResponseItemAnswer[] | undefined, newAnswers: QuestionnaireResponseItemAnswer[]): QuestionnaireResponseItemAnswer[];
64
+
40
65
  export declare function buildInitialResponse(questionnaire: Questionnaire, questionnaireResponse?: QuestionnaireResponse): QuestionnaireResponse;
41
66
 
42
67
  export declare function buildInitialResponseItem(item: QuestionnaireItem): QuestionnaireResponseItem;
@@ -106,8 +131,22 @@ export declare function isChoiceQuestion(item: QuestionnaireItem): boolean;
106
131
  */
107
132
  export declare function isQuestionEnabled(item: QuestionnaireItem, questionnaireResponse: QuestionnaireResponse | undefined): boolean;
108
133
 
134
+ /**
135
+ * Returns true if an error thrown while expanding a ValueSet means the value set itself is
136
+ * unavailable — a permanent 400/404 (e.g. "ValueSet not found"). Transient failures (429 rate
137
+ * limit, 401, 5xx, network) return false so a blip never disables a field.
138
+ * @param err - The error thrown by `valueSetExpand`.
139
+ * @returns True for a permanent 400/404, false for a transient failure.
140
+ */
141
+ export declare function isValueSetUnavailableError(err: unknown): boolean;
142
+
143
+ /** Thrown by {@link UseMedicationCartReturn.checkout} when an {@link UseMedicationCartReturn.addToCart} call is still in flight. */
144
+ export declare const MEDICATION_CART_ADD_IN_PROGRESS = "Cannot checkout while a medication is still being added to the cart";
145
+
109
146
  export declare interface MedicationIFrameOptions {
110
147
  readonly patientId?: string;
148
+ /** Selected practice location for multi-practice deployments. */
149
+ readonly organization?: Reference<Organization>;
111
150
  readonly onPatientSyncSuccess?: () => void;
112
151
  readonly onIframeSuccess?: (url: string) => void;
113
152
  readonly onError?: (err: unknown) => void;
@@ -154,6 +193,8 @@ export declare const QUESTIONNAIRE_HIDDEN_URL = "http://hl7.org/fhir/StructureDe
154
193
 
155
194
  export declare const QUESTIONNAIRE_ITEM_CONTROL_URL = "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl";
156
195
 
196
+ export declare const QUESTIONNAIRE_OPTION_EXCLUSIVE_URL = "http://hl7.org/fhir/StructureDefinition/questionnaire-optionExclusive";
197
+
157
198
  export declare const QUESTIONNAIRE_REFERENCE_FILTER_URL = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceFilter";
158
199
 
159
200
  export declare const QUESTIONNAIRE_REFERENCE_RESOURCE_URL = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource";
@@ -296,6 +337,53 @@ export declare function typedValueToResponseItem(item: QuestionnaireItem, value:
296
337
 
297
338
  export declare const useCachedBinaryUrl: (binaryUrl: string | undefined) => string | undefined;
298
339
 
340
+ /**
341
+ * Vendor-neutral hook for the full **medication cart** lifecycle: add a draft
342
+ * line (`createResource`), check out a set of drafts into the vendor's batch
343
+ * approval queue (`$checkout-medications`), and remove/clear cart lines
344
+ * (`$remove-cart-medication` / `$clear-cart`).
345
+ *
346
+ * Cart checkout / remove / clear hit project-scoped **FHIR custom operations**
347
+ * whose backing Bot is chosen at deploy time via an `OperationDefinition`
348
+ * carrying the `operationDefinition-implementation` extension — see
349
+ * [bot operations docs](https://www.medplum.com/docs/bots/custom-fhir-operations).
350
+ * The server's `tryCustomOperation` dispatch handles the OD → Bot lookup, so
351
+ * projects swap vendors by deploying a different bot under the same code.
352
+ *
353
+ * `addToCart` is plain FHIR `createResource` (no `$add-cart` operation): the
354
+ * Medplum-side cart is the set of draft `MedicationRequest`s. Vendor staging
355
+ * (e.g. ScriptSure MedCart) happens at checkout. Vendors without a batch
356
+ * approval queue (e.g. DoseSpot iframe-first) simply never call `checkout` /
357
+ * `removeFromCart` / `clearCart`.
358
+ *
359
+ * Requests for the custom operations are encoded as `Parameters` bodies and
360
+ * decoded by the matching `@medplum/core` helpers. Per-line outcomes arrive in
361
+ * `response.items`.
362
+ *
363
+ * @returns Cart add / checkout / remove / clear callbacks plus `adding` state.
364
+ */
365
+ export declare function useMedicationCart(): UseMedicationCartReturn;
366
+
367
+ export declare interface UseMedicationCartReturn {
368
+ /**
369
+ * Persist a draft `MedicationRequest` as a cart line via plain FHIR
370
+ * `createResource` (no custom operation). Vendor staging happens later at
371
+ * {@link UseMedicationCartReturn.checkout}.
372
+ */
373
+ addToCart: (medicationRequest: MedicationRequest) => Promise<MedicationRequest>;
374
+ /** True while one or more {@link UseMedicationCartReturn.addToCart} calls are in flight. */
375
+ adding: boolean;
376
+ /**
377
+ * Submit draft cart lines to the vendor's batch approval queue and return an
378
+ * embeddable approval-widget URL. Refuses while {@link UseMedicationCartReturn.adding} is true.
379
+ */
380
+ checkout: (input: MedicationCheckoutRequest) => Promise<MedicationCheckoutResponse>;
381
+ /** Remove a single draft `MedicationRequest` from the patient's vendor cart. */
382
+ removeFromCart: (input: MedicationCartRemoveRequest) => Promise<MedicationCartManageResponse>;
383
+ /** Remove every item from the patient's vendor cart. */
384
+ clearCart: (input: MedicationCartClearRequest) => Promise<MedicationCartManageResponse>;
385
+ }
386
+
299
387
  /**
300
388
  * Generic React hook that syncs a patient to a medication-order vendor and
301
389
  * returns the chart iframe URL.
@@ -379,6 +467,8 @@ export declare interface UseMedicationOrderSetOptions {
379
467
  /** Vendor-side order set id, when picked directly (escape hatch when no synced PD exists yet). */
380
468
  readonly vendorOrderSetId?: number | string;
381
469
  readonly appId?: string;
470
+ /** Selected practice location for multi-practice deployments. */
471
+ readonly organization?: Reference<Organization>;
382
472
  }
383
473
 
384
474
  export declare interface UseMedicationOrderSetReturn {
@@ -523,7 +613,6 @@ export declare interface UseResourceBoardProps<T extends Resource = Resource> {
523
613
  * without changing the search. Reloads in place — no skeleton — like `refresh()`.
524
614
  */
525
615
  readonly reloadKey?: unknown;
526
- readonly onSelectFirst?: (item: WithId<T>) => void;
527
616
  readonly onLoad?: (items: WithId<T>[], total: number | undefined) => void;
528
617
  readonly onError?: (error: unknown) => void;
529
618
  }
@@ -542,6 +631,30 @@ export declare interface UseResourceBoardResult<T extends Resource = Resource> {
542
631
  readonly refresh: () => Promise<void>;
543
632
  }
544
633
 
634
+ /**
635
+ * React hook for observing FHIR resource modifications made through the Medplum client.
636
+ *
637
+ * The callback is invoked whenever this client instance creates, updates, patches, or deletes
638
+ * a resource of one of the given types, including modifications announced with
639
+ * `MedplumClient.notifyResourceModified`. Use it to keep local component state in sync with
640
+ * mutations made elsewhere in the application. Subscribing to a single resource type narrows
641
+ * the event so `event.resource` is typed to that resource, no type guard required:
642
+ *
643
+ * ```tsx
644
+ * useResourceModified('Slot', (event) => {
645
+ * // event.resource is `WithId<Slot> | undefined`
646
+ * });
647
+ * useResourceModified(['Slot', 'Appointment'], () => refreshSchedule());
648
+ * ```
649
+ *
650
+ * Modifications made by other clients (or other users) are not observed;
651
+ * use `useSubscription` for server-side change notifications.
652
+ *
653
+ * @param resourceType - The resource type or types to observe.
654
+ * @param callback - Invoked with the event payload for each matching modification.
655
+ */
656
+ export declare function useResourceModified<K extends ResourceType>(resourceType: K | K[], callback: (event: ResourceModifiedEvent<ExtractResource<K>>) => void): void;
657
+
545
658
  /**
546
659
  * React hook for searching FHIR resources.
547
660
  *
@@ -615,13 +728,18 @@ export declare type UseSubscriptionOptions = {
615
728
  * to the configured e-prescribing vendor via the `$sync-orderset` custom FHIR operation
616
729
  * (`POST /fhir/R4/PlanDefinition/$sync-orderset`).
617
730
  *
618
- * Silently no-ops when the operation is not deployed (i.e. no e-prescribing vendor
619
- * is configured for the project), so callers do not need to guard against missing
620
- * integrations.
731
+ * Resolves with the decoded `OrderSetSyncResponse` so callers can surface
732
+ * per-action failures (`results[i].status === 'failed'` / `failedCount > 0`) —
733
+ * without this, an order set that only partially synced would silently apply
734
+ * with fewer meds than the PlanDefinition requested.
621
735
  *
622
- * @returns A stable `syncOrderSet(planDefinitionId)` callback.
736
+ * Resolves with `undefined` when the operation is not deployed (i.e. no
737
+ * e-prescribing vendor is configured for the project), so callers do not need to
738
+ * guard against missing integrations.
739
+ *
740
+ * @returns A stable `syncOrderSet(planDefinitionId, organization?)` callback.
623
741
  */
624
- export declare function useSyncOrderSet(): (planDefinitionId: string) => Promise<void>;
742
+ export declare function useSyncOrderSet(): (planDefinitionId: string, organization?: Reference<Organization>) => Promise<OrderSetSyncResponse | undefined>;
625
743
 
626
744
  export declare function useThreadInbox({ query, threadId }: UseThreadInboxOptions): UseThreadInboxReturn;
627
745
 
@@ -641,6 +759,30 @@ export declare interface UseThreadInboxReturn {
641
759
  refreshThreadMessages: () => Promise<void>;
642
760
  }
643
761
 
762
+ /**
763
+ * Probes a set of ValueSet URLs for availability, each with a filter-free, count-limited expansion.
764
+ *
765
+ * A filter-free probe means a 400/404 unambiguously describes the value set itself (unlike a
766
+ * user-typed search, whose 400 can be filter-specific), so the verdict is safe to act on. Repeated
767
+ * probes of the same URL are deduplicated by the `MedplumClient` request cache, which caches
768
+ * rejections too, so many fields bound to the same missing value set cost one request. Recovery
769
+ * after a value set is imported happens on the next mount (i.e. a page refresh) — there is no live
770
+ * subscription. Transient failures (429/5xx/network) resolve as available so a blip never disables
771
+ * a field; only a permanent 400/404 marks a URL unavailable.
772
+ * @param urls - The ValueSet URLs to probe. Falsy entries are ignored, and duplicates collapse to a
773
+ * single probe.
774
+ * @returns The availability verdict, with `loading` true until every requested URL has settled.
775
+ */
776
+ export declare function useValueSetAvailabilities(urls: readonly (string | undefined)[]): ValueSetAvailability;
777
+
778
+ /**
779
+ * Probes a single ValueSet's availability once on mount. A thin wrapper around
780
+ * {@link useValueSetAvailabilities} for the common single-value-set case.
781
+ * @param url - The ValueSet URL, or undefined for unbound inputs (always available).
782
+ * @returns undefined while the probe is in flight, true if available, false if unavailable.
783
+ */
784
+ export declare function useValueSetAvailability(url: string | undefined): boolean | undefined;
785
+
644
786
  export declare function useWhisper({ language, model, onTranscript, idleTimeoutMs, }: UseWhisperOptions): UseWhisperResult;
645
787
 
646
788
  export declare type UseWhisperOptions = {
@@ -666,6 +808,18 @@ export declare type UseWhisperResult = {
666
808
  setMuted: (value: boolean) => void;
667
809
  };
668
810
 
811
+ /**
812
+ * The result of probing one or more ValueSet URLs for availability.
813
+ */
814
+ export declare interface ValueSetAvailability {
815
+ /** True while at least one requested URL is still being probed. */
816
+ readonly loading: boolean;
817
+ /** The subset of requested URLs known to be available. */
818
+ readonly available: string[];
819
+ /** The subset of requested URLs known to be unavailable (a permanent 400/404). */
820
+ readonly unavailable: string[];
821
+ }
822
+
669
823
  export declare type WhisperStatus = 'idle' | 'requesting_microphone' | 'connecting' | 'connected' | 'listening' | 'speech_started' | 'speech_stopped' | 'disconnected' | 'error';
670
824
 
671
825
  export { }