formanitor 0.2.4 → 0.2.5
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/{AddProcedureWidget-HK7UNRXH.cjs → AddProcedureWidget-QHV5CQKX.cjs} +2 -2
- package/dist/AddProcedureWidget-QHV5CQKX.cjs.map +1 -0
- package/dist/{AddProcedureWidget-F74WGSFX.mjs → AddProcedureWidget-VJZ6NO4Q.mjs} +2 -2
- package/dist/AddProcedureWidget-VJZ6NO4Q.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/AddProcedureWidget-F74WGSFX.mjs.map +0 -1
- package/dist/AddProcedureWidget-HK7UNRXH.cjs.map +0 -1
|
@@ -274,5 +274,5 @@ var AddProcedureWidget = ({ fieldId }) => {
|
|
|
274
274
|
};
|
|
275
275
|
|
|
276
276
|
exports.AddProcedureWidget = AddProcedureWidget;
|
|
277
|
-
//# sourceMappingURL=AddProcedureWidget-
|
|
278
|
-
//# sourceMappingURL=AddProcedureWidget-
|
|
277
|
+
//# sourceMappingURL=AddProcedureWidget-QHV5CQKX.cjs.map
|
|
278
|
+
//# sourceMappingURL=AddProcedureWidget-QHV5CQKX.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/widgets/AddProcedureField.tsx","../src/ui/widgets/AddProcedureWidget.tsx"],"names":["useState","useRef","useEffect","jsxs","cn","jsx","X","AddEntityDialog","Input","Check","useField","useFieldHandlers","useFrequentItems"],"mappings":"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","file":"AddProcedureWidget-QHV5CQKX.cjs","sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { X, Check } from 'lucide-react';\nimport { cn } from '../../core/utils';\nimport { Input } from '../shadcn/input';\nimport { AddEntityDialog } from './AddEntityDialog';\nimport type { ProcedureFrequentItem } from '../../core/types';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n// Matches search API response.results[] shape\n\nexport type ProcedureSearchResult = {\n id: string;\n name: string;\n code?: string;\n description?: string;\n specialization?: string;\n /** Catalog diagnostic service (service_type=SERVICES) merged into procedures search/save. */\n service_type?: string;\n /** Present on service items when reopening a saved prescription. */\n type?: string;\n score?: number;\n};\n\n/** Master row from search / frequent resolution — full metadata. */\nexport type MasterProcedure = ProcedureSearchResult & {\n label: string;\n is_custom: false;\n fromAI: boolean;\n};\n\n/** Custom free-text row — only `name` and `is_custom` (no extra keys). */\nexport type CustomProcedure = {\n name: string;\n is_custom: true;\n};\n\nexport type Procedure = MasterProcedure | CustomProcedure;\n\nexport type AddProcedureFieldProps = {\n label?: string;\n value: Procedure[];\n onChange: (items: Procedure[]) => void;\n onSearch: (query: string) => Promise<ProcedureSearchResult[]>;\n recentlyUsed?: ProcedureSearchResult[];\n /** Doctor-scoped frequently used procedures (from FormProvider frequentItems) */\n frequentItems?: ProcedureFrequentItem[];\n};\n\nconst ADD_FEEDBACK_MS = 320;\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\nfunction mapToProcedure(result: ProcedureSearchResult): MasterProcedure {\n return {\n ...result,\n label: result.name,\n is_custom: false,\n fromAI: false,\n };\n}\n\nfunction createCustomProcedure(trimmedName: string): CustomProcedure {\n return { name: trimmedName.trim(), is_custom: true };\n}\n\n// ─── Main component ───────────────────────────────────────────────────────────\n\nexport const AddProcedureField: React.FC<AddProcedureFieldProps> = ({\n label = 'Procedures',\n value,\n onChange,\n onSearch,\n recentlyUsed = [],\n frequentItems = [],\n}) => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [results, setResults] = useState<ProcedureSearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [addingId, setAddingId] = useState<string | null>(null);\n const [addingFrequentId, setAddingFrequentId] = useState<string | null>(null);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const valueRef = useRef<Procedure[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n const safeValue: Procedure[] = Array.isArray(value) ? value : [];\n\n valueRef.current = safeValue;\n const addedIds = new Set(\n safeValue.filter((proc): proc is MasterProcedure => !proc.is_custom).map((proc) => proc.id),\n );\n\n useEffect(() => {\n if (!open) {\n setQuery('');\n setResults([]);\n setAddingId(null);\n setAddingFrequentId(null);\n }\n }, [open]);\n\n function handleQueryChange(q: string) {\n setQuery(q);\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (!q.trim()) {\n setResults([]);\n return;\n }\n debounceRef.current = setTimeout(async () => {\n setLoading(true);\n try {\n const res = await onSearch(q);\n setResults(res);\n } finally {\n setLoading(false);\n }\n }, 500);\n }\n\n function addProcedure(result: ProcedureSearchResult) {\n if (!addedIds.has(result.id)) {\n onChange([...valueRef.current, mapToProcedure(result)]);\n }\n setQuery('');\n setResults([]);\n }\n\n function handleResultClick(result: ProcedureSearchResult) {\n if (addedIds.has(result.id)) return;\n setAddingId(result.id);\n setTimeout(() => {\n addProcedure(result);\n setAddingId(null);\n setTimeout(() => searchInputRef.current?.focus(), 0);\n }, ADD_FEEDBACK_MS);\n }\n\n function removeAt(index: number) {\n onChange(safeValue.filter((_, i) => i !== index));\n }\n\n function removeBySearchId(id: string) {\n onChange(safeValue.filter((proc) => proc.is_custom || proc.id !== id));\n }\n\n function handleAddCustom() {\n const trimmed = query.trim();\n if (!trimmed) return;\n if (valueRef.current.some((p) => p.is_custom && p.name === trimmed)) return;\n onChange([...valueRef.current, createCustomProcedure(trimmed)]);\n setQuery('');\n setResults([]);\n }\n\n function handleRecentlyUsedToggle(result: ProcedureSearchResult) {\n if (addedIds.has(result.id)) {\n removeBySearchId(result.id);\n } else {\n addProcedure(result);\n }\n }\n\n async function handleFrequentItemToggle(item: ProcedureFrequentItem) {\n const id = String(item.id);\n const addedById = addedIds.has(id);\n const addedByName = safeValue.some((proc) => proc.name === item.name);\n if (addedById || addedByName) {\n if (addedById) removeBySearchId(id);\n else onChange(safeValue.filter((proc) => proc.name !== item.name));\n return;\n }\n setAddingFrequentId(id);\n try {\n const searchResults = await onSearch(item.name);\n const first = searchResults?.[0];\n if (first && !valueRef.current.some((proc) => !proc.is_custom && proc.id === first.id)) {\n onChange([...valueRef.current, mapToProcedure(first)]);\n }\n } finally {\n setAddingFrequentId(null);\n }\n }\n\n const recentlyUsedChips = recentlyUsed.map((r) => {\n const isAdded = addedIds.has(r.id);\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleRecentlyUsedToggle(r)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {r.name}\n </button>\n );\n });\n\n const limitedFrequentItems = frequentItems.slice(0, 25);\n\n const frequentItemChips =\n limitedFrequentItems.length > 0\n ? limitedFrequentItems.map((item) => {\n const id = String(item.id);\n const isAdded =\n safeValue.some((proc) => !proc.is_custom && proc.id === id) ||\n safeValue.some((proc) => proc.name === item.name);\n const isAdding = addingFrequentId === id;\n return (\n <button\n key={item.id}\n type=\"button\"\n disabled={isAdding}\n onClick={() => handleFrequentItemToggle(item)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50',\n isAdding && 'opacity-70 pointer-events-none'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {isAdding ? '…' : item.name}\n </button>\n );\n })\n : [];\n\n return (\n <div className=\"rounded-md overflow-hidden flex flex-col bg-white border border-[#D0D0D0] space-y-3 p-3 h-fit\">\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-sm font-semibold\">{label}</span>\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"text-sm font-semibold text-purple-600 hover:text-purple-800 cursor-pointer\"\n >\n ADD\n </button>\n </div>\n\n {/* Added procedures — one row each */}\n {safeValue.length > 0 && (\n <div className=\"divide-y divide-border rounded-lg border border-border overflow-hidden\">\n {safeValue.map((proc, index) => (\n <div\n key={proc.is_custom ? `custom-${index}` : proc.id}\n className=\"flex items-center justify-between px-3 py-2 bg-white hover:bg-gray-50\"\n >\n <span className=\"text-sm\">{proc.name}</span>\n <button\n type=\"button\"\n onClick={() => removeAt(index)}\n className=\"text-muted-foreground hover:text-red-500 transition-colors cursor-pointer\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Dialog */}\n <AddEntityDialog\n open={open}\n onClose={() => setOpen(false)}\n title=\"Add Procedure\"\n recentlyUsedSlot={\n frequentItemChips.length > 0\n ? frequentItemChips\n : recentlyUsedChips.length > 0\n ? recentlyUsedChips\n : undefined\n }\n chipSectionLabel={frequentItemChips.length > 0 ? 'Frequently used' : undefined}\n actionSlot={\n <button\n type=\"button\"\n disabled={\n !query.trim() ||\n valueRef.current.some((p) => p.is_custom && p.name === query.trim())\n }\n onClick={handleAddCustom}\n className={cn(\n 'rounded-md px-5 py-2 text-sm font-semibold bg-primary text-primary-foreground hover:bg-primary/90 transition-opacity cursor-pointer',\n (!query.trim() ||\n valueRef.current.some((p) => p.is_custom && p.name === query.trim())) &&\n 'opacity-40 cursor-not-allowed'\n )}\n >\n Save Procedure\n </button>\n }\n >\n <div className=\"space-y-2\">\n <Input\n ref={searchInputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n placeholder=\"Search for a procedure...\"\n className=\"border border-border rounded-md focus-visible:ring-0\"\n />\n\n {/* Inline results — no absolute positioning to avoid overflow-clip */}\n {loading && (\n <p className=\"text-xs text-muted-foreground py-1\">Searching…</p>\n )}\n {!loading && results.length > 0 && (\n <div className=\"border border-border rounded-md overflow-hidden\">\n {results.map((r) => {\n const isAdding = addingId === r.id;\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleResultClick(r)}\n className={cn(\n 'w-full text-left px-3 py-2 text-sm transition-all duration-300 ease-out border-b border-border last:border-b-0 cursor-pointer flex items-center justify-between gap-2',\n isAdding\n ? 'bg-green-50 border-green-200'\n : 'hover:bg-gray-50'\n )}\n >\n <span className=\"truncate\">{r.name}</span>\n {isAdding && <Check className=\"h-4 w-4 shrink-0 text-green-600\" />}\n </button>\n );\n })}\n </div>\n )}\n </div>\n </AddEntityDialog>\n </div>\n );\n};\n","import React from 'react';\nimport { useField } from '../../react/useField';\nimport { useFieldHandlers, useFrequentItems } from '../../react/FormProvider';\nimport { AddProcedureField } from './AddProcedureField';\nimport type { Procedure, ProcedureSearchResult } from './AddProcedureField';\n\nexport const AddProcedureWidget: React.FC<{ fieldId: string }> = ({ fieldId }) => {\n const { value, setValue } = useField(fieldId);\n const handlers = useFieldHandlers(fieldId);\n const { procedures: frequentProcedures } = useFrequentItems();\n\n const safeValue: Procedure[] = Array.isArray(value) ? (value as Procedure[]) : [];\n\n return (\n <AddProcedureField\n value={safeValue}\n onChange={setValue}\n onSearch={handlers.onSearch as (query: string) => Promise<ProcedureSearchResult[]>}\n recentlyUsed={handlers.recentlyUsed as ProcedureSearchResult[] | undefined}\n frequentItems={frequentProcedures}\n />\n );\n};\n"]}
|
|
@@ -272,5 +272,5 @@ var AddProcedureWidget = ({ fieldId }) => {
|
|
|
272
272
|
};
|
|
273
273
|
|
|
274
274
|
export { AddProcedureWidget };
|
|
275
|
-
//# sourceMappingURL=AddProcedureWidget-
|
|
276
|
-
//# sourceMappingURL=AddProcedureWidget-
|
|
275
|
+
//# sourceMappingURL=AddProcedureWidget-VJZ6NO4Q.mjs.map
|
|
276
|
+
//# sourceMappingURL=AddProcedureWidget-VJZ6NO4Q.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/widgets/AddProcedureField.tsx","../src/ui/widgets/AddProcedureWidget.tsx"],"names":["jsx"],"mappings":"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","file":"AddProcedureWidget-VJZ6NO4Q.mjs","sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { X, Check } from 'lucide-react';\nimport { cn } from '../../core/utils';\nimport { Input } from '../shadcn/input';\nimport { AddEntityDialog } from './AddEntityDialog';\nimport type { ProcedureFrequentItem } from '../../core/types';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n// Matches search API response.results[] shape\n\nexport type ProcedureSearchResult = {\n id: string;\n name: string;\n code?: string;\n description?: string;\n specialization?: string;\n /** Catalog diagnostic service (service_type=SERVICES) merged into procedures search/save. */\n service_type?: string;\n /** Present on service items when reopening a saved prescription. */\n type?: string;\n score?: number;\n};\n\n/** Master row from search / frequent resolution — full metadata. */\nexport type MasterProcedure = ProcedureSearchResult & {\n label: string;\n is_custom: false;\n fromAI: boolean;\n};\n\n/** Custom free-text row — only `name` and `is_custom` (no extra keys). */\nexport type CustomProcedure = {\n name: string;\n is_custom: true;\n};\n\nexport type Procedure = MasterProcedure | CustomProcedure;\n\nexport type AddProcedureFieldProps = {\n label?: string;\n value: Procedure[];\n onChange: (items: Procedure[]) => void;\n onSearch: (query: string) => Promise<ProcedureSearchResult[]>;\n recentlyUsed?: ProcedureSearchResult[];\n /** Doctor-scoped frequently used procedures (from FormProvider frequentItems) */\n frequentItems?: ProcedureFrequentItem[];\n};\n\nconst ADD_FEEDBACK_MS = 320;\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\nfunction mapToProcedure(result: ProcedureSearchResult): MasterProcedure {\n return {\n ...result,\n label: result.name,\n is_custom: false,\n fromAI: false,\n };\n}\n\nfunction createCustomProcedure(trimmedName: string): CustomProcedure {\n return { name: trimmedName.trim(), is_custom: true };\n}\n\n// ─── Main component ───────────────────────────────────────────────────────────\n\nexport const AddProcedureField: React.FC<AddProcedureFieldProps> = ({\n label = 'Procedures',\n value,\n onChange,\n onSearch,\n recentlyUsed = [],\n frequentItems = [],\n}) => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [results, setResults] = useState<ProcedureSearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [addingId, setAddingId] = useState<string | null>(null);\n const [addingFrequentId, setAddingFrequentId] = useState<string | null>(null);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const valueRef = useRef<Procedure[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n const safeValue: Procedure[] = Array.isArray(value) ? value : [];\n\n valueRef.current = safeValue;\n const addedIds = new Set(\n safeValue.filter((proc): proc is MasterProcedure => !proc.is_custom).map((proc) => proc.id),\n );\n\n useEffect(() => {\n if (!open) {\n setQuery('');\n setResults([]);\n setAddingId(null);\n setAddingFrequentId(null);\n }\n }, [open]);\n\n function handleQueryChange(q: string) {\n setQuery(q);\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (!q.trim()) {\n setResults([]);\n return;\n }\n debounceRef.current = setTimeout(async () => {\n setLoading(true);\n try {\n const res = await onSearch(q);\n setResults(res);\n } finally {\n setLoading(false);\n }\n }, 500);\n }\n\n function addProcedure(result: ProcedureSearchResult) {\n if (!addedIds.has(result.id)) {\n onChange([...valueRef.current, mapToProcedure(result)]);\n }\n setQuery('');\n setResults([]);\n }\n\n function handleResultClick(result: ProcedureSearchResult) {\n if (addedIds.has(result.id)) return;\n setAddingId(result.id);\n setTimeout(() => {\n addProcedure(result);\n setAddingId(null);\n setTimeout(() => searchInputRef.current?.focus(), 0);\n }, ADD_FEEDBACK_MS);\n }\n\n function removeAt(index: number) {\n onChange(safeValue.filter((_, i) => i !== index));\n }\n\n function removeBySearchId(id: string) {\n onChange(safeValue.filter((proc) => proc.is_custom || proc.id !== id));\n }\n\n function handleAddCustom() {\n const trimmed = query.trim();\n if (!trimmed) return;\n if (valueRef.current.some((p) => p.is_custom && p.name === trimmed)) return;\n onChange([...valueRef.current, createCustomProcedure(trimmed)]);\n setQuery('');\n setResults([]);\n }\n\n function handleRecentlyUsedToggle(result: ProcedureSearchResult) {\n if (addedIds.has(result.id)) {\n removeBySearchId(result.id);\n } else {\n addProcedure(result);\n }\n }\n\n async function handleFrequentItemToggle(item: ProcedureFrequentItem) {\n const id = String(item.id);\n const addedById = addedIds.has(id);\n const addedByName = safeValue.some((proc) => proc.name === item.name);\n if (addedById || addedByName) {\n if (addedById) removeBySearchId(id);\n else onChange(safeValue.filter((proc) => proc.name !== item.name));\n return;\n }\n setAddingFrequentId(id);\n try {\n const searchResults = await onSearch(item.name);\n const first = searchResults?.[0];\n if (first && !valueRef.current.some((proc) => !proc.is_custom && proc.id === first.id)) {\n onChange([...valueRef.current, mapToProcedure(first)]);\n }\n } finally {\n setAddingFrequentId(null);\n }\n }\n\n const recentlyUsedChips = recentlyUsed.map((r) => {\n const isAdded = addedIds.has(r.id);\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleRecentlyUsedToggle(r)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {r.name}\n </button>\n );\n });\n\n const limitedFrequentItems = frequentItems.slice(0, 25);\n\n const frequentItemChips =\n limitedFrequentItems.length > 0\n ? limitedFrequentItems.map((item) => {\n const id = String(item.id);\n const isAdded =\n safeValue.some((proc) => !proc.is_custom && proc.id === id) ||\n safeValue.some((proc) => proc.name === item.name);\n const isAdding = addingFrequentId === id;\n return (\n <button\n key={item.id}\n type=\"button\"\n disabled={isAdding}\n onClick={() => handleFrequentItemToggle(item)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50',\n isAdding && 'opacity-70 pointer-events-none'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {isAdding ? '…' : item.name}\n </button>\n );\n })\n : [];\n\n return (\n <div className=\"rounded-md overflow-hidden flex flex-col bg-white border border-[#D0D0D0] space-y-3 p-3 h-fit\">\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-sm font-semibold\">{label}</span>\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"text-sm font-semibold text-purple-600 hover:text-purple-800 cursor-pointer\"\n >\n ADD\n </button>\n </div>\n\n {/* Added procedures — one row each */}\n {safeValue.length > 0 && (\n <div className=\"divide-y divide-border rounded-lg border border-border overflow-hidden\">\n {safeValue.map((proc, index) => (\n <div\n key={proc.is_custom ? `custom-${index}` : proc.id}\n className=\"flex items-center justify-between px-3 py-2 bg-white hover:bg-gray-50\"\n >\n <span className=\"text-sm\">{proc.name}</span>\n <button\n type=\"button\"\n onClick={() => removeAt(index)}\n className=\"text-muted-foreground hover:text-red-500 transition-colors cursor-pointer\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Dialog */}\n <AddEntityDialog\n open={open}\n onClose={() => setOpen(false)}\n title=\"Add Procedure\"\n recentlyUsedSlot={\n frequentItemChips.length > 0\n ? frequentItemChips\n : recentlyUsedChips.length > 0\n ? recentlyUsedChips\n : undefined\n }\n chipSectionLabel={frequentItemChips.length > 0 ? 'Frequently used' : undefined}\n actionSlot={\n <button\n type=\"button\"\n disabled={\n !query.trim() ||\n valueRef.current.some((p) => p.is_custom && p.name === query.trim())\n }\n onClick={handleAddCustom}\n className={cn(\n 'rounded-md px-5 py-2 text-sm font-semibold bg-primary text-primary-foreground hover:bg-primary/90 transition-opacity cursor-pointer',\n (!query.trim() ||\n valueRef.current.some((p) => p.is_custom && p.name === query.trim())) &&\n 'opacity-40 cursor-not-allowed'\n )}\n >\n Save Procedure\n </button>\n }\n >\n <div className=\"space-y-2\">\n <Input\n ref={searchInputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n placeholder=\"Search for a procedure...\"\n className=\"border border-border rounded-md focus-visible:ring-0\"\n />\n\n {/* Inline results — no absolute positioning to avoid overflow-clip */}\n {loading && (\n <p className=\"text-xs text-muted-foreground py-1\">Searching…</p>\n )}\n {!loading && results.length > 0 && (\n <div className=\"border border-border rounded-md overflow-hidden\">\n {results.map((r) => {\n const isAdding = addingId === r.id;\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleResultClick(r)}\n className={cn(\n 'w-full text-left px-3 py-2 text-sm transition-all duration-300 ease-out border-b border-border last:border-b-0 cursor-pointer flex items-center justify-between gap-2',\n isAdding\n ? 'bg-green-50 border-green-200'\n : 'hover:bg-gray-50'\n )}\n >\n <span className=\"truncate\">{r.name}</span>\n {isAdding && <Check className=\"h-4 w-4 shrink-0 text-green-600\" />}\n </button>\n );\n })}\n </div>\n )}\n </div>\n </AddEntityDialog>\n </div>\n );\n};\n","import React from 'react';\nimport { useField } from '../../react/useField';\nimport { useFieldHandlers, useFrequentItems } from '../../react/FormProvider';\nimport { AddProcedureField } from './AddProcedureField';\nimport type { Procedure, ProcedureSearchResult } from './AddProcedureField';\n\nexport const AddProcedureWidget: React.FC<{ fieldId: string }> = ({ fieldId }) => {\n const { value, setValue } = useField(fieldId);\n const handlers = useFieldHandlers(fieldId);\n const { procedures: frequentProcedures } = useFrequentItems();\n\n const safeValue: Procedure[] = Array.isArray(value) ? (value as Procedure[]) : [];\n\n return (\n <AddProcedureField\n value={safeValue}\n onChange={setValue}\n onSearch={handlers.onSearch as (query: string) => Promise<ProcedureSearchResult[]>}\n recentlyUsed={handlers.recentlyUsed as ProcedureSearchResult[] | undefined}\n frequentItems={frequentProcedures}\n />\n );\n};\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -2194,7 +2194,7 @@ var EditableTableWidget = lazyNamed(() => import('./EditableTable-OW5LC6OC.cjs')
|
|
|
2194
2194
|
var AddMedicationWidget = lazyNamed(() => import('./AddMedicationWidget-45T4XVEL.cjs'), "AddMedicationWidget");
|
|
2195
2195
|
var DischargeMedicationOrdersWidget = lazyNamed(() => import('./DischargeMedicationOrdersWidget-WRJRYL6F.cjs'), "DischargeMedicationOrdersWidget");
|
|
2196
2196
|
var AddInvestigationWidget = lazyNamed(() => import('./AddInvestigationWidget-7FLINCTT.cjs'), "AddInvestigationWidget");
|
|
2197
|
-
var AddProcedureWidget = lazyNamed(() => import('./AddProcedureWidget-
|
|
2197
|
+
var AddProcedureWidget = lazyNamed(() => import('./AddProcedureWidget-QHV5CQKX.cjs'), "AddProcedureWidget");
|
|
2198
2198
|
var DifferentialDiagnosisWidget = lazyNamed(() => import('./DifferentialDiagnosisWidget-XESNHNQQ.cjs'), "DifferentialDiagnosisWidget");
|
|
2199
2199
|
var VitalsWidget = lazyNamed(() => import('./VitalsWidget-MS3OOZSW.cjs'), "VitalsWidget");
|
|
2200
2200
|
var HiddenVitalsWidget = lazyNamed(() => import('./HiddenVitalsWidget-5GFBDDPT.cjs'), "HiddenVitalsWidget");
|
package/dist/index.mjs
CHANGED
|
@@ -2179,7 +2179,7 @@ var EditableTableWidget = lazyNamed(() => import('./EditableTable-VZ66IXYI.mjs')
|
|
|
2179
2179
|
var AddMedicationWidget = lazyNamed(() => import('./AddMedicationWidget-B5RXRYBK.mjs'), "AddMedicationWidget");
|
|
2180
2180
|
var DischargeMedicationOrdersWidget = lazyNamed(() => import('./DischargeMedicationOrdersWidget-KA3HANHE.mjs'), "DischargeMedicationOrdersWidget");
|
|
2181
2181
|
var AddInvestigationWidget = lazyNamed(() => import('./AddInvestigationWidget-FABXZDEZ.mjs'), "AddInvestigationWidget");
|
|
2182
|
-
var AddProcedureWidget = lazyNamed(() => import('./AddProcedureWidget-
|
|
2182
|
+
var AddProcedureWidget = lazyNamed(() => import('./AddProcedureWidget-VJZ6NO4Q.mjs'), "AddProcedureWidget");
|
|
2183
2183
|
var DifferentialDiagnosisWidget = lazyNamed(() => import('./DifferentialDiagnosisWidget-IZEZVW5F.mjs'), "DifferentialDiagnosisWidget");
|
|
2184
2184
|
var VitalsWidget = lazyNamed(() => import('./VitalsWidget-63HTXK2M.mjs'), "VitalsWidget");
|
|
2185
2185
|
var HiddenVitalsWidget = lazyNamed(() => import('./HiddenVitalsWidget-CIE3KERT.mjs'), "HiddenVitalsWidget");
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/widgets/AddProcedureField.tsx","../src/ui/widgets/AddProcedureWidget.tsx"],"names":["jsx"],"mappings":"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","file":"AddProcedureWidget-F74WGSFX.mjs","sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { X, Check } from 'lucide-react';\nimport { cn } from '../../core/utils';\nimport { Input } from '../shadcn/input';\nimport { AddEntityDialog } from './AddEntityDialog';\nimport type { ProcedureFrequentItem } from '../../core/types';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n// Matches search API response.results[] shape\n\nexport type ProcedureSearchResult = {\n id: string;\n name: string;\n code?: string;\n description?: string;\n specialization?: string;\n score?: number;\n};\n\n/** Master row from search / frequent resolution — full metadata. */\nexport type MasterProcedure = ProcedureSearchResult & {\n label: string;\n is_custom: false;\n fromAI: boolean;\n};\n\n/** Custom free-text row — only `name` and `is_custom` (no extra keys). */\nexport type CustomProcedure = {\n name: string;\n is_custom: true;\n};\n\nexport type Procedure = MasterProcedure | CustomProcedure;\n\nexport type AddProcedureFieldProps = {\n label?: string;\n value: Procedure[];\n onChange: (items: Procedure[]) => void;\n onSearch: (query: string) => Promise<ProcedureSearchResult[]>;\n recentlyUsed?: ProcedureSearchResult[];\n /** Doctor-scoped frequently used procedures (from FormProvider frequentItems) */\n frequentItems?: ProcedureFrequentItem[];\n};\n\nconst ADD_FEEDBACK_MS = 320;\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\nfunction mapToProcedure(result: ProcedureSearchResult): MasterProcedure {\n return {\n ...result,\n label: result.name,\n is_custom: false,\n fromAI: false,\n };\n}\n\nfunction createCustomProcedure(trimmedName: string): CustomProcedure {\n return { name: trimmedName.trim(), is_custom: true };\n}\n\n// ─── Main component ───────────────────────────────────────────────────────────\n\nexport const AddProcedureField: React.FC<AddProcedureFieldProps> = ({\n label = 'Procedures',\n value,\n onChange,\n onSearch,\n recentlyUsed = [],\n frequentItems = [],\n}) => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [results, setResults] = useState<ProcedureSearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [addingId, setAddingId] = useState<string | null>(null);\n const [addingFrequentId, setAddingFrequentId] = useState<string | null>(null);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const valueRef = useRef<Procedure[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n const safeValue: Procedure[] = Array.isArray(value) ? value : [];\n\n valueRef.current = safeValue;\n const addedIds = new Set(\n safeValue.filter((proc): proc is MasterProcedure => !proc.is_custom).map((proc) => proc.id),\n );\n\n useEffect(() => {\n if (!open) {\n setQuery('');\n setResults([]);\n setAddingId(null);\n setAddingFrequentId(null);\n }\n }, [open]);\n\n function handleQueryChange(q: string) {\n setQuery(q);\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (!q.trim()) {\n setResults([]);\n return;\n }\n debounceRef.current = setTimeout(async () => {\n setLoading(true);\n try {\n const res = await onSearch(q);\n setResults(res);\n } finally {\n setLoading(false);\n }\n }, 500);\n }\n\n function addProcedure(result: ProcedureSearchResult) {\n if (!addedIds.has(result.id)) {\n onChange([...valueRef.current, mapToProcedure(result)]);\n }\n setQuery('');\n setResults([]);\n }\n\n function handleResultClick(result: ProcedureSearchResult) {\n if (addedIds.has(result.id)) return;\n setAddingId(result.id);\n setTimeout(() => {\n addProcedure(result);\n setAddingId(null);\n setTimeout(() => searchInputRef.current?.focus(), 0);\n }, ADD_FEEDBACK_MS);\n }\n\n function removeAt(index: number) {\n onChange(safeValue.filter((_, i) => i !== index));\n }\n\n function removeBySearchId(id: string) {\n onChange(safeValue.filter((proc) => proc.is_custom || proc.id !== id));\n }\n\n function handleAddCustom() {\n const trimmed = query.trim();\n if (!trimmed) return;\n if (valueRef.current.some((p) => p.is_custom && p.name === trimmed)) return;\n onChange([...valueRef.current, createCustomProcedure(trimmed)]);\n setQuery('');\n setResults([]);\n }\n\n function handleRecentlyUsedToggle(result: ProcedureSearchResult) {\n if (addedIds.has(result.id)) {\n removeBySearchId(result.id);\n } else {\n addProcedure(result);\n }\n }\n\n async function handleFrequentItemToggle(item: ProcedureFrequentItem) {\n const id = String(item.id);\n const addedById = addedIds.has(id);\n const addedByName = safeValue.some((proc) => proc.name === item.name);\n if (addedById || addedByName) {\n if (addedById) removeBySearchId(id);\n else onChange(safeValue.filter((proc) => proc.name !== item.name));\n return;\n }\n setAddingFrequentId(id);\n try {\n const searchResults = await onSearch(item.name);\n const first = searchResults?.[0];\n if (first && !valueRef.current.some((proc) => !proc.is_custom && proc.id === first.id)) {\n onChange([...valueRef.current, mapToProcedure(first)]);\n }\n } finally {\n setAddingFrequentId(null);\n }\n }\n\n const recentlyUsedChips = recentlyUsed.map((r) => {\n const isAdded = addedIds.has(r.id);\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleRecentlyUsedToggle(r)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {r.name}\n </button>\n );\n });\n\n const limitedFrequentItems = frequentItems.slice(0, 25);\n\n const frequentItemChips =\n limitedFrequentItems.length > 0\n ? limitedFrequentItems.map((item) => {\n const id = String(item.id);\n const isAdded =\n safeValue.some((proc) => !proc.is_custom && proc.id === id) ||\n safeValue.some((proc) => proc.name === item.name);\n const isAdding = addingFrequentId === id;\n return (\n <button\n key={item.id}\n type=\"button\"\n disabled={isAdding}\n onClick={() => handleFrequentItemToggle(item)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50',\n isAdding && 'opacity-70 pointer-events-none'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {isAdding ? '…' : item.name}\n </button>\n );\n })\n : [];\n\n return (\n <div className=\"rounded-md overflow-hidden flex flex-col bg-white border border-[#D0D0D0] space-y-3 p-3 h-fit\">\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-sm font-semibold\">{label}</span>\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"text-sm font-semibold text-purple-600 hover:text-purple-800 cursor-pointer\"\n >\n ADD\n </button>\n </div>\n\n {/* Added procedures — one row each */}\n {safeValue.length > 0 && (\n <div className=\"divide-y divide-border rounded-lg border border-border overflow-hidden\">\n {safeValue.map((proc, index) => (\n <div\n key={proc.is_custom ? `custom-${index}` : proc.id}\n className=\"flex items-center justify-between px-3 py-2 bg-white hover:bg-gray-50\"\n >\n <span className=\"text-sm\">{proc.name}</span>\n <button\n type=\"button\"\n onClick={() => removeAt(index)}\n className=\"text-muted-foreground hover:text-red-500 transition-colors cursor-pointer\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Dialog */}\n <AddEntityDialog\n open={open}\n onClose={() => setOpen(false)}\n title=\"Add Procedure\"\n recentlyUsedSlot={\n frequentItemChips.length > 0\n ? frequentItemChips\n : recentlyUsedChips.length > 0\n ? recentlyUsedChips\n : undefined\n }\n chipSectionLabel={frequentItemChips.length > 0 ? 'Frequently used' : undefined}\n actionSlot={\n <button\n type=\"button\"\n disabled={\n !query.trim() ||\n valueRef.current.some((p) => p.is_custom && p.name === query.trim())\n }\n onClick={handleAddCustom}\n className={cn(\n 'rounded-md px-5 py-2 text-sm font-semibold bg-primary text-primary-foreground hover:bg-primary/90 transition-opacity cursor-pointer',\n (!query.trim() ||\n valueRef.current.some((p) => p.is_custom && p.name === query.trim())) &&\n 'opacity-40 cursor-not-allowed'\n )}\n >\n Save Procedure\n </button>\n }\n >\n <div className=\"space-y-2\">\n <Input\n ref={searchInputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n placeholder=\"Search for a procedure...\"\n className=\"border border-border rounded-md focus-visible:ring-0\"\n />\n\n {/* Inline results — no absolute positioning to avoid overflow-clip */}\n {loading && (\n <p className=\"text-xs text-muted-foreground py-1\">Searching…</p>\n )}\n {!loading && results.length > 0 && (\n <div className=\"border border-border rounded-md overflow-hidden\">\n {results.map((r) => {\n const isAdding = addingId === r.id;\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleResultClick(r)}\n className={cn(\n 'w-full text-left px-3 py-2 text-sm transition-all duration-300 ease-out border-b border-border last:border-b-0 cursor-pointer flex items-center justify-between gap-2',\n isAdding\n ? 'bg-green-50 border-green-200'\n : 'hover:bg-gray-50'\n )}\n >\n <span className=\"truncate\">{r.name}</span>\n {isAdding && <Check className=\"h-4 w-4 shrink-0 text-green-600\" />}\n </button>\n );\n })}\n </div>\n )}\n </div>\n </AddEntityDialog>\n </div>\n );\n};\n","import React from 'react';\nimport { useField } from '../../react/useField';\nimport { useFieldHandlers, useFrequentItems } from '../../react/FormProvider';\nimport { AddProcedureField } from './AddProcedureField';\nimport type { Procedure, ProcedureSearchResult } from './AddProcedureField';\n\nexport const AddProcedureWidget: React.FC<{ fieldId: string }> = ({ fieldId }) => {\n const { value, setValue } = useField(fieldId);\n const handlers = useFieldHandlers(fieldId);\n const { procedures: frequentProcedures } = useFrequentItems();\n\n const safeValue: Procedure[] = Array.isArray(value) ? (value as Procedure[]) : [];\n\n return (\n <AddProcedureField\n value={safeValue}\n onChange={setValue}\n onSearch={handlers.onSearch as (query: string) => Promise<ProcedureSearchResult[]>}\n recentlyUsed={handlers.recentlyUsed as ProcedureSearchResult[] | undefined}\n frequentItems={frequentProcedures}\n />\n );\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/widgets/AddProcedureField.tsx","../src/ui/widgets/AddProcedureWidget.tsx"],"names":["useState","useRef","useEffect","jsxs","cn","jsx","X","AddEntityDialog","Input","Check","useField","useFieldHandlers","useFrequentItems"],"mappings":"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","file":"AddProcedureWidget-HK7UNRXH.cjs","sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { X, Check } from 'lucide-react';\nimport { cn } from '../../core/utils';\nimport { Input } from '../shadcn/input';\nimport { AddEntityDialog } from './AddEntityDialog';\nimport type { ProcedureFrequentItem } from '../../core/types';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n// Matches search API response.results[] shape\n\nexport type ProcedureSearchResult = {\n id: string;\n name: string;\n code?: string;\n description?: string;\n specialization?: string;\n score?: number;\n};\n\n/** Master row from search / frequent resolution — full metadata. */\nexport type MasterProcedure = ProcedureSearchResult & {\n label: string;\n is_custom: false;\n fromAI: boolean;\n};\n\n/** Custom free-text row — only `name` and `is_custom` (no extra keys). */\nexport type CustomProcedure = {\n name: string;\n is_custom: true;\n};\n\nexport type Procedure = MasterProcedure | CustomProcedure;\n\nexport type AddProcedureFieldProps = {\n label?: string;\n value: Procedure[];\n onChange: (items: Procedure[]) => void;\n onSearch: (query: string) => Promise<ProcedureSearchResult[]>;\n recentlyUsed?: ProcedureSearchResult[];\n /** Doctor-scoped frequently used procedures (from FormProvider frequentItems) */\n frequentItems?: ProcedureFrequentItem[];\n};\n\nconst ADD_FEEDBACK_MS = 320;\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\nfunction mapToProcedure(result: ProcedureSearchResult): MasterProcedure {\n return {\n ...result,\n label: result.name,\n is_custom: false,\n fromAI: false,\n };\n}\n\nfunction createCustomProcedure(trimmedName: string): CustomProcedure {\n return { name: trimmedName.trim(), is_custom: true };\n}\n\n// ─── Main component ───────────────────────────────────────────────────────────\n\nexport const AddProcedureField: React.FC<AddProcedureFieldProps> = ({\n label = 'Procedures',\n value,\n onChange,\n onSearch,\n recentlyUsed = [],\n frequentItems = [],\n}) => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [results, setResults] = useState<ProcedureSearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [addingId, setAddingId] = useState<string | null>(null);\n const [addingFrequentId, setAddingFrequentId] = useState<string | null>(null);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const valueRef = useRef<Procedure[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n const safeValue: Procedure[] = Array.isArray(value) ? value : [];\n\n valueRef.current = safeValue;\n const addedIds = new Set(\n safeValue.filter((proc): proc is MasterProcedure => !proc.is_custom).map((proc) => proc.id),\n );\n\n useEffect(() => {\n if (!open) {\n setQuery('');\n setResults([]);\n setAddingId(null);\n setAddingFrequentId(null);\n }\n }, [open]);\n\n function handleQueryChange(q: string) {\n setQuery(q);\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (!q.trim()) {\n setResults([]);\n return;\n }\n debounceRef.current = setTimeout(async () => {\n setLoading(true);\n try {\n const res = await onSearch(q);\n setResults(res);\n } finally {\n setLoading(false);\n }\n }, 500);\n }\n\n function addProcedure(result: ProcedureSearchResult) {\n if (!addedIds.has(result.id)) {\n onChange([...valueRef.current, mapToProcedure(result)]);\n }\n setQuery('');\n setResults([]);\n }\n\n function handleResultClick(result: ProcedureSearchResult) {\n if (addedIds.has(result.id)) return;\n setAddingId(result.id);\n setTimeout(() => {\n addProcedure(result);\n setAddingId(null);\n setTimeout(() => searchInputRef.current?.focus(), 0);\n }, ADD_FEEDBACK_MS);\n }\n\n function removeAt(index: number) {\n onChange(safeValue.filter((_, i) => i !== index));\n }\n\n function removeBySearchId(id: string) {\n onChange(safeValue.filter((proc) => proc.is_custom || proc.id !== id));\n }\n\n function handleAddCustom() {\n const trimmed = query.trim();\n if (!trimmed) return;\n if (valueRef.current.some((p) => p.is_custom && p.name === trimmed)) return;\n onChange([...valueRef.current, createCustomProcedure(trimmed)]);\n setQuery('');\n setResults([]);\n }\n\n function handleRecentlyUsedToggle(result: ProcedureSearchResult) {\n if (addedIds.has(result.id)) {\n removeBySearchId(result.id);\n } else {\n addProcedure(result);\n }\n }\n\n async function handleFrequentItemToggle(item: ProcedureFrequentItem) {\n const id = String(item.id);\n const addedById = addedIds.has(id);\n const addedByName = safeValue.some((proc) => proc.name === item.name);\n if (addedById || addedByName) {\n if (addedById) removeBySearchId(id);\n else onChange(safeValue.filter((proc) => proc.name !== item.name));\n return;\n }\n setAddingFrequentId(id);\n try {\n const searchResults = await onSearch(item.name);\n const first = searchResults?.[0];\n if (first && !valueRef.current.some((proc) => !proc.is_custom && proc.id === first.id)) {\n onChange([...valueRef.current, mapToProcedure(first)]);\n }\n } finally {\n setAddingFrequentId(null);\n }\n }\n\n const recentlyUsedChips = recentlyUsed.map((r) => {\n const isAdded = addedIds.has(r.id);\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleRecentlyUsedToggle(r)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {r.name}\n </button>\n );\n });\n\n const limitedFrequentItems = frequentItems.slice(0, 25);\n\n const frequentItemChips =\n limitedFrequentItems.length > 0\n ? limitedFrequentItems.map((item) => {\n const id = String(item.id);\n const isAdded =\n safeValue.some((proc) => !proc.is_custom && proc.id === id) ||\n safeValue.some((proc) => proc.name === item.name);\n const isAdding = addingFrequentId === id;\n return (\n <button\n key={item.id}\n type=\"button\"\n disabled={isAdding}\n onClick={() => handleFrequentItemToggle(item)}\n className={cn(\n 'rounded-full border text-xs px-3 py-1 transition-colors',\n isAdded\n ? 'border-green-300 bg-green-50 text-green-700'\n : 'border-border bg-white hover:bg-gray-50',\n isAdding && 'opacity-70 pointer-events-none'\n )}\n >\n {isAdded && <span className=\"mr-1\">✓</span>}\n {isAdding ? '…' : item.name}\n </button>\n );\n })\n : [];\n\n return (\n <div className=\"rounded-md overflow-hidden flex flex-col bg-white border border-[#D0D0D0] space-y-3 p-3 h-fit\">\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-sm font-semibold\">{label}</span>\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"text-sm font-semibold text-purple-600 hover:text-purple-800 cursor-pointer\"\n >\n ADD\n </button>\n </div>\n\n {/* Added procedures — one row each */}\n {safeValue.length > 0 && (\n <div className=\"divide-y divide-border rounded-lg border border-border overflow-hidden\">\n {safeValue.map((proc, index) => (\n <div\n key={proc.is_custom ? `custom-${index}` : proc.id}\n className=\"flex items-center justify-between px-3 py-2 bg-white hover:bg-gray-50\"\n >\n <span className=\"text-sm\">{proc.name}</span>\n <button\n type=\"button\"\n onClick={() => removeAt(index)}\n className=\"text-muted-foreground hover:text-red-500 transition-colors cursor-pointer\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Dialog */}\n <AddEntityDialog\n open={open}\n onClose={() => setOpen(false)}\n title=\"Add Procedure\"\n recentlyUsedSlot={\n frequentItemChips.length > 0\n ? frequentItemChips\n : recentlyUsedChips.length > 0\n ? recentlyUsedChips\n : undefined\n }\n chipSectionLabel={frequentItemChips.length > 0 ? 'Frequently used' : undefined}\n actionSlot={\n <button\n type=\"button\"\n disabled={\n !query.trim() ||\n valueRef.current.some((p) => p.is_custom && p.name === query.trim())\n }\n onClick={handleAddCustom}\n className={cn(\n 'rounded-md px-5 py-2 text-sm font-semibold bg-primary text-primary-foreground hover:bg-primary/90 transition-opacity cursor-pointer',\n (!query.trim() ||\n valueRef.current.some((p) => p.is_custom && p.name === query.trim())) &&\n 'opacity-40 cursor-not-allowed'\n )}\n >\n Save Procedure\n </button>\n }\n >\n <div className=\"space-y-2\">\n <Input\n ref={searchInputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n placeholder=\"Search for a procedure...\"\n className=\"border border-border rounded-md focus-visible:ring-0\"\n />\n\n {/* Inline results — no absolute positioning to avoid overflow-clip */}\n {loading && (\n <p className=\"text-xs text-muted-foreground py-1\">Searching…</p>\n )}\n {!loading && results.length > 0 && (\n <div className=\"border border-border rounded-md overflow-hidden\">\n {results.map((r) => {\n const isAdding = addingId === r.id;\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => handleResultClick(r)}\n className={cn(\n 'w-full text-left px-3 py-2 text-sm transition-all duration-300 ease-out border-b border-border last:border-b-0 cursor-pointer flex items-center justify-between gap-2',\n isAdding\n ? 'bg-green-50 border-green-200'\n : 'hover:bg-gray-50'\n )}\n >\n <span className=\"truncate\">{r.name}</span>\n {isAdding && <Check className=\"h-4 w-4 shrink-0 text-green-600\" />}\n </button>\n );\n })}\n </div>\n )}\n </div>\n </AddEntityDialog>\n </div>\n );\n};\n","import React from 'react';\nimport { useField } from '../../react/useField';\nimport { useFieldHandlers, useFrequentItems } from '../../react/FormProvider';\nimport { AddProcedureField } from './AddProcedureField';\nimport type { Procedure, ProcedureSearchResult } from './AddProcedureField';\n\nexport const AddProcedureWidget: React.FC<{ fieldId: string }> = ({ fieldId }) => {\n const { value, setValue } = useField(fieldId);\n const handlers = useFieldHandlers(fieldId);\n const { procedures: frequentProcedures } = useFrequentItems();\n\n const safeValue: Procedure[] = Array.isArray(value) ? (value as Procedure[]) : [];\n\n return (\n <AddProcedureField\n value={safeValue}\n onChange={setValue}\n onSearch={handlers.onSearch as (query: string) => Promise<ProcedureSearchResult[]>}\n recentlyUsed={handlers.recentlyUsed as ProcedureSearchResult[] | undefined}\n frequentItems={frequentProcedures}\n />\n );\n};\n"]}
|