@mindbill/react 0.77.46 → 0.77.47

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.js CHANGED
@@ -10519,6 +10519,7 @@ function TreatmentDraftShell({ title, description, children, hideHeading = false
10519
10519
  .mbtd .mbrfa-template-save{display:grid;grid-template-columns:minmax(0,420px);gap:10px 16px;margin-top:10px}.mbtd .mbrfa-template-save>label{display:grid;gap:4px;font-size:12px;color:var(--mb-muted)}.mbtd .mbrfa-template-save>.mbrfa-check{display:flex;flex-direction:row;align-items:center;gap:8px;cursor:pointer}.mbtd .mbrfa-template-save>.mbrfa-check>input{width:16px;height:16px;min-height:16px;margin:0;padding:0;flex:0 0 16px;accent-color:var(--mb-accent)}.mbtd .mbrfa-template-save>:is(.mbrfa-check,.mbrfa-section-actions){grid-column:1/-1;margin-top:0;padding-top:0;border-top:0}
10520
10520
  @media(max-width:760px){.mbtd .mbrfa-template-save{grid-template-columns:minmax(0,1fr)}}
10521
10521
  .mbtd .mbrfa-form-grid>.mbrfa-row-start{grid-column:1/span 3}.mbtd .mbrfa-form-grid textarea[rows="2"]{min-height:44px}
10522
+ .mbtd .mbrfa-dx-list{list-style:none;margin:0 0 8px;padding:0;display:grid;gap:6px}.mbtd .mbrfa-dx-list>li{display:flex;align-items:center;gap:10px;min-height:36px;padding:4px 6px 4px 12px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:color-mix(in srgb,var(--mb-accent) 5%,var(--mb-surface));font-size:13px}.mbtd .mbrfa-dx-list>li>strong{font-weight:600;white-space:nowrap}.mbtd .mbrfa-dx-list>li>span{flex:1;min-width:0;color:var(--mb-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mbtd .mbrfa-dx-list>li>input{flex:1;min-width:0;min-height:30px;padding:4px 8px}.mbtd .mbrfa-dx-list>li>button{flex:none;width:28px;height:28px;min-height:28px;padding:0;border:0;background:none;color:var(--mb-muted);font-size:18px;line-height:1;cursor:pointer}.mbtd .mbrfa-dx-list>li>button:hover{color:var(--mb-danger,#b42318)}
10522
10523
  .mbtd .mbrfa-doc-hint{margin:0 0 12px;font-size:12px;color:var(--mb-muted)}
10523
10524
  .mbtd .mbrfa-treatments{display:grid;gap:14px}.mbtd .mbrfa-treatment+.mbrfa-treatment{padding-top:16px;border-top:1px solid var(--mb-border)}
10524
10525
  .mbtd .mbrfa-treatment-head{display:flex;align-items:center;gap:14px;margin-bottom:10px;font-size:13px}.mbtd .mbrfa-treatment-head>strong{font-weight:600;margin-right:auto}.mbtd button.mbrfa-link.mbrfa-link.mbrfa-treatment-remove{color:var(--mb-danger,#b42318)}
@@ -12806,7 +12807,6 @@ function RfaDiagnosisFields({ code, description, onChange, search, officialForm
12806
12807
  const [query, setQuery] = useState24("");
12807
12808
  const [results, setResults] = useState24([]);
12808
12809
  const [error, setError] = useState24("");
12809
- const [manualDiagnosis, setManualDiagnosis] = useState24(false);
12810
12810
  const [searching, setSearching] = useState24(false);
12811
12811
  useEffect21(() => {
12812
12812
  let active = true;
@@ -12845,64 +12845,64 @@ function RfaDiagnosisFields({ code, description, onChange, search, officialForm
12845
12845
  clearTimeout(timer);
12846
12846
  };
12847
12847
  }, [query, search]);
12848
+ const codes2 = code.split(",").map((part) => part.trim()).filter(Boolean);
12849
+ const parts = (description ?? "").split(";").map((part) => part.trim());
12850
+ const descriptions2 = codes2.map((_, index) => parts.length === codes2.length ? parts[index] : codes2.length === 1 ? (description ?? "").trim() : "");
12851
+ const emit = (nextCodes, nextDescriptions) => onChange({
12852
+ diagnosisCode: nextCodes.join(", "),
12853
+ diagnosisDescription: nextDescriptions.some(Boolean) ? nextDescriptions.map((text3) => text3.replace(/;/g, ",").trim()).join("; ") : ""
12854
+ });
12848
12855
  const resolved = useRef19(/* @__PURE__ */ new Set());
12849
- const [resolving, setResolving] = useState24(false);
12856
+ const [resolving, setResolving] = useState24("");
12857
+ const pending = officialForm && search ? codes2.find((item, index) => !descriptions2[index] && !resolved.current.has(item)) ?? "" : "";
12858
+ const latest = useRef19({ codes: codes2, descriptions: descriptions2, emit });
12859
+ latest.current = { codes: codes2, descriptions: descriptions2, emit };
12850
12860
  useEffect21(() => {
12851
- if (!officialForm || !search || !code || description || manualDiagnosis || resolved.current.has(code)) return;
12852
- resolved.current.add(code);
12861
+ if (!pending || !search) return;
12862
+ resolved.current.add(pending);
12853
12863
  let active = true;
12854
- setResolving(true);
12855
- void search(code).then((items) => {
12856
- const match = items.find((item) => item.code.replace(".", "").toUpperCase() === code.replace(".", "").toUpperCase());
12857
- if (active && match) onChange({ diagnosisCode: match.code, diagnosisDescription: match.description });
12864
+ setResolving(pending);
12865
+ const same = (left, right) => left.replace(".", "").toUpperCase() === right.replace(".", "").toUpperCase();
12866
+ void search(pending).then((items) => {
12867
+ const match = items.find((item) => same(item.code, pending));
12868
+ if (!active || !match) return;
12869
+ const now = latest.current, at = now.codes.indexOf(pending);
12870
+ if (at < 0) return;
12871
+ now.emit(now.codes.map((item, index) => index === at ? match.code : item), now.descriptions.map((text3, index) => index === at ? match.description : text3));
12858
12872
  }).catch(() => void 0).finally(() => {
12859
- if (active) setResolving(false);
12873
+ if (active) setResolving("");
12860
12874
  });
12861
12875
  return () => {
12862
12876
  active = false;
12863
12877
  };
12864
- }, [code, description, search, officialForm, manualDiagnosis]);
12878
+ }, [pending, search]);
12865
12879
  if (officialForm && search) {
12866
12880
  const typed = query.trim().toUpperCase(), known = results.some((item) => item.code.toUpperCase() === typed);
12881
+ const chosen = (value) => codes2.includes(value);
12867
12882
  const options = [
12868
- ...code && !typed && !results.some((item) => item.code === code) ? [{ id: code, label: code, ...description ? { detail: description } : {} }] : [],
12869
- ...!typed ? savedCodes.filter((saved) => saved && saved !== code).map((saved) => ({ id: `saved:${saved}`, label: saved, detail: "Saved on this injury" })) : [],
12870
- ...results.map((item) => ({ id: item.code, label: item.code, detail: item.description })),
12871
- .../^[A-Z]\d[0-9A-Z](\.?[0-9A-Z]{1,4})?$/.test(typed) && !known && typed !== code ? [{ id: `entered:${typed}`, label: `Use ${typed}`, detail: "Enter the diagnosis yourself" }] : []
12883
+ ...!typed ? savedCodes.filter((saved) => saved && !chosen(saved)).map((saved) => ({ id: `saved:${saved}`, label: saved, detail: "Saved on this injury" })) : [],
12884
+ ...results.filter((item) => !chosen(item.code)).map((item) => ({ id: item.code, label: item.code, detail: item.description })),
12885
+ .../^[A-Z]\d[0-9A-Z](\.?[0-9A-Z]{1,4})?$/.test(typed) && !known && !chosen(typed) ? [{ id: `entered:${typed}`, label: `Use ${typed}`, detail: "Enter the diagnosis yourself" }] : []
12872
12886
  ];
12873
- const listed = results.find((item) => item.code === code);
12874
- return /* @__PURE__ */ jsxs37(Fragment22, { children: [
12875
- /* @__PURE__ */ jsx39("div", { className: "mbrfa-s3", children: /* @__PURE__ */ jsx39(RfaPicker, { required: true, label: "ICD-10 Code", children: /* @__PURE__ */ jsx39(
12876
- RfaIdentitySelect,
12877
- {
12878
- label: "ICD-10 Code",
12879
- placeholder: "Enter code",
12880
- searchPlaceholder: "Search by code or diagnosis",
12881
- query,
12882
- onSearch: setQuery,
12883
- searchable: true,
12884
- value: code,
12885
- current: code ? { id: code, label: code, ...description ? { detail: description } : {} } : void 0,
12886
- options,
12887
- error,
12888
- loading: searching && !results.length,
12889
- onSelect: (value) => {
12890
- const item = results.find((item2) => item2.code === value);
12891
- if (item) onChange({ diagnosisCode: item.code, diagnosisDescription: item.description });
12892
- else if (value.startsWith("entered:")) onChange({ diagnosisCode: value.slice(8), diagnosisDescription: "" });
12893
- else if (value.startsWith("saved:")) onChange({ diagnosisCode: value.slice(6), diagnosisDescription: "" });
12894
- setQuery("");
12895
- }
12896
- }
12897
- ) }) }),
12898
- code && !listed && !resolving && (manualDiagnosis || !description) ? /* @__PURE__ */ jsxs37("label", { className: "mbrfa-s3", children: [
12899
- /* @__PURE__ */ jsxs37("span", { children: [
12900
- "Diagnosis",
12901
- /* @__PURE__ */ jsx39(RfaRequired, {})
12902
- ] }),
12903
- /* @__PURE__ */ jsx39("input", { required: true, autoFocus: manualDiagnosis, maxLength: 1e3, placeholder: "Diagnosis for this code", value: description ?? "", onFocus: () => setManualDiagnosis(true), onChange: (event) => onChange({ diagnosisCode: code, diagnosisDescription: event.target.value }) })
12904
- ] }) : null
12905
- ] });
12887
+ const add = (value) => {
12888
+ const item = results.find((item2) => item2.code === value);
12889
+ if (item) emit([...codes2, item.code], [...descriptions2, item.description]);
12890
+ else if (value.startsWith("entered:")) {
12891
+ resolved.current.add(value.slice(8));
12892
+ emit([...codes2, value.slice(8)], [...descriptions2, ""]);
12893
+ } else if (value.startsWith("saved:")) emit([...codes2, value.slice(6)], [...descriptions2, ""]);
12894
+ setQuery("");
12895
+ };
12896
+ return /* @__PURE__ */ jsx39("div", { className: "mbrfa-s6", children: /* @__PURE__ */ jsxs37(RfaPicker, { required: true, label: "ICD-10 Code", children: [
12897
+ codes2.length ? /* @__PURE__ */ jsx39("ul", { className: "mbrfa-dx-list", "aria-label": "Selected ICD-10 codes", children: codes2.map((item, index) => /* @__PURE__ */ jsxs37("li", { children: [
12898
+ /* @__PURE__ */ jsx39("strong", { children: item }),
12899
+ 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) => {
12900
+ if (event.target.value.trim()) emit(codes2, descriptions2.map((text3, position) => position === index ? event.target.value : text3));
12901
+ } }),
12902
+ /* @__PURE__ */ jsx39("button", { type: "button", "aria-label": `Remove ${item}`, onClick: () => emit(codes2.filter((_, position) => position !== index), descriptions2.filter((_, position) => position !== index)), children: "\xD7" })
12903
+ ] }, item)) }) : null,
12904
+ codes2.length < 12 ? /* @__PURE__ */ jsx39(RfaIdentitySelect, { label: "ICD-10 Code", placeholder: codes2.length ? "Add another ICD-10 code" : "Enter code", searchPlaceholder: "Search by code or diagnosis", query, onSearch: setQuery, searchable: true, loading: searching && !options.length, error, value: "", options, onSelect: add }) : null
12905
+ ] }) });
12906
12906
  }
12907
12907
  if (officialForm) return /* @__PURE__ */ jsxs37(Fragment22, { children: [
12908
12908
  /* @__PURE__ */ jsxs37("label", { className: "mbrfa-s2", children: [
@@ -13288,7 +13288,7 @@ function validateRfaDraft(draft2) {
13288
13288
  if ((item.diagnosisDescription?.length ?? 0) > 1e3) return "Diagnosis descriptions must be at most 1,000 characters.";
13289
13289
  const prefix = `Service ${index + 1}: `;
13290
13290
  if (item.metadata?.otherInformation !== void 0 && (typeof item.metadata.otherInformation !== "string" || item.metadata.otherInformation.length > 2e3)) return prefix + "Other Information must be text up to 2,000 characters.";
13291
- if (!item.diagnosisCode.trim() || item.diagnosisCode.length > 16 || !item.serviceDescription.trim() || item.serviceDescription.length > 1e3) return prefix + "a diagnosis code and service description are required.";
13291
+ if (!item.diagnosisCode.trim() || item.diagnosisCode.length > 200 || !item.serviceDescription.trim() || item.serviceDescription.length > 1e3) return prefix + "a diagnosis code and service description are required.";
13292
13292
  for (const [value, max] of [[item.externalId, 255], [item.procedureCode, 16], [item.frequency, 200], [item.duration, 200]]) if (value !== void 0 && (!value.trim() || value.length > max)) return prefix + `optional text must contain 1 to ${max} characters.`;
13293
13293
  if (item.units !== void 0 && (!Number.isInteger(item.units) || item.units < 1 || item.units > 1e5)) return prefix + "units must be a whole number between 1 and 100,000.";
13294
13294
  if (item.quantity !== void 0 && (!Number.isFinite(item.quantity) || item.quantity <= 0 || item.quantity > 1e5)) return prefix + "quantity must be positive and at most 100,000.";
@@ -13348,7 +13348,7 @@ function RfaDraftForm({ initialDraft, identity, officialForm = false, formDetail
13348
13348
  useEffect23(() => {
13349
13349
  if (previousClaim.current !== identityKey) {
13350
13350
  setAdministratorOverride(null);
13351
- setDraft((current) => ({ ...current, authorizationContact: null, ...officialForm ? { items: [{ diagnosisCode: savedDiagnosisCodes[0] ?? "", serviceDescription: "" }] } : {} }));
13351
+ setDraft((current) => ({ ...current, authorizationContact: null, ...officialForm ? { items: [{ diagnosisCode: savedDiagnosisCodes.slice(0, 12).join(", "), serviceDescription: "" }] } : {} }));
13352
13352
  previousClaim.current = identityKey;
13353
13353
  }
13354
13354
  }, [identityKey]);
@@ -13993,7 +13993,7 @@ function SavedIdentityForm({ client, claimId, renderingProviderId, onSave, canCr
13993
13993
  ...appearance,
13994
13994
  ...draftFormProps,
13995
13995
  disabled: official ? disabled || addingClaim : disabled || loading || addingClaim || !claim || !provider || !!error,
13996
- initialDraft: { claimId: "", patientId: "", renderingProviderId: "", employeeName: "", providerName: "", requestType: "new", reviewType: "prospective", items: [{ diagnosisCode: claim?.diagnosisCodes?.[0] ?? "", serviceDescription: "" }] },
13996
+ initialDraft: { claimId: "", patientId: "", renderingProviderId: "", employeeName: "", providerName: "", requestType: "new", reviewType: "prospective", items: [{ diagnosisCode: (draftFormProps?.officialForm ? claim?.diagnosisCodes?.slice(0, 12).join(", ") : claim?.diagnosisCodes?.[0]) ?? "", serviceDescription: "" }] },
13997
13997
  ...official ? { formDetails, selectors: { claim: /* @__PURE__ */ jsx44("fieldset", { className: "mbrfa-plain", disabled, children: renderClaimSelector ? claimFields : /* @__PURE__ */ jsx44(RfaPicker, { label: "Patient and claim", children: claimFields }) }), physician: /* @__PURE__ */ jsx44("fieldset", { className: "mbrfa-plain", disabled, children: providerFields }) } } : {},
13998
13998
  identity,
13999
13999
  supportingDocuments,