formanitor 0.0.42 → 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1722 -276
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -9
- package/dist/index.d.ts +61 -9
- package/dist/index.mjs +1722 -277
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -137,12 +137,82 @@ function validateForm(values, fields) {
|
|
|
137
137
|
return errors;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
// src/core/suggestionTokens.ts
|
|
141
|
+
function getSuggestionTokensFromText(text) {
|
|
142
|
+
return text.split(/[,\n\r]+/).map((p) => p.trim()).filter(Boolean);
|
|
143
|
+
}
|
|
144
|
+
var DEFAULT_TOKEN_SEPARATOR = ", ";
|
|
145
|
+
function commaSplitLine(line) {
|
|
146
|
+
return line.split(",").map((p) => p.trim()).filter(Boolean);
|
|
147
|
+
}
|
|
148
|
+
function dedupeChipOrder(chips) {
|
|
149
|
+
const seen = /* @__PURE__ */ new Set();
|
|
150
|
+
const out = [];
|
|
151
|
+
for (const c of chips) {
|
|
152
|
+
if (seen.has(c)) continue;
|
|
153
|
+
seen.add(c);
|
|
154
|
+
out.push(c);
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
function parseProseAndChipTokens(text, allowed) {
|
|
159
|
+
const normalized = text.replace(/\r\n/g, "\n");
|
|
160
|
+
let lines = normalized.split("\n");
|
|
161
|
+
while (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
162
|
+
lines.pop();
|
|
163
|
+
}
|
|
164
|
+
if (lines.length === 0) return { prose: "", chips: [] };
|
|
165
|
+
let chipStart = lines.length;
|
|
166
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
167
|
+
const toks = commaSplitLine(lines[i]);
|
|
168
|
+
if (toks.length === 0) break;
|
|
169
|
+
if (!toks.every((t) => allowed.has(t))) break;
|
|
170
|
+
chipStart = i;
|
|
171
|
+
}
|
|
172
|
+
if (chipStart < lines.length) {
|
|
173
|
+
const chipLines = lines.slice(chipStart);
|
|
174
|
+
const prose = lines.slice(0, chipStart).join("\n");
|
|
175
|
+
const chips = dedupeChipOrder(chipLines.flatMap(commaSplitLine));
|
|
176
|
+
return { prose, chips };
|
|
177
|
+
}
|
|
178
|
+
const parts = getSuggestionTokensFromText(normalized);
|
|
179
|
+
const chipsFallback = dedupeChipOrder(parts.filter((t) => allowed.has(t)));
|
|
180
|
+
const proseParts = parts.filter((t) => !allowed.has(t));
|
|
181
|
+
return { prose: proseParts.join(DEFAULT_TOKEN_SEPARATOR), chips: chipsFallback };
|
|
182
|
+
}
|
|
183
|
+
function composeProseAndChips(prose, chips, separator = DEFAULT_TOKEN_SEPARATOR) {
|
|
184
|
+
const chipStr = dedupeChipOrder(chips).join(separator);
|
|
185
|
+
const p = prose.replace(/\s+$/, "");
|
|
186
|
+
if (p && chipStr) return `${p}
|
|
187
|
+
${chipStr}`;
|
|
188
|
+
if (chipStr) return chipStr;
|
|
189
|
+
return p;
|
|
190
|
+
}
|
|
191
|
+
function toggleSuggestionTokenInText(current, token, separator = DEFAULT_TOKEN_SEPARATOR, allowedChipValues) {
|
|
192
|
+
const t = String(token).trim();
|
|
193
|
+
if (!t) return current;
|
|
194
|
+
if (!allowedChipValues || allowedChipValues.size === 0) {
|
|
195
|
+
const parts = getSuggestionTokensFromText(current);
|
|
196
|
+
const i = parts.findIndex((p) => p === t);
|
|
197
|
+
if (i >= 0) parts.splice(i, 1);
|
|
198
|
+
else parts.push(t);
|
|
199
|
+
return parts.join(separator);
|
|
200
|
+
}
|
|
201
|
+
if (!allowedChipValues.has(t)) return current;
|
|
202
|
+
let { prose, chips } = parseProseAndChipTokens(current, allowedChipValues);
|
|
203
|
+
const idx = chips.indexOf(t);
|
|
204
|
+
if (idx >= 0) chips.splice(idx, 1);
|
|
205
|
+
else chips.push(t);
|
|
206
|
+
chips = dedupeChipOrder(chips);
|
|
207
|
+
return composeProseAndChips(prose, chips, separator);
|
|
208
|
+
}
|
|
209
|
+
|
|
140
210
|
// src/core/rules.ts
|
|
141
211
|
function tokenListContainsString(text, needle) {
|
|
142
212
|
if (typeof text !== "string") return false;
|
|
143
213
|
const want = String(needle).trim();
|
|
144
214
|
if (!want) return false;
|
|
145
|
-
const parts = text
|
|
215
|
+
const parts = getSuggestionTokensFromText(text);
|
|
146
216
|
return parts.includes(want);
|
|
147
217
|
}
|
|
148
218
|
function evaluateCondition(value, condition) {
|
|
@@ -353,7 +423,7 @@ function normalizeGeneralSurgerySmartHistory(raw) {
|
|
|
353
423
|
...painIn,
|
|
354
424
|
severity: Number.isFinite(sev) ? Math.min(10, Math.max(0, Math.round(sev))) : d.pain.severity
|
|
355
425
|
};
|
|
356
|
-
const
|
|
426
|
+
const str4 = (x) => typeof x === "string" ? x : "";
|
|
357
427
|
const strArr = (x) => Array.isArray(x) ? x.filter((i) => typeof i === "string") : [];
|
|
358
428
|
const swell = v.swelling && typeof v.swelling === "object" ? v.swelling : {};
|
|
359
429
|
const gi = v.gi && typeof v.gi === "object" ? v.gi : {};
|
|
@@ -363,44 +433,44 @@ function normalizeGeneralSurgerySmartHistory(raw) {
|
|
|
363
433
|
return {
|
|
364
434
|
pain,
|
|
365
435
|
swelling: {
|
|
366
|
-
duration:
|
|
367
|
-
sizeProgression:
|
|
368
|
-
painfulPainless:
|
|
436
|
+
duration: str4(swell.duration),
|
|
437
|
+
sizeProgression: str4(swell.sizeProgression),
|
|
438
|
+
painfulPainless: str4(swell.painfulPainless),
|
|
369
439
|
checks: strArr(swell.checks)
|
|
370
440
|
},
|
|
371
441
|
gi: {
|
|
372
|
-
appetite:
|
|
373
|
-
weightLoss:
|
|
374
|
-
bowelHabits:
|
|
442
|
+
appetite: str4(gi.appetite),
|
|
443
|
+
weightLoss: str4(gi.weightLoss),
|
|
444
|
+
bowelHabits: str4(gi.bowelHabits),
|
|
375
445
|
checks: strArr(gi.checks)
|
|
376
446
|
},
|
|
377
447
|
breast: {
|
|
378
|
-
lumpDuration:
|
|
379
|
-
nippleDischarge:
|
|
448
|
+
lumpDuration: str4(breast.lumpDuration),
|
|
449
|
+
nippleDischarge: str4(breast.nippleDischarge),
|
|
380
450
|
checks: strArr(breast.checks)
|
|
381
451
|
},
|
|
382
452
|
ano: { checks: strArr(ano.checks) },
|
|
383
453
|
thyroid: {
|
|
384
|
-
swellingDuration:
|
|
454
|
+
swellingDuration: str4(thy.swellingDuration),
|
|
385
455
|
checks: strArr(thy.checks)
|
|
386
456
|
}
|
|
387
457
|
};
|
|
388
458
|
}
|
|
389
459
|
function normalizeBreastExamSide(partial) {
|
|
390
460
|
const e = defaultBreastExamSide();
|
|
391
|
-
const
|
|
392
|
-
const
|
|
461
|
+
const str4 = (x) => typeof x === "string" ? x : "";
|
|
462
|
+
const bool2 = (x) => x === true;
|
|
393
463
|
if (!partial || typeof partial !== "object") return e;
|
|
394
464
|
const p = partial;
|
|
395
465
|
return {
|
|
396
|
-
size:
|
|
397
|
-
quadrant:
|
|
398
|
-
tenderness:
|
|
399
|
-
fixity:
|
|
400
|
-
skinInvolvement:
|
|
401
|
-
consistency:
|
|
402
|
-
axillaryNodes:
|
|
403
|
-
nippleAreolarComplex:
|
|
466
|
+
size: str4(p.size),
|
|
467
|
+
quadrant: str4(p.quadrant),
|
|
468
|
+
tenderness: str4(p.tenderness),
|
|
469
|
+
fixity: str4(p.fixity),
|
|
470
|
+
skinInvolvement: str4(p.skinInvolvement),
|
|
471
|
+
consistency: str4(p.consistency),
|
|
472
|
+
axillaryNodes: bool2(p.axillaryNodes),
|
|
473
|
+
nippleAreolarComplex: bool2(p.nippleAreolarComplex)
|
|
404
474
|
};
|
|
405
475
|
}
|
|
406
476
|
function normalizeBreastExaminationBlock(raw) {
|
|
@@ -424,7 +494,7 @@ function normalizeGeneralSurgeryExamination(raw) {
|
|
|
424
494
|
const th = v.thyroid && typeof v.thyroid === "object" ? v.thyroid : {};
|
|
425
495
|
const ar = v.anorectal && typeof v.anorectal === "object" ? v.anorectal : {};
|
|
426
496
|
const lm = v.limb && typeof v.limb === "object" ? v.limb : {};
|
|
427
|
-
const
|
|
497
|
+
const bool2 = (x) => x === true;
|
|
428
498
|
return {
|
|
429
499
|
general: strArr(v.general),
|
|
430
500
|
regions: strArr(v.regions),
|
|
@@ -437,27 +507,27 @@ function normalizeGeneralSurgeryExamination(raw) {
|
|
|
437
507
|
},
|
|
438
508
|
hernia: {
|
|
439
509
|
site: typeof hb.site === "string" ? hb.site : "",
|
|
440
|
-
reducible:
|
|
441
|
-
coughImpulse:
|
|
442
|
-
tenderness:
|
|
510
|
+
reducible: bool2(hb.reducible),
|
|
511
|
+
coughImpulse: bool2(hb.coughImpulse),
|
|
512
|
+
tenderness: bool2(hb.tenderness)
|
|
443
513
|
},
|
|
444
514
|
breast: normalizeBreastExaminationBlock(br),
|
|
445
515
|
thyroid: {
|
|
446
516
|
size: typeof th.size === "string" ? th.size : "",
|
|
447
|
-
mobileDeglutition:
|
|
448
|
-
nodules:
|
|
449
|
-
cervicalNodes:
|
|
517
|
+
mobileDeglutition: bool2(th.mobileDeglutition),
|
|
518
|
+
nodules: bool2(th.nodules),
|
|
519
|
+
cervicalNodes: bool2(th.cervicalNodes)
|
|
450
520
|
},
|
|
451
521
|
anorectal: {
|
|
452
522
|
inspection: typeof ar.inspection === "string" ? ar.inspection : "",
|
|
453
|
-
dreDone:
|
|
454
|
-
proctoscopyDone:
|
|
523
|
+
dreDone: bool2(ar.dreDone),
|
|
524
|
+
proctoscopyDone: bool2(ar.proctoscopyDone),
|
|
455
525
|
notes: typeof ar.notes === "string" ? ar.notes : ""
|
|
456
526
|
},
|
|
457
527
|
limb: {
|
|
458
|
-
dilatedVeins:
|
|
459
|
-
ulcer:
|
|
460
|
-
oedema:
|
|
528
|
+
dilatedVeins: bool2(lm.dilatedVeins),
|
|
529
|
+
ulcer: bool2(lm.ulcer),
|
|
530
|
+
oedema: bool2(lm.oedema)
|
|
461
531
|
}
|
|
462
532
|
};
|
|
463
533
|
}
|
|
@@ -733,6 +803,375 @@ function formatGeneralSurgeryExaminationToNarrative(v) {
|
|
|
733
803
|
return blocks.join("\n\n");
|
|
734
804
|
}
|
|
735
805
|
|
|
806
|
+
// src/core/urologyPathway.ts
|
|
807
|
+
function defaultUrologySmartHistory() {
|
|
808
|
+
return {
|
|
809
|
+
socrates: {
|
|
810
|
+
site: "",
|
|
811
|
+
onset: "",
|
|
812
|
+
character: "",
|
|
813
|
+
radiation: "",
|
|
814
|
+
associated: "",
|
|
815
|
+
timing: "",
|
|
816
|
+
exacerbating: "",
|
|
817
|
+
severity: 0
|
|
818
|
+
},
|
|
819
|
+
ipss: {
|
|
820
|
+
incomplete: 0,
|
|
821
|
+
frequency: 0,
|
|
822
|
+
intermittency: 0,
|
|
823
|
+
urgency: 0,
|
|
824
|
+
weakStream: 0,
|
|
825
|
+
straining: 0,
|
|
826
|
+
nocturia: 0
|
|
827
|
+
},
|
|
828
|
+
ipssQoL: 0,
|
|
829
|
+
haematuria: {
|
|
830
|
+
present: false,
|
|
831
|
+
timing: "none",
|
|
832
|
+
painful: false,
|
|
833
|
+
clots: false
|
|
834
|
+
},
|
|
835
|
+
sexual: {
|
|
836
|
+
erectile: "none",
|
|
837
|
+
libido: "none",
|
|
838
|
+
ejaculation: "none",
|
|
839
|
+
infertilityMonths: 0
|
|
840
|
+
},
|
|
841
|
+
pastNotes: ""
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
function defaultUrologyExamination() {
|
|
845
|
+
return {
|
|
846
|
+
regions: [],
|
|
847
|
+
general: {
|
|
848
|
+
pallor: false,
|
|
849
|
+
oedema: false,
|
|
850
|
+
icterus: false,
|
|
851
|
+
lymphadenopathy: false
|
|
852
|
+
},
|
|
853
|
+
abdomen: {
|
|
854
|
+
distension: false,
|
|
855
|
+
scars: false,
|
|
856
|
+
mass: false,
|
|
857
|
+
kidneyPalpable: false,
|
|
858
|
+
bladderPalpable: false,
|
|
859
|
+
renalAngleTender: false,
|
|
860
|
+
bladderDull: false
|
|
861
|
+
},
|
|
862
|
+
gu: {
|
|
863
|
+
meatusAbnormal: false,
|
|
864
|
+
phimosis: false,
|
|
865
|
+
lesions: false,
|
|
866
|
+
scrotalSwelling: false,
|
|
867
|
+
transilluminant: false,
|
|
868
|
+
tenderTestis: false,
|
|
869
|
+
hydrocele: false,
|
|
870
|
+
varicocele: false,
|
|
871
|
+
suspiciousMass: false
|
|
872
|
+
},
|
|
873
|
+
dre: {
|
|
874
|
+
done: false,
|
|
875
|
+
sizeGrams: 0,
|
|
876
|
+
consistency: "",
|
|
877
|
+
medianSulcus: "",
|
|
878
|
+
tenderness: false
|
|
879
|
+
},
|
|
880
|
+
examinationNotes: ""
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
function defaultUrologyPathway() {
|
|
884
|
+
return {
|
|
885
|
+
stoneSizeMm: 0,
|
|
886
|
+
hydronephrosis: false,
|
|
887
|
+
prostateVolumeCc: 0,
|
|
888
|
+
psaNgMl: 0,
|
|
889
|
+
uroflowQmaxMlSec: 0,
|
|
890
|
+
risk: {
|
|
891
|
+
ckd: false,
|
|
892
|
+
diabetes: false,
|
|
893
|
+
anticoagulants: false,
|
|
894
|
+
activeInfection: false
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
function ipssItem(v) {
|
|
899
|
+
const n = Number(v);
|
|
900
|
+
if (!Number.isFinite(n)) return 0;
|
|
901
|
+
return Math.min(5, Math.max(0, Math.round(n)));
|
|
902
|
+
}
|
|
903
|
+
function urologyIpssSevenTotal(ipss) {
|
|
904
|
+
return ipss.incomplete + ipss.frequency + ipss.intermittency + ipss.urgency + ipss.weakStream + ipss.straining + ipss.nocturia;
|
|
905
|
+
}
|
|
906
|
+
function urologyIpssBand(total) {
|
|
907
|
+
if (total <= 7) return "Mild";
|
|
908
|
+
if (total <= 19) return "Moderate";
|
|
909
|
+
return "Severe";
|
|
910
|
+
}
|
|
911
|
+
function hopcMeaningfulStr(x) {
|
|
912
|
+
if (typeof x !== "string") return "";
|
|
913
|
+
const t = x.trim();
|
|
914
|
+
if (!t || t.toLowerCase() === "none") return "";
|
|
915
|
+
return t;
|
|
916
|
+
}
|
|
917
|
+
function hopcNonEmpty(lines) {
|
|
918
|
+
return lines.map((s) => (s ?? "").trim()).filter(Boolean);
|
|
919
|
+
}
|
|
920
|
+
function formatUrologySmartHistoryToSymptomsNarrative(safe, flags) {
|
|
921
|
+
const { showPain, showLUTS, showHaem, showSex } = flags;
|
|
922
|
+
const parts = [];
|
|
923
|
+
if (showPain) {
|
|
924
|
+
const s = safe.socrates;
|
|
925
|
+
const painLines = hopcNonEmpty([
|
|
926
|
+
s.site ? `Site: ${s.site}` : "",
|
|
927
|
+
s.onset ? `Onset: ${s.onset}` : "",
|
|
928
|
+
s.character ? `Character: ${s.character}` : "",
|
|
929
|
+
s.radiation ? `Radiation: ${s.radiation}` : "",
|
|
930
|
+
s.associated ? `Associated: ${s.associated}` : "",
|
|
931
|
+
s.timing ? `Timing: ${s.timing}` : "",
|
|
932
|
+
s.exacerbating ? `Exacerbating/relieving: ${s.exacerbating}` : "",
|
|
933
|
+
`Severity: ${s.severity}/10`
|
|
934
|
+
]);
|
|
935
|
+
const hasNonDefaultPain = painLines.length > 1 || painLines.length === 1 && painLines[0] !== "Severity: 0/10";
|
|
936
|
+
if (hasNonDefaultPain) parts.push(`SOCRATES:
|
|
937
|
+
${painLines.join("\n")}`);
|
|
938
|
+
}
|
|
939
|
+
if (showLUTS) {
|
|
940
|
+
const ip = safe.ipss;
|
|
941
|
+
const any = ip.incomplete || ip.frequency || ip.intermittency || ip.urgency || ip.weakStream || ip.straining || ip.nocturia || safe.ipssQoL;
|
|
942
|
+
if (any) {
|
|
943
|
+
const ipssTotal = urologyIpssSevenTotal(safe.ipss);
|
|
944
|
+
const ipssBandLabel = urologyIpssBand(ipssTotal);
|
|
945
|
+
parts.push(`IPSS: ${ipssTotal}/35 (${ipssBandLabel}) \xB7 QoL ${safe.ipssQoL}/6`);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
if (showHaem) {
|
|
949
|
+
const h = safe.haematuria;
|
|
950
|
+
const timing = hopcMeaningfulStr(h.timing);
|
|
951
|
+
const haemLines = hopcNonEmpty([
|
|
952
|
+
h.present ? "Haematuria present" : "",
|
|
953
|
+
timing ? `Timing: ${timing}` : "",
|
|
954
|
+
h.painful ? "Painful" : "",
|
|
955
|
+
h.clots ? "Clots" : ""
|
|
956
|
+
]);
|
|
957
|
+
if (haemLines.length) parts.push(`Haematuria:
|
|
958
|
+
${haemLines.join("\n")}`);
|
|
959
|
+
}
|
|
960
|
+
if (showSex) {
|
|
961
|
+
const sx = safe.sexual;
|
|
962
|
+
const infertility = sx.infertilityMonths;
|
|
963
|
+
const sexLines = hopcNonEmpty([
|
|
964
|
+
hopcMeaningfulStr(sx.erectile) ? `Erectile function: ${hopcMeaningfulStr(sx.erectile)}` : "",
|
|
965
|
+
hopcMeaningfulStr(sx.libido) ? `Libido: ${hopcMeaningfulStr(sx.libido)}` : "",
|
|
966
|
+
hopcMeaningfulStr(sx.ejaculation) ? `Ejaculation: ${hopcMeaningfulStr(sx.ejaculation)}` : "",
|
|
967
|
+
Number.isFinite(infertility) && infertility > 0 ? `Infertility: ${infertility} months` : ""
|
|
968
|
+
]);
|
|
969
|
+
if (sexLines.length) parts.push(`Sexual/reproductive:
|
|
970
|
+
${sexLines.join("\n")}`);
|
|
971
|
+
}
|
|
972
|
+
return parts.join("\n\n").trim();
|
|
973
|
+
}
|
|
974
|
+
function formatUrologyExaminationToClinicalExamination(v) {
|
|
975
|
+
const sections = [];
|
|
976
|
+
const generalLabels = {
|
|
977
|
+
pallor: "Pallor (chronic dz)",
|
|
978
|
+
oedema: "Oedema (renal)",
|
|
979
|
+
icterus: "Icterus",
|
|
980
|
+
lymphadenopathy: "Lymphadenopathy"
|
|
981
|
+
};
|
|
982
|
+
const general = Object.keys(generalLabels).filter((k) => v.general[k]).map((k) => generalLabels[k]);
|
|
983
|
+
if (general.length) sections.push(`General: ${general.join(", ")}`);
|
|
984
|
+
const abdLabels = {
|
|
985
|
+
distension: "Distension",
|
|
986
|
+
scars: "Surgical scars",
|
|
987
|
+
mass: "Visible mass",
|
|
988
|
+
kidneyPalpable: "Kidney palpable",
|
|
989
|
+
bladderPalpable: "Bladder palpable",
|
|
990
|
+
renalAngleTender: "Renal angle tender",
|
|
991
|
+
bladderDull: "Bladder dullness (retention)"
|
|
992
|
+
};
|
|
993
|
+
const abd = Object.keys(abdLabels).filter((k) => v.abdomen[k]).map((k) => abdLabels[k]);
|
|
994
|
+
if (abd.length) sections.push(`Abdomen: ${abd.join(", ")}`);
|
|
995
|
+
const guLabels = {
|
|
996
|
+
meatusAbnormal: "Meatus abnormal (hypospadias?)",
|
|
997
|
+
phimosis: "Phimosis / paraphimosis",
|
|
998
|
+
lesions: "Penile lesions / ulcers",
|
|
999
|
+
scrotalSwelling: "Scrotal swelling",
|
|
1000
|
+
transilluminant: "Transilluminant",
|
|
1001
|
+
tenderTestis: "Tender testis",
|
|
1002
|
+
hydrocele: "Hydrocele",
|
|
1003
|
+
varicocele: "Varicocele",
|
|
1004
|
+
suspiciousMass: "Suspicious mass"
|
|
1005
|
+
};
|
|
1006
|
+
const gu = Object.keys(guLabels).filter((k) => v.gu[k]).map((k) => guLabels[k]);
|
|
1007
|
+
if (gu.length) sections.push(`GU: ${gu.join(", ")}`);
|
|
1008
|
+
const dreBits = hopcNonEmpty([
|
|
1009
|
+
v.dre.done ? "Performed" : "",
|
|
1010
|
+
v.dre.sizeGrams > 0 ? `Size ~${v.dre.sizeGrams} g` : "",
|
|
1011
|
+
v.dre.consistency ? `Consistency: ${v.dre.consistency}` : "",
|
|
1012
|
+
v.dre.medianSulcus ? `Median sulcus: ${v.dre.medianSulcus}` : "",
|
|
1013
|
+
v.dre.tenderness ? "Tenderness" : ""
|
|
1014
|
+
]);
|
|
1015
|
+
if (dreBits.length) sections.push(`DRE: ${dreBits.join(", ")}`);
|
|
1016
|
+
return sections.join("\n");
|
|
1017
|
+
}
|
|
1018
|
+
function str(x) {
|
|
1019
|
+
return typeof x === "string" ? x : "";
|
|
1020
|
+
}
|
|
1021
|
+
function bool(x) {
|
|
1022
|
+
return x === true;
|
|
1023
|
+
}
|
|
1024
|
+
function nonNegInt(x) {
|
|
1025
|
+
const n = Number(x);
|
|
1026
|
+
if (!Number.isFinite(n)) return 0;
|
|
1027
|
+
return Math.max(0, Math.round(n));
|
|
1028
|
+
}
|
|
1029
|
+
function normalizeUrologySmartHistory(raw) {
|
|
1030
|
+
const base = defaultUrologySmartHistory();
|
|
1031
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return base;
|
|
1032
|
+
const r = raw;
|
|
1033
|
+
const soc = r.socrates && typeof r.socrates === "object" && !Array.isArray(r.socrates) ? r.socrates : {};
|
|
1034
|
+
const socObj = soc;
|
|
1035
|
+
const sev = Number(socObj.severity);
|
|
1036
|
+
const socrates = {
|
|
1037
|
+
site: str(socObj.site),
|
|
1038
|
+
onset: str(socObj.onset),
|
|
1039
|
+
character: str(socObj.character),
|
|
1040
|
+
radiation: str(socObj.radiation),
|
|
1041
|
+
associated: str(socObj.associated),
|
|
1042
|
+
timing: str(socObj.timing),
|
|
1043
|
+
exacerbating: str(socObj.exacerbating),
|
|
1044
|
+
severity: Number.isFinite(sev) ? Math.min(10, Math.max(0, Math.round(sev))) : 0
|
|
1045
|
+
};
|
|
1046
|
+
const ipRaw = r.ipss && typeof r.ipss === "object" && !Array.isArray(r.ipss) ? r.ipss : {};
|
|
1047
|
+
const ip = ipRaw;
|
|
1048
|
+
const ipss = {
|
|
1049
|
+
incomplete: ipssItem(ip.incomplete),
|
|
1050
|
+
frequency: ipssItem(ip.frequency),
|
|
1051
|
+
intermittency: ipssItem(ip.intermittency),
|
|
1052
|
+
urgency: ipssItem(ip.urgency),
|
|
1053
|
+
weakStream: ipssItem(ip.weakStream ?? ip.weak_stream),
|
|
1054
|
+
straining: ipssItem(ip.straining),
|
|
1055
|
+
nocturia: ipssItem(ip.nocturia)
|
|
1056
|
+
};
|
|
1057
|
+
const qolRaw = Number(r.ipssQoL);
|
|
1058
|
+
const ipssQoL = Number.isFinite(qolRaw) ? Math.min(6, Math.max(0, Math.round(qolRaw))) : 0;
|
|
1059
|
+
const haRaw = r.haematuria && typeof r.haematuria === "object" && !Array.isArray(r.haematuria) ? r.haematuria : {};
|
|
1060
|
+
const ha = haRaw;
|
|
1061
|
+
const haematuria = {
|
|
1062
|
+
present: bool(ha.present),
|
|
1063
|
+
timing: str(ha.timing) || "none",
|
|
1064
|
+
painful: bool(ha.painful),
|
|
1065
|
+
clots: bool(ha.clots)
|
|
1066
|
+
};
|
|
1067
|
+
const sxRaw = r.sexual && typeof r.sexual === "object" && !Array.isArray(r.sexual) ? r.sexual : {};
|
|
1068
|
+
const sx = sxRaw;
|
|
1069
|
+
const infertilityMonths = nonNegInt(sx.infertilityMonths);
|
|
1070
|
+
const sexual = {
|
|
1071
|
+
erectile: str(sx.erectile) || "none",
|
|
1072
|
+
libido: str(sx.libido) || "none",
|
|
1073
|
+
ejaculation: str(sx.ejaculation) || "none",
|
|
1074
|
+
infertilityMonths
|
|
1075
|
+
};
|
|
1076
|
+
const pastNotes = str(r.pastNotes);
|
|
1077
|
+
return {
|
|
1078
|
+
socrates,
|
|
1079
|
+
ipss,
|
|
1080
|
+
ipssQoL,
|
|
1081
|
+
haematuria,
|
|
1082
|
+
sexual,
|
|
1083
|
+
pastNotes
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
function dreSelectStr(x) {
|
|
1087
|
+
const t = str(x).trim();
|
|
1088
|
+
if (!t || t.toLowerCase() === "none") return "";
|
|
1089
|
+
return t;
|
|
1090
|
+
}
|
|
1091
|
+
function normalizeUrologyExamination(raw) {
|
|
1092
|
+
const base = defaultUrologyExamination();
|
|
1093
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return base;
|
|
1094
|
+
const r = raw;
|
|
1095
|
+
const regions = Array.isArray(r.regions) ? r.regions.filter((x) => typeof x === "string") : [];
|
|
1096
|
+
const g = r.general && typeof r.general === "object" && !Array.isArray(r.general) ? r.general : {};
|
|
1097
|
+
const gObj = g;
|
|
1098
|
+
const general = {
|
|
1099
|
+
pallor: bool(gObj.pallor),
|
|
1100
|
+
oedema: bool(gObj.oedema),
|
|
1101
|
+
icterus: bool(gObj.icterus),
|
|
1102
|
+
lymphadenopathy: bool(gObj.lymphadenopathy)
|
|
1103
|
+
};
|
|
1104
|
+
const ab = r.abdomen && typeof r.abdomen === "object" && !Array.isArray(r.abdomen) ? r.abdomen : {};
|
|
1105
|
+
const abObj = ab;
|
|
1106
|
+
const abdomen = {
|
|
1107
|
+
distension: bool(abObj.distension),
|
|
1108
|
+
scars: bool(abObj.scars),
|
|
1109
|
+
mass: bool(abObj.mass),
|
|
1110
|
+
kidneyPalpable: bool(abObj.kidneyPalpable),
|
|
1111
|
+
bladderPalpable: bool(abObj.bladderPalpable),
|
|
1112
|
+
renalAngleTender: bool(abObj.renalAngleTender),
|
|
1113
|
+
bladderDull: bool(abObj.bladderDull)
|
|
1114
|
+
};
|
|
1115
|
+
const guRaw = r.gu && typeof r.gu === "object" && !Array.isArray(r.gu) ? r.gu : {};
|
|
1116
|
+
const guObj = guRaw;
|
|
1117
|
+
const gu = {
|
|
1118
|
+
meatusAbnormal: bool(guObj.meatusAbnormal),
|
|
1119
|
+
phimosis: bool(guObj.phimosis),
|
|
1120
|
+
lesions: bool(guObj.lesions),
|
|
1121
|
+
scrotalSwelling: bool(guObj.scrotalSwelling),
|
|
1122
|
+
transilluminant: bool(guObj.transilluminant),
|
|
1123
|
+
tenderTestis: bool(guObj.tenderTestis),
|
|
1124
|
+
hydrocele: bool(guObj.hydrocele),
|
|
1125
|
+
varicocele: bool(guObj.varicocele),
|
|
1126
|
+
suspiciousMass: bool(guObj.suspiciousMass)
|
|
1127
|
+
};
|
|
1128
|
+
const dr = r.dre && typeof r.dre === "object" && !Array.isArray(r.dre) ? r.dre : {};
|
|
1129
|
+
const drObj = dr;
|
|
1130
|
+
const sizeG = Number(drObj.sizeGrams);
|
|
1131
|
+
const dre = {
|
|
1132
|
+
done: bool(drObj.done),
|
|
1133
|
+
sizeGrams: Number.isFinite(sizeG) && sizeG >= 0 ? Math.round(sizeG) : 0,
|
|
1134
|
+
consistency: dreSelectStr(drObj.consistency),
|
|
1135
|
+
medianSulcus: dreSelectStr(drObj.medianSulcus),
|
|
1136
|
+
tenderness: bool(drObj.tenderness)
|
|
1137
|
+
};
|
|
1138
|
+
const examinationNotes = str(r.examinationNotes);
|
|
1139
|
+
return {
|
|
1140
|
+
regions,
|
|
1141
|
+
general,
|
|
1142
|
+
abdomen,
|
|
1143
|
+
gu,
|
|
1144
|
+
dre,
|
|
1145
|
+
examinationNotes
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
function normalizeUrologyPathway(raw) {
|
|
1149
|
+
const base = defaultUrologyPathway();
|
|
1150
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return base;
|
|
1151
|
+
const r = raw;
|
|
1152
|
+
const stoneSizeMm = nonNegInt(r.stoneSizeMm);
|
|
1153
|
+
const hydronephrosis = bool(r.hydronephrosis);
|
|
1154
|
+
const prostateVolumeCc = Math.max(0, Number(r.prostateVolumeCc) || 0);
|
|
1155
|
+
const psaNgMl = Math.max(0, Number(r.psaNgMl) || 0);
|
|
1156
|
+
const uroflowQmaxMlSec = Math.max(0, Number(r.uroflowQmaxMlSec) || 0);
|
|
1157
|
+
const riskRaw = r.risk && typeof r.risk === "object" && !Array.isArray(r.risk) ? r.risk : {};
|
|
1158
|
+
const rk = riskRaw;
|
|
1159
|
+
const risk = {
|
|
1160
|
+
ckd: bool(rk.ckd),
|
|
1161
|
+
diabetes: bool(rk.diabetes),
|
|
1162
|
+
anticoagulants: bool(rk.anticoagulants),
|
|
1163
|
+
activeInfection: bool(rk.activeInfection)
|
|
1164
|
+
};
|
|
1165
|
+
return {
|
|
1166
|
+
stoneSizeMm,
|
|
1167
|
+
hydronephrosis,
|
|
1168
|
+
prostateVolumeCc,
|
|
1169
|
+
psaNgMl,
|
|
1170
|
+
uroflowQmaxMlSec,
|
|
1171
|
+
risk
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
|
|
736
1175
|
// src/core/painScaleFlags.ts
|
|
737
1176
|
function normalizePainScaleFlags(raw, bounds) {
|
|
738
1177
|
const min = bounds?.min ?? 0;
|
|
@@ -845,6 +1284,12 @@ var FormStore = class {
|
|
|
845
1284
|
values[field.id] = field.defaultValue ?? defaultGeneralSurgeryExamination();
|
|
846
1285
|
} else if (field.type === "general_surgery_grading") {
|
|
847
1286
|
values[field.id] = field.defaultValue ?? defaultGeneralSurgeryGrading();
|
|
1287
|
+
} else if (field.type === "urology_smart_history") {
|
|
1288
|
+
values[field.id] = field.defaultValue ?? defaultUrologySmartHistory();
|
|
1289
|
+
} else if (field.type === "urology_examination") {
|
|
1290
|
+
values[field.id] = field.defaultValue ?? defaultUrologyExamination();
|
|
1291
|
+
} else if (field.type === "urology_pathway") {
|
|
1292
|
+
values[field.id] = field.defaultValue ?? defaultUrologyPathway();
|
|
848
1293
|
} else if (field.type === "pain_scale_flags") {
|
|
849
1294
|
const f = field;
|
|
850
1295
|
values[field.id] = normalizePainScaleFlags(
|
|
@@ -8558,26 +9003,11 @@ var DischargeMedicationOrdersWidget = ({ fieldId }) => {
|
|
|
8558
9003
|
showError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500", children: error })
|
|
8559
9004
|
] });
|
|
8560
9005
|
};
|
|
8561
|
-
var
|
|
9006
|
+
var DEFAULT_TOKEN_SEPARATOR2 = ", ";
|
|
8562
9007
|
function getAppendSeparator(def) {
|
|
8563
|
-
const raw = def.meta && typeof def.meta.appendSeparator === "string" ? def.meta.appendSeparator :
|
|
9008
|
+
const raw = def.meta && typeof def.meta.appendSeparator === "string" ? def.meta.appendSeparator : DEFAULT_TOKEN_SEPARATOR2;
|
|
8564
9009
|
return raw;
|
|
8565
9010
|
}
|
|
8566
|
-
function getSuggestionTokensFromText(text) {
|
|
8567
|
-
return text.split(",").map((p) => p.trim()).filter(Boolean);
|
|
8568
|
-
}
|
|
8569
|
-
function toggleSuggestionTokenInText(current, token, separator = DEFAULT_TOKEN_SEPARATOR) {
|
|
8570
|
-
const t = String(token).trim();
|
|
8571
|
-
if (!t) return current;
|
|
8572
|
-
const parts = getSuggestionTokensFromText(current);
|
|
8573
|
-
const i = parts.findIndex((p) => p === t);
|
|
8574
|
-
if (i >= 0) {
|
|
8575
|
-
parts.splice(i, 1);
|
|
8576
|
-
} else {
|
|
8577
|
-
parts.push(t);
|
|
8578
|
-
}
|
|
8579
|
-
return parts.join(separator);
|
|
8580
|
-
}
|
|
8581
9011
|
function isTokenSelected(text, optionValue) {
|
|
8582
9012
|
const t = String(optionValue).trim();
|
|
8583
9013
|
if (!t) return false;
|
|
@@ -8651,8 +9081,11 @@ var SuggestionTextareaWidget = ({ fieldId }) => {
|
|
|
8651
9081
|
setOptions([]);
|
|
8652
9082
|
}
|
|
8653
9083
|
}, [def]);
|
|
9084
|
+
const chipAllowedSet = React15.useMemo(
|
|
9085
|
+
() => new Set(options.map((o) => String(o.value).trim()).filter(Boolean)),
|
|
9086
|
+
[options]
|
|
9087
|
+
);
|
|
8654
9088
|
React15.useEffect(() => {
|
|
8655
|
-
if (!parallelChipFieldId || !def) return;
|
|
8656
9089
|
const parallelDef = store.getFieldDef(parallelChipFieldId);
|
|
8657
9090
|
if (!parallelDef || parallelDef.type !== "multiselect") return;
|
|
8658
9091
|
const next = deriveKnownSuggestionChipValues(textValue, options);
|
|
@@ -8678,7 +9111,7 @@ var SuggestionTextareaWidget = ({ fieldId }) => {
|
|
|
8678
9111
|
const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { children: labelContent });
|
|
8679
9112
|
const onChipClick = (optValue) => {
|
|
8680
9113
|
if (disabled) return;
|
|
8681
|
-
setValue(toggleSuggestionTokenInText(textValue, String(optValue), appendSeparator));
|
|
9114
|
+
setValue(toggleSuggestionTokenInText(textValue, String(optValue), appendSeparator, chipAllowedSet));
|
|
8682
9115
|
};
|
|
8683
9116
|
const hasSuggestions = options.length > 0;
|
|
8684
9117
|
const hasEmbedded = embeddedFieldIds.length > 0;
|
|
@@ -9117,7 +9550,7 @@ var EMPTY = {
|
|
|
9117
9550
|
specularMicroscopyDone: false,
|
|
9118
9551
|
endothelialCount: ""
|
|
9119
9552
|
};
|
|
9120
|
-
function
|
|
9553
|
+
function str2(x) {
|
|
9121
9554
|
return typeof x === "string" ? x : "";
|
|
9122
9555
|
}
|
|
9123
9556
|
function parseValue2(raw) {
|
|
@@ -9125,24 +9558,24 @@ function parseValue2(raw) {
|
|
|
9125
9558
|
const o = raw;
|
|
9126
9559
|
const m = o.method;
|
|
9127
9560
|
const method = m === "ascan_immersion" || m === "ascan_contact" || m === "optical_biometry" ? m : "optical_biometry";
|
|
9128
|
-
const formula =
|
|
9561
|
+
const formula = str2(o.formula);
|
|
9129
9562
|
return {
|
|
9130
9563
|
...EMPTY,
|
|
9131
|
-
axialLengthOD:
|
|
9132
|
-
axialLengthOS:
|
|
9133
|
-
k1k2AxisOD:
|
|
9134
|
-
k1k2AxisOS:
|
|
9135
|
-
anteriorChamberDepthOD:
|
|
9136
|
-
anteriorChamberDepthOS:
|
|
9137
|
-
iolPowerOD:
|
|
9138
|
-
iolPowerOS:
|
|
9139
|
-
targetRefractionOD:
|
|
9140
|
-
targetRefractionOS:
|
|
9564
|
+
axialLengthOD: str2(o.axialLengthOD),
|
|
9565
|
+
axialLengthOS: str2(o.axialLengthOS),
|
|
9566
|
+
k1k2AxisOD: str2(o.k1k2AxisOD),
|
|
9567
|
+
k1k2AxisOS: str2(o.k1k2AxisOS),
|
|
9568
|
+
anteriorChamberDepthOD: str2(o.anteriorChamberDepthOD),
|
|
9569
|
+
anteriorChamberDepthOS: str2(o.anteriorChamberDepthOS),
|
|
9570
|
+
iolPowerOD: str2(o.iolPowerOD),
|
|
9571
|
+
iolPowerOS: str2(o.iolPowerOS),
|
|
9572
|
+
targetRefractionOD: str2(o.targetRefractionOD),
|
|
9573
|
+
targetRefractionOS: str2(o.targetRefractionOS),
|
|
9141
9574
|
formula: formula || "SRK/T",
|
|
9142
9575
|
method,
|
|
9143
9576
|
cornealTopoUploaded: o.cornealTopoUploaded === true,
|
|
9144
9577
|
specularMicroscopyDone: o.specularMicroscopyDone === true,
|
|
9145
|
-
endothelialCount:
|
|
9578
|
+
endothelialCount: str2(o.endothelialCount)
|
|
9146
9579
|
};
|
|
9147
9580
|
}
|
|
9148
9581
|
var paramCell = "emr-biometry-param text-[11px] font-semibold leading-snug text-foreground sm:text-xs py-2";
|
|
@@ -10613,172 +11046,1020 @@ var PainScaleFlagsWidget = ({ fieldId }) => {
|
|
|
10613
11046
|
showError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500", children: error })
|
|
10614
11047
|
] });
|
|
10615
11048
|
};
|
|
10616
|
-
var
|
|
10617
|
-
|
|
10618
|
-
|
|
10619
|
-
|
|
10620
|
-
|
|
10621
|
-
|
|
11049
|
+
var CHIEF_CHIPS_FIELD3 = "chief_complaints_chips";
|
|
11050
|
+
var ACTIVE_SYNDROME_FIELD = "uro_active_syndrome";
|
|
11051
|
+
var CHIEF_TEXT_FIELD = "chief_complaints";
|
|
11052
|
+
var SYMPTOMS_FIELD = "symptoms";
|
|
11053
|
+
var DIAGNOSIS_FIELD = "diagnosis";
|
|
11054
|
+
var URO_DURATION_FIELD = "uro_chief_duration";
|
|
11055
|
+
var URO_ONSET_FIELD = "uro_chief_onset";
|
|
11056
|
+
var URO_PROGRESSION_FIELD = "uro_chief_progression";
|
|
11057
|
+
var SYNDROME_LABELS = {
|
|
11058
|
+
luts: "LUTS / BPH",
|
|
11059
|
+
stone: "Urolithiasis (stone)",
|
|
11060
|
+
haematuria: "Haematuria",
|
|
11061
|
+
scrotal: "Scrotal swelling",
|
|
11062
|
+
retention: "Acute retention",
|
|
11063
|
+
ed_infertility: "ED / Infertility",
|
|
11064
|
+
uti: "UTI / infection"
|
|
10622
11065
|
};
|
|
10623
|
-
function
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
case "number":
|
|
10627
|
-
return /* @__PURE__ */ jsxRuntime.jsx(TextWidget, { fieldId });
|
|
10628
|
-
case "slider":
|
|
10629
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SliderWidget, { fieldId });
|
|
10630
|
-
case "textarea":
|
|
10631
|
-
if (fieldMetaRequestsMarMedicationOrdersButton(fieldDef.meta)) {
|
|
10632
|
-
return /* @__PURE__ */ jsxRuntime.jsx(MarMedicationOrdersWidget, { fieldId });
|
|
10633
|
-
}
|
|
10634
|
-
return /* @__PURE__ */ jsxRuntime.jsx(TextWidget, { fieldId });
|
|
10635
|
-
case "richtext":
|
|
10636
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RichTextWidget, { fieldId });
|
|
10637
|
-
case "date":
|
|
10638
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DateWidget, { fieldId });
|
|
10639
|
-
case "datetime":
|
|
10640
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DateTimeWidget, { fieldId });
|
|
10641
|
-
case "select":
|
|
10642
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SelectWidget, { fieldId });
|
|
10643
|
-
case "radio":
|
|
10644
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RadioWidget, { fieldId });
|
|
10645
|
-
case "checkbox":
|
|
10646
|
-
return /* @__PURE__ */ jsxRuntime.jsx(CheckboxWidget, { fieldId });
|
|
10647
|
-
case "multiselect":
|
|
10648
|
-
return /* @__PURE__ */ jsxRuntime.jsx(MultiSelectWidget, { fieldId });
|
|
10649
|
-
case "repeatable":
|
|
10650
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RepeatableWidget, { fieldId });
|
|
10651
|
-
case "image_upload":
|
|
10652
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ImageUploadWidget, { fieldId });
|
|
10653
|
-
case "media_upload":
|
|
10654
|
-
return /* @__PURE__ */ jsxRuntime.jsx(MediaUploadWidget, { fieldId });
|
|
10655
|
-
case "signature":
|
|
10656
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SignatureUploadWidget, { fieldId });
|
|
10657
|
-
case "editable_table":
|
|
10658
|
-
return /* @__PURE__ */ jsxRuntime.jsx(EditableTableWidget, { fieldId });
|
|
10659
|
-
case "medications":
|
|
10660
|
-
return /* @__PURE__ */ jsxRuntime.jsx(AddMedicationWidget, { fieldId });
|
|
10661
|
-
case "discharge_medication_orders":
|
|
10662
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DischargeMedicationOrdersWidget, { fieldId });
|
|
10663
|
-
case "investigations":
|
|
10664
|
-
return /* @__PURE__ */ jsxRuntime.jsx(AddInvestigationWidget, { fieldId });
|
|
10665
|
-
case "procedures":
|
|
10666
|
-
return /* @__PURE__ */ jsxRuntime.jsx(AddProcedureWidget, { fieldId });
|
|
10667
|
-
case "differential_diagnosis":
|
|
10668
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DifferentialDiagnosisWidget, { fieldId });
|
|
10669
|
-
case "vitals":
|
|
10670
|
-
return /* @__PURE__ */ jsxRuntime.jsx(VitalsWidget, { fieldId });
|
|
10671
|
-
case "hidden_vitals":
|
|
10672
|
-
return /* @__PURE__ */ jsxRuntime.jsx(HiddenVitalsWidget, { fieldId });
|
|
10673
|
-
case "referral":
|
|
10674
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ReferralWidget, { fieldId });
|
|
10675
|
-
case "followup":
|
|
10676
|
-
return /* @__PURE__ */ jsxRuntime.jsx(FollowupWidget, { fieldId });
|
|
10677
|
-
case "smart_textarea":
|
|
10678
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SmartTextareaWidget, { fieldId });
|
|
10679
|
-
case "diagnosis_textarea":
|
|
10680
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DiagnosisTextareaWidget, { fieldId });
|
|
10681
|
-
case "obstetric_history":
|
|
10682
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ObstetricHistoryWidget, { fieldId });
|
|
10683
|
-
case "eye_prescription":
|
|
10684
|
-
return /* @__PURE__ */ jsxRuntime.jsx(OphthalmologyWidget, { fieldId });
|
|
10685
|
-
case "ophthal_diagnosis":
|
|
10686
|
-
return /* @__PURE__ */ jsxRuntime.jsx(OphthalDiagnosisWidget, { fieldId });
|
|
10687
|
-
case "orthopedic_exam":
|
|
10688
|
-
return /* @__PURE__ */ jsxRuntime.jsx(OrthopedicExamWidget, { fieldId });
|
|
10689
|
-
case "general_surgery_smart_history":
|
|
10690
|
-
return /* @__PURE__ */ jsxRuntime.jsx(GsSmartHistoryWidget, { fieldId });
|
|
10691
|
-
case "general_surgery_examination":
|
|
10692
|
-
return /* @__PURE__ */ jsxRuntime.jsx(GsExaminationWidget, { fieldId });
|
|
10693
|
-
case "general_surgery_grading":
|
|
10694
|
-
return /* @__PURE__ */ jsxRuntime.jsx(GsGradingWidget, { fieldId });
|
|
10695
|
-
case "pain_scale_flags":
|
|
10696
|
-
return /* @__PURE__ */ jsxRuntime.jsx(PainScaleFlagsWidget, { fieldId });
|
|
10697
|
-
case "toggle": {
|
|
10698
|
-
const { value, setValue, setTouched, disabled } = useField(fieldId);
|
|
10699
|
-
const store = useFormStore();
|
|
10700
|
-
const excludes = fieldDef.excludes ?? [];
|
|
10701
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
10702
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10703
|
-
Switch,
|
|
10704
|
-
{
|
|
10705
|
-
checked: value === true,
|
|
10706
|
-
disabled,
|
|
10707
|
-
onCheckedChange: (checked) => {
|
|
10708
|
-
setValue(checked);
|
|
10709
|
-
setTouched();
|
|
10710
|
-
if (checked) excludes.forEach((id) => store.setValue(id, false));
|
|
10711
|
-
}
|
|
10712
|
-
}
|
|
10713
|
-
),
|
|
10714
|
-
/* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium leading-none cursor-pointer select-none", children: fieldDef.label })
|
|
10715
|
-
] });
|
|
10716
|
-
}
|
|
10717
|
-
case "suggestion_textarea":
|
|
10718
|
-
case "complaint_chips":
|
|
10719
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SuggestionTextareaWidget, { fieldId });
|
|
10720
|
-
case "lens_assessment":
|
|
10721
|
-
return /* @__PURE__ */ jsxRuntime.jsx(LensAssessmentWidget, { fieldId });
|
|
10722
|
-
case "functional_impairment_score":
|
|
10723
|
-
return /* @__PURE__ */ jsxRuntime.jsx(FunctionalImpairmentScoreWidget, { fieldId });
|
|
10724
|
-
case "biometry_iol_workup":
|
|
10725
|
-
return /* @__PURE__ */ jsxRuntime.jsx(BiometryIolWorkupWidget, { fieldId });
|
|
10726
|
-
case "surgical_risk_flags":
|
|
10727
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SurgicalRiskFlagsWidget, { fieldId });
|
|
10728
|
-
case "static_text": {
|
|
10729
|
-
const def = fieldDef;
|
|
10730
|
-
const size = def.size ?? "regular";
|
|
10731
|
-
const labelClass = size === "large" ? "text-base" : "text-sm";
|
|
10732
|
-
const descClass = size === "large" ? "text-sm" : "text-xs";
|
|
10733
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${labelClass} text-muted-foreground`, children: [
|
|
10734
|
-
def.label,
|
|
10735
|
-
def.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `mt-1 ${descClass} opacity-90`, children: def.description })
|
|
10736
|
-
] });
|
|
10737
|
-
}
|
|
10738
|
-
default:
|
|
10739
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500", children: [
|
|
10740
|
-
"Unknown field type: ",
|
|
10741
|
-
fieldDef.type
|
|
10742
|
-
] });
|
|
10743
|
-
}
|
|
11066
|
+
function chipList2(state) {
|
|
11067
|
+
const raw = state.values[CHIEF_CHIPS_FIELD3];
|
|
11068
|
+
return Array.isArray(raw) ? raw.filter((x) => typeof x === "string") : [];
|
|
10744
11069
|
}
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
|
|
10757
|
-
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
),
|
|
10765
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: contentClassName, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 pt-4 space-y-4 border-t-0", children }) })
|
|
10766
|
-
] });
|
|
11070
|
+
function str3(x) {
|
|
11071
|
+
return typeof x === "string" ? x : "";
|
|
11072
|
+
}
|
|
11073
|
+
function chiefOptionalFieldDisplay(x) {
|
|
11074
|
+
const s = str3(x).trim();
|
|
11075
|
+
if (!s || s.toLowerCase() === "none") return "";
|
|
11076
|
+
return s;
|
|
11077
|
+
}
|
|
11078
|
+
function nonEmptyLines(lines) {
|
|
11079
|
+
return lines.map((s) => (s ?? "").trim()).filter(Boolean);
|
|
11080
|
+
}
|
|
11081
|
+
var IPSS_LABELS = {
|
|
11082
|
+
incomplete: "Incomplete emptying",
|
|
11083
|
+
frequency: "Frequency (<2h)",
|
|
11084
|
+
intermittency: "Intermittency",
|
|
11085
|
+
urgency: "Urgency",
|
|
11086
|
+
weakStream: "Weak stream",
|
|
11087
|
+
straining: "Straining",
|
|
11088
|
+
nocturia: "Nocturia (\xD7/night)"
|
|
10767
11089
|
};
|
|
10768
|
-
var
|
|
10769
|
-
|
|
10770
|
-
|
|
11090
|
+
var SOCRATES_KEYS2 = [
|
|
11091
|
+
"site",
|
|
11092
|
+
"onset",
|
|
11093
|
+
"character",
|
|
11094
|
+
"radiation",
|
|
11095
|
+
"associated",
|
|
11096
|
+
"timing",
|
|
11097
|
+
"exacerbating"
|
|
11098
|
+
];
|
|
11099
|
+
function Panel2({
|
|
11100
|
+
title,
|
|
11101
|
+
right,
|
|
10771
11102
|
children
|
|
10772
|
-
})
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
11103
|
+
}) {
|
|
11104
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-hidden rounded-md border border-[#D0D0D0] bg-white", children: [
|
|
11105
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b border-[#D0D0D0] bg-[#FEE8EC]/50 px-3 py-1.5", children: [
|
|
11106
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-slate-700", children: title }),
|
|
11107
|
+
right
|
|
11108
|
+
] }),
|
|
11109
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3", children })
|
|
11110
|
+
] });
|
|
11111
|
+
}
|
|
11112
|
+
var UrologySmartHistoryWidget = ({ fieldId }) => {
|
|
11113
|
+
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
11114
|
+
const hopcField = useField(SYMPTOMS_FIELD);
|
|
11115
|
+
const syndromeField = useField(ACTIVE_SYNDROME_FIELD);
|
|
11116
|
+
const { state } = useForm();
|
|
11117
|
+
const store = useFormStore();
|
|
11118
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
11119
|
+
const safe = React15.useMemo(() => normalizeUrologySmartHistory(value), [value]);
|
|
11120
|
+
const chips = React15.useMemo(() => chipList2(state), [state]);
|
|
11121
|
+
const rawSyndrome = syndromeField.value ?? state.values[ACTIVE_SYNDROME_FIELD];
|
|
11122
|
+
const syndrome = typeof rawSyndrome === "string" && rawSyndrome !== "" && rawSyndrome !== "none" ? rawSyndrome : "none";
|
|
11123
|
+
const showPain = chips.includes("pain abdomen flank") || chips.includes("scrotal swelling pain") || syndrome === "stone" || syndrome === "scrotal";
|
|
11124
|
+
const showLUTS = syndrome === "luts" || syndrome === "retention" || chips.includes("frequency urgency") || chips.includes("poor stream") || chips.includes("acute retention");
|
|
11125
|
+
const showHaem = syndrome === "haematuria" || chips.includes("haematuria");
|
|
11126
|
+
const showSex = syndrome === "ed_infertility" || chips.includes("erectile dysfunction") || chips.includes("infertility concern");
|
|
11127
|
+
const update = (next) => {
|
|
11128
|
+
setValue(next);
|
|
11129
|
+
setTouched();
|
|
11130
|
+
};
|
|
11131
|
+
const ipssTotal = urologyIpssSevenTotal(safe.ipss);
|
|
11132
|
+
const ipssBandLabel = urologyIpssBand(ipssTotal);
|
|
11133
|
+
const bandClass = ipssBandLabel === "Severe" ? "bg-red-500/15 text-red-700" : ipssBandLabel === "Moderate" ? "bg-amber-500/15 text-amber-800" : "bg-emerald-500/15 text-emerald-800";
|
|
11134
|
+
const setSocrates = (key, v) => {
|
|
11135
|
+
if (key === "severity") {
|
|
11136
|
+
const n = typeof v === "number" ? v : Number(v);
|
|
11137
|
+
const sev = Number.isFinite(n) ? Math.min(10, Math.max(0, Math.round(n))) : 0;
|
|
11138
|
+
update({ ...safe, socrates: { ...safe.socrates, severity: sev } });
|
|
11139
|
+
return;
|
|
11140
|
+
}
|
|
11141
|
+
update({ ...safe, socrates: { ...safe.socrates, [key]: String(v) } });
|
|
11142
|
+
};
|
|
11143
|
+
const setIpss = (key, v) => {
|
|
11144
|
+
update({ ...safe, ipss: { ...safe.ipss, [key]: v } });
|
|
11145
|
+
};
|
|
11146
|
+
const [hopcNarrativeLocked, setHopcNarrativeLocked] = React15.useState(false);
|
|
11147
|
+
React15.useEffect(() => {
|
|
11148
|
+
if (hopcNarrativeLocked || disabled) return;
|
|
11149
|
+
const next = formatUrologySmartHistoryToSymptomsNarrative(normalizeUrologySmartHistory(value), {
|
|
11150
|
+
showPain,
|
|
11151
|
+
showLUTS,
|
|
11152
|
+
showHaem,
|
|
11153
|
+
showSex
|
|
11154
|
+
});
|
|
11155
|
+
hopcField.setValue(next);
|
|
11156
|
+
}, [value, hopcNarrativeLocked, showPain, showLUTS, showHaem, showSex, disabled]);
|
|
11157
|
+
React15.useEffect(() => {
|
|
11158
|
+
if (disabled) return;
|
|
11159
|
+
const label = syndrome && syndrome !== "none" ? SYNDROME_LABELS[syndrome] ?? syndrome : "";
|
|
11160
|
+
const prev = store.getFieldState(DIAGNOSIS_FIELD)?.value;
|
|
11161
|
+
const prevText = typeof prev === "string" ? prev : "";
|
|
11162
|
+
const syndromeLabels = new Set(Object.values(SYNDROME_LABELS));
|
|
11163
|
+
const keptLines = prevText.split("\n").map((l) => l.trim()).filter(Boolean).filter((l) => !syndromeLabels.has(l));
|
|
11164
|
+
const nextLines = label ? [...keptLines, label] : keptLines;
|
|
11165
|
+
const next = nextLines.join("\n");
|
|
11166
|
+
if (prevText.trim() === next.trim()) return;
|
|
11167
|
+
store.setValues({ [DIAGNOSIS_FIELD]: next }, { touch: false });
|
|
11168
|
+
}, [disabled, store, syndrome]);
|
|
11169
|
+
React15.useEffect(() => {
|
|
11170
|
+
if (disabled) return;
|
|
11171
|
+
const duration = chiefOptionalFieldDisplay(state.values[URO_DURATION_FIELD]);
|
|
11172
|
+
const onset = chiefOptionalFieldDisplay(state.values[URO_ONSET_FIELD]);
|
|
11173
|
+
const progression = chiefOptionalFieldDisplay(state.values[URO_PROGRESSION_FIELD]);
|
|
11174
|
+
const prev = store.getFieldState(CHIEF_TEXT_FIELD)?.value;
|
|
11175
|
+
const prevText = typeof prev === "string" ? prev : "";
|
|
11176
|
+
const kept = prevText.split(",").map((t) => t.trim()).filter(Boolean).filter((t) => {
|
|
11177
|
+
const lower = t.toLowerCase();
|
|
11178
|
+
return !lower.startsWith("duration:") && !lower.startsWith("onset:") && !lower.startsWith("progression:");
|
|
11179
|
+
});
|
|
11180
|
+
const extra = nonEmptyLines([
|
|
11181
|
+
duration ? `Duration: ${duration}` : "",
|
|
11182
|
+
onset ? `Onset: ${onset}` : "",
|
|
11183
|
+
progression ? `Progression: ${progression}` : ""
|
|
11184
|
+
]);
|
|
11185
|
+
const next = [...kept, ...extra].join(", ").trim();
|
|
11186
|
+
if (prevText.trim() === next.trim()) return;
|
|
11187
|
+
store.setValues({ [CHIEF_TEXT_FIELD]: next }, { touch: false });
|
|
11188
|
+
}, [
|
|
11189
|
+
disabled,
|
|
11190
|
+
state.values[URO_DURATION_FIELD],
|
|
11191
|
+
state.values[URO_ONSET_FIELD],
|
|
11192
|
+
state.values[URO_PROGRESSION_FIELD],
|
|
11193
|
+
store
|
|
11194
|
+
]);
|
|
11195
|
+
if (!fieldDef) return null;
|
|
11196
|
+
const theme = getThemeConfig("textarea", fieldDef.theme);
|
|
11197
|
+
const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
|
|
11198
|
+
const labelClass = theme?.labelClassName;
|
|
11199
|
+
const labelContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11200
|
+
fieldDef.label,
|
|
11201
|
+
fieldDef.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
|
|
11202
|
+
] });
|
|
11203
|
+
const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium", children: labelContent });
|
|
11204
|
+
const bodyClass = cn(
|
|
11205
|
+
"-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
|
|
11206
|
+
disabled && "pointer-events-none opacity-60"
|
|
11207
|
+
);
|
|
11208
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
|
|
11209
|
+
labelEl,
|
|
11210
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: bodyClass, children: [
|
|
11211
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-muted-foreground", children: "Panels follow chief complaint chips and active syndrome (Clearsight SmartHistoryUro)." }),
|
|
11212
|
+
showPain ? /* @__PURE__ */ jsxRuntime.jsx(Panel2, { title: "SOCRATES \u2014 Pain (flank / suprapubic / testicular)", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-2 md:grid-cols-4", children: [
|
|
11213
|
+
SOCRATES_KEYS2.map((k) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
11214
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: k }),
|
|
11215
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11216
|
+
Input,
|
|
11217
|
+
{
|
|
11218
|
+
className: "h-8 text-xs",
|
|
11219
|
+
value: safe.socrates[k],
|
|
11220
|
+
onChange: (e) => setSocrates(k, e.target.value),
|
|
11221
|
+
placeholder: k === "radiation" ? "e.g. groin \u2192 ureteric" : k === "character" ? "colicky / dull" : "",
|
|
11222
|
+
disabled
|
|
11223
|
+
}
|
|
11224
|
+
)
|
|
11225
|
+
] }, k)),
|
|
11226
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
11227
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: "Severity 0\u201310" }),
|
|
11228
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11229
|
+
Input,
|
|
11230
|
+
{
|
|
11231
|
+
type: "number",
|
|
11232
|
+
min: 0,
|
|
11233
|
+
max: 10,
|
|
11234
|
+
className: "h-8 text-xs",
|
|
11235
|
+
value: safe.socrates.severity,
|
|
11236
|
+
onChange: (e) => setSocrates("severity", e.target.value),
|
|
11237
|
+
disabled
|
|
11238
|
+
}
|
|
11239
|
+
)
|
|
11240
|
+
] })
|
|
11241
|
+
] }) }) : null,
|
|
11242
|
+
showLUTS ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11243
|
+
Panel2,
|
|
11244
|
+
{
|
|
11245
|
+
title: "IPSS \u2014 International Prostate Symptom Score",
|
|
11246
|
+
right: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `rounded-full px-2 py-0.5 text-[10px] font-medium ${bandClass}`, children: [
|
|
11247
|
+
ipssTotal,
|
|
11248
|
+
"/35 \u2014 ",
|
|
11249
|
+
ipssBandLabel
|
|
11250
|
+
] }),
|
|
11251
|
+
children: [
|
|
11252
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-2 md:grid-cols-4", children: [
|
|
11253
|
+
Object.keys(IPSS_LABELS).map((k) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
11254
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: IPSS_LABELS[k] }),
|
|
11255
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11256
|
+
Select,
|
|
11257
|
+
{
|
|
11258
|
+
value: String(safe.ipss[k]),
|
|
11259
|
+
onValueChange: (val) => setIpss(k, Number(val)),
|
|
11260
|
+
disabled,
|
|
11261
|
+
children: [
|
|
11262
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }),
|
|
11263
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: [0, 1, 2, 3, 4, 5].map((n) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: String(n), children: n }, n)) })
|
|
11264
|
+
]
|
|
11265
|
+
}
|
|
11266
|
+
)
|
|
11267
|
+
] }, k)),
|
|
11268
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
11269
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "QoL (0\u20136)" }),
|
|
11270
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11271
|
+
Select,
|
|
11272
|
+
{
|
|
11273
|
+
value: String(safe.ipssQoL),
|
|
11274
|
+
onValueChange: (val) => update({ ...safe, ipssQoL: Math.min(6, Math.max(0, Number(val))) }),
|
|
11275
|
+
disabled,
|
|
11276
|
+
children: [
|
|
11277
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }),
|
|
11278
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: [0, 1, 2, 3, 4, 5, 6].map((n) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: String(n), children: n }, n)) })
|
|
11279
|
+
]
|
|
11280
|
+
}
|
|
11281
|
+
)
|
|
11282
|
+
] })
|
|
11283
|
+
] }),
|
|
11284
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-2 text-[10px] text-muted-foreground", children: [
|
|
11285
|
+
"Bands: 0\u20137 mild \xB7 8\u201319 moderate \xB7 20\u201335 severe.",
|
|
11286
|
+
" ",
|
|
11287
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground", children: "IPSS \u2265 20 \u2192 consider surgical intervention." })
|
|
11288
|
+
] })
|
|
11289
|
+
]
|
|
11290
|
+
}
|
|
11291
|
+
) : null,
|
|
11292
|
+
showHaem ? /* @__PURE__ */ jsxRuntime.jsxs(Panel2, { title: "Haematuria profile", children: [
|
|
11293
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 text-xs md:grid-cols-4", children: [
|
|
11294
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11295
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11296
|
+
Checkbox,
|
|
11297
|
+
{
|
|
11298
|
+
checked: safe.haematuria.present,
|
|
11299
|
+
onCheckedChange: (c) => update({
|
|
11300
|
+
...safe,
|
|
11301
|
+
haematuria: { ...safe.haematuria, present: c === true }
|
|
11302
|
+
}),
|
|
11303
|
+
disabled
|
|
11304
|
+
}
|
|
11305
|
+
),
|
|
11306
|
+
"Present"
|
|
11307
|
+
] }),
|
|
11308
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11309
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Timing" }),
|
|
11310
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11311
|
+
Select,
|
|
11312
|
+
{
|
|
11313
|
+
value: safe.haematuria.timing || "none",
|
|
11314
|
+
onValueChange: (val) => update({
|
|
11315
|
+
...safe,
|
|
11316
|
+
haematuria: { ...safe.haematuria, timing: val === "none" ? "" : val }
|
|
11317
|
+
}),
|
|
11318
|
+
disabled,
|
|
11319
|
+
children: [
|
|
11320
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11321
|
+
/* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { children: [
|
|
11322
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "none", children: "\u2014" }),
|
|
11323
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Initial", children: "Initial" }),
|
|
11324
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Terminal", children: "Terminal" }),
|
|
11325
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Total", children: "Total" })
|
|
11326
|
+
] })
|
|
11327
|
+
]
|
|
11328
|
+
}
|
|
11329
|
+
)
|
|
11330
|
+
] }),
|
|
11331
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11332
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11333
|
+
Checkbox,
|
|
11334
|
+
{
|
|
11335
|
+
checked: safe.haematuria.painful,
|
|
11336
|
+
onCheckedChange: (c) => update({ ...safe, haematuria: { ...safe.haematuria, painful: c === true } }),
|
|
11337
|
+
disabled
|
|
11338
|
+
}
|
|
11339
|
+
),
|
|
11340
|
+
"Painful"
|
|
11341
|
+
] }),
|
|
11342
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11343
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11344
|
+
Checkbox,
|
|
11345
|
+
{
|
|
11346
|
+
checked: safe.haematuria.clots,
|
|
11347
|
+
onCheckedChange: (c) => update({ ...safe, haematuria: { ...safe.haematuria, clots: c === true } }),
|
|
11348
|
+
disabled
|
|
11349
|
+
}
|
|
11350
|
+
),
|
|
11351
|
+
"Clots"
|
|
11352
|
+
] })
|
|
11353
|
+
] }),
|
|
11354
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-[10px] text-red-600", children: "Painless haematuria = malignancy until proven otherwise." })
|
|
11355
|
+
] }) : null,
|
|
11356
|
+
showSex ? /* @__PURE__ */ jsxRuntime.jsx(Panel2, { title: "Sexual & reproductive history", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 text-xs md:grid-cols-4", children: [
|
|
11357
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11358
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Erectile function" }),
|
|
11359
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11360
|
+
Select,
|
|
11361
|
+
{
|
|
11362
|
+
value: safe.sexual.erectile || "none",
|
|
11363
|
+
onValueChange: (val) => update({
|
|
11364
|
+
...safe,
|
|
11365
|
+
sexual: { ...safe.sexual, erectile: val === "none" ? "" : val }
|
|
11366
|
+
}),
|
|
11367
|
+
disabled,
|
|
11368
|
+
children: [
|
|
11369
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11370
|
+
/* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { children: [
|
|
11371
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "none", children: "\u2014" }),
|
|
11372
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Normal", children: "Normal" }),
|
|
11373
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Mild", children: "Mild" }),
|
|
11374
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Moderate", children: "Moderate" }),
|
|
11375
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Severe", children: "Severe" })
|
|
11376
|
+
] })
|
|
11377
|
+
]
|
|
11378
|
+
}
|
|
11379
|
+
)
|
|
11380
|
+
] }),
|
|
11381
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11382
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Libido" }),
|
|
11383
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11384
|
+
Select,
|
|
11385
|
+
{
|
|
11386
|
+
value: safe.sexual.libido || "none",
|
|
11387
|
+
onValueChange: (val) => update({
|
|
11388
|
+
...safe,
|
|
11389
|
+
sexual: { ...safe.sexual, libido: val === "none" ? "" : val }
|
|
11390
|
+
}),
|
|
11391
|
+
disabled,
|
|
11392
|
+
children: [
|
|
11393
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11394
|
+
/* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { children: [
|
|
11395
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "none", children: "\u2014" }),
|
|
11396
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Normal", children: "Normal" }),
|
|
11397
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Reduced", children: "Reduced" })
|
|
11398
|
+
] })
|
|
11399
|
+
]
|
|
11400
|
+
}
|
|
11401
|
+
)
|
|
11402
|
+
] }),
|
|
11403
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11404
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Ejaculation" }),
|
|
11405
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11406
|
+
Select,
|
|
11407
|
+
{
|
|
11408
|
+
value: safe.sexual.ejaculation || "none",
|
|
11409
|
+
onValueChange: (val) => update({
|
|
11410
|
+
...safe,
|
|
11411
|
+
sexual: { ...safe.sexual, ejaculation: val === "none" ? "" : val }
|
|
11412
|
+
}),
|
|
11413
|
+
disabled,
|
|
11414
|
+
children: [
|
|
11415
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11416
|
+
/* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { children: [
|
|
11417
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "none", children: "\u2014" }),
|
|
11418
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Normal", children: "Normal" }),
|
|
11419
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Premature", children: "Premature" }),
|
|
11420
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Retrograde", children: "Retrograde" }),
|
|
11421
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "Anejaculation", children: "Anejaculation" })
|
|
11422
|
+
] })
|
|
11423
|
+
]
|
|
11424
|
+
}
|
|
11425
|
+
)
|
|
11426
|
+
] }),
|
|
11427
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11428
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Infertility (months)" }),
|
|
11429
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11430
|
+
Input,
|
|
11431
|
+
{
|
|
11432
|
+
type: "number",
|
|
11433
|
+
min: 0,
|
|
11434
|
+
className: "h-8 text-xs",
|
|
11435
|
+
value: safe.sexual.infertilityMonths,
|
|
11436
|
+
onChange: (e) => update({
|
|
11437
|
+
...safe,
|
|
11438
|
+
sexual: {
|
|
11439
|
+
...safe.sexual,
|
|
11440
|
+
infertilityMonths: Math.max(0, Math.round(Number(e.target.value)) || 0)
|
|
11441
|
+
}
|
|
11442
|
+
}),
|
|
11443
|
+
disabled
|
|
11444
|
+
}
|
|
11445
|
+
)
|
|
11446
|
+
] })
|
|
11447
|
+
] }) }) : null,
|
|
11448
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
11449
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
11450
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-xs font-semibold text-slate-700", children: hopcField.fieldDef?.label ?? "History of presenting complaint" }),
|
|
11451
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
11452
|
+
hopcNarrativeLocked ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "rounded bg-amber-50 px-1.5 py-0.5 text-[10px] font-medium text-amber-900 ring-1 ring-amber-200/80", children: [
|
|
11453
|
+
"You edited this summary. Use",
|
|
11454
|
+
" ",
|
|
11455
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "italic", children: "'Regenerate'" }),
|
|
11456
|
+
" to update it from the form."
|
|
11457
|
+
] }) : null,
|
|
11458
|
+
hopcNarrativeLocked ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11459
|
+
Button,
|
|
11460
|
+
{
|
|
11461
|
+
type: "button",
|
|
11462
|
+
variant: "outline",
|
|
11463
|
+
size: "sm",
|
|
11464
|
+
className: "h-7 shrink-0 px-2 text-xs",
|
|
11465
|
+
disabled: disabled || hopcField.disabled,
|
|
11466
|
+
onClick: () => {
|
|
11467
|
+
setHopcNarrativeLocked(false);
|
|
11468
|
+
hopcField.setValue(
|
|
11469
|
+
formatUrologySmartHistoryToSymptomsNarrative(
|
|
11470
|
+
normalizeUrologySmartHistory(value),
|
|
11471
|
+
{ showPain, showLUTS, showHaem, showSex }
|
|
11472
|
+
)
|
|
11473
|
+
);
|
|
11474
|
+
},
|
|
11475
|
+
children: "Regenerate"
|
|
11476
|
+
}
|
|
11477
|
+
) : null
|
|
11478
|
+
] })
|
|
11479
|
+
] }),
|
|
11480
|
+
hopcNarrativeLocked ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground", children: "Edit this box anytime. Use Regenerate to replace with fresh text from the structured fields." }) : null,
|
|
11481
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11482
|
+
Textarea,
|
|
11483
|
+
{
|
|
11484
|
+
className: "min-h-[88px] rounded-md border border-input bg-white text-sm",
|
|
11485
|
+
placeholder: "Auto-filled from chief complaints + smart history\u2026",
|
|
11486
|
+
value: typeof hopcField.value === "string" ? hopcField.value : hopcField.value == null ? "" : String(hopcField.value),
|
|
11487
|
+
onChange: (e) => {
|
|
11488
|
+
setHopcNarrativeLocked(true);
|
|
11489
|
+
hopcField.setValue(e.target.value);
|
|
11490
|
+
hopcField.setTouched();
|
|
11491
|
+
},
|
|
11492
|
+
disabled: disabled || hopcField.disabled
|
|
11493
|
+
}
|
|
11494
|
+
)
|
|
11495
|
+
] })
|
|
11496
|
+
] }),
|
|
11497
|
+
showError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
|
|
11498
|
+
] });
|
|
11499
|
+
};
|
|
11500
|
+
var URO_CLINICAL_EXAMINATION_FIELD = "clinical_examination";
|
|
11501
|
+
var GENERAL_ROWS = [
|
|
11502
|
+
{ key: "pallor", label: "Pallor (chronic dz)" },
|
|
11503
|
+
{ key: "oedema", label: "Oedema (renal)" },
|
|
11504
|
+
{ key: "icterus", label: "Icterus" },
|
|
11505
|
+
{ key: "lymphadenopathy", label: "Lymphadenopathy" }
|
|
11506
|
+
];
|
|
11507
|
+
var ABD_ROWS = [
|
|
11508
|
+
{ key: "distension", label: "Distension" },
|
|
11509
|
+
{ key: "scars", label: "Surgical scars" },
|
|
11510
|
+
{ key: "mass", label: "Visible mass" },
|
|
11511
|
+
{ key: "kidneyPalpable", label: "Kidney palpable" },
|
|
11512
|
+
{ key: "bladderPalpable", label: "Bladder palpable" },
|
|
11513
|
+
{ key: "renalAngleTender", label: "Renal angle tender" },
|
|
11514
|
+
{ key: "bladderDull", label: "Bladder dullness (retention)" }
|
|
11515
|
+
];
|
|
11516
|
+
var GU_ROWS = [
|
|
11517
|
+
{ key: "meatusAbnormal", label: "Meatus abnormal (hypospadias?)" },
|
|
11518
|
+
{ key: "phimosis", label: "Phimosis / paraphimosis" },
|
|
11519
|
+
{ key: "lesions", label: "Penile lesions / ulcers" },
|
|
11520
|
+
{ key: "scrotalSwelling", label: "Scrotal swelling" },
|
|
11521
|
+
{ key: "transilluminant", label: "Transilluminant" },
|
|
11522
|
+
{ key: "tenderTestis", label: "Tender testis" },
|
|
11523
|
+
{ key: "hydrocele", label: "Hydrocele" },
|
|
11524
|
+
{ key: "varicocele", label: "Varicocele" },
|
|
11525
|
+
{ key: "suspiciousMass", label: "Suspicious mass" }
|
|
11526
|
+
];
|
|
11527
|
+
var DRE_CONSISTENCY = ["none", "Soft (benign)", "Firm", "Hard / nodular (malignancy?)"];
|
|
11528
|
+
var DRE_SULCUS = ["none", "Preserved", "Obliterated"];
|
|
11529
|
+
var UrologyExaminationWidget = ({ fieldId }) => {
|
|
11530
|
+
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
11531
|
+
const clinicalField = useField(URO_CLINICAL_EXAMINATION_FIELD);
|
|
11532
|
+
const { state } = useForm();
|
|
11533
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
11534
|
+
const safe = React15.useMemo(() => normalizeUrologyExamination(value), [value]);
|
|
11535
|
+
const [clinicalNarrativeLocked, setClinicalNarrativeLocked] = React15.useState(false);
|
|
11536
|
+
React15.useEffect(() => {
|
|
11537
|
+
if (clinicalNarrativeLocked || disabled) return;
|
|
11538
|
+
const norm = normalizeUrologyExamination(value);
|
|
11539
|
+
const next = formatUrologyExaminationToClinicalExamination(norm);
|
|
11540
|
+
clinicalField.setValue(next);
|
|
11541
|
+
if (norm.examinationNotes !== next) {
|
|
11542
|
+
setValue({ ...norm, examinationNotes: next });
|
|
11543
|
+
}
|
|
11544
|
+
}, [value, clinicalNarrativeLocked, disabled]);
|
|
11545
|
+
const bump = (next) => {
|
|
11546
|
+
setValue(next);
|
|
11547
|
+
setTouched();
|
|
11548
|
+
};
|
|
11549
|
+
const toggleGeneral = (key) => {
|
|
11550
|
+
bump({ ...safe, general: { ...safe.general, [key]: !safe.general[key] } });
|
|
11551
|
+
};
|
|
11552
|
+
const toggleAbdomen = (key) => {
|
|
11553
|
+
bump({ ...safe, abdomen: { ...safe.abdomen, [key]: !safe.abdomen[key] } });
|
|
11554
|
+
};
|
|
11555
|
+
const toggleGu = (key) => {
|
|
11556
|
+
bump({ ...safe, gu: { ...safe.gu, [key]: !safe.gu[key] } });
|
|
11557
|
+
};
|
|
11558
|
+
if (!fieldDef) return null;
|
|
11559
|
+
const theme = getThemeConfig("textarea", fieldDef.theme);
|
|
11560
|
+
const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
|
|
11561
|
+
const labelClass = theme?.labelClassName;
|
|
11562
|
+
const labelContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11563
|
+
fieldDef.label,
|
|
11564
|
+
fieldDef.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
|
|
11565
|
+
] });
|
|
11566
|
+
const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium", children: labelContent });
|
|
11567
|
+
const bodyClass = cn(
|
|
11568
|
+
"-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
|
|
11569
|
+
disabled && "pointer-events-none opacity-60"
|
|
11570
|
+
);
|
|
11571
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
|
|
11572
|
+
labelEl,
|
|
11573
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: bodyClass, children: [
|
|
11574
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-2 xl:grid-cols-4", children: [
|
|
11575
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
11576
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-slate-800", children: "General" }),
|
|
11577
|
+
GENERAL_ROWS.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11578
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11579
|
+
Checkbox,
|
|
11580
|
+
{
|
|
11581
|
+
checked: safe.general[r.key],
|
|
11582
|
+
onCheckedChange: () => toggleGeneral(r.key),
|
|
11583
|
+
disabled
|
|
11584
|
+
}
|
|
11585
|
+
),
|
|
11586
|
+
r.label
|
|
11587
|
+
] }, r.key))
|
|
11588
|
+
] }),
|
|
11589
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
11590
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-slate-800", children: "Abdomen" }),
|
|
11591
|
+
ABD_ROWS.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11592
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11593
|
+
Checkbox,
|
|
11594
|
+
{
|
|
11595
|
+
checked: safe.abdomen[r.key],
|
|
11596
|
+
onCheckedChange: () => toggleAbdomen(r.key),
|
|
11597
|
+
disabled
|
|
11598
|
+
}
|
|
11599
|
+
),
|
|
11600
|
+
r.label
|
|
11601
|
+
] }, r.key))
|
|
11602
|
+
] }),
|
|
11603
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
11604
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-slate-800", children: "External genitalia / scrotum" }),
|
|
11605
|
+
GU_ROWS.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11606
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11607
|
+
Checkbox,
|
|
11608
|
+
{
|
|
11609
|
+
checked: safe.gu[r.key],
|
|
11610
|
+
onCheckedChange: () => toggleGu(r.key),
|
|
11611
|
+
disabled
|
|
11612
|
+
}
|
|
11613
|
+
),
|
|
11614
|
+
r.key === "suspiciousMass" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-red-600", children: r.label }) : r.label
|
|
11615
|
+
] }, r.key))
|
|
11616
|
+
] }),
|
|
11617
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
11618
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-slate-800", children: "DRE \u2014 Prostate" }),
|
|
11619
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11620
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11621
|
+
Checkbox,
|
|
11622
|
+
{
|
|
11623
|
+
checked: safe.dre.done,
|
|
11624
|
+
onCheckedChange: (c) => bump({ ...safe, dre: { ...safe.dre, done: c === true } }),
|
|
11625
|
+
disabled
|
|
11626
|
+
}
|
|
11627
|
+
),
|
|
11628
|
+
"DRE performed"
|
|
11629
|
+
] }),
|
|
11630
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block", children: [
|
|
11631
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block font-medium", children: "Estimated size (g)" }),
|
|
11632
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11633
|
+
Input,
|
|
11634
|
+
{
|
|
11635
|
+
type: "number",
|
|
11636
|
+
min: 0,
|
|
11637
|
+
className: "h-8 text-xs",
|
|
11638
|
+
value: safe.dre.sizeGrams,
|
|
11639
|
+
onChange: (e) => {
|
|
11640
|
+
const n = Number(e.target.value);
|
|
11641
|
+
bump({
|
|
11642
|
+
...safe,
|
|
11643
|
+
dre: {
|
|
11644
|
+
...safe.dre,
|
|
11645
|
+
sizeGrams: Number.isFinite(n) && n >= 0 ? Math.round(n) : 0
|
|
11646
|
+
}
|
|
11647
|
+
});
|
|
11648
|
+
},
|
|
11649
|
+
disabled
|
|
11650
|
+
}
|
|
11651
|
+
)
|
|
11652
|
+
] }),
|
|
11653
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block", children: [
|
|
11654
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block font-medium", children: "Consistency" }),
|
|
11655
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11656
|
+
Select,
|
|
11657
|
+
{
|
|
11658
|
+
value: safe.dre.consistency || "none",
|
|
11659
|
+
onValueChange: (val) => bump({
|
|
11660
|
+
...safe,
|
|
11661
|
+
dre: { ...safe.dre, consistency: val === "none" ? "" : val }
|
|
11662
|
+
}),
|
|
11663
|
+
disabled,
|
|
11664
|
+
children: [
|
|
11665
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11666
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: DRE_CONSISTENCY.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: opt, children: opt === "none" ? "\u2014" : opt }, opt)) })
|
|
11667
|
+
]
|
|
11668
|
+
}
|
|
11669
|
+
)
|
|
11670
|
+
] }),
|
|
11671
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block", children: [
|
|
11672
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block font-medium", children: "Median sulcus" }),
|
|
11673
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11674
|
+
Select,
|
|
11675
|
+
{
|
|
11676
|
+
value: safe.dre.medianSulcus || "none",
|
|
11677
|
+
onValueChange: (val) => bump({
|
|
11678
|
+
...safe,
|
|
11679
|
+
dre: { ...safe.dre, medianSulcus: val === "none" ? "" : val }
|
|
11680
|
+
}),
|
|
11681
|
+
disabled,
|
|
11682
|
+
children: [
|
|
11683
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11684
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: DRE_SULCUS.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: opt, children: opt === "none" ? "\u2014" : opt }, opt)) })
|
|
11685
|
+
]
|
|
11686
|
+
}
|
|
11687
|
+
)
|
|
11688
|
+
] }),
|
|
11689
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11690
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11691
|
+
Checkbox,
|
|
11692
|
+
{
|
|
11693
|
+
checked: safe.dre.tenderness,
|
|
11694
|
+
onCheckedChange: (c) => bump({ ...safe, dre: { ...safe.dre, tenderness: c === true } }),
|
|
11695
|
+
disabled
|
|
11696
|
+
}
|
|
11697
|
+
),
|
|
11698
|
+
"Tender (prostatitis?)"
|
|
11699
|
+
] })
|
|
11700
|
+
] })
|
|
11701
|
+
] }),
|
|
11702
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
11703
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
11704
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-xs font-semibold text-slate-700", children: clinicalField.fieldDef?.label ?? "Clinical examination" }),
|
|
11705
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
11706
|
+
clinicalNarrativeLocked ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "rounded bg-amber-50 px-1.5 py-0.5 text-[10px] font-medium text-amber-900 ring-1 ring-amber-200/80", children: [
|
|
11707
|
+
"You edited this summary. Use",
|
|
11708
|
+
" ",
|
|
11709
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "italic", children: "'Regenerate'" }),
|
|
11710
|
+
" to update it from the form."
|
|
11711
|
+
] }) : null,
|
|
11712
|
+
clinicalNarrativeLocked ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11713
|
+
Button,
|
|
11714
|
+
{
|
|
11715
|
+
type: "button",
|
|
11716
|
+
variant: "outline",
|
|
11717
|
+
size: "sm",
|
|
11718
|
+
className: "h-7 shrink-0 px-2 text-xs",
|
|
11719
|
+
disabled: disabled || clinicalField.disabled,
|
|
11720
|
+
onClick: () => {
|
|
11721
|
+
setClinicalNarrativeLocked(false);
|
|
11722
|
+
const norm = normalizeUrologyExamination(value);
|
|
11723
|
+
clinicalField.setValue(formatUrologyExaminationToClinicalExamination(norm));
|
|
11724
|
+
},
|
|
11725
|
+
children: "Regenerate"
|
|
11726
|
+
}
|
|
11727
|
+
) : null
|
|
11728
|
+
] })
|
|
11729
|
+
] }),
|
|
11730
|
+
clinicalNarrativeLocked ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground", children: "Edit this box anytime. Use Regenerate to replace with fresh text from the structured examination." }) : null,
|
|
11731
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11732
|
+
Textarea,
|
|
11733
|
+
{
|
|
11734
|
+
className: "min-h-[88px] rounded-md border border-input bg-white text-sm",
|
|
11735
|
+
placeholder: "Auto-filled from selections above\u2026",
|
|
11736
|
+
value: typeof clinicalField.value === "string" ? clinicalField.value : clinicalField.value == null ? "" : String(clinicalField.value),
|
|
11737
|
+
onChange: (e) => {
|
|
11738
|
+
setClinicalNarrativeLocked(true);
|
|
11739
|
+
const t = e.target.value;
|
|
11740
|
+
clinicalField.setValue(t);
|
|
11741
|
+
clinicalField.setTouched();
|
|
11742
|
+
setValue({ ...safe, examinationNotes: t });
|
|
11743
|
+
setTouched();
|
|
11744
|
+
},
|
|
11745
|
+
disabled: disabled || clinicalField.disabled
|
|
11746
|
+
}
|
|
11747
|
+
)
|
|
11748
|
+
] })
|
|
11749
|
+
] }),
|
|
11750
|
+
showError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
|
|
11751
|
+
] });
|
|
11752
|
+
};
|
|
11753
|
+
var RISK_ROWS = [
|
|
11754
|
+
{ key: "ckd", label: "Chronic kidney disease" },
|
|
11755
|
+
{ key: "diabetes", label: "Diabetes" },
|
|
11756
|
+
{ key: "anticoagulants", label: "Anticoagulants" },
|
|
11757
|
+
{ key: "activeInfection", label: "Active infection" }
|
|
11758
|
+
];
|
|
11759
|
+
var UrologyPathwayWidget = ({ fieldId }) => {
|
|
11760
|
+
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
11761
|
+
const { state } = useForm();
|
|
11762
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
11763
|
+
const safe = React15.useMemo(() => normalizeUrologyPathway(value), [value]);
|
|
11764
|
+
const update = (next) => {
|
|
11765
|
+
setValue(next);
|
|
11766
|
+
setTouched();
|
|
11767
|
+
};
|
|
11768
|
+
const setNum = (key, raw) => {
|
|
11769
|
+
const n = Number(raw);
|
|
11770
|
+
const v = Number.isFinite(n) && n >= 0 ? n : 0;
|
|
11771
|
+
if (key === "stoneSizeMm") {
|
|
11772
|
+
update({ ...safe, stoneSizeMm: Math.round(v) });
|
|
11773
|
+
return;
|
|
11774
|
+
}
|
|
11775
|
+
update({ ...safe, [key]: v });
|
|
11776
|
+
};
|
|
11777
|
+
const toggleRisk = (key) => {
|
|
11778
|
+
update({
|
|
11779
|
+
...safe,
|
|
11780
|
+
risk: { ...safe.risk, [key]: !safe.risk[key] }
|
|
11781
|
+
});
|
|
11782
|
+
};
|
|
11783
|
+
if (!fieldDef) return null;
|
|
11784
|
+
const theme = getThemeConfig("textarea", fieldDef.theme);
|
|
11785
|
+
const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
|
|
11786
|
+
const labelClass = theme?.labelClassName;
|
|
11787
|
+
const subtitle = fieldDef.meta && typeof fieldDef.meta === "object" && fieldDef.meta !== null ? String(fieldDef.meta.subtitle ?? "") : "";
|
|
11788
|
+
const labelContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11789
|
+
fieldDef.label,
|
|
11790
|
+
fieldDef.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
|
|
11791
|
+
] });
|
|
11792
|
+
const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium", children: labelContent });
|
|
11793
|
+
const bodyClass = cn(
|
|
11794
|
+
"-mt-1 flex min-w-0 flex-col gap-4 border-t border-[#D0D0D0] bg-white px-3 py-3",
|
|
11795
|
+
disabled && "pointer-events-none opacity-60"
|
|
11796
|
+
);
|
|
11797
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
|
|
11798
|
+
labelEl,
|
|
11799
|
+
subtitle ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pt-2 text-[11px] text-muted-foreground", children: subtitle }) : null,
|
|
11800
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: bodyClass, children: [
|
|
11801
|
+
showError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-600", children: error }) : null,
|
|
11802
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 md:grid-cols-2", children: [
|
|
11803
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block space-y-1 text-xs", children: [
|
|
11804
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Stone size (mm)" }),
|
|
11805
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11806
|
+
Input,
|
|
11807
|
+
{
|
|
11808
|
+
type: "number",
|
|
11809
|
+
min: 0,
|
|
11810
|
+
className: "h-8 text-xs",
|
|
11811
|
+
value: safe.stoneSizeMm,
|
|
11812
|
+
onChange: (e) => setNum("stoneSizeMm", e.target.value),
|
|
11813
|
+
disabled
|
|
11814
|
+
}
|
|
11815
|
+
)
|
|
11816
|
+
] }),
|
|
11817
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 pt-6 text-xs", children: [
|
|
11818
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11819
|
+
Checkbox,
|
|
11820
|
+
{
|
|
11821
|
+
checked: safe.hydronephrosis,
|
|
11822
|
+
onCheckedChange: (c) => update({ ...safe, hydronephrosis: c === true }),
|
|
11823
|
+
disabled
|
|
11824
|
+
}
|
|
11825
|
+
),
|
|
11826
|
+
"Hydronephrosis on imaging"
|
|
11827
|
+
] }),
|
|
11828
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block space-y-1 text-xs", children: [
|
|
11829
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Prostate volume (cc)" }),
|
|
11830
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11831
|
+
Input,
|
|
11832
|
+
{
|
|
11833
|
+
type: "number",
|
|
11834
|
+
min: 0,
|
|
11835
|
+
step: 0.1,
|
|
11836
|
+
className: "h-8 text-xs",
|
|
11837
|
+
value: safe.prostateVolumeCc,
|
|
11838
|
+
onChange: (e) => setNum("prostateVolumeCc", e.target.value),
|
|
11839
|
+
disabled
|
|
11840
|
+
}
|
|
11841
|
+
)
|
|
11842
|
+
] }),
|
|
11843
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block space-y-1 text-xs", children: [
|
|
11844
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "PSA (ng/mL)" }),
|
|
11845
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11846
|
+
Input,
|
|
11847
|
+
{
|
|
11848
|
+
type: "number",
|
|
11849
|
+
min: 0,
|
|
11850
|
+
step: 0.01,
|
|
11851
|
+
className: "h-8 text-xs",
|
|
11852
|
+
value: safe.psaNgMl,
|
|
11853
|
+
onChange: (e) => setNum("psaNgMl", e.target.value),
|
|
11854
|
+
disabled
|
|
11855
|
+
}
|
|
11856
|
+
)
|
|
11857
|
+
] }),
|
|
11858
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block space-y-1 text-xs md:col-span-2", children: [
|
|
11859
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Uroflow Qmax (mL/s)" }),
|
|
11860
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11861
|
+
Input,
|
|
11862
|
+
{
|
|
11863
|
+
type: "number",
|
|
11864
|
+
min: 0,
|
|
11865
|
+
step: 0.1,
|
|
11866
|
+
className: "h-8 text-xs",
|
|
11867
|
+
value: safe.uroflowQmaxMlSec,
|
|
11868
|
+
onChange: (e) => setNum("uroflowQmaxMlSec", e.target.value),
|
|
11869
|
+
disabled
|
|
11870
|
+
}
|
|
11871
|
+
)
|
|
11872
|
+
] })
|
|
11873
|
+
] }),
|
|
11874
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 border-t border-muted-foreground/20 pt-3", children: [
|
|
11875
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold text-slate-800", children: "Risk stratification" }),
|
|
11876
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: RISK_ROWS.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
|
|
11877
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11878
|
+
Checkbox,
|
|
11879
|
+
{
|
|
11880
|
+
checked: safe.risk[r.key],
|
|
11881
|
+
onCheckedChange: () => toggleRisk(r.key),
|
|
11882
|
+
disabled
|
|
11883
|
+
}
|
|
11884
|
+
),
|
|
11885
|
+
r.label
|
|
11886
|
+
] }, r.key)) })
|
|
11887
|
+
] })
|
|
11888
|
+
] })
|
|
11889
|
+
] });
|
|
11890
|
+
};
|
|
11891
|
+
var FieldRenderer = ({ fieldId }) => {
|
|
11892
|
+
const { fieldDef, visible } = useField(fieldId);
|
|
11893
|
+
if (!visible || !fieldDef) {
|
|
11894
|
+
return null;
|
|
11895
|
+
}
|
|
11896
|
+
return renderWidget(fieldId, fieldDef);
|
|
11897
|
+
};
|
|
11898
|
+
function renderWidget(fieldId, fieldDef) {
|
|
11899
|
+
switch (fieldDef.type) {
|
|
11900
|
+
case "text":
|
|
11901
|
+
case "number":
|
|
11902
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TextWidget, { fieldId });
|
|
11903
|
+
case "slider":
|
|
11904
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SliderWidget, { fieldId });
|
|
11905
|
+
case "textarea":
|
|
11906
|
+
if (fieldMetaRequestsMarMedicationOrdersButton(fieldDef.meta)) {
|
|
11907
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MarMedicationOrdersWidget, { fieldId });
|
|
11908
|
+
}
|
|
11909
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TextWidget, { fieldId });
|
|
11910
|
+
case "richtext":
|
|
11911
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RichTextWidget, { fieldId });
|
|
11912
|
+
case "date":
|
|
11913
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DateWidget, { fieldId });
|
|
11914
|
+
case "datetime":
|
|
11915
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DateTimeWidget, { fieldId });
|
|
11916
|
+
case "select":
|
|
11917
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SelectWidget, { fieldId });
|
|
11918
|
+
case "radio":
|
|
11919
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RadioWidget, { fieldId });
|
|
11920
|
+
case "checkbox":
|
|
11921
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CheckboxWidget, { fieldId });
|
|
11922
|
+
case "multiselect":
|
|
11923
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MultiSelectWidget, { fieldId });
|
|
11924
|
+
case "repeatable":
|
|
11925
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RepeatableWidget, { fieldId });
|
|
11926
|
+
case "image_upload":
|
|
11927
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ImageUploadWidget, { fieldId });
|
|
11928
|
+
case "media_upload":
|
|
11929
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MediaUploadWidget, { fieldId });
|
|
11930
|
+
case "signature":
|
|
11931
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SignatureUploadWidget, { fieldId });
|
|
11932
|
+
case "editable_table":
|
|
11933
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EditableTableWidget, { fieldId });
|
|
11934
|
+
case "medications":
|
|
11935
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AddMedicationWidget, { fieldId });
|
|
11936
|
+
case "discharge_medication_orders":
|
|
11937
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DischargeMedicationOrdersWidget, { fieldId });
|
|
11938
|
+
case "investigations":
|
|
11939
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AddInvestigationWidget, { fieldId });
|
|
11940
|
+
case "procedures":
|
|
11941
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AddProcedureWidget, { fieldId });
|
|
11942
|
+
case "differential_diagnosis":
|
|
11943
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DifferentialDiagnosisWidget, { fieldId });
|
|
11944
|
+
case "vitals":
|
|
11945
|
+
return /* @__PURE__ */ jsxRuntime.jsx(VitalsWidget, { fieldId });
|
|
11946
|
+
case "hidden_vitals":
|
|
11947
|
+
return /* @__PURE__ */ jsxRuntime.jsx(HiddenVitalsWidget, { fieldId });
|
|
11948
|
+
case "referral":
|
|
11949
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ReferralWidget, { fieldId });
|
|
11950
|
+
case "followup":
|
|
11951
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FollowupWidget, { fieldId });
|
|
11952
|
+
case "smart_textarea":
|
|
11953
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SmartTextareaWidget, { fieldId });
|
|
11954
|
+
case "diagnosis_textarea":
|
|
11955
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DiagnosisTextareaWidget, { fieldId });
|
|
11956
|
+
case "obstetric_history":
|
|
11957
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ObstetricHistoryWidget, { fieldId });
|
|
11958
|
+
case "eye_prescription":
|
|
11959
|
+
return /* @__PURE__ */ jsxRuntime.jsx(OphthalmologyWidget, { fieldId });
|
|
11960
|
+
case "ophthal_diagnosis":
|
|
11961
|
+
return /* @__PURE__ */ jsxRuntime.jsx(OphthalDiagnosisWidget, { fieldId });
|
|
11962
|
+
case "orthopedic_exam":
|
|
11963
|
+
return /* @__PURE__ */ jsxRuntime.jsx(OrthopedicExamWidget, { fieldId });
|
|
11964
|
+
case "general_surgery_smart_history":
|
|
11965
|
+
return /* @__PURE__ */ jsxRuntime.jsx(GsSmartHistoryWidget, { fieldId });
|
|
11966
|
+
case "general_surgery_examination":
|
|
11967
|
+
return /* @__PURE__ */ jsxRuntime.jsx(GsExaminationWidget, { fieldId });
|
|
11968
|
+
case "general_surgery_grading":
|
|
11969
|
+
return /* @__PURE__ */ jsxRuntime.jsx(GsGradingWidget, { fieldId });
|
|
11970
|
+
case "pain_scale_flags":
|
|
11971
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PainScaleFlagsWidget, { fieldId });
|
|
11972
|
+
case "urology_smart_history":
|
|
11973
|
+
return /* @__PURE__ */ jsxRuntime.jsx(UrologySmartHistoryWidget, { fieldId });
|
|
11974
|
+
case "urology_examination":
|
|
11975
|
+
return /* @__PURE__ */ jsxRuntime.jsx(UrologyExaminationWidget, { fieldId });
|
|
11976
|
+
case "urology_pathway":
|
|
11977
|
+
return /* @__PURE__ */ jsxRuntime.jsx(UrologyPathwayWidget, { fieldId });
|
|
11978
|
+
case "toggle": {
|
|
11979
|
+
const { value, setValue, setTouched, disabled } = useField(fieldId);
|
|
11980
|
+
const store = useFormStore();
|
|
11981
|
+
const excludes = fieldDef.excludes ?? [];
|
|
11982
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
11983
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11984
|
+
Switch,
|
|
11985
|
+
{
|
|
11986
|
+
checked: value === true,
|
|
11987
|
+
disabled,
|
|
11988
|
+
onCheckedChange: (checked) => {
|
|
11989
|
+
setValue(checked);
|
|
11990
|
+
setTouched();
|
|
11991
|
+
if (checked) excludes.forEach((id) => store.setValue(id, false));
|
|
11992
|
+
}
|
|
11993
|
+
}
|
|
11994
|
+
),
|
|
11995
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium leading-none cursor-pointer select-none", children: fieldDef.label })
|
|
11996
|
+
] });
|
|
11997
|
+
}
|
|
11998
|
+
case "suggestion_textarea":
|
|
11999
|
+
case "complaint_chips":
|
|
12000
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SuggestionTextareaWidget, { fieldId });
|
|
12001
|
+
case "lens_assessment":
|
|
12002
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LensAssessmentWidget, { fieldId });
|
|
12003
|
+
case "functional_impairment_score":
|
|
12004
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FunctionalImpairmentScoreWidget, { fieldId });
|
|
12005
|
+
case "biometry_iol_workup":
|
|
12006
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BiometryIolWorkupWidget, { fieldId });
|
|
12007
|
+
case "surgical_risk_flags":
|
|
12008
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SurgicalRiskFlagsWidget, { fieldId });
|
|
12009
|
+
case "static_text": {
|
|
12010
|
+
const def = fieldDef;
|
|
12011
|
+
const size = def.size ?? "regular";
|
|
12012
|
+
const labelClass = size === "large" ? "text-base" : "text-sm";
|
|
12013
|
+
const descClass = size === "large" ? "text-sm" : "text-xs";
|
|
12014
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${labelClass} text-muted-foreground`, children: [
|
|
12015
|
+
def.label,
|
|
12016
|
+
def.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `mt-1 ${descClass} opacity-90`, children: def.description })
|
|
12017
|
+
] });
|
|
12018
|
+
}
|
|
12019
|
+
default:
|
|
12020
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500", children: [
|
|
12021
|
+
"Unknown field type: ",
|
|
12022
|
+
fieldDef.type
|
|
12023
|
+
] });
|
|
12024
|
+
}
|
|
12025
|
+
}
|
|
12026
|
+
var Section = ({ title, children }) => {
|
|
12027
|
+
const [expanded, setExpanded] = React15.useState(true);
|
|
12028
|
+
const handleToggle = () => setExpanded((prev) => !prev);
|
|
12029
|
+
const contentClassName = cn(
|
|
12030
|
+
"overflow-hidden transition-[height] duration-200 ease-in-out",
|
|
12031
|
+
!expanded && "hidden"
|
|
12032
|
+
);
|
|
12033
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 border rounded-lg bg-white shadow-sm overflow-hidden", children: [
|
|
12034
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
12035
|
+
"button",
|
|
12036
|
+
{
|
|
12037
|
+
type: "button",
|
|
12038
|
+
onClick: handleToggle,
|
|
12039
|
+
className: "w-full flex items-center justify-between gap-2 p-4 text-left border-b hover:bg-gray-50/80 transition-colors",
|
|
12040
|
+
children: [
|
|
12041
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-medium", children: title }),
|
|
12042
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 text-muted-foreground", "aria-hidden": true, children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-5 w-5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-5 w-5" }) })
|
|
12043
|
+
]
|
|
12044
|
+
}
|
|
12045
|
+
),
|
|
12046
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: contentClassName, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 pt-4 space-y-4 border-t-0", children }) })
|
|
12047
|
+
] });
|
|
12048
|
+
};
|
|
12049
|
+
var ColumnLayout = ({
|
|
12050
|
+
columns,
|
|
12051
|
+
label,
|
|
12052
|
+
children
|
|
12053
|
+
}) => {
|
|
12054
|
+
const gridCols = Math.max(1, Math.min(columns, 12));
|
|
12055
|
+
const gridClass = `grid gap-4 w-full`;
|
|
12056
|
+
const style = {
|
|
12057
|
+
gridTemplateColumns: `repeat(${gridCols}, minmax(0, 1fr))`
|
|
12058
|
+
};
|
|
12059
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
|
|
12060
|
+
label != null && label !== "" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-sm font-medium text-gray-700", children: label }),
|
|
12061
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: gridClass, style, children })
|
|
12062
|
+
] });
|
|
10782
12063
|
};
|
|
10783
12064
|
var DynamicForm = () => {
|
|
10784
12065
|
const store = useFormStore();
|
|
@@ -10814,6 +12095,75 @@ var DynamicForm = () => {
|
|
|
10814
12095
|
})
|
|
10815
12096
|
] });
|
|
10816
12097
|
};
|
|
12098
|
+
function PlainSection({
|
|
12099
|
+
title,
|
|
12100
|
+
showHeading,
|
|
12101
|
+
children
|
|
12102
|
+
}) {
|
|
12103
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 space-y-4", children: [
|
|
12104
|
+
showHeading ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-base font-medium text-foreground", children: title }) : null,
|
|
12105
|
+
children
|
|
12106
|
+
] });
|
|
12107
|
+
}
|
|
12108
|
+
function renderSectionChildren(children) {
|
|
12109
|
+
return children.map((child, index) => {
|
|
12110
|
+
if (typeof child === "string") {
|
|
12111
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FieldRenderer, { fieldId: child }, child);
|
|
12112
|
+
}
|
|
12113
|
+
if (child.type === "column_layout") {
|
|
12114
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12115
|
+
ColumnLayout,
|
|
12116
|
+
{
|
|
12117
|
+
columns: child.columns,
|
|
12118
|
+
label: child.label,
|
|
12119
|
+
children: child.children.map((fieldId) => /* @__PURE__ */ jsxRuntime.jsx(FieldRenderer, { fieldId }, fieldId))
|
|
12120
|
+
},
|
|
12121
|
+
child.id
|
|
12122
|
+
);
|
|
12123
|
+
}
|
|
12124
|
+
return /* @__PURE__ */ jsxRuntime.jsx(React15__namespace.default.Fragment, {}, index);
|
|
12125
|
+
});
|
|
12126
|
+
}
|
|
12127
|
+
var DynamicFormV2 = ({
|
|
12128
|
+
showTitle = true,
|
|
12129
|
+
sectionMode = "plain",
|
|
12130
|
+
showSectionTitles = true,
|
|
12131
|
+
className
|
|
12132
|
+
}) => {
|
|
12133
|
+
const store = useFormStore();
|
|
12134
|
+
const schema = store.getSchema();
|
|
12135
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-6", className), children: [
|
|
12136
|
+
showTitle ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold", children: schema.title }) }) : null,
|
|
12137
|
+
schema.layout.map((node) => {
|
|
12138
|
+
if (node.type === "section") {
|
|
12139
|
+
if (sectionMode === "accordion") {
|
|
12140
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Section, { title: node.title, children: renderSectionChildren(node.children) }, node.id);
|
|
12141
|
+
}
|
|
12142
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12143
|
+
PlainSection,
|
|
12144
|
+
{
|
|
12145
|
+
title: node.title,
|
|
12146
|
+
showHeading: showSectionTitles,
|
|
12147
|
+
children: renderSectionChildren(node.children)
|
|
12148
|
+
},
|
|
12149
|
+
node.id
|
|
12150
|
+
);
|
|
12151
|
+
}
|
|
12152
|
+
if (node.type === "column_layout") {
|
|
12153
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12154
|
+
ColumnLayout,
|
|
12155
|
+
{
|
|
12156
|
+
columns: node.columns,
|
|
12157
|
+
label: node.label,
|
|
12158
|
+
children: node.children.map((fieldId) => /* @__PURE__ */ jsxRuntime.jsx(FieldRenderer, { fieldId }, fieldId))
|
|
12159
|
+
},
|
|
12160
|
+
node.id
|
|
12161
|
+
);
|
|
12162
|
+
}
|
|
12163
|
+
return null;
|
|
12164
|
+
})
|
|
12165
|
+
] });
|
|
12166
|
+
};
|
|
10817
12167
|
var SUGGESTION_KEYS = /* @__PURE__ */ new Set(["medications", "investigations", "procedures"]);
|
|
10818
12168
|
function shallowEqualKeys(a, b) {
|
|
10819
12169
|
const keysA = Object.keys(a);
|
|
@@ -11557,6 +12907,40 @@ var ReadOnlyFieldRenderer = ({
|
|
|
11557
12907
|
].join("\n");
|
|
11558
12908
|
return /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value: lines });
|
|
11559
12909
|
}
|
|
12910
|
+
case "urology_smart_history": {
|
|
12911
|
+
const structuredDisplay = value && typeof value === "object" ? JSON.stringify(normalizeUrologySmartHistory(value), null, 2) : value == null || value === "" ? "\u2014" : String(value);
|
|
12912
|
+
const hopcDef = resolveFieldDef?.("symptoms");
|
|
12913
|
+
const hopcRaw = allValues?.["symptoms"];
|
|
12914
|
+
const hopcStr = typeof hopcRaw === "string" ? hopcRaw : hopcRaw != null && hopcRaw !== "" ? String(hopcRaw) : "";
|
|
12915
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
12916
|
+
/* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value: structuredDisplay }),
|
|
12917
|
+
hopcDef ? /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef: hopcDef, value: hopcStr }) : hopcStr ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
12918
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-700", children: "History of presenting complaint" }),
|
|
12919
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-900 border border-gray-200 rounded-md p-3 bg-gray-50 min-h-[2.5rem] whitespace-pre-wrap", children: hopcStr })
|
|
12920
|
+
] }) : null
|
|
12921
|
+
] });
|
|
12922
|
+
}
|
|
12923
|
+
case "urology_examination": {
|
|
12924
|
+
const structuredDisplay = value && typeof value === "object" ? JSON.stringify(value, null, 2) : value == null || value === "" ? "\u2014" : String(value);
|
|
12925
|
+
const clinicalDef = resolveFieldDef?.("clinical_examination");
|
|
12926
|
+
const clinicalRaw = allValues?.["clinical_examination"];
|
|
12927
|
+
const clinicalStr = typeof clinicalRaw === "string" ? clinicalRaw : clinicalRaw != null && clinicalRaw !== "" ? String(clinicalRaw) : "";
|
|
12928
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
12929
|
+
/* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value: structuredDisplay }),
|
|
12930
|
+
clinicalDef ? /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef: clinicalDef, value: clinicalStr }) : clinicalStr ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
12931
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-700", children: "Clinical examination" }),
|
|
12932
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-900 border border-gray-200 rounded-md p-3 bg-gray-50 min-h-[2.5rem] whitespace-pre-wrap", children: clinicalStr })
|
|
12933
|
+
] }) : null
|
|
12934
|
+
] });
|
|
12935
|
+
}
|
|
12936
|
+
case "urology_pathway":
|
|
12937
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12938
|
+
ReadOnlyText,
|
|
12939
|
+
{
|
|
12940
|
+
fieldDef,
|
|
12941
|
+
value: value && typeof value === "object" ? JSON.stringify(value, null, 2) : value == null || value === "" ? "\u2014" : String(value)
|
|
12942
|
+
}
|
|
12943
|
+
);
|
|
11560
12944
|
case "general_surgery_smart_history": {
|
|
11561
12945
|
const structuredDisplay = value && typeof value === "object" ? JSON.stringify(normalizeGeneralSurgerySmartHistory(value), null, 2) : value == null || value === "" ? "\u2014" : String(value);
|
|
11562
12946
|
const hopcDef = resolveFieldDef?.("symptoms");
|
|
@@ -11707,65 +13091,126 @@ var ReadOnlyForm = ({ schema, submission }) => {
|
|
|
11707
13091
|
};
|
|
11708
13092
|
var FormControls = ({
|
|
11709
13093
|
className,
|
|
13094
|
+
containerStyle,
|
|
13095
|
+
showWorkflowStatus = true,
|
|
13096
|
+
statusClassName,
|
|
13097
|
+
statusStyle,
|
|
13098
|
+
actionsClassName,
|
|
13099
|
+
actionsStyle,
|
|
13100
|
+
actionsFullWidth = false,
|
|
13101
|
+
buttonClassName,
|
|
11710
13102
|
onSaveDraft,
|
|
11711
13103
|
onSubmit
|
|
11712
13104
|
}) => {
|
|
11713
|
-
const {
|
|
13105
|
+
const {
|
|
13106
|
+
state,
|
|
13107
|
+
availableTransitions,
|
|
13108
|
+
submit,
|
|
13109
|
+
transition,
|
|
13110
|
+
hasPersistence,
|
|
13111
|
+
markSubmitAttempted
|
|
13112
|
+
} = useForm();
|
|
11714
13113
|
const hasUploadsInFlight = (state.pendingUploads ?? 0) > 0;
|
|
11715
13114
|
const draftAvailable = onSaveDraft || hasPersistence && submit;
|
|
11716
13115
|
const submitAvailable = onSubmit || availableTransitions.length > 0 && transition;
|
|
11717
13116
|
if (!draftAvailable && !submitAvailable) {
|
|
11718
13117
|
return null;
|
|
11719
13118
|
}
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
11727
|
-
|
|
11728
|
-
|
|
11729
|
-
|
|
11730
|
-
|
|
11731
|
-
|
|
11732
|
-
onClick: onSaveDraft || submit,
|
|
11733
|
-
variant: "outline",
|
|
11734
|
-
size: "sm",
|
|
11735
|
-
disabled: hasUploadsInFlight,
|
|
11736
|
-
children: hasUploadsInFlight ? "Upload in progress\u2026" : "Save Draft"
|
|
11737
|
-
}
|
|
13119
|
+
const useWideActions = !showWorkflowStatus && actionsFullWidth;
|
|
13120
|
+
const buttonCn = cn(
|
|
13121
|
+
buttonClassName,
|
|
13122
|
+
useWideActions && "w-full sm:flex-1 min-w-0"
|
|
13123
|
+
);
|
|
13124
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13125
|
+
"div",
|
|
13126
|
+
{
|
|
13127
|
+
className: cn(
|
|
13128
|
+
"flex gap-4 border-t bg-white p-4 items-center",
|
|
13129
|
+
showWorkflowStatus ? "justify-between" : useWideActions ? "flex-col sm:flex-row sm:justify-stretch sm:gap-4" : "justify-end",
|
|
13130
|
+
className
|
|
11738
13131
|
),
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
|
|
11742
|
-
|
|
11743
|
-
|
|
11744
|
-
|
|
11745
|
-
|
|
11746
|
-
|
|
11747
|
-
|
|
11748
|
-
|
|
11749
|
-
|
|
11750
|
-
|
|
11751
|
-
|
|
11752
|
-
|
|
11753
|
-
|
|
11754
|
-
|
|
11755
|
-
|
|
11756
|
-
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
|
|
11760
|
-
|
|
11761
|
-
|
|
11762
|
-
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
|
|
11766
|
-
|
|
11767
|
-
|
|
11768
|
-
|
|
13132
|
+
style: containerStyle,
|
|
13133
|
+
children: [
|
|
13134
|
+
showWorkflowStatus ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13135
|
+
"div",
|
|
13136
|
+
{
|
|
13137
|
+
className: cn("flex items-center gap-4", statusClassName),
|
|
13138
|
+
style: statusStyle,
|
|
13139
|
+
children: [
|
|
13140
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold text-sm text-gray-700", children: [
|
|
13141
|
+
"State: ",
|
|
13142
|
+
state.workflowState
|
|
13143
|
+
] }),
|
|
13144
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13145
|
+
"span",
|
|
13146
|
+
{
|
|
13147
|
+
className: cn(
|
|
13148
|
+
"text-sm",
|
|
13149
|
+
state.isValid ? "text-green-600" : "text-red-600"
|
|
13150
|
+
),
|
|
13151
|
+
children: state.isValid ? "Valid" : "Invalid"
|
|
13152
|
+
}
|
|
13153
|
+
)
|
|
13154
|
+
]
|
|
13155
|
+
}
|
|
13156
|
+
) : null,
|
|
13157
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
13158
|
+
"div",
|
|
13159
|
+
{
|
|
13160
|
+
className: cn(
|
|
13161
|
+
"flex gap-2",
|
|
13162
|
+
useWideActions ? "w-full flex-col sm:flex-row sm:flex-1 sm:justify-end sm:max-w-none" : "flex-shrink-0",
|
|
13163
|
+
actionsClassName
|
|
13164
|
+
),
|
|
13165
|
+
style: actionsStyle,
|
|
13166
|
+
children: [
|
|
13167
|
+
draftAvailable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
13168
|
+
Button,
|
|
13169
|
+
{
|
|
13170
|
+
onClick: onSaveDraft || submit,
|
|
13171
|
+
variant: "outline",
|
|
13172
|
+
size: "sm",
|
|
13173
|
+
disabled: hasUploadsInFlight,
|
|
13174
|
+
className: buttonCn,
|
|
13175
|
+
children: hasUploadsInFlight ? "Upload in progress\u2026" : "Save Draft"
|
|
13176
|
+
}
|
|
13177
|
+
),
|
|
13178
|
+
submitAvailable && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: availableTransitions.length > 0 ? availableTransitions.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
13179
|
+
Button,
|
|
13180
|
+
{
|
|
13181
|
+
onClick: () => {
|
|
13182
|
+
markSubmitAttempted();
|
|
13183
|
+
if (onSubmit) {
|
|
13184
|
+
onSubmit(t.to);
|
|
13185
|
+
} else {
|
|
13186
|
+
transition(t.to);
|
|
13187
|
+
}
|
|
13188
|
+
},
|
|
13189
|
+
disabled: !state.isValid || hasUploadsInFlight,
|
|
13190
|
+
size: "sm",
|
|
13191
|
+
className: buttonCn,
|
|
13192
|
+
children: hasUploadsInFlight ? "Upload in progress\u2026" : availableTransitions.length > 1 ? `Submit to ${t.to}` : "Submit"
|
|
13193
|
+
},
|
|
13194
|
+
t.to
|
|
13195
|
+
)) : onSubmit ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
13196
|
+
Button,
|
|
13197
|
+
{
|
|
13198
|
+
onClick: () => {
|
|
13199
|
+
markSubmitAttempted();
|
|
13200
|
+
onSubmit(state.workflowState || "submit");
|
|
13201
|
+
},
|
|
13202
|
+
disabled: !state.isValid || hasUploadsInFlight,
|
|
13203
|
+
size: "sm",
|
|
13204
|
+
className: buttonCn,
|
|
13205
|
+
children: hasUploadsInFlight ? "Upload in progress\u2026" : "Submit"
|
|
13206
|
+
}
|
|
13207
|
+
) : null })
|
|
13208
|
+
]
|
|
13209
|
+
}
|
|
13210
|
+
)
|
|
13211
|
+
]
|
|
13212
|
+
}
|
|
13213
|
+
);
|
|
11769
13214
|
};
|
|
11770
13215
|
|
|
11771
13216
|
// src/utils/createUploadHandler.ts
|
|
@@ -11802,6 +13247,7 @@ exports.AddInvestigationField = AddInvestigationField;
|
|
|
11802
13247
|
exports.AddMedicationField = AddMedicationField;
|
|
11803
13248
|
exports.DifferentialDiagnosis = DifferentialDiagnosis;
|
|
11804
13249
|
exports.DynamicForm = DynamicForm;
|
|
13250
|
+
exports.DynamicFormV2 = DynamicFormV2;
|
|
11805
13251
|
exports.EMAIL_REGEX = EMAIL_REGEX;
|
|
11806
13252
|
exports.FieldRenderer = FieldRenderer;
|
|
11807
13253
|
exports.FormControls = FormControls;
|