formanitor 0.1.10 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AddInvestigationWidget-G7NPTSFY.cjs +32 -0
- package/dist/AddInvestigationWidget-G7NPTSFY.cjs.map +1 -0
- package/dist/AddInvestigationWidget-TQUKTGAW.mjs +30 -0
- package/dist/AddInvestigationWidget-TQUKTGAW.mjs.map +1 -0
- package/dist/AddMedicationWidget-26RHKIA6.cjs +32 -0
- package/dist/AddMedicationWidget-26RHKIA6.cjs.map +1 -0
- package/dist/AddMedicationWidget-I5UIT3WG.mjs +30 -0
- package/dist/AddMedicationWidget-I5UIT3WG.mjs.map +1 -0
- package/dist/AddProcedureWidget-B6OUF3BM.cjs +278 -0
- package/dist/AddProcedureWidget-B6OUF3BM.cjs.map +1 -0
- package/dist/AddProcedureWidget-NB46COB6.mjs +276 -0
- package/dist/AddProcedureWidget-NB46COB6.mjs.map +1 -0
- package/dist/BiometryIolWorkupWidget-F7HRYMOJ.mjs +298 -0
- package/dist/BiometryIolWorkupWidget-F7HRYMOJ.mjs.map +1 -0
- package/dist/BiometryIolWorkupWidget-TCU4MMVI.cjs +300 -0
- package/dist/BiometryIolWorkupWidget-TCU4MMVI.cjs.map +1 -0
- package/dist/DateTimeWidget-72YUK7PX.cjs +61 -0
- package/dist/DateTimeWidget-72YUK7PX.cjs.map +1 -0
- package/dist/DateTimeWidget-WKQIEQSA.mjs +59 -0
- package/dist/DateTimeWidget-WKQIEQSA.mjs.map +1 -0
- package/dist/DateWidget-K2TVTZ7Z.mjs +72 -0
- package/dist/DateWidget-K2TVTZ7Z.mjs.map +1 -0
- package/dist/DateWidget-SYDMSGWO.cjs +74 -0
- package/dist/DateWidget-SYDMSGWO.cjs.map +1 -0
- package/dist/DiagnosisTextareaWidget-RD65PGDY.mjs +184 -0
- package/dist/DiagnosisTextareaWidget-RD65PGDY.mjs.map +1 -0
- package/dist/DiagnosisTextareaWidget-UKWLE2SQ.cjs +190 -0
- package/dist/DiagnosisTextareaWidget-UKWLE2SQ.cjs.map +1 -0
- package/dist/DifferentialDiagnosisWidget-FENJP245.mjs +15 -0
- package/dist/DifferentialDiagnosisWidget-FENJP245.mjs.map +1 -0
- package/dist/DifferentialDiagnosisWidget-ZGFXP2BH.cjs +17 -0
- package/dist/DifferentialDiagnosisWidget-ZGFXP2BH.cjs.map +1 -0
- package/dist/DischargeMedicationOrdersWidget-26ALTGJM.mjs +161 -0
- package/dist/DischargeMedicationOrdersWidget-26ALTGJM.mjs.map +1 -0
- package/dist/DischargeMedicationOrdersWidget-B4CJQ3QS.cjs +163 -0
- package/dist/DischargeMedicationOrdersWidget-B4CJQ3QS.cjs.map +1 -0
- package/dist/EditableTable-LPAYCK36.mjs +279 -0
- package/dist/EditableTable-LPAYCK36.mjs.map +1 -0
- package/dist/EditableTable-YB4IC3ZK.cjs +281 -0
- package/dist/EditableTable-YB4IC3ZK.cjs.map +1 -0
- package/dist/FollowupWidget-EEKOI2TW.cjs +285 -0
- package/dist/FollowupWidget-EEKOI2TW.cjs.map +1 -0
- package/dist/FollowupWidget-NJ4QDBOG.mjs +283 -0
- package/dist/FollowupWidget-NJ4QDBOG.mjs.map +1 -0
- package/dist/FunctionalImpairmentScoreWidget-HAAPCMIS.cjs +93 -0
- package/dist/FunctionalImpairmentScoreWidget-HAAPCMIS.cjs.map +1 -0
- package/dist/FunctionalImpairmentScoreWidget-ZNLKKBYN.mjs +91 -0
- package/dist/FunctionalImpairmentScoreWidget-ZNLKKBYN.mjs.map +1 -0
- package/dist/GsExaminationWidget-EX6C3EF5.cjs +528 -0
- package/dist/GsExaminationWidget-EX6C3EF5.cjs.map +1 -0
- package/dist/GsExaminationWidget-MEIUHRQQ.mjs +526 -0
- package/dist/GsExaminationWidget-MEIUHRQQ.mjs.map +1 -0
- package/dist/GsGradingWidget-4UPOEYNL.mjs +90 -0
- package/dist/GsGradingWidget-4UPOEYNL.mjs.map +1 -0
- package/dist/GsGradingWidget-IV3UF63W.cjs +92 -0
- package/dist/GsGradingWidget-IV3UF63W.cjs.map +1 -0
- package/dist/GsSmartHistoryWidget-7QNJZEI4.cjs +398 -0
- package/dist/GsSmartHistoryWidget-7QNJZEI4.cjs.map +1 -0
- package/dist/GsSmartHistoryWidget-LGN7W2AV.mjs +396 -0
- package/dist/GsSmartHistoryWidget-LGN7W2AV.mjs.map +1 -0
- package/dist/HiddenVitalsWidget-AMH32HT2.cjs +55 -0
- package/dist/HiddenVitalsWidget-AMH32HT2.cjs.map +1 -0
- package/dist/HiddenVitalsWidget-W23IFSEF.mjs +53 -0
- package/dist/HiddenVitalsWidget-W23IFSEF.mjs.map +1 -0
- package/dist/LensAssessmentWidget-LSHBUTT5.cjs +234 -0
- package/dist/LensAssessmentWidget-LSHBUTT5.cjs.map +1 -0
- package/dist/LensAssessmentWidget-SJ6YUTSN.mjs +232 -0
- package/dist/LensAssessmentWidget-SJ6YUTSN.mjs.map +1 -0
- package/dist/MarMedicationOrdersWidget-IKMAFPRG.mjs +74 -0
- package/dist/MarMedicationOrdersWidget-IKMAFPRG.mjs.map +1 -0
- package/dist/MarMedicationOrdersWidget-ZKZLSZRN.cjs +76 -0
- package/dist/MarMedicationOrdersWidget-ZKZLSZRN.cjs.map +1 -0
- package/dist/OBGExaminationWidget-BK4ERETW.mjs +213 -0
- package/dist/OBGExaminationWidget-BK4ERETW.mjs.map +1 -0
- package/dist/OBGExaminationWidget-SMFZ2WCL.cjs +215 -0
- package/dist/OBGExaminationWidget-SMFZ2WCL.cjs.map +1 -0
- package/dist/OBGPathwayWidget-5YTUDBEH.cjs +519 -0
- package/dist/OBGPathwayWidget-5YTUDBEH.cjs.map +1 -0
- package/dist/OBGPathwayWidget-U5BCAESB.mjs +517 -0
- package/dist/OBGPathwayWidget-U5BCAESB.mjs.map +1 -0
- package/dist/ObstetricHistoryWidget-GC63CB3U.cjs +1115 -0
- package/dist/ObstetricHistoryWidget-GC63CB3U.cjs.map +1 -0
- package/dist/ObstetricHistoryWidget-WD572Q7H.mjs +1113 -0
- package/dist/ObstetricHistoryWidget-WD572Q7H.mjs.map +1 -0
- package/dist/OphthalDiagnosisWidget-QXFK446I.cjs +91 -0
- package/dist/OphthalDiagnosisWidget-QXFK446I.cjs.map +1 -0
- package/dist/OphthalDiagnosisWidget-Y3AHD6AG.mjs +89 -0
- package/dist/OphthalDiagnosisWidget-Y3AHD6AG.mjs.map +1 -0
- package/dist/OphthalmologyWidget-CRQMN5QU.mjs +1329 -0
- package/dist/OphthalmologyWidget-CRQMN5QU.mjs.map +1 -0
- package/dist/OphthalmologyWidget-U2HQMZ4J.cjs +1331 -0
- package/dist/OphthalmologyWidget-U2HQMZ4J.cjs.map +1 -0
- package/dist/OrthopedicExamWidget-LP7VN3W5.cjs +368 -0
- package/dist/OrthopedicExamWidget-LP7VN3W5.cjs.map +1 -0
- package/dist/OrthopedicExamWidget-PAOIVU6Z.mjs +366 -0
- package/dist/OrthopedicExamWidget-PAOIVU6Z.mjs.map +1 -0
- package/dist/PainScaleFlagsWidget-IBNGVVHD.cjs +153 -0
- package/dist/PainScaleFlagsWidget-IBNGVVHD.cjs.map +1 -0
- package/dist/PainScaleFlagsWidget-MRMQ7HPJ.mjs +151 -0
- package/dist/PainScaleFlagsWidget-MRMQ7HPJ.mjs.map +1 -0
- package/dist/ReadOnlyTable-4Y2XW4MX.mjs +6 -0
- package/dist/ReadOnlyTable-4Y2XW4MX.mjs.map +1 -0
- package/dist/ReadOnlyTable-L7G6GWEJ.cjs +15 -0
- package/dist/ReadOnlyTable-L7G6GWEJ.cjs.map +1 -0
- package/dist/ReferralWidget-IYTS32TS.mjs +169 -0
- package/dist/ReferralWidget-IYTS32TS.mjs.map +1 -0
- package/dist/ReferralWidget-PDNEKHFO.cjs +171 -0
- package/dist/ReferralWidget-PDNEKHFO.cjs.map +1 -0
- package/dist/RichTextWidget-5OOJ2LJN.mjs +11 -0
- package/dist/RichTextWidget-5OOJ2LJN.mjs.map +1 -0
- package/dist/RichTextWidget-XWLOHKLE.cjs +24 -0
- package/dist/RichTextWidget-XWLOHKLE.cjs.map +1 -0
- package/dist/SmartTextarea-L7Q4CORK.cjs +19 -0
- package/dist/SmartTextarea-L7Q4CORK.cjs.map +1 -0
- package/dist/SmartTextarea-ZCXGMZLG.mjs +10 -0
- package/dist/SmartTextarea-ZCXGMZLG.mjs.map +1 -0
- package/dist/SuggestionTextareaWidget-2TEITBPF.cjs +226 -0
- package/dist/SuggestionTextareaWidget-2TEITBPF.cjs.map +1 -0
- package/dist/SuggestionTextareaWidget-RN5LZYFC.mjs +215 -0
- package/dist/SuggestionTextareaWidget-RN5LZYFC.mjs.map +1 -0
- package/dist/SurgicalRiskFlagsWidget-DBICX4MB.mjs +144 -0
- package/dist/SurgicalRiskFlagsWidget-DBICX4MB.mjs.map +1 -0
- package/dist/SurgicalRiskFlagsWidget-JCSL3GWS.cjs +146 -0
- package/dist/SurgicalRiskFlagsWidget-JCSL3GWS.cjs.map +1 -0
- package/dist/UrologyExaminationWidget-74L3IN2X.cjs +273 -0
- package/dist/UrologyExaminationWidget-74L3IN2X.cjs.map +1 -0
- package/dist/UrologyExaminationWidget-IQEBP6CI.mjs +271 -0
- package/dist/UrologyExaminationWidget-IQEBP6CI.mjs.map +1 -0
- package/dist/UrologyPathwayWidget-S4QY6RD6.mjs +153 -0
- package/dist/UrologyPathwayWidget-S4QY6RD6.mjs.map +1 -0
- package/dist/UrologyPathwayWidget-UJY5EW2G.cjs +155 -0
- package/dist/UrologyPathwayWidget-UJY5EW2G.cjs.map +1 -0
- package/dist/UrologySmartHistoryWidget-NFTHHK6A.mjs +469 -0
- package/dist/UrologySmartHistoryWidget-NFTHHK6A.mjs.map +1 -0
- package/dist/UrologySmartHistoryWidget-XKZF63BV.cjs +471 -0
- package/dist/UrologySmartHistoryWidget-XKZF63BV.cjs.map +1 -0
- package/dist/VitalsWidget-44UWQGIF.cjs +208 -0
- package/dist/VitalsWidget-44UWQGIF.cjs.map +1 -0
- package/dist/VitalsWidget-MBYDGC7U.mjs +187 -0
- package/dist/VitalsWidget-MBYDGC7U.mjs.map +1 -0
- package/dist/chunk-4BAKQIPJ.mjs +27 -0
- package/dist/chunk-4BAKQIPJ.mjs.map +1 -0
- package/dist/chunk-4KSZUIJE.cjs +143 -0
- package/dist/chunk-4KSZUIJE.cjs.map +1 -0
- package/dist/chunk-4PMNVBJD.mjs +121 -0
- package/dist/chunk-4PMNVBJD.mjs.map +1 -0
- package/dist/chunk-5E3APMY6.cjs +54 -0
- package/dist/chunk-5E3APMY6.cjs.map +1 -0
- package/dist/chunk-AIZ3XYEZ.cjs +551 -0
- package/dist/chunk-AIZ3XYEZ.cjs.map +1 -0
- package/dist/chunk-AZHTIUOL.mjs +116 -0
- package/dist/chunk-AZHTIUOL.mjs.map +1 -0
- package/dist/chunk-AZSAPO2V.cjs +174 -0
- package/dist/chunk-AZSAPO2V.cjs.map +1 -0
- package/dist/chunk-AZVJU7NZ.mjs +137 -0
- package/dist/chunk-AZVJU7NZ.mjs.map +1 -0
- package/dist/chunk-B3GBIAHZ.mjs +285 -0
- package/dist/chunk-B3GBIAHZ.mjs.map +1 -0
- package/dist/chunk-BMNY7F6H.mjs +148 -0
- package/dist/chunk-BMNY7F6H.mjs.map +1 -0
- package/dist/chunk-BU4ZEAAP.mjs +102 -0
- package/dist/chunk-BU4ZEAAP.mjs.map +1 -0
- package/dist/chunk-CTW65YW2.cjs +388 -0
- package/dist/chunk-CTW65YW2.cjs.map +1 -0
- package/dist/chunk-DE7VZVKR.cjs +140 -0
- package/dist/chunk-DE7VZVKR.cjs.map +1 -0
- package/dist/chunk-DZYV47QC.mjs +54 -0
- package/dist/chunk-DZYV47QC.mjs.map +1 -0
- package/dist/chunk-E7WUDHSA.cjs +127 -0
- package/dist/chunk-E7WUDHSA.cjs.map +1 -0
- package/dist/chunk-FHHISVCH.cjs +13 -0
- package/dist/chunk-FHHISVCH.cjs.map +1 -0
- package/dist/chunk-FZEEWRW3.cjs +77 -0
- package/dist/chunk-FZEEWRW3.cjs.map +1 -0
- package/dist/chunk-GFDE2KZC.mjs +228 -0
- package/dist/chunk-GFDE2KZC.mjs.map +1 -0
- package/dist/chunk-GNZWSVTB.mjs +29 -0
- package/dist/chunk-GNZWSVTB.mjs.map +1 -0
- package/dist/chunk-GXXWMHAA.mjs +49 -0
- package/dist/chunk-GXXWMHAA.mjs.map +1 -0
- package/dist/chunk-GZPCYSJK.mjs +104 -0
- package/dist/chunk-GZPCYSJK.mjs.map +1 -0
- package/dist/chunk-HEFZA2AH.mjs +22 -0
- package/dist/chunk-HEFZA2AH.mjs.map +1 -0
- package/dist/chunk-I4AV6BQF.mjs +10 -0
- package/dist/chunk-I4AV6BQF.mjs.map +1 -0
- package/dist/chunk-IDSBJOFY.cjs +1885 -0
- package/dist/chunk-IDSBJOFY.cjs.map +1 -0
- package/dist/chunk-IFMQKLNW.mjs +39 -0
- package/dist/chunk-IFMQKLNW.mjs.map +1 -0
- package/dist/chunk-IFSKLIS2.cjs +12 -0
- package/dist/chunk-IFSKLIS2.cjs.map +1 -0
- package/dist/chunk-IKAKE7TR.mjs +527 -0
- package/dist/chunk-IKAKE7TR.mjs.map +1 -0
- package/dist/chunk-JE6VXRWW.cjs +86 -0
- package/dist/chunk-JE6VXRWW.cjs.map +1 -0
- package/dist/chunk-JMGUUFOJ.cjs +45 -0
- package/dist/chunk-JMGUUFOJ.cjs.map +1 -0
- package/dist/chunk-JNVSA77L.cjs +236 -0
- package/dist/chunk-JNVSA77L.cjs.map +1 -0
- package/dist/chunk-KJA5BLGX.cjs +31 -0
- package/dist/chunk-KJA5BLGX.cjs.map +1 -0
- package/dist/chunk-KMJOTMUQ.cjs +109 -0
- package/dist/chunk-KMJOTMUQ.cjs.map +1 -0
- package/dist/chunk-KPGTPJDH.cjs +32 -0
- package/dist/chunk-KPGTPJDH.cjs.map +1 -0
- package/dist/chunk-LBWB7MYU.cjs +287 -0
- package/dist/chunk-LBWB7MYU.cjs.map +1 -0
- package/dist/chunk-LGGOBIEA.mjs +61 -0
- package/dist/chunk-LGGOBIEA.mjs.map +1 -0
- package/dist/chunk-LQYWMYEC.mjs +28 -0
- package/dist/chunk-LQYWMYEC.mjs.map +1 -0
- package/dist/chunk-MIUUO4CI.mjs +361 -0
- package/dist/chunk-MIUUO4CI.mjs.map +1 -0
- package/dist/chunk-N4L76SHJ.cjs +65 -0
- package/dist/chunk-N4L76SHJ.cjs.map +1 -0
- package/dist/chunk-NJJTIL3U.cjs +73 -0
- package/dist/chunk-NJJTIL3U.cjs.map +1 -0
- package/dist/chunk-O3VQBPEW.cjs +72 -0
- package/dist/chunk-O3VQBPEW.cjs.map +1 -0
- package/dist/chunk-P62377LB.cjs +27 -0
- package/dist/chunk-P62377LB.cjs.map +1 -0
- package/dist/chunk-PHADAQSH.cjs +49 -0
- package/dist/chunk-PHADAQSH.cjs.map +1 -0
- package/dist/chunk-PZBJYPWW.cjs +52 -0
- package/dist/chunk-PZBJYPWW.cjs.map +1 -0
- package/dist/chunk-QKJ7BQSR.cjs +538 -0
- package/dist/chunk-QKJ7BQSR.cjs.map +1 -0
- package/dist/chunk-QS6WG2XJ.cjs +56 -0
- package/dist/chunk-QS6WG2XJ.cjs.map +1 -0
- package/dist/chunk-S7EMPE2D.cjs +104 -0
- package/dist/chunk-S7EMPE2D.cjs.map +1 -0
- package/dist/chunk-SCMXLRX5.mjs +42 -0
- package/dist/chunk-SCMXLRX5.mjs.map +1 -0
- package/dist/chunk-TJHG5WHX.cjs +47 -0
- package/dist/chunk-TJHG5WHX.cjs.map +1 -0
- package/dist/chunk-UGGUIXUS.cjs +41 -0
- package/dist/chunk-UGGUIXUS.cjs.map +1 -0
- package/dist/chunk-UULLSS4O.mjs +82 -0
- package/dist/chunk-UULLSS4O.mjs.map +1 -0
- package/dist/chunk-VNFBUAZD.mjs +25 -0
- package/dist/chunk-VNFBUAZD.mjs.map +1 -0
- package/dist/chunk-VPU66PI6.mjs +11 -0
- package/dist/chunk-VPU66PI6.mjs.map +1 -0
- package/dist/chunk-WYVXXEZI.mjs +46 -0
- package/dist/chunk-WYVXXEZI.mjs.map +1 -0
- package/dist/chunk-XDUVO3IZ.mjs +547 -0
- package/dist/chunk-XDUVO3IZ.mjs.map +1 -0
- package/dist/chunk-XR2ZM654.mjs +30 -0
- package/dist/chunk-XR2ZM654.mjs.map +1 -0
- package/dist/chunk-Y7TIWH4I.mjs +25 -0
- package/dist/chunk-Y7TIWH4I.mjs.map +1 -0
- package/dist/chunk-YEFM2ERQ.cjs +143 -0
- package/dist/chunk-YEFM2ERQ.cjs.map +1 -0
- package/dist/chunk-YYPMIUDW.mjs +69 -0
- package/dist/chunk-YYPMIUDW.mjs.map +1 -0
- package/dist/chunk-ZGPHTPAN.mjs +1851 -0
- package/dist/chunk-ZGPHTPAN.mjs.map +1 -0
- package/dist/chunk-ZSOIQVB3.mjs +75 -0
- package/dist/chunk-ZSOIQVB3.mjs.map +1 -0
- package/dist/index.cjs +1596 -14537
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -767
- package/dist/index.d.ts +4 -767
- package/dist/index.mjs +1358 -14346
- package/dist/index.mjs.map +1 -1
- package/dist/read-only-table.cjs +15 -0
- package/dist/read-only-table.cjs.map +1 -0
- package/dist/read-only-table.d.cts +10 -0
- package/dist/read-only-table.d.ts +10 -0
- package/dist/read-only-table.mjs +6 -0
- package/dist/read-only-table.mjs.map +1 -0
- package/dist/rich-text.cjs +24 -0
- package/dist/rich-text.cjs.map +1 -0
- package/dist/rich-text.d.cts +8 -0
- package/dist/rich-text.d.ts +8 -0
- package/dist/rich-text.mjs +11 -0
- package/dist/rich-text.mjs.map +1 -0
- package/dist/richTextClassName--8wkuHkW.d.cts +10 -0
- package/dist/richTextClassName--8wkuHkW.d.ts +10 -0
- package/dist/smart.cjs +23 -0
- package/dist/smart.cjs.map +1 -0
- package/dist/smart.d.cts +23 -0
- package/dist/smart.d.ts +23 -0
- package/dist/smart.mjs +10 -0
- package/dist/smart.mjs.map +1 -0
- package/dist/types-D0iYXUOo.d.cts +736 -0
- package/dist/types-D0iYXUOo.d.ts +736 -0
- package/package.json +20 -2
- package/src/styles/index.css +35 -2
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { AddEntityDialog } from './chunk-GZPCYSJK.mjs';
|
|
2
|
+
import { Input } from './chunk-VNFBUAZD.mjs';
|
|
3
|
+
import { cn } from './chunk-VPU66PI6.mjs';
|
|
4
|
+
import { useState, useRef, useEffect } from 'react';
|
|
5
|
+
import { X, Check } from 'lucide-react';
|
|
6
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var ADD_FEEDBACK_MS = 320;
|
|
9
|
+
function mapToInvestigation(result) {
|
|
10
|
+
return {
|
|
11
|
+
...result,
|
|
12
|
+
label: result.name,
|
|
13
|
+
is_custom: false,
|
|
14
|
+
fromAI: false
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
var AddInvestigationField = ({
|
|
18
|
+
label = "Investigations",
|
|
19
|
+
value,
|
|
20
|
+
onChange,
|
|
21
|
+
onSearch,
|
|
22
|
+
recentlyUsed = [],
|
|
23
|
+
frequentItems = [],
|
|
24
|
+
packages = []
|
|
25
|
+
}) => {
|
|
26
|
+
const [open, setOpen] = useState(false);
|
|
27
|
+
const [query, setQuery] = useState("");
|
|
28
|
+
const [results, setResults] = useState([]);
|
|
29
|
+
const [loading, setLoading] = useState(false);
|
|
30
|
+
const [addingId, setAddingId] = useState(null);
|
|
31
|
+
const [addingFrequentId, setAddingFrequentId] = useState(null);
|
|
32
|
+
const debounceRef = useRef(null);
|
|
33
|
+
const valueRef = useRef([]);
|
|
34
|
+
const searchInputRef = useRef(null);
|
|
35
|
+
const addedByPackage = useRef(/* @__PURE__ */ new Map());
|
|
36
|
+
const [selectedPackageIds, setSelectedPackageIds] = useState(/* @__PURE__ */ new Set());
|
|
37
|
+
const safeValue = Array.isArray(value) ? value : [];
|
|
38
|
+
valueRef.current = safeValue;
|
|
39
|
+
const addedIds = new Set(safeValue.map((inv) => inv.id));
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!open) {
|
|
42
|
+
setQuery("");
|
|
43
|
+
setResults([]);
|
|
44
|
+
setAddingId(null);
|
|
45
|
+
setAddingFrequentId(null);
|
|
46
|
+
}
|
|
47
|
+
}, [open]);
|
|
48
|
+
function handleQueryChange(q) {
|
|
49
|
+
setQuery(q);
|
|
50
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
51
|
+
if (!q.trim()) {
|
|
52
|
+
setResults([]);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
debounceRef.current = setTimeout(async () => {
|
|
56
|
+
setLoading(true);
|
|
57
|
+
try {
|
|
58
|
+
const res = await onSearch(q);
|
|
59
|
+
setResults(res);
|
|
60
|
+
} finally {
|
|
61
|
+
setLoading(false);
|
|
62
|
+
}
|
|
63
|
+
}, 500);
|
|
64
|
+
}
|
|
65
|
+
function addInvestigation(result) {
|
|
66
|
+
if (!addedIds.has(result.id)) {
|
|
67
|
+
onChange([...valueRef.current, mapToInvestigation(result)]);
|
|
68
|
+
}
|
|
69
|
+
setQuery("");
|
|
70
|
+
setResults([]);
|
|
71
|
+
}
|
|
72
|
+
function handleResultClick(result) {
|
|
73
|
+
if (addedIds.has(result.id)) return;
|
|
74
|
+
setAddingId(result.id);
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
addInvestigation(result);
|
|
77
|
+
setAddingId(null);
|
|
78
|
+
setTimeout(() => searchInputRef.current?.focus(), 0);
|
|
79
|
+
}, ADD_FEEDBACK_MS);
|
|
80
|
+
}
|
|
81
|
+
function removeInvestigation(id) {
|
|
82
|
+
onChange(safeValue.filter((inv) => inv.id !== id));
|
|
83
|
+
}
|
|
84
|
+
function handleRecentlyUsedToggle(result) {
|
|
85
|
+
if (addedIds.has(result.id)) {
|
|
86
|
+
removeInvestigation(result.id);
|
|
87
|
+
} else {
|
|
88
|
+
addInvestigation(result);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function handleFrequentItemToggle(item) {
|
|
92
|
+
const id = String(item.id);
|
|
93
|
+
const addedById = addedIds.has(id);
|
|
94
|
+
const addedByName = safeValue.some((inv) => inv.name === item.name);
|
|
95
|
+
if (addedById || addedByName) {
|
|
96
|
+
if (addedById) removeInvestigation(id);
|
|
97
|
+
else onChange(safeValue.filter((inv) => inv.name !== item.name));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
setAddingFrequentId(id);
|
|
101
|
+
try {
|
|
102
|
+
const searchResults = await onSearch(item.name);
|
|
103
|
+
const first = searchResults?.[0];
|
|
104
|
+
if (first && !valueRef.current.some((inv) => inv.id === first.id)) {
|
|
105
|
+
onChange([...valueRef.current, mapToInvestigation(first)]);
|
|
106
|
+
}
|
|
107
|
+
} finally {
|
|
108
|
+
setAddingFrequentId(null);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function handlePackageToggle(pkg) {
|
|
112
|
+
const alreadyAdded = addedByPackage.current.has(pkg.id);
|
|
113
|
+
if (alreadyAdded) {
|
|
114
|
+
const idsToRemove = new Set(addedByPackage.current.get(pkg.id) ?? []);
|
|
115
|
+
onChange(valueRef.current.filter((inv) => !idsToRemove.has(inv.id)));
|
|
116
|
+
addedByPackage.current.delete(pkg.id);
|
|
117
|
+
setSelectedPackageIds((prev) => {
|
|
118
|
+
const next = new Set(prev);
|
|
119
|
+
next.delete(pkg.id);
|
|
120
|
+
return next;
|
|
121
|
+
});
|
|
122
|
+
} else {
|
|
123
|
+
const currentIds = new Set(valueRef.current.map((inv) => inv.id));
|
|
124
|
+
const newTests = pkg.tests.filter((t) => !currentIds.has(t.id)).map((t) => mapToInvestigation(t));
|
|
125
|
+
if (newTests.length > 0) {
|
|
126
|
+
onChange([...valueRef.current, ...newTests]);
|
|
127
|
+
}
|
|
128
|
+
addedByPackage.current.set(pkg.id, newTests.map((t) => t.id));
|
|
129
|
+
setSelectedPackageIds((prev) => new Set(prev).add(pkg.id));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const recentlyUsedChips = recentlyUsed.map((r) => {
|
|
133
|
+
const isAdded = addedIds.has(r.id);
|
|
134
|
+
return /* @__PURE__ */ jsxs(
|
|
135
|
+
"button",
|
|
136
|
+
{
|
|
137
|
+
type: "button",
|
|
138
|
+
onClick: () => handleRecentlyUsedToggle(r),
|
|
139
|
+
className: cn(
|
|
140
|
+
"rounded-full border text-xs px-3 py-1 transition-colors",
|
|
141
|
+
isAdded ? "border-green-300 bg-green-50 text-green-700" : "border-border bg-white hover:bg-gray-50"
|
|
142
|
+
),
|
|
143
|
+
children: [
|
|
144
|
+
isAdded && /* @__PURE__ */ jsx("span", { className: "mr-1", children: "\u2713" }),
|
|
145
|
+
r.name
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
r.id
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
const limitedFrequentItems = frequentItems.slice(0, 25);
|
|
152
|
+
const frequentItemChips = limitedFrequentItems.length > 0 ? limitedFrequentItems.map((item) => {
|
|
153
|
+
const id = String(item.id);
|
|
154
|
+
const isAdded = safeValue.some((inv) => inv.id === id) || safeValue.some((inv) => inv.name === item.name);
|
|
155
|
+
const isAdding = addingFrequentId === id;
|
|
156
|
+
return /* @__PURE__ */ jsxs(
|
|
157
|
+
"button",
|
|
158
|
+
{
|
|
159
|
+
type: "button",
|
|
160
|
+
disabled: isAdding,
|
|
161
|
+
onClick: () => handleFrequentItemToggle(item),
|
|
162
|
+
className: cn(
|
|
163
|
+
"rounded-full border text-xs px-3 py-1 transition-colors",
|
|
164
|
+
isAdded ? "border-green-300 bg-green-50 text-green-700" : "border-border bg-white hover:bg-gray-50",
|
|
165
|
+
isAdding && "opacity-70 pointer-events-none"
|
|
166
|
+
),
|
|
167
|
+
children: [
|
|
168
|
+
isAdded && /* @__PURE__ */ jsx("span", { className: "mr-1", children: "\u2713" }),
|
|
169
|
+
isAdding ? "\u2026" : item.name
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
item.id
|
|
173
|
+
);
|
|
174
|
+
}) : [];
|
|
175
|
+
const packageChips = packages.map((pkg) => {
|
|
176
|
+
const isAdded = selectedPackageIds.has(pkg.id);
|
|
177
|
+
return /* @__PURE__ */ jsxs(
|
|
178
|
+
"button",
|
|
179
|
+
{
|
|
180
|
+
type: "button",
|
|
181
|
+
onClick: () => handlePackageToggle(pkg),
|
|
182
|
+
className: cn(
|
|
183
|
+
"rounded-full border text-xs px-4 py-1.5 transition-colors flex items-center gap-2",
|
|
184
|
+
isAdded ? "border-green-300 bg-green-50 text-green-700" : "border-border bg-white hover:bg-gray-50"
|
|
185
|
+
),
|
|
186
|
+
children: [
|
|
187
|
+
isAdded && /* @__PURE__ */ jsx("span", { children: "\u2713" }),
|
|
188
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold", children: pkg.name }),
|
|
189
|
+
/* @__PURE__ */ jsx("span", { className: cn(
|
|
190
|
+
"rounded-full px-1.5 py-0.5 text-[10px] font-medium",
|
|
191
|
+
isAdded ? "bg-green-100 text-green-600" : "bg-purple-100 text-purple-600"
|
|
192
|
+
), children: pkg.tests.length })
|
|
193
|
+
]
|
|
194
|
+
},
|
|
195
|
+
pkg.id
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
const chipSections = [];
|
|
199
|
+
if (frequentItemChips.length > 0) {
|
|
200
|
+
chipSections.push({ label: "Frequently used", content: /* @__PURE__ */ jsx(Fragment, { children: frequentItemChips }) });
|
|
201
|
+
} else if (recentlyUsedChips.length > 0) {
|
|
202
|
+
chipSections.push({ label: "Recently Used", content: /* @__PURE__ */ jsx(Fragment, { children: recentlyUsedChips }) });
|
|
203
|
+
}
|
|
204
|
+
if (packageChips.length > 0) {
|
|
205
|
+
chipSections.push({ label: "Packages", content: /* @__PURE__ */ jsx(Fragment, { children: packageChips }) });
|
|
206
|
+
}
|
|
207
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-md overflow-hidden flex flex-col bg-white border border-[#D0D0D0] space-y-3 p-3 h-fit", children: [
|
|
208
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
209
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: label }),
|
|
210
|
+
/* @__PURE__ */ jsx(
|
|
211
|
+
"button",
|
|
212
|
+
{
|
|
213
|
+
type: "button",
|
|
214
|
+
onClick: () => setOpen(true),
|
|
215
|
+
className: "text-sm font-semibold text-purple-600 hover:text-purple-800 cursor-pointer",
|
|
216
|
+
children: "ADD"
|
|
217
|
+
}
|
|
218
|
+
)
|
|
219
|
+
] }),
|
|
220
|
+
safeValue.length > 0 && /* @__PURE__ */ jsx("div", { className: "divide-y divide-border rounded-lg border border-border overflow-hidden", children: safeValue.map((inv) => /* @__PURE__ */ jsxs(
|
|
221
|
+
"div",
|
|
222
|
+
{
|
|
223
|
+
className: "flex items-center justify-between px-3 py-2 bg-white hover:bg-gray-50",
|
|
224
|
+
children: [
|
|
225
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: inv.name }),
|
|
226
|
+
/* @__PURE__ */ jsx(
|
|
227
|
+
"button",
|
|
228
|
+
{
|
|
229
|
+
type: "button",
|
|
230
|
+
onClick: () => removeInvestigation(inv.id),
|
|
231
|
+
className: "text-muted-foreground hover:text-red-500 transition-colors cursor-pointer",
|
|
232
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
233
|
+
}
|
|
234
|
+
)
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
inv.id
|
|
238
|
+
)) }),
|
|
239
|
+
/* @__PURE__ */ jsx(
|
|
240
|
+
AddEntityDialog,
|
|
241
|
+
{
|
|
242
|
+
open,
|
|
243
|
+
onClose: () => setOpen(false),
|
|
244
|
+
title: "Add Investigation",
|
|
245
|
+
chipSections: chipSections.length > 0 ? chipSections : void 0,
|
|
246
|
+
children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
247
|
+
/* @__PURE__ */ jsx(
|
|
248
|
+
Input,
|
|
249
|
+
{
|
|
250
|
+
ref: searchInputRef,
|
|
251
|
+
value: query,
|
|
252
|
+
onChange: (e) => handleQueryChange(e.target.value),
|
|
253
|
+
placeholder: "Search for an investigation...",
|
|
254
|
+
className: "border border-border rounded-md focus-visible:ring-0"
|
|
255
|
+
}
|
|
256
|
+
),
|
|
257
|
+
loading && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground py-1", children: "Searching\u2026" }),
|
|
258
|
+
!loading && results.length > 0 && /* @__PURE__ */ jsx("div", { className: "border border-border rounded-md overflow-hidden", children: results.map((r) => {
|
|
259
|
+
const isAdding = addingId === r.id;
|
|
260
|
+
return /* @__PURE__ */ jsxs(
|
|
261
|
+
"button",
|
|
262
|
+
{
|
|
263
|
+
type: "button",
|
|
264
|
+
onClick: () => handleResultClick(r),
|
|
265
|
+
className: cn(
|
|
266
|
+
"w-full text-left px-3 py-2 text-sm transition-all duration-300 ease-out border-b border-border last:border-b-0 cursor-pointer flex items-center justify-between gap-2",
|
|
267
|
+
isAdding ? "bg-green-50 border-green-200" : "hover:bg-gray-50"
|
|
268
|
+
),
|
|
269
|
+
children: [
|
|
270
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: r.name }),
|
|
271
|
+
isAdding && /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 shrink-0 text-green-600" })
|
|
272
|
+
]
|
|
273
|
+
},
|
|
274
|
+
r.id
|
|
275
|
+
);
|
|
276
|
+
}) })
|
|
277
|
+
] })
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
] });
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
export { AddInvestigationField };
|
|
284
|
+
//# sourceMappingURL=chunk-B3GBIAHZ.mjs.map
|
|
285
|
+
//# sourceMappingURL=chunk-B3GBIAHZ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/widgets/AddInvestigationField.tsx"],"names":[],"mappings":"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","file":"chunk-B3GBIAHZ.mjs","sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { X, Check } from 'lucide-react';\nimport { cn } from '../../core/utils';\nimport { Input } from '../shadcn/input';\nimport { AddEntityDialog } from './AddEntityDialog';\nimport type { InvestigationFrequentItem, DiagnosticPackage } from '../../core/types';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type InvestigationSearchResult = {\n id: string;\n name: string;\n code?: string;\n description?: string;\n categories?: string[];\n synonyms?: string[];\n sample_type?: string;\n method?: string;\n reference_range?: string;\n sample_unit?: string;\n sample_qty?: number;\n turnaround_time?: number;\n preparation?: string;\n service_type?: string;\n department?: string;\n is_vip_enabled?: boolean;\n is_pacs_enabled?: boolean;\n score?: number;\n};\n\nexport type Investigation = InvestigationSearchResult & {\n label: string;\n is_custom: boolean;\n fromAI: boolean;\n};\n\nexport type AddInvestigationFieldProps = {\n label?: string;\n value: Investigation[];\n onChange: (items: Investigation[]) => void;\n onSearch: (query: string) => Promise<InvestigationSearchResult[]>;\n recentlyUsed?: InvestigationSearchResult[];\n frequentItems?: InvestigationFrequentItem[];\n packages?: DiagnosticPackage[];\n};\n\nconst ADD_FEEDBACK_MS = 320;\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\nfunction mapToInvestigation(result: InvestigationSearchResult): Investigation {\n return {\n ...result,\n label: result.name,\n is_custom: false,\n fromAI: false,\n };\n}\n\n// function mapFrequentItemToInvestigation(item: InvestigationFrequentItem): Investigation {\n// return {\n// id: String(item.id),\n// name: item.name,\n// code: item.code ?? undefined,\n// label: item.name,\n// is_custom: false,\n// fromAI: false,\n// };\n// }\n\n// ─── Main component ───────────────────────────────────────────────────────────\n\nexport const AddInvestigationField: React.FC<AddInvestigationFieldProps> = ({\n label = 'Investigations',\n value,\n onChange,\n onSearch,\n recentlyUsed = [],\n frequentItems = [],\n packages = [],\n}) => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [results, setResults] = useState<InvestigationSearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [addingId, setAddingId] = useState<string | null>(null);\n const [addingFrequentId, setAddingFrequentId] = useState<string | null>(null);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const valueRef = useRef<Investigation[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n // tracks which test IDs were added by each package: packageId → testId[]\n const addedByPackage = useRef<Map<string, string[]>>(new Map());\n // drives re-renders for package chip selected state\n const [selectedPackageIds, setSelectedPackageIds] = useState<Set<string>>(new Set());\n\n const safeValue: Investigation[] = Array.isArray(value) ? value : [];\n\n valueRef.current = safeValue;\n const addedIds = new Set(safeValue.map((inv) => inv.id));\n\n useEffect(() => {\n if (!open) {\n setQuery('');\n setResults([]);\n setAddingId(null);\n setAddingFrequentId(null);\n }\n }, [open]);\n\n function handleQueryChange(q: string) {\n setQuery(q);\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (!q.trim()) {\n setResults([]);\n return;\n }\n debounceRef.current = setTimeout(async () => {\n setLoading(true);\n try {\n const res = await onSearch(q);\n setResults(res);\n } finally {\n setLoading(false);\n }\n }, 500);\n }\n\n function addInvestigation(result: InvestigationSearchResult) {\n if (!addedIds.has(result.id)) {\n onChange([...valueRef.current, mapToInvestigation(result)]);\n }\n setQuery('');\n setResults([]);\n }\n\n function handleResultClick(result: InvestigationSearchResult) {\n if (addedIds.has(result.id)) return;\n setAddingId(result.id);\n setTimeout(() => {\n addInvestigation(result);\n setAddingId(null);\n setTimeout(() => searchInputRef.current?.focus(), 0);\n }, ADD_FEEDBACK_MS);\n }\n\n function removeInvestigation(id: string) {\n onChange(safeValue.filter((inv) => inv.id !== id));\n }\n\n function handleRecentlyUsedToggle(result: InvestigationSearchResult) {\n if (addedIds.has(result.id)) {\n removeInvestigation(result.id);\n } else {\n addInvestigation(result);\n }\n }\n\n async function handleFrequentItemToggle(item: InvestigationFrequentItem) {\n const id = String(item.id);\n const addedById = addedIds.has(id);\n const addedByName = safeValue.some((inv) => inv.name === item.name);\n if (addedById || addedByName) {\n if (addedById) removeInvestigation(id);\n else onChange(safeValue.filter((inv) => inv.name !== item.name));\n return;\n }\n setAddingFrequentId(id);\n try {\n const searchResults = await onSearch(item.name);\n const first = searchResults?.[0];\n if (first && !valueRef.current.some((inv) => inv.id === first.id)) {\n onChange([...valueRef.current, mapToInvestigation(first)]);\n }\n } finally {\n setAddingFrequentId(null);\n }\n }\n\n function handlePackageToggle(pkg: DiagnosticPackage) {\n const alreadyAdded = addedByPackage.current.has(pkg.id);\n if (alreadyAdded) {\n const idsToRemove = new Set(addedByPackage.current.get(pkg.id) ?? []);\n onChange(valueRef.current.filter((inv) => !idsToRemove.has(inv.id)));\n addedByPackage.current.delete(pkg.id);\n setSelectedPackageIds((prev) => {\n const next = new Set(prev);\n next.delete(pkg.id);\n return next;\n });\n } else {\n const currentIds = new Set(valueRef.current.map((inv) => inv.id));\n const newTests = pkg.tests\n .filter((t) => !currentIds.has(t.id))\n .map((t) => mapToInvestigation(t));\n if (newTests.length > 0) {\n onChange([...valueRef.current, ...newTests]);\n }\n addedByPackage.current.set(pkg.id, newTests.map((t) => t.id));\n setSelectedPackageIds((prev) => new Set(prev).add(pkg.id));\n }\n }\n\n // ─── Chip builders ────────────────────────────────────────────────────────\n\n const recentlyUsedChips = recentlyUsed.map((r) => {\n const isAdded = addedIds.has(r.id);\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleRecentlyUsedToggle(r)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {r.name}\n </button>\n );\n });\n\n const limitedFrequentItems = frequentItems.slice(0, 25);\n\n const frequentItemChips =\n limitedFrequentItems.length > 0\n ? limitedFrequentItems.map((item) => {\n const id = String(item.id);\n const isAdded = safeValue.some((inv) => inv.id === id) || safeValue.some((inv) => inv.name === item.name);\n const isAdding = addingFrequentId === id;\n return (\n <button\n key={item.id}\n type=\"button\"\n disabled={isAdding}\n onClick={() => handleFrequentItemToggle(item)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50',\n isAdding && 'opacity-70 pointer-events-none'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {isAdding ? '…' : item.name}\n </button>\n );\n })\n : [];\n\n const packageChips = packages.map((pkg) => {\n const isAdded = selectedPackageIds.has(pkg.id);\n return (\n <button\n key={pkg.id}\n type=\"button\"\n onClick={() => handlePackageToggle(pkg)}\n className={cn(\n 'rounded-full border text-xs px-4 py-1.5 transition-colors flex items-center gap-2',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50'\n )}\n >\n {isAdded && <span>✓</span>}\n <span className=\"font-semibold\">{pkg.name}</span>\n <span className={cn(\n 'rounded-full px-1.5 py-0.5 text-[10px] font-medium',\n isAdded ? 'bg-green-100 text-green-600' : 'bg-purple-100 text-purple-600'\n )}>\n {pkg.tests.length}\n </span>\n </button>\n );\n });\n\n // ─── Build chip sections ──────────────────────────────────────────────────\n\n const chipSections = [];\n if (frequentItemChips.length > 0) {\n chipSections.push({ label: 'Frequently used', content: <>{frequentItemChips}</> });\n } else if (recentlyUsedChips.length > 0) {\n chipSections.push({ label: 'Recently Used', content: <>{recentlyUsedChips}</> });\n }\n if (packageChips.length > 0) {\n chipSections.push({ label: 'Packages', content: <>{packageChips}</> });\n }\n\n return (\n <div className=\"rounded-md overflow-hidden flex flex-col bg-white border border-[#D0D0D0] space-y-3 p-3 h-fit\">\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-sm font-semibold\">{label}</span>\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"text-sm font-semibold text-purple-600 hover:text-purple-800 cursor-pointer\"\n >\n ADD\n </button>\n </div>\n\n {/* Added investigations — one row each */}\n {safeValue.length > 0 && (\n <div className=\"divide-y divide-border rounded-lg border border-border overflow-hidden\">\n {safeValue.map((inv) => (\n <div\n key={inv.id}\n className=\"flex items-center justify-between px-3 py-2 bg-white hover:bg-gray-50\"\n >\n <span className=\"text-sm\">{inv.name}</span>\n <button\n type=\"button\"\n onClick={() => removeInvestigation(inv.id)}\n className=\"text-muted-foreground hover:text-red-500 transition-colors cursor-pointer\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Dialog */}\n <AddEntityDialog\n open={open}\n onClose={() => setOpen(false)}\n title=\"Add Investigation\"\n chipSections={chipSections.length > 0 ? chipSections : undefined}\n >\n <div className=\"space-y-2\">\n <Input\n ref={searchInputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n placeholder=\"Search for an investigation...\"\n className=\"border border-border rounded-md focus-visible:ring-0\"\n />\n\n {loading && (\n <p className=\"text-xs text-muted-foreground py-1\">Searching…</p>\n )}\n {!loading && results.length > 0 && (\n <div className=\"border border-border rounded-md overflow-hidden\">\n {results.map((r) => {\n const isAdding = addingId === r.id;\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleResultClick(r)}\n className={cn(\n 'w-full text-left px-3 py-2 text-sm transition-all duration-300 ease-out border-b border-border last:border-b-0 cursor-pointer flex items-center justify-between gap-2',\n isAdding\n ? 'bg-green-50 border-green-200'\n : 'hover:bg-gray-50'\n )}\n >\n <span className=\"truncate\">{r.name}</span>\n {isAdding && <Check className=\"h-4 w-4 shrink-0 text-green-600\" />}\n </button>\n );\n })}\n </div>\n )}\n </div>\n </AddEntityDialog>\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-AZHTIUOL.mjs';
|
|
2
|
+
import { buttonVariants } from './chunk-GXXWMHAA.mjs';
|
|
3
|
+
import { cn } from './chunk-VPU66PI6.mjs';
|
|
4
|
+
import * as React2 from 'react';
|
|
5
|
+
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
6
|
+
import { DayPicker } from 'react-day-picker';
|
|
7
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
9
|
+
|
|
10
|
+
function CalendarDropdown(props) {
|
|
11
|
+
const { options, value, onChange } = props;
|
|
12
|
+
const handleValueChange = (newValue) => {
|
|
13
|
+
if (!onChange) return;
|
|
14
|
+
const syntheticEvent = {
|
|
15
|
+
target: { value: newValue }
|
|
16
|
+
};
|
|
17
|
+
onChange(syntheticEvent);
|
|
18
|
+
};
|
|
19
|
+
return /* @__PURE__ */ jsxs(Select, { value: value?.toString(), onValueChange: handleValueChange, children: [
|
|
20
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-7 px-2 text-sm", "aria-label": props["aria-label"], children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
21
|
+
/* @__PURE__ */ jsx(SelectContent, { children: options?.map((option) => /* @__PURE__ */ jsx(
|
|
22
|
+
SelectItem,
|
|
23
|
+
{
|
|
24
|
+
value: option.value.toString(),
|
|
25
|
+
disabled: option.disabled,
|
|
26
|
+
children: option.label
|
|
27
|
+
},
|
|
28
|
+
option.value.toString()
|
|
29
|
+
)) })
|
|
30
|
+
] });
|
|
31
|
+
}
|
|
32
|
+
function Calendar({
|
|
33
|
+
className,
|
|
34
|
+
classNames,
|
|
35
|
+
showOutsideDays = true,
|
|
36
|
+
...props
|
|
37
|
+
}) {
|
|
38
|
+
const captionLayout = props.captionLayout ?? "dropdown";
|
|
39
|
+
const isDropdownCaption = captionLayout === "dropdown" || captionLayout === "dropdown-months" || captionLayout === "dropdown-years";
|
|
40
|
+
const startMonth = props.startMonth ?? (isDropdownCaption ? new Date(1900, 0) : void 0);
|
|
41
|
+
const endMonth = props.endMonth ?? (isDropdownCaption ? new Date(2100, 11) : void 0);
|
|
42
|
+
return /* @__PURE__ */ jsx(
|
|
43
|
+
DayPicker,
|
|
44
|
+
{
|
|
45
|
+
showOutsideDays,
|
|
46
|
+
captionLayout,
|
|
47
|
+
hideNavigation: props.hideNavigation ?? isDropdownCaption,
|
|
48
|
+
navLayout: props.navLayout ?? (isDropdownCaption ? "around" : void 0),
|
|
49
|
+
startMonth,
|
|
50
|
+
endMonth,
|
|
51
|
+
className: cn("p-3 relative", className),
|
|
52
|
+
classNames: {
|
|
53
|
+
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
|
|
54
|
+
month: "space-y-4",
|
|
55
|
+
caption: "flex justify-center pt-1 relative items-center",
|
|
56
|
+
caption_label: cn(
|
|
57
|
+
"text-sm font-medium",
|
|
58
|
+
isDropdownCaption && "sr-only"
|
|
59
|
+
),
|
|
60
|
+
dropdowns: "flex items-center gap-2",
|
|
61
|
+
months_dropdown: "h-7 rounded-md border border-input bg-background px-2 text-sm",
|
|
62
|
+
years_dropdown: "h-7 rounded-md border border-input bg-background px-2 text-sm",
|
|
63
|
+
nav: "space-x-1 flex items-center",
|
|
64
|
+
nav_button: cn(
|
|
65
|
+
buttonVariants({ variant: "outline" }),
|
|
66
|
+
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
|
|
67
|
+
),
|
|
68
|
+
nav_button_previous: isDropdownCaption ? "" : "absolute left-1",
|
|
69
|
+
nav_button_next: isDropdownCaption ? "" : "absolute right-1",
|
|
70
|
+
table: "w-full border-collapse space-y-1",
|
|
71
|
+
head_row: "flex",
|
|
72
|
+
head_cell: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
|
|
73
|
+
row: "flex w-full mt-2",
|
|
74
|
+
cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
|
|
75
|
+
day: cn(
|
|
76
|
+
buttonVariants({ variant: "ghost" }),
|
|
77
|
+
"h-9 w-9 p-0 font-normal aria-selected:opacity-100"
|
|
78
|
+
),
|
|
79
|
+
day_range_end: "day-range-end",
|
|
80
|
+
day_selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
|
|
81
|
+
day_today: "bg-accent text-accent-foreground",
|
|
82
|
+
day_outside: "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
|
|
83
|
+
day_disabled: "text-muted-foreground opacity-50",
|
|
84
|
+
day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
|
|
85
|
+
day_hidden: "invisible",
|
|
86
|
+
// v9 keys with explicit positioning relative to the NEW container
|
|
87
|
+
button_previous: cn(
|
|
88
|
+
buttonVariants({ variant: "outline" }),
|
|
89
|
+
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
|
90
|
+
isDropdownCaption ? "" : "absolute left-1 top-3"
|
|
91
|
+
),
|
|
92
|
+
button_next: cn(
|
|
93
|
+
buttonVariants({ variant: "outline" }),
|
|
94
|
+
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
|
95
|
+
isDropdownCaption ? "" : "absolute right-1 top-3"
|
|
96
|
+
),
|
|
97
|
+
month_grid: "w-full border-collapse space-y-1",
|
|
98
|
+
weekdays: "flex",
|
|
99
|
+
weekday: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
|
|
100
|
+
week: "flex w-full mt-2",
|
|
101
|
+
day_button: cn(
|
|
102
|
+
buttonVariants({ variant: "ghost" }),
|
|
103
|
+
"h-9 w-9 p-0 font-normal aria-selected:opacity-100"
|
|
104
|
+
),
|
|
105
|
+
range_end: "day-range-end",
|
|
106
|
+
selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
|
|
107
|
+
today: "bg-accent text-accent-foreground",
|
|
108
|
+
outside: "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
|
|
109
|
+
disabled: "text-muted-foreground opacity-50",
|
|
110
|
+
range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
|
|
111
|
+
hidden: "invisible",
|
|
112
|
+
...classNames
|
|
113
|
+
},
|
|
114
|
+
components: {
|
|
115
|
+
IconLeft: () => /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" }),
|
|
116
|
+
IconRight: () => /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" }),
|
|
117
|
+
// @ts-expect-error react-day-picker v9 component typing differences
|
|
118
|
+
Dropdown: CalendarDropdown,
|
|
119
|
+
Chevron: ({ orientation }) => {
|
|
120
|
+
const Icon = orientation === "left" ? ChevronLeft : ChevronRight;
|
|
121
|
+
return /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4" });
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
...props
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
Calendar.displayName = "Calendar";
|
|
129
|
+
var Popover = PopoverPrimitive.Root;
|
|
130
|
+
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
131
|
+
var PopoverContent = React2.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
132
|
+
PopoverPrimitive.Content,
|
|
133
|
+
{
|
|
134
|
+
ref,
|
|
135
|
+
align,
|
|
136
|
+
sideOffset,
|
|
137
|
+
className: cn(
|
|
138
|
+
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
139
|
+
className
|
|
140
|
+
),
|
|
141
|
+
...props
|
|
142
|
+
}
|
|
143
|
+
) }));
|
|
144
|
+
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
145
|
+
|
|
146
|
+
export { Calendar, Popover, PopoverContent, PopoverTrigger };
|
|
147
|
+
//# sourceMappingURL=chunk-BMNY7F6H.mjs.map
|
|
148
|
+
//# sourceMappingURL=chunk-BMNY7F6H.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/shadcn/calendar.tsx","../src/ui/shadcn/popover.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-BMNY7F6H.mjs","sourcesContent":["import * as React from \"react\"\nimport { ChevronLeft, ChevronRight } from \"lucide-react\"\nimport { DayPicker } from \"react-day-picker\"\n\nimport { cn } from \"../../core/utils\"\nimport { buttonVariants } from \"./button\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"./select\"\n\nexport type CalendarProps = React.ComponentProps<typeof DayPicker>\n\ntype RdpDropdownOption = {\n value: string | number\n label: string\n disabled?: boolean\n}\n\ntype RdpDropdownProps = {\n options?: RdpDropdownOption[]\n value?: string | number\n onChange?: React.ChangeEventHandler<HTMLSelectElement>\n \"aria-label\"?: string\n}\n\nfunction CalendarDropdown(props: RdpDropdownProps) {\n const { options, value, onChange } = props\n\n const handleValueChange = (newValue: string) => {\n if (!onChange) return\n const syntheticEvent = {\n target: { value: newValue },\n } as unknown as React.ChangeEvent<HTMLSelectElement>\n onChange(syntheticEvent)\n }\n\n return (\n <Select value={value?.toString()} onValueChange={handleValueChange}>\n <SelectTrigger className=\"h-7 px-2 text-sm\" aria-label={props[\"aria-label\"]}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options?.map((option) => (\n <SelectItem\n key={option.value.toString()}\n value={option.value.toString()}\n disabled={option.disabled}\n >\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n const captionLayout = props.captionLayout ?? \"dropdown\"\n const isDropdownCaption =\n captionLayout === \"dropdown\" ||\n captionLayout === \"dropdown-months\" ||\n captionLayout === \"dropdown-years\"\n\n // Provide a broad default year range for dropdown captions.\n // Callers can override by passing `startMonth` / `endMonth`.\n const startMonth =\n props.startMonth ?? (isDropdownCaption ? new Date(1900, 0) : undefined)\n const endMonth =\n props.endMonth ?? (isDropdownCaption ? new Date(2100, 11) : undefined)\n\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n captionLayout={captionLayout}\n hideNavigation={props.hideNavigation ?? isDropdownCaption}\n navLayout={props.navLayout ?? (isDropdownCaption ? \"around\" : undefined)}\n startMonth={startMonth}\n endMonth={endMonth}\n className={cn(\"p-3 relative\", className)}\n classNames={{\n months: \"flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0\",\n month: \"space-y-4\",\n caption: \"flex justify-center pt-1 relative items-center\",\n caption_label: cn(\n \"text-sm font-medium\",\n isDropdownCaption && \"sr-only\"\n ),\n dropdowns: \"flex items-center gap-2\",\n months_dropdown:\n \"h-7 rounded-md border border-input bg-background px-2 text-sm\",\n years_dropdown:\n \"h-7 rounded-md border border-input bg-background px-2 text-sm\",\n nav: \"space-x-1 flex items-center\",\n nav_button: cn(\n buttonVariants({ variant: \"outline\" }),\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\"\n ),\n nav_button_previous: isDropdownCaption ? \"\" : \"absolute left-1\",\n nav_button_next: isDropdownCaption ? \"\" : \"absolute right-1\",\n table: \"w-full border-collapse space-y-1\",\n head_row: \"flex\",\n head_cell:\n \"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]\",\n row: \"flex w-full mt-2\",\n cell: \"h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20\",\n day: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"h-9 w-9 p-0 font-normal aria-selected:opacity-100\"\n ),\n day_range_end: \"day-range-end\",\n day_selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n day_today: \"bg-accent text-accent-foreground\",\n day_outside:\n \"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30\",\n day_disabled: \"text-muted-foreground opacity-50\",\n day_range_middle:\n \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n day_hidden: \"invisible\",\n\n // v9 keys with explicit positioning relative to the NEW container\n button_previous: cn(\n buttonVariants({ variant: \"outline\" }),\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\",\n isDropdownCaption ? \"\" : \"absolute left-1 top-3\"\n ),\n button_next: cn(\n buttonVariants({ variant: \"outline\" }),\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\",\n isDropdownCaption ? \"\" : \"absolute right-1 top-3\"\n ),\n month_grid: \"w-full border-collapse space-y-1\",\n weekdays: \"flex\",\n weekday: \"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]\",\n week: \"flex w-full mt-2\",\n day_button: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"h-9 w-9 p-0 font-normal aria-selected:opacity-100\"\n ),\n range_end: \"day-range-end\",\n selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n today: \"bg-accent text-accent-foreground\",\n outside: \"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30\",\n disabled: \"text-muted-foreground opacity-50\",\n range_middle: \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n hidden: \"invisible\",\n \n ...classNames,\n }}\n components={{\n IconLeft: () => <ChevronLeft className=\"h-4 w-4\" />,\n IconRight: () => <ChevronRight className=\"h-4 w-4\" />,\n // @ts-expect-error react-day-picker v9 component typing differences\n Dropdown: CalendarDropdown,\n Chevron: ({ orientation }) => {\n const Icon = orientation === 'left' ? ChevronLeft : ChevronRight\n return <Icon className=\"h-4 w-4\" />\n }\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n","import * as React from \"react\"\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\n\nimport { cn } from \"../../core/utils\"\n\nconst Popover = PopoverPrimitive.Root\n\nconst PopoverTrigger = PopoverPrimitive.Trigger\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n))\nPopoverContent.displayName = PopoverPrimitive.Content.displayName\n\nexport { Popover, PopoverTrigger, PopoverContent }\n\n"]}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { cn } from './chunk-VPU66PI6.mjs';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { ChevronRight } from 'lucide-react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function getStatusBasedClass(status) {
|
|
7
|
+
switch ((status || "").toLowerCase()) {
|
|
8
|
+
case "high":
|
|
9
|
+
return "bg-red-100 text-red-500";
|
|
10
|
+
case "medium":
|
|
11
|
+
return "bg-yellow-100 text-yellow-600";
|
|
12
|
+
case "low":
|
|
13
|
+
return "bg-green-100 text-green-600";
|
|
14
|
+
default:
|
|
15
|
+
return "bg-gray-200 text-gray-600";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function DiagnosisCard({ item, defaultOpen = false }) {
|
|
19
|
+
const [open, setOpen] = useState(defaultOpen);
|
|
20
|
+
return /* @__PURE__ */ jsxs("div", { className: "border border-gray-200 rounded-lg bg-[#F2F2F2] mb-2 last:mb-0 overflow-hidden", children: [
|
|
21
|
+
/* @__PURE__ */ jsxs(
|
|
22
|
+
"button",
|
|
23
|
+
{
|
|
24
|
+
type: "button",
|
|
25
|
+
onClick: () => setOpen((o) => !o),
|
|
26
|
+
className: cn(
|
|
27
|
+
"w-full text-left flex items-center gap-2 py-2 px-3 rounded-lg",
|
|
28
|
+
"cursor-pointer hover:bg-gray-200/60 transition-colors"
|
|
29
|
+
),
|
|
30
|
+
children: [
|
|
31
|
+
/* @__PURE__ */ jsx(
|
|
32
|
+
ChevronRight,
|
|
33
|
+
{
|
|
34
|
+
className: cn("h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform", open && "rotate-90")
|
|
35
|
+
}
|
|
36
|
+
),
|
|
37
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
38
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500 font-medium", children: item.category.charAt(0).toUpperCase() + item.category.slice(1) }),
|
|
39
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-black font-semibold mt-0.5 leading-tight", children: item.condition })
|
|
40
|
+
] })
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
),
|
|
44
|
+
open && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 px-3 pb-3 pt-0 pl-9", children: [
|
|
45
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between text-xs font-semibold text-gray-500", children: [
|
|
46
|
+
/* @__PURE__ */ jsx("span", { children: "LIKELIHOOD" }),
|
|
47
|
+
/* @__PURE__ */ jsx("span", { children: "SEVERITY" }),
|
|
48
|
+
/* @__PURE__ */ jsx("span", { children: "TREATABILITY" })
|
|
49
|
+
] }),
|
|
50
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-2", children: [
|
|
51
|
+
/* @__PURE__ */ jsx("span", { className: cn("px-2.5 py-0.5 rounded-full text-xs font-bold shrink-0", getStatusBasedClass(item.likelihood)), children: item.likelihood }),
|
|
52
|
+
/* @__PURE__ */ jsx("span", { className: cn("px-2.5 py-0.5 rounded-full text-xs font-bold shrink-0", getStatusBasedClass(item.severity)), children: item.severity }),
|
|
53
|
+
/* @__PURE__ */ jsx("span", { className: cn("px-2.5 py-0.5 rounded-full text-xs font-bold shrink-0", getStatusBasedClass(item.treatability)), children: item.treatability })
|
|
54
|
+
] }),
|
|
55
|
+
item.keyFeatures && item.keyFeatures.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
|
|
56
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs font-semibold text-gray-500 mb-0.5 uppercase tracking-wider", children: "Key Features" }),
|
|
57
|
+
/* @__PURE__ */ jsx("ul", { className: "list-disc pl-4 text-xs text-gray-700 space-y-0.5", children: item.keyFeatures.map((feature, i) => /* @__PURE__ */ jsx("li", { children: feature }, i)) })
|
|
58
|
+
] }),
|
|
59
|
+
item.nextSteps && item.nextSteps.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
|
|
60
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs font-semibold text-gray-500 mb-0.5 uppercase tracking-wider", children: "Next Steps" }),
|
|
61
|
+
/* @__PURE__ */ jsx("ul", { className: "list-disc pl-4 text-xs text-gray-700 space-y-0.5", children: item.nextSteps.map((step, i) => /* @__PURE__ */ jsx("li", { children: step }, i)) })
|
|
62
|
+
] })
|
|
63
|
+
] })
|
|
64
|
+
] });
|
|
65
|
+
}
|
|
66
|
+
var DifferentialDiagnosis = ({
|
|
67
|
+
differentialDiagnosis,
|
|
68
|
+
className = "",
|
|
69
|
+
height = "300px"
|
|
70
|
+
}) => {
|
|
71
|
+
const hasItems = Array.isArray(differentialDiagnosis) && differentialDiagnosis.length > 0;
|
|
72
|
+
return /* @__PURE__ */ jsxs(
|
|
73
|
+
"div",
|
|
74
|
+
{
|
|
75
|
+
className: cn(
|
|
76
|
+
"rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]",
|
|
77
|
+
className
|
|
78
|
+
),
|
|
79
|
+
children: [
|
|
80
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-t-md bg-[#FEE8EC] px-3 py-1.5 text-xs shrink-0 z-[1] text-slate-600 flex items-center font-semibold", children: /* @__PURE__ */ jsx("span", { children: "Differential Diagnosis" }) }),
|
|
81
|
+
/* @__PURE__ */ jsxs(
|
|
82
|
+
"div",
|
|
83
|
+
{
|
|
84
|
+
className: cn(
|
|
85
|
+
"relative bg-white rounded-b-md border-t border-[#D0D0D0] overflow-y-auto p-3",
|
|
86
|
+
"focus-visible:outline-none"
|
|
87
|
+
),
|
|
88
|
+
style: { minHeight: height, maxHeight: height },
|
|
89
|
+
children: [
|
|
90
|
+
hasItems ? differentialDiagnosis.map((item, idx) => /* @__PURE__ */ jsx(DiagnosisCard, { item, defaultOpen: idx === 0 }, idx)) : /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "No differential diagnosis yet." }),
|
|
91
|
+
/* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-[30%] bg-gradient-to-t from-white via-white/80 to-transparent" })
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export { DifferentialDiagnosis };
|
|
101
|
+
//# sourceMappingURL=chunk-BU4ZEAAP.mjs.map
|
|
102
|
+
//# sourceMappingURL=chunk-BU4ZEAAP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/widgets/DifferentialDiagnosis.tsx"],"names":[],"mappings":"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","file":"chunk-BU4ZEAAP.mjs","sourcesContent":["import React, { useState } from 'react';\nimport { ChevronRight } from 'lucide-react';\nimport { cn } from '../../core/utils';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type DifferentialDiagnosisItem = {\n category: string;\n condition: string;\n likelihood: string;\n severity: string;\n treatability: string;\n keyFeatures?: string[];\n nextSteps?: string[];\n};\n\nexport type DifferentialDiagnosisProps = {\n differentialDiagnosis: DifferentialDiagnosisItem[];\n className?: string;\n height?: string;\n};\n\n// ─── Helpers ────────────────────────────────────────────────────────────────────\n\nfunction getStatusBasedClass(status: string): string {\n switch ((status || '').toLowerCase()) {\n case 'high':\n return 'bg-red-100 text-red-500';\n case 'medium':\n return 'bg-yellow-100 text-yellow-600';\n case 'low':\n return 'bg-green-100 text-green-600';\n default:\n return 'bg-gray-200 text-gray-600';\n }\n}\n\n// ─── Diagnosis card (accordion) ─────────────────────────────────────────────────\n\nfunction DiagnosisCard({ item, defaultOpen = false }: { item: DifferentialDiagnosisItem; defaultOpen?: boolean }) {\n const [open, setOpen] = useState(defaultOpen);\n\n return (\n <div className=\"border border-gray-200 rounded-lg bg-[#F2F2F2] mb-2 last:mb-0 overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n className={cn(\n 'w-full text-left flex items-center gap-2 py-2 px-3 rounded-lg',\n 'cursor-pointer hover:bg-gray-200/60 transition-colors'\n )}\n >\n <ChevronRight\n className={cn('h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform', open && 'rotate-90')}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-xs text-gray-500 font-medium\">\n {item.category.charAt(0).toUpperCase() + item.category.slice(1)}\n </div>\n <div className=\"text-sm text-black font-semibold mt-0.5 leading-tight\">{item.condition}</div>\n </div>\n </button>\n\n {open && (\n <div className=\"flex flex-col gap-2 px-3 pb-3 pt-0 pl-9\">\n <div className=\"flex justify-between text-xs font-semibold text-gray-500\">\n <span>LIKELIHOOD</span>\n <span>SEVERITY</span>\n <span>TREATABILITY</span>\n </div>\n <div className=\"flex justify-between gap-2\">\n <span className={cn('px-2.5 py-0.5 rounded-full text-xs font-bold shrink-0', getStatusBasedClass(item.likelihood))}>\n {item.likelihood}\n </span>\n <span className={cn('px-2.5 py-0.5 rounded-full text-xs font-bold shrink-0', getStatusBasedClass(item.severity))}>\n {item.severity}\n </span>\n <span className={cn('px-2.5 py-0.5 rounded-full text-xs font-bold shrink-0', getStatusBasedClass(item.treatability))}>\n {item.treatability}\n </span>\n </div>\n\n {item.keyFeatures && item.keyFeatures.length > 0 && (\n <div className=\"pt-1\">\n <div className=\"text-xs font-semibold text-gray-500 mb-0.5 uppercase tracking-wider\">Key Features</div>\n <ul className=\"list-disc pl-4 text-xs text-gray-700 space-y-0.5\">\n {item.keyFeatures.map((feature, i) => (\n <li key={i}>{feature}</li>\n ))}\n </ul>\n </div>\n )}\n\n {item.nextSteps && item.nextSteps.length > 0 && (\n <div className=\"pt-1\">\n <div className=\"text-xs font-semibold text-gray-500 mb-0.5 uppercase tracking-wider\">Next Steps</div>\n <ul className=\"list-disc pl-4 text-xs text-gray-700 space-y-0.5\">\n {item.nextSteps.map((step, i) => (\n <li key={i}>{step}</li>\n ))}\n </ul>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// ─── Main component ───────────────────────────────────────────────────────────\n\n/**\n * - Outer: rounded border [#D0D0D0], highlight label strip (#FEE8EC)\n * - Body: scrollable list of diagnosis cards with accordion expand/collapse\n */\nexport const DifferentialDiagnosis: React.FC<DifferentialDiagnosisProps> = ({\n differentialDiagnosis,\n className = '',\n height = '300px',\n}) => {\n const hasItems = Array.isArray(differentialDiagnosis) && differentialDiagnosis.length > 0;\n\n return (\n <div\n className={cn(\n 'rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]',\n className\n )}\n >\n {/* Header: highlight-label style */}\n <div className=\"rounded-t-md bg-[#FEE8EC] px-3 py-1.5 text-xs shrink-0 z-[1] text-slate-600 flex items-center font-semibold\">\n <span>Differential Diagnosis</span>\n </div>\n\n {/* Body: scrollable list */}\n <div\n className={cn(\n 'relative bg-white rounded-b-md border-t border-[#D0D0D0] overflow-y-auto p-3',\n 'focus-visible:outline-none'\n )}\n style={{ minHeight: height, maxHeight: height }}\n >\n {hasItems ? (\n differentialDiagnosis.map((item, idx) => (\n <DiagnosisCard key={idx} item={item} defaultOpen={idx === 0} />\n ))\n ) : (\n <p className=\"text-xs text-muted-foreground\">No differential diagnosis yet.</p>\n )}\n\n {/* Progressive blur-style overlay at bottom (30% height) */}\n <div className=\"pointer-events-none absolute inset-x-0 bottom-0 h-[30%] bg-gradient-to-t from-white via-white/80 to-transparent\" />\n </div>\n </div>\n );\n};\n"]}
|