@eka-care/medical-records-ui 1.0.49 → 1.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{OriginalRecordPanel-KWJGVVFE.js → OriginalRecordPanel-DQF55MG3.js} +12 -12
- package/dist/{OriginalRecordPanel-KWJGVVFE.js.map → OriginalRecordPanel-DQF55MG3.js.map} +1 -1
- package/dist/{OriginalRecordPanel-GBDY4YJB.mjs → OriginalRecordPanel-FBSPPGVL.mjs} +3 -3
- package/dist/VitalHistoryPanel-KXYWVG55.mjs +10 -0
- package/dist/VitalHistoryPanel-V6NJE5JI.js +10 -0
- package/dist/{VitalHistoryPanel-YELPW6AL.js.map → VitalHistoryPanel-V6NJE5JI.js.map} +1 -1
- package/dist/chunk-LSDWS36C.mjs +49 -0
- package/dist/chunk-LSDWS36C.mjs.map +1 -0
- package/dist/{chunk-ZHIKJH2I.mjs → chunk-MI2JSHXL.mjs} +1 -2
- package/dist/chunk-MI2JSHXL.mjs.map +1 -0
- package/dist/{chunk-OA4KJNZA.js → chunk-QK7VGCUW.js} +8 -8
- package/dist/{chunk-OA4KJNZA.js.map → chunk-QK7VGCUW.js.map} +1 -1
- package/dist/chunk-QXXC4RX4.js +49 -0
- package/dist/chunk-QXXC4RX4.js.map +1 -0
- package/dist/{chunk-N3KF2CPW.mjs → chunk-TFR7PUDT.mjs} +2 -2
- package/dist/{chunk-5IFIBS2V.js → chunk-WUON6OEN.js} +2 -3
- package/dist/chunk-WUON6OEN.js.map +1 -0
- package/dist/index.js +404 -556
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +808 -960
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/VitalHistoryPanel-QERVAYAS.mjs +0 -10
- package/dist/VitalHistoryPanel-YELPW6AL.js +0 -10
- package/dist/chunk-5IFIBS2V.js.map +0 -1
- package/dist/chunk-ENYBGCLO.mjs +0 -115
- package/dist/chunk-ENYBGCLO.mjs.map +0 -1
- package/dist/chunk-I5KFQ3FK.js +0 -115
- package/dist/chunk-I5KFQ3FK.js.map +0 -1
- package/dist/chunk-ZHIKJH2I.mjs.map +0 -1
- /package/dist/{OriginalRecordPanel-GBDY4YJB.mjs.map → OriginalRecordPanel-FBSPPGVL.mjs.map} +0 -0
- /package/dist/{VitalHistoryPanel-QERVAYAS.mjs.map → VitalHistoryPanel-KXYWVG55.mjs.map} +0 -0
- /package/dist/{chunk-N3KF2CPW.mjs.map → chunk-TFR7PUDT.mjs.map} +0 -0
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkQXXC4RX4js = require('./chunk-QXXC4RX4.js');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunkWUON6OENjs = require('./chunk-WUON6OEN.js');
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
@@ -43,9 +43,9 @@ function OriginalRecordPanel({
|
|
|
43
43
|
const { store } = _chunkPN7IJ5MGjs.useSdk.call(void 0, );
|
|
44
44
|
const record = _zustand.useStore.call(void 0, store, (s) => s.records.byId[recordId]);
|
|
45
45
|
const recordsById = _zustand.useStore.call(void 0, store, (s) => s.records.byId);
|
|
46
|
-
const preview =
|
|
47
|
-
const { replaceOriginal, onCopyToNote, onCopyVitalsToNote, hasCopyToNote, onToast } =
|
|
48
|
-
const { status: vitalsStatus, table } =
|
|
46
|
+
const preview = _chunkWUON6OENjs.useRecordPreview.call(void 0, recordId);
|
|
47
|
+
const { replaceOriginal, onCopyToNote, onCopyVitalsToNote, hasCopyToNote, onToast } = _chunkWUON6OENjs.useSmartRecordsActions.call(void 0, );
|
|
48
|
+
const { status: vitalsStatus, table } = _chunkWUON6OENjs.useRecordPanelTable.call(void 0,
|
|
49
49
|
_optionalChain([record, 'optionalAccess', _3 => _3.isSmart]) ? recordId : null
|
|
50
50
|
);
|
|
51
51
|
const [smartPanelOpen, setSmartPanelOpen] = _react.useState.call(void 0, true);
|
|
@@ -148,7 +148,7 @@ function OriginalRecordPanel({
|
|
|
148
148
|
void onCopyToNote(
|
|
149
149
|
text,
|
|
150
150
|
rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : void 0,
|
|
151
|
-
|
|
151
|
+
_chunkQXXC4RX4js.toVitalNoteRows.call(void 0, selectedRows)
|
|
152
152
|
);
|
|
153
153
|
}
|
|
154
154
|
}, [filteredRows, srSelected, onCopyVitalsToNote, onCopyToNote]);
|
|
@@ -261,7 +261,7 @@ function OriginalRecordPanel({
|
|
|
261
261
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mr-orig__dropdown-icon", children: [
|
|
262
262
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.File, { size: 16, "aria-hidden": true }),
|
|
263
263
|
r.isSmart && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
264
|
-
|
|
264
|
+
_chunkQXXC4RX4js.SmartSparkles_default,
|
|
265
265
|
{
|
|
266
266
|
className: "mr-orig__dropdown-smart-dot",
|
|
267
267
|
"aria-label": "Smart report"
|
|
@@ -272,7 +272,7 @@ function OriginalRecordPanel({
|
|
|
272
272
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mr-orig__dropdown-title-row", children: [
|
|
273
273
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mr-orig__dropdown-title", children: r.title }),
|
|
274
274
|
r.isSmart && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "mr-orig__dropdown-smart-badge", children: [
|
|
275
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
275
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQXXC4RX4js.SmartSparkles_default, { "aria-hidden": true }),
|
|
276
276
|
"Smart Report"
|
|
277
277
|
] }),
|
|
278
278
|
_optionalChain([r, 'access', _20 => _20.fileType, 'optionalAccess', _21 => _21.toUpperCase, 'call', _22 => _22()]) === "HTML" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mr-tag-chip mr-tag-chip--html", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mr-tag-chip__label", children: "HTML" }) })
|
|
@@ -388,7 +388,7 @@ function OriginalRecordPanel({
|
|
|
388
388
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mr-orig__smart-hdr", children: [
|
|
389
389
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "mr-orig__smart-title-row", children: [
|
|
390
390
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mr-orig__smart-title", children: "Smart Report" }),
|
|
391
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
391
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQXXC4RX4js.SmartSparkles_default, { className: "mr-orig__smart-title-icon", "aria-hidden": true })
|
|
392
392
|
] }),
|
|
393
393
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
394
394
|
"button",
|
|
@@ -565,7 +565,7 @@ function OriginalRecordPanel({
|
|
|
565
565
|
"aria-label": "Expand smart report panel",
|
|
566
566
|
"aria-expanded": false,
|
|
567
567
|
onClick: () => setSmartPanelOpen(true),
|
|
568
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mr-orig__smart-collapsed-icon-wrap", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
568
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mr-orig__smart-collapsed-icon-wrap", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQXXC4RX4js.SmartSparkles_default, { className: "mr-orig__smart-collapsed-icon", "aria-hidden": true }) })
|
|
569
569
|
}
|
|
570
570
|
) }) })
|
|
571
571
|
] })
|
|
@@ -575,7 +575,7 @@ function OriginalRecordPanel({
|
|
|
575
575
|
] });
|
|
576
576
|
}
|
|
577
577
|
function VitalReadingsExpanded({ vitalName, ekaId }) {
|
|
578
|
-
const { data: trendData, status } =
|
|
578
|
+
const { data: trendData, status } = _chunkWUON6OENjs.useParameterTrend.call(void 0, ekaId);
|
|
579
579
|
const readings = _react.useMemo.call(void 0, () => {
|
|
580
580
|
const trend = trendData;
|
|
581
581
|
if (!_optionalChain([trend, 'optionalAccess', _25 => _25.vitals_info, 'optionalAccess', _26 => _26.length])) return [];
|
|
@@ -609,4 +609,4 @@ function VitalReadingsExpanded({ vitalName, ekaId }) {
|
|
|
609
609
|
|
|
610
610
|
|
|
611
611
|
exports.OriginalRecordPanel = OriginalRecordPanel;
|
|
612
|
-
//# sourceMappingURL=OriginalRecordPanel-
|
|
612
|
+
//# sourceMappingURL=OriginalRecordPanel-DQF55MG3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/OriginalRecordPanel-KWJGVVFE.js","../src/views/components/shared/OriginalRecordPanel.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/medical-records-ui/medical-records-ui/dist/OriginalRecordPanel-KWJGVVFE.js","sourcesContent":[null,"\"use client\";\n\nimport { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { ChevronLeft, ChevronRight, ChevronDown, ExternalLink, Check, File, LoaderCircle } from \"lucide-react\";\nimport { useStore } from \"zustand\";\nimport { useSdk } from \"../../../connection/useSdk\";\nimport { useRecordPreview } from \"../../../connection/useRecordPreview\";\nimport { useRecordPanelTable } from \"../../hooks/care-panel/useRecordPanelTable\";\nimport { useParameterTrend } from \"../../hooks/care-panel/useParameterTrend\";\nimport { epochToDisplay } from \"../../../helpers/formatters\";\nimport type { ParameterTrendResponse } from \"@eka-care/medical-records-ts-sdk\";\nimport { useSmartRecordsActions } from \"../../context/SmartRecordsActionsContext\";\nimport { IconButton, Typography, SearchInput, Tooltip } from \"widgets\";\nimport type { RecordItem } from \"../../../helpers\";\nimport type { PanelRow } from \"../../../helpers/vitalsPanel\";\nimport { toVitalNoteRows } from \"../../../helpers/vitalsPanel\";\nimport SmartSparkles from \"icons/SmartSparkles\";\n\nconst DocumentViewer = lazy(() =>\n import(\"../../RecordPreview/DocumentViewer\").then((m) => ({\n default: m.DocumentViewer,\n })),\n);\n\ninterface OriginalRecordPanelProps {\n recordId: string;\n caseId?: string;\n onBack: () => void;\n}\n\ntype SrTab = \"all\" | \"oor\" | \"none\";\n\nfunction buildVitalsText(rows: PanelRow[]): string {\n return rows\n .map((r) => {\n const cell = r.cells[0];\n const ref = cell?.refRange ? ` (Ref: ${cell.refRange})` : \"\";\n return `${r.name}: ${cell?.value ?? \"—\"} ${r.unit}${ref}`;\n })\n .join(\"\\n\");\n}\n\nexport function OriginalRecordPanel({\n recordId,\n caseId,\n onBack,\n}: OriginalRecordPanelProps) {\n const { store } = useSdk();\n const record = useStore(store, (s) => s.records.byId[recordId]);\n const recordsById = useStore(store, (s) => s.records.byId);\n const preview = useRecordPreview(recordId);\n const { replaceOriginal, onCopyToNote, onCopyVitalsToNote, hasCopyToNote, onToast } =\n useSmartRecordsActions();\n\n // Smart report vitals (only fetched when record.isSmart)\n const { status: vitalsStatus, table } = useRecordPanelTable(\n record?.isSmart ? recordId : null,\n );\n const [smartPanelOpen, setSmartPanelOpen] = useState(true);\n const [srSearch, setSrSearch] = useState(\"\");\n const [srTab, setSrTab] = useState<SrTab>(\"all\");\n const [expandedVital, setExpandedVital] = useState<string | null>(null);\n const toggleExpand = useCallback((key: string) => {\n setExpandedVital((prev) => (prev === key ? null : key));\n }, []);\n const [srSelected, setSrSelected] = useState<Set<string>>(new Set());\n const srCopyBtnRef = useRef<HTMLButtonElement>(null);\n\n // Dropdown state\n const [dropdownOpen, setDropdownOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!dropdownOpen) return;\n const handler = (e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setDropdownOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [dropdownOpen]);\n\n const caseRecords = useMemo<RecordItem[]>(() => {\n if (!caseId) return [];\n return Object.values(recordsById)\n .filter(\n (r): r is RecordItem =>\n r != null &&\n (caseId === \"__ungrouped__\" ? r.cases.length === 0 : r.cases.includes(caseId)),\n )\n .sort((a, b) => b.createdAtEpoch - a.createdAtEpoch);\n }, [recordsById, caseId]);\n\n const currentIndex = caseRecords.findIndex((r) => r.id === recordId);\n const total = caseRecords.length;\n const isUngrouped = caseId === \"__ungrouped__\";\n\n const goTo = useCallback(\n (r: RecordItem) => {\n setDropdownOpen(false);\n replaceOriginal(r.id, caseId);\n },\n [replaceOriginal, caseId],\n );\n\n const goPrev = useCallback(() => {\n if (currentIndex > 0) goTo(caseRecords[currentIndex - 1]);\n }, [currentIndex, caseRecords, goTo]);\n\n const goNext = useCallback(() => {\n if (currentIndex < total - 1) goTo(caseRecords[currentIndex + 1]);\n }, [currentIndex, total, caseRecords, goTo]);\n\n const showNavPicker = caseId && total > 0;\n\n // Smart report vitals filtering\n const allRows = table.rows;\n const oorRows = useMemo(\n () => allRows.filter((r) => r.latestStatus === \"high\" || r.latestStatus === \"low\"),\n [allRows],\n );\n const noInterpRows = useMemo(\n () => allRows.filter((r) => r.latestStatus === \"unknown\"),\n [allRows],\n );\n\n const baseRows = srTab === \"oor\" ? oorRows : srTab === \"none\" ? noInterpRows : allRows;\n\n const filteredRows = useMemo(() => {\n if (!srSearch) return baseRows;\n const q = srSearch.toLowerCase();\n return baseRows.filter((r) => r.name.toLowerCase().includes(q));\n }, [baseRows, srSearch]);\n\n const tabCounts = useMemo(() => {\n if (!srSearch) return { all: allRows.length, oor: oorRows.length, none: noInterpRows.length };\n const q = srSearch.toLowerCase();\n return {\n all: allRows.filter((r) => r.name.toLowerCase().includes(q)).length,\n oor: oorRows.filter((r) => r.name.toLowerCase().includes(q)).length,\n none: noInterpRows.filter((r) => r.name.toLowerCase().includes(q)).length,\n };\n }, [srSearch, allRows, oorRows, noInterpRows]);\n\n useEffect(() => {\n setSrSelected(new Set());\n }, [srTab, srSearch]);\n\n useEffect(() => {\n if (srTab === \"oor\" && oorRows.length === 0) setSrTab(\"all\");\n if (srTab === \"none\" && noInterpRows.length === 0) setSrTab(\"all\");\n }, [srTab, oorRows.length, noInterpRows.length]);\n\n const srAllSelected =\n filteredRows.length > 0 && filteredRows.every((r) => srSelected.has(r.key));\n const srSomeSelected = srSelected.size > 0;\n\n const toggleSrRow = useCallback((key: string) => {\n setSrSelected((prev) => {\n const next = new Set(prev);\n next.has(key) ? next.delete(key) : next.add(key);\n return next;\n });\n }, []);\n\n const toggleSrAll = useCallback(() => {\n setSrSelected(\n srAllSelected ? new Set() : new Set(filteredRows.map((r) => r.key)),\n );\n }, [srAllSelected, filteredRows]);\n\n const handleSrCopyToNote = useCallback(() => {\n const selectedRows = filteredRows.filter((r) => srSelected.has(r.key));\n if (!selectedRows.length) return;\n const text = buildVitalsText(selectedRows);\n if (onCopyVitalsToNote) {\n void onCopyVitalsToNote(text);\n } else if (onCopyToNote) {\n const rect = srCopyBtnRef.current?.getBoundingClientRect();\n void onCopyToNote(\n text,\n rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : undefined,\n toVitalNoteRows(selectedRows),\n );\n }\n }, [filteredRows, srSelected, onCopyVitalsToNote, onCopyToNote]);\n\n const htmlCopyBtnRef = useRef<HTMLButtonElement>(null);\n const [isHtmlCopying, setIsHtmlCopying] = useState(false);\n\n const handleHtmlCopyToNote = useCallback(async () => {\n const url = preview.files[0]?.url;\n if (!url) return;\n setIsHtmlCopying(true);\n try {\n const res = await fetch(url);\n const html = await res.text();\n const doc = new DOMParser().parseFromString(html, \"text/html\");\n const text = doc.body.textContent?.trim() ?? \"\";\n if (!text) return;\n if (onCopyVitalsToNote) {\n void onCopyVitalsToNote(text);\n } else if (onCopyToNote) {\n const rect = htmlCopyBtnRef.current?.getBoundingClientRect();\n void onCopyToNote(\n text,\n rect ? { x: rect.left, y: rect.bottom } : undefined,\n );\n }\n } catch {\n onToast?.(\"Failed to copy document text\", \"error\");\n } finally {\n setIsHtmlCopying(false);\n }\n }, [preview.files, onCopyVitalsToNote, onCopyToNote, onToast]);\n\n const isSmart = record?.isSmart ?? false;\n const hasPreview = preview.status === \"loaded\" && preview.files.length > 0;\n\n return (\n <div className=\"mr-sv__panel\">\n <div className=\"mr-sv__panel-header\">\n <button type=\"button\" className=\"mr-sv__back-btn\" onClick={onBack}>\n <ChevronLeft size={16} aria-hidden />\n Back\n </button>\n\n {showNavPicker ? (\n <div className=\"mr-orig__nav-wrap\" ref={dropdownRef}>\n <div\n className={`mr-orig__nav-pill${dropdownOpen ? \" mr-orig__nav-pill--open\" : \"\"}`}\n role=\"button\"\n tabIndex={0}\n onClick={() => setDropdownOpen((v) => !v)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setDropdownOpen((v) => !v);\n }\n }}\n >\n <button\n type=\"button\"\n className=\"mr-orig__nav-chevron\"\n onClick={(e) => { e.stopPropagation(); goPrev(); }}\n aria-label=\"Previous record\"\n disabled={currentIndex <= 0}\n >\n <ChevronLeft size={14} aria-hidden />\n </button>\n <div className=\"mr-orig__nav-text\">\n <span className=\"mr-orig__nav-title\">{record?.title ?? \"Record\"}</span>\n <span className=\"mr-orig__nav-counter\">\n {currentIndex + 1} of {total}\n </span>\n </div>\n <button\n type=\"button\"\n className=\"mr-orig__nav-chevron\"\n onClick={(e) => { e.stopPropagation(); goNext(); }}\n aria-label=\"Next record\"\n disabled={currentIndex >= total - 1}\n >\n <ChevronRight size={14} aria-hidden />\n </button>\n </div>\n\n {dropdownOpen && (\n <div className=\"mr-orig__dropdown\">\n <div className=\"mr-orig__dropdown-eyebrow\">\n {total} RECORD{total !== 1 ? \"S\" : \"\"}{\" \"}\n {isUngrouped ? \"WITH NO CARE CONTEXT\" : \"FOUND IN THIS ENCOUNTER\"}\n </div>\n <div className=\"mr-orig__dropdown-list\">\n {caseRecords.map((r) => {\n const isActive = r.id === recordId;\n return (\n <button\n key={r.id}\n type=\"button\"\n className={`mr-orig__dropdown-item${isActive ? \" mr-orig__dropdown-item--active\" : \"\"}`}\n onClick={() => goTo(r)}\n >\n <div className=\"mr-orig__dropdown-icon\">\n <File size={16} aria-hidden />\n {r.isSmart && (\n <SmartSparkles\n className=\"mr-orig__dropdown-smart-dot\"\n aria-label=\"Smart report\"\n />\n )}\n </div>\n <div className=\"mr-orig__dropdown-info\">\n <div className=\"mr-orig__dropdown-title-row\">\n <span className=\"mr-orig__dropdown-title\">{r.title}</span>\n {r.isSmart && (\n <span className=\"mr-orig__dropdown-smart-badge\">\n <SmartSparkles aria-hidden />\n Smart Report\n </span>\n )}\n {r.fileType?.toUpperCase() === \"HTML\" && (\n <span className=\"mr-tag-chip mr-tag-chip--html\">\n <span className=\"mr-tag-chip__label\">HTML</span>\n </span>\n )}\n </div>\n <div className=\"mr-orig__dropdown-meta\">\n <span>{epochToDisplay(r.createdAtEpoch)}</span>\n {r.isSmart && r.totalVitals > 0 && (\n <>\n <span className=\"mr-orig__dropdown-dot\">·</span>\n <span>{r.totalVitals} vitals</span>\n </>\n )}\n {r.isSmart && r.outOfRangeVitals > 0 && (\n <>\n <span className=\"mr-orig__dropdown-dot\">·</span>\n <span className=\"mr-orig__dropdown-oor\">\n {r.outOfRangeVitals} out of range\n </span>\n </>\n )}\n </div>\n </div>\n {isActive && (\n <Check\n size={14}\n className=\"mr-orig__dropdown-check\"\n aria-hidden\n />\n )}\n </button>\n );\n })}\n </div>\n </div>\n )}\n </div>\n ) : record ? (\n <div className=\"mr-sv__panel-info\">\n <Typography variant=\"label\" as=\"span\" className=\"mr-sv__panel-name\">\n {record.title}\n </Typography>\n <Typography variant=\"hint\" as=\"span\" className=\"mr-sv__panel-meta-text\">\n {epochToDisplay(record.createdAtEpoch)}\n </Typography>\n </div>\n ) : null}\n\n <div className=\"mr-orig__header-actions\">\n {preview.isHtml && hasCopyToNote && (\n <button\n ref={htmlCopyBtnRef}\n type=\"button\"\n className=\"mr-orig__html-copy-btn\"\n onClick={handleHtmlCopyToNote}\n disabled={isHtmlCopying}\n >\n {isHtmlCopying && <LoaderCircle size={12} className=\"mr-sv__loading-spinner\" aria-hidden />}\n Copy to note\n </button>\n )}\n {hasPreview && (\n <IconButton\n icon={<ExternalLink size={16} aria-hidden />}\n label=\"Open in new tab\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() =>\n window.open(preview.files[0].url, \"_blank\", \"noopener,noreferrer\")\n }\n />\n )}\n </div>\n </div>\n\n <div\n className=\"mr-sv__panel-body\"\n style={{ flex: 1, display: \"flex\", flexDirection: \"column\", overflow: \"hidden\" }}\n >\n {preview.status === \"loading\" && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100%\",\n }}\n >\n <LoaderCircle size={44} className=\"mr-sv__loading-spinner\" aria-hidden />\n </div>\n )}\n {preview.status === \"error\" && (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n Failed to load document preview.\n </Typography>\n )}\n {preview.status === \"loaded\" && preview.files.length === 0 && (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No preview available for this record.\n </Typography>\n )}\n\n {/* Non-smart: full-width PDF */}\n {hasPreview && !isSmart && (\n <div\n className=\"mr-record-preview__body\"\n style={{ flex: 1, display: \"flex\", overflow: \"hidden\" }}\n >\n <Suspense fallback={null}>\n <DocumentViewer\n files={preview.files}\n title={record?.title ?? \"\"}\n isHtml={preview.isHtml}\n />\n </Suspense>\n </div>\n )}\n\n {/* Smart: split view — PDF left, smart report panel right */}\n {hasPreview && isSmart && (\n <div className=\"mr-orig__split\">\n <div className=\"mr-orig__pdf-side\">\n <Suspense fallback={null}>\n <DocumentViewer\n files={preview.files}\n title={record?.title ?? \"\"}\n isHtml={preview.isHtml}\n />\n </Suspense>\n </div>\n\n {smartPanelOpen ? (\n <div className=\"mr-orig__smart-side\">\n {/* Header */}\n <div className=\"mr-orig__smart-hdr\">\n <span className=\"mr-orig__smart-title-row\">\n <span className=\"mr-orig__smart-title\">Smart Report</span>\n <SmartSparkles className=\"mr-orig__smart-title-icon\" aria-hidden />\n </span>\n <button\n type=\"button\"\n className=\"mr-sv__sidebar-collapse-btn mr-orig__smart-expanded-btn\"\n aria-label=\"Collapse smart report panel\"\n aria-expanded={true}\n onClick={() => setSmartPanelOpen(false)}\n >\n <ChevronRight size={14} aria-hidden />\n </button>\n </div>\n\n {/* Search */}\n <SearchInput\n className=\"mr-orig__smart-search\"\n iconSize={16}\n placeholder=\"Search vitals\"\n value={srSearch}\n onChange={setSrSearch}\n />\n\n {/* Filter tabs — only when at least one sub-category has data */}\n {(oorRows.length > 0 || noInterpRows.length > 0) && (\n <div className=\"mr-orig__smart-tabs-wrap\">\n <div className=\"mr-orig__smart-tabs\">\n {([\"all\", \"oor\", \"none\"] as SrTab[]).map((tab) => {\n if (tab === \"oor\" && oorRows.length === 0) return null;\n if (tab === \"none\" && noInterpRows.length === 0) return null;\n const count =\n tab === \"all\"\n ? tabCounts.all\n : tab === \"oor\"\n ? tabCounts.oor\n : tabCounts.none;\n const label =\n tab === \"all\"\n ? \"All\"\n : tab === \"oor\"\n ? \"Out of range\"\n : \"No interpretation\";\n return (\n <button\n key={tab}\n type=\"button\"\n className={`mr-orig__smart-tab${srTab === tab ? \" mr-orig__smart-tab--active\" : \"\"}`}\n onClick={() => setSrTab(tab)}\n >\n {label} ({count})\n </button>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Vital list */}\n <div className=\"mr-orig__smart-list\">\n {vitalsStatus === \"loading\" && (\n <div className=\"mr-orig__smart-loading\">\n <LoaderCircle\n size={20}\n className=\"mr-sv__loading-spinner\"\n aria-hidden\n />\n </div>\n )}\n {vitalsStatus === \"loaded\" && filteredRows.length === 0 && (\n <Typography variant=\"muted\" className=\"mr-orig__smart-empty\">\n No vitals match.\n </Typography>\n )}\n {vitalsStatus === \"loaded\" &&\n filteredRows.map((row, idx) => {\n const cell = row.cells[0];\n const isOor =\n row.latestStatus === \"high\" || row.latestStatus === \"low\";\n const isSelected = srSelected.has(row.key);\n const isLast = idx === filteredRows.length - 1;\n return (\n <div\n key={row.key}\n className={`mr-orig__vital-item${isLast ? \" mr-orig__vital-item--last\" : \"\"}`}\n >\n <div\n className={`mr-orig__vital-row mr-orig__vital-row--selectable${isSelected ? \" mr-orig__vital-row--selected\" : \"\"}`}\n onClick={() => toggleSrRow(row.key)}\n >\n <span\n className={`mr-sv__checkbox mr-cc-table__row-check${isSelected ? \" mr-sv__checkbox--checked\" : \"\"}`}\n role=\"checkbox\"\n aria-checked={isSelected}\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n toggleSrRow(row.key);\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n toggleSrRow(row.key);\n }\n }}\n >\n {isSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <div className=\"mr-orig__vital-info\">\n <span className=\"mr-orig__vital-name\">{row.name}</span>\n {row.refRange && (\n <span className=\"mr-orig__vital-ref\">\n Ref {row.refRange}\n </span>\n )}\n </div>\n {cell && (\n <div className=\"mr-orig__vital-value\">\n <span\n className={`mr-orig__vital-val${isOor ? \" mr-orig__vital-val--oor\" : \"\"}`}\n >\n {cell.value}\n </span>\n {cell.unit && (\n <span className=\"mr-orig__vital-unit\">{cell.unit}</span>\n )}\n </div>\n )}\n {row.ekaId && (\n <button\n type=\"button\"\n className={`mr-orig__vital-expand-btn${expandedVital === row.key ? \" mr-orig__vital-expand-btn--open\" : \"\"}`}\n onClick={(e) => { e.stopPropagation(); toggleExpand(row.key); }}\n aria-label={expandedVital === row.key ? \"Collapse readings\" : \"Show latest readings\"}\n >\n <ChevronDown size={13} aria-hidden />\n </button>\n )}\n </div>\n {expandedVital === row.key && row.ekaId && (\n <VitalReadingsExpanded vitalName={row.name} ekaId={row.ekaId} />\n )}\n </div>\n );\n })}\n </div>\n\n {/* Footer */}\n <div className=\"mr-cc-table__footer\">\n <span\n className={`mr-sv__checkbox mr-cc-table__footer-check${srAllSelected ? \" mr-sv__checkbox--checked\" : \"\"}`}\n role=\"checkbox\"\n aria-checked={srAllSelected}\n tabIndex={0}\n onClick={toggleSrAll}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n toggleSrAll();\n }\n }}\n >\n {srAllSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <span className=\"mr-cc-table__footer-label\" onClick={toggleSrAll}>Select all</span>\n <span className=\"mr-cc-table__footer-count\">\n {srSelected.size} of {filteredRows.length} selected\n </span>\n <button\n ref={srCopyBtnRef}\n type=\"button\"\n className=\"mr-cc-table__copy-note-btn\"\n disabled={!srSomeSelected || !hasCopyToNote}\n onClick={handleSrCopyToNote}\n >\n Copy to note\n </button>\n </div>\n </div>\n ) : (\n <div className=\"mr-orig__smart-side mr-orig__smart-side--collapsed\">\n <Tooltip content=\"Show smart report\">\n <button\n type=\"button\"\n className=\"mr-sv__sidebar-collapse-btn mr-orig__smart-collapsed-btn\"\n aria-label=\"Expand smart report panel\"\n aria-expanded={false}\n onClick={() => setSmartPanelOpen(true)}\n >\n <span className=\"mr-orig__smart-collapsed-icon-wrap\">\n <SmartSparkles className=\"mr-orig__smart-collapsed-icon\" aria-hidden />\n </span>\n </button>\n </Tooltip>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction VitalReadingsExpanded({ vitalName, ekaId }: { vitalName: string; ekaId: string }) {\n const { data: trendData, status } = useParameterTrend(ekaId);\n\n const readings = useMemo(() => {\n const trend = trendData as ParameterTrendResponse | null;\n if (!trend?.vitals_info?.length) return [];\n return [...trend.vitals_info]\n .sort((a, b) => (b.date ?? 0) - (a.date ?? 0))\n .slice(0, 3)\n .map((info) => {\n const dr = (info.display_result ?? \"\").toLowerCase();\n const isOor = dr.includes(\"high\") || dr.includes(\"above\") || dr.includes(\"abnormal_high\") ||\n dr.includes(\"low\") || dr.includes(\"below\") || dr.includes(\"abnormal_low\");\n return {\n value: info.val != null ? String(info.val) : ((info as any).val_string ?? \"—\"),\n date: (info.display_time || \"\").replace(/['‘’]/g, \" \"),\n isOor,\n };\n });\n }, [trendData]);\n\n if (status === \"loading\") {\n return (\n <div className=\"mr-orig__vital-readings mr-orig__vital-readings--loading\">\n <LoaderCircle size={16} className=\"mr-sv__loading-spinner\" aria-hidden />\n </div>\n );\n }\n\n if (status === \"error\" || !readings.length) {\n return (\n <div className=\"mr-orig__vital-readings\">\n <Typography variant=\"muted\" className=\"mr-orig__vital-readings-empty\">\n No readings available\n </Typography>\n </div>\n );\n }\n\n return (\n <div className=\"mr-orig__vital-readings\">\n <div className=\"mr-orig__vital-readings-title\">\n LATEST READINGS FOR {vitalName.toUpperCase()}\n </div>\n <div className=\"mr-orig__vital-readings-grid\">\n {readings.map((r, i) => (\n <div key={i} className=\"mr-orig__vital-reading-item\">\n <span className={`mr-orig__vital-reading-value${r.isOor ? \" mr-orig__vital-reading-value--oor\" : \"\"}`}>{r.value}</span>\n <span className=\"mr-orig__vital-reading-date\">{r.date}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/OriginalRecordPanel-DQF55MG3.js","../src/views/components/shared/OriginalRecordPanel.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/medical-records-ui/medical-records-ui/dist/OriginalRecordPanel-DQF55MG3.js","sourcesContent":[null,"\"use client\";\n\nimport { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { ChevronLeft, ChevronRight, ChevronDown, ExternalLink, Check, File, LoaderCircle } from \"lucide-react\";\nimport { useStore } from \"zustand\";\nimport { useSdk } from \"../../../connection/useSdk\";\nimport { useRecordPreview } from \"../../../connection/useRecordPreview\";\nimport { useRecordPanelTable } from \"../../hooks/care-panel/useRecordPanelTable\";\nimport { useParameterTrend } from \"../../hooks/care-panel/useParameterTrend\";\nimport { epochToDisplay } from \"../../../helpers/formatters\";\nimport type { ParameterTrendResponse } from \"@eka-care/medical-records-ts-sdk\";\nimport { useSmartRecordsActions } from \"../../context/SmartRecordsActionsContext\";\nimport { IconButton, Typography, SearchInput, Tooltip } from \"widgets\";\nimport type { RecordItem } from \"../../../helpers\";\nimport type { PanelRow } from \"../../../helpers/vitalsPanel\";\nimport { toVitalNoteRows } from \"../../../helpers/vitalsPanel\";\nimport SmartSparkles from \"icons/SmartSparkles\";\n\nconst DocumentViewer = lazy(() =>\n import(\"../../RecordPreview/DocumentViewer\").then((m) => ({\n default: m.DocumentViewer,\n })),\n);\n\ninterface OriginalRecordPanelProps {\n recordId: string;\n caseId?: string;\n onBack: () => void;\n}\n\ntype SrTab = \"all\" | \"oor\" | \"none\";\n\nfunction buildVitalsText(rows: PanelRow[]): string {\n return rows\n .map((r) => {\n const cell = r.cells[0];\n const ref = cell?.refRange ? ` (Ref: ${cell.refRange})` : \"\";\n return `${r.name}: ${cell?.value ?? \"—\"} ${r.unit}${ref}`;\n })\n .join(\"\\n\");\n}\n\nexport function OriginalRecordPanel({\n recordId,\n caseId,\n onBack,\n}: OriginalRecordPanelProps) {\n const { store } = useSdk();\n const record = useStore(store, (s) => s.records.byId[recordId]);\n const recordsById = useStore(store, (s) => s.records.byId);\n const preview = useRecordPreview(recordId);\n const { replaceOriginal, onCopyToNote, onCopyVitalsToNote, hasCopyToNote, onToast } =\n useSmartRecordsActions();\n\n // Smart report vitals (only fetched when record.isSmart)\n const { status: vitalsStatus, table } = useRecordPanelTable(\n record?.isSmart ? recordId : null,\n );\n const [smartPanelOpen, setSmartPanelOpen] = useState(true);\n const [srSearch, setSrSearch] = useState(\"\");\n const [srTab, setSrTab] = useState<SrTab>(\"all\");\n const [expandedVital, setExpandedVital] = useState<string | null>(null);\n const toggleExpand = useCallback((key: string) => {\n setExpandedVital((prev) => (prev === key ? null : key));\n }, []);\n const [srSelected, setSrSelected] = useState<Set<string>>(new Set());\n const srCopyBtnRef = useRef<HTMLButtonElement>(null);\n\n // Dropdown state\n const [dropdownOpen, setDropdownOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!dropdownOpen) return;\n const handler = (e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setDropdownOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [dropdownOpen]);\n\n const caseRecords = useMemo<RecordItem[]>(() => {\n if (!caseId) return [];\n return Object.values(recordsById)\n .filter(\n (r): r is RecordItem =>\n r != null &&\n (caseId === \"__ungrouped__\" ? r.cases.length === 0 : r.cases.includes(caseId)),\n )\n .sort((a, b) => b.createdAtEpoch - a.createdAtEpoch);\n }, [recordsById, caseId]);\n\n const currentIndex = caseRecords.findIndex((r) => r.id === recordId);\n const total = caseRecords.length;\n const isUngrouped = caseId === \"__ungrouped__\";\n\n const goTo = useCallback(\n (r: RecordItem) => {\n setDropdownOpen(false);\n replaceOriginal(r.id, caseId);\n },\n [replaceOriginal, caseId],\n );\n\n const goPrev = useCallback(() => {\n if (currentIndex > 0) goTo(caseRecords[currentIndex - 1]);\n }, [currentIndex, caseRecords, goTo]);\n\n const goNext = useCallback(() => {\n if (currentIndex < total - 1) goTo(caseRecords[currentIndex + 1]);\n }, [currentIndex, total, caseRecords, goTo]);\n\n const showNavPicker = caseId && total > 0;\n\n // Smart report vitals filtering\n const allRows = table.rows;\n const oorRows = useMemo(\n () => allRows.filter((r) => r.latestStatus === \"high\" || r.latestStatus === \"low\"),\n [allRows],\n );\n const noInterpRows = useMemo(\n () => allRows.filter((r) => r.latestStatus === \"unknown\"),\n [allRows],\n );\n\n const baseRows = srTab === \"oor\" ? oorRows : srTab === \"none\" ? noInterpRows : allRows;\n\n const filteredRows = useMemo(() => {\n if (!srSearch) return baseRows;\n const q = srSearch.toLowerCase();\n return baseRows.filter((r) => r.name.toLowerCase().includes(q));\n }, [baseRows, srSearch]);\n\n const tabCounts = useMemo(() => {\n if (!srSearch) return { all: allRows.length, oor: oorRows.length, none: noInterpRows.length };\n const q = srSearch.toLowerCase();\n return {\n all: allRows.filter((r) => r.name.toLowerCase().includes(q)).length,\n oor: oorRows.filter((r) => r.name.toLowerCase().includes(q)).length,\n none: noInterpRows.filter((r) => r.name.toLowerCase().includes(q)).length,\n };\n }, [srSearch, allRows, oorRows, noInterpRows]);\n\n useEffect(() => {\n setSrSelected(new Set());\n }, [srTab, srSearch]);\n\n useEffect(() => {\n if (srTab === \"oor\" && oorRows.length === 0) setSrTab(\"all\");\n if (srTab === \"none\" && noInterpRows.length === 0) setSrTab(\"all\");\n }, [srTab, oorRows.length, noInterpRows.length]);\n\n const srAllSelected =\n filteredRows.length > 0 && filteredRows.every((r) => srSelected.has(r.key));\n const srSomeSelected = srSelected.size > 0;\n\n const toggleSrRow = useCallback((key: string) => {\n setSrSelected((prev) => {\n const next = new Set(prev);\n next.has(key) ? next.delete(key) : next.add(key);\n return next;\n });\n }, []);\n\n const toggleSrAll = useCallback(() => {\n setSrSelected(\n srAllSelected ? new Set() : new Set(filteredRows.map((r) => r.key)),\n );\n }, [srAllSelected, filteredRows]);\n\n const handleSrCopyToNote = useCallback(() => {\n const selectedRows = filteredRows.filter((r) => srSelected.has(r.key));\n if (!selectedRows.length) return;\n const text = buildVitalsText(selectedRows);\n if (onCopyVitalsToNote) {\n void onCopyVitalsToNote(text);\n } else if (onCopyToNote) {\n const rect = srCopyBtnRef.current?.getBoundingClientRect();\n void onCopyToNote(\n text,\n rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : undefined,\n toVitalNoteRows(selectedRows),\n );\n }\n }, [filteredRows, srSelected, onCopyVitalsToNote, onCopyToNote]);\n\n const htmlCopyBtnRef = useRef<HTMLButtonElement>(null);\n const [isHtmlCopying, setIsHtmlCopying] = useState(false);\n\n const handleHtmlCopyToNote = useCallback(async () => {\n const url = preview.files[0]?.url;\n if (!url) return;\n setIsHtmlCopying(true);\n try {\n const res = await fetch(url);\n const html = await res.text();\n const doc = new DOMParser().parseFromString(html, \"text/html\");\n const text = doc.body.textContent?.trim() ?? \"\";\n if (!text) return;\n if (onCopyVitalsToNote) {\n void onCopyVitalsToNote(text);\n } else if (onCopyToNote) {\n const rect = htmlCopyBtnRef.current?.getBoundingClientRect();\n void onCopyToNote(\n text,\n rect ? { x: rect.left, y: rect.bottom } : undefined,\n );\n }\n } catch {\n onToast?.(\"Failed to copy document text\", \"error\");\n } finally {\n setIsHtmlCopying(false);\n }\n }, [preview.files, onCopyVitalsToNote, onCopyToNote, onToast]);\n\n const isSmart = record?.isSmart ?? false;\n const hasPreview = preview.status === \"loaded\" && preview.files.length > 0;\n\n return (\n <div className=\"mr-sv__panel\">\n <div className=\"mr-sv__panel-header\">\n <button type=\"button\" className=\"mr-sv__back-btn\" onClick={onBack}>\n <ChevronLeft size={16} aria-hidden />\n Back\n </button>\n\n {showNavPicker ? (\n <div className=\"mr-orig__nav-wrap\" ref={dropdownRef}>\n <div\n className={`mr-orig__nav-pill${dropdownOpen ? \" mr-orig__nav-pill--open\" : \"\"}`}\n role=\"button\"\n tabIndex={0}\n onClick={() => setDropdownOpen((v) => !v)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setDropdownOpen((v) => !v);\n }\n }}\n >\n <button\n type=\"button\"\n className=\"mr-orig__nav-chevron\"\n onClick={(e) => { e.stopPropagation(); goPrev(); }}\n aria-label=\"Previous record\"\n disabled={currentIndex <= 0}\n >\n <ChevronLeft size={14} aria-hidden />\n </button>\n <div className=\"mr-orig__nav-text\">\n <span className=\"mr-orig__nav-title\">{record?.title ?? \"Record\"}</span>\n <span className=\"mr-orig__nav-counter\">\n {currentIndex + 1} of {total}\n </span>\n </div>\n <button\n type=\"button\"\n className=\"mr-orig__nav-chevron\"\n onClick={(e) => { e.stopPropagation(); goNext(); }}\n aria-label=\"Next record\"\n disabled={currentIndex >= total - 1}\n >\n <ChevronRight size={14} aria-hidden />\n </button>\n </div>\n\n {dropdownOpen && (\n <div className=\"mr-orig__dropdown\">\n <div className=\"mr-orig__dropdown-eyebrow\">\n {total} RECORD{total !== 1 ? \"S\" : \"\"}{\" \"}\n {isUngrouped ? \"WITH NO CARE CONTEXT\" : \"FOUND IN THIS ENCOUNTER\"}\n </div>\n <div className=\"mr-orig__dropdown-list\">\n {caseRecords.map((r) => {\n const isActive = r.id === recordId;\n return (\n <button\n key={r.id}\n type=\"button\"\n className={`mr-orig__dropdown-item${isActive ? \" mr-orig__dropdown-item--active\" : \"\"}`}\n onClick={() => goTo(r)}\n >\n <div className=\"mr-orig__dropdown-icon\">\n <File size={16} aria-hidden />\n {r.isSmart && (\n <SmartSparkles\n className=\"mr-orig__dropdown-smart-dot\"\n aria-label=\"Smart report\"\n />\n )}\n </div>\n <div className=\"mr-orig__dropdown-info\">\n <div className=\"mr-orig__dropdown-title-row\">\n <span className=\"mr-orig__dropdown-title\">{r.title}</span>\n {r.isSmart && (\n <span className=\"mr-orig__dropdown-smart-badge\">\n <SmartSparkles aria-hidden />\n Smart Report\n </span>\n )}\n {r.fileType?.toUpperCase() === \"HTML\" && (\n <span className=\"mr-tag-chip mr-tag-chip--html\">\n <span className=\"mr-tag-chip__label\">HTML</span>\n </span>\n )}\n </div>\n <div className=\"mr-orig__dropdown-meta\">\n <span>{epochToDisplay(r.createdAtEpoch)}</span>\n {r.isSmart && r.totalVitals > 0 && (\n <>\n <span className=\"mr-orig__dropdown-dot\">·</span>\n <span>{r.totalVitals} vitals</span>\n </>\n )}\n {r.isSmart && r.outOfRangeVitals > 0 && (\n <>\n <span className=\"mr-orig__dropdown-dot\">·</span>\n <span className=\"mr-orig__dropdown-oor\">\n {r.outOfRangeVitals} out of range\n </span>\n </>\n )}\n </div>\n </div>\n {isActive && (\n <Check\n size={14}\n className=\"mr-orig__dropdown-check\"\n aria-hidden\n />\n )}\n </button>\n );\n })}\n </div>\n </div>\n )}\n </div>\n ) : record ? (\n <div className=\"mr-sv__panel-info\">\n <Typography variant=\"label\" as=\"span\" className=\"mr-sv__panel-name\">\n {record.title}\n </Typography>\n <Typography variant=\"hint\" as=\"span\" className=\"mr-sv__panel-meta-text\">\n {epochToDisplay(record.createdAtEpoch)}\n </Typography>\n </div>\n ) : null}\n\n <div className=\"mr-orig__header-actions\">\n {preview.isHtml && hasCopyToNote && (\n <button\n ref={htmlCopyBtnRef}\n type=\"button\"\n className=\"mr-orig__html-copy-btn\"\n onClick={handleHtmlCopyToNote}\n disabled={isHtmlCopying}\n >\n {isHtmlCopying && <LoaderCircle size={12} className=\"mr-sv__loading-spinner\" aria-hidden />}\n Copy to note\n </button>\n )}\n {hasPreview && (\n <IconButton\n icon={<ExternalLink size={16} aria-hidden />}\n label=\"Open in new tab\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() =>\n window.open(preview.files[0].url, \"_blank\", \"noopener,noreferrer\")\n }\n />\n )}\n </div>\n </div>\n\n <div\n className=\"mr-sv__panel-body\"\n style={{ flex: 1, display: \"flex\", flexDirection: \"column\", overflow: \"hidden\" }}\n >\n {preview.status === \"loading\" && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100%\",\n }}\n >\n <LoaderCircle size={44} className=\"mr-sv__loading-spinner\" aria-hidden />\n </div>\n )}\n {preview.status === \"error\" && (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n Failed to load document preview.\n </Typography>\n )}\n {preview.status === \"loaded\" && preview.files.length === 0 && (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No preview available for this record.\n </Typography>\n )}\n\n {/* Non-smart: full-width PDF */}\n {hasPreview && !isSmart && (\n <div\n className=\"mr-record-preview__body\"\n style={{ flex: 1, display: \"flex\", overflow: \"hidden\" }}\n >\n <Suspense fallback={null}>\n <DocumentViewer\n files={preview.files}\n title={record?.title ?? \"\"}\n isHtml={preview.isHtml}\n />\n </Suspense>\n </div>\n )}\n\n {/* Smart: split view — PDF left, smart report panel right */}\n {hasPreview && isSmart && (\n <div className=\"mr-orig__split\">\n <div className=\"mr-orig__pdf-side\">\n <Suspense fallback={null}>\n <DocumentViewer\n files={preview.files}\n title={record?.title ?? \"\"}\n isHtml={preview.isHtml}\n />\n </Suspense>\n </div>\n\n {smartPanelOpen ? (\n <div className=\"mr-orig__smart-side\">\n {/* Header */}\n <div className=\"mr-orig__smart-hdr\">\n <span className=\"mr-orig__smart-title-row\">\n <span className=\"mr-orig__smart-title\">Smart Report</span>\n <SmartSparkles className=\"mr-orig__smart-title-icon\" aria-hidden />\n </span>\n <button\n type=\"button\"\n className=\"mr-sv__sidebar-collapse-btn mr-orig__smart-expanded-btn\"\n aria-label=\"Collapse smart report panel\"\n aria-expanded={true}\n onClick={() => setSmartPanelOpen(false)}\n >\n <ChevronRight size={14} aria-hidden />\n </button>\n </div>\n\n {/* Search */}\n <SearchInput\n className=\"mr-orig__smart-search\"\n iconSize={16}\n placeholder=\"Search vitals\"\n value={srSearch}\n onChange={setSrSearch}\n />\n\n {/* Filter tabs — only when at least one sub-category has data */}\n {(oorRows.length > 0 || noInterpRows.length > 0) && (\n <div className=\"mr-orig__smart-tabs-wrap\">\n <div className=\"mr-orig__smart-tabs\">\n {([\"all\", \"oor\", \"none\"] as SrTab[]).map((tab) => {\n if (tab === \"oor\" && oorRows.length === 0) return null;\n if (tab === \"none\" && noInterpRows.length === 0) return null;\n const count =\n tab === \"all\"\n ? tabCounts.all\n : tab === \"oor\"\n ? tabCounts.oor\n : tabCounts.none;\n const label =\n tab === \"all\"\n ? \"All\"\n : tab === \"oor\"\n ? \"Out of range\"\n : \"No interpretation\";\n return (\n <button\n key={tab}\n type=\"button\"\n className={`mr-orig__smart-tab${srTab === tab ? \" mr-orig__smart-tab--active\" : \"\"}`}\n onClick={() => setSrTab(tab)}\n >\n {label} ({count})\n </button>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Vital list */}\n <div className=\"mr-orig__smart-list\">\n {vitalsStatus === \"loading\" && (\n <div className=\"mr-orig__smart-loading\">\n <LoaderCircle\n size={20}\n className=\"mr-sv__loading-spinner\"\n aria-hidden\n />\n </div>\n )}\n {vitalsStatus === \"loaded\" && filteredRows.length === 0 && (\n <Typography variant=\"muted\" className=\"mr-orig__smart-empty\">\n No vitals match.\n </Typography>\n )}\n {vitalsStatus === \"loaded\" &&\n filteredRows.map((row, idx) => {\n const cell = row.cells[0];\n const isOor =\n row.latestStatus === \"high\" || row.latestStatus === \"low\";\n const isSelected = srSelected.has(row.key);\n const isLast = idx === filteredRows.length - 1;\n return (\n <div\n key={row.key}\n className={`mr-orig__vital-item${isLast ? \" mr-orig__vital-item--last\" : \"\"}`}\n >\n <div\n className={`mr-orig__vital-row mr-orig__vital-row--selectable${isSelected ? \" mr-orig__vital-row--selected\" : \"\"}`}\n onClick={() => toggleSrRow(row.key)}\n >\n <span\n className={`mr-sv__checkbox mr-cc-table__row-check${isSelected ? \" mr-sv__checkbox--checked\" : \"\"}`}\n role=\"checkbox\"\n aria-checked={isSelected}\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n toggleSrRow(row.key);\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n toggleSrRow(row.key);\n }\n }}\n >\n {isSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <div className=\"mr-orig__vital-info\">\n <span className=\"mr-orig__vital-name\">{row.name}</span>\n {row.refRange && (\n <span className=\"mr-orig__vital-ref\">\n Ref {row.refRange}\n </span>\n )}\n </div>\n {cell && (\n <div className=\"mr-orig__vital-value\">\n <span\n className={`mr-orig__vital-val${isOor ? \" mr-orig__vital-val--oor\" : \"\"}`}\n >\n {cell.value}\n </span>\n {cell.unit && (\n <span className=\"mr-orig__vital-unit\">{cell.unit}</span>\n )}\n </div>\n )}\n {row.ekaId && (\n <button\n type=\"button\"\n className={`mr-orig__vital-expand-btn${expandedVital === row.key ? \" mr-orig__vital-expand-btn--open\" : \"\"}`}\n onClick={(e) => { e.stopPropagation(); toggleExpand(row.key); }}\n aria-label={expandedVital === row.key ? \"Collapse readings\" : \"Show latest readings\"}\n >\n <ChevronDown size={13} aria-hidden />\n </button>\n )}\n </div>\n {expandedVital === row.key && row.ekaId && (\n <VitalReadingsExpanded vitalName={row.name} ekaId={row.ekaId} />\n )}\n </div>\n );\n })}\n </div>\n\n {/* Footer */}\n <div className=\"mr-cc-table__footer\">\n <span\n className={`mr-sv__checkbox mr-cc-table__footer-check${srAllSelected ? \" mr-sv__checkbox--checked\" : \"\"}`}\n role=\"checkbox\"\n aria-checked={srAllSelected}\n tabIndex={0}\n onClick={toggleSrAll}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n toggleSrAll();\n }\n }}\n >\n {srAllSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <span className=\"mr-cc-table__footer-label\" onClick={toggleSrAll}>Select all</span>\n <span className=\"mr-cc-table__footer-count\">\n {srSelected.size} of {filteredRows.length} selected\n </span>\n <button\n ref={srCopyBtnRef}\n type=\"button\"\n className=\"mr-cc-table__copy-note-btn\"\n disabled={!srSomeSelected || !hasCopyToNote}\n onClick={handleSrCopyToNote}\n >\n Copy to note\n </button>\n </div>\n </div>\n ) : (\n <div className=\"mr-orig__smart-side mr-orig__smart-side--collapsed\">\n <Tooltip content=\"Show smart report\">\n <button\n type=\"button\"\n className=\"mr-sv__sidebar-collapse-btn mr-orig__smart-collapsed-btn\"\n aria-label=\"Expand smart report panel\"\n aria-expanded={false}\n onClick={() => setSmartPanelOpen(true)}\n >\n <span className=\"mr-orig__smart-collapsed-icon-wrap\">\n <SmartSparkles className=\"mr-orig__smart-collapsed-icon\" aria-hidden />\n </span>\n </button>\n </Tooltip>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction VitalReadingsExpanded({ vitalName, ekaId }: { vitalName: string; ekaId: string }) {\n const { data: trendData, status } = useParameterTrend(ekaId);\n\n const readings = useMemo(() => {\n const trend = trendData as ParameterTrendResponse | null;\n if (!trend?.vitals_info?.length) return [];\n return [...trend.vitals_info]\n .sort((a, b) => (b.date ?? 0) - (a.date ?? 0))\n .slice(0, 3)\n .map((info) => {\n const dr = (info.display_result ?? \"\").toLowerCase();\n const isOor = dr.includes(\"high\") || dr.includes(\"above\") || dr.includes(\"abnormal_high\") ||\n dr.includes(\"low\") || dr.includes(\"below\") || dr.includes(\"abnormal_low\");\n return {\n value: info.val != null ? String(info.val) : ((info as any).val_string ?? \"—\"),\n date: (info.display_time || \"\").replace(/['‘’]/g, \" \"),\n isOor,\n };\n });\n }, [trendData]);\n\n if (status === \"loading\") {\n return (\n <div className=\"mr-orig__vital-readings mr-orig__vital-readings--loading\">\n <LoaderCircle size={16} className=\"mr-sv__loading-spinner\" aria-hidden />\n </div>\n );\n }\n\n if (status === \"error\" || !readings.length) {\n return (\n <div className=\"mr-orig__vital-readings\">\n <Typography variant=\"muted\" className=\"mr-orig__vital-readings-empty\">\n No readings available\n </Typography>\n </div>\n );\n }\n\n return (\n <div className=\"mr-orig__vital-readings\">\n <div className=\"mr-orig__vital-readings-title\">\n LATEST READINGS FOR {vitalName.toUpperCase()}\n </div>\n <div className=\"mr-orig__vital-readings-grid\">\n {readings.map((r, i) => (\n <div key={i} className=\"mr-orig__vital-reading-item\">\n <span className={`mr-orig__vital-reading-value${r.isOor ? \" mr-orig__vital-reading-value--oor\" : \"\"}`}>{r.value}</span>\n <span className=\"mr-orig__vital-reading-date\">{r.date}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n"]}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
SmartSparkles_default,
|
|
4
4
|
toVitalNoteRows
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-LSDWS36C.mjs";
|
|
6
6
|
import {
|
|
7
7
|
useParameterTrend,
|
|
8
8
|
useRecordPanelTable,
|
|
9
9
|
useRecordPreview,
|
|
10
10
|
useSmartRecordsActions
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MI2JSHXL.mjs";
|
|
12
12
|
import {
|
|
13
13
|
IconButton,
|
|
14
14
|
SearchInput_default,
|
|
@@ -609,4 +609,4 @@ function VitalReadingsExpanded({ vitalName, ekaId }) {
|
|
|
609
609
|
export {
|
|
610
610
|
OriginalRecordPanel
|
|
611
611
|
};
|
|
612
|
-
//# sourceMappingURL=OriginalRecordPanel-
|
|
612
|
+
//# sourceMappingURL=OriginalRecordPanel-FBSPPGVL.mjs.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkQK7VGCUWjs = require('./chunk-QK7VGCUW.js');
|
|
5
|
+
require('./chunk-WUON6OEN.js');
|
|
6
|
+
require('./chunk-PN7IJ5MG.js');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
exports.VitalHistoryPanel = _chunkQK7VGCUWjs.VitalHistoryPanel;
|
|
10
|
+
//# sourceMappingURL=VitalHistoryPanel-V6NJE5JI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/VitalHistoryPanel-
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/VitalHistoryPanel-V6NJE5JI.js"],"names":[],"mappings":"AAAA,qFAAY;AACZ;AACE;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACF,+DAAC","file":"/home/runner/work/medical-records-ui/medical-records-ui/dist/VitalHistoryPanel-V6NJE5JI.js"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// src/icons/SmartSparkles.tsx
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
function SmartSparkles({ className, "aria-label": ariaLabel }) {
|
|
4
|
+
return /* @__PURE__ */ jsxs(
|
|
5
|
+
"svg",
|
|
6
|
+
{
|
|
7
|
+
width: "12",
|
|
8
|
+
height: "12",
|
|
9
|
+
viewBox: "0 0 12 12",
|
|
10
|
+
fill: "none",
|
|
11
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
12
|
+
className,
|
|
13
|
+
"aria-label": ariaLabel,
|
|
14
|
+
"aria-hidden": ariaLabel ? void 0 : true,
|
|
15
|
+
children: [
|
|
16
|
+
/* @__PURE__ */ jsx(
|
|
17
|
+
"path",
|
|
18
|
+
{
|
|
19
|
+
d: "M0 6C0 2.68629 2.68629 0 6 0C9.31371 0 12 2.68629 12 6C12 9.31371 9.31371 12 6 12C2.68629 12 0 9.31371 0 6Z",
|
|
20
|
+
fill: "#008055"
|
|
21
|
+
}
|
|
22
|
+
),
|
|
23
|
+
/* @__PURE__ */ jsx("g", { clipPath: "url(#clip0_879_4470)", children: /* @__PURE__ */ jsx(
|
|
24
|
+
"path",
|
|
25
|
+
{
|
|
26
|
+
d: "M5.99984 2.66667L7.02984 4.75333L9.33317 5.09L7.6665 6.71334L8.05984 9.00667L5.99984 7.92334L3.93984 9.00667L4.33317 6.71334L2.6665 5.09L4.96984 4.75333L5.99984 2.66667Z",
|
|
27
|
+
fill: "white"
|
|
28
|
+
}
|
|
29
|
+
) }),
|
|
30
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id: "clip0_879_4470", children: /* @__PURE__ */ jsx("rect", { width: "8", height: "8", fill: "white", transform: "translate(2 2)" }) }) })
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
var SmartSparkles_default = SmartSparkles;
|
|
36
|
+
|
|
37
|
+
// src/helpers/vitalsPanel.ts
|
|
38
|
+
function toVitalNoteRows(rows) {
|
|
39
|
+
return rows.map((r) => {
|
|
40
|
+
const cell = r.cells[0];
|
|
41
|
+
return { name: r.name, value: cell?.value ?? "\u2014", unit: r.unit, refRange: r.refRange };
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export {
|
|
46
|
+
SmartSparkles_default,
|
|
47
|
+
toVitalNoteRows
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=chunk-LSDWS36C.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/icons/SmartSparkles.tsx","../src/helpers/vitalsPanel.ts"],"sourcesContent":["function SmartSparkles({ className, \"aria-label\": ariaLabel }: { className?: string; \"aria-label\"?: string }) {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n aria-label={ariaLabel}\n aria-hidden={ariaLabel ? undefined : true}\n >\n <path\n d=\"M0 6C0 2.68629 2.68629 0 6 0C9.31371 0 12 2.68629 12 6C12 9.31371 9.31371 12 6 12C2.68629 12 0 9.31371 0 6Z\"\n fill=\"#008055\"\n />\n <g clipPath=\"url(#clip0_879_4470)\">\n <path\n d=\"M5.99984 2.66667L7.02984 4.75333L9.33317 5.09L7.6665 6.71334L8.05984 9.00667L5.99984 7.92334L3.93984 9.00667L4.33317 6.71334L2.6665 5.09L4.96984 4.75333L5.99984 2.66667Z\"\n fill=\"white\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_879_4470\">\n <rect width=\"8\" height=\"8\" fill=\"white\" transform=\"translate(2 2)\" />\n </clipPath>\n </defs>\n </svg>\n );\n}\n\nexport default SmartSparkles;","import type { VitalStatus } from './smartReport';\nimport type { ParameterTrendResponse, VitalLog } from '@eka-care/medical-records-ts-sdk';\n\nexport interface PanelCell {\n value: string;\n unit: string;\n date: string;\n dateEpoch: number;\n status: VitalStatus;\n refRange: string;\n recordId: string;\n}\n\nexport interface PanelRow {\n key: string;\n ekaId?: string;\n name: string;\n unit: string;\n refRange: string;\n cells: (PanelCell | null)[];\n latestStatus: VitalStatus;\n /** Record + vital id to open the existing per-vital history panel. */\n anchorRecordId: string;\n anchorVitalId: string;\n}\n\nexport interface PanelTable {\n columns: string[];\n rows: PanelRow[];\n}\n\n/** Structured shape for copy-to-note vitals table rendering (vital / value / reference value). */\nexport interface VitalNoteRow {\n name: string;\n value: string;\n unit: string;\n refRange: string;\n}\n\nexport function toVitalNoteRows(rows: PanelRow[]): VitalNoteRow[] {\n return rows.map((r) => {\n const cell = r.cells[0];\n return { name: r.name, value: cell?.value ?? '—', unit: r.unit, refRange: r.refRange };\n });\n}\n\n/** One parameter (table row) sourced from the case's smart records. */\nexport interface PanelParam {\n key: string;\n ekaId?: string;\n name: string;\n unit: string;\n refRange: string;\n /** The case record this param was anchored to (newest in the case). */\n anchorRecordId: string;\n /** The vital's id within that record's smart report — for openHistory(). */\n anchorVitalId: string;\n anchorEpoch: number;\n /** Used when the parameter has no trend (no ekaId, or the fetch failed). */\n fallbackValue: string;\n fallbackStatus: VitalStatus;\n}\n\nconst COLUMNS = ['Latest', 'Previous', 'Older'];\nconst COLUMN_COUNT = 3;\n\nfunction statusFromLog(log: VitalLog): VitalStatus {\n const label = (log.display_result ?? '').toLowerCase();\n if (label.includes('high') || label.includes('above')) return 'high';\n if (label.includes('low') || label.includes('below')) return 'low';\n if (label.includes('normal') || label.includes('in range') || label === 'ok') return 'normal';\n const v = log.val;\n const lo = log.range?.low;\n const hi = log.range?.high;\n if (typeof v === 'number') {\n if (typeof lo === 'number' && v < lo) return 'low';\n if (typeof hi === 'number' && v > hi) return 'high';\n if (typeof lo === 'number' || typeof hi === 'number') return 'normal';\n }\n return 'unknown';\n}\n\nfunction toCell(log: VitalLog, unit: string): PanelCell {\n const value =\n log.val != null ? String(log.val) : ((log as { val_string?: string }).val_string ?? '');\n return {\n value,\n unit,\n date: (log.display_time ?? '').replace(/['‘’]/g, ' '),\n dateEpoch: log.date ?? 0,\n status: statusFromLog(log),\n refRange: log.range?.display_text ?? '',\n recordId: log.document_id,\n };\n}\n\nfunction fallbackCell(p: PanelParam): PanelCell {\n return {\n value: p.fallbackValue,\n unit: p.unit,\n date: '',\n dateEpoch: p.anchorEpoch,\n status: p.fallbackStatus,\n refRange: p.refRange,\n recordId: p.anchorRecordId,\n };\n}\n\nconst isOutOfRange = (s: VitalStatus) => s === 'high' || s === 'low';\n\n/**\n * Merge the case's parameters with each parameter's full reading history into a\n * positional table: rows = parameters, columns = [Latest, Previous, Older].\n *\n * For each parameter we locate its anchor reading (the case's own record) inside\n * the patient-wide trend and take that reading plus the two before it. With\n * `anchorToCase: false`, columns are simply the patient's 3 most recent readings.\n */\nexport function buildVitalsPanel(\n params: PanelParam[],\n trendByEka: Map<string, ParameterTrendResponse>,\n opts: { anchorToCase?: boolean } = {},\n): PanelTable {\n const { anchorToCase = true } = opts;\n\n const rows: PanelRow[] = params.map((p) => {\n const trend = p.ekaId ? trendByEka.get(p.ekaId) : undefined;\n const unit = trend?.unit || p.unit;\n const logs = [...(trend?.vitals_info ?? [])].sort((a, b) => (b.date ?? 0) - (a.date ?? 0));\n\n let cells: (PanelCell | null)[];\n if (logs.length === 0) {\n cells = [fallbackCell(p)];\n } else {\n const idx = anchorToCase ? logs.findIndex((l) => l.document_id === p.anchorRecordId) : 0;\n const start = idx >= 0 ? idx : 0;\n cells = logs.slice(start, start + COLUMN_COUNT).map((l) => toCell(l, unit));\n }\n while (cells.length < COLUMN_COUNT) cells.push(null);\n\n return {\n key: p.key,\n ekaId: p.ekaId,\n name: p.name,\n unit,\n refRange: p.refRange,\n cells,\n latestStatus: cells[0]?.status ?? 'unknown',\n anchorRecordId: p.anchorRecordId,\n anchorVitalId: p.anchorVitalId,\n };\n });\n\n rows.sort((a, b) => {\n const oa = isOutOfRange(a.latestStatus) ? 0 : 1;\n const ob = isOutOfRange(b.latestStatus) ? 0 : 1;\n if (oa !== ob) return oa - ob;\n return a.name.localeCompare(b.name);\n });\n\n return { columns: COLUMNS, rows };\n}\n\n/** Run `fn` over `items` with at most `limit` promises in flight at once. */\nexport async function mapLimit<T, R>(\n items: T[],\n limit: number,\n fn: (item: T) => Promise<R>,\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let cursor = 0;\n const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {\n while (cursor < items.length) {\n const i = cursor++;\n results[i] = await fn(items[i]);\n }\n });\n await Promise.all(workers);\n return results;\n}\n"],"mappings":";AAEI,SAUE,KAVF;AAFJ,SAAS,cAAc,EAAE,WAAW,cAAc,UAAU,GAAkD;AAC5G,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN;AAAA,MACA,cAAY;AAAA,MACZ,eAAa,YAAY,SAAY;AAAA,MAErC;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA,oBAAC,OAAE,UAAS,wBACV;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP,GACF;AAAA,QACA,oBAAC,UACC,8BAAC,cAAS,IAAG,kBACX,8BAAC,UAAK,OAAM,KAAI,QAAO,KAAI,MAAK,SAAQ,WAAU,kBAAiB,GACrE,GACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,wBAAQ;;;ACQR,SAAS,gBAAgB,MAAkC;AAChE,SAAO,KAAK,IAAI,CAAC,MAAM;AACrB,UAAM,OAAO,EAAE,MAAM,CAAC;AACtB,WAAO,EAAE,MAAM,EAAE,MAAM,OAAO,MAAM,SAAS,UAAK,MAAM,EAAE,MAAM,UAAU,EAAE,SAAS;AAAA,EACvF,CAAC;AACH;","names":[]}
|
|
@@ -283,11 +283,10 @@ function useRecordPreview(documentId) {
|
|
|
283
283
|
export {
|
|
284
284
|
SmartRecordsActionsContext,
|
|
285
285
|
useSmartRecordsActions,
|
|
286
|
-
parseVitals,
|
|
287
286
|
isOutOfRange,
|
|
288
287
|
useParameterTrend,
|
|
289
288
|
invalidateRecordPanelTable,
|
|
290
289
|
useRecordPanelTable,
|
|
291
290
|
useRecordPreview
|
|
292
291
|
};
|
|
293
|
-
//# sourceMappingURL=chunk-
|
|
292
|
+
//# sourceMappingURL=chunk-MI2JSHXL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/views/context/SmartRecordsActionsContext.ts","../src/helpers/smartReport.ts","../src/views/hooks/care-panel/useParameterTrend.ts","../src/views/hooks/care-panel/useRecordPanelTable.ts","../src/connection/useRecordPreview.ts"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { VitalNoteRow } from \"../../helpers/vitalsPanel\";\n\nexport interface SmartRecordsActions {\n onCopyToNote?: (\n text: string,\n anchor?: { x: number; y: number },\n vitalsRows?: VitalNoteRow[],\n ) => void | boolean | Promise<void | boolean>;\n hasCopyToNote: boolean;\n onCopyVitalsToNote?: (text: string) => void | Promise<void>;\n selectRecord: (id: string, isSmart?: boolean) => void;\n openSmartRecord: (recordId: string, caseId?: string) => void;\n openHistory: (recordId: string, vitalId: string, returnTo?: \"smart\" | \"careContext\", caseId?: string) => void;\n openOriginal: (\n recordId: string,\n returnTo: \"smart\" | \"history\" | \"careContext\",\n returnVitalId?: string,\n returnCaseId?: string,\n ) => void;\n replaceOriginal: (recordId: string, returnCaseId?: string) => void;\n back: () => void;\n attachToContext?: (documentId: string, name: string) => void | Promise<void>;\n requestDelete: (id: string) => void;\n onToast?: (message: string, type: \"success\" | \"error\") => void;\n}\n\nexport const SmartRecordsActionsContext =\n createContext<SmartRecordsActions | null>(null);\n\nexport function useSmartRecordsActions(): SmartRecordsActions {\n const ctx = useContext(SmartRecordsActionsContext);\n if (!ctx)\n throw new Error(\n \"useSmartRecordsActions must be used inside SmartRecordsView\",\n );\n return ctx;\n}\n","export type VitalStatus = 'high' | 'low' | 'normal' | 'unknown';\n\nexport interface VitalHistoryPoint {\n value: string;\n label: string; \n}\nexport interface Vital {\n id: string;\n vitalId?: string;\n ekaId?: string;\n name: string;\n value: string;\n unit: string;\n refRange: string;\n status: VitalStatus;\n history: VitalHistoryPoint[];\n}\n\ntype RawField = Record<string, unknown>;\n\nconst str = (o: RawField, keys: string[]): string => {\n for (const k of keys) {\n const v = o[k];\n if (typeof v === 'string' && v.trim()) return v.trim();\n if (typeof v === 'number') return String(v);\n }\n return '';\n};\n\nconst normalizeStatus = (raw: string): VitalStatus => {\n const s = raw.toLowerCase();\n if (s.includes('high') || s === 'h' || s.includes('above') || s === 'abnormal_high') return 'high';\n if (s.includes('low') || s === 'l' || s.includes('below') || s === 'abnormal_low') return 'low';\n if (s.includes('normal') || s.includes('in range') || s === 'n' || s === 'ok') return 'normal';\n return 'unknown';\n};\n\n/**\n * Derive a status by comparing the numeric value against the reference range\n * when the report didn't give an explicit status. Handles \"min-max\",\n * \"min – max\", \"< x\" / \"<= x\", \"> x\" / \">= x\", and \"up to x\".\n */\nconst deriveStatusFromRange = (value: string, refRange: string): VitalStatus => {\n const num = parseFloat(value.replace(/,/g, ''));\n if (Number.isNaN(num) || !refRange) return 'unknown';\n const r = refRange.toLowerCase().replace(/,/g, '');\n\n // \"min - max\" (en-dash, hyphen, or \"to\")\n const between = r.match(/(-?\\d+\\.?\\d*)\\s*(?:-|–|to)\\s*(-?\\d+\\.?\\d*)/);\n if (between) {\n const lo = parseFloat(between[1]);\n const hi = parseFloat(between[2]);\n if (num < lo) return 'low';\n if (num > hi) return 'high';\n return 'normal';\n }\n // \"<= x\" / \"< x\" / \"up to x\" → only an upper bound\n const upper = r.match(/(?:<=?|up to|below)\\s*(-?\\d+\\.?\\d*)/);\n if (upper) return num > parseFloat(upper[1]) ? 'high' : 'normal';\n // \">= x\" / \"> x\" → only a lower bound\n const lower = r.match(/(?:>=?|above)\\s*(-?\\d+\\.?\\d*)/);\n if (lower) return num < parseFloat(lower[1]) ? 'low' : 'normal';\n\n return 'unknown';\n};\n\nfunction parseHistory(field: RawField): VitalHistoryPoint[] {\n const raw = field.history ?? field.previous ?? field.trend ?? field.historical;\n if (!Array.isArray(raw)) return [];\n return raw\n .map((p): VitalHistoryPoint | null => {\n if (p == null || typeof p !== 'object') return null;\n const o = p as RawField;\n const value = str(o, ['value', 'result', 'val', 'reading']);\n const label = str(o, ['date', 'label', 'when', 'at']);\n if (!value) return null;\n return { value, label: label || '' };\n })\n .filter((p): p is VitalHistoryPoint => p !== null);\n}\n\nexport function parseVitals(report: {\n verified?: RawField[];\n unverified?: RawField[];\n}): Vital[] {\n const fields = [...(report.verified ?? []), ...(report.unverified ?? [])];\n return fields\n .map((field, i): Vital | null => {\n const name = str(field, ['name', 'label', 'parameter', 'key', 'title', 'test']);\n const value = str(field, ['value', 'result', 'val', 'reading']);\n if (!name && !value) return null;\n const refRange = str(field, ['range', 'ref_range', 'reference', 'refRange', 'normal_range']);\n // Prefer an explicit status; otherwise compute it from value vs. range.\n let status = normalizeStatus(str(field, ['status', 'flag', 'interpretation', 'severity']));\n if (status === 'unknown') status = deriveStatusFromRange(value, refRange);\n const vitalId = str(field, ['vital_id', 'eka_id']) || undefined;\n const ekaId = str(field, ['eka_id']) || undefined;\n return {\n id: str(field, ['id', 'code']) || `${name || 'vital'}-${i}`,\n vitalId,\n ekaId,\n name: name || 'Unknown',\n value,\n unit: str(field, ['unit', 'units']),\n refRange,\n status,\n history: parseHistory(field),\n };\n })\n .filter((v): v is Vital => v !== null);\n}\n\nexport const isOutOfRange = (v: Vital): boolean => v.status === 'high' || v.status === 'low';\n\nexport function vitalsNoteHeading(opts?: { reportName?: string; date?: string }): string {\n return `**Vitals / Lab parameters — ${opts?.reportName ?? 'Report'}${\n opts?.date ? ` (${opts.date})` : ''\n }:**`;\n}\n\nexport function vitalsToNoteText(\n vitals: Vital[],\n opts?: { reportName?: string; date?: string },\n): string {\n const lines = vitals.map((v) => {\n const val = [v.value, v.unit].filter(Boolean).join(' ');\n return val ? `${v.name}: ${val}` : v.name;\n });\n return [vitalsNoteHeading(opts), ...lines].join('\\n');\n}\n","import { useEffect, useState } from \"react\";\nimport { getCore } from \"../../../connection/sdkClient\";\nimport { useSdk } from \"../../../connection/useSdk\";\n\nexport type ParameterTrendStatus = \"idle\" | \"loading\" | \"loaded\" | \"error\";\n\nexport function useParameterTrend(ekaId: string | undefined) {\n const { bid, patientId } = useSdk();\n const [data, setData] = useState<unknown>(null);\n const [status, setStatus] = useState<ParameterTrendStatus>(\"idle\");\n\n useEffect(() => {\n if (!ekaId || !bid || !patientId) return;\n setStatus(\"loading\");\n setData(null);\n let cancelled = false;\n getCore()\n .getParameterTrend({ parameterId: ekaId, bid, patientId })\n .then((res) => {\n if (!cancelled) {\n setData(res);\n setStatus(\"loaded\");\n }\n })\n .catch(() => {\n if (!cancelled) setStatus(\"error\");\n });\n return () => {\n cancelled = true;\n };\n }, [ekaId, bid, patientId]);\n\n return { data, status };\n}\n","import { useEffect, useState } from 'react';\nimport { useStore } from 'zustand';\nimport { useSdk } from '../../../connection/useSdk';\nimport { getCore } from '../../../connection/sdkClient';\nimport { parseVitals } from '../../../helpers/smartReport';\nimport { epochToDisplay } from '../../../helpers/formatters';\nimport type { PanelTable, PanelCell } from '../../../helpers/vitalsPanel';\nimport type { VitalStatus } from '../../../helpers/smartReport';\n\nexport type CarePanelStatus = 'idle' | 'loading' | 'loaded' | 'error';\n\nconst EMPTY: PanelTable = { columns: ['Latest'], rows: [] };\n\n// Module-level cache: recordId → { sig, table }\ninterface CacheEntry { sig: string; table: PanelTable }\nconst tableCache = new Map<string, CacheEntry>();\n\nfunction cacheGet(recordId: string, sig: string): PanelTable | null {\n const entry = tableCache.get(recordId);\n return entry?.sig === sig ? entry.table : null;\n}\n\nfunction cacheSet(recordId: string, sig: string, table: PanelTable): void {\n if (tableCache.size >= 100) {\n const oldest = tableCache.keys().next().value;\n if (oldest) tableCache.delete(oldest);\n }\n tableCache.set(recordId, { sig, table });\n}\n\nexport function invalidateRecordPanelTable(recordId: string): void {\n tableCache.delete(recordId);\n}\n\nconst OOR: VitalStatus[] = ['high', 'low'];\n\nexport function useRecordPanelTable(recordId: string | null) {\n const { store, bid, patientId } = useSdk();\n const recordSig = useStore(store, (s) => {\n const r = recordId ? s.records.byId[recordId] : undefined;\n return r?.isSmart ? `${r.id}:${r.createdAtEpoch}` : '';\n });\n\n const [status, setStatus] = useState<CarePanelStatus>(() => {\n if (!recordId || !recordSig) return 'idle';\n return cacheGet(recordId, recordSig) ? 'loaded' : 'idle';\n });\n const [table, setTable] = useState<PanelTable>(() => {\n if (!recordId || !recordSig) return EMPTY;\n return cacheGet(recordId, recordSig) ?? EMPTY;\n });\n\n useEffect(() => {\n if (!recordId || !recordSig) {\n setStatus('idle');\n setTable(EMPTY);\n return;\n }\n\n const record = store.getState().records.byId[recordId];\n if (!record?.isSmart) {\n setStatus('idle');\n setTable(EMPTY);\n return;\n }\n\n const cached = cacheGet(recordId, recordSig);\n if (cached) {\n setTable(cached);\n setStatus('loaded');\n return;\n }\n\n let cancelled = false;\n setStatus('loading');\n\n (async () => {\n try {\n const rep = await getCore().getSmartReport({ documentId: recordId, bid, patientId });\n if (cancelled) return;\n\n const vitals = rep\n ? parseVitals(rep as unknown as Parameters<typeof parseVitals>[0])\n : [];\n\n if (vitals.length === 0) {\n setStatus('loaded');\n setTable(EMPTY);\n return;\n }\n\n const dateStr = epochToDisplay(record.createdAtEpoch);\n\n const rows = vitals.map((v) => {\n const cell: PanelCell = {\n value: v.value,\n unit: v.unit,\n date: dateStr,\n dateEpoch: record.createdAtEpoch,\n status: v.status,\n refRange: v.refRange,\n recordId: record.id,\n };\n return {\n key: v.ekaId ?? `name:${v.name.trim().toLowerCase()}`,\n ekaId: v.ekaId,\n name: v.name,\n unit: v.unit,\n refRange: v.refRange,\n cells: [cell] as (PanelCell | null)[],\n latestStatus: v.status,\n anchorRecordId: record.id,\n anchorVitalId: v.id,\n };\n });\n\n rows.sort((a, b) => {\n const oa = OOR.includes(a.latestStatus) ? 0 : 1;\n const ob = OOR.includes(b.latestStatus) ? 0 : 1;\n if (oa !== ob) return oa - ob;\n return a.name.localeCompare(b.name);\n });\n\n const result: PanelTable = { columns: ['Latest'], rows };\n cacheSet(recordId, recordSig, result);\n setTable(result);\n setStatus('loaded');\n } catch {\n if (!cancelled) {\n setStatus('error');\n setTable(EMPTY);\n }\n }\n })();\n\n return () => { cancelled = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [recordId, recordSig, bid, patientId]);\n\n return { status, table };\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { useSdk } from './useSdk';\nimport { getCore } from './sdkClient';\nimport { parseVitals, type Vital } from '../helpers/smartReport';\n\nexport type PreviewFileKind = 'pdf' | 'image' | 'text';\nexport interface PreviewFile {\n url: string;\n kind: PreviewFileKind;\n}\n\n/**\n * The SDK's `file_type` is inconsistent — sometimes the typed union ('PDF'|'IMG'\n * |'HTML'), sometimes a MIME string ('application/pdf', 'image/png') when served\n * from the blob cache. Normalise both into a viewer kind.\n */\nfunction classifyFile(rawType: string | undefined): PreviewFileKind {\n const t = (rawType ?? '').toLowerCase();\n if (t.includes('pdf')) return 'pdf';\n if (t.includes('image') || t === 'img' || /(png|jpe?g|gif|webp|heic)/.test(t)) return 'image';\n return 'text';\n}\n\nexport interface RecordPreviewData {\n status: 'loading' | 'loaded' | 'error';\n files: PreviewFile[];\n vitals: Vital[];\n hasSmartReport: boolean;\n isHtml: boolean;\n}\n\nconst EMPTY: RecordPreviewData = {\n status: 'loading',\n files: [],\n vitals: [],\n hasSmartReport: false,\n isHtml: false,\n};\n\n/**\n * Fetch the full detail of the open record — the file attachments (signed URLs)\n * for the document viewer and the smart report parsed into vitals. Runs only\n * for the single record being previewed (not every card).\n */\nexport function useRecordPreview(documentId: string | null): RecordPreviewData {\n const { bid, patientId } = useSdk();\n const [data, setData] = useState<RecordPreviewData>(EMPTY);\n const inflightRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!documentId) {\n setData(EMPTY);\n return;\n }\n\n if (inflightRef.current === documentId) return;\n inflightRef.current = documentId;\n\n let cancelled = false;\n setData(EMPTY);\n\n (async () => {\n try {\n const res = await getCore().describeDocument({ documentId, bid, patientId, preferenceType: 'HTML' });\n if (cancelled) return;\n const rawFiles = res.files ?? [];\n const files: PreviewFile[] = rawFiles\n .filter((f) => f.asset_url)\n .map((f) => ({ url: f.asset_url, kind: classifyFile(f.file_type) }));\n const isHtml = (rawFiles[0]?.file_type ?? '').toUpperCase() === 'HTML';\n const vitals = res.smart_report ? parseVitals(res.smart_report as unknown as Parameters<typeof parseVitals>[0]) : [];\n setData({\n status: 'loaded',\n files,\n vitals,\n hasSmartReport: res.smart_report != null,\n isHtml,\n });\n } catch {\n if (!cancelled) setData({ status: 'error', files: [], vitals: [], hasSmartReport: false, isHtml: false });\n }\n })();\n\n return () => {\n cancelled = true;\n inflightRef.current = null;\n };\n }, [documentId, bid, patientId]);\n\n return data;\n}\n"],"mappings":"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","names":["useEffect","useState","useState","useEffect","useEffect","useState","EMPTY","useState","useEffect"]}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkWUON6OENjs = require('./chunk-WUON6OEN.js');
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
var _chunkPN7IJ5MGjs = require('./chunk-PN7IJ5MG.js');
|
|
@@ -19,7 +19,7 @@ var _reactvirtual = require('@tanstack/react-virtual');
|
|
|
19
19
|
function useVitalHistoryPanel(vital, points) {
|
|
20
20
|
const [selected, setSelected] = _react.useState.call(void 0, /* @__PURE__ */ new Set());
|
|
21
21
|
const outOfRangeCount = _react.useMemo.call(void 0,
|
|
22
|
-
() => points.filter((p) =>
|
|
22
|
+
() => points.filter((p) => _chunkWUON6OENjs.isOutOfRange.call(void 0, { ...vital, status: p.status })).length,
|
|
23
23
|
[points, vital]
|
|
24
24
|
);
|
|
25
25
|
const allSelected = points.length > 0 && points.every((_, i) => selected.has(i));
|
|
@@ -89,7 +89,7 @@ var HistoryRow = _react.memo.call(void 0, function HistoryRow2({
|
|
|
89
89
|
onToggle,
|
|
90
90
|
onViewRecord
|
|
91
91
|
}) {
|
|
92
|
-
const oor =
|
|
92
|
+
const oor = _chunkWUON6OENjs.isOutOfRange.call(void 0, { ...vital, status: point.status });
|
|
93
93
|
const handleToggle = _react.useCallback.call(void 0, () => onToggle(index), [onToggle, index]);
|
|
94
94
|
const handleViewRecord = _react.useCallback.call(void 0,
|
|
95
95
|
() => onViewRecord(point.recordId, "history", vital.id),
|
|
@@ -171,19 +171,19 @@ function VitalHistoryPanel({
|
|
|
171
171
|
vitalId,
|
|
172
172
|
caseId
|
|
173
173
|
}) {
|
|
174
|
-
const { back, openOriginal: _openOriginal, onCopyToNote, onCopyVitalsToNote, onToast } =
|
|
174
|
+
const { back, openOriginal: _openOriginal, onCopyToNote, onCopyVitalsToNote, onToast } = _chunkWUON6OENjs.useSmartRecordsActions.call(void 0, );
|
|
175
175
|
const openOriginal = _react.useCallback.call(void 0,
|
|
176
176
|
(recordId2, returnTo, returnVitalId) => {
|
|
177
|
-
|
|
177
|
+
_chunkWUON6OENjs.invalidateRecordPanelTable.call(void 0, recordId2);
|
|
178
178
|
_openOriginal(recordId2, caseId ? "careContext" : returnTo, returnVitalId, caseId);
|
|
179
179
|
},
|
|
180
180
|
[_openOriginal, caseId]
|
|
181
181
|
);
|
|
182
|
-
const preview =
|
|
182
|
+
const preview = _chunkWUON6OENjs.useRecordPreview.call(void 0, recordId);
|
|
183
183
|
const vital = preview.vitals.find((v) => v.id === vitalId);
|
|
184
184
|
const copyBtnRef = _react.useRef.call(void 0, null);
|
|
185
185
|
const scrollRef = _react.useRef.call(void 0, null);
|
|
186
|
-
const { data: trendData, status: trendStatus } =
|
|
186
|
+
const { data: trendData, status: trendStatus } = _chunkWUON6OENjs.useParameterTrend.call(void 0,
|
|
187
187
|
_optionalChain([vital, 'optionalAccess', _2 => _2.ekaId])
|
|
188
188
|
);
|
|
189
189
|
const points = _react.useMemo.call(void 0, () => {
|
|
@@ -440,4 +440,4 @@ function VitalHistoryPanel({
|
|
|
440
440
|
|
|
441
441
|
|
|
442
442
|
exports.VitalHistoryPanel = VitalHistoryPanel;
|
|
443
|
-
//# sourceMappingURL=chunk-
|
|
443
|
+
//# sourceMappingURL=chunk-QK7VGCUW.js.map
|