formanitor 0.0.23 → 0.0.25

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.d.cts CHANGED
@@ -719,6 +719,38 @@ type AIMedication = {
719
719
  reason?: string;
720
720
  };
721
721
 
722
+ declare const BEFORE_AFTER_OPTIONS: readonly [{
723
+ readonly label: "Blank";
724
+ readonly value: "";
725
+ }, {
726
+ readonly label: "AFTER FOOD";
727
+ readonly value: "AFTER FOOD";
728
+ }, {
729
+ readonly label: "BEFORE FOOD";
730
+ readonly value: "BEFORE FOOD";
731
+ }, {
732
+ readonly label: "WITH FOOD";
733
+ readonly value: "WITH FOOD";
734
+ }, {
735
+ readonly label: "SINGLE DOSE";
736
+ readonly value: "SINGLE DOSE";
737
+ }, {
738
+ readonly label: "BED TIME";
739
+ readonly value: "BED TIME";
740
+ }, {
741
+ readonly label: "EMPTY STOMACH";
742
+ readonly value: "EMPTY STOMACH";
743
+ }, {
744
+ readonly label: "LOCAL APPLICATION";
745
+ readonly value: "LOCAL APPLICATION";
746
+ }, {
747
+ readonly label: "STAT";
748
+ readonly value: "STAT";
749
+ }, {
750
+ readonly label: "INHALATION";
751
+ readonly value: "INHALATION";
752
+ }];
753
+ type BeforeAfterOption = (typeof BEFORE_AFTER_OPTIONS)[number]['value'];
722
754
  type MedicationSearchResult = {
723
755
  id: string;
724
756
  name: string;
@@ -734,7 +766,7 @@ type Medication = {
734
766
  is_custom: boolean;
735
767
  duration_value: string;
736
768
  duration_unit: 'days' | 'weeks' | 'months';
737
- before_after: 'AFTER FOOD' | 'BEFORE FOOD';
769
+ before_after: BeforeAfterOption;
738
770
  morning: string;
739
771
  afternoon: string;
740
772
  night: string;
package/dist/index.d.ts CHANGED
@@ -719,6 +719,38 @@ type AIMedication = {
719
719
  reason?: string;
720
720
  };
721
721
 
722
+ declare const BEFORE_AFTER_OPTIONS: readonly [{
723
+ readonly label: "Blank";
724
+ readonly value: "";
725
+ }, {
726
+ readonly label: "AFTER FOOD";
727
+ readonly value: "AFTER FOOD";
728
+ }, {
729
+ readonly label: "BEFORE FOOD";
730
+ readonly value: "BEFORE FOOD";
731
+ }, {
732
+ readonly label: "WITH FOOD";
733
+ readonly value: "WITH FOOD";
734
+ }, {
735
+ readonly label: "SINGLE DOSE";
736
+ readonly value: "SINGLE DOSE";
737
+ }, {
738
+ readonly label: "BED TIME";
739
+ readonly value: "BED TIME";
740
+ }, {
741
+ readonly label: "EMPTY STOMACH";
742
+ readonly value: "EMPTY STOMACH";
743
+ }, {
744
+ readonly label: "LOCAL APPLICATION";
745
+ readonly value: "LOCAL APPLICATION";
746
+ }, {
747
+ readonly label: "STAT";
748
+ readonly value: "STAT";
749
+ }, {
750
+ readonly label: "INHALATION";
751
+ readonly value: "INHALATION";
752
+ }];
753
+ type BeforeAfterOption = (typeof BEFORE_AFTER_OPTIONS)[number]['value'];
722
754
  type MedicationSearchResult = {
723
755
  id: string;
724
756
  name: string;
@@ -734,7 +766,7 @@ type Medication = {
734
766
  is_custom: boolean;
735
767
  duration_value: string;
736
768
  duration_unit: 'days' | 'weeks' | 'months';
737
- before_after: 'AFTER FOOD' | 'BEFORE FOOD';
769
+ before_after: BeforeAfterOption;
738
770
  morning: string;
739
771
  afternoon: string;
740
772
  night: string;
package/dist/index.mjs CHANGED
@@ -2778,6 +2778,22 @@ var AddEntityDialog = ({
2778
2778
  actionSlot != null && /* @__PURE__ */ jsx("div", { className: "px-6 py-4 flex justify-end shrink-0 border-t border-border bg-background", children: actionSlot })
2779
2779
  ] }) });
2780
2780
  };
2781
+ var BEFORE_AFTER_OPTIONS = [
2782
+ { label: "Blank", value: "" },
2783
+ { label: "AFTER FOOD", value: "AFTER FOOD" },
2784
+ { label: "BEFORE FOOD", value: "BEFORE FOOD" },
2785
+ { label: "WITH FOOD", value: "WITH FOOD" },
2786
+ { label: "SINGLE DOSE", value: "SINGLE DOSE" },
2787
+ { label: "BED TIME", value: "BED TIME" },
2788
+ { label: "EMPTY STOMACH", value: "EMPTY STOMACH" },
2789
+ { label: "LOCAL APPLICATION", value: "LOCAL APPLICATION" },
2790
+ { label: "STAT", value: "STAT" },
2791
+ { label: "INHALATION", value: "INHALATION" }
2792
+ ];
2793
+ var BEFORE_AFTER_NORMALIZATION_MAP = {
2794
+ AF: "AFTER FOOD",
2795
+ BF: "BEFORE FOOD"
2796
+ };
2781
2797
  function mapToMedication(result) {
2782
2798
  return {
2783
2799
  id: result.id,
@@ -2841,7 +2857,7 @@ function mapFrequentItemToMedication(item) {
2841
2857
  const parsed = parseDuration(item.duration);
2842
2858
  const duration_value = item.duration_value ?? parsed.value;
2843
2859
  const duration_unit = item.duration_unit ?? parsed.unit;
2844
- const before_after = item.before_after === "BEFORE FOOD" ? "BEFORE FOOD" : "AFTER FOOD";
2860
+ const before_after = normalizeBeforeAfter(item.before_after);
2845
2861
  const routeNote = item.route ? `Route: ${item.route}` : "";
2846
2862
  const baseNotes = item.notes?.trim() || "";
2847
2863
  const combinedNotes = [baseNotes, routeNote.trim()].filter((part) => part.length > 0).join(" \u2014 ");
@@ -2860,6 +2876,13 @@ function mapFrequentItemToMedication(item) {
2860
2876
  notes: combinedNotes
2861
2877
  };
2862
2878
  }
2879
+ function normalizeBeforeAfter(value) {
2880
+ if (value == null) return "AFTER FOOD";
2881
+ const mapped = BEFORE_AFTER_NORMALIZATION_MAP[value];
2882
+ if (mapped) return mapped;
2883
+ const validValues = BEFORE_AFTER_OPTIONS.map((option) => option.value);
2884
+ return validValues.includes(value) ? value : "AFTER FOOD";
2885
+ }
2863
2886
  function Spinner({
2864
2887
  value,
2865
2888
  onChange
@@ -2967,16 +2990,13 @@ function MedicationCard({
2967
2990
  )
2968
2991
  ] }),
2969
2992
  /* @__PURE__ */ jsx("div", { className: "flex gap-2 items-center flex-1 min-w-0 justify-end", children: ["morning", "afternoon", "night"].map((slot) => /* @__PURE__ */ jsx("div", { className: "flex flex-col items-center gap-0.5", children: /* @__PURE__ */ jsx(Spinner, { value: med[slot], onChange: (v) => set(slot, v) }) }, slot)) }),
2970
- /* @__PURE__ */ jsxs(
2993
+ /* @__PURE__ */ jsx(
2971
2994
  "select",
2972
2995
  {
2973
2996
  className: "text-xs border border-border rounded px-2 py-1 bg-white shrink-0",
2974
- value: med.before_after === "AFTER FOOD" ? "AF" : "BF",
2975
- onChange: (e) => set("before_after", e.target.value === "AF" ? "AFTER FOOD" : "BEFORE FOOD"),
2976
- children: [
2977
- /* @__PURE__ */ jsx("option", { value: "AF", children: "AF" }),
2978
- /* @__PURE__ */ jsx("option", { value: "BF", children: "BF" })
2979
- ]
2997
+ value: normalizeBeforeAfter(med.before_after),
2998
+ onChange: (e) => set("before_after", e.target.value),
2999
+ children: BEFORE_AFTER_OPTIONS.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.label))
2980
3000
  }
2981
3001
  )
2982
3002
  ] }),
@@ -3521,6 +3541,9 @@ function mapToProcedure(result) {
3521
3541
  fromAI: false
3522
3542
  };
3523
3543
  }
3544
+ function createCustomProcedure(trimmedName) {
3545
+ return { name: trimmedName.trim(), is_custom: true };
3546
+ }
3524
3547
  var AddProcedureField = ({
3525
3548
  label = "Procedures",
3526
3549
  value,
@@ -3539,7 +3562,9 @@ var AddProcedureField = ({
3539
3562
  const valueRef = useRef([]);
3540
3563
  const searchInputRef = useRef(null);
3541
3564
  valueRef.current = value;
3542
- const addedIds = new Set(value.map((proc) => proc.id));
3565
+ const addedIds = new Set(
3566
+ value.filter((proc) => !proc.is_custom).map((proc) => proc.id)
3567
+ );
3543
3568
  useEffect(() => {
3544
3569
  if (!open) {
3545
3570
  setQuery("");
@@ -3581,12 +3606,23 @@ var AddProcedureField = ({
3581
3606
  setTimeout(() => searchInputRef.current?.focus(), 0);
3582
3607
  }, ADD_FEEDBACK_MS3);
3583
3608
  }
3584
- function removeProcedure(id) {
3585
- onChange(value.filter((proc) => proc.id !== id));
3609
+ function removeAt(index) {
3610
+ onChange(value.filter((_, i) => i !== index));
3611
+ }
3612
+ function removeBySearchId(id) {
3613
+ onChange(value.filter((proc) => proc.is_custom || proc.id !== id));
3614
+ }
3615
+ function handleAddCustom() {
3616
+ const trimmed = query.trim();
3617
+ if (!trimmed) return;
3618
+ if (valueRef.current.some((p) => p.is_custom && p.name === trimmed)) return;
3619
+ onChange([...valueRef.current, createCustomProcedure(trimmed)]);
3620
+ setQuery("");
3621
+ setResults([]);
3586
3622
  }
3587
3623
  function handleRecentlyUsedToggle(result) {
3588
3624
  if (addedIds.has(result.id)) {
3589
- removeProcedure(result.id);
3625
+ removeBySearchId(result.id);
3590
3626
  } else {
3591
3627
  addProcedure(result);
3592
3628
  }
@@ -3596,7 +3632,7 @@ var AddProcedureField = ({
3596
3632
  const addedById = addedIds.has(id);
3597
3633
  const addedByName = value.some((proc) => proc.name === item.name);
3598
3634
  if (addedById || addedByName) {
3599
- if (addedById) removeProcedure(id);
3635
+ if (addedById) removeBySearchId(id);
3600
3636
  else onChange(value.filter((proc) => proc.name !== item.name));
3601
3637
  return;
3602
3638
  }
@@ -3604,7 +3640,7 @@ var AddProcedureField = ({
3604
3640
  try {
3605
3641
  const searchResults = await onSearch(item.name);
3606
3642
  const first = searchResults?.[0];
3607
- if (first && !valueRef.current.some((proc) => proc.id === first.id)) {
3643
+ if (first && !valueRef.current.some((proc) => !proc.is_custom && proc.id === first.id)) {
3608
3644
  onChange([...valueRef.current, mapToProcedure(first)]);
3609
3645
  }
3610
3646
  } finally {
@@ -3633,7 +3669,7 @@ var AddProcedureField = ({
3633
3669
  const limitedFrequentItems = frequentItems.slice(0, 25);
3634
3670
  const frequentItemChips = limitedFrequentItems.length > 0 ? limitedFrequentItems.map((item) => {
3635
3671
  const id = String(item.id);
3636
- const isAdded = value.some((proc) => proc.id === id) || value.some((proc) => proc.name === item.name);
3672
+ const isAdded = value.some((proc) => !proc.is_custom && proc.id === id) || value.some((proc) => proc.name === item.name);
3637
3673
  const isAdding = addingFrequentId === id;
3638
3674
  return /* @__PURE__ */ jsxs(
3639
3675
  "button",
@@ -3667,7 +3703,7 @@ var AddProcedureField = ({
3667
3703
  }
3668
3704
  )
3669
3705
  ] }),
3670
- value.length > 0 && /* @__PURE__ */ jsx("div", { className: "divide-y divide-border rounded-lg border border-border overflow-hidden", children: value.map((proc) => /* @__PURE__ */ jsxs(
3706
+ value.length > 0 && /* @__PURE__ */ jsx("div", { className: "divide-y divide-border rounded-lg border border-border overflow-hidden", children: value.map((proc, index) => /* @__PURE__ */ jsxs(
3671
3707
  "div",
3672
3708
  {
3673
3709
  className: "flex items-center justify-between px-3 py-2 bg-white hover:bg-gray-50",
@@ -3677,14 +3713,14 @@ var AddProcedureField = ({
3677
3713
  "button",
3678
3714
  {
3679
3715
  type: "button",
3680
- onClick: () => removeProcedure(proc.id),
3716
+ onClick: () => removeAt(index),
3681
3717
  className: "text-muted-foreground hover:text-red-500 transition-colors cursor-pointer",
3682
3718
  children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
3683
3719
  }
3684
3720
  )
3685
3721
  ]
3686
3722
  },
3687
- proc.id
3723
+ proc.is_custom ? `custom-${index}` : proc.id
3688
3724
  )) }),
3689
3725
  /* @__PURE__ */ jsx(
3690
3726
  AddEntityDialog,
@@ -3694,6 +3730,19 @@ var AddProcedureField = ({
3694
3730
  title: "Add Procedure",
3695
3731
  recentlyUsedSlot: frequentItemChips.length > 0 ? frequentItemChips : recentlyUsedChips.length > 0 ? recentlyUsedChips : void 0,
3696
3732
  chipSectionLabel: frequentItemChips.length > 0 ? "Frequently used" : void 0,
3733
+ actionSlot: /* @__PURE__ */ jsx(
3734
+ "button",
3735
+ {
3736
+ type: "button",
3737
+ disabled: !query.trim() || valueRef.current.some((p) => p.is_custom && p.name === query.trim()),
3738
+ onClick: handleAddCustom,
3739
+ className: cn(
3740
+ "rounded-md px-5 py-2 text-sm font-semibold bg-primary text-primary-foreground hover:bg-primary/90 transition-opacity cursor-pointer",
3741
+ (!query.trim() || valueRef.current.some((p) => p.is_custom && p.name === query.trim())) && "opacity-40 cursor-not-allowed"
3742
+ ),
3743
+ children: "Save Procedure"
3744
+ }
3745
+ ),
3697
3746
  children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
3698
3747
  /* @__PURE__ */ jsx(
3699
3748
  Input,