@mindbill/react 0.41.2 → 0.42.0
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/README.md +3 -2
- package/dist/index.d.ts +16 -9
- package/dist/index.js +168 -47
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -191,7 +191,8 @@ The component includes the interaction model, not just the markup:
|
|
|
191
191
|
- paste-friendly `MM/DD/YYYY` date fields and required-field asterisks;
|
|
192
192
|
- ZIP-to-city/state completion through MindBill's authenticated postal directory;
|
|
193
193
|
- complete, server-backed ICD-10 search with an alphabetized 100-code first page, automatic 100-code scroll paging, common-injury quick picks, and removable chips;
|
|
194
|
-
-
|
|
194
|
+
- an authenticated claims-administrator browser that opens to an alphabetized 50-item page, loads later pages on scroll, searches from the first character, and preserves exact-name and claim-number evidence;
|
|
195
|
+
- explicit routing-payer selection when the administrator requires it, with aliases, affiliated entities, claim-number hints, delivery type, clearinghouse routes, and payer identifiers shown in context;
|
|
195
196
|
- QME, AME, and Psych QME evaluation modes with medical-legal modifier defaults; Psych QME also seeds `Z04.6` when no more specific diagnosis was supplied, and exposes it as a Psych quick pick;
|
|
196
197
|
- a searchable rendering-provider taxonomy combobox that accepts either a human-readable specialty search or an exact 10-character taxonomy code;
|
|
197
198
|
- searchable workers-comp procedure/modifier controls, medical-legal fee-schedule amounts, totals, valid manual CPT/HCPCS entry, and an automatically maintained empty line;
|
|
@@ -317,7 +318,7 @@ Never send a Partner API key or long-lived credential to React/browser code.
|
|
|
317
318
|
|
|
318
319
|
## Bill tasks worklist, submissions ribbon, and payer status calls
|
|
319
320
|
|
|
320
|
-
`BillTasksDashboard` is
|
|
321
|
+
`BillTasksDashboard` is a Bill Tasks worklist: one tone-colored card per task section, rows bucketed by age (1-30 / 31-60 / 61-90 / 91-180 / 181+ days), clickable counts that carry the bill refs behind them, and a grand-total card. It is purely props-driven — aggregate your own work items with `buildBillTasksDashboard` (re-exported from `@mindbill/browser`):
|
|
321
322
|
|
|
322
323
|
```tsx
|
|
323
324
|
import { BillTasksDashboard, buildBillTasksDashboard } from "@mindbill/react";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { MindBillAppearance, MindBillEventDetail, MindBillErrorDetail } from '@mindbill/embed';
|
|
2
2
|
export { MindBillAppearance, MindBillErrorDetail, MindBillEventDetail } from '@mindbill/embed';
|
|
3
3
|
import { CSSProperties, ReactElement, ReactNode } from 'react';
|
|
4
|
-
import { BillReviewData as BillReviewData$1, BillLifecycleDelivery, BillReviewAttachment as BillReviewAttachment$1, BillReviewPayerOption, BrowserBillSubmissionResult, BillLifecycleSessionProvider, BillReviewPayer as BillReviewPayer$1, BillClaimsAdministratorDirectory, BrowserBillSubmissionDocument, BillDeliveryOptions as BillDeliveryOptions$1, SubmitBillInput, BillTasksDashboardData, BillTasksAgingBucket, BillHistoryEntry, ReportBillStatusInput, OrganizationProfileData, BillRemittanceSummary, BillEorDocument, BillPaymentRecord, BillLifecycleAction, BillRejection, BillLifecycleData, BillLifecycleClientOptions, BillLifecycleClient } from '@mindbill/browser';
|
|
5
|
-
export { BILL_TASKS_AGING_BUCKETS, BillActivityRecord, BillClaimsAdministratorContact, BillClaimsAdministratorDirectory, BillClaimsAdministratorMailingAddress, BillClaimsAdministratorPattern, BillClaimsAdministratorPayer, BillEorDocument, BillLifecycleAction, BillLifecycleActionId, BillLifecycleClient, BillLifecycleClientOptions, BillLifecycleData, BillLifecycleDelivery, BillLifecycleSession, BillLifecycleSessionProvider, BillLifecycleSessionRequest, BillPaymentRecord, BillRejection, BillRemittanceSummary, BillReviewPayerOption, BillTasksAgingBucket, BillTasksDashboardData, BillTasksDashboardItem, BillTasksDashboardRow, BillTasksDashboardSection, BillTasksDashboardSectionInput, BillTasksDashboardTone, BrowserBillSubmissionResult, CloseBillInput, PostBillPaymentInput, REPORT_BILL_STATUS_OPTIONS, ReopenBillInput, ReportBillStatusContacts, ReportBillStatusId, ReportBillStatusInput, SECOND_REVIEW_REASON_TEMPLATE, SECOND_REVIEW_WINDOW_DAYS, SecondReviewDeadline, SendDuplicateBillInput, SubmitSecondReviewInput, billTasksAgingBucketIndex, buildBillTasksDashboard, createBillLifecycleClient, reportBillStatusContacts, secondReviewDeadline } from '@mindbill/browser';
|
|
4
|
+
import { BillReviewData as BillReviewData$1, BillLifecycleDelivery, BillReviewAttachment as BillReviewAttachment$1, BillReviewPayerOption, BrowserBillSubmissionResult, BillLifecycleSessionProvider, BillReviewPayerListInput, BillReviewPayerPage, BillReviewPayer as BillReviewPayer$1, BillClaimsAdministratorDirectory, BillClaimsAdministratorSource, BrowserBillSubmissionDocument, BillDeliveryOptions as BillDeliveryOptions$1, SubmitBillInput, BillTasksDashboardData, BillTasksAgingBucket, BillHistoryEntry, ReportBillStatusInput, OrganizationProfileData, BillRemittanceSummary, BillEorDocument, BillPaymentRecord, BillLifecycleAction, BillRejection, BillLifecycleData, BillLifecycleClientOptions, BillLifecycleClient } from '@mindbill/browser';
|
|
5
|
+
export { BILL_TASKS_AGING_BUCKETS, BillActivityRecord, BillClaimsAdministratorContact, BillClaimsAdministratorDirectory, BillClaimsAdministratorMailingAddress, BillClaimsAdministratorPattern, BillClaimsAdministratorPayer, BillClaimsAdministratorSource, BillEorDocument, BillLifecycleAction, BillLifecycleActionId, BillLifecycleClient, BillLifecycleClientOptions, BillLifecycleData, BillLifecycleDelivery, BillLifecycleSession, BillLifecycleSessionProvider, BillLifecycleSessionRequest, BillPaymentRecord, BillRejection, BillRemittanceSummary, BillReviewPayerOption, BillReviewPayerSuggestion, BillTasksAgingBucket, BillTasksDashboardData, BillTasksDashboardItem, BillTasksDashboardRow, BillTasksDashboardSection, BillTasksDashboardSectionInput, BillTasksDashboardTone, BrowserBillSubmissionResult, CloseBillInput, PostBillPaymentInput, REPORT_BILL_STATUS_OPTIONS, ReopenBillInput, ReportBillStatusContacts, ReportBillStatusId, ReportBillStatusInput, SECOND_REVIEW_REASON_TEMPLATE, SECOND_REVIEW_WINDOW_DAYS, SecondReviewDeadline, SendDuplicateBillInput, SubmitSecondReviewInput, billTasksAgingBucketIndex, buildBillTasksDashboard, createBillLifecycleClient, reportBillStatusContacts, secondReviewDeadline } from '@mindbill/browser';
|
|
6
6
|
|
|
7
7
|
type MindBillThemePreset = "mindbill" | "qme-companion" | "orange-bright" | "clinical-blue" | "midnight-cyan";
|
|
8
8
|
type MindBillReactAppearance = MindBillAppearance & {
|
|
@@ -568,9 +568,14 @@ type BillSubmissionFormProps = {
|
|
|
568
568
|
sessionEndpoint?: string;
|
|
569
569
|
apiBaseUrl?: string;
|
|
570
570
|
fetch?: typeof globalThis.fetch;
|
|
571
|
+
/** Paginated claims-administrator directory. Empty queries return the alphabetical first page. */
|
|
572
|
+
onListClaimsAdministrators?: (input?: BillReviewPayerListInput) => Promise<BillReviewPayerPage>;
|
|
573
|
+
/** @deprecated Prefer onListClaimsAdministrators for browse and pagination support. */
|
|
571
574
|
onSearchClaimsAdministrators?: (query: string, claimNumber?: string) => Promise<BillReviewPayer$1[]>;
|
|
572
575
|
onGetClaimsAdministratorDirectory?: (id: string, injuryState?: string) => Promise<BillClaimsAdministratorDirectory>;
|
|
573
|
-
/**
|
|
576
|
+
/** Host-system evidence shown without preselecting a canonical directory entry. EAMS evidence takes precedence. */
|
|
577
|
+
claimsAdministratorSources?: readonly BillClaimsAdministratorSource[];
|
|
578
|
+
/** @deprecated Prefer claimsAdministratorSources so the source label and optional URL remain explicit. */
|
|
574
579
|
claimsAdministratorHint?: ReactNode;
|
|
575
580
|
diagnosisOptions?: BillSubmissionDiagnosisOption[];
|
|
576
581
|
onSearchDiagnoses?: (query: string, limit?: number, offset?: number) => Promise<BillSubmissionDiagnosisOption[]>;
|
|
@@ -580,7 +585,7 @@ type BillSubmissionFormProps = {
|
|
|
580
585
|
/** Common NUCC provider taxonomies are bundled; supplied values extend or replace matching codes. */
|
|
581
586
|
taxonomyOptions?: BillSubmissionTaxonomyOption[];
|
|
582
587
|
/**
|
|
583
|
-
* The
|
|
588
|
+
* The delivery-method dialog shown when the biller submits.
|
|
584
589
|
* "auto" (default) shows it in connected mode whenever the delivery preview
|
|
585
590
|
* is available; "off" submits directly on MindBill's recommended route.
|
|
586
591
|
*/
|
|
@@ -631,11 +636,11 @@ declare function exactClaimsAdministratorMatch(results: BillReviewPayer$1[], sup
|
|
|
631
636
|
declare function claimsAdministratorRecommendations(results: BillReviewPayer$1[], limit?: number): BillReviewPayer$1[];
|
|
632
637
|
/**
|
|
633
638
|
* Form-state claims administrator for a directory pick. When the administrator
|
|
634
|
-
* requires payer selection it carries the payer (
|
|
635
|
-
*
|
|
639
|
+
* requires payer selection it carries the payer (routing payer) choices and
|
|
640
|
+
* requires an explicit user choice; administrators without routing payers stay a
|
|
636
641
|
* plain `{ id, name }` reference.
|
|
637
642
|
*/
|
|
638
|
-
declare function chooseClaimsAdministrator(payer: Pick<BillReviewPayer$1, "id" | "name" | "payerSelectionRequired" | "payers"
|
|
643
|
+
declare function chooseClaimsAdministrator(payer: Pick<BillReviewPayer$1, "id" | "name" | "payerSelectionRequired" | "payers">, selectedPayerId?: string): NonNullable<BillSubmissionInput["claim"]["claimsAdministrator"]>;
|
|
639
644
|
/**
|
|
640
645
|
* The claims administrator reference exactly as submitted to MindBill: picker
|
|
641
646
|
* metadata (payerSelectionRequired, payers) stays client-side and the chosen
|
|
@@ -654,7 +659,7 @@ declare function BillSubmissionProvidersSection(): ReactElement;
|
|
|
654
659
|
declare function BillSubmissionServiceLinesSection(): ReactElement;
|
|
655
660
|
declare function BillSubmissionAttachmentsSection(): ReactElement;
|
|
656
661
|
declare function BillSubmissionActions(): ReactElement;
|
|
657
|
-
declare function BillSubmissionForm({ initialBill, attachments, onSubmit, onSubmitted, getSession, sessionEndpoint, apiBaseUrl, fetch: fetchOverride, onSearchClaimsAdministrators, onGetClaimsAdministratorDirectory, claimsAdministratorHint, diagnosisOptions, onSearchDiagnoses, onLookupPostalCode, procedureOptions, modifierOptions, taxonomyOptions, deliveryRoutePicker, attachmentReportTypeMode, attachmentReportTypes, defaultAttachmentReportType, appearance, className, style, disabled, submitLabel, heading, description, attentionFields, attentionMessage, children, }: BillSubmissionFormProps): ReactElement;
|
|
662
|
+
declare function BillSubmissionForm({ initialBill, attachments, onSubmit, onSubmitted, getSession, sessionEndpoint, apiBaseUrl, fetch: fetchOverride, onListClaimsAdministrators, onSearchClaimsAdministrators, onGetClaimsAdministratorDirectory, claimsAdministratorSources, claimsAdministratorHint, diagnosisOptions, onSearchDiagnoses, onLookupPostalCode, procedureOptions, modifierOptions, taxonomyOptions, deliveryRoutePicker, attachmentReportTypeMode, attachmentReportTypes, defaultAttachmentReportType, appearance, className, style, disabled, submitLabel, heading, description, attentionFields, attentionMessage, children, }: BillSubmissionFormProps): ReactElement;
|
|
658
663
|
|
|
659
664
|
/** First plausible email address inside a raw contact string, or null. */
|
|
660
665
|
declare function extractSendRouteEmail(raw: string | null | undefined): string | null;
|
|
@@ -1123,6 +1128,8 @@ type ConnectedBillLifecycleProps = UseBillLifecycleOptions & {
|
|
|
1123
1128
|
actorName?: string;
|
|
1124
1129
|
/** Optional host-system claims-administrator name shown as a selection hint. */
|
|
1125
1130
|
claimsAdministratorHint?: ReactNode;
|
|
1131
|
+
/** Host-system evidence shown without preselecting a canonical directory entry. */
|
|
1132
|
+
claimsAdministratorSources?: readonly BillClaimsAdministratorSource[];
|
|
1126
1133
|
/**
|
|
1127
1134
|
* Exposes payer-response simulation controls for an explicit sandbox
|
|
1128
1135
|
* playground. Sandbox responses remain indistinguishable from live
|
|
@@ -1135,7 +1142,7 @@ type ConnectedBillLifecycleProps = UseBillLifecycleOptions & {
|
|
|
1135
1142
|
errorFallback?: (error: Error, retry: () => Promise<void>) => ReactNode;
|
|
1136
1143
|
onChanged?: (data: BillLifecycleData) => void;
|
|
1137
1144
|
};
|
|
1138
|
-
declare function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint, sandboxControls, className, style, loadingFallback, errorFallback, onChanged, ...options }: ConnectedBillLifecycleProps): ReactElement;
|
|
1145
|
+
declare function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint, claimsAdministratorSources, sandboxControls, className, style, loadingFallback, errorFallback, onChanged, ...options }: ConnectedBillLifecycleProps): ReactElement;
|
|
1139
1146
|
|
|
1140
1147
|
type ClaimsAdministratorDirectoryDialogProps = {
|
|
1141
1148
|
open: boolean;
|
package/dist/index.js
CHANGED
|
@@ -1301,8 +1301,7 @@ var READ_ONLY_STYLES = `
|
|
|
1301
1301
|
import { createContext, useCallback, useContext, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef2, useState as useState5 } from "react";
|
|
1302
1302
|
import {
|
|
1303
1303
|
createBillReferenceClient,
|
|
1304
|
-
createBillSubmissionClient
|
|
1305
|
-
defaultBillReviewPayerOption
|
|
1304
|
+
createBillSubmissionClient
|
|
1306
1305
|
} from "@mindbill/browser";
|
|
1307
1306
|
|
|
1308
1307
|
// src/send-route-dialog.tsx
|
|
@@ -1702,7 +1701,7 @@ var css2 = `
|
|
|
1702
1701
|
.mbcad-dialog{--mbcad-accent:var(--mb-accent,#176c70);--mbcad-border:var(--mb-border,#d7e0df);--mbcad-surface:var(--mb-surface,#fff);--mbcad-text:var(--mb-text,#17282d);--mbcad-muted:var(--mb-muted,#607176);display:grid;grid-template-rows:auto auto minmax(0,1fr);width:min(1180px,100%);max-height:min(860px,92vh);overflow:hidden;border:1px solid var(--mbcad-border);border-radius:14px;background:var(--mbcad-surface);color:var(--mbcad-text);box-shadow:0 28px 80px rgba(14,31,43,.28);font-family:var(--mb-font,Inter,ui-sans-serif,system-ui,sans-serif)}
|
|
1703
1702
|
.mbcad-head{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:18px 22px;border-bottom:1px solid var(--mbcad-border)}.mbcad-head h2{margin:0;font-size:24px;line-height:1.2}.mbcad-close{width:40px;height:40px;border:0;border-radius:9px;background:color-mix(in srgb,var(--mbcad-muted) 9%,var(--mbcad-surface));color:var(--mbcad-accent);font:inherit;font-size:28px;line-height:1;cursor:pointer}
|
|
1704
1703
|
.mbcad-tabs{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));margin:18px 22px 0;border-radius:10px;background:color-mix(in srgb,var(--mbcad-muted) 8%,var(--mbcad-surface));overflow:hidden}.mbcad-tab{min-height:64px;padding:10px;border:0;border-right:1px solid var(--mbcad-border);border-top:4px solid transparent;background:transparent;color:var(--mbcad-muted);font:inherit;font-weight:750;cursor:pointer}.mbcad-tab:last-child{border-right:0}.mbcad-tab[aria-selected=true]{border-top-color:var(--mbcad-accent);background:var(--mbcad-surface);color:var(--mbcad-text)}
|
|
1705
|
-
.mbcad-body{overflow:auto;padding:24px 22px 28px}.mbcad-grid{display:grid;gap:0;border:1px solid var(--mbcad-border);border-radius:10px;overflow:hidden}.mbcad-row{display:grid;grid-template-columns:minmax(180px,.8fr) minmax(0,2fr);gap:18px;padding:11px 14px;border-bottom:1px solid var(--mbcad-border)}.mbcad-row:last-child{border-bottom:0}.mbcad-row strong{font-weight:750}.mbcad-list{display:grid;gap:5px;margin:0;padding:0;list-style:none}.mbcad-list a,.mbcad-table a{color:var(--mbcad-accent);overflow-wrap:anywhere}.mbcad-table{width:100%;border-collapse:collapse;border:1px solid var(--mbcad-border);border-radius:10px;overflow:hidden}.mbcad-table th,.mbcad-table td{padding:13px 14px;border-bottom:1px solid var(--mbcad-border);text-align:left;vertical-align:top}.mbcad-table th{background:color-mix(in srgb,var(--mbcad-muted) 7%,var(--mbcad-surface));font-size:13px}.mbcad-empty{padding:36px;text-align:center;color:var(--mbcad-muted)}.mbcad-notice{padding:14px 16px;border:1px solid color-mix(in srgb,var(--mbcad-accent) 70%,var(--mbcad-border));border-radius:9px;background:color-mix(in srgb,var(--mbcad-accent) 5%,var(--mbcad-surface));font-weight:650}
|
|
1704
|
+
.mbcad-body{overflow:auto;padding:24px 22px 28px}.mbcad-grid{display:grid;gap:0;border:1px solid var(--mbcad-border);border-radius:10px;overflow:hidden}.mbcad-row{display:grid;grid-template-columns:minmax(180px,.8fr) minmax(0,2fr);gap:18px;padding:11px 14px;border-bottom:1px solid var(--mbcad-border)}.mbcad-row:last-child{border-bottom:0}.mbcad-row strong{font-weight:750}.mbcad-list{display:grid;gap:5px;margin:0;padding:0;list-style:none}.mbcad-list a,.mbcad-table a{color:var(--mbcad-accent);overflow-wrap:anywhere}.mbcad-payers{display:grid;gap:9px;margin:0;padding:0;list-style:none}.mbcad-payer{display:grid;gap:7px;padding:12px;border:1px solid var(--mbcad-border);border-radius:9px;background:color-mix(in srgb,var(--mbcad-muted) 3%,var(--mbcad-surface))}.mbcad-payer-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.mbcad-payer-route{color:var(--mbcad-accent);font-size:13px;font-weight:750;white-space:nowrap}.mbcad-payer-meta{display:flex;flex-wrap:wrap;gap:6px}.mbcad-payer-meta span{padding:3px 7px;border:1px solid var(--mbcad-border);border-radius:999px;color:var(--mbcad-muted);font-size:12px}.mbcad-payer-note{margin:0;color:var(--mbcad-muted);font-size:13px}.mbcad-table{width:100%;border-collapse:collapse;border:1px solid var(--mbcad-border);border-radius:10px;overflow:hidden}.mbcad-table th,.mbcad-table td{padding:13px 14px;border-bottom:1px solid var(--mbcad-border);text-align:left;vertical-align:top}.mbcad-table th{background:color-mix(in srgb,var(--mbcad-muted) 7%,var(--mbcad-surface));font-size:13px}.mbcad-empty{padding:36px;text-align:center;color:var(--mbcad-muted)}.mbcad-notice{padding:14px 16px;border:1px solid color-mix(in srgb,var(--mbcad-accent) 70%,var(--mbcad-border));border-radius:9px;background:color-mix(in srgb,var(--mbcad-accent) 5%,var(--mbcad-surface));font-weight:650}
|
|
1706
1705
|
@media(max-width:760px){.mbcad-backdrop{padding:8px}.mbcad-dialog{max-height:96vh}.mbcad-head{padding:14px}.mbcad-head h2{font-size:19px}.mbcad-tabs{display:flex;overflow-x:auto;margin:10px 12px 0}.mbcad-tab{min-width:145px}.mbcad-body{padding:14px 12px 18px}.mbcad-row{grid-template-columns:1fr;gap:5px}.mbcad-table{display:block;overflow-x:auto}}
|
|
1707
1706
|
`;
|
|
1708
1707
|
function outbound(value, kind) {
|
|
@@ -1712,6 +1711,33 @@ function outbound(value, kind) {
|
|
|
1712
1711
|
function list(values, kind) {
|
|
1713
1712
|
return values?.length ? /* @__PURE__ */ jsx4("ul", { className: "mbcad-list", children: values.map((value, index) => /* @__PURE__ */ jsx4("li", { children: kind ? outbound(value, kind) : value }, `${value}-${index}`)) }) : "\u2014";
|
|
1714
1713
|
}
|
|
1714
|
+
function payerDetails(payer, index) {
|
|
1715
|
+
const identifiers = Object.entries(payer.clearinghousePayerIds ?? {}).map(([name, id]) => `${name.replace(/_/g, " ")}: ${id}`);
|
|
1716
|
+
const metadata = [
|
|
1717
|
+
payer.optionType ? `Type: ${payer.optionType}` : null,
|
|
1718
|
+
payer.deliveryType ? `Delivery: ${payer.deliveryType}` : null,
|
|
1719
|
+
payer.clearinghouse && payer.payerId ? `${payer.clearinghouse}: ${payer.payerId}` : null,
|
|
1720
|
+
payer.sourceClearinghouse && payer.sourcePayerId ? `Catalog route: ${payer.sourceClearinghouse} ${payer.sourcePayerId}` : null,
|
|
1721
|
+
...identifiers,
|
|
1722
|
+
payer.preferredClearinghouse ? `Preferred: ${payer.preferredClearinghouse}` : null
|
|
1723
|
+
].filter((value) => Boolean(value));
|
|
1724
|
+
return /* @__PURE__ */ jsxs4("li", { className: "mbcad-payer", children: [
|
|
1725
|
+
/* @__PURE__ */ jsxs4("div", { className: "mbcad-payer-head", children: [
|
|
1726
|
+
/* @__PURE__ */ jsx4("strong", { children: payer.name }),
|
|
1727
|
+
payer.route ? /* @__PURE__ */ jsx4("span", { className: "mbcad-payer-route", children: payer.route }) : null
|
|
1728
|
+
] }),
|
|
1729
|
+
payer.aliases?.length ? /* @__PURE__ */ jsxs4("p", { className: "mbcad-payer-note", children: [
|
|
1730
|
+
"Also known as ",
|
|
1731
|
+
payer.aliases.join(", ")
|
|
1732
|
+
] }) : null,
|
|
1733
|
+
payer.hint ? /* @__PURE__ */ jsx4("p", { className: "mbcad-payer-note", children: payer.hint }) : null,
|
|
1734
|
+
payer.affiliatedEntities?.length ? /* @__PURE__ */ jsxs4("p", { className: "mbcad-payer-note", children: [
|
|
1735
|
+
"Affiliated with ",
|
|
1736
|
+
payer.affiliatedEntities.join(", ")
|
|
1737
|
+
] }) : null,
|
|
1738
|
+
metadata.length ? /* @__PURE__ */ jsx4("div", { className: "mbcad-payer-meta", children: metadata.map((item) => /* @__PURE__ */ jsx4("span", { children: item }, item)) }) : null
|
|
1739
|
+
] }, `${payer.name}-${index}`);
|
|
1740
|
+
}
|
|
1715
1741
|
function Main({ directory }) {
|
|
1716
1742
|
return /* @__PURE__ */ jsx4("div", { className: "mbcad-grid", children: [
|
|
1717
1743
|
["Name", directory.name ?? "\u2014"],
|
|
@@ -1724,12 +1750,7 @@ function Main({ directory }) {
|
|
|
1724
1750
|
["Telephone numbers", list(directory.telephoneNumbers, "phone")],
|
|
1725
1751
|
["Email addresses", list(directory.emailAddresses, "email")],
|
|
1726
1752
|
["Web portals", list(directory.webPortals, "url")],
|
|
1727
|
-
["Payers", directory.payers?.length ? /* @__PURE__ */ jsx4("ul", { className: "mbcad-
|
|
1728
|
-
/* @__PURE__ */ jsx4("strong", { children: payer.name }),
|
|
1729
|
-
payer.daisyBillPayerId ? ` \xB7 daisyBill Payer ID ${payer.daisyBillPayerId}` : "",
|
|
1730
|
-
payer.route ? ` \xB7 ${payer.route}` : "",
|
|
1731
|
-
payer.hint ? /* @__PURE__ */ jsx4("small", { children: payer.hint }) : null
|
|
1732
|
-
] }, `${payer.name}-${index}`)) }) : "\u2014"],
|
|
1753
|
+
["Payers", directory.payers?.length ? /* @__PURE__ */ jsx4("ul", { className: "mbcad-payers", children: directory.payers.map(payerDetails) }) : "\u2014"],
|
|
1733
1754
|
["Bill processing workflow", directory.billProcessingWorkflow ?? "\u2014"],
|
|
1734
1755
|
["Bill processing workflow notes", directory.billProcessingWorkflowNotes ?? "\u2014"],
|
|
1735
1756
|
["Claim number hint", directory.claimNumberHint ?? "\u2014"]
|
|
@@ -2118,6 +2139,7 @@ var MAX_PDF_BYTES = 25 * 1024 * 1024;
|
|
|
2118
2139
|
var MAX_UPLOAD_BYTES = 100 * 1024 * 1024;
|
|
2119
2140
|
var MAX_DOCUMENTS = 25;
|
|
2120
2141
|
var DIAGNOSIS_PAGE_SIZE = 100;
|
|
2142
|
+
var PAYER_PAGE_SIZE = 50;
|
|
2121
2143
|
var EMPTY_ATTACHMENTS = [];
|
|
2122
2144
|
function bytesToBase64(bytes) {
|
|
2123
2145
|
let binary = "";
|
|
@@ -2317,8 +2339,9 @@ var css3 = `
|
|
|
2317
2339
|
.mbsf-attention{padding:14px 16px;border-left:4px solid var(--mb-danger);border-radius:var(--mb-control-radius);background:color-mix(in srgb,var(--mb-danger) 8%,var(--mb-surface));color:var(--mb-text)}.mbsf [data-attention=true] .mbsf-input,.mbsf [data-attention=true] .mbsf-select,.mbsf [data-attention=true].mbsf-lines{border-color:var(--mb-danger);background:color-mix(in srgb,var(--mb-danger) 4%,var(--mb-input))}.mbsf [data-attention=true]>.mbsf-label{color:var(--mb-danger)}
|
|
2318
2340
|
.mbsf-head,.mbsf-section-head,.mbsf-attach-row,.mbsf-actions{display:flex;align-items:center;justify-content:space-between;gap:16px}.mbsf-title{margin:0;font-size:24px}.mbsf-copy,.mbsf-help{color:var(--mb-muted);margin:5px 0 0}.mbsf-required{font-size:13px;color:var(--mb-muted);white-space:nowrap}.mbsf-star,.mbsf-error{color:var(--mb-danger)}
|
|
2319
2341
|
.mbsf-card{min-width:0;margin:0;padding:24px;border:1px solid var(--mb-border);border-radius:var(--mb-radius);background:var(--mb-surface);box-shadow:var(--mb-shadow)}.mbsf-card[data-invalid=true]{border-color:var(--mb-danger)}.mbsf-legend{padding:0 10px;font-size:18px;font-weight:760}.mbsf-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 24px}.mbsf-subhead{grid-column:1/-1;margin:6px 0 -2px;padding-top:14px;border-top:1px solid var(--mb-border);font-size:15px;font-weight:780;letter-spacing:.01em}.mbsf-subhead:first-child{margin-top:0;padding-top:0;border-top:0}.mbsf-span{grid-column:1/-1}.mbsf-field{display:grid;align-content:start;gap:7px;min-width:0}.mbsf-label{font-weight:680}.mbsf-input,.mbsf-select{width:100%;min-height:46px;padding:10px 12px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:var(--mb-input);color:var(--mb-text);font:inherit}.mbsf-input:focus,.mbsf-select:focus{outline:3px solid color-mix(in srgb,var(--mb-accent) 22%,transparent);border-color:var(--mb-accent)}.mbsf-field[data-invalid=true] .mbsf-input,.mbsf-field[data-invalid=true] .mbsf-select,.mbsf-invalid-control .mbsf-input{border-color:var(--mb-danger);background:color-mix(in srgb,var(--mb-danger) 4%,var(--mb-input))}.mbsf-field[data-invalid=true] .mbsf-input:focus,.mbsf-field[data-invalid=true] .mbsf-select:focus{outline-color:color-mix(in srgb,var(--mb-danger) 24%,transparent)}
|
|
2320
|
-
.mbsf-combo{position:relative}.mbsf-menu{position:absolute;z-index:20;top:calc(100% + 5px);left:0;right:0;max-height:min(
|
|
2342
|
+
.mbsf-combo{position:relative}.mbsf-menu{position:absolute;z-index:20;top:calc(100% + 5px);left:0;right:0;max-height:min(420px,52vh);overflow:auto;overscroll-behavior:contain;padding:7px;border:1px solid var(--mb-border);border-radius:12px;background:var(--mb-surface);box-shadow:0 14px 35px rgba(17,38,49,.16)}.mbsf-option{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:14px;width:100%;padding:11px 12px;border:0;border-radius:8px;background:transparent;color:var(--mb-text);font:inherit;text-align:left;cursor:pointer}.mbsf-option+.mbsf-option{border-top:1px solid color-mix(in srgb,var(--mb-border) 65%,transparent)}.mbsf-option:hover,.mbsf-option:focus{background:color-mix(in srgb,var(--mb-accent) 9%,var(--mb-surface));outline:0}.mbsf-option-main{display:grid;gap:5px;min-width:0}.mbsf-option small{color:var(--mb-muted);overflow-wrap:anywhere;line-height:1.35}.mbsf-option-route{align-self:start;margin-top:2px;color:var(--mb-accent);font-size:13px;font-weight:750;white-space:nowrap}.mbsf-option-badges{display:flex;flex-wrap:wrap;gap:5px}.mbsf-option-badge{padding:2px 7px;border:1px solid var(--mb-border);border-radius:999px;color:var(--mb-muted);font-size:11px;line-height:1.35}.mbsf-option-affiliates{display:block}.mbsf-option-affiliates strong{color:var(--mb-text);font-size:12px}.mbsf-menu-status{padding:12px;text-align:center;color:var(--mb-muted);font-size:13px}.mbsf-directory-link{justify-self:start;border:0;padding:0;background:transparent;color:var(--mb-accent);font:inherit;font-weight:700;text-align:left;text-decoration:underline;cursor:pointer}
|
|
2321
2343
|
.mbsf-payer-status{display:flex;align-items:center;gap:7px;color:#087f5b;font-size:13px;font-weight:650}.mbsf-payer-intro{margin:4px 0 0;color:var(--mb-muted)}.mbsf-payer-list{display:grid;gap:8px}.mbsf-payer-option{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:11px 12px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:color-mix(in srgb,var(--mb-accent) 3%,var(--mb-surface))}.mbsf-payer-option-main{display:grid;gap:5px;min-width:0}.mbsf-payer-option-main strong{overflow-wrap:anywhere}.mbsf-payer-signals{display:flex;flex-wrap:wrap;gap:6px}.mbsf-payer-signal{padding:2px 7px;border:1px solid var(--mb-border);border-radius:999px;color:var(--mb-muted);font-size:12px}.mbsf-payer-signal[data-state=match]{border-color:color-mix(in srgb,#159447 45%,var(--mb-border));color:#087f5b}.mbsf-payer-signal[data-state=warning]{border-color:color-mix(in srgb,#c56a00 55%,var(--mb-border));color:#9a5200}
|
|
2344
|
+
.mbsf-source-evidence{display:grid;gap:4px;color:var(--mb-muted);font-size:13px}.mbsf-source-evidence a{color:var(--mb-accent);font-weight:700}.mbsf-source-evidence q{color:var(--mb-text)}.mbsf-suggestions{display:flex;align-items:center;flex-wrap:wrap;gap:7px;color:var(--mb-muted);font-size:13px}.mbsf-suggestion{padding:5px 10px;border:1px solid color-mix(in srgb,var(--mb-accent) 55%,var(--mb-border));border-radius:999px;background:color-mix(in srgb,var(--mb-accent) 7%,var(--mb-surface));color:var(--mb-accent);font:inherit;font-weight:700;cursor:pointer}.mbsf-suggestion:hover,.mbsf-suggestion:focus{outline:2px solid color-mix(in srgb,var(--mb-accent) 25%,transparent)}.mbsf-claim-patterns{display:grid;gap:4px;margin-top:2px;font-size:13px}.mbsf-claim-patterns[data-state=match]{color:#087f5b}.mbsf-claim-patterns[data-state=warning]{color:#9a5200}.mbsf-claim-pattern-list{color:var(--mb-muted)}
|
|
2322
2345
|
.mbsf-chips,.mbsf-quick-picks{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:8px}.mbsf-chip,.mbsf-quick-pick{display:inline-flex;align-items:center;gap:7px;padding:5px 9px;border:1px solid var(--mb-border);border-radius:999px;background:var(--mb-input)}.mbsf-chip button{border:0;background:transparent;color:var(--mb-muted);cursor:pointer;font:inherit}.mbsf-quick-pick{color:var(--mb-text);font:inherit;cursor:pointer}.mbsf-quick-pick[data-selected=true]{border-color:var(--mb-accent);color:var(--mb-accent)}
|
|
2323
2346
|
.mbsf-segments{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);overflow:hidden}.mbsf-segment{min-height:44px;border:0;border-right:1px solid var(--mb-border);background:var(--mb-input);color:var(--mb-text);font:inherit;font-weight:700;cursor:pointer}.mbsf-segment:last-child{border-right:0}.mbsf-segment[aria-pressed=true]{background:var(--mb-accent);color:var(--mb-accent-contrast)}
|
|
2324
2347
|
.mbsf-lines{margin-top:18px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);overflow:visible}.mbsf-lines[data-invalid=true]{border-color:var(--mb-danger)}.mbsf-line-head,.mbsf-line{display:grid;grid-template-columns:minmax(190px,1.05fr) minmax(190px,1.3fr) minmax(112px,.7fr) 100px 120px 42px;gap:12px;align-items:start;padding:12px}.mbsf-line-head{color:var(--mb-muted);font-size:13px;font-weight:700;border-bottom:1px solid var(--mb-border)}.mbsf-line{border-bottom:1px solid var(--mb-border)}.mbsf-line:last-child{border-bottom:0}.mbsf-line [data-invalid=true] .mbsf-input{border-color:var(--mb-danger);background:color-mix(in srgb,var(--mb-danger) 4%,var(--mb-input))}.mbsf-money{padding-top:12px;text-align:right;font-variant-numeric:tabular-nums}.mbsf-dx{display:flex;flex-wrap:wrap;gap:5px;padding-top:6px}.mbsf-dx-chip{width:30px;height:30px;border:1px solid var(--mb-border);border-radius:8px;background:var(--mb-surface);color:var(--mb-muted);font:inherit;font-size:13px;font-weight:750;cursor:pointer}.mbsf-dx-chip[data-active=true]{border-color:var(--mb-accent);background:color-mix(in srgb,var(--mb-accent) 10%,var(--mb-surface));color:var(--mb-accent)}.mbsf-total{display:flex;justify-content:flex-end;gap:45px;padding:16px 56px 16px 16px;font-size:17px;font-weight:760}
|
|
@@ -2357,16 +2380,16 @@ function TextDateInput({ value, onChange, disabled, required, ariaLabel }) {
|
|
|
2357
2380
|
invalid ? /* @__PURE__ */ jsx5("small", { className: "mbsf-error", children: "Use MM/DD/YYYY" }) : null
|
|
2358
2381
|
] });
|
|
2359
2382
|
}
|
|
2360
|
-
function ComboBox({ value, placeholder, options, disabled, loading, loadingMore, invalid, preserveValueOnOpen = false, onOpen, onQuery, onEndReached, onSelect, createOption, ariaLabel }) {
|
|
2383
|
+
function ComboBox({ value, placeholder, options, disabled, loading, loadingMore, invalid, preserveValueOnOpen = false, filterOptions = true, onOpen, onQuery, onEndReached, onSelect, createOption, ariaLabel }) {
|
|
2361
2384
|
const [open, setOpen] = useState5(false);
|
|
2362
2385
|
const [query, setQuery] = useState5("");
|
|
2363
2386
|
const visible = useMemo3(() => {
|
|
2364
2387
|
const q = query.trim().toLowerCase();
|
|
2365
|
-
const matches = q ? options.filter((option) => `${option.id} ${option.label} ${option.detail ?? ""} ${option.trailing ?? ""}`.toLowerCase().includes(q)) : options;
|
|
2388
|
+
const matches = q && filterOptions ? options.filter((option) => `${option.id} ${option.label} ${option.detail ?? ""} ${(option.badges ?? []).join(" ")} ${(option.affiliatedEntities ?? []).join(" ")} ${option.trailing ?? ""}`.toLowerCase().includes(q)) : options;
|
|
2366
2389
|
const custom = createOption?.(query) ?? null;
|
|
2367
2390
|
return custom && !matches.some((option) => option.id.toUpperCase() === custom.id.toUpperCase()) ? [...matches, custom] : matches;
|
|
2368
|
-
}, [createOption, options, query]);
|
|
2369
|
-
const showMenu = open
|
|
2391
|
+
}, [createOption, filterOptions, options, query]);
|
|
2392
|
+
const showMenu = open;
|
|
2370
2393
|
return /* @__PURE__ */ jsxs5("div", { className: "mbsf-combo", children: [
|
|
2371
2394
|
/* @__PURE__ */ jsx5("input", { className: "mbsf-input", role: "combobox", "aria-label": ariaLabel, "aria-invalid": invalid, "aria-expanded": showMenu, autoComplete: "off", disabled, placeholder, value: open ? query : value, onFocus: () => {
|
|
2372
2395
|
const next = preserveValueOnOpen ? value : "";
|
|
@@ -2390,7 +2413,13 @@ function ComboBox({ value, placeholder, options, disabled, loading, loadingMore,
|
|
|
2390
2413
|
}, children: [
|
|
2391
2414
|
/* @__PURE__ */ jsxs5("span", { className: "mbsf-option-main", children: [
|
|
2392
2415
|
/* @__PURE__ */ jsx5("strong", { children: option.label }),
|
|
2393
|
-
option.detail ? /* @__PURE__ */ jsx5("small", { children: option.detail }) : null
|
|
2416
|
+
option.detail ? /* @__PURE__ */ jsx5("small", { children: option.detail }) : null,
|
|
2417
|
+
option.badges?.length ? /* @__PURE__ */ jsx5("span", { className: "mbsf-option-badges", children: option.badges.map((badge) => /* @__PURE__ */ jsx5("span", { className: "mbsf-option-badge", children: badge }, badge)) }) : null,
|
|
2418
|
+
option.affiliatedEntities?.length ? /* @__PURE__ */ jsxs5("small", { className: "mbsf-option-affiliates", children: [
|
|
2419
|
+
/* @__PURE__ */ jsx5("strong", { children: "Affiliated entities:" }),
|
|
2420
|
+
" ",
|
|
2421
|
+
option.affiliatedEntities.join(", ")
|
|
2422
|
+
] }) : null
|
|
2394
2423
|
] }),
|
|
2395
2424
|
option.trailing ? /* @__PURE__ */ jsx5("span", { className: "mbsf-option-route", children: option.trailing }) : null
|
|
2396
2425
|
] }, option.id)) : /* @__PURE__ */ jsx5("div", { className: "mbsf-option", children: "No matches" }),
|
|
@@ -2440,16 +2469,24 @@ function exactClaimsAdministratorMatch(results, suppliedName) {
|
|
|
2440
2469
|
function claimsAdministratorRecommendations(results, limit = 5) {
|
|
2441
2470
|
return [...results].sort((left, right) => Number(Boolean(right.recommended)) - Number(Boolean(left.recommended))).slice(0, Math.max(0, limit));
|
|
2442
2471
|
}
|
|
2443
|
-
function
|
|
2472
|
+
function claimNumberPatternMatches(pattern, claimNumber) {
|
|
2473
|
+
const example = pattern.example?.trim();
|
|
2474
|
+
if (example && /9{2,}/.test(example)) {
|
|
2475
|
+
const expression = [...example].map((character) => character === "9" ? "\\d" : character.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
|
|
2476
|
+
return new RegExp(`^${expression}$`, "i").test(claimNumber.trim());
|
|
2477
|
+
}
|
|
2478
|
+
return pattern.matches ?? null;
|
|
2479
|
+
}
|
|
2480
|
+
function chooseClaimsAdministrator(payer, selectedPayerId) {
|
|
2444
2481
|
if (!payer.payerSelectionRequired) return { id: payer.id, name: payer.name };
|
|
2445
2482
|
const payers = (payer.payers ?? []).map((option) => ({ ...option }));
|
|
2446
|
-
const
|
|
2483
|
+
const resolvedPayerId = selectedPayerId && payers.some((option) => option.id === selectedPayerId) ? selectedPayerId : void 0;
|
|
2447
2484
|
return {
|
|
2448
2485
|
id: payer.id,
|
|
2449
2486
|
name: payer.name,
|
|
2450
2487
|
payerSelectionRequired: true,
|
|
2451
2488
|
...payers.length ? { payers } : {},
|
|
2452
|
-
...
|
|
2489
|
+
...resolvedPayerId ? { payerId: resolvedPayerId } : {}
|
|
2453
2490
|
};
|
|
2454
2491
|
}
|
|
2455
2492
|
function submittedClaimsAdministrator(administrator) {
|
|
@@ -2495,8 +2532,10 @@ function BillSubmissionForm({
|
|
|
2495
2532
|
sessionEndpoint,
|
|
2496
2533
|
apiBaseUrl,
|
|
2497
2534
|
fetch: fetchOverride,
|
|
2535
|
+
onListClaimsAdministrators,
|
|
2498
2536
|
onSearchClaimsAdministrators,
|
|
2499
2537
|
onGetClaimsAdministratorDirectory,
|
|
2538
|
+
claimsAdministratorSources,
|
|
2500
2539
|
claimsAdministratorHint,
|
|
2501
2540
|
diagnosisOptions = [],
|
|
2502
2541
|
onSearchDiagnoses,
|
|
@@ -2532,6 +2571,11 @@ function BillSubmissionForm({
|
|
|
2532
2571
|
const [routeError, setRouteError] = useState5(null);
|
|
2533
2572
|
const [payerResults, setPayerResults] = useState5([]);
|
|
2534
2573
|
const [payerLoading, setPayerLoading] = useState5(false);
|
|
2574
|
+
const [payerSuggestions, setPayerSuggestions] = useState5([]);
|
|
2575
|
+
const [selectedPayerMetadata, setSelectedPayerMetadata] = useState5(null);
|
|
2576
|
+
const [payerLoadingMore, setPayerLoadingMore] = useState5(false);
|
|
2577
|
+
const [payerQuery, setPayerQuery] = useState5(null);
|
|
2578
|
+
const [payerHasMore, setPayerHasMore] = useState5(true);
|
|
2535
2579
|
const [directoryOpen, setDirectoryOpen] = useState5(false);
|
|
2536
2580
|
const [directory, setDirectory] = useState5(null);
|
|
2537
2581
|
const [directoryLoading, setDirectoryLoading] = useState5(false);
|
|
@@ -2548,7 +2592,10 @@ function BillSubmissionForm({
|
|
|
2548
2592
|
const diagnosisRequest = useRef2(0);
|
|
2549
2593
|
const diagnosisAppendPending = useRef2(false);
|
|
2550
2594
|
const payerRequest = useRef2(0);
|
|
2595
|
+
const payerAppendPending = useRef2(false);
|
|
2551
2596
|
const procedures = useMemo3(() => mergeOptions(DEFAULT_BILL_SUBMISSION_PROCEDURES, procedureOptions), [procedureOptions]);
|
|
2597
|
+
const orderedClaimsAdministratorSources = useMemo3(() => [...claimsAdministratorSources ?? []].filter((source) => source.name.trim()).sort((left, right) => Number(right.source.toLowerCase() === "eams") - Number(left.source.toLowerCase() === "eams")), [claimsAdministratorSources]);
|
|
2598
|
+
const sourceClaimsAdministratorName = orderedClaimsAdministratorSources[0]?.name.trim() ?? "";
|
|
2552
2599
|
const modifiers = useMemo3(() => mergeOptions(DEFAULT_BILL_SUBMISSION_MODIFIERS, modifierOptions), [modifierOptions]);
|
|
2553
2600
|
const taxonomies = useMemo3(() => mergeOptions(DEFAULT_BILL_SUBMISSION_TAXONOMIES, taxonomyOptions), [taxonomyOptions]);
|
|
2554
2601
|
const [evaluationType, setEvaluationType] = useState5(() => initialEvaluationType(initialBill));
|
|
@@ -2575,7 +2622,14 @@ function BillSubmissionForm({
|
|
|
2575
2622
|
setDiagnosisHasMore(true);
|
|
2576
2623
|
diagnosisRequest.current += 1;
|
|
2577
2624
|
diagnosisAppendPending.current = false;
|
|
2578
|
-
|
|
2625
|
+
setPayerResults([]);
|
|
2626
|
+
setPayerSuggestions([]);
|
|
2627
|
+
setSelectedPayerMetadata(null);
|
|
2628
|
+
setPayerQuery(null);
|
|
2629
|
+
setPayerHasMore(true);
|
|
2630
|
+
payerRequest.current += 1;
|
|
2631
|
+
payerAppendPending.current = false;
|
|
2632
|
+
}, [initialBill, attachments, sourceClaimsAdministratorName]);
|
|
2579
2633
|
useEffect5(() => {
|
|
2580
2634
|
if (!validationActive) return;
|
|
2581
2635
|
const next = validateBillSubmission(bill).fieldErrors;
|
|
@@ -2649,33 +2703,50 @@ function BillSubmissionForm({
|
|
|
2649
2703
|
return next;
|
|
2650
2704
|
})) }));
|
|
2651
2705
|
const text = (value, onChange, options = {}) => /* @__PURE__ */ jsx5("input", { className: "mbsf-input", disabled: locked, value: value ?? "", onChange: (event) => onChange(event.target.value), ...options });
|
|
2652
|
-
const
|
|
2706
|
+
const loadPayers = useCallback((query, append = false) => {
|
|
2653
2707
|
const trimmed = query.trim();
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2708
|
+
const list2 = onListClaimsAdministrators ?? referenceClient?.listClaimsAdministrators;
|
|
2709
|
+
const legacySearch = onSearchClaimsAdministrators ?? referenceClient?.searchClaimsAdministrators;
|
|
2710
|
+
if (!list2 && !legacySearch) return;
|
|
2711
|
+
const continuing = append && payerQuery === trimmed;
|
|
2712
|
+
if (continuing && (!payerHasMore || payerAppendPending.current)) return;
|
|
2713
|
+
const offset = continuing ? payerResults.length : 0;
|
|
2660
2714
|
const request = ++payerRequest.current;
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2715
|
+
if (continuing) {
|
|
2716
|
+
payerAppendPending.current = true;
|
|
2717
|
+
setPayerLoadingMore(true);
|
|
2718
|
+
} else {
|
|
2719
|
+
setPayerLoading(true);
|
|
2720
|
+
setPayerLoadingMore(false);
|
|
2721
|
+
setPayerQuery(trimmed);
|
|
2722
|
+
setPayerHasMore(true);
|
|
2723
|
+
}
|
|
2724
|
+
const page = list2 ? list2({ query: trimmed, claimNumber: bill.claim.claimNumber, ...sourceClaimsAdministratorName ? { sourceClaimsAdministratorName } : {}, ...bill.claim.employer ? { employerName: bill.claim.employer } : {}, limit: PAYER_PAGE_SIZE, offset }) : legacySearch(trimmed, bill.claim.claimNumber).then((results) => ({ results, total: results.length }));
|
|
2725
|
+
void page.then((result) => {
|
|
2664
2726
|
if (request !== payerRequest.current) return;
|
|
2665
|
-
setPayerResults(
|
|
2666
|
-
|
|
2727
|
+
setPayerResults((current) => {
|
|
2728
|
+
const combined = continuing ? [...current, ...result.results] : result.results;
|
|
2729
|
+
return [...new Map(combined.map((payer) => [payer.id, payer])).values()];
|
|
2730
|
+
});
|
|
2731
|
+
if (!continuing) setPayerSuggestions(result.suggestions ?? []);
|
|
2732
|
+
setPayerHasMore(result.nextOffset != null ? result.nextOffset > offset : offset + result.results.length < result.total);
|
|
2733
|
+
}).catch((caught) => {
|
|
2667
2734
|
if (request === payerRequest.current) setFormError(caught instanceof Error ? caught.message : "Claims administrator search is unavailable.");
|
|
2668
|
-
}
|
|
2669
|
-
if (request
|
|
2670
|
-
|
|
2671
|
-
|
|
2735
|
+
}).finally(() => {
|
|
2736
|
+
if (request !== payerRequest.current) return;
|
|
2737
|
+
payerAppendPending.current = false;
|
|
2738
|
+
setPayerLoading(false);
|
|
2739
|
+
setPayerLoadingMore(false);
|
|
2740
|
+
});
|
|
2741
|
+
}, [bill.claim.claimNumber, bill.claim.employer, onListClaimsAdministrators, onSearchClaimsAdministrators, payerHasMore, payerQuery, payerResults.length, referenceClient, sourceClaimsAdministratorName]);
|
|
2672
2742
|
const searchPayers = (query) => {
|
|
2743
|
+
setSelectedPayerMetadata(null);
|
|
2673
2744
|
setBill((current) => {
|
|
2674
2745
|
const selected = current.claim.claimsAdministrator;
|
|
2675
2746
|
if (selected?.id && selected.name === query) return current;
|
|
2676
2747
|
return { ...current, claim: { ...current.claim, claimsAdministrator: { name: query } } };
|
|
2677
2748
|
});
|
|
2678
|
-
|
|
2749
|
+
loadPayers(query);
|
|
2679
2750
|
};
|
|
2680
2751
|
const loadDiagnoses = (query, append = false) => {
|
|
2681
2752
|
const trimmed = query.trim();
|
|
@@ -2817,8 +2888,19 @@ function BillSubmissionForm({
|
|
|
2817
2888
|
}
|
|
2818
2889
|
}
|
|
2819
2890
|
const claimsAdministratorError = errors["claim.claimsAdministrator"];
|
|
2820
|
-
const choosePayer = (payer
|
|
2891
|
+
const choosePayer = (payer, selectedPayerId) => {
|
|
2892
|
+
setSelectedPayerMetadata(payer);
|
|
2893
|
+
setBill((current) => ({ ...current, claim: { ...current.claim, claimsAdministrator: chooseClaimsAdministrator(payer, selectedPayerId) } }));
|
|
2894
|
+
};
|
|
2821
2895
|
const administrator = bill.claim.claimsAdministrator;
|
|
2896
|
+
const displayedPayerMetadata = selectedPayerMetadata?.id === administrator?.id ? selectedPayerMetadata : null;
|
|
2897
|
+
const displayedClaimPatterns = (displayedPayerMetadata?.claimNumberPatterns ?? []).map((pattern) => ({
|
|
2898
|
+
...pattern,
|
|
2899
|
+
matches: claimNumberPatternMatches(pattern, bill.claim.claimNumber)
|
|
2900
|
+
}));
|
|
2901
|
+
const evaluatedClaimPatterns = displayedClaimPatterns.filter((pattern) => pattern.matches != null);
|
|
2902
|
+
const claimNumberMatches = evaluatedClaimPatterns.some((pattern) => pattern.matches);
|
|
2903
|
+
const claimNumberPatternState = evaluatedClaimPatterns.length ? claimNumberMatches ? "match" : "warning" : null;
|
|
2822
2904
|
const subpayorOptions = administrator?.payerSelectionRequired ? administrator.payers ?? [] : [];
|
|
2823
2905
|
const subpayorError = errors["claim.claimsAdministrator.payerId"];
|
|
2824
2906
|
const selectedSubpayor = subpayorOptions.find((option) => option.id === administrator?.payerId);
|
|
@@ -2876,14 +2958,40 @@ function BillSubmissionForm({
|
|
|
2876
2958
|
] }),
|
|
2877
2959
|
/* @__PURE__ */ jsx5(Field2, { path: "claim.dateOfInjury", label: "Date of injury", required: true, error: errors["claim.dateOfInjury"], children: /* @__PURE__ */ jsx5(TextDateInput, { ariaLabel: "Date of injury", value: bill.claim.dateOfInjury, disabled: locked, required: true, onChange: (dateOfInjury) => setBill((c) => ({ ...c, claim: { ...c.claim, dateOfInjury } })) }) }),
|
|
2878
2960
|
/* @__PURE__ */ jsx5(Field2, { path: "claim.employer", label: "Employer name", required: true, error: errors["claim.employer"], children: text(bill.claim.employer, (employer) => setBill((c) => ({ ...c, claim: { ...c.claim, employer } }))) }),
|
|
2879
|
-
/* @__PURE__ */
|
|
2961
|
+
/* @__PURE__ */ jsxs5(Field2, { path: "claim.claimNumber", label: "Claim number", required: true, error: errors["claim.claimNumber"], children: [
|
|
2962
|
+
text(bill.claim.claimNumber, (claimNumber) => setBill((c) => ({ ...c, claim: { ...c.claim, claimNumber } }))),
|
|
2963
|
+
displayedClaimPatterns.length ? /* @__PURE__ */ jsxs5("div", { className: "mbsf-claim-patterns", "data-state": claimNumberPatternState ?? void 0, role: "status", children: [
|
|
2964
|
+
claimNumberPatternState === "match" ? /* @__PURE__ */ jsx5("strong", { children: "\u2713 Matches a known claim number pattern" }) : claimNumberPatternState === "warning" ? /* @__PURE__ */ jsx5("strong", { children: "\u26A0 Does not match the known claim number patterns" }) : /* @__PURE__ */ jsx5("strong", { children: "Known claim number patterns" }),
|
|
2965
|
+
/* @__PURE__ */ jsx5("span", { className: "mbsf-claim-pattern-list", children: displayedClaimPatterns.map((pattern) => `${pattern.pattern}${pattern.example ? ` (example: ${pattern.example})` : ""}`).join(" \xB7 ") })
|
|
2966
|
+
] }) : null
|
|
2967
|
+
] }),
|
|
2880
2968
|
/* @__PURE__ */ jsx5(Field2, { label: "WCAB / ADJ number (optional)", children: text(bill.claim.adjNumber, (adjNumber) => setBill((c) => ({ ...c, claim: { ...c.claim, adjNumber } }))) }),
|
|
2881
2969
|
/* @__PURE__ */ jsxs5(Field2, { path: "claim.claimsAdministrator", label: "Claims administrator", required: true, span: true, error: claimsAdministratorError, invalid: !administrator?.id, children: [
|
|
2882
|
-
/* @__PURE__ */ jsx5(ComboBox, { ariaLabel: "Claims administrator", invalid: Boolean(claimsAdministratorError) || !administrator?.id, disabled: locked, loading: payerLoading,
|
|
2970
|
+
/* @__PURE__ */ jsx5(ComboBox, { ariaLabel: "Claims administrator", invalid: Boolean(claimsAdministratorError) || !administrator?.id, disabled: locked, loading: payerLoading, loadingMore: payerLoadingMore, filterOptions: false, value: administrator?.name ?? "", placeholder: "Browse or search claims administrators\u2026", options: payerResults.map((payer) => {
|
|
2971
|
+
const patternDetail = payer.claimNumberPatterns?.map((pattern) => `${pattern.pattern}${pattern.example ? ` (example: ${pattern.example})` : ""}`).join(" \xB7 ") ?? payer.claimNumberHint ?? "";
|
|
2972
|
+
return { id: payer.id, label: payer.name, detail: [payer.aliases?.length ? `Also known as ${payer.aliases.join(", ")}` : "", patternDetail].filter(Boolean).join(" \xB7 ") || "Claims administrator", ...payer.affiliatedEntities?.length ? { affiliatedEntities: payer.affiliatedEntities } : {}, ...payer.route ? { trailing: payer.route } : {} };
|
|
2973
|
+
}), onOpen: () => {
|
|
2974
|
+
if (payerQuery !== "") loadPayers("");
|
|
2975
|
+
}, onQuery: searchPayers, onEndReached: () => loadPayers(payerQuery ?? "", true), onSelect: (option) => choosePayer(payerResults.find((payer) => payer.id === option.id) ?? { id: option.id, name: option.label }) }),
|
|
2976
|
+
orderedClaimsAdministratorSources.length ? /* @__PURE__ */ jsx5("div", { className: "mbsf-source-evidence", children: orderedClaimsAdministratorSources.map((source, index) => /* @__PURE__ */ jsxs5("span", { children: [
|
|
2977
|
+
source.url ? /* @__PURE__ */ jsx5("a", { href: source.url, target: "_blank", rel: "noopener noreferrer", children: source.label }) : /* @__PURE__ */ jsx5("strong", { children: source.label }),
|
|
2978
|
+
": ",
|
|
2979
|
+
/* @__PURE__ */ jsx5("q", { children: source.name })
|
|
2980
|
+
] }, `${source.source}-${source.name}-${index}`)) }) : null,
|
|
2883
2981
|
claimsAdministratorHint ? /* @__PURE__ */ jsxs5("small", { className: "mbsf-help", children: [
|
|
2884
2982
|
"Claims administrator in your system: ",
|
|
2885
2983
|
claimsAdministratorHint
|
|
2886
2984
|
] }) : null,
|
|
2985
|
+
payerSuggestions.length ? /* @__PURE__ */ jsxs5("div", { className: "mbsf-suggestions", children: [
|
|
2986
|
+
/* @__PURE__ */ jsx5("strong", { children: "Suggested:" }),
|
|
2987
|
+
payerSuggestions.slice(0, 5).map((suggestion) => {
|
|
2988
|
+
const suggestedSubpayor = suggestion.payers?.find((option) => option.id === suggestion.selectedPayerId);
|
|
2989
|
+
return /* @__PURE__ */ jsxs5("button", { className: "mbsf-suggestion", type: "button", title: suggestion.reason, onClick: () => choosePayer(suggestion, suggestion.selectedPayerId), children: [
|
|
2990
|
+
suggestion.name,
|
|
2991
|
+
suggestedSubpayor ? ` \xB7 ${suggestedSubpayor.label}` : ""
|
|
2992
|
+
] }, `${suggestion.id}-${suggestion.selectedPayerId ?? "admin"}`);
|
|
2993
|
+
})
|
|
2994
|
+
] }) : null,
|
|
2887
2995
|
administrator?.id ? /* @__PURE__ */ jsxs5("button", { className: "mbsf-directory-link", type: "button", onClick: () => {
|
|
2888
2996
|
void openAdministratorDirectory();
|
|
2889
2997
|
}, children: [
|
|
@@ -2891,16 +2999,27 @@ function BillSubmissionForm({
|
|
|
2891
2999
|
administrator.name
|
|
2892
3000
|
] }) : /* @__PURE__ */ jsx5("small", { className: "mbsf-help", children: "Search the directory and choose a claims administrator." })
|
|
2893
3001
|
] }),
|
|
2894
|
-
administrator?.payerSelectionRequired
|
|
2895
|
-
/* @__PURE__ */ jsx5(ComboBox, { ariaLabel: "Payer", invalid: Boolean(subpayorError), disabled: locked,
|
|
2896
|
-
const
|
|
2897
|
-
|
|
2898
|
-
|
|
3002
|
+
administrator?.payerSelectionRequired ? /* @__PURE__ */ jsxs5(Field2, { path: "claim.claimsAdministrator.payerId", label: "Payer", required: true, span: true, error: subpayorError, children: [
|
|
3003
|
+
subpayorOptions.length ? /* @__PURE__ */ jsx5(ComboBox, { ariaLabel: "Payer", invalid: Boolean(subpayorError), disabled: locked, value: selectedSubpayor?.label ?? "", placeholder: "Select the payer named on the claim or report\u2026", options: subpayorOptions.map((option) => {
|
|
3004
|
+
const identifiers = Object.entries(option.clearinghousePayerIds ?? {}).map(([name, id]) => `${name.replace(/_/g, " ")} ${id}`);
|
|
3005
|
+
const sourceRoute = option.sourceClearinghouse && option.sourcePayerId ? `Catalog: ${option.sourceClearinghouse} ${option.sourcePayerId}` : "";
|
|
3006
|
+
const detail = [option.aliases?.length ? `Also known as ${option.aliases.join(", ")}` : "", option.hint ?? "", sourceRoute].filter(Boolean).join(" \xB7 ");
|
|
3007
|
+
const badges = [option.optionType ? `Type: ${option.optionType}` : "", option.deliveryType ? `Delivery: ${option.deliveryType}` : "", option.clearinghouse && option.payerId ? `Delivered via ${option.clearinghouse} ${option.payerId}` : "", ...identifiers, option.preferredClearinghouse ? `Preferred: ${option.preferredClearinghouse}` : "", option.default ? "Directory default" : ""].filter(Boolean);
|
|
3008
|
+
return { id: option.id, label: option.label, ...detail ? { detail } : {}, ...badges.length ? { badges } : {}, ...option.affiliatedEntities?.length ? { affiliatedEntities: option.affiliatedEntities } : {}, ...option.route ? { trailing: option.route } : {} };
|
|
3009
|
+
}), onSelect: (option) => chooseSubpayor(option.id) }) : /* @__PURE__ */ jsxs5("div", { className: "mbsf-error", role: "alert", children: [
|
|
3010
|
+
"No routing payers are available for ",
|
|
3011
|
+
administrator.name,
|
|
3012
|
+
". Electronic submission remains blocked; contact support to correct the payer directory."
|
|
3013
|
+
] }),
|
|
2899
3014
|
selectedSubpayor ? /* @__PURE__ */ jsxs5("div", { className: "mbsf-payer-status", role: "status", children: [
|
|
2900
3015
|
/* @__PURE__ */ jsx5("strong", { children: "\u2713 Payer set:" }),
|
|
2901
3016
|
" ",
|
|
2902
|
-
selectedSubpayor.label
|
|
2903
|
-
|
|
3017
|
+
selectedSubpayor.label,
|
|
3018
|
+
selectedSubpayor.route ? ` \xB7 ${selectedSubpayor.route}` : ""
|
|
3019
|
+
] }) : /* @__PURE__ */ jsxs5("small", { className: "mbsf-help", children: [
|
|
3020
|
+
administrator.name,
|
|
3021
|
+
" administers multiple payers. Choose the payer named on the claim or report so MindBill can route the bill correctly."
|
|
3022
|
+
] })
|
|
2904
3023
|
] }) : null,
|
|
2905
3024
|
/* @__PURE__ */ jsx5(Field2, { label: "Injury description (optional)", span: true, children: text(bill.claim.description, (description2) => setBill((c) => ({ ...c, claim: { ...c.claim, description: description2 } }))) }),
|
|
2906
3025
|
/* @__PURE__ */ jsxs5(Field2, { path: "diagnoses", label: "Diagnosis codes (ICD-10)", required: true, span: true, error: errors.diagnoses, children: [
|
|
@@ -5404,7 +5523,7 @@ function sandboxScenarios(state) {
|
|
|
5404
5523
|
function shouldShowSandboxControls(environment, enabled = false) {
|
|
5405
5524
|
return enabled && environment === "sandbox";
|
|
5406
5525
|
}
|
|
5407
|
-
function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint, sandboxControls = false, className, style, loadingFallback, errorFallback, onChanged, ...options }) {
|
|
5526
|
+
function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint, claimsAdministratorSources, sandboxControls = false, className, style, loadingFallback, errorFallback, onChanged, ...options }) {
|
|
5408
5527
|
const lifecycle = useBillLifecycle(options);
|
|
5409
5528
|
const { data } = lifecycle;
|
|
5410
5529
|
const [tab, setTab] = useState11("details");
|
|
@@ -5625,6 +5744,7 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5625
5744
|
onSearchClaimsAdministrators: lifecycle.searchClaimsAdministrators,
|
|
5626
5745
|
onGetClaimsAdministratorDirectory: lifecycle.getClaimsAdministratorDirectory,
|
|
5627
5746
|
claimsAdministratorHint,
|
|
5747
|
+
...claimsAdministratorSources ? { claimsAdministratorSources } : {},
|
|
5628
5748
|
attentionFields: correctionAttentionFields,
|
|
5629
5749
|
attentionMessage: correctionAttentionFields.length ? "The rejected response points to the highlighted fields. Confirm every required value before resubmitting." : "Confirm the bill information below before resubmitting.",
|
|
5630
5750
|
submitLabel: lifecycle.isMutating ? "Resubmitting\u2026" : "Resubmit bill",
|
|
@@ -5661,6 +5781,7 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5661
5781
|
onSearchClaimsAdministrators: lifecycle.searchClaimsAdministrators,
|
|
5662
5782
|
onGetClaimsAdministratorDirectory: lifecycle.getClaimsAdministratorDirectory,
|
|
5663
5783
|
claimsAdministratorHint,
|
|
5784
|
+
...claimsAdministratorSources ? { claimsAdministratorSources } : {},
|
|
5664
5785
|
attentionMessage: "Confirm every value carried over from the closed bill before submitting the new bill.",
|
|
5665
5786
|
submitLabel: lifecycle.isMutating ? "Submitting\u2026" : "Submit New Bill",
|
|
5666
5787
|
heading: "New bill information",
|