@medplum/react 3.3.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +2 -2
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/esm/index.mjs +3 -3
- package/dist/esm/index.mjs.map +3 -3
- package/package.json +8 -8
package/dist/esm/index.mjs
CHANGED
|
@@ -62,15 +62,15 @@ var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropD
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
}`.replace(/\s+/g," ")}function getResourcesFromResponse(response,query){let resources=[];return response.data.Patients1&&resources.push(...response.data.Patients1),response.data.Patients2&&resources.push(...response.data.Patients2),response.data.ServiceRequestList&&resources.push(...response.data.ServiceRequestList),sortByRelevance(dedupeResources(resources),query).slice(0,5)}function dedupeResources(resources){let ids=new Set,result=[];for(let resource of resources)ids.has(resource.id)||(ids.add(resource.id),result.push(resource));return result}function sortByRelevance(resources,query){return resources.sort((a,b)=>getResourceScore(b,query)-getResourceScore(a,query))}function getResourceScore(resource,query){let bestScore=0;if(resource.identifier)for(let identifier of resource.identifier)bestScore=Math.max(bestScore,getStringScore(identifier.value,query));if(resource.resourceType==="Patient"&&resource.name)for(let name of resource.name)bestScore=Math.max(bestScore,getStringScore(formatHumanName2(name),query));return bestScore}function getStringScore(str,query){if(!str)return 0;let index=str.toLowerCase().indexOf(query.toLowerCase());return index<0?0:100-index}import{jsx as jsx12,jsxs as jsxs5}from"react/jsx-runtime";function Header(props){let profile=useMedplumProfile2(),[userMenuOpened,setUserMenuOpened]=useState4(!1);return jsx12(MantineAppShell.Header,{p:8,style:{zIndex:101},children:jsxs5(Group5,{justify:"space-between",children:[jsxs5(Group5,{gap:"xs",children:[jsx12(UnstyledButton,{className:Header_default.logoButton,onClick:props.navbarToggle,children:props.logo}),!props.headerSearchDisabled&&jsx12(HeaderSearchInput,{pathname:props.pathname,searchParams:props.searchParams})]}),jsxs5(Group5,{gap:"lg",pr:"sm",children:[props.notifications,jsxs5(Menu2,{width:260,shadow:"xl",position:"bottom-end",transitionProps:{transition:"pop-top-right"},opened:userMenuOpened,onClose:()=>setUserMenuOpened(!1),children:[jsx12(Menu2.Target,{children:jsx12(UnstyledButton,{className:clsx_default(Header_default.user,{[Header_default.userActive]:userMenuOpened}),onClick:()=>setUserMenuOpened(o=>!o),children:jsxs5(Group5,{gap:7,children:[jsx12(ResourceAvatar,{value:profile,radius:"xl",size:24}),jsx12(Text3,{size:"sm",className:Header_default.userName,children:formatHumanName3(profile?.name?.[0])}),jsx12(IconChevronDown,{size:12,stroke:1.5})]})})}),jsx12(Menu2.Dropdown,{children:jsx12(HeaderDropdown,{version:props.version})})]})]})]})})}import{Button as Button2,AppShell as MantineAppShell2,ScrollArea,Space,Text as Text5}from"@mantine/core";import{useMedplumNavigate as useMedplumNavigate3}from"@medplum/react-hooks";import{Fragment as Fragment4,useState as useState7}from"react";import{Button,Group as Group6,Modal,NativeSelect as NativeSelect2,Stack as Stack2,TextInput as TextInput3}from"@mantine/core";import{showNotification as showNotification2}from"@mantine/notifications";import{deepClone,normalizeErrorString as normalizeErrorString3}from"@medplum/core";import{useMedplum as useMedplum2}from"@medplum/react-hooks";function parseForm(form){let result={};for(let element of Array.from(form.elements))element instanceof HTMLInputElement?parseInputElement(result,element):element instanceof HTMLTextAreaElement?result[element.name]=element.value:element instanceof HTMLSelectElement&&parseSelectElement(result,element);return result}function parseInputElement(result,el){el.disabled||(el.type==="checkbox"||el.type==="radio")&&!el.checked||(result[el.name]=el.value)}function parseSelectElement(result,el){result[el.name]=el.value}import{jsx as jsx13}from"react/jsx-runtime";function Form(props){return jsx13("form",{style:props.style,"data-testid":props.testid,onSubmit:e=>{e.preventDefault();let formData=parseForm(e.target);props.onSubmit&&props.onSubmit(formData)},children:props.children})}import{jsx as jsx14,jsxs as jsxs6}from"react/jsx-runtime";function BookmarkDialog(props){let medplum=useMedplum2(),config=medplum.getUserConfiguration();function submitHandler(formData){let{menuname,bookmarkname:name}=formData,target=`${props.pathname}?${props.searchParams.toString()}`,newConfig=deepClone(config);newConfig.menu?.find(({title})=>title===menuname)?.link?.push({name,target}),medplum.updateResource(newConfig).then(res=>{config.menu=res.menu,medplum.dispatchEvent({type:"change"}),showNotification2({color:"green",message:"Success"}),props.onOk()}).catch(err=>{showNotification2({color:"red",message:normalizeErrorString3(err)})})}return jsx14(Modal,{title:"Add Bookmark",closeButtonProps:{"aria-label":"Close"},opened:props.visible,onClose:props.onCancel,children:jsx14(Form,{onSubmit:submitHandler,children:jsxs6(Stack2,{children:[jsx14(SelectMenu,{config}),jsx14(TextInput3,{label:"Bookmark Name",type:"text",name:"bookmarkname",placeholder:"Bookmark Name",withAsterisk:!0}),jsx14(Group6,{justify:"flex-end",children:jsx14(Button,{mt:"sm",type:"submit",children:"OK"})})]})})})}function SelectMenu(props){function userConfigToMenu(config){return config?.menu?.map(menu=>menu.title)}let menus=userConfigToMenu(props.config);return jsx14(NativeSelect2,{name:"menuname",defaultValue:menus[0],label:"Select Menu Option",data:menus,withAsterisk:!0})}import{useCallback as useCallback4,useState as useState6}from"react";import{useState as useState5}from"react";import{Group as Group7,Text as Text4}from"@mantine/core";import{useMedplum as useMedplum3}from"@medplum/react-hooks";import{forwardRef as forwardRef3,useCallback as useCallback3}from"react";import{jsx as jsx15,jsxs as jsxs7}from"react/jsx-runtime";function toKey(element){return typeof element.code=="string"?element.code:JSON.stringify(element)}function getDisplay(item){return typeof item.display=="string"?item.display:toKey(item)}function toOption2(element){return{value:toKey(element),label:getDisplay(element),resource:element}}function createValue(input){return{code:input,display:input}}function ValueSetAutocomplete(props){let medplum=useMedplum3(),{binding,creatable,clearable,expandParams,withHelpText,...rest}=props,loadValues=useCallback3(async(input,signal)=>{if(!binding)return[];let valueSetElements=(await medplum.valueSetExpand({...expandParams,url:binding,filter:input},{signal})).expansion?.contains??[],newData=[];for(let valueSetElement of valueSetElements)valueSetElement.code&&!newData.some(item=>item.code===valueSetElement.code)&&newData.push(valueSetElement);return newData},[medplum,expandParams,binding]);return jsx15(AsyncAutocomplete,{...rest,creatable:creatable??!0,clearable:clearable??!0,toOption:toOption2,loadOptions:loadValues,onCreate:createValue,itemComponent:withHelpText?ItemComponent2:void 0})}var ItemComponent2=forwardRef3(({label,resource,active,...others},ref)=>jsx15("div",{ref,...others,children:jsxs7(Group7,{wrap:"nowrap",gap:"xs",children:[active&&jsx15(IconCheck,{size:12}),jsxs7("div",{children:[jsx15(Text4,{children:label}),jsx15(Text4,{size:"xs",c:"dimmed",children:`${resource.system}#${resource.code}`})]})]})}));import{jsx as jsx16}from"react/jsx-runtime";function CodeInput(props){let{defaultValue:defaultValue2,onChange,withHelpText,...rest}=props,[value,setValue]=useState5(defaultValue2);function handleChange(newValues){let newValue=newValues[0],newCode=valueSetElementToCode(newValue);setValue(newCode),onChange&&onChange(newCode)}return jsx16(ValueSetAutocomplete,{defaultValue:codeToValueSetElement(value),onChange:handleChange,withHelpText:withHelpText??!0,...rest})}function codeToValueSetElement(code){return code?{code}:void 0}function valueSetElementToCode(element){return element?.code}import{jsx as jsx17}from"react/jsx-runtime";function ResourceTypeInput(props){let[resourceType,setResourceType]=useState6(props.defaultValue),onChange=props.onChange,setResourceTypeWrapper=useCallback4(newResourceType=>{setResourceType(newResourceType),onChange&&onChange(newResourceType)},[onChange]);return jsx17(CodeInput,{disabled:props.disabled,"data-autofocus":props.autoFocus,"data-testid":props.testId,defaultValue:resourceType,onChange:setResourceTypeWrapper,name:props.name,placeholder:props.placeholder,binding:"https://medplum.com/fhir/ValueSet/resource-types",creatable:!1,maxValues:props.maxValues??1,clearable:!1,withHelpText:!1})}var Navbar_default={menuTitle:"Navbar_menuTitle",link:"Navbar_link",linkActive:"Navbar_linkActive"};import{Fragment as Fragment5,jsx as jsx18,jsxs as jsxs8}from"react/jsx-runtime";function Navbar(props){let navigate=useMedplumNavigate3(),activeLink=getActiveLink(props.pathname,props.searchParams,props.menus),[bookmarkDialogVisible,setBookmarkDialogVisible]=useState7(!1);function onLinkClick(e,to){e.stopPropagation(),e.preventDefault(),navigate(to),window.innerWidth<768&&props.closeNavbar()}function navigateResourceType(resourceType){resourceType&&navigate(`/${resourceType}`)}return jsxs8(Fragment5,{children:[jsx18(MantineAppShell2.Navbar,{children:jsxs8(ScrollArea,{p:"xs",children:[!props.resourceTypeSearchDisabled&&jsx18(MantineAppShell2.Section,{mb:"sm",children:jsx18(ResourceTypeInput,{name:"resourceType",placeholder:"Resource Type",maxValues:0,onChange:newValue=>navigateResourceType(newValue)},window.location.pathname)}),jsxs8(MantineAppShell2.Section,{grow:!0,children:[props.menus?.map(menu=>jsxs8(Fragment4,{children:[jsx18(Text5,{className:Navbar_default.menuTitle,children:menu.title}),menu.links?.map(link=>jsxs8(NavbarLink,{to:link.href,active:link.href===activeLink?.href,onClick:e=>onLinkClick(e,link.href),children:[jsx18(NavLinkIcon,{to:link.href,icon:link.icon}),jsx18("span",{children:link.label})]},link.href))]},`menu-${menu.title}`)),props.displayAddBookmark&&jsx18(Button2,{variant:"subtle",size:"xs",mt:"xl",leftSection:jsx18(IconPlus,{size:"0.75rem"}),onClick:()=>setBookmarkDialogVisible(!0),children:"Add Bookmark"})]})]})}),props.pathname&&props.searchParams&&jsx18(BookmarkDialog,{pathname:props.pathname,searchParams:props.searchParams,visible:bookmarkDialogVisible,onOk:()=>setBookmarkDialogVisible(!1),onCancel:()=>setBookmarkDialogVisible(!1)})]})}function NavbarLink(props){return jsx18(MedplumLink,{onClick:props.onClick,to:props.to,className:clsx_default(Navbar_default.link,{[Navbar_default.linkActive]:props.active}),children:props.children})}function NavLinkIcon(props){return props.icon?props.icon:jsx18(Space,{w:30})}function getActiveLink(currentPathname,currentSearchParams,menus){if(!currentPathname||!currentSearchParams||!menus)return;let bestLink,bestScore=0;for(let menu of menus)if(menu.links)for(let link of menu.links){let score=getLinkScore(currentPathname,currentSearchParams,link.href);score>bestScore&&(bestScore=score,bestLink=link)}return bestLink}function getLinkScore(currentPathname,currentSearchParams,linkHref){let linkUrl=new URL(linkHref,"https://example.com");if(currentPathname!==linkUrl.pathname)return 0;let ignoredParams=["_count","_offset"];for(let[key,value]of linkUrl.searchParams.entries())if(!ignoredParams.includes(key)&¤tSearchParams.get(key)!==value)return 0;let count=1;for(let[key,value]of currentSearchParams.entries())ignoredParams.includes(key)||linkUrl.searchParams.get(key)===value&&count++;return count}import{jsx as jsx19,jsxs as jsxs9}from"react/jsx-runtime";function AppShell(props){let[navbarOpen,setNavbarOpen]=useState8(localStorage.navbarOpen==="true"),medplum=useMedplum4(),profile=useMedplumProfile3();useEffect2(()=>{function eventListener(){showNotification3({id:"offline",color:"red",message:"No connection to server",autoClose:!1})}return medplum.addEventListener("offline",eventListener),()=>medplum.removeEventListener("offline",eventListener)},[medplum]);function setNavbarOpenWrapper(open){localStorage.navbarOpen=open.toString(),setNavbarOpen(open)}function closeNavbar(){setNavbarOpenWrapper(!1)}function toggleNavbar(){setNavbarOpenWrapper(!navbarOpen)}return medplum.isLoading()?jsx19(Loading,{}):jsxs9(MantineAppShell3,{header:{height:60},navbar:{width:250,breakpoint:"sm",collapsed:{desktop:!profile||!navbarOpen,mobile:!profile||!navbarOpen}},padding:0,children:[profile&&jsx19(Header,{pathname:props.pathname,searchParams:props.searchParams,headerSearchDisabled:props.headerSearchDisabled,logo:props.logo,version:props.version,navbarToggle:toggleNavbar,notifications:props.notifications}),profile&&navbarOpen?jsx19(Navbar,{pathname:props.pathname,searchParams:props.searchParams,menus:props.menus,closeNavbar,displayAddBookmark:props.displayAddBookmark,resourceTypeSearchDisabled:props.resourceTypeSearchDisabled}):void 0,jsx19(MantineAppShell3.Main,{className:AppShell_default.main,children:jsx19(ErrorBoundary,{children:jsx19(Suspense,{fallback:jsx19(Loading,{}),children:props.children})})})]})}import{Anchor as Anchor2}from"@mantine/core";import{ContentType}from"@medplum/core";import{useCachedBinaryUrl as useCachedBinaryUrl2}from"@medplum/react-hooks";import{useEffect as useEffect3,useRef as useRef3,useState as useState9}from"react";import{jsx as jsx20}from"react/jsx-runtime";var CCDA_VIEWER_URL="https://ccda.medplum.com";function CcdaDisplay(props){let{url}=props,[shouldSend,setShouldSend]=useState9(!1),iframeRef=useRef3(null);return useEffect3(()=>{url&&shouldSend&&iframeRef.current&&(sendCommand(iframeRef.current,{command:"loadCcdaXml",value:url}).catch(console.error),setShouldSend(!1))},[url,shouldSend]),url?jsx20("div",{"data-testid":"ccda-iframe",style:{maxWidth:props.maxWidth,minHeight:400},children:jsx20("iframe",{title:"C-CDA Viewer",width:"100%",height:"400",ref:iframeRef,src:CCDA_VIEWER_URL,allowFullScreen:!0,frameBorder:0,seamless:!0,onLoad:()=>setShouldSend(!0)})}):null}import{jsx as jsx21,jsxs as jsxs10}from"react/jsx-runtime";function AttachmentDisplay(props){let{contentType,url:uncachedUrl,title}=props.value??{},url=useCachedBinaryUrl2(uncachedUrl);return url?jsxs10("div",{"data-testid":"attachment-display",children:[contentType?.startsWith("image/")&&jsx21("img",{"data-testid":"attachment-image",style:{maxWidth:props.maxWidth},src:url,alt:title}),contentType?.startsWith("video/")&&jsx21("video",{"data-testid":"attachment-video",style:{maxWidth:props.maxWidth},controls:!0,children:jsx21("source",{type:contentType,src:url})}),(contentType?.startsWith("text/")||contentType==="application/json"||contentType==="application/pdf")&&jsx21("div",{"data-testid":"attachment-iframe",style:{maxWidth:props.maxWidth,minHeight:400},children:jsx21("iframe",{width:"100%",height:"400",src:url+"#navpanes=0",allowFullScreen:!0,frameBorder:0,seamless:!0})}),contentType===ContentType.CDA_XML&&jsx21(CcdaDisplay,{url}),jsx21("div",{"data-testid":"download-link",style:{padding:"2px 16px 16px 16px"},children:jsx21(Anchor2,{href:uncachedUrl,"data-testid":"attachment-details",target:"_blank",rel:"noopener noreferrer",download:getDownloadName(title),children:title||"Download"})})]}):null}function getDownloadName(title){return title?.includes(".")?title:void 0}var DescriptionList_default={root:"DescriptionList_root",compact:"DescriptionList_compact"};import{Fragment as Fragment6,jsx as jsx22,jsxs as jsxs11}from"react/jsx-runtime";function DescriptionList(props){let{children,compact}=props;return jsx22("dl",{className:clsx_default(DescriptionList_default.root,{[DescriptionList_default.compact]:compact}),children})}function DescriptionListEntry(props){return jsxs11(Fragment6,{children:[jsx22("dt",{children:props.term}),jsx22("dd",{children:props.children})]})}import{getPathDisplayName,isPopulated as isPopulated2}from"@medplum/core";import{Fragment as Fragment7,jsx as jsx23}from"react/jsx-runtime";function AttachmentArrayDisplay(props){let attachmentElements=props.values?.map((v,index)=>jsx23("div",{children:jsx23(AttachmentDisplay,{value:v,maxWidth:props.maxWidth})},"attatchment-"+index)),content;if(props.includeDescriptionListEntry){if(props.property===void 0)throw new Error("props.property is required when includeDescriptionListEntry is true");if(!isPopulated2(props.path))throw new Error("props.path is required when includeDescriptionListEntry is true");let key=props.path.split(".").pop();content=jsx23(DescriptionListEntry,{term:getPathDisplayName(key),children:attachmentElements})}else content=jsx23(Fragment7,{children:attachmentElements});return content}import{ActionIcon}from"@mantine/core";import{useRef as useRef5,useState as useState10}from"react";import{normalizeOperationOutcome}from"@medplum/core";import{useMedplum as useMedplum5}from"@medplum/react-hooks";import{useRef as useRef4}from"react";import{Fragment as Fragment8,jsx as jsx24,jsxs as jsxs12}from"react/jsx-runtime";function AttachmentButton(props){let medplum=useMedplum5(),fileInputRef=useRef4(null);function onClick(e){killEvent(e),fileInputRef.current?.click()}function onFileChange(e){killEvent(e);let files=e.target.files;files&&Array.from(files).forEach(processFile)}function processFile(file){!file||!file.name||(props.onUploadStart&&props.onUploadStart(),medplum.createAttachment({data:file,contentType:file.type||"application/octet-stream",filename:file.name,securityContext:props.securityContext,onProgress:props.onUploadProgress}).then(attachment=>props.onUpload(attachment)).catch(err=>{props.onUploadError&&props.onUploadError(normalizeOperationOutcome(err))}))}return jsxs12(Fragment8,{children:[jsx24("input",{disabled:props.disabled,type:"file","data-testid":"upload-file-input",style:{display:"none"},ref:fileInputRef,onChange:e=>onFileChange(e)}),props.children({onClick,disabled:props.disabled})]})}import{jsx as jsx25,jsxs as jsxs13}from"react/jsx-runtime";function AttachmentArrayInput(props){let[values,setValues]=useState10(props.defaultValue??[]),valuesRef=useRef5();valuesRef.current=values;function setValuesWrapper(newValues){setValues(newValues),props.onChange&&props.onChange(newValues)}return jsxs13("table",{style:{width:"100%"},children:[jsxs13("colgroup",{children:[jsx25("col",{width:"97%"}),jsx25("col",{width:"3%"})]}),jsxs13("tbody",{children:[values.map((v,index)=>jsxs13("tr",{children:[jsx25("td",{children:jsx25(AttachmentDisplay,{value:v,maxWidth:200})}),jsx25("td",{children:jsx25(ActionIcon,{disabled:props.disabled,title:"Remove",variant:"subtle",size:"sm",color:"gray",onClick:e=>{killEvent(e);let copy=values.slice();copy.splice(index,1),setValuesWrapper(copy)},children:jsx25(IconCircleMinus,{})})})]},`${index}-${values.length}`)),jsxs13("tr",{children:[jsx25("td",{}),jsx25("td",{children:jsx25(AttachmentButton,{disabled:props.disabled,onUpload:attachment=>{setValuesWrapper([...valuesRef.current,attachment])},children:props2=>jsx25(ActionIcon,{...props2,title:"Add",variant:"subtle",size:"sm",color:props2.disabled?"gray":"green",children:jsx25(IconCloudUpload,{})})})})]})]})]})}import{Button as Button3}from"@mantine/core";import{useState as useState11}from"react";import{Fragment as Fragment9,jsx as jsx26,jsxs as jsxs14}from"react/jsx-runtime";function AttachmentInput(props){let[value,setValue]=useState11(props.defaultValue);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}return value?jsxs14(Fragment9,{children:[jsx26(AttachmentDisplay,{value,maxWidth:200}),jsx26(Button3,{disabled:props.disabled,onClick:e=>{killEvent(e),setValueWrapper(void 0)},children:"Remove"})]}):jsx26(AttachmentButton,{disabled:props.disabled,securityContext:props.securityContext,onUpload:setValueWrapper,children:props2=>jsx26(Button3,{...props2,children:"Upload..."})})}import{normalizeOperationOutcome as normalizeOperationOutcome4}from"@medplum/core";import{useMedplum as useMedplum9}from"@medplum/react-hooks";import{useEffect as useEffect6,useState as useState15}from"react";import{Container as MantineContainer}from"@mantine/core";var Container_default={root:"Container_root"};import{jsx as jsx27}from"react/jsx-runtime";function Container(props){let{children,...others}=props;return jsx27(MantineContainer,{className:Container_default.root,...others,children})}import{Paper}from"@mantine/core";var Panel_default={paper:"Panel_paper",fill:"Panel_fill"};import{jsx as jsx28}from"react/jsx-runtime";function Panel(props){let{width,fill,className,children,...rest}=props,style=width?{maxWidth:width}:void 0;return jsx28(Paper,{className:clsx_default(Panel_default.paper,fill&&Panel_default.fill,className),style,shadow:"sm",radius:"sm",withBorder:!0,...rest,children})}import{jsx as jsx29}from"react/jsx-runtime";function Document(props){let{children,...others}=props;return jsx29(Container,{children:jsx29(Panel,{...others,children})})}import{Anchor as Anchor3,Button as Button4,Center as Center2,Group as Group8,Stack as Stack3,Text as Text6,TextInput as TextInput4,Title}from"@mantine/core";import{normalizeOperationOutcome as normalizeOperationOutcome2}from"@medplum/core";import{useMedplum as useMedplum6}from"@medplum/react-hooks";import{useState as useState12}from"react";import{jsx as jsx30,jsxs as jsxs15}from"react/jsx-runtime";function Logo(props){return jsxs15("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 491 491",style:{width:props.size,height:props.size},children:[jsx30("title",{children:"Medplum Logo"}),jsx30("path",{fill:props.fill??"#ad7136",d:"M282 67c6-16 16-29 29-40L289 0c-22 17-37 41-43 68l17 23 19-24z"}),jsx30("path",{fill:props.fill??"#946af9",d:"M311 63c-17 0-33 4-48 11-16-7-32-11-49-11-87 0-158 96-158 214s71 214 158 214c17 0 33-4 49-11 15 7 31 11 48 11 87 0 158-96 158-214S398 63 311 63z"}),jsx30("path",{fill:props.fill??"#7857c5",d:"M231 489l-17 2c-87 0-158-96-158-214S127 63 214 63l17 1c-39 12-70 102-70 213s31 201 70 212z"}),jsx30("path",{fill:props.fill??"#40bc26",d:"M207 220a176 176 0 01-177 43A176 176 0 01251 43l1 5c17 59 2 125-45 172z"}),jsx30("path",{fill:props.fill??"#33961e",d:"M252 48A421 421 0 0057 270l-27-7A176 176 0 01251 43l1 5z"})]})}function getErrorsForInput(outcome,expression){return outcome?.issue?.filter(issue=>isExpressionMatch(issue.expression?.[0],expression))?.map(issue=>issue.details?.text)?.join(`
|
|
65
|
-
`)}function getIssuesForExpression(outcome,expression){return outcome?.issue?.filter(issue=>isExpressionMatch(issue.expression?.[0],expression))}var ARRAY_INDEX_REGEX=/\[\d+\]/;function isExpressionMatch(expr1,expr2){let isExpr1Indexed=typeof expr1=="string"&&ARRAY_INDEX_REGEX.test(expr1),isExpr2Indexed=typeof expr2=="string"&&ARRAY_INDEX_REGEX.test(expr2);if(isExpr1Indexed!==isExpr2Indexed&&(expr1=expr1?.replace(ARRAY_INDEX_REGEX,""),expr2=expr2?.replace(ARRAY_INDEX_REGEX,"")),expr1===expr2)return!0;if(!expr1||!expr2)return!1;let dot1=expr1.indexOf(".");if(dot1>=0&&expr1.substring(dot1+1)===expr2)return!0;let dot2=expr2.indexOf(".");return dot2>=0&&expr2.substring(dot2+1)===expr1}import{jsx as jsx31,jsxs as jsxs16}from"react/jsx-runtime";function NewProjectForm(props){let medplum=useMedplum6(),[outcome,setOutcome]=useState12();return jsxs16(Form,{onSubmit:async formData=>{try{props.handleAuthResponse(await medplum.startNewProject({login:props.login,projectName:formData.projectName}))}catch(err){setOutcome(normalizeOperationOutcome2(err))}},children:[jsxs16(Center2,{style:{flexDirection:"column"},children:[jsx31(Logo,{size:32}),jsx31(Title,{children:"Create project"})]}),jsxs16(Stack3,{gap:"xl",children:[jsx31(TextInput4,{name:"projectName",label:"Project Name",placeholder:"My Project",required:!0,autoFocus:!0,error:getErrorsForInput(outcome,"projectName")}),jsxs16(Text6,{c:"dimmed",size:"xs",children:["By clicking submit you agree to the Medplum"," ",jsx31(Anchor3,{href:"https://www.medplum.com/privacy",children:"Privacy\xA0Policy"})," and ",jsx31(Anchor3,{href:"https://www.medplum.com/terms",children:"Terms\xA0of\xA0Service"}),"."]})]}),jsx31(Group8,{justify:"flex-end",mt:"xl",wrap:"nowrap",children:jsx31(Button4,{type:"submit",children:"Create project"})})]})}import{Anchor as Anchor4,Button as Button5,Center as Center3,Checkbox,Divider,Group as Group9,PasswordInput,Stack as Stack4,Text as Text7,TextInput as TextInput5}from"@mantine/core";import{normalizeOperationOutcome as normalizeOperationOutcome3}from"@medplum/core";import{useMedplum as useMedplum8}from"@medplum/react-hooks";import{useEffect as useEffect5,useState as useState14}from"react";import{useMedplum as useMedplum7}from"@medplum/react-hooks";import{useEffect as useEffect4,useRef as useRef6,useState as useState13}from"react";function createScriptTag(src,onload){let head=document.getElementsByTagName("head")[0],script=document.createElement("script");script.async=!0,script.src=src,script.onload=onload??null,head.appendChild(script)}import{jsx as jsx32}from"react/jsx-runtime";function GoogleButton(props){let medplum=useMedplum7(),{googleClientId,handleGoogleCredential}=props,parentRef=useRef6(null),[scriptLoaded,setScriptLoaded]=useState13(typeof google<"u"),[initialized,setInitialized]=useState13(!1),[buttonRendered,setButtonRendered]=useState13(!1);return useEffect4(()=>{if(typeof google>"u"){createScriptTag("https://accounts.google.com/gsi/client",()=>setScriptLoaded(!0));return}initialized||(google.accounts.id.initialize({client_id:googleClientId,callback:handleGoogleCredential}),setInitialized(!0)),parentRef.current&&!buttonRendered&&(google.accounts.id.renderButton(parentRef.current,{}),setButtonRendered(!0))},[medplum,googleClientId,initialized,scriptLoaded,parentRef,buttonRendered,handleGoogleCredential]),googleClientId?jsx32("div",{ref:parentRef}):null}function getGoogleClientId(clientId){if(clientId)return clientId;if(typeof window<"u"){let origin=window.location.protocol+"//"+window.location.host;if(("undefined"?.split(",")??[]).includes(origin))return"__GOOGLE_CLIENT_ID__"}}import{Alert as Alert2}from"@mantine/core";import{operationOutcomeIssueToString}from"@medplum/core";import{jsx as jsx33}from"react/jsx-runtime";function OperationOutcomeAlert(props){let issues=props.outcome?.issue||props.issues;return!issues||issues.length===0?null:jsx33(Alert2,{icon:jsx33(IconAlertCircle,{size:16}),color:"red",children:issues.map(issue=>jsx33("div",{"data-testid":"text-field-error",children:operationOutcomeIssueToString(issue)},issue.details?.text))})}function initRecaptcha(siteKey){typeof grecaptcha>"u"&&createScriptTag("https://www.google.com/recaptcha/api.js?render="+siteKey)}function getRecaptcha(siteKey){return new Promise((resolve,reject)=>{grecaptcha.ready(async()=>{try{resolve(await grecaptcha.execute(siteKey,{action:"submit"}))}catch(err){reject(err)}})})}import{Fragment as Fragment10,jsx as jsx34,jsxs as jsxs17}from"react/jsx-runtime";function NewUserForm(props){let googleClientId=getGoogleClientId(props.googleClientId),recaptchaSiteKey=props.recaptchaSiteKey,medplum=useMedplum8(),[outcome,setOutcome]=useState14(),issues=getIssuesForExpression(outcome,void 0);return useEffect5(()=>{recaptchaSiteKey&&initRecaptcha(recaptchaSiteKey)},[recaptchaSiteKey]),jsxs17(Form,{onSubmit:async formData=>{try{let recaptchaToken="";recaptchaSiteKey&&(recaptchaToken=await getRecaptcha(recaptchaSiteKey)),props.handleAuthResponse(await medplum.startNewUser({projectId:props.projectId,clientId:props.clientId,firstName:formData.firstName,lastName:formData.lastName,email:formData.email,password:formData.password,remember:formData.remember==="true",recaptchaSiteKey,recaptchaToken}))}catch(err){setOutcome(normalizeOperationOutcome3(err))}},children:[jsx34(Center3,{style:{flexDirection:"column"},children:props.children}),jsx34(OperationOutcomeAlert,{issues}),googleClientId&&jsxs17(Fragment10,{children:[jsx34(Group9,{justify:"center",p:"xl",style:{height:70},children:jsx34(GoogleButton,{googleClientId,handleGoogleCredential:async response=>{try{props.handleAuthResponse(await medplum.startGoogleLogin({googleClientId:response.clientId,googleCredential:response.credential,projectId:props.projectId,createUser:!0}))}catch(err){setOutcome(normalizeOperationOutcome3(err))}}})}),jsx34(Divider,{label:"or",labelPosition:"center",my:"lg"})]}),jsxs17(Stack4,{gap:"xl",children:[jsx34(TextInput5,{name:"firstName",type:"text",label:"First name",placeholder:"First name",required:!0,autoFocus:!0,error:getErrorsForInput(outcome,"firstName")}),jsx34(TextInput5,{name:"lastName",type:"text",label:"Last name",placeholder:"Last name",required:!0,error:getErrorsForInput(outcome,"lastName")}),jsx34(TextInput5,{name:"email",type:"email",label:"Email",placeholder:"name@domain.com",required:!0,error:getErrorsForInput(outcome,"email")}),jsx34(PasswordInput,{name:"password",label:"Password",autoComplete:"off",required:!0,error:getErrorsForInput(outcome,"password")}),jsxs17(Text7,{c:"dimmed",size:"xs",children:["By clicking submit you agree to the Medplum"," ",jsx34(Anchor4,{href:"https://www.medplum.com/privacy",children:"Privacy\xA0Policy"})," and ",jsx34(Anchor4,{href:"https://www.medplum.com/terms",children:"Terms\xA0of\xA0Service"}),"."]}),jsxs17(Text7,{c:"dimmed",size:"xs",children:["This site is protected by reCAPTCHA and the Google"," ",jsx34(Anchor4,{href:"https://policies.google.com/privacy",children:"Privacy\xA0Policy"})," and ",jsx34(Anchor4,{href:"https://policies.google.com/terms",children:"Terms\xA0of\xA0Service"})," apply."]})]}),jsxs17(Group9,{justify:"space-between",mt:"xl",wrap:"nowrap",children:[jsx34(Checkbox,{name:"remember",label:"Remember me",size:"xs"}),jsx34(Button5,{type:"submit",children:"Create account"})]})]})}import{jsx as jsx35,jsxs as jsxs18}from"react/jsx-runtime";function RegisterForm(props){let{type,projectId,clientId,googleClientId,recaptchaSiteKey,onSuccess}=props,medplum=useMedplum9(),[login,setLogin]=useState15(),[outcome,setOutcome]=useState15();useEffect6(()=>{type==="patient"&&login&&medplum.startNewPatient({login,projectId}).then(response=>medplum.processCode(response.code)).then(()=>onSuccess()).catch(err=>setOutcome(normalizeOperationOutcome4(err)))},[medplum,type,projectId,login,onSuccess]);function handleAuthResponse(response){response.code?medplum.processCode(response.code).then(()=>onSuccess()).catch(console.log):response.login&&setLogin(response.login)}return jsxs18(Document,{width:450,children:[outcome&&jsx35("pre",{children:JSON.stringify(outcome,null,2)}),!login&&jsx35(NewUserForm,{projectId,clientId,googleClientId,recaptchaSiteKey,handleAuthResponse,children:props.children}),login&&type==="project"&&jsx35(NewProjectForm,{login,handleAuthResponse})]})}import{showNotification as showNotification4}from"@mantine/notifications";import{normalizeErrorString as normalizeErrorString5}from"@medplum/core";import{useMedplum as useMedplum13}from"@medplum/react-hooks";import{useCallback as useCallback6,useEffect as useEffect7,useRef as useRef7,useState as useState19}from"react";import{Anchor as Anchor5,Button as Button6,Center as Center4,Checkbox as Checkbox2,Divider as Divider2,Group as Group10,PasswordInput as PasswordInput2,Stack as Stack5,TextInput as TextInput6}from"@mantine/core";import{normalizeOperationOutcome as normalizeOperationOutcome5}from"@medplum/core";import{useMedplum as useMedplum10}from"@medplum/react-hooks";import{useCallback as useCallback5,useState as useState16}from"react";import{Fragment as Fragment11,jsx as jsx36,jsxs as jsxs19}from"react/jsx-runtime";function AuthenticationForm(props){let[email,setEmail]=useState16();return email?jsx36(PasswordForm,{email,...props}):jsx36(EmailForm,{setEmail,...props})}function EmailForm(props){let{setEmail,onRegister,handleAuthResponse,children,disableEmailAuth,...baseLoginRequest}=props,medplum=useMedplum10(),googleClientId=!props.disableGoogleAuth&&getGoogleClientId(props.googleClientId),[outcome,setOutcome]=useState16(),issues=getIssuesForExpression(outcome,void 0),isExternalAuth=useCallback5(async authMethod=>{if(!authMethod.authorizeUrl)return!1;let state=JSON.stringify({...await medplum.ensureCodeChallenge(baseLoginRequest),domain:authMethod.domain}),url=new URL(authMethod.authorizeUrl);return url.searchParams.set("state",state),window.location.assign(url.toString()),!0},[medplum,baseLoginRequest]),handleSubmit=useCallback5(async formData=>{let authMethod=await medplum.post("auth/method",{email:formData.email});await isExternalAuth(authMethod)||setEmail(formData.email)},[medplum,isExternalAuth,setEmail]),handleGoogleCredential=useCallback5(async response=>{try{let authResponse=await medplum.startGoogleLogin({...baseLoginRequest,googleCredential:response.credential});await isExternalAuth(authResponse)||handleAuthResponse(authResponse)}catch(err){setOutcome(normalizeOperationOutcome5(err))}},[medplum,baseLoginRequest,isExternalAuth,handleAuthResponse]);return jsxs19(Form,{onSubmit:handleSubmit,children:[jsx36(Center4,{style:{flexDirection:"column"},children}),jsx36(OperationOutcomeAlert,{issues}),googleClientId&&jsxs19(Fragment11,{children:[jsx36(Group10,{justify:"center",p:"xl",style:{height:70},children:jsx36(GoogleButton,{googleClientId,handleGoogleCredential})}),!disableEmailAuth&&jsx36(Divider2,{label:"or",labelPosition:"center",my:"lg"})]}),!disableEmailAuth&&jsx36(TextInput6,{name:"email",type:"email",label:"Email",placeholder:"name@domain.com",required:!0,autoFocus:!0,error:getErrorsForInput(outcome,"email")}),jsxs19(Group10,{justify:"space-between",mt:"xl",gap:0,wrap:"nowrap",children:[jsx36("div",{children:onRegister&&jsx36(Anchor5,{component:"button",type:"button",color:"dimmed",onClick:onRegister,size:"xs",children:"Register"})}),!disableEmailAuth&&jsx36(Button6,{type:"submit",children:"Next"})]})]})}function PasswordForm(props){let{onForgotPassword,handleAuthResponse,children,...baseLoginRequest}=props,medplum=useMedplum10(),[outcome,setOutcome]=useState16(),issues=getIssuesForExpression(outcome,void 0),handleSubmit=useCallback5(formData=>{medplum.startLogin({...baseLoginRequest,password:formData.password,remember:formData.remember==="on"}).then(handleAuthResponse).catch(err=>setOutcome(normalizeOperationOutcome5(err)))},[medplum,baseLoginRequest,handleAuthResponse]);return jsxs19(Form,{onSubmit:handleSubmit,children:[jsx36(Center4,{style:{flexDirection:"column"},children}),jsx36(OperationOutcomeAlert,{issues}),jsx36(Stack5,{gap:"xl",children:jsx36(PasswordInput2,{name:"password",label:"Password",autoComplete:"off",required:!0,autoFocus:!0,error:getErrorsForInput(outcome,"password")})}),jsxs19(Group10,{justify:"space-between",mt:"xl",gap:0,wrap:"nowrap",children:[onForgotPassword&&jsx36(Anchor5,{component:"button",type:"button",c:"dimmed",onClick:onForgotPassword,size:"xs",children:"Forgot password"}),jsx36(Checkbox2,{id:"remember",name:"remember",label:"Remember me",size:"xs",style:{lineHeight:1}}),jsx36(Button6,{type:"submit",children:"Sign in"})]})]})}import{Avatar as Avatar3,Combobox as Combobox2,Flex,Group as Group11,Stack as Stack6,Text as Text8,TextInput as TextInput7,Title as Title2,useCombobox as useCombobox2}from"@mantine/core";import{normalizeOperationOutcome as normalizeOperationOutcome6}from"@medplum/core";import{useMedplum as useMedplum11}from"@medplum/react-hooks";import{useState as useState17}from"react";import{jsx as jsx37,jsxs as jsxs20}from"react/jsx-runtime";function ChooseProfileForm(props){let medplum=useMedplum11(),combobox=useCombobox2(),[search,setSearch]=useState17(""),[outcome,setOutcome]=useState17();function filterDisplay(display){return!!display?.toLowerCase()?.includes(search.toLowerCase())}function filterMembership(membership){return filterDisplay(membership.profile?.display)||filterDisplay(membership.project?.display)}function handleValueSelect(membershipId){medplum.post("auth/profile",{login:props.login,profile:membershipId}).then(props.handleAuthResponse).catch(err=>setOutcome(normalizeOperationOutcome6(err)))}let options=props.memberships.filter(filterMembership).slice(0,10).map(item=>jsx37(Combobox2.Option,{value:item.id,children:jsx37(SelectOption,{...item})},item.id));return jsxs20(Stack6,{children:[jsxs20(Flex,{gap:"md",mb:"md",justify:"center",align:"center",direction:"column",wrap:"nowrap",children:[jsx37(Logo,{size:32}),jsx37(Title2,{order:3,children:"Choose profile"})]}),jsx37(OperationOutcomeAlert,{outcome}),jsxs20(Combobox2,{store:combobox,onOptionSubmit:handleValueSelect,children:[jsx37(Combobox2.EventsTarget,{children:jsx37(TextInput7,{placeholder:"Search",value:search,onChange:event=>{setSearch(event.currentTarget.value),combobox.updateSelectedOptionIndex()}})}),jsx37("div",{children:jsx37(Combobox2.Options,{children:options.length>0?options:jsx37(Combobox2.Empty,{children:"Nothing found..."})})})]})]})}function SelectOption(membership){return jsxs20(Group11,{children:[jsx37(Avatar3,{radius:"xl"}),jsxs20("div",{children:[jsx37(Text8,{fz:"sm",fw:500,children:membership.profile?.display}),jsx37(Text8,{fz:"xs",opacity:.6,children:membership.project?.display})]})]})}import{Button as Button7,Center as Center5,Checkbox as Checkbox3,Group as Group12,Stack as Stack7,Title as Title3}from"@mantine/core";import{useMedplum as useMedplum12}from"@medplum/react-hooks";import{Fragment as Fragment12,jsx as jsx38,jsxs as jsxs21}from"react/jsx-runtime";var openConditionScope=/^patient\/Condition\.(?:\*|c?r?u?d?s?)$/,encounterDiagnosis="?category=http://terminology.hl7.org/CodeSystem/condition-category|encounter-diagnosis",problemListItem="?category=http://terminology.hl7.org/CodeSystem/condition-category|problem-list-item",healthConcern="?category=http://hl7.org/fhir/us/core/CodeSystem/condition-category|health-concern",openObservationScope=/^patient\/Observation\.(?:\*|c?r?u?d?s?)$/,clinicalTest="?category=http://hl7.org/fhir/us/core/CodeSystem/us-core-observation-category|clinical-test",laboratory="?category=http://terminology.hl7.org/CodeSystem/observation-category|laboratory",socialHistory="?category=http://terminology.hl7.org/CodeSystem/observation-category|social-history",sdoh="?category=http://hl7.org/fhir/us/core/CodeSystem/us-core-category|sdoh",survey="?category=http://terminology.hl7.org/CodeSystem/observation-category|survey",vitalSigns="?category=http://terminology.hl7.org/CodeSystem/observation-category|vital-signs";function ChooseScopeForm(props){let medplum=useMedplum12();return jsx38(Form,{onSubmit:formData=>{medplum.post("auth/scope",{login:props.login,scope:Object.keys(formData).join(" ")}).then(props.handleAuthResponse).catch(console.log)},children:jsxs21(Stack7,{children:[jsxs21(Center5,{style:{flexDirection:"column"},children:[jsx38(Logo,{size:32}),jsx38(Title3,{children:"Choose scope"})]}),jsx38(Stack7,{children:(props.scope??"openid").split(" ").map(scopeName=>{let additionalScopes;return openConditionScope.test(scopeName)?additionalScopes=[scopeName+encounterDiagnosis,scopeName+problemListItem,scopeName+healthConcern]:openObservationScope.test(scopeName)&&(additionalScopes=[scopeName+clinicalTest,scopeName+laboratory,scopeName+socialHistory,scopeName+sdoh,scopeName+survey,scopeName+vitalSigns]),jsxs21(Fragment12,{children:[jsx38(Checkbox3,{id:scopeName,name:scopeName,label:scopeName,defaultChecked:!0},scopeName),additionalScopes?.map(scope=>jsx38(Checkbox3,{id:scope,name:scope,label:scope},scope))]})})}),jsx38(Group12,{justify:"flex-end",mt:"xl",children:jsx38(Button7,{type:"submit",children:"Set scope"})})]})})}import{Alert as Alert3,Button as Button8,Center as Center6,Group as Group13,Stack as Stack8,TextInput as TextInput8,Title as Title4}from"@mantine/core";import{normalizeErrorString as normalizeErrorString4}from"@medplum/core";import{useState as useState18}from"react";import{jsx as jsx39,jsxs as jsxs22}from"react/jsx-runtime";function MfaForm(props){let[errorMessage,setErrorMessage]=useState18();return jsx39(Form,{onSubmit:formData=>{setErrorMessage(void 0),props.onSubmit(formData).catch(err=>setErrorMessage(normalizeErrorString4(err)))},children:jsxs22(Stack8,{children:[jsxs22(Center6,{style:{flexDirection:"column"},children:[jsx39(Logo,{size:32}),jsx39(Title4,{children:"Enter MFA code"})]}),errorMessage&&jsx39(Alert3,{icon:jsx39(IconAlertCircle,{size:16}),title:"Error",color:"red",children:errorMessage}),jsx39(Stack8,{children:jsx39(TextInput8,{name:"token",label:"MFA code",required:!0,autoFocus:!0})}),jsx39(Group13,{justify:"flex-end",mt:"xl",children:jsx39(Button8,{type:"submit",children:"Submit code"})})]})})}import{jsx as jsx40}from"react/jsx-runtime";function SignInForm(props){let{login:loginCode,chooseScopes,onSuccess,onForgotPassword,onRegister,onCode,...baseLoginRequest}=props,medplum=useMedplum13(),[login,setLogin]=useState19(),loginRequested=useRef7(!1),[mfaRequired,setAuthenticatorRequired]=useState19(!1),[memberships,setMemberships]=useState19(),handleCode=useCallback6(code=>{onCode?onCode(code):medplum.processCode(code).then(()=>{onSuccess&&onSuccess()}).catch(err=>showNotification4({color:"red",message:normalizeErrorString5(err)}))},[medplum,onCode,onSuccess]),handleAuthResponse=useCallback6(response=>{setAuthenticatorRequired(!!response.mfaRequired),response.login&&setLogin(response.login),response.memberships&&setMemberships(response.memberships),response.code&&(chooseScopes?setMemberships(void 0):handleCode(response.code))},[chooseScopes,handleCode]),handleScopeResponse=useCallback6(response=>{handleCode(response.code)},[handleCode]);return useEffect7(()=>{loginCode&&!loginRequested.current&&!login&&(loginRequested.current=!0,medplum.get("auth/login/"+loginCode).then(handleAuthResponse).catch(err=>showNotification4({color:"red",message:normalizeErrorString5(err)})))},[medplum,loginCode,loginRequested,login,handleAuthResponse]),jsx40(Document,{width:450,px:"sm",py:"md",children:login?mfaRequired?jsx40(MfaForm,{onSubmit:async fields=>{let res=await medplum.post("auth/mfa/verify",{login,token:fields.token});handleAuthResponse(res)}}):memberships?jsx40(ChooseProfileForm,{login,memberships,handleAuthResponse}):props.projectId==="new"?jsx40(NewProjectForm,{login,handleAuthResponse}):props.chooseScopes?jsx40(ChooseScopeForm,{login,scope:props.scope,handleAuthResponse:handleScopeResponse}):jsx40("div",{children:"Success"}):jsx40(AuthenticationForm,{onForgotPassword,onRegister,handleAuthResponse,disableGoogleAuth:props.disableGoogleAuth,disableEmailAuth:props.disableEmailAuth,...baseLoginRequest,children:props.children})})}import{buildElementsContext as buildElementsContext2,getPathDisplayName as getPathDisplayName3,isEmpty as isEmpty2,tryGetDataType}from"@medplum/core";import{ActionIcon as ActionIcon2,Box,CopyButton,Tooltip}from"@mantine/core";import{PropertyType,formatDateTime,formatPeriod,formatTiming,isEmpty}from"@medplum/core";import{formatCodeableConcept}from"@medplum/core";import{Fragment as Fragment13,jsx as jsx41}from"react/jsx-runtime";function CodeableConceptDisplay(props){return jsx41(Fragment13,{children:formatCodeableConcept(props.value)})}import{formatCoding}from"@medplum/core";import{Fragment as Fragment14,jsx as jsx42}from"react/jsx-runtime";function CodingDisplay(props){return jsx42(Fragment14,{children:formatCoding(props.value)})}import{Fragment as Fragment15,jsx as jsx43}from"react/jsx-runtime";function ContactPointDisplay(props){let contactPoint=props.value;if(!contactPoint)return null;let builder=[];return contactPoint.value&&builder.push(contactPoint.value),(contactPoint.use||contactPoint.system)&&(builder.push(" ["),contactPoint.use&&builder.push(contactPoint.use),contactPoint.use&&contactPoint.system&&builder.push(" "),contactPoint.system&&builder.push(contactPoint.system),builder.push("]")),jsx43(Fragment15,{children:builder.join("").trim()})}import{Fragment as Fragment16,jsx as jsx44,jsxs as jsxs23}from"react/jsx-runtime";function ContactDetailDisplay(props){let contactDetail=props.value;return contactDetail?jsxs23(Fragment16,{children:[contactDetail.name,contactDetail.name&&": ",contactDetail.telecom?.map(telecom=>jsx44(ContactPointDisplay,{value:telecom},`telecom-${contactDetail.name}-${telecom.value}`))]}):null}import{jsxs as jsxs24}from"react/jsx-runtime";function IdentifierDisplay(props){return jsxs24("div",{children:[props.value?.system,": ",props.value?.value]})}import{formatMoney}from"@medplum/core";import{Fragment as Fragment17,jsx as jsx45}from"react/jsx-runtime";function MoneyDisplay(props){return jsx45(Fragment17,{children:formatMoney(props.value)})}import{formatQuantity}from"@medplum/core";import{Fragment as Fragment18,jsx as jsx46}from"react/jsx-runtime";function QuantityDisplay(props){return jsx46(Fragment18,{children:formatQuantity(props.value)})}import{formatRange}from"@medplum/core";import{Fragment as Fragment19,jsx as jsx47}from"react/jsx-runtime";function RangeDisplay(props){return jsx47(Fragment19,{children:formatRange(props.value)})}import{Fragment as Fragment20,jsx as jsx48,jsxs as jsxs25}from"react/jsx-runtime";function RatioDisplay(props){let value=props.value;return value?jsxs25(Fragment20,{children:[jsx48(QuantityDisplay,{value:value.numerator}),"\xA0/\xA0",jsx48(QuantityDisplay,{value:value.denominator})]}):null}import{stringify}from"@medplum/core";import{Fragment as Fragment21,jsx as jsx49}from"react/jsx-runtime";function ReferenceDisplay(props){if(!props.value)return null;let displayString=props.value.display||props.value.reference||stringify(props.value);return props.link!==!1&&props.value.reference?jsx49(MedplumLink,{to:props.value,children:displayString}):jsx49(Fragment21,{children:displayString})}import{getPathDisplayName as getPathDisplayName2,isPopulated as isPopulated5}from"@medplum/core";import{useState as useState20,useContext as useContext3,useEffect as useEffect8,useMemo as useMemo4}from"react";import{getValueSliceName,isPopulated as isPopulated3,isSliceDefinitionWithTypes,tryGetProfile}from"@medplum/core";function assignValuesIntoSlices(values,slices,slicing,profileUrl){if(!isPopulated3(slicing?.slices))return[values];let slicedValues=new Array(slices.length+1);for(let i=0;i<slicedValues.length;i++)slicedValues[i]=[];for(let value of values){let sliceName=getValueSliceName(value,slices,slicing.discriminator,profileUrl),sliceIndex=sliceName?slices.findIndex(slice=>slice.name===sliceName):-1;sliceIndex===-1&&(sliceIndex=slices.length),slicedValues[sliceIndex].push(value)}return slicedValues}async function prepareSlices({medplum,property}){return new Promise((resolve,reject)=>{if(!property.slicing){resolve([]);return}let supportedSlices=[],profileUrls=[],promises=[];for(let slice of property.slicing.slices){if(!isSliceDefinitionWithTypes(slice)){console.debug("Unsupported slice definition",slice);continue}let profileUrl;isPopulated3(slice.elements)||(profileUrl=slice.type[0]?.profile?.[0]),supportedSlices.push(slice),profileUrls.push(profileUrl),profileUrl&&promises.push(medplum.requestProfileSchema(profileUrl))}Promise.all(promises).then(()=>{for(let i=0;i<supportedSlices.length;i++){let slice=supportedSlices[i],profileUrl=profileUrls[i];if(profileUrl){let typeSchema=tryGetProfile(profileUrl);slice.typeSchema=typeSchema}}resolve(supportedSlices)}).catch(reject)})}import{useMedplum as useMedplum14}from"@medplum/react-hooks";import{buildElementsContext,isPopulated as isPopulated4}from"@medplum/core";import{useContext as useContext2,useMemo as useMemo3}from"react";import{jsx as jsx50}from"react/jsx-runtime";function maybeWrapWithContext(ContextProvider,contextValue,contents){return contextValue!==void 0?jsx50(ContextProvider,{value:contextValue,children:contents}):contents}import{Fragment as Fragment22,jsx as jsx51}from"react/jsx-runtime";function SliceDisplay(props){let{slice,property}=props,sliceElements=slice.typeSchema?.elements??slice.elements,parentContext=useContext2(ElementsContext),contextValue=useMemo3(()=>{if(isPopulated4(sliceElements))return buildElementsContext({parentContext,elements:sliceElements,path:props.path,profileUrl:slice.typeSchema?.url})},[parentContext,props.path,slice.typeSchema?.url,sliceElements]);return maybeWrapWithContext(ElementsContext.Provider,contextValue,jsx51(Fragment22,{children:props.value.map((value,valueIndex)=>jsx51("div",{children:jsx51(ResourcePropertyDisplay,{property,path:props.path,arrayElement:!0,elementDefinitionType:slice.type[0],propertyType:slice.type[0].code,value,ignoreMissingValues:props.ignoreMissingValues,link:props.link})},`${valueIndex}-${props.value.length}`))}))}import{Fragment as Fragment23,jsx as jsx52,jsxs as jsxs26}from"react/jsx-runtime";function ResourceArrayDisplay(props){let{property,propertyType}=props,medplum=useMedplum14(),values=useMemo4(()=>Array.isArray(props.values)?props.values:[],[props.values]),[loading,setLoading]=useState20(!0),[slices,setSlices]=useState20([]),[slicedValues,setSlicedValues]=useState20(()=>[values]),ctx=useContext3(ElementsContext);if(useEffect8(()=>{prepareSlices({medplum,property}).then(slices2=>{setSlices(slices2);let slicedValues2=assignValuesIntoSlices(values,slices2,property.slicing,ctx.profileUrl);setSlicedValues(slicedValues2),setLoading(!1)}).catch(reason=>{console.error(reason),setLoading(!1)})},[medplum,property,ctx.profileUrl,setSlicedValues,values]),loading)return jsx52("div",{children:"Loading..."});let nonSliceContent;if(property.type[0]?.code!=="Extension"){let nonSliceValues=slicedValues[slices.length],nonSliceElements=nonSliceValues.map((value,valueIndex)=>jsx52("div",{children:jsx52(ResourcePropertyDisplay,{path:props.path,arrayElement:!0,property,propertyType,value,ignoreMissingValues:props.ignoreMissingValues,link:props.link})},`${valueIndex}-${nonSliceValues.length}`));if(props.includeDescriptionListEntry){if(!isPopulated5(props.path))throw new Error("props.path is required when includeDescriptionListEntry is true");let key=props.path.split(".").pop();nonSliceContent=jsx52(DescriptionListEntry,{term:getPathDisplayName2(key),children:nonSliceElements})}else nonSliceContent=jsx52(Fragment23,{children:nonSliceElements})}return jsxs26(Fragment23,{children:[slices.map((slice,sliceIndex)=>{if(!props.path)throw Error(`Displaying a resource property with slices of type ${props.propertyType} requires path`);let sliceDisplay=jsx52(SliceDisplay,{path:props.path,slice,property,value:slicedValues[sliceIndex],ignoreMissingValues:props.ignoreMissingValues,link:props.link},slice.name);return props.includeDescriptionListEntry&&(sliceDisplay=jsx52(DescriptionListEntry,{term:getPathDisplayName2(slice.name),children:sliceDisplay},slice.name)),sliceDisplay}),nonSliceContent]})}import{getDataType,isPopulated as isPopulated6,isProfileLoaded,tryGetProfile as tryGetProfile2}from"@medplum/core";import{useMedplum as useMedplum15}from"@medplum/react-hooks";import{useContext as useContext4,useEffect as useEffect9,useMemo as useMemo5,useState as useState21}from"react";import{getTypedPropertyValue,getTypedPropertyValueWithSchema}from"@medplum/core";function getValueAndType(context,path,profileUrl){let typedResult=getTypedPropertyValue(context,path,{profileUrl});return typedResult?Array.isArray(typedResult)?[typedResult.map(e=>e.value),typedResult[0].type]:[typedResult.value,typedResult.type]:[void 0,"undefined"]}function getValueAndTypeFromElement(typedValue,path,element){let typedResult=getTypedPropertyValueWithSchema(typedValue,path,element);return typedResult?Array.isArray(typedResult)?[typedResult.map(e=>e.value),typedResult[0].type]:[typedResult.value,typedResult.type]:[void 0,"undefined"]}import{jsx as jsx53}from"react/jsx-runtime";function ExtensionDisplay(props){let{elementDefinitionType}=props,medplum=useMedplum15(),ctx=useContext4(ElementsContext),[typeSchema,setTypeSchema]=useState21(getDataType("Extension")),profileUrl=useMemo5(()=>{if(isPopulated6(elementDefinitionType?.profile))return elementDefinitionType.profile[0]},[elementDefinitionType]),[loadingProfile,setLoadingProfile]=useState21(profileUrl!==void 0);if(useEffect9(()=>{profileUrl&&(setLoadingProfile(!0),medplum.requestProfileSchema(profileUrl).then(()=>{let profile=tryGetProfile2(profileUrl);setLoadingProfile(!1),profile&&setTypeSchema(profile)}).catch(reason=>{setLoadingProfile(!1),console.warn(reason)}))},[medplum,profileUrl]),profileUrl&&(loadingProfile||!isProfileLoaded(profileUrl)))return jsx53("div",{children:"Loading..."});if(typeSchema.elements["value[x]"]?.max!==0){let[propertyValue,propertyType]=getValueAndType({type:"Extension",value:props.value},"value[x]",profileUrl??ctx.profileUrl);return jsx53(ResourcePropertyDisplay,{propertyType,value:propertyValue})}return jsx53(BackboneElementDisplay,{path:props.path,value:{type:typeSchema.type,value:props.value},compact:props.compact,ignoreMissingValues:props.ignoreMissingValues,link:props.link,profileUrl})}import{Fragment as Fragment24,jsx as jsx54,jsxs as jsxs27}from"react/jsx-runtime";function ResourcePropertyDisplay(props){let{property,propertyType,value}=props;if(property?.path?.endsWith(".id"))return jsxs27(Box,{component:"div",style:{display:"flex",gap:3,alignItems:"center"},children:[value,!isEmpty(value)&&jsx54(CopyButton,{value,timeout:2e3,children:({copied,copy})=>jsx54(Tooltip,{label:copied?"Copied":"Copy",withArrow:!0,position:"right",children:jsx54(ActionIcon2,{variant:"subtle",color:copied?"teal":"gray",onClick:copy,children:copied?jsx54(IconCheck,{size:"1rem"}):jsx54(IconCopy,{size:"1rem"})})})})]});if(property&&(property.isArray||property.max>1)&&!props.arrayElement)return propertyType===PropertyType.Attachment?jsx54(AttachmentArrayDisplay,{values:value,maxWidth:props.maxWidth,includeDescriptionListEntry:props.includeArrayDescriptionListEntry,property,path:props.path}):jsx54(ResourceArrayDisplay,{path:props.path,property,propertyType,values:value,includeDescriptionListEntry:props.includeArrayDescriptionListEntry,ignoreMissingValues:props.ignoreMissingValues,link:props.link});switch(propertyType){case PropertyType.boolean:return jsx54(Fragment24,{children:value===void 0?"":(!!value).toString()});case PropertyType.SystemString:case PropertyType.string:return jsx54("div",{style:{whiteSpace:"pre-wrap"},children:value});case PropertyType.code:case PropertyType.date:case PropertyType.decimal:case PropertyType.id:case PropertyType.integer:case PropertyType.positiveInt:case PropertyType.unsignedInt:case PropertyType.uri:case PropertyType.url:return jsx54(Fragment24,{children:value});case PropertyType.canonical:return jsx54(ReferenceDisplay,{value:{reference:value},link:props.link});case PropertyType.dateTime:case PropertyType.instant:return jsx54(Fragment24,{children:formatDateTime(value)});case PropertyType.markdown:return jsx54("pre",{children:value});case PropertyType.Address:return jsx54(AddressDisplay,{value});case PropertyType.Annotation:return jsx54(Fragment24,{children:value?.text});case PropertyType.Attachment:return jsx54(AttachmentDisplay,{value,maxWidth:props.maxWidth});case PropertyType.CodeableConcept:return jsx54(CodeableConceptDisplay,{value});case PropertyType.Coding:return jsx54(CodingDisplay,{value});case PropertyType.ContactDetail:return jsx54(ContactDetailDisplay,{value});case PropertyType.ContactPoint:return jsx54(ContactPointDisplay,{value});case PropertyType.HumanName:return jsx54(HumanNameDisplay,{value});case PropertyType.Identifier:return jsx54(IdentifierDisplay,{value});case PropertyType.Money:return jsx54(MoneyDisplay,{value});case PropertyType.Period:return jsx54(Fragment24,{children:formatPeriod(value)});case PropertyType.Quantity:case PropertyType.Duration:return jsx54(QuantityDisplay,{value});case PropertyType.Range:return jsx54(RangeDisplay,{value});case PropertyType.Ratio:return jsx54(RatioDisplay,{value});case PropertyType.Reference:return jsx54(ReferenceDisplay,{value,link:props.link});case PropertyType.Timing:return jsx54(Fragment24,{children:formatTiming(value)});case PropertyType.Dosage:case PropertyType.UsageContext:if(!props.path)throw Error(`Displaying property of type ${props.propertyType} requires path`);return jsx54(BackboneElementDisplay,{path:props.path,value:{type:propertyType,value},compact:!0,ignoreMissingValues:props.ignoreMissingValues});case PropertyType.Extension:if(!props.path)throw Error(`Displaying property of type ${props.propertyType} requires path`);return jsx54(ExtensionDisplay,{path:props.path,value,compact:!0,ignoreMissingValues:props.ignoreMissingValues,elementDefinitionType:props.elementDefinitionType});default:if(!property)throw Error(`Displaying property of type ${props.propertyType} requires element schema`);if(!props.path)throw Error(`Displaying property of type ${props.propertyType} requires path`);return jsx54(BackboneElementDisplay,{path:props.path,value:{type:property.type[0].code,value},compact:!0,ignoreMissingValues:props.ignoreMissingValues})}}import{useContext as useContext5,useMemo as useMemo6}from"react";import{jsx as jsx55,jsxs as jsxs28}from"react/jsx-runtime";var EXTENSION_KEYS2=["extension","modifierExtension"],IGNORED_PROPERTIES2=DEFAULT_IGNORED_PROPERTIES.filter(prop=>!EXTENSION_KEYS2.includes(prop));function BackboneElementDisplay(props){let typedValue=props.value,{value,type:typeName}=typedValue,parentElementsContext=useContext5(ElementsContext),profileUrl=props.profileUrl??parentElementsContext?.profileUrl,typeSchema=useMemo6(()=>tryGetDataType(typeName,profileUrl),[profileUrl,typeName]),newElementsContext=useMemo6(()=>{if(typeSchema)return buildElementsContext2({parentContext:parentElementsContext,elements:typeSchema.elements,path:props.path,profileUrl:typeSchema.url,accessPolicyResource:props.accessPolicyResource})},[typeSchema,parentElementsContext,props.path,props.accessPolicyResource]);if(isEmpty2(value))return null;if(!typeSchema)return jsxs28("div",{children:[typeName,"\xA0not implemented"]});if(typeof value=="object"&&"name"in value&&Object.keys(value).length===1&&typeof value.name=="string")return jsx55("div",{children:value.name});let elementsContext=newElementsContext??parentElementsContext;return maybeWrapWithContext(ElementsContext.Provider,newElementsContext,jsx55(DescriptionList,{compact:props.compact,children:Object.entries(elementsContext.elements).map(([key,property])=>{if(EXTENSION_KEYS2.includes(key)&&isEmpty2(property.slicing?.slices))return null;if(IGNORED_PROPERTIES2.includes(key))return null;if(DEFAULT_IGNORED_NON_NESTED_PROPERTIES.includes(key)&&property.path.split(".").length===2||key.includes("."))return null;let[propertyValue,propertyType]=getValueAndType(typedValue,key,elementsContext.profileUrl);if((props.ignoreMissingValues||property.max===0)&&isEmpty2(propertyValue)||props.path.endsWith(".extension")&&(key==="url"||key==="id"))return null;let isArrayProperty=property.max>1||property.isArray,resourcePropertyDisplay=jsx55(ResourcePropertyDisplay,{property,propertyType,path:props.path+"."+key,value:propertyValue,ignoreMissingValues:props.ignoreMissingValues,includeArrayDescriptionListEntry:isArrayProperty,link:props.link},key);return isArrayProperty?resourcePropertyDisplay:jsx55(DescriptionListEntry,{term:getPathDisplayName3(key),children:resourcePropertyDisplay},key)})}))}import{buildElementsContext as buildElementsContext4,tryGetDataType as tryGetDataType2}from"@medplum/core";import{useContext as useContext22,useMemo as useMemo22,useState as useState42}from"react";import{Stack as Stack12}from"@mantine/core";import{getPathDisplayName as getPathDisplayName5}from"@medplum/core";import{useContext as useContext21,useMemo as useMemo21,useState as useState41}from"react";import{Group as Group14,Input}from"@mantine/core";import{useContext as useContext6}from"react";import{Tooltip as Tooltip2}from"@mantine/core";import{jsx as jsx56}from"react/jsx-runtime";var READ_ONLY_TOOLTIP_TEXT="Read Only";function maybeWrapWithTooltip(tooltipText,children){return tooltipText?jsx56(Tooltip2.Floating,{label:tooltipText,children}):children}var FormSection_default={dimmed:"FormSection_dimmed",preserveBreaks:"FormSection_preserveBreaks"};import{jsx as jsx57,jsxs as jsxs29}from"react/jsx-runtime";function CheckboxFormSection(props){let{debugMode}=useContext6(ElementsContext),label;return debugMode&&props.fhirPath?label=`${props.title} - ${props.fhirPath}`:label=props.title,maybeWrapWithTooltip(props?.readonly?READ_ONLY_TOOLTIP_TEXT:void 0,jsxs29(Group14,{wrap:"nowrap","data-testid":props.testId,children:[jsx57("div",{children:props.children}),jsx57("div",{children:jsx57(Input.Wrapper,{id:props.htmlFor,label,classNames:{label:props?.readonly?FormSection_default.dimmed:void 0},description:props.description,withAsterisk:props.withAsterisk,children:null})})]}))}import{Input as Input2}from"@mantine/core";import{useContext as useContext7}from"react";import{jsx as jsx58}from"react/jsx-runtime";function FormSection(props){let{debugMode}=useContext7(ElementsContext),label;return debugMode&&props.fhirPath?label=`${props.title} - ${props.fhirPath}`:label=props.title,maybeWrapWithTooltip(props?.readonly?READ_ONLY_TOOLTIP_TEXT:void 0,jsx58(Input2.Wrapper,{id:props.htmlFor,label,classNames:{label:clsx_default({[FormSection_default.dimmed]:props?.readonly},FormSection_default.preserveBreaks)},description:props.description,withAsterisk:props.withAsterisk,error:getErrorsForInput(props.outcome,props.errorExpression??props.htmlFor),"data-testid":props.testId,children:props.children}))}import{capitalize,isEmpty as isEmpty3}from"@medplum/core";function setPropertyValue(obj,key,propName,elementDefinition,value){let types=elementDefinition.type;if(types.length>1)for(let type of types){let compoundKey=key.replace("[x]",capitalize(type.code));compoundKey in obj&&delete obj[compoundKey]}return isEmpty3(value)?obj[propName]=void 0:obj[propName]=value,obj}function isSupportedProfileStructureDefinition(profile){return!!profile&&!isEmpty3(profile.url)&&!isEmpty3(profile.name)}import{Checkbox as Checkbox4,Group as Group28,NativeSelect as NativeSelect9,Textarea as Textarea2,TextInput as TextInput17}from"@mantine/core";import{applyDefaultValuesToElement,capitalize as capitalize2,getPathDifference,HTTP_HL7_ORG,isComplexTypeCode,isEmpty as isEmpty6,isPopulated as isPopulated11,PropertyType as PropertyType2}from"@medplum/core";import{useContext as useContext20,useMemo as useMemo20,useState as useState40}from"react";import{useState as useState22}from"react";import{jsx as jsx59}from"react/jsx-runtime";function CodeableConceptInput(props){let{defaultValue:defaultValue2,onChange,withHelpText,outcome:_outcome,path:_path,valuePath:_valuePath,...rest}=props,[value,setValue]=useState22(defaultValue2);function handleChange(newValues){let newConcept=valueSetElementToCodeableConcept(newValues);setValue(newConcept),onChange&&onChange(newConcept)}return jsx59(ValueSetAutocomplete,{defaultValue:value&&codeableConceptToValueSetElement(value),onChange:handleChange,withHelpText:withHelpText??!0,...rest})}function codeableConceptToValueSetElement(concept){return concept.coding?.map(c=>({system:c.system,code:c.code,display:c.display}))}function valueSetElementToCodeableConcept(elements){if(elements.length!==0)return{coding:elements.map(e=>({system:e.system,code:e.code,display:e.display}))}}import{useState as useState23}from"react";import{jsx as jsx60}from"react/jsx-runtime";function CodingInput(props){let{defaultValue:defaultValue2,onChange,withHelpText,response,...rest}=props,[value,setValue]=useState23(response?.answer?.[0]?.valueCoding??defaultValue2);function handleChange(newValues){let newValue=newValues[0],newConcept=newValue&&valueSetElementToCoding(newValue);setValue(newConcept),onChange&&onChange(newConcept)}return jsx60(ValueSetAutocomplete,{defaultValue:value?codingToValueSetElement(value):void 0,maxValues:1,onChange:handleChange,withHelpText:withHelpText??!0,...rest})}function codingToValueSetElement(coding){return{system:coding.system,code:coding.code,display:coding.display}}function valueSetElementToCoding(element){return{system:element.system,code:element.code,display:element.display}}import{Group as Group16,TextInput as TextInput10}from"@mantine/core";import{useContext as useContext9,useMemo as useMemo8,useRef as useRef9,useState as useState25}from"react";import{Group as Group15,NativeSelect as NativeSelect3,TextInput as TextInput9}from"@mantine/core";import{useContext as useContext8,useMemo as useMemo7,useRef as useRef8,useState as useState24}from"react";import{jsx as jsx61,jsxs as jsxs30}from"react/jsx-runtime";function ContactPointInput(props){let{path,outcome}=props,{elementsByPath,getExtendedProps}=useContext8(ElementsContext),[contactPoint,setContactPoint]=useState24(props.defaultValue),ref=useRef8();ref.current=contactPoint;let[systemElement,useElement,valueElement]=useMemo7(()=>["system","use","value"].map(field=>elementsByPath[path+"."+field]),[elementsByPath,path]),[systemProps,useProps,valueProps]=useMemo7(()=>["system","use","value"].map(field=>getExtendedProps(path+"."+field)),[getExtendedProps,path]);function setContactPointWrapper(newValue){newValue&&Object.keys(newValue).length===0&&(newValue=void 0),setContactPoint(newValue),props.onChange&&props.onChange(newValue)}function setSystem(system){let newValue={...ref.current,system};system||delete newValue.system,setContactPointWrapper(newValue)}function setUse(use){let newValue={...ref.current,use};use||delete newValue.use,setContactPointWrapper(newValue)}function setValue(value){let newValue={...ref.current,value};value||delete newValue.value,setContactPointWrapper(newValue)}let errorPath=props.valuePath??path;return jsxs30(Group15,{gap:"xs",grow:!0,wrap:"nowrap",align:"flex-start",children:[jsx61(NativeSelect3,{disabled:props.disabled||systemProps?.readonly,"data-testid":"system",defaultValue:contactPoint?.system,required:(systemElement?.min??0)>0,onChange:e=>setSystem(e.currentTarget.value),data:["","email","phone","fax","pager","sms","other"],error:getErrorsForInput(outcome,errorPath+".system")}),jsx61(NativeSelect3,{disabled:props.disabled||useProps?.readonly,"data-testid":"use",defaultValue:contactPoint?.use,required:(useElement?.min??0)>0,onChange:e=>setUse(e.currentTarget.value),data:["","home","work","temp","old","mobile"],error:getErrorsForInput(outcome,errorPath+".use")}),jsx61(TextInput9,{disabled:props.disabled||valueProps?.readonly,placeholder:"Value",defaultValue:contactPoint?.value,required:(valueElement?.min??0)>0,onChange:e=>setValue(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".value")})]})}import{jsx as jsx62,jsxs as jsxs31}from"react/jsx-runtime";function ContactDetailInput(props){let[contactPoint,setContactDetail]=useState25(props.defaultValue),ref=useRef9();ref.current=contactPoint;let{getExtendedProps}=useContext9(ElementsContext),[nameProps,telecomProps]=useMemo8(()=>["name","telecom"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setContactDetailWrapper(newValue){setContactDetail(newValue),props.onChange&&props.onChange(newValue)}function setName(name){let newValue={...ref.current,name};name||delete newValue.name,setContactDetailWrapper(newValue)}function setTelecom(telecom){let newValue={...ref.current,telecom:telecom&&[telecom]};telecom||delete newValue.telecom,setContactDetailWrapper(newValue)}return jsxs31(Group16,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx62(TextInput10,{disabled:props.disabled||nameProps?.readonly,"data-testid":props.name+"-name",name:props.name+"-name",placeholder:"Name",style:{width:180},defaultValue:contactPoint?.name,onChange:e=>setName(e.currentTarget.value)}),jsx62(ContactPointInput,{disabled:props.disabled||telecomProps?.readonly,name:props.name+"-telecom",path:props.path+".telecom",defaultValue:contactPoint?.telecom?.[0],onChange:setTelecom,outcome:props.outcome})]})}import{TextInput as TextInput11}from"@mantine/core";import{isValidDate}from"@medplum/core";function convertIsoToLocal(isoString){if(!isoString)return"";let date=new Date(isoString);return isValidDate(date)?date.toLocaleDateString("sv")+"T"+date.toLocaleTimeString("sv"):""}function convertLocalToIso(localString){if(!localString)return"";let date=new Date(localString);return isValidDate(date)?date.toISOString():""}import{jsx as jsx63}from"react/jsx-runtime";function DateTimeInput(props){return jsx63(TextInput11,{id:props.name,name:props.name,label:props.label,"data-autofocus":props.autoFocus,"data-testid":props["data-testid"]??props.name,placeholder:props.placeholder,required:props.required,disabled:props.disabled,type:getInputType(),defaultValue:convertIsoToLocal(props.defaultValue),autoFocus:props.autoFocus,error:getErrorsForInput(props.outcome,props.name),onChange:e=>{if(props.onChange){let newValue=e.currentTarget.value;props.onChange(convertLocalToIso(newValue))}}})}function getInputType(){return"datetime-local"}import{isPopulated as isPopulated7,isProfileLoaded as isProfileLoaded2}from"@medplum/core";import{useMedplum as useMedplum16}from"@medplum/react-hooks";import{useEffect as useEffect10,useMemo as useMemo9,useState as useState26}from"react";import{jsx as jsx64}from"react/jsx-runtime";function ExtensionInput(props){let{propertyType}=props,medplum=useMedplum16(),profileUrl=useMemo9(()=>{if(isPopulated7(propertyType.profile))return propertyType.profile[0]},[propertyType]),[loadingProfile,setLoadingProfile]=useState26(profileUrl!==void 0);return useEffect10(()=>{profileUrl&&(setLoadingProfile(!0),medplum.requestProfileSchema(profileUrl).then(()=>setLoadingProfile(!1)).catch(reason=>{setLoadingProfile(!1),console.warn(reason)}))},[medplum,profileUrl]),profileUrl&&(loadingProfile||!isProfileLoaded2(profileUrl))?jsx64("div",{children:"Loading..."}):jsx64(BackboneElementInput,{profileUrl,path:props.path,typeName:"Extension",defaultValue:props.defaultValue,onChange:props.onChange})}import{Group as Group17,NativeSelect as NativeSelect4,TextInput as TextInput12}from"@mantine/core";import{useContext as useContext10,useMemo as useMemo10,useState as useState27}from"react";import{jsx as jsx65,jsxs as jsxs32}from"react/jsx-runtime";function HumanNameInput(props){let{outcome,path}=props,[value,setValue]=useState27(props.defaultValue),{getExtendedProps}=useContext10(ElementsContext),[useProps,prefixProps,givenProps,familyProps,suffixProps]=useMemo10(()=>["use","prefix","given","family","suffix"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}function setUse(use){setValueWrapper({...value,use:use||void 0})}function setPrefix(prefix){setValueWrapper({...value,prefix:prefix?prefix.split(" "):void 0})}function setGiven(given){setValueWrapper({...value,given:given?given.split(" "):void 0})}function setFamily(family){setValueWrapper({...value,family:family||void 0})}function setSuffix(suffix){setValueWrapper({...value,suffix:suffix?suffix.split(" "):void 0})}let errorPath=props.valuePath??path;return jsxs32(Group17,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx65(NativeSelect4,{disabled:props.disabled||useProps?.readonly,defaultValue:value?.use,name:props.name+"-use","data-testid":"use",onChange:e=>setUse(e.currentTarget.value),data:["","temp","old","usual","official","nickname","anonymous","maiden"],error:getErrorsForInput(outcome,errorPath+".use")}),jsx65(TextInput12,{disabled:props.disabled||prefixProps?.readonly,placeholder:"Prefix",name:props.name+"-prefix",defaultValue:value?.prefix?.join(" "),onChange:e=>setPrefix(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".prefix")}),jsx65(TextInput12,{disabled:props.disabled||givenProps?.readonly,placeholder:"Given",name:props.name+"-given",defaultValue:value?.given?.join(" "),onChange:e=>setGiven(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".given")}),jsx65(TextInput12,{disabled:props.disabled||familyProps?.readonly,name:props.name+"-family",placeholder:"Family",defaultValue:value?.family,onChange:e=>setFamily(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".family")}),jsx65(TextInput12,{disabled:props.disabled||suffixProps?.readonly,placeholder:"Suffix",name:props.name+"-suffix",defaultValue:value?.suffix?.join(" "),onChange:e=>setSuffix(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".suffix")})]})}import{Group as Group18,TextInput as TextInput13}from"@mantine/core";import{useContext as useContext11,useMemo as useMemo11,useState as useState28}from"react";import{jsx as jsx66,jsxs as jsxs33}from"react/jsx-runtime";function IdentifierInput(props){let[value,setValue]=useState28(props.defaultValue),{elementsByPath,getExtendedProps}=useContext11(ElementsContext),[systemElement,valueElement]=useMemo11(()=>["system","value"].map(field=>elementsByPath[props.path+"."+field]),[elementsByPath,props.path]),[systemProps,valueProps]=useMemo11(()=>["system","value"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}let errorPath=props.valuePath??props.path;return jsxs33(Group18,{gap:"xs",grow:!0,wrap:"nowrap",align:"flex-start",children:[jsx66(TextInput13,{disabled:props.disabled||systemProps?.readonly,placeholder:"System",required:(systemElement?.min??0)>0,defaultValue:value?.system,onChange:e=>setValueWrapper({...value,system:e.currentTarget.value}),error:getErrorsForInput(props.outcome,errorPath+".system")}),jsx66(TextInput13,{disabled:props.disabled||valueProps?.readonly,placeholder:"Value",required:(valueElement?.min??0)>0,defaultValue:value?.value,onChange:e=>setValueWrapper({...value,value:e.currentTarget.value}),error:getErrorsForInput(props.outcome,errorPath+".value")})]})}import{NativeSelect as NativeSelect5,TextInput as TextInput14}from"@mantine/core";import{useCallback as useCallback7,useContext as useContext12,useMemo as useMemo12,useState as useState29}from"react";import{jsx as jsx67}from"react/jsx-runtime";var data=["USD","EUR","CAD","GBP","AUD"];function MoneyInput(props){let{onChange}=props,[value,setValue]=useState29(props.defaultValue),{getExtendedProps}=useContext12(ElementsContext),[currencyProps,valueProps]=useMemo12(()=>["currency","value"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]),setValueWrapper=useCallback7(newValue=>{setValue(newValue),onChange&&onChange(newValue)},[onChange]),handleCurrencyChange=useCallback7(e=>{setValueWrapper({...value,currency:e.currentTarget.value})},[value,setValueWrapper]),handleValueChange=useCallback7(e=>{setValueWrapper({...value,value:e.currentTarget.valueAsNumber})},[value,setValueWrapper]),select=jsx67(NativeSelect5,{disabled:props.disabled||currencyProps?.readonly,defaultValue:value?.currency,data,styles:{input:{fontWeight:500,borderTopLeftRadius:0,borderBottomLeftRadius:0,width:92}},onChange:handleCurrencyChange});return jsx67(TextInput14,{disabled:props.disabled||valueProps?.readonly,type:"number",name:props.name,label:props.label,placeholder:props.placeholder??"Value",defaultValue:value?.value?.toString()??"USD",leftSection:jsx67(IconCurrencyDollar,{size:14}),rightSection:select,rightSectionWidth:92,onChange:handleValueChange})}import{Group as Group19}from"@mantine/core";import{useContext as useContext13,useMemo as useMemo13,useState as useState30}from"react";import{jsx as jsx68,jsxs as jsxs34}from"react/jsx-runtime";function PeriodInput(props){let[value,setValue]=useState30(props.defaultValue),{getExtendedProps}=useContext13(ElementsContext),[startProps,endProps]=useMemo13(()=>["start","end"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}return jsxs34(Group19,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx68(DateTimeInput,{disabled:props.disabled||startProps?.readonly,name:props.name+".start",placeholder:"Start",defaultValue:value?.start,onChange:newValue=>setValueWrapper({...value,start:newValue})}),jsx68(DateTimeInput,{disabled:props.disabled||endProps?.readonly,name:props.name+".end",placeholder:"End",defaultValue:value?.end,onChange:newValue=>setValueWrapper({...value,end:newValue})})]})}import{Group as Group20,NativeSelect as NativeSelect6,TextInput as TextInput15}from"@mantine/core";import{useContext as useContext14,useMemo as useMemo14,useState as useState31}from"react";import{jsx as jsx69,jsxs as jsxs35}from"react/jsx-runtime";function QuantityInput(props){let[value,setValue]=useState31(props.defaultValue),{getExtendedProps}=useContext14(ElementsContext),[comparatorProps,valueProps,unitProps]=useMemo14(()=>["comparator","value","unit"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}return jsxs35(Group20,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx69(NativeSelect6,{disabled:props.disabled||comparatorProps?.readonly,style:{width:80},"data-testid":props.name+"-comparator",defaultValue:value?.comparator,data:["","<","<=",">=",">"],onChange:e=>setValueWrapper({...value,comparator:e.currentTarget.value})}),jsx69(TextInput15,{disabled:props.disabled||valueProps?.readonly,id:props.name,name:props.name,required:props.required,"data-autofocus":props.autoFocus,"data-testid":props.name+"-value",type:"number",placeholder:"Value",defaultValue:value?.value,autoFocus:props.autoFocus,step:"any",onWheel:e=>{props.disableWheel&&e.currentTarget.blur()},onChange:e=>{setValueWrapper({...value,value:tryParseNumber(e.currentTarget.value)})}}),jsx69(TextInput15,{disabled:props.disabled||unitProps?.readonly,placeholder:"Unit","data-testid":props.name+"-unit",defaultValue:value?.unit,onChange:e=>setValueWrapper({...value,unit:e.currentTarget.value})})]})}function tryParseNumber(str){if(str)return parseFloat(str)}import{Group as Group21}from"@mantine/core";import{useContext as useContext15,useMemo as useMemo15,useState as useState32}from"react";import{jsx as jsx70,jsxs as jsxs36}from"react/jsx-runtime";function RangeInput(props){let[value,setValue]=useState32(props.defaultValue),{getExtendedProps}=useContext15(ElementsContext),[lowProps,highProps]=useMemo15(()=>["low","high"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}return jsxs36(Group21,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx70(QuantityInput,{path:props.path+".low",disabled:props.disabled||lowProps?.readonly,name:props.name+"-low",defaultValue:value?.low,onChange:v=>setValueWrapper({...value,low:v})}),jsx70(QuantityInput,{path:props.path+".high",disabled:props.disabled||highProps?.readonly,name:props.name+"-high",defaultValue:value?.high,onChange:v=>setValueWrapper({...value,high:v})})]})}import{Group as Group22}from"@mantine/core";import{useContext as useContext16,useMemo as useMemo16,useState as useState33}from"react";import{jsx as jsx71,jsxs as jsxs37}from"react/jsx-runtime";function RatioInput(props){let[value,setValue]=useState33(props.defaultValue),{getExtendedProps}=useContext16(ElementsContext),[numeratorProps,denominatorProps]=useMemo16(()=>["numerator","denominator"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}return jsxs37(Group22,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx71(QuantityInput,{path:props.path+".numerator",disabled:props.disabled||numeratorProps?.readonly,name:props.name+"-numerator",defaultValue:value?.numerator,onChange:v=>setValueWrapper({...value,numerator:v})}),jsx71(QuantityInput,{path:props.path+".denominator",disabled:props.disabled||denominatorProps?.readonly,name:props.name+"-denominator",defaultValue:value?.denominator,onChange:v=>setValueWrapper({...value,denominator:v})})]})}import{Group as Group24,NativeSelect as NativeSelect7}from"@mantine/core";import{LRUCache,ReadablePromise,createReference as createReference2,isEmpty as isEmpty4,isPopulated as isPopulated9,tryGetProfile as tryGetProfile3}from"@medplum/core";import{useMedplum as useMedplum18}from"@medplum/react-hooks";import{useCallback as useCallback9,useEffect as useEffect11,useMemo as useMemo17,useRef as useRef10,useState as useState35}from"react";import{Group as Group23,Text as Text9}from"@mantine/core";import{getDisplayString as getDisplayString3,getReferenceString as getReferenceString3,isPopulated as isPopulated8}from"@medplum/core";import{useMedplum as useMedplum17,useResource as useResource2}from"@medplum/react-hooks";import{forwardRef as forwardRef4,useCallback as useCallback8,useState as useState34}from"react";import{jsx as jsx72,jsxs as jsxs38}from"react/jsx-runtime";var SEARCH_CODES={Device:"device-name",Observation:"code",Subscription:"criteria",User:"email:contains"},NAME_RESOURCE_TYPES=["AccessPolicy","Account","ActivityDefinition","Bot","CapabilityStatement","CareTeam","ClientApplication","CodeSystem","CompartmentDefinition","ConceptMap","EffectEvidenceSynthesis","Endpoint","EventDefinition","Evidence","EvidenceVariable","ExampleScenario","GraphDefinition","Group","HealthcareService","ImplementationGuide","InsurancePlan","Library","Location","Measure","MedicinalProduct","MessageDefinition","NamingSystem","OperationDefinition","Organization","Patient","Person","PlanDefinition","Practitioner","Project","Questionnaire","RelatedPerson","ResearchDefinition","ResearchElementDefinition","ResearchStudy","RiskEvidenceSynthesis","SearchParameter","StructureDefinition","StructureMap","TerminologyCapabilities","TestScript","UserConfiguration","ValueSet"];function toOption3(resource){return{value:getReferenceString3(resource),label:getDisplayString3(resource),resource}}function ResourceInput(props){let medplum=useMedplum17(),{resourceType,searchCriteria}=props,[outcome,setOutcome]=useState34(),defaultValue2=useResource2(props.defaultValue,setOutcome),ItemComponent3=props.itemComponent??DefaultItemComponent2,onChange=props.onChange,loadValues=useCallback8(async(input,signal)=>{let searchCode=getSearchParamForResourceType(resourceType),searchParams=new URLSearchParams({[searchCode]:input??"",_count:"10",...searchCriteria});return await medplum.searchResources(resourceType,searchParams,{signal})},[medplum,resourceType,searchCriteria]),handleChange=useCallback8(newResources=>{onChange&&onChange(newResources[0])},[onChange]);return isPopulated8(props.defaultValue)&&!outcome&&!defaultValue2?null:jsx72(AsyncAutocomplete,{disabled:props.disabled,name:props.name,label:props.label,error:props.error,required:props.required,itemComponent:ItemComponent3,defaultValue:defaultValue2,placeholder:props.placeholder,maxValues:1,toOption:toOption3,loadOptions:loadValues,onChange:handleChange,clearable:!0})}var DefaultItemComponent2=forwardRef4(({label,resource,active:_active,...others},ref)=>jsx72("div",{ref,...others,children:jsxs38(Group23,{wrap:"nowrap",children:[jsx72(ResourceAvatar,{value:resource}),jsxs38("div",{children:[jsx72(Text9,{children:label}),jsx72(Text9,{size:"xs",c:"dimmed",children:resource.birthDate||resource.id})]})]})}));function getSearchParamForResourceType(resourceType){return SEARCH_CODES[resourceType]??(NAME_RESOURCE_TYPES.includes(resourceType)?"name":"_id")}import{jsx as jsx73,jsxs as jsxs39}from"react/jsx-runtime";function ReferenceInput(props){let{onChange}=props,medplum=useMedplum18(),[value,setValue]=useState35(props.defaultValue),[targetTypes,setTargetTypes]=useState35(()=>createTargetTypes(props.targetTypes)),[targetType,setTargetType]=useState35(()=>getInitialTargetType(props.defaultValue,targetTypes)),promiseCache=useRef10(new LRUCache),searchCriteria=useMemo17(()=>targetType?.type==="profile"?{...props.searchCriteria,_profile:targetType.value}:props.searchCriteria,[props.searchCriteria,targetType]);useEffect11(()=>{let anyToFetch=!1,newTargetTypePromises=targetTypes?.map(tt=>{if(!shouldFetchResourceType(tt))return Promise.resolve(tt);anyToFetch=!0;let cacheKey=tt.value,cached=promiseCache.current.get(cacheKey);if(cached)return cached;let promise=fetchResourceTypeOfProfile(medplum,tt.value).then(profile=>{let newTargetType={...tt};return profile?isPopulated9(profile.type)?(newTargetType.resourceType=profile.type,newTargetType.name=profile.name,newTargetType.title=profile.title):(console.error(`StructureDefinition.type missing for ${tt.value}`),newTargetType.error="StructureDefinition.type missing"):(console.error(`StructureDefinition not found for ${tt.value}`),newTargetType.error="StructureDefinition not found"),newTargetType}).catch(reason=>(console.error(reason),{...tt,error:reason})),readablePromise=new ReadablePromise(promise);return promiseCache.current.set(cacheKey,readablePromise),readablePromise});!newTargetTypePromises||!anyToFetch||Promise.all(newTargetTypePromises).then(newTargetTypes=>{if(setTargetTypes(newTargetTypes),!targetType)return;let index=newTargetTypes.findIndex(tt=>tt.value===targetType.value||tt.resourceType===targetType.resourceType);if(index===-1){console.debug(`defaultValue had unexpected resourceType: ${targetType.resourceType}`);return}setTargetType(newTargetTypes[index])}).catch(console.error)},[medplum,targetType,targetTypes]);let setValueHelper=useCallback9(item=>{let newValue=item?createReference2(item):void 0;setValue(newValue),onChange&&onChange(newValue)},[onChange]),typeSelectOptions=useMemo17(()=>targetTypes?targetTypes.map(tt=>({value:tt.value,label:tt.type==="profile"?tt.title??tt.name??tt.resourceType??tt.value:tt.value})):[],[targetTypes]);return jsxs39(Group24,{gap:"xs",grow:!0,wrap:"nowrap",children:[targetTypes&&targetTypes.length>1&&jsx73(NativeSelect7,{disabled:props.disabled,"data-autofocus":props.autoFocus,"data-testid":"reference-input-resource-type-select",defaultValue:targetType?.resourceType,autoFocus:props.autoFocus,onChange:e=>{let newValue=e.currentTarget.value,newTargetType=targetTypes.find(tt=>tt.value===newValue);setTargetType(newTargetType)},data:typeSelectOptions}),!targetTypes&&jsx73(ResourceTypeInput,{disabled:props.disabled,autoFocus:props.autoFocus,testId:"reference-input-resource-type-input",defaultValue:targetType?.resourceType,onChange:newResourceType=>{setTargetType(newResourceType?{type:"resourceType",value:newResourceType,resourceType:newResourceType}:void 0)},name:props.name+"-resourceType",placeholder:"Resource Type"}),jsx73(ResourceInput,{resourceType:targetType?.resourceType,name:props.name+"-id",required:props.required,placeholder:props.placeholder,defaultValue:value,searchCriteria,onChange:setValueHelper,disabled:props.disabled})]})}function createTargetTypes(resourceTypesAndProfileUrls){if(!resourceTypesAndProfileUrls||resourceTypesAndProfileUrls.length===0||resourceTypesAndProfileUrls.length===1&&resourceTypesAndProfileUrls[0]==="Resource")return;let results=[];for(let value of resourceTypesAndProfileUrls)value.includes("/")?results.push({type:"profile",value}):results.push({type:"resourceType",value,resourceType:value});return results}function getInitialTargetType(defaultValue2,targetTypes){let defaultValueResourceType=defaultValue2?.reference?.split("/")[0];if(defaultValueResourceType){let targetType=targetTypes?.find(tt=>tt.resourceType===defaultValueResourceType);return targetType||{type:"resourceType",value:defaultValueResourceType,resourceType:defaultValueResourceType}}if(targetTypes&&targetTypes.length>0)return targetTypes[0]}async function fetchResourceTypeOfProfile(medplum,profileUrl){let profile=tryGetProfile3(profileUrl);if(profile)return{type:profile.type,name:profile.name,title:profile.title};let query=`{
|
|
65
|
+
`)}function getIssuesForExpression(outcome,expression){return outcome?.issue?.filter(issue=>isExpressionMatch(issue.expression?.[0],expression))}var ARRAY_INDEX_REGEX=/\[\d+\]/;function isExpressionMatch(expr1,expr2){let isExpr1Indexed=typeof expr1=="string"&&ARRAY_INDEX_REGEX.test(expr1),isExpr2Indexed=typeof expr2=="string"&&ARRAY_INDEX_REGEX.test(expr2);if(isExpr1Indexed!==isExpr2Indexed&&(expr1=expr1?.replace(ARRAY_INDEX_REGEX,""),expr2=expr2?.replace(ARRAY_INDEX_REGEX,"")),expr1===expr2)return!0;if(!expr1||!expr2)return!1;let dot1=expr1.indexOf(".");if(dot1>=0&&expr1.substring(dot1+1)===expr2)return!0;let dot2=expr2.indexOf(".");return dot2>=0&&expr2.substring(dot2+1)===expr1}import{jsx as jsx31,jsxs as jsxs16}from"react/jsx-runtime";function NewProjectForm(props){let medplum=useMedplum6(),[outcome,setOutcome]=useState12();return jsxs16(Form,{onSubmit:async formData=>{try{props.handleAuthResponse(await medplum.startNewProject({login:props.login,projectName:formData.projectName}))}catch(err){setOutcome(normalizeOperationOutcome2(err))}},children:[jsxs16(Center2,{style:{flexDirection:"column"},children:[jsx31(Logo,{size:32}),jsx31(Title,{children:"Create project"})]}),jsxs16(Stack3,{gap:"xl",children:[jsx31(TextInput4,{name:"projectName",label:"Project Name",placeholder:"My Project",required:!0,autoFocus:!0,error:getErrorsForInput(outcome,"projectName")}),jsxs16(Text6,{c:"dimmed",size:"xs",children:["By clicking submit you agree to the Medplum"," ",jsx31(Anchor3,{href:"https://www.medplum.com/privacy",children:"Privacy\xA0Policy"})," and ",jsx31(Anchor3,{href:"https://www.medplum.com/terms",children:"Terms\xA0of\xA0Service"}),"."]})]}),jsx31(Group8,{justify:"flex-end",mt:"xl",wrap:"nowrap",children:jsx31(Button4,{type:"submit",children:"Create project"})})]})}import{Anchor as Anchor4,Button as Button5,Center as Center3,Checkbox,Divider,Group as Group9,PasswordInput,Stack as Stack4,Text as Text7,TextInput as TextInput5}from"@mantine/core";import{normalizeOperationOutcome as normalizeOperationOutcome3}from"@medplum/core";import{useMedplum as useMedplum8}from"@medplum/react-hooks";import{useEffect as useEffect5,useState as useState14}from"react";import{useMedplum as useMedplum7}from"@medplum/react-hooks";import{useEffect as useEffect4,useRef as useRef6,useState as useState13}from"react";function createScriptTag(src,onload){let head=document.getElementsByTagName("head")[0],script=document.createElement("script");script.async=!0,script.src=src,script.onload=onload??null,head.appendChild(script)}import{jsx as jsx32}from"react/jsx-runtime";function GoogleButton(props){let medplum=useMedplum7(),{googleClientId,handleGoogleCredential}=props,parentRef=useRef6(null),[scriptLoaded,setScriptLoaded]=useState13(typeof google<"u"),[initialized,setInitialized]=useState13(!1),[buttonRendered,setButtonRendered]=useState13(!1);return useEffect4(()=>{if(typeof google>"u"){createScriptTag("https://accounts.google.com/gsi/client",()=>setScriptLoaded(!0));return}initialized||(google.accounts.id.initialize({client_id:googleClientId,callback:handleGoogleCredential}),setInitialized(!0)),parentRef.current&&!buttonRendered&&(google.accounts.id.renderButton(parentRef.current,{}),setButtonRendered(!0))},[medplum,googleClientId,initialized,scriptLoaded,parentRef,buttonRendered,handleGoogleCredential]),googleClientId?jsx32("div",{ref:parentRef}):null}function getGoogleClientId(clientId){if(clientId)return clientId;if(typeof window<"u"){let origin=window.location.protocol+"//"+window.location.host;if(("undefined"?.split(",")??[]).includes(origin))return"__GOOGLE_CLIENT_ID__"}}import{Alert as Alert2}from"@mantine/core";import{operationOutcomeIssueToString}from"@medplum/core";import{jsx as jsx33}from"react/jsx-runtime";function OperationOutcomeAlert(props){let issues=props.outcome?.issue||props.issues;return!issues||issues.length===0?null:jsx33(Alert2,{icon:jsx33(IconAlertCircle,{size:16}),color:"red",children:issues.map(issue=>jsx33("div",{"data-testid":"text-field-error",children:operationOutcomeIssueToString(issue)},issue.details?.text))})}function initRecaptcha(siteKey){typeof grecaptcha>"u"&&createScriptTag("https://www.google.com/recaptcha/api.js?render="+siteKey)}function getRecaptcha(siteKey){return new Promise((resolve,reject)=>{grecaptcha.ready(async()=>{try{resolve(await grecaptcha.execute(siteKey,{action:"submit"}))}catch(err){reject(err)}})})}import{Fragment as Fragment10,jsx as jsx34,jsxs as jsxs17}from"react/jsx-runtime";function NewUserForm(props){let googleClientId=getGoogleClientId(props.googleClientId),recaptchaSiteKey=props.recaptchaSiteKey,medplum=useMedplum8(),[outcome,setOutcome]=useState14(),issues=getIssuesForExpression(outcome,void 0);return useEffect5(()=>{recaptchaSiteKey&&initRecaptcha(recaptchaSiteKey)},[recaptchaSiteKey]),jsxs17(Form,{onSubmit:async formData=>{try{let recaptchaToken="";recaptchaSiteKey&&(recaptchaToken=await getRecaptcha(recaptchaSiteKey)),props.handleAuthResponse(await medplum.startNewUser({projectId:props.projectId,clientId:props.clientId,firstName:formData.firstName,lastName:formData.lastName,email:formData.email,password:formData.password,remember:formData.remember==="true",recaptchaSiteKey,recaptchaToken}))}catch(err){setOutcome(normalizeOperationOutcome3(err))}},children:[jsx34(Center3,{style:{flexDirection:"column"},children:props.children}),jsx34(OperationOutcomeAlert,{issues}),googleClientId&&jsxs17(Fragment10,{children:[jsx34(Group9,{justify:"center",p:"xl",style:{height:70},children:jsx34(GoogleButton,{googleClientId,handleGoogleCredential:async response=>{try{props.handleAuthResponse(await medplum.startGoogleLogin({googleClientId:response.clientId,googleCredential:response.credential,projectId:props.projectId,createUser:!0}))}catch(err){setOutcome(normalizeOperationOutcome3(err))}}})}),jsx34(Divider,{label:"or",labelPosition:"center",my:"lg"})]}),jsxs17(Stack4,{gap:"xl",children:[jsx34(TextInput5,{name:"firstName",type:"text",label:"First name",placeholder:"First name",required:!0,autoFocus:!0,error:getErrorsForInput(outcome,"firstName")}),jsx34(TextInput5,{name:"lastName",type:"text",label:"Last name",placeholder:"Last name",required:!0,error:getErrorsForInput(outcome,"lastName")}),jsx34(TextInput5,{name:"email",type:"email",label:"Email",placeholder:"name@domain.com",required:!0,error:getErrorsForInput(outcome,"email")}),jsx34(PasswordInput,{name:"password",label:"Password",autoComplete:"off",required:!0,error:getErrorsForInput(outcome,"password")}),jsxs17(Text7,{c:"dimmed",size:"xs",children:["By clicking submit you agree to the Medplum"," ",jsx34(Anchor4,{href:"https://www.medplum.com/privacy",children:"Privacy\xA0Policy"})," and ",jsx34(Anchor4,{href:"https://www.medplum.com/terms",children:"Terms\xA0of\xA0Service"}),"."]}),jsxs17(Text7,{c:"dimmed",size:"xs",children:["This site is protected by reCAPTCHA and the Google"," ",jsx34(Anchor4,{href:"https://policies.google.com/privacy",children:"Privacy\xA0Policy"})," and ",jsx34(Anchor4,{href:"https://policies.google.com/terms",children:"Terms\xA0of\xA0Service"})," apply."]})]}),jsxs17(Group9,{justify:"space-between",mt:"xl",wrap:"nowrap",children:[jsx34(Checkbox,{name:"remember",label:"Remember me",size:"xs"}),jsx34(Button5,{type:"submit",children:"Create account"})]})]})}import{jsx as jsx35,jsxs as jsxs18}from"react/jsx-runtime";function RegisterForm(props){let{type,projectId,clientId,googleClientId,recaptchaSiteKey,onSuccess}=props,medplum=useMedplum9(),[login,setLogin]=useState15(),[outcome,setOutcome]=useState15();useEffect6(()=>{type==="patient"&&login&&medplum.startNewPatient({login,projectId}).then(response=>medplum.processCode(response.code)).then(()=>onSuccess()).catch(err=>setOutcome(normalizeOperationOutcome4(err)))},[medplum,type,projectId,login,onSuccess]);function handleAuthResponse(response){response.code?medplum.processCode(response.code).then(()=>onSuccess()).catch(console.log):response.login&&setLogin(response.login)}return jsxs18(Document,{width:450,children:[outcome&&jsx35("pre",{children:JSON.stringify(outcome,null,2)}),!login&&jsx35(NewUserForm,{projectId,clientId,googleClientId,recaptchaSiteKey,handleAuthResponse,children:props.children}),login&&type==="project"&&jsx35(NewProjectForm,{login,handleAuthResponse})]})}import{showNotification as showNotification4}from"@mantine/notifications";import{normalizeErrorString as normalizeErrorString5}from"@medplum/core";import{useMedplum as useMedplum13}from"@medplum/react-hooks";import{useCallback as useCallback6,useEffect as useEffect7,useRef as useRef7,useState as useState19}from"react";import{Anchor as Anchor5,Button as Button6,Center as Center4,Checkbox as Checkbox2,Divider as Divider2,Group as Group10,PasswordInput as PasswordInput2,Stack as Stack5,TextInput as TextInput6}from"@mantine/core";import{normalizeOperationOutcome as normalizeOperationOutcome5}from"@medplum/core";import{useMedplum as useMedplum10}from"@medplum/react-hooks";import{useCallback as useCallback5,useState as useState16}from"react";import{Fragment as Fragment11,jsx as jsx36,jsxs as jsxs19}from"react/jsx-runtime";function AuthenticationForm(props){let[email,setEmail]=useState16();return email?jsx36(PasswordForm,{email,...props}):jsx36(EmailForm,{setEmail,...props})}function EmailForm(props){let{setEmail,onRegister,handleAuthResponse,children,disableEmailAuth,...baseLoginRequest}=props,medplum=useMedplum10(),googleClientId=!props.disableGoogleAuth&&getGoogleClientId(props.googleClientId),[outcome,setOutcome]=useState16(),issues=getIssuesForExpression(outcome,void 0),isExternalAuth=useCallback5(async authMethod=>{if(!authMethod.authorizeUrl)return!1;let state=JSON.stringify({...await medplum.ensureCodeChallenge(baseLoginRequest),domain:authMethod.domain}),url=new URL(authMethod.authorizeUrl);return url.searchParams.set("state",state),window.location.assign(url.toString()),!0},[medplum,baseLoginRequest]),handleSubmit=useCallback5(async formData=>{let authMethod=await medplum.post("auth/method",{email:formData.email});await isExternalAuth(authMethod)||setEmail(formData.email)},[medplum,isExternalAuth,setEmail]),handleGoogleCredential=useCallback5(async response=>{try{let authResponse=await medplum.startGoogleLogin({...baseLoginRequest,googleCredential:response.credential});await isExternalAuth(authResponse)||handleAuthResponse(authResponse)}catch(err){setOutcome(normalizeOperationOutcome5(err))}},[medplum,baseLoginRequest,isExternalAuth,handleAuthResponse]);return jsxs19(Form,{onSubmit:handleSubmit,children:[jsx36(Center4,{style:{flexDirection:"column"},children}),jsx36(OperationOutcomeAlert,{issues}),googleClientId&&jsxs19(Fragment11,{children:[jsx36(Group10,{justify:"center",p:"xl",style:{height:70},children:jsx36(GoogleButton,{googleClientId,handleGoogleCredential})}),!disableEmailAuth&&jsx36(Divider2,{label:"or",labelPosition:"center",my:"lg"})]}),!disableEmailAuth&&jsx36(TextInput6,{name:"email",type:"email",label:"Email",placeholder:"name@domain.com",required:!0,autoFocus:!0,error:getErrorsForInput(outcome,"email")}),jsxs19(Group10,{justify:"space-between",mt:"xl",gap:0,wrap:"nowrap",children:[jsx36("div",{children:onRegister&&jsx36(Anchor5,{component:"button",type:"button",color:"dimmed",onClick:onRegister,size:"xs",children:"Register"})}),!disableEmailAuth&&jsx36(Button6,{type:"submit",children:"Next"})]})]})}function PasswordForm(props){let{onForgotPassword,handleAuthResponse,children,...baseLoginRequest}=props,medplum=useMedplum10(),[outcome,setOutcome]=useState16(),issues=getIssuesForExpression(outcome,void 0),handleSubmit=useCallback5(formData=>{medplum.startLogin({...baseLoginRequest,password:formData.password,remember:formData.remember==="on"}).then(handleAuthResponse).catch(err=>setOutcome(normalizeOperationOutcome5(err)))},[medplum,baseLoginRequest,handleAuthResponse]);return jsxs19(Form,{onSubmit:handleSubmit,children:[jsx36(Center4,{style:{flexDirection:"column"},children}),jsx36(OperationOutcomeAlert,{issues}),jsx36(Stack5,{gap:"xl",children:jsx36(PasswordInput2,{name:"password",label:"Password",autoComplete:"off",required:!0,autoFocus:!0,error:getErrorsForInput(outcome,"password")})}),jsxs19(Group10,{justify:"space-between",mt:"xl",gap:0,wrap:"nowrap",children:[onForgotPassword&&jsx36(Anchor5,{component:"button",type:"button",c:"dimmed",onClick:onForgotPassword,size:"xs",children:"Forgot password"}),jsx36(Checkbox2,{id:"remember",name:"remember",label:"Remember me",size:"xs",style:{lineHeight:1}}),jsx36(Button6,{type:"submit",children:"Sign in"})]})]})}import{Avatar as Avatar3,Combobox as Combobox2,Flex,Group as Group11,Stack as Stack6,Text as Text8,TextInput as TextInput7,Title as Title2,useCombobox as useCombobox2}from"@mantine/core";import{normalizeOperationOutcome as normalizeOperationOutcome6}from"@medplum/core";import{useMedplum as useMedplum11}from"@medplum/react-hooks";import{useState as useState17}from"react";import{jsx as jsx37,jsxs as jsxs20}from"react/jsx-runtime";function ChooseProfileForm(props){let medplum=useMedplum11(),combobox=useCombobox2(),[search,setSearch]=useState17(""),[outcome,setOutcome]=useState17();function filterDisplay(display){return!!display?.toLowerCase()?.includes(search.toLowerCase())}function filterMembership(membership){return filterDisplay(membership.profile?.display)||filterDisplay(membership.project?.display)}function handleValueSelect(membershipId){medplum.post("auth/profile",{login:props.login,profile:membershipId}).then(props.handleAuthResponse).catch(err=>setOutcome(normalizeOperationOutcome6(err)))}let options=props.memberships.filter(filterMembership).slice(0,10).map(item=>jsx37(Combobox2.Option,{value:item.id,children:jsx37(SelectOption,{...item})},item.id));return jsxs20(Stack6,{children:[jsxs20(Flex,{gap:"md",mb:"md",justify:"center",align:"center",direction:"column",wrap:"nowrap",children:[jsx37(Logo,{size:32}),jsx37(Title2,{order:3,children:"Choose profile"})]}),jsx37(OperationOutcomeAlert,{outcome}),jsxs20(Combobox2,{store:combobox,onOptionSubmit:handleValueSelect,children:[jsx37(Combobox2.EventsTarget,{children:jsx37(TextInput7,{placeholder:"Search",value:search,onChange:event=>{setSearch(event.currentTarget.value),combobox.updateSelectedOptionIndex()}})}),jsx37("div",{children:jsx37(Combobox2.Options,{children:options.length>0?options:jsx37(Combobox2.Empty,{children:"Nothing found..."})})})]})]})}function SelectOption(membership){return jsxs20(Group11,{children:[jsx37(Avatar3,{radius:"xl"}),jsxs20("div",{children:[jsx37(Text8,{fz:"sm",fw:500,children:membership.profile?.display}),jsx37(Text8,{fz:"xs",opacity:.6,children:membership.project?.display})]})]})}import{Button as Button7,Center as Center5,Checkbox as Checkbox3,Group as Group12,Stack as Stack7,Title as Title3}from"@mantine/core";import{useMedplum as useMedplum12}from"@medplum/react-hooks";import{Fragment as Fragment12,jsx as jsx38,jsxs as jsxs21}from"react/jsx-runtime";var openConditionScope=/^patient\/Condition\.(?:\*|c?r?u?d?s?)$/,encounterDiagnosis="?category=http://terminology.hl7.org/CodeSystem/condition-category|encounter-diagnosis",problemListItem="?category=http://terminology.hl7.org/CodeSystem/condition-category|problem-list-item",healthConcern="?category=http://hl7.org/fhir/us/core/CodeSystem/condition-category|health-concern",openObservationScope=/^patient\/Observation\.(?:\*|c?r?u?d?s?)$/,clinicalTest="?category=http://hl7.org/fhir/us/core/CodeSystem/us-core-observation-category|clinical-test",laboratory="?category=http://terminology.hl7.org/CodeSystem/observation-category|laboratory",socialHistory="?category=http://terminology.hl7.org/CodeSystem/observation-category|social-history",sdoh="?category=http://hl7.org/fhir/us/core/CodeSystem/us-core-category|sdoh",survey="?category=http://terminology.hl7.org/CodeSystem/observation-category|survey",vitalSigns="?category=http://terminology.hl7.org/CodeSystem/observation-category|vital-signs";function ChooseScopeForm(props){let medplum=useMedplum12();return jsx38(Form,{onSubmit:formData=>{medplum.post("auth/scope",{login:props.login,scope:Object.keys(formData).join(" ")}).then(props.handleAuthResponse).catch(console.log)},children:jsxs21(Stack7,{children:[jsxs21(Center5,{style:{flexDirection:"column"},children:[jsx38(Logo,{size:32}),jsx38(Title3,{children:"Choose scope"})]}),jsx38(Stack7,{children:(props.scope??"openid").split(" ").map(scopeName=>{let additionalScopes;return openConditionScope.test(scopeName)?additionalScopes=[scopeName+encounterDiagnosis,scopeName+problemListItem,scopeName+healthConcern]:openObservationScope.test(scopeName)&&(additionalScopes=[scopeName+clinicalTest,scopeName+laboratory,scopeName+socialHistory,scopeName+sdoh,scopeName+survey,scopeName+vitalSigns]),jsxs21(Fragment12,{children:[jsx38(Checkbox3,{id:scopeName,name:scopeName,label:scopeName,defaultChecked:!0},scopeName),additionalScopes?.map(scope=>jsx38(Checkbox3,{id:scope,name:scope,label:scope},scope))]})})}),jsx38(Group12,{justify:"flex-end",mt:"xl",children:jsx38(Button7,{type:"submit",children:"Set scope"})})]})})}import{Alert as Alert3,Button as Button8,Center as Center6,Group as Group13,Stack as Stack8,TextInput as TextInput8,Title as Title4}from"@mantine/core";import{normalizeErrorString as normalizeErrorString4}from"@medplum/core";import{useState as useState18}from"react";import{jsx as jsx39,jsxs as jsxs22}from"react/jsx-runtime";function MfaForm(props){let[errorMessage,setErrorMessage]=useState18();return jsx39(Form,{onSubmit:formData=>{setErrorMessage(void 0),props.onSubmit(formData).catch(err=>setErrorMessage(normalizeErrorString4(err)))},children:jsxs22(Stack8,{children:[jsxs22(Center6,{style:{flexDirection:"column"},children:[jsx39(Logo,{size:32}),jsx39(Title4,{children:"Enter MFA code"})]}),errorMessage&&jsx39(Alert3,{icon:jsx39(IconAlertCircle,{size:16}),title:"Error",color:"red",children:errorMessage}),jsx39(Stack8,{children:jsx39(TextInput8,{name:"token",label:"MFA code",required:!0,autoFocus:!0})}),jsx39(Group13,{justify:"flex-end",mt:"xl",children:jsx39(Button8,{type:"submit",children:"Submit code"})})]})})}import{jsx as jsx40}from"react/jsx-runtime";function SignInForm(props){let{login:loginCode,chooseScopes,onSuccess,onForgotPassword,onRegister,onCode,...baseLoginRequest}=props,medplum=useMedplum13(),[login,setLogin]=useState19(),loginRequested=useRef7(!1),[mfaRequired,setAuthenticatorRequired]=useState19(!1),[memberships,setMemberships]=useState19(),handleCode=useCallback6(code=>{onCode?onCode(code):medplum.processCode(code).then(()=>{onSuccess&&onSuccess()}).catch(err=>showNotification4({color:"red",message:normalizeErrorString5(err)}))},[medplum,onCode,onSuccess]),handleAuthResponse=useCallback6(response=>{setAuthenticatorRequired(!!response.mfaRequired),response.login&&setLogin(response.login),response.memberships&&setMemberships(response.memberships),response.code&&(chooseScopes?setMemberships(void 0):handleCode(response.code))},[chooseScopes,handleCode]),handleScopeResponse=useCallback6(response=>{handleCode(response.code)},[handleCode]);return useEffect7(()=>{loginCode&&!loginRequested.current&&!login&&(loginRequested.current=!0,medplum.get("auth/login/"+loginCode).then(handleAuthResponse).catch(err=>showNotification4({color:"red",message:normalizeErrorString5(err)})))},[medplum,loginCode,loginRequested,login,handleAuthResponse]),jsx40(Document,{width:450,px:"sm",py:"md",children:login?mfaRequired?jsx40(MfaForm,{onSubmit:async fields=>{let res=await medplum.post("auth/mfa/verify",{login,token:fields.token});handleAuthResponse(res)}}):memberships?jsx40(ChooseProfileForm,{login,memberships,handleAuthResponse}):props.projectId==="new"?jsx40(NewProjectForm,{login,handleAuthResponse}):props.chooseScopes?jsx40(ChooseScopeForm,{login,scope:props.scope,handleAuthResponse:handleScopeResponse}):jsx40("div",{children:"Success"}):jsx40(AuthenticationForm,{onForgotPassword,onRegister,handleAuthResponse,disableGoogleAuth:props.disableGoogleAuth,disableEmailAuth:props.disableEmailAuth,...baseLoginRequest,children:props.children})})}import{buildElementsContext as buildElementsContext2,getPathDisplayName as getPathDisplayName3,isEmpty as isEmpty2,tryGetDataType}from"@medplum/core";import{ActionIcon as ActionIcon2,Box,CopyButton,Tooltip}from"@mantine/core";import{PropertyType,formatDateTime,formatPeriod,formatTiming,isEmpty}from"@medplum/core";import{formatCodeableConcept}from"@medplum/core";import{Fragment as Fragment13,jsx as jsx41}from"react/jsx-runtime";function CodeableConceptDisplay(props){return jsx41(Fragment13,{children:formatCodeableConcept(props.value)})}import{formatCoding}from"@medplum/core";import{Fragment as Fragment14,jsx as jsx42}from"react/jsx-runtime";function CodingDisplay(props){return jsx42(Fragment14,{children:formatCoding(props.value)})}import{Fragment as Fragment15,jsx as jsx43}from"react/jsx-runtime";function ContactPointDisplay(props){let contactPoint=props.value;if(!contactPoint)return null;let builder=[];return contactPoint.value&&builder.push(contactPoint.value),(contactPoint.use||contactPoint.system)&&(builder.push(" ["),contactPoint.use&&builder.push(contactPoint.use),contactPoint.use&&contactPoint.system&&builder.push(" "),contactPoint.system&&builder.push(contactPoint.system),builder.push("]")),jsx43(Fragment15,{children:builder.join("").trim()})}import{Fragment as Fragment16,jsx as jsx44,jsxs as jsxs23}from"react/jsx-runtime";function ContactDetailDisplay(props){let contactDetail=props.value;return contactDetail?jsxs23(Fragment16,{children:[contactDetail.name,contactDetail.name&&": ",contactDetail.telecom?.map(telecom=>jsx44(ContactPointDisplay,{value:telecom},`telecom-${contactDetail.name}-${telecom.value}`))]}):null}import{jsxs as jsxs24}from"react/jsx-runtime";function IdentifierDisplay(props){return jsxs24("div",{children:[props.value?.system,": ",props.value?.value]})}import{formatMoney}from"@medplum/core";import{Fragment as Fragment17,jsx as jsx45}from"react/jsx-runtime";function MoneyDisplay(props){return jsx45(Fragment17,{children:formatMoney(props.value)})}import{formatQuantity}from"@medplum/core";import{Fragment as Fragment18,jsx as jsx46}from"react/jsx-runtime";function QuantityDisplay(props){return jsx46(Fragment18,{children:formatQuantity(props.value)})}import{formatRange}from"@medplum/core";import{Fragment as Fragment19,jsx as jsx47}from"react/jsx-runtime";function RangeDisplay(props){return jsx47(Fragment19,{children:formatRange(props.value)})}import{Fragment as Fragment20,jsx as jsx48,jsxs as jsxs25}from"react/jsx-runtime";function RatioDisplay(props){let value=props.value;return value?jsxs25(Fragment20,{children:[jsx48(QuantityDisplay,{value:value.numerator}),"\xA0/\xA0",jsx48(QuantityDisplay,{value:value.denominator})]}):null}import{stringify}from"@medplum/core";import{Fragment as Fragment21,jsx as jsx49}from"react/jsx-runtime";function ReferenceDisplay(props){if(!props.value)return null;let displayString=props.value.display||props.value.reference||stringify(props.value);return props.link!==!1&&props.value.reference?jsx49(MedplumLink,{to:props.value,children:displayString}):jsx49(Fragment21,{children:displayString})}import{getPathDisplayName as getPathDisplayName2,isPopulated as isPopulated5}from"@medplum/core";import{useState as useState20,useContext as useContext3,useEffect as useEffect8,useMemo as useMemo4}from"react";import{getValueSliceName,isPopulated as isPopulated3,isSliceDefinitionWithTypes,tryGetProfile}from"@medplum/core";function assignValuesIntoSlices(values,slices,slicing,profileUrl){if(!isPopulated3(slicing?.slices))return[values];let slicedValues=new Array(slices.length+1);for(let i=0;i<slicedValues.length;i++)slicedValues[i]=[];for(let value of values){let sliceName=getValueSliceName(value,slices,slicing.discriminator,profileUrl),sliceIndex=sliceName?slices.findIndex(slice=>slice.name===sliceName):-1;sliceIndex===-1&&(sliceIndex=slices.length),slicedValues[sliceIndex].push(value)}return slicedValues}async function prepareSlices({medplum,property}){return new Promise((resolve,reject)=>{if(!property.slicing){resolve([]);return}let supportedSlices=[],profileUrls=[],promises=[];for(let slice of property.slicing.slices){if(!isSliceDefinitionWithTypes(slice)){console.debug("Unsupported slice definition",slice);continue}let profileUrl;isPopulated3(slice.elements)||(profileUrl=slice.type[0]?.profile?.[0]),supportedSlices.push(slice),profileUrls.push(profileUrl),profileUrl&&promises.push(medplum.requestProfileSchema(profileUrl))}Promise.all(promises).then(()=>{for(let i=0;i<supportedSlices.length;i++){let slice=supportedSlices[i],profileUrl=profileUrls[i];if(profileUrl){let typeSchema=tryGetProfile(profileUrl);slice.typeSchema=typeSchema}}resolve(supportedSlices)}).catch(reject)})}import{useMedplum as useMedplum14}from"@medplum/react-hooks";import{buildElementsContext,isPopulated as isPopulated4}from"@medplum/core";import{useContext as useContext2,useMemo as useMemo3}from"react";import{jsx as jsx50}from"react/jsx-runtime";function maybeWrapWithContext(ContextProvider,contextValue,contents){return contextValue!==void 0?jsx50(ContextProvider,{value:contextValue,children:contents}):contents}import{Fragment as Fragment22,jsx as jsx51}from"react/jsx-runtime";function SliceDisplay(props){let{slice,property}=props,sliceElements=slice.typeSchema?.elements??slice.elements,parentContext=useContext2(ElementsContext),contextValue=useMemo3(()=>{if(isPopulated4(sliceElements))return buildElementsContext({parentContext,elements:sliceElements,path:props.path,profileUrl:slice.typeSchema?.url})},[parentContext,props.path,slice.typeSchema?.url,sliceElements]);return maybeWrapWithContext(ElementsContext.Provider,contextValue,jsx51(Fragment22,{children:props.value.map((value,valueIndex)=>jsx51("div",{children:jsx51(ResourcePropertyDisplay,{property,path:props.path,arrayElement:!0,elementDefinitionType:slice.type[0],propertyType:slice.type[0].code,value,ignoreMissingValues:props.ignoreMissingValues,link:props.link})},`${valueIndex}-${props.value.length}`))}))}import{Fragment as Fragment23,jsx as jsx52,jsxs as jsxs26}from"react/jsx-runtime";function ResourceArrayDisplay(props){let{property,propertyType}=props,medplum=useMedplum14(),values=useMemo4(()=>Array.isArray(props.values)?props.values:[],[props.values]),[loading,setLoading]=useState20(!0),[slices,setSlices]=useState20([]),[slicedValues,setSlicedValues]=useState20(()=>[values]),ctx=useContext3(ElementsContext);if(useEffect8(()=>{prepareSlices({medplum,property}).then(slices2=>{setSlices(slices2);let slicedValues2=assignValuesIntoSlices(values,slices2,property.slicing,ctx.profileUrl);setSlicedValues(slicedValues2),setLoading(!1)}).catch(reason=>{console.error(reason),setLoading(!1)})},[medplum,property,ctx.profileUrl,setSlicedValues,values]),loading)return jsx52("div",{children:"Loading..."});let nonSliceContent;if(property.type[0]?.code!=="Extension"){let nonSliceValues=slicedValues[slices.length],nonSliceElements=nonSliceValues.map((value,valueIndex)=>jsx52("div",{children:jsx52(ResourcePropertyDisplay,{path:props.path,arrayElement:!0,property,propertyType,value,ignoreMissingValues:props.ignoreMissingValues,link:props.link})},`${valueIndex}-${nonSliceValues.length}`));if(props.includeDescriptionListEntry){if(!isPopulated5(props.path))throw new Error("props.path is required when includeDescriptionListEntry is true");let key=props.path.split(".").pop();nonSliceContent=jsx52(DescriptionListEntry,{term:getPathDisplayName2(key),children:nonSliceElements})}else nonSliceContent=jsx52(Fragment23,{children:nonSliceElements})}return jsxs26(Fragment23,{children:[slices.map((slice,sliceIndex)=>{if(!props.path)throw Error(`Displaying a resource property with slices of type ${props.propertyType} requires path`);let sliceDisplay=jsx52(SliceDisplay,{path:props.path,slice,property,value:slicedValues[sliceIndex],ignoreMissingValues:props.ignoreMissingValues,link:props.link},slice.name);return props.includeDescriptionListEntry&&(sliceDisplay=jsx52(DescriptionListEntry,{term:getPathDisplayName2(slice.name),children:sliceDisplay},slice.name)),sliceDisplay}),nonSliceContent]})}import{getDataType,isPopulated as isPopulated6,isProfileLoaded,tryGetProfile as tryGetProfile2}from"@medplum/core";import{useMedplum as useMedplum15}from"@medplum/react-hooks";import{useContext as useContext4,useEffect as useEffect9,useMemo as useMemo5,useState as useState21}from"react";import{getTypedPropertyValue,getTypedPropertyValueWithSchema}from"@medplum/core";function getValueAndType(context,path,profileUrl){let typedResult=getTypedPropertyValue(context,path,{profileUrl});return typedResult?Array.isArray(typedResult)?[typedResult.map(e=>e.value),typedResult[0].type]:[typedResult.value,typedResult.type]:[void 0,"undefined"]}function getValueAndTypeFromElement(typedValue,path,element){let typedResult=getTypedPropertyValueWithSchema(typedValue,path,element);return typedResult?Array.isArray(typedResult)?[typedResult.map(e=>e.value),typedResult[0].type]:[typedResult.value,typedResult.type]:[void 0,"undefined"]}import{jsx as jsx53}from"react/jsx-runtime";function ExtensionDisplay(props){let{elementDefinitionType}=props,medplum=useMedplum15(),ctx=useContext4(ElementsContext),[typeSchema,setTypeSchema]=useState21(getDataType("Extension")),profileUrl=useMemo5(()=>{if(isPopulated6(elementDefinitionType?.profile))return elementDefinitionType.profile[0]},[elementDefinitionType]),[loadingProfile,setLoadingProfile]=useState21(profileUrl!==void 0);if(useEffect9(()=>{profileUrl&&(setLoadingProfile(!0),medplum.requestProfileSchema(profileUrl).then(()=>{let profile=tryGetProfile2(profileUrl);setLoadingProfile(!1),profile&&setTypeSchema(profile)}).catch(reason=>{setLoadingProfile(!1),console.warn(reason)}))},[medplum,profileUrl]),profileUrl&&(loadingProfile||!isProfileLoaded(profileUrl)))return jsx53("div",{children:"Loading..."});if(typeSchema.elements["value[x]"]?.max!==0){let[propertyValue,propertyType]=getValueAndType({type:"Extension",value:props.value},"value[x]",profileUrl??ctx.profileUrl);return jsx53(ResourcePropertyDisplay,{propertyType,value:propertyValue})}return jsx53(BackboneElementDisplay,{path:props.path,value:{type:typeSchema.type,value:props.value},compact:props.compact,ignoreMissingValues:props.ignoreMissingValues,link:props.link,profileUrl})}import{Fragment as Fragment24,jsx as jsx54,jsxs as jsxs27}from"react/jsx-runtime";function ResourcePropertyDisplay(props){let{property,propertyType,value}=props;if(property?.path?.endsWith(".id"))return jsxs27(Box,{component:"div",style:{display:"flex",gap:3,alignItems:"center"},children:[value,!isEmpty(value)&&jsx54(CopyButton,{value,timeout:2e3,children:({copied,copy})=>jsx54(Tooltip,{label:copied?"Copied":"Copy",withArrow:!0,position:"right",children:jsx54(ActionIcon2,{variant:"subtle",color:copied?"teal":"gray",onClick:copy,children:copied?jsx54(IconCheck,{size:"1rem"}):jsx54(IconCopy,{size:"1rem"})})})})]});if(property&&(property.isArray||property.max>1)&&!props.arrayElement)return propertyType===PropertyType.Attachment?jsx54(AttachmentArrayDisplay,{values:value,maxWidth:props.maxWidth,includeDescriptionListEntry:props.includeArrayDescriptionListEntry,property,path:props.path}):jsx54(ResourceArrayDisplay,{path:props.path,property,propertyType,values:value,includeDescriptionListEntry:props.includeArrayDescriptionListEntry,ignoreMissingValues:props.ignoreMissingValues,link:props.link});switch(propertyType){case PropertyType.boolean:return jsx54(Fragment24,{children:value===void 0?"":(!!value).toString()});case PropertyType.SystemString:case PropertyType.string:return jsx54("div",{style:{whiteSpace:"pre-wrap"},children:value});case PropertyType.code:case PropertyType.date:case PropertyType.decimal:case PropertyType.id:case PropertyType.integer:case PropertyType.positiveInt:case PropertyType.unsignedInt:case PropertyType.uri:case PropertyType.url:return jsx54(Fragment24,{children:value});case PropertyType.canonical:return jsx54(ReferenceDisplay,{value:{reference:value},link:props.link});case PropertyType.dateTime:case PropertyType.instant:return jsx54(Fragment24,{children:formatDateTime(value)});case PropertyType.markdown:return jsx54("pre",{children:value});case PropertyType.Address:return jsx54(AddressDisplay,{value});case PropertyType.Annotation:return jsx54(Fragment24,{children:value?.text});case PropertyType.Attachment:return jsx54(AttachmentDisplay,{value,maxWidth:props.maxWidth});case PropertyType.CodeableConcept:return jsx54(CodeableConceptDisplay,{value});case PropertyType.Coding:return jsx54(CodingDisplay,{value});case PropertyType.ContactDetail:return jsx54(ContactDetailDisplay,{value});case PropertyType.ContactPoint:return jsx54(ContactPointDisplay,{value});case PropertyType.HumanName:return jsx54(HumanNameDisplay,{value});case PropertyType.Identifier:return jsx54(IdentifierDisplay,{value});case PropertyType.Money:return jsx54(MoneyDisplay,{value});case PropertyType.Period:return jsx54(Fragment24,{children:formatPeriod(value)});case PropertyType.Quantity:case PropertyType.Duration:return jsx54(QuantityDisplay,{value});case PropertyType.Range:return jsx54(RangeDisplay,{value});case PropertyType.Ratio:return jsx54(RatioDisplay,{value});case PropertyType.Reference:return jsx54(ReferenceDisplay,{value,link:props.link});case PropertyType.Timing:return jsx54(Fragment24,{children:formatTiming(value)});case PropertyType.Dosage:case PropertyType.UsageContext:if(!props.path)throw Error(`Displaying property of type ${props.propertyType} requires path`);return jsx54(BackboneElementDisplay,{path:props.path,value:{type:propertyType,value},compact:!0,ignoreMissingValues:props.ignoreMissingValues});case PropertyType.Extension:if(!props.path)throw Error(`Displaying property of type ${props.propertyType} requires path`);return jsx54(ExtensionDisplay,{path:props.path,value,compact:!0,ignoreMissingValues:props.ignoreMissingValues,elementDefinitionType:props.elementDefinitionType});default:if(!property)throw Error(`Displaying property of type ${props.propertyType} requires element schema`);if(!props.path)throw Error(`Displaying property of type ${props.propertyType} requires path`);return jsx54(BackboneElementDisplay,{path:props.path,value:{type:property.type[0].code,value},compact:!0,ignoreMissingValues:props.ignoreMissingValues})}}import{useContext as useContext5,useMemo as useMemo6}from"react";import{jsx as jsx55,jsxs as jsxs28}from"react/jsx-runtime";var EXTENSION_KEYS2=["extension","modifierExtension"],IGNORED_PROPERTIES2=DEFAULT_IGNORED_PROPERTIES.filter(prop=>!EXTENSION_KEYS2.includes(prop));function BackboneElementDisplay(props){let typedValue=props.value,{value,type:typeName}=typedValue,parentElementsContext=useContext5(ElementsContext),profileUrl=props.profileUrl??parentElementsContext?.profileUrl,typeSchema=useMemo6(()=>tryGetDataType(typeName,profileUrl),[profileUrl,typeName]),newElementsContext=useMemo6(()=>{if(typeSchema)return buildElementsContext2({parentContext:parentElementsContext,elements:typeSchema.elements,path:props.path,profileUrl:typeSchema.url,accessPolicyResource:props.accessPolicyResource})},[typeSchema,parentElementsContext,props.path,props.accessPolicyResource]);if(isEmpty2(value))return null;if(!typeSchema)return jsxs28("div",{children:[typeName,"\xA0not implemented"]});if(typeof value=="object"&&"name"in value&&Object.keys(value).length===1&&typeof value.name=="string")return jsx55("div",{children:value.name});let elementsContext=newElementsContext??parentElementsContext;return maybeWrapWithContext(ElementsContext.Provider,newElementsContext,jsx55(DescriptionList,{compact:props.compact,children:Object.entries(elementsContext.elements).map(([key,property])=>{if(EXTENSION_KEYS2.includes(key)&&isEmpty2(property.slicing?.slices))return null;if(IGNORED_PROPERTIES2.includes(key))return null;if(DEFAULT_IGNORED_NON_NESTED_PROPERTIES.includes(key)&&property.path.split(".").length===2||key.includes("."))return null;let[propertyValue,propertyType]=getValueAndType(typedValue,key,elementsContext.profileUrl);if((props.ignoreMissingValues||property.max===0)&&isEmpty2(propertyValue)||props.path.endsWith(".extension")&&(key==="url"||key==="id"))return null;let isArrayProperty=property.max>1||property.isArray,resourcePropertyDisplay=jsx55(ResourcePropertyDisplay,{property,propertyType,path:props.path+"."+key,value:propertyValue,ignoreMissingValues:props.ignoreMissingValues,includeArrayDescriptionListEntry:isArrayProperty,link:props.link},key);return isArrayProperty?resourcePropertyDisplay:jsx55(DescriptionListEntry,{term:getPathDisplayName3(key),children:resourcePropertyDisplay},key)})}))}import{buildElementsContext as buildElementsContext4,tryGetDataType as tryGetDataType2}from"@medplum/core";import{useContext as useContext22,useMemo as useMemo22,useState as useState42}from"react";import{Stack as Stack12}from"@mantine/core";import{getPathDisplayName as getPathDisplayName5}from"@medplum/core";import{useContext as useContext21,useMemo as useMemo21,useState as useState41}from"react";import{Group as Group14,Input}from"@mantine/core";import{useContext as useContext6}from"react";import{Tooltip as Tooltip2}from"@mantine/core";import{jsx as jsx56}from"react/jsx-runtime";var READ_ONLY_TOOLTIP_TEXT="Read Only";function maybeWrapWithTooltip(tooltipText,children){return tooltipText?jsx56(Tooltip2.Floating,{label:tooltipText,children}):children}var FormSection_default={dimmed:"FormSection_dimmed",preserveBreaks:"FormSection_preserveBreaks"};import{jsx as jsx57,jsxs as jsxs29}from"react/jsx-runtime";function CheckboxFormSection(props){let{debugMode}=useContext6(ElementsContext),label;return debugMode&&props.fhirPath?label=`${props.title} - ${props.fhirPath}`:label=props.title,maybeWrapWithTooltip(props?.readonly?READ_ONLY_TOOLTIP_TEXT:void 0,jsxs29(Group14,{wrap:"nowrap","data-testid":props.testId,children:[jsx57("div",{children:props.children}),jsx57("div",{children:jsx57(Input.Wrapper,{id:props.htmlFor,label,classNames:{label:props?.readonly?FormSection_default.dimmed:void 0},description:props.description,withAsterisk:props.withAsterisk,children:null})})]}))}import{Input as Input2}from"@mantine/core";import{useContext as useContext7}from"react";import{jsx as jsx58}from"react/jsx-runtime";function FormSection(props){let{debugMode}=useContext7(ElementsContext),label;return debugMode&&props.fhirPath?label=`${props.title} - ${props.fhirPath}`:label=props.title,maybeWrapWithTooltip(props?.readonly?READ_ONLY_TOOLTIP_TEXT:void 0,jsx58(Input2.Wrapper,{id:props.htmlFor,label,classNames:{label:clsx_default({[FormSection_default.dimmed]:props?.readonly},FormSection_default.preserveBreaks)},description:props.description,withAsterisk:props.withAsterisk,error:getErrorsForInput(props.outcome,props.errorExpression??props.htmlFor),"data-testid":props.testId,children:props.children}))}import{capitalize,isEmpty as isEmpty3}from"@medplum/core";function setPropertyValue(obj,key,propName,elementDefinition,value){let types=elementDefinition.type;if(types.length>1)for(let type of types){let compoundKey=key.replace("[x]",capitalize(type.code));compoundKey in obj&&delete obj[compoundKey]}return isEmpty3(value)?obj[propName]=void 0:obj[propName]=value,obj}function isSupportedProfileStructureDefinition(profile){return!!profile&&!isEmpty3(profile.url)&&!isEmpty3(profile.name)}import{Checkbox as Checkbox4,Group as Group28,NativeSelect as NativeSelect9,Textarea as Textarea2,TextInput as TextInput17}from"@mantine/core";import{applyDefaultValuesToElement,capitalize as capitalize2,getPathDifference,HTTP_HL7_ORG,isComplexTypeCode,isEmpty as isEmpty6,isPopulated as isPopulated11,PropertyType as PropertyType2}from"@medplum/core";import{useContext as useContext20,useMemo as useMemo20,useState as useState40}from"react";import{useState as useState22}from"react";import{jsx as jsx59}from"react/jsx-runtime";function CodeableConceptInput(props){let{defaultValue:defaultValue2,onChange,withHelpText,outcome:_outcome,path:_path,valuePath:_valuePath,...rest}=props,[value,setValue]=useState22(defaultValue2);function handleChange(newValues){let newConcept=valueSetElementToCodeableConcept(newValues);setValue(newConcept),onChange&&onChange(newConcept)}return jsx59(ValueSetAutocomplete,{defaultValue:value&&codeableConceptToValueSetElement(value),onChange:handleChange,withHelpText:withHelpText??!0,...rest})}function codeableConceptToValueSetElement(concept){return concept.coding?.map(c=>({system:c.system,code:c.code,display:c.display}))}function valueSetElementToCodeableConcept(elements){if(elements.length!==0)return{coding:elements.map(e=>({system:e.system,code:e.code,display:e.display}))}}import{useState as useState23}from"react";import{jsx as jsx60}from"react/jsx-runtime";function CodingInput(props){let{defaultValue:defaultValue2,onChange,withHelpText,response,...rest}=props,[value,setValue]=useState23(response?.answer?.[0]?.valueCoding??defaultValue2);function handleChange(newValues){let newValue=newValues[0],newConcept=newValue&&valueSetElementToCoding(newValue);setValue(newConcept),onChange&&onChange(newConcept)}return jsx60(ValueSetAutocomplete,{defaultValue:value?codingToValueSetElement(value):void 0,maxValues:1,onChange:handleChange,withHelpText:withHelpText??!0,...rest})}function codingToValueSetElement(coding){return{system:coding.system,code:coding.code,display:coding.display}}function valueSetElementToCoding(element){return{system:element.system,code:element.code,display:element.display}}import{Group as Group16,TextInput as TextInput10}from"@mantine/core";import{useContext as useContext9,useMemo as useMemo8,useRef as useRef9,useState as useState25}from"react";import{Group as Group15,NativeSelect as NativeSelect3,TextInput as TextInput9}from"@mantine/core";import{useContext as useContext8,useMemo as useMemo7,useRef as useRef8,useState as useState24}from"react";import{jsx as jsx61,jsxs as jsxs30}from"react/jsx-runtime";function ContactPointInput(props){let{path,outcome}=props,{elementsByPath,getExtendedProps}=useContext8(ElementsContext),[contactPoint,setContactPoint]=useState24(props.defaultValue),ref=useRef8();ref.current=contactPoint;let[systemElement,useElement,valueElement]=useMemo7(()=>["system","use","value"].map(field=>elementsByPath[path+"."+field]),[elementsByPath,path]),[systemProps,useProps,valueProps]=useMemo7(()=>["system","use","value"].map(field=>getExtendedProps(path+"."+field)),[getExtendedProps,path]);function setContactPointWrapper(newValue){newValue&&Object.keys(newValue).length===0&&(newValue=void 0),setContactPoint(newValue),props.onChange&&props.onChange(newValue)}function setSystem(system){let newValue={...ref.current,system};system||delete newValue.system,setContactPointWrapper(newValue)}function setUse(use){let newValue={...ref.current,use};use||delete newValue.use,setContactPointWrapper(newValue)}function setValue(value){let newValue={...ref.current,value};value||delete newValue.value,setContactPointWrapper(newValue)}let errorPath=props.valuePath??path;return jsxs30(Group15,{gap:"xs",grow:!0,wrap:"nowrap",align:"flex-start",children:[jsx61(NativeSelect3,{disabled:props.disabled||systemProps?.readonly,"data-testid":"system",defaultValue:contactPoint?.system,required:(systemElement?.min??0)>0,onChange:e=>setSystem(e.currentTarget.value),data:["","email","phone","fax","pager","sms","other"],error:getErrorsForInput(outcome,errorPath+".system")}),jsx61(NativeSelect3,{disabled:props.disabled||useProps?.readonly,"data-testid":"use",defaultValue:contactPoint?.use,required:(useElement?.min??0)>0,onChange:e=>setUse(e.currentTarget.value),data:["","home","work","temp","old","mobile"],error:getErrorsForInput(outcome,errorPath+".use")}),jsx61(TextInput9,{disabled:props.disabled||valueProps?.readonly,placeholder:"Value",defaultValue:contactPoint?.value,required:(valueElement?.min??0)>0,onChange:e=>setValue(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".value")})]})}import{jsx as jsx62,jsxs as jsxs31}from"react/jsx-runtime";function ContactDetailInput(props){let[contactPoint,setContactDetail]=useState25(props.defaultValue),ref=useRef9();ref.current=contactPoint;let{getExtendedProps}=useContext9(ElementsContext),[nameProps,telecomProps]=useMemo8(()=>["name","telecom"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setContactDetailWrapper(newValue){setContactDetail(newValue),props.onChange&&props.onChange(newValue)}function setName(name){let newValue={...ref.current,name};name||delete newValue.name,setContactDetailWrapper(newValue)}function setTelecom(telecom){let newValue={...ref.current,telecom:telecom&&[telecom]};telecom||delete newValue.telecom,setContactDetailWrapper(newValue)}return jsxs31(Group16,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx62(TextInput10,{disabled:props.disabled||nameProps?.readonly,"data-testid":props.name+"-name",name:props.name+"-name",placeholder:"Name",style:{width:180},defaultValue:contactPoint?.name,onChange:e=>setName(e.currentTarget.value)}),jsx62(ContactPointInput,{disabled:props.disabled||telecomProps?.readonly,name:props.name+"-telecom",path:props.path+".telecom",defaultValue:contactPoint?.telecom?.[0],onChange:setTelecom,outcome:props.outcome})]})}import{TextInput as TextInput11}from"@mantine/core";import{isValidDate}from"@medplum/core";function convertIsoToLocal(isoString){if(!isoString)return"";let date=new Date(isoString);return isValidDate(date)?date.toLocaleDateString("sv")+"T"+date.toLocaleTimeString("sv"):""}function convertLocalToIso(localString){if(!localString)return"";let date=new Date(localString);return isValidDate(date)?date.toISOString():""}import{jsx as jsx63}from"react/jsx-runtime";function DateTimeInput(props){return jsx63(TextInput11,{id:props.name,name:props.name,label:props.label,"data-autofocus":props.autoFocus,"data-testid":props["data-testid"]??props.name,placeholder:props.placeholder,required:props.required,disabled:props.disabled,type:getInputType(),defaultValue:convertIsoToLocal(props.defaultValue),autoFocus:props.autoFocus,error:getErrorsForInput(props.outcome,props.name),onChange:e=>{if(props.onChange){let newValue=e.currentTarget.value;props.onChange(convertLocalToIso(newValue))}}})}function getInputType(){return"datetime-local"}import{isPopulated as isPopulated7,isProfileLoaded as isProfileLoaded2}from"@medplum/core";import{useMedplum as useMedplum16}from"@medplum/react-hooks";import{useEffect as useEffect10,useMemo as useMemo9,useState as useState26}from"react";import{jsx as jsx64}from"react/jsx-runtime";function ExtensionInput(props){let{propertyType}=props,medplum=useMedplum16(),profileUrl=useMemo9(()=>{if(isPopulated7(propertyType.profile))return propertyType.profile[0]},[propertyType]),[loadingProfile,setLoadingProfile]=useState26(profileUrl!==void 0);return useEffect10(()=>{profileUrl&&(setLoadingProfile(!0),medplum.requestProfileSchema(profileUrl).then(()=>setLoadingProfile(!1)).catch(reason=>{setLoadingProfile(!1),console.warn(reason)}))},[medplum,profileUrl]),profileUrl&&(loadingProfile||!isProfileLoaded2(profileUrl))?jsx64("div",{children:"Loading..."}):jsx64(BackboneElementInput,{profileUrl,path:props.path,typeName:"Extension",defaultValue:props.defaultValue,onChange:props.onChange})}import{Group as Group17,NativeSelect as NativeSelect4,TextInput as TextInput12}from"@mantine/core";import{useContext as useContext10,useMemo as useMemo10,useState as useState27}from"react";import{jsx as jsx65,jsxs as jsxs32}from"react/jsx-runtime";function HumanNameInput(props){let{outcome,path}=props,[value,setValue]=useState27(props.defaultValue),{getExtendedProps}=useContext10(ElementsContext),[useProps,prefixProps,givenProps,familyProps,suffixProps]=useMemo10(()=>["use","prefix","given","family","suffix"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}function setUse(use){setValueWrapper({...value,use:use||void 0})}function setPrefix(prefix){setValueWrapper({...value,prefix:prefix?prefix.split(" "):void 0})}function setGiven(given){setValueWrapper({...value,given:given?given.split(" "):void 0})}function setFamily(family){setValueWrapper({...value,family:family||void 0})}function setSuffix(suffix){setValueWrapper({...value,suffix:suffix?suffix.split(" "):void 0})}let errorPath=props.valuePath??path;return jsxs32(Group17,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx65(NativeSelect4,{disabled:props.disabled||useProps?.readonly,defaultValue:value?.use,name:props.name+"-use","data-testid":"use",onChange:e=>setUse(e.currentTarget.value),data:["","temp","old","usual","official","nickname","anonymous","maiden"],error:getErrorsForInput(outcome,errorPath+".use")}),jsx65(TextInput12,{disabled:props.disabled||prefixProps?.readonly,placeholder:"Prefix",name:props.name+"-prefix",defaultValue:value?.prefix?.join(" "),onChange:e=>setPrefix(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".prefix")}),jsx65(TextInput12,{disabled:props.disabled||givenProps?.readonly,placeholder:"Given",name:props.name+"-given",defaultValue:value?.given?.join(" "),onChange:e=>setGiven(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".given")}),jsx65(TextInput12,{disabled:props.disabled||familyProps?.readonly,name:props.name+"-family",placeholder:"Family",defaultValue:value?.family,onChange:e=>setFamily(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".family")}),jsx65(TextInput12,{disabled:props.disabled||suffixProps?.readonly,placeholder:"Suffix",name:props.name+"-suffix",defaultValue:value?.suffix?.join(" "),onChange:e=>setSuffix(e.currentTarget.value),error:getErrorsForInput(outcome,errorPath+".suffix")})]})}import{Group as Group18,TextInput as TextInput13}from"@mantine/core";import{useContext as useContext11,useMemo as useMemo11,useState as useState28}from"react";import{jsx as jsx66,jsxs as jsxs33}from"react/jsx-runtime";function IdentifierInput(props){let[value,setValue]=useState28(props.defaultValue),{elementsByPath,getExtendedProps}=useContext11(ElementsContext),[systemElement,valueElement]=useMemo11(()=>["system","value"].map(field=>elementsByPath[props.path+"."+field]),[elementsByPath,props.path]),[systemProps,valueProps]=useMemo11(()=>["system","value"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}let errorPath=props.valuePath??props.path;return jsxs33(Group18,{gap:"xs",grow:!0,wrap:"nowrap",align:"flex-start",children:[jsx66(TextInput13,{disabled:props.disabled||systemProps?.readonly,placeholder:"System",required:(systemElement?.min??0)>0,defaultValue:value?.system,onChange:e=>setValueWrapper({...value,system:e.currentTarget.value}),error:getErrorsForInput(props.outcome,errorPath+".system")}),jsx66(TextInput13,{disabled:props.disabled||valueProps?.readonly,placeholder:"Value",required:(valueElement?.min??0)>0,defaultValue:value?.value,onChange:e=>setValueWrapper({...value,value:e.currentTarget.value}),error:getErrorsForInput(props.outcome,errorPath+".value")})]})}import{NativeSelect as NativeSelect5,TextInput as TextInput14}from"@mantine/core";import{useCallback as useCallback7,useContext as useContext12,useMemo as useMemo12,useState as useState29}from"react";import{jsx as jsx67}from"react/jsx-runtime";var data=["USD","EUR","CAD","GBP","AUD"];function MoneyInput(props){let{onChange}=props,[value,setValue]=useState29(props.defaultValue),{getExtendedProps}=useContext12(ElementsContext),[currencyProps,valueProps]=useMemo12(()=>["currency","value"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]),setValueWrapper=useCallback7(newValue=>{setValue(newValue),onChange&&onChange(newValue)},[onChange]),handleCurrencyChange=useCallback7(e=>{setValueWrapper({...value,currency:e.currentTarget.value})},[value,setValueWrapper]),handleValueChange=useCallback7(e=>{setValueWrapper({...value,value:e.currentTarget.valueAsNumber})},[value,setValueWrapper]),select=jsx67(NativeSelect5,{disabled:props.disabled||currencyProps?.readonly,defaultValue:value?.currency,data,styles:{input:{fontWeight:500,borderTopLeftRadius:0,borderBottomLeftRadius:0,width:92}},onChange:handleCurrencyChange});return jsx67(TextInput14,{disabled:props.disabled||valueProps?.readonly,type:"number",name:props.name,label:props.label,placeholder:props.placeholder??"Value",defaultValue:value?.value?.toString()??"USD",leftSection:jsx67(IconCurrencyDollar,{size:14}),rightSection:select,rightSectionWidth:92,onChange:handleValueChange})}import{Group as Group19}from"@mantine/core";import{useContext as useContext13,useMemo as useMemo13,useState as useState30}from"react";import{jsx as jsx68,jsxs as jsxs34}from"react/jsx-runtime";function PeriodInput(props){let[value,setValue]=useState30(props.defaultValue),{getExtendedProps}=useContext13(ElementsContext),[startProps,endProps]=useMemo13(()=>["start","end"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}return jsxs34(Group19,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx68(DateTimeInput,{disabled:props.disabled||startProps?.readonly,name:props.name+".start",placeholder:"Start",defaultValue:value?.start,onChange:newValue=>setValueWrapper({...value,start:newValue})}),jsx68(DateTimeInput,{disabled:props.disabled||endProps?.readonly,name:props.name+".end",placeholder:"End",defaultValue:value?.end,onChange:newValue=>setValueWrapper({...value,end:newValue})})]})}import{Group as Group20,NativeSelect as NativeSelect6,TextInput as TextInput15}from"@mantine/core";import{useContext as useContext14,useMemo as useMemo14,useState as useState31}from"react";import{jsx as jsx69,jsxs as jsxs35}from"react/jsx-runtime";function QuantityInput(props){let[value,setValue]=useState31(props.defaultValue),{getExtendedProps}=useContext14(ElementsContext),[comparatorProps,valueProps,unitProps]=useMemo14(()=>["comparator","value","unit"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}return jsxs35(Group20,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx69(NativeSelect6,{disabled:props.disabled||comparatorProps?.readonly,style:{width:80},"data-testid":props.name+"-comparator",defaultValue:value?.comparator,data:["","<","<=",">=",">"],onChange:e=>setValueWrapper({...value,comparator:e.currentTarget.value})}),jsx69(TextInput15,{disabled:props.disabled||valueProps?.readonly,id:props.name,name:props.name,required:props.required,"data-autofocus":props.autoFocus,"data-testid":props.name+"-value",type:"number",placeholder:"Value",defaultValue:value?.value,autoFocus:props.autoFocus,step:"any",onWheel:e=>{props.disableWheel&&e.currentTarget.blur()},onChange:e=>{setValueWrapper({...value,value:tryParseNumber(e.currentTarget.value)})}}),jsx69(TextInput15,{disabled:props.disabled||unitProps?.readonly,placeholder:"Unit","data-testid":props.name+"-unit",defaultValue:value?.unit,onChange:e=>setValueWrapper({...value,unit:e.currentTarget.value})})]})}function tryParseNumber(str){if(str)return parseFloat(str)}import{Group as Group21}from"@mantine/core";import{useContext as useContext15,useMemo as useMemo15,useState as useState32}from"react";import{jsx as jsx70,jsxs as jsxs36}from"react/jsx-runtime";function RangeInput(props){let[value,setValue]=useState32(props.defaultValue),{getExtendedProps}=useContext15(ElementsContext),[lowProps,highProps]=useMemo15(()=>["low","high"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}return jsxs36(Group21,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx70(QuantityInput,{path:props.path+".low",disabled:props.disabled||lowProps?.readonly,name:props.name+"-low",defaultValue:value?.low,onChange:v=>setValueWrapper({...value,low:v})}),jsx70(QuantityInput,{path:props.path+".high",disabled:props.disabled||highProps?.readonly,name:props.name+"-high",defaultValue:value?.high,onChange:v=>setValueWrapper({...value,high:v})})]})}import{Group as Group22}from"@mantine/core";import{useContext as useContext16,useMemo as useMemo16,useState as useState33}from"react";import{jsx as jsx71,jsxs as jsxs37}from"react/jsx-runtime";function RatioInput(props){let[value,setValue]=useState33(props.defaultValue),{getExtendedProps}=useContext16(ElementsContext),[numeratorProps,denominatorProps]=useMemo16(()=>["numerator","denominator"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}return jsxs37(Group22,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx71(QuantityInput,{path:props.path+".numerator",disabled:props.disabled||numeratorProps?.readonly,name:props.name+"-numerator",defaultValue:value?.numerator,onChange:v=>setValueWrapper({...value,numerator:v})}),jsx71(QuantityInput,{path:props.path+".denominator",disabled:props.disabled||denominatorProps?.readonly,name:props.name+"-denominator",defaultValue:value?.denominator,onChange:v=>setValueWrapper({...value,denominator:v})})]})}import{Group as Group24,NativeSelect as NativeSelect7}from"@mantine/core";import{LRUCache,ReadablePromise,createReference as createReference2,isEmpty as isEmpty4,isPopulated as isPopulated9,tryGetProfile as tryGetProfile3}from"@medplum/core";import{useMedplum as useMedplum18}from"@medplum/react-hooks";import{useCallback as useCallback9,useEffect as useEffect11,useMemo as useMemo17,useRef as useRef10,useState as useState35}from"react";import{Group as Group23,Text as Text9}from"@mantine/core";import{getDisplayString as getDisplayString3,getReferenceString as getReferenceString3,isPopulated as isPopulated8}from"@medplum/core";import{useMedplum as useMedplum17,useResource as useResource2}from"@medplum/react-hooks";import{forwardRef as forwardRef4,useCallback as useCallback8,useState as useState34}from"react";import{jsx as jsx72,jsxs as jsxs38}from"react/jsx-runtime";var SEARCH_CODES={Device:"device-name",Observation:"code",Subscription:"criteria",User:"email:contains"},NAME_RESOURCE_TYPES=["AccessPolicy","Account","ActivityDefinition","Bot","CapabilityStatement","CareTeam","ClientApplication","CodeSystem","CompartmentDefinition","ConceptMap","EffectEvidenceSynthesis","Endpoint","EventDefinition","Evidence","EvidenceVariable","ExampleScenario","GraphDefinition","Group","HealthcareService","ImplementationGuide","InsurancePlan","Library","Location","Measure","MedicinalProduct","MessageDefinition","NamingSystem","OperationDefinition","Organization","Patient","Person","PlanDefinition","Practitioner","Project","Questionnaire","RelatedPerson","ResearchDefinition","ResearchElementDefinition","ResearchStudy","RiskEvidenceSynthesis","SearchParameter","StructureDefinition","StructureMap","TerminologyCapabilities","TestScript","UserConfiguration","ValueSet"];function toOption3(resource){return{value:getReferenceString3(resource)??"",label:getDisplayString3(resource),resource}}function ResourceInput(props){let medplum=useMedplum17(),{resourceType,searchCriteria}=props,[outcome,setOutcome]=useState34(),defaultValue2=useResource2(props.defaultValue,setOutcome),ItemComponent3=props.itemComponent??DefaultItemComponent2,onChange=props.onChange,loadValues=useCallback8(async(input,signal)=>{let searchCode=getSearchParamForResourceType(resourceType),searchParams=new URLSearchParams({[searchCode]:input??"",_count:"10",...searchCriteria});return await medplum.searchResources(resourceType,searchParams,{signal})},[medplum,resourceType,searchCriteria]),handleChange=useCallback8(newResources=>{onChange&&onChange(newResources[0])},[onChange]);return isPopulated8(props.defaultValue)&&!outcome&&!defaultValue2?null:jsx72(AsyncAutocomplete,{disabled:props.disabled,name:props.name,label:props.label,error:props.error,required:props.required,itemComponent:ItemComponent3,defaultValue:defaultValue2,placeholder:props.placeholder,maxValues:1,toOption:toOption3,loadOptions:loadValues,onChange:handleChange,clearable:!0})}var DefaultItemComponent2=forwardRef4(({label,resource,active:_active,...others},ref)=>jsx72("div",{ref,...others,children:jsxs38(Group23,{wrap:"nowrap",children:[jsx72(ResourceAvatar,{value:resource}),jsxs38("div",{children:[jsx72(Text9,{children:label}),jsx72(Text9,{size:"xs",c:"dimmed",children:resource.birthDate||resource.id})]})]})}));function getSearchParamForResourceType(resourceType){return SEARCH_CODES[resourceType]??(NAME_RESOURCE_TYPES.includes(resourceType)?"name":"_id")}import{jsx as jsx73,jsxs as jsxs39}from"react/jsx-runtime";function ReferenceInput(props){let{onChange}=props,medplum=useMedplum18(),[value,setValue]=useState35(props.defaultValue),[targetTypes,setTargetTypes]=useState35(()=>createTargetTypes(props.targetTypes)),[targetType,setTargetType]=useState35(()=>getInitialTargetType(props.defaultValue,targetTypes)),promiseCache=useRef10(new LRUCache),searchCriteria=useMemo17(()=>targetType?.type==="profile"?{...props.searchCriteria,_profile:targetType.value}:props.searchCriteria,[props.searchCriteria,targetType]);useEffect11(()=>{let anyToFetch=!1,newTargetTypePromises=targetTypes?.map(tt=>{if(!shouldFetchResourceType(tt))return Promise.resolve(tt);anyToFetch=!0;let cacheKey=tt.value,cached=promiseCache.current.get(cacheKey);if(cached)return cached;let promise=fetchResourceTypeOfProfile(medplum,tt.value).then(profile=>{let newTargetType={...tt};return profile?isPopulated9(profile.type)?(newTargetType.resourceType=profile.type,newTargetType.name=profile.name,newTargetType.title=profile.title):(console.error(`StructureDefinition.type missing for ${tt.value}`),newTargetType.error="StructureDefinition.type missing"):(console.error(`StructureDefinition not found for ${tt.value}`),newTargetType.error="StructureDefinition not found"),newTargetType}).catch(reason=>(console.error(reason),{...tt,error:reason})),readablePromise=new ReadablePromise(promise);return promiseCache.current.set(cacheKey,readablePromise),readablePromise});!newTargetTypePromises||!anyToFetch||Promise.all(newTargetTypePromises).then(newTargetTypes=>{if(setTargetTypes(newTargetTypes),!targetType)return;let index=newTargetTypes.findIndex(tt=>tt.value===targetType.value||tt.resourceType===targetType.resourceType);if(index===-1){console.debug(`defaultValue had unexpected resourceType: ${targetType.resourceType}`);return}setTargetType(newTargetTypes[index])}).catch(console.error)},[medplum,targetType,targetTypes]);let setValueHelper=useCallback9(item=>{let newValue=item?createReference2(item):void 0;setValue(newValue),onChange&&onChange(newValue)},[onChange]),typeSelectOptions=useMemo17(()=>targetTypes?targetTypes.map(tt=>({value:tt.value,label:tt.type==="profile"?tt.title??tt.name??tt.resourceType??tt.value:tt.value})):[],[targetTypes]);return jsxs39(Group24,{gap:"xs",grow:!0,wrap:"nowrap",children:[targetTypes&&targetTypes.length>1&&jsx73(NativeSelect7,{disabled:props.disabled,"data-autofocus":props.autoFocus,"data-testid":"reference-input-resource-type-select",defaultValue:targetType?.resourceType,autoFocus:props.autoFocus,onChange:e=>{let newValue=e.currentTarget.value,newTargetType=targetTypes.find(tt=>tt.value===newValue);setTargetType(newTargetType)},data:typeSelectOptions}),!targetTypes&&jsx73(ResourceTypeInput,{disabled:props.disabled,autoFocus:props.autoFocus,testId:"reference-input-resource-type-input",defaultValue:targetType?.resourceType,onChange:newResourceType=>{setTargetType(newResourceType?{type:"resourceType",value:newResourceType,resourceType:newResourceType}:void 0)},name:props.name+"-resourceType",placeholder:"Resource Type"}),jsx73(ResourceInput,{resourceType:targetType?.resourceType,name:props.name+"-id",required:props.required,placeholder:props.placeholder,defaultValue:value,searchCriteria,onChange:setValueHelper,disabled:props.disabled})]})}function createTargetTypes(resourceTypesAndProfileUrls){if(!resourceTypesAndProfileUrls||resourceTypesAndProfileUrls.length===0||resourceTypesAndProfileUrls.length===1&&resourceTypesAndProfileUrls[0]==="Resource")return;let results=[];for(let value of resourceTypesAndProfileUrls)value.includes("/")?results.push({type:"profile",value}):results.push({type:"resourceType",value,resourceType:value});return results}function getInitialTargetType(defaultValue2,targetTypes){let defaultValueResourceType=defaultValue2?.reference?.split("/")[0];if(defaultValueResourceType){let targetType=targetTypes?.find(tt=>tt.resourceType===defaultValueResourceType);return targetType||{type:"resourceType",value:defaultValueResourceType,resourceType:defaultValueResourceType}}if(targetTypes&&targetTypes.length>0)return targetTypes[0]}async function fetchResourceTypeOfProfile(medplum,profileUrl){let profile=tryGetProfile3(profileUrl);if(profile)return{type:profile.type,name:profile.name,title:profile.title};let query=`{
|
|
66
66
|
StructureDefinitionList(url: "${profileUrl}", _sort: "_lastUpdated", _count: 1) {
|
|
67
67
|
type,
|
|
68
68
|
name,
|
|
69
69
|
title,
|
|
70
70
|
}
|
|
71
|
-
}`.replace(/\s+/g," ");return(await medplum.graphql(query)).data.StructureDefinitionList[0]}function shouldFetchResourceType(targetType){return targetType.type==="profile"&&!targetType?.error&&isEmpty4(targetType.resourceType)}import{Group as Group26,Stack as Stack10,Text as Text11}from"@mantine/core";import{getPathDisplayName as getPathDisplayName4}from"@medplum/core";import{useMedplum as useMedplum19}from"@medplum/react-hooks";import{useContext as useContext18,useEffect as useEffect12,useState as useState37}from"react";import{Group as Group25,Stack as Stack9,Text as Text10}from"@mantine/core";import{buildElementsContext as buildElementsContext3,getPropertyDisplayName,isEmpty as isEmpty5,isPopulated as isPopulated10}from"@medplum/core";import{useContext as useContext17,useMemo as useMemo18,useState as useState36}from"react";var ResourceArrayInput_default={indented:"ResourceArrayInput_indented"};import{ActionIcon as ActionIcon3,Button as Button9}from"@mantine/core";import{jsx as jsx74}from"react/jsx-runtime";function ArrayAddButton({propertyDisplayName,onClick,testId}){let text=propertyDisplayName?`Add ${propertyDisplayName}`:"Add";return propertyDisplayName?jsx74(Button9,{title:text,size:"sm",color:"green.6",variant:"subtle","data-testid":testId,leftSection:jsx74(IconCirclePlus,{size:"1.25rem"}),onClick,children:text}):jsx74(ActionIcon3,{title:text,color:"green.6","data-testid":testId,onClick,children:jsx74(IconCirclePlus,{size:"1.25rem"})})}import{ActionIcon as ActionIcon4}from"@mantine/core";import{jsx as jsx75}from"react/jsx-runtime";function ArrayRemoveButton({propertyDisplayName,onClick,testId}){return jsx75(ActionIcon4,{title:propertyDisplayName?`Remove ${propertyDisplayName}`:"Remove",color:"red.5","data-testid":testId,variant:"subtle",onClick,children:jsx75(IconCircleMinus,{size:"1.25rem"})})}import{jsx as jsx76,jsxs as jsxs40}from"react/jsx-runtime";function SliceInput(props){let{slice,property}=props,[values,setValues]=useState36(props.defaultValue),sliceElements=slice.typeSchema?.elements??slice.elements,parentElementsContextValue=useContext17(ElementsContext),contextValue=useMemo18(()=>{if(isPopulated10(sliceElements))return buildElementsContext3({parentContext:parentElementsContextValue,elements:sliceElements,path:props.path,profileUrl:slice.typeSchema?.url})},[parentElementsContextValue,props.path,slice.typeSchema?.url,sliceElements]);function setValuesWrapper(newValues){setValues(newValues),props.onChange&&props.onChange(newValues)}let required=slice.min>0,indentedStack=isEmpty5(slice.elements),propertyDisplayName=getPropertyDisplayName(slice.name),showEmptyMessage=props.property.readonly&&values.length===0;return maybeWrapWithContext(ElementsContext.Provider,contextValue,jsx76(FormSection,{title:propertyDisplayName,description:slice.definition,withAsterisk:required,fhirPath:`${property.path}:${slice.name}`,testId:props.testId,readonly:props.property.readonly,children:showEmptyMessage?jsx76(Text10,{c:"dimmed",children:"(empty)"}):jsxs40(Stack9,{className:indentedStack?ResourceArrayInput_default.indented:void 0,children:[values.map((value,valueIndex)=>jsxs40(Group25,{wrap:"nowrap",children:[jsx76("div",{style:{flexGrow:1},"data-testid":props.testId&&`${props.testId}-elements-${valueIndex}`,children:jsx76(ElementDefinitionTypeInput,{elementDefinitionType:slice.type[0],name:slice.name,defaultValue:value,onChange:newValue=>{let newValues=[...values];newValues[valueIndex]=newValue,setValuesWrapper(newValues)},outcome:props.outcome,min:slice.min,max:slice.max,binding:slice.binding,path:props.path,valuePath:void 0,readOnly:props.property.readonly})}),!props.property.readonly&&values.length>slice.min&&jsx76(ArrayRemoveButton,{propertyDisplayName,testId:props.testId&&`${props.testId}-remove-${valueIndex}`,onClick:e=>{killEvent(e);let newValues=[...values];newValues.splice(valueIndex,1),setValuesWrapper(newValues)}})]},`${valueIndex}-${values.length}`)),!props.property.readonly&&values.length<slice.max&&jsx76(Group25,{wrap:"nowrap",style:{justifyContent:"flex-start"},children:jsx76(ArrayAddButton,{propertyDisplayName,onClick:e=>{killEvent(e);let newValues=[...values,void 0];setValuesWrapper(newValues)},testId:props.testId&&`${props.testId}-add`})})]})}))}function getValuePath(elementPath,valuePath,arrayIndex){return valuePath===void 0?elementPath:arrayIndex===void 0?valuePath:`${valuePath}[${arrayIndex}]`}import{jsx as jsx77,jsxs as jsxs41}from"react/jsx-runtime";function ResourceArrayInput(props){let{property}=props,medplum=useMedplum19(),[loading,setLoading]=useState37(!0),[slices,setSlices]=useState37([]),[defaultValue2]=useState37(()=>Array.isArray(props.defaultValue)?props.defaultValue:[]),[slicedValues,setSlicedValues]=useState37(()=>[defaultValue2]),ctx=useContext18(ElementsContext),propertyTypeCode=property.type[0]?.code;useEffect12(()=>{prepareSlices({medplum,property}).then(slices2=>{setSlices(slices2);let slicedValues2=assignValuesIntoSlices(defaultValue2,slices2,property.slicing,ctx.profileUrl);addPlaceholderValues(slicedValues2,slices2),setSlicedValues(slicedValues2),setLoading(!1)}).catch(reason=>{console.error(reason),setLoading(!1)})},[medplum,property,defaultValue2,ctx.profileUrl,setSlicedValues]);function setValuesWrapper(newValues,sliceIndex){let newSlicedValues=[...slicedValues];if(newSlicedValues[sliceIndex]=newValues,setSlicedValues(newSlicedValues),props.onChange){let cleaned=newSlicedValues.flat().filter(val=>val!==void 0);props.onChange(cleaned)}}if(loading)return jsx77("div",{children:"Loading..."});let nonSliceIndex=slices.length,nonSliceValues=slicedValues[nonSliceIndex],showNonSliceValues=!(props.hideNonSliceValues??(propertyTypeCode==="Extension"&&slices.length>0)),propertyDisplayName=getPathDisplayName4(property.path),showEmptyMessage=props.property.readonly&&slices.length===0&&defaultValue2.length===0;return jsxs41(Stack10,{className:props.indent?ResourceArrayInput_default.indented:void 0,children:[showEmptyMessage&&jsx77(Text11,{c:"dimmed",children:"(empty)"}),slices.map((slice,sliceIndex)=>jsx77(SliceInput,{slice,path:props.path,valuePath:props.valuePath,property,defaultValue:slicedValues[sliceIndex],onChange:newValue=>{setValuesWrapper(newValue,sliceIndex)},testId:`slice-${slice.name}`},slice.name)),showNonSliceValues&&nonSliceValues.map((value,valueIndex)=>jsxs41(Group26,{wrap:"nowrap",style:{flexGrow:1},children:[jsx77("div",{style:{flexGrow:1},children:jsx77(ResourcePropertyInput,{arrayElement:!0,property:props.property,name:props.name+"."+valueIndex,path:props.path,valuePath:getValuePath(props.path,props.valuePath,valueIndex),defaultValue:value,onChange:newValue=>{let newNonSliceValues=[...nonSliceValues];newNonSliceValues[valueIndex]=newValue,setValuesWrapper(newNonSliceValues,nonSliceIndex)},defaultPropertyType:void 0,outcome:props.outcome})}),!props.property.readonly&&jsx77(ArrayRemoveButton,{propertyDisplayName,testId:`nonsliced-remove-${valueIndex}`,onClick:e=>{killEvent(e);let newNonSliceValues=[...nonSliceValues];newNonSliceValues.splice(valueIndex,1),setValuesWrapper(newNonSliceValues,nonSliceIndex)}})]},`${valueIndex}-${nonSliceValues.length}`)),!props.property.readonly&&showNonSliceValues&&slicedValues.flat().length<property.max&&jsx77(Group26,{wrap:"nowrap",style:{justifyContent:"flex-start"},children:jsx77(ArrayAddButton,{propertyDisplayName,onClick:e=>{killEvent(e);let newNonSliceValues=[...nonSliceValues];newNonSliceValues.push(void 0),setValuesWrapper(newNonSliceValues,nonSliceIndex)},testId:"nonsliced-add"})})]})}function addPlaceholderValues(slicedValues,slices){for(let sliceIndex=0;sliceIndex<slices.length;sliceIndex++){let slice=slices[sliceIndex],sliceValues=slicedValues[sliceIndex];for(;sliceValues.length<slice.min;)sliceValues.push(void 0)}}import{ActionIcon as ActionIcon5,Flex as Flex2,Textarea}from"@mantine/core";import{useClipboard}from"@mantine/hooks";import{showNotification as showNotification5}from"@mantine/notifications";import{useRef as useRef11,useState as useState38}from"react";import{jsx as jsx78,jsxs as jsxs42}from"react/jsx-runtime";function SensitiveTextarea(props){let[revealed,setRevealed]=useState38(!1),clipboard=useClipboard(),ref=useRef11(null),styles={...props.styles};return revealed||(styles.input||(styles.input={}),styles.input.WebkitTextSecurity="disc"),jsxs42(Flex2,{gap:"xs",children:[jsx78(Textarea,{...props,styles:{...styles,root:{...styles.root??{},flexGrow:1}},ref,autosize:!0,minRows:1,onFocus:()=>setRevealed(!0),onBlur:()=>setRevealed(!1)}),jsx78(ActionIcon5,{title:"Copy secret",onClick:()=>{clipboard.copy(ref.current?.value),showNotification5({color:"green",message:"Copied"})},children:jsx78(IconCopy,{})})]})}import{Button as Button10,Chip,Group as Group27,Modal as Modal2,NativeSelect as NativeSelect8,Stack as Stack11,Switch,TextInput as TextInput16}from"@mantine/core";import{formatTiming as formatTiming2}from"@medplum/core";import{useContext as useContext19,useMemo as useMemo19,useRef as useRef12,useState as useState39}from"react";import{Fragment as Fragment25,jsx as jsx79,jsxs as jsxs43}from"react/jsx-runtime";var daysOfWeek=["sun","mon","tue","wed","thu","fri","sat"];function TimingInput(props){let[value,setValue]=useState39(props.defaultValue),[open,setOpen]=useState39(!props.disabled&&(props.defaultModalOpen??!1)),valueRef=useRef12();return valueRef.current=value,jsxs43(Fragment25,{children:[jsxs43(Group27,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx79("span",{children:formatTiming2(valueRef.current)||"No repeat"}),jsx79(Button10,{disabled:props.disabled,onClick:()=>setOpen(!0),children:"Edit"})]}),!props.disabled&&jsx79(TimingEditorDialog,{path:props.path,visible:open,defaultValue:valueRef.current,onOk:newValue=>{props.onChange&&props.onChange(newValue),setValue(newValue),setOpen(!1)},onCancel:()=>setOpen(!1)})]})}var defaultValue={repeat:{period:1,periodUnit:"d"}};function TimingEditorDialog(props){let[value,setValue]=useState39(props.defaultValue||defaultValue),{getExtendedProps}=useContext19(ElementsContext),[eventProps,repeatProps,repeatPeriodProps,repeatPeriodUnitProps,repeatDayOfWeekProps]=useMemo19(()=>["event","repeat","repeat.period","repeat.periodUnit","repeat.dayOfWeek"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]),valueRef=useRef12();valueRef.current=value;function setStart(newStart){setValue({...valueRef.current,event:[newStart]})}function setRepeat(repeat){setValue({...valueRef.current,repeat})}function setPeriod(newPeriod){setRepeat({...valueRef.current?.repeat,period:newPeriod})}function setPeriodUnit(newPeriodUnit){setRepeat({...valueRef.current?.repeat,periodUnit:newPeriodUnit})}function setDaysOfWeek(newDaysOfWeek){setRepeat({...valueRef.current?.repeat,dayOfWeek:newDaysOfWeek})}return jsx79(Modal2,{title:"Timing",closeButtonProps:{"aria-label":"Close"},opened:props.visible,onClose:()=>props.onCancel(),children:jsxs43(Stack11,{children:[jsx79(FormSection,{title:"Starts on",htmlFor:"timing-dialog-start",children:jsx79(DateTimeInput,{disabled:eventProps?.readonly,name:"timing-dialog-start",onChange:newValue=>setStart(newValue)})}),jsx79(Switch,{disabled:repeatProps?.readonly,label:"Repeat",checked:!!value.repeat,onChange:e=>setRepeat(e.currentTarget.checked?defaultValue.repeat:void 0)}),value.repeat&&jsxs43(Fragment25,{children:[jsx79(FormSection,{title:"Repeat every",htmlFor:"timing-dialog-period",children:jsxs43(Group27,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx79(TextInput16,{disabled:repeatPeriodProps?.readonly,type:"number",step:1,id:"timing-dialog-period",name:"timing-dialog-period",defaultValue:value.repeat.period||1,onChange:e=>setPeriod(parseInt(e.currentTarget.value,10)||1)}),jsx79(NativeSelect8,{disabled:repeatPeriodUnitProps?.readonly,id:"timing-dialog-periodUnit",name:"timing-dialog-periodUnit",defaultValue:value.repeat.periodUnit,onChange:e=>setPeriodUnit(e.currentTarget.value),data:[{label:"second",value:"s"},{label:"minute",value:"min"},{label:"hour",value:"h"},{label:"day",value:"d"},{label:"week",value:"wk"},{label:"month",value:"mo"},{label:"year",value:"a"}]})]})}),value.repeat.periodUnit==="wk"&&jsx79(FormSection,{title:"Repeat on",children:jsx79(Chip.Group,{multiple:!0,onChange:setDaysOfWeek,children:jsx79(Group27,{justify:"space-between",mt:"md",gap:"xs",children:daysOfWeek.map(day=>jsx79(Chip,{value:day,size:"xs",radius:"xl",disabled:repeatDayOfWeekProps?.readonly,children:day.charAt(0).toUpperCase()},day))})})})]}),jsx79(Group27,{justify:"flex-end",children:jsx79(Button10,{onClick:()=>props.onOk(value),children:"OK"})})]})})}import{jsx as jsx80,jsxs as jsxs44}from"react/jsx-runtime";function ResourcePropertyInput(props){let{property,name,onChange,defaultValue:defaultValue2}=props,defaultPropertyType=props.defaultPropertyType&&props.defaultPropertyType!=="undefined"?props.defaultPropertyType:property.type[0].code,propertyTypes=property.type;if((property.isArray||property.max>1)&&!props.arrayElement){if(defaultPropertyType===PropertyType2.Attachment)return jsx80(AttachmentArrayInput,{name,defaultValue:defaultValue2,onChange,disabled:property.readonly});let indent=propertyTypes[0]?.code!==PropertyType2.Extension;return jsx80(ResourceArrayInput,{property,name,path:props.path,valuePath:props.valuePath,defaultValue:defaultValue2,indent,onChange,outcome:props.outcome})}else return propertyTypes.length>1?jsx80(ElementDefinitionInputSelector,{elementDefinitionTypes:propertyTypes,...props}):jsx80(ElementDefinitionTypeInput,{name,defaultValue:defaultValue2,onChange:newValue=>{if(props.onChange){let newPropName=props.name.replace("[x]",capitalize2(propertyTypes[0].code));props.onChange(newValue,newPropName)}},outcome:props.outcome,elementDefinitionType:propertyTypes[0],min:property.min,max:property.min,binding:property.binding,path:props.path,valuePath:props.valuePath,readOnly:property.readonly})}function ElementDefinitionInputSelector(props){let propertyTypes=props.elementDefinitionTypes,initialPropertyType;props.defaultPropertyType&&(initialPropertyType=propertyTypes.find(t=>t.code===props.defaultPropertyType)),initialPropertyType||(initialPropertyType=propertyTypes[0]);let[selectedType,setSelectedType]=useState40(initialPropertyType);return jsxs44(Group28,{gap:"xs",grow:!0,wrap:"nowrap",align:"flex-start",children:[jsx80(NativeSelect9,{disabled:props.property.readonly,style:{width:"200px"},defaultValue:selectedType.code,"data-testid":props.name&&props.name+"-selector",onChange:e=>{setSelectedType(propertyTypes.find(type=>type.code===e.currentTarget.value))},data:propertyTypes.map(type=>({value:type.code,label:type.code}))}),jsx80(ElementDefinitionTypeInput,{name:props.name,defaultValue:props.defaultValue,outcome:props.outcome,elementDefinitionType:selectedType,onChange:newValue=>{props.onChange&&props.onChange(newValue,props.name.replace("[x]",capitalize2(selectedType.code)))},min:props.property.min,max:props.property.max,binding:props.property.binding,path:props.property.path,valuePath:props.valuePath,readOnly:props.property.readonly})]})}function ElementDefinitionTypeInput(props){let{name,onChange,outcome,binding,path,valuePath,readOnly}=props,required=props.min!==void 0&&props.min>0,propertyType=props.elementDefinitionType.code,elementsContext=useContext20(ElementsContext),defaultValue2=useMemo20(()=>{if(!isComplexTypeCode(propertyType)||!isEmpty6(props.defaultValue))return props.defaultValue;let withDefaults=Object.create(null);if(elementsContext.path===props.path)applyDefaultValuesToElement(withDefaults,elementsContext.elements);else{let key=getPathDifference(elementsContext.path,props.path);if(key===void 0)return props.defaultValue;applyDefaultValuesToElement(withDefaults,elementsContext.elements,key)}return isPopulated11(withDefaults)?withDefaults:props.defaultValue},[propertyType,elementsContext.path,elementsContext.elements,props.path,props.defaultValue]);if(!propertyType)return jsx80("div",{children:"Property type not specified "});function getComplexInputProps(){return{name,defaultValue:defaultValue2,onChange,outcome,path,valuePath,disabled:readOnly}}function getPrimitiveInputProps(){let error=getErrorsForInput(props.outcome,valuePath??path);return{id:name,name,"data-testid":name,defaultValue:defaultValue2,required,error,disabled:readOnly}}switch(propertyType){case PropertyType2.SystemString:case PropertyType2.canonical:case PropertyType2.string:case PropertyType2.time:case PropertyType2.uri:case PropertyType2.url:return props.path==="Project.secret.value[x]"?jsx80(SensitiveTextarea,{...getPrimitiveInputProps(),onChange:e=>{props.onChange&&props.onChange(e.currentTarget.value)}}):jsx80(TextInput17,{...getPrimitiveInputProps(),onChange:e=>{onChange&&onChange(e.currentTarget.value)}});case PropertyType2.date:return jsx80(TextInput17,{...getPrimitiveInputProps(),type:"date",onChange:e=>{onChange&&onChange(e.currentTarget.value)}});case PropertyType2.dateTime:case PropertyType2.instant:return jsx80(DateTimeInput,{...getPrimitiveInputProps(),onChange,outcome});case PropertyType2.decimal:case PropertyType2.integer:case PropertyType2.positiveInt:case PropertyType2.unsignedInt:return jsx80(TextInput17,{...getPrimitiveInputProps(),type:"number",step:propertyType===PropertyType2.decimal?"any":"1",onChange:e=>{if(onChange){let num=e.currentTarget.valueAsNumber;onChange(Number.isNaN(num)?void 0:num)}}});case PropertyType2.code:return jsx80(CodeInput,{...getPrimitiveInputProps(),error:void 0,onChange,binding:binding?.valueSet,creatable:!0,maxValues:1});case PropertyType2.boolean:return jsx80(Checkbox4,{...getPrimitiveInputProps(),defaultChecked:!!defaultValue2,onChange:e=>{onChange&&onChange(e.currentTarget.checked)}});case PropertyType2.base64Binary:case PropertyType2.markdown:return jsx80(Textarea2,{...getPrimitiveInputProps(),spellCheck:propertyType!==PropertyType2.base64Binary,onChange:e=>{onChange&&onChange(e.currentTarget.value)}});case PropertyType2.Address:return jsx80(AddressInput,{...getComplexInputProps()});case PropertyType2.Annotation:return jsx80(AnnotationInput,{...getComplexInputProps()});case PropertyType2.Attachment:return jsx80(AttachmentInput,{...getComplexInputProps()});case PropertyType2.CodeableConcept:return jsx80(CodeableConceptInput,{binding:binding?.valueSet,...getComplexInputProps()});case PropertyType2.Coding:return jsx80(CodingInput,{binding:binding?.valueSet,...getComplexInputProps()});case PropertyType2.ContactDetail:return jsx80(ContactDetailInput,{...getComplexInputProps()});case PropertyType2.ContactPoint:return jsx80(ContactPointInput,{...getComplexInputProps()});case PropertyType2.Extension:return jsx80(ExtensionInput,{...getComplexInputProps(),propertyType:props.elementDefinitionType});case PropertyType2.HumanName:return jsx80(HumanNameInput,{...getComplexInputProps()});case PropertyType2.Identifier:return jsx80(IdentifierInput,{...getComplexInputProps()});case PropertyType2.Money:return jsx80(MoneyInput,{...getComplexInputProps()});case PropertyType2.Period:return jsx80(PeriodInput,{...getComplexInputProps()});case PropertyType2.Duration:case PropertyType2.Quantity:return jsx80(QuantityInput,{...getComplexInputProps()});case PropertyType2.Range:return jsx80(RangeInput,{...getComplexInputProps()});case PropertyType2.Ratio:return jsx80(RatioInput,{...getComplexInputProps()});case PropertyType2.Reference:return jsx80(ReferenceInput,{...getComplexInputProps(),targetTypes:getTargetTypes(props.elementDefinitionType)});case PropertyType2.Timing:return jsx80(TimingInput,{...getComplexInputProps()});case PropertyType2.Dosage:case PropertyType2.UsageContext:default:return jsx80(BackboneElementInput,{...getComplexInputProps(),typeName:propertyType})}}var RESOURCE_TYPE_URL_PREFIXES=[`${HTTP_HL7_ORG}/fhir/StructureDefinition/`,"https://medplum.com/fhir/StructureDefinition/"];function getTargetTypes(elementDefinitionType){return elementDefinitionType?.targetProfile?.map(p=>{let resourceTypePrefix=RESOURCE_TYPE_URL_PREFIXES.find(prefix=>p.startsWith(prefix));return resourceTypePrefix?p.slice(resourceTypePrefix.length):p})}import{jsx as jsx81}from"react/jsx-runtime";function ElementsInput(props){let[value,setValue]=useState41(props.defaultValue??{}),elementsContext=useContext21(ElementsContext),elementsToRender=useMemo21(()=>getElementsToRender(elementsContext.elements),[elementsContext.elements]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}let typedValue={type:props.type,value};return jsx81(Stack12,{style:{flexGrow:1},"data-testid":props.testId,children:elementsToRender.map(([key,element])=>{let[propertyValue,propertyType]=getValueAndTypeFromElement(typedValue,key,element),required=element.min!==void 0&&element.min>0,valuePath=props.valuePath?props.valuePath+"."+key:void 0,resourcePropertyInput=jsx81(ResourcePropertyInput,{property:element,name:key,path:props.path+"."+key,valuePath,defaultValue:propertyValue,defaultPropertyType:propertyType,onChange:(newValue,propName)=>{setValueWrapper(setPropertyValue({...value},key,propName??key,element,newValue))},outcome:props.outcome},key);return props.type==="Extension"||EXTENSION_KEYS.includes(key)?resourcePropertyInput:element.type.length===1&&element.type[0].code==="boolean"?jsx81(CheckboxFormSection,{title:getPathDisplayName5(key),description:element.description,htmlFor:key,fhirPath:element.path,withAsterisk:required,readonly:element.readonly,children:resourcePropertyInput},key):jsx81(FormSection,{title:getPathDisplayName5(key),description:element.description,withAsterisk:required,htmlFor:key,outcome:props.outcome,fhirPath:element.path,errorExpression:valuePath,readonly:element.readonly,children:resourcePropertyInput},key)})})}import{jsx as jsx82,jsxs as jsxs45}from"react/jsx-runtime";function BackboneElementInput(props){let[defaultValue2]=useState42(()=>props.defaultValue??{}),parentElementsContext=useContext22(ElementsContext),profileUrl=props.profileUrl??parentElementsContext?.profileUrl,typeSchema=useMemo22(()=>tryGetDataType2(props.typeName,profileUrl),[props.typeName,profileUrl]),type=typeSchema?.type??props.typeName,contextValue=useMemo22(()=>{if(typeSchema)return buildElementsContext4({parentContext:parentElementsContext,elements:typeSchema.elements,path:props.path,profileUrl:typeSchema.url,accessPolicyResource:props.accessPolicyResource})},[typeSchema,parentElementsContext,props.path,props.accessPolicyResource]);return typeSchema?maybeWrapWithContext(ElementsContext.Provider,contextValue,jsx82(ElementsInput,{path:props.path,valuePath:props.valuePath,type,defaultValue:defaultValue2,onChange:props.onChange,outcome:props.outcome})):jsxs45("div",{children:[type,"\xA0not implemented"]})}import{Button as Button11,Group as Group29}from"@mantine/core";import{useMemo as useMemo23,useState as useState43}from"react";var CalendarInput_default={table:"CalendarInput_table"};function getMonthString(date){return date.toLocaleString("default",{month:"long"})+" "+date.getFullYear()}function getStartMonth(){let result=new Date;return result.setDate(1),result.setHours(0,0,0,0),result}import{jsx as jsx83,jsxs as jsxs46}from"react/jsx-runtime";function CalendarInput(props){let{onChangeMonth,onClick}=props,[month,setMonth]=useState43(getStartMonth);function moveMonth(delta){setMonth(currMonth=>{let newMonth=new Date(currMonth.getTime());return newMonth.setMonth(currMonth.getMonth()+delta),onChangeMonth(newMonth),newMonth})}let grid=useMemo23(()=>buildGrid(month,props.slots),[month,props.slots]);return jsxs46("div",{children:[jsxs46(Group29,{justify:"space-between",gap:"xs",grow:!0,wrap:"nowrap",children:[jsx83("p",{style:{flex:1},children:getMonthString(month)}),jsxs46(Group29,{justify:"flex-end",gap:"xs",children:[jsx83(Button11,{variant:"outline","aria-label":"Previous month",onClick:()=>moveMonth(-1),children:"<"}),jsx83(Button11,{variant:"outline","aria-label":"Next month",onClick:()=>moveMonth(1),children:">"})]})]}),jsxs46("table",{className:CalendarInput_default.table,children:[jsx83("thead",{children:jsxs46("tr",{children:[jsx83("th",{children:"SUN"}),jsx83("th",{children:"MON"}),jsx83("th",{children:"TUE"}),jsx83("th",{children:"WED"}),jsx83("th",{children:"THU"}),jsx83("th",{children:"FRI"}),jsx83("th",{children:"SAT"})]})}),jsx83("tbody",{children:grid.map((week,weekIndex)=>jsx83("tr",{children:week.map((day,dayIndex)=>jsx83("td",{children:day&&jsx83(Button11,{variant:"light",disabled:!day.available,onClick:()=>onClick(day.date),children:day.date.getDate()})},"day-"+dayIndex))},"week-"+weekIndex))})]})]})}function buildGrid(startDate,slots){let d=new Date(startDate.getFullYear(),startDate.getMonth()),grid=[],row=[];for(let i=0;i<d.getDay();i++)row.push(void 0);for(;d.getMonth()===startDate.getMonth();)row.push({date:new Date(d.getTime()),available:isDayAvailable(d,slots)}),d.getDay()===6&&(grid.push(row),row=[]),d.setDate(d.getDate()+1);if(d.getDay()!==0){for(let i=d.getDay();i<7;i++)row.push(void 0);grid.push(row)}return grid}function isDayAvailable(day,slots){for(let slot of slots){let slotStart=new Date(slot.start);if(slotStart.getFullYear()===day.getFullYear()&&slotStart.getMonth()===day.getMonth()&&slotStart.getDate()===day.getDate())return!0}return!1}import{ActionIcon as ActionIcon6,Group as Group30,LoadingOverlay,Paper as Paper2,ScrollArea as ScrollArea2,Skeleton,Stack as Stack13,TextInput as TextInput18,Title as Title5}from"@mantine/core";import{useResizeObserver}from"@mantine/hooks";import{showNotification as showNotification6}from"@mantine/notifications";import{getDisplayString as getDisplayString4,getReferenceString as getReferenceString4,normalizeErrorString as normalizeErrorString6}from"@medplum/core";import{useMedplum as useMedplum20,useResource as useResource3,useSubscription}from"@medplum/react-hooks";import{useCallback as useCallback10,useEffect as useEffect13,useMemo as useMemo24,useRef as useRef13,useState as useState44}from"react";var BaseChat_default={chatPaper:"BaseChat_chatPaper",chatTitle:"BaseChat_chatTitle",chatBody:"BaseChat_chatBody",chatScrollArea:"BaseChat_chatScrollArea",chatInputContainer:"BaseChat_chatInputContainer",chatBubbleOuterWrap:"BaseChat_chatBubbleOuterWrap",chatBubbleRightAlignedInnerWrap:"BaseChat_chatBubbleRightAlignedInnerWrap",chatBubbleLeftAlignedInnerWrap:"BaseChat_chatBubbleLeftAlignedInnerWrap",chatBubble:"BaseChat_chatBubble",chatBubbleName:"BaseChat_chatBubbleName",chatBubbleNameRight:"BaseChat_chatBubbleNameRight"};import{jsx as jsx84,jsxs as jsxs47}from"react/jsx-runtime";function showError(message){showNotification6({color:"red",title:"Error",message,autoClose:!1})}function parseSentTime(communication){let sentTime=new Date(communication.sent??0),sentTimeMins=sentTime.getMinutes().toString();return`${sentTime.getHours()}:${sentTimeMins.length===1?"0":""}${sentTimeMins}`}function upsertCommunications(communications,received,setCommunications){let newCommunications=[...communications],foundNew=!1;for(let comm of received){let existingIdx=newCommunications.findIndex(c=>c.id===comm.id);existingIdx!==-1?newCommunications[existingIdx]=comm:(newCommunications.push(comm),foundNew=!0)}foundNew&&newCommunications.sort((a,b)=>a.sent.localeCompare(b.sent)),setCommunications(newCommunications)}function BaseChat(props){let{title,communications,setCommunications,query,sendMessage,onMessageReceived,onMessageUpdated,inputDisabled,onError,...paperProps}=props,medplum=useMedplum20(),inputRef=useRef13(null),scrollAreaRef=useRef13(null),firstScrollRef=useRef13(!0),initialLoadRef=useRef13(!0),[profile,setProfile]=useState44(medplum.getProfile()),[reconnecting,setReconnecting]=useState44(!1),[loading,setLoading]=useState44(!0);loading||(initialLoadRef.current=!1);let profileRefStr=useMemo24(()=>profile?getReferenceString4(medplum.getProfile()):"",[profile,medplum]),searchMessages=useCallback10(async()=>{setLoading(!0);let searchParams=new URLSearchParams(query);searchParams.append("_sort","-sent"),searchParams.append("sent:missing","false");let searchResult=await medplum.searchResources("Communication",searchParams,{cache:"no-cache"});upsertCommunications(communicationsRef.current,searchResult,setCommunications),setLoading(!1)},[medplum,setCommunications,query]);useEffect13(()=>{searchMessages().catch(err=>showNotification6({color:"red",message:normalizeErrorString6(err)}))},[searchMessages]),useSubscription(`Communication?${query}`,bundle=>{let communication=bundle.entry?.[1]?.resource;upsertCommunications(communicationsRef.current,[communication],setCommunications),getReferenceString4(communication.sender)!==profileRefStr&&(communicationsRef.current.find(c=>c.id===communication.id)?onMessageUpdated?.(communication):onMessageReceived?.(communication))},{onWebSocketClose:useCallback10(()=>{reconnecting||setReconnecting(!0),showNotification6({color:"red",message:"Live chat disconnected. Attempting to reconnect..."})},[reconnecting]),onWebSocketOpen:useCallback10(()=>{reconnecting&&showNotification6({color:"green",message:"Live chat reconnected."})},[reconnecting]),onSubscriptionConnect:useCallback10(()=>{reconnecting&&(searchMessages().catch(err=>showNotification6({color:"red",message:normalizeErrorString6(err)})),setReconnecting(!1))},[reconnecting,searchMessages]),onError:useCallback10(err=>{onError?onError(err):showError(normalizeErrorString6(err))},[onError])});let sendMessageInternal=useCallback10(formData=>{inputDisabled||(inputRef.current&&(inputRef.current.value=""),sendMessage(formData.message),scrollToBottomRef.current=!0)},[inputDisabled,sendMessage]);useEffect13(()=>{let latestProfile=medplum.getProfile();profile?.id!==latestProfile?.id&&(setProfile(latestProfile),setCommunications([]))});let[parentRef,parentRect]=useResizeObserver(),communicationsRef=useRef13(communications);communicationsRef.current=communications;let prevCommunicationsRef=useRef13(communications),scrollToBottomRef=useRef13(!0);useEffect13(()=>{communications!==prevCommunicationsRef.current&&(scrollToBottomRef.current=!0),prevCommunicationsRef.current=communications},[communications]),useEffect13(()=>{scrollToBottomRef.current&&scrollAreaRef.current?.scrollTo&&(scrollAreaRef.current.scrollTo({top:scrollAreaRef.current.scrollHeight,...firstScrollRef.current?{duration:0}:{behavior:"smooth"}}),firstScrollRef.current=!1,scrollToBottomRef.current=!1)});let myLastDeliveredId=useMemo24(()=>{let i=communications.length;for(;i--;){let comm=communications[i];if(comm.sender?.reference===profileRefStr&&comm.received)return comm.id}return""},[communications,profileRefStr]);return profile?jsxs47(Paper2,{className:BaseChat_default.chatPaper,p:0,radius:"md",...paperProps,children:[jsx84(Title5,{order:2,className:BaseChat_default.chatTitle,children:title}),jsx84("div",{className:BaseChat_default.chatBody,ref:parentRef,children:initialLoadRef.current?jsxs47(Stack13,{align:"stretch",mt:"lg",children:[jsxs47(Group30,{justify:"flex-start",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(Skeleton,{height:38,circle:!0,ml:"md"}),jsx84(ChatBubbleSkeleton,{alignment:"left",parentWidth:parentRect.width})]}),jsxs47(Group30,{justify:"flex-end",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(ChatBubbleSkeleton,{alignment:"right",parentWidth:parentRect.width}),jsx84(Skeleton,{height:38,circle:!0,mr:"md"})]}),jsxs47(Group30,{justify:"flex-start",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(Skeleton,{height:38,circle:!0,ml:"md"}),jsx84(ChatBubbleSkeleton,{alignment:"left",parentWidth:parentRect.width})]})]},"skeleton-chat-messages"):jsxs47(ScrollArea2,{viewportRef:scrollAreaRef,className:BaseChat_default.chatScrollArea,h:parentRect.height,children:[jsx84(LoadingOverlay,{visible:loading||reconnecting,style:{width:parentRect.width,height:parentRect.height,position:"absolute",zIndex:1}}),communications.map((c,i)=>{let prevCommunication=i>0?communications[i-1]:void 0,prevCommTime=prevCommunication?parseSentTime(prevCommunication):void 0,currCommTime=parseSentTime(c);return jsxs47(Stack13,{align:"stretch",children:[(!prevCommTime||currCommTime!==prevCommTime)&&jsx84("div",{style:{textAlign:"center"},children:currCommTime}),c.sender?.reference===profileRefStr?jsxs47(Group30,{justify:"flex-end",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(ChatBubble,{alignment:"right",communication:c,showDelivered:!!c.received&&c.id===myLastDeliveredId}),jsx84(ResourceAvatar,{radius:"xl",color:"orange",value:c.sender})]}):jsxs47(Group30,{justify:"flex-start",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(ResourceAvatar,{radius:"xl",value:c.sender}),jsx84(ChatBubble,{alignment:"left",communication:c})]})]},`${c.id}--${c.meta?.versionId??"no-version"}`)})]})}),jsx84("div",{className:BaseChat_default.chatInputContainer,children:jsx84(Form,{onSubmit:sendMessageInternal,children:jsx84(TextInput18,{ref:inputRef,name:"message",placeholder:inputDisabled?"Replies are disabled":"Type a message...",radius:"xl",rightSectionWidth:42,disabled:inputDisabled,rightSection:inputDisabled?void 0:jsx84(ActionIcon6,{type:"submit",size:"1.5rem",radius:"xl",color:"blue",variant:"filled","aria-label":"Send message",children:jsx84(IconArrowRight,{size:"1rem",stroke:1.5})})})})})]}):null}function ChatBubble(props){let{communication,alignment,showDelivered}=props,content=communication.payload?.[0]?.contentString||"",seenTime=new Date(communication.received??-1),senderResource=useResource3(communication.sender);return jsxs47("div",{className:BaseChat_default.chatBubbleOuterWrap,children:[jsx84("div",{className:clsx_default(BaseChat_default.chatBubbleName,alignment==="right"&&BaseChat_default.chatBubbleNameRight),"aria-label":"Sender name",children:senderResource?getDisplayString4(senderResource):"[Unknown sender]"}),jsx84("div",{className:alignment==="left"?BaseChat_default.chatBubbleLeftAlignedInnerWrap:BaseChat_default.chatBubbleRightAlignedInnerWrap,children:jsx84("div",{className:BaseChat_default.chatBubble,children:content})}),showDelivered&&jsxs47("div",{style:{textAlign:"right"},children:["Delivered ",seenTime.getHours(),":",seenTime.getMinutes().toString().length===1?"0":"",seenTime.getMinutes()]})]})}function ChatBubbleSkeleton(props){let{alignment,parentWidth}=props;return jsxs47("div",{className:BaseChat_default.chatBubbleOuterWrap,children:[jsx84("div",{className:BaseChat_default.chatBubbleName,"aria-label":"Placeholder sender name",children:jsx84("div",{style:{position:"relative"},children:jsx84(Skeleton,{height:14,width:"100px",radius:"l",ml:alignment==="left"?"sm":void 0,style:alignment==="right"?{position:"absolute",right:5,top:-15}:void 0})})}),jsx84("div",{className:alignment==="left"?BaseChat_default.chatBubbleLeftAlignedInnerWrap:BaseChat_default.chatBubbleRightAlignedInnerWrap,children:jsx84("div",{className:BaseChat_default.chatBubble,children:jsx84(Skeleton,{height:14,width:parentWidth*.5,radius:"l"})})})]})}import{ActionIcon as ActionIcon7}from"@mantine/core";import{useMedplumProfile as useMedplumProfile4}from"@medplum/react-hooks";import{useEffect as useEffect14,useState as useState45}from"react";var ChatModal_default={iconContainer:"ChatModal_iconContainer",icon:"ChatModal_icon",chatModalContainer:"ChatModal_chatModalContainer"};import{Fragment as Fragment26,jsx as jsx85,jsxs as jsxs48}from"react/jsx-runtime";function ChatModal(props){let{open,children}=props,profile=useMedplumProfile4(),[opened,setOpened]=useState45(open??!1);return useEffect14(()=>{setOpened(prevVal=>open??prevVal)},[open]),profile?jsxs48(Fragment26,{children:[opened&&jsx85("div",{className:ChatModal_default.chatModalContainer,children}),opened?jsx85("div",{className:ChatModal_default.iconContainer,children:jsx85(ActionIcon7,{className:ChatModal_default.icon,color:"blue",size:"lg",radius:"xl",variant:"outline",onClick:()=>setOpened(!1),"aria-label":"Close chat",children:jsx85(IconChevronDown,{size:"1.625rem"})})}):jsx85("div",{className:ChatModal_default.iconContainer,children:jsx85(ActionIcon7,{className:ChatModal_default.icon,color:"blue",size:"lg",radius:"xl",variant:"outline",onClick:()=>setOpened(!0),"aria-label":"Open chat",children:jsx85(IconChevronUp,{size:"1.625rem"})})})]}):null}import{createReference as createReference3,formatCodeableConcept as formatCodeableConcept2,getReferenceString as getReferenceString5}from"@medplum/core";import{useMedplum as useMedplum21,useMedplumProfile as useMedplumProfile5,usePrevious}from"@medplum/react-hooks";import{useCallback as useCallback11,useEffect as useEffect15,useMemo as useMemo25,useState as useState46}from"react";import{jsx as jsx86}from"react/jsx-runtime";function ThreadChat(props){let{thread,title,onMessageSent,inputDisabled,onError}=props,medplum=useMedplum21(),profile=useMedplumProfile5(),prevThreadId=usePrevious(thread?.id),[communications,setCommunications]=useState46([]),profileRef=useMemo25(()=>profile?createReference3(profile):void 0,[profile]),threadRef=useMemo25(()=>createReference3(thread),[thread]);useEffect15(()=>{thread?.id!==prevThreadId&&setCommunications([])},[thread?.id,prevThreadId]);let sendMessage=useCallback11(message=>{let profileRefStr=profileRef?getReferenceString5(profileRef):void 0;profileRefStr&&medplum.createResource({resourceType:"Communication",status:"in-progress",sender:profileRef,recipient:thread.recipient?.filter(ref=>getReferenceString5(ref)!==profileRefStr)??[],sent:new Date().toISOString(),payload:[{contentString:message}],partOf:[threadRef]}).then(communication=>{setCommunications([...communications,communication]),onMessageSent?.(communication)}).catch(console.error)},[medplum,profileRef,thread,threadRef,communications,onMessageSent]),onMessageReceived=useMemo25(()=>thread.recipient?.length===2?message=>{message.received&&message.status==="completed"||medplum.updateResource({...message,received:message.received??new Date().toISOString(),status:"completed"}).catch(console.error)}:void 0,[medplum,thread.recipient?.length]);return profile?jsx86(BaseChat,{title:title??(thread?.topic?formatCodeableConcept2(thread.topic):"[No thread title]"),communications,setCommunications,query:`part-of=Communication/${thread.id}`,sendMessage,onMessageReceived,inputDisabled,onError}):null}import{ActionIcon as ActionIcon9,Center as Center7,Group as Group34,Loader as Loader3,ScrollArea as ScrollArea3,TextInput as TextInput19}from"@mantine/core";import{showNotification as showNotification7,updateNotification}from"@mantine/notifications";import{createReference as createReference4,normalizeErrorString as normalizeErrorString8}from"@medplum/core";import{useMedplum as useMedplum25,useResource as useResource7}from"@medplum/react-hooks";import{useCallback as useCallback12,useEffect as useEffect19,useRef as useRef14,useState as useState52}from"react";import{Group as Group32,List,Stack as Stack15,Text as Text13,Title as Title6}from"@mantine/core";import{capitalize as capitalize3,formatCodeableConcept as formatCodeableConcept3,formatDateTime as formatDateTime2,formatObservationValue,isReference as isReference2}from"@medplum/core";import{useMedplum as useMedplum22,useResource as useResource5}from"@medplum/react-hooks";import{useEffect as useEffect16,useState as useState48}from"react";import{Blockquote,Stack as Stack14}from"@mantine/core";var NoteDisplay_default={noteBody:"NoteDisplay_noteBody",noteCite:"NoteDisplay_noteCite",noteRoot:"NoteDisplay_noteRoot"};import{jsx as jsx87}from"react/jsx-runtime";function NoteDisplay({value}){return value?jsx87(Stack14,{justify:"flex-start",gap:"xs",children:value.map(note=>note.text&&jsx87(Blockquote,{classNames:{cite:NoteDisplay_default.noteCite,root:NoteDisplay_default.noteRoot},cite:note.authorReference?.display||note.authorString,icon:null,children:note.text},`note-${note.text}`))}):null}import{Group as Group31}from"@mantine/core";import{Text as Text12}from"@mantine/core";import{getDisplayString as getDisplayString5,isOk,normalizeErrorString as normalizeErrorString7}from"@medplum/core";import{useResource as useResource4}from"@medplum/react-hooks";import{useState as useState47}from"react";import{jsx as jsx88}from"react/jsx-runtime";function ResourceName(props){let{value,link,...rest}=props,[outcome,setOutcome]=useState47(),resource=useResource4(value,setOutcome),text;if(outcome&&!isOk(outcome))text=`[${normalizeErrorString7(outcome)}]`;else if(resource)text=getDisplayString5(resource);else return null;return link?jsx88(MedplumLink,{to:value,...rest,children:text}):jsx88(Text12,{component:"span",...rest,children:text})}import{jsx as jsx89,jsxs as jsxs49}from"react/jsx-runtime";function ResourceBadge(props){return jsxs49(Group31,{gap:"xs",children:[jsx89(ResourceAvatar,{size:24,radius:12,value:props.value,link:props.link}),jsx89(ResourceName,{value:props.value,link:props.link})]})}import{Badge}from"@mantine/core";import{jsx as jsx90}from"react/jsx-runtime";var statusToColor={draft:"blue",active:"blue","on-hold":"yellow",revoked:"red",completed:"green","entered-in-error":"red",unknown:"gray",retired:"gray",registered:"blue",preliminary:"blue",final:"green",amended:"yellow",corrected:"yellow",cancelled:"red",requested:"blue",received:"blue",accepted:"blue",rejected:"red",ready:"blue","in-progress":"blue",failed:"red",proposed:"blue",pending:"blue",booked:"blue",arrived:"blue",fulfilled:"green",noshow:"red","checked-in":"blue",waitlist:"gray",routine:"gray",urgent:"red",asap:"red",stat:"red","not-done":"red",connected:"green",disconnected:"red"};function StatusBadge(props){return jsx90(Badge,{color:statusToColor[props.status],children:props.status})}var DiagnosticReportDisplay_default={table:"DiagnosticReportDisplay_table",criticalRow:"DiagnosticReportDisplay_criticalRow",noteBody:"DiagnosticReportDisplay_noteBody",noteCite:"DiagnosticReportDisplay_noteCite",noteRoot:"DiagnosticReportDisplay_noteRoot"};import{Fragment as Fragment27,jsx as jsx91,jsxs as jsxs50}from"react/jsx-runtime";DiagnosticReportDisplay.defaultProps={hideObservationNotes:!1,hideSpecimenInfo:!1};function DiagnosticReportDisplay(props){let medplum=useMedplum22(),diagnosticReport=useResource5(props.value),[specimens,setSpecimens]=useState48();if(useEffect16(()=>{diagnosticReport?.specimen&&Promise.allSettled(diagnosticReport.specimen.map(ref=>medplum.readReference(ref))).then(outcomes=>outcomes.filter(outcome=>outcome.status==="fulfilled").map(outcome=>outcome.value)).then(setSpecimens).catch(console.error)},[medplum,diagnosticReport]),!diagnosticReport)return null;let specimenNotes=specimens?.flatMap(spec=>spec.note||[])||[];if(diagnosticReport.presentedForm&&diagnosticReport.presentedForm.length>0){let pf=diagnosticReport.presentedForm[0];pf.contentType?.startsWith("text/plain")&&pf.data&&specimenNotes.push({text:window.atob(pf.data)})}return jsxs50(Stack15,{children:[jsx91(Title6,{children:"Diagnostic Report"}),jsx91(DiagnosticReportHeader,{value:diagnosticReport}),specimens&&!props.hideSpecimenInfo&&SpecimenInfo(specimens),diagnosticReport.result&&jsx91(ObservationTable,{hideObservationNotes:props.hideObservationNotes,value:diagnosticReport.result}),specimenNotes.length>0&&jsx91(NoteDisplay,{value:specimenNotes})]})}function DiagnosticReportHeader({value}){return jsxs50(Group32,{mt:"md",gap:30,children:[value.subject&&jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Subject"}),jsx91(ResourceBadge,{value:value.subject,link:!0})]}),value.resultsInterpreter?.map(interpreter=>jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Interpreter"}),jsx91(ResourceBadge,{value:interpreter,link:!0})]},interpreter.reference)),value.performer?.map(performer=>jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Performer"}),jsx91(ResourceBadge,{value:performer,link:!0})]},performer.reference)),value.issued&&jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Issued"}),jsx91(Text13,{children:formatDateTime2(value.issued)})]}),value.status&&jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Status"}),jsx91(Text13,{children:capitalize3(value.status)})]})]})}function SpecimenInfo(specimens){return jsxs50(Stack15,{gap:"xs",children:[jsx91(Title6,{order:2,size:"h6",children:"Specimens"}),jsx91(List,{type:"ordered",children:specimens?.map(specimen=>jsx91(List.Item,{ml:"sm",children:jsxs50(Group32,{gap:20,children:[jsxs50(Group32,{gap:5,children:[jsx91(Text13,{fw:500,children:"Collected:"})," ",formatDateTime2(specimen.collection?.collectedDateTime)]}),jsxs50(Group32,{gap:5,children:[jsx91(Text13,{fw:500,children:"Received:"})," ",formatDateTime2(specimen.receivedTime)]})]})},`specimen-${specimen.id}`))})]})}function ObservationTable(props){return jsxs50("table",{className:DiagnosticReportDisplay_default.table,children:[jsx91("thead",{children:jsxs50("tr",{children:[jsx91("th",{children:"Test"}),jsx91("th",{children:"Value"}),jsx91("th",{children:"Reference Range"}),jsx91("th",{children:"Interpretation"}),jsx91("th",{children:"Category"}),jsx91("th",{children:"Performer"}),jsx91("th",{children:"Status"})]})}),jsx91("tbody",{children:jsx91(ObservationRowGroup,{value:props.value,ancestorIds:props.ancestorIds,hideObservationNotes:props.hideObservationNotes})})]})}function ObservationRowGroup(props){return jsx91(Fragment27,{children:props.value?.map(observation=>jsx91(ObservationRow,{value:observation,ancestorIds:props.ancestorIds,hideObservationNotes:props.hideObservationNotes},`obs-${isReference2(observation)?observation.reference:observation.id}`))})}function ObservationRow(props){let observation=useResource5(props.value);if(!observation||props.ancestorIds?.includes(observation.id))return null;let displayNotes=!props.hideObservationNotes&&observation.note,critical=isCritical(observation);return jsxs50(Fragment27,{children:[jsxs50("tr",{className:clsx_default({[DiagnosticReportDisplay_default.criticalRow]:critical}),children:[jsx91("td",{rowSpan:displayNotes?2:1,children:jsx91(MedplumLink,{to:observation,children:jsx91(CodeableConceptDisplay,{value:observation.code})})}),jsx91("td",{children:jsx91(ObservationValueDisplay,{value:observation})}),jsx91("td",{children:jsx91(ReferenceRangeDisplay,{value:observation.referenceRange})}),jsx91("td",{children:observation.interpretation&&observation.interpretation.length>0&&jsx91(CodeableConceptDisplay,{value:observation.interpretation[0]})}),jsx91("td",{children:observation.category&&observation.category.length>0&&jsx91(Fragment27,{children:observation.category.map(concept=>jsx91("div",{children:jsx91(CodeableConceptDisplay,{value:concept})},`category-${formatCodeableConcept3(concept)}`))})}),jsx91("td",{children:observation.performer?.map(performer=>jsx91(ReferenceDisplay,{value:performer},performer.reference))}),jsx91("td",{children:observation.status&&jsx91(StatusBadge,{status:observation.status})})]}),observation.hasMember&&jsx91(ObservationRowGroup,{value:observation.hasMember,ancestorIds:props.ancestorIds?[...props.ancestorIds,observation.id]:[observation.id],hideObservationNotes:props.hideObservationNotes}),displayNotes&&jsx91("tr",{children:jsx91("td",{colSpan:6,children:jsx91(NoteDisplay,{value:observation.note})})})]})}function ObservationValueDisplay(props){let obs=props.value;return jsx91(Fragment27,{children:formatObservationValue(obs)})}function ReferenceRangeDisplay(props){let range=props.value&&props.value.length>0&&props.value[0];return range?range.text?jsx91(Fragment27,{children:range.text}):jsx91(RangeDisplay,{value:range}):null}function isCritical(observation){let code=observation.interpretation?.[0]?.coding?.[0]?.code;return code==="AA"||code==="LL"||code==="HH"||code==="A"}var import_rfc6902=__toESM(require_rfc6902(),1);import{Table as Table2}from"@mantine/core";import{arrayify,capitalize as capitalize4,evalFhirPathTyped,getSearchParameterDetails,toTypedValue}from"@medplum/core";import{useMedplum as useMedplum23}from"@medplum/react-hooks";import{useEffect as useEffect17,useMemo as useMemo26,useState as useState50}from"react";import{useState as useState49}from"react";import{Table,Button as Button12}from"@mantine/core";var ResourceDiffRow_default={removed:"ResourceDiffRow_removed",added:"ResourceDiffRow_added"};import{Fragment as Fragment28,jsx as jsx92,jsxs as jsxs51}from"react/jsx-runtime";function ResourceDiffRow(props){let{name,path,property,originalValue,revisedValue}=props,isAttachmentType=!!property?.type?.find(t=>t.code==="Attachment"),[isCollapsed,setIsCollapsed]=useState49(isAttachmentType),toggleCollapse=()=>setIsCollapsed(prev=>!prev);return jsx92(Fragment28,{children:isAttachmentType&&!isCollapsed||!isAttachmentType?jsx92(Fragment28,{children:jsxs51(Table.Tr,{children:[jsx92(Table.Td,{children:name}),jsx92(Table.Td,{className:ResourceDiffRow_default.removed,children:originalValue&&jsx92(ResourcePropertyDisplay,{path,property,propertyType:originalValue.type,value:originalValue.value,ignoreMissingValues:!0})}),jsx92(Table.Td,{className:ResourceDiffRow_default.added,children:revisedValue&&jsx92(ResourcePropertyDisplay,{path,property,propertyType:revisedValue.type,value:revisedValue.value,ignoreMissingValues:!0})})]})}):jsxs51(Table.Tr,{children:[jsx92(Table.Td,{children:name}),jsx92(Table.Td,{colSpan:2,style:{textAlign:"right"},children:jsx92(Button12,{onClick:toggleCollapse,variant:"light",children:"Expand"})})]})})}var ResourceDiffTable_default={root:"ResourceDiffTable_root",removed:"ResourceDiffTable_removed",added:"ResourceDiffTable_added"};import{jsx as jsx93,jsxs as jsxs52}from"react/jsx-runtime";function ResourceDiffTable(props){let medplum=useMedplum23(),{original,revised}=props,[schemaLoaded,setSchemaLoaded]=useState50(!1);useEffect17(()=>{medplum.requestSchema(props.original.resourceType).then(()=>setSchemaLoaded(!0)).catch(console.log)},[medplum,props.original.resourceType]);let diffTable=useMemo26(()=>{if(!schemaLoaded)return null;let typedOriginal=[toTypedValue(original)],typedRevised=[toTypedValue(revised)],result=[],patch=mergePatchOperations((0,import_rfc6902.createPatch)(original,revised));for(let op of patch){let path=op.path,fhirPath=jsonPathToFhirPath(path),property=tryGetElementDefinition(original.resourceType,fhirPath),originalValue=op.op==="add"?void 0:evalFhirPathTyped(fhirPath,typedOriginal),revisedValue=op.op==="remove"?void 0:evalFhirPathTyped(fhirPath,typedRevised);result.push({key:`op-${op.op}-${op.path}`,name:`${capitalize4(op.op)} ${fhirPath}`,path:property?.path??original.resourceType+"."+fhirPath,property,originalValue:touchUpValue(property,originalValue),revisedValue:touchUpValue(property,revisedValue)})}return result},[schemaLoaded,original,revised]);return diffTable?jsxs52(Table2,{className:ResourceDiffTable_default.root,children:[jsx93(Table2.Thead,{children:jsxs52(Table2.Tr,{children:[jsx93(Table2.Th,{}),jsx93(Table2.Th,{children:"Before"}),jsx93(Table2.Th,{children:"After"})]})}),jsx93(Table2.Tbody,{children:diffTable.map(row=>jsx93(ResourceDiffRow,{...row}))})]}):null}function mergePatchOperations(patch){let result=[];for(let patchOperation of patch){let{op,path}=patchOperation;if(path.startsWith("/meta/author")||path.startsWith("/meta/compartment")||path.startsWith("/meta/lastUpdated")||path.startsWith("/meta/versionId"))continue;let count=patch.filter(el=>el.op===op&&el.path===path).length,resultOperation={op,path};count>1&&(op==="add"||op==="remove")&&/\/[0-9-]+$/.test(path)&&(resultOperation.op="replace",resultOperation.path=path.replace(/\/[^/]+$/,"")),result.some(el=>el.op===resultOperation.op&&el.path===resultOperation.path)||result.push(resultOperation)}return result}function jsonPathToFhirPath(path){let parts=path.split("/").filter(Boolean),result="";for(let i=0;i<parts.length;i++){let part=parts[i];part==="-"?result+=".last()":/^\d+$/.test(part)?result+=`[${part}]`:(i>0&&(result+="."),result+=part)}return result.endsWith(".url")&&(result=result.replace(/\.url$/,"")),result}function tryGetElementDefinition(resourceType,fhirPath){return getSearchParameterDetails(resourceType,{resourceType:"SearchParameter",base:[resourceType],code:resourceType+"."+fhirPath,expression:resourceType+"."+fhirPath})?.elementDefinitions?.[0]}function touchUpValue(property,input){return input&&{type:Array.isArray(input)?input[0].type:input.type,value:fixArray(input,!!property?.isArray)}}function fixArray(input,isArray){let inputValue=arrayify(input).flatMap(v=>v.value);return isArray?inputValue:inputValue[0]}import{AccessPolicyInteraction,satisfiedAccessPolicy,tryGetProfile as tryGetProfile4}from"@medplum/core";import{useMedplum as useMedplum24,useResource as useResource6}from"@medplum/react-hooks";import{useEffect as useEffect18,useMemo as useMemo27,useState as useState51}from"react";import{jsx as jsx94}from"react/jsx-runtime";function ResourceTable(props){let{profileUrl}=props,medplum=useMedplum24(),accessPolicy=medplum.getAccessPolicy(),value=useResource6(props.value),[schemaLoaded,setSchemaLoaded]=useState51(!1);useEffect18(()=>{if(value)if(profileUrl)medplum.requestProfileSchema(profileUrl,{expandProfile:!0}).then(()=>{tryGetProfile4(profileUrl)?setSchemaLoaded(!0):console.error(`Schema not found for ${profileUrl}`)}).catch(reason=>{console.error("Error in requestProfileSchema",reason)});else{let schemaName=value.resourceType;medplum.requestSchema(schemaName).then(()=>{setSchemaLoaded(!0)}).catch(console.error)}},[medplum,profileUrl,value]);let accessPolicyResource=useMemo27(()=>value&&satisfiedAccessPolicy(value,AccessPolicyInteraction.READ,accessPolicy),[accessPolicy,value]);return!schemaLoaded||!value?null:jsx94(BackboneElementDisplay,{path:value.resourceType,value:{type:value.resourceType,value:props.forceUseInput?props.value:value},profileUrl,ignoreMissingValues:props.ignoreMissingValues,accessPolicyResource})}import{ActionIcon as ActionIcon8,Group as Group33,Menu as Menu3,Text as Text14}from"@mantine/core";import{formatDateTime as formatDateTime3,getReferenceString as getReferenceString6}from"@medplum/core";var Timeline_default={item:"Timeline_item",itemPadding:"Timeline_itemPadding"};import{jsx as jsx95,jsxs as jsxs53}from"react/jsx-runtime";function Timeline(props){return jsx95(Container,{children:props.children})}function TimelineItem(props){let{resource,profile,padding,popupMenuItems,...others}=props,author=profile??resource.meta?.author,dateTime=props.dateTime??resource.meta?.lastUpdated;return jsxs53(Panel,{"data-testid":"timeline-item",fill:!0,...others,children:[jsxs53(Group33,{justify:"space-between",gap:8,mx:"xs",my:"sm",children:[jsx95(ResourceAvatar,{value:author,link:!0,size:"md"}),jsxs53("div",{style:{flex:1},children:[jsx95(Text14,{size:"sm",children:jsx95(ResourceName,{c:"dark",fw:500,value:author,link:!0})}),jsxs53(Text14,{size:"xs",children:[jsx95(MedplumLink,{c:"dimmed",to:props.resource,children:formatDateTime3(dateTime)}),jsx95(Text14,{component:"span",c:"dimmed",mx:8,children:"\xB7"}),jsx95(MedplumLink,{c:"dimmed",to:props.resource,children:props.resource.resourceType})]})]}),popupMenuItems&&jsxs53(Menu3,{position:"bottom-end",shadow:"md",width:200,children:[jsx95(Menu3.Target,{children:jsx95(ActionIcon8,{color:"gray",variant:"subtle",radius:"xl","aria-label":`Actions for ${getReferenceString6(props.resource)}`,children:jsx95(IconDots,{})})}),popupMenuItems]})]}),jsx95(ErrorBoundary,{children:jsx95("div",{className:clsx_default(Timeline_default.item,{[Timeline_default.itemPadding]:padding}),children:props.children})})]})}function sortByDateAndPriority(resources,timelineResource){resources.sort((a,b)=>{let priority1=getPriorityScore(a,timelineResource),priority2=getPriorityScore(b,timelineResource);return priority1>priority2?1:priority1<priority2?-1:getTime(a,timelineResource)-getTime(b,timelineResource)})}function getPriorityScore(resource,timelineResource){if(!isSameResourceType(resource,timelineResource)){let priority=resource.priority;if(typeof priority=="string")return{stat:4,asap:3,urgent:2}[priority]??0}return 0}function getTime(resource,timelineResource){if(!isSameResourceType(resource,timelineResource)){if(resource.resourceType==="Communication"&&resource.sent)return new Date(resource.sent).getTime();if((resource.resourceType==="DiagnosticReport"||resource.resourceType==="Media"||resource.resourceType==="Observation")&&resource.issued)return new Date(resource.issued).getTime();if(resource.resourceType==="DocumentReference"&&resource.date)return new Date(resource.date).getTime()}let dateTime=resource.meta?.lastUpdated;return dateTime?new Date(dateTime).getTime():0}function isSameResourceType(a,b){return!!b&&a.resourceType===b.resourceType&&a.id===b.id}var ResourceTimeline_default={pinnedComment:"ResourceTimeline_pinnedComment"};import{jsx as jsx96,jsxs as jsxs54}from"react/jsx-runtime";function ResourceTimeline(props){let medplum=useMedplum25(),sender=medplum.getProfile(),inputRef=useRef14(null),resource=useResource7(props.value),[history,setHistory]=useState52(),[items,setItems]=useState52([]),loadTimelineResources=props.loadTimelineResources,itemsRef=useRef14(items);itemsRef.current=items;let sortAndSetItems=useCallback12(newItems=>{sortByDateAndPriority(newItems,resource),newItems.reverse(),setItems(newItems)},[resource]),handleBatchResponse=useCallback12(batchResponse=>{let newItems=[];for(let settledResult of batchResponse){if(settledResult.status!=="fulfilled")continue;let bundle=settledResult.value;if(bundle.type==="history"&&setHistory(bundle),bundle.entry)for(let entry of bundle.entry)newItems.push(entry.resource)}sortAndSetItems(newItems)},[sortAndSetItems]),addResource=useCallback12(resource2=>sortAndSetItems([...itemsRef.current,resource2]),[sortAndSetItems]),loadTimeline=useCallback12(()=>{let resourceType,id;"resourceType"in props.value?(resourceType=props.value.resourceType,id=props.value.id):[resourceType,id]=props.value.reference?.split("/"),loadTimelineResources(medplum,resourceType,id).then(handleBatchResponse).catch(console.error)},[medplum,props.value,loadTimelineResources,handleBatchResponse]);useEffect19(()=>loadTimeline(),[loadTimeline]);function createComment(contentString){!resource||!props.createCommunication||medplum.createResource(props.createCommunication(resource,sender,contentString)).then(result=>addResource(result)).catch(console.error)}function createMedia(attachment){!resource||!props.createMedia||medplum.createResource(props.createMedia(resource,sender,attachment)).then(result=>addResource(result)).then(()=>updateNotification({id:"upload-notification",color:"teal",title:"Upload complete",message:"",icon:jsx96(IconCheck,{size:16}),autoClose:2e3})).catch(reason=>updateNotification({id:"upload-notification",color:"red",title:"Upload error",message:normalizeErrorString8(reason),icon:jsx96(IconFileAlert,{size:16}),autoClose:2e3}))}function onUploadStart(){showNotification7({id:"upload-notification",loading:!0,title:"Initializing upload...",message:"Please wait...",autoClose:!1,withCloseButton:!1})}function onUploadProgress(e){updateNotification({id:"upload-notification",loading:!0,title:"Uploading...",message:getProgressMessage(e),autoClose:!1,withCloseButton:!1})}function onUploadError(outcome){updateNotification({id:"upload-notification",color:"red",title:"Upload error",message:normalizeErrorString8(outcome),icon:jsx96(IconFileAlert,{size:16}),autoClose:2e3})}return resource?jsxs54(Timeline,{children:[props.createCommunication&&jsx96(Panel,{children:jsx96(Form,{testid:"timeline-form",onSubmit:formData=>{createComment(formData.text);let input=inputRef.current;input&&(input.value="",input.focus())},children:jsxs54(Group34,{gap:"xs",wrap:"nowrap",style:{width:"100%"},children:[jsx96(ResourceAvatar,{value:sender}),jsx96(TextInput19,{name:"text",ref:inputRef,placeholder:"Add comment",style:{width:"100%",maxWidth:300}}),jsx96(ActionIcon9,{type:"submit",radius:"xl",color:"blue",variant:"filled",children:jsx96(IconMessage,{size:16})}),jsx96(AttachmentButton,{securityContext:createReference4(resource),onUpload:createMedia,onUploadStart,onUploadProgress,onUploadError,children:props2=>jsx96(ActionIcon9,{...props2,radius:"xl",color:"blue",variant:"filled",children:jsx96(IconCloudUpload,{size:16})})})]})})}),items.map(item=>{if(!item)return null;let key=`${item.resourceType}/${item.id}/${item.meta?.versionId}`,menu=props.getMenu?props.getMenu({primaryResource:resource,currentResource:item,reloadTimeline:loadTimeline}):void 0;if(item.resourceType===resource.resourceType&&item.id===resource.id)return jsx96(HistoryTimelineItem,{history,resource:item,popupMenuItems:menu},key);switch(item.resourceType){case"AuditEvent":return jsx96(AuditEventTimelineItem,{resource:item,popupMenuItems:menu},key);case"Communication":return jsx96(CommunicationTimelineItem,{resource:item,popupMenuItems:menu},key);case"DiagnosticReport":return jsx96(DiagnosticReportTimelineItem,{resource:item,popupMenuItems:menu},key);case"Media":return jsx96(MediaTimelineItem,{resource:item,popupMenuItems:menu},key);default:return jsx96(TimelineItem,{resource:item,padding:!0,children:jsx96(ResourceTable,{value:item,ignoreMissingValues:!0})},key)}})]}):jsx96(Center7,{style:{width:"100%",height:"100%"},children:jsx96(Loader3,{})})}function HistoryTimelineItem(props){let{history,resource,...rest}=props,previous=getPrevious(history,resource);return previous?jsx96(TimelineItem,{resource,padding:!0,...rest,children:jsx96(ResourceDiffTable,{original:previous,revised:props.resource})}):jsxs54(TimelineItem,{resource,padding:!0,...rest,children:[jsx96("h3",{children:"Created"}),jsx96(ResourceTable,{value:resource,ignoreMissingValues:!0,forceUseInput:!0})]})}function getPrevious(history,version){let entries=history.entry??[],index=entries.findIndex(entry=>entry.resource?.meta?.versionId===version.meta?.versionId);if(!(index>=entries.length-1))return entries[index+1].resource}function CommunicationTimelineItem(props){let className=!props.resource.priority||props.resource.priority==="routine"?void 0:ResourceTimeline_default.pinnedComment;return jsx96(TimelineItem,{resource:props.resource,profile:props.resource.sender,dateTime:props.resource.sent,padding:!0,className,popupMenuItems:props.popupMenuItems,children:jsx96("p",{children:props.resource.payload?.[0]?.contentString})})}function MediaTimelineItem(props){let contentType=props.resource.content?.contentType,padding=contentType&&!contentType.startsWith("image/")&&!contentType.startsWith("video/")&&contentType!=="application/pdf";return jsx96(TimelineItem,{resource:props.resource,padding:!!padding,popupMenuItems:props.popupMenuItems,children:jsx96(AttachmentDisplay,{value:props.resource.content})})}function AuditEventTimelineItem(props){return jsx96(TimelineItem,{resource:props.resource,padding:!0,popupMenuItems:props.popupMenuItems,children:jsx96(ScrollArea3,{children:jsx96("pre",{children:props.resource.outcomeDesc})})})}function DiagnosticReportTimelineItem(props){return jsx96(TimelineItem,{resource:props.resource,padding:!0,popupMenuItems:props.popupMenuItems,children:jsx96(DiagnosticReportDisplay,{value:props.resource})})}function getProgressMessage(e){if(e.lengthComputable){let percent=100*e.loaded/e.total;return`Uploaded: ${formatFileSize(e.loaded)} / ${formatFileSize(e.total)} ${percent.toFixed(2)}%`}return`Uploaded: ${formatFileSize(e.loaded)}`}function formatFileSize(bytes){if(bytes===0)return"0.00 B";let e=Math.floor(Math.log(bytes)/Math.log(1024));return(bytes/Math.pow(1024,e)).toFixed(2)+" "+" KMGTP".charAt(e)+"B"}import{jsx as jsx97}from"react/jsx-runtime";function DefaultResourceTimeline(props){let{resource,...rest}=props;return jsx97(ResourceTimeline,{value:resource,loadTimelineResources:async(medplum,resourceType,id)=>{let ref=`${resourceType}/${id}`;return Promise.allSettled([medplum.readHistory(resourceType,id),medplum.search("Task",{_filter:`based-on eq ${ref} or focus eq ${ref} or subject eq ${ref}`,_count:100})])},...rest})}import{createReference as createReference5}from"@medplum/core";import{jsx as jsx98}from"react/jsx-runtime";function EncounterTimeline(props){let{encounter,...rest}=props;return jsx98(ResourceTimeline,{value:encounter,loadTimelineResources:async(medplum,_resourceType,id)=>Promise.allSettled([medplum.readHistory("Encounter",id),medplum.search("Communication","encounter=Encounter/"+id),medplum.search("Media","encounter=Encounter/"+id)]),createCommunication:(resource,sender,text)=>({resourceType:"Communication",status:"completed",encounter:createReference5(resource),subject:resource.subject,sender:createReference5(sender),sent:new Date().toISOString(),payload:[{contentString:text}]}),createMedia:(resource,operator,content)=>({resourceType:"Media",status:"completed",encounter:createReference5(resource),subject:resource.subject,operator:createReference5(operator),issued:new Date().toISOString(),content}),...rest})}import{Button as Button18,Loader as Loader5,Table as Table4}from"@mantine/core";import{normalizeOperationOutcome as normalizeOperationOutcome8}from"@medplum/core";import{useMedplum as useMedplum27}from"@medplum/react-hooks";import{memo,useEffect as useEffect23,useRef as useRef18,useState as useState57}from"react";import{evalFhirPath}from"@medplum/core";import{jsx as jsx99}from"react/jsx-runtime";function FhirPathDisplay(props){let value;try{value=evalFhirPath(props.path,props.resource)}catch(err){return console.warn("FhirPathDisplay:",err),null}if(value.length>1)throw new Error(`Component "path" for "FhirPathDisplay" must resolve to a single element. Received ${value.length} elements [${JSON.stringify(value,null,2)}]`);return jsx99(ResourcePropertyDisplay,{value:value[0]||"",propertyType:props.propertyType})}import{ActionIcon as ActionIcon11,Button as Button17,Center as Center8,Group as Group37,Loader as Loader4,Menu as Menu5,Pagination,Table as Table3,Text as Text16,UnstyledButton as UnstyledButton2}from"@mantine/core";import{DEFAULT_SEARCH_COUNT as DEFAULT_SEARCH_COUNT2,deepEquals,formatSearchQuery,isDataTypeLoaded,normalizeOperationOutcome as normalizeOperationOutcome7}from"@medplum/core";import{useMedplum as useMedplum26}from"@medplum/react-hooks";import{useCallback as useCallback13,useEffect as useEffect22,useRef as useRef17,useState as useState56}from"react";import{Box as Box2,Button as Button13,Modal as Modal3,Text as Text15}from"@mantine/core";import{jsx as jsx100,jsxs as jsxs55}from"react/jsx-runtime";function SearchExportDialog(props){return jsxs55(Modal3,{title:"Export",closeButtonProps:{"aria-label":"Close"},opened:props.visible,onClose:props.onCancel,children:[jsxs55(Box2,{display:"flex",style:{justifyContent:"space-between"},children:[props.exportCsv&&jsx100(ExportButton,{text:"CSV",exportLogic:props.exportCsv,onCancel:props.onCancel}),props.exportTransactionBundle&&jsx100(ExportButton,{text:"Transaction Bundle",exportLogic:props.exportTransactionBundle,onCancel:props.onCancel})]}),jsx100(Text15,{style:{marginTop:"10px",marginLeft:"2px"},children:"Limited to 1000 records"})]})}function ExportButton(props){return jsx100(Button13,{onClick:()=>{props.exportLogic(),props.onCancel()},children:`Export as ${props.text}`})}import{Button as Button14,Group as Group35,Modal as Modal4,MultiSelect,Stack as Stack16}from"@mantine/core";import{getDataType as getDataType2,getSearchParameters,sortStringArray,stringify as stringify2}from"@medplum/core";import{useEffect as useEffect20,useMemo as useMemo28,useRef as useRef15,useState as useState53}from"react";import{capitalize as capitalize5,DEFAULT_SEARCH_COUNT,evalFhirPathTyped as evalFhirPathTyped2,formatDateTime as formatDateTime4,Operator}from"@medplum/core";import{Fragment as Fragment29,jsx as jsx101}from"react/jsx-runtime";var searchParamToOperators={string:[Operator.EQUALS,Operator.NOT,Operator.CONTAINS,Operator.EXACT],fulltext:[Operator.EQUALS,Operator.NOT,Operator.CONTAINS,Operator.EXACT],token:[Operator.EQUALS,Operator.NOT],reference:[Operator.EQUALS,Operator.NOT],numeric:[Operator.EQUALS,Operator.NOT_EQUALS,Operator.GREATER_THAN,Operator.LESS_THAN,Operator.GREATER_THAN_OR_EQUALS,Operator.LESS_THAN_OR_EQUALS],quantity:[Operator.EQUALS,Operator.NOT_EQUALS,Operator.GREATER_THAN,Operator.LESS_THAN,Operator.GREATER_THAN_OR_EQUALS,Operator.LESS_THAN_OR_EQUALS],date:[Operator.EQUALS,Operator.NOT_EQUALS,Operator.GREATER_THAN,Operator.LESS_THAN,Operator.GREATER_THAN_OR_EQUALS,Operator.LESS_THAN_OR_EQUALS,Operator.STARTS_AFTER,Operator.ENDS_BEFORE,Operator.APPROXIMATELY],datetime:[Operator.EQUALS,Operator.NOT_EQUALS,Operator.GREATER_THAN,Operator.LESS_THAN,Operator.GREATER_THAN_OR_EQUALS,Operator.LESS_THAN_OR_EQUALS,Operator.STARTS_AFTER,Operator.ENDS_BEFORE,Operator.APPROXIMATELY],uri:[Operator.EQUALS,Operator.NOT,Operator.ABOVE,Operator.BELOW]},operatorNames={eq:"equals",ne:"not equals",gt:"greater than",lt:"less than",ge:"greater than or equals",le:"less than or equals",sa:"starts after",eb:"ends before",ap:"approximately",sw:"starts with",contains:"contains",exact:"exact",text:"text",not:"not",above:"above",below:"below",in:"in","not-in":"not in","of-type":"of type",missing:"missing",present:"present",identifier:"identifier",iterate:"iterate"};function setFilters(definition,filters){return{...definition,filters,offset:0,name:void 0}}function clearFilters(definition){return setFilters(definition,[])}function clearFiltersOnField(definition,code){return setFilters(definition,(definition.filters??[]).filter(f=>f.code!==code))}function addFilter(definition,field,op,value,opt_clear){opt_clear&&(definition=clearFiltersOnField(definition,field));let nextFilters=[];return definition.filters&&nextFilters.push(...definition.filters),nextFilters.push({code:field,operator:op,value:value??""}),setFilters(definition,nextFilters)}function addField(definition,field){if(definition.fields?.includes(field))return definition;let newFields=[];return definition.fields&&newFields.push(...definition.fields),newFields.push(field),{...definition,fields:newFields,name:void 0}}function deleteFilter(definition,index){if(!definition.filters)return definition;let newFilters=[...definition.filters];return newFilters.splice(index,1),{...definition,filters:newFilters,name:void 0}}function addYesterdayFilter(definition,field){return addDayFilter(definition,field,-1)}function addTodayFilter(definition,field){return addDayFilter(definition,field,0)}function addTomorrowFilter(definition,field){return addDayFilter(definition,field,1)}function addDayFilter(definition,field,delta){let startTime=new Date;startTime.setDate(startTime.getDate()+delta),startTime.setHours(0,0,0,0);let endTime=new Date(startTime.getTime());return endTime.setDate(endTime.getDate()+1),endTime.setTime(endTime.getTime()-1),addDateFilterBetween(definition,field,startTime,endTime)}function addLastMonthFilter(definition,field){return addMonthFilter(definition,field,-1)}function addThisMonthFilter(definition,field){return addMonthFilter(definition,field,0)}function addNextMonthFilter(definition,field){return addMonthFilter(definition,field,1)}function addMonthFilter(definition,field,delta){let startTime=new Date;startTime.setMonth(startTime.getMonth()+delta),startTime.setDate(1),startTime.setHours(0,0,0,0);let endTime=new Date(startTime.getTime());return endTime.setMonth(endTime.getMonth()+1),endTime.setDate(1),endTime.setHours(0,0,0,0),endTime.setTime(endTime.getTime()-1),addDateFilterBetween(definition,field,startTime,endTime)}function addYearToDateFilter(definition,field){let startTime=new Date;return startTime.setMonth(0),startTime.setDate(1),startTime.setHours(0,0,0,0),addDateFilterBetween(definition,field,startTime,new Date)}function addDateFilterBetween(definition,field,d1,d2){return definition=clearFiltersOnField(definition,field),definition=addDateFilterImpl(definition,field,Operator.GREATER_THAN_OR_EQUALS,d1),definition=addDateFilterImpl(definition,field,Operator.LESS_THAN_OR_EQUALS,d2),definition}function addDateFilterImpl(definition,field,op,value){return addFilter(definition,field,op,value.toISOString())}function addMissingFilter(definition,field,value=!0){return addFilter(definition,field,Operator.MISSING,value.toString())}function setOffset(definition,offset){return definition.offset===offset?definition:{...definition,offset,name:void 0}}function setPage(definition,page){let count=definition.count??DEFAULT_SEARCH_COUNT,newOffset=(page-1)*count;return setOffset(definition,newOffset)}function setSort(definition,sort,desc){return sort===getSortField(definition)&&desc!==void 0&&desc===isSortDescending(definition)?definition:{...definition,sortRules:[{code:sort,descending:!!desc}],name:void 0}}function toggleSort(definition,key){let desc=!1;return getSortField(definition)===key&&(desc=!isSortDescending(definition)),setSort(definition,key,desc)}function getSortField(definition){let sortRules=definition.sortRules;if(!sortRules||sortRules.length===0)return;let field=sortRules[0].code;return field.startsWith("-")?field.substr(1):field}function isSortDescending(definition){let sortRules=definition.sortRules;return!sortRules||sortRules.length===0?!1:!!sortRules[0].descending}function getSearchOperators(searchParam){return searchParamToOperators[searchParam.type]}function getOpString(op){return operatorNames[op]??""}function buildFieldNameString(key){let tmp=key;return tmp.includes(".")&&(tmp=tmp.split(".").pop()),tmp==="versionId"?"Version ID":(tmp=tmp.replace("[x]",""),tmp=tmp.replace(/([A-Z])/g," $1"),tmp=tmp.replace(/[-_]/g," "),tmp=tmp.replace(/\s+/g," "),tmp=tmp.trim(),tmp.toLowerCase()==="id"?"ID":tmp.split(/\s/).map(capitalize5).join(" "))}function renderValue(resource,field){let key=field.name;return key==="id"?resource.id:key==="meta.versionId"?resource.meta?.versionId:key==="_lastUpdated"?formatDateTime4(resource.meta?.lastUpdated):field.elementDefinition&&`${resource.resourceType}.${field.name}`===field.elementDefinition.path?renderPropertyValue(resource,field.elementDefinition):field.searchParams&&field.searchParams.length===1&&field.name===field.searchParams[0].code?renderSearchParameterValue(resource,field.searchParams[0]):null}function renderPropertyValue(resource,elementDefinition){let path=elementDefinition.path?.split(".")?.pop()?.replaceAll("[x]","")??"",[value,propertyType]=getValueAndType({type:resource.resourceType,value:resource},path);return value?jsx101(ResourcePropertyDisplay,{path:elementDefinition.path,property:elementDefinition,propertyType,value,maxWidth:200,ignoreMissingValues:!0,link:!1}):null}function renderSearchParameterValue(resource,searchParam){let value=evalFhirPathTyped2(searchParam.expression,[{type:resource.resourceType,value:resource}]);return!value||value.length===0?null:jsx101(Fragment29,{children:value.map((v,index)=>jsx101(ResourcePropertyDisplay,{propertyType:v.type,value:v.value,maxWidth:200,ignoreMissingValues:!0,link:!1},`${index}-${value.length}`))})}import{jsx as jsx102,jsxs as jsxs56}from"react/jsx-runtime";function SearchFieldEditor(props){let wasDropdownOpen=useRef15(!1),[state,setState]=useState53({search:JSON.parse(stringify2(props.search))}),[isDropdownOpen,setIsDropdownOpen]=useState53(!1);useEffect20(()=>{setState({search:props.search})},[props.search]);let allFields=useMemo28(()=>{if(!props.visible)return[];let resourceType=props.search.resourceType,typeSchema=getDataType2(resourceType),searchParams=getSearchParameters(resourceType);return sortStringArray(getFieldsList(typeSchema,searchParams)).map(field=>({value:field,label:buildFieldNameString(field)}))},[props.visible,props.search.resourceType]);if(!props.visible)return null;function handleChange(newFields){setState({search:{...state.search,fields:newFields}})}return jsx102(Modal4,{title:"Fields",closeButtonProps:{"aria-label":"Close"},opened:props.visible,onClose:()=>{props.onCancel()},size:"auto",withOverlay:!0,closeOnClickOutside:!1,overlayProps:{onMouseDownCapture:()=>{wasDropdownOpen.current=isDropdownOpen},onClick:()=>{wasDropdownOpen.current||props.onCancel(),wasDropdownOpen.current=!1},children:jsx102("div",{"data-testid":"overlay-child"})},children:jsxs56(Stack16,{children:[jsx102(MultiSelect,{style:{width:550},placeholder:"Select fields to display",data:allFields,value:state.search.fields??[],onChange:handleChange,onDropdownOpen:()=>setIsDropdownOpen(!0),onDropdownClose:()=>setIsDropdownOpen(!1),maxDropdownHeight:"250px",clearButtonProps:{"aria-label":"Clear selection"},clearable:!0,searchable:!0}),jsx102(Group35,{justify:"flex-end",children:jsx102(Button14,{onClick:()=>props.onOk(state.search),children:"OK"})})]})})}function getFieldsList(typeSchema,searchParams){let result=[],keys=new Set,names=new Set;for(let key of Object.keys(typeSchema.elements))result.push(key),keys.add(key.toLowerCase()),names.add(buildFieldNameString(key));if(searchParams)for(let code of Object.keys(searchParams)){let name=buildFieldNameString(code);!keys.has(code)&&!names.has(name)&&(result.push(code),keys.add(code),names.add(name))}return result}import{ActionIcon as ActionIcon10,Button as Button15,Group as Group36,Modal as Modal5,NativeSelect as NativeSelect10}from"@mantine/core";import{Operator as Operator2,deepClone as deepClone2,getSearchParameters as getSearchParameters2}from"@medplum/core";import{useEffect as useEffect21,useRef as useRef16,useState as useState54}from"react";import{Checkbox as Checkbox5,TextInput as TextInput20}from"@mantine/core";import{getSearchParameterDetails as getSearchParameterDetails2,SearchParameterType}from"@medplum/core";import{jsx as jsx103}from"react/jsx-runtime";function SearchFilterValueInput(props){let details=getSearchParameterDetails2(props.resourceType,props.searchParam),name=props.name??"filter-value";switch(details.type){case SearchParameterType.REFERENCE:return jsx103(ReferenceInput,{name,defaultValue:props.defaultValue?{reference:props.defaultValue}:void 0,targetTypes:props.searchParam.target,autoFocus:props.autoFocus,onChange:newReference=>{newReference?props.onChange(newReference.reference):props.onChange("")}});case SearchParameterType.BOOLEAN:return jsx103(Checkbox5,{name,"data-autofocus":props.autoFocus,"data-testid":name,defaultChecked:props.defaultValue==="true",autoFocus:props.autoFocus,onChange:e=>props.onChange(e.currentTarget.checked.toString())});case SearchParameterType.DATE:return jsx103(TextInput20,{type:"date",name,"data-autofocus":props.autoFocus,"data-testid":name,defaultValue:props.defaultValue,autoFocus:props.autoFocus,onChange:e=>props.onChange(e.currentTarget.value)});case SearchParameterType.DATETIME:return jsx103(DateTimeInput,{name,defaultValue:props.defaultValue,autoFocus:props.autoFocus,onChange:props.onChange});case SearchParameterType.NUMBER:return jsx103(TextInput20,{type:"number",name,"data-autofocus":props.autoFocus,"data-testid":name,defaultValue:props.defaultValue,autoFocus:props.autoFocus,onChange:e=>props.onChange(e.currentTarget.value)});case SearchParameterType.QUANTITY:return jsx103(QuantityInput,{name,path:"",defaultValue:tryParseQuantity(props.defaultValue),autoFocus:props.autoFocus,onChange:newQuantity=>{newQuantity?props.onChange(`${newQuantity.value}`):props.onChange("")}});default:return jsx103(TextInput20,{name,"data-autofocus":props.autoFocus,"data-testid":name,defaultValue:props.defaultValue,autoFocus:props.autoFocus,onChange:e=>props.onChange(e.currentTarget.value),placeholder:"Search value"})}}function tryParseQuantity(value){if(value){let[valueString,systemString,unitString]=value.split("|");if(valueString)return{value:parseFloat(valueString),system:systemString,unit:unitString}}}import{jsx as jsx104,jsxs as jsxs57}from"react/jsx-runtime";function SearchFilterEditor(props){let[search,setSearch]=useState54(deepClone2(props.search)),searchRef=useRef16(search);searchRef.current=search,useEffect21(()=>{setSearch(deepClone2(props.search))},[props.search]);function onAddFilter(filter){setSearch(addFilter(searchRef.current,filter.code,filter.operator,filter.value))}if(!props.visible)return null;let resourceType=props.search.resourceType,searchParams=getSearchParameters2(resourceType)??{},filters=search.filters||[];return jsx104(Modal5,{title:"Filters",closeButtonProps:{"aria-label":"Close"},size:900,opened:props.visible,onClose:props.onCancel,children:jsxs57(Form,{onSubmit:()=>props.onOk(searchRef.current),children:[jsxs57("div",{children:[jsxs57("table",{children:[jsxs57("colgroup",{children:[jsx104("col",{style:{width:200}}),jsx104("col",{style:{width:200}}),jsx104("col",{style:{width:380}}),jsx104("col",{style:{width:40}})]}),jsx104("thead",{children:jsxs57("tr",{children:[jsx104("th",{children:"Field"}),jsx104("th",{children:"Operation"}),jsx104("th",{children:"Value"}),jsx104("th",{})]})}),jsx104("tbody",{children:filters.map((filter,index)=>jsx104(FilterRowInput,{id:`filter-${index}-row`,resourceType,searchParams,value:filter,onChange:newFilter=>{let newFilters=[...filters];newFilters[index]=newFilter,setSearch(setFilters(searchRef.current,newFilters))},onDelete:()=>setSearch(deleteFilter(searchRef.current,index))},`filter-${index}-row`))})]}),jsx104(ArrayAddButton,{propertyDisplayName:"Filter",onClick:()=>onAddFilter({})})]}),jsx104(Group36,{justify:"flex-end",mt:"xl",children:jsx104(Button15,{type:"submit",children:"OK"})})]})})}function FilterRowInput(props){let value=props.value,valueRef=useRef16(value);valueRef.current=value;function setFilterCode(newCode){valueRef.current.code=newCode,valueRef.current.operator=Operator2.EQUALS,valueRef.current.value="",props.onChange(valueRef.current)}function setFilterOperator(newOperator){valueRef.current.operator=newOperator,valueRef.current.value="",props.onChange(valueRef.current)}function setFilterValue(newFilterValue){valueRef.current.value=newFilterValue,props.onChange(valueRef.current)}let searchParam=props.searchParams[value.code],operators=searchParam&&getSearchOperators(searchParam);return jsxs57("tr",{children:[jsx104("td",{children:jsx104(NativeSelect10,{"data-testid":`${props.id}-filter-field`,defaultValue:props.value.code,onChange:e=>setFilterCode(e.currentTarget.value),data:["",...Object.keys(props.searchParams).map(param=>({value:param,label:buildFieldNameString(param)}))]})}),jsx104("td",{children:operators&&jsx104(NativeSelect10,{"data-testid":`${props.id}-filter-operation`,defaultValue:value.operator,onChange:e=>setFilterOperator(e.currentTarget.value),data:["",...operators.map(op=>({value:op,label:getOpString(op)}))]})}),jsx104("td",{children:searchParam&&value.operator&&jsx104(SearchFilterValueInput,{name:`${props.id}-filter-value`,resourceType:props.resourceType,searchParam,defaultValue:value.value,onChange:setFilterValue})}),jsx104("td",{children:props.onDelete&&jsx104(ActionIcon10,{variant:"outline",color:"red",radius:"xl","aria-label":"Delete filter",onClick:props.onDelete,children:jsx104(IconX,{style:{width:"70%",height:"70%"},stroke:1.5})})})]})}import{Button as Button16,Grid,Modal as Modal6}from"@mantine/core";import{useState as useState55}from"react";import{jsx as jsx105,jsxs as jsxs58}from"react/jsx-runtime";function SearchFilterValueDialog(props){let[value,setValue]=useState55(props.defaultValue??"");if(!props.visible||!props.searchParam||!props.filter)return null;function onOk(){props.onOk({...props.filter,value})}return jsx105(Modal6,{title:props.title,size:"xl",opened:props.visible,onClose:props.onCancel,children:jsx105(Form,{onSubmit:onOk,children:jsxs58(Grid,{children:[jsx105(Grid.Col,{span:10,children:jsx105(SearchFilterValueInput,{resourceType:props.resourceType,searchParam:props.searchParam,defaultValue:value,autoFocus:!0,onChange:setValue})}),jsx105(Grid.Col,{span:2,children:jsx105(Button16,{onClick:onOk,fullWidth:!0,children:"OK"})})]})})})}import{formatDateTime as formatDateTime5,getSearchParameterDetails as getSearchParameterDetails3,globalSchema,Operator as Operator3,SearchParameterType as SearchParameterType2}from"@medplum/core";import{Fragment as Fragment30,jsx as jsx106}from"react/jsx-runtime";function SearchFilterValueDisplay(props){let{resourceType,filter}=props,searchParam=globalSchema.types[resourceType].searchParams?.[filter.code];if(searchParam){if(searchParam.type==="reference"&&(filter.operator===Operator3.EQUALS||filter.operator===Operator3.NOT_EQUALS))return jsx106(ResourceName,{value:{reference:filter.value}});let searchParamDetails=getSearchParameterDetails3(resourceType,searchParam);if(filter.code==="_lastUpdated"||searchParamDetails.type===SearchParameterType2.DATETIME)return jsx106(Fragment30,{children:formatDateTime5(filter.value)})}return jsx106(Fragment30,{children:filter.value})}import{Menu as Menu4}from"@mantine/core";import{Operator as Operator4}from"@medplum/core";import{Fragment as Fragment31,jsx as jsx107,jsxs as jsxs59}from"react/jsx-runtime";function SearchPopupMenu(props){if(!props.searchParams)return null;function onSort(searchParam,desc){onChange(setSort(props.search,searchParam.code,desc))}function onClear(searchParam){onChange(clearFiltersOnField(props.search,searchParam.code))}function onPrompt(searchParam,operator){props.onPrompt(searchParam,{code:searchParam.code,operator,value:""})}function onChange(definition){props.onChange(definition)}return props.searchParams.length===1?jsx107(SearchParameterSubMenu,{search:props.search,searchParam:props.searchParams[0],onSort,onPrompt,onChange,onClear}):jsx107(Menu4.Dropdown,{children:props.searchParams.map(searchParam=>jsx107(Menu4.Item,{children:buildFieldNameString(searchParam.code)},searchParam.code))})}function SearchParameterSubMenu(props){switch(props.searchParam.type){case"date":return jsx107(DateFilterSubMenu,{...props});case"number":case"quantity":return jsx107(NumericFilterSubMenu,{...props});case"reference":return jsx107(ReferenceFilterSubMenu,{...props});case"string":return jsx107(TextFilterSubMenu,{...props});case"token":case"uri":return jsx107(TokenFilterSubMenu,{...props});default:return jsxs59(Fragment31,{children:["Unknown search param type: ",props.searchParam.type]})}}function DateFilterSubMenu(props){let{searchParam}=props,code=searchParam.code;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconSortAscending,{size:14}),onClick:()=>props.onSort(searchParam,!1),children:"Sort Oldest to Newest"}),jsx107(Menu4.Item,{leftSection:jsx107(IconSortDescending,{size:14}),onClick:()=>props.onSort(searchParam,!0),children:"Sort Newest to Oldest"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT_EQUALS),children:"Does not equal..."}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconMathLower,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.ENDS_BEFORE),children:"Before..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconMathGreater,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.STARTS_AFTER),children:"After..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconBracketsContain,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Between..."}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addTomorrowFilter(props.search,code)),children:"Tomorrow"}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addTodayFilter(props.search,code)),children:"Today"}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addYesterdayFilter(props.search,code)),children:"Yesterday"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addNextMonthFilter(props.search,code)),children:"Next Month"}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addThisMonthFilter(props.search,code)),children:"This Month"}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addLastMonthFilter(props.search,code)),children:"Last Month"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addYearToDateFilter(props.search,code)),children:"Year to date"}),jsx107(CommonMenuItems,{...props})]})}function NumericFilterSubMenu(props){let{searchParam}=props;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconSortAscending,{size:14}),onClick:()=>props.onSort(searchParam,!1),children:"Sort Smallest to Largest"}),jsx107(Menu4.Item,{leftSection:jsx107(IconSortDescending,{size:14}),onClick:()=>props.onSort(searchParam,!0),children:"Sort Largest to Smallest"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT_EQUALS),children:"Does not equal..."}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconMathGreater,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.GREATER_THAN),children:"Greater than..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconSettings,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.GREATER_THAN_OR_EQUALS),children:"Greater than or equal to..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconMathLower,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.LESS_THAN),children:"Less than..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconSettings,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.LESS_THAN_OR_EQUALS),children:"Less than or equal to..."}),jsx107(CommonMenuItems,{...props})]})}function ReferenceFilterSubMenu(props){let{searchParam}=props;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT),children:"Does not equal..."}),jsx107(CommonMenuItems,{...props})]})}function TextFilterSubMenu(props){let{searchParam}=props;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconSortAscending,{size:14}),onClick:()=>props.onSort(searchParam,!1),children:"Sort A to Z"}),jsx107(Menu4.Item,{leftSection:jsx107(IconSortDescending,{size:14}),onClick:()=>props.onSort(searchParam,!0),children:"Sort Z to A"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT),children:"Does not equal..."}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconBucket,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.CONTAINS),children:"Contains..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconBucketOff,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Does not contain..."}),jsx107(CommonMenuItems,{...props})]})}function TokenFilterSubMenu(props){let{searchParam}=props;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT),children:"Does not equal..."}),jsx107(CommonMenuItems,{...props})]})}function CommonMenuItems(props){let{searchParam}=props,code=searchParam.code;return jsxs59(Fragment31,{children:[jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconBleach,{size:14}),onClick:()=>props.onChange(addMissingFilter(props.search,code)),children:"Missing"}),jsx107(Menu4.Item,{leftSection:jsx107(IconBleachOff,{size:14}),onClick:()=>props.onChange(addMissingFilter(props.search,code,!1)),children:"Not missing"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconX,{size:14}),onClick:()=>props.onClear(searchParam),children:"Clear filters"})]})}var SearchControl_default={root:"SearchControl_root",table:"SearchControl_table",tr:"SearchControl_tr",th:"SearchControl_th",control:"SearchControl_control",icon:"SearchControl_icon"};import{getElementDefinition,getSearchParameter,getSearchParameterDetails as getSearchParameterDetails4,getSearchParameters as getSearchParameters3}from"@medplum/core";function getFieldDefinitions(search){let resourceType=search.resourceType,fields=[];for(let name of search.fields||["id","_lastUpdated"])fields.push(getFieldDefinition(resourceType,name));return fields}function getFieldDefinition(resourceType,name){if(name==="_lastUpdated")return{name:"_lastUpdated",searchParams:[{resourceType:"SearchParameter",base:["Resource"],code:"_lastUpdated",name:"_lastUpdated",type:"date",expression:"Resource.meta.lastUpdated"}]};if(name==="meta.versionId")return{name:"meta.versionId",searchParams:[{resourceType:"SearchParameter",base:["Resource"],code:"_versionId",name:"_versionId",type:"token",expression:"Resource.meta.versionId"}]};let exactElementDefinition=getElementDefinition(resourceType,name),exactSearchParam=getSearchParameter(resourceType,name.toLowerCase());if(exactElementDefinition&&exactSearchParam)return{name,elementDefinition:exactElementDefinition,searchParams:[exactSearchParam]};if(exactElementDefinition){let allSearchParams=getSearchParameters3(resourceType),searchParams;if(allSearchParams){let pathRegex=new RegExp(`${resourceType}\\.${name.replaceAll("[x]","")}([^\\w-]|$)`);searchParams=Object.values(allSearchParams).filter(p=>!!p.expression&&pathRegex.test(p?.expression)),searchParams.length===0&&(searchParams=void 0)}return{name,elementDefinition:exactElementDefinition,searchParams}}if(exactSearchParam){let details=getSearchParameterDetails4(resourceType,exactSearchParam);return{name,elementDefinition:details.elementDefinitions?.[0],searchParams:[exactSearchParam]}}return{name}}import{Fragment as Fragment32,jsx as jsx108,jsxs as jsxs60}from"react/jsx-runtime";var SearchChangeEvent=class extends Event{constructor(definition){super("change"),this.definition=definition}},SearchLoadEvent=class extends Event{constructor(response){super("load"),this.response=response}},SearchClickEvent=class extends Event{constructor(resource,browserEvent){super("click"),this.resource=resource,this.browserEvent=browserEvent}};function SearchControl(props){let medplum=useMedplum26(),[outcome,setOutcome]=useState56(),{search,onLoad}=props,[memoizedSearch,setMemoizedSearch]=useState56(search);deepEquals(search,memoizedSearch)||setMemoizedSearch(search);let[state,setState]=useState56({selected:{},fieldEditorVisible:!1,filterEditorVisible:!1,exportDialogVisible:!1,filterDialogVisible:!1}),stateRef=useRef17(state);stateRef.current=state;let total=memoizedSearch.total??"accurate",loadResults=useCallback13(options=>{setOutcome(void 0),medplum.requestSchema(memoizedSearch.resourceType).then(()=>medplum.search(memoizedSearch.resourceType,formatSearchQuery({...memoizedSearch,total,fields:void 0}),options)).then(response=>{setState({...stateRef.current,searchResponse:response}),onLoad&&onLoad(new SearchLoadEvent(response))}).catch(reason=>{setState({...stateRef.current,searchResponse:void 0}),setOutcome(normalizeOperationOutcome7(reason))})},[medplum,memoizedSearch,total,onLoad]),refreshResults=useCallback13(()=>{setState({...stateRef.current,searchResponse:void 0}),loadResults({cache:"reload"})},[loadResults]);useEffect22(()=>{loadResults()},[loadResults]);function handleSingleCheckboxClick(e,id){e.stopPropagation();let checked=e.target.checked,newSelected={...stateRef.current.selected};checked?newSelected[id]=!0:delete newSelected[id],setState({...stateRef.current,selected:newSelected})}function handleAllCheckboxClick(e){e.stopPropagation();let checked=e.target.checked,newSelected={},searchResponse=stateRef.current.searchResponse;checked&&searchResponse?.entry&&searchResponse.entry.forEach(entry=>{entry.resource?.id&&(newSelected[entry.resource.id]=!0)}),setState({...stateRef.current,selected:newSelected})}function isAllSelected(){let state2=stateRef.current;if(!state2.searchResponse?.entry||state2.searchResponse.entry.length===0)return!1;for(let e of state2.searchResponse.entry)if(e.resource?.id&&!state2.selected[e.resource.id])return!1;return!0}function emitSearchChange(newSearch){props.onChange&&props.onChange(new SearchChangeEvent(newSearch))}function handleRowClick(e,resource){if(isCheckboxCell(e.target)||e.button===2)return;killEvent(e);let isAux=e.button===1||e.ctrlKey||e.metaKey;!isAux&&props.onClick&&props.onClick(new SearchClickEvent(resource,e)),isAux&&props.onAuxClick&&props.onAuxClick(new SearchClickEvent(resource,e))}function isExportPassed(){return!!(props.onExport??props.onExportCsv??props.onExportTransactionBundle)}if(outcome)return jsx108(OperationOutcomeAlert,{outcome});if(!isDataTypeLoaded(memoizedSearch.resourceType))return jsx108(Center8,{style:{width:"100%",height:"100%"},children:jsx108(Loader4,{})});let checkboxColumn=props.checkboxesEnabled,fields=getFieldDefinitions(memoizedSearch),resourceType=memoizedSearch.resourceType,lastResult=state.searchResponse,resources=lastResult?.entry?.map(e=>e.resource),buttonVariant="subtle",buttonColor="gray",iconSize=16,isMobile=window.innerWidth<768;return jsxs60("div",{className:SearchControl_default.root,"data-testid":"search-control",children:[!props.hideToolbar&&jsxs60(Group37,{justify:"space-between",mb:"xl",children:[jsxs60(Group37,{gap:2,children:[jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconColumns,{size:iconSize}),onClick:()=>setState({...stateRef.current,fieldEditorVisible:!0}),children:"Fields"}),jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconFilter,{size:iconSize}),onClick:()=>setState({...stateRef.current,filterEditorVisible:!0}),children:"Filters"}),props.onNew&&jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconFilePlus,{size:iconSize}),onClick:props.onNew,children:"New..."}),!isMobile&&isExportPassed()&&jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconTableExport,{size:iconSize}),onClick:props.onExport?props.onExport:()=>setState({...stateRef.current,exportDialogVisible:!0}),children:"Export..."}),!isMobile&&props.onDelete&&jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconTrash,{size:iconSize}),onClick:()=>props.onDelete(Object.keys(state.selected)),children:"Delete..."}),!isMobile&&props.onBulk&&jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconBoxMultiple,{size:iconSize}),onClick:()=>props.onBulk(Object.keys(state.selected)),children:"Bulk..."})]}),jsxs60(Group37,{gap:2,children:[lastResult&&jsxs60(Text16,{size:"xs",c:"dimmed","data-testid":"count-display",children:[getStart(memoizedSearch,lastResult).toLocaleString(),"-",getEnd(memoizedSearch,lastResult).toLocaleString(),lastResult.total!==void 0&&` of ${memoizedSearch.total==="estimate"?"~":""}${lastResult.total?.toLocaleString()}`]}),jsx108(ActionIcon11,{variant:buttonVariant,color:buttonColor,title:"Refresh",onClick:refreshResults,children:jsx108(IconRefresh,{size:iconSize})})]})]}),jsxs60(Table3,{className:SearchControl_default.table,children:[jsxs60(Table3.Thead,{children:[jsxs60(Table3.Tr,{children:[checkboxColumn&&jsx108(Table3.Th,{children:jsx108("input",{type:"checkbox",value:"checked","aria-label":"all-checkbox","data-testid":"all-checkbox",checked:isAllSelected(),onChange:e=>handleAllCheckboxClick(e)})}),fields.map(field=>jsx108(Table3.Th,{children:jsxs60(Menu5,{shadow:"md",width:240,position:"bottom-end",children:[jsx108(Menu5.Target,{children:jsx108(UnstyledButton2,{className:SearchControl_default.control,p:2,children:jsxs60(Group37,{justify:"space-between",wrap:"nowrap",children:[jsx108(Text16,{fw:500,children:buildFieldNameString(field.name)}),jsx108(Center8,{className:SearchControl_default.icon,children:jsx108(IconAdjustmentsHorizontal,{size:14,stroke:1.5})})]})})}),jsx108(SearchPopupMenu,{search:memoizedSearch,searchParams:field.searchParams,onPrompt:(searchParam,filter)=>{setState({...stateRef.current,filterDialogVisible:!0,filterDialogSearchParam:searchParam,filterDialogFilter:filter})},onChange:result=>{emitSearchChange(result)}})]})},field.name))]}),!props.hideFilters&&jsxs60(Table3.Tr,{children:[checkboxColumn&&jsx108(Table3.Th,{}),fields.map(field=>jsx108(Table3.Th,{children:field.searchParams&&jsx108(FilterDescription,{resourceType,searchParams:field.searchParams,filters:memoizedSearch.filters})},field.name))]})]}),jsx108(Table3.Tbody,{children:resources?.map(resource=>resource&&jsxs60(Table3.Tr,{className:SearchControl_default.tr,"data-testid":"search-control-row",onClick:e=>handleRowClick(e,resource),onAuxClick:e=>handleRowClick(e,resource),children:[checkboxColumn&&jsx108(Table3.Td,{children:jsx108("input",{type:"checkbox",value:"checked","data-testid":"row-checkbox","aria-label":`Checkbox for ${resource.id}`,checked:!!state.selected[resource.id],onChange:e=>handleSingleCheckboxClick(e,resource.id)})}),fields.map(field=>jsx108(Table3.Td,{children:renderValue(resource,field)},field.name))]},resource.id))})]}),!resources?.length&&jsx108(Container,{children:jsx108(Center8,{style:{height:150},children:jsx108(Text16,{size:"xl",c:"dimmed",children:"No results"})})}),lastResult&&jsx108(Center8,{m:"md",p:"md",children:jsx108(Pagination,{value:getPage(memoizedSearch),total:getTotalPages(memoizedSearch,lastResult),onChange:newPage=>emitSearchChange(setPage(memoizedSearch,newPage)),getControlProps:control=>{switch(control){case"previous":return{"aria-label":"Previous page"};case"next":return{"aria-label":"Next page"};default:return{}}}})}),jsx108(SearchFieldEditor,{search:memoizedSearch,visible:stateRef.current.fieldEditorVisible,onOk:result=>{emitSearchChange(result),setState({...stateRef.current,fieldEditorVisible:!1})},onCancel:()=>{setState({...stateRef.current,fieldEditorVisible:!1})}}),jsx108(SearchFilterEditor,{search:memoizedSearch,visible:stateRef.current.filterEditorVisible,onOk:result=>{emitSearchChange(result),setState({...stateRef.current,filterEditorVisible:!1})},onCancel:()=>{setState({...stateRef.current,filterEditorVisible:!1})}}),jsx108(SearchExportDialog,{visible:stateRef.current.exportDialogVisible,exportCsv:props.onExportCsv,exportTransactionBundle:props.onExportTransactionBundle,onCancel:()=>{setState({...stateRef.current,exportDialogVisible:!1})}}),jsx108(SearchFilterValueDialog,{visible:stateRef.current.filterDialogVisible,title:state.filterDialogSearchParam?.code?buildFieldNameString(state.filterDialogSearchParam.code):"",resourceType,searchParam:state.filterDialogSearchParam,filter:state.filterDialogFilter,defaultValue:"",onOk:filter=>{emitSearchChange(addFilter(memoizedSearch,filter.code,filter.operator,filter.value)),setState({...stateRef.current,filterDialogVisible:!1})},onCancel:()=>{setState({...stateRef.current,filterDialogVisible:!1})}},state.filterDialogSearchParam?.code)]})}var MemoizedSearchControl=SearchControl;function FilterDescription(props){let filters=(props.filters??[]).filter(f=>props.searchParams.find(p=>p.code===f.code));return filters.length===0?jsx108("span",{children:"no filters"}):jsx108(Fragment32,{children:filters.map(filter=>jsxs60("div",{children:[getOpString(filter.operator),"\xA0",jsx108(SearchFilterValueDisplay,{resourceType:props.resourceType,filter})]},`filter-${filter.code}-${filter.operator}-${filter.value}`))})}function getPage(search){return Math.floor((search.offset??0)/(search.count??DEFAULT_SEARCH_COUNT2))+1}function getTotalPages(search,lastResult){let pageSize=search.count??DEFAULT_SEARCH_COUNT2,total=getTotal(search,lastResult);return Math.ceil(total/pageSize)}function getStart(search,lastResult){return Math.min(getTotal(search,lastResult),(search.offset??0)+1)}function getEnd(search,lastResult){return Math.max(getStart(search,lastResult)+(lastResult.entry?.length??0)-1,0)}function getTotal(search,lastResult){let total=lastResult.total;return total===void 0&&(total=(search.offset??0)+(lastResult.entry?.length??0)+(lastResult.link?.some(l=>l.relation==="next")?1:0)),total}import{jsx as jsx109,jsxs as jsxs61}from"react/jsx-runtime";function FhirPathTable(props){let medplum=useMedplum27(),[schemaLoaded,setSchemaLoaded]=useState57(!1),[outcome,setOutcome]=useState57(),{query,fields}=props,[response,setResponse]=useState57(),[selected,setSelected]=useState57({}),responseRef=useRef18();responseRef.current=response;let selectedRef=useRef18({});selectedRef.current=selected,useEffect23(()=>{setOutcome(void 0),medplum.graphql(query).then(setResponse).catch(err=>setOutcome(normalizeOperationOutcome8(err)))},[medplum,query]);function handleSingleCheckboxClick(e,id){e.stopPropagation();let checked=e.target.checked,newSelected={...selectedRef.current};checked?newSelected[id]=!0:delete newSelected[id],setSelected(newSelected)}function handleAllCheckboxClick(e){e.stopPropagation();let checked=e.target.checked,newSelected={},resources=responseRef.current?.data.ResourceList;checked&&resources&&resources.forEach(resource=>{resource.id&&(newSelected[resource.id]=!0)}),setSelected(newSelected)}function isAllSelected(){let resources=responseRef.current?.data.ResourceList;if(!resources||resources.length===0)return!1;for(let resource of resources)if(resource.id&&!selectedRef.current[resource.id])return!1;return!0}function handleRowClick(e,resource){isCheckboxCell(e.target)||(killEvent(e),e.button!==1&&props.onClick&&props.onClick(new SearchClickEvent(resource,e)),e.button===1&&props.onAuxClick&&props.onAuxClick(new SearchClickEvent(resource,e)))}if(useEffect23(()=>{medplum.requestSchema(props.resourceType).then(()=>setSchemaLoaded(!0)).catch(console.log)},[medplum,props.resourceType]),!schemaLoaded)return jsx109(Loader5,{});let checkboxColumn=props.checkboxesEnabled;return jsxs61("div",{onContextMenu:e=>killEvent(e),"data-testid":"search-control",children:[jsxs61(Table4,{children:[jsx109(Table4.Thead,{children:jsxs61(Table4.Tr,{children:[checkboxColumn&&jsx109(Table4.Th,{children:jsx109("input",{type:"checkbox",value:"checked","aria-label":"all-checkbox","data-testid":"all-checkbox",checked:isAllSelected(),onChange:e=>handleAllCheckboxClick(e)})}),fields.map(field=>jsx109(Table4.Th,{children:field.name},field.name))]})}),jsx109(Table4.Tbody,{children:response?.data.ResourceList.map(resource=>resource&&jsxs61(Table4.Tr,{"data-testid":"search-control-row",onClick:e=>handleRowClick(e,resource),onAuxClick:e=>handleRowClick(e,resource),children:[checkboxColumn&&jsx109(Table4.Td,{children:jsx109("input",{type:"checkbox",value:"checked","data-testid":"row-checkbox","aria-label":`Checkbox for ${resource.id}`,checked:!!selected[resource.id],onChange:e=>handleSingleCheckboxClick(e,resource.id)})}),fields.map(field=>jsx109(Table4.Td,{children:jsx109(FhirPathDisplay,{propertyType:field.propertyType,path:field.fhirPath,resource})},field.name))]},resource.id))})]}),response?.data.ResourceList.length===0&&jsx109("div",{"data-testid":"empty-search",children:"No results"}),outcome&&jsx109("div",{"data-testid":"search-error",children:jsx109("pre",{style:{textAlign:"left"},children:JSON.stringify(outcome,void 0,2)})}),props.onBulk&&jsx109(Button18,{onClick:()=>props.onBulk(Object.keys(selectedRef.current)),children:"Bulk..."})]})}var MemoizedFhirPathTable=memo(FhirPathTable);import{Box as Box4,SimpleGrid}from"@mantine/core";import{useResource as useResource8,useSearchOne}from"@medplum/react-hooks";import{Box as Box3,Flex as Flex3,Group as Group38,Paper as Paper3,RingProgress,Text as Text17,Title as Title7}from"@mantine/core";import{formatCodeableConcept as formatCodeableConcept4}from"@medplum/core";import{Fragment as Fragment33,jsx as jsx110,jsxs as jsxs62}from"react/jsx-runtime";function MeasureReportGroupDisplay(props){let{group}=props;return jsx110(Paper3,{withBorder:!0,radius:"md",p:"xs",display:"flex",style:{alignItems:"center",justifyContent:"center"},children:jsxs62(Group38,{children:[group.measureScore&&jsx110(MeasureScore,{group}),!group.measureScore&&jsx110(MeasureReportPopulation,{group})]})})}function MeasureTitle(props){let{measure}=props;return jsxs62(Fragment33,{children:[jsx110(Text17,{fz:"md",fw:500,mb:8,children:measure.title}),jsx110(Text17,{fz:"xs",c:"dimmed",mb:8,children:measure.subtitle})]})}function MeasureReportPopulation(props){let{group}=props,populations=group.population,numerator=populations?.find(p=>formatCodeableConcept4(p.code)==="numerator"),denominator=populations?.find(p=>formatCodeableConcept4(p.code)==="denominator"),numeratorCount=numerator?.count,denominatorCount=denominator?.count;if(denominatorCount===0)return jsxs62(Box3,{children:[jsx110(Title7,{order:3,children:"Not Applicable"}),jsx110(Text17,{children:`Denominator: ${denominatorCount}`})]});if(numeratorCount===void 0||denominatorCount===void 0)return jsxs62(Box3,{children:[jsx110(Title7,{order:3,children:"Insufficient Data"}),jsx110(Text17,{children:`Numerator: ${numeratorCount}`}),jsx110(Text17,{children:`Denominator: ${denominatorCount}`})]});let value=numeratorCount/denominatorCount*100;return jsx110(RingProgress,{size:120,thickness:12,roundCaps:!0,sections:[{value,color:groupColor(value)}],label:jsx110(Flex3,{justify:"center",children:jsxs62(Text17,{fw:700,fz:18,children:[numeratorCount," / ",denominatorCount]})})})}function MeasureScore(props){let{group}=props,unit=group.measureScore?.unit??group.measureScore?.code;return jsx110(Fragment33,{children:unit==="%"?jsx110(RingProgress,{size:120,thickness:12,roundCaps:!0,sections:[{value:groupValue(group),color:groupColor(group?.measureScore?.value??0)}],label:jsx110(Flex3,{justify:"center",children:jsx110(Text17,{fw:700,fz:18,children:jsx110(QuantityDisplay,{value:group.measureScore})})})}):jsx110(Flex3,{h:120,align:"center",children:jsx110(Title7,{order:3,children:jsx110(QuantityDisplay,{value:group.measureScore})})})})}function groupValue(group){let score=group.measureScore?.value,unit=group.measureScore?.unit;return score?score<=1&&unit==="%"?score*100:score:0}function groupColor(score){return score<=33?"red":score<=67?"yellow":"green"}import{jsx as jsx111,jsxs as jsxs63}from"react/jsx-runtime";function MeasureReportDisplay(props){let report=useResource8(props.measureReport),[measure]=useSearchOne("Measure",{url:report?.measure});return report?jsxs63(Box4,{children:[measure&&jsx111(MeasureTitle,{measure}),jsx111(SimpleGrid,{cols:{base:3,sm:1},spacing:{base:"md",sm:"sm"},children:report.group?.map((group,idx)=>jsx111(MeasureReportGroupDisplay,{group},group.id??idx))})]}):null}import{ActionIcon as ActionIcon12,Indicator,Tooltip as Tooltip3}from"@mantine/core";import{useMedplum as useMedplum28,useSubscription as useSubscription2}from"@medplum/react-hooks";import{useCallback as useCallback14,useEffect as useEffect24,useState as useState58}from"react";import{jsx as jsx112}from"react/jsx-runtime";function NotificationIcon(props){let medplum=useMedplum28(),{label,resourceType,countCriteria,subscriptionCriteria,onClick}=props,[unreadCount,setUnreadCount]=useState58(0),updateCount=useCallback14(cache=>{medplum.search(resourceType,countCriteria,{cache}).then(result=>setUnreadCount(result.total)).catch(console.error)},[medplum,resourceType,countCriteria]);useEffect24(()=>{updateCount("default")},[updateCount]),useSubscription2(subscriptionCriteria,()=>{updateCount("reload")});let icon=jsx112(Tooltip3,{label,children:jsx112(ActionIcon12,{variant:"subtle",color:"gray",size:"lg","aria-label":label,onClick,children:props.iconComponent})});return unreadCount>0?jsx112(Indicator,{inline:!0,label:unreadCount.toLocaleString(),size:16,offset:2,position:"bottom-end",color:"red",children:icon}):icon}import{Button as Button19,Group as Group39,SegmentedControl as SegmentedControl2,Stack as Stack17}from"@mantine/core";import{notifications}from"@mantine/notifications";import{ContentType as ContentType2,normalizeErrorString as normalizeErrorString9,resolveId}from"@medplum/core";import{useMedplum as useMedplum29}from"@medplum/react-hooks";import{useCallback as useCallback15}from"react";import{jsx as jsx113,jsxs as jsxs64}from"react/jsx-runtime";var NOTIFICATION_ID="patient-export",NOTIFICATION_TITLE="Patient Export",formats={everything:{operation:"$everything",extension:"json",contentType:ContentType2.FHIR_JSON},summary:{operation:"$summary",extension:"json",contentType:ContentType2.FHIR_JSON},ccda:{operation:"$ccda-export",extension:"xml",contentType:ContentType2.CDA_XML}};function PatientExportForm(props){let medplum=useMedplum29(),{patient}=props,handleSubmit=useCallback15(async data2=>{let patientId=resolveId(patient),format=data2.format,{operation,contentType,extension}=formats[format],url=medplum.fhirUrl("Patient",patientId,operation);data2.startDate&&url.searchParams.append("start",data2.startDate),data2.endDate&&url.searchParams.append("end",data2.endDate),notifications.show({id:NOTIFICATION_ID,title:NOTIFICATION_TITLE,loading:!0,message:"Exporting...",autoClose:!1,withCloseButton:!1});try{let response=await medplum.get(url,{cache:"no-cache",headers:{Accept:contentType}}),fileName=`Patient-export-${patientId}-${new Date().toISOString().replaceAll(":","-")}.${extension}`;saveData(response,fileName,contentType),notifications.update({id:NOTIFICATION_ID,title:NOTIFICATION_TITLE,color:"green",message:"Done",icon:jsx113(IconCheck,{size:"1rem"}),loading:!1,autoClose:!1,withCloseButton:!0})}catch(err){notifications.update({id:NOTIFICATION_ID,title:NOTIFICATION_TITLE,color:"red",message:normalizeErrorString9(err),icon:jsx113(IconX,{size:"1rem"}),loading:!1,autoClose:!1,withCloseButton:!0})}},[medplum,patient]);return jsx113(Form,{onSubmit:handleSubmit,children:jsxs64(Stack17,{children:[jsx113(FormSection,{title:"Export Format",description:"Required",withAsterisk:!0,children:jsx113(SegmentedControl2,{name:"format",data:[{label:"FHIR Everything",value:"everything"},{label:"Patient Summary",value:"summary"},{label:"C-CDA",value:"ccda"}],fullWidth:!0})}),jsx113(FormSection,{title:"Start Date",description:"If no start date is provided, all records prior to the end date are in scope.",children:jsx113(DateTimeInput,{name:"startDate",placeholder:"Start date"})}),jsx113(FormSection,{title:"End Date",description:"If no end date is provided, all records subsequent to the start date are in scope.",children:jsx113(DateTimeInput,{name:"endDate",placeholder:"End date"})}),jsx113(Group39,{justify:"right",children:jsx113(Button19,{type:"submit",children:"Request Export"})})]})})}function saveData(data2,fileName,contentType){let content=typeof data2=="string"?data2:JSON.stringify(data2,null,2),blob=new Blob([content],{type:contentType}),url=window.URL.createObjectURL(blob),a=document.createElement("a");document.body.appendChild(a),a.style.display="none",a.href=url,a.download=fileName,a.click(),window.URL.revokeObjectURL(url)}import{Card,Divider as Divider3,Flex as Flex4,Group as Group49,Paper as Paper4,Stack as Stack23,Text as Text24}from"@mantine/core";import{calculateAgeString,formatHumanName as formatHumanName4,resolveId as resolveId2}from"@medplum/core";import{useMedplum as useMedplum36,useResource as useResource9}from"@medplum/react-hooks";import{useEffect as useEffect25,useMemo as useMemo29,useState as useState68}from"react";import{Anchor as Anchor6,Box as Box5,Group as Group41,Modal as Modal7,Text as Text18}from"@mantine/core";import{useDisclosure}from"@mantine/hooks";import{useMedplum as useMedplum30}from"@medplum/react-hooks";import{useCallback as useCallback17,useState as useState60}from"react";import{Button as Button20,Group as Group40,Stack as Stack18,TextInput as TextInput21}from"@mantine/core";import{HTTP_HL7_ORG as HTTP_HL7_ORG2,addProfileToResource,createReference as createReference6}from"@medplum/core";import{useCallback as useCallback16,useState as useState59}from"react";import{jsx as jsx114,jsxs as jsxs65}from"react/jsx-runtime";var HTTP="http://",PATIENT_ALLERGY_PROFILE=HTTP_HL7_ORG2+"/fhir/us/core/StructureDefinition/us-core-allergyintolerance";function AllergyDialog(props){let{patient,encounter,allergy,onSubmit}=props,[code,setCode]=useState59(allergy?.code),[clinicalStatus,setClinicalStatus]=useState59(allergy?.clinicalStatus),handleSubmit=useCallback16(formData=>{onSubmit(addProfileToResource({...allergy,resourceType:"AllergyIntolerance",patient:createReference6(patient),encounter:encounter?createReference6(encounter):void 0,code,clinicalStatus,onsetDateTime:formData.onsetDateTime?formData.onsetDateTime:void 0,reaction:formData.reaction?[{manifestation:[{text:formData.reaction}]}]:void 0},PATIENT_ALLERGY_PROFILE))},[patient,encounter,allergy,code,clinicalStatus,onSubmit]);return jsx114(Form,{onSubmit:handleSubmit,children:jsxs65(Stack18,{children:[jsx114(CodeableConceptInput,{name:"allergy",label:"Code",path:"AllergyIntolerance.code","data-autofocus":!0,binding:HTTP+"cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.8",maxValues:1,defaultValue:allergy?.code,onChange:code2=>setCode(code2),outcome:void 0}),jsx114(TextInput21,{name:"reaction",label:"Reaction",defaultValue:allergy?.reaction?.[0]?.manifestation?.[0]?.text}),jsx114(CodeableConceptInput,{name:"clinicalStatus",label:"Clinical Status",path:"AllergyIntolerance.clinicalStatus",binding:HTTP_HL7_ORG2+"/fhir/ValueSet/allergyintolerance-clinical",maxValues:1,defaultValue:allergy?.clinicalStatus,onChange:clinicalStatus2=>setClinicalStatus(clinicalStatus2),outcome:void 0}),jsx114(DateTimeInput,{name:"onsetDateTime",label:"Onset",defaultValue:allergy?.recordedDate}),jsx114(Group40,{justify:"flex-end",gap:4,mt:"md",children:jsx114(Button20,{type:"submit",children:"Save"})})]})},allergy?.id)}import{ActionIcon as ActionIcon13,Badge as Badge2}from"@mantine/core";import{getDisplayString as getDisplayString6}from"@medplum/core";import{jsx as jsx115}from"react/jsx-runtime";function ConceptBadge(props){let{resource,display,onClick,onEdit}=props,rightSection;return onEdit&&(rightSection=jsx115(ActionIcon13,{variant:"subtle",size:12,radius:"xl",children:jsx115(IconPencil,{"aria-label":`Edit ${getDisplayString6(resource)}`,size:12,onClick:e=>{killEvent(e),onEdit(resource)}})})),jsx115(MedplumLink,{to:onClick?void 0:resource,onClick:onClick?()=>onClick(resource):void 0,children:jsx115(Badge2,{variant:"light",maw:"100%",rightSection,style:{cursor:"pointer"},children:display??getDisplayString6(resource)})},resource.id)}import{Fragment as Fragment34,jsx as jsx116,jsxs as jsxs66}from"react/jsx-runtime";function Allergies(props){let medplum=useMedplum30(),{patient,encounter}=props,[allergies,setAllergies]=useState60(props.allergies),[opened,{open,close}]=useDisclosure(!1),[editAllergy,setEditAllergy]=useState60(),handleSubmit=useCallback17(async allergy=>{if(allergy.id){let updatedAllergy=await medplum.updateResource(allergy);setAllergies(allergies.map(a=>a.id===updatedAllergy.id?updatedAllergy:a))}else{let newAllergy=await medplum.createResource(allergy);setAllergies([...allergies,newAllergy])}setEditAllergy(void 0),close()},[medplum,allergies,close]);return jsxs66(Fragment34,{children:[jsxs66(Group41,{justify:"space-between",children:[jsx116(Text18,{fz:"md",fw:700,children:"Allergies"}),jsx116(Anchor6,{component:"button",onClick:e=>{killEvent(e),setEditAllergy(void 0),open()},children:"+ Add"})]}),allergies.length>0?jsx116(Box5,{children:allergies.map(allergy=>jsx116(ConceptBadge,{resource:allergy,onClick:props.onClickResource,onEdit:a=>{setEditAllergy(a),open()}},allergy.id))}):jsx116(Text18,{children:"(none)"}),jsx116(Modal7,{opened,onClose:close,title:editAllergy?"Edit Allergy":"Add Allergy",children:jsx116(AllergyDialog,{patient,encounter,allergy:editAllergy,onSubmit:handleSubmit})})]})}import{Anchor as Anchor7,Box as Box6,Group as Group43,Modal as Modal8,Text as Text19}from"@mantine/core";import{useDisclosure as useDisclosure2}from"@mantine/hooks";import{useMedplum as useMedplum31}from"@medplum/react-hooks";import{useCallback as useCallback19,useState as useState62}from"react";import{Alert as Alert4,Button as Button21,Group as Group42,Radio,Stack as Stack19}from"@mantine/core";import{HTTP_HL7_ORG as HTTP_HL7_ORG3,addProfileToResource as addProfileToResource2,createReference as createReference7}from"@medplum/core";import{useCallback as useCallback18,useState as useState61}from"react";import{useMedplumProfile as useMedplumProfile6}from"@medplum/react-hooks";import{jsx as jsx117,jsxs as jsxs67}from"react/jsx-runtime";var HTTP2="http://",statusValues=["active","stopped","on-hold","cancelled","completed","entered-in-error","draft","unknown"];function MedicationDialog(props){let me=useMedplumProfile6(),{patient,encounter,medication,onSubmit}=props,[code,setCode]=useState61(medication?.medicationCodeableConcept),handleSubmit=useCallback18(formData=>{if(!me)throw new Error("Not signed in");onSubmit(addProfileToResource2({...medication,resourceType:"MedicationRequest",status:formData.status,intent:medication?.intent??"order",encounter:medication?.encounter??(encounter&&createReference7(encounter)),requester:medication?.requester??createReference7(me),medicationCodeableConcept:code,subject:createReference7(patient)},HTTP_HL7_ORG3+"/fhir/us/core/StructureDefinition/us-core-medicationrequest"))},[me,onSubmit,medication,encounter,code,patient]);return me?jsx117(Form,{onSubmit:handleSubmit,children:jsxs67(Stack19,{children:[jsx117(CodeableConceptInput,{name:"request",path:"MedicationRequest.medication[x]","data-autofocus":!0,binding:HTTP2+"cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.4",maxValues:1,defaultValue:medication?.medicationCodeableConcept,onChange:request=>setCode(request),outcome:void 0}),jsx117(Radio.Group,{name:"status",label:"Request Status",required:!0,defaultValue:medication?.status,children:statusValues.map(sv=>jsx117(Radio,{value:sv,label:sv,my:"xs",required:!0},sv))}),jsx117(Group42,{justify:"flex-end",gap:4,children:jsx117(Button21,{type:"submit",children:"Save"})})]})}):jsx117(Alert4,{color:"red",children:"Not signed in"})}import{Fragment as Fragment35,jsx as jsx118,jsxs as jsxs68}from"react/jsx-runtime";function Medications(props){let medplum=useMedplum31(),[medicationRequests,setMedicationRequests]=useState62(props.medicationRequests),[editMedication,setEditMedication]=useState62(),[opened,{open,close}]=useDisclosure2(!1),handleSubmit=useCallback19(async medication=>{if(medication.id){let updatedMedication=await medplum.updateResource(medication);setMedicationRequests(medicationRequests.map(m=>m.id===updatedMedication.id?updatedMedication:m))}else{let newMedication=await medplum.createResource(medication);setMedicationRequests([newMedication,...medicationRequests])}setEditMedication(void 0),close()},[medplum,medicationRequests,close]);return jsxs68(Fragment35,{children:[jsxs68(Group43,{justify:"space-between",children:[jsx118(Text19,{fz:"md",fw:700,children:"Medications"}),jsx118(Anchor7,{component:"button",onClick:e=>{killEvent(e),setEditMedication(void 0),open()},children:"+ Add"})]}),medicationRequests.length>0?jsx118(Box6,{children:medicationRequests.map(request=>jsx118(ConceptBadge,{resource:request,onClick:props.onClickResource,onEdit:mr=>{setEditMedication(mr),open()}},request.id))}):jsx118(Text19,{children:"(none)"}),jsx118(Modal8,{opened,onClose:close,title:editMedication?"Edit Medication":"Add Medication",children:jsx118(MedicationDialog,{patient:props.patient,encounter:props.encounter,medication:editMedication,onSubmit:handleSubmit})})]})}import{Anchor as Anchor8,Grid as Grid2,Group as Group45,Modal as Modal9,Text as Text20}from"@mantine/core";import{useDisclosure as useDisclosure3}from"@mantine/hooks";import{useMedplum as useMedplum32}from"@medplum/react-hooks";import{Fragment as Fragment36,useCallback as useCallback21,useState as useState64}from"react";import{Button as Button22,Group as Group44,Stack as Stack20}from"@mantine/core";import{HTTP_HL7_ORG as HTTP_HL7_ORG4,HTTP_TERMINOLOGY_HL7_ORG,addProfileToResource as addProfileToResource3,createReference as createReference8}from"@medplum/core";import{useCallback as useCallback20,useState as useState63}from"react";import{jsx as jsx119,jsxs as jsxs69}from"react/jsx-runtime";function ConditionDialog(props){let{patient,encounter,condition,onSubmit}=props,[code,setCode]=useState63(condition?.code),[clinicalStatus,setClinicalStatus]=useState63(condition?.clinicalStatus),handleSubmit=useCallback20(formData=>{let updatedCondition=addProfileToResource3({...condition,resourceType:"Condition",category:[{coding:[{system:HTTP_TERMINOLOGY_HL7_ORG+"/CodeSystem/condition-category",code:"problem-list-item",display:"Problem List Item"}],text:"Problem List Item"}],subject:createReference8(patient),encounter:encounter&&createReference8(encounter),code,clinicalStatus,onsetDateTime:formData.onsetDateTime?convertLocalToIso(formData.onsetDateTime):void 0},HTTP_HL7_ORG4+"/fhir/us/core/StructureDefinition/us-core-condition-problems-health-concerns");onSubmit(updatedCondition)},[patient,encounter,condition,code,clinicalStatus,onSubmit]);return jsx119(Form,{onSubmit:handleSubmit,children:jsxs69(Stack20,{children:[jsx119(CodeableConceptInput,{name:"code",label:"Problem",path:"Condition.code","data-autofocus":!0,binding:HTTP_HL7_ORG4+"/fhir/us/core/ValueSet/us-core-condition-code",defaultValue:condition?.code,onChange:code2=>setCode(code2),outcome:void 0}),jsx119(CodeableConceptInput,{name:"clinicalStatus",label:"Status",path:"Condition.clinicalStatus",binding:HTTP_HL7_ORG4+"/fhir/ValueSet/condition-clinical",defaultValue:condition?.clinicalStatus,onChange:clinicalStatus2=>setClinicalStatus(clinicalStatus2),outcome:void 0}),jsx119(DateTimeInput,{name:"onsetDateTime",label:"Dx Date",defaultValue:condition?.onsetDateTime,required:!0}),jsx119(Group44,{justify:"flex-end",gap:4,mt:"md",children:jsx119(Button22,{type:"submit",children:"Save"})})]})},condition?.id)}import{Fragment as Fragment37,jsx as jsx120,jsxs as jsxs70}from"react/jsx-runtime";function ProblemList(props){let medplum=useMedplum32(),{patient,encounter}=props,[problems,setProblems]=useState64(props.problems),[editCondition,setEditCondition]=useState64(),[opened,{open,close}]=useDisclosure3(!1),handleSubmit=useCallback21(async condition=>{if(condition.id){let updatedCondition=await medplum.updateResource(condition);setProblems(problems.map(p=>p.id===updatedCondition.id?updatedCondition:p))}else{let newCondition=await medplum.createResource(condition);setProblems([...problems,newCondition])}setEditCondition(void 0),close()},[medplum,problems,close]);return jsxs70(Fragment37,{children:[jsxs70(Group45,{justify:"space-between",children:[jsx120(Text20,{fz:"md",fw:700,children:"Problem List"}),jsx120(Anchor8,{component:"button",onClick:e=>{killEvent(e),setEditCondition(void 0),open()},children:"+ Add"})]}),problems.length>0?jsx120(Grid2,{gutter:"xs",children:problems.map(problem=>jsxs70(Fragment36,{children:[jsx120(Grid2.Col,{span:2,children:problem.onsetDateTime?.substring(0,4)}),jsx120(Grid2.Col,{span:10,children:jsx120(ConceptBadge,{resource:problem,onClick:props.onClickResource,onEdit:c=>{setEditCondition(c),open()}},problem.id)})]},problem.id))}):jsx120(Text20,{children:"(none)"}),jsx120(Modal9,{opened,onClose:close,title:editCondition?"Edit Problem":"Add Problem",children:jsx120(ConditionDialog,{patient,encounter,condition:editCondition,onSubmit:handleSubmit})})]})}import{Anchor as Anchor9,Button as Button23,Group as Group46,Modal as Modal10,Radio as Radio2,Stack as Stack21,Text as Text21}from"@mantine/core";import{useDisclosure as useDisclosure4}from"@mantine/hooks";import{HTTP_HL7_ORG as HTTP_HL7_ORG5,HTTP_TERMINOLOGY_HL7_ORG as HTTP_TERMINOLOGY_HL7_ORG2,LOINC,SNOMED,createReference as createReference9,formatCodeableConcept as formatCodeableConcept5}from"@medplum/core";import{useMedplum as useMedplum33}from"@medplum/react-hooks";import{useCallback as useCallback22,useState as useState65}from"react";import{Fragment as Fragment38,jsx as jsx121,jsxs as jsxs71}from"react/jsx-runtime";var NULLFLAVOR=HTTP_TERMINOLOGY_HL7_ORG2+"/CodeSystem/v3-NullFlavor",CodesToText={38628009:"Homosexual",20430005:"Heterosexual",42035005:"Bisexual",OTH:"Other",UNK:"Unknown",ASKU:"Asked but no answer"},CodesToSystem={38628009:SNOMED,20430005:SNOMED,42035005:SNOMED,OTH:NULLFLAVOR,UNK:NULLFLAVOR,ASKU:NULLFLAVOR};function SexualOrientation(props){let medplum=useMedplum33(),{patient,encounter}=props,[sexualOrientation,setSexualOrientation]=useState65(props.sexualOrientation),[opened,{open,close}]=useDisclosure4(!1),handleSubmit=useCallback22(formData=>{let code=formData.sexualOrientation;medplum.createResource({resourceType:"Observation",meta:{profile:[HTTP_HL7_ORG5+"/fhir/us/core/ValueSet/us-core-sexual-orientation"]},status:"final",category:[{coding:[{system:HTTP_TERMINOLOGY_HL7_ORG2+"/CodeSystem/observation-category",code:"social-history",display:"Social History"}],text:"Social History"}],code:{coding:[{system:LOINC,code:"76690-7",display:"Sexual orientation"}],text:"Sexual orientation"},subject:createReference9(patient),encounter:encounter?createReference9(encounter):void 0,effectiveDateTime:new Date().toISOString(),valueCodeableConcept:{coding:[{system:CodesToSystem[code],code:formData.sexualOrientation}],text:CodesToText[code]}}).then(newSexualOrientation=>{setSexualOrientation(newSexualOrientation),close()}).catch(console.error)},[medplum,patient,encounter,close]);return jsxs71(Fragment38,{children:[jsxs71(Group46,{justify:"space-between",children:[jsx121(Text21,{fz:"md",fw:700,children:"Sexual Orientation"}),jsx121(Anchor9,{href:"#",onClick:e=>{killEvent(e),open()},children:"+ Edit"})]}),sexualOrientation?.valueCodeableConcept?jsx121(ConceptBadge,{resource:sexualOrientation,display:formatCodeableConcept5(sexualOrientation.valueCodeableConcept),onClick:props.onClickResource,onEdit:()=>open()},sexualOrientation.id):jsx121(Text21,{children:"(none)"}),jsx121(Modal10,{opened,onClose:close,title:"Set Sexual Orientation",children:jsx121(Form,{onSubmit:handleSubmit,children:jsxs71(Stack21,{children:[jsx121(Radio2.Group,{name:"sexualOrientation",label:"Sexual Orientation",required:!0,children:Object.entries(CodesToText).map(([code,text])=>jsx121(Radio2,{value:code,label:text,my:"xs"},code))}),jsx121(Group46,{justify:"flex-end",gap:4,mt:"md",children:jsx121(Button23,{type:"submit",children:"Save"})})]})})})]})}import{Anchor as Anchor10,Button as Button24,Group as Group47,Modal as Modal11,Radio as Radio3,Stack as Stack22,Text as Text22}from"@mantine/core";import{useDisclosure as useDisclosure5}from"@mantine/hooks";import{HTTP_HL7_ORG as HTTP_HL7_ORG6,LOINC as LOINC2,SNOMED as SNOMED2,createReference as createReference10,formatCodeableConcept as formatCodeableConcept6}from"@medplum/core";import{useMedplum as useMedplum34}from"@medplum/react-hooks";import{useCallback as useCallback23,useState as useState66}from"react";import{Fragment as Fragment39,jsx as jsx122,jsxs as jsxs72}from"react/jsx-runtime";var smokingStatusOptions={266919005:"Never smoked tobacco",266927001:"Tobacco smoking consumption unknown","428041000124106":"Occasional tobacco smoker","428061000124105":"Light tobacco smoker","428071000124103":"Heavy tobacco smoker",449868002:"Smokes tobacco daily",77176002:"Smoker",8517006:"Ex-smoker"};function SmokingStatus(props){let medplum=useMedplum34(),{patient,encounter}=props,[smokingStatus,setSmokingStatus]=useState66(props.smokingStatus),[opened,{open,close}]=useDisclosure5(!1),handleSubmit=useCallback23(formData=>{medplum.createResource({resourceType:"Observation",meta:{profile:[HTTP_HL7_ORG6+"/fhir/us/core/StructureDefinition/us-core-smokingstatus"]},status:"final",category:[{coding:[{system:"http://terminology.hl7.org/CodeSystem/observation-category",code:"social-history",display:"Social History"}],text:"Social History"}],code:{coding:[{system:LOINC2,code:"72166-2",display:"Tobacco smoking status"}],text:"Tobacco smoking status"},subject:createReference10(patient),encounter:encounter?createReference10(encounter):void 0,effectiveDateTime:new Date().toISOString(),valueCodeableConcept:{coding:[{system:SNOMED2,version:SNOMED2+"/731000124108",code:formData.smokingStatus}],text:smokingStatusOptions[formData.smokingStatus]}}).then(newSmokingStatus=>{setSmokingStatus(newSmokingStatus),close()}).catch(console.error)},[medplum,patient,encounter,close]);return jsxs72(Fragment39,{children:[jsxs72(Group47,{justify:"space-between",children:[jsx122(Text22,{fz:"md",fw:700,children:"Smoking Status"}),jsx122(Anchor10,{href:"#",onClick:e=>{killEvent(e),open()},children:"+ Edit"})]}),smokingStatus?.valueCodeableConcept?jsx122(ConceptBadge,{resource:smokingStatus,display:formatCodeableConcept6(smokingStatus.valueCodeableConcept),onClick:props.onClickResource,onEdit:()=>open()},smokingStatus.id):jsx122(Text22,{children:"(none)"}),jsx122(Modal11,{opened,onClose:close,title:"Set Smoking Status",children:jsx122(Form,{onSubmit:handleSubmit,children:jsxs72(Stack22,{children:[jsx122(Radio3.Group,{name:"smokingStatus",label:"Smoking Status",required:!0,children:Object.entries(smokingStatusOptions).map(([code,text])=>jsx122(Radio3,{value:code,label:text,my:"xs"},code))}),jsx122(Group47,{justify:"flex-end",gap:4,mt:"md",children:jsx122(Button24,{type:"submit",children:"Save"})})]})})})]})}import{Anchor as Anchor11,Button as Button25,Grid as Grid3,Group as Group48,Modal as Modal12,SimpleGrid as SimpleGrid2,Text as Text23,Textarea as Textarea3,TextInput as TextInput22,Tooltip as Tooltip4}from"@mantine/core";import{useDisclosure as useDisclosure6}from"@mantine/hooks";import{formatQuantity as formatQuantity2}from"@medplum/core";import{useMedplum as useMedplum35}from"@medplum/react-hooks";import{Fragment as Fragment40,useCallback as useCallback24,useState as useState67}from"react";import{LOINC as LOINC3,UCUM,createReference as createReference11}from"@medplum/core";function getObservationValue(obs,component){return component?obs.component?.find(c=>c.code?.coding?.[0].code===component)?.valueQuantity:obs.valueQuantity}function createObservation(patient,encounter,code,title,valueQuantity){if(isValidNumber(valueQuantity.value))return{...createBaseObservation(patient,encounter,code,title),valueQuantity}}function createCompoundObservation(patient,encounter,code,title,components){let component=components.filter(c=>isValidNumber(c.valueQuantity?.value));if(component.length!==0)return{...createBaseObservation(patient,encounter,code,title),component}}function createBaseObservation(patient,encounter,code,title){return{resourceType:"Observation",status:"preliminary",subject:createReference11(patient),encounter:encounter?createReference11(encounter):void 0,effectiveDateTime:new Date().toISOString(),category:[{coding:[{system:"http://terminology.hl7.org/CodeSystem/observation-category",code:"vital-signs",display:"Vital Signs"}]}],code:createLoincCode(code,title)}}function createLoincCode(code,display){return{coding:[{code,display,system:LOINC3}],text:display}}function createQuantity(value,unit){return{value,system:UCUM,unit,code:unit}}function isValidNumber(value){return value!==void 0&&!isNaN(value)&&isFinite(value)}import{Fragment as Fragment41,jsx as jsx123,jsxs as jsxs73}from"react/jsx-runtime";var BP="85354-9",SYSTOLIC="8480-6",DIASTOLIC="8462-4",LOINC_CODES=[{name:"systolic",short:"BP Sys",code:BP,component:SYSTOLIC,title:"Blood Pressure",unit:"mm[Hg]"},{name:"diastolic",short:"BP Dias",code:BP,component:DIASTOLIC,title:"Blood Pressure",unit:"mm[Hg]"},{name:"heartRate",short:"HR",code:"8867-4",title:"Heart Rate",unit:"/min"},{name:"bodyTemperature",short:"Temp",code:"8310-5",title:"Body Temperature",unit:"Cel"},{name:"respiratoryRate",short:"RR",code:"9279-1",title:"Respiratory Rate",unit:"/min"},{name:"height",short:"Ht",code:"8302-2",title:"Height",unit:"cm"},{name:"weight",short:"Wt",code:"29463-7",title:"Weight",unit:"kg"},{name:"bmi",short:"BMI",code:"39156-5",title:"BMI",unit:"kg/m2"},{name:"oxygen",short:"O2",code:"2708-6",title:"Oxygen",unit:"%"},{name:"headCircumference",short:"HC",code:"9843-4",title:"Head Circumference",unit:"cm"}];function Vitals(props){let medplum=useMedplum35(),{patient,encounter}=props,[vitals,setVitals]=useState67(props.vitals),[opened,{open,close}]=useDisclosure6(!1),handleSubmit=useCallback24(formData=>{let newObservations=[];newObservations.push(createCompoundObservation(patient,encounter,BP,"Blood pressure",[{code:createLoincCode(SYSTOLIC,"Systolic blood pressure"),valueQuantity:createQuantity(parseFloat(formData.systolic),"mm[Hg]")},{code:createLoincCode(DIASTOLIC,"Diastolic blood pressure"),valueQuantity:createQuantity(parseFloat(formData.diastolic),"mm[Hg]")}]));for(let meta of LOINC_CODES)meta.component||newObservations.push(createObservation(patient,encounter,meta.code,meta.title,createQuantity(parseFloat(formData[meta.name]),meta.unit)));Promise.all(newObservations.filter(Boolean).map(obs=>medplum.createResource(obs))).then(newVitals=>setVitals([...newVitals,...vitals])).catch(console.error),close()},[medplum,patient,encounter,vitals,close]);return jsxs73(Fragment41,{children:[jsxs73(Group48,{justify:"space-between",children:[jsx123(Text23,{fz:"md",fw:700,children:"Vitals"}),jsx123(Anchor11,{href:"#",onClick:e=>{killEvent(e),open()},children:"+ Add"})]}),jsx123(Grid3,{children:LOINC_CODES.map(meta=>{let obs=vitals.find(o=>o.code?.coding?.[0].code===meta.code);return jsxs73(Fragment40,{children:[jsx123(Grid3.Col,{span:2,ta:"right",children:jsx123(Tooltip4,{label:meta.title,children:jsx123(Text23,{c:"dimmed",size:"xs",children:meta.short})})}),jsx123(Grid3.Col,{span:4,children:jsx123(Text23,{size:"xs",children:obs&&jsx123(ConceptBadge,{resource:obs,display:formatQuantity2(getObservationValue(obs,meta.component)),onClick:props.onClickResource},meta.name)})})]},meta.name)})}),jsx123(Modal12,{opened,onClose:close,title:"Add Vitals",children:jsxs73(Form,{onSubmit:handleSubmit,children:[jsx123(SimpleGrid2,{cols:2,children:LOINC_CODES.map((meta,index)=>jsx123(TextInput22,{name:meta.name,label:meta.short,description:meta.title,"data-autofocus":index===0,autoFocus:index===0},meta.name))}),jsx123(Textarea3,{name:"notes",label:"Notes"}),jsx123(Group48,{justify:"flex-end",gap:4,mt:"md",children:jsx123(Button25,{type:"submit",children:"Save"})})]})})]})}import{Fragment as Fragment42,jsx as jsx124,jsxs as jsxs74}from"react/jsx-runtime";function getGenderIcon(patient){switch(patient?.gender){case"female":return IconGenderFemale;case"male":return IconGenderMale;default:return}}function pluralize(count,singular,plural){return count===0?`No ${plural}`:count===1?`1 ${singular}`:`${count} ${plural}`}function PatientSummary(props){let medplum=useMedplum36(),{patient:propsPatient,background,appointmentsUrl:propsAppointmentsUrl,encountersUrl:propsEncountersUrl,onClickResource,...cardProps}=props,patient=useResource9(propsPatient),[medicalData,setMedicalData]=useState68(),appointmentsUrl="appointmentsUrl"in props?propsAppointmentsUrl:"#",encountersUrl="encountersUrl"in props?propsEncountersUrl:"#";useEffect25(()=>{let ref=`Patient/${resolveId2(propsPatient)}`,searchMeta={_count:100,_sort:"-_lastUpdated"},today=new Date().toISOString().substring(0,10);Promise.all([medplum.searchResources("AllergyIntolerance",{patient:ref,...searchMeta}),medplum.searchResources("Condition",{patient:ref,...searchMeta}),medplum.searchResources("MedicationRequest",{subject:ref,...searchMeta}),medplum.searchResources("Observation",{subject:ref,...searchMeta}),medplum.searchResources("Appointment",{patient:ref,date:`ge${today}`,status:"proposed,pending,booked",...searchMeta}),medplum.searchResources("Encounter",{subject:ref,date:`le${today}`,status:"finished",...searchMeta})]).then(results=>{let observations=results[3];setMedicalData({allergies:results[0],problems:results[1],medicationRequests:results[2],sexualOrientation:observations.find(obs=>obs.code?.coding?.[0].code==="76690-7"),smokingStatus:observations.find(obs=>obs.code?.coding?.[0].code==="72166-2"),vitals:observations.filter(obs=>obs.category?.[0]?.coding?.[0].code==="vital-signs"),appointments:results[4],encounters:results[5]})}).catch(console.error)},[medplum,propsPatient]);let links=useMemo29(()=>{let appointmentsLink=appointmentsUrl===void 0?void 0:jsx124(MedplumLink,{to:appointmentsUrl,children:pluralize(medicalData?.appointments?.length,"upcoming appointment","upcoming appointments")},"appt"),encountersLink=encountersUrl===void 0?void 0:jsx124(MedplumLink,{to:encountersUrl,children:pluralize(medicalData?.encounters?.length,"documented visit","documented visits")},"enc");return[appointmentsLink,encountersLink].filter(Boolean)},[appointmentsUrl,medicalData?.appointments?.length,medicalData?.encounters?.length,encountersUrl]);if(!patient)return null;let GenderIconComponent=getGenderIcon(patient);return jsxs74(Card,{...cardProps,children:[jsx124(Card.Section,{h:100,style:{background}}),jsx124(ResourceAvatar,{value:patient,size:80,radius:80,mx:"auto",mt:-50,style:{border:"2px solid white"}}),jsx124(Text24,{ta:"center",fz:"lg",fw:500,children:formatHumanName4(patient.name?.[0])}),patient.birthDate&&jsxs74(Text24,{ta:"center",fz:"xs",c:"dimmed",children:[patient.birthDate," (",calculateAgeString(patient.birthDate),")"]}),jsx124(Paper4,{withBorder:!0,p:"md",my:"md",children:jsxs74(Group49,{wrap:"nowrap",justify:"space-evenly",children:[jsxs74(Flex4,{justify:"center",align:"center",direction:"column",gap:0,children:[jsx124(IconUserSquare,{size:24,color:"gray"}),jsx124(Text24,{fz:"xs",ta:"center",style:{whiteSpace:"nowrap"},children:"Self"})]}),jsxs74(Flex4,{justify:"center",align:"center",direction:"column",gap:0,children:[jsx124(IconStethoscope,{size:24,color:"gray"}),jsx124(Text24,{fz:"xs",style:{whiteSpace:"nowrap"},children:patient?.generalPractitioner?.[0]?.display??"No provider"})]}),GenderIconComponent&&jsxs74(Flex4,{justify:"center",align:"center",direction:"column",gap:0,children:[jsx124(GenderIconComponent,{size:24,color:"gray"}),jsx124(Text24,{fz:"xs",style:{whiteSpace:"nowrap"},children:patient.gender})]})]})}),jsxs74(Stack23,{gap:"xs",children:[links.length>0&&jsxs74(Fragment42,{children:[links,jsx124(Divider3,{})]}),medicalData&&jsxs74(Fragment42,{children:[jsx124(Allergies,{patient,allergies:medicalData.allergies,onClickResource}),jsx124(Divider3,{}),jsx124(ProblemList,{patient,problems:medicalData.problems,onClickResource}),jsx124(Divider3,{}),jsx124(Medications,{patient,medicationRequests:medicalData.medicationRequests,onClickResource}),jsx124(Divider3,{}),jsx124(SexualOrientation,{patient,sexualOrientation:medicalData.sexualOrientation,onClickResource}),jsx124(Divider3,{}),jsx124(SmokingStatus,{patient,smokingStatus:medicalData.smokingStatus,onClickResource}),jsx124(Divider3,{}),jsx124(Vitals,{patient,vitals:medicalData.vitals,onClickResource})]})]})]})}import{createReference as createReference12}from"@medplum/core";import{useCallback as useCallback25}from"react";import{jsx as jsx125}from"react/jsx-runtime";function PatientTimeline(props){let{patient,...rest}=props,loadTimelineResources=useCallback25((medplum,resourceType,id)=>{let ref=`${resourceType}/${id}`,_count=100;return Promise.allSettled([medplum.readHistory("Patient",id),medplum.search("Communication",{subject:ref,_count}),medplum.search("Device",{patient:ref,_count}),medplum.search("DeviceRequest",{patient:ref,_count}),medplum.search("DiagnosticReport",{subject:ref,_count}),medplum.search("Media",{subject:ref,_count}),medplum.search("ServiceRequest",{subject:ref,_count}),medplum.search("Task",{subject:ref,_count})])},[]);return jsx125(ResourceTimeline,{value:patient,loadTimelineResources,createCommunication:(resource,sender,text)=>({resourceType:"Communication",status:"completed",subject:createReference12(resource),sender:createReference12(sender),sent:new Date().toISOString(),payload:[{contentString:text}]}),createMedia:(resource,operator,content)=>({resourceType:"Media",status:"completed",subject:createReference12(resource),operator:createReference12(operator),issued:new Date().toISOString(),content}),...rest})}import{Anchor as Anchor12,Box as Box7,Button as Button26,CloseButton,Group as Group50,Paper as Paper5,Stack as Stack24,TextInput as TextInput23,Text as Text25,Radio as Radio4,ActionIcon as ActionIcon14,Flex as Flex5}from"@mantine/core";import{getReferenceString as getReferenceString7}from"@medplum/core";import{useMedplum as useMedplum37,useResource as useResource10}from"@medplum/react-hooks";import{useEffect as useEffect26,useRef as useRef19,useState as useState69}from"react";var PlanDefinitionBuilder_default={section:"PlanDefinitionBuilder_section",hovering:"PlanDefinitionBuilder_hovering",editing:"PlanDefinitionBuilder_editing"};import{jsx as jsx126,jsxs as jsxs75}from"react/jsx-runtime";function PlanDefinitionBuilder(props){let medplum=useMedplum37(),defaultValue2=useResource10(props.value),[schemaLoaded,setSchemaLoaded]=useState69(!1),[selectedKey,setSelectedKey]=useState69(),[hoverKey,setHoverKey]=useState69(),[value,setValue]=useState69();function handleDocumentMouseOver(){setHoverKey(void 0)}function handleDocumentClick(){setSelectedKey(void 0)}let valueRef=useRef19();if(valueRef.current=value,useEffect26(()=>{medplum.requestSchema("PlanDefinition").then(()=>setSchemaLoaded(!0)).catch(console.log)},[medplum]),useEffect26(()=>(setValue(ensurePlanDefinitionKeys(defaultValue2??{resourceType:"PlanDefinition",status:"active"})),document.addEventListener("mouseover",handleDocumentMouseOver),document.addEventListener("click",handleDocumentClick),()=>{document.removeEventListener("mouseover",handleDocumentMouseOver),document.removeEventListener("click",handleDocumentClick)}),[defaultValue2]),!schemaLoaded||!value)return null;function changeProperty(property,newValue){setValue({...valueRef.current,[property]:newValue})}return jsx126("div",{children:jsxs75(Form,{testid:"questionnaire-form",onSubmit:()=>props.onSubmit(value),children:[jsx126(TextInput23,{label:"Plan Title",py:"md",defaultValue:value.title,onChange:e=>changeProperty("title",e.currentTarget.value)}),jsx126(ActionArrayBuilder,{actions:value.action||[],selectedKey,setSelectedKey,hoverKey,setHoverKey,onChange:x=>changeProperty("action",x)}),jsx126(Button26,{type:"submit",children:"Save"})]})})}function ActionArrayBuilder(props){let actionsRef=useRef19();actionsRef.current=props.actions;function changeAction(changedAction){props.onChange(actionsRef.current.map(i=>i.id===changedAction.id?changedAction:i))}function addAction(addedAction){props.onChange([...actionsRef.current,addedAction]),props.setSelectedKey(addedAction.id)}function removeAction(removedAction){props.onChange(actionsRef.current.filter(i=>i!==removedAction))}return jsxs75(Stack24,{gap:"md",className:PlanDefinitionBuilder_default.section,children:[props.actions.map(action=>jsx126(ActionBuilder,{action,selectedKey:props.selectedKey,setSelectedKey:props.setSelectedKey,hoverKey:props.hoverKey,setHoverKey:props.setHoverKey,onChange:changeAction,onRemove:()=>removeAction(action)},action.id)),jsx126("div",{children:jsx126(Button26,{variant:"outline",onClick:e=>{killEvent(e),addAction({id:generateId()})},children:"Add action"})})]})}function ActionBuilder(props){let{action}=props,actionType=getInitialActionType(action);function onClick(e){e.stopPropagation(),props.setSelectedKey(props.action.id)}function onHover(e){killEvent(e),props.setHoverKey(props.action.id)}return jsx126("div",{onClick,onMouseOver:onHover,onFocus:onHover,children:jsx126(ActionEditor,{action,actionType,onChange:props.onChange,selectedKey:props.selectedKey,setSelectedKey:props.setSelectedKey,hoverKey:props.hoverKey,setHoverKey:props.setHoverKey,onRemove:props.onRemove})})}function ActionEditor(props){let{action}=props,[actionType,setActionType]=useState69(props.actionType),editing=props.selectedKey===props.action.id,hovering=props.hoverKey===props.action.id;function changeProperty(property,value){props.onChange({...action,[property]:value})}let className=clsx_default(PlanDefinitionBuilder_default.section,{[PlanDefinitionBuilder_default.hovering]:hovering&&!editing});return jsxs75(Paper5,{"data-testid":action.id,className,p:0,radius:"sm",withBorder:!0,children:[jsxs75(Flex5,{w:"100%",p:"xs",bg:"gray.0",gap:"md",align:"center",justify:"space-between",children:[jsx126(TextInput23,{w:"100%",name:`actionTitle-${action.id}`,defaultValue:action.title,placeholder:"Title",onChange:e=>changeProperty("title",e.currentTarget.value)}),jsx126(ActionIcon14,{variant:"subtle",color:"gray",onClick:props.onRemove,children:jsx126(CloseButton,{"data-testid":"close-button"})})]}),editing&&jsxs75(Stack24,{gap:"xl",p:"md",children:[jsxs75(Box7,{children:[jsx126(Text25,{fw:600,mb:"xs",children:"Task Description"}),jsx126(TextInput23,{placeholder:"Enter task description",name:`actionDescription-${action.id}`,defaultValue:action.description,onChange:e=>changeProperty("description",e.currentTarget.value)})]}),jsxs75(Box7,{children:[jsx126(Text25,{fw:600,mb:"xs",children:"Type"}),jsx126(Radio4.Group,{value:actionType,onChange:setActionType,children:jsxs75(Stack24,{gap:"sm",children:[jsx126(Radio4,{value:"standard",label:"Standard task",onChange:()=>props.onChange({...props.action,definitionCanonical:void 0})}),jsx126(Radio4,{value:"questionnaire",label:"Task with Questionnaire"})]})})]}),actionType==="questionnaire"&&jsxs75(Box7,{children:[jsxs75(Group50,{gap:"xs",mb:"xs",children:[jsx126(Text25,{fw:600,children:"Select questionnaire"}),jsx126(Text25,{c:"red",children:"*"})]}),jsxs75(Text25,{size:"sm",c:"dimmed",mb:"sm",children:["Questionnaire to be shown in the task in Encounter view. You can create new one from"," ",jsx126(Anchor12,{href:"/Questionnaire",target:"_blank",c:"blue",children:"questionnaires list"})]}),jsx126(ActionResourceTypeBuilder,{title:"Questionnaire",description:"The subject must complete the selected questionnaire.",resourceType:"Questionnaire",action,onChange:props.onChange})]})]})]})}function ActionResourceTypeBuilder(props){let{id,definitionCanonical}=props.action,reference=definitionCanonical?.startsWith(props.resourceType+"/")?{reference:definitionCanonical}:void 0;return jsx126(ResourceInput,{name:id,resourceType:props.resourceType,defaultValue:reference,loadOnFocus:!0,onChange:newValue=>{newValue?props.onChange({...props.action,definitionCanonical:getReferenceString7(newValue)}):props.onChange({...props.action,definitionCanonical:void 0})}})}function getInitialActionType(action){return action.definitionCanonical?.startsWith("Questionnaire")?"questionnaire":"standard"}var nextId=1;function generateId(existing){if(existing){if(existing.startsWith("id-")){let existingNum=parseInt(existing.substring(3),10);isNaN(existingNum)||(nextId=Math.max(nextId,existingNum+1))}return existing}return"id-"+nextId++}function ensurePlanDefinitionKeys(planDefinition){return{...planDefinition,action:ensurePlanDefinitionActionKeys(planDefinition.action)}}function ensurePlanDefinitionActionKeys(actions){if(actions)return actions.map(action=>({...action,id:generateId(action.id),action:ensurePlanDefinitionActionKeys(action.action)}))}import{Anchor as Anchor13,Box as Box8,Button as Button27,Group as Group52,NativeSelect as NativeSelect12,Space as Space2,Textarea as Textarea5,TextInput as TextInput25,Title as Title8}from"@mantine/core";import{getElementDefinition as getElementDefinition3,isResource as isResourceType}from"@medplum/core";import{useMedplum as useMedplum38,useResource as useResource11}from"@medplum/react-hooks";import{useEffect as useEffect27,useRef as useRef20,useState as useState70}from"react";import{Checkbox as Checkbox6,Group as Group51,MultiSelect as MultiSelect2,NativeSelect as NativeSelect11,Radio as Radio5,Textarea as Textarea4,TextInput as TextInput24}from"@mantine/core";import{capitalize as capitalize6,deepEquals as deepEquals2,formatCoding as formatCoding2,getElementDefinition as getElementDefinition2,HTTP_HL7_ORG as HTTP_HL7_ORG8,stringify as stringify3,typedValueToString as typedValueToString2}from"@medplum/core";import{useContext as useContext23}from"react";import{HTTP_HL7_ORG as HTTP_HL7_ORG7,PropertyType as PropertyType3,deepClone as deepClone3,evalFhirPathTyped as evalFhirPathTyped3,getExtension,getReferenceString as getReferenceString8,getTypedPropertyValueWithoutSchema,splitN,toJsBoolean,toTypedValue as toTypedValue2,typedValueToString}from"@medplum/core";var QuestionnaireItemType=(QuestionnaireItemType2=>(QuestionnaireItemType2.group="group",QuestionnaireItemType2.display="display",QuestionnaireItemType2.question="question",QuestionnaireItemType2.boolean="boolean",QuestionnaireItemType2.decimal="decimal",QuestionnaireItemType2.integer="integer",QuestionnaireItemType2.date="date",QuestionnaireItemType2.dateTime="dateTime",QuestionnaireItemType2.time="time",QuestionnaireItemType2.string="string",QuestionnaireItemType2.text="text",QuestionnaireItemType2.url="url",QuestionnaireItemType2.choice="choice",QuestionnaireItemType2.openChoice="open-choice",QuestionnaireItemType2.attachment="attachment",QuestionnaireItemType2.reference="reference",QuestionnaireItemType2.quantity="quantity",QuestionnaireItemType2))(QuestionnaireItemType||{});function isChoiceQuestion(item){return item.type==="choice"||item.type==="open-choice"}function isQuestionEnabled(item,questionnaireResponse){let extension=getExtension(item,HTTP_HL7_ORG7+"/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression");if(questionnaireResponse&&extension){let expression=extension.valueExpression?.expression;if(expression){let value=toTypedValue2(questionnaireResponse),result=evalFhirPathTyped3(expression,[value],{"%resource":value});return toJsBoolean(result)}}if(!item.enableWhen)return!0;let enableBehavior=item.enableBehavior??"any";for(let enableWhen of item.enableWhen){let actualAnswers=getByLinkId(questionnaireResponse?.item,enableWhen.question);if(enableWhen.operator==="exists"&&!enableWhen.answerBoolean&&!actualAnswers?.length){if(enableBehavior==="any")return!0;continue}let{anyMatch,allMatch}=checkAnswers(enableWhen,actualAnswers,enableBehavior);if(enableBehavior==="any"&&anyMatch)return!0;if(enableBehavior==="all"&&!allMatch)return!1}return enableBehavior!=="any"}function evaluateCalculatedExpressionsInQuestionnaire(items,response){return items.map(item=>{if(item.item)return{...item,item:evaluateCalculatedExpressionsInQuestionnaire(item.item,response)};{let calculatedValue=evaluateCalculatedExpression(item,response);if(!calculatedValue)return null;let answer=typedValueToResponseItem(item,calculatedValue);return answer?{id:item?.id,linkId:item?.linkId,text:item.text,answer:[answer]}:null}}).filter(item=>item!==null)}function typedValueToResponseItem(item,value){if(item.type)switch(item.type){case"boolean":return value.type===PropertyType3.boolean?{valueBoolean:value.value}:void 0;case"date":return value.type===PropertyType3.date?{valueDate:value.value}:void 0;case"dateTime":return value.type===PropertyType3.dateTime?{valueDateTime:value.value}:void 0;case"time":return value.type===PropertyType3.time?{valueTime:value.value}:void 0;case"url":return value.type===PropertyType3.url?{valueString:value.value}:void 0;case"text":return value.type===PropertyType3.string?{valueString:value.value}:void 0;case"attachment":return value.type===PropertyType3.Attachment?{valueAttachment:value.value}:void 0;case"reference":return value.type===PropertyType3.Reference?{valueReference:value.value}:void 0;case"quantity":return{valueQuantity:value.value};case"decimal":return{valueDecimal:value.value};case"integer":return{valueInteger:value.value};case"string":return{valueString:value.value};default:return}}function evaluateCalculatedExpression(item,response){if(!response)return;let extension=getExtension(item,HTTP_HL7_ORG7+"/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression");if(extension){let expression=extension.valueExpression?.expression;if(expression){let value=toTypedValue2(response),result=evalFhirPathTyped3(expression,[value],{"%resource":value});return result.length!==0?result[0]:void 0}}}function mergeUpdatedItems(mergedItems,updatedItems){return mergedItems.map(mergedItem=>{let updatedItem=updatedItems.find(updated=>updated.linkId===mergedItem.linkId);return updatedItem?{...mergedItem,item:updatedItem.item?mergeUpdatedItems(mergedItem.item||[],updatedItem.item):mergedItem.item,answer:updatedItem.answer||mergedItem.answer}:mergedItem})}function getNewMultiSelectValues(selected,propertyName,item){let result=[];for(let selectedStr of selected){let option=item.answerOption?.find(candidate=>typedValueToString(getItemAnswerOptionValue(candidate))===selectedStr);if(option){let optionValue=getItemAnswerOptionValue(option);optionValue&&result.push({[propertyName]:optionValue.value})}}return result}function getByLinkId(responseItems,linkId){if(responseItems)for(let response of responseItems){if(response.linkId===linkId)return response.answer;if(response.item){let nestedAnswer=getByLinkId(response.item,linkId);if(nestedAnswer)return nestedAnswer}}}function evaluateMatch(actualAnswer,expectedAnswer,operator){if(operator==="exists")return!!actualAnswer===expectedAnswer.value;if(actualAnswer){let fhirPathOperator=operator==="="||operator==="!="?operator?.replace("=","~"):operator,[{value}]=evalFhirPathTyped3(`%actualAnswer ${fhirPathOperator} %expectedAnswer`,[actualAnswer],{"%actualAnswer":actualAnswer,"%expectedAnswer":expectedAnswer});return value}else return!1}function checkAnswers(enableWhen,answers,enableBehavior){let actualAnswers=answers||[],expectedAnswer=getItemEnableWhenValueAnswer(enableWhen),anyMatch=!1,allMatch=!0;for(let actualAnswerValue of actualAnswers){let actualAnswer=getResponseItemAnswerValue(actualAnswerValue),{operator}=enableWhen;if(evaluateMatch(actualAnswer,expectedAnswer,operator)?anyMatch=!0:allMatch=!1,enableBehavior==="any"&&anyMatch)break}return{anyMatch,allMatch}}function getQuestionnaireItemReferenceTargetTypes(item){let extension=getExtension(item,"http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource");if(extension){if(extension.valueCode!==void 0)return[extension.valueCode];if(extension.valueCodeableConcept)return extension.valueCodeableConcept?.coding?.map(c=>c.code)}}function setQuestionnaireItemReferenceTargetTypes(item,targetTypes){let result=deepClone3(item),extension=getExtension(result,"http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource");return!targetTypes||targetTypes.length===0?(extension&&(result.extension=result.extension?.filter(e=>e!==extension)),result):(extension||(result.extension||(result.extension=[]),extension={url:"http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource"},result.extension.push(extension)),targetTypes.length===1?(extension.valueCode=targetTypes[0],delete extension.valueCodeableConcept):(extension.valueCodeableConcept={coding:targetTypes.map(t=>({code:t}))},delete extension.valueCode),result)}function getQuestionnaireItemReferenceFilter(item,subject,encounter){let extension=getExtension(item,"http://hl7.org/fhir/StructureDefinition/questionnaire-referenceFilter");if(!extension?.valueString)return;let filter=extension.valueString;subject?.reference&&(filter=filter.replaceAll("$subj",subject.reference)),encounter?.reference&&(filter=filter.replaceAll("$encounter",encounter.reference));let result={},parts=filter.split("&");for(let part of parts){let[key,value]=splitN(part,"=",2);result[key]=value}return result}function buildInitialResponse(questionnaire){return{resourceType:"QuestionnaireResponse",questionnaire:getReferenceString8(questionnaire),item:buildInitialResponseItems(questionnaire.item),status:"in-progress"}}function buildInitialResponseItems(items){return items?.map(buildInitialResponseItem)??[]}function buildInitialResponseItem(item){return{id:generateId2(),linkId:item.linkId,text:item.text,item:buildInitialResponseItems(item.item),answer:item.initial?.map(buildInitialResponseAnswer)??[]}}var nextId2=1;function generateId2(){return"id-"+nextId2++}function buildInitialResponseAnswer(answer){return{...answer}}function getNumberOfPages(questionnaire){let firstItem=questionnaire?.item?.[0];return firstItem&&getExtension(firstItem,"http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl")?.valueCodeableConcept?.coding?.[0]?.code==="page"?questionnaire.item.length:1}function getItemInitialValue(initial){return getTypedPropertyValueWithoutSchema({type:"QuestionnaireItemInitial",value:initial},"value")}function getItemAnswerOptionValue(option){return getTypedPropertyValueWithoutSchema({type:"QuestionnaireItemAnswerOption",value:option},"value")}function getItemEnableWhenValueAnswer(enableWhen){return getTypedPropertyValueWithoutSchema({type:"QuestionnaireItemEnableWhen",value:enableWhen},"answer")}function getResponseItemAnswerValue(answer){return getTypedPropertyValueWithoutSchema({type:"QuestionnaireResponseItemAnswer",value:answer},"value")}import{createContext as createContext2}from"react";var QuestionnaireFormContext=createContext2({});import{jsx as jsx127}from"react/jsx-runtime";function QuestionnaireFormItem(props){let context=useContext23(QuestionnaireFormContext),item=props.item,response=props.response;function onChangeAnswer(newResponseAnswer){let updatedAnswers;Array.isArray(newResponseAnswer)?updatedAnswers=newResponseAnswer:props.index>=(props.response?.answer?.length??0)?updatedAnswers=(props.response?.answer??[]).concat([newResponseAnswer]):updatedAnswers=(props.response?.answer??[]).map((a,idx)=>idx===props.index?newResponseAnswer:a)??[],props.onChange({id:response?.id,linkId:response?.linkId,text:item.text,answer:updatedAnswers})}let type=item.type;if(!type)return null;let name=item.linkId;if(!name)return null;let initial=item.initial&&item.initial.length>0?item.initial[0]:void 0,defaultValue2=getCurrentAnswer(response,props.index)??getItemInitialValue(initial);switch(type){case"display":return jsx127("p",{children:props.item.text},props.item.linkId);case"boolean":return jsx127(CheckboxFormSection,{title:props.item.text,htmlFor:props.item.linkId,children:jsx127(Checkbox6,{id:props.item.linkId,name:props.item.linkId,defaultChecked:defaultValue2?.value,onChange:e=>onChangeAnswer({valueBoolean:e.currentTarget.checked})})},props.item.linkId);case"decimal":return jsx127(TextInput24,{type:"number",step:"any",id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueDecimal:e.currentTarget.valueAsNumber})});case"integer":return jsx127(TextInput24,{type:"number",step:1,id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueInteger:e.currentTarget.valueAsNumber})});case"date":return jsx127(TextInput24,{type:"date",id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueDate:e.currentTarget.value})});case"dateTime":return jsx127(DateTimeInput,{name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:newValue=>onChangeAnswer({valueDateTime:newValue})});case"time":return jsx127(TextInput24,{type:"time",id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueTime:e.currentTarget.value})});case"string":case"url":return jsx127(TextInput24,{id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueString:e.currentTarget.value})});case"text":return jsx127(Textarea4,{id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueString:e.currentTarget.value})});case"attachment":return jsx127(Group51,{py:4,children:jsx127(AttachmentInput,{path:"",name,defaultValue:defaultValue2?.value,onChange:newValue=>onChangeAnswer({valueAttachment:newValue})})});case"reference":return jsx127(ReferenceInput,{name,required:props.required??item.required,targetTypes:getQuestionnaireItemReferenceTargetTypes(item),searchCriteria:getQuestionnaireItemReferenceFilter(item,context.subject,context.encounter),defaultValue:defaultValue2?.value,onChange:newValue=>onChangeAnswer({valueReference:newValue})});case"quantity":return jsx127(QuantityInput,{path:"",name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:newValue=>onChangeAnswer({valueQuantity:newValue}),disableWheel:!0});case"choice":case"open-choice":return isDropDownChoice(item)&&!item.answerValueSet?jsx127(QuestionnaireChoiceDropDownInput,{name,item,initial,response,onChangeAnswer:e=>onChangeAnswer(e)}):isMultiSelectChoice(item)&&!item.answerValueSet?jsx127(QuestionnaireMultiSelectInput,{name,item,initial,response,onChangeAnswer:e=>onChangeAnswer(e)}):jsx127(QuestionnaireChoiceSetInput,{name,item,initial,response,onChangeAnswer:e=>onChangeAnswer(e)});default:return null}}function QuestionnaireChoiceDropDownInput(props){let{name,item,initial,response}=props;if(!item.answerOption?.length)return jsx127(NoAnswerDisplay,{});let initialValue=getItemInitialValue(initial),data2=[""];for(let option of item.answerOption){let optionValue=getItemAnswerOptionValue(option);data2.push(typedValueToString2(optionValue))}let defaultValue2=getCurrentAnswer(response)??initialValue;if(item.repeats){let{propertyName,data:data3}=formatSelectData(props.item),currentAnswer=getCurrentMultiSelectAnswer(response);return jsx127(MultiSelect2,{data:data3,placeholder:"Select items",searchable:!0,defaultValue:currentAnswer||[typedValueToString2(initialValue)],onChange:selected=>{let values=getNewMultiSelectValues(selected,propertyName,item);props.onChangeAnswer(values)}})}return jsx127(NativeSelect11,{id:name,name,onChange:e=>{let index=e.currentTarget.selectedIndex;if(index===0){props.onChangeAnswer({});return}let option=item.answerOption[index-1],optionValue=getItemAnswerOptionValue(option),propertyName="value"+capitalize6(optionValue.type);props.onChangeAnswer({[propertyName]:optionValue.value})},defaultValue:formatCoding2(defaultValue2?.value)||defaultValue2?.value,data:data2})}function QuestionnaireMultiSelectInput(props){let{item,initial,response}=props;if(!item.answerOption?.length)return jsx127(NoAnswerDisplay,{});let initialValue=getItemInitialValue(initial),{propertyName,data:data2}=formatSelectData(props.item),currentAnswer=getCurrentMultiSelectAnswer(response);return jsx127(MultiSelect2,{data:data2,placeholder:"Select items",searchable:!0,defaultValue:currentAnswer||[typedValueToString2(initialValue)],onChange:selected=>{let values=getNewMultiSelectValues(selected,propertyName,item);props.onChangeAnswer(values)}})}function QuestionnaireChoiceSetInput(props){let{name,item,initial,onChangeAnswer,response}=props;return!item.answerOption?.length&&!item.answerValueSet?jsx127(NoAnswerDisplay,{}):item.answerValueSet?jsx127(CodingInput,{path:"",name,binding:item.answerValueSet,response,onChange:code=>onChangeAnswer({valueCoding:code}),creatable:item.type==="open-choice"}):jsx127(QuestionnaireChoiceRadioInput,{name:response?.id??name,item,initial,response,onChangeAnswer})}function QuestionnaireChoiceRadioInput(props){let{name,item,initial,onChangeAnswer,response}=props,valueElementDefinition=getElementDefinition2("QuestionnaireItemAnswerOption","value[x]"),initialValue=getItemInitialValue(initial),options=[],defaultValue2;if(item.answerOption)for(let i=0;i<item.answerOption.length;i++){let option=item.answerOption[i],optionName=`${name}-option-${i}`,optionValue=getItemAnswerOptionValue(option);optionValue?.value&&(initialValue&&stringify3(optionValue)===stringify3(initialValue)&&(defaultValue2=optionName),options.push([optionName,optionValue]))}let defaultAnswer=getCurrentAnswer(response),answerLinkId=getCurrentRadioAnswer(options,defaultAnswer);return jsx127(Radio5.Group,{name,value:answerLinkId??defaultValue2,onChange:newValue=>{let option=options.find(option2=>option2[0]===newValue);if(option){let optionValue=option[1],propertyName="value"+capitalize6(optionValue.type);onChangeAnswer({[propertyName]:optionValue.value})}},children:options.map(([optionName,optionValue])=>jsx127(Radio5,{id:optionName,value:optionName,py:4,label:jsx127(ResourcePropertyDisplay,{property:valueElementDefinition,propertyType:optionValue.type,value:optionValue.value})},optionName))})}function NoAnswerDisplay(){return jsx127(TextInput24,{disabled:!0,placeholder:"No Answers Defined"})}function getCurrentAnswer(response,index=0){let results=response.answer;return getItemAnswerOptionValue(results?.[index]??{})}function getCurrentMultiSelectAnswer(response){let results=response.answer;return results?results.map(a=>getItemAnswerOptionValue(a)).map(type=>formatCoding2(type?.value)||type?.value):[]}function getCurrentRadioAnswer(options,defaultAnswer){return options.find(option=>deepEquals2(option[1].value,defaultAnswer?.value))?.[0]}function isDropDownChoice(item){return!!item.extension?.some(e=>e.url==="http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl"&&e.valueCodeableConcept?.coding?.[0]?.code==="drop-down")}function isMultiSelectChoice(item){return!!item.extension?.some(e=>e.url===HTTP_HL7_ORG8+"/fhir/StructureDefinition/questionnaire-itemControl"&&e.valueCodeableConcept?.coding?.[0]?.code==="multi-select")}function formatSelectData(item){if(item.answerOption?.length===0)return{propertyName:"",data:[]};let option=item.answerOption[0],optionValue=getItemAnswerOptionValue(option),propertyName="value"+capitalize6(optionValue.type),data2=(item.answerOption??[]).map(answerOption=>{let answerOptionValue=getItemAnswerOptionValue(answerOption),answerOptionValueStr=typedValueToString2(answerOptionValue);return{value:answerOptionValueStr,label:answerOptionValueStr}});return{propertyName,data:data2}}var QuestionnaireBuilder_default={section:"QuestionnaireBuilder_section",hovering:"QuestionnaireBuilder_hovering",editing:"QuestionnaireBuilder_editing",questionBody:"QuestionnaireBuilder_questionBody",topActions:"QuestionnaireBuilder_topActions",bottomActions:"QuestionnaireBuilder_bottomActions",movementActions:"QuestionnaireBuilder_movementActions",movementIcons:"QuestionnaireBuilder_movementIcons",columnAlignment:"QuestionnaireBuilder_columnAlignment",linkIdInput:"QuestionnaireBuilder_linkIdInput",typeSelect:"QuestionnaireBuilder_typeSelect",preserveBreaks:"QuestionnaireBuilder_preserveBreaks"};import{Fragment as Fragment43,jsx as jsx128,jsxs as jsxs76}from"react/jsx-runtime";function QuestionnaireBuilder(props){let medplum=useMedplum38(),defaultValue2=useResource11(props.questionnaire),[schemaLoaded,setSchemaLoaded]=useState70(!1),[value,setValue]=useState70(),[selectedKey,setSelectedKey]=useState70(),[hoverKey,setHoverKey]=useState70();function handleDocumentMouseOver(){setHoverKey(void 0)}function handleDocumentClick(){setSelectedKey(void 0)}useEffect27(()=>{medplum.requestSchema("Questionnaire").then(()=>setSchemaLoaded(!0)).catch(console.log)},[medplum]),useEffect27(()=>(setValue(ensureQuestionnaireKeys(defaultValue2??{resourceType:"Questionnaire",status:"active"})),document.addEventListener("mouseover",handleDocumentMouseOver),document.addEventListener("click",handleDocumentClick),()=>{document.removeEventListener("mouseover",handleDocumentMouseOver),document.removeEventListener("click",handleDocumentClick)}),[defaultValue2]);let handleChange=(questionnaire,disableSubmit)=>{setValue(questionnaire),props.autoSave&&!disableSubmit&&props.onSubmit&&props.onSubmit(questionnaire)};return!schemaLoaded||!value?null:jsx128("div",{children:jsxs76(Form,{testid:"questionnaire-form",onSubmit:()=>props.onSubmit(value),children:[jsx128(ItemBuilder,{item:value,selectedKey,setSelectedKey,hoverKey,setHoverKey,onChange:handleChange}),jsx128(Button27,{type:"submit",children:"Save"})]})})}function ItemBuilder(props){let resource=props.item,item=props.item,isResource2=isResourceType(props.item),isContainer=isResource2||item.type==="group",linkId=item.linkId??"[untitled]",editing=props.selectedKey===props.item.id,hovering=props.hoverKey===props.item.id,itemRef=useRef20();itemRef.current=props.item;function onClick(e){killEvent(e),props.setSelectedKey(props.item.id)}function onHover(e){killEvent(e),props.setHoverKey(props.item.id)}function changeItem(changedItem){let curr=itemRef.current;props.onChange({...curr,item:curr.item?.map(i=>i.id===changedItem.id?changedItem:i)})}function addItem(addedItem,disableSubmit){props.onChange({...props.item,item:[...props.item.item??[],addedItem]},disableSubmit)}function removeItem(removedItem){props.onChange({...props.item,item:props.item.item?.filter(i=>i!==removedItem)})}function changeProperty(property,value){props.onChange({...itemRef.current,[property]:value})}function updateItem(updatedItem){props.onChange({...props.item,...updatedItem})}function toggleRepeatable(item2){props.onChange({...props.item,item:props.item.item?.map(i=>i===item2?{...i,repeats:!i.repeats}:i)})}function moveItem(itemIndex,delta){let updatedItems=reorderItems(props.item.item,itemIndex,delta);props.onChange({...props.item,item:updatedItems})}let className=clsx_default(QuestionnaireBuilder_default.section,{[QuestionnaireBuilder_default.editing]:editing,[QuestionnaireBuilder_default.hovering]:hovering&&!editing});return jsxs76("div",{"data-testid":item.linkId,className,onClick,onMouseOver:onHover,onFocus:onHover,children:[jsx128("div",{className:QuestionnaireBuilder_default.questionBody,children:editing?jsxs76(Fragment43,{children:[isResource2&&jsx128(TextInput25,{size:"xl",defaultValue:resource.title,onBlur:e=>changeProperty("title",e.currentTarget.value)}),!isResource2&&jsx128(Textarea5,{autosize:!0,minRows:2,defaultValue:item.text,onBlur:e=>changeProperty("text",e.currentTarget.value)}),item.type==="reference"&&jsx128(ReferenceProfiles,{item,onChange:updateItem}),isChoiceQuestion(item)&&jsx128(AnswerBuilder,{item,onChange:item2=>updateItem(item2)})]}):jsxs76(Fragment43,{children:[resource.title&&jsx128(Title8,{children:resource.title}),item.text&&jsx128("div",{className:QuestionnaireBuilder_default.preserveBreaks,children:item.text}),!isContainer&&jsx128(QuestionnaireFormItem,{item,index:0,required:!1,onChange:()=>{},response:{linkId:item.linkId}})]})}),item.item?.map((item2,i)=>jsx128("div",{children:jsx128(ItemBuilder,{item:item2,selectedKey:props.selectedKey,setSelectedKey:props.setSelectedKey,hoverKey:props.hoverKey,isFirst:i===0,isLast:i===(props.item.item??[]).length-1,setHoverKey:props.setHoverKey,onChange:changeItem,onRemove:()=>removeItem(item2),onRepeatable:toggleRepeatable,onMoveUp:()=>moveItem(i,-1),onMoveDown:()=>moveItem(i,1)})},item2.id)),!isContainer&&jsx128("div",{className:QuestionnaireBuilder_default.topActions,children:editing?jsxs76(Fragment43,{children:[jsx128(TextInput25,{size:"xs",className:QuestionnaireBuilder_default.linkIdInput,defaultValue:item.linkId,onBlur:e=>changeProperty("linkId",e.currentTarget.value)}),!isContainer&&jsx128(NativeSelect12,{size:"xs",className:QuestionnaireBuilder_default.typeSelect,defaultValue:item.type,onChange:e=>changeProperty("type",e.currentTarget.value),data:[{value:"display",label:"Display"},{value:"boolean",label:"Boolean"},{value:"decimal",label:"Decimal"},{value:"integer",label:"Integer"},{value:"date",label:"Date"},{value:"dateTime",label:"Date/Time"},{value:"time",label:"Time"},{value:"string",label:"String"},{value:"text",label:"Text"},{value:"url",label:"URL"},{value:"choice",label:"Choice"},{value:"open-choice",label:"Open Choice"},{value:"attachment",label:"Attachment"},{value:"reference",label:"Reference"},{value:"quantity",label:"Quantity"}]})]}):jsx128("div",{children:linkId})}),!isResource2&&jsx128(Box8,{className:QuestionnaireBuilder_default.movementActions,children:jsxs76(Box8,{className:QuestionnaireBuilder_default.columnAlignment,children:[!props.isFirst&&jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),props.onMoveUp&&props.onMoveUp()},children:jsx128(IconArrowUp,{"data-testid":"up-button",size:15,className:QuestionnaireBuilder_default.movementIcons})}),!props.isLast&&jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),props.onMoveDown&&props.onMoveDown()},children:jsx128(IconArrowDown,{"data-testid":"down-button",size:15,className:QuestionnaireBuilder_default.movementIcons})})]})}),jsxs76("div",{className:QuestionnaireBuilder_default.bottomActions,children:[isContainer&&jsxs76(Fragment43,{children:[jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),addItem({id:generateId3(),linkId:generateLinkId("q"),type:"string",text:"Question"})},children:"Add item"}),jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),addItem({id:generateId3(),linkId:generateLinkId("g"),type:"group",text:"Group"},!0)},children:"Add group"})]}),isResource2&&jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),addItem(createPage(),!0)},children:"Add Page"}),editing&&!isResource2&&jsxs76(Fragment43,{children:[jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),props.onRepeatable&&props.onRepeatable(item)},children:item.repeats?"Remove Repeatable":"Make Repeatable"}),jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),props.onRemove&&props.onRemove()},children:"Remove"})]})]})]})}function AnswerBuilder(props){let property=getElementDefinition3("QuestionnaireItemAnswerOption","value[x]"),options=props.item.answerOption??[];return jsxs76("div",{children:[props.item.answerValueSet!==void 0?jsx128(TextInput25,{placeholder:"Enter Value Set",defaultValue:props.item.answerValueSet,onChange:e=>props.onChange({...props.item,answerValueSet:e.target.value})}):jsx128(AnswerOptionsInput,{options,property,item:props.item,onChange:props.onChange}),jsxs76(Box8,{display:"flex",children:[jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange({...props.item,answerValueSet:void 0,answerOption:[...options,{id:generateId3()}]})},children:"Add choice"}),jsx128(Space2,{w:"lg"}),jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange({...props.item,answerOption:[],answerValueSet:""})},children:"Add value set"})]})]})}function AnswerOptionsInput(props){return jsx128("div",{children:props.options.map(option=>{let[propertyValue,propertyType]=getValueAndType({type:"QuestionnaireItemAnswerOption",value:option},"value");return jsxs76("div",{style:{display:"flex",flexDirection:"row",justifyContent:"space-between",alignItems:"center",width:"80%"},children:[jsx128("div",{children:jsx128(ResourcePropertyInput,{name:"value[x]",path:"Questionnaire.answerOption.value[x]",property:props.property,defaultPropertyType:propertyType,defaultValue:propertyValue,onChange:(newValue,propName)=>{let newOptions=[...props.options],index=newOptions.findIndex(o=>o.id===option.id);newOptions[index]={id:option.id,[propName]:newValue},props.onChange({...props.item,answerOption:newOptions})},outcome:void 0},option.id)}),jsx128("div",{children:jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange({...props.item,answerOption:props.options.filter(o=>o.id!==option.id)})},children:"Remove"})})]},option.id)})})}function ReferenceProfiles(props){let targetTypes=getQuestionnaireItemReferenceTargetTypes(props.item)??[];return jsxs76(Fragment43,{children:[targetTypes.map((targetType,index)=>jsxs76(Group52,{children:[jsx128(ResourceTypeInput,{name:"resourceType",placeholder:"Resource Type",defaultValue:targetType,onChange:newValue=>{props.onChange(setQuestionnaireItemReferenceTargetTypes(props.item,targetTypes.map(t=>t===targetType?newValue:t)))}}),jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange(setQuestionnaireItemReferenceTargetTypes(props.item,targetTypes.filter(t=>t!==targetType)))},children:"Remove"})]},`${targetType}-${index}`)),jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange(setQuestionnaireItemReferenceTargetTypes(props.item,[...targetTypes,""]))},children:"Add Resource Type"})]})}var nextLinkId=1,nextId3=1;function generateLinkId(prefix){return prefix+nextLinkId++}function generateId3(){return"id-"+nextId3++}function ensureQuestionnaireKeys(questionnaire){return{...questionnaire,id:questionnaire.id||generateId3(),item:ensureQuestionnaireItemKeys(questionnaire.item)}}function ensureQuestionnaireItemKeys(items){if(items)return items.forEach(item=>{item.id?.match(/^id-\d+$/)&&(nextId3=Math.max(nextId3,parseInt(item.id.substring(3),10)+1)),item.linkId?.match(/^q\d+$/)&&(nextLinkId=Math.max(nextLinkId,parseInt(item.linkId.substring(1),10)+1))}),items.map(item=>({...item,id:item.id||generateId3(),item:ensureQuestionnaireItemKeys(item.item),answerOption:ensureQuestionnaireOptionKeys(item.answerOption)}))}function ensureQuestionnaireOptionKeys(options){if(options)return options.map(option=>({...option,id:option.id||generateId3()}))}function createPage(){return{id:generateId3(),linkId:generateLinkId("s"),type:"group",text:"New Page",extension:[{url:"http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl",valueCodeableConcept:{coding:[{system:"http://hl7.org/fhir/questionnaire-item-control",code:"page"}]}}]}}function reorderItems(items,itemIndex,delta){let currentItems=items??[],newIndex=itemIndex+delta;if(newIndex<0||newIndex>=currentItems.length)return currentItems;let updatedItems=[...currentItems];return[updatedItems[itemIndex],updatedItems[newIndex]]=[updatedItems[newIndex],updatedItems[itemIndex]],updatedItems}import{Title as Title10}from"@mantine/core";import{createReference as createReference13,getReferenceString as getReferenceString9}from"@medplum/core";import{useMedplum as useMedplum39,usePrevious as usePrevious2,useResource as useResource12}from"@medplum/react-hooks";import{useCallback as useCallback26,useEffect as useEffect29,useRef as useRef21,useState as useState73}from"react";import{Button as Button28,Group as Group53,Stack as Stack26,Stepper}from"@mantine/core";import{Anchor as Anchor14}from"@mantine/core";import{useState as useState71}from"react";import{jsx as jsx129,jsxs as jsxs77}from"react/jsx-runtime";function QuestionnaireRepeatableItem(props){let{item,response,onChange}=props,[number,setNumber]=useState71(getNumberOfRepeats(item,response??{linkId:item.linkId}));if(!props.checkForQuestionEnabled(item)||!response)return null;if(item.type==="display")return jsx129("p",{children:item.text},item.linkId);let showAddButton=item?.repeats&&item.type!=="choice"&&item.type!=="open-choice";return item.type==="boolean"?jsx129(QuestionnaireFormItem,{item,response,onChange:r2=>onChange([r2]),index:0},item.linkId):jsxs77(FormSection,{htmlFor:props.item.linkId,title:props.item.text,withAsterisk:props.item.required,children:[[...Array(number)].map((_,index)=>jsx129(QuestionnaireFormItem,{item,response,onChange:r2=>onChange([r2]),index},`${item.linkId}-${index}`)),showAddButton&&jsx129(Anchor14,{onClick:()=>setNumber(n=>n+1),children:"Add Item"})]},props.item.linkId)}function getNumberOfRepeats(item,response){if(item.type==="choice"||item.type==="open-choice")return 1;let answers=response.answer;return answers?.length?answers.length:1}import{Anchor as Anchor15,Stack as Stack25,Title as Title9}from"@mantine/core";import{useEffect as useEffect28,useState as useState72}from"react";import{Fragment as Fragment44,jsx as jsx130,jsxs as jsxs78}from"react/jsx-runtime";function QuestionnaireRepeatedGroup(props){let[responses,setResponses]=useState72(props.response);if(useEffect28(()=>{setResponses(props.response)},[props.response]),responses.length===0)return null;function handleRepeatableGroup(newResponseItems,index){let newResponses=responses.map((responses2,idx)=>idx===index?newResponseItems[0]:responses2);setResponses(newResponses),props.onChange(newResponses)}function insertNewGroup(){let newResponse=buildInitialResponseItem(props.item);setResponses([...responses,newResponse])}return jsxs78(Fragment44,{children:[responses.map((response,idx)=>jsx130(QuestionnaireGroup,{item:props.item,response,checkForQuestionEnabled:props.checkForQuestionEnabled,onChange:r2=>handleRepeatableGroup(r2,idx)},response.id)),props.item.repeats&&jsx130(Anchor15,{onClick:insertNewGroup,children:`Add Group: ${props.item.text}`})]})}function QuestionnaireGroup(props){let{response,checkForQuestionEnabled,onChange}=props;function onSetGroup(newResponseItem){let mergedResponse=response.item?.map(current=>newResponseItem.find(newResponse2=>newResponse2.id===current.id)??current)?.concat(newResponseItem.slice(1)),groupResponse={...response,item:mergedResponse};onChange([groupResponse])}return props.checkForQuestionEnabled(props.item)?jsxs78("div",{children:[props.item.text&&jsx130(Title9,{order:3,mb:"md",children:props.item.text}),jsx130(Stack25,{children:props.item.item?.map(item=>item.type==="group"?item.repeats?jsx130(QuestionnaireRepeatedGroup,{item,response:response.item?.filter(i=>i.linkId===item.linkId)??[],checkForQuestionEnabled,onChange:onSetGroup},item.linkId):jsx130(QuestionnaireGroup,{item,checkForQuestionEnabled,response:response.item?.find(i=>i.linkId===item.linkId)??{linkId:item.linkId},onChange:onSetGroup},item.linkId):jsx130(QuestionnaireRepeatableItem,{item,response:response.item?.find(i=>i.linkId===item.linkId),onChange:onSetGroup,checkForQuestionEnabled},item.linkId))})]},props.item.linkId):null}import{Fragment as Fragment45,jsx as jsx131,jsxs as jsxs79}from"react/jsx-runtime";function QuestionnairePageSequence(props){let{items,response,activePage,onChange,nextStep,prevStep,numberOfPages,renderPages,submitButtonText,excludeButtons,checkForQuestionEnabled}=props,form=items.map(item=>{let itemResponse=response?.item?.filter(i=>i.linkId===item.linkId)??[],repeatedItem=item.type==="group"?jsx131(QuestionnaireRepeatedGroup,{item,response:itemResponse,onChange,checkForQuestionEnabled},item.linkId):jsx131(QuestionnaireRepeatableItem,{item,response:itemResponse?.[0],onChange,checkForQuestionEnabled},item.linkId);return renderPages?jsx131(Stepper.Step,{label:item.text,children:repeatedItem},item.linkId):repeatedItem});return jsxs79(Fragment45,{children:[renderPages&&jsx131(Stepper,{active:activePage??0,allowNextStepsSelect:!1,p:6,children:form}),!renderPages&&jsx131(Stack26,{children:form}),!excludeButtons&&jsx131(ButtonGroup,{activePage:activePage??0,numberOfPages,nextStep:renderPages?nextStep:void 0,prevStep:renderPages?prevStep:void 0,renderPages,submitButtonText})]})}function ButtonGroup(props){let showBackButton=props.renderPages&&props.activePage>0,showNextButton=props.renderPages&&props.activePage<props.numberOfPages-1,showSubmitButton=!props.renderPages||props.activePage===props.numberOfPages-1;return jsxs79(Group53,{justify:"flex-end",mt:"xl",gap:"xs",children:[showBackButton&&jsx131(Button28,{onClick:props.prevStep,children:"Back"}),showNextButton&&jsx131(Button28,{onClick:e=>{let form=e.currentTarget.closest("form");props.nextStep&&form.reportValidity()&&props.nextStep()},children:"Next"}),showSubmitButton&&jsx131(Button28,{type:"submit",children:props.submitButtonText??"Submit"})]})}import{jsx as jsx132,jsxs as jsxs80}from"react/jsx-runtime";function QuestionnaireForm(props){let medplum=useMedplum39(),{subject,source:sourceFromProps}=props,questionnaire=useResource12(props.questionnaire),prevQuestionnaire=usePrevious2(questionnaire),questionnaireResponse=useResource12(props.questionnaireResponse),[response,setResponse]=useState73(questionnaireResponse),[activePage,setActivePage]=useState73(0),onChangeRef=useRef21(props.onChange);onChangeRef.current=props.onChange;let onSubmitRef=useRef21(props.onSubmit);onSubmitRef.current=props.onSubmit,useEffect29(()=>{if(questionnaireResponse?.item)setResponse(prevResponse=>updateResponseItems(prevResponse,questionnaireResponse.item,questionnaire));else{if(questionnaire&&getQuestionnaireIdentity(prevQuestionnaire)===getQuestionnaireIdentity(questionnaire))return;setResponse(questionnaire?buildInitialResponse(questionnaire):void 0)}},[questionnaireResponse,questionnaire,prevQuestionnaire]),useEffect29(()=>{if(response&&onChangeRef.current)try{onChangeRef.current(response)}catch(e){console.error("Error invoking QuestionnaireForm.onChange callback",e)}},[response]);let setItems=useCallback26(newResponseItems=>{setResponse(prevResponse=>updateResponseItems(prevResponse,newResponseItems,questionnaire))},[questionnaire]),handleSubmit=useCallback26(()=>{let onSubmit=onSubmitRef.current;if(onSubmit&&response){let source=sourceFromProps;if(!source){let profile=medplum.getProfile();profile&&(source=createReference13(profile))}onSubmit({...response,questionnaire:getReferenceString9(questionnaire),subject,source,authored:new Date().toISOString(),status:"completed"})}},[medplum,questionnaire,response,subject,sourceFromProps]);function checkForQuestionEnabled(item){return isQuestionEnabled(item,response)}if(!questionnaire||!response)return null;let numberOfPages=getNumberOfPages(questionnaire),nextStep=()=>setActivePage(current=>current+1),prevStep=()=>setActivePage(current=>current-1);return jsx132(QuestionnaireFormContext.Provider,{value:{subject:props.subject,encounter:props.encounter},children:jsxs80(Form,{testid:"questionnaire-form",onSubmit:handleSubmit,children:[questionnaire.title&&jsx132(Title10,{children:questionnaire.title}),jsx132(QuestionnairePageSequence,{items:questionnaire.item??[],response,onChange:setItems,renderPages:!props.disablePagination&&numberOfPages>1,activePage,numberOfPages,excludeButtons:props.excludeButtons,submitButtonText:props.submitButtonText,checkForQuestionEnabled,nextStep,prevStep})]})})}function mergeIndividualItems(prevItem,newItem){let mergedNestedItems=mergeItems(prevItem.item??[],newItem.item??[]);return{...newItem,item:mergedNestedItems.length>0?mergedNestedItems:void 0,answer:newItem.answer&&newItem.answer.length>0?newItem.answer:prevItem.answer}}function mergeItems(prevItems,newItems){let result=[],usedIds=new Set;for(let prevItem of prevItems){let itemId=prevItem.id,newItem=newItems.find(item=>item.id===itemId);newItem?(result.push(mergeIndividualItems(prevItem,newItem)),usedIds.add(newItem.id)):result.push(prevItem)}for(let newItem of newItems)usedIds.has(newItem.id)||result.push(newItem);return result}function getQuestionnaireIdentity(questionnaire){return questionnaire?.id||questionnaire}function updateResponseItems(prevResponse,newResponseItems,questionnaire){if(!newResponseItems)return{resourceType:"QuestionnaireResponse",status:"in-progress"};let currentItems=prevResponse?.item??[],mergedItems=mergeItems(currentItems,Array.isArray(newResponseItems)?newResponseItems:[newResponseItems]),tempResponse={resourceType:"QuestionnaireResponse",status:"in-progress",item:mergedItems},updatedItems=evaluateCalculatedExpressionsInQuestionnaire(questionnaire?.item??[],tempResponse);return{resourceType:"QuestionnaireResponse",status:"in-progress",item:mergeUpdatedItems(mergedItems,updatedItems)}}import{ActionIcon as ActionIcon15,Button as Button29,Divider as Divider4,Group as Group54,NativeSelect as NativeSelect13,Stack as Stack27,Text as Text26,TextInput as TextInput26}from"@mantine/core";import{formatRange as formatRange2,getCodeBySystem}from"@medplum/core";import{useEffect as useEffect30,useState as useState74}from"react";var ReferenceRangeEditor_default={section:"ReferenceRangeEditor_section"};import{jsx as jsx133,jsxs as jsxs81}from"react/jsx-runtime";var intervalFilters=["gender","age","gestationalAge","context","appliesTo","category"],defaultProps={definition:{resourceType:"ObservationDefinition",code:{text:""}},onSubmit:()=>{}};function ReferenceRangeEditor(props){props=Object.assign(defaultProps,props);let defaultDefinition=props.definition,[intervalGroups,setIntervalGroups]=useState74([]),[groupId,setGroupId]=useState74(1),[intervalId,setIntervalId]=useState74(1);return useEffect30(()=>{let definition=ensureQualifiedIntervalKeys(defaultDefinition,setIntervalId);setIntervalGroups(groupQualifiedIntervals(definition.qualifiedInterval||[],setGroupId))},[defaultDefinition]),jsxs81(Form,{testid:"reference-range-editor",onSubmit:submitDefinition,children:[jsx133(Stack27,{children:intervalGroups.map(intervalGroup=>jsx133(ReferenceRangeGroupEditor,{unit:getUnitString(defaultDefinition.quantitativeDetails?.unit),onChange:changeInterval,onAdd:addInterval,onRemove:removeInterval,onRemoveGroup:removeGroup,intervalGroup},`group-${intervalGroup.id}`))}),jsx133(ActionIcon15,{title:"Add Group",variant:"subtle",size:"sm",onClick:e=>{killEvent(e),addGroup({id:`group-id-${groupId}`,filters:{},intervals:[]}),setGroupId(id=>id+1)},children:jsx133(IconCirclePlus,{})}),jsx133(Group54,{justify:"flex-end",children:jsx133(Button29,{type:"submit",children:"Save"})})]});function submitDefinition(){let qualifiedInterval=intervalGroups.flatMap(group=>group.intervals).filter(interval=>!isEmptyInterval(interval));props.onSubmit({...defaultDefinition,qualifiedInterval})}function addGroup(addedGroup){setIntervalGroups(currentGroups=>[...currentGroups,addedGroup])}function removeGroup(removedGroup){setIntervalGroups(currentGroups=>currentGroups.filter(group=>group.id!==removedGroup.id))}function changeInterval(groupId2,changedInterval){setIntervalGroups(groups=>{groups=[...groups];let currentGroup=groups.find(g=>g.id===groupId2),index=currentGroup?.intervals.findIndex(interval=>interval.id===changedInterval.id);return index!==void 0&¤tGroup?.intervals[index]&&(currentGroup.intervals[index]=changedInterval),groups})}function addInterval(groupId2,addedInterval){addedInterval.id===void 0&&(addedInterval.id=`id-${intervalId}`,setIntervalId(id=>id+1)),setIntervalGroups(groups=>{groups=[...groups];let currentGroupIndex=groups.findIndex(g=>g.id===groupId2);if(currentGroupIndex!==-1){let currentGroup={...groups[currentGroupIndex]};addedInterval={...addedInterval,...currentGroup.filters},currentGroup.intervals=[...currentGroup.intervals,addedInterval],groups[currentGroupIndex]=currentGroup}return groups})}function removeInterval(groupId2,removedInterval){setIntervalGroups(groups=>{groups=[...groups];let currentGroup=groups.find(g=>g.id===groupId2);return currentGroup&&(currentGroup.intervals=currentGroup.intervals.filter(interval=>interval.id!==removedInterval.id)),groups})}}function ReferenceRangeGroupEditor(props){let{intervalGroup,unit}=props;return jsx133(Container,{"data-testid":intervalGroup.id,className:ReferenceRangeEditor_default.section,children:jsxs81(Stack27,{gap:"lg",children:[jsx133(Group54,{justify:"flex-end",children:jsx133(ActionIcon15,{title:"Remove Group",variant:"subtle","data-testid":`remove-group-button-${intervalGroup.id}`,size:"sm",onClick:e=>{killEvent(e),props.onRemoveGroup(intervalGroup)},children:jsx133(IconCircleMinus,{})},`remove-group-button-${intervalGroup.id}`)}),jsx133(ReferenceRangeGroupFilters,{intervalGroup,onChange:props.onChange}),jsx133(Divider4,{}),intervalGroup.intervals.map(interval=>jsxs81(Stack27,{gap:"xs",children:[jsxs81(Group54,{children:[jsx133(TextInput26,{"data-testid":`condition-${interval.id}`,defaultValue:interval.condition,label:"Condition: ",size:"sm",onChange:e=>{killEvent(e),props.onChange(intervalGroup.id,{...interval,condition:e.currentTarget.value.trim()})}},`condition-${interval.id}`),jsx133(ActionIcon15,{title:"Remove Interval",variant:"subtle",size:"sm","data-testid":`remove-interval-${interval.id}`,onClick:e=>{killEvent(e),props.onRemove(intervalGroup.id,interval)},children:jsx133(IconCircleMinus,{})},`remove-interval-${interval.id}`)]}),jsx133(RangeInput,{path:"",onChange:range=>{props.onChange(intervalGroup.id,{...interval,range})},name:`range-${interval.id}`,defaultValue:interval.range},`range-${interval.id}`)]},`interval-${interval.id}`)),jsx133(ActionIcon15,{title:"Add Interval",variant:"subtle",size:"sm",onClick:e=>{killEvent(e),props.onAdd(intervalGroup.id,{range:{low:{unit},high:{unit}}})},children:jsx133(IconCirclePlus,{})})]})})}function ReferenceRangeGroupFilters(props){let{intervalGroup,onChange}=props;intervalGroup.filters.age||(intervalGroup.filters.age={});for(let key of["low","high"])intervalGroup.filters.age[key]?.unit||(intervalGroup.filters.age[key]={...intervalGroup.filters.age[key],unit:"years",system:"http://unitsofmeasure.org"});return jsxs81(Stack27,{style:{maxWidth:"50%"},children:[jsx133(Group54,{children:jsx133(NativeSelect13,{data:["","male","female"],label:"Gender:",defaultValue:intervalGroup.filters.gender||"",onChange:e=>{for(let interval of intervalGroup.intervals){let newGender=e.currentTarget.value;newGender===""&&(newGender=void 0),onChange(intervalGroup.id,{...interval,gender:newGender})}}})}),jsxs81(Group54,{gap:"xs",children:[jsx133(Text26,{component:"label",htmlFor:`div-age-${intervalGroup.id}`,children:"Age:"}),jsx133("div",{id:`div-age-${intervalGroup.id}`,children:jsx133(RangeInput,{path:"",name:`age-${intervalGroup.id}`,defaultValue:intervalGroup.filters.age,onChange:ageRange=>{for(let interval of intervalGroup.intervals)onChange(intervalGroup.id,{...interval,age:ageRange})}},`age-${intervalGroup.id}`)})]}),jsx133(NativeSelect13,{data:["","pre-puberty","follicular","midcycle","luteal","postmenopausal"],label:"Endocrine:",defaultValue:intervalGroup.filters.context?.text||"",onChange:e=>{for(let interval of intervalGroup.intervals){let newEndocrine=e.currentTarget.value;newEndocrine===""?(newEndocrine=void 0,onChange(intervalGroup.id,{...interval,context:void 0})):onChange(intervalGroup.id,{...interval,context:{text:newEndocrine,coding:[{code:newEndocrine,system:"http://terminology.hl7.org/CodeSystem/referencerange-meaning"}]}})}}}),jsx133(NativeSelect13,{data:["","reference","critical","absolute"],label:"Category: ",defaultValue:intervalGroup.filters.category,onChange:e=>{for(let interval of intervalGroup.intervals){let newCategory=e.currentTarget.value;newCategory===""?onChange(intervalGroup.id,{...interval,category:void 0}):onChange(intervalGroup.id,{...interval,category:newCategory})}}})]})}function ensureQualifiedIntervalKeys(definition,setIntervalId){let intervals=definition.qualifiedInterval||[],nextId4=Math.max(...intervals.map(interval=>{let existingNum=parseInt(interval.id?.substring(3)||"",10);return isNaN(existingNum)?Number.NEGATIVE_INFINITY:existingNum}))+1;return Number.isFinite(nextId4)||(nextId4=1),definition={...definition,qualifiedInterval:intervals.map(interval=>({...interval,id:interval.id||`id-${nextId4++}`}))},setIntervalId(nextId4),definition}function groupQualifiedIntervals(intervals,setGroupId){let groupId=1,groups={};for(let interval of intervals){let groupKey=generateGroupKey(interval);groupKey in groups||(groups[groupKey]={id:`group-id-${groupId++}`,filters:Object.fromEntries(intervalFilters.map(f=>[f,interval[f]])),intervals:[]}),groups[groupKey].intervals.push(interval)}return setGroupId(groupId),Object.values(groups)}function generateGroupKey(interval){return[`gender=${interval.gender}`,`age=${formatRange2(interval.age)}`,`gestationalAge=${formatRange2(interval.gestationalAge)}`,`context=${interval.context?.text}`,`appliesTo=${interval.appliesTo?.map(c=>c.text).join("+")}`,`category=${interval.category}`].join(":")}function getUnitString(unit){return unit&&(getCodeBySystem(unit,"http://unitsofmeasure.org")||unit.text)}function isEmptyInterval(interval){return interval.range?.low?.value===void 0&&interval.range?.high?.value===void 0}import{Button as Button30,Grid as Grid4,Text as Text27}from"@mantine/core";import{formatDateTime as formatDateTime6,getReferenceString as getReferenceString10}from"@medplum/core";import{useMedplum as useMedplum40,useResource as useResource13}from"@medplum/react-hooks";import{Fragment as Fragment46,useEffect as useEffect31,useState as useState75}from"react";import{jsx as jsx134,jsxs as jsxs82}from"react/jsx-runtime";function RequestGroupDisplay(props){let medplum=useMedplum40(),requestGroup=useResource13(props.value),[startedLoading,setStartedLoading]=useState75(!1),[responseBundle,setResponseBundle]=useState75();if(useEffect31(()=>{requestGroup&&!startedLoading&&(medplum.executeBatch(buildBatchRequest(requestGroup)).then(setResponseBundle).catch(console.log),setStartedLoading(!0))},[medplum,requestGroup,startedLoading]),!requestGroup||!responseBundle)return null;return jsx134(Grid4,{children:requestGroup.action?.map((action,index)=>{let task=action.resource&&findBundleEntry(action.resource),taskInput=task?.input?.[0]?.valueReference,taskOutput=task?.output?.[0]?.valueReference;return jsxs82(Fragment46,{children:[jsx134(Grid4.Col,{span:1,p:"md",children:task?.status==="completed"?jsx134(IconCheckbox,{}):jsx134(IconSquare,{color:"gray"})}),jsxs82(Grid4.Col,{span:9,p:"xs",children:[jsx134(Text27,{fw:500,children:action.title}),action.description&&jsx134("div",{children:action.description}),jsxs82("div",{children:["Last edited by\xA0",jsx134(ResourceName,{value:task?.meta?.author}),"\xA0on\xA0",formatDateTime6(task?.meta?.lastUpdated)]}),jsxs82("div",{children:["Status: ",jsx134(StatusBadge,{status:task?.status||"unknown"})]})]}),jsxs82(Grid4.Col,{span:2,p:"md",children:[taskInput&&!taskOutput&&jsx134(Button30,{onClick:()=>props.onStart(task,taskInput),children:"Start"}),taskInput&&taskOutput&&jsx134(Button30,{onClick:()=>props.onEdit(task,taskInput,taskOutput),children:"Edit"})]})]},`action-${index}`)})});function buildBatchRequest(request){let batchEntries=[];if(request.action)for(let action of request.action)action.resource?.reference&&batchEntries.push({request:{method:"GET",url:action.resource.reference}});return{resourceType:"Bundle",type:"batch",entry:batchEntries}}function findBundleEntry(reference){for(let entry of responseBundle?.entry??[])if(entry.resource&&reference.reference===getReferenceString10(entry.resource))return entry.resource}}import{useMedplum as useMedplum41}from"@medplum/react-hooks";import{useEffect as useEffect32,useState as useState76}from"react";import{stringify as stringify4}from"@medplum/core";function diff(original,revised){let path=buildPath(original,revised);return buildRevisions(path,original,revised)}function buildPath(orig,rev){let N=orig.length,M=rev.length,MAX=N+M+1,size=1+2*MAX,middle=size/2|0,diagonal=new Array(size);diagonal[middle+1]={i:0,j:-1,prev:void 0,snake:!0};for(let d=0;d<MAX;d++){for(let k=-d;k<=d;k+=2){let kmiddle=middle+k,kplus=kmiddle+1,kminus=kmiddle-1,kplusNode=diagonal[kplus],kminusNode=diagonal[kminus],prev,i=0;k===-d||k!==d&&kminusNode.i<kplusNode.i?(i=kplusNode.i,prev=kplusNode):(i=kminusNode.i+1,prev=kminusNode),diagonal[kminus]=void 0;let j=i-k,node={i,j,prev:previousSnake(prev),snake:!1};for(;i<N&&j<M&&orig[i]===rev[j];)i++,j++;if(i>node.i&&(node={i,j,prev:node,snake:!0}),diagonal[kmiddle]=node,i>=N&&j>=M)return diagonal[kmiddle]}diagonal[middle+d-1]=void 0}}function buildRevisions(startNode,orig,rev){let deltas=[],path=startNode;for(path.snake&&(path=path.prev);path?.prev&&path.prev.j>=0;){let i=path.i,j=path.j;path=path.prev;let ianchor=path.i,janchor=path.j,original={position:ianchor,lines:orig.slice(ianchor,i)},revised={position:janchor,lines:rev.slice(janchor,j)},type;original.lines.length===0&&revised.lines.length>0?type="insert":original.lines.length>0&&revised.lines.length===0?type="delete":type="change",deltas.push({original,revised,type}),path.snake&&(path=path.prev)}return deltas}function previousSnake(node){return node&&!node.snake&&node.prev?node.prev:node}function blame(history){let versions=(history.entry??[]).filter(entry=>!!entry.resource).map(entry=>({meta:entry.resource?.meta,lines:stringify4(entry.resource,!0).match(/[^\r\n]+/g)})).sort((a,b)=>a.meta.lastUpdated.localeCompare(b.meta.lastUpdated));if(!versions.length)return[];let table=versions[0].lines.map(line=>({id:versions[0].meta.versionId,meta:versions[0].meta,value:line,span:1}));return compareVersions(table,versions),combineSpans(table),table}function compareVersions(table,versions){for(let i=1;i<versions.length;i++){let revisions=diff(versions[i-1].lines,versions[i].lines);for(let revision of revisions){let position=revision.original.position,oldLines=revision.original.lines,newLines=revision.revised.lines;if((revision.type==="delete"||revision.type==="change")&&table.splice(position,oldLines.length),revision.type==="insert"||revision.type==="change")for(let k=0;k<revision.revised.lines.length;k++)table.splice(position+k,0,{id:versions[i].meta.versionId,meta:versions[i].meta,value:newLines[k],span:1})}}}function combineSpans(table){let start=0;for(;start<table.length;){let curr=start;for(;curr<table.length&&table[curr].id===table[start].id;)table[curr].span=-1,curr++;table[start].span=curr-start,start=curr}}var ResourceBlame_default={container:"ResourceBlame_container",root:"ResourceBlame_root",startRow:"ResourceBlame_startRow",normalRow:"ResourceBlame_normalRow",author:"ResourceBlame_author",dateTime:"ResourceBlame_dateTime",lineNumber:"ResourceBlame_lineNumber",line:"ResourceBlame_line",pre:"ResourceBlame_pre"};function getVersionUrl(resource,versionId){return`/${resource.resourceType}/${resource.id}/_history/${versionId}`}function getTimeString(lastUpdated){let seconds=Math.floor((Date.now()-Date.parse(lastUpdated))/1e3),years=Math.floor(seconds/31536e3);if(years>0)return pluralizeTime(years,"year");let months=Math.floor(seconds/2592e3);if(months>0)return pluralizeTime(months,"month");let days=Math.floor(seconds/86400);if(days>0)return pluralizeTime(days,"day");let hours=Math.floor(seconds/3600);if(hours>0)return pluralizeTime(hours,"hour");let minutes=Math.floor(seconds/60);return minutes>0?pluralizeTime(minutes,"minute"):pluralizeTime(seconds,"second")}function pluralizeTime(count,noun){return`${count} ${count===1?noun:noun+"s"} ago`}import{Fragment as Fragment47,jsx as jsx135,jsxs as jsxs83}from"react/jsx-runtime";function ResourceBlame(props){let medplum=useMedplum41(),[value,setValue]=useState76(props.history);if(useEffect32(()=>{!props.history&&props.resourceType&&props.id&&medplum.readHistory(props.resourceType,props.id).then(setValue).catch(console.log)},[medplum,props.history,props.resourceType,props.id]),!value)return jsx135("div",{children:"Loading..."});let resource=value.entry?.[0]?.resource;if(!resource)return null;let table=blame(value);return jsx135("div",{className:ResourceBlame_default.container,children:jsx135("table",{className:ResourceBlame_default.root,children:jsx135("tbody",{children:table.map((row,index)=>jsxs83("tr",{className:row.span>0?ResourceBlame_default.startRow:ResourceBlame_default.normalRow,children:[row.span>0&&jsxs83(Fragment47,{children:[jsx135("td",{className:ResourceBlame_default.author,rowSpan:row.span,children:jsx135(ResourceBadge,{value:row.meta.author,link:!0})}),jsx135("td",{className:ResourceBlame_default.dateTime,rowSpan:row.span,children:jsx135(MedplumLink,{to:getVersionUrl(resource,row.meta.versionId),children:getTimeString(row.meta.lastUpdated)})})]}),jsx135("td",{className:ResourceBlame_default.lineNumber,children:index+1}),jsx135("td",{className:ResourceBlame_default.line,children:jsx135("pre",{className:ResourceBlame_default.pre,children:row.value})})]},"row-"+index))})})})}import{stringify as stringify5}from"@medplum/core";var ResourceDiff_default={removed:"ResourceDiff_removed",added:"ResourceDiff_added"};import{Fragment as Fragment48,jsx as jsx136,jsxs as jsxs84}from"react/jsx-runtime";function ResourceDiff(props){let originalResource=props.original,revisedResource=props.revised;props.ignoreMeta&&(originalResource={...originalResource,meta:void 0},revisedResource={...revisedResource,meta:void 0});let original=stringify5(originalResource,!0).match(/[^\r\n]+/g),revised=stringify5(revisedResource,!0).match(/[^\r\n]+/g),deltas=diff(original,revised);return jsx136("pre",{style:{color:"gray"},children:deltas.map((delta,index)=>jsx136(ChangeDiff,{delta},"delta"+index))})}function ChangeDiff(props){return jsxs84(Fragment48,{children:["...",jsx136("br",{}),props.delta.original.lines.length>0&&jsx136("div",{className:ResourceDiff_default.removed,children:props.delta.original.lines.join(`
|
|
71
|
+
}`.replace(/\s+/g," ");return(await medplum.graphql(query)).data.StructureDefinitionList[0]}function shouldFetchResourceType(targetType){return targetType.type==="profile"&&!targetType?.error&&isEmpty4(targetType.resourceType)}import{Group as Group26,Stack as Stack10,Text as Text11}from"@mantine/core";import{getPathDisplayName as getPathDisplayName4}from"@medplum/core";import{useMedplum as useMedplum19}from"@medplum/react-hooks";import{useContext as useContext18,useEffect as useEffect12,useState as useState37}from"react";import{Group as Group25,Stack as Stack9,Text as Text10}from"@mantine/core";import{buildElementsContext as buildElementsContext3,getPropertyDisplayName,isEmpty as isEmpty5,isPopulated as isPopulated10}from"@medplum/core";import{useContext as useContext17,useMemo as useMemo18,useState as useState36}from"react";var ResourceArrayInput_default={indented:"ResourceArrayInput_indented"};import{ActionIcon as ActionIcon3,Button as Button9}from"@mantine/core";import{jsx as jsx74}from"react/jsx-runtime";function ArrayAddButton({propertyDisplayName,onClick,testId}){let text=propertyDisplayName?`Add ${propertyDisplayName}`:"Add";return propertyDisplayName?jsx74(Button9,{title:text,size:"sm",color:"green.6",variant:"subtle","data-testid":testId,leftSection:jsx74(IconCirclePlus,{size:"1.25rem"}),onClick,children:text}):jsx74(ActionIcon3,{title:text,color:"green.6","data-testid":testId,onClick,children:jsx74(IconCirclePlus,{size:"1.25rem"})})}import{ActionIcon as ActionIcon4}from"@mantine/core";import{jsx as jsx75}from"react/jsx-runtime";function ArrayRemoveButton({propertyDisplayName,onClick,testId}){return jsx75(ActionIcon4,{title:propertyDisplayName?`Remove ${propertyDisplayName}`:"Remove",color:"red.5","data-testid":testId,variant:"subtle",onClick,children:jsx75(IconCircleMinus,{size:"1.25rem"})})}import{jsx as jsx76,jsxs as jsxs40}from"react/jsx-runtime";function SliceInput(props){let{slice,property}=props,[values,setValues]=useState36(props.defaultValue),sliceElements=slice.typeSchema?.elements??slice.elements,parentElementsContextValue=useContext17(ElementsContext),contextValue=useMemo18(()=>{if(isPopulated10(sliceElements))return buildElementsContext3({parentContext:parentElementsContextValue,elements:sliceElements,path:props.path,profileUrl:slice.typeSchema?.url})},[parentElementsContextValue,props.path,slice.typeSchema?.url,sliceElements]);function setValuesWrapper(newValues){setValues(newValues),props.onChange&&props.onChange(newValues)}let required=slice.min>0,indentedStack=isEmpty5(slice.elements),propertyDisplayName=getPropertyDisplayName(slice.name),showEmptyMessage=props.property.readonly&&values.length===0;return maybeWrapWithContext(ElementsContext.Provider,contextValue,jsx76(FormSection,{title:propertyDisplayName,description:slice.definition,withAsterisk:required,fhirPath:`${property.path}:${slice.name}`,testId:props.testId,readonly:props.property.readonly,children:showEmptyMessage?jsx76(Text10,{c:"dimmed",children:"(empty)"}):jsxs40(Stack9,{className:indentedStack?ResourceArrayInput_default.indented:void 0,children:[values.map((value,valueIndex)=>jsxs40(Group25,{wrap:"nowrap",children:[jsx76("div",{style:{flexGrow:1},"data-testid":props.testId&&`${props.testId}-elements-${valueIndex}`,children:jsx76(ElementDefinitionTypeInput,{elementDefinitionType:slice.type[0],name:slice.name,defaultValue:value,onChange:newValue=>{let newValues=[...values];newValues[valueIndex]=newValue,setValuesWrapper(newValues)},outcome:props.outcome,min:slice.min,max:slice.max,binding:slice.binding,path:props.path,valuePath:void 0,readOnly:props.property.readonly})}),!props.property.readonly&&values.length>slice.min&&jsx76(ArrayRemoveButton,{propertyDisplayName,testId:props.testId&&`${props.testId}-remove-${valueIndex}`,onClick:e=>{killEvent(e);let newValues=[...values];newValues.splice(valueIndex,1),setValuesWrapper(newValues)}})]},`${valueIndex}-${values.length}`)),!props.property.readonly&&values.length<slice.max&&jsx76(Group25,{wrap:"nowrap",style:{justifyContent:"flex-start"},children:jsx76(ArrayAddButton,{propertyDisplayName,onClick:e=>{killEvent(e);let newValues=[...values,void 0];setValuesWrapper(newValues)},testId:props.testId&&`${props.testId}-add`})})]})}))}function getValuePath(elementPath,valuePath,arrayIndex){return valuePath===void 0?elementPath:arrayIndex===void 0?valuePath:`${valuePath}[${arrayIndex}]`}import{jsx as jsx77,jsxs as jsxs41}from"react/jsx-runtime";function ResourceArrayInput(props){let{property}=props,medplum=useMedplum19(),[loading,setLoading]=useState37(!0),[slices,setSlices]=useState37([]),[defaultValue2]=useState37(()=>Array.isArray(props.defaultValue)?props.defaultValue:[]),[slicedValues,setSlicedValues]=useState37(()=>[defaultValue2]),ctx=useContext18(ElementsContext),propertyTypeCode=property.type[0]?.code;useEffect12(()=>{prepareSlices({medplum,property}).then(slices2=>{setSlices(slices2);let slicedValues2=assignValuesIntoSlices(defaultValue2,slices2,property.slicing,ctx.profileUrl);addPlaceholderValues(slicedValues2,slices2),setSlicedValues(slicedValues2),setLoading(!1)}).catch(reason=>{console.error(reason),setLoading(!1)})},[medplum,property,defaultValue2,ctx.profileUrl,setSlicedValues]);function setValuesWrapper(newValues,sliceIndex){let newSlicedValues=[...slicedValues];if(newSlicedValues[sliceIndex]=newValues,setSlicedValues(newSlicedValues),props.onChange){let cleaned=newSlicedValues.flat().filter(val=>val!==void 0);props.onChange(cleaned)}}if(loading)return jsx77("div",{children:"Loading..."});let nonSliceIndex=slices.length,nonSliceValues=slicedValues[nonSliceIndex],showNonSliceValues=!(props.hideNonSliceValues??(propertyTypeCode==="Extension"&&slices.length>0)),propertyDisplayName=getPathDisplayName4(property.path),showEmptyMessage=props.property.readonly&&slices.length===0&&defaultValue2.length===0;return jsxs41(Stack10,{className:props.indent?ResourceArrayInput_default.indented:void 0,children:[showEmptyMessage&&jsx77(Text11,{c:"dimmed",children:"(empty)"}),slices.map((slice,sliceIndex)=>jsx77(SliceInput,{slice,path:props.path,valuePath:props.valuePath,property,defaultValue:slicedValues[sliceIndex],onChange:newValue=>{setValuesWrapper(newValue,sliceIndex)},testId:`slice-${slice.name}`},slice.name)),showNonSliceValues&&nonSliceValues.map((value,valueIndex)=>jsxs41(Group26,{wrap:"nowrap",style:{flexGrow:1},children:[jsx77("div",{style:{flexGrow:1},children:jsx77(ResourcePropertyInput,{arrayElement:!0,property:props.property,name:props.name+"."+valueIndex,path:props.path,valuePath:getValuePath(props.path,props.valuePath,valueIndex),defaultValue:value,onChange:newValue=>{let newNonSliceValues=[...nonSliceValues];newNonSliceValues[valueIndex]=newValue,setValuesWrapper(newNonSliceValues,nonSliceIndex)},defaultPropertyType:void 0,outcome:props.outcome})}),!props.property.readonly&&jsx77(ArrayRemoveButton,{propertyDisplayName,testId:`nonsliced-remove-${valueIndex}`,onClick:e=>{killEvent(e);let newNonSliceValues=[...nonSliceValues];newNonSliceValues.splice(valueIndex,1),setValuesWrapper(newNonSliceValues,nonSliceIndex)}})]},`${valueIndex}-${nonSliceValues.length}`)),!props.property.readonly&&showNonSliceValues&&slicedValues.flat().length<property.max&&jsx77(Group26,{wrap:"nowrap",style:{justifyContent:"flex-start"},children:jsx77(ArrayAddButton,{propertyDisplayName,onClick:e=>{killEvent(e);let newNonSliceValues=[...nonSliceValues];newNonSliceValues.push(void 0),setValuesWrapper(newNonSliceValues,nonSliceIndex)},testId:"nonsliced-add"})})]})}function addPlaceholderValues(slicedValues,slices){for(let sliceIndex=0;sliceIndex<slices.length;sliceIndex++){let slice=slices[sliceIndex],sliceValues=slicedValues[sliceIndex];for(;sliceValues.length<slice.min;)sliceValues.push(void 0)}}import{ActionIcon as ActionIcon5,Flex as Flex2,Textarea}from"@mantine/core";import{useClipboard}from"@mantine/hooks";import{showNotification as showNotification5}from"@mantine/notifications";import{useRef as useRef11,useState as useState38}from"react";import{jsx as jsx78,jsxs as jsxs42}from"react/jsx-runtime";function SensitiveTextarea(props){let[revealed,setRevealed]=useState38(!1),clipboard=useClipboard(),ref=useRef11(null),styles={...props.styles};return revealed||(styles.input||(styles.input={}),styles.input.WebkitTextSecurity="disc"),jsxs42(Flex2,{gap:"xs",children:[jsx78(Textarea,{...props,styles:{...styles,root:{...styles.root??{},flexGrow:1}},ref,autosize:!0,minRows:1,onFocus:()=>setRevealed(!0),onBlur:()=>setRevealed(!1)}),jsx78(ActionIcon5,{title:"Copy secret",onClick:()=>{clipboard.copy(ref.current?.value),showNotification5({color:"green",message:"Copied"})},children:jsx78(IconCopy,{})})]})}import{Button as Button10,Chip,Group as Group27,Modal as Modal2,NativeSelect as NativeSelect8,Stack as Stack11,Switch,TextInput as TextInput16}from"@mantine/core";import{formatTiming as formatTiming2}from"@medplum/core";import{useContext as useContext19,useMemo as useMemo19,useRef as useRef12,useState as useState39}from"react";import{Fragment as Fragment25,jsx as jsx79,jsxs as jsxs43}from"react/jsx-runtime";var daysOfWeek=["sun","mon","tue","wed","thu","fri","sat"];function TimingInput(props){let[value,setValue]=useState39(props.defaultValue),[open,setOpen]=useState39(!props.disabled&&(props.defaultModalOpen??!1)),valueRef=useRef12();return valueRef.current=value,jsxs43(Fragment25,{children:[jsxs43(Group27,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx79("span",{children:formatTiming2(valueRef.current)||"No repeat"}),jsx79(Button10,{disabled:props.disabled,onClick:()=>setOpen(!0),children:"Edit"})]}),!props.disabled&&jsx79(TimingEditorDialog,{path:props.path,visible:open,defaultValue:valueRef.current,onOk:newValue=>{props.onChange&&props.onChange(newValue),setValue(newValue),setOpen(!1)},onCancel:()=>setOpen(!1)})]})}var defaultValue={repeat:{period:1,periodUnit:"d"}};function TimingEditorDialog(props){let[value,setValue]=useState39(props.defaultValue||defaultValue),{getExtendedProps}=useContext19(ElementsContext),[eventProps,repeatProps,repeatPeriodProps,repeatPeriodUnitProps,repeatDayOfWeekProps]=useMemo19(()=>["event","repeat","repeat.period","repeat.periodUnit","repeat.dayOfWeek"].map(field=>getExtendedProps(props.path+"."+field)),[getExtendedProps,props.path]),valueRef=useRef12();valueRef.current=value;function setStart(newStart){setValue({...valueRef.current,event:[newStart]})}function setRepeat(repeat){setValue({...valueRef.current,repeat})}function setPeriod(newPeriod){setRepeat({...valueRef.current?.repeat,period:newPeriod})}function setPeriodUnit(newPeriodUnit){setRepeat({...valueRef.current?.repeat,periodUnit:newPeriodUnit})}function setDaysOfWeek(newDaysOfWeek){setRepeat({...valueRef.current?.repeat,dayOfWeek:newDaysOfWeek})}return jsx79(Modal2,{title:"Timing",closeButtonProps:{"aria-label":"Close"},opened:props.visible,onClose:()=>props.onCancel(),children:jsxs43(Stack11,{children:[jsx79(FormSection,{title:"Starts on",htmlFor:"timing-dialog-start",children:jsx79(DateTimeInput,{disabled:eventProps?.readonly,name:"timing-dialog-start",onChange:newValue=>setStart(newValue)})}),jsx79(Switch,{disabled:repeatProps?.readonly,label:"Repeat",checked:!!value.repeat,onChange:e=>setRepeat(e.currentTarget.checked?defaultValue.repeat:void 0)}),value.repeat&&jsxs43(Fragment25,{children:[jsx79(FormSection,{title:"Repeat every",htmlFor:"timing-dialog-period",children:jsxs43(Group27,{gap:"xs",grow:!0,wrap:"nowrap",children:[jsx79(TextInput16,{disabled:repeatPeriodProps?.readonly,type:"number",step:1,id:"timing-dialog-period",name:"timing-dialog-period",defaultValue:value.repeat.period||1,onChange:e=>setPeriod(parseInt(e.currentTarget.value,10)||1)}),jsx79(NativeSelect8,{disabled:repeatPeriodUnitProps?.readonly,id:"timing-dialog-periodUnit",name:"timing-dialog-periodUnit",defaultValue:value.repeat.periodUnit,onChange:e=>setPeriodUnit(e.currentTarget.value),data:[{label:"second",value:"s"},{label:"minute",value:"min"},{label:"hour",value:"h"},{label:"day",value:"d"},{label:"week",value:"wk"},{label:"month",value:"mo"},{label:"year",value:"a"}]})]})}),value.repeat.periodUnit==="wk"&&jsx79(FormSection,{title:"Repeat on",children:jsx79(Chip.Group,{multiple:!0,onChange:setDaysOfWeek,children:jsx79(Group27,{justify:"space-between",mt:"md",gap:"xs",children:daysOfWeek.map(day=>jsx79(Chip,{value:day,size:"xs",radius:"xl",disabled:repeatDayOfWeekProps?.readonly,children:day.charAt(0).toUpperCase()},day))})})})]}),jsx79(Group27,{justify:"flex-end",children:jsx79(Button10,{onClick:()=>props.onOk(value),children:"OK"})})]})})}import{jsx as jsx80,jsxs as jsxs44}from"react/jsx-runtime";function ResourcePropertyInput(props){let{property,name,onChange,defaultValue:defaultValue2}=props,defaultPropertyType=props.defaultPropertyType&&props.defaultPropertyType!=="undefined"?props.defaultPropertyType:property.type[0].code,propertyTypes=property.type;if((property.isArray||property.max>1)&&!props.arrayElement){if(defaultPropertyType===PropertyType2.Attachment)return jsx80(AttachmentArrayInput,{name,defaultValue:defaultValue2,onChange,disabled:property.readonly});let indent=propertyTypes[0]?.code!==PropertyType2.Extension;return jsx80(ResourceArrayInput,{property,name,path:props.path,valuePath:props.valuePath,defaultValue:defaultValue2,indent,onChange,outcome:props.outcome})}else return propertyTypes.length>1?jsx80(ElementDefinitionInputSelector,{elementDefinitionTypes:propertyTypes,...props}):jsx80(ElementDefinitionTypeInput,{name,defaultValue:defaultValue2,onChange:newValue=>{if(props.onChange){let newPropName=props.name.replace("[x]",capitalize2(propertyTypes[0].code));props.onChange(newValue,newPropName)}},outcome:props.outcome,elementDefinitionType:propertyTypes[0],min:property.min,max:property.min,binding:property.binding,path:props.path,valuePath:props.valuePath,readOnly:property.readonly})}function ElementDefinitionInputSelector(props){let propertyTypes=props.elementDefinitionTypes,initialPropertyType;props.defaultPropertyType&&(initialPropertyType=propertyTypes.find(t=>t.code===props.defaultPropertyType)),initialPropertyType||(initialPropertyType=propertyTypes[0]);let[selectedType,setSelectedType]=useState40(initialPropertyType);return jsxs44(Group28,{gap:"xs",grow:!0,wrap:"nowrap",align:"flex-start",children:[jsx80(NativeSelect9,{disabled:props.property.readonly,style:{width:"200px"},defaultValue:selectedType.code,"data-testid":props.name&&props.name+"-selector",onChange:e=>{setSelectedType(propertyTypes.find(type=>type.code===e.currentTarget.value))},data:propertyTypes.map(type=>({value:type.code,label:type.code}))}),jsx80(ElementDefinitionTypeInput,{name:props.name,defaultValue:props.defaultValue,outcome:props.outcome,elementDefinitionType:selectedType,onChange:newValue=>{props.onChange&&props.onChange(newValue,props.name.replace("[x]",capitalize2(selectedType.code)))},min:props.property.min,max:props.property.max,binding:props.property.binding,path:props.property.path,valuePath:props.valuePath,readOnly:props.property.readonly})]})}function ElementDefinitionTypeInput(props){let{name,onChange,outcome,binding,path,valuePath,readOnly}=props,required=props.min!==void 0&&props.min>0,propertyType=props.elementDefinitionType.code,elementsContext=useContext20(ElementsContext),defaultValue2=useMemo20(()=>{if(!isComplexTypeCode(propertyType)||!isEmpty6(props.defaultValue))return props.defaultValue;let withDefaults=Object.create(null);if(elementsContext.path===props.path)applyDefaultValuesToElement(withDefaults,elementsContext.elements);else{let key=getPathDifference(elementsContext.path,props.path);if(key===void 0)return props.defaultValue;applyDefaultValuesToElement(withDefaults,elementsContext.elements,key)}return isPopulated11(withDefaults)?withDefaults:props.defaultValue},[propertyType,elementsContext.path,elementsContext.elements,props.path,props.defaultValue]);if(!propertyType)return jsx80("div",{children:"Property type not specified "});function getComplexInputProps(){return{name,defaultValue:defaultValue2,onChange,outcome,path,valuePath,disabled:readOnly}}function getPrimitiveInputProps(){let error=getErrorsForInput(props.outcome,valuePath??path);return{id:name,name,"data-testid":name,defaultValue:defaultValue2,required,error,disabled:readOnly}}switch(propertyType){case PropertyType2.SystemString:case PropertyType2.canonical:case PropertyType2.string:case PropertyType2.time:case PropertyType2.uri:case PropertyType2.url:return props.path==="Project.secret.value[x]"?jsx80(SensitiveTextarea,{...getPrimitiveInputProps(),onChange:e=>{props.onChange&&props.onChange(e.currentTarget.value)}}):jsx80(TextInput17,{...getPrimitiveInputProps(),onChange:e=>{onChange&&onChange(e.currentTarget.value)}});case PropertyType2.date:return jsx80(TextInput17,{...getPrimitiveInputProps(),type:"date",onChange:e=>{onChange&&onChange(e.currentTarget.value)}});case PropertyType2.dateTime:case PropertyType2.instant:return jsx80(DateTimeInput,{...getPrimitiveInputProps(),onChange,outcome});case PropertyType2.decimal:case PropertyType2.integer:case PropertyType2.positiveInt:case PropertyType2.unsignedInt:return jsx80(TextInput17,{...getPrimitiveInputProps(),type:"number",step:propertyType===PropertyType2.decimal?"any":"1",onChange:e=>{if(onChange){let num=e.currentTarget.valueAsNumber;onChange(Number.isNaN(num)?void 0:num)}}});case PropertyType2.code:return jsx80(CodeInput,{...getPrimitiveInputProps(),error:void 0,onChange,binding:binding?.valueSet,creatable:!0,maxValues:1});case PropertyType2.boolean:return jsx80(Checkbox4,{...getPrimitiveInputProps(),defaultChecked:!!defaultValue2,onChange:e=>{onChange&&onChange(e.currentTarget.checked)}});case PropertyType2.base64Binary:case PropertyType2.markdown:return jsx80(Textarea2,{...getPrimitiveInputProps(),spellCheck:propertyType!==PropertyType2.base64Binary,onChange:e=>{onChange&&onChange(e.currentTarget.value)}});case PropertyType2.Address:return jsx80(AddressInput,{...getComplexInputProps()});case PropertyType2.Annotation:return jsx80(AnnotationInput,{...getComplexInputProps()});case PropertyType2.Attachment:return jsx80(AttachmentInput,{...getComplexInputProps()});case PropertyType2.CodeableConcept:return jsx80(CodeableConceptInput,{binding:binding?.valueSet,...getComplexInputProps()});case PropertyType2.Coding:return jsx80(CodingInput,{binding:binding?.valueSet,...getComplexInputProps()});case PropertyType2.ContactDetail:return jsx80(ContactDetailInput,{...getComplexInputProps()});case PropertyType2.ContactPoint:return jsx80(ContactPointInput,{...getComplexInputProps()});case PropertyType2.Extension:return jsx80(ExtensionInput,{...getComplexInputProps(),propertyType:props.elementDefinitionType});case PropertyType2.HumanName:return jsx80(HumanNameInput,{...getComplexInputProps()});case PropertyType2.Identifier:return jsx80(IdentifierInput,{...getComplexInputProps()});case PropertyType2.Money:return jsx80(MoneyInput,{...getComplexInputProps()});case PropertyType2.Period:return jsx80(PeriodInput,{...getComplexInputProps()});case PropertyType2.Duration:case PropertyType2.Quantity:return jsx80(QuantityInput,{...getComplexInputProps()});case PropertyType2.Range:return jsx80(RangeInput,{...getComplexInputProps()});case PropertyType2.Ratio:return jsx80(RatioInput,{...getComplexInputProps()});case PropertyType2.Reference:return jsx80(ReferenceInput,{...getComplexInputProps(),targetTypes:getTargetTypes(props.elementDefinitionType)});case PropertyType2.Timing:return jsx80(TimingInput,{...getComplexInputProps()});case PropertyType2.Dosage:case PropertyType2.UsageContext:default:return jsx80(BackboneElementInput,{...getComplexInputProps(),typeName:propertyType})}}var RESOURCE_TYPE_URL_PREFIXES=[`${HTTP_HL7_ORG}/fhir/StructureDefinition/`,"https://medplum.com/fhir/StructureDefinition/"];function getTargetTypes(elementDefinitionType){return elementDefinitionType?.targetProfile?.map(p=>{let resourceTypePrefix=RESOURCE_TYPE_URL_PREFIXES.find(prefix=>p.startsWith(prefix));return resourceTypePrefix?p.slice(resourceTypePrefix.length):p})}import{jsx as jsx81}from"react/jsx-runtime";function ElementsInput(props){let[value,setValue]=useState41(props.defaultValue??{}),elementsContext=useContext21(ElementsContext),elementsToRender=useMemo21(()=>getElementsToRender(elementsContext.elements),[elementsContext.elements]);function setValueWrapper(newValue){setValue(newValue),props.onChange&&props.onChange(newValue)}let typedValue={type:props.type,value};return jsx81(Stack12,{style:{flexGrow:1},"data-testid":props.testId,children:elementsToRender.map(([key,element])=>{let[propertyValue,propertyType]=getValueAndTypeFromElement(typedValue,key,element),required=element.min!==void 0&&element.min>0,valuePath=props.valuePath?props.valuePath+"."+key:void 0,resourcePropertyInput=jsx81(ResourcePropertyInput,{property:element,name:key,path:props.path+"."+key,valuePath,defaultValue:propertyValue,defaultPropertyType:propertyType,onChange:(newValue,propName)=>{setValueWrapper(setPropertyValue({...value},key,propName??key,element,newValue))},outcome:props.outcome},key);return props.type==="Extension"||EXTENSION_KEYS.includes(key)?resourcePropertyInput:element.type.length===1&&element.type[0].code==="boolean"?jsx81(CheckboxFormSection,{title:getPathDisplayName5(key),description:element.description,htmlFor:key,fhirPath:element.path,withAsterisk:required,readonly:element.readonly,children:resourcePropertyInput},key):jsx81(FormSection,{title:getPathDisplayName5(key),description:element.description,withAsterisk:required,htmlFor:key,outcome:props.outcome,fhirPath:element.path,errorExpression:valuePath,readonly:element.readonly,children:resourcePropertyInput},key)})})}import{jsx as jsx82,jsxs as jsxs45}from"react/jsx-runtime";function BackboneElementInput(props){let[defaultValue2]=useState42(()=>props.defaultValue??{}),parentElementsContext=useContext22(ElementsContext),profileUrl=props.profileUrl??parentElementsContext?.profileUrl,typeSchema=useMemo22(()=>tryGetDataType2(props.typeName,profileUrl),[props.typeName,profileUrl]),type=typeSchema?.type??props.typeName,contextValue=useMemo22(()=>{if(typeSchema)return buildElementsContext4({parentContext:parentElementsContext,elements:typeSchema.elements,path:props.path,profileUrl:typeSchema.url,accessPolicyResource:props.accessPolicyResource})},[typeSchema,parentElementsContext,props.path,props.accessPolicyResource]);return typeSchema?maybeWrapWithContext(ElementsContext.Provider,contextValue,jsx82(ElementsInput,{path:props.path,valuePath:props.valuePath,type,defaultValue:defaultValue2,onChange:props.onChange,outcome:props.outcome})):jsxs45("div",{children:[type,"\xA0not implemented"]})}import{Button as Button11,Group as Group29}from"@mantine/core";import{useMemo as useMemo23,useState as useState43}from"react";var CalendarInput_default={table:"CalendarInput_table"};function getMonthString(date){return date.toLocaleString("default",{month:"long"})+" "+date.getFullYear()}function getStartMonth(){let result=new Date;return result.setDate(1),result.setHours(0,0,0,0),result}import{jsx as jsx83,jsxs as jsxs46}from"react/jsx-runtime";function CalendarInput(props){let{onChangeMonth,onClick}=props,[month,setMonth]=useState43(getStartMonth);function moveMonth(delta){setMonth(currMonth=>{let newMonth=new Date(currMonth.getTime());return newMonth.setMonth(currMonth.getMonth()+delta),onChangeMonth(newMonth),newMonth})}let grid=useMemo23(()=>buildGrid(month,props.slots),[month,props.slots]);return jsxs46("div",{children:[jsxs46(Group29,{justify:"space-between",gap:"xs",grow:!0,wrap:"nowrap",children:[jsx83("p",{style:{flex:1},children:getMonthString(month)}),jsxs46(Group29,{justify:"flex-end",gap:"xs",children:[jsx83(Button11,{variant:"outline","aria-label":"Previous month",onClick:()=>moveMonth(-1),children:"<"}),jsx83(Button11,{variant:"outline","aria-label":"Next month",onClick:()=>moveMonth(1),children:">"})]})]}),jsxs46("table",{className:CalendarInput_default.table,children:[jsx83("thead",{children:jsxs46("tr",{children:[jsx83("th",{children:"SUN"}),jsx83("th",{children:"MON"}),jsx83("th",{children:"TUE"}),jsx83("th",{children:"WED"}),jsx83("th",{children:"THU"}),jsx83("th",{children:"FRI"}),jsx83("th",{children:"SAT"})]})}),jsx83("tbody",{children:grid.map((week,weekIndex)=>jsx83("tr",{children:week.map((day,dayIndex)=>jsx83("td",{children:day&&jsx83(Button11,{variant:"light",disabled:!day.available,onClick:()=>onClick(day.date),children:day.date.getDate()})},"day-"+dayIndex))},"week-"+weekIndex))})]})]})}function buildGrid(startDate,slots){let d=new Date(startDate.getFullYear(),startDate.getMonth()),grid=[],row=[];for(let i=0;i<d.getDay();i++)row.push(void 0);for(;d.getMonth()===startDate.getMonth();)row.push({date:new Date(d.getTime()),available:isDayAvailable(d,slots)}),d.getDay()===6&&(grid.push(row),row=[]),d.setDate(d.getDate()+1);if(d.getDay()!==0){for(let i=d.getDay();i<7;i++)row.push(void 0);grid.push(row)}return grid}function isDayAvailable(day,slots){for(let slot of slots){let slotStart=new Date(slot.start);if(slotStart.getFullYear()===day.getFullYear()&&slotStart.getMonth()===day.getMonth()&&slotStart.getDate()===day.getDate())return!0}return!1}import{ActionIcon as ActionIcon6,Group as Group30,LoadingOverlay,Paper as Paper2,ScrollArea as ScrollArea2,Skeleton,Stack as Stack13,TextInput as TextInput18,Title as Title5}from"@mantine/core";import{useResizeObserver}from"@mantine/hooks";import{showNotification as showNotification6}from"@mantine/notifications";import{getDisplayString as getDisplayString4,getReferenceString as getReferenceString4,normalizeErrorString as normalizeErrorString6}from"@medplum/core";import{useMedplum as useMedplum20,useResource as useResource3,useSubscription}from"@medplum/react-hooks";import{useCallback as useCallback10,useEffect as useEffect13,useMemo as useMemo24,useRef as useRef13,useState as useState44}from"react";var BaseChat_default={chatPaper:"BaseChat_chatPaper",chatTitle:"BaseChat_chatTitle",chatBody:"BaseChat_chatBody",chatScrollArea:"BaseChat_chatScrollArea",chatInputContainer:"BaseChat_chatInputContainer",chatBubbleOuterWrap:"BaseChat_chatBubbleOuterWrap",chatBubbleRightAlignedInnerWrap:"BaseChat_chatBubbleRightAlignedInnerWrap",chatBubbleLeftAlignedInnerWrap:"BaseChat_chatBubbleLeftAlignedInnerWrap",chatBubble:"BaseChat_chatBubble",chatBubbleName:"BaseChat_chatBubbleName",chatBubbleNameRight:"BaseChat_chatBubbleNameRight"};import{jsx as jsx84,jsxs as jsxs47}from"react/jsx-runtime";function showError(message){showNotification6({color:"red",title:"Error",message,autoClose:!1})}function parseSentTime(communication){let sentTime=new Date(communication.sent??0),sentTimeMins=sentTime.getMinutes().toString();return`${sentTime.getHours()}:${sentTimeMins.length===1?"0":""}${sentTimeMins}`}function upsertCommunications(communications,received,setCommunications){let newCommunications=[...communications],foundNew=!1;for(let comm of received){let existingIdx=newCommunications.findIndex(c=>c.id===comm.id);existingIdx!==-1?newCommunications[existingIdx]=comm:(newCommunications.push(comm),foundNew=!0)}foundNew&&newCommunications.sort((a,b)=>a.sent.localeCompare(b.sent)),setCommunications(newCommunications)}function BaseChat(props){let{title,communications,setCommunications,query,sendMessage,onMessageReceived,onMessageUpdated,inputDisabled,onError,...paperProps}=props,medplum=useMedplum20(),inputRef=useRef13(null),scrollAreaRef=useRef13(null),firstScrollRef=useRef13(!0),initialLoadRef=useRef13(!0),[profile,setProfile]=useState44(medplum.getProfile()),[reconnecting,setReconnecting]=useState44(!1),[loading,setLoading]=useState44(!0);loading||(initialLoadRef.current=!1);let profileRefStr=useMemo24(()=>profile?getReferenceString4(medplum.getProfile()):"",[profile,medplum]),searchMessages=useCallback10(async()=>{setLoading(!0);let searchParams=new URLSearchParams(query);searchParams.append("_sort","-sent"),searchParams.append("sent:missing","false");let searchResult=await medplum.searchResources("Communication",searchParams,{cache:"no-cache"});upsertCommunications(communicationsRef.current,searchResult,setCommunications),setLoading(!1)},[medplum,setCommunications,query]);useEffect13(()=>{searchMessages().catch(err=>showNotification6({color:"red",message:normalizeErrorString6(err)}))},[searchMessages]),useSubscription(`Communication?${query}`,bundle=>{let communication=bundle.entry?.[1]?.resource;upsertCommunications(communicationsRef.current,[communication],setCommunications),getReferenceString4(communication.sender)!==profileRefStr&&(communicationsRef.current.find(c=>c.id===communication.id)?onMessageUpdated?.(communication):onMessageReceived?.(communication))},{onWebSocketClose:useCallback10(()=>{reconnecting||setReconnecting(!0),showNotification6({color:"red",message:"Live chat disconnected. Attempting to reconnect..."})},[reconnecting]),onWebSocketOpen:useCallback10(()=>{reconnecting&&showNotification6({color:"green",message:"Live chat reconnected."})},[reconnecting]),onSubscriptionConnect:useCallback10(()=>{reconnecting&&(searchMessages().catch(err=>showNotification6({color:"red",message:normalizeErrorString6(err)})),setReconnecting(!1))},[reconnecting,searchMessages]),onError:useCallback10(err=>{onError?onError(err):showError(normalizeErrorString6(err))},[onError])});let sendMessageInternal=useCallback10(formData=>{inputDisabled||(inputRef.current&&(inputRef.current.value=""),sendMessage(formData.message),scrollToBottomRef.current=!0)},[inputDisabled,sendMessage]);useEffect13(()=>{let latestProfile=medplum.getProfile();profile?.id!==latestProfile?.id&&(setProfile(latestProfile),setCommunications([]))});let[parentRef,parentRect]=useResizeObserver(),communicationsRef=useRef13(communications);communicationsRef.current=communications;let prevCommunicationsRef=useRef13(communications),scrollToBottomRef=useRef13(!0);useEffect13(()=>{communications!==prevCommunicationsRef.current&&(scrollToBottomRef.current=!0),prevCommunicationsRef.current=communications},[communications]),useEffect13(()=>{scrollToBottomRef.current&&scrollAreaRef.current?.scrollTo&&(scrollAreaRef.current.scrollTo({top:scrollAreaRef.current.scrollHeight,...firstScrollRef.current?{duration:0}:{behavior:"smooth"}}),firstScrollRef.current=!1,scrollToBottomRef.current=!1)});let myLastDeliveredId=useMemo24(()=>{let i=communications.length;for(;i--;){let comm=communications[i];if(comm.sender?.reference===profileRefStr&&comm.received)return comm.id}return""},[communications,profileRefStr]);return profile?jsxs47(Paper2,{className:BaseChat_default.chatPaper,p:0,radius:"md",...paperProps,children:[jsx84(Title5,{order:2,className:BaseChat_default.chatTitle,children:title}),jsx84("div",{className:BaseChat_default.chatBody,ref:parentRef,children:initialLoadRef.current?jsxs47(Stack13,{align:"stretch",mt:"lg",children:[jsxs47(Group30,{justify:"flex-start",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(Skeleton,{height:38,circle:!0,ml:"md"}),jsx84(ChatBubbleSkeleton,{alignment:"left",parentWidth:parentRect.width})]}),jsxs47(Group30,{justify:"flex-end",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(ChatBubbleSkeleton,{alignment:"right",parentWidth:parentRect.width}),jsx84(Skeleton,{height:38,circle:!0,mr:"md"})]}),jsxs47(Group30,{justify:"flex-start",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(Skeleton,{height:38,circle:!0,ml:"md"}),jsx84(ChatBubbleSkeleton,{alignment:"left",parentWidth:parentRect.width})]})]},"skeleton-chat-messages"):jsxs47(ScrollArea2,{viewportRef:scrollAreaRef,className:BaseChat_default.chatScrollArea,h:parentRect.height,children:[jsx84(LoadingOverlay,{visible:loading||reconnecting,style:{width:parentRect.width,height:parentRect.height,position:"absolute",zIndex:1}}),communications.map((c,i)=>{let prevCommunication=i>0?communications[i-1]:void 0,prevCommTime=prevCommunication?parseSentTime(prevCommunication):void 0,currCommTime=parseSentTime(c);return jsxs47(Stack13,{align:"stretch",children:[(!prevCommTime||currCommTime!==prevCommTime)&&jsx84("div",{style:{textAlign:"center"},children:currCommTime}),c.sender?.reference===profileRefStr?jsxs47(Group30,{justify:"flex-end",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(ChatBubble,{alignment:"right",communication:c,showDelivered:!!c.received&&c.id===myLastDeliveredId}),jsx84(ResourceAvatar,{radius:"xl",color:"orange",value:c.sender})]}):jsxs47(Group30,{justify:"flex-start",align:"flex-end",gap:"xs",mb:"sm",children:[jsx84(ResourceAvatar,{radius:"xl",value:c.sender}),jsx84(ChatBubble,{alignment:"left",communication:c})]})]},`${c.id}--${c.meta?.versionId??"no-version"}`)})]})}),jsx84("div",{className:BaseChat_default.chatInputContainer,children:jsx84(Form,{onSubmit:sendMessageInternal,children:jsx84(TextInput18,{ref:inputRef,name:"message",placeholder:inputDisabled?"Replies are disabled":"Type a message...",radius:"xl",rightSectionWidth:42,disabled:inputDisabled,rightSection:inputDisabled?void 0:jsx84(ActionIcon6,{type:"submit",size:"1.5rem",radius:"xl",color:"blue",variant:"filled","aria-label":"Send message",children:jsx84(IconArrowRight,{size:"1rem",stroke:1.5})})})})})]}):null}function ChatBubble(props){let{communication,alignment,showDelivered}=props,content=communication.payload?.[0]?.contentString||"",seenTime=new Date(communication.received??-1),senderResource=useResource3(communication.sender);return jsxs47("div",{className:BaseChat_default.chatBubbleOuterWrap,children:[jsx84("div",{className:clsx_default(BaseChat_default.chatBubbleName,alignment==="right"&&BaseChat_default.chatBubbleNameRight),"aria-label":"Sender name",children:senderResource?getDisplayString4(senderResource):"[Unknown sender]"}),jsx84("div",{className:alignment==="left"?BaseChat_default.chatBubbleLeftAlignedInnerWrap:BaseChat_default.chatBubbleRightAlignedInnerWrap,children:jsx84("div",{className:BaseChat_default.chatBubble,children:content})}),showDelivered&&jsxs47("div",{style:{textAlign:"right"},children:["Delivered ",seenTime.getHours(),":",seenTime.getMinutes().toString().length===1?"0":"",seenTime.getMinutes()]})]})}function ChatBubbleSkeleton(props){let{alignment,parentWidth}=props;return jsxs47("div",{className:BaseChat_default.chatBubbleOuterWrap,children:[jsx84("div",{className:BaseChat_default.chatBubbleName,"aria-label":"Placeholder sender name",children:jsx84("div",{style:{position:"relative"},children:jsx84(Skeleton,{height:14,width:"100px",radius:"l",ml:alignment==="left"?"sm":void 0,style:alignment==="right"?{position:"absolute",right:5,top:-15}:void 0})})}),jsx84("div",{className:alignment==="left"?BaseChat_default.chatBubbleLeftAlignedInnerWrap:BaseChat_default.chatBubbleRightAlignedInnerWrap,children:jsx84("div",{className:BaseChat_default.chatBubble,children:jsx84(Skeleton,{height:14,width:parentWidth*.5,radius:"l"})})})]})}import{ActionIcon as ActionIcon7}from"@mantine/core";import{useMedplumProfile as useMedplumProfile4}from"@medplum/react-hooks";import{useEffect as useEffect14,useState as useState45}from"react";var ChatModal_default={iconContainer:"ChatModal_iconContainer",icon:"ChatModal_icon",chatModalContainer:"ChatModal_chatModalContainer"};import{Fragment as Fragment26,jsx as jsx85,jsxs as jsxs48}from"react/jsx-runtime";function ChatModal(props){let{open,children}=props,profile=useMedplumProfile4(),[opened,setOpened]=useState45(open??!1);return useEffect14(()=>{setOpened(prevVal=>open??prevVal)},[open]),profile?jsxs48(Fragment26,{children:[opened&&jsx85("div",{className:ChatModal_default.chatModalContainer,children}),opened?jsx85("div",{className:ChatModal_default.iconContainer,children:jsx85(ActionIcon7,{className:ChatModal_default.icon,color:"blue",size:"lg",radius:"xl",variant:"outline",onClick:()=>setOpened(!1),"aria-label":"Close chat",children:jsx85(IconChevronDown,{size:"1.625rem"})})}):jsx85("div",{className:ChatModal_default.iconContainer,children:jsx85(ActionIcon7,{className:ChatModal_default.icon,color:"blue",size:"lg",radius:"xl",variant:"outline",onClick:()=>setOpened(!0),"aria-label":"Open chat",children:jsx85(IconChevronUp,{size:"1.625rem"})})})]}):null}import{createReference as createReference3,formatCodeableConcept as formatCodeableConcept2,getReferenceString as getReferenceString5}from"@medplum/core";import{useMedplum as useMedplum21,useMedplumProfile as useMedplumProfile5,usePrevious}from"@medplum/react-hooks";import{useCallback as useCallback11,useEffect as useEffect15,useMemo as useMemo25,useState as useState46}from"react";import{jsx as jsx86}from"react/jsx-runtime";function ThreadChat(props){let{thread,title,onMessageSent,inputDisabled,onError}=props,medplum=useMedplum21(),profile=useMedplumProfile5(),prevThreadId=usePrevious(thread?.id),[communications,setCommunications]=useState46([]),profileRef=useMemo25(()=>profile?createReference3(profile):void 0,[profile]),threadRef=useMemo25(()=>createReference3(thread),[thread]);useEffect15(()=>{thread?.id!==prevThreadId&&setCommunications([])},[thread?.id,prevThreadId]);let sendMessage=useCallback11(message=>{let profileRefStr=profileRef?getReferenceString5(profileRef):void 0;profileRefStr&&medplum.createResource({resourceType:"Communication",status:"in-progress",sender:profileRef,recipient:thread.recipient?.filter(ref=>getReferenceString5(ref)!==profileRefStr)??[],sent:new Date().toISOString(),payload:[{contentString:message}],partOf:[threadRef]}).then(communication=>{setCommunications([...communications,communication]),onMessageSent?.(communication)}).catch(console.error)},[medplum,profileRef,thread,threadRef,communications,onMessageSent]),onMessageReceived=useMemo25(()=>thread.recipient?.length===2?message=>{message.received&&message.status==="completed"||medplum.updateResource({...message,received:message.received??new Date().toISOString(),status:"completed"}).catch(console.error)}:void 0,[medplum,thread.recipient?.length]);return profile?jsx86(BaseChat,{title:title??(thread?.topic?formatCodeableConcept2(thread.topic):"[No thread title]"),communications,setCommunications,query:`part-of=Communication/${thread.id}`,sendMessage,onMessageReceived,inputDisabled,onError}):null}import{ActionIcon as ActionIcon9,Center as Center7,Group as Group34,Loader as Loader3,ScrollArea as ScrollArea3,TextInput as TextInput19}from"@mantine/core";import{showNotification as showNotification7,updateNotification}from"@mantine/notifications";import{createReference as createReference4,normalizeErrorString as normalizeErrorString8}from"@medplum/core";import{useMedplum as useMedplum25,useResource as useResource7}from"@medplum/react-hooks";import{useCallback as useCallback12,useEffect as useEffect19,useRef as useRef14,useState as useState52}from"react";import{Group as Group32,List,Stack as Stack15,Text as Text13,Title as Title6}from"@mantine/core";import{capitalize as capitalize3,formatCodeableConcept as formatCodeableConcept3,formatDateTime as formatDateTime2,formatObservationValue,isReference as isReference2}from"@medplum/core";import{useMedplum as useMedplum22,useResource as useResource5}from"@medplum/react-hooks";import{useEffect as useEffect16,useState as useState48}from"react";import{Blockquote,Stack as Stack14}from"@mantine/core";var NoteDisplay_default={noteBody:"NoteDisplay_noteBody",noteCite:"NoteDisplay_noteCite",noteRoot:"NoteDisplay_noteRoot"};import{jsx as jsx87}from"react/jsx-runtime";function NoteDisplay({value}){return value?jsx87(Stack14,{justify:"flex-start",gap:"xs",children:value.map(note=>note.text&&jsx87(Blockquote,{classNames:{cite:NoteDisplay_default.noteCite,root:NoteDisplay_default.noteRoot},cite:note.authorReference?.display||note.authorString,icon:null,children:note.text},`note-${note.text}`))}):null}import{Group as Group31}from"@mantine/core";import{Text as Text12}from"@mantine/core";import{getDisplayString as getDisplayString5,isOk,normalizeErrorString as normalizeErrorString7}from"@medplum/core";import{useResource as useResource4}from"@medplum/react-hooks";import{useState as useState47}from"react";import{jsx as jsx88}from"react/jsx-runtime";function ResourceName(props){let{value,link,...rest}=props,[outcome,setOutcome]=useState47(),resource=useResource4(value,setOutcome),text;if(outcome&&!isOk(outcome))text=`[${normalizeErrorString7(outcome)}]`;else if(resource)text=getDisplayString5(resource);else return null;return link?jsx88(MedplumLink,{to:value,...rest,children:text}):jsx88(Text12,{component:"span",...rest,children:text})}import{jsx as jsx89,jsxs as jsxs49}from"react/jsx-runtime";function ResourceBadge(props){return jsxs49(Group31,{gap:"xs",children:[jsx89(ResourceAvatar,{size:24,radius:12,value:props.value,link:props.link}),jsx89(ResourceName,{value:props.value,link:props.link})]})}import{Badge}from"@mantine/core";import{jsx as jsx90}from"react/jsx-runtime";var statusToColor={draft:"blue",active:"blue","on-hold":"yellow",revoked:"red",completed:"green","entered-in-error":"red",unknown:"gray",retired:"gray",registered:"blue",preliminary:"blue",final:"green",amended:"yellow",corrected:"yellow",cancelled:"red",requested:"blue",received:"blue",accepted:"blue",rejected:"red",ready:"blue","in-progress":"blue",failed:"red",proposed:"blue",pending:"blue",booked:"blue",arrived:"blue",fulfilled:"green",noshow:"red","checked-in":"blue",waitlist:"gray",routine:"gray",urgent:"red",asap:"red",stat:"red","not-done":"red",connected:"green",disconnected:"red"};function StatusBadge(props){return jsx90(Badge,{color:statusToColor[props.status],children:props.status})}var DiagnosticReportDisplay_default={table:"DiagnosticReportDisplay_table",criticalRow:"DiagnosticReportDisplay_criticalRow",noteBody:"DiagnosticReportDisplay_noteBody",noteCite:"DiagnosticReportDisplay_noteCite",noteRoot:"DiagnosticReportDisplay_noteRoot"};import{Fragment as Fragment27,jsx as jsx91,jsxs as jsxs50}from"react/jsx-runtime";DiagnosticReportDisplay.defaultProps={hideObservationNotes:!1,hideSpecimenInfo:!1};function DiagnosticReportDisplay(props){let medplum=useMedplum22(),diagnosticReport=useResource5(props.value),[specimens,setSpecimens]=useState48();if(useEffect16(()=>{diagnosticReport?.specimen&&Promise.allSettled(diagnosticReport.specimen.map(ref=>medplum.readReference(ref))).then(outcomes=>outcomes.filter(outcome=>outcome.status==="fulfilled").map(outcome=>outcome.value)).then(setSpecimens).catch(console.error)},[medplum,diagnosticReport]),!diagnosticReport)return null;let specimenNotes=specimens?.flatMap(spec=>spec.note||[])||[];if(diagnosticReport.presentedForm&&diagnosticReport.presentedForm.length>0){let pf=diagnosticReport.presentedForm[0];pf.contentType?.startsWith("text/plain")&&pf.data&&specimenNotes.push({text:window.atob(pf.data)})}return jsxs50(Stack15,{children:[jsx91(Title6,{children:"Diagnostic Report"}),jsx91(DiagnosticReportHeader,{value:diagnosticReport}),specimens&&!props.hideSpecimenInfo&&SpecimenInfo(specimens),diagnosticReport.result&&jsx91(ObservationTable,{hideObservationNotes:props.hideObservationNotes,value:diagnosticReport.result}),specimenNotes.length>0&&jsx91(NoteDisplay,{value:specimenNotes})]})}function DiagnosticReportHeader({value}){return jsxs50(Group32,{mt:"md",gap:30,children:[value.subject&&jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Subject"}),jsx91(ResourceBadge,{value:value.subject,link:!0})]}),value.resultsInterpreter?.map(interpreter=>jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Interpreter"}),jsx91(ResourceBadge,{value:interpreter,link:!0})]},interpreter.reference)),value.performer?.map(performer=>jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Performer"}),jsx91(ResourceBadge,{value:performer,link:!0})]},performer.reference)),value.issued&&jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Issued"}),jsx91(Text13,{children:formatDateTime2(value.issued)})]}),value.status&&jsxs50("div",{children:[jsx91(Text13,{size:"xs",tt:"uppercase",c:"dimmed",children:"Status"}),jsx91(Text13,{children:capitalize3(value.status)})]})]})}function SpecimenInfo(specimens){return jsxs50(Stack15,{gap:"xs",children:[jsx91(Title6,{order:2,size:"h6",children:"Specimens"}),jsx91(List,{type:"ordered",children:specimens?.map(specimen=>jsx91(List.Item,{ml:"sm",children:jsxs50(Group32,{gap:20,children:[jsxs50(Group32,{gap:5,children:[jsx91(Text13,{fw:500,children:"Collected:"})," ",formatDateTime2(specimen.collection?.collectedDateTime)]}),jsxs50(Group32,{gap:5,children:[jsx91(Text13,{fw:500,children:"Received:"})," ",formatDateTime2(specimen.receivedTime)]})]})},`specimen-${specimen.id}`))})]})}function ObservationTable(props){return jsxs50("table",{className:DiagnosticReportDisplay_default.table,children:[jsx91("thead",{children:jsxs50("tr",{children:[jsx91("th",{children:"Test"}),jsx91("th",{children:"Value"}),jsx91("th",{children:"Reference Range"}),jsx91("th",{children:"Interpretation"}),jsx91("th",{children:"Category"}),jsx91("th",{children:"Performer"}),jsx91("th",{children:"Status"})]})}),jsx91("tbody",{children:jsx91(ObservationRowGroup,{value:props.value,ancestorIds:props.ancestorIds,hideObservationNotes:props.hideObservationNotes})})]})}function ObservationRowGroup(props){return jsx91(Fragment27,{children:props.value?.map(observation=>jsx91(ObservationRow,{value:observation,ancestorIds:props.ancestorIds,hideObservationNotes:props.hideObservationNotes},`obs-${isReference2(observation)?observation.reference:observation.id}`))})}function ObservationRow(props){let observation=useResource5(props.value);if(!observation||props.ancestorIds?.includes(observation.id))return null;let displayNotes=!props.hideObservationNotes&&observation.note,critical=isCritical(observation);return jsxs50(Fragment27,{children:[jsxs50("tr",{className:clsx_default({[DiagnosticReportDisplay_default.criticalRow]:critical}),children:[jsx91("td",{rowSpan:displayNotes?2:1,children:jsx91(MedplumLink,{to:observation,children:jsx91(CodeableConceptDisplay,{value:observation.code})})}),jsx91("td",{children:jsx91(ObservationValueDisplay,{value:observation})}),jsx91("td",{children:jsx91(ReferenceRangeDisplay,{value:observation.referenceRange})}),jsx91("td",{children:observation.interpretation&&observation.interpretation.length>0&&jsx91(CodeableConceptDisplay,{value:observation.interpretation[0]})}),jsx91("td",{children:observation.category&&observation.category.length>0&&jsx91(Fragment27,{children:observation.category.map(concept=>jsx91("div",{children:jsx91(CodeableConceptDisplay,{value:concept})},`category-${formatCodeableConcept3(concept)}`))})}),jsx91("td",{children:observation.performer?.map(performer=>jsx91(ReferenceDisplay,{value:performer},performer.reference))}),jsx91("td",{children:observation.status&&jsx91(StatusBadge,{status:observation.status})})]}),observation.hasMember&&jsx91(ObservationRowGroup,{value:observation.hasMember,ancestorIds:props.ancestorIds?[...props.ancestorIds,observation.id]:[observation.id],hideObservationNotes:props.hideObservationNotes}),displayNotes&&jsx91("tr",{children:jsx91("td",{colSpan:6,children:jsx91(NoteDisplay,{value:observation.note})})})]})}function ObservationValueDisplay(props){let obs=props.value;return jsx91(Fragment27,{children:formatObservationValue(obs)})}function ReferenceRangeDisplay(props){let range=props.value&&props.value.length>0&&props.value[0];return range?range.text?jsx91(Fragment27,{children:range.text}):jsx91(RangeDisplay,{value:range}):null}function isCritical(observation){let code=observation.interpretation?.[0]?.coding?.[0]?.code;return code==="AA"||code==="LL"||code==="HH"||code==="A"}var import_rfc6902=__toESM(require_rfc6902(),1);import{Table as Table2}from"@mantine/core";import{arrayify,capitalize as capitalize4,evalFhirPathTyped,getSearchParameterDetails,toTypedValue}from"@medplum/core";import{useMedplum as useMedplum23}from"@medplum/react-hooks";import{useEffect as useEffect17,useMemo as useMemo26,useState as useState50}from"react";import{useState as useState49}from"react";import{Table,Button as Button12}from"@mantine/core";var ResourceDiffRow_default={removed:"ResourceDiffRow_removed",added:"ResourceDiffRow_added"};import{Fragment as Fragment28,jsx as jsx92,jsxs as jsxs51}from"react/jsx-runtime";function ResourceDiffRow(props){let{name,path,property,originalValue,revisedValue}=props,isAttachmentType=!!property?.type?.find(t=>t.code==="Attachment"),[isCollapsed,setIsCollapsed]=useState49(isAttachmentType),toggleCollapse=()=>setIsCollapsed(prev=>!prev);return jsx92(Fragment28,{children:isAttachmentType&&!isCollapsed||!isAttachmentType?jsx92(Fragment28,{children:jsxs51(Table.Tr,{children:[jsx92(Table.Td,{children:name}),jsx92(Table.Td,{className:ResourceDiffRow_default.removed,children:originalValue&&jsx92(ResourcePropertyDisplay,{path,property,propertyType:originalValue.type,value:originalValue.value,ignoreMissingValues:!0})}),jsx92(Table.Td,{className:ResourceDiffRow_default.added,children:revisedValue&&jsx92(ResourcePropertyDisplay,{path,property,propertyType:revisedValue.type,value:revisedValue.value,ignoreMissingValues:!0})})]})}):jsxs51(Table.Tr,{children:[jsx92(Table.Td,{children:name}),jsx92(Table.Td,{colSpan:2,style:{textAlign:"right"},children:jsx92(Button12,{onClick:toggleCollapse,variant:"light",children:"Expand"})})]})})}var ResourceDiffTable_default={root:"ResourceDiffTable_root",removed:"ResourceDiffTable_removed",added:"ResourceDiffTable_added"};import{jsx as jsx93,jsxs as jsxs52}from"react/jsx-runtime";function ResourceDiffTable(props){let medplum=useMedplum23(),{original,revised}=props,[schemaLoaded,setSchemaLoaded]=useState50(!1);useEffect17(()=>{medplum.requestSchema(props.original.resourceType).then(()=>setSchemaLoaded(!0)).catch(console.log)},[medplum,props.original.resourceType]);let diffTable=useMemo26(()=>{if(!schemaLoaded)return null;let typedOriginal=[toTypedValue(original)],typedRevised=[toTypedValue(revised)],result=[],patch=mergePatchOperations((0,import_rfc6902.createPatch)(original,revised));for(let op of patch){let path=op.path,fhirPath=jsonPathToFhirPath(path),property=tryGetElementDefinition(original.resourceType,fhirPath),originalValue=op.op==="add"?void 0:evalFhirPathTyped(fhirPath,typedOriginal),revisedValue=op.op==="remove"?void 0:evalFhirPathTyped(fhirPath,typedRevised);result.push({key:`op-${op.op}-${op.path}`,name:`${capitalize4(op.op)} ${fhirPath}`,path:property?.path??original.resourceType+"."+fhirPath,property,originalValue:touchUpValue(property,originalValue),revisedValue:touchUpValue(property,revisedValue)})}return result},[schemaLoaded,original,revised]);return diffTable?jsxs52(Table2,{className:ResourceDiffTable_default.root,children:[jsx93(Table2.Thead,{children:jsxs52(Table2.Tr,{children:[jsx93(Table2.Th,{}),jsx93(Table2.Th,{children:"Before"}),jsx93(Table2.Th,{children:"After"})]})}),jsx93(Table2.Tbody,{children:diffTable.map(row=>jsx93(ResourceDiffRow,{...row}))})]}):null}function mergePatchOperations(patch){let result=[];for(let patchOperation of patch){let{op,path}=patchOperation;if(path.startsWith("/meta/author")||path.startsWith("/meta/compartment")||path.startsWith("/meta/lastUpdated")||path.startsWith("/meta/versionId"))continue;let count=patch.filter(el=>el.op===op&&el.path===path).length,resultOperation={op,path};count>1&&(op==="add"||op==="remove")&&/\/[0-9-]+$/.test(path)&&(resultOperation.op="replace",resultOperation.path=path.replace(/\/[^/]+$/,"")),result.some(el=>el.op===resultOperation.op&&el.path===resultOperation.path)||result.push(resultOperation)}return result}function jsonPathToFhirPath(path){let parts=path.split("/").filter(Boolean),result="";for(let i=0;i<parts.length;i++){let part=parts[i];part==="-"?result+=".last()":/^\d+$/.test(part)?result+=`[${part}]`:(i>0&&(result+="."),result+=part)}return result.endsWith(".url")&&(result=result.replace(/\.url$/,"")),result}function tryGetElementDefinition(resourceType,fhirPath){return getSearchParameterDetails(resourceType,{resourceType:"SearchParameter",base:[resourceType],code:resourceType+"."+fhirPath,expression:resourceType+"."+fhirPath})?.elementDefinitions?.[0]}function touchUpValue(property,input){return input&&{type:Array.isArray(input)?input[0].type:input.type,value:fixArray(input,!!property?.isArray)}}function fixArray(input,isArray){let inputValue=arrayify(input).flatMap(v=>v.value);return isArray?inputValue:inputValue[0]}import{AccessPolicyInteraction,satisfiedAccessPolicy,tryGetProfile as tryGetProfile4}from"@medplum/core";import{useMedplum as useMedplum24,useResource as useResource6}from"@medplum/react-hooks";import{useEffect as useEffect18,useMemo as useMemo27,useState as useState51}from"react";import{jsx as jsx94}from"react/jsx-runtime";function ResourceTable(props){let{profileUrl}=props,medplum=useMedplum24(),accessPolicy=medplum.getAccessPolicy(),value=useResource6(props.value),[schemaLoaded,setSchemaLoaded]=useState51(!1);useEffect18(()=>{if(value)if(profileUrl)medplum.requestProfileSchema(profileUrl,{expandProfile:!0}).then(()=>{tryGetProfile4(profileUrl)?setSchemaLoaded(!0):console.error(`Schema not found for ${profileUrl}`)}).catch(reason=>{console.error("Error in requestProfileSchema",reason)});else{let schemaName=value.resourceType;medplum.requestSchema(schemaName).then(()=>{setSchemaLoaded(!0)}).catch(console.error)}},[medplum,profileUrl,value]);let accessPolicyResource=useMemo27(()=>value&&satisfiedAccessPolicy(value,AccessPolicyInteraction.READ,accessPolicy),[accessPolicy,value]);return!schemaLoaded||!value?null:jsx94(BackboneElementDisplay,{path:value.resourceType,value:{type:value.resourceType,value:props.forceUseInput?props.value:value},profileUrl,ignoreMissingValues:props.ignoreMissingValues,accessPolicyResource})}import{ActionIcon as ActionIcon8,Group as Group33,Menu as Menu3,Text as Text14}from"@mantine/core";import{formatDateTime as formatDateTime3,getReferenceString as getReferenceString6}from"@medplum/core";var Timeline_default={item:"Timeline_item",itemPadding:"Timeline_itemPadding"};import{jsx as jsx95,jsxs as jsxs53}from"react/jsx-runtime";function Timeline(props){return jsx95(Container,{children:props.children})}function TimelineItem(props){let{resource,profile,padding,popupMenuItems,...others}=props,author=profile??resource.meta?.author,dateTime=props.dateTime??resource.meta?.lastUpdated;return jsxs53(Panel,{"data-testid":"timeline-item",fill:!0,...others,children:[jsxs53(Group33,{justify:"space-between",gap:8,mx:"xs",my:"sm",children:[jsx95(ResourceAvatar,{value:author,link:!0,size:"md"}),jsxs53("div",{style:{flex:1},children:[jsx95(Text14,{size:"sm",children:jsx95(ResourceName,{c:"dark",fw:500,value:author,link:!0})}),jsxs53(Text14,{size:"xs",children:[jsx95(MedplumLink,{c:"dimmed",to:props.resource,children:formatDateTime3(dateTime)}),jsx95(Text14,{component:"span",c:"dimmed",mx:8,children:"\xB7"}),jsx95(MedplumLink,{c:"dimmed",to:props.resource,children:props.resource.resourceType})]})]}),popupMenuItems&&jsxs53(Menu3,{position:"bottom-end",shadow:"md",width:200,children:[jsx95(Menu3.Target,{children:jsx95(ActionIcon8,{color:"gray",variant:"subtle",radius:"xl","aria-label":`Actions for ${getReferenceString6(props.resource)}`,children:jsx95(IconDots,{})})}),popupMenuItems]})]}),jsx95(ErrorBoundary,{children:jsx95("div",{className:clsx_default(Timeline_default.item,{[Timeline_default.itemPadding]:padding}),children:props.children})})]})}function sortByDateAndPriority(resources,timelineResource){resources.sort((a,b)=>{let priority1=getPriorityScore(a,timelineResource),priority2=getPriorityScore(b,timelineResource);return priority1>priority2?1:priority1<priority2?-1:getTime(a,timelineResource)-getTime(b,timelineResource)})}function getPriorityScore(resource,timelineResource){if(!isSameResourceType(resource,timelineResource)){let priority=resource.priority;if(typeof priority=="string")return{stat:4,asap:3,urgent:2}[priority]??0}return 0}function getTime(resource,timelineResource){if(!isSameResourceType(resource,timelineResource)){if(resource.resourceType==="Communication"&&resource.sent)return new Date(resource.sent).getTime();if((resource.resourceType==="DiagnosticReport"||resource.resourceType==="Media"||resource.resourceType==="Observation")&&resource.issued)return new Date(resource.issued).getTime();if(resource.resourceType==="DocumentReference"&&resource.date)return new Date(resource.date).getTime()}let dateTime=resource.meta?.lastUpdated;return dateTime?new Date(dateTime).getTime():0}function isSameResourceType(a,b){return!!b&&a.resourceType===b.resourceType&&a.id===b.id}var ResourceTimeline_default={pinnedComment:"ResourceTimeline_pinnedComment"};import{jsx as jsx96,jsxs as jsxs54}from"react/jsx-runtime";function ResourceTimeline(props){let medplum=useMedplum25(),sender=medplum.getProfile(),inputRef=useRef14(null),resource=useResource7(props.value),[history,setHistory]=useState52(),[items,setItems]=useState52([]),loadTimelineResources=props.loadTimelineResources,itemsRef=useRef14(items);itemsRef.current=items;let sortAndSetItems=useCallback12(newItems=>{sortByDateAndPriority(newItems,resource),newItems.reverse(),setItems(newItems)},[resource]),handleBatchResponse=useCallback12(batchResponse=>{let newItems=[];for(let settledResult of batchResponse){if(settledResult.status!=="fulfilled")continue;let bundle=settledResult.value;if(bundle.type==="history"&&setHistory(bundle),bundle.entry)for(let entry of bundle.entry)newItems.push(entry.resource)}sortAndSetItems(newItems)},[sortAndSetItems]),addResource=useCallback12(resource2=>sortAndSetItems([...itemsRef.current,resource2]),[sortAndSetItems]),loadTimeline=useCallback12(()=>{let resourceType,id;"resourceType"in props.value?(resourceType=props.value.resourceType,id=props.value.id):[resourceType,id]=props.value.reference?.split("/"),loadTimelineResources(medplum,resourceType,id).then(handleBatchResponse).catch(console.error)},[medplum,props.value,loadTimelineResources,handleBatchResponse]);useEffect19(()=>loadTimeline(),[loadTimeline]);function createComment(contentString){!resource||!props.createCommunication||medplum.createResource(props.createCommunication(resource,sender,contentString)).then(result=>addResource(result)).catch(console.error)}function createMedia(attachment){!resource||!props.createMedia||medplum.createResource(props.createMedia(resource,sender,attachment)).then(result=>addResource(result)).then(()=>updateNotification({id:"upload-notification",color:"teal",title:"Upload complete",message:"",icon:jsx96(IconCheck,{size:16}),autoClose:2e3})).catch(reason=>updateNotification({id:"upload-notification",color:"red",title:"Upload error",message:normalizeErrorString8(reason),icon:jsx96(IconFileAlert,{size:16}),autoClose:2e3}))}function onUploadStart(){showNotification7({id:"upload-notification",loading:!0,title:"Initializing upload...",message:"Please wait...",autoClose:!1,withCloseButton:!1})}function onUploadProgress(e){updateNotification({id:"upload-notification",loading:!0,title:"Uploading...",message:getProgressMessage(e),autoClose:!1,withCloseButton:!1})}function onUploadError(outcome){updateNotification({id:"upload-notification",color:"red",title:"Upload error",message:normalizeErrorString8(outcome),icon:jsx96(IconFileAlert,{size:16}),autoClose:2e3})}return resource?jsxs54(Timeline,{children:[props.createCommunication&&jsx96(Panel,{children:jsx96(Form,{testid:"timeline-form",onSubmit:formData=>{createComment(formData.text);let input=inputRef.current;input&&(input.value="",input.focus())},children:jsxs54(Group34,{gap:"xs",wrap:"nowrap",style:{width:"100%"},children:[jsx96(ResourceAvatar,{value:sender}),jsx96(TextInput19,{name:"text",ref:inputRef,placeholder:"Add comment",style:{width:"100%",maxWidth:300}}),jsx96(ActionIcon9,{type:"submit",radius:"xl",color:"blue",variant:"filled",children:jsx96(IconMessage,{size:16})}),jsx96(AttachmentButton,{securityContext:createReference4(resource),onUpload:createMedia,onUploadStart,onUploadProgress,onUploadError,children:props2=>jsx96(ActionIcon9,{...props2,radius:"xl",color:"blue",variant:"filled",children:jsx96(IconCloudUpload,{size:16})})})]})})}),items.map(item=>{if(!item)return null;let key=`${item.resourceType}/${item.id}/${item.meta?.versionId}`,menu=props.getMenu?props.getMenu({primaryResource:resource,currentResource:item,reloadTimeline:loadTimeline}):void 0;if(item.resourceType===resource.resourceType&&item.id===resource.id)return jsx96(HistoryTimelineItem,{history,resource:item,popupMenuItems:menu},key);switch(item.resourceType){case"AuditEvent":return jsx96(AuditEventTimelineItem,{resource:item,popupMenuItems:menu},key);case"Communication":return jsx96(CommunicationTimelineItem,{resource:item,popupMenuItems:menu},key);case"DiagnosticReport":return jsx96(DiagnosticReportTimelineItem,{resource:item,popupMenuItems:menu},key);case"Media":return jsx96(MediaTimelineItem,{resource:item,popupMenuItems:menu},key);default:return jsx96(TimelineItem,{resource:item,padding:!0,children:jsx96(ResourceTable,{value:item,ignoreMissingValues:!0})},key)}})]}):jsx96(Center7,{style:{width:"100%",height:"100%"},children:jsx96(Loader3,{})})}function HistoryTimelineItem(props){let{history,resource,...rest}=props,previous=getPrevious(history,resource);return previous?jsx96(TimelineItem,{resource,padding:!0,...rest,children:jsx96(ResourceDiffTable,{original:previous,revised:props.resource})}):jsxs54(TimelineItem,{resource,padding:!0,...rest,children:[jsx96("h3",{children:"Created"}),jsx96(ResourceTable,{value:resource,ignoreMissingValues:!0,forceUseInput:!0})]})}function getPrevious(history,version){let entries=history.entry??[],index=entries.findIndex(entry=>entry.resource?.meta?.versionId===version.meta?.versionId);if(!(index>=entries.length-1))return entries[index+1].resource}function CommunicationTimelineItem(props){let className=!props.resource.priority||props.resource.priority==="routine"?void 0:ResourceTimeline_default.pinnedComment;return jsx96(TimelineItem,{resource:props.resource,profile:props.resource.sender,dateTime:props.resource.sent,padding:!0,className,popupMenuItems:props.popupMenuItems,children:jsx96("p",{children:props.resource.payload?.[0]?.contentString})})}function MediaTimelineItem(props){let contentType=props.resource.content?.contentType,padding=contentType&&!contentType.startsWith("image/")&&!contentType.startsWith("video/")&&contentType!=="application/pdf";return jsx96(TimelineItem,{resource:props.resource,padding:!!padding,popupMenuItems:props.popupMenuItems,children:jsx96(AttachmentDisplay,{value:props.resource.content})})}function AuditEventTimelineItem(props){return jsx96(TimelineItem,{resource:props.resource,padding:!0,popupMenuItems:props.popupMenuItems,children:jsx96(ScrollArea3,{children:jsx96("pre",{children:props.resource.outcomeDesc})})})}function DiagnosticReportTimelineItem(props){return jsx96(TimelineItem,{resource:props.resource,padding:!0,popupMenuItems:props.popupMenuItems,children:jsx96(DiagnosticReportDisplay,{value:props.resource})})}function getProgressMessage(e){if(e.lengthComputable){let percent=100*e.loaded/e.total;return`Uploaded: ${formatFileSize(e.loaded)} / ${formatFileSize(e.total)} ${percent.toFixed(2)}%`}return`Uploaded: ${formatFileSize(e.loaded)}`}function formatFileSize(bytes){if(bytes===0)return"0.00 B";let e=Math.floor(Math.log(bytes)/Math.log(1024));return(bytes/Math.pow(1024,e)).toFixed(2)+" "+" KMGTP".charAt(e)+"B"}import{jsx as jsx97}from"react/jsx-runtime";function DefaultResourceTimeline(props){let{resource,...rest}=props;return jsx97(ResourceTimeline,{value:resource,loadTimelineResources:async(medplum,resourceType,id)=>{let ref=`${resourceType}/${id}`;return Promise.allSettled([medplum.readHistory(resourceType,id),medplum.search("Task",{_filter:`based-on eq ${ref} or focus eq ${ref} or subject eq ${ref}`,_count:100})])},...rest})}import{createReference as createReference5}from"@medplum/core";import{jsx as jsx98}from"react/jsx-runtime";function EncounterTimeline(props){let{encounter,...rest}=props;return jsx98(ResourceTimeline,{value:encounter,loadTimelineResources:async(medplum,_resourceType,id)=>Promise.allSettled([medplum.readHistory("Encounter",id),medplum.search("Communication","encounter=Encounter/"+id),medplum.search("Media","encounter=Encounter/"+id)]),createCommunication:(resource,sender,text)=>({resourceType:"Communication",status:"completed",encounter:createReference5(resource),subject:resource.subject,sender:createReference5(sender),sent:new Date().toISOString(),payload:[{contentString:text}]}),createMedia:(resource,operator,content)=>({resourceType:"Media",status:"completed",encounter:createReference5(resource),subject:resource.subject,operator:createReference5(operator),issued:new Date().toISOString(),content}),...rest})}import{Button as Button18,Loader as Loader5,Table as Table4}from"@mantine/core";import{normalizeOperationOutcome as normalizeOperationOutcome8}from"@medplum/core";import{useMedplum as useMedplum27}from"@medplum/react-hooks";import{memo,useEffect as useEffect23,useRef as useRef18,useState as useState57}from"react";import{evalFhirPath}from"@medplum/core";import{jsx as jsx99}from"react/jsx-runtime";function FhirPathDisplay(props){let value;try{value=evalFhirPath(props.path,props.resource)}catch(err){return console.warn("FhirPathDisplay:",err),null}if(value.length>1)throw new Error(`Component "path" for "FhirPathDisplay" must resolve to a single element. Received ${value.length} elements [${JSON.stringify(value,null,2)}]`);return jsx99(ResourcePropertyDisplay,{value:value[0]||"",propertyType:props.propertyType})}import{ActionIcon as ActionIcon11,Button as Button17,Center as Center8,Group as Group37,Loader as Loader4,Menu as Menu5,Pagination,Table as Table3,Text as Text16,UnstyledButton as UnstyledButton2}from"@mantine/core";import{DEFAULT_SEARCH_COUNT as DEFAULT_SEARCH_COUNT2,deepEquals,formatSearchQuery,isDataTypeLoaded,normalizeOperationOutcome as normalizeOperationOutcome7}from"@medplum/core";import{useMedplum as useMedplum26}from"@medplum/react-hooks";import{useCallback as useCallback13,useEffect as useEffect22,useRef as useRef17,useState as useState56}from"react";import{Box as Box2,Button as Button13,Modal as Modal3,Text as Text15}from"@mantine/core";import{jsx as jsx100,jsxs as jsxs55}from"react/jsx-runtime";function SearchExportDialog(props){return jsxs55(Modal3,{title:"Export",closeButtonProps:{"aria-label":"Close"},opened:props.visible,onClose:props.onCancel,children:[jsxs55(Box2,{display:"flex",style:{justifyContent:"space-between"},children:[props.exportCsv&&jsx100(ExportButton,{text:"CSV",exportLogic:props.exportCsv,onCancel:props.onCancel}),props.exportTransactionBundle&&jsx100(ExportButton,{text:"Transaction Bundle",exportLogic:props.exportTransactionBundle,onCancel:props.onCancel})]}),jsx100(Text15,{style:{marginTop:"10px",marginLeft:"2px"},children:"Limited to 1000 records"})]})}function ExportButton(props){return jsx100(Button13,{onClick:()=>{props.exportLogic(),props.onCancel()},children:`Export as ${props.text}`})}import{Button as Button14,Group as Group35,Modal as Modal4,MultiSelect,Stack as Stack16}from"@mantine/core";import{getDataType as getDataType2,getSearchParameters,sortStringArray,stringify as stringify2}from"@medplum/core";import{useEffect as useEffect20,useMemo as useMemo28,useRef as useRef15,useState as useState53}from"react";import{capitalize as capitalize5,DEFAULT_SEARCH_COUNT,evalFhirPathTyped as evalFhirPathTyped2,formatDateTime as formatDateTime4,Operator}from"@medplum/core";import{Fragment as Fragment29,jsx as jsx101}from"react/jsx-runtime";var searchParamToOperators={string:[Operator.EQUALS,Operator.NOT,Operator.CONTAINS,Operator.EXACT],fulltext:[Operator.EQUALS,Operator.NOT,Operator.CONTAINS,Operator.EXACT],token:[Operator.EQUALS,Operator.NOT],reference:[Operator.EQUALS,Operator.NOT],numeric:[Operator.EQUALS,Operator.NOT_EQUALS,Operator.GREATER_THAN,Operator.LESS_THAN,Operator.GREATER_THAN_OR_EQUALS,Operator.LESS_THAN_OR_EQUALS],quantity:[Operator.EQUALS,Operator.NOT_EQUALS,Operator.GREATER_THAN,Operator.LESS_THAN,Operator.GREATER_THAN_OR_EQUALS,Operator.LESS_THAN_OR_EQUALS],date:[Operator.EQUALS,Operator.NOT_EQUALS,Operator.GREATER_THAN,Operator.LESS_THAN,Operator.GREATER_THAN_OR_EQUALS,Operator.LESS_THAN_OR_EQUALS,Operator.STARTS_AFTER,Operator.ENDS_BEFORE,Operator.APPROXIMATELY],datetime:[Operator.EQUALS,Operator.NOT_EQUALS,Operator.GREATER_THAN,Operator.LESS_THAN,Operator.GREATER_THAN_OR_EQUALS,Operator.LESS_THAN_OR_EQUALS,Operator.STARTS_AFTER,Operator.ENDS_BEFORE,Operator.APPROXIMATELY],uri:[Operator.EQUALS,Operator.NOT,Operator.ABOVE,Operator.BELOW]},operatorNames={eq:"equals",ne:"not equals",gt:"greater than",lt:"less than",ge:"greater than or equals",le:"less than or equals",sa:"starts after",eb:"ends before",ap:"approximately",sw:"starts with",contains:"contains",exact:"exact",text:"text",not:"not",above:"above",below:"below",in:"in","not-in":"not in","of-type":"of type",missing:"missing",present:"present",identifier:"identifier",iterate:"iterate"};function setFilters(definition,filters){return{...definition,filters,offset:0,name:void 0}}function clearFilters(definition){return setFilters(definition,[])}function clearFiltersOnField(definition,code){return setFilters(definition,(definition.filters??[]).filter(f=>f.code!==code))}function addFilter(definition,field,op,value,opt_clear){opt_clear&&(definition=clearFiltersOnField(definition,field));let nextFilters=[];return definition.filters&&nextFilters.push(...definition.filters),nextFilters.push({code:field,operator:op,value:value??""}),setFilters(definition,nextFilters)}function addField(definition,field){if(definition.fields?.includes(field))return definition;let newFields=[];return definition.fields&&newFields.push(...definition.fields),newFields.push(field),{...definition,fields:newFields,name:void 0}}function deleteFilter(definition,index){if(!definition.filters)return definition;let newFilters=[...definition.filters];return newFilters.splice(index,1),{...definition,filters:newFilters,name:void 0}}function addYesterdayFilter(definition,field){return addDayFilter(definition,field,-1)}function addTodayFilter(definition,field){return addDayFilter(definition,field,0)}function addTomorrowFilter(definition,field){return addDayFilter(definition,field,1)}function addDayFilter(definition,field,delta){let startTime=new Date;startTime.setDate(startTime.getDate()+delta),startTime.setHours(0,0,0,0);let endTime=new Date(startTime.getTime());return endTime.setDate(endTime.getDate()+1),endTime.setTime(endTime.getTime()-1),addDateFilterBetween(definition,field,startTime,endTime)}function addLastMonthFilter(definition,field){return addMonthFilter(definition,field,-1)}function addThisMonthFilter(definition,field){return addMonthFilter(definition,field,0)}function addNextMonthFilter(definition,field){return addMonthFilter(definition,field,1)}function addMonthFilter(definition,field,delta){let startTime=new Date;startTime.setMonth(startTime.getMonth()+delta),startTime.setDate(1),startTime.setHours(0,0,0,0);let endTime=new Date(startTime.getTime());return endTime.setMonth(endTime.getMonth()+1),endTime.setDate(1),endTime.setHours(0,0,0,0),endTime.setTime(endTime.getTime()-1),addDateFilterBetween(definition,field,startTime,endTime)}function addYearToDateFilter(definition,field){let startTime=new Date;return startTime.setMonth(0),startTime.setDate(1),startTime.setHours(0,0,0,0),addDateFilterBetween(definition,field,startTime,new Date)}function addDateFilterBetween(definition,field,d1,d2){return definition=clearFiltersOnField(definition,field),definition=addDateFilterImpl(definition,field,Operator.GREATER_THAN_OR_EQUALS,d1),definition=addDateFilterImpl(definition,field,Operator.LESS_THAN_OR_EQUALS,d2),definition}function addDateFilterImpl(definition,field,op,value){return addFilter(definition,field,op,value.toISOString())}function addMissingFilter(definition,field,value=!0){return addFilter(definition,field,Operator.MISSING,value.toString())}function setOffset(definition,offset){return definition.offset===offset?definition:{...definition,offset,name:void 0}}function setPage(definition,page){let count=definition.count??DEFAULT_SEARCH_COUNT,newOffset=(page-1)*count;return setOffset(definition,newOffset)}function setSort(definition,sort,desc){return sort===getSortField(definition)&&desc!==void 0&&desc===isSortDescending(definition)?definition:{...definition,sortRules:[{code:sort,descending:!!desc}],name:void 0}}function toggleSort(definition,key){let desc=!1;return getSortField(definition)===key&&(desc=!isSortDescending(definition)),setSort(definition,key,desc)}function getSortField(definition){let sortRules=definition.sortRules;if(!sortRules||sortRules.length===0)return;let field=sortRules[0].code;return field.startsWith("-")?field.substr(1):field}function isSortDescending(definition){let sortRules=definition.sortRules;return!sortRules||sortRules.length===0?!1:!!sortRules[0].descending}function getSearchOperators(searchParam){return searchParamToOperators[searchParam.type]}function getOpString(op){return operatorNames[op]??""}function buildFieldNameString(key){let tmp=key;return tmp.includes(".")&&(tmp=tmp.split(".").pop()),tmp==="versionId"?"Version ID":(tmp=tmp.replace("[x]",""),tmp=tmp.replace(/([A-Z])/g," $1"),tmp=tmp.replace(/[-_]/g," "),tmp=tmp.replace(/\s+/g," "),tmp=tmp.trim(),tmp.toLowerCase()==="id"?"ID":tmp.split(/\s/).map(capitalize5).join(" "))}function renderValue(resource,field){let key=field.name;return key==="id"?resource.id:key==="meta.versionId"?resource.meta?.versionId:key==="_lastUpdated"?formatDateTime4(resource.meta?.lastUpdated):field.elementDefinition&&`${resource.resourceType}.${field.name}`===field.elementDefinition.path?renderPropertyValue(resource,field.elementDefinition):field.searchParams&&field.searchParams.length===1&&field.name===field.searchParams[0].code?renderSearchParameterValue(resource,field.searchParams[0]):null}function renderPropertyValue(resource,elementDefinition){let path=elementDefinition.path?.split(".")?.pop()?.replaceAll("[x]","")??"",[value,propertyType]=getValueAndType({type:resource.resourceType,value:resource},path);return value?jsx101(ResourcePropertyDisplay,{path:elementDefinition.path,property:elementDefinition,propertyType,value,maxWidth:200,ignoreMissingValues:!0,link:!1}):null}function renderSearchParameterValue(resource,searchParam){let value=evalFhirPathTyped2(searchParam.expression,[{type:resource.resourceType,value:resource}]);return!value||value.length===0?null:jsx101(Fragment29,{children:value.map((v,index)=>jsx101(ResourcePropertyDisplay,{propertyType:v.type,value:v.value,maxWidth:200,ignoreMissingValues:!0,link:!1},`${index}-${value.length}`))})}import{jsx as jsx102,jsxs as jsxs56}from"react/jsx-runtime";function SearchFieldEditor(props){let wasDropdownOpen=useRef15(!1),[state,setState]=useState53({search:JSON.parse(stringify2(props.search))}),[isDropdownOpen,setIsDropdownOpen]=useState53(!1);useEffect20(()=>{setState({search:props.search})},[props.search]);let allFields=useMemo28(()=>{if(!props.visible)return[];let resourceType=props.search.resourceType,typeSchema=getDataType2(resourceType),searchParams=getSearchParameters(resourceType);return sortStringArray(getFieldsList(typeSchema,searchParams)).map(field=>({value:field,label:buildFieldNameString(field)}))},[props.visible,props.search.resourceType]);if(!props.visible)return null;function handleChange(newFields){setState({search:{...state.search,fields:newFields}})}return jsx102(Modal4,{title:"Fields",closeButtonProps:{"aria-label":"Close"},opened:props.visible,onClose:()=>{props.onCancel()},size:"auto",withOverlay:!0,closeOnClickOutside:!1,overlayProps:{onMouseDownCapture:()=>{wasDropdownOpen.current=isDropdownOpen},onClick:()=>{wasDropdownOpen.current||props.onCancel(),wasDropdownOpen.current=!1},children:jsx102("div",{"data-testid":"overlay-child"})},children:jsxs56(Stack16,{children:[jsx102(MultiSelect,{style:{width:550},placeholder:"Select fields to display",data:allFields,value:state.search.fields??[],onChange:handleChange,onDropdownOpen:()=>setIsDropdownOpen(!0),onDropdownClose:()=>setIsDropdownOpen(!1),maxDropdownHeight:"250px",clearButtonProps:{"aria-label":"Clear selection"},clearable:!0,searchable:!0}),jsx102(Group35,{justify:"flex-end",children:jsx102(Button14,{onClick:()=>props.onOk(state.search),children:"OK"})})]})})}function getFieldsList(typeSchema,searchParams){let result=[],keys=new Set,names=new Set;for(let key of Object.keys(typeSchema.elements))result.push(key),keys.add(key.toLowerCase()),names.add(buildFieldNameString(key));if(searchParams)for(let code of Object.keys(searchParams)){let name=buildFieldNameString(code);!keys.has(code)&&!names.has(name)&&(result.push(code),keys.add(code),names.add(name))}return result}import{ActionIcon as ActionIcon10,Button as Button15,Group as Group36,Modal as Modal5,NativeSelect as NativeSelect10}from"@mantine/core";import{Operator as Operator2,deepClone as deepClone2,getSearchParameters as getSearchParameters2}from"@medplum/core";import{useEffect as useEffect21,useRef as useRef16,useState as useState54}from"react";import{Checkbox as Checkbox5,TextInput as TextInput20}from"@mantine/core";import{getSearchParameterDetails as getSearchParameterDetails2,SearchParameterType}from"@medplum/core";import{jsx as jsx103}from"react/jsx-runtime";function SearchFilterValueInput(props){let details=getSearchParameterDetails2(props.resourceType,props.searchParam),name=props.name??"filter-value";switch(details.type){case SearchParameterType.REFERENCE:return jsx103(ReferenceInput,{name,defaultValue:props.defaultValue?{reference:props.defaultValue}:void 0,targetTypes:props.searchParam.target,autoFocus:props.autoFocus,onChange:newReference=>{newReference?props.onChange(newReference.reference):props.onChange("")}});case SearchParameterType.BOOLEAN:return jsx103(Checkbox5,{name,"data-autofocus":props.autoFocus,"data-testid":name,defaultChecked:props.defaultValue==="true",autoFocus:props.autoFocus,onChange:e=>props.onChange(e.currentTarget.checked.toString())});case SearchParameterType.DATE:return jsx103(TextInput20,{type:"date",name,"data-autofocus":props.autoFocus,"data-testid":name,defaultValue:props.defaultValue,autoFocus:props.autoFocus,onChange:e=>props.onChange(e.currentTarget.value)});case SearchParameterType.DATETIME:return jsx103(DateTimeInput,{name,defaultValue:props.defaultValue,autoFocus:props.autoFocus,onChange:props.onChange});case SearchParameterType.NUMBER:return jsx103(TextInput20,{type:"number",name,"data-autofocus":props.autoFocus,"data-testid":name,defaultValue:props.defaultValue,autoFocus:props.autoFocus,onChange:e=>props.onChange(e.currentTarget.value)});case SearchParameterType.QUANTITY:return jsx103(QuantityInput,{name,path:"",defaultValue:tryParseQuantity(props.defaultValue),autoFocus:props.autoFocus,onChange:newQuantity=>{newQuantity?props.onChange(`${newQuantity.value}`):props.onChange("")}});default:return jsx103(TextInput20,{name,"data-autofocus":props.autoFocus,"data-testid":name,defaultValue:props.defaultValue,autoFocus:props.autoFocus,onChange:e=>props.onChange(e.currentTarget.value),placeholder:"Search value"})}}function tryParseQuantity(value){if(value){let[valueString,systemString,unitString]=value.split("|");if(valueString)return{value:parseFloat(valueString),system:systemString,unit:unitString}}}import{jsx as jsx104,jsxs as jsxs57}from"react/jsx-runtime";function SearchFilterEditor(props){let[search,setSearch]=useState54(deepClone2(props.search)),searchRef=useRef16(search);searchRef.current=search,useEffect21(()=>{setSearch(deepClone2(props.search))},[props.search]);function onAddFilter(filter){setSearch(addFilter(searchRef.current,filter.code,filter.operator,filter.value))}if(!props.visible)return null;let resourceType=props.search.resourceType,searchParams=getSearchParameters2(resourceType)??{},filters=search.filters||[];return jsx104(Modal5,{title:"Filters",closeButtonProps:{"aria-label":"Close"},size:900,opened:props.visible,onClose:props.onCancel,children:jsxs57(Form,{onSubmit:()=>props.onOk(searchRef.current),children:[jsxs57("div",{children:[jsxs57("table",{children:[jsxs57("colgroup",{children:[jsx104("col",{style:{width:200}}),jsx104("col",{style:{width:200}}),jsx104("col",{style:{width:380}}),jsx104("col",{style:{width:40}})]}),jsx104("thead",{children:jsxs57("tr",{children:[jsx104("th",{children:"Field"}),jsx104("th",{children:"Operation"}),jsx104("th",{children:"Value"}),jsx104("th",{})]})}),jsx104("tbody",{children:filters.map((filter,index)=>jsx104(FilterRowInput,{id:`filter-${index}-row`,resourceType,searchParams,value:filter,onChange:newFilter=>{let newFilters=[...filters];newFilters[index]=newFilter,setSearch(setFilters(searchRef.current,newFilters))},onDelete:()=>setSearch(deleteFilter(searchRef.current,index))},`filter-${index}-row`))})]}),jsx104(ArrayAddButton,{propertyDisplayName:"Filter",onClick:()=>onAddFilter({})})]}),jsx104(Group36,{justify:"flex-end",mt:"xl",children:jsx104(Button15,{type:"submit",children:"OK"})})]})})}function FilterRowInput(props){let value=props.value,valueRef=useRef16(value);valueRef.current=value;function setFilterCode(newCode){valueRef.current.code=newCode,valueRef.current.operator=Operator2.EQUALS,valueRef.current.value="",props.onChange(valueRef.current)}function setFilterOperator(newOperator){valueRef.current.operator=newOperator,valueRef.current.value="",props.onChange(valueRef.current)}function setFilterValue(newFilterValue){valueRef.current.value=newFilterValue,props.onChange(valueRef.current)}let searchParam=props.searchParams[value.code],operators=searchParam&&getSearchOperators(searchParam);return jsxs57("tr",{children:[jsx104("td",{children:jsx104(NativeSelect10,{"data-testid":`${props.id}-filter-field`,defaultValue:props.value.code,onChange:e=>setFilterCode(e.currentTarget.value),data:["",...Object.keys(props.searchParams).map(param=>({value:param,label:buildFieldNameString(param)}))]})}),jsx104("td",{children:operators&&jsx104(NativeSelect10,{"data-testid":`${props.id}-filter-operation`,defaultValue:value.operator,onChange:e=>setFilterOperator(e.currentTarget.value),data:["",...operators.map(op=>({value:op,label:getOpString(op)}))]})}),jsx104("td",{children:searchParam&&value.operator&&jsx104(SearchFilterValueInput,{name:`${props.id}-filter-value`,resourceType:props.resourceType,searchParam,defaultValue:value.value,onChange:setFilterValue})}),jsx104("td",{children:props.onDelete&&jsx104(ActionIcon10,{variant:"outline",color:"red",radius:"xl","aria-label":"Delete filter",onClick:props.onDelete,children:jsx104(IconX,{style:{width:"70%",height:"70%"},stroke:1.5})})})]})}import{Button as Button16,Grid,Modal as Modal6}from"@mantine/core";import{useState as useState55}from"react";import{jsx as jsx105,jsxs as jsxs58}from"react/jsx-runtime";function SearchFilterValueDialog(props){let[value,setValue]=useState55(props.defaultValue??"");if(!props.visible||!props.searchParam||!props.filter)return null;function onOk(){props.onOk({...props.filter,value})}return jsx105(Modal6,{title:props.title,size:"xl",opened:props.visible,onClose:props.onCancel,children:jsx105(Form,{onSubmit:onOk,children:jsxs58(Grid,{children:[jsx105(Grid.Col,{span:10,children:jsx105(SearchFilterValueInput,{resourceType:props.resourceType,searchParam:props.searchParam,defaultValue:value,autoFocus:!0,onChange:setValue})}),jsx105(Grid.Col,{span:2,children:jsx105(Button16,{onClick:onOk,fullWidth:!0,children:"OK"})})]})})})}import{formatDateTime as formatDateTime5,getSearchParameterDetails as getSearchParameterDetails3,globalSchema,Operator as Operator3,SearchParameterType as SearchParameterType2}from"@medplum/core";import{Fragment as Fragment30,jsx as jsx106}from"react/jsx-runtime";function SearchFilterValueDisplay(props){let{resourceType,filter}=props,searchParam=globalSchema.types[resourceType].searchParams?.[filter.code];if(searchParam){if(searchParam.type==="reference"&&(filter.operator===Operator3.EQUALS||filter.operator===Operator3.NOT_EQUALS))return jsx106(ResourceName,{value:{reference:filter.value}});let searchParamDetails=getSearchParameterDetails3(resourceType,searchParam);if(filter.code==="_lastUpdated"||searchParamDetails.type===SearchParameterType2.DATETIME)return jsx106(Fragment30,{children:formatDateTime5(filter.value)})}return jsx106(Fragment30,{children:filter.value})}import{Menu as Menu4}from"@mantine/core";import{Operator as Operator4}from"@medplum/core";import{Fragment as Fragment31,jsx as jsx107,jsxs as jsxs59}from"react/jsx-runtime";function SearchPopupMenu(props){if(!props.searchParams)return null;function onSort(searchParam,desc){onChange(setSort(props.search,searchParam.code,desc))}function onClear(searchParam){onChange(clearFiltersOnField(props.search,searchParam.code))}function onPrompt(searchParam,operator){props.onPrompt(searchParam,{code:searchParam.code,operator,value:""})}function onChange(definition){props.onChange(definition)}return props.searchParams.length===1?jsx107(SearchParameterSubMenu,{search:props.search,searchParam:props.searchParams[0],onSort,onPrompt,onChange,onClear}):jsx107(Menu4.Dropdown,{children:props.searchParams.map(searchParam=>jsx107(Menu4.Item,{children:buildFieldNameString(searchParam.code)},searchParam.code))})}function SearchParameterSubMenu(props){switch(props.searchParam.type){case"date":return jsx107(DateFilterSubMenu,{...props});case"number":case"quantity":return jsx107(NumericFilterSubMenu,{...props});case"reference":return jsx107(ReferenceFilterSubMenu,{...props});case"string":return jsx107(TextFilterSubMenu,{...props});case"token":case"uri":return jsx107(TokenFilterSubMenu,{...props});default:return jsxs59(Fragment31,{children:["Unknown search param type: ",props.searchParam.type]})}}function DateFilterSubMenu(props){let{searchParam}=props,code=searchParam.code;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconSortAscending,{size:14}),onClick:()=>props.onSort(searchParam,!1),children:"Sort Oldest to Newest"}),jsx107(Menu4.Item,{leftSection:jsx107(IconSortDescending,{size:14}),onClick:()=>props.onSort(searchParam,!0),children:"Sort Newest to Oldest"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT_EQUALS),children:"Does not equal..."}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconMathLower,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.ENDS_BEFORE),children:"Before..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconMathGreater,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.STARTS_AFTER),children:"After..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconBracketsContain,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Between..."}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addTomorrowFilter(props.search,code)),children:"Tomorrow"}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addTodayFilter(props.search,code)),children:"Today"}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addYesterdayFilter(props.search,code)),children:"Yesterday"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addNextMonthFilter(props.search,code)),children:"Next Month"}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addThisMonthFilter(props.search,code)),children:"This Month"}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addLastMonthFilter(props.search,code)),children:"Last Month"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconCalendar,{size:14}),onClick:()=>props.onChange(addYearToDateFilter(props.search,code)),children:"Year to date"}),jsx107(CommonMenuItems,{...props})]})}function NumericFilterSubMenu(props){let{searchParam}=props;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconSortAscending,{size:14}),onClick:()=>props.onSort(searchParam,!1),children:"Sort Smallest to Largest"}),jsx107(Menu4.Item,{leftSection:jsx107(IconSortDescending,{size:14}),onClick:()=>props.onSort(searchParam,!0),children:"Sort Largest to Smallest"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT_EQUALS),children:"Does not equal..."}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconMathGreater,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.GREATER_THAN),children:"Greater than..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconSettings,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.GREATER_THAN_OR_EQUALS),children:"Greater than or equal to..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconMathLower,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.LESS_THAN),children:"Less than..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconSettings,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.LESS_THAN_OR_EQUALS),children:"Less than or equal to..."}),jsx107(CommonMenuItems,{...props})]})}function ReferenceFilterSubMenu(props){let{searchParam}=props;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT),children:"Does not equal..."}),jsx107(CommonMenuItems,{...props})]})}function TextFilterSubMenu(props){let{searchParam}=props;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconSortAscending,{size:14}),onClick:()=>props.onSort(searchParam,!1),children:"Sort A to Z"}),jsx107(Menu4.Item,{leftSection:jsx107(IconSortDescending,{size:14}),onClick:()=>props.onSort(searchParam,!0),children:"Sort Z to A"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT),children:"Does not equal..."}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconBucket,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.CONTAINS),children:"Contains..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconBucketOff,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Does not contain..."}),jsx107(CommonMenuItems,{...props})]})}function TokenFilterSubMenu(props){let{searchParam}=props;return jsxs59(Menu4.Dropdown,{children:[jsx107(Menu4.Item,{leftSection:jsx107(IconEqual,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.EQUALS),children:"Equals..."}),jsx107(Menu4.Item,{leftSection:jsx107(IconEqualNot,{size:14}),onClick:()=>props.onPrompt(searchParam,Operator4.NOT),children:"Does not equal..."}),jsx107(CommonMenuItems,{...props})]})}function CommonMenuItems(props){let{searchParam}=props,code=searchParam.code;return jsxs59(Fragment31,{children:[jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconBleach,{size:14}),onClick:()=>props.onChange(addMissingFilter(props.search,code)),children:"Missing"}),jsx107(Menu4.Item,{leftSection:jsx107(IconBleachOff,{size:14}),onClick:()=>props.onChange(addMissingFilter(props.search,code,!1)),children:"Not missing"}),jsx107(Menu4.Divider,{}),jsx107(Menu4.Item,{leftSection:jsx107(IconX,{size:14}),onClick:()=>props.onClear(searchParam),children:"Clear filters"})]})}var SearchControl_default={root:"SearchControl_root",table:"SearchControl_table",tr:"SearchControl_tr",th:"SearchControl_th",control:"SearchControl_control",icon:"SearchControl_icon"};import{getElementDefinition,getSearchParameter,getSearchParameterDetails as getSearchParameterDetails4,getSearchParameters as getSearchParameters3}from"@medplum/core";function getFieldDefinitions(search){let resourceType=search.resourceType,fields=[];for(let name of search.fields||["id","_lastUpdated"])fields.push(getFieldDefinition(resourceType,name));return fields}function getFieldDefinition(resourceType,name){if(name==="_lastUpdated")return{name:"_lastUpdated",searchParams:[{resourceType:"SearchParameter",base:["Resource"],code:"_lastUpdated",name:"_lastUpdated",type:"date",expression:"Resource.meta.lastUpdated"}]};if(name==="meta.versionId")return{name:"meta.versionId",searchParams:[{resourceType:"SearchParameter",base:["Resource"],code:"_versionId",name:"_versionId",type:"token",expression:"Resource.meta.versionId"}]};let exactElementDefinition=getElementDefinition(resourceType,name),exactSearchParam=getSearchParameter(resourceType,name.toLowerCase());if(exactElementDefinition&&exactSearchParam)return{name,elementDefinition:exactElementDefinition,searchParams:[exactSearchParam]};if(exactElementDefinition){let allSearchParams=getSearchParameters3(resourceType),searchParams;if(allSearchParams){let pathRegex=new RegExp(`${resourceType}\\.${name.replaceAll("[x]","")}([^\\w-]|$)`);searchParams=Object.values(allSearchParams).filter(p=>!!p.expression&&pathRegex.test(p?.expression)),searchParams.length===0&&(searchParams=void 0)}return{name,elementDefinition:exactElementDefinition,searchParams}}if(exactSearchParam){let details=getSearchParameterDetails4(resourceType,exactSearchParam);return{name,elementDefinition:details.elementDefinitions?.[0],searchParams:[exactSearchParam]}}return{name}}import{Fragment as Fragment32,jsx as jsx108,jsxs as jsxs60}from"react/jsx-runtime";var SearchChangeEvent=class extends Event{constructor(definition){super("change"),this.definition=definition}},SearchLoadEvent=class extends Event{constructor(response){super("load"),this.response=response}},SearchClickEvent=class extends Event{constructor(resource,browserEvent){super("click"),this.resource=resource,this.browserEvent=browserEvent}};function SearchControl(props){let medplum=useMedplum26(),[outcome,setOutcome]=useState56(),{search,onLoad}=props,[memoizedSearch,setMemoizedSearch]=useState56(search);deepEquals(search,memoizedSearch)||setMemoizedSearch(search);let[state,setState]=useState56({selected:{},fieldEditorVisible:!1,filterEditorVisible:!1,exportDialogVisible:!1,filterDialogVisible:!1}),stateRef=useRef17(state);stateRef.current=state;let total=memoizedSearch.total??"accurate",loadResults=useCallback13(options=>{setOutcome(void 0),medplum.requestSchema(memoizedSearch.resourceType).then(()=>medplum.search(memoizedSearch.resourceType,formatSearchQuery({...memoizedSearch,total,fields:void 0}),options)).then(response=>{setState({...stateRef.current,searchResponse:response}),onLoad&&onLoad(new SearchLoadEvent(response))}).catch(reason=>{setState({...stateRef.current,searchResponse:void 0}),setOutcome(normalizeOperationOutcome7(reason))})},[medplum,memoizedSearch,total,onLoad]),refreshResults=useCallback13(()=>{setState({...stateRef.current,searchResponse:void 0}),loadResults({cache:"reload"})},[loadResults]);useEffect22(()=>{loadResults()},[loadResults]);function handleSingleCheckboxClick(e,id){e.stopPropagation();let checked=e.target.checked,newSelected={...stateRef.current.selected};checked?newSelected[id]=!0:delete newSelected[id],setState({...stateRef.current,selected:newSelected})}function handleAllCheckboxClick(e){e.stopPropagation();let checked=e.target.checked,newSelected={},searchResponse=stateRef.current.searchResponse;checked&&searchResponse?.entry&&searchResponse.entry.forEach(entry=>{entry.resource?.id&&(newSelected[entry.resource.id]=!0)}),setState({...stateRef.current,selected:newSelected})}function isAllSelected(){let state2=stateRef.current;if(!state2.searchResponse?.entry||state2.searchResponse.entry.length===0)return!1;for(let e of state2.searchResponse.entry)if(e.resource?.id&&!state2.selected[e.resource.id])return!1;return!0}function emitSearchChange(newSearch){props.onChange&&props.onChange(new SearchChangeEvent(newSearch))}function handleRowClick(e,resource){if(isCheckboxCell(e.target)||e.button===2)return;killEvent(e);let isAux=e.button===1||e.ctrlKey||e.metaKey;!isAux&&props.onClick&&props.onClick(new SearchClickEvent(resource,e)),isAux&&props.onAuxClick&&props.onAuxClick(new SearchClickEvent(resource,e))}function isExportPassed(){return!!(props.onExport??props.onExportCsv??props.onExportTransactionBundle)}if(outcome)return jsx108(OperationOutcomeAlert,{outcome});if(!isDataTypeLoaded(memoizedSearch.resourceType))return jsx108(Center8,{style:{width:"100%",height:"100%"},children:jsx108(Loader4,{})});let checkboxColumn=props.checkboxesEnabled,fields=getFieldDefinitions(memoizedSearch),resourceType=memoizedSearch.resourceType,lastResult=state.searchResponse,resources=lastResult?.entry?.map(e=>e.resource),buttonVariant="subtle",buttonColor="gray",iconSize=16,isMobile=window.innerWidth<768;return jsxs60("div",{className:SearchControl_default.root,"data-testid":"search-control",children:[!props.hideToolbar&&jsxs60(Group37,{justify:"space-between",mb:"xl",children:[jsxs60(Group37,{gap:2,children:[jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconColumns,{size:iconSize}),onClick:()=>setState({...stateRef.current,fieldEditorVisible:!0}),children:"Fields"}),jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconFilter,{size:iconSize}),onClick:()=>setState({...stateRef.current,filterEditorVisible:!0}),children:"Filters"}),props.onNew&&jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconFilePlus,{size:iconSize}),onClick:props.onNew,children:"New..."}),!isMobile&&isExportPassed()&&jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconTableExport,{size:iconSize}),onClick:props.onExport?props.onExport:()=>setState({...stateRef.current,exportDialogVisible:!0}),children:"Export..."}),!isMobile&&props.onDelete&&jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconTrash,{size:iconSize}),onClick:()=>props.onDelete(Object.keys(state.selected)),children:"Delete..."}),!isMobile&&props.onBulk&&jsx108(Button17,{size:"compact-md",variant:buttonVariant,color:buttonColor,leftSection:jsx108(IconBoxMultiple,{size:iconSize}),onClick:()=>props.onBulk(Object.keys(state.selected)),children:"Bulk..."})]}),jsxs60(Group37,{gap:2,children:[lastResult&&jsxs60(Text16,{size:"xs",c:"dimmed","data-testid":"count-display",children:[getStart(memoizedSearch,lastResult).toLocaleString(),"-",getEnd(memoizedSearch,lastResult).toLocaleString(),lastResult.total!==void 0&&` of ${memoizedSearch.total==="estimate"?"~":""}${lastResult.total?.toLocaleString()}`]}),jsx108(ActionIcon11,{variant:buttonVariant,color:buttonColor,title:"Refresh",onClick:refreshResults,children:jsx108(IconRefresh,{size:iconSize})})]})]}),jsxs60(Table3,{className:SearchControl_default.table,children:[jsxs60(Table3.Thead,{children:[jsxs60(Table3.Tr,{children:[checkboxColumn&&jsx108(Table3.Th,{children:jsx108("input",{type:"checkbox",value:"checked","aria-label":"all-checkbox","data-testid":"all-checkbox",checked:isAllSelected(),onChange:e=>handleAllCheckboxClick(e)})}),fields.map(field=>jsx108(Table3.Th,{children:jsxs60(Menu5,{shadow:"md",width:240,position:"bottom-end",children:[jsx108(Menu5.Target,{children:jsx108(UnstyledButton2,{className:SearchControl_default.control,p:2,children:jsxs60(Group37,{justify:"space-between",wrap:"nowrap",children:[jsx108(Text16,{fw:500,children:buildFieldNameString(field.name)}),jsx108(Center8,{className:SearchControl_default.icon,children:jsx108(IconAdjustmentsHorizontal,{size:14,stroke:1.5})})]})})}),jsx108(SearchPopupMenu,{search:memoizedSearch,searchParams:field.searchParams,onPrompt:(searchParam,filter)=>{setState({...stateRef.current,filterDialogVisible:!0,filterDialogSearchParam:searchParam,filterDialogFilter:filter})},onChange:result=>{emitSearchChange(result)}})]})},field.name))]}),!props.hideFilters&&jsxs60(Table3.Tr,{children:[checkboxColumn&&jsx108(Table3.Th,{}),fields.map(field=>jsx108(Table3.Th,{children:field.searchParams&&jsx108(FilterDescription,{resourceType,searchParams:field.searchParams,filters:memoizedSearch.filters})},field.name))]})]}),jsx108(Table3.Tbody,{children:resources?.map(resource=>resource&&jsxs60(Table3.Tr,{className:SearchControl_default.tr,"data-testid":"search-control-row",onClick:e=>handleRowClick(e,resource),onAuxClick:e=>handleRowClick(e,resource),children:[checkboxColumn&&jsx108(Table3.Td,{children:jsx108("input",{type:"checkbox",value:"checked","data-testid":"row-checkbox","aria-label":`Checkbox for ${resource.id}`,checked:!!state.selected[resource.id],onChange:e=>handleSingleCheckboxClick(e,resource.id)})}),fields.map(field=>jsx108(Table3.Td,{children:renderValue(resource,field)},field.name))]},resource.id))})]}),!resources?.length&&jsx108(Container,{children:jsx108(Center8,{style:{height:150},children:jsx108(Text16,{size:"xl",c:"dimmed",children:"No results"})})}),lastResult&&jsx108(Center8,{m:"md",p:"md",children:jsx108(Pagination,{value:getPage(memoizedSearch),total:getTotalPages(memoizedSearch,lastResult),onChange:newPage=>emitSearchChange(setPage(memoizedSearch,newPage)),getControlProps:control=>{switch(control){case"previous":return{"aria-label":"Previous page"};case"next":return{"aria-label":"Next page"};default:return{}}}})}),jsx108(SearchFieldEditor,{search:memoizedSearch,visible:stateRef.current.fieldEditorVisible,onOk:result=>{emitSearchChange(result),setState({...stateRef.current,fieldEditorVisible:!1})},onCancel:()=>{setState({...stateRef.current,fieldEditorVisible:!1})}}),jsx108(SearchFilterEditor,{search:memoizedSearch,visible:stateRef.current.filterEditorVisible,onOk:result=>{emitSearchChange(result),setState({...stateRef.current,filterEditorVisible:!1})},onCancel:()=>{setState({...stateRef.current,filterEditorVisible:!1})}}),jsx108(SearchExportDialog,{visible:stateRef.current.exportDialogVisible,exportCsv:props.onExportCsv,exportTransactionBundle:props.onExportTransactionBundle,onCancel:()=>{setState({...stateRef.current,exportDialogVisible:!1})}}),jsx108(SearchFilterValueDialog,{visible:stateRef.current.filterDialogVisible,title:state.filterDialogSearchParam?.code?buildFieldNameString(state.filterDialogSearchParam.code):"",resourceType,searchParam:state.filterDialogSearchParam,filter:state.filterDialogFilter,defaultValue:"",onOk:filter=>{emitSearchChange(addFilter(memoizedSearch,filter.code,filter.operator,filter.value)),setState({...stateRef.current,filterDialogVisible:!1})},onCancel:()=>{setState({...stateRef.current,filterDialogVisible:!1})}},state.filterDialogSearchParam?.code)]})}var MemoizedSearchControl=SearchControl;function FilterDescription(props){let filters=(props.filters??[]).filter(f=>props.searchParams.find(p=>p.code===f.code));return filters.length===0?jsx108("span",{children:"no filters"}):jsx108(Fragment32,{children:filters.map(filter=>jsxs60("div",{children:[getOpString(filter.operator),"\xA0",jsx108(SearchFilterValueDisplay,{resourceType:props.resourceType,filter})]},`filter-${filter.code}-${filter.operator}-${filter.value}`))})}function getPage(search){return Math.floor((search.offset??0)/(search.count??DEFAULT_SEARCH_COUNT2))+1}function getTotalPages(search,lastResult){let pageSize=search.count??DEFAULT_SEARCH_COUNT2,total=getTotal(search,lastResult);return Math.ceil(total/pageSize)}function getStart(search,lastResult){return Math.min(getTotal(search,lastResult),(search.offset??0)+1)}function getEnd(search,lastResult){return Math.max(getStart(search,lastResult)+(lastResult.entry?.length??0)-1,0)}function getTotal(search,lastResult){let total=lastResult.total;return total===void 0&&(total=(search.offset??0)+(lastResult.entry?.length??0)+(lastResult.link?.some(l=>l.relation==="next")?1:0)),total}import{jsx as jsx109,jsxs as jsxs61}from"react/jsx-runtime";function FhirPathTable(props){let medplum=useMedplum27(),[schemaLoaded,setSchemaLoaded]=useState57(!1),[outcome,setOutcome]=useState57(),{query,fields}=props,[response,setResponse]=useState57(),[selected,setSelected]=useState57({}),responseRef=useRef18();responseRef.current=response;let selectedRef=useRef18({});selectedRef.current=selected,useEffect23(()=>{setOutcome(void 0),medplum.graphql(query).then(setResponse).catch(err=>setOutcome(normalizeOperationOutcome8(err)))},[medplum,query]);function handleSingleCheckboxClick(e,id){e.stopPropagation();let checked=e.target.checked,newSelected={...selectedRef.current};checked?newSelected[id]=!0:delete newSelected[id],setSelected(newSelected)}function handleAllCheckboxClick(e){e.stopPropagation();let checked=e.target.checked,newSelected={},resources=responseRef.current?.data.ResourceList;checked&&resources&&resources.forEach(resource=>{resource.id&&(newSelected[resource.id]=!0)}),setSelected(newSelected)}function isAllSelected(){let resources=responseRef.current?.data.ResourceList;if(!resources||resources.length===0)return!1;for(let resource of resources)if(resource.id&&!selectedRef.current[resource.id])return!1;return!0}function handleRowClick(e,resource){isCheckboxCell(e.target)||(killEvent(e),e.button!==1&&props.onClick&&props.onClick(new SearchClickEvent(resource,e)),e.button===1&&props.onAuxClick&&props.onAuxClick(new SearchClickEvent(resource,e)))}if(useEffect23(()=>{medplum.requestSchema(props.resourceType).then(()=>setSchemaLoaded(!0)).catch(console.log)},[medplum,props.resourceType]),!schemaLoaded)return jsx109(Loader5,{});let checkboxColumn=props.checkboxesEnabled;return jsxs61("div",{onContextMenu:e=>killEvent(e),"data-testid":"search-control",children:[jsxs61(Table4,{children:[jsx109(Table4.Thead,{children:jsxs61(Table4.Tr,{children:[checkboxColumn&&jsx109(Table4.Th,{children:jsx109("input",{type:"checkbox",value:"checked","aria-label":"all-checkbox","data-testid":"all-checkbox",checked:isAllSelected(),onChange:e=>handleAllCheckboxClick(e)})}),fields.map(field=>jsx109(Table4.Th,{children:field.name},field.name))]})}),jsx109(Table4.Tbody,{children:response?.data.ResourceList.map(resource=>resource&&jsxs61(Table4.Tr,{"data-testid":"search-control-row",onClick:e=>handleRowClick(e,resource),onAuxClick:e=>handleRowClick(e,resource),children:[checkboxColumn&&jsx109(Table4.Td,{children:jsx109("input",{type:"checkbox",value:"checked","data-testid":"row-checkbox","aria-label":`Checkbox for ${resource.id}`,checked:!!selected[resource.id],onChange:e=>handleSingleCheckboxClick(e,resource.id)})}),fields.map(field=>jsx109(Table4.Td,{children:jsx109(FhirPathDisplay,{propertyType:field.propertyType,path:field.fhirPath,resource})},field.name))]},resource.id))})]}),response?.data.ResourceList.length===0&&jsx109("div",{"data-testid":"empty-search",children:"No results"}),outcome&&jsx109("div",{"data-testid":"search-error",children:jsx109("pre",{style:{textAlign:"left"},children:JSON.stringify(outcome,void 0,2)})}),props.onBulk&&jsx109(Button18,{onClick:()=>props.onBulk(Object.keys(selectedRef.current)),children:"Bulk..."})]})}var MemoizedFhirPathTable=memo(FhirPathTable);import{Box as Box4,SimpleGrid}from"@mantine/core";import{useResource as useResource8,useSearchOne}from"@medplum/react-hooks";import{Box as Box3,Flex as Flex3,Group as Group38,Paper as Paper3,RingProgress,Text as Text17,Title as Title7}from"@mantine/core";import{formatCodeableConcept as formatCodeableConcept4}from"@medplum/core";import{Fragment as Fragment33,jsx as jsx110,jsxs as jsxs62}from"react/jsx-runtime";function MeasureReportGroupDisplay(props){let{group}=props;return jsx110(Paper3,{withBorder:!0,radius:"md",p:"xs",display:"flex",style:{alignItems:"center",justifyContent:"center"},children:jsxs62(Group38,{children:[group.measureScore&&jsx110(MeasureScore,{group}),!group.measureScore&&jsx110(MeasureReportPopulation,{group})]})})}function MeasureTitle(props){let{measure}=props;return jsxs62(Fragment33,{children:[jsx110(Text17,{fz:"md",fw:500,mb:8,children:measure.title}),jsx110(Text17,{fz:"xs",c:"dimmed",mb:8,children:measure.subtitle})]})}function MeasureReportPopulation(props){let{group}=props,populations=group.population,numerator=populations?.find(p=>formatCodeableConcept4(p.code)==="numerator"),denominator=populations?.find(p=>formatCodeableConcept4(p.code)==="denominator"),numeratorCount=numerator?.count,denominatorCount=denominator?.count;if(denominatorCount===0)return jsxs62(Box3,{children:[jsx110(Title7,{order:3,children:"Not Applicable"}),jsx110(Text17,{children:`Denominator: ${denominatorCount}`})]});if(numeratorCount===void 0||denominatorCount===void 0)return jsxs62(Box3,{children:[jsx110(Title7,{order:3,children:"Insufficient Data"}),jsx110(Text17,{children:`Numerator: ${numeratorCount}`}),jsx110(Text17,{children:`Denominator: ${denominatorCount}`})]});let value=numeratorCount/denominatorCount*100;return jsx110(RingProgress,{size:120,thickness:12,roundCaps:!0,sections:[{value,color:groupColor(value)}],label:jsx110(Flex3,{justify:"center",children:jsxs62(Text17,{fw:700,fz:18,children:[numeratorCount," / ",denominatorCount]})})})}function MeasureScore(props){let{group}=props,unit=group.measureScore?.unit??group.measureScore?.code;return jsx110(Fragment33,{children:unit==="%"?jsx110(RingProgress,{size:120,thickness:12,roundCaps:!0,sections:[{value:groupValue(group),color:groupColor(group?.measureScore?.value??0)}],label:jsx110(Flex3,{justify:"center",children:jsx110(Text17,{fw:700,fz:18,children:jsx110(QuantityDisplay,{value:group.measureScore})})})}):jsx110(Flex3,{h:120,align:"center",children:jsx110(Title7,{order:3,children:jsx110(QuantityDisplay,{value:group.measureScore})})})})}function groupValue(group){let score=group.measureScore?.value,unit=group.measureScore?.unit;return score?score<=1&&unit==="%"?score*100:score:0}function groupColor(score){return score<=33?"red":score<=67?"yellow":"green"}import{jsx as jsx111,jsxs as jsxs63}from"react/jsx-runtime";function MeasureReportDisplay(props){let report=useResource8(props.measureReport),[measure]=useSearchOne("Measure",{url:report?.measure});return report?jsxs63(Box4,{children:[measure&&jsx111(MeasureTitle,{measure}),jsx111(SimpleGrid,{cols:{base:3,sm:1},spacing:{base:"md",sm:"sm"},children:report.group?.map((group,idx)=>jsx111(MeasureReportGroupDisplay,{group},group.id??idx))})]}):null}import{ActionIcon as ActionIcon12,Indicator,Tooltip as Tooltip3}from"@mantine/core";import{useMedplum as useMedplum28,useSubscription as useSubscription2}from"@medplum/react-hooks";import{useCallback as useCallback14,useEffect as useEffect24,useState as useState58}from"react";import{jsx as jsx112}from"react/jsx-runtime";function NotificationIcon(props){let medplum=useMedplum28(),{label,resourceType,countCriteria,subscriptionCriteria,onClick}=props,[unreadCount,setUnreadCount]=useState58(0),updateCount=useCallback14(cache=>{medplum.search(resourceType,countCriteria,{cache}).then(result=>setUnreadCount(result.total)).catch(console.error)},[medplum,resourceType,countCriteria]);useEffect24(()=>{updateCount("default")},[updateCount]),useSubscription2(subscriptionCriteria,()=>{updateCount("reload")});let icon=jsx112(Tooltip3,{label,children:jsx112(ActionIcon12,{variant:"subtle",color:"gray",size:"lg","aria-label":label,onClick,children:props.iconComponent})});return unreadCount>0?jsx112(Indicator,{inline:!0,label:unreadCount.toLocaleString(),size:16,offset:2,position:"bottom-end",color:"red",children:icon}):icon}import{Button as Button19,Group as Group39,SegmentedControl as SegmentedControl2,Stack as Stack17}from"@mantine/core";import{notifications}from"@mantine/notifications";import{ContentType as ContentType2,normalizeErrorString as normalizeErrorString9,resolveId}from"@medplum/core";import{useMedplum as useMedplum29}from"@medplum/react-hooks";import{useCallback as useCallback15}from"react";import{jsx as jsx113,jsxs as jsxs64}from"react/jsx-runtime";var NOTIFICATION_ID="patient-export",NOTIFICATION_TITLE="Patient Export",formats={everything:{operation:"$everything",extension:"json",contentType:ContentType2.FHIR_JSON},summary:{operation:"$summary",extension:"json",contentType:ContentType2.FHIR_JSON},ccda:{operation:"$ccda-export",extension:"xml",contentType:ContentType2.CDA_XML}};function PatientExportForm(props){let medplum=useMedplum29(),{patient}=props,handleSubmit=useCallback15(async data2=>{let patientId=resolveId(patient),format=data2.format,{operation,contentType,extension}=formats[format],url=medplum.fhirUrl("Patient",patientId,operation);data2.startDate&&url.searchParams.append("start",data2.startDate),data2.endDate&&url.searchParams.append("end",data2.endDate),notifications.show({id:NOTIFICATION_ID,title:NOTIFICATION_TITLE,loading:!0,message:"Exporting...",autoClose:!1,withCloseButton:!1});try{let response=await medplum.get(url,{cache:"no-cache",headers:{Accept:contentType}}),fileName=`Patient-export-${patientId}-${new Date().toISOString().replaceAll(":","-")}.${extension}`;saveData(response,fileName,contentType),notifications.update({id:NOTIFICATION_ID,title:NOTIFICATION_TITLE,color:"green",message:"Done",icon:jsx113(IconCheck,{size:"1rem"}),loading:!1,autoClose:!1,withCloseButton:!0})}catch(err){notifications.update({id:NOTIFICATION_ID,title:NOTIFICATION_TITLE,color:"red",message:normalizeErrorString9(err),icon:jsx113(IconX,{size:"1rem"}),loading:!1,autoClose:!1,withCloseButton:!0})}},[medplum,patient]);return jsx113(Form,{onSubmit:handleSubmit,children:jsxs64(Stack17,{children:[jsx113(FormSection,{title:"Export Format",description:"Required",withAsterisk:!0,children:jsx113(SegmentedControl2,{name:"format",data:[{label:"FHIR Everything",value:"everything"},{label:"Patient Summary",value:"summary"},{label:"C-CDA",value:"ccda"}],fullWidth:!0})}),jsx113(FormSection,{title:"Start Date",description:"If no start date is provided, all records prior to the end date are in scope.",children:jsx113(DateTimeInput,{name:"startDate",placeholder:"Start date"})}),jsx113(FormSection,{title:"End Date",description:"If no end date is provided, all records subsequent to the start date are in scope.",children:jsx113(DateTimeInput,{name:"endDate",placeholder:"End date"})}),jsx113(Group39,{justify:"right",children:jsx113(Button19,{type:"submit",children:"Request Export"})})]})})}function saveData(data2,fileName,contentType){let content=typeof data2=="string"?data2:JSON.stringify(data2,null,2),blob=new Blob([content],{type:contentType}),url=window.URL.createObjectURL(blob),a=document.createElement("a");document.body.appendChild(a),a.style.display="none",a.href=url,a.download=fileName,a.click(),window.URL.revokeObjectURL(url)}import{Card,Divider as Divider3,Flex as Flex4,Group as Group49,Paper as Paper4,Stack as Stack23,Text as Text24}from"@mantine/core";import{calculateAgeString,formatHumanName as formatHumanName4,resolveId as resolveId2}from"@medplum/core";import{useMedplum as useMedplum36,useResource as useResource9}from"@medplum/react-hooks";import{useEffect as useEffect25,useMemo as useMemo29,useState as useState68}from"react";import{Anchor as Anchor6,Box as Box5,Group as Group41,Modal as Modal7,Text as Text18}from"@mantine/core";import{useDisclosure}from"@mantine/hooks";import{useMedplum as useMedplum30}from"@medplum/react-hooks";import{useCallback as useCallback17,useState as useState60}from"react";import{Button as Button20,Group as Group40,Stack as Stack18,TextInput as TextInput21}from"@mantine/core";import{HTTP_HL7_ORG as HTTP_HL7_ORG2,addProfileToResource,createReference as createReference6}from"@medplum/core";import{useCallback as useCallback16,useState as useState59}from"react";import{jsx as jsx114,jsxs as jsxs65}from"react/jsx-runtime";var HTTP="http://",PATIENT_ALLERGY_PROFILE=HTTP_HL7_ORG2+"/fhir/us/core/StructureDefinition/us-core-allergyintolerance";function AllergyDialog(props){let{patient,encounter,allergy,onSubmit}=props,[code,setCode]=useState59(allergy?.code),[clinicalStatus,setClinicalStatus]=useState59(allergy?.clinicalStatus),handleSubmit=useCallback16(formData=>{onSubmit(addProfileToResource({...allergy,resourceType:"AllergyIntolerance",patient:createReference6(patient),encounter:encounter?createReference6(encounter):void 0,code,clinicalStatus,onsetDateTime:formData.onsetDateTime?formData.onsetDateTime:void 0,reaction:formData.reaction?[{manifestation:[{text:formData.reaction}]}]:void 0},PATIENT_ALLERGY_PROFILE))},[patient,encounter,allergy,code,clinicalStatus,onSubmit]);return jsx114(Form,{onSubmit:handleSubmit,children:jsxs65(Stack18,{children:[jsx114(CodeableConceptInput,{name:"allergy",label:"Code",path:"AllergyIntolerance.code","data-autofocus":!0,binding:HTTP+"cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.8",maxValues:1,defaultValue:allergy?.code,onChange:code2=>setCode(code2),outcome:void 0}),jsx114(TextInput21,{name:"reaction",label:"Reaction",defaultValue:allergy?.reaction?.[0]?.manifestation?.[0]?.text}),jsx114(CodeableConceptInput,{name:"clinicalStatus",label:"Clinical Status",path:"AllergyIntolerance.clinicalStatus",binding:HTTP_HL7_ORG2+"/fhir/ValueSet/allergyintolerance-clinical",maxValues:1,defaultValue:allergy?.clinicalStatus,onChange:clinicalStatus2=>setClinicalStatus(clinicalStatus2),outcome:void 0}),jsx114(DateTimeInput,{name:"onsetDateTime",label:"Onset",defaultValue:allergy?.recordedDate}),jsx114(Group40,{justify:"flex-end",gap:4,mt:"md",children:jsx114(Button20,{type:"submit",children:"Save"})})]})},allergy?.id)}import{ActionIcon as ActionIcon13,Badge as Badge2}from"@mantine/core";import{getDisplayString as getDisplayString6}from"@medplum/core";import{jsx as jsx115}from"react/jsx-runtime";function ConceptBadge(props){let{resource,display,onClick,onEdit}=props,rightSection;return onEdit&&(rightSection=jsx115(ActionIcon13,{variant:"subtle",size:12,radius:"xl",children:jsx115(IconPencil,{"aria-label":`Edit ${getDisplayString6(resource)}`,size:12,onClick:e=>{killEvent(e),onEdit(resource)}})})),jsx115(MedplumLink,{to:onClick?void 0:resource,onClick:onClick?()=>onClick(resource):void 0,children:jsx115(Badge2,{variant:"light",maw:"100%",rightSection,style:{cursor:"pointer"},children:display??getDisplayString6(resource)})},resource.id)}import{Fragment as Fragment34,jsx as jsx116,jsxs as jsxs66}from"react/jsx-runtime";function Allergies(props){let medplum=useMedplum30(),{patient,encounter}=props,[allergies,setAllergies]=useState60(props.allergies),[opened,{open,close}]=useDisclosure(!1),[editAllergy,setEditAllergy]=useState60(),handleSubmit=useCallback17(async allergy=>{if(allergy.id){let updatedAllergy=await medplum.updateResource(allergy);setAllergies(allergies.map(a=>a.id===updatedAllergy.id?updatedAllergy:a))}else{let newAllergy=await medplum.createResource(allergy);setAllergies([...allergies,newAllergy])}setEditAllergy(void 0),close()},[medplum,allergies,close]);return jsxs66(Fragment34,{children:[jsxs66(Group41,{justify:"space-between",children:[jsx116(Text18,{fz:"md",fw:700,children:"Allergies"}),jsx116(Anchor6,{component:"button",onClick:e=>{killEvent(e),setEditAllergy(void 0),open()},children:"+ Add"})]}),allergies.length>0?jsx116(Box5,{children:allergies.map(allergy=>jsx116(ConceptBadge,{resource:allergy,onClick:props.onClickResource,onEdit:a=>{setEditAllergy(a),open()}},allergy.id))}):jsx116(Text18,{children:"(none)"}),jsx116(Modal7,{opened,onClose:close,title:editAllergy?"Edit Allergy":"Add Allergy",children:jsx116(AllergyDialog,{patient,encounter,allergy:editAllergy,onSubmit:handleSubmit})})]})}import{Anchor as Anchor7,Box as Box6,Group as Group43,Modal as Modal8,Text as Text19}from"@mantine/core";import{useDisclosure as useDisclosure2}from"@mantine/hooks";import{useMedplum as useMedplum31}from"@medplum/react-hooks";import{useCallback as useCallback19,useState as useState62}from"react";import{Alert as Alert4,Button as Button21,Group as Group42,Radio,Stack as Stack19}from"@mantine/core";import{HTTP_HL7_ORG as HTTP_HL7_ORG3,addProfileToResource as addProfileToResource2,createReference as createReference7}from"@medplum/core";import{useCallback as useCallback18,useState as useState61}from"react";import{useMedplumProfile as useMedplumProfile6}from"@medplum/react-hooks";import{jsx as jsx117,jsxs as jsxs67}from"react/jsx-runtime";var HTTP2="http://",statusValues=["active","stopped","on-hold","cancelled","completed","entered-in-error","draft","unknown"];function MedicationDialog(props){let me=useMedplumProfile6(),{patient,encounter,medication,onSubmit}=props,[code,setCode]=useState61(medication?.medicationCodeableConcept),handleSubmit=useCallback18(formData=>{if(!me)throw new Error("Not signed in");onSubmit(addProfileToResource2({...medication,resourceType:"MedicationRequest",status:formData.status,intent:medication?.intent??"order",encounter:medication?.encounter??(encounter&&createReference7(encounter)),requester:medication?.requester??createReference7(me),medicationCodeableConcept:code,subject:createReference7(patient)},HTTP_HL7_ORG3+"/fhir/us/core/StructureDefinition/us-core-medicationrequest"))},[me,onSubmit,medication,encounter,code,patient]);return me?jsx117(Form,{onSubmit:handleSubmit,children:jsxs67(Stack19,{children:[jsx117(CodeableConceptInput,{name:"request",path:"MedicationRequest.medication[x]","data-autofocus":!0,binding:HTTP2+"cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.4",maxValues:1,defaultValue:medication?.medicationCodeableConcept,onChange:request=>setCode(request),outcome:void 0}),jsx117(Radio.Group,{name:"status",label:"Request Status",required:!0,defaultValue:medication?.status,children:statusValues.map(sv=>jsx117(Radio,{value:sv,label:sv,my:"xs",required:!0},sv))}),jsx117(Group42,{justify:"flex-end",gap:4,children:jsx117(Button21,{type:"submit",children:"Save"})})]})}):jsx117(Alert4,{color:"red",children:"Not signed in"})}import{Fragment as Fragment35,jsx as jsx118,jsxs as jsxs68}from"react/jsx-runtime";function Medications(props){let medplum=useMedplum31(),[medicationRequests,setMedicationRequests]=useState62(props.medicationRequests),[editMedication,setEditMedication]=useState62(),[opened,{open,close}]=useDisclosure2(!1),handleSubmit=useCallback19(async medication=>{if(medication.id){let updatedMedication=await medplum.updateResource(medication);setMedicationRequests(medicationRequests.map(m=>m.id===updatedMedication.id?updatedMedication:m))}else{let newMedication=await medplum.createResource(medication);setMedicationRequests([newMedication,...medicationRequests])}setEditMedication(void 0),close()},[medplum,medicationRequests,close]);return jsxs68(Fragment35,{children:[jsxs68(Group43,{justify:"space-between",children:[jsx118(Text19,{fz:"md",fw:700,children:"Medications"}),jsx118(Anchor7,{component:"button",onClick:e=>{killEvent(e),setEditMedication(void 0),open()},children:"+ Add"})]}),medicationRequests.length>0?jsx118(Box6,{children:medicationRequests.map(request=>jsx118(ConceptBadge,{resource:request,onClick:props.onClickResource,onEdit:mr=>{setEditMedication(mr),open()}},request.id))}):jsx118(Text19,{children:"(none)"}),jsx118(Modal8,{opened,onClose:close,title:editMedication?"Edit Medication":"Add Medication",children:jsx118(MedicationDialog,{patient:props.patient,encounter:props.encounter,medication:editMedication,onSubmit:handleSubmit})})]})}import{Anchor as Anchor8,Grid as Grid2,Group as Group45,Modal as Modal9,Text as Text20}from"@mantine/core";import{useDisclosure as useDisclosure3}from"@mantine/hooks";import{useMedplum as useMedplum32}from"@medplum/react-hooks";import{Fragment as Fragment36,useCallback as useCallback21,useState as useState64}from"react";import{Button as Button22,Group as Group44,Stack as Stack20}from"@mantine/core";import{HTTP_HL7_ORG as HTTP_HL7_ORG4,HTTP_TERMINOLOGY_HL7_ORG,addProfileToResource as addProfileToResource3,createReference as createReference8}from"@medplum/core";import{useCallback as useCallback20,useState as useState63}from"react";import{jsx as jsx119,jsxs as jsxs69}from"react/jsx-runtime";function ConditionDialog(props){let{patient,encounter,condition,onSubmit}=props,[code,setCode]=useState63(condition?.code),[clinicalStatus,setClinicalStatus]=useState63(condition?.clinicalStatus),handleSubmit=useCallback20(formData=>{let updatedCondition=addProfileToResource3({...condition,resourceType:"Condition",category:[{coding:[{system:HTTP_TERMINOLOGY_HL7_ORG+"/CodeSystem/condition-category",code:"problem-list-item",display:"Problem List Item"}],text:"Problem List Item"}],subject:createReference8(patient),encounter:encounter&&createReference8(encounter),code,clinicalStatus,onsetDateTime:formData.onsetDateTime?convertLocalToIso(formData.onsetDateTime):void 0},HTTP_HL7_ORG4+"/fhir/us/core/StructureDefinition/us-core-condition-problems-health-concerns");onSubmit(updatedCondition)},[patient,encounter,condition,code,clinicalStatus,onSubmit]);return jsx119(Form,{onSubmit:handleSubmit,children:jsxs69(Stack20,{children:[jsx119(CodeableConceptInput,{name:"code",label:"Problem",path:"Condition.code","data-autofocus":!0,binding:HTTP_HL7_ORG4+"/fhir/us/core/ValueSet/us-core-condition-code",defaultValue:condition?.code,onChange:code2=>setCode(code2),outcome:void 0}),jsx119(CodeableConceptInput,{name:"clinicalStatus",label:"Status",path:"Condition.clinicalStatus",binding:HTTP_HL7_ORG4+"/fhir/ValueSet/condition-clinical",defaultValue:condition?.clinicalStatus,onChange:clinicalStatus2=>setClinicalStatus(clinicalStatus2),outcome:void 0}),jsx119(DateTimeInput,{name:"onsetDateTime",label:"Dx Date",defaultValue:condition?.onsetDateTime,required:!0}),jsx119(Group44,{justify:"flex-end",gap:4,mt:"md",children:jsx119(Button22,{type:"submit",children:"Save"})})]})},condition?.id)}import{Fragment as Fragment37,jsx as jsx120,jsxs as jsxs70}from"react/jsx-runtime";function ProblemList(props){let medplum=useMedplum32(),{patient,encounter}=props,[problems,setProblems]=useState64(props.problems),[editCondition,setEditCondition]=useState64(),[opened,{open,close}]=useDisclosure3(!1),handleSubmit=useCallback21(async condition=>{if(condition.id){let updatedCondition=await medplum.updateResource(condition);setProblems(problems.map(p=>p.id===updatedCondition.id?updatedCondition:p))}else{let newCondition=await medplum.createResource(condition);setProblems([...problems,newCondition])}setEditCondition(void 0),close()},[medplum,problems,close]);return jsxs70(Fragment37,{children:[jsxs70(Group45,{justify:"space-between",children:[jsx120(Text20,{fz:"md",fw:700,children:"Problem List"}),jsx120(Anchor8,{component:"button",onClick:e=>{killEvent(e),setEditCondition(void 0),open()},children:"+ Add"})]}),problems.length>0?jsx120(Grid2,{gutter:"xs",children:problems.map(problem=>jsxs70(Fragment36,{children:[jsx120(Grid2.Col,{span:2,children:problem.onsetDateTime?.substring(0,4)}),jsx120(Grid2.Col,{span:10,children:jsx120(ConceptBadge,{resource:problem,onClick:props.onClickResource,onEdit:c=>{setEditCondition(c),open()}},problem.id)})]},problem.id))}):jsx120(Text20,{children:"(none)"}),jsx120(Modal9,{opened,onClose:close,title:editCondition?"Edit Problem":"Add Problem",children:jsx120(ConditionDialog,{patient,encounter,condition:editCondition,onSubmit:handleSubmit})})]})}import{Anchor as Anchor9,Button as Button23,Group as Group46,Modal as Modal10,Radio as Radio2,Stack as Stack21,Text as Text21}from"@mantine/core";import{useDisclosure as useDisclosure4}from"@mantine/hooks";import{HTTP_HL7_ORG as HTTP_HL7_ORG5,HTTP_TERMINOLOGY_HL7_ORG as HTTP_TERMINOLOGY_HL7_ORG2,LOINC,SNOMED,createReference as createReference9,formatCodeableConcept as formatCodeableConcept5}from"@medplum/core";import{useMedplum as useMedplum33}from"@medplum/react-hooks";import{useCallback as useCallback22,useState as useState65}from"react";import{Fragment as Fragment38,jsx as jsx121,jsxs as jsxs71}from"react/jsx-runtime";var NULLFLAVOR=HTTP_TERMINOLOGY_HL7_ORG2+"/CodeSystem/v3-NullFlavor",CodesToText={38628009:"Homosexual",20430005:"Heterosexual",42035005:"Bisexual",OTH:"Other",UNK:"Unknown",ASKU:"Asked but no answer"},CodesToSystem={38628009:SNOMED,20430005:SNOMED,42035005:SNOMED,OTH:NULLFLAVOR,UNK:NULLFLAVOR,ASKU:NULLFLAVOR};function SexualOrientation(props){let medplum=useMedplum33(),{patient,encounter}=props,[sexualOrientation,setSexualOrientation]=useState65(props.sexualOrientation),[opened,{open,close}]=useDisclosure4(!1),handleSubmit=useCallback22(formData=>{let code=formData.sexualOrientation;medplum.createResource({resourceType:"Observation",meta:{profile:[HTTP_HL7_ORG5+"/fhir/us/core/ValueSet/us-core-sexual-orientation"]},status:"final",category:[{coding:[{system:HTTP_TERMINOLOGY_HL7_ORG2+"/CodeSystem/observation-category",code:"social-history",display:"Social History"}],text:"Social History"}],code:{coding:[{system:LOINC,code:"76690-7",display:"Sexual orientation"}],text:"Sexual orientation"},subject:createReference9(patient),encounter:encounter?createReference9(encounter):void 0,effectiveDateTime:new Date().toISOString(),valueCodeableConcept:{coding:[{system:CodesToSystem[code],code:formData.sexualOrientation}],text:CodesToText[code]}}).then(newSexualOrientation=>{setSexualOrientation(newSexualOrientation),close()}).catch(console.error)},[medplum,patient,encounter,close]);return jsxs71(Fragment38,{children:[jsxs71(Group46,{justify:"space-between",children:[jsx121(Text21,{fz:"md",fw:700,children:"Sexual Orientation"}),jsx121(Anchor9,{href:"#",onClick:e=>{killEvent(e),open()},children:"+ Edit"})]}),sexualOrientation?.valueCodeableConcept?jsx121(ConceptBadge,{resource:sexualOrientation,display:formatCodeableConcept5(sexualOrientation.valueCodeableConcept),onClick:props.onClickResource,onEdit:()=>open()},sexualOrientation.id):jsx121(Text21,{children:"(none)"}),jsx121(Modal10,{opened,onClose:close,title:"Set Sexual Orientation",children:jsx121(Form,{onSubmit:handleSubmit,children:jsxs71(Stack21,{children:[jsx121(Radio2.Group,{name:"sexualOrientation",label:"Sexual Orientation",required:!0,children:Object.entries(CodesToText).map(([code,text])=>jsx121(Radio2,{value:code,label:text,my:"xs"},code))}),jsx121(Group46,{justify:"flex-end",gap:4,mt:"md",children:jsx121(Button23,{type:"submit",children:"Save"})})]})})})]})}import{Anchor as Anchor10,Button as Button24,Group as Group47,Modal as Modal11,Radio as Radio3,Stack as Stack22,Text as Text22}from"@mantine/core";import{useDisclosure as useDisclosure5}from"@mantine/hooks";import{HTTP_HL7_ORG as HTTP_HL7_ORG6,LOINC as LOINC2,SNOMED as SNOMED2,createReference as createReference10,formatCodeableConcept as formatCodeableConcept6}from"@medplum/core";import{useMedplum as useMedplum34}from"@medplum/react-hooks";import{useCallback as useCallback23,useState as useState66}from"react";import{Fragment as Fragment39,jsx as jsx122,jsxs as jsxs72}from"react/jsx-runtime";var smokingStatusOptions={266919005:"Never smoked tobacco",266927001:"Tobacco smoking consumption unknown","428041000124106":"Occasional tobacco smoker","428061000124105":"Light tobacco smoker","428071000124103":"Heavy tobacco smoker",449868002:"Smokes tobacco daily",77176002:"Smoker",8517006:"Ex-smoker"};function SmokingStatus(props){let medplum=useMedplum34(),{patient,encounter}=props,[smokingStatus,setSmokingStatus]=useState66(props.smokingStatus),[opened,{open,close}]=useDisclosure5(!1),handleSubmit=useCallback23(formData=>{medplum.createResource({resourceType:"Observation",meta:{profile:[HTTP_HL7_ORG6+"/fhir/us/core/StructureDefinition/us-core-smokingstatus"]},status:"final",category:[{coding:[{system:"http://terminology.hl7.org/CodeSystem/observation-category",code:"social-history",display:"Social History"}],text:"Social History"}],code:{coding:[{system:LOINC2,code:"72166-2",display:"Tobacco smoking status"}],text:"Tobacco smoking status"},subject:createReference10(patient),encounter:encounter?createReference10(encounter):void 0,effectiveDateTime:new Date().toISOString(),valueCodeableConcept:{coding:[{system:SNOMED2,version:SNOMED2+"/731000124108",code:formData.smokingStatus}],text:smokingStatusOptions[formData.smokingStatus]}}).then(newSmokingStatus=>{setSmokingStatus(newSmokingStatus),close()}).catch(console.error)},[medplum,patient,encounter,close]);return jsxs72(Fragment39,{children:[jsxs72(Group47,{justify:"space-between",children:[jsx122(Text22,{fz:"md",fw:700,children:"Smoking Status"}),jsx122(Anchor10,{href:"#",onClick:e=>{killEvent(e),open()},children:"+ Edit"})]}),smokingStatus?.valueCodeableConcept?jsx122(ConceptBadge,{resource:smokingStatus,display:formatCodeableConcept6(smokingStatus.valueCodeableConcept),onClick:props.onClickResource,onEdit:()=>open()},smokingStatus.id):jsx122(Text22,{children:"(none)"}),jsx122(Modal11,{opened,onClose:close,title:"Set Smoking Status",children:jsx122(Form,{onSubmit:handleSubmit,children:jsxs72(Stack22,{children:[jsx122(Radio3.Group,{name:"smokingStatus",label:"Smoking Status",required:!0,children:Object.entries(smokingStatusOptions).map(([code,text])=>jsx122(Radio3,{value:code,label:text,my:"xs"},code))}),jsx122(Group47,{justify:"flex-end",gap:4,mt:"md",children:jsx122(Button24,{type:"submit",children:"Save"})})]})})})]})}import{Anchor as Anchor11,Button as Button25,Grid as Grid3,Group as Group48,Modal as Modal12,SimpleGrid as SimpleGrid2,Text as Text23,Textarea as Textarea3,TextInput as TextInput22,Tooltip as Tooltip4}from"@mantine/core";import{useDisclosure as useDisclosure6}from"@mantine/hooks";import{formatQuantity as formatQuantity2}from"@medplum/core";import{useMedplum as useMedplum35}from"@medplum/react-hooks";import{Fragment as Fragment40,useCallback as useCallback24,useState as useState67}from"react";import{LOINC as LOINC3,UCUM,createReference as createReference11}from"@medplum/core";function getObservationValue(obs,component){return component?obs.component?.find(c=>c.code?.coding?.[0].code===component)?.valueQuantity:obs.valueQuantity}function createObservation(patient,encounter,code,title,valueQuantity){if(isValidNumber(valueQuantity.value))return{...createBaseObservation(patient,encounter,code,title),valueQuantity}}function createCompoundObservation(patient,encounter,code,title,components){let component=components.filter(c=>isValidNumber(c.valueQuantity?.value));if(component.length!==0)return{...createBaseObservation(patient,encounter,code,title),component}}function createBaseObservation(patient,encounter,code,title){return{resourceType:"Observation",status:"preliminary",subject:createReference11(patient),encounter:encounter?createReference11(encounter):void 0,effectiveDateTime:new Date().toISOString(),category:[{coding:[{system:"http://terminology.hl7.org/CodeSystem/observation-category",code:"vital-signs",display:"Vital Signs"}]}],code:createLoincCode(code,title)}}function createLoincCode(code,display){return{coding:[{code,display,system:LOINC3}],text:display}}function createQuantity(value,unit){return{value,system:UCUM,unit,code:unit}}function isValidNumber(value){return value!==void 0&&!isNaN(value)&&isFinite(value)}import{Fragment as Fragment41,jsx as jsx123,jsxs as jsxs73}from"react/jsx-runtime";var BP="85354-9",SYSTOLIC="8480-6",DIASTOLIC="8462-4",LOINC_CODES=[{name:"systolic",short:"BP Sys",code:BP,component:SYSTOLIC,title:"Blood Pressure",unit:"mm[Hg]"},{name:"diastolic",short:"BP Dias",code:BP,component:DIASTOLIC,title:"Blood Pressure",unit:"mm[Hg]"},{name:"heartRate",short:"HR",code:"8867-4",title:"Heart Rate",unit:"/min"},{name:"bodyTemperature",short:"Temp",code:"8310-5",title:"Body Temperature",unit:"Cel"},{name:"respiratoryRate",short:"RR",code:"9279-1",title:"Respiratory Rate",unit:"/min"},{name:"height",short:"Ht",code:"8302-2",title:"Height",unit:"cm"},{name:"weight",short:"Wt",code:"29463-7",title:"Weight",unit:"kg"},{name:"bmi",short:"BMI",code:"39156-5",title:"BMI",unit:"kg/m2"},{name:"oxygen",short:"O2",code:"2708-6",title:"Oxygen",unit:"%"},{name:"headCircumference",short:"HC",code:"9843-4",title:"Head Circumference",unit:"cm"}];function Vitals(props){let medplum=useMedplum35(),{patient,encounter}=props,[vitals,setVitals]=useState67(props.vitals),[opened,{open,close}]=useDisclosure6(!1),handleSubmit=useCallback24(formData=>{let newObservations=[];newObservations.push(createCompoundObservation(patient,encounter,BP,"Blood pressure",[{code:createLoincCode(SYSTOLIC,"Systolic blood pressure"),valueQuantity:createQuantity(parseFloat(formData.systolic),"mm[Hg]")},{code:createLoincCode(DIASTOLIC,"Diastolic blood pressure"),valueQuantity:createQuantity(parseFloat(formData.diastolic),"mm[Hg]")}]));for(let meta of LOINC_CODES)meta.component||newObservations.push(createObservation(patient,encounter,meta.code,meta.title,createQuantity(parseFloat(formData[meta.name]),meta.unit)));Promise.all(newObservations.filter(Boolean).map(obs=>medplum.createResource(obs))).then(newVitals=>setVitals([...newVitals,...vitals])).catch(console.error),close()},[medplum,patient,encounter,vitals,close]);return jsxs73(Fragment41,{children:[jsxs73(Group48,{justify:"space-between",children:[jsx123(Text23,{fz:"md",fw:700,children:"Vitals"}),jsx123(Anchor11,{href:"#",onClick:e=>{killEvent(e),open()},children:"+ Add"})]}),jsx123(Grid3,{children:LOINC_CODES.map(meta=>{let obs=vitals.find(o=>o.code?.coding?.[0].code===meta.code);return jsxs73(Fragment40,{children:[jsx123(Grid3.Col,{span:2,ta:"right",children:jsx123(Tooltip4,{label:meta.title,children:jsx123(Text23,{c:"dimmed",size:"xs",children:meta.short})})}),jsx123(Grid3.Col,{span:4,children:jsx123(Text23,{size:"xs",children:obs&&jsx123(ConceptBadge,{resource:obs,display:formatQuantity2(getObservationValue(obs,meta.component)),onClick:props.onClickResource},meta.name)})})]},meta.name)})}),jsx123(Modal12,{opened,onClose:close,title:"Add Vitals",children:jsxs73(Form,{onSubmit:handleSubmit,children:[jsx123(SimpleGrid2,{cols:2,children:LOINC_CODES.map((meta,index)=>jsx123(TextInput22,{name:meta.name,label:meta.short,description:meta.title,"data-autofocus":index===0,autoFocus:index===0},meta.name))}),jsx123(Textarea3,{name:"notes",label:"Notes"}),jsx123(Group48,{justify:"flex-end",gap:4,mt:"md",children:jsx123(Button25,{type:"submit",children:"Save"})})]})})]})}import{Fragment as Fragment42,jsx as jsx124,jsxs as jsxs74}from"react/jsx-runtime";function getGenderIcon(patient){switch(patient?.gender){case"female":return IconGenderFemale;case"male":return IconGenderMale;default:return}}function pluralize(count,singular,plural){return count===0?`No ${plural}`:count===1?`1 ${singular}`:`${count} ${plural}`}function PatientSummary(props){let medplum=useMedplum36(),{patient:propsPatient,background,appointmentsUrl:propsAppointmentsUrl,encountersUrl:propsEncountersUrl,onClickResource,...cardProps}=props,patient=useResource9(propsPatient),[medicalData,setMedicalData]=useState68(),appointmentsUrl="appointmentsUrl"in props?propsAppointmentsUrl:"#",encountersUrl="encountersUrl"in props?propsEncountersUrl:"#";useEffect25(()=>{let ref=`Patient/${resolveId2(propsPatient)}`,searchMeta={_count:100,_sort:"-_lastUpdated"},today=new Date().toISOString().substring(0,10);Promise.all([medplum.searchResources("AllergyIntolerance",{patient:ref,...searchMeta}),medplum.searchResources("Condition",{patient:ref,...searchMeta}),medplum.searchResources("MedicationRequest",{subject:ref,...searchMeta}),medplum.searchResources("Observation",{subject:ref,...searchMeta}),medplum.searchResources("Appointment",{patient:ref,date:`ge${today}`,status:"proposed,pending,booked",...searchMeta}),medplum.searchResources("Encounter",{subject:ref,date:`le${today}`,status:"finished",...searchMeta})]).then(results=>{let observations=results[3];setMedicalData({allergies:results[0],problems:results[1],medicationRequests:results[2],sexualOrientation:observations.find(obs=>obs.code?.coding?.[0].code==="76690-7"),smokingStatus:observations.find(obs=>obs.code?.coding?.[0].code==="72166-2"),vitals:observations.filter(obs=>obs.category?.[0]?.coding?.[0].code==="vital-signs"),appointments:results[4],encounters:results[5]})}).catch(console.error)},[medplum,propsPatient]);let links=useMemo29(()=>{let appointmentsLink=appointmentsUrl===void 0?void 0:jsx124(MedplumLink,{to:appointmentsUrl,children:pluralize(medicalData?.appointments?.length,"upcoming appointment","upcoming appointments")},"appt"),encountersLink=encountersUrl===void 0?void 0:jsx124(MedplumLink,{to:encountersUrl,children:pluralize(medicalData?.encounters?.length,"documented visit","documented visits")},"enc");return[appointmentsLink,encountersLink].filter(Boolean)},[appointmentsUrl,medicalData?.appointments?.length,medicalData?.encounters?.length,encountersUrl]);if(!patient)return null;let GenderIconComponent=getGenderIcon(patient);return jsxs74(Card,{...cardProps,children:[jsx124(Card.Section,{h:100,style:{background}}),jsx124(ResourceAvatar,{value:patient,size:80,radius:80,mx:"auto",mt:-50,style:{border:"2px solid white"}}),jsx124(Text24,{ta:"center",fz:"lg",fw:500,children:formatHumanName4(patient.name?.[0])}),patient.birthDate&&jsxs74(Text24,{ta:"center",fz:"xs",c:"dimmed",children:[patient.birthDate," (",calculateAgeString(patient.birthDate),")"]}),jsx124(Paper4,{withBorder:!0,p:"md",my:"md",children:jsxs74(Group49,{wrap:"nowrap",justify:"space-evenly",children:[jsxs74(Flex4,{justify:"center",align:"center",direction:"column",gap:0,children:[jsx124(IconUserSquare,{size:24,color:"gray"}),jsx124(Text24,{fz:"xs",ta:"center",style:{whiteSpace:"nowrap"},children:"Self"})]}),jsxs74(Flex4,{justify:"center",align:"center",direction:"column",gap:0,children:[jsx124(IconStethoscope,{size:24,color:"gray"}),jsx124(Text24,{fz:"xs",style:{whiteSpace:"nowrap"},children:patient?.generalPractitioner?.[0]?.display??"No provider"})]}),GenderIconComponent&&jsxs74(Flex4,{justify:"center",align:"center",direction:"column",gap:0,children:[jsx124(GenderIconComponent,{size:24,color:"gray"}),jsx124(Text24,{fz:"xs",style:{whiteSpace:"nowrap"},children:patient.gender})]})]})}),jsxs74(Stack23,{gap:"xs",children:[links.length>0&&jsxs74(Fragment42,{children:[links,jsx124(Divider3,{})]}),medicalData&&jsxs74(Fragment42,{children:[jsx124(Allergies,{patient,allergies:medicalData.allergies,onClickResource}),jsx124(Divider3,{}),jsx124(ProblemList,{patient,problems:medicalData.problems,onClickResource}),jsx124(Divider3,{}),jsx124(Medications,{patient,medicationRequests:medicalData.medicationRequests,onClickResource}),jsx124(Divider3,{}),jsx124(SexualOrientation,{patient,sexualOrientation:medicalData.sexualOrientation,onClickResource}),jsx124(Divider3,{}),jsx124(SmokingStatus,{patient,smokingStatus:medicalData.smokingStatus,onClickResource}),jsx124(Divider3,{}),jsx124(Vitals,{patient,vitals:medicalData.vitals,onClickResource})]})]})]})}import{createReference as createReference12}from"@medplum/core";import{useCallback as useCallback25}from"react";import{jsx as jsx125}from"react/jsx-runtime";function PatientTimeline(props){let{patient,...rest}=props,loadTimelineResources=useCallback25((medplum,resourceType,id)=>{let ref=`${resourceType}/${id}`,_count=100;return Promise.allSettled([medplum.readHistory("Patient",id),medplum.search("Communication",{subject:ref,_count}),medplum.search("Device",{patient:ref,_count}),medplum.search("DeviceRequest",{patient:ref,_count}),medplum.search("DiagnosticReport",{subject:ref,_count}),medplum.search("Media",{subject:ref,_count}),medplum.search("ServiceRequest",{subject:ref,_count}),medplum.search("Task",{subject:ref,_count})])},[]);return jsx125(ResourceTimeline,{value:patient,loadTimelineResources,createCommunication:(resource,sender,text)=>({resourceType:"Communication",status:"completed",subject:createReference12(resource),sender:createReference12(sender),sent:new Date().toISOString(),payload:[{contentString:text}]}),createMedia:(resource,operator,content)=>({resourceType:"Media",status:"completed",subject:createReference12(resource),operator:createReference12(operator),issued:new Date().toISOString(),content}),...rest})}import{Anchor as Anchor12,Box as Box7,Button as Button26,CloseButton,Group as Group50,Paper as Paper5,Stack as Stack24,TextInput as TextInput23,Text as Text25,Radio as Radio4,ActionIcon as ActionIcon14,Flex as Flex5}from"@mantine/core";import{getReferenceString as getReferenceString7}from"@medplum/core";import{useMedplum as useMedplum37,useResource as useResource10}from"@medplum/react-hooks";import{useEffect as useEffect26,useRef as useRef19,useState as useState69}from"react";var PlanDefinitionBuilder_default={section:"PlanDefinitionBuilder_section",hovering:"PlanDefinitionBuilder_hovering",editing:"PlanDefinitionBuilder_editing"};import{jsx as jsx126,jsxs as jsxs75}from"react/jsx-runtime";function PlanDefinitionBuilder(props){let medplum=useMedplum37(),defaultValue2=useResource10(props.value),[schemaLoaded,setSchemaLoaded]=useState69(!1),[selectedKey,setSelectedKey]=useState69(),[hoverKey,setHoverKey]=useState69(),[value,setValue]=useState69();function handleDocumentMouseOver(){setHoverKey(void 0)}function handleDocumentClick(){setSelectedKey(void 0)}let valueRef=useRef19();if(valueRef.current=value,useEffect26(()=>{medplum.requestSchema("PlanDefinition").then(()=>setSchemaLoaded(!0)).catch(console.log)},[medplum]),useEffect26(()=>(setValue(ensurePlanDefinitionKeys(defaultValue2??{resourceType:"PlanDefinition",status:"active"})),document.addEventListener("mouseover",handleDocumentMouseOver),document.addEventListener("click",handleDocumentClick),()=>{document.removeEventListener("mouseover",handleDocumentMouseOver),document.removeEventListener("click",handleDocumentClick)}),[defaultValue2]),!schemaLoaded||!value)return null;function changeProperty(property,newValue){setValue({...valueRef.current,[property]:newValue})}return jsx126("div",{children:jsxs75(Form,{testid:"questionnaire-form",onSubmit:()=>props.onSubmit(value),children:[jsx126(TextInput23,{label:"Plan Title",py:"md",defaultValue:value.title,onChange:e=>changeProperty("title",e.currentTarget.value)}),jsx126(ActionArrayBuilder,{actions:value.action||[],selectedKey,setSelectedKey,hoverKey,setHoverKey,onChange:x=>changeProperty("action",x)}),jsx126(Button26,{type:"submit",children:"Save"})]})})}function ActionArrayBuilder(props){let actionsRef=useRef19();actionsRef.current=props.actions;function changeAction(changedAction){props.onChange(actionsRef.current.map(i=>i.id===changedAction.id?changedAction:i))}function addAction(addedAction){props.onChange([...actionsRef.current,addedAction]),props.setSelectedKey(addedAction.id)}function removeAction(removedAction){props.onChange(actionsRef.current.filter(i=>i!==removedAction))}return jsxs75(Stack24,{gap:"md",className:PlanDefinitionBuilder_default.section,children:[props.actions.map(action=>jsx126(ActionBuilder,{action,selectedKey:props.selectedKey,setSelectedKey:props.setSelectedKey,hoverKey:props.hoverKey,setHoverKey:props.setHoverKey,onChange:changeAction,onRemove:()=>removeAction(action)},action.id)),jsx126("div",{children:jsx126(Button26,{variant:"outline",onClick:e=>{killEvent(e),addAction({id:generateId()})},children:"Add action"})})]})}function ActionBuilder(props){let{action}=props,actionType=getInitialActionType(action);function onClick(e){e.stopPropagation(),props.setSelectedKey(props.action.id)}function onHover(e){killEvent(e),props.setHoverKey(props.action.id)}return jsx126("div",{onClick,onMouseOver:onHover,onFocus:onHover,children:jsx126(ActionEditor,{action,actionType,onChange:props.onChange,selectedKey:props.selectedKey,setSelectedKey:props.setSelectedKey,hoverKey:props.hoverKey,setHoverKey:props.setHoverKey,onRemove:props.onRemove})})}function ActionEditor(props){let{action}=props,[actionType,setActionType]=useState69(props.actionType),editing=props.selectedKey===props.action.id,hovering=props.hoverKey===props.action.id;function changeProperty(property,value){props.onChange({...action,[property]:value})}let className=clsx_default(PlanDefinitionBuilder_default.section,{[PlanDefinitionBuilder_default.hovering]:hovering&&!editing});return jsxs75(Paper5,{"data-testid":action.id,className,p:0,radius:"sm",withBorder:!0,children:[jsxs75(Flex5,{w:"100%",p:"xs",bg:"gray.0",gap:"md",align:"center",justify:"space-between",children:[jsx126(TextInput23,{w:"100%",name:`actionTitle-${action.id}`,defaultValue:action.title,placeholder:"Title",onChange:e=>changeProperty("title",e.currentTarget.value)}),jsx126(ActionIcon14,{variant:"subtle",color:"gray",onClick:props.onRemove,children:jsx126(CloseButton,{"data-testid":"close-button"})})]}),editing&&jsxs75(Stack24,{gap:"xl",p:"md",children:[jsxs75(Box7,{children:[jsx126(Text25,{fw:600,mb:"xs",children:"Task Description"}),jsx126(TextInput23,{placeholder:"Enter task description",name:`actionDescription-${action.id}`,defaultValue:action.description,onChange:e=>changeProperty("description",e.currentTarget.value)})]}),jsxs75(Box7,{children:[jsx126(Text25,{fw:600,mb:"xs",children:"Type"}),jsx126(Radio4.Group,{value:actionType,onChange:setActionType,children:jsxs75(Stack24,{gap:"sm",children:[jsx126(Radio4,{value:"standard",label:"Standard task",onChange:()=>props.onChange({...props.action,definitionCanonical:void 0})}),jsx126(Radio4,{value:"questionnaire",label:"Task with Questionnaire"})]})})]}),actionType==="questionnaire"&&jsxs75(Box7,{children:[jsxs75(Group50,{gap:"xs",mb:"xs",children:[jsx126(Text25,{fw:600,children:"Select questionnaire"}),jsx126(Text25,{c:"red",children:"*"})]}),jsxs75(Text25,{size:"sm",c:"dimmed",mb:"sm",children:["Questionnaire to be shown in the task in Encounter view. You can create new one from"," ",jsx126(Anchor12,{href:"/Questionnaire",target:"_blank",c:"blue",children:"questionnaires list"})]}),jsx126(ActionResourceTypeBuilder,{title:"Questionnaire",description:"The subject must complete the selected questionnaire.",resourceType:"Questionnaire",action,onChange:props.onChange})]})]})]})}function ActionResourceTypeBuilder(props){let{id,definitionCanonical}=props.action,reference=definitionCanonical?.startsWith(props.resourceType+"/")?{reference:definitionCanonical}:void 0;return jsx126(ResourceInput,{name:id,resourceType:props.resourceType,defaultValue:reference,loadOnFocus:!0,onChange:newValue=>{newValue?props.onChange({...props.action,definitionCanonical:getReferenceString7(newValue)}):props.onChange({...props.action,definitionCanonical:void 0})}})}function getInitialActionType(action){return action.definitionCanonical?.startsWith("Questionnaire")?"questionnaire":"standard"}var nextId=1;function generateId(existing){if(existing){if(existing.startsWith("id-")){let existingNum=parseInt(existing.substring(3),10);isNaN(existingNum)||(nextId=Math.max(nextId,existingNum+1))}return existing}return"id-"+nextId++}function ensurePlanDefinitionKeys(planDefinition){return{...planDefinition,action:ensurePlanDefinitionActionKeys(planDefinition.action)}}function ensurePlanDefinitionActionKeys(actions){if(actions)return actions.map(action=>({...action,id:generateId(action.id),action:ensurePlanDefinitionActionKeys(action.action)}))}import{Anchor as Anchor13,Box as Box8,Button as Button27,Group as Group52,NativeSelect as NativeSelect12,Space as Space2,Textarea as Textarea5,TextInput as TextInput25,Title as Title8}from"@mantine/core";import{getElementDefinition as getElementDefinition3,isResource as isResourceType}from"@medplum/core";import{useMedplum as useMedplum38,useResource as useResource11}from"@medplum/react-hooks";import{useEffect as useEffect27,useRef as useRef20,useState as useState70}from"react";import{Checkbox as Checkbox6,Group as Group51,MultiSelect as MultiSelect2,NativeSelect as NativeSelect11,Radio as Radio5,Textarea as Textarea4,TextInput as TextInput24}from"@mantine/core";import{capitalize as capitalize6,deepEquals as deepEquals2,formatCoding as formatCoding2,getElementDefinition as getElementDefinition2,HTTP_HL7_ORG as HTTP_HL7_ORG8,stringify as stringify3,typedValueToString as typedValueToString2}from"@medplum/core";import{useContext as useContext23}from"react";import{HTTP_HL7_ORG as HTTP_HL7_ORG7,PropertyType as PropertyType3,deepClone as deepClone3,evalFhirPathTyped as evalFhirPathTyped3,getExtension,getReferenceString as getReferenceString8,getTypedPropertyValueWithoutSchema,splitN,toJsBoolean,toTypedValue as toTypedValue2,typedValueToString}from"@medplum/core";var QuestionnaireItemType=(QuestionnaireItemType2=>(QuestionnaireItemType2.group="group",QuestionnaireItemType2.display="display",QuestionnaireItemType2.question="question",QuestionnaireItemType2.boolean="boolean",QuestionnaireItemType2.decimal="decimal",QuestionnaireItemType2.integer="integer",QuestionnaireItemType2.date="date",QuestionnaireItemType2.dateTime="dateTime",QuestionnaireItemType2.time="time",QuestionnaireItemType2.string="string",QuestionnaireItemType2.text="text",QuestionnaireItemType2.url="url",QuestionnaireItemType2.choice="choice",QuestionnaireItemType2.openChoice="open-choice",QuestionnaireItemType2.attachment="attachment",QuestionnaireItemType2.reference="reference",QuestionnaireItemType2.quantity="quantity",QuestionnaireItemType2))(QuestionnaireItemType||{});function isChoiceQuestion(item){return item.type==="choice"||item.type==="open-choice"}function isQuestionEnabled(item,questionnaireResponse){let extension=getExtension(item,HTTP_HL7_ORG7+"/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression");if(questionnaireResponse&&extension){let expression=extension.valueExpression?.expression;if(expression){let value=toTypedValue2(questionnaireResponse),result=evalFhirPathTyped3(expression,[value],{"%resource":value});return toJsBoolean(result)}}if(!item.enableWhen)return!0;let enableBehavior=item.enableBehavior??"any";for(let enableWhen of item.enableWhen){let actualAnswers=getByLinkId(questionnaireResponse?.item,enableWhen.question);if(enableWhen.operator==="exists"&&!enableWhen.answerBoolean&&!actualAnswers?.length){if(enableBehavior==="any")return!0;continue}let{anyMatch,allMatch}=checkAnswers(enableWhen,actualAnswers,enableBehavior);if(enableBehavior==="any"&&anyMatch)return!0;if(enableBehavior==="all"&&!allMatch)return!1}return enableBehavior!=="any"}function evaluateCalculatedExpressionsInQuestionnaire(items,response){return items.map(item=>{if(item.item)return{...item,item:evaluateCalculatedExpressionsInQuestionnaire(item.item,response)};{let calculatedValue=evaluateCalculatedExpression(item,response);if(!calculatedValue)return null;let answer=typedValueToResponseItem(item,calculatedValue);return answer?{id:item?.id,linkId:item?.linkId,text:item.text,answer:[answer]}:null}}).filter(item=>item!==null)}function typedValueToResponseItem(item,value){if(item.type)switch(item.type){case"boolean":return value.type===PropertyType3.boolean?{valueBoolean:value.value}:void 0;case"date":return value.type===PropertyType3.date?{valueDate:value.value}:void 0;case"dateTime":return value.type===PropertyType3.dateTime?{valueDateTime:value.value}:void 0;case"time":return value.type===PropertyType3.time?{valueTime:value.value}:void 0;case"url":return value.type===PropertyType3.url?{valueString:value.value}:void 0;case"text":return value.type===PropertyType3.string?{valueString:value.value}:void 0;case"attachment":return value.type===PropertyType3.Attachment?{valueAttachment:value.value}:void 0;case"reference":return value.type===PropertyType3.Reference?{valueReference:value.value}:void 0;case"quantity":return{valueQuantity:value.value};case"decimal":return{valueDecimal:value.value};case"integer":return{valueInteger:value.value};case"string":return{valueString:value.value};default:return}}function evaluateCalculatedExpression(item,response){if(!response)return;let extension=getExtension(item,HTTP_HL7_ORG7+"/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression");if(extension){let expression=extension.valueExpression?.expression;if(expression){let value=toTypedValue2(response),result=evalFhirPathTyped3(expression,[value],{"%resource":value});return result.length!==0?result[0]:void 0}}}function mergeUpdatedItems(mergedItems,updatedItems){return mergedItems.map(mergedItem=>{let updatedItem=updatedItems.find(updated=>updated.linkId===mergedItem.linkId);return updatedItem?{...mergedItem,item:updatedItem.item?mergeUpdatedItems(mergedItem.item||[],updatedItem.item):mergedItem.item,answer:updatedItem.answer||mergedItem.answer}:mergedItem})}function getNewMultiSelectValues(selected,propertyName,item){let result=[];for(let selectedStr of selected){let option=item.answerOption?.find(candidate=>typedValueToString(getItemAnswerOptionValue(candidate))===selectedStr);if(option){let optionValue=getItemAnswerOptionValue(option);optionValue&&result.push({[propertyName]:optionValue.value})}}return result}function getByLinkId(responseItems,linkId){if(responseItems)for(let response of responseItems){if(response.linkId===linkId)return response.answer;if(response.item){let nestedAnswer=getByLinkId(response.item,linkId);if(nestedAnswer)return nestedAnswer}}}function evaluateMatch(actualAnswer,expectedAnswer,operator){if(operator==="exists")return!!actualAnswer===expectedAnswer.value;if(actualAnswer){let fhirPathOperator=operator==="="||operator==="!="?operator?.replace("=","~"):operator,[{value}]=evalFhirPathTyped3(`%actualAnswer ${fhirPathOperator} %expectedAnswer`,[actualAnswer],{"%actualAnswer":actualAnswer,"%expectedAnswer":expectedAnswer});return value}else return!1}function checkAnswers(enableWhen,answers,enableBehavior){let actualAnswers=answers||[],expectedAnswer=getItemEnableWhenValueAnswer(enableWhen),anyMatch=!1,allMatch=!0;for(let actualAnswerValue of actualAnswers){let actualAnswer=getResponseItemAnswerValue(actualAnswerValue),{operator}=enableWhen;if(evaluateMatch(actualAnswer,expectedAnswer,operator)?anyMatch=!0:allMatch=!1,enableBehavior==="any"&&anyMatch)break}return{anyMatch,allMatch}}function getQuestionnaireItemReferenceTargetTypes(item){let extension=getExtension(item,"http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource");if(extension){if(extension.valueCode!==void 0)return[extension.valueCode];if(extension.valueCodeableConcept)return extension.valueCodeableConcept?.coding?.map(c=>c.code)}}function setQuestionnaireItemReferenceTargetTypes(item,targetTypes){let result=deepClone3(item),extension=getExtension(result,"http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource");return!targetTypes||targetTypes.length===0?(extension&&(result.extension=result.extension?.filter(e=>e!==extension)),result):(extension||(result.extension||(result.extension=[]),extension={url:"http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource"},result.extension.push(extension)),targetTypes.length===1?(extension.valueCode=targetTypes[0],delete extension.valueCodeableConcept):(extension.valueCodeableConcept={coding:targetTypes.map(t=>({code:t}))},delete extension.valueCode),result)}function getQuestionnaireItemReferenceFilter(item,subject,encounter){let extension=getExtension(item,"http://hl7.org/fhir/StructureDefinition/questionnaire-referenceFilter");if(!extension?.valueString)return;let filter=extension.valueString;subject?.reference&&(filter=filter.replaceAll("$subj",subject.reference)),encounter?.reference&&(filter=filter.replaceAll("$encounter",encounter.reference));let result={},parts=filter.split("&");for(let part of parts){let[key,value]=splitN(part,"=",2);result[key]=value}return result}function buildInitialResponse(questionnaire){return{resourceType:"QuestionnaireResponse",questionnaire:getReferenceString8(questionnaire),item:buildInitialResponseItems(questionnaire.item),status:"in-progress"}}function buildInitialResponseItems(items){return items?.map(buildInitialResponseItem)??[]}function buildInitialResponseItem(item){return{id:generateId2(),linkId:item.linkId,text:item.text,item:buildInitialResponseItems(item.item),answer:item.initial?.map(buildInitialResponseAnswer)??[]}}var nextId2=1;function generateId2(){return"id-"+nextId2++}function buildInitialResponseAnswer(answer){return{...answer}}function getNumberOfPages(questionnaire){let firstItem=questionnaire?.item?.[0];return firstItem&&getExtension(firstItem,"http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl")?.valueCodeableConcept?.coding?.[0]?.code==="page"?questionnaire.item.length:1}function getItemInitialValue(initial){return getTypedPropertyValueWithoutSchema({type:"QuestionnaireItemInitial",value:initial},"value")}function getItemAnswerOptionValue(option){return getTypedPropertyValueWithoutSchema({type:"QuestionnaireItemAnswerOption",value:option},"value")}function getItemEnableWhenValueAnswer(enableWhen){return getTypedPropertyValueWithoutSchema({type:"QuestionnaireItemEnableWhen",value:enableWhen},"answer")}function getResponseItemAnswerValue(answer){return getTypedPropertyValueWithoutSchema({type:"QuestionnaireResponseItemAnswer",value:answer},"value")}import{createContext as createContext2}from"react";var QuestionnaireFormContext=createContext2({});import{jsx as jsx127}from"react/jsx-runtime";function QuestionnaireFormItem(props){let context=useContext23(QuestionnaireFormContext),item=props.item,response=props.response;function onChangeAnswer(newResponseAnswer){let updatedAnswers;Array.isArray(newResponseAnswer)?updatedAnswers=newResponseAnswer:props.index>=(props.response?.answer?.length??0)?updatedAnswers=(props.response?.answer??[]).concat([newResponseAnswer]):updatedAnswers=(props.response?.answer??[]).map((a,idx)=>idx===props.index?newResponseAnswer:a)??[],props.onChange({id:response?.id,linkId:response?.linkId,text:item.text,answer:updatedAnswers})}let type=item.type;if(!type)return null;let name=item.linkId;if(!name)return null;let initial=item.initial&&item.initial.length>0?item.initial[0]:void 0,defaultValue2=getCurrentAnswer(response,props.index)??getItemInitialValue(initial);switch(type){case"display":return jsx127("p",{children:props.item.text},props.item.linkId);case"boolean":return jsx127(CheckboxFormSection,{title:props.item.text,htmlFor:props.item.linkId,children:jsx127(Checkbox6,{id:props.item.linkId,name:props.item.linkId,defaultChecked:defaultValue2?.value,onChange:e=>onChangeAnswer({valueBoolean:e.currentTarget.checked})})},props.item.linkId);case"decimal":return jsx127(TextInput24,{type:"number",step:"any",id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueDecimal:e.currentTarget.valueAsNumber})});case"integer":return jsx127(TextInput24,{type:"number",step:1,id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueInteger:e.currentTarget.valueAsNumber})});case"date":return jsx127(TextInput24,{type:"date",id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueDate:e.currentTarget.value})});case"dateTime":return jsx127(DateTimeInput,{name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:newValue=>onChangeAnswer({valueDateTime:newValue})});case"time":return jsx127(TextInput24,{type:"time",id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueTime:e.currentTarget.value})});case"string":case"url":return jsx127(TextInput24,{id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueString:e.currentTarget.value})});case"text":return jsx127(Textarea4,{id:name,name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:e=>onChangeAnswer({valueString:e.currentTarget.value})});case"attachment":return jsx127(Group51,{py:4,children:jsx127(AttachmentInput,{path:"",name,defaultValue:defaultValue2?.value,onChange:newValue=>onChangeAnswer({valueAttachment:newValue})})});case"reference":return jsx127(ReferenceInput,{name,required:props.required??item.required,targetTypes:getQuestionnaireItemReferenceTargetTypes(item),searchCriteria:getQuestionnaireItemReferenceFilter(item,context.subject,context.encounter),defaultValue:defaultValue2?.value,onChange:newValue=>onChangeAnswer({valueReference:newValue})});case"quantity":return jsx127(QuantityInput,{path:"",name,required:props.required??item.required,defaultValue:defaultValue2?.value,onChange:newValue=>onChangeAnswer({valueQuantity:newValue}),disableWheel:!0});case"choice":case"open-choice":return isDropDownChoice(item)&&!item.answerValueSet?jsx127(QuestionnaireChoiceDropDownInput,{name,item,initial,response,onChangeAnswer:e=>onChangeAnswer(e)}):isMultiSelectChoice(item)&&!item.answerValueSet?jsx127(QuestionnaireMultiSelectInput,{name,item,initial,response,onChangeAnswer:e=>onChangeAnswer(e)}):jsx127(QuestionnaireChoiceSetInput,{name,item,initial,response,onChangeAnswer:e=>onChangeAnswer(e)});default:return null}}function QuestionnaireChoiceDropDownInput(props){let{name,item,initial,response}=props;if(!item.answerOption?.length)return jsx127(NoAnswerDisplay,{});let initialValue=getItemInitialValue(initial),data2=[""];for(let option of item.answerOption){let optionValue=getItemAnswerOptionValue(option);data2.push(typedValueToString2(optionValue))}let defaultValue2=getCurrentAnswer(response)??initialValue;if(item.repeats){let{propertyName,data:data3}=formatSelectData(props.item),currentAnswer=getCurrentMultiSelectAnswer(response);return jsx127(MultiSelect2,{data:data3,placeholder:"Select items",searchable:!0,defaultValue:currentAnswer||[typedValueToString2(initialValue)],onChange:selected=>{let values=getNewMultiSelectValues(selected,propertyName,item);props.onChangeAnswer(values)}})}return jsx127(NativeSelect11,{id:name,name,onChange:e=>{let index=e.currentTarget.selectedIndex;if(index===0){props.onChangeAnswer({});return}let option=item.answerOption[index-1],optionValue=getItemAnswerOptionValue(option),propertyName="value"+capitalize6(optionValue.type);props.onChangeAnswer({[propertyName]:optionValue.value})},defaultValue:formatCoding2(defaultValue2?.value)||defaultValue2?.value,data:data2})}function QuestionnaireMultiSelectInput(props){let{item,initial,response}=props;if(!item.answerOption?.length)return jsx127(NoAnswerDisplay,{});let initialValue=getItemInitialValue(initial),{propertyName,data:data2}=formatSelectData(props.item),currentAnswer=getCurrentMultiSelectAnswer(response);return jsx127(MultiSelect2,{data:data2,placeholder:"Select items",searchable:!0,defaultValue:currentAnswer||[typedValueToString2(initialValue)],onChange:selected=>{let values=getNewMultiSelectValues(selected,propertyName,item);props.onChangeAnswer(values)}})}function QuestionnaireChoiceSetInput(props){let{name,item,initial,onChangeAnswer,response}=props;return!item.answerOption?.length&&!item.answerValueSet?jsx127(NoAnswerDisplay,{}):item.answerValueSet?jsx127(CodingInput,{path:"",name,binding:item.answerValueSet,response,onChange:code=>onChangeAnswer({valueCoding:code}),creatable:item.type==="open-choice"}):jsx127(QuestionnaireChoiceRadioInput,{name:response?.id??name,item,initial,response,onChangeAnswer})}function QuestionnaireChoiceRadioInput(props){let{name,item,initial,onChangeAnswer,response}=props,valueElementDefinition=getElementDefinition2("QuestionnaireItemAnswerOption","value[x]"),initialValue=getItemInitialValue(initial),options=[],defaultValue2;if(item.answerOption)for(let i=0;i<item.answerOption.length;i++){let option=item.answerOption[i],optionName=`${name}-option-${i}`,optionValue=getItemAnswerOptionValue(option);optionValue?.value&&(initialValue&&stringify3(optionValue)===stringify3(initialValue)&&(defaultValue2=optionName),options.push([optionName,optionValue]))}let defaultAnswer=getCurrentAnswer(response),answerLinkId=getCurrentRadioAnswer(options,defaultAnswer);return jsx127(Radio5.Group,{name,value:answerLinkId??defaultValue2,onChange:newValue=>{let option=options.find(option2=>option2[0]===newValue);if(option){let optionValue=option[1],propertyName="value"+capitalize6(optionValue.type);onChangeAnswer({[propertyName]:optionValue.value})}},children:options.map(([optionName,optionValue])=>jsx127(Radio5,{id:optionName,value:optionName,py:4,label:jsx127(ResourcePropertyDisplay,{property:valueElementDefinition,propertyType:optionValue.type,value:optionValue.value})},optionName))})}function NoAnswerDisplay(){return jsx127(TextInput24,{disabled:!0,placeholder:"No Answers Defined"})}function getCurrentAnswer(response,index=0){let results=response.answer;return getItemAnswerOptionValue(results?.[index]??{})}function getCurrentMultiSelectAnswer(response){let results=response.answer;return results?results.map(a=>getItemAnswerOptionValue(a)).map(type=>formatCoding2(type?.value)||type?.value):[]}function getCurrentRadioAnswer(options,defaultAnswer){return options.find(option=>deepEquals2(option[1].value,defaultAnswer?.value))?.[0]}function isDropDownChoice(item){return!!item.extension?.some(e=>e.url==="http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl"&&e.valueCodeableConcept?.coding?.[0]?.code==="drop-down")}function isMultiSelectChoice(item){return!!item.extension?.some(e=>e.url===HTTP_HL7_ORG8+"/fhir/StructureDefinition/questionnaire-itemControl"&&e.valueCodeableConcept?.coding?.[0]?.code==="multi-select")}function formatSelectData(item){if(item.answerOption?.length===0)return{propertyName:"",data:[]};let option=item.answerOption[0],optionValue=getItemAnswerOptionValue(option),propertyName="value"+capitalize6(optionValue.type),data2=(item.answerOption??[]).map(answerOption=>{let answerOptionValue=getItemAnswerOptionValue(answerOption),answerOptionValueStr=typedValueToString2(answerOptionValue);return{value:answerOptionValueStr,label:answerOptionValueStr}});return{propertyName,data:data2}}var QuestionnaireBuilder_default={section:"QuestionnaireBuilder_section",hovering:"QuestionnaireBuilder_hovering",editing:"QuestionnaireBuilder_editing",questionBody:"QuestionnaireBuilder_questionBody",topActions:"QuestionnaireBuilder_topActions",bottomActions:"QuestionnaireBuilder_bottomActions",movementActions:"QuestionnaireBuilder_movementActions",movementIcons:"QuestionnaireBuilder_movementIcons",columnAlignment:"QuestionnaireBuilder_columnAlignment",linkIdInput:"QuestionnaireBuilder_linkIdInput",typeSelect:"QuestionnaireBuilder_typeSelect",preserveBreaks:"QuestionnaireBuilder_preserveBreaks"};import{Fragment as Fragment43,jsx as jsx128,jsxs as jsxs76}from"react/jsx-runtime";function QuestionnaireBuilder(props){let medplum=useMedplum38(),defaultValue2=useResource11(props.questionnaire),[schemaLoaded,setSchemaLoaded]=useState70(!1),[value,setValue]=useState70(),[selectedKey,setSelectedKey]=useState70(),[hoverKey,setHoverKey]=useState70();function handleDocumentMouseOver(){setHoverKey(void 0)}function handleDocumentClick(){setSelectedKey(void 0)}useEffect27(()=>{medplum.requestSchema("Questionnaire").then(()=>setSchemaLoaded(!0)).catch(console.log)},[medplum]),useEffect27(()=>(setValue(ensureQuestionnaireKeys(defaultValue2??{resourceType:"Questionnaire",status:"active"})),document.addEventListener("mouseover",handleDocumentMouseOver),document.addEventListener("click",handleDocumentClick),()=>{document.removeEventListener("mouseover",handleDocumentMouseOver),document.removeEventListener("click",handleDocumentClick)}),[defaultValue2]);let handleChange=(questionnaire,disableSubmit)=>{setValue(questionnaire),props.autoSave&&!disableSubmit&&props.onSubmit&&props.onSubmit(questionnaire)};return!schemaLoaded||!value?null:jsx128("div",{children:jsxs76(Form,{testid:"questionnaire-form",onSubmit:()=>props.onSubmit(value),children:[jsx128(ItemBuilder,{item:value,selectedKey,setSelectedKey,hoverKey,setHoverKey,onChange:handleChange}),jsx128(Button27,{type:"submit",children:"Save"})]})})}function ItemBuilder(props){let resource=props.item,item=props.item,isResource2=isResourceType(props.item),isContainer=isResource2||item.type==="group",linkId=item.linkId??"[untitled]",editing=props.selectedKey===props.item.id,hovering=props.hoverKey===props.item.id,itemRef=useRef20();itemRef.current=props.item;function onClick(e){killEvent(e),props.setSelectedKey(props.item.id)}function onHover(e){killEvent(e),props.setHoverKey(props.item.id)}function changeItem(changedItem){let curr=itemRef.current;props.onChange({...curr,item:curr.item?.map(i=>i.id===changedItem.id?changedItem:i)})}function addItem(addedItem,disableSubmit){props.onChange({...props.item,item:[...props.item.item??[],addedItem]},disableSubmit)}function removeItem(removedItem){props.onChange({...props.item,item:props.item.item?.filter(i=>i!==removedItem)})}function changeProperty(property,value){props.onChange({...itemRef.current,[property]:value})}function updateItem(updatedItem){props.onChange({...props.item,...updatedItem})}function toggleRepeatable(item2){props.onChange({...props.item,item:props.item.item?.map(i=>i===item2?{...i,repeats:!i.repeats}:i)})}function moveItem(itemIndex,delta){let updatedItems=reorderItems(props.item.item,itemIndex,delta);props.onChange({...props.item,item:updatedItems})}let className=clsx_default(QuestionnaireBuilder_default.section,{[QuestionnaireBuilder_default.editing]:editing,[QuestionnaireBuilder_default.hovering]:hovering&&!editing});return jsxs76("div",{"data-testid":item.linkId,className,onClick,onMouseOver:onHover,onFocus:onHover,children:[jsx128("div",{className:QuestionnaireBuilder_default.questionBody,children:editing?jsxs76(Fragment43,{children:[isResource2&&jsx128(TextInput25,{size:"xl",defaultValue:resource.title,onBlur:e=>changeProperty("title",e.currentTarget.value)}),!isResource2&&jsx128(Textarea5,{autosize:!0,minRows:2,defaultValue:item.text,onBlur:e=>changeProperty("text",e.currentTarget.value)}),item.type==="reference"&&jsx128(ReferenceProfiles,{item,onChange:updateItem}),isChoiceQuestion(item)&&jsx128(AnswerBuilder,{item,onChange:item2=>updateItem(item2)})]}):jsxs76(Fragment43,{children:[resource.title&&jsx128(Title8,{children:resource.title}),item.text&&jsx128("div",{className:QuestionnaireBuilder_default.preserveBreaks,children:item.text}),!isContainer&&jsx128(QuestionnaireFormItem,{item,index:0,required:!1,onChange:()=>{},response:{linkId:item.linkId}})]})}),item.item?.map((item2,i)=>jsx128("div",{children:jsx128(ItemBuilder,{item:item2,selectedKey:props.selectedKey,setSelectedKey:props.setSelectedKey,hoverKey:props.hoverKey,isFirst:i===0,isLast:i===(props.item.item??[]).length-1,setHoverKey:props.setHoverKey,onChange:changeItem,onRemove:()=>removeItem(item2),onRepeatable:toggleRepeatable,onMoveUp:()=>moveItem(i,-1),onMoveDown:()=>moveItem(i,1)})},item2.id)),!isContainer&&jsx128("div",{className:QuestionnaireBuilder_default.topActions,children:editing?jsxs76(Fragment43,{children:[jsx128(TextInput25,{size:"xs",className:QuestionnaireBuilder_default.linkIdInput,defaultValue:item.linkId,onBlur:e=>changeProperty("linkId",e.currentTarget.value)}),!isContainer&&jsx128(NativeSelect12,{size:"xs",className:QuestionnaireBuilder_default.typeSelect,defaultValue:item.type,onChange:e=>changeProperty("type",e.currentTarget.value),data:[{value:"display",label:"Display"},{value:"boolean",label:"Boolean"},{value:"decimal",label:"Decimal"},{value:"integer",label:"Integer"},{value:"date",label:"Date"},{value:"dateTime",label:"Date/Time"},{value:"time",label:"Time"},{value:"string",label:"String"},{value:"text",label:"Text"},{value:"url",label:"URL"},{value:"choice",label:"Choice"},{value:"open-choice",label:"Open Choice"},{value:"attachment",label:"Attachment"},{value:"reference",label:"Reference"},{value:"quantity",label:"Quantity"}]})]}):jsx128("div",{children:linkId})}),!isResource2&&jsx128(Box8,{className:QuestionnaireBuilder_default.movementActions,children:jsxs76(Box8,{className:QuestionnaireBuilder_default.columnAlignment,children:[!props.isFirst&&jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),props.onMoveUp&&props.onMoveUp()},children:jsx128(IconArrowUp,{"data-testid":"up-button",size:15,className:QuestionnaireBuilder_default.movementIcons})}),!props.isLast&&jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),props.onMoveDown&&props.onMoveDown()},children:jsx128(IconArrowDown,{"data-testid":"down-button",size:15,className:QuestionnaireBuilder_default.movementIcons})})]})}),jsxs76("div",{className:QuestionnaireBuilder_default.bottomActions,children:[isContainer&&jsxs76(Fragment43,{children:[jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),addItem({id:generateId3(),linkId:generateLinkId("q"),type:"string",text:"Question"})},children:"Add item"}),jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),addItem({id:generateId3(),linkId:generateLinkId("g"),type:"group",text:"Group"},!0)},children:"Add group"})]}),isResource2&&jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),addItem(createPage(),!0)},children:"Add Page"}),editing&&!isResource2&&jsxs76(Fragment43,{children:[jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),props.onRepeatable&&props.onRepeatable(item)},children:item.repeats?"Remove Repeatable":"Make Repeatable"}),jsx128(Anchor13,{href:"#",onClick:e=>{e.preventDefault(),props.onRemove&&props.onRemove()},children:"Remove"})]})]})]})}function AnswerBuilder(props){let property=getElementDefinition3("QuestionnaireItemAnswerOption","value[x]"),options=props.item.answerOption??[];return jsxs76("div",{children:[props.item.answerValueSet!==void 0?jsx128(TextInput25,{placeholder:"Enter Value Set",defaultValue:props.item.answerValueSet,onChange:e=>props.onChange({...props.item,answerValueSet:e.target.value})}):jsx128(AnswerOptionsInput,{options,property,item:props.item,onChange:props.onChange}),jsxs76(Box8,{display:"flex",children:[jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange({...props.item,answerValueSet:void 0,answerOption:[...options,{id:generateId3()}]})},children:"Add choice"}),jsx128(Space2,{w:"lg"}),jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange({...props.item,answerOption:[],answerValueSet:""})},children:"Add value set"})]})]})}function AnswerOptionsInput(props){return jsx128("div",{children:props.options.map(option=>{let[propertyValue,propertyType]=getValueAndType({type:"QuestionnaireItemAnswerOption",value:option},"value");return jsxs76("div",{style:{display:"flex",flexDirection:"row",justifyContent:"space-between",alignItems:"center",width:"80%"},children:[jsx128("div",{children:jsx128(ResourcePropertyInput,{name:"value[x]",path:"Questionnaire.answerOption.value[x]",property:props.property,defaultPropertyType:propertyType,defaultValue:propertyValue,onChange:(newValue,propName)=>{let newOptions=[...props.options],index=newOptions.findIndex(o=>o.id===option.id);newOptions[index]={id:option.id,[propName]:newValue},props.onChange({...props.item,answerOption:newOptions})},outcome:void 0},option.id)}),jsx128("div",{children:jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange({...props.item,answerOption:props.options.filter(o=>o.id!==option.id)})},children:"Remove"})})]},option.id)})})}function ReferenceProfiles(props){let targetTypes=getQuestionnaireItemReferenceTargetTypes(props.item)??[];return jsxs76(Fragment43,{children:[targetTypes.map((targetType,index)=>jsxs76(Group52,{children:[jsx128(ResourceTypeInput,{name:"resourceType",placeholder:"Resource Type",defaultValue:targetType,onChange:newValue=>{props.onChange(setQuestionnaireItemReferenceTargetTypes(props.item,targetTypes.map(t=>t===targetType?newValue:t)))}}),jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange(setQuestionnaireItemReferenceTargetTypes(props.item,targetTypes.filter(t=>t!==targetType)))},children:"Remove"})]},`${targetType}-${index}`)),jsx128(Anchor13,{href:"#",onClick:e=>{killEvent(e),props.onChange(setQuestionnaireItemReferenceTargetTypes(props.item,[...targetTypes,""]))},children:"Add Resource Type"})]})}var nextLinkId=1,nextId3=1;function generateLinkId(prefix){return prefix+nextLinkId++}function generateId3(){return"id-"+nextId3++}function ensureQuestionnaireKeys(questionnaire){return{...questionnaire,id:questionnaire.id||generateId3(),item:ensureQuestionnaireItemKeys(questionnaire.item)}}function ensureQuestionnaireItemKeys(items){if(items)return items.forEach(item=>{item.id?.match(/^id-\d+$/)&&(nextId3=Math.max(nextId3,parseInt(item.id.substring(3),10)+1)),item.linkId?.match(/^q\d+$/)&&(nextLinkId=Math.max(nextLinkId,parseInt(item.linkId.substring(1),10)+1))}),items.map(item=>({...item,id:item.id||generateId3(),item:ensureQuestionnaireItemKeys(item.item),answerOption:ensureQuestionnaireOptionKeys(item.answerOption)}))}function ensureQuestionnaireOptionKeys(options){if(options)return options.map(option=>({...option,id:option.id||generateId3()}))}function createPage(){return{id:generateId3(),linkId:generateLinkId("s"),type:"group",text:"New Page",extension:[{url:"http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl",valueCodeableConcept:{coding:[{system:"http://hl7.org/fhir/questionnaire-item-control",code:"page"}]}}]}}function reorderItems(items,itemIndex,delta){let currentItems=items??[],newIndex=itemIndex+delta;if(newIndex<0||newIndex>=currentItems.length)return currentItems;let updatedItems=[...currentItems];return[updatedItems[itemIndex],updatedItems[newIndex]]=[updatedItems[newIndex],updatedItems[itemIndex]],updatedItems}import{Title as Title10}from"@mantine/core";import{createReference as createReference13}from"@medplum/core";import{useMedplum as useMedplum39,usePrevious as usePrevious2,useResource as useResource12}from"@medplum/react-hooks";import{useCallback as useCallback26,useEffect as useEffect29,useRef as useRef21,useState as useState73}from"react";import{Button as Button28,Group as Group53,Stack as Stack26,Stepper}from"@mantine/core";import{Anchor as Anchor14}from"@mantine/core";import{useState as useState71}from"react";import{jsx as jsx129,jsxs as jsxs77}from"react/jsx-runtime";function QuestionnaireRepeatableItem(props){let{item,response,onChange}=props,[number,setNumber]=useState71(getNumberOfRepeats(item,response??{linkId:item.linkId}));if(!props.checkForQuestionEnabled(item)||!response)return null;if(item.type==="display")return jsx129("p",{children:item.text},item.linkId);let showAddButton=item?.repeats&&item.type!=="choice"&&item.type!=="open-choice";return item.type==="boolean"?jsx129(QuestionnaireFormItem,{item,response,onChange:r2=>onChange([r2]),index:0},item.linkId):jsxs77(FormSection,{htmlFor:props.item.linkId,title:props.item.text,withAsterisk:props.item.required,children:[[...Array(number)].map((_,index)=>jsx129(QuestionnaireFormItem,{item,response,onChange:r2=>onChange([r2]),index},`${item.linkId}-${index}`)),showAddButton&&jsx129(Anchor14,{onClick:()=>setNumber(n=>n+1),children:"Add Item"})]},props.item.linkId)}function getNumberOfRepeats(item,response){if(item.type==="choice"||item.type==="open-choice")return 1;let answers=response.answer;return answers?.length?answers.length:1}import{Anchor as Anchor15,Stack as Stack25,Title as Title9}from"@mantine/core";import{useEffect as useEffect28,useState as useState72}from"react";import{Fragment as Fragment44,jsx as jsx130,jsxs as jsxs78}from"react/jsx-runtime";function QuestionnaireRepeatedGroup(props){let[responses,setResponses]=useState72(props.response);if(useEffect28(()=>{setResponses(props.response)},[props.response]),responses.length===0)return null;function handleRepeatableGroup(newResponseItems,index){let newResponses=responses.map((responses2,idx)=>idx===index?newResponseItems[0]:responses2);setResponses(newResponses),props.onChange(newResponses)}function insertNewGroup(){let newResponse=buildInitialResponseItem(props.item);setResponses([...responses,newResponse])}return jsxs78(Fragment44,{children:[responses.map((response,idx)=>jsx130(QuestionnaireGroup,{item:props.item,response,checkForQuestionEnabled:props.checkForQuestionEnabled,onChange:r2=>handleRepeatableGroup(r2,idx)},response.id)),props.item.repeats&&jsx130(Anchor15,{onClick:insertNewGroup,children:`Add Group: ${props.item.text}`})]})}function QuestionnaireGroup(props){let{response,checkForQuestionEnabled,onChange}=props;function onSetGroup(newResponseItem){let mergedResponse=response.item?.map(current=>newResponseItem.find(newResponse2=>newResponse2.id===current.id)??current)?.concat(newResponseItem.slice(1)),groupResponse={...response,item:mergedResponse};onChange([groupResponse])}return props.checkForQuestionEnabled(props.item)?jsxs78("div",{children:[props.item.text&&jsx130(Title9,{order:3,mb:"md",children:props.item.text}),jsx130(Stack25,{children:props.item.item?.map(item=>item.type==="group"?item.repeats?jsx130(QuestionnaireRepeatedGroup,{item,response:response.item?.filter(i=>i.linkId===item.linkId)??[],checkForQuestionEnabled,onChange:onSetGroup},item.linkId):jsx130(QuestionnaireGroup,{item,checkForQuestionEnabled,response:response.item?.find(i=>i.linkId===item.linkId)??{linkId:item.linkId},onChange:onSetGroup},item.linkId):jsx130(QuestionnaireRepeatableItem,{item,response:response.item?.find(i=>i.linkId===item.linkId),onChange:onSetGroup,checkForQuestionEnabled},item.linkId))})]},props.item.linkId):null}import{Fragment as Fragment45,jsx as jsx131,jsxs as jsxs79}from"react/jsx-runtime";function QuestionnairePageSequence(props){let{items,response,activePage,onChange,nextStep,prevStep,numberOfPages,renderPages,submitButtonText,excludeButtons,checkForQuestionEnabled}=props,form=items.map(item=>{let itemResponse=response?.item?.filter(i=>i.linkId===item.linkId)??[],repeatedItem=item.type==="group"?jsx131(QuestionnaireRepeatedGroup,{item,response:itemResponse,onChange,checkForQuestionEnabled},item.linkId):jsx131(QuestionnaireRepeatableItem,{item,response:itemResponse?.[0],onChange,checkForQuestionEnabled},item.linkId);return renderPages?jsx131(Stepper.Step,{label:item.text,children:repeatedItem},item.linkId):repeatedItem});return jsxs79(Fragment45,{children:[renderPages&&jsx131(Stepper,{active:activePage??0,allowNextStepsSelect:!1,p:6,children:form}),!renderPages&&jsx131(Stack26,{children:form}),!excludeButtons&&jsx131(ButtonGroup,{activePage:activePage??0,numberOfPages,nextStep:renderPages?nextStep:void 0,prevStep:renderPages?prevStep:void 0,renderPages,submitButtonText})]})}function ButtonGroup(props){let showBackButton=props.renderPages&&props.activePage>0,showNextButton=props.renderPages&&props.activePage<props.numberOfPages-1,showSubmitButton=!props.renderPages||props.activePage===props.numberOfPages-1;return jsxs79(Group53,{justify:"flex-end",mt:"xl",gap:"xs",children:[showBackButton&&jsx131(Button28,{onClick:props.prevStep,children:"Back"}),showNextButton&&jsx131(Button28,{onClick:e=>{let form=e.currentTarget.closest("form");props.nextStep&&form.reportValidity()&&props.nextStep()},children:"Next"}),showSubmitButton&&jsx131(Button28,{type:"submit",children:props.submitButtonText??"Submit"})]})}import{jsx as jsx132,jsxs as jsxs80}from"react/jsx-runtime";function QuestionnaireForm(props){let medplum=useMedplum39(),{subject,source:sourceFromProps}=props,questionnaire=useResource12(props.questionnaire),prevQuestionnaire=usePrevious2(questionnaire),questionnaireResponse=useResource12(props.questionnaireResponse),[response,setResponse]=useState73(questionnaireResponse),[activePage,setActivePage]=useState73(0),onChangeRef=useRef21(props.onChange);onChangeRef.current=props.onChange;let onSubmitRef=useRef21(props.onSubmit);onSubmitRef.current=props.onSubmit,useEffect29(()=>{if(questionnaireResponse?.item)setResponse(prevResponse=>updateResponseItems(prevResponse,questionnaireResponse.item,questionnaire));else{if(questionnaire&&getQuestionnaireIdentity(prevQuestionnaire)===getQuestionnaireIdentity(questionnaire))return;setResponse(questionnaire?buildInitialResponse(questionnaire):void 0)}},[questionnaireResponse,questionnaire,prevQuestionnaire]),useEffect29(()=>{if(response&&onChangeRef.current)try{onChangeRef.current(response)}catch(e){console.error("Error invoking QuestionnaireForm.onChange callback",e)}},[response]);let setItems=useCallback26(newResponseItems=>{setResponse(prevResponse=>updateResponseItems(prevResponse,newResponseItems,questionnaire))},[questionnaire]),handleSubmit=useCallback26(()=>{let onSubmit=onSubmitRef.current;if(onSubmit&&response){let source=sourceFromProps;if(!source){let profile=medplum.getProfile();profile&&(source=createReference13(profile))}onSubmit({...response,questionnaire:questionnaire?.url,subject,source,authored:new Date().toISOString(),status:"completed"})}},[medplum,questionnaire,response,subject,sourceFromProps]);function checkForQuestionEnabled(item){return isQuestionEnabled(item,response)}if(!questionnaire||!response)return null;let numberOfPages=getNumberOfPages(questionnaire),nextStep=()=>setActivePage(current=>current+1),prevStep=()=>setActivePage(current=>current-1);return jsx132(QuestionnaireFormContext.Provider,{value:{subject:props.subject,encounter:props.encounter},children:jsxs80(Form,{testid:"questionnaire-form",onSubmit:handleSubmit,children:[questionnaire.title&&jsx132(Title10,{children:questionnaire.title}),jsx132(QuestionnairePageSequence,{items:questionnaire.item??[],response,onChange:setItems,renderPages:!props.disablePagination&&numberOfPages>1,activePage,numberOfPages,excludeButtons:props.excludeButtons,submitButtonText:props.submitButtonText,checkForQuestionEnabled,nextStep,prevStep})]})})}function mergeIndividualItems(prevItem,newItem){let mergedNestedItems=mergeItems(prevItem.item??[],newItem.item??[]);return{...newItem,item:mergedNestedItems.length>0?mergedNestedItems:void 0,answer:newItem.answer&&newItem.answer.length>0?newItem.answer:prevItem.answer}}function mergeItems(prevItems,newItems){let result=[],usedIds=new Set;for(let prevItem of prevItems){let itemId=prevItem.id,newItem=newItems.find(item=>item.id===itemId);newItem?(result.push(mergeIndividualItems(prevItem,newItem)),usedIds.add(newItem.id)):result.push(prevItem)}for(let newItem of newItems)usedIds.has(newItem.id)||result.push(newItem);return result}function getQuestionnaireIdentity(questionnaire){return questionnaire?.id||questionnaire}function updateResponseItems(prevResponse,newResponseItems,questionnaire){if(!newResponseItems)return{resourceType:"QuestionnaireResponse",status:"in-progress"};let currentItems=prevResponse?.item??[],mergedItems=mergeItems(currentItems,Array.isArray(newResponseItems)?newResponseItems:[newResponseItems]),tempResponse={resourceType:"QuestionnaireResponse",status:"in-progress",item:mergedItems},updatedItems=evaluateCalculatedExpressionsInQuestionnaire(questionnaire?.item??[],tempResponse);return{resourceType:"QuestionnaireResponse",status:"in-progress",item:mergeUpdatedItems(mergedItems,updatedItems)}}import{ActionIcon as ActionIcon15,Button as Button29,Divider as Divider4,Group as Group54,NativeSelect as NativeSelect13,Stack as Stack27,Text as Text26,TextInput as TextInput26}from"@mantine/core";import{formatRange as formatRange2,getCodeBySystem}from"@medplum/core";import{useEffect as useEffect30,useState as useState74}from"react";var ReferenceRangeEditor_default={section:"ReferenceRangeEditor_section"};import{jsx as jsx133,jsxs as jsxs81}from"react/jsx-runtime";var intervalFilters=["gender","age","gestationalAge","context","appliesTo","category"],defaultProps={definition:{resourceType:"ObservationDefinition",code:{text:""}},onSubmit:()=>{}};function ReferenceRangeEditor(props){props=Object.assign(defaultProps,props);let defaultDefinition=props.definition,[intervalGroups,setIntervalGroups]=useState74([]),[groupId,setGroupId]=useState74(1),[intervalId,setIntervalId]=useState74(1);return useEffect30(()=>{let definition=ensureQualifiedIntervalKeys(defaultDefinition,setIntervalId);setIntervalGroups(groupQualifiedIntervals(definition.qualifiedInterval||[],setGroupId))},[defaultDefinition]),jsxs81(Form,{testid:"reference-range-editor",onSubmit:submitDefinition,children:[jsx133(Stack27,{children:intervalGroups.map(intervalGroup=>jsx133(ReferenceRangeGroupEditor,{unit:getUnitString(defaultDefinition.quantitativeDetails?.unit),onChange:changeInterval,onAdd:addInterval,onRemove:removeInterval,onRemoveGroup:removeGroup,intervalGroup},`group-${intervalGroup.id}`))}),jsx133(ActionIcon15,{title:"Add Group",variant:"subtle",size:"sm",onClick:e=>{killEvent(e),addGroup({id:`group-id-${groupId}`,filters:{},intervals:[]}),setGroupId(id=>id+1)},children:jsx133(IconCirclePlus,{})}),jsx133(Group54,{justify:"flex-end",children:jsx133(Button29,{type:"submit",children:"Save"})})]});function submitDefinition(){let qualifiedInterval=intervalGroups.flatMap(group=>group.intervals).filter(interval=>!isEmptyInterval(interval));props.onSubmit({...defaultDefinition,qualifiedInterval})}function addGroup(addedGroup){setIntervalGroups(currentGroups=>[...currentGroups,addedGroup])}function removeGroup(removedGroup){setIntervalGroups(currentGroups=>currentGroups.filter(group=>group.id!==removedGroup.id))}function changeInterval(groupId2,changedInterval){setIntervalGroups(groups=>{groups=[...groups];let currentGroup=groups.find(g=>g.id===groupId2),index=currentGroup?.intervals.findIndex(interval=>interval.id===changedInterval.id);return index!==void 0&¤tGroup?.intervals[index]&&(currentGroup.intervals[index]=changedInterval),groups})}function addInterval(groupId2,addedInterval){addedInterval.id===void 0&&(addedInterval.id=`id-${intervalId}`,setIntervalId(id=>id+1)),setIntervalGroups(groups=>{groups=[...groups];let currentGroupIndex=groups.findIndex(g=>g.id===groupId2);if(currentGroupIndex!==-1){let currentGroup={...groups[currentGroupIndex]};addedInterval={...addedInterval,...currentGroup.filters},currentGroup.intervals=[...currentGroup.intervals,addedInterval],groups[currentGroupIndex]=currentGroup}return groups})}function removeInterval(groupId2,removedInterval){setIntervalGroups(groups=>{groups=[...groups];let currentGroup=groups.find(g=>g.id===groupId2);return currentGroup&&(currentGroup.intervals=currentGroup.intervals.filter(interval=>interval.id!==removedInterval.id)),groups})}}function ReferenceRangeGroupEditor(props){let{intervalGroup,unit}=props;return jsx133(Container,{"data-testid":intervalGroup.id,className:ReferenceRangeEditor_default.section,children:jsxs81(Stack27,{gap:"lg",children:[jsx133(Group54,{justify:"flex-end",children:jsx133(ActionIcon15,{title:"Remove Group",variant:"subtle","data-testid":`remove-group-button-${intervalGroup.id}`,size:"sm",onClick:e=>{killEvent(e),props.onRemoveGroup(intervalGroup)},children:jsx133(IconCircleMinus,{})},`remove-group-button-${intervalGroup.id}`)}),jsx133(ReferenceRangeGroupFilters,{intervalGroup,onChange:props.onChange}),jsx133(Divider4,{}),intervalGroup.intervals.map(interval=>jsxs81(Stack27,{gap:"xs",children:[jsxs81(Group54,{children:[jsx133(TextInput26,{"data-testid":`condition-${interval.id}`,defaultValue:interval.condition,label:"Condition: ",size:"sm",onChange:e=>{killEvent(e),props.onChange(intervalGroup.id,{...interval,condition:e.currentTarget.value.trim()})}},`condition-${interval.id}`),jsx133(ActionIcon15,{title:"Remove Interval",variant:"subtle",size:"sm","data-testid":`remove-interval-${interval.id}`,onClick:e=>{killEvent(e),props.onRemove(intervalGroup.id,interval)},children:jsx133(IconCircleMinus,{})},`remove-interval-${interval.id}`)]}),jsx133(RangeInput,{path:"",onChange:range=>{props.onChange(intervalGroup.id,{...interval,range})},name:`range-${interval.id}`,defaultValue:interval.range},`range-${interval.id}`)]},`interval-${interval.id}`)),jsx133(ActionIcon15,{title:"Add Interval",variant:"subtle",size:"sm",onClick:e=>{killEvent(e),props.onAdd(intervalGroup.id,{range:{low:{unit},high:{unit}}})},children:jsx133(IconCirclePlus,{})})]})})}function ReferenceRangeGroupFilters(props){let{intervalGroup,onChange}=props;intervalGroup.filters.age||(intervalGroup.filters.age={});for(let key of["low","high"])intervalGroup.filters.age[key]?.unit||(intervalGroup.filters.age[key]={...intervalGroup.filters.age[key],unit:"years",system:"http://unitsofmeasure.org"});return jsxs81(Stack27,{style:{maxWidth:"50%"},children:[jsx133(Group54,{children:jsx133(NativeSelect13,{data:["","male","female"],label:"Gender:",defaultValue:intervalGroup.filters.gender||"",onChange:e=>{for(let interval of intervalGroup.intervals){let newGender=e.currentTarget.value;newGender===""&&(newGender=void 0),onChange(intervalGroup.id,{...interval,gender:newGender})}}})}),jsxs81(Group54,{gap:"xs",children:[jsx133(Text26,{component:"label",htmlFor:`div-age-${intervalGroup.id}`,children:"Age:"}),jsx133("div",{id:`div-age-${intervalGroup.id}`,children:jsx133(RangeInput,{path:"",name:`age-${intervalGroup.id}`,defaultValue:intervalGroup.filters.age,onChange:ageRange=>{for(let interval of intervalGroup.intervals)onChange(intervalGroup.id,{...interval,age:ageRange})}},`age-${intervalGroup.id}`)})]}),jsx133(NativeSelect13,{data:["","pre-puberty","follicular","midcycle","luteal","postmenopausal"],label:"Endocrine:",defaultValue:intervalGroup.filters.context?.text||"",onChange:e=>{for(let interval of intervalGroup.intervals){let newEndocrine=e.currentTarget.value;newEndocrine===""?(newEndocrine=void 0,onChange(intervalGroup.id,{...interval,context:void 0})):onChange(intervalGroup.id,{...interval,context:{text:newEndocrine,coding:[{code:newEndocrine,system:"http://terminology.hl7.org/CodeSystem/referencerange-meaning"}]}})}}}),jsx133(NativeSelect13,{data:["","reference","critical","absolute"],label:"Category: ",defaultValue:intervalGroup.filters.category,onChange:e=>{for(let interval of intervalGroup.intervals){let newCategory=e.currentTarget.value;newCategory===""?onChange(intervalGroup.id,{...interval,category:void 0}):onChange(intervalGroup.id,{...interval,category:newCategory})}}})]})}function ensureQualifiedIntervalKeys(definition,setIntervalId){let intervals=definition.qualifiedInterval||[],nextId4=Math.max(...intervals.map(interval=>{let existingNum=parseInt(interval.id?.substring(3)||"",10);return isNaN(existingNum)?Number.NEGATIVE_INFINITY:existingNum}))+1;return Number.isFinite(nextId4)||(nextId4=1),definition={...definition,qualifiedInterval:intervals.map(interval=>({...interval,id:interval.id||`id-${nextId4++}`}))},setIntervalId(nextId4),definition}function groupQualifiedIntervals(intervals,setGroupId){let groupId=1,groups={};for(let interval of intervals){let groupKey=generateGroupKey(interval);groupKey in groups||(groups[groupKey]={id:`group-id-${groupId++}`,filters:Object.fromEntries(intervalFilters.map(f=>[f,interval[f]])),intervals:[]}),groups[groupKey].intervals.push(interval)}return setGroupId(groupId),Object.values(groups)}function generateGroupKey(interval){return[`gender=${interval.gender}`,`age=${formatRange2(interval.age)}`,`gestationalAge=${formatRange2(interval.gestationalAge)}`,`context=${interval.context?.text}`,`appliesTo=${interval.appliesTo?.map(c=>c.text).join("+")}`,`category=${interval.category}`].join(":")}function getUnitString(unit){return unit&&(getCodeBySystem(unit,"http://unitsofmeasure.org")||unit.text)}function isEmptyInterval(interval){return interval.range?.low?.value===void 0&&interval.range?.high?.value===void 0}import{Button as Button30,Grid as Grid4,Text as Text27}from"@mantine/core";import{formatDateTime as formatDateTime6,getReferenceString as getReferenceString9}from"@medplum/core";import{useMedplum as useMedplum40,useResource as useResource13}from"@medplum/react-hooks";import{Fragment as Fragment46,useEffect as useEffect31,useState as useState75}from"react";import{jsx as jsx134,jsxs as jsxs82}from"react/jsx-runtime";function RequestGroupDisplay(props){let medplum=useMedplum40(),requestGroup=useResource13(props.value),[startedLoading,setStartedLoading]=useState75(!1),[responseBundle,setResponseBundle]=useState75();if(useEffect31(()=>{requestGroup&&!startedLoading&&(medplum.executeBatch(buildBatchRequest(requestGroup)).then(setResponseBundle).catch(console.log),setStartedLoading(!0))},[medplum,requestGroup,startedLoading]),!requestGroup||!responseBundle)return null;return jsx134(Grid4,{children:requestGroup.action?.map((action,index)=>{let task=action.resource&&findBundleEntry(action.resource),taskInput=task?.input?.[0]?.valueReference,taskOutput=task?.output?.[0]?.valueReference;return jsxs82(Fragment46,{children:[jsx134(Grid4.Col,{span:1,p:"md",children:task?.status==="completed"?jsx134(IconCheckbox,{}):jsx134(IconSquare,{color:"gray"})}),jsxs82(Grid4.Col,{span:9,p:"xs",children:[jsx134(Text27,{fw:500,children:action.title}),action.description&&jsx134("div",{children:action.description}),jsxs82("div",{children:["Last edited by\xA0",jsx134(ResourceName,{value:task?.meta?.author}),"\xA0on\xA0",formatDateTime6(task?.meta?.lastUpdated)]}),jsxs82("div",{children:["Status: ",jsx134(StatusBadge,{status:task?.status||"unknown"})]})]}),jsxs82(Grid4.Col,{span:2,p:"md",children:[taskInput&&!taskOutput&&jsx134(Button30,{onClick:()=>props.onStart(task,taskInput),children:"Start"}),taskInput&&taskOutput&&jsx134(Button30,{onClick:()=>props.onEdit(task,taskInput,taskOutput),children:"Edit"})]})]},`action-${index}`)})});function buildBatchRequest(request){let batchEntries=[];if(request.action)for(let action of request.action)action.resource?.reference&&batchEntries.push({request:{method:"GET",url:action.resource.reference}});return{resourceType:"Bundle",type:"batch",entry:batchEntries}}function findBundleEntry(reference){for(let entry of responseBundle?.entry??[])if(entry.resource&&reference.reference===getReferenceString9(entry.resource))return entry.resource}}import{useMedplum as useMedplum41}from"@medplum/react-hooks";import{useEffect as useEffect32,useState as useState76}from"react";import{stringify as stringify4}from"@medplum/core";function diff(original,revised){let path=buildPath(original,revised);return buildRevisions(path,original,revised)}function buildPath(orig,rev){let N=orig.length,M=rev.length,MAX=N+M+1,size=1+2*MAX,middle=size/2|0,diagonal=new Array(size);diagonal[middle+1]={i:0,j:-1,prev:void 0,snake:!0};for(let d=0;d<MAX;d++){for(let k=-d;k<=d;k+=2){let kmiddle=middle+k,kplus=kmiddle+1,kminus=kmiddle-1,kplusNode=diagonal[kplus],kminusNode=diagonal[kminus],prev,i=0;k===-d||k!==d&&kminusNode.i<kplusNode.i?(i=kplusNode.i,prev=kplusNode):(i=kminusNode.i+1,prev=kminusNode),diagonal[kminus]=void 0;let j=i-k,node={i,j,prev:previousSnake(prev),snake:!1};for(;i<N&&j<M&&orig[i]===rev[j];)i++,j++;if(i>node.i&&(node={i,j,prev:node,snake:!0}),diagonal[kmiddle]=node,i>=N&&j>=M)return diagonal[kmiddle]}diagonal[middle+d-1]=void 0}}function buildRevisions(startNode,orig,rev){let deltas=[],path=startNode;for(path.snake&&(path=path.prev);path?.prev&&path.prev.j>=0;){let i=path.i,j=path.j;path=path.prev;let ianchor=path.i,janchor=path.j,original={position:ianchor,lines:orig.slice(ianchor,i)},revised={position:janchor,lines:rev.slice(janchor,j)},type;original.lines.length===0&&revised.lines.length>0?type="insert":original.lines.length>0&&revised.lines.length===0?type="delete":type="change",deltas.push({original,revised,type}),path.snake&&(path=path.prev)}return deltas}function previousSnake(node){return node&&!node.snake&&node.prev?node.prev:node}function blame(history){let versions=(history.entry??[]).filter(entry=>!!entry.resource).map(entry=>({meta:entry.resource?.meta,lines:stringify4(entry.resource,!0).match(/[^\r\n]+/g)})).sort((a,b)=>a.meta.lastUpdated.localeCompare(b.meta.lastUpdated));if(!versions.length)return[];let table=versions[0].lines.map(line=>({id:versions[0].meta.versionId,meta:versions[0].meta,value:line,span:1}));return compareVersions(table,versions),combineSpans(table),table}function compareVersions(table,versions){for(let i=1;i<versions.length;i++){let revisions=diff(versions[i-1].lines,versions[i].lines);for(let revision of revisions){let position=revision.original.position,oldLines=revision.original.lines,newLines=revision.revised.lines;if((revision.type==="delete"||revision.type==="change")&&table.splice(position,oldLines.length),revision.type==="insert"||revision.type==="change")for(let k=0;k<revision.revised.lines.length;k++)table.splice(position+k,0,{id:versions[i].meta.versionId,meta:versions[i].meta,value:newLines[k],span:1})}}}function combineSpans(table){let start=0;for(;start<table.length;){let curr=start;for(;curr<table.length&&table[curr].id===table[start].id;)table[curr].span=-1,curr++;table[start].span=curr-start,start=curr}}var ResourceBlame_default={container:"ResourceBlame_container",root:"ResourceBlame_root",startRow:"ResourceBlame_startRow",normalRow:"ResourceBlame_normalRow",author:"ResourceBlame_author",dateTime:"ResourceBlame_dateTime",lineNumber:"ResourceBlame_lineNumber",line:"ResourceBlame_line",pre:"ResourceBlame_pre"};function getVersionUrl(resource,versionId){return`/${resource.resourceType}/${resource.id}/_history/${versionId}`}function getTimeString(lastUpdated){let seconds=Math.floor((Date.now()-Date.parse(lastUpdated))/1e3),years=Math.floor(seconds/31536e3);if(years>0)return pluralizeTime(years,"year");let months=Math.floor(seconds/2592e3);if(months>0)return pluralizeTime(months,"month");let days=Math.floor(seconds/86400);if(days>0)return pluralizeTime(days,"day");let hours=Math.floor(seconds/3600);if(hours>0)return pluralizeTime(hours,"hour");let minutes=Math.floor(seconds/60);return minutes>0?pluralizeTime(minutes,"minute"):pluralizeTime(seconds,"second")}function pluralizeTime(count,noun){return`${count} ${count===1?noun:noun+"s"} ago`}import{Fragment as Fragment47,jsx as jsx135,jsxs as jsxs83}from"react/jsx-runtime";function ResourceBlame(props){let medplum=useMedplum41(),[value,setValue]=useState76(props.history);if(useEffect32(()=>{!props.history&&props.resourceType&&props.id&&medplum.readHistory(props.resourceType,props.id).then(setValue).catch(console.log)},[medplum,props.history,props.resourceType,props.id]),!value)return jsx135("div",{children:"Loading..."});let resource=value.entry?.[0]?.resource;if(!resource)return null;let table=blame(value);return jsx135("div",{className:ResourceBlame_default.container,children:jsx135("table",{className:ResourceBlame_default.root,children:jsx135("tbody",{children:table.map((row,index)=>jsxs83("tr",{className:row.span>0?ResourceBlame_default.startRow:ResourceBlame_default.normalRow,children:[row.span>0&&jsxs83(Fragment47,{children:[jsx135("td",{className:ResourceBlame_default.author,rowSpan:row.span,children:jsx135(ResourceBadge,{value:row.meta.author,link:!0})}),jsx135("td",{className:ResourceBlame_default.dateTime,rowSpan:row.span,children:jsx135(MedplumLink,{to:getVersionUrl(resource,row.meta.versionId),children:getTimeString(row.meta.lastUpdated)})})]}),jsx135("td",{className:ResourceBlame_default.lineNumber,children:index+1}),jsx135("td",{className:ResourceBlame_default.line,children:jsx135("pre",{className:ResourceBlame_default.pre,children:row.value})})]},"row-"+index))})})})}import{stringify as stringify5}from"@medplum/core";var ResourceDiff_default={removed:"ResourceDiff_removed",added:"ResourceDiff_added"};import{Fragment as Fragment48,jsx as jsx136,jsxs as jsxs84}from"react/jsx-runtime";function ResourceDiff(props){let originalResource=props.original,revisedResource=props.revised;props.ignoreMeta&&(originalResource={...originalResource,meta:void 0},revisedResource={...revisedResource,meta:void 0});let original=stringify5(originalResource,!0).match(/[^\r\n]+/g),revised=stringify5(revisedResource,!0).match(/[^\r\n]+/g),deltas=diff(original,revised);return jsx136("pre",{style:{color:"gray"},children:deltas.map((delta,index)=>jsx136(ChangeDiff,{delta},"delta"+index))})}function ChangeDiff(props){return jsxs84(Fragment48,{children:["...",jsx136("br",{}),props.delta.original.lines.length>0&&jsx136("div",{className:ResourceDiff_default.removed,children:props.delta.original.lines.join(`
|
|
72
72
|
`)}),props.delta.revised.lines.length>0&&jsx136("div",{className:ResourceDiff_default.added,children:props.delta.revised.lines.join(`
|
|
73
|
-
`)}),"...",jsx136("br",{})]})}import{ActionIcon as ActionIcon16,Alert as Alert5,Button as Button31,Group as Group55,Menu as Menu6,Stack as Stack28,TextInput as TextInput27,useMantineTheme}from"@mantine/core";import{AccessPolicyInteraction as AccessPolicyInteraction2,applyDefaultValuesToResource,canWriteResourceType,isPopulated as isPopulated12,satisfiedAccessPolicy as satisfiedAccessPolicy2,tryGetProfile as tryGetProfile5}from"@medplum/core";import{useMedplum as useMedplum42,useResource as useResource14}from"@medplum/react-hooks";import{useEffect as useEffect33,useMemo as useMemo30,useState as useState77}from"react";var ResourceForm_default={splitButton:"ResourceForm_splitButton",menuControl:"ResourceForm_menuControl"};import{jsx as jsx137,jsxs as jsxs85}from"react/jsx-runtime";function ResourceForm(props){let{outcome}=props,medplum=useMedplum42(),defaultValue2=useResource14(props.defaultValue),resourceType=defaultValue2?.resourceType,[schemaLoaded,setSchemaLoaded]=useState77(!1),[value,setValue]=useState77(),accessPolicy=medplum.getAccessPolicy(),theme=useMantineTheme();useEffect33(()=>{if(defaultValue2)if(props.profileUrl){let profileUrl=props.profileUrl;medplum.requestProfileSchema(props.profileUrl,{expandProfile:!0}).then(()=>{let profile=tryGetProfile5(profileUrl);if(profile){setSchemaLoaded(!0);let modifiedDefaultValue=applyDefaultValuesToResource(defaultValue2,profile);setValue(modifiedDefaultValue)}else console.error(`Schema not found for ${profileUrl}`)}).catch(reason=>{console.error("Error in requestProfileSchema",reason)})}else medplum.requestSchema(resourceType).then(()=>{setValue(defaultValue2),setSchemaLoaded(!0)}).catch(console.log)},[medplum,defaultValue2,resourceType,props.profileUrl]);let accessPolicyResource=useMemo30(()=>defaultValue2&&satisfiedAccessPolicy2(defaultValue2,AccessPolicyInteraction2.READ,accessPolicy),[accessPolicy,defaultValue2]),canWrite=useMemo30(()=>medplum.isSuperAdmin()||!accessPolicy||!isPopulated12(value?.resourceType)?!0:canWriteResourceType(accessPolicy,value?.resourceType),[medplum,accessPolicy,value?.resourceType]);return!schemaLoaded||!value?jsx137("div",{children:"Loading..."}):canWrite?jsxs85("form",{noValidate:!0,autoComplete:"off",onSubmit:e=>{e.preventDefault(),props.onSubmit&&props.onSubmit(value)},children:[jsxs85(Stack28,{mb:"xl",children:[jsx137(FormSection,{title:"Resource Type",htmlFor:"resourceType",outcome,children:jsx137(TextInput27,{name:"resourceType",defaultValue:value.resourceType,disabled:!0})}),jsx137(FormSection,{title:"ID",htmlFor:"id",outcome,children:jsx137(TextInput27,{name:"id",defaultValue:value.id,disabled:!0})})]}),jsx137(BackboneElementInput,{path:value.resourceType,valuePath:value.resourceType,typeName:resourceType,defaultValue:value,outcome,onChange:setValue,profileUrl:props.profileUrl,accessPolicyResource}),jsxs85(Group55,{justify:"flex-end",mt:"xl",wrap:"nowrap",gap:0,children:[jsx137(Button31,{type:"submit",className:clsx_default((props.onPatch||props.onDelete)&&ResourceForm_default.splitButton),children:defaultValue2?.id?"Update":"Create"}),(props.onPatch||props.onDelete)&&jsxs85(Menu6,{transitionProps:{transition:"pop"},position:"bottom-end",withinPortal:!0,children:[jsx137(Menu6.Target,{children:jsx137(ActionIcon16,{variant:"filled",color:theme.primaryColor,size:36,className:ResourceForm_default.menuControl,"aria-label":"More actions",children:jsx137(IconChevronDown,{size:14,stroke:1.5})})}),jsxs85(Menu6.Dropdown,{children:[props.onPatch&&jsx137(Menu6.Item,{leftSection:jsx137(IconEdit,{size:14,stroke:1.5}),onClick:()=>{props.onPatch(value)},children:"Patch"}),props.onDelete&&jsx137(Menu6.Item,{color:"red",leftSection:jsx137(IconTrash,{size:14,stroke:1.5,color:"red"}),onClick:()=>{props.onDelete(value)},children:"Delete"})]})]})]})]}):jsxs85(Alert5,{color:"red",title:"Permission denied",icon:jsx137(IconAlertCircle,{}),children:["Your access level prevents you from editing and creating ",value.resourceType," resources."]})}import{Table as Table5}from"@mantine/core";import{formatDateTime as formatDateTime7,normalizeErrorString as normalizeErrorString10}from"@medplum/core";import{useMedplum as useMedplum43}from"@medplum/react-hooks";import{useEffect as useEffect34,useState as useState78}from"react";import{jsx as jsx138,jsxs as jsxs86}from"react/jsx-runtime";function ResourceHistoryTable(props){let medplum=useMedplum43(),[value,setValue]=useState78(props.history);return useEffect34(()=>{!props.history&&props.resourceType&&props.id&&medplum.readHistory(props.resourceType,props.id).then(setValue).catch(console.log)},[medplum,props.history,props.resourceType,props.id]),value?jsxs86(Table5,{withTableBorder:!0,withRowBorders:!0,withColumnBorders:!0,children:[jsx138(Table5.Thead,{children:jsxs86(Table5.Tr,{children:[jsx138(Table5.Th,{children:"Author"}),jsx138(Table5.Th,{children:"Date"}),jsx138(Table5.Th,{children:"Version"})]})}),jsx138(Table5.Tbody,{children:value.entry?.map((entry,index)=>jsx138(HistoryRow,{entry},"entry-"+index))})]}):jsx138("div",{children:"Loading..."})}function HistoryRow(props){let{response,resource}=props.entry;return resource?jsxs86(Table5.Tr,{children:[jsx138(Table5.Td,{children:jsx138(ResourceBadge,{value:resource.meta?.author,link:!0})}),jsx138(Table5.Td,{children:formatDateTime7(resource.meta?.lastUpdated)}),jsx138(Table5.Td,{children:jsx138(MedplumLink,{to:getVersionUrl2(resource),children:resource.meta?.versionId})})]}):jsx138(Table5.Tr,{children:jsx138(Table5.Td,{colSpan:3,children:normalizeErrorString10(response?.outcome)})})}function getVersionUrl2(resource){return`/${resource.resourceType}/${resource.id}/_history/${resource.meta?.versionId}`}import{Button as Button32,Stack as Stack29,Text as Text28}from"@mantine/core";import{getReferenceString as getReferenceString11,isReference as isReference3}from"@medplum/core";import{useResource as useResource15,useSearchResources}from"@medplum/react-hooks";import{useState as useState79}from"react";var Scheduler_default={container:"Scheduler_container",info:"Scheduler_info",selection:"Scheduler_selection"};import{jsx as jsx139,jsxs as jsxs87}from"react/jsx-runtime";function Scheduler(props){let schedule=useResource15(props.schedule),questionnaire=useResource15(props.questionnaire),[month,setMonth]=useState79(getStartMonth()),[date,setDate]=useState79(),[slot,setSlot]=useState79(),[response,setResponse]=useState79(),[slots]=useSearchResources("Slot",new URLSearchParams([["_count",(30*24).toString()],["schedule",isReference3(props.schedule)?props.schedule.reference:getReferenceString11(props.schedule)],["start","gt"+getStart2(month)],["start","lt"+getEnd2(month)]]));if(!schedule||!slots||!questionnaire)return null;let actor=schedule.actor?.[0];return jsxs87("div",{className:Scheduler_default.container,"data-testid":"scheduler",children:[jsxs87("div",{className:Scheduler_default.info,children:[actor&&jsx139(ResourceAvatar,{value:actor,size:"xl"}),actor&&jsx139(Text28,{size:"xl",fw:500,children:jsx139(ResourceName,{value:actor})}),jsx139("p",{children:"1 hour"}),date&&jsx139("p",{children:date.toLocaleDateString()}),slot&&jsx139("p",{children:formatTime(new Date(slot.start))})]}),jsxs87("div",{className:Scheduler_default.selection,children:[!date&&jsxs87("div",{children:[jsx139("h3",{children:"Select date"}),jsx139(CalendarInput,{slots,onChangeMonth:setMonth,onClick:setDate})]}),date&&!slot&&jsxs87("div",{children:[jsx139("h3",{children:"Select time"}),jsx139(Stack29,{children:slots.map(s=>{let slotStart=new Date(s.start);return slotStart.getTime()>date.getTime()&&slotStart.getTime()<date.getTime()+24*3600*1e3&&jsx139("div",{children:jsx139(Button32,{variant:"outline",style:{width:150},onClick:()=>setSlot(s),children:formatTime(slotStart)})},s.id)})})]}),date&&slot&&!response&&jsx139(QuestionnaireForm,{questionnaire,submitButtonText:"Next",onSubmit:setResponse}),date&&slot&&response&&jsxs87("div",{children:[jsx139("h3",{children:"You're all set!"}),jsx139("p",{children:"Check your email for a calendar invite."})]})]})]})}function getStart2(month){return formatSlotInstant(month.getTime())}function getEnd2(month){return formatSlotInstant(month.getTime()+31*24*60*60*1e3)}function formatSlotInstant(time){let date=new Date(Math.max(Date.now(),time));return date.setHours(0,0,0,0),date.toISOString()}function formatTime(date){return date.toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}import{createReference as createReference14}from"@medplum/core";import{jsx as jsx140}from"react/jsx-runtime";function ServiceRequestTimeline(props){let{serviceRequest,...rest}=props;return jsx140(ResourceTimeline,{value:serviceRequest,loadTimelineResources:async(medplum,resourceType,id)=>{let ref=`${resourceType}/${id}`,_count=100;return Promise.allSettled([medplum.readHistory("ServiceRequest",id),medplum.search("Communication",{"based-on":ref,_count}),medplum.search("DiagnosticReport",{"based-on":ref,_count}),medplum.search("Media",{"based-on":ref,_count}),medplum.search("DocumentReference",{related:ref,_count}),medplum.search("Task",{_filter:`based-on eq ${ref} or focus eq ${ref} or subject eq ${ref}`,_count})])},createCommunication:(resource,sender,text)=>({resourceType:"Communication",status:"completed",basedOn:[createReference14(resource)],subject:resource.subject,sender:createReference14(sender),sent:new Date().toISOString(),payload:[{contentString:text}]}),createMedia:(resource,operator,content)=>({resourceType:"Media",status:"completed",basedOn:[createReference14(resource)],subject:resource.subject,operator:createReference14(operator),issued:new Date().toISOString(),content}),...rest})}import{Anchor as Anchor16}from"@mantine/core";import{showNotification as showNotification8}from"@mantine/notifications";import{ensureTrailingSlash,normalizeErrorString as normalizeErrorString11}from"@medplum/core";import{useMedplum as useMedplum44}from"@medplum/react-hooks";import{jsx as jsx141}from"react/jsx-runtime";function SmartAppLaunchLink(props){let medplum=useMedplum44(),{client,patient,encounter,children,...rest}=props;function launchApp(){medplum.createResource({resourceType:"SmartAppLaunch",patient,encounter}).then(result=>{let url=new URL(client.launchUri);url.searchParams.set("iss",ensureTrailingSlash(medplum.fhirUrl().toString())),url.searchParams.set("launch",result.id),window.location.assign(url.toString())}).catch(err=>showNotification8({color:"red",message:normalizeErrorString11(err),autoClose:!1}))}return jsx141(Anchor16,{onClick:()=>launchApp(),...rest,children})}export{AddressDisplay,AddressInput,AnnotationInput,AppShell,AsyncAutocomplete,AttachmentArrayDisplay,AttachmentArrayInput,AttachmentButton,AttachmentDisplay,AttachmentInput,BackboneElementDisplay,BackboneElementInput,BaseChat,CalendarInput,ChatModal,CheckboxFormSection,CodeInput,CodeableConceptDisplay,CodeableConceptInput,CodingDisplay,CodingInput,ContactDetailDisplay,ContactDetailInput,ContactPointDisplay,ContactPointInput,Container,DateTimeInput,DefaultResourceTimeline,DescriptionList,DescriptionListEntry,DiagnosticReportDisplay,Document,ElementDefinitionInputSelector,ElementDefinitionTypeInput,EncounterTimeline,ErrorBoundary,FhirPathTable,Form,FormSection,Header,HumanNameDisplay,HumanNameInput,IdentifierDisplay,IdentifierInput,Loading,Logo,MeasureReportDisplay,MedplumLink,MemoizedFhirPathTable,MemoizedSearchControl,MoneyDisplay,MoneyInput,Navbar,NoteDisplay,NotificationIcon,ObservationTable,OperationOutcomeAlert,Panel,PatientExportForm,PatientSummary,PatientTimeline,PlanDefinitionBuilder,QuantityDisplay,QuantityInput,QuestionnaireBuilder,QuestionnaireForm,QuestionnaireFormContext,QuestionnaireItemType,RangeDisplay,RangeInput,RatioInput,ReferenceDisplay,ReferenceInput,ReferenceRangeEditor,ReferenceRangeGroupEditor,RegisterForm,RequestGroupDisplay,ResourceArrayDisplay,ResourceArrayInput,ResourceAvatar,ResourceBadge,ResourceBlame,ResourceDiff,ResourceForm,ResourceHistoryTable,ResourceInput,ResourceName,ResourcePropertyDisplay,ResourcePropertyInput,ResourceTable,ResourceTimeline,Scheduler,SearchChangeEvent,SearchClickEvent,SearchControl,SearchFieldEditor,SearchFilterEditor,SearchLoadEvent,ServiceRequestTimeline,SignInForm,SmartAppLaunchLink,StatusBadge,ThreadChat,Timeline,TimelineItem,TimingInput,ValueSetAutocomplete,addDateFilterBetween,addField,addFilter,addLastMonthFilter,addMissingFilter,addNextMonthFilter,addThisMonthFilter,addTodayFilter,addTomorrowFilter,addYearToDateFilter,addYesterdayFilter,buildFieldNameString,buildInitialResponse,buildInitialResponseItem,clearFilters,clearFiltersOnField,convertIsoToLocal,convertLocalToIso,createScriptTag,deleteFilter,evaluateCalculatedExpressionsInQuestionnaire,getErrorsForInput,getFieldDefinitions,getIssuesForExpression,getItemAnswerOptionValue,getItemEnableWhenValueAnswer,getItemInitialValue,getNewMultiSelectValues,getNumberOfPages,getOpString,getQuestionnaireItemReferenceFilter,getQuestionnaireItemReferenceTargetTypes,getRecaptcha,getResponseItemAnswerValue,getSearchOperators,getSortField,getValuePath,initRecaptcha,isCheckboxCell,isChoiceQuestion,isQuestionEnabled,isSortDescending,isSupportedProfileStructureDefinition,killEvent,mergeUpdatedItems,parseForm,renderValue,sendCommand,setFilters,setOffset,setPage,setPropertyValue,setQuestionnaireItemReferenceTargetTypes,setSort,sortByDateAndPriority,toggleSort,typedValueToResponseItem};
|
|
73
|
+
`)}),"...",jsx136("br",{})]})}import{ActionIcon as ActionIcon16,Alert as Alert5,Button as Button31,Group as Group55,Menu as Menu6,Stack as Stack28,TextInput as TextInput27,useMantineTheme}from"@mantine/core";import{AccessPolicyInteraction as AccessPolicyInteraction2,applyDefaultValuesToResource,canWriteResourceType,isPopulated as isPopulated12,satisfiedAccessPolicy as satisfiedAccessPolicy2,tryGetProfile as tryGetProfile5}from"@medplum/core";import{useMedplum as useMedplum42,useResource as useResource14}from"@medplum/react-hooks";import{useEffect as useEffect33,useMemo as useMemo30,useState as useState77}from"react";var ResourceForm_default={splitButton:"ResourceForm_splitButton",menuControl:"ResourceForm_menuControl"};import{jsx as jsx137,jsxs as jsxs85}from"react/jsx-runtime";function ResourceForm(props){let{outcome}=props,medplum=useMedplum42(),defaultValue2=useResource14(props.defaultValue),resourceType=defaultValue2?.resourceType,[schemaLoaded,setSchemaLoaded]=useState77(!1),[value,setValue]=useState77(),accessPolicy=medplum.getAccessPolicy(),theme=useMantineTheme();useEffect33(()=>{if(defaultValue2)if(props.profileUrl){let profileUrl=props.profileUrl;medplum.requestProfileSchema(props.profileUrl,{expandProfile:!0}).then(()=>{let profile=tryGetProfile5(profileUrl);if(profile){setSchemaLoaded(!0);let modifiedDefaultValue=applyDefaultValuesToResource(defaultValue2,profile);setValue(modifiedDefaultValue)}else console.error(`Schema not found for ${profileUrl}`)}).catch(reason=>{console.error("Error in requestProfileSchema",reason)})}else medplum.requestSchema(resourceType).then(()=>{setValue(defaultValue2),setSchemaLoaded(!0)}).catch(console.log)},[medplum,defaultValue2,resourceType,props.profileUrl]);let accessPolicyResource=useMemo30(()=>defaultValue2&&satisfiedAccessPolicy2(defaultValue2,AccessPolicyInteraction2.READ,accessPolicy),[accessPolicy,defaultValue2]),canWrite=useMemo30(()=>medplum.isSuperAdmin()||!accessPolicy||!isPopulated12(value?.resourceType)?!0:canWriteResourceType(accessPolicy,value?.resourceType),[medplum,accessPolicy,value?.resourceType]);return!schemaLoaded||!value?jsx137("div",{children:"Loading..."}):canWrite?jsxs85("form",{noValidate:!0,autoComplete:"off",onSubmit:e=>{e.preventDefault(),props.onSubmit&&props.onSubmit(value)},children:[jsxs85(Stack28,{mb:"xl",children:[jsx137(FormSection,{title:"Resource Type",htmlFor:"resourceType",outcome,children:jsx137(TextInput27,{name:"resourceType",defaultValue:value.resourceType,disabled:!0})}),jsx137(FormSection,{title:"ID",htmlFor:"id",outcome,children:jsx137(TextInput27,{name:"id",defaultValue:value.id,disabled:!0})})]}),jsx137(BackboneElementInput,{path:value.resourceType,valuePath:value.resourceType,typeName:resourceType,defaultValue:value,outcome,onChange:setValue,profileUrl:props.profileUrl,accessPolicyResource}),jsxs85(Group55,{justify:"flex-end",mt:"xl",wrap:"nowrap",gap:0,children:[jsx137(Button31,{type:"submit",className:clsx_default((props.onPatch||props.onDelete)&&ResourceForm_default.splitButton),children:defaultValue2?.id?"Update":"Create"}),(props.onPatch||props.onDelete)&&jsxs85(Menu6,{transitionProps:{transition:"pop"},position:"bottom-end",withinPortal:!0,children:[jsx137(Menu6.Target,{children:jsx137(ActionIcon16,{variant:"filled",color:theme.primaryColor,size:36,className:ResourceForm_default.menuControl,"aria-label":"More actions",children:jsx137(IconChevronDown,{size:14,stroke:1.5})})}),jsxs85(Menu6.Dropdown,{children:[props.onPatch&&jsx137(Menu6.Item,{leftSection:jsx137(IconEdit,{size:14,stroke:1.5}),onClick:()=>{props.onPatch(value)},children:"Patch"}),props.onDelete&&jsx137(Menu6.Item,{color:"red",leftSection:jsx137(IconTrash,{size:14,stroke:1.5,color:"red"}),onClick:()=>{props.onDelete(value)},children:"Delete"})]})]})]})]}):jsxs85(Alert5,{color:"red",title:"Permission denied",icon:jsx137(IconAlertCircle,{}),children:["Your access level prevents you from editing and creating ",value.resourceType," resources."]})}import{Table as Table5}from"@mantine/core";import{formatDateTime as formatDateTime7,normalizeErrorString as normalizeErrorString10}from"@medplum/core";import{useMedplum as useMedplum43}from"@medplum/react-hooks";import{useEffect as useEffect34,useState as useState78}from"react";import{jsx as jsx138,jsxs as jsxs86}from"react/jsx-runtime";function ResourceHistoryTable(props){let medplum=useMedplum43(),[value,setValue]=useState78(props.history);return useEffect34(()=>{!props.history&&props.resourceType&&props.id&&medplum.readHistory(props.resourceType,props.id).then(setValue).catch(console.log)},[medplum,props.history,props.resourceType,props.id]),value?jsxs86(Table5,{withTableBorder:!0,withRowBorders:!0,withColumnBorders:!0,children:[jsx138(Table5.Thead,{children:jsxs86(Table5.Tr,{children:[jsx138(Table5.Th,{children:"Author"}),jsx138(Table5.Th,{children:"Date"}),jsx138(Table5.Th,{children:"Version"})]})}),jsx138(Table5.Tbody,{children:value.entry?.map((entry,index)=>jsx138(HistoryRow,{entry},"entry-"+index))})]}):jsx138("div",{children:"Loading..."})}function HistoryRow(props){let{response,resource}=props.entry;return resource?jsxs86(Table5.Tr,{children:[jsx138(Table5.Td,{children:jsx138(ResourceBadge,{value:resource.meta?.author,link:!0})}),jsx138(Table5.Td,{children:formatDateTime7(resource.meta?.lastUpdated)}),jsx138(Table5.Td,{children:jsx138(MedplumLink,{to:getVersionUrl2(resource),children:resource.meta?.versionId})})]}):jsx138(Table5.Tr,{children:jsx138(Table5.Td,{colSpan:3,children:normalizeErrorString10(response?.outcome)})})}function getVersionUrl2(resource){return`/${resource.resourceType}/${resource.id}/_history/${resource.meta?.versionId}`}import{Button as Button32,Stack as Stack29,Text as Text28}from"@mantine/core";import{getReferenceString as getReferenceString10,isReference as isReference3}from"@medplum/core";import{useResource as useResource15,useSearchResources}from"@medplum/react-hooks";import{useState as useState79}from"react";var Scheduler_default={container:"Scheduler_container",info:"Scheduler_info",selection:"Scheduler_selection"};import{jsx as jsx139,jsxs as jsxs87}from"react/jsx-runtime";function Scheduler(props){let schedule=useResource15(props.schedule),questionnaire=useResource15(props.questionnaire),[month,setMonth]=useState79(getStartMonth()),[date,setDate]=useState79(),[slot,setSlot]=useState79(),[response,setResponse]=useState79(),[slots]=useSearchResources("Slot",new URLSearchParams([["_count",(30*24).toString()],["schedule",isReference3(props.schedule)?props.schedule.reference:getReferenceString10(props.schedule)],["start","gt"+getStart2(month)],["start","lt"+getEnd2(month)]]));if(!schedule||!slots||!questionnaire)return null;let actor=schedule.actor?.[0];return jsxs87("div",{className:Scheduler_default.container,"data-testid":"scheduler",children:[jsxs87("div",{className:Scheduler_default.info,children:[actor&&jsx139(ResourceAvatar,{value:actor,size:"xl"}),actor&&jsx139(Text28,{size:"xl",fw:500,children:jsx139(ResourceName,{value:actor})}),jsx139("p",{children:"1 hour"}),date&&jsx139("p",{children:date.toLocaleDateString()}),slot&&jsx139("p",{children:formatTime(new Date(slot.start))})]}),jsxs87("div",{className:Scheduler_default.selection,children:[!date&&jsxs87("div",{children:[jsx139("h3",{children:"Select date"}),jsx139(CalendarInput,{slots,onChangeMonth:setMonth,onClick:setDate})]}),date&&!slot&&jsxs87("div",{children:[jsx139("h3",{children:"Select time"}),jsx139(Stack29,{children:slots.map(s=>{let slotStart=new Date(s.start);return slotStart.getTime()>date.getTime()&&slotStart.getTime()<date.getTime()+24*3600*1e3&&jsx139("div",{children:jsx139(Button32,{variant:"outline",style:{width:150},onClick:()=>setSlot(s),children:formatTime(slotStart)})},s.id)})})]}),date&&slot&&!response&&jsx139(QuestionnaireForm,{questionnaire,submitButtonText:"Next",onSubmit:setResponse}),date&&slot&&response&&jsxs87("div",{children:[jsx139("h3",{children:"You're all set!"}),jsx139("p",{children:"Check your email for a calendar invite."})]})]})]})}function getStart2(month){return formatSlotInstant(month.getTime())}function getEnd2(month){return formatSlotInstant(month.getTime()+31*24*60*60*1e3)}function formatSlotInstant(time){let date=new Date(Math.max(Date.now(),time));return date.setHours(0,0,0,0),date.toISOString()}function formatTime(date){return date.toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}import{createReference as createReference14}from"@medplum/core";import{jsx as jsx140}from"react/jsx-runtime";function ServiceRequestTimeline(props){let{serviceRequest,...rest}=props;return jsx140(ResourceTimeline,{value:serviceRequest,loadTimelineResources:async(medplum,resourceType,id)=>{let ref=`${resourceType}/${id}`,_count=100;return Promise.allSettled([medplum.readHistory("ServiceRequest",id),medplum.search("Communication",{"based-on":ref,_count}),medplum.search("DiagnosticReport",{"based-on":ref,_count}),medplum.search("Media",{"based-on":ref,_count}),medplum.search("DocumentReference",{related:ref,_count}),medplum.search("Task",{_filter:`based-on eq ${ref} or focus eq ${ref} or subject eq ${ref}`,_count})])},createCommunication:(resource,sender,text)=>({resourceType:"Communication",status:"completed",basedOn:[createReference14(resource)],subject:resource.subject,sender:createReference14(sender),sent:new Date().toISOString(),payload:[{contentString:text}]}),createMedia:(resource,operator,content)=>({resourceType:"Media",status:"completed",basedOn:[createReference14(resource)],subject:resource.subject,operator:createReference14(operator),issued:new Date().toISOString(),content}),...rest})}import{Anchor as Anchor16}from"@mantine/core";import{showNotification as showNotification8}from"@mantine/notifications";import{ensureTrailingSlash,normalizeErrorString as normalizeErrorString11}from"@medplum/core";import{useMedplum as useMedplum44}from"@medplum/react-hooks";import{jsx as jsx141}from"react/jsx-runtime";function SmartAppLaunchLink(props){let medplum=useMedplum44(),{client,patient,encounter,children,...rest}=props;function launchApp(){medplum.createResource({resourceType:"SmartAppLaunch",patient,encounter}).then(result=>{let url=new URL(client.launchUri);url.searchParams.set("iss",ensureTrailingSlash(medplum.fhirUrl().toString())),url.searchParams.set("launch",result.id),window.location.assign(url.toString())}).catch(err=>showNotification8({color:"red",message:normalizeErrorString11(err),autoClose:!1}))}return jsx141(Anchor16,{onClick:()=>launchApp(),...rest,children})}export{AddressDisplay,AddressInput,AnnotationInput,AppShell,AsyncAutocomplete,AttachmentArrayDisplay,AttachmentArrayInput,AttachmentButton,AttachmentDisplay,AttachmentInput,BackboneElementDisplay,BackboneElementInput,BaseChat,CalendarInput,ChatModal,CheckboxFormSection,CodeInput,CodeableConceptDisplay,CodeableConceptInput,CodingDisplay,CodingInput,ContactDetailDisplay,ContactDetailInput,ContactPointDisplay,ContactPointInput,Container,DateTimeInput,DefaultResourceTimeline,DescriptionList,DescriptionListEntry,DiagnosticReportDisplay,Document,ElementDefinitionInputSelector,ElementDefinitionTypeInput,EncounterTimeline,ErrorBoundary,FhirPathTable,Form,FormSection,Header,HumanNameDisplay,HumanNameInput,IdentifierDisplay,IdentifierInput,Loading,Logo,MeasureReportDisplay,MedplumLink,MemoizedFhirPathTable,MemoizedSearchControl,MoneyDisplay,MoneyInput,Navbar,NoteDisplay,NotificationIcon,ObservationTable,OperationOutcomeAlert,Panel,PatientExportForm,PatientSummary,PatientTimeline,PlanDefinitionBuilder,QuantityDisplay,QuantityInput,QuestionnaireBuilder,QuestionnaireForm,QuestionnaireFormContext,QuestionnaireItemType,RangeDisplay,RangeInput,RatioInput,ReferenceDisplay,ReferenceInput,ReferenceRangeEditor,ReferenceRangeGroupEditor,RegisterForm,RequestGroupDisplay,ResourceArrayDisplay,ResourceArrayInput,ResourceAvatar,ResourceBadge,ResourceBlame,ResourceDiff,ResourceForm,ResourceHistoryTable,ResourceInput,ResourceName,ResourcePropertyDisplay,ResourcePropertyInput,ResourceTable,ResourceTimeline,Scheduler,SearchChangeEvent,SearchClickEvent,SearchControl,SearchFieldEditor,SearchFilterEditor,SearchLoadEvent,ServiceRequestTimeline,SignInForm,SmartAppLaunchLink,StatusBadge,ThreadChat,Timeline,TimelineItem,TimingInput,ValueSetAutocomplete,addDateFilterBetween,addField,addFilter,addLastMonthFilter,addMissingFilter,addNextMonthFilter,addThisMonthFilter,addTodayFilter,addTomorrowFilter,addYearToDateFilter,addYesterdayFilter,buildFieldNameString,buildInitialResponse,buildInitialResponseItem,clearFilters,clearFiltersOnField,convertIsoToLocal,convertLocalToIso,createScriptTag,deleteFilter,evaluateCalculatedExpressionsInQuestionnaire,getErrorsForInput,getFieldDefinitions,getIssuesForExpression,getItemAnswerOptionValue,getItemEnableWhenValueAnswer,getItemInitialValue,getNewMultiSelectValues,getNumberOfPages,getOpString,getQuestionnaireItemReferenceFilter,getQuestionnaireItemReferenceTargetTypes,getRecaptcha,getResponseItemAnswerValue,getSearchOperators,getSortField,getValuePath,initRecaptcha,isCheckboxCell,isChoiceQuestion,isQuestionEnabled,isSortDescending,isSupportedProfileStructureDefinition,killEvent,mergeUpdatedItems,parseForm,renderValue,sendCommand,setFilters,setOffset,setPage,setPropertyValue,setQuestionnaireItemReferenceTargetTypes,setSort,sortByDateAndPriority,toggleSort,typedValueToResponseItem};
|
|
74
74
|
/*! Bundled license information:
|
|
75
75
|
|
|
76
76
|
@tabler/icons-react/dist/esm/defaultAttributes.mjs:
|