@eka-care/medical-records-ui 1.0.21 → 1.0.23

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.mjs CHANGED
@@ -329,12 +329,20 @@ var SdkContext = createContext(null);
329
329
 
330
330
  // src/helpers/documentTypeLabels.ts
331
331
  var STATIC_LABELS = DOCUMENT_TYPE_LABELS ?? {};
332
- function createDocumentTypeLabelResolver(types) {
332
+ function toTitleCase(code) {
333
+ return code.replace(/[_\-]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
334
+ }
335
+ function createDocumentTypeLabelResolver(types, onUnknownDocumentType) {
333
336
  const fromConfig = /* @__PURE__ */ new Map();
334
337
  for (const t of types ?? []) {
335
338
  if (t.id && t.display_name) fromConfig.set(t.id, t.display_name);
336
339
  }
337
- return (code) => fromConfig.get(code) ?? STATIC_LABELS[code] ?? "Other";
340
+ return (code) => {
341
+ const label = fromConfig.get(code) ?? STATIC_LABELS[code];
342
+ if (label) return label;
343
+ onUnknownDocumentType?.(code);
344
+ return toTitleCase(code);
345
+ };
338
346
  }
339
347
 
340
348
  // src/components/icons/EmptyRecordsIcon.tsx
@@ -514,7 +522,7 @@ function RecordsPlaceholder() {
514
522
  /* @__PURE__ */ jsx2("p", { className: "mr-records-view__empty-desc", children: "Browse and attach the patient's medical records here." })
515
523
  ] });
516
524
  }
517
- function SdkProviderInner({ config, bid, patientId, documentTypes, children }) {
525
+ function SdkProviderInner({ config, bid, patientId, documentTypes, onUnknownDocumentType, children }) {
518
526
  initWorkerClient(config, patientId);
519
527
  useEffect(() => {
520
528
  setAuthToken(config.accessToken);
@@ -529,8 +537,8 @@ function SdkProviderInner({ config, bid, patientId, documentTypes, children }) {
529
537
  return () => window.removeEventListener("online", handleOnline);
530
538
  }, []);
531
539
  const labelOf = useMemo(
532
- () => createDocumentTypeLabelResolver(documentTypes),
533
- [documentTypes]
540
+ () => createDocumentTypeLabelResolver(documentTypes, onUnknownDocumentType),
541
+ [documentTypes, onUnknownDocumentType]
534
542
  );
535
543
  const docTypes = useMemo(
536
544
  () => documentTypes ?? Object.entries(DOCUMENT_TYPE_LABELS).map(([id, display_name]) => ({ id, display_name })),
@@ -542,9 +550,9 @@ function SdkProviderInner({ config, bid, patientId, documentTypes, children }) {
542
550
  );
543
551
  return /* @__PURE__ */ jsx2(SdkContext.Provider, { value, children });
544
552
  }
545
- function SdkProvider({ config, bid, patientId, documentTypes, children }) {
553
+ function SdkProvider({ config, bid, patientId, documentTypes, onUnknownDocumentType, children }) {
546
554
  if (!bid || !patientId) return /* @__PURE__ */ jsx2(RecordsPlaceholder, {});
547
- return /* @__PURE__ */ jsx2(SdkProviderInner, { config, bid, patientId, documentTypes, children });
555
+ return /* @__PURE__ */ jsx2(SdkProviderInner, { config, bid, patientId, documentTypes, onUnknownDocumentType, children });
548
556
  }
549
557
 
550
558
  // src/connection/useSdk.ts
@@ -719,7 +727,7 @@ function relativeTime(epochMs, now = Date.now()) {
719
727
  }
720
728
 
721
729
  // src/views/RecordsView/RecordsToolbar.tsx
722
- import { useCallback as useCallback5, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef8, useState as useState9 } from "react";
730
+ import { useCallback as useCallback5, useEffect as useEffect10, useMemo as useMemo6, useRef as useRef8, useState as useState8 } from "react";
723
731
  import { useStore as useStore7 } from "zustand";
724
732
  import {
725
733
  ChevronLeft,
@@ -798,7 +806,7 @@ function Tooltip({ content, children }) {
798
806
  }
799
807
 
800
808
  // src/views/RecordsView/FilterPopover.tsx
801
- import { useMemo as useMemo5, useState as useState8 } from "react";
809
+ import { useMemo as useMemo5, useState as useState7 } from "react";
802
810
  import { useStore as useStore6 } from "zustand";
803
811
 
804
812
  // src/components/PresetSelect/PresetSelect.tsx
@@ -1233,7 +1241,11 @@ function useRecordsConnection() {
1233
1241
  store.getState().records.setError(e instanceof Error ? e.message : "Failed to refresh");
1234
1242
  }
1235
1243
  }, [bid, patientId, store, applyItems]);
1236
- return { refresh, sourceRefreshedAt, editRecord, deleteRecord };
1244
+ const retry = useCallback(async () => {
1245
+ loadedKeyRef.current = null;
1246
+ await load();
1247
+ }, [load]);
1248
+ return { refresh, retry, sourceRefreshedAt, editRecord, deleteRecord };
1237
1249
  }
1238
1250
 
1239
1251
  // src/connection/useRecordDetail.ts
@@ -1526,28 +1538,6 @@ function useLogout() {
1526
1538
  }, []);
1527
1539
  }
1528
1540
 
1529
- // src/connection/useDenialList.ts
1530
- import { useEffect as useEffect10, useState as useState7 } from "react";
1531
- var HUB_URLS = {
1532
- prod: "https://hub.eka.care",
1533
- dev: "https://hub.dev.eka.care"
1534
- };
1535
- function useDenialList(environment) {
1536
- const [denialList, setDenialList] = useState7([]);
1537
- useEffect10(() => {
1538
- const controller = new AbortController();
1539
- const hubUrl = HUB_URLS[environment ?? "prod"] ?? HUB_URLS.prod;
1540
- const url = `${hubUrl}/onboarding/5/configuration/?config_keys=denial_list&format=json`;
1541
- fetch(url, { signal: controller.signal }).then((res) => res.json()).then((data) => {
1542
- const list = data?.denial_list;
1543
- if (Array.isArray(list)) setDenialList(list);
1544
- }).catch(() => {
1545
- });
1546
- return () => controller.abort();
1547
- }, [environment]);
1548
- return denialList;
1549
- }
1550
-
1551
1541
  // src/stores/selectors/recordsSelectors.ts
1552
1542
  import { useMemo as useMemo3 } from "react";
1553
1543
  import { useStore as useStore3 } from "zustand";
@@ -1599,15 +1589,8 @@ import { useMemo as useMemo4 } from "react";
1599
1589
  import { useStore as useStore5 } from "zustand";
1600
1590
 
1601
1591
  // src/helpers/recordFilter.ts
1602
- var OTHER_TYPE_SENTINEL = "__other__";
1603
- function recordMatchesFilters(r, filters, { skipType = false, labelOf } = {}) {
1604
- if (!skipType && filters.type) {
1605
- if (filters.type === OTHER_TYPE_SENTINEL) {
1606
- if (!labelOf || labelOf(r.typeCode) !== "Other") return false;
1607
- } else if (r.typeCode !== filters.type) {
1608
- return false;
1609
- }
1610
- }
1592
+ function recordMatchesFilters(r, filters, { skipType = false } = {}) {
1593
+ if (!skipType && filters.type && r.typeCode !== filters.type) return false;
1611
1594
  const search = filters.search.trim().toLowerCase();
1612
1595
  if (search && !r.title.toLowerCase().includes(search)) return false;
1613
1596
  if (filters.documentDateFrom != null && r.createdAtEpoch < filters.documentDateFrom) return false;
@@ -1622,14 +1605,14 @@ function recordMatchesFilters(r, filters, { skipType = false, labelOf } = {}) {
1622
1605
  }
1623
1606
 
1624
1607
  // src/stores/selectors/filteredSelectors.ts
1625
- function useFilteredRecordIds(store, labelOf) {
1608
+ function useFilteredRecordIds(store) {
1626
1609
  const ids = useStore5(store, (s) => s.records.ids);
1627
1610
  const byId = useStore5(store, (s) => s.records.byId);
1628
1611
  const filters = useStore5(store, (s) => s.filters);
1629
1612
  return useMemo4(() => {
1630
1613
  const filtered = ids.filter((id) => {
1631
1614
  const r = byId[id];
1632
- return r ? recordMatchesFilters(r, filters, { labelOf }) : false;
1615
+ return r ? recordMatchesFilters(r, filters) : false;
1633
1616
  });
1634
1617
  const dir = filters.sortDir === "asc" ? 1 : -1;
1635
1618
  const sorted = [...filtered].sort((a, b) => {
@@ -1674,8 +1657,7 @@ function useCasesStatus2() {
1674
1657
  return useCasesStatus(useSdk().store);
1675
1658
  }
1676
1659
  function useFilteredRecordIds2() {
1677
- const { store, labelOf } = useSdk();
1678
- return useFilteredRecordIds(store, labelOf);
1660
+ return useFilteredRecordIds(useSdk().store);
1679
1661
  }
1680
1662
 
1681
1663
  // src/views/RecordsView/FilterPopover.tsx
@@ -1717,31 +1699,16 @@ function FilterPopover({ onClose }) {
1717
1699
  const ids = useStore6(store, (s) => s.records.ids);
1718
1700
  const typeOptions = useMemo5(() => {
1719
1701
  const seen = /* @__PURE__ */ new Set();
1720
- let hasOther = false;
1721
- const options = [];
1722
- for (const id of ids) {
1723
- const code = byId[id]?.typeCode;
1724
- if (!code) continue;
1725
- const label = labelOf(code);
1726
- if (label === "Other") {
1727
- hasOther = true;
1728
- continue;
1729
- }
1730
- if (seen.has(code)) continue;
1731
- seen.add(code);
1732
- options.push({ value: code, label });
1733
- }
1734
- if (hasOther) options.push({ value: OTHER_TYPE_SENTINEL, label: "Other" });
1735
- return options;
1702
+ return ids.map((id) => byId[id]?.typeCode).filter((code) => !!code && !seen.has(code) && !!seen.add(code)).map((code) => ({ value: code, label: labelOf(code) }));
1736
1703
  }, [ids, byId, labelOf]);
1737
- const [docType, setDocType] = useState8(filters.type ?? "");
1738
- const [docPreset, setDocPreset] = useState8(filters.documentDatePreset);
1739
- const [docFrom, setDocFrom] = useState8(toInput(filters.documentDateFrom));
1740
- const [docTo, setDocTo] = useState8(toInput(filters.documentDateTo));
1741
- const [upPreset, setUpPreset] = useState8(filters.uploadDatePreset);
1742
- const [upFrom, setUpFrom] = useState8(toInput(filters.uploadDateFrom));
1743
- const [upTo, setUpTo] = useState8(toInput(filters.uploadDateTo));
1744
- const [tags, setTags] = useState8(filters.tags);
1704
+ const [docType, setDocType] = useState7(filters.type ?? "");
1705
+ const [docPreset, setDocPreset] = useState7(filters.documentDatePreset);
1706
+ const [docFrom, setDocFrom] = useState7(toInput(filters.documentDateFrom));
1707
+ const [docTo, setDocTo] = useState7(toInput(filters.documentDateTo));
1708
+ const [upPreset, setUpPreset] = useState7(filters.uploadDatePreset);
1709
+ const [upFrom, setUpFrom] = useState7(toInput(filters.uploadDateFrom));
1710
+ const [upTo, setUpTo] = useState7(toInput(filters.uploadDateTo));
1711
+ const [tags, setTags] = useState7(filters.tags);
1745
1712
  const handleClear = () => {
1746
1713
  setDocType("");
1747
1714
  setDocPreset("anytime");
@@ -1901,9 +1868,9 @@ function RecordsToolbar({
1901
1868
  return docDate + upDate + f.tags.length;
1902
1869
  });
1903
1870
  const scrollRef = useRef8(null);
1904
- const [filterOpen, setFilterOpen] = useState9(false);
1871
+ const [filterOpen, setFilterOpen] = useState8(false);
1905
1872
  const filterRef = useRef8(null);
1906
- useEffect11(() => {
1873
+ useEffect10(() => {
1907
1874
  if (!filterOpen) return;
1908
1875
  const onDown = (e) => {
1909
1876
  const t = e.target;
@@ -1913,9 +1880,9 @@ function RecordsToolbar({
1913
1880
  document.addEventListener("mousedown", onDown);
1914
1881
  return () => document.removeEventListener("mousedown", onDown);
1915
1882
  }, [filterOpen]);
1916
- const [isRefreshing, setIsRefreshing] = useState9(false);
1917
- const [, setNow] = useState9(0);
1918
- useEffect11(() => {
1883
+ const [isRefreshing, setIsRefreshing] = useState8(false);
1884
+ const [, setNow] = useState8(0);
1885
+ useEffect10(() => {
1919
1886
  const t = setInterval(() => setNow((n) => n + 1), 3e4);
1920
1887
  return () => clearInterval(t);
1921
1888
  }, []);
@@ -1934,15 +1901,14 @@ function RecordsToolbar({
1934
1901
  for (const id of ids) {
1935
1902
  const r = byId[id];
1936
1903
  if (!r) continue;
1937
- const key = labelOf(r.typeCode) === "Other" ? OTHER_TYPE_SENTINEL : r.typeCode;
1938
- if (!counts.has(key)) counts.set(key, 0);
1939
- if (recordMatchesFilters(r, filters, { skipType: true, labelOf })) {
1940
- counts.set(key, (counts.get(key) ?? 0) + 1);
1904
+ if (!counts.has(r.typeCode)) counts.set(r.typeCode, 0);
1905
+ if (recordMatchesFilters(r, filters, { skipType: true })) {
1906
+ counts.set(r.typeCode, (counts.get(r.typeCode) ?? 0) + 1);
1941
1907
  }
1942
1908
  }
1943
1909
  return [...counts.entries()].map(([code, count]) => ({
1944
1910
  code,
1945
- label: code === OTHER_TYPE_SENTINEL ? "Other" : labelOf(code),
1911
+ label: labelOf(code),
1946
1912
  count
1947
1913
  }));
1948
1914
  }, [ids, byId, labelOf, filters]);
@@ -2175,7 +2141,7 @@ function SidebarPagination({ page, pageCount, onChange }) {
2175
2141
  }
2176
2142
 
2177
2143
  // src/components/CasePicker/CasePicker.tsx
2178
- import { useEffect as useEffect12, useMemo as useMemo7, useRef as useRef9, useState as useState10 } from "react";
2144
+ import { useEffect as useEffect11, useMemo as useMemo7, useRef as useRef9, useState as useState9 } from "react";
2179
2145
  import { createPortal as createPortal5 } from "react-dom";
2180
2146
  import { Search as Search2, Check as Check3, Plus as Plus2, ChevronDown, X as X2 } from "lucide-react";
2181
2147
  import { useStore as useStore8 } from "zustand";
@@ -2198,13 +2164,13 @@ function CasePicker({ selected, onChange, mode = "dropdown" }) {
2198
2164
  [caseIds, casesById]
2199
2165
  );
2200
2166
  const selectedCase = cases.find((c) => c.id === selected) ?? null;
2201
- const [creating, setCreating] = useState10(false);
2202
- const [newName, setNewName] = useState10("");
2203
- const [newType, setNewType] = useState10("OP");
2204
- const [newDate, setNewDate] = useState10(todayISO());
2205
- const [saving, setSaving] = useState10(false);
2206
- const [query, setQuery] = useState10("");
2207
- const [menuPos, setMenuPos] = useState10(null);
2167
+ const [creating, setCreating] = useState9(false);
2168
+ const [newName, setNewName] = useState9("");
2169
+ const [newType, setNewType] = useState9("OP");
2170
+ const [newDate, setNewDate] = useState9(todayISO());
2171
+ const [saving, setSaving] = useState9(false);
2172
+ const [query, setQuery] = useState9("");
2173
+ const [menuPos, setMenuPos] = useState9(null);
2208
2174
  const fieldRef = useRef9(null);
2209
2175
  const menuRef = useRef9(null);
2210
2176
  const open = menuPos !== null;
@@ -2224,7 +2190,7 @@ function CasePicker({ selected, onChange, mode = "dropdown" }) {
2224
2190
  setMenuPos({ bottom: window.innerHeight - r.top + 4, left: r.left, width: r.width, maxH: Math.min(320, spaceAbove) });
2225
2191
  }
2226
2192
  };
2227
- useEffect12(() => {
2193
+ useEffect11(() => {
2228
2194
  if (!open) {
2229
2195
  setQuery("");
2230
2196
  setCreating(false);
@@ -2515,7 +2481,7 @@ function RecordsSidebar({
2515
2481
  }
2516
2482
 
2517
2483
  // src/views/RecordsView/RecordsGrid.tsx
2518
- import { useEffect as useEffect17, useRef as useRef14 } from "react";
2484
+ import { useEffect as useEffect16, useRef as useRef14 } from "react";
2519
2485
 
2520
2486
  // src/views/RecordsView/RecordCardContainer.tsx
2521
2487
  import { memo as memo8 } from "react";
@@ -2630,17 +2596,17 @@ var TagChip = memo5(function TagChip2({ label, removable, onRemove, onClick }) {
2630
2596
  });
2631
2597
 
2632
2598
  // src/components/Thumbnail/Thumbnail.tsx
2633
- import { memo as memo6, useEffect as useEffect13, useRef as useRef10, useState as useState11 } from "react";
2599
+ import { memo as memo6, useEffect as useEffect12, useRef as useRef10, useState as useState10 } from "react";
2634
2600
  import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
2635
2601
  var blobCache = /* @__PURE__ */ new Map();
2636
2602
  var Thumbnail = memo6(function Thumbnail2({ url, size, alt }) {
2637
2603
  const wrapRef = useRef10(null);
2638
2604
  const canvasRef = useRef10(null);
2639
2605
  const bitmapRef = useRef10(null);
2640
- const [decoded, setDecoded] = useState11(false);
2641
- const [errored, setErrored] = useState11(false);
2606
+ const [decoded, setDecoded] = useState10(false);
2607
+ const [errored, setErrored] = useState10(false);
2642
2608
  const decodedUrlRef = useRef10(null);
2643
- useEffect13(() => {
2609
+ useEffect12(() => {
2644
2610
  if (url && decoded && decodedUrlRef.current !== null) return;
2645
2611
  setErrored(false);
2646
2612
  if (!url) {
@@ -2781,7 +2747,7 @@ function ThumbnailFallbackIcon() {
2781
2747
  }
2782
2748
 
2783
2749
  // src/components/OverflowMenu/OverflowMenu.tsx
2784
- import { useEffect as useEffect14, useRef as useRef11, useState as useState12 } from "react";
2750
+ import { useEffect as useEffect13, useRef as useRef11, useState as useState11 } from "react";
2785
2751
  import { createPortal as createPortal6 } from "react-dom";
2786
2752
  import { ChevronLeft as ChevronLeft3, EllipsisVertical } from "lucide-react";
2787
2753
  import { Fragment as Fragment2, jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
@@ -2789,8 +2755,8 @@ var ITEM_HEIGHT = 36;
2789
2755
  var MENU_PADDING = 8;
2790
2756
  var GAP = 4;
2791
2757
  function OverflowMenu({ items, "aria-label": ariaLabel = "More options" }) {
2792
- const [coords, setCoords] = useState12(null);
2793
- const [activeSubPanel, setActiveSubPanel] = useState12(null);
2758
+ const [coords, setCoords] = useState11(null);
2759
+ const [activeSubPanel, setActiveSubPanel] = useState11(null);
2794
2760
  const triggerRef = useRef11(null);
2795
2761
  const menuRef = useRef11(null);
2796
2762
  const open = coords !== null;
@@ -2811,7 +2777,7 @@ function OverflowMenu({ items, "aria-label": ariaLabel = "More options" }) {
2811
2777
  setCoords({ right, top: r.bottom + GAP });
2812
2778
  }
2813
2779
  };
2814
- useEffect14(() => {
2780
+ useEffect13(() => {
2815
2781
  if (!open) return;
2816
2782
  const onDown = (e) => {
2817
2783
  const node = e.target;
@@ -2931,7 +2897,7 @@ function AttachContextIcon({ size = 28 }) {
2931
2897
  }
2932
2898
 
2933
2899
  // src/views/RecordsView/AddToContextSubPanel.tsx
2934
- import { useEffect as useEffect15, useMemo as useMemo8, useRef as useRef12, useState as useState13 } from "react";
2900
+ import { useEffect as useEffect14, useMemo as useMemo8, useRef as useRef12, useState as useState12 } from "react";
2935
2901
  import { createPortal as createPortal7 } from "react-dom";
2936
2902
  import { useStore as useStore9 } from "zustand";
2937
2903
  import { Check as Check4, Search as Search3, Plus as Plus3, ChevronsUpDown as ChevronsUpDown3 } from "lucide-react";
@@ -2969,16 +2935,16 @@ function AddToContextSubPanel({
2969
2935
  () => caseIds.map((id) => casesById[id]).filter(Boolean),
2970
2936
  [caseIds, casesById]
2971
2937
  );
2972
- const [selected, setSelected] = useState13(
2938
+ const [selected, setSelected] = useState12(
2973
2939
  linkedCaseIds.length > 0 ? linkedCaseIds[0] : null
2974
2940
  );
2975
- const [dropPos, setDropPos] = useState13(null);
2976
- const [query, setQuery] = useState13("");
2977
- const [creating, setCreating] = useState13(false);
2978
- const [newName, setNewName] = useState13("");
2979
- const [newType, setNewType] = useState13("OP");
2980
- const [newDate, setNewDate] = useState13(todayISO2());
2981
- const [saving, setSaving] = useState13(false);
2941
+ const [dropPos, setDropPos] = useState12(null);
2942
+ const [query, setQuery] = useState12("");
2943
+ const [creating, setCreating] = useState12(false);
2944
+ const [newName, setNewName] = useState12("");
2945
+ const [newType, setNewType] = useState12("OP");
2946
+ const [newDate, setNewDate] = useState12(todayISO2());
2947
+ const [saving, setSaving] = useState12(false);
2982
2948
  const fieldRef = useRef12(null);
2983
2949
  const dropRef = useRef12(null);
2984
2950
  const dropOpen = dropPos !== null;
@@ -3003,7 +2969,7 @@ function AddToContextSubPanel({
3003
2969
  setDropPos({ top: r.bottom + GAP2, left: r.left, width: r.width, maxH });
3004
2970
  }
3005
2971
  };
3006
- useEffect15(() => {
2972
+ useEffect14(() => {
3007
2973
  if (!dropOpen) {
3008
2974
  setQuery("");
3009
2975
  setCreating(false);
@@ -3382,11 +3348,11 @@ async function copyRecordNotes(record) {
3382
3348
  }
3383
3349
 
3384
3350
  // src/views/RecordsView/useInViewport.ts
3385
- import { useEffect as useEffect16, useRef as useRef13, useState as useState14 } from "react";
3351
+ import { useEffect as useEffect15, useRef as useRef13, useState as useState13 } from "react";
3386
3352
  function useInViewport() {
3387
3353
  const ref = useRef13(null);
3388
- const [seen, setSeen] = useState14(false);
3389
- useEffect16(() => {
3354
+ const [seen, setSeen] = useState13(false);
3355
+ useEffect15(() => {
3390
3356
  if (seen) return;
3391
3357
  const el = ref.current;
3392
3358
  if (!el) return;
@@ -3666,7 +3632,7 @@ function RecordsGrid({
3666
3632
  }) {
3667
3633
  const isList = viewMode === "list";
3668
3634
  const headerRefs = useRef14(/* @__PURE__ */ new Map());
3669
- useEffect17(() => {
3635
+ useEffect16(() => {
3670
3636
  if (!scrollToKey) return;
3671
3637
  headerRefs.current.get(scrollToKey)?.scrollIntoView({ behavior: "smooth", block: "start" });
3672
3638
  }, [scrollToKey]);
@@ -3759,12 +3725,12 @@ function RecordsSelectionFooter({
3759
3725
  }
3760
3726
 
3761
3727
  // src/views/RecordPreview/RecordPreview.tsx
3762
- import { lazy, Suspense, useState as useState16 } from "react";
3728
+ import { lazy, Suspense, useState as useState15 } from "react";
3763
3729
  import { ChevronLeft as ChevronLeft4, FilePlus, Check as Check8, Copy as Copy4 } from "lucide-react";
3764
3730
  import TurndownService from "turndown";
3765
3731
 
3766
3732
  // src/views/RecordPreview/SmartReportPanel.tsx
3767
- import { useMemo as useMemo11, useState as useState15 } from "react";
3733
+ import { useMemo as useMemo11, useState as useState14 } from "react";
3768
3734
  import { Search as Search4, ChevronRight as ChevronRight3, ArrowRight, Check as Check7, Copy as Copy3 } from "lucide-react";
3769
3735
  import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
3770
3736
  var STATUS_LABEL = {
@@ -3780,9 +3746,9 @@ function SmartReportPanel({
3780
3746
  onHide,
3781
3747
  onCopyToNote
3782
3748
  }) {
3783
- const [tab, setTab] = useState15("all");
3784
- const [search, setSearch] = useState15("");
3785
- const [selected, setSelected] = useState15(/* @__PURE__ */ new Set());
3749
+ const [tab, setTab] = useState14("all");
3750
+ const [search, setSearch] = useState14("");
3751
+ const [selected, setSelected] = useState14(/* @__PURE__ */ new Set());
3786
3752
  const outOfRangeCount = useMemo11(() => vitals.filter(isOutOfRange).length, [vitals]);
3787
3753
  const shown = useMemo11(() => {
3788
3754
  const q = search.trim().toLowerCase();
@@ -3960,14 +3926,14 @@ function VitalCard({
3960
3926
  import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
3961
3927
  var turndown = new TurndownService({ headingStyle: "atx", bulletListMarker: "-" });
3962
3928
  var DocumentViewer = lazy(
3963
- () => import("./DocumentViewer-WXL7OZXK.mjs").then((m) => ({ default: m.DocumentViewer }))
3929
+ () => import("./DocumentViewer-LJR3CLJP.mjs").then((m) => ({ default: m.DocumentViewer }))
3964
3930
  );
3965
3931
  var MAX_PREVIEW_TAGS = 2;
3966
3932
  function RecordPreview({ recordId, onBack }) {
3967
3933
  const record = useRecordById2(recordId);
3968
3934
  const preview = useRecordPreview(recordId);
3969
3935
  const { attachedIds, onAttachToContext, onRemoveAttachment, onCopyToNote } = useRecordsActions();
3970
- const [smartOpen, setSmartOpen] = useState16(true);
3936
+ const [smartOpen, setSmartOpen] = useState15(true);
3971
3937
  if (!record) return null;
3972
3938
  const attached = attachedIds?.has(recordId) ?? false;
3973
3939
  const attachFull = !attached && (attachedIds?.size ?? 0) >= MAX_CONTEXT_ATTACHMENTS;
@@ -4073,21 +4039,21 @@ function RecordPreview({ recordId, onBack }) {
4073
4039
  }
4074
4040
 
4075
4041
  // src/views/RecordsView/UploadModal.tsx
4076
- import { useEffect as useEffect18, useMemo as useMemo12, useRef as useRef15, useState as useState17 } from "react";
4042
+ import { useEffect as useEffect17, useMemo as useMemo12, useRef as useRef15, useState as useState16 } from "react";
4077
4043
  import { Upload as Upload2, X as X4 } from "lucide-react";
4078
4044
  import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
4079
4045
  var ACCEPT = ".pdf,.jpg,.jpeg,.png,image/*,application/pdf";
4080
4046
  var fileSeq = 0;
4081
4047
  function UploadModal({ onUpload, onError, onSuccess, onClose }) {
4082
4048
  const { documentTypes } = useSdk();
4083
- const [files, setFiles] = useState17([]);
4084
- const [dragging, setDragging] = useState17(false);
4049
+ const [files, setFiles] = useState16([]);
4050
+ const [dragging, setDragging] = useState16(false);
4085
4051
  const inputRef = useRef15(null);
4086
4052
  const docTypeOptions = useMemo12(
4087
4053
  () => documentTypes.map((t) => ({ value: t.id, label: t.display_name })),
4088
4054
  [documentTypes]
4089
4055
  );
4090
- useEffect18(() => {
4056
+ useEffect17(() => {
4091
4057
  const onKey = (e) => {
4092
4058
  if (e.key === "Escape") onClose();
4093
4059
  };
@@ -4257,7 +4223,7 @@ function UploadModal({ onUpload, onError, onSuccess, onClose }) {
4257
4223
  }
4258
4224
 
4259
4225
  // src/views/RecordsView/useRecordsView.ts
4260
- import { useCallback as useCallback7, useEffect as useEffect19, useMemo as useMemo15, useRef as useRef16, useState as useState18 } from "react";
4226
+ import { useCallback as useCallback7, useEffect as useEffect18, useMemo as useMemo15, useRef as useRef16, useState as useState17 } from "react";
4261
4227
  import { useStore as useStore12 } from "zustand";
4262
4228
 
4263
4229
  // src/views/RecordsView/useRecordSections.ts
@@ -4383,12 +4349,11 @@ function useRecordsView({
4383
4349
  attachedIds,
4384
4350
  onAttachManyToContext,
4385
4351
  onRemoveAttachment,
4386
- onToast
4352
+ onToast,
4353
+ allowUpload = true
4387
4354
  }) {
4388
- const { store, labelOf, environment } = useSdk();
4389
- const denialList = useDenialList(environment);
4390
- const allowUpload = !denialList.includes("UPLOAD_MEDICAL_RECORDS");
4391
- const { refresh, sourceRefreshedAt, deleteRecord } = useRecordsConnection();
4355
+ const { store, labelOf } = useSdk();
4356
+ const { refresh, retry, sourceRefreshedAt, deleteRecord } = useRecordsConnection();
4392
4357
  const { upload } = useUploadConnection();
4393
4358
  const status = useRecordsStatus2();
4394
4359
  const filteredIds = useFilteredRecordIds2();
@@ -4397,18 +4362,18 @@ function useRecordsView({
4397
4362
  const openDetailId = useStore12(store, (s) => s.selection.openDetailId);
4398
4363
  const activeFilters = useStore12(store, (s) => s.filters);
4399
4364
  const attachedIdSet = useMemo15(() => new Set(attachedIds ?? []), [attachedIds]);
4400
- const [viewMode, setViewMode] = useState18("grid");
4401
- const [sidebarTab, setSidebarTab] = useState18("date");
4402
- const [activeKey, setActiveKey] = useState18(null);
4403
- const [selectionMode, setSelectionMode] = useState18(false);
4404
- const [page, setPage] = useState18(0);
4405
- const [deleteTargetId, setDeleteTargetId] = useState18(null);
4406
- const [deleting, setDeleting] = useState18(false);
4407
- const [uploadOpen, setUploadOpen] = useState18(false);
4365
+ const [viewMode, setViewMode] = useState17("grid");
4366
+ const [sidebarTab, setSidebarTab] = useState17("date");
4367
+ const [activeKey, setActiveKey] = useState17(null);
4368
+ const [selectionMode, setSelectionMode] = useState17(false);
4369
+ const [page, setPage] = useState17(0);
4370
+ const [deleteTargetId, setDeleteTargetId] = useState17(null);
4371
+ const [deleting, setDeleting] = useState17(false);
4372
+ const [uploadOpen, setUploadOpen] = useState17(false);
4408
4373
  useCasesConnection();
4409
4374
  const sections = useRecordSections(sidebarTab, allIds);
4410
4375
  const autoSelectedRef = useRef16(false);
4411
- useEffect19(() => {
4376
+ useEffect18(() => {
4412
4377
  if (sidebarTab !== "careContext") {
4413
4378
  autoSelectedRef.current = false;
4414
4379
  return;
@@ -4536,6 +4501,7 @@ function useRecordsView({
4536
4501
  // data
4537
4502
  upload,
4538
4503
  refresh,
4504
+ retry,
4539
4505
  sourceRefreshedAt,
4540
4506
  actions,
4541
4507
  allowUpload,
@@ -4563,7 +4529,8 @@ function RecordsView({
4563
4529
  attachedIds,
4564
4530
  onAttachManyToContext,
4565
4531
  onRemoveAttachment,
4566
- onToast
4532
+ onToast,
4533
+ allowUpload: allowUploadProp = true
4567
4534
  }) {
4568
4535
  const {
4569
4536
  store,
@@ -4590,6 +4557,7 @@ function RecordsView({
4590
4557
  isTabEmpty,
4591
4558
  upload,
4592
4559
  refresh,
4560
+ retry,
4593
4561
  sourceRefreshedAt,
4594
4562
  actions,
4595
4563
  allowUpload,
@@ -4608,14 +4576,15 @@ function RecordsView({
4608
4576
  attachedIds,
4609
4577
  onAttachManyToContext,
4610
4578
  onRemoveAttachment,
4611
- onToast
4579
+ onToast,
4580
+ allowUpload: allowUploadProp
4612
4581
  });
4613
4582
  if (isInitialLoading) {
4614
4583
  return /* @__PURE__ */ jsx35("div", { className: `mr-records-view${className ? ` ${className}` : ""}`, children: /* @__PURE__ */ jsx35(RecordsLoadingState, {}) });
4615
4584
  }
4616
4585
  if (isLoadFailed || isTabEmpty) {
4617
4586
  return /* @__PURE__ */ jsxs30(Fragment6, { children: [
4618
- /* @__PURE__ */ jsx35("div", { className: `mr-records-view mr-records-view--state${className ? ` ${className}` : ""}`, children: isLoadFailed ? /* @__PURE__ */ jsx35(RecordsErrorState, { onRetry: refresh }) : /* @__PURE__ */ jsx35(RecordsEmptyState, { onUpload: allowUpload ? openUpload : void 0 }) }),
4587
+ /* @__PURE__ */ jsx35("div", { className: `mr-records-view mr-records-view--state${className ? ` ${className}` : ""}`, children: isLoadFailed ? /* @__PURE__ */ jsx35(RecordsErrorState, { onRetry: retry }) : /* @__PURE__ */ jsx35(RecordsEmptyState, { onUpload: allowUpload ? openUpload : void 0 }) }),
4619
4588
  uploadOpen && /* @__PURE__ */ jsx35(
4620
4589
  UploadModal,
4621
4590
  {