@eka-care/medical-records-ui 1.0.55 → 1.0.57

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.
@@ -137,19 +137,21 @@ function OriginalRecordPanel({
137
137
  srAllSelected ? /* @__PURE__ */ new Set() : new Set(filteredRows.map((r) => r.key))
138
138
  );
139
139
  }, [srAllSelected, filteredRows]);
140
- const handleSrCopyToNote = _react.useCallback.call(void 0, () => {
140
+ const handleSrCopyToNote = _react.useCallback.call(void 0, async () => {
141
141
  const selectedRows = filteredRows.filter((r) => srSelected.has(r.key));
142
142
  if (!selectedRows.length) return;
143
143
  const text = buildVitalsText(selectedRows);
144
144
  if (onCopyVitalsToNote) {
145
- void onCopyVitalsToNote(text);
145
+ await onCopyVitalsToNote(text);
146
+ setSrSelected(/* @__PURE__ */ new Set());
146
147
  } else if (onCopyToNote) {
147
148
  const rect = _optionalChain([srCopyBtnRef, 'access', _4 => _4.current, 'optionalAccess', _5 => _5.getBoundingClientRect, 'call', _6 => _6()]);
148
- void onCopyToNote(
149
+ const result = await onCopyToNote(
149
150
  text,
150
151
  rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : void 0,
151
152
  _chunkQYUEKKMVjs.toVitalNoteRows.call(void 0, selectedRows)
152
153
  );
154
+ if (result !== false) setSrSelected(/* @__PURE__ */ new Set());
153
155
  }
154
156
  }, [filteredRows, srSelected, onCopyVitalsToNote, onCopyToNote]);
155
157
  const htmlCopyBtnRef = _react.useRef.call(void 0, null);
@@ -487,4 +489,4 @@ function VitalReadingsExpanded({ vitalName, ekaId }) {
487
489
 
488
490
 
489
491
  exports.OriginalRecordPanel = OriginalRecordPanel;
490
- //# sourceMappingURL=OriginalRecordPanel-PR35G6KV.js.map
492
+ //# sourceMappingURL=OriginalRecordPanel-DCGRXQST.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/views/components/shared/OriginalRecordPanel.tsx"],"sourcesContent":["\"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 {/* Prev/next record carousel + dropdown — temporarily disabled, will re-enable later.\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 </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 */}\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\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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/OriginalRecordPanel-DCGRXQST.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-DCGRXQST.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(async () => {\n const selectedRows = filteredRows.filter((r) => srSelected.has(r.key));\n if (!selectedRows.length) return;\n const text = buildVitalsText(selectedRows);\n if (onCopyVitalsToNote) {\n await onCopyVitalsToNote(text);\n setSrSelected(new Set());\n } else if (onCopyToNote) {\n const rect = srCopyBtnRef.current?.getBoundingClientRect();\n const result = await onCopyToNote(\n text,\n rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : undefined,\n toVitalNoteRows(selectedRows),\n );\n if (result !== false) setSrSelected(new Set());\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 {/* Prev/next record carousel + dropdown — temporarily disabled, will re-enable later.\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 </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 */}\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\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"]}
@@ -137,19 +137,21 @@ function OriginalRecordPanel({
137
137
  srAllSelected ? /* @__PURE__ */ new Set() : new Set(filteredRows.map((r) => r.key))
138
138
  );
139
139
  }, [srAllSelected, filteredRows]);
140
- const handleSrCopyToNote = useCallback(() => {
140
+ const handleSrCopyToNote = useCallback(async () => {
141
141
  const selectedRows = filteredRows.filter((r) => srSelected.has(r.key));
142
142
  if (!selectedRows.length) return;
143
143
  const text = buildVitalsText(selectedRows);
144
144
  if (onCopyVitalsToNote) {
145
- void onCopyVitalsToNote(text);
145
+ await onCopyVitalsToNote(text);
146
+ setSrSelected(/* @__PURE__ */ new Set());
146
147
  } else if (onCopyToNote) {
147
148
  const rect = srCopyBtnRef.current?.getBoundingClientRect();
148
- void onCopyToNote(
149
+ const result = await onCopyToNote(
149
150
  text,
150
151
  rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : void 0,
151
152
  toVitalNoteRows(selectedRows)
152
153
  );
154
+ if (result !== false) setSrSelected(/* @__PURE__ */ new Set());
153
155
  }
154
156
  }, [filteredRows, srSelected, onCopyVitalsToNote, onCopyToNote]);
155
157
  const htmlCopyBtnRef = useRef(null);
@@ -487,4 +489,4 @@ function VitalReadingsExpanded({ vitalName, ekaId }) {
487
489
  export {
488
490
  OriginalRecordPanel
489
491
  };
490
- //# sourceMappingURL=OriginalRecordPanel-QYGV744W.mjs.map
492
+ //# sourceMappingURL=OriginalRecordPanel-NGLSSJLE.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/views/components/shared/OriginalRecordPanel.tsx"],"sourcesContent":["\"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(async () => {\n const selectedRows = filteredRows.filter((r) => srSelected.has(r.key));\n if (!selectedRows.length) return;\n const text = buildVitalsText(selectedRows);\n if (onCopyVitalsToNote) {\n await onCopyVitalsToNote(text);\n setSrSelected(new Set());\n } else if (onCopyToNote) {\n const rect = srCopyBtnRef.current?.getBoundingClientRect();\n const result = await onCopyToNote(\n text,\n rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : undefined,\n toVitalNoteRows(selectedRows),\n );\n if (result !== false) setSrSelected(new Set());\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 {/* Prev/next record carousel + dropdown — temporarily disabled, will re-enable later.\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 </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 */}\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\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"],"mappings":"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","names":[]}
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  VitalHistoryPanel
4
- } from "./chunk-IIAX5R33.mjs";
4
+ } from "./chunk-5TPILQYM.mjs";
5
5
  import "./chunk-7AO6M347.mjs";
6
6
  import "./chunk-NZNI6YJ5.mjs";
7
7
  export {
8
8
  VitalHistoryPanel
9
9
  };
10
- //# sourceMappingURL=VitalHistoryPanel-76GSKJPJ.mjs.map
10
+ //# sourceMappingURL=VitalHistoryPanel-FT5VMJ37.mjs.map
@@ -0,0 +1,10 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
+
3
+
4
+ var _chunkKTHLLAAGjs = require('./chunk-KTHLLAAG.js');
5
+ require('./chunk-STQYPHI3.js');
6
+ require('./chunk-QGGLSO4W.js');
7
+
8
+
9
+ exports.VitalHistoryPanel = _chunkKTHLLAAGjs.VitalHistoryPanel;
10
+ //# sourceMappingURL=VitalHistoryPanel-VQQ27P6Q.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/VitalHistoryPanel-7GT3GZEJ.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-7GT3GZEJ.js"}
1
+ {"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/VitalHistoryPanel-VQQ27P6Q.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-VQQ27P6Q.js"}
@@ -235,6 +235,7 @@ function VitalHistoryPanel({
235
235
  someSelected,
236
236
  togglePoint,
237
237
  toggleAll,
238
+ clearSelection,
238
239
  buildHistoryText
239
240
  } = useVitalHistoryPanel(
240
241
  vital ?? {
@@ -248,21 +249,23 @@ function VitalHistoryPanel({
248
249
  },
249
250
  filteredPoints
250
251
  );
251
- const handleCopyToNote = useCallback2(() => {
252
+ const handleCopyToNote = useCallback2(async () => {
252
253
  const chosen = points.filter((_, i) => selected.has(i));
253
254
  if (!chosen.length) return;
254
255
  const text = buildHistoryText(chosen);
255
256
  if (onCopyVitalsToNote) {
256
- void onCopyVitalsToNote(text);
257
+ await onCopyVitalsToNote(text);
258
+ clearSelection();
257
259
  } else if (onCopyToNote) {
258
260
  const rect = copyBtnRef.current?.getBoundingClientRect();
259
- void onCopyToNote(
261
+ const result = await onCopyToNote(
260
262
  text,
261
263
  rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : void 0,
262
264
  vital ? toHistoryNoteRows(vital, chosen) : void 0
263
265
  );
266
+ if (result !== false) clearSelection();
264
267
  }
265
- }, [points, selected, buildHistoryText, onCopyVitalsToNote, onCopyToNote, vital]);
268
+ }, [points, selected, buildHistoryText, onCopyVitalsToNote, onCopyToNote, vital, clearSelection]);
266
269
  const hasCopyToNote = !!(onCopyToNote || onCopyVitalsToNote);
267
270
  if (preview.status === "loading") {
268
271
  return /* @__PURE__ */ jsx(
@@ -440,4 +443,4 @@ function VitalHistoryPanel({
440
443
  export {
441
444
  VitalHistoryPanel
442
445
  };
443
- //# sourceMappingURL=chunk-IIAX5R33.mjs.map
446
+ //# sourceMappingURL=chunk-5TPILQYM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/views/containers/care-panel/VitalHistoryPanel.tsx","../src/views/hooks/care-panel/useVitalHistoryPanel.ts"],"sourcesContent":["\"use client\";\n\nimport { ChevronLeft, Check, LoaderCircle } from \"lucide-react\";\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { isOutOfRange } from \"../../../helpers/smartReport\";\nimport { useSmartRecordsActions } from \"../../context/SmartRecordsActionsContext\";\nimport { useVitalHistoryPanel } from \"../../hooks/care-panel/useVitalHistoryPanel\";\nimport { useParameterTrend } from \"../../hooks/care-panel/useParameterTrend\";\nimport { invalidateRecordPanelTable } from \"../../hooks/care-panel/useRecordPanelTable\";\nimport { useRecordPreview } from \"../../../connection/useRecordPreview\";\nimport type { HistoryPoint } from \"../../types\";\nimport type {\n VitalStatus,\n Vital,\n VitalHistoryPoint,\n} from \"../../../helpers/smartReport\";\nimport type { VitalNoteRow } from \"../../../helpers/vitalsPanel\";\nimport type { ParameterTrendResponse } from \"@eka-care/medical-records-ts-sdk\";\nimport { Typography } from \"widgets\";\n\nconst HISTORY_COLS = \"2fr 2fr 88px\";\n\n// One row per reading — date is folded into `value` since the shared note\n// table has no dedicated date column (each reading needs to stay distinguishable).\nfunction toHistoryNoteRows(vital: Vital, pts: HistoryPoint[]): VitalNoteRow[] {\n return pts.map((p) => {\n const dateSuffix = p.date ? ` (${p.date}${p.caseLabel ? ` · ${p.caseLabel}` : \"\"})` : \"\";\n return {\n name: vital.name,\n value: `${p.value}${p.unit ? ` ${p.unit}` : \"\"}${dateSuffix}`,\n unit: \"\",\n refRange: vital.refRange,\n };\n });\n}\n\nfunction normalizeStatus(displayResult: string): VitalStatus {\n const s = displayResult.toLowerCase();\n if (s.includes(\"high\") || s.includes(\"above\") || s === \"abnormal_high\")\n return \"high\";\n if (s.includes(\"low\") || s.includes(\"below\") || s === \"abnormal_low\")\n return \"low\";\n if (s.includes(\"normal\") || s.includes(\"in range\") || s === \"ok\")\n return \"normal\";\n return \"unknown\";\n}\n\ninterface VitalHistoryPanelProps {\n recordId: string;\n vitalId: string;\n caseId?: string;\n returnTo?: \"smart\" | \"careContext\";\n}\n\ninterface HistoryRowProps {\n index: number;\n point: HistoryPoint;\n vital: Vital;\n isSelected: boolean;\n isLast: boolean;\n onToggle: (i: number) => void;\n onViewRecord: (\n recordId: string,\n returnTo: \"smart\" | \"history\",\n returnVitalId?: string,\n ) => void;\n}\n\nconst HistoryRow = memo(function HistoryRow({\n index,\n point,\n vital,\n isSelected,\n isLast,\n onToggle,\n onViewRecord,\n}: HistoryRowProps) {\n const oor = isOutOfRange({ ...vital, status: point.status });\n const handleToggle = useCallback(() => onToggle(index), [onToggle, index]);\n const handleViewRecord = useCallback(\n () => onViewRecord(point.recordId, \"history\", vital.id),\n [onViewRecord, point.recordId, vital.id],\n );\n\n return (\n <div className={`mr-cc-table__row-wrap${isLast ? \" mr-cc-table__row-wrap--last\" : \"\"}`}>\n <div\n className={`mr-cc-table__row${isSelected ? \" mr-cc-table__row--selected\" : \"\"}`}\n role=\"row\"\n style={{ gridTemplateColumns: HISTORY_COLS, cursor: \"pointer\" }}\n onClick={handleToggle}\n >\n <div\n className=\"mr-cc-table__reading-cell\"\n role=\"cell\"\n style={{ flexDirection: \"row\", alignItems: \"center\", gap: \"8px\" }}\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 handleToggle();\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n handleToggle();\n }\n }}\n >\n {isSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <div className=\"mr-cc-table__reading-value-row\">\n {point.value ? (\n <>\n <span\n className={`mr-cc-table__rvalue${oor ? \" mr-cc-table__rvalue--oor\" : \"\"}`}\n >\n {point.value}\n </span>\n {point.unit && (\n <span className=\"mr-cc-table__runit\">{point.unit}</span>\n )}\n </>\n ) : (\n <span className=\"mr-cc-table__empty-dash\">—</span>\n )}\n </div>\n </div>\n\n <div className=\"mr-cc-table__reading-cell\" role=\"cell\">\n {point.date ? (\n <span className=\"mr-cc-table__rvalue\">{point.date}</span>\n ) : (\n <span className=\"mr-cc-table__empty-dash\">—</span>\n )}\n </div>\n\n <div\n className=\"mr-cc-table__actions\"\n role=\"cell\"\n onClick={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n className=\"mr-sv__view-record-btn\"\n onClick={handleViewRecord}\n >\n View record\n </button>\n </div>\n </div>\n </div>\n );\n});\n\nexport function VitalHistoryPanel({\n recordId,\n vitalId,\n caseId,\n}: VitalHistoryPanelProps) {\n const { back, openOriginal: _openOriginal, onCopyToNote, onCopyVitalsToNote, onToast } =\n useSmartRecordsActions();\n\n const openOriginal = useCallback(\n (recordId: string, returnTo: \"smart\" | \"history\" | \"careContext\", returnVitalId?: string) => {\n invalidateRecordPanelTable(recordId);\n _openOriginal(recordId, caseId ? \"careContext\" : returnTo, returnVitalId, caseId);\n },\n [_openOriginal, caseId],\n );\n const preview = useRecordPreview(recordId);\n const vital = preview.vitals.find((v) => v.id === vitalId);\n const copyBtnRef = useRef<HTMLButtonElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n const { data: trendData, status: trendStatus } = useParameterTrend(\n vital?.ekaId,\n );\n\n const points = useMemo((): HistoryPoint[] => {\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 .map((info) => ({\n date: (info.display_time || \"\").replace(/['‘’]/g, \" \"),\n caseLabel: \"\",\n value:\n info.val !== undefined\n ? String(info.val)\n : ((info as any).val_string ?? \"\"),\n unit: trend.unit,\n status: normalizeStatus(info.display_result ?? \"\"),\n recordId: info.document_id,\n recordName: trend.name,\n }));\n }, [trendData]);\n\n type VhpTab = \"all\" | \"oor\" | \"none\";\n const [activeTab, setActiveTab] = useState<VhpTab>(\"all\");\n\n const oorCount = useMemo(\n () => points.filter((p) => p.status === \"high\" || p.status === \"low\").length,\n [points],\n );\n const noneCount = useMemo(\n () => points.filter((p) => p.status === \"unknown\").length,\n [points],\n );\n\n useEffect(() => {\n if (activeTab === \"oor\" && oorCount === 0) setActiveTab(\"all\");\n if (activeTab === \"none\" && noneCount === 0) setActiveTab(\"all\");\n }, [activeTab, oorCount, noneCount]);\n\n useEffect(() => {\n if (trendStatus === \"error\") {\n back();\n onToast?.(\"Failed to load vital history\", \"error\");\n }\n }, [trendStatus, back, onToast]);\n\n const filteredPoints = useMemo(() => {\n if (activeTab === \"oor\") return points.filter((p) => p.status === \"high\" || p.status === \"low\");\n if (activeTab === \"none\") return points.filter((p) => p.status === \"unknown\");\n return points;\n }, [points, activeTab]);\n\n const rowVirtualizer = useVirtualizer({\n count: filteredPoints.length,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 50,\n overscan: 5,\n });\n\n const {\n selected,\n allSelected,\n someSelected,\n togglePoint,\n toggleAll,\n clearSelection,\n buildHistoryText,\n } = useVitalHistoryPanel(\n vital ?? {\n id: vitalId,\n name: \"\",\n value: \"\",\n unit: \"\",\n refRange: \"\",\n status: \"normal\" as VitalStatus,\n history: [] as VitalHistoryPoint[],\n },\n filteredPoints,\n );\n\n const handleCopyToNote = useCallback(async () => {\n const chosen = points.filter((_, i) => selected.has(i));\n if (!chosen.length) return;\n const text = buildHistoryText(chosen);\n if (onCopyVitalsToNote) {\n await onCopyVitalsToNote(text);\n clearSelection();\n } else if (onCopyToNote) {\n const rect = copyBtnRef.current?.getBoundingClientRect();\n const result = await onCopyToNote(\n text,\n rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : undefined,\n vital ? toHistoryNoteRows(vital, chosen) : undefined,\n );\n if (result !== false) clearSelection();\n }\n }, [points, selected, buildHistoryText, onCopyVitalsToNote, onCopyToNote, vital, clearSelection]);\n\n const hasCopyToNote = !!(onCopyToNote || onCopyVitalsToNote);\n\n if (preview.status === \"loading\") {\n return (\n <div\n className=\"mr-sv__panel\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <LoaderCircle\n size={32}\n className=\"mr-sv__loading-spinner\"\n aria-hidden\n />\n </div>\n );\n }\n\n if (!vital) {\n return (\n <div className=\"mr-sv__panel\">\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n Vital not found.\n </Typography>\n </div>\n );\n }\n\n return (\n <div className=\"mr-sv__panel\">\n <div className=\"mr-sv__back-row\">\n <button type=\"button\" className=\"mr-sv__back-btn\" onClick={back}>\n <ChevronLeft size={16} aria-hidden />\n Back\n </button>\n </div>\n {/* Header */}\n <div className=\"mr-sv__panel-header\">\n <div className=\"mr-sv__panel-left\">\n <div className=\"mr-sv__panel-info\">\n <div className=\"mr-sv__panel-name-row\">\n <Typography\n variant=\"label\"\n as=\"span\"\n className=\"mr-sv__panel-name\"\n >\n {vital.name}\n </Typography>\n {vital.refRange && (\n <span className=\"mr-sv__panel-ref-badge\">\n Ref: {vital.refRange}\n </span>\n )}\n </div>\n <div className=\"mr-sv__panel-meta\">\n {trendStatus === \"loaded\" && (\n <span>\n {points.length} reading{points.length !== 1 ? \"s\" : \"\"}\n {oorCount > 0 && (\n <>\n {\" \"}\n ·{\" \"}\n <span className=\"mr-sv__oor\">\n {oorCount} out of range\n </span>\n </>\n )}\n </span>\n )}\n </div>\n </div>\n </div>\n <span className=\"mr-cc-panel__viewing-label\">Viewing vital history</span>\n </div>\n\n {/* Filter tabs — only shown when at least one sub-category has data */}\n {trendStatus === \"loaded\" && points.length > 0 && (oorCount > 0 || noneCount > 0) && (\n <div className=\"mr-orig__smart-tabs-wrap\" style={{ padding: \"8px 16px 0\" }}>\n <div className=\"mr-orig__smart-tabs\">\n {([\"all\", \"oor\", \"none\"] as VhpTab[]).map((tab) => {\n if (tab === \"oor\" && oorCount === 0) return null;\n if (tab === \"none\" && noneCount === 0) return null;\n const count = tab === \"all\" ? points.length : tab === \"oor\" ? oorCount : noneCount;\n const label = tab === \"all\" ? \"All\" : tab === \"oor\" ? \"Out of range\" : \"No interpretation\";\n return (\n <button\n key={tab}\n type=\"button\"\n className={`mr-orig__smart-tab${activeTab === tab ? \" mr-orig__smart-tab--active\" : \"\"}`}\n onClick={() => setActiveTab(tab)}\n >\n {label} ({count})\n </button>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Body */}\n <div className=\"mr-sv__panel-body\" ref={scrollRef} style={{ overflowY: \"auto\" }}>\n {trendStatus === \"loading\" && (\n <div className=\"mr-cc-table mr-cc-table--state\">\n <LoaderCircle size={20} className=\"mr-sv__loading-spinner\" aria-hidden />\n <Typography variant=\"muted\">Loading vital history…</Typography>\n </div>\n )}\n {trendStatus === \"loaded\" && points.length === 0 && (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No historical data available for this vital.\n </Typography>\n )}\n {points.length > 0 && (\n <div className=\"mr-vhp-table\" role=\"table\">\n <div\n className=\"mr-cc-table__row mr-cc-table__row--head\"\n role=\"row\"\n style={{ gridTemplateColumns: HISTORY_COLS, margin: 0 }}\n >\n <span className=\"mr-cc-table__head-cell\" role=\"columnheader\">READING</span>\n <span className=\"mr-cc-table__head-cell\" role=\"columnheader\">DATE</span>\n <span className=\"mr-cc-table__head-cell\" aria-hidden />\n </div>\n {filteredPoints.length === 0 ? (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No readings match this filter.\n </Typography>\n ) : (\n <div style={{ height: `${rowVirtualizer.getTotalSize()}px`, position: \"relative\" }}>\n {rowVirtualizer.getVirtualItems().map((virtualRow) => (\n <div\n key={virtualRow.key}\n data-index={virtualRow.index}\n ref={rowVirtualizer.measureElement}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n <HistoryRow\n index={virtualRow.index}\n point={filteredPoints[virtualRow.index]}\n vital={vital}\n isSelected={selected.has(virtualRow.index)}\n isLast={virtualRow.index === filteredPoints.length - 1}\n onToggle={togglePoint}\n onViewRecord={openOriginal}\n />\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"mr-cc-table__footer\">\n <span\n className={`mr-sv__checkbox mr-cc-table__footer-check${allSelected ? \" mr-sv__checkbox--checked\" : \"\"}`}\n role=\"checkbox\"\n aria-checked={allSelected}\n tabIndex={0}\n onClick={toggleAll}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n toggleAll();\n }\n }}\n >\n {allSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <span className=\"mr-cc-table__footer-label\" onClick={toggleAll}>Select all</span>\n <span className=\"mr-cc-table__footer-count\">{selected.size} of {points.length} selected</span>\n <button\n ref={copyBtnRef}\n type=\"button\"\n className=\"mr-cc-table__copy-note-btn\"\n disabled={!someSelected || !hasCopyToNote}\n onClick={handleCopyToNote}\n >\n Copy to note\n </button>\n </div>\n </div>\n );\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport { isOutOfRange } from \"../../../helpers/smartReport\";\nimport type { Vital, HistoryPoint } from \"../../types\";\n\nexport function useVitalHistoryPanel(vital: Vital, points: HistoryPoint[]) {\n const [selected, setSelected] = useState<Set<number>>(new Set());\n\n const outOfRangeCount = useMemo(\n () => points.filter((p) => isOutOfRange({ ...vital, status: p.status })).length,\n [points, vital],\n );\n\n const allSelected = points.length > 0 && points.every((_, i) => selected.has(i));\n const someSelected = selected.size > 0;\n\n const togglePoint = useCallback((i: number) => {\n setSelected((prev) => {\n const n = new Set(prev);\n n.has(i) ? n.delete(i) : n.add(i);\n return n;\n });\n }, []);\n\n const toggleAll = useCallback(() => {\n setSelected(allSelected ? new Set() : new Set(points.map((_, i) => i)));\n }, [allSelected, points]);\n\n const clearSelection = useCallback(() => setSelected(new Set()), []);\n\n const buildHistoryText = useCallback(\n (pts: HistoryPoint[]) => {\n const lines = pts.map(\n (p) => `${vital.name}: ${p.value} ${p.unit} (${p.date}${p.caseLabel ? ` · ${p.caseLabel}` : \"\"})`,\n );\n return [`**${vital.name} — Historical data:**`, ...lines].join(\"\\n\");\n },\n [vital.name],\n );\n\n return {\n selected,\n outOfRangeCount,\n allSelected,\n someSelected,\n togglePoint,\n toggleAll,\n clearSelection,\n buildHistoryText,\n };\n}\n"],"mappings":"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","names":["useCallback","useMemo","useState","HistoryRow","useCallback","recordId","useMemo","useState"]}
@@ -235,6 +235,7 @@ function VitalHistoryPanel({
235
235
  someSelected,
236
236
  togglePoint,
237
237
  toggleAll,
238
+ clearSelection,
238
239
  buildHistoryText
239
240
  } = useVitalHistoryPanel(
240
241
  _nullishCoalesce(vital, () => ( {
@@ -248,21 +249,23 @@ function VitalHistoryPanel({
248
249
  })),
249
250
  filteredPoints
250
251
  );
251
- const handleCopyToNote = _react.useCallback.call(void 0, () => {
252
+ const handleCopyToNote = _react.useCallback.call(void 0, async () => {
252
253
  const chosen = points.filter((_, i) => selected.has(i));
253
254
  if (!chosen.length) return;
254
255
  const text = buildHistoryText(chosen);
255
256
  if (onCopyVitalsToNote) {
256
- void onCopyVitalsToNote(text);
257
+ await onCopyVitalsToNote(text);
258
+ clearSelection();
257
259
  } else if (onCopyToNote) {
258
260
  const rect = _optionalChain([copyBtnRef, 'access', _6 => _6.current, 'optionalAccess', _7 => _7.getBoundingClientRect, 'call', _8 => _8()]);
259
- void onCopyToNote(
261
+ const result = await onCopyToNote(
260
262
  text,
261
263
  rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : void 0,
262
264
  vital ? toHistoryNoteRows(vital, chosen) : void 0
263
265
  );
266
+ if (result !== false) clearSelection();
264
267
  }
265
- }, [points, selected, buildHistoryText, onCopyVitalsToNote, onCopyToNote, vital]);
268
+ }, [points, selected, buildHistoryText, onCopyVitalsToNote, onCopyToNote, vital, clearSelection]);
266
269
  const hasCopyToNote = !!(onCopyToNote || onCopyVitalsToNote);
267
270
  if (preview.status === "loading") {
268
271
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -440,4 +443,4 @@ function VitalHistoryPanel({
440
443
 
441
444
 
442
445
  exports.VitalHistoryPanel = VitalHistoryPanel;
443
- //# sourceMappingURL=chunk-636WE5XC.js.map
446
+ //# sourceMappingURL=chunk-KTHLLAAG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/chunk-KTHLLAAG.js","../src/views/containers/care-panel/VitalHistoryPanel.tsx","../src/views/hooks/care-panel/useVitalHistoryPanel.ts"],"names":[],"mappings":"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","file":"/home/runner/work/medical-records-ui/medical-records-ui/dist/chunk-KTHLLAAG.js","sourcesContent":[null,"\"use client\";\n\nimport { ChevronLeft, Check, LoaderCircle } from \"lucide-react\";\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { isOutOfRange } from \"../../../helpers/smartReport\";\nimport { useSmartRecordsActions } from \"../../context/SmartRecordsActionsContext\";\nimport { useVitalHistoryPanel } from \"../../hooks/care-panel/useVitalHistoryPanel\";\nimport { useParameterTrend } from \"../../hooks/care-panel/useParameterTrend\";\nimport { invalidateRecordPanelTable } from \"../../hooks/care-panel/useRecordPanelTable\";\nimport { useRecordPreview } from \"../../../connection/useRecordPreview\";\nimport type { HistoryPoint } from \"../../types\";\nimport type {\n VitalStatus,\n Vital,\n VitalHistoryPoint,\n} from \"../../../helpers/smartReport\";\nimport type { VitalNoteRow } from \"../../../helpers/vitalsPanel\";\nimport type { ParameterTrendResponse } from \"@eka-care/medical-records-ts-sdk\";\nimport { Typography } from \"widgets\";\n\nconst HISTORY_COLS = \"2fr 2fr 88px\";\n\n// One row per reading — date is folded into `value` since the shared note\n// table has no dedicated date column (each reading needs to stay distinguishable).\nfunction toHistoryNoteRows(vital: Vital, pts: HistoryPoint[]): VitalNoteRow[] {\n return pts.map((p) => {\n const dateSuffix = p.date ? ` (${p.date}${p.caseLabel ? ` · ${p.caseLabel}` : \"\"})` : \"\";\n return {\n name: vital.name,\n value: `${p.value}${p.unit ? ` ${p.unit}` : \"\"}${dateSuffix}`,\n unit: \"\",\n refRange: vital.refRange,\n };\n });\n}\n\nfunction normalizeStatus(displayResult: string): VitalStatus {\n const s = displayResult.toLowerCase();\n if (s.includes(\"high\") || s.includes(\"above\") || s === \"abnormal_high\")\n return \"high\";\n if (s.includes(\"low\") || s.includes(\"below\") || s === \"abnormal_low\")\n return \"low\";\n if (s.includes(\"normal\") || s.includes(\"in range\") || s === \"ok\")\n return \"normal\";\n return \"unknown\";\n}\n\ninterface VitalHistoryPanelProps {\n recordId: string;\n vitalId: string;\n caseId?: string;\n returnTo?: \"smart\" | \"careContext\";\n}\n\ninterface HistoryRowProps {\n index: number;\n point: HistoryPoint;\n vital: Vital;\n isSelected: boolean;\n isLast: boolean;\n onToggle: (i: number) => void;\n onViewRecord: (\n recordId: string,\n returnTo: \"smart\" | \"history\",\n returnVitalId?: string,\n ) => void;\n}\n\nconst HistoryRow = memo(function HistoryRow({\n index,\n point,\n vital,\n isSelected,\n isLast,\n onToggle,\n onViewRecord,\n}: HistoryRowProps) {\n const oor = isOutOfRange({ ...vital, status: point.status });\n const handleToggle = useCallback(() => onToggle(index), [onToggle, index]);\n const handleViewRecord = useCallback(\n () => onViewRecord(point.recordId, \"history\", vital.id),\n [onViewRecord, point.recordId, vital.id],\n );\n\n return (\n <div className={`mr-cc-table__row-wrap${isLast ? \" mr-cc-table__row-wrap--last\" : \"\"}`}>\n <div\n className={`mr-cc-table__row${isSelected ? \" mr-cc-table__row--selected\" : \"\"}`}\n role=\"row\"\n style={{ gridTemplateColumns: HISTORY_COLS, cursor: \"pointer\" }}\n onClick={handleToggle}\n >\n <div\n className=\"mr-cc-table__reading-cell\"\n role=\"cell\"\n style={{ flexDirection: \"row\", alignItems: \"center\", gap: \"8px\" }}\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 handleToggle();\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n handleToggle();\n }\n }}\n >\n {isSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <div className=\"mr-cc-table__reading-value-row\">\n {point.value ? (\n <>\n <span\n className={`mr-cc-table__rvalue${oor ? \" mr-cc-table__rvalue--oor\" : \"\"}`}\n >\n {point.value}\n </span>\n {point.unit && (\n <span className=\"mr-cc-table__runit\">{point.unit}</span>\n )}\n </>\n ) : (\n <span className=\"mr-cc-table__empty-dash\">—</span>\n )}\n </div>\n </div>\n\n <div className=\"mr-cc-table__reading-cell\" role=\"cell\">\n {point.date ? (\n <span className=\"mr-cc-table__rvalue\">{point.date}</span>\n ) : (\n <span className=\"mr-cc-table__empty-dash\">—</span>\n )}\n </div>\n\n <div\n className=\"mr-cc-table__actions\"\n role=\"cell\"\n onClick={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n className=\"mr-sv__view-record-btn\"\n onClick={handleViewRecord}\n >\n View record\n </button>\n </div>\n </div>\n </div>\n );\n});\n\nexport function VitalHistoryPanel({\n recordId,\n vitalId,\n caseId,\n}: VitalHistoryPanelProps) {\n const { back, openOriginal: _openOriginal, onCopyToNote, onCopyVitalsToNote, onToast } =\n useSmartRecordsActions();\n\n const openOriginal = useCallback(\n (recordId: string, returnTo: \"smart\" | \"history\" | \"careContext\", returnVitalId?: string) => {\n invalidateRecordPanelTable(recordId);\n _openOriginal(recordId, caseId ? \"careContext\" : returnTo, returnVitalId, caseId);\n },\n [_openOriginal, caseId],\n );\n const preview = useRecordPreview(recordId);\n const vital = preview.vitals.find((v) => v.id === vitalId);\n const copyBtnRef = useRef<HTMLButtonElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n const { data: trendData, status: trendStatus } = useParameterTrend(\n vital?.ekaId,\n );\n\n const points = useMemo((): HistoryPoint[] => {\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 .map((info) => ({\n date: (info.display_time || \"\").replace(/['‘’]/g, \" \"),\n caseLabel: \"\",\n value:\n info.val !== undefined\n ? String(info.val)\n : ((info as any).val_string ?? \"\"),\n unit: trend.unit,\n status: normalizeStatus(info.display_result ?? \"\"),\n recordId: info.document_id,\n recordName: trend.name,\n }));\n }, [trendData]);\n\n type VhpTab = \"all\" | \"oor\" | \"none\";\n const [activeTab, setActiveTab] = useState<VhpTab>(\"all\");\n\n const oorCount = useMemo(\n () => points.filter((p) => p.status === \"high\" || p.status === \"low\").length,\n [points],\n );\n const noneCount = useMemo(\n () => points.filter((p) => p.status === \"unknown\").length,\n [points],\n );\n\n useEffect(() => {\n if (activeTab === \"oor\" && oorCount === 0) setActiveTab(\"all\");\n if (activeTab === \"none\" && noneCount === 0) setActiveTab(\"all\");\n }, [activeTab, oorCount, noneCount]);\n\n useEffect(() => {\n if (trendStatus === \"error\") {\n back();\n onToast?.(\"Failed to load vital history\", \"error\");\n }\n }, [trendStatus, back, onToast]);\n\n const filteredPoints = useMemo(() => {\n if (activeTab === \"oor\") return points.filter((p) => p.status === \"high\" || p.status === \"low\");\n if (activeTab === \"none\") return points.filter((p) => p.status === \"unknown\");\n return points;\n }, [points, activeTab]);\n\n const rowVirtualizer = useVirtualizer({\n count: filteredPoints.length,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 50,\n overscan: 5,\n });\n\n const {\n selected,\n allSelected,\n someSelected,\n togglePoint,\n toggleAll,\n clearSelection,\n buildHistoryText,\n } = useVitalHistoryPanel(\n vital ?? {\n id: vitalId,\n name: \"\",\n value: \"\",\n unit: \"\",\n refRange: \"\",\n status: \"normal\" as VitalStatus,\n history: [] as VitalHistoryPoint[],\n },\n filteredPoints,\n );\n\n const handleCopyToNote = useCallback(async () => {\n const chosen = points.filter((_, i) => selected.has(i));\n if (!chosen.length) return;\n const text = buildHistoryText(chosen);\n if (onCopyVitalsToNote) {\n await onCopyVitalsToNote(text);\n clearSelection();\n } else if (onCopyToNote) {\n const rect = copyBtnRef.current?.getBoundingClientRect();\n const result = await onCopyToNote(\n text,\n rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : undefined,\n vital ? toHistoryNoteRows(vital, chosen) : undefined,\n );\n if (result !== false) clearSelection();\n }\n }, [points, selected, buildHistoryText, onCopyVitalsToNote, onCopyToNote, vital, clearSelection]);\n\n const hasCopyToNote = !!(onCopyToNote || onCopyVitalsToNote);\n\n if (preview.status === \"loading\") {\n return (\n <div\n className=\"mr-sv__panel\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <LoaderCircle\n size={32}\n className=\"mr-sv__loading-spinner\"\n aria-hidden\n />\n </div>\n );\n }\n\n if (!vital) {\n return (\n <div className=\"mr-sv__panel\">\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n Vital not found.\n </Typography>\n </div>\n );\n }\n\n return (\n <div className=\"mr-sv__panel\">\n <div className=\"mr-sv__back-row\">\n <button type=\"button\" className=\"mr-sv__back-btn\" onClick={back}>\n <ChevronLeft size={16} aria-hidden />\n Back\n </button>\n </div>\n {/* Header */}\n <div className=\"mr-sv__panel-header\">\n <div className=\"mr-sv__panel-left\">\n <div className=\"mr-sv__panel-info\">\n <div className=\"mr-sv__panel-name-row\">\n <Typography\n variant=\"label\"\n as=\"span\"\n className=\"mr-sv__panel-name\"\n >\n {vital.name}\n </Typography>\n {vital.refRange && (\n <span className=\"mr-sv__panel-ref-badge\">\n Ref: {vital.refRange}\n </span>\n )}\n </div>\n <div className=\"mr-sv__panel-meta\">\n {trendStatus === \"loaded\" && (\n <span>\n {points.length} reading{points.length !== 1 ? \"s\" : \"\"}\n {oorCount > 0 && (\n <>\n {\" \"}\n ·{\" \"}\n <span className=\"mr-sv__oor\">\n {oorCount} out of range\n </span>\n </>\n )}\n </span>\n )}\n </div>\n </div>\n </div>\n <span className=\"mr-cc-panel__viewing-label\">Viewing vital history</span>\n </div>\n\n {/* Filter tabs — only shown when at least one sub-category has data */}\n {trendStatus === \"loaded\" && points.length > 0 && (oorCount > 0 || noneCount > 0) && (\n <div className=\"mr-orig__smart-tabs-wrap\" style={{ padding: \"8px 16px 0\" }}>\n <div className=\"mr-orig__smart-tabs\">\n {([\"all\", \"oor\", \"none\"] as VhpTab[]).map((tab) => {\n if (tab === \"oor\" && oorCount === 0) return null;\n if (tab === \"none\" && noneCount === 0) return null;\n const count = tab === \"all\" ? points.length : tab === \"oor\" ? oorCount : noneCount;\n const label = tab === \"all\" ? \"All\" : tab === \"oor\" ? \"Out of range\" : \"No interpretation\";\n return (\n <button\n key={tab}\n type=\"button\"\n className={`mr-orig__smart-tab${activeTab === tab ? \" mr-orig__smart-tab--active\" : \"\"}`}\n onClick={() => setActiveTab(tab)}\n >\n {label} ({count})\n </button>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Body */}\n <div className=\"mr-sv__panel-body\" ref={scrollRef} style={{ overflowY: \"auto\" }}>\n {trendStatus === \"loading\" && (\n <div className=\"mr-cc-table mr-cc-table--state\">\n <LoaderCircle size={20} className=\"mr-sv__loading-spinner\" aria-hidden />\n <Typography variant=\"muted\">Loading vital history…</Typography>\n </div>\n )}\n {trendStatus === \"loaded\" && points.length === 0 && (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No historical data available for this vital.\n </Typography>\n )}\n {points.length > 0 && (\n <div className=\"mr-vhp-table\" role=\"table\">\n <div\n className=\"mr-cc-table__row mr-cc-table__row--head\"\n role=\"row\"\n style={{ gridTemplateColumns: HISTORY_COLS, margin: 0 }}\n >\n <span className=\"mr-cc-table__head-cell\" role=\"columnheader\">READING</span>\n <span className=\"mr-cc-table__head-cell\" role=\"columnheader\">DATE</span>\n <span className=\"mr-cc-table__head-cell\" aria-hidden />\n </div>\n {filteredPoints.length === 0 ? (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No readings match this filter.\n </Typography>\n ) : (\n <div style={{ height: `${rowVirtualizer.getTotalSize()}px`, position: \"relative\" }}>\n {rowVirtualizer.getVirtualItems().map((virtualRow) => (\n <div\n key={virtualRow.key}\n data-index={virtualRow.index}\n ref={rowVirtualizer.measureElement}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n <HistoryRow\n index={virtualRow.index}\n point={filteredPoints[virtualRow.index]}\n vital={vital}\n isSelected={selected.has(virtualRow.index)}\n isLast={virtualRow.index === filteredPoints.length - 1}\n onToggle={togglePoint}\n onViewRecord={openOriginal}\n />\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"mr-cc-table__footer\">\n <span\n className={`mr-sv__checkbox mr-cc-table__footer-check${allSelected ? \" mr-sv__checkbox--checked\" : \"\"}`}\n role=\"checkbox\"\n aria-checked={allSelected}\n tabIndex={0}\n onClick={toggleAll}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n toggleAll();\n }\n }}\n >\n {allSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <span className=\"mr-cc-table__footer-label\" onClick={toggleAll}>Select all</span>\n <span className=\"mr-cc-table__footer-count\">{selected.size} of {points.length} selected</span>\n <button\n ref={copyBtnRef}\n type=\"button\"\n className=\"mr-cc-table__copy-note-btn\"\n disabled={!someSelected || !hasCopyToNote}\n onClick={handleCopyToNote}\n >\n Copy to note\n </button>\n </div>\n </div>\n );\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport { isOutOfRange } from \"../../../helpers/smartReport\";\nimport type { Vital, HistoryPoint } from \"../../types\";\n\nexport function useVitalHistoryPanel(vital: Vital, points: HistoryPoint[]) {\n const [selected, setSelected] = useState<Set<number>>(new Set());\n\n const outOfRangeCount = useMemo(\n () => points.filter((p) => isOutOfRange({ ...vital, status: p.status })).length,\n [points, vital],\n );\n\n const allSelected = points.length > 0 && points.every((_, i) => selected.has(i));\n const someSelected = selected.size > 0;\n\n const togglePoint = useCallback((i: number) => {\n setSelected((prev) => {\n const n = new Set(prev);\n n.has(i) ? n.delete(i) : n.add(i);\n return n;\n });\n }, []);\n\n const toggleAll = useCallback(() => {\n setSelected(allSelected ? new Set() : new Set(points.map((_, i) => i)));\n }, [allSelected, points]);\n\n const clearSelection = useCallback(() => setSelected(new Set()), []);\n\n const buildHistoryText = useCallback(\n (pts: HistoryPoint[]) => {\n const lines = pts.map(\n (p) => `${vital.name}: ${p.value} ${p.unit} (${p.date}${p.caseLabel ? ` · ${p.caseLabel}` : \"\"})`,\n );\n return [`**${vital.name} — Historical data:**`, ...lines].join(\"\\n\");\n },\n [vital.name],\n );\n\n return {\n selected,\n outOfRangeCount,\n allSelected,\n someSelected,\n togglePoint,\n toggleAll,\n clearSelection,\n buildHistoryText,\n };\n}\n"]}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }require('./chunk-636WE5XC.js');
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }require('./chunk-KTHLLAAG.js');
2
2
  require('./chunk-WXCGQDIL.js');
3
3
 
4
4
 
@@ -2432,12 +2432,12 @@ function CareContextEmptyState() {
2432
2432
 
2433
2433
 
2434
2434
  var VitalHistoryPanel2 = _react.lazy.call(void 0,
2435
- () => Promise.resolve().then(() => _interopRequireWildcard(require("./VitalHistoryPanel-7GT3GZEJ.js"))).then((m) => ({
2435
+ () => Promise.resolve().then(() => _interopRequireWildcard(require("./VitalHistoryPanel-VQQ27P6Q.js"))).then((m) => ({
2436
2436
  default: m.VitalHistoryPanel
2437
2437
  }))
2438
2438
  );
2439
2439
  var OriginalRecordPanel = _react.lazy.call(void 0,
2440
- () => Promise.resolve().then(() => _interopRequireWildcard(require("./OriginalRecordPanel-PR35G6KV.js"))).then((m) => ({
2440
+ () => Promise.resolve().then(() => _interopRequireWildcard(require("./OriginalRecordPanel-DCGRXQST.js"))).then((m) => ({
2441
2441
  default: m.OriginalRecordPanel
2442
2442
  }))
2443
2443
  );
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import "./chunk-IIAX5R33.mjs";
1
+ import "./chunk-5TPILQYM.mjs";
2
2
  import "./chunk-3J6XMPXB.mjs";
3
3
  import {
4
4
  SmartSparkles_default,
@@ -2432,12 +2432,12 @@ function CareContextEmptyState() {
2432
2432
  import { memo as memo5, Suspense as Suspense2, lazy as lazy2 } from "react";
2433
2433
  import { jsx as jsx11 } from "react/jsx-runtime";
2434
2434
  var VitalHistoryPanel2 = lazy2(
2435
- () => import("./VitalHistoryPanel-76GSKJPJ.mjs").then((m) => ({
2435
+ () => import("./VitalHistoryPanel-FT5VMJ37.mjs").then((m) => ({
2436
2436
  default: m.VitalHistoryPanel
2437
2437
  }))
2438
2438
  );
2439
2439
  var OriginalRecordPanel = lazy2(
2440
- () => import("./OriginalRecordPanel-QYGV744W.mjs").then((m) => ({
2440
+ () => import("./OriginalRecordPanel-NGLSSJLE.mjs").then((m) => ({
2441
2441
  default: m.OriginalRecordPanel
2442
2442
  }))
2443
2443
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eka-care/medical-records-ui",
3
- "version": "1.0.55",
3
+ "version": "1.0.57",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/OriginalRecordPanel-PR35G6KV.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-PR35G6KV.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 {/* Prev/next record carousel + dropdown — temporarily disabled, will re-enable later.\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 </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 */}\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\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,10 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
-
3
-
4
- var _chunk636WE5XCjs = require('./chunk-636WE5XC.js');
5
- require('./chunk-STQYPHI3.js');
6
- require('./chunk-QGGLSO4W.js');
7
-
8
-
9
- exports.VitalHistoryPanel = _chunk636WE5XCjs.VitalHistoryPanel;
10
- //# sourceMappingURL=VitalHistoryPanel-7GT3GZEJ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/medical-records-ui/medical-records-ui/dist/chunk-636WE5XC.js","../src/views/containers/care-panel/VitalHistoryPanel.tsx","../src/views/hooks/care-panel/useVitalHistoryPanel.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;ACTA,2CAAiD;AACjD,8BAAwE;AACxE,uDAA+B;ADW/B;AACA;AEhBA;AAIO,SAAS,oBAAA,CAAqB,KAAA,EAAc,MAAA,EAAwB;AACzE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,EAAA,EAAI,6BAAA,gBAAsB,IAAI,GAAA,CAAI,CAAC,CAAA;AAE/D,EAAA,MAAM,gBAAA,EAAkB,4BAAA;AAAA,IACtB,CAAA,EAAA,GAAM,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,EAAA,GAAM,2CAAA,EAAe,GAAG,KAAA,EAAO,MAAA,EAAQ,CAAA,CAAE,OAAO,CAAC,CAAC,CAAA,CAAE,MAAA;AAAA,IACzE,CAAC,MAAA,EAAQ,KAAK;AAAA,EAChB,CAAA;AAEA,EAAA,MAAM,YAAA,EAAc,MAAA,CAAO,OAAA,EAAS,EAAA,GAAK,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,EAAA,GAAM,QAAA,CAAS,GAAA,CAAI,CAAC,CAAC,CAAA;AAC/E,EAAA,MAAM,aAAA,EAAe,QAAA,CAAS,KAAA,EAAO,CAAA;AAErC,EAAA,MAAM,YAAA,EAAc,gCAAA,CAAa,CAAA,EAAA,GAAc;AAC7C,IAAA,WAAA,CAAY,CAAC,IAAA,EAAA,GAAS;AACpB,MAAA,MAAM,EAAA,EAAI,IAAI,GAAA,CAAI,IAAI,CAAA;AACtB,MAAA,CAAA,CAAE,GAAA,CAAI,CAAC,EAAA,EAAI,CAAA,CAAE,MAAA,CAAO,CAAC,EAAA,EAAI,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA;AAChC,MAAA,OAAO,CAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,CAAC,CAAA;AAEL,EAAA,MAAM,UAAA,EAAY,gCAAA,CAAY,EAAA,GAAM;AAClC,IAAA,WAAA,CAAY,YAAA,kBAAc,IAAI,GAAA,CAAI,EAAA,EAAI,IAAI,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,EAAA,GAAM,CAAC,CAAC,CAAC,CAAA;AAAA,EACxE,CAAA,EAAG,CAAC,WAAA,EAAa,MAAM,CAAC,CAAA;AAExB,EAAA,MAAM,eAAA,EAAiB,gCAAA,CAAY,EAAA,GAAM,WAAA,iBAAY,IAAI,GAAA,CAAI,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAEnE,EAAA,MAAM,iBAAA,EAAmB,gCAAA;AAAA,IACvB,CAAC,GAAA,EAAA,GAAwB;AACvB,MAAA,MAAM,MAAA,EAAQ,GAAA,CAAI,GAAA;AAAA,QAChB,CAAC,CAAA,EAAA,GAAM,CAAA,EAAA;AACT,MAAA;AACQ,MAAA;AACV,IAAA;AACW,IAAA;AACb,EAAA;AAEO,EAAA;AACL,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AACF;AFQgB;AACA;AC6DJ;AAlGN;AAIG;AACI,EAAA;AACH,IAAA;AACC,IAAA;AACC,MAAA;AACI,MAAA;AACJ,MAAA;AACI,MAAA;AACZ,IAAA;AACD,EAAA;AACH;AAES;AACG,EAAA;AACJ,EAAA;AACG,IAAA;AACH,EAAA;AACG,IAAA;AACH,EAAA;AACG,IAAA;AACF,EAAA;AACT;AAuBM;AACJ,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACkB;AACN,EAAA;AACN,EAAA;AACA,EAAA;AACE,IAAA;AACL,IAAA;AACH,EAAA;AAGE,EAAA;AACC,IAAA;AAAA,IAAA;AACC,MAAA;AACK,MAAA;AACI,MAAA;AACA,MAAA;AAET,MAAA;AAAA,wBAAA;AAAC,UAAA;AAAA,UAAA;AACC,YAAA;AACA,YAAA;AACA,YAAA;AAEA,YAAA;AAAA,8BAAA;AAAC,gBAAA;AAAA,gBAAA;AAAA,kBAAA;AACkG,kBAAA;AAC5F,kBAAA;AACS,kBAAA;AACJ,kBAAA;AAER,oBAAA;AACA,oBAAA;AAAa,kBAAA;AACf,kBAAA;AAEE,oBAAA;AACE,sBAAA;AACA,sBAAA;AACA,sBAAA;AAAa,oBAAA;AACf,kBAAA;AACF,kBAAA;AAEgD,gBAAA;AAClD,cAAA;AACA,8BAAA;AAGM,gCAAA;AAAA,kBAAA;AAAC,kBAAA;AAAA,oBAAA;AACwE,oBAAA;AAEhE,kBAAA;AACT,gBAAA;AACC,gBAAA;AACkD,cAAA;AAMzD,YAAA;AAAA,UAAA;AACF,QAAA;AAEA,wBAAA;AAQA,wBAAA;AAAC,UAAA;AAAA,UAAA;AACC,YAAA;AACA,YAAA;AACA,YAAA;AAEA,YAAA;AAAC,cAAA;AAAA,cAAA;AACC,gBAAA;AACA,gBAAA;AACA,gBAAA;AACD,gBAAA;AAAA,cAAA;AAED,YAAA;AAAA,UAAA;AACF,QAAA;AAAA,MAAA;AAAA,IAAA;AAEF,EAAA;AAEH;AAEe;AACd,EAAA;AACA,EAAA;AACA,EAAA;AACyB;AACX,EAAA;AAGR,EAAA;AACe,IAAA;AACjB,MAAA;AACA,MAAA;AACF,IAAA;AACC,IAAA;AACH,EAAA;AACM,EAAA;AACQ,EAAA;AACR,EAAA;AACA,EAAA;AAEQ,EAAA;AACL,oBAAA;AACT,EAAA;AAEM,EAAA;AACE,IAAA;AACM,IAAA;AACL,IAAA;AAGM,MAAA;AACP,MAAA;AAEE,MAAA;AAGI,MAAA;AACE,MAAA;AACE,MAAA;AACV,MAAA;AACF,IAAA;AACQ,EAAA;AAGP,EAAA;AAED,EAAA;AACE,IAAA;AACC,IAAA;AACT,EAAA;AACM,EAAA;AACE,IAAA;AACC,IAAA;AACT,EAAA;AAEU,EAAA;AACJ,IAAA;AACA,IAAA;AACF,EAAA;AAEM,EAAA;AACJ,IAAA;AACG,MAAA;AACK,sBAAA;AACZ,IAAA;AACE,EAAA;AAEE,EAAA;AACA,IAAA;AACA,IAAA;AACG,IAAA;AACG,EAAA;AAEN,EAAA;AACG,IAAA;AACP,IAAA;AACA,IAAA;AACU,IAAA;AACX,EAAA;AAEK,EAAA;AACJ,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACE,EAAA;AACO,qBAAA;AACH,MAAA;AACE,MAAA;AACC,MAAA;AACD,MAAA;AACI,MAAA;AACF,MAAA;AACE,MAAA;AACZ,IAAA;AACA,IAAA;AACF,EAAA;AAEM,EAAA;AACE,IAAA;AACM,IAAA;AACN,IAAA;AACF,IAAA;AACG,MAAA;AACI,IAAA;AACH,MAAA;AACD,MAAA;AACH,QAAA;AACO,QAAA;AACC,QAAA;AACV,MAAA;AACF,IAAA;AACU,EAAA;AAEN,EAAA;AAEM,EAAA;AAER,IAAA;AAAC,MAAA;AAAA,MAAA;AACC,QAAA;AACO,QAAA;AACL,UAAA;AACA,UAAA;AACA,UAAA;AACF,QAAA;AAEA,QAAA;AAAC,UAAA;AAAA,UAAA;AACC,YAAA;AACA,YAAA;AACA,YAAA;AAAW,UAAA;AACb,QAAA;AAAA,MAAA;AACF,IAAA;AAEJ,EAAA;AAEY,EAAA;AAER,IAAA;AAMJ,EAAA;AAGE,EAAA;AACE,oBAAA;AAEI,sBAAA;AAAqC,MAAA;AAGzC,IAAA;AAEA,oBAAA;AACE,sBAAA;AAEI,wBAAA;AACE,0BAAA;AAAC,YAAA;AAAA,YAAA;AACC,cAAA;AACA,cAAA;AACA,cAAA;AAEC,cAAA;AAAM,YAAA;AACT,UAAA;AACO,UAAA;AACoC,YAAA;AACjC,YAAA;AACR,UAAA;AAEJ,QAAA;AACA,wBAAA;AAGO,UAAA;AAAc,UAAA;AAAS,UAAA;AACvB,UAAA;AAEI,YAAA;AAAI,YAAA;AACH,YAAA;AACF,4BAAA;AACG,cAAA;AAAS,cAAA;AACZ,YAAA;AACF,UAAA;AAIR,QAAA;AAEJ,MAAA;AACA,sBAAA;AACF,IAAA;AAGC,IAAA;AAIW,MAAA;AACA,MAAA;AACE,MAAA;AACA,MAAA;AAEJ,MAAA;AAAC,QAAA;AAAA,QAAA;AAEM,UAAA;AACL,UAAA;AACA,UAAA;AAEC,UAAA;AAAA,YAAA;AAAM,YAAA;AAAG,YAAA;AAAM,YAAA;AAAA,UAAA;AAAA,QAAA;AALX,QAAA;AAMP,MAAA;AAIR,IAAA;AAIF,oBAAA;AACG,MAAA;AAEG,wBAAA;AACA,wBAAA;AACF,MAAA;AAED,MAAA;AAKO,MAAA;AAEJ,wBAAA;AAAC,UAAA;AAAA,UAAA;AACC,YAAA;AACA,YAAA;AACA,YAAA;AAEA,YAAA;AAAA,8BAAA;AACA,8BAAA;AACA,8BAAA;AAAqD,YAAA;AAAA,UAAA;AACvD,QAAA;AACC,QAAA;AAOM,UAAA;AAAA,UAAA;AAEC,YAAA;AACA,YAAA;AACA,YAAA;AACE,cAAA;AACA,cAAA;AACA,cAAA;AACA,cAAA;AACA,cAAA;AACF,YAAA;AAEA,YAAA;AAAC,cAAA;AAAA,cAAA;AACC,gBAAA;AACA,gBAAA;AACA,gBAAA;AACA,gBAAA;AACA,gBAAA;AACA,gBAAA;AACA,gBAAA;AAAc,cAAA;AAChB,YAAA;AAAA,UAAA;AAnBK,UAAA;AAsBX,QAAA;AAEJ,MAAA;AAEJ,IAAA;AAEA,oBAAA;AACE,sBAAA;AAAC,QAAA;AAAA,QAAA;AACC,UAAA;AACK,UAAA;AACL,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACM,YAAA;AACA,cAAA;AACF,cAAA;AACF,YAAA;AACF,UAAA;AAEC,UAAA;AAAgD,QAAA;AACnD,MAAA;AACA,sBAAA;AACA,sBAAA;AAA6C,QAAA;AAAc,QAAA;AAAY,QAAA;AAAO,QAAA;AAAS,MAAA;AACvF,sBAAA;AAAC,QAAA;AAAA,QAAA;AACM,UAAA;AACA,UAAA;AACL,UAAA;AACA,UAAA;AACA,UAAA;AACD,UAAA;AAAA,QAAA;AAED,MAAA;AACF,IAAA;AACF,EAAA;AAEJ;AD/BgB;AACA;AACA;AACA","file":"/home/runner/work/medical-records-ui/medical-records-ui/dist/chunk-636WE5XC.js","sourcesContent":[null,"\"use client\";\n\nimport { ChevronLeft, Check, LoaderCircle } from \"lucide-react\";\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { isOutOfRange } from \"../../../helpers/smartReport\";\nimport { useSmartRecordsActions } from \"../../context/SmartRecordsActionsContext\";\nimport { useVitalHistoryPanel } from \"../../hooks/care-panel/useVitalHistoryPanel\";\nimport { useParameterTrend } from \"../../hooks/care-panel/useParameterTrend\";\nimport { invalidateRecordPanelTable } from \"../../hooks/care-panel/useRecordPanelTable\";\nimport { useRecordPreview } from \"../../../connection/useRecordPreview\";\nimport type { HistoryPoint } from \"../../types\";\nimport type {\n VitalStatus,\n Vital,\n VitalHistoryPoint,\n} from \"../../../helpers/smartReport\";\nimport type { VitalNoteRow } from \"../../../helpers/vitalsPanel\";\nimport type { ParameterTrendResponse } from \"@eka-care/medical-records-ts-sdk\";\nimport { Typography } from \"widgets\";\n\nconst HISTORY_COLS = \"2fr 2fr 88px\";\n\n// One row per reading — date is folded into `value` since the shared note\n// table has no dedicated date column (each reading needs to stay distinguishable).\nfunction toHistoryNoteRows(vital: Vital, pts: HistoryPoint[]): VitalNoteRow[] {\n return pts.map((p) => {\n const dateSuffix = p.date ? ` (${p.date}${p.caseLabel ? ` · ${p.caseLabel}` : \"\"})` : \"\";\n return {\n name: vital.name,\n value: `${p.value}${p.unit ? ` ${p.unit}` : \"\"}${dateSuffix}`,\n unit: \"\",\n refRange: vital.refRange,\n };\n });\n}\n\nfunction normalizeStatus(displayResult: string): VitalStatus {\n const s = displayResult.toLowerCase();\n if (s.includes(\"high\") || s.includes(\"above\") || s === \"abnormal_high\")\n return \"high\";\n if (s.includes(\"low\") || s.includes(\"below\") || s === \"abnormal_low\")\n return \"low\";\n if (s.includes(\"normal\") || s.includes(\"in range\") || s === \"ok\")\n return \"normal\";\n return \"unknown\";\n}\n\ninterface VitalHistoryPanelProps {\n recordId: string;\n vitalId: string;\n caseId?: string;\n returnTo?: \"smart\" | \"careContext\";\n}\n\ninterface HistoryRowProps {\n index: number;\n point: HistoryPoint;\n vital: Vital;\n isSelected: boolean;\n isLast: boolean;\n onToggle: (i: number) => void;\n onViewRecord: (\n recordId: string,\n returnTo: \"smart\" | \"history\",\n returnVitalId?: string,\n ) => void;\n}\n\nconst HistoryRow = memo(function HistoryRow({\n index,\n point,\n vital,\n isSelected,\n isLast,\n onToggle,\n onViewRecord,\n}: HistoryRowProps) {\n const oor = isOutOfRange({ ...vital, status: point.status });\n const handleToggle = useCallback(() => onToggle(index), [onToggle, index]);\n const handleViewRecord = useCallback(\n () => onViewRecord(point.recordId, \"history\", vital.id),\n [onViewRecord, point.recordId, vital.id],\n );\n\n return (\n <div className={`mr-cc-table__row-wrap${isLast ? \" mr-cc-table__row-wrap--last\" : \"\"}`}>\n <div\n className={`mr-cc-table__row${isSelected ? \" mr-cc-table__row--selected\" : \"\"}`}\n role=\"row\"\n style={{ gridTemplateColumns: HISTORY_COLS, cursor: \"pointer\" }}\n onClick={handleToggle}\n >\n <div\n className=\"mr-cc-table__reading-cell\"\n role=\"cell\"\n style={{ flexDirection: \"row\", alignItems: \"center\", gap: \"8px\" }}\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 handleToggle();\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n handleToggle();\n }\n }}\n >\n {isSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <div className=\"mr-cc-table__reading-value-row\">\n {point.value ? (\n <>\n <span\n className={`mr-cc-table__rvalue${oor ? \" mr-cc-table__rvalue--oor\" : \"\"}`}\n >\n {point.value}\n </span>\n {point.unit && (\n <span className=\"mr-cc-table__runit\">{point.unit}</span>\n )}\n </>\n ) : (\n <span className=\"mr-cc-table__empty-dash\">—</span>\n )}\n </div>\n </div>\n\n <div className=\"mr-cc-table__reading-cell\" role=\"cell\">\n {point.date ? (\n <span className=\"mr-cc-table__rvalue\">{point.date}</span>\n ) : (\n <span className=\"mr-cc-table__empty-dash\">—</span>\n )}\n </div>\n\n <div\n className=\"mr-cc-table__actions\"\n role=\"cell\"\n onClick={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n className=\"mr-sv__view-record-btn\"\n onClick={handleViewRecord}\n >\n View record\n </button>\n </div>\n </div>\n </div>\n );\n});\n\nexport function VitalHistoryPanel({\n recordId,\n vitalId,\n caseId,\n}: VitalHistoryPanelProps) {\n const { back, openOriginal: _openOriginal, onCopyToNote, onCopyVitalsToNote, onToast } =\n useSmartRecordsActions();\n\n const openOriginal = useCallback(\n (recordId: string, returnTo: \"smart\" | \"history\" | \"careContext\", returnVitalId?: string) => {\n invalidateRecordPanelTable(recordId);\n _openOriginal(recordId, caseId ? \"careContext\" : returnTo, returnVitalId, caseId);\n },\n [_openOriginal, caseId],\n );\n const preview = useRecordPreview(recordId);\n const vital = preview.vitals.find((v) => v.id === vitalId);\n const copyBtnRef = useRef<HTMLButtonElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n const { data: trendData, status: trendStatus } = useParameterTrend(\n vital?.ekaId,\n );\n\n const points = useMemo((): HistoryPoint[] => {\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 .map((info) => ({\n date: (info.display_time || \"\").replace(/['‘’]/g, \" \"),\n caseLabel: \"\",\n value:\n info.val !== undefined\n ? String(info.val)\n : ((info as any).val_string ?? \"\"),\n unit: trend.unit,\n status: normalizeStatus(info.display_result ?? \"\"),\n recordId: info.document_id,\n recordName: trend.name,\n }));\n }, [trendData]);\n\n type VhpTab = \"all\" | \"oor\" | \"none\";\n const [activeTab, setActiveTab] = useState<VhpTab>(\"all\");\n\n const oorCount = useMemo(\n () => points.filter((p) => p.status === \"high\" || p.status === \"low\").length,\n [points],\n );\n const noneCount = useMemo(\n () => points.filter((p) => p.status === \"unknown\").length,\n [points],\n );\n\n useEffect(() => {\n if (activeTab === \"oor\" && oorCount === 0) setActiveTab(\"all\");\n if (activeTab === \"none\" && noneCount === 0) setActiveTab(\"all\");\n }, [activeTab, oorCount, noneCount]);\n\n useEffect(() => {\n if (trendStatus === \"error\") {\n back();\n onToast?.(\"Failed to load vital history\", \"error\");\n }\n }, [trendStatus, back, onToast]);\n\n const filteredPoints = useMemo(() => {\n if (activeTab === \"oor\") return points.filter((p) => p.status === \"high\" || p.status === \"low\");\n if (activeTab === \"none\") return points.filter((p) => p.status === \"unknown\");\n return points;\n }, [points, activeTab]);\n\n const rowVirtualizer = useVirtualizer({\n count: filteredPoints.length,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 50,\n overscan: 5,\n });\n\n const {\n selected,\n allSelected,\n someSelected,\n togglePoint,\n toggleAll,\n buildHistoryText,\n } = useVitalHistoryPanel(\n vital ?? {\n id: vitalId,\n name: \"\",\n value: \"\",\n unit: \"\",\n refRange: \"\",\n status: \"normal\" as VitalStatus,\n history: [] as VitalHistoryPoint[],\n },\n filteredPoints,\n );\n\n const handleCopyToNote = useCallback(() => {\n const chosen = points.filter((_, i) => selected.has(i));\n if (!chosen.length) return;\n const text = buildHistoryText(chosen);\n if (onCopyVitalsToNote) {\n void onCopyVitalsToNote(text);\n } else if (onCopyToNote) {\n const rect = copyBtnRef.current?.getBoundingClientRect();\n void onCopyToNote(\n text,\n rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : undefined,\n vital ? toHistoryNoteRows(vital, chosen) : undefined,\n );\n }\n }, [points, selected, buildHistoryText, onCopyVitalsToNote, onCopyToNote, vital]);\n\n const hasCopyToNote = !!(onCopyToNote || onCopyVitalsToNote);\n\n if (preview.status === \"loading\") {\n return (\n <div\n className=\"mr-sv__panel\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <LoaderCircle\n size={32}\n className=\"mr-sv__loading-spinner\"\n aria-hidden\n />\n </div>\n );\n }\n\n if (!vital) {\n return (\n <div className=\"mr-sv__panel\">\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n Vital not found.\n </Typography>\n </div>\n );\n }\n\n return (\n <div className=\"mr-sv__panel\">\n <div className=\"mr-sv__back-row\">\n <button type=\"button\" className=\"mr-sv__back-btn\" onClick={back}>\n <ChevronLeft size={16} aria-hidden />\n Back\n </button>\n </div>\n {/* Header */}\n <div className=\"mr-sv__panel-header\">\n <div className=\"mr-sv__panel-left\">\n <div className=\"mr-sv__panel-info\">\n <div className=\"mr-sv__panel-name-row\">\n <Typography\n variant=\"label\"\n as=\"span\"\n className=\"mr-sv__panel-name\"\n >\n {vital.name}\n </Typography>\n {vital.refRange && (\n <span className=\"mr-sv__panel-ref-badge\">\n Ref: {vital.refRange}\n </span>\n )}\n </div>\n <div className=\"mr-sv__panel-meta\">\n {trendStatus === \"loaded\" && (\n <span>\n {points.length} reading{points.length !== 1 ? \"s\" : \"\"}\n {oorCount > 0 && (\n <>\n {\" \"}\n ·{\" \"}\n <span className=\"mr-sv__oor\">\n {oorCount} out of range\n </span>\n </>\n )}\n </span>\n )}\n </div>\n </div>\n </div>\n <span className=\"mr-cc-panel__viewing-label\">Viewing vital history</span>\n </div>\n\n {/* Filter tabs — only shown when at least one sub-category has data */}\n {trendStatus === \"loaded\" && points.length > 0 && (oorCount > 0 || noneCount > 0) && (\n <div className=\"mr-orig__smart-tabs-wrap\" style={{ padding: \"8px 16px 0\" }}>\n <div className=\"mr-orig__smart-tabs\">\n {([\"all\", \"oor\", \"none\"] as VhpTab[]).map((tab) => {\n if (tab === \"oor\" && oorCount === 0) return null;\n if (tab === \"none\" && noneCount === 0) return null;\n const count = tab === \"all\" ? points.length : tab === \"oor\" ? oorCount : noneCount;\n const label = tab === \"all\" ? \"All\" : tab === \"oor\" ? \"Out of range\" : \"No interpretation\";\n return (\n <button\n key={tab}\n type=\"button\"\n className={`mr-orig__smart-tab${activeTab === tab ? \" mr-orig__smart-tab--active\" : \"\"}`}\n onClick={() => setActiveTab(tab)}\n >\n {label} ({count})\n </button>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Body */}\n <div className=\"mr-sv__panel-body\" ref={scrollRef} style={{ overflowY: \"auto\" }}>\n {trendStatus === \"loading\" && (\n <div className=\"mr-cc-table mr-cc-table--state\">\n <LoaderCircle size={20} className=\"mr-sv__loading-spinner\" aria-hidden />\n <Typography variant=\"muted\">Loading vital history…</Typography>\n </div>\n )}\n {trendStatus === \"loaded\" && points.length === 0 && (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No historical data available for this vital.\n </Typography>\n )}\n {points.length > 0 && (\n <div className=\"mr-vhp-table\" role=\"table\">\n <div\n className=\"mr-cc-table__row mr-cc-table__row--head\"\n role=\"row\"\n style={{ gridTemplateColumns: HISTORY_COLS, margin: 0 }}\n >\n <span className=\"mr-cc-table__head-cell\" role=\"columnheader\">READING</span>\n <span className=\"mr-cc-table__head-cell\" role=\"columnheader\">DATE</span>\n <span className=\"mr-cc-table__head-cell\" aria-hidden />\n </div>\n {filteredPoints.length === 0 ? (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No readings match this filter.\n </Typography>\n ) : (\n <div style={{ height: `${rowVirtualizer.getTotalSize()}px`, position: \"relative\" }}>\n {rowVirtualizer.getVirtualItems().map((virtualRow) => (\n <div\n key={virtualRow.key}\n data-index={virtualRow.index}\n ref={rowVirtualizer.measureElement}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n <HistoryRow\n index={virtualRow.index}\n point={filteredPoints[virtualRow.index]}\n vital={vital}\n isSelected={selected.has(virtualRow.index)}\n isLast={virtualRow.index === filteredPoints.length - 1}\n onToggle={togglePoint}\n onViewRecord={openOriginal}\n />\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"mr-cc-table__footer\">\n <span\n className={`mr-sv__checkbox mr-cc-table__footer-check${allSelected ? \" mr-sv__checkbox--checked\" : \"\"}`}\n role=\"checkbox\"\n aria-checked={allSelected}\n tabIndex={0}\n onClick={toggleAll}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n toggleAll();\n }\n }}\n >\n {allSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <span className=\"mr-cc-table__footer-label\" onClick={toggleAll}>Select all</span>\n <span className=\"mr-cc-table__footer-count\">{selected.size} of {points.length} selected</span>\n <button\n ref={copyBtnRef}\n type=\"button\"\n className=\"mr-cc-table__copy-note-btn\"\n disabled={!someSelected || !hasCopyToNote}\n onClick={handleCopyToNote}\n >\n Copy to note\n </button>\n </div>\n </div>\n );\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport { isOutOfRange } from \"../../../helpers/smartReport\";\nimport type { Vital, HistoryPoint } from \"../../types\";\n\nexport function useVitalHistoryPanel(vital: Vital, points: HistoryPoint[]) {\n const [selected, setSelected] = useState<Set<number>>(new Set());\n\n const outOfRangeCount = useMemo(\n () => points.filter((p) => isOutOfRange({ ...vital, status: p.status })).length,\n [points, vital],\n );\n\n const allSelected = points.length > 0 && points.every((_, i) => selected.has(i));\n const someSelected = selected.size > 0;\n\n const togglePoint = useCallback((i: number) => {\n setSelected((prev) => {\n const n = new Set(prev);\n n.has(i) ? n.delete(i) : n.add(i);\n return n;\n });\n }, []);\n\n const toggleAll = useCallback(() => {\n setSelected(allSelected ? new Set() : new Set(points.map((_, i) => i)));\n }, [allSelected, points]);\n\n const clearSelection = useCallback(() => setSelected(new Set()), []);\n\n const buildHistoryText = useCallback(\n (pts: HistoryPoint[]) => {\n const lines = pts.map(\n (p) => `${vital.name}: ${p.value} ${p.unit} (${p.date}${p.caseLabel ? ` · ${p.caseLabel}` : \"\"})`,\n );\n return [`**${vital.name} — Historical data:**`, ...lines].join(\"\\n\");\n },\n [vital.name],\n );\n\n return {\n selected,\n outOfRangeCount,\n allSelected,\n someSelected,\n togglePoint,\n toggleAll,\n clearSelection,\n buildHistoryText,\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/views/containers/care-panel/VitalHistoryPanel.tsx","../src/views/hooks/care-panel/useVitalHistoryPanel.ts"],"sourcesContent":["\"use client\";\n\nimport { ChevronLeft, Check, LoaderCircle } from \"lucide-react\";\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { isOutOfRange } from \"../../../helpers/smartReport\";\nimport { useSmartRecordsActions } from \"../../context/SmartRecordsActionsContext\";\nimport { useVitalHistoryPanel } from \"../../hooks/care-panel/useVitalHistoryPanel\";\nimport { useParameterTrend } from \"../../hooks/care-panel/useParameterTrend\";\nimport { invalidateRecordPanelTable } from \"../../hooks/care-panel/useRecordPanelTable\";\nimport { useRecordPreview } from \"../../../connection/useRecordPreview\";\nimport type { HistoryPoint } from \"../../types\";\nimport type {\n VitalStatus,\n Vital,\n VitalHistoryPoint,\n} from \"../../../helpers/smartReport\";\nimport type { VitalNoteRow } from \"../../../helpers/vitalsPanel\";\nimport type { ParameterTrendResponse } from \"@eka-care/medical-records-ts-sdk\";\nimport { Typography } from \"widgets\";\n\nconst HISTORY_COLS = \"2fr 2fr 88px\";\n\n// One row per reading — date is folded into `value` since the shared note\n// table has no dedicated date column (each reading needs to stay distinguishable).\nfunction toHistoryNoteRows(vital: Vital, pts: HistoryPoint[]): VitalNoteRow[] {\n return pts.map((p) => {\n const dateSuffix = p.date ? ` (${p.date}${p.caseLabel ? ` · ${p.caseLabel}` : \"\"})` : \"\";\n return {\n name: vital.name,\n value: `${p.value}${p.unit ? ` ${p.unit}` : \"\"}${dateSuffix}`,\n unit: \"\",\n refRange: vital.refRange,\n };\n });\n}\n\nfunction normalizeStatus(displayResult: string): VitalStatus {\n const s = displayResult.toLowerCase();\n if (s.includes(\"high\") || s.includes(\"above\") || s === \"abnormal_high\")\n return \"high\";\n if (s.includes(\"low\") || s.includes(\"below\") || s === \"abnormal_low\")\n return \"low\";\n if (s.includes(\"normal\") || s.includes(\"in range\") || s === \"ok\")\n return \"normal\";\n return \"unknown\";\n}\n\ninterface VitalHistoryPanelProps {\n recordId: string;\n vitalId: string;\n caseId?: string;\n returnTo?: \"smart\" | \"careContext\";\n}\n\ninterface HistoryRowProps {\n index: number;\n point: HistoryPoint;\n vital: Vital;\n isSelected: boolean;\n isLast: boolean;\n onToggle: (i: number) => void;\n onViewRecord: (\n recordId: string,\n returnTo: \"smart\" | \"history\",\n returnVitalId?: string,\n ) => void;\n}\n\nconst HistoryRow = memo(function HistoryRow({\n index,\n point,\n vital,\n isSelected,\n isLast,\n onToggle,\n onViewRecord,\n}: HistoryRowProps) {\n const oor = isOutOfRange({ ...vital, status: point.status });\n const handleToggle = useCallback(() => onToggle(index), [onToggle, index]);\n const handleViewRecord = useCallback(\n () => onViewRecord(point.recordId, \"history\", vital.id),\n [onViewRecord, point.recordId, vital.id],\n );\n\n return (\n <div className={`mr-cc-table__row-wrap${isLast ? \" mr-cc-table__row-wrap--last\" : \"\"}`}>\n <div\n className={`mr-cc-table__row${isSelected ? \" mr-cc-table__row--selected\" : \"\"}`}\n role=\"row\"\n style={{ gridTemplateColumns: HISTORY_COLS, cursor: \"pointer\" }}\n onClick={handleToggle}\n >\n <div\n className=\"mr-cc-table__reading-cell\"\n role=\"cell\"\n style={{ flexDirection: \"row\", alignItems: \"center\", gap: \"8px\" }}\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 handleToggle();\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n handleToggle();\n }\n }}\n >\n {isSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <div className=\"mr-cc-table__reading-value-row\">\n {point.value ? (\n <>\n <span\n className={`mr-cc-table__rvalue${oor ? \" mr-cc-table__rvalue--oor\" : \"\"}`}\n >\n {point.value}\n </span>\n {point.unit && (\n <span className=\"mr-cc-table__runit\">{point.unit}</span>\n )}\n </>\n ) : (\n <span className=\"mr-cc-table__empty-dash\">—</span>\n )}\n </div>\n </div>\n\n <div className=\"mr-cc-table__reading-cell\" role=\"cell\">\n {point.date ? (\n <span className=\"mr-cc-table__rvalue\">{point.date}</span>\n ) : (\n <span className=\"mr-cc-table__empty-dash\">—</span>\n )}\n </div>\n\n <div\n className=\"mr-cc-table__actions\"\n role=\"cell\"\n onClick={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n className=\"mr-sv__view-record-btn\"\n onClick={handleViewRecord}\n >\n View record\n </button>\n </div>\n </div>\n </div>\n );\n});\n\nexport function VitalHistoryPanel({\n recordId,\n vitalId,\n caseId,\n}: VitalHistoryPanelProps) {\n const { back, openOriginal: _openOriginal, onCopyToNote, onCopyVitalsToNote, onToast } =\n useSmartRecordsActions();\n\n const openOriginal = useCallback(\n (recordId: string, returnTo: \"smart\" | \"history\" | \"careContext\", returnVitalId?: string) => {\n invalidateRecordPanelTable(recordId);\n _openOriginal(recordId, caseId ? \"careContext\" : returnTo, returnVitalId, caseId);\n },\n [_openOriginal, caseId],\n );\n const preview = useRecordPreview(recordId);\n const vital = preview.vitals.find((v) => v.id === vitalId);\n const copyBtnRef = useRef<HTMLButtonElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n const { data: trendData, status: trendStatus } = useParameterTrend(\n vital?.ekaId,\n );\n\n const points = useMemo((): HistoryPoint[] => {\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 .map((info) => ({\n date: (info.display_time || \"\").replace(/['‘’]/g, \" \"),\n caseLabel: \"\",\n value:\n info.val !== undefined\n ? String(info.val)\n : ((info as any).val_string ?? \"\"),\n unit: trend.unit,\n status: normalizeStatus(info.display_result ?? \"\"),\n recordId: info.document_id,\n recordName: trend.name,\n }));\n }, [trendData]);\n\n type VhpTab = \"all\" | \"oor\" | \"none\";\n const [activeTab, setActiveTab] = useState<VhpTab>(\"all\");\n\n const oorCount = useMemo(\n () => points.filter((p) => p.status === \"high\" || p.status === \"low\").length,\n [points],\n );\n const noneCount = useMemo(\n () => points.filter((p) => p.status === \"unknown\").length,\n [points],\n );\n\n useEffect(() => {\n if (activeTab === \"oor\" && oorCount === 0) setActiveTab(\"all\");\n if (activeTab === \"none\" && noneCount === 0) setActiveTab(\"all\");\n }, [activeTab, oorCount, noneCount]);\n\n useEffect(() => {\n if (trendStatus === \"error\") {\n back();\n onToast?.(\"Failed to load vital history\", \"error\");\n }\n }, [trendStatus, back, onToast]);\n\n const filteredPoints = useMemo(() => {\n if (activeTab === \"oor\") return points.filter((p) => p.status === \"high\" || p.status === \"low\");\n if (activeTab === \"none\") return points.filter((p) => p.status === \"unknown\");\n return points;\n }, [points, activeTab]);\n\n const rowVirtualizer = useVirtualizer({\n count: filteredPoints.length,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 50,\n overscan: 5,\n });\n\n const {\n selected,\n allSelected,\n someSelected,\n togglePoint,\n toggleAll,\n buildHistoryText,\n } = useVitalHistoryPanel(\n vital ?? {\n id: vitalId,\n name: \"\",\n value: \"\",\n unit: \"\",\n refRange: \"\",\n status: \"normal\" as VitalStatus,\n history: [] as VitalHistoryPoint[],\n },\n filteredPoints,\n );\n\n const handleCopyToNote = useCallback(() => {\n const chosen = points.filter((_, i) => selected.has(i));\n if (!chosen.length) return;\n const text = buildHistoryText(chosen);\n if (onCopyVitalsToNote) {\n void onCopyVitalsToNote(text);\n } else if (onCopyToNote) {\n const rect = copyBtnRef.current?.getBoundingClientRect();\n void onCopyToNote(\n text,\n rect ? { x: rect.left + rect.width / 2, y: rect.bottom } : undefined,\n vital ? toHistoryNoteRows(vital, chosen) : undefined,\n );\n }\n }, [points, selected, buildHistoryText, onCopyVitalsToNote, onCopyToNote, vital]);\n\n const hasCopyToNote = !!(onCopyToNote || onCopyVitalsToNote);\n\n if (preview.status === \"loading\") {\n return (\n <div\n className=\"mr-sv__panel\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <LoaderCircle\n size={32}\n className=\"mr-sv__loading-spinner\"\n aria-hidden\n />\n </div>\n );\n }\n\n if (!vital) {\n return (\n <div className=\"mr-sv__panel\">\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n Vital not found.\n </Typography>\n </div>\n );\n }\n\n return (\n <div className=\"mr-sv__panel\">\n <div className=\"mr-sv__back-row\">\n <button type=\"button\" className=\"mr-sv__back-btn\" onClick={back}>\n <ChevronLeft size={16} aria-hidden />\n Back\n </button>\n </div>\n {/* Header */}\n <div className=\"mr-sv__panel-header\">\n <div className=\"mr-sv__panel-left\">\n <div className=\"mr-sv__panel-info\">\n <div className=\"mr-sv__panel-name-row\">\n <Typography\n variant=\"label\"\n as=\"span\"\n className=\"mr-sv__panel-name\"\n >\n {vital.name}\n </Typography>\n {vital.refRange && (\n <span className=\"mr-sv__panel-ref-badge\">\n Ref: {vital.refRange}\n </span>\n )}\n </div>\n <div className=\"mr-sv__panel-meta\">\n {trendStatus === \"loaded\" && (\n <span>\n {points.length} reading{points.length !== 1 ? \"s\" : \"\"}\n {oorCount > 0 && (\n <>\n {\" \"}\n ·{\" \"}\n <span className=\"mr-sv__oor\">\n {oorCount} out of range\n </span>\n </>\n )}\n </span>\n )}\n </div>\n </div>\n </div>\n <span className=\"mr-cc-panel__viewing-label\">Viewing vital history</span>\n </div>\n\n {/* Filter tabs — only shown when at least one sub-category has data */}\n {trendStatus === \"loaded\" && points.length > 0 && (oorCount > 0 || noneCount > 0) && (\n <div className=\"mr-orig__smart-tabs-wrap\" style={{ padding: \"8px 16px 0\" }}>\n <div className=\"mr-orig__smart-tabs\">\n {([\"all\", \"oor\", \"none\"] as VhpTab[]).map((tab) => {\n if (tab === \"oor\" && oorCount === 0) return null;\n if (tab === \"none\" && noneCount === 0) return null;\n const count = tab === \"all\" ? points.length : tab === \"oor\" ? oorCount : noneCount;\n const label = tab === \"all\" ? \"All\" : tab === \"oor\" ? \"Out of range\" : \"No interpretation\";\n return (\n <button\n key={tab}\n type=\"button\"\n className={`mr-orig__smart-tab${activeTab === tab ? \" mr-orig__smart-tab--active\" : \"\"}`}\n onClick={() => setActiveTab(tab)}\n >\n {label} ({count})\n </button>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Body */}\n <div className=\"mr-sv__panel-body\" ref={scrollRef} style={{ overflowY: \"auto\" }}>\n {trendStatus === \"loading\" && (\n <div className=\"mr-cc-table mr-cc-table--state\">\n <LoaderCircle size={20} className=\"mr-sv__loading-spinner\" aria-hidden />\n <Typography variant=\"muted\">Loading vital history…</Typography>\n </div>\n )}\n {trendStatus === \"loaded\" && points.length === 0 && (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No historical data available for this vital.\n </Typography>\n )}\n {points.length > 0 && (\n <div className=\"mr-vhp-table\" role=\"table\">\n <div\n className=\"mr-cc-table__row mr-cc-table__row--head\"\n role=\"row\"\n style={{ gridTemplateColumns: HISTORY_COLS, margin: 0 }}\n >\n <span className=\"mr-cc-table__head-cell\" role=\"columnheader\">READING</span>\n <span className=\"mr-cc-table__head-cell\" role=\"columnheader\">DATE</span>\n <span className=\"mr-cc-table__head-cell\" aria-hidden />\n </div>\n {filteredPoints.length === 0 ? (\n <Typography variant=\"muted\" className=\"mr-sv__panel-empty\">\n No readings match this filter.\n </Typography>\n ) : (\n <div style={{ height: `${rowVirtualizer.getTotalSize()}px`, position: \"relative\" }}>\n {rowVirtualizer.getVirtualItems().map((virtualRow) => (\n <div\n key={virtualRow.key}\n data-index={virtualRow.index}\n ref={rowVirtualizer.measureElement}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n <HistoryRow\n index={virtualRow.index}\n point={filteredPoints[virtualRow.index]}\n vital={vital}\n isSelected={selected.has(virtualRow.index)}\n isLast={virtualRow.index === filteredPoints.length - 1}\n onToggle={togglePoint}\n onViewRecord={openOriginal}\n />\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"mr-cc-table__footer\">\n <span\n className={`mr-sv__checkbox mr-cc-table__footer-check${allSelected ? \" mr-sv__checkbox--checked\" : \"\"}`}\n role=\"checkbox\"\n aria-checked={allSelected}\n tabIndex={0}\n onClick={toggleAll}\n onKeyDown={(e) => {\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n toggleAll();\n }\n }}\n >\n {allSelected && <Check size={10} strokeWidth={3} />}\n </span>\n <span className=\"mr-cc-table__footer-label\" onClick={toggleAll}>Select all</span>\n <span className=\"mr-cc-table__footer-count\">{selected.size} of {points.length} selected</span>\n <button\n ref={copyBtnRef}\n type=\"button\"\n className=\"mr-cc-table__copy-note-btn\"\n disabled={!someSelected || !hasCopyToNote}\n onClick={handleCopyToNote}\n >\n Copy to note\n </button>\n </div>\n </div>\n );\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport { isOutOfRange } from \"../../../helpers/smartReport\";\nimport type { Vital, HistoryPoint } from \"../../types\";\n\nexport function useVitalHistoryPanel(vital: Vital, points: HistoryPoint[]) {\n const [selected, setSelected] = useState<Set<number>>(new Set());\n\n const outOfRangeCount = useMemo(\n () => points.filter((p) => isOutOfRange({ ...vital, status: p.status })).length,\n [points, vital],\n );\n\n const allSelected = points.length > 0 && points.every((_, i) => selected.has(i));\n const someSelected = selected.size > 0;\n\n const togglePoint = useCallback((i: number) => {\n setSelected((prev) => {\n const n = new Set(prev);\n n.has(i) ? n.delete(i) : n.add(i);\n return n;\n });\n }, []);\n\n const toggleAll = useCallback(() => {\n setSelected(allSelected ? new Set() : new Set(points.map((_, i) => i)));\n }, [allSelected, points]);\n\n const clearSelection = useCallback(() => setSelected(new Set()), []);\n\n const buildHistoryText = useCallback(\n (pts: HistoryPoint[]) => {\n const lines = pts.map(\n (p) => `${vital.name}: ${p.value} ${p.unit} (${p.date}${p.caseLabel ? ` · ${p.caseLabel}` : \"\"})`,\n );\n return [`**${vital.name} — Historical data:**`, ...lines].join(\"\\n\");\n },\n [vital.name],\n );\n\n return {\n selected,\n outOfRangeCount,\n allSelected,\n someSelected,\n togglePoint,\n toggleAll,\n clearSelection,\n buildHistoryText,\n };\n}\n"],"mappings":"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","names":["useCallback","useMemo","useState","HistoryRow","useCallback","recordId","useMemo","useState"]}