@mindbill/react 0.77.49 → 0.77.51

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.
package/dist/index.d.ts CHANGED
@@ -1028,6 +1028,8 @@ type RfaDraftFormProps = TreatmentDraftAppearance & RfaContactDirectoryProps & {
1028
1028
  onReview?: (draft: RfaDraftInput) => Promise<void>;
1029
1029
  /** Save unsigned content before opening the host's actual PDF packet preview. */
1030
1030
  onPreview?: (draft: RfaDraftInput) => Promise<void>;
1031
+ /** Shows the form as filled in so far, without saving it or requiring any field. Replaces `onPreview`. */
1032
+ onPreviewDraft?: (draft: RfaDraftInput) => Promise<void>;
1031
1033
  /** Suppress the repeated title when composing a single creation page. */
1032
1034
  embedded?: boolean;
1033
1035
  /** Live identity selection on the same creation page; clinical fields remain local. */
@@ -1059,7 +1061,7 @@ type RfaDraftFormProps = TreatmentDraftAppearance & RfaContactDirectoryProps & {
1059
1061
  /** Remove blank optional item fields, retaining an explicitly cleared return fax. */
1060
1062
  declare function normalizeRfaDraft(draft: RfaDraftInput): RfaDraftInput;
1061
1063
  declare function validateRfaDraft(draft: RfaDraftInput): string | null;
1062
- declare function RfaDraftForm({ initialDraft, identity, officialForm, formDetails, selectors, onEditPractice, onAddPractice, onEditLocation, treatmentTemplates, onSaveTreatmentTemplate, onManageTreatmentTemplates, managePracticeHref, manageLocationsHref, onRefreshProfile, profilePending, onReview, onPreview, searchClaimsAdministrators, getClaimsAdministratorDirectory, embedded, onSave, onBack, mode, searchDiagnosisCodes, organizationProfile, savedDiagnosisCodes, supportingDocuments, disabled, ...appearance }: RfaDraftFormProps): ReactElement;
1064
+ declare function RfaDraftForm({ initialDraft, identity, officialForm, formDetails, selectors, onEditPractice, onAddPractice, onEditLocation, treatmentTemplates, onSaveTreatmentTemplate, onManageTreatmentTemplates, managePracticeHref, manageLocationsHref, onRefreshProfile, profilePending, onReview, onPreview, onPreviewDraft, searchClaimsAdministrators, getClaimsAdministratorDirectory, embedded, onSave, onBack, mode, searchDiagnosisCodes, organizationProfile, savedDiagnosisCodes, supportingDocuments, disabled, ...appearance }: RfaDraftFormProps): ReactElement;
1063
1065
 
1064
1066
  /** A saved set of requested treatments. Diagnoses stay with the claim, so templates do not carry them. */
1065
1067
  type RfaTreatmentTemplate = {
@@ -1152,6 +1154,8 @@ type RfaDashboardProps = OrganizationClientOptions & TreatmentDraftAppearance &
1152
1154
  manageLocationsHref?: string;
1153
1155
  /** Opens the actual saved packet. Creation first saves and attaches files, then selects its detail view. */
1154
1156
  onPreviewRequest?: (id: string) => Promise<void>;
1157
+ /** Shows an unsaved request form as filled in so far; the Preview button then needs no saved draft. */
1158
+ onPreviewDraft?: (draft: RfaDraftInput) => Promise<void>;
1155
1159
  hideBackButton?: boolean;
1156
1160
  hideHeading?: boolean;
1157
1161
  /** Opt in to a list-first workspace with focused Request, Responses, Documents and History tabs. */
package/dist/index.js CHANGED
@@ -12783,15 +12783,21 @@ function RfaPracticePicker({ profile, value, onChange, managePracticeHref, manag
12783
12783
  const practices = profile?.billingProviders ?? [];
12784
12784
  const [practice, setPractice] = useState23(() => practices.find((item) => item.name === value?.name)?.id ?? "");
12785
12785
  const [location, setLocation] = useState23(() => practice ? (profile?.locations ?? []).find((item) => item.active !== false && item.street === value?.address && (!item.billingProviderId || item.billingProviderId === practice))?.id ?? "" : "");
12786
- const located = (chosen, phone) => ({ address: chosen.street, city: chosen.city, state: chosen.state, zip: chosen.zip, ...chosen.contact?.name ? { contactName: chosen.contact.name } : {}, ...chosen.contact?.phone || phone ? { phone: chosen.contact?.phone || phone } : {}, ...chosen.contact?.fax ? { fax: chosen.contact.fax } : {}, ...chosen.contact?.email ? { email: chosen.contact.email } : {} });
12786
+ const contactOf = (saved) => saved?.contact ?? {};
12787
+ const contactFields = (provider, chosen) => {
12788
+ const own = chosen?.contact ?? {}, shared = contactOf(provider);
12789
+ const name = own.name || shared.name, fax = own.fax || shared.fax, email = own.email || shared.email;
12790
+ return { phone: own.phone || shared.phone || provider?.phone || "", ...name ? { contactName: name } : {}, ...fax ? { fax } : {}, ...email ? { email } : {} };
12791
+ };
12792
+ const located = (chosen, provider) => ({ address: chosen.street, city: chosen.city, state: chosen.state, zip: chosen.zip, ...contactFields(provider, chosen) });
12787
12793
  const savedPractice = practices.find((item) => item.id === practice), savedLocation = (profile?.locations ?? []).find((item) => item.id === location);
12788
- const savedKey = JSON.stringify([savedPractice?.name, savedPractice?.phone, savedPractice?.billingStreet, savedPractice?.billingCity, savedPractice?.billingState, savedPractice?.billingZip, savedLocation?.street, savedLocation?.city, savedLocation?.state, savedLocation?.zip, savedLocation?.contact]);
12794
+ const savedKey = JSON.stringify([savedPractice?.name, savedPractice?.phone, savedPractice?.billingStreet, savedPractice?.billingCity, savedPractice?.billingState, savedPractice?.billingZip, contactOf(savedPractice), savedLocation?.street, savedLocation?.city, savedLocation?.state, savedLocation?.zip, savedLocation?.contact]);
12789
12795
  const appliedKey = useRef18(savedKey);
12790
12796
  useEffect20(() => {
12791
12797
  if (appliedKey.current === savedKey) return;
12792
12798
  appliedKey.current = savedKey;
12793
12799
  if (!savedPractice) return;
12794
- onChange({ ...value, name: savedPractice.name, phone: savedPractice.phone ?? "", address: savedPractice.billingStreet ?? "", city: savedPractice.billingCity ?? "", state: savedPractice.billingState ?? "", zip: savedPractice.billingZip ?? "", ...savedLocation ? located(savedLocation, savedPractice.phone) : {} });
12800
+ onChange({ ...value, name: savedPractice.name, address: savedPractice.billingStreet ?? "", city: savedPractice.billingCity ?? "", state: savedPractice.billingState ?? "", zip: savedPractice.billingZip ?? "", ...contactFields(savedPractice), ...savedLocation ? located(savedLocation, savedPractice) : {} });
12795
12801
  }, [savedKey]);
12796
12802
  const [practiceQuery, setPracticeQuery] = useState23("");
12797
12803
  const [locationQuery, setLocationQuery] = useState23("");
@@ -12805,7 +12811,7 @@ function RfaPracticePicker({ profile, value, onChange, managePracticeHref, manag
12805
12811
  const primary = matching.filter((item) => item.isPrimary);
12806
12812
  const chosen = matching.length === 1 ? matching[0] : primary.length === 1 ? primary[0] : void 0;
12807
12813
  setLocation(chosen?.id ?? "");
12808
- onChange({ ...value, name: provider.name, phone: provider.phone ?? "", address: provider.billingStreet ?? "", city: provider.billingCity ?? "", state: provider.billingState ?? "", zip: provider.billingZip ?? "", ...chosen ? located(chosen, provider.phone) : {} });
12814
+ onChange({ ...value, name: provider.name, address: provider.billingStreet ?? "", city: provider.billingCity ?? "", state: provider.billingState ?? "", zip: provider.billingZip ?? "", ...contactFields(provider), ...chosen ? located(chosen, provider) : {} });
12809
12815
  };
12810
12816
  const onlyPractice = practices.length === 1 && !practice && !value?.name?.trim() && !value?.address?.trim() ? practices[0].id : "";
12811
12817
  useEffect20(() => {
@@ -12829,7 +12835,7 @@ function RfaPracticePicker({ profile, value, onChange, managePracticeHref, manag
12829
12835
  setLocation(id);
12830
12836
  setLocationQuery("");
12831
12837
  onChosen?.();
12832
- onChange({ ...value, ...located(chosen, practices.find((item) => item.id === practice)?.phone) });
12838
+ onChange({ ...value, ...located(chosen, practices.find((item) => item.id === practice)) });
12833
12839
  };
12834
12840
  const ADD = "__add__";
12835
12841
  return /* @__PURE__ */ jsxs36(Fragment21, { children: [
@@ -12935,29 +12941,42 @@ function RfaDiagnosisFields({ code, description, onChange, search, officialForm
12935
12941
  diagnosisDescription: nextDescriptions.some(Boolean) ? nextDescriptions.map((text3) => text3.replace(/;/g, ",").trim()).join("; ") : ""
12936
12942
  });
12937
12943
  const resolved = useRef19(/* @__PURE__ */ new Set());
12938
- const [resolving, setResolving] = useState24("");
12939
- const pending = officialForm && search ? codes2.find((item, index) => !descriptions2[index] && !resolved.current.has(item)) ?? "" : "";
12944
+ const started = useRef19(/* @__PURE__ */ new Set());
12945
+ const [, lookedUp] = useState24(0);
12946
+ for (const known of [...started.current]) if (!codes2.includes(known)) {
12947
+ started.current.delete(known);
12948
+ resolved.current.delete(known);
12949
+ }
12950
+ const missing = officialForm && search ? codes2.filter((item, index) => !descriptions2[index] && !started.current.has(item)) : [];
12940
12951
  const latest = useRef19({ codes: codes2, descriptions: descriptions2, emit });
12941
12952
  latest.current = { codes: codes2, descriptions: descriptions2, emit };
12953
+ const mounted = useRef19(true);
12942
12954
  useEffect21(() => {
12943
- if (!pending || !search) return;
12944
- resolved.current.add(pending);
12945
- let active = true;
12946
- setResolving(pending);
12947
- const same = (left, right) => left.replace(".", "").toUpperCase() === right.replace(".", "").toUpperCase();
12948
- void search(pending).then((items) => {
12949
- const match = items.find((item) => same(item.code, pending));
12950
- if (!active || !match) return;
12951
- const now = latest.current, at = now.codes.indexOf(pending);
12952
- if (at < 0) return;
12953
- now.emit(now.codes.map((item, index) => index === at ? match.code : item), now.descriptions.map((text3, index) => index === at ? match.description : text3));
12954
- }).catch(() => void 0).finally(() => {
12955
- if (active) setResolving("");
12956
- });
12955
+ mounted.current = true;
12957
12956
  return () => {
12958
- active = false;
12957
+ mounted.current = false;
12959
12958
  };
12960
- }, [pending, search]);
12959
+ }, []);
12960
+ const missingKey = missing.join("|");
12961
+ useEffect21(() => {
12962
+ if (!missing.length || !search) return;
12963
+ const same = (left, right) => left.replace(".", "").toUpperCase() === right.replace(".", "").toUpperCase();
12964
+ for (const wanted of missing) {
12965
+ started.current.add(wanted);
12966
+ void search(wanted).then((items) => {
12967
+ const match = items.find((item) => same(item.code, wanted));
12968
+ if (!mounted.current || !match) return;
12969
+ const now = latest.current, at = now.codes.indexOf(wanted);
12970
+ if (at < 0 || now.descriptions[at]) return;
12971
+ const descriptions3 = now.descriptions.map((text3, index) => index === at ? match.description : text3);
12972
+ latest.current = { ...now, descriptions: descriptions3 };
12973
+ now.emit(now.codes, descriptions3);
12974
+ }).catch(() => void 0).finally(() => {
12975
+ resolved.current.add(wanted);
12976
+ if (mounted.current) lookedUp((count) => count + 1);
12977
+ });
12978
+ }
12979
+ }, [missingKey, search]);
12961
12980
  if (officialForm && search) {
12962
12981
  const typed = query.trim().toUpperCase(), known = results.some((item) => item.code.toUpperCase() === typed);
12963
12982
  const chosen = (value) => codes2.includes(value);
@@ -12970,6 +12989,7 @@ function RfaDiagnosisFields({ code, description, onChange, search, officialForm
12970
12989
  const item = results.find((item2) => item2.code === value);
12971
12990
  if (item) emit([...codes2, item.code], [...descriptions2, item.description]);
12972
12991
  else if (value.startsWith("entered:")) {
12992
+ started.current.add(value.slice(8));
12973
12993
  resolved.current.add(value.slice(8));
12974
12994
  emit([...codes2, value.slice(8)], [...descriptions2, ""]);
12975
12995
  } else if (value.startsWith("saved:")) emit([...codes2, value.slice(6)], [...descriptions2, ""]);
@@ -12978,7 +12998,7 @@ function RfaDiagnosisFields({ code, description, onChange, search, officialForm
12978
12998
  return /* @__PURE__ */ jsx39("div", { className: "mbrfa-s6", children: /* @__PURE__ */ jsxs37(RfaPicker, { required: true, label: "ICD-10 Code", children: [
12979
12999
  codes2.length ? /* @__PURE__ */ jsx39("ul", { className: "mbrfa-dx-list", "aria-label": "Selected ICD-10 codes", children: codes2.map((item, index) => /* @__PURE__ */ jsxs37("li", { children: [
12980
13000
  /* @__PURE__ */ jsx39("strong", { children: item }),
12981
- descriptions2[index] || resolving === item || !resolved.current.has(item) ? /* @__PURE__ */ jsx39("span", { children: descriptions2[index] || "Looking up\u2026" }) : /* @__PURE__ */ jsx39("input", { required: true, "aria-label": `Diagnosis for ${item}`, maxLength: 400, placeholder: "Type the diagnosis for this code", defaultValue: "", onBlur: (event) => {
13001
+ descriptions2[index] || !resolved.current.has(item) ? /* @__PURE__ */ jsx39("span", { children: descriptions2[index] || "Looking up\u2026" }) : /* @__PURE__ */ jsx39("input", { required: true, "aria-label": `Diagnosis for ${item}`, maxLength: 400, placeholder: "Type the diagnosis for this code", defaultValue: "", onBlur: (event) => {
12982
13002
  if (event.target.value.trim()) emit(codes2, descriptions2.map((text3, position) => position === index ? event.target.value : text3));
12983
13003
  } }),
12984
13004
  /* @__PURE__ */ jsx39("button", { type: "button", "aria-label": `Remove ${item}`, onClick: () => emit(codes2.filter((_, position) => position !== index), descriptions2.filter((_, position) => position !== index)), children: "\xD7" })
@@ -13378,7 +13398,7 @@ function validateRfaDraft(draft2) {
13378
13398
  }
13379
13399
  return null;
13380
13400
  }
13381
- function RfaDraftForm({ initialDraft, identity, officialForm = false, formDetails, selectors, onEditPractice, onAddPractice, onEditLocation, treatmentTemplates, onSaveTreatmentTemplate, onManageTreatmentTemplates, managePracticeHref, manageLocationsHref, onRefreshProfile, profilePending = false, onReview, onPreview, searchClaimsAdministrators, getClaimsAdministratorDirectory, embedded = false, onSave, onBack, mode = "create", searchDiagnosisCodes, organizationProfile, savedDiagnosisCodes = [], supportingDocuments, disabled = false, ...appearance }) {
13401
+ function RfaDraftForm({ initialDraft, identity, officialForm = false, formDetails, selectors, onEditPractice, onAddPractice, onEditLocation, treatmentTemplates, onSaveTreatmentTemplate, onManageTreatmentTemplates, managePracticeHref, manageLocationsHref, onRefreshProfile, profilePending = false, onReview, onPreview, onPreviewDraft, searchClaimsAdministrators, getClaimsAdministratorDirectory, embedded = false, onSave, onBack, mode = "create", searchDiagnosisCodes, organizationProfile, savedDiagnosisCodes = [], supportingDocuments, disabled = false, ...appearance }) {
13382
13402
  const [savedDraft, setDraft] = useState28(() => normalizeRfaDraft(initialDraft));
13383
13403
  useEffect23(() => {
13384
13404
  if (identity) setDraft((current) => {
@@ -13455,6 +13475,20 @@ function RfaDraftForm({ initialDraft, identity, officialForm = false, formDetail
13455
13475
  const action = useDraftSave(async (value) => {
13456
13476
  await (intentRef.current === "preview" && onPreview ? onPreview : intentRef.current === "review" && onReview ? onReview : onSave)(value);
13457
13477
  }), locked = disabled || action.busy;
13478
+ const [previewing, setPreviewing] = useState28(false);
13479
+ const [previewError, setPreviewError] = useState28("");
13480
+ const previewDraft = async () => {
13481
+ if (!onPreviewDraft || previewing) return;
13482
+ setPreviewing(true);
13483
+ setPreviewError("");
13484
+ try {
13485
+ await onPreviewDraft(normalizeRfaDraft(draft2));
13486
+ } catch {
13487
+ setPreviewError("The preview could not be opened. Try again.");
13488
+ } finally {
13489
+ setPreviewing(false);
13490
+ }
13491
+ };
13458
13492
  const billingProviders = Array.isArray(organizationProfile?.billingProviders) ? organizationProfile.billingProviders : [];
13459
13493
  const locations = Array.isArray(organizationProfile?.locations) ? organizationProfile.locations : [];
13460
13494
  const update = (patch) => {
@@ -13634,9 +13668,10 @@ function RfaDraftForm({ initialDraft, identity, officialForm = false, formDetail
13634
13668
  saveError,
13635
13669
  /* @__PURE__ */ jsxs41("div", { className: "mbtd-actions", children: [
13636
13670
  onReview ? /* @__PURE__ */ jsx43("button", { type: "submit", className: "mbtd-primary", disabled: locked, onClick: () => chooseIntent("review"), children: action.busy && intent === "review" ? "Saving\u2026" : officialForm ? "Send" : "Review & submit" }) : null,
13637
- onPreview ? /* @__PURE__ */ jsx43("button", { type: "submit", disabled: locked, onClick: () => chooseIntent("preview"), children: action.busy && intent === "preview" ? "Preparing preview\u2026" : "Preview" }) : null,
13671
+ onPreviewDraft ? /* @__PURE__ */ jsx43("button", { type: "button", disabled: locked || previewing, onClick: () => void previewDraft(), children: previewing ? "Preparing preview\u2026" : "Preview" }) : onPreview ? /* @__PURE__ */ jsx43("button", { type: "submit", disabled: locked, onClick: () => chooseIntent("preview"), children: action.busy && intent === "preview" ? "Preparing preview\u2026" : "Preview" }) : null,
13638
13672
  /* @__PURE__ */ jsx43("button", { type: "submit", className: onReview ? void 0 : "mbtd-primary", disabled: locked, onClick: () => chooseIntent("save"), children: action.busy && intent === "save" ? "Saving\u2026" : mode === "edit" ? "Save draft changes" : "Save draft" }),
13639
- /* @__PURE__ */ jsx43("p", { role: "status", children: action.message })
13673
+ /* @__PURE__ */ jsx43("p", { role: "status", children: action.message }),
13674
+ previewError ? /* @__PURE__ */ jsx43("p", { role: "alert", children: previewError }) : null
13640
13675
  ] })
13641
13676
  ] })
13642
13677
  ] });
@@ -14883,7 +14918,7 @@ function RfaDashboard({ sessionEndpoint, getSession, apiBaseUrl, fetch: fetchOve
14883
14918
  const identity = useMemo12(() => ({ client, signatureClient, key: key() }), [client, signatureClient]);
14884
14919
  return /* @__PURE__ */ jsx48(RfaDashboardContent, { ...props, ...patientId ? { patientId } : {}, ...claimId ? { claimId } : {}, ...renderingProviderId ? { renderingProviderId } : {}, client, signatureClient, options }, `${identity.key}:${patientId ?? ""}:${claimId ?? ""}:${renderingProviderId ?? ""}`);
14885
14920
  }
14886
- function RfaDashboardContent({ client, signatureClient, options, patientId, claimId, renderingProviderId, initialDraft, initialView = "overview", initialDetailAction, initialOverviewView, initialStatus = "", initialAgingBucket = "", taskPresentation, taskQuery: taskQuery2, renderTaskIdentity, navigation, permissions = [], canCreateClaim = false, renderClaimSelector, renderProviderSelector, officialForm = false, managePracticeHref, onEditPractice, onAddPractice, onEditLocation, treatmentTemplates, onSaveTreatmentTemplate, onManageTreatmentTemplates, savedProfileChanges, manageLocationsHref, onPreviewRequest, canManageProviderSignatures = false, environment = "sandbox", actorReference, onCreated, onContinue, selectedRfaId, selectedTreatmentId, selectedResponseDocumentId: controlledResponseDocumentId, onSelectRfa, getRfaHref, getPatientHref, getClaimHref, getProviderHref, formPreviewUrl, hideBackButton = false, hideHeading = false, layout = "classic", ...appearance }) {
14921
+ function RfaDashboardContent({ client, signatureClient, options, patientId, claimId, renderingProviderId, initialDraft, initialView = "overview", initialDetailAction, initialOverviewView, initialStatus = "", initialAgingBucket = "", taskPresentation, taskQuery: taskQuery2, renderTaskIdentity, navigation, permissions = [], canCreateClaim = false, renderClaimSelector, renderProviderSelector, officialForm = false, managePracticeHref, onEditPractice, onAddPractice, onEditLocation, treatmentTemplates, onSaveTreatmentTemplate, onManageTreatmentTemplates, savedProfileChanges, manageLocationsHref, onPreviewRequest, onPreviewDraft, canManageProviderSignatures = false, environment = "sandbox", actorReference, onCreated, onContinue, selectedRfaId, selectedTreatmentId, selectedResponseDocumentId: controlledResponseDocumentId, onSelectRfa, getRfaHref, getPatientHref, getClaimHref, getProviderHref, formPreviewUrl, hideBackButton = false, hideHeading = false, layout = "classic", ...appearance }) {
14887
14922
  const active = useRef25(true);
14888
14923
  useEffect27(() => {
14889
14924
  active.current = true;
@@ -14899,7 +14934,7 @@ function RfaDashboardContent({ client, signatureClient, options, patientId, clai
14899
14934
  const merge = (current, saved) => saved?.length ? [...current.map((item) => saved.find((next) => next.id === item.id) ?? item), ...saved.filter((next) => !current.some((item) => item.id === next.id))] : current;
14900
14935
  setProfile((current) => current ? { ...current, billingProviders: merge(current.billingProviders, savedProfileChanges.billingProviders), locations: merge(current.locations, savedProfileChanges.locations) } : current);
14901
14936
  }, [savedProfileChanges]);
14902
- const draftFormProps = { officialForm, profilePending: !profile && !profileSettled, ...officialForm && (treatmentTemplates || onSaveTreatmentTemplate) ? { treatmentTemplates: treatmentTemplates ?? [], onSaveTreatmentTemplate, onManageTreatmentTemplates } : {}, ...onEditPractice ? { onEditPractice } : {}, ...onAddPractice ? { onAddPractice } : {}, ...onEditLocation ? { onEditLocation } : {}, ...managePracticeHref ? { managePracticeHref } : {}, ...manageLocationsHref ? { manageLocationsHref } : {}, onRefreshProfile: async () => {
14937
+ const draftFormProps = { officialForm, profilePending: !profile && !profileSettled, ...onPreviewDraft ? { onPreviewDraft } : {}, ...officialForm && (treatmentTemplates || onSaveTreatmentTemplate) ? { treatmentTemplates: treatmentTemplates ?? [], onSaveTreatmentTemplate, onManageTreatmentTemplates } : {}, ...onEditPractice ? { onEditPractice } : {}, ...onAddPractice ? { onAddPractice } : {}, ...onEditLocation ? { onEditLocation } : {}, ...managePracticeHref ? { managePracticeHref } : {}, ...manageLocationsHref ? { manageLocationsHref } : {}, onRefreshProfile: async () => {
14903
14938
  const next = await createOrganizationClient4(options).getBillingProfile();
14904
14939
  if (active.current) setProfile(next);
14905
14940
  }, ...client.searchClaimsAdministrators ? { searchClaimsAdministrators: client.searchClaimsAdministrators } : {}, ...client.getClaimsAdministratorDirectory ? { getClaimsAdministratorDirectory: client.getClaimsAdministratorDirectory } : {}, searchDiagnosisCodes: references.searchDiagnosisCodes, ...profile ? { organizationProfile: profile } : {} };