@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/{DocumentViewer-WXL7OZXK.mjs → DocumentViewer-LJR3CLJP.mjs} +5 -4
- package/dist/{DocumentViewer-WXL7OZXK.mjs.map → DocumentViewer-LJR3CLJP.mjs.map} +1 -1
- package/dist/{DocumentViewer-Z3GOU5NU.js → DocumentViewer-NM5THP2V.js} +5 -4
- package/dist/DocumentViewer-NM5THP2V.js.map +1 -0
- package/dist/index.d.mts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +51 -82
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +109 -140
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/DocumentViewer-Z3GOU5NU.js.map +0 -1
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
|
|
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) =>
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1603
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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] =
|
|
1738
|
-
const [docPreset, setDocPreset] =
|
|
1739
|
-
const [docFrom, setDocFrom] =
|
|
1740
|
-
const [docTo, setDocTo] =
|
|
1741
|
-
const [upPreset, setUpPreset] =
|
|
1742
|
-
const [upFrom, setUpFrom] =
|
|
1743
|
-
const [upTo, setUpTo] =
|
|
1744
|
-
const [tags, setTags] =
|
|
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] =
|
|
1871
|
+
const [filterOpen, setFilterOpen] = useState8(false);
|
|
1905
1872
|
const filterRef = useRef8(null);
|
|
1906
|
-
|
|
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] =
|
|
1917
|
-
const [, setNow] =
|
|
1918
|
-
|
|
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
|
-
|
|
1938
|
-
if (
|
|
1939
|
-
|
|
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:
|
|
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
|
|
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] =
|
|
2202
|
-
const [newName, setNewName] =
|
|
2203
|
-
const [newType, setNewType] =
|
|
2204
|
-
const [newDate, setNewDate] =
|
|
2205
|
-
const [saving, setSaving] =
|
|
2206
|
-
const [query, setQuery] =
|
|
2207
|
-
const [menuPos, setMenuPos] =
|
|
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
|
-
|
|
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
|
|
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
|
|
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] =
|
|
2641
|
-
const [errored, setErrored] =
|
|
2606
|
+
const [decoded, setDecoded] = useState10(false);
|
|
2607
|
+
const [errored, setErrored] = useState10(false);
|
|
2642
2608
|
const decodedUrlRef = useRef10(null);
|
|
2643
|
-
|
|
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
|
|
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] =
|
|
2793
|
-
const [activeSubPanel, setActiveSubPanel] =
|
|
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
|
-
|
|
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
|
|
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] =
|
|
2938
|
+
const [selected, setSelected] = useState12(
|
|
2973
2939
|
linkedCaseIds.length > 0 ? linkedCaseIds[0] : null
|
|
2974
2940
|
);
|
|
2975
|
-
const [dropPos, setDropPos] =
|
|
2976
|
-
const [query, setQuery] =
|
|
2977
|
-
const [creating, setCreating] =
|
|
2978
|
-
const [newName, setNewName] =
|
|
2979
|
-
const [newType, setNewType] =
|
|
2980
|
-
const [newDate, setNewDate] =
|
|
2981
|
-
const [saving, setSaving] =
|
|
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
|
-
|
|
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
|
|
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] =
|
|
3389
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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] =
|
|
3784
|
-
const [search, setSearch] =
|
|
3785
|
-
const [selected, setSelected] =
|
|
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-
|
|
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] =
|
|
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
|
|
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] =
|
|
4084
|
-
const [dragging, setDragging] =
|
|
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
|
-
|
|
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
|
|
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
|
|
4389
|
-
const
|
|
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] =
|
|
4401
|
-
const [sidebarTab, setSidebarTab] =
|
|
4402
|
-
const [activeKey, setActiveKey] =
|
|
4403
|
-
const [selectionMode, setSelectionMode] =
|
|
4404
|
-
const [page, setPage] =
|
|
4405
|
-
const [deleteTargetId, setDeleteTargetId] =
|
|
4406
|
-
const [deleting, setDeleting] =
|
|
4407
|
-
const [uploadOpen, setUploadOpen] =
|
|
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
|
-
|
|
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:
|
|
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
|
{
|