@mindbill/react 0.77.50 → 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
@@ -12941,29 +12941,42 @@ function RfaDiagnosisFields({ code, description, onChange, search, officialForm
12941
12941
  diagnosisDescription: nextDescriptions.some(Boolean) ? nextDescriptions.map((text3) => text3.replace(/;/g, ",").trim()).join("; ") : ""
12942
12942
  });
12943
12943
  const resolved = useRef19(/* @__PURE__ */ new Set());
12944
- const [resolving, setResolving] = useState24("");
12945
- 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)) : [];
12946
12951
  const latest = useRef19({ codes: codes2, descriptions: descriptions2, emit });
12947
12952
  latest.current = { codes: codes2, descriptions: descriptions2, emit };
12953
+ const mounted = useRef19(true);
12948
12954
  useEffect21(() => {
12949
- if (!pending || !search) return;
12950
- resolved.current.add(pending);
12951
- let active = true;
12952
- setResolving(pending);
12953
- const same = (left, right) => left.replace(".", "").toUpperCase() === right.replace(".", "").toUpperCase();
12954
- void search(pending).then((items) => {
12955
- const match = items.find((item) => same(item.code, pending));
12956
- if (!active || !match) return;
12957
- const now = latest.current, at = now.codes.indexOf(pending);
12958
- if (at < 0) return;
12959
- now.emit(now.codes.map((item, index) => index === at ? match.code : item), now.descriptions.map((text3, index) => index === at ? match.description : text3));
12960
- }).catch(() => void 0).finally(() => {
12961
- if (active) setResolving("");
12962
- });
12955
+ mounted.current = true;
12963
12956
  return () => {
12964
- active = false;
12957
+ mounted.current = false;
12965
12958
  };
12966
- }, [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]);
12967
12980
  if (officialForm && search) {
12968
12981
  const typed = query.trim().toUpperCase(), known = results.some((item) => item.code.toUpperCase() === typed);
12969
12982
  const chosen = (value) => codes2.includes(value);
@@ -12976,6 +12989,7 @@ function RfaDiagnosisFields({ code, description, onChange, search, officialForm
12976
12989
  const item = results.find((item2) => item2.code === value);
12977
12990
  if (item) emit([...codes2, item.code], [...descriptions2, item.description]);
12978
12991
  else if (value.startsWith("entered:")) {
12992
+ started.current.add(value.slice(8));
12979
12993
  resolved.current.add(value.slice(8));
12980
12994
  emit([...codes2, value.slice(8)], [...descriptions2, ""]);
12981
12995
  } else if (value.startsWith("saved:")) emit([...codes2, value.slice(6)], [...descriptions2, ""]);
@@ -12984,7 +12998,7 @@ function RfaDiagnosisFields({ code, description, onChange, search, officialForm
12984
12998
  return /* @__PURE__ */ jsx39("div", { className: "mbrfa-s6", children: /* @__PURE__ */ jsxs37(RfaPicker, { required: true, label: "ICD-10 Code", children: [
12985
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: [
12986
13000
  /* @__PURE__ */ jsx39("strong", { children: item }),
12987
- 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) => {
12988
13002
  if (event.target.value.trim()) emit(codes2, descriptions2.map((text3, position) => position === index ? event.target.value : text3));
12989
13003
  } }),
12990
13004
  /* @__PURE__ */ jsx39("button", { type: "button", "aria-label": `Remove ${item}`, onClick: () => emit(codes2.filter((_, position) => position !== index), descriptions2.filter((_, position) => position !== index)), children: "\xD7" })
@@ -13384,7 +13398,7 @@ function validateRfaDraft(draft2) {
13384
13398
  }
13385
13399
  return null;
13386
13400
  }
13387
- 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 }) {
13388
13402
  const [savedDraft, setDraft] = useState28(() => normalizeRfaDraft(initialDraft));
13389
13403
  useEffect23(() => {
13390
13404
  if (identity) setDraft((current) => {
@@ -13461,6 +13475,20 @@ function RfaDraftForm({ initialDraft, identity, officialForm = false, formDetail
13461
13475
  const action = useDraftSave(async (value) => {
13462
13476
  await (intentRef.current === "preview" && onPreview ? onPreview : intentRef.current === "review" && onReview ? onReview : onSave)(value);
13463
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
+ };
13464
13492
  const billingProviders = Array.isArray(organizationProfile?.billingProviders) ? organizationProfile.billingProviders : [];
13465
13493
  const locations = Array.isArray(organizationProfile?.locations) ? organizationProfile.locations : [];
13466
13494
  const update = (patch) => {
@@ -13640,9 +13668,10 @@ function RfaDraftForm({ initialDraft, identity, officialForm = false, formDetail
13640
13668
  saveError,
13641
13669
  /* @__PURE__ */ jsxs41("div", { className: "mbtd-actions", children: [
13642
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,
13643
- 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,
13644
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" }),
13645
- /* @__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
13646
13675
  ] })
13647
13676
  ] })
13648
13677
  ] });
@@ -14889,7 +14918,7 @@ function RfaDashboard({ sessionEndpoint, getSession, apiBaseUrl, fetch: fetchOve
14889
14918
  const identity = useMemo12(() => ({ client, signatureClient, key: key() }), [client, signatureClient]);
14890
14919
  return /* @__PURE__ */ jsx48(RfaDashboardContent, { ...props, ...patientId ? { patientId } : {}, ...claimId ? { claimId } : {}, ...renderingProviderId ? { renderingProviderId } : {}, client, signatureClient, options }, `${identity.key}:${patientId ?? ""}:${claimId ?? ""}:${renderingProviderId ?? ""}`);
14891
14920
  }
14892
- 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 }) {
14893
14922
  const active = useRef25(true);
14894
14923
  useEffect27(() => {
14895
14924
  active.current = true;
@@ -14905,7 +14934,7 @@ function RfaDashboardContent({ client, signatureClient, options, patientId, clai
14905
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;
14906
14935
  setProfile((current) => current ? { ...current, billingProviders: merge(current.billingProviders, savedProfileChanges.billingProviders), locations: merge(current.locations, savedProfileChanges.locations) } : current);
14907
14936
  }, [savedProfileChanges]);
14908
- 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 () => {
14909
14938
  const next = await createOrganizationClient4(options).getBillingProfile();
14910
14939
  if (active.current) setProfile(next);
14911
14940
  }, ...client.searchClaimsAdministrators ? { searchClaimsAdministrators: client.searchClaimsAdministrators } : {}, ...client.getClaimsAdministratorDirectory ? { getClaimsAdministratorDirectory: client.getClaimsAdministratorDirectory } : {}, searchDiagnosisCodes: references.searchDiagnosisCodes, ...profile ? { organizationProfile: profile } : {} };