@medplum/react 2.0.21 → 2.0.23
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 +173 -128
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.min.cjs +1 -1
- package/dist/esm/AttachmentButton/AttachmentButton.mjs +1 -2
- package/dist/esm/AttachmentButton/AttachmentButton.mjs.map +1 -1
- package/dist/esm/DateTimeInput/DateTimeInput.mjs +1 -0
- package/dist/esm/DateTimeInput/DateTimeInput.mjs.map +1 -1
- package/dist/esm/FhirPathTable/FhirPathTable.mjs +2 -0
- package/dist/esm/FhirPathTable/FhirPathTable.mjs.map +1 -1
- package/dist/esm/Form/FormUtils.mjs +2 -1
- package/dist/esm/Form/FormUtils.mjs.map +1 -1
- package/dist/esm/GoogleButton/GoogleButton.mjs +2 -2
- package/dist/esm/GoogleButton/GoogleButton.mjs.map +1 -1
- package/dist/esm/MedplumProvider/MedplumProvider.mjs +4 -0
- package/dist/esm/MedplumProvider/MedplumProvider.mjs.map +1 -1
- package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.mjs +2 -1
- package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.mjs.map +1 -1
- package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.mjs +3 -2
- package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.mjs.map +1 -1
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.mjs +13 -5
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.mjs.map +1 -1
- package/dist/esm/ResourceName/ResourceName.mjs +0 -5
- package/dist/esm/ResourceName/ResourceName.mjs.map +1 -1
- package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.mjs +6 -3
- package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.mjs.map +1 -1
- package/dist/esm/SearchControl/SearchControl.mjs +2 -1
- package/dist/esm/SearchControl/SearchControl.mjs.map +1 -1
- package/dist/esm/SearchControl/SearchUtils.mjs +77 -54
- package/dist/esm/SearchControl/SearchUtils.mjs.map +1 -1
- package/dist/esm/SearchFieldEditor/SearchFieldEditor.mjs +6 -7
- package/dist/esm/SearchFieldEditor/SearchFieldEditor.mjs.map +1 -1
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.mjs +3 -0
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.mjs.map +1 -1
- package/dist/esm/auth/SignInForm.mjs +6 -2
- package/dist/esm/auth/SignInForm.mjs.map +1 -1
- package/dist/esm/index.min.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/defaultAttributes.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/defaultAttributes.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconAdjustmentsHorizontal.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconAdjustmentsHorizontal.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconAlertCircle.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconAlertCircle.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBleach.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBleach.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBleachOff.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBleachOff.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBoxMultiple.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBoxMultiple.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBracketsContain.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBracketsContain.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBucket.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBucket.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBucketOff.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconBucketOff.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCalendar.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCalendar.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCheckbox.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCheckbox.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronDown.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronDown.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleMinus.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleMinus.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCirclePlus.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCirclePlus.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCloudUpload.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCloudUpload.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconColumns.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconColumns.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCurrencyDollar.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconCurrencyDollar.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconDots.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconDots.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconEdit.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconEdit.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconEqual.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconEqual.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconEqualNot.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconEqualNot.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconFileAlert.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconFileAlert.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconFilePlus.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconFilePlus.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconFilter.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconFilter.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconListDetails.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconListDetails.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconLogout.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconLogout.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconMathGreater.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconMathGreater.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconMathLower.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconMathLower.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconMessage.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconMessage.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconPin.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconPin.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconPinnedOff.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconPinnedOff.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSearch.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSearch.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSettings.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSettings.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSortAscending.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSortAscending.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSortDescending.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSortDescending.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSquare.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSquare.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSwitchHorizontal.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconSwitchHorizontal.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconTableExport.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconTableExport.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconTrash.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconTrash.mjs.map +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconX.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconX.mjs.map +1 -1
- package/dist/esm/useResource/useResource.mjs +1 -0
- package/dist/esm/useResource/useResource.mjs.map +1 -1
- package/dist/esm/utils/script.mjs +1 -0
- package/dist/esm/utils/script.mjs.map +1 -1
- package/dist/types/FhirPathTable/FhirPathTable.d.ts +2 -0
- package/dist/types/Form/FormUtils.d.ts +1 -0
- package/dist/types/MedplumProvider/MedplumProvider.d.ts +4 -0
- package/dist/types/ResourceName/ResourceName.d.ts +0 -5
- package/dist/types/ResourcePropertyDisplay/ResourcePropertyDisplay.d.ts +4 -2
- package/dist/types/SearchControl/SearchControl.d.ts +2 -0
- package/dist/types/SearchControl/SearchUtils.d.ts +64 -44
- package/dist/types/ValueSetAutocomplete/ValueSetAutocomplete.d.ts +3 -0
- package/dist/types/auth/SignInForm.d.ts +2 -0
- package/dist/types/useResource/useResource.d.ts +1 -0
- package/dist/types/utils/script.d.ts +1 -0
- package/package.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachmentButton.mjs","sources":["../../../src/AttachmentButton/AttachmentButton.tsx"],"sourcesContent":["import { Attachment, Binary, OperationOutcome } from '@medplum/fhirtypes';\nimport React, { useRef } from 'react';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { killEvent } from '../utils/dom';\n\nexport interface AttachmentButtonProps {\n onUpload: (attachment: Attachment) => void;\n onUploadStart?: () => void;\n onUploadProgress?: (e: ProgressEvent) => void;\n children(props: { onClick(e: React.MouseEvent): void }): React.ReactNode;\n}\n\nexport function AttachmentButton(props: AttachmentButtonProps): JSX.Element {\n const medplum = useMedplum();\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n function onClick(e: React.MouseEvent): void {\n killEvent(e);\n fileInputRef.current?.click();\n }\n\n function onFileChange(e: React.ChangeEvent): void {\n killEvent(e);\n const files = (e.target as HTMLInputElement).files;\n if (files) {\n Array.from(files).forEach(processFile);\n }\n }\n\n /**\n * Processes a single file.\n
|
|
1
|
+
{"version":3,"file":"AttachmentButton.mjs","sources":["../../../src/AttachmentButton/AttachmentButton.tsx"],"sourcesContent":["import { Attachment, Binary, OperationOutcome } from '@medplum/fhirtypes';\nimport React, { useRef } from 'react';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { killEvent } from '../utils/dom';\n\nexport interface AttachmentButtonProps {\n onUpload: (attachment: Attachment) => void;\n onUploadStart?: () => void;\n onUploadProgress?: (e: ProgressEvent) => void;\n children(props: { onClick(e: React.MouseEvent): void }): React.ReactNode;\n}\n\nexport function AttachmentButton(props: AttachmentButtonProps): JSX.Element {\n const medplum = useMedplum();\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n function onClick(e: React.MouseEvent): void {\n killEvent(e);\n fileInputRef.current?.click();\n }\n\n function onFileChange(e: React.ChangeEvent): void {\n killEvent(e);\n const files = (e.target as HTMLInputElement).files;\n if (files) {\n Array.from(files).forEach(processFile);\n }\n }\n\n /**\n * Processes a single file.\n * @param file The file descriptor.\n */\n function processFile(file: File): void {\n if (!file) {\n return;\n }\n\n const fileName = file.name;\n if (!fileName) {\n return;\n }\n\n if (props.onUploadStart) {\n props.onUploadStart();\n }\n\n const filename = file.name;\n const contentType = file.type || 'application/octet-stream';\n medplum\n .createBinary(file, filename, contentType, props.onUploadProgress)\n .then((binary: Binary) => {\n props.onUpload({\n contentType: binary.contentType,\n url: binary.url,\n title: filename,\n });\n })\n .catch((outcome: OperationOutcome) => {\n alert(outcome?.issue?.[0]?.details?.text);\n });\n }\n\n return (\n <>\n <input\n type=\"file\"\n data-testid=\"upload-file-input\"\n style={{ display: 'none' }}\n ref={fileInputRef}\n onChange={(e) => onFileChange(e)}\n />\n {props.children({ onClick })}\n </>\n );\n}\n"],"names":[],"mappings":";;;;AAYM,SAAU,gBAAgB,CAAC,KAA4B,EAAA;AAC3D,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,YAAY,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAEpD,SAAS,OAAO,CAAC,CAAmB,EAAA;QAClC,SAAS,CAAC,CAAC,CAAC,CAAC;AACb,QAAA,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;KAC/B;IAED,SAAS,YAAY,CAAC,CAAoB,EAAA;QACxC,SAAS,CAAC,CAAC,CAAC,CAAC;AACb,QAAA,MAAM,KAAK,GAAI,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC;AACnD,QAAA,IAAI,KAAK,EAAE;YACT,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;AACxC,SAAA;KACF;AAED;;;AAGG;IACH,SAAS,WAAW,CAAC,IAAU,EAAA;QAC7B,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;AACR,SAAA;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,QAAQ,EAAE;YACb,OAAO;AACR,SAAA;QAED,IAAI,KAAK,CAAC,aAAa,EAAE;YACvB,KAAK,CAAC,aAAa,EAAE,CAAC;AACvB,SAAA;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;AAC3B,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAC;QAC5D,OAAO;aACJ,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC;AACjE,aAAA,IAAI,CAAC,CAAC,MAAc,KAAI;YACvB,KAAK,CAAC,QAAQ,CAAC;gBACb,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,GAAG,EAAE,MAAM,CAAC,GAAG;AACf,gBAAA,KAAK,EAAE,QAAQ;AAChB,aAAA,CAAC,CAAC;AACL,SAAC,CAAC;AACD,aAAA,KAAK,CAAC,CAAC,OAAyB,KAAI;AACnC,YAAA,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAC5C,SAAC,CAAC,CAAC;KACN;AAED,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA;AACE,QAAA,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EACE,IAAI,EAAC,MAAM,EAAA,aAAA,EACC,mBAAmB,EAC/B,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAC1B,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,EAChC,CAAA;QACD,KAAK,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAC3B,EACH;AACJ;;;;"}
|
|
@@ -61,6 +61,7 @@ function convertLocalToIso(localString) {
|
|
|
61
61
|
* Returns the input type for the requested type.
|
|
62
62
|
* JSDOM does not support many of the valid <input> type attributes.
|
|
63
63
|
* For example, it won't fire change events for <input type="datetime-local">.
|
|
64
|
+
* @returns The input type for the current environment.
|
|
64
65
|
*/
|
|
65
66
|
function getInputType() {
|
|
66
67
|
return 'datetime-local';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateTimeInput.mjs","sources":["../../../src/DateTimeInput/DateTimeInput.tsx"],"sourcesContent":["import { TextInput } from '@mantine/core';\nimport { isValidDate } from '@medplum/core';\nimport { OperationOutcome } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { getErrorsForInput } from '../utils/outcomes';\n\nexport interface DateTimeInputProps {\n name?: string;\n placeholder?: string;\n defaultValue?: string;\n required?: boolean;\n outcome?: OperationOutcome;\n onChange?: (value: string) => void;\n}\n\n/**\n * The DateTimeInput component is a wrapper around the HTML5 input type=\"datetime-local\".\n * The main purpose is to reconcile time zones.\n * Most of our date/time values are in ISO-8601, which includes a time zone offset.\n * The datetime-local input does not support the time zone offset.\n * @param props The Input props.\n * @returns The JSX element to render.\n */\nexport function DateTimeInput(props: DateTimeInputProps): JSX.Element {\n return (\n <TextInput\n id={props.name}\n name={props.name}\n data-testid={props.name}\n placeholder={props.placeholder}\n required={props.required}\n type={getInputType()}\n defaultValue={convertIsoToLocal(props.defaultValue)}\n error={getErrorsForInput(props.outcome, props.name)}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n if (props.onChange) {\n const newValue = e.currentTarget.value;\n props.onChange(convertLocalToIso(newValue));\n }\n }}\n />\n );\n}\n\n/**\n * Converts an ISO-8601 date/time string to a local date/time string.\n * @param isoString The ISO-8601 date/time string to convert.\n * @returns The local date/time string.\n */\nexport function convertIsoToLocal(isoString: string | undefined): string {\n if (!isoString) {\n return '';\n }\n\n // Convert the ISO-8601 date to a local datetime-local value.\n // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Date_and_time_formats#local_date_and_time_strings\n // See: https://stackoverflow.com/a/60368477\n const date = new Date(isoString);\n if (!isValidDate(date)) {\n // If the input string was malformed, return an empty string.\n return '';\n }\n\n return date.toLocaleDateString('sv') + 'T' + date.toLocaleTimeString('sv');\n}\n\n/**\n * Converts a local date/time string to an ISO-8601 date/time string.\n * @param localString The local date/time string to convert.\n * @returns The ISO-8601 date/time string.\n */\nexport function convertLocalToIso(localString: string | undefined): string {\n if (!localString) {\n return '';\n }\n\n // Try to parse the local string as a Date\n // JavaScript's Date() constructor defaults to the local time zone.\n // The Date() constructor will throw if the value is malformed.\n const date = new Date(localString);\n if (!isValidDate(date)) {\n // If the input string was malformed, return an empty string.\n return '';\n }\n\n return date.toISOString();\n}\n\n/**\n * Returns the input type for the requested type.\n * JSDOM does not support many of the valid <input> type attributes.\n * For example, it won't fire change events for <input type=\"datetime-local\">.\n */\nfunction getInputType(): string {\n return process.env.NODE_ENV === 'test' ? 'text' : 'datetime-local';\n}\n"],"names":[],"mappings":";;;;;AAeA;;;;;;;AAOG;AACG,SAAU,aAAa,CAAC,KAAyB,EAAA;AACrD,IAAA,QACE,KAAA,CAAA,aAAA,CAAC,SAAS,EAAA,EACR,EAAE,EAAE,KAAK,CAAC,IAAI,EACd,IAAI,EAAE,KAAK,CAAC,IAAI,EACH,aAAA,EAAA,KAAK,CAAC,IAAI,EACvB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,IAAI,EAAE,YAAY,EAAE,EACpB,YAAY,EAAE,iBAAiB,CAAC,KAAK,CAAC,YAAY,CAAC,EACnD,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EACnD,QAAQ,EAAE,CAAC,CAAsC,KAAI;YACnD,IAAI,KAAK,CAAC,QAAQ,EAAE;AAClB,gBAAA,MAAM,QAAQ,GAAG,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC;gBACvC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC7C,aAAA;SACF,EAAA,CACD,EACF;AACJ,CAAC;AAED;;;;AAIG;AACG,SAAU,iBAAiB,CAAC,SAA6B,EAAA;IAC7D,IAAI,CAAC,SAAS,EAAE;AACd,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;;;;AAKD,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;AACjC,IAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;;AAEtB,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;AAED,IAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAC7E,CAAC;AAED;;;;AAIG;AACG,SAAU,iBAAiB,CAAC,WAA+B,EAAA;IAC/D,IAAI,CAAC,WAAW,EAAE;AAChB,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;;;;AAKD,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC;AACnC,IAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;;AAEtB,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;AAED,IAAA,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;AAC5B,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"DateTimeInput.mjs","sources":["../../../src/DateTimeInput/DateTimeInput.tsx"],"sourcesContent":["import { TextInput } from '@mantine/core';\nimport { isValidDate } from '@medplum/core';\nimport { OperationOutcome } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { getErrorsForInput } from '../utils/outcomes';\n\nexport interface DateTimeInputProps {\n name?: string;\n placeholder?: string;\n defaultValue?: string;\n required?: boolean;\n outcome?: OperationOutcome;\n onChange?: (value: string) => void;\n}\n\n/**\n * The DateTimeInput component is a wrapper around the HTML5 input type=\"datetime-local\".\n * The main purpose is to reconcile time zones.\n * Most of our date/time values are in ISO-8601, which includes a time zone offset.\n * The datetime-local input does not support the time zone offset.\n * @param props The Input props.\n * @returns The JSX element to render.\n */\nexport function DateTimeInput(props: DateTimeInputProps): JSX.Element {\n return (\n <TextInput\n id={props.name}\n name={props.name}\n data-testid={props.name}\n placeholder={props.placeholder}\n required={props.required}\n type={getInputType()}\n defaultValue={convertIsoToLocal(props.defaultValue)}\n error={getErrorsForInput(props.outcome, props.name)}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n if (props.onChange) {\n const newValue = e.currentTarget.value;\n props.onChange(convertLocalToIso(newValue));\n }\n }}\n />\n );\n}\n\n/**\n * Converts an ISO-8601 date/time string to a local date/time string.\n * @param isoString The ISO-8601 date/time string to convert.\n * @returns The local date/time string.\n */\nexport function convertIsoToLocal(isoString: string | undefined): string {\n if (!isoString) {\n return '';\n }\n\n // Convert the ISO-8601 date to a local datetime-local value.\n // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Date_and_time_formats#local_date_and_time_strings\n // See: https://stackoverflow.com/a/60368477\n const date = new Date(isoString);\n if (!isValidDate(date)) {\n // If the input string was malformed, return an empty string.\n return '';\n }\n\n return date.toLocaleDateString('sv') + 'T' + date.toLocaleTimeString('sv');\n}\n\n/**\n * Converts a local date/time string to an ISO-8601 date/time string.\n * @param localString The local date/time string to convert.\n * @returns The ISO-8601 date/time string.\n */\nexport function convertLocalToIso(localString: string | undefined): string {\n if (!localString) {\n return '';\n }\n\n // Try to parse the local string as a Date\n // JavaScript's Date() constructor defaults to the local time zone.\n // The Date() constructor will throw if the value is malformed.\n const date = new Date(localString);\n if (!isValidDate(date)) {\n // If the input string was malformed, return an empty string.\n return '';\n }\n\n return date.toISOString();\n}\n\n/**\n * Returns the input type for the requested type.\n * JSDOM does not support many of the valid <input> type attributes.\n * For example, it won't fire change events for <input type=\"datetime-local\">.\n * @returns The input type for the current environment.\n */\nfunction getInputType(): string {\n return process.env.NODE_ENV === 'test' ? 'text' : 'datetime-local';\n}\n"],"names":[],"mappings":";;;;;AAeA;;;;;;;AAOG;AACG,SAAU,aAAa,CAAC,KAAyB,EAAA;AACrD,IAAA,QACE,KAAA,CAAA,aAAA,CAAC,SAAS,EAAA,EACR,EAAE,EAAE,KAAK,CAAC,IAAI,EACd,IAAI,EAAE,KAAK,CAAC,IAAI,EACH,aAAA,EAAA,KAAK,CAAC,IAAI,EACvB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,IAAI,EAAE,YAAY,EAAE,EACpB,YAAY,EAAE,iBAAiB,CAAC,KAAK,CAAC,YAAY,CAAC,EACnD,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EACnD,QAAQ,EAAE,CAAC,CAAsC,KAAI;YACnD,IAAI,KAAK,CAAC,QAAQ,EAAE;AAClB,gBAAA,MAAM,QAAQ,GAAG,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC;gBACvC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC7C,aAAA;SACF,EAAA,CACD,EACF;AACJ,CAAC;AAED;;;;AAIG;AACG,SAAU,iBAAiB,CAAC,SAA6B,EAAA;IAC7D,IAAI,CAAC,SAAS,EAAE;AACd,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;;;;AAKD,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;AACjC,IAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;;AAEtB,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;AAED,IAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAC7E,CAAC;AAED;;;;AAIG;AACG,SAAU,iBAAiB,CAAC,WAA+B,EAAA;IAC/D,IAAI,CAAC,WAAW,EAAE;AAChB,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;;;;AAKD,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC;AACnC,IAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;;AAEtB,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;AAED,IAAA,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;AAKG;AACH,SAAS,YAAY,GAAA;AACnB,IAAA,OAAkD,gBAAgB,CAAC;AACrE;;;;"}
|
|
@@ -8,6 +8,8 @@ import { killEvent, isCheckboxCell } from '../utils/dom.mjs';
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* The FhirPathTable component represents the embeddable search table control.
|
|
11
|
+
* @param props FhirPathTable React props.
|
|
12
|
+
* @returns FhirPathTable React node.
|
|
11
13
|
*/
|
|
12
14
|
function FhirPathTable(props) {
|
|
13
15
|
const medplum = useMedplum();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FhirPathTable.mjs","sources":["../../../src/FhirPathTable/FhirPathTable.tsx"],"sourcesContent":["import { Button, Loader, Table } from '@mantine/core';\nimport { IndexedStructureDefinition, normalizeOperationOutcome, PropertyType } from '@medplum/core';\nimport { OperationOutcome, Resource } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { FhirPathDisplay } from '../FhirPathDisplay/FhirPathDisplay';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { SearchClickEvent } from '../SearchControl/SearchControl';\nimport { isCheckboxCell, killEvent } from '../utils/dom';\n\nexport interface FhirPathTableField {\n readonly propertyType: PropertyType;\n readonly name: string;\n readonly fhirPath: string;\n}\n\nexport interface FhirPathTableProps {\n resourceType: string;\n query: string;\n fields: FhirPathTableField[];\n checkboxesEnabled?: boolean;\n onClick?: (e: SearchClickEvent) => void;\n onAuxClick?: (e: SearchClickEvent) => void;\n onBulk?: (ids: string[]) => void;\n}\n\nexport interface SmartSearchResponse {\n data: {\n ResourceList: Resource[];\n };\n}\n\n/**\n * The FhirPathTable component represents the embeddable search table control.\n */\nexport function FhirPathTable(props: FhirPathTableProps): JSX.Element {\n const medplum = useMedplum();\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n const [outcome, setOutcome] = useState<OperationOutcome | undefined>();\n const { query, fields } = props;\n const [response, setResponse] = useState<SmartSearchResponse | undefined>();\n const [selected, setSelected] = useState<{ [id: string]: boolean }>({});\n\n const responseRef = useRef<SmartSearchResponse>();\n responseRef.current = response;\n\n const selectedRef = useRef<{ [id: string]: boolean }>({});\n selectedRef.current = selected;\n\n useEffect(() => {\n setOutcome(undefined);\n medplum\n .graphql(query)\n .then(setResponse)\n .catch((err) => setOutcome(normalizeOperationOutcome(err)));\n }, [medplum, query]);\n\n function handleSingleCheckboxClick(e: React.ChangeEvent, id: string): void {\n e.stopPropagation();\n\n const el = e.target as HTMLInputElement;\n const checked = el.checked;\n const newSelected = { ...selectedRef.current };\n if (checked) {\n newSelected[id] = true;\n } else {\n delete newSelected[id];\n }\n setSelected(newSelected);\n }\n\n function handleAllCheckboxClick(e: React.ChangeEvent): void {\n e.stopPropagation();\n\n const el = e.target as HTMLInputElement;\n const checked = el.checked;\n const newSelected = {} as { [id: string]: boolean };\n const resources = responseRef.current?.data?.ResourceList;\n if (checked && resources) {\n resources.forEach((resource) => {\n if (resource?.id) {\n newSelected[resource.id] = true;\n }\n });\n }\n setSelected(newSelected);\n }\n\n function isAllSelected(): boolean {\n const resources = responseRef.current?.data?.ResourceList;\n if (!resources || resources.length === 0) {\n return false;\n }\n for (const resource of resources) {\n if (resource?.id && !selectedRef.current[resource.id]) {\n return false;\n }\n }\n return true;\n }\n\n function handleRowClick(e: React.MouseEvent, resource: Resource): void {\n if (isCheckboxCell(e.target as Element)) {\n // Ignore clicks on checkboxes\n return;\n }\n\n killEvent(e);\n\n if (e.button !== 1 && props.onClick) {\n props.onClick(new SearchClickEvent(resource, e));\n }\n\n if (e.button === 1 && props.onAuxClick) {\n props.onAuxClick(new SearchClickEvent(resource, e));\n }\n }\n\n useEffect(() => {\n medplum\n .requestSchema(props.resourceType)\n .then((newSchema) => {\n // The schema could have the same object identity,\n // so need to use the spread operator to kick React re-render.\n setSchema({ ...newSchema });\n })\n .catch(console.log);\n }, [medplum, props.resourceType]);\n\n const typeSchema = schema?.types?.[props.resourceType];\n if (!typeSchema) {\n return <Loader />;\n }\n\n const checkboxColumn = props.checkboxesEnabled;\n\n return (\n <div onContextMenu={(e) => killEvent(e)} data-testid=\"search-control\">\n <Table>\n <thead>\n <tr>\n {checkboxColumn && (\n <th>\n <input\n type=\"checkbox\"\n value=\"checked\"\n aria-label=\"all-checkbox\"\n data-testid=\"all-checkbox\"\n checked={isAllSelected()}\n onChange={(e) => handleAllCheckboxClick(e)}\n />\n </th>\n )}\n {fields.map((field) => (\n <th key={field.name}>{field.name}</th>\n ))}\n </tr>\n </thead>\n <tbody>\n {response?.data?.ResourceList?.map(\n (resource) =>\n resource && (\n <tr\n key={resource.id}\n data-testid=\"search-control-row\"\n onClick={(e) => handleRowClick(e, resource)}\n onAuxClick={(e) => handleRowClick(e, resource)}\n >\n {checkboxColumn && (\n <td>\n <input\n type=\"checkbox\"\n value=\"checked\"\n data-testid=\"row-checkbox\"\n aria-label={`Checkbox for ${resource.id}`}\n checked={!!selected[resource.id as string]}\n onChange={(e) => handleSingleCheckboxClick(e, resource.id as string)}\n />\n </td>\n )}\n {fields.map((field) => {\n return (\n <td key={field.name}>\n <FhirPathDisplay propertyType={field.propertyType} path={field.fhirPath} resource={resource} />\n </td>\n );\n })}\n </tr>\n )\n )}\n </tbody>\n </Table>\n {response?.data?.ResourceList?.length === 0 && <div data-testid=\"empty-search\">No results</div>}\n {outcome && (\n <div data-testid=\"search-error\">\n <pre style={{ textAlign: 'left' }}>{JSON.stringify(outcome, undefined, 2)}</pre>\n </div>\n )}\n {props.onBulk && (\n <Button onClick={() => (props.onBulk as (ids: string[]) => any)(Object.keys(selectedRef.current))}>\n Bulk...\n </Button>\n )}\n </div>\n );\n}\n\nexport const MemoizedFhirPathTable = React.memo(FhirPathTable);\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FhirPathTable.mjs","sources":["../../../src/FhirPathTable/FhirPathTable.tsx"],"sourcesContent":["import { Button, Loader, Table } from '@mantine/core';\nimport { IndexedStructureDefinition, normalizeOperationOutcome, PropertyType } from '@medplum/core';\nimport { OperationOutcome, Resource } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { FhirPathDisplay } from '../FhirPathDisplay/FhirPathDisplay';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { SearchClickEvent } from '../SearchControl/SearchControl';\nimport { isCheckboxCell, killEvent } from '../utils/dom';\n\nexport interface FhirPathTableField {\n readonly propertyType: PropertyType;\n readonly name: string;\n readonly fhirPath: string;\n}\n\nexport interface FhirPathTableProps {\n resourceType: string;\n query: string;\n fields: FhirPathTableField[];\n checkboxesEnabled?: boolean;\n onClick?: (e: SearchClickEvent) => void;\n onAuxClick?: (e: SearchClickEvent) => void;\n onBulk?: (ids: string[]) => void;\n}\n\nexport interface SmartSearchResponse {\n data: {\n ResourceList: Resource[];\n };\n}\n\n/**\n * The FhirPathTable component represents the embeddable search table control.\n * @param props FhirPathTable React props.\n * @returns FhirPathTable React node.\n */\nexport function FhirPathTable(props: FhirPathTableProps): JSX.Element {\n const medplum = useMedplum();\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n const [outcome, setOutcome] = useState<OperationOutcome | undefined>();\n const { query, fields } = props;\n const [response, setResponse] = useState<SmartSearchResponse | undefined>();\n const [selected, setSelected] = useState<{ [id: string]: boolean }>({});\n\n const responseRef = useRef<SmartSearchResponse>();\n responseRef.current = response;\n\n const selectedRef = useRef<{ [id: string]: boolean }>({});\n selectedRef.current = selected;\n\n useEffect(() => {\n setOutcome(undefined);\n medplum\n .graphql(query)\n .then(setResponse)\n .catch((err) => setOutcome(normalizeOperationOutcome(err)));\n }, [medplum, query]);\n\n function handleSingleCheckboxClick(e: React.ChangeEvent, id: string): void {\n e.stopPropagation();\n\n const el = e.target as HTMLInputElement;\n const checked = el.checked;\n const newSelected = { ...selectedRef.current };\n if (checked) {\n newSelected[id] = true;\n } else {\n delete newSelected[id];\n }\n setSelected(newSelected);\n }\n\n function handleAllCheckboxClick(e: React.ChangeEvent): void {\n e.stopPropagation();\n\n const el = e.target as HTMLInputElement;\n const checked = el.checked;\n const newSelected = {} as { [id: string]: boolean };\n const resources = responseRef.current?.data?.ResourceList;\n if (checked && resources) {\n resources.forEach((resource) => {\n if (resource?.id) {\n newSelected[resource.id] = true;\n }\n });\n }\n setSelected(newSelected);\n }\n\n function isAllSelected(): boolean {\n const resources = responseRef.current?.data?.ResourceList;\n if (!resources || resources.length === 0) {\n return false;\n }\n for (const resource of resources) {\n if (resource?.id && !selectedRef.current[resource.id]) {\n return false;\n }\n }\n return true;\n }\n\n function handleRowClick(e: React.MouseEvent, resource: Resource): void {\n if (isCheckboxCell(e.target as Element)) {\n // Ignore clicks on checkboxes\n return;\n }\n\n killEvent(e);\n\n if (e.button !== 1 && props.onClick) {\n props.onClick(new SearchClickEvent(resource, e));\n }\n\n if (e.button === 1 && props.onAuxClick) {\n props.onAuxClick(new SearchClickEvent(resource, e));\n }\n }\n\n useEffect(() => {\n medplum\n .requestSchema(props.resourceType)\n .then((newSchema) => {\n // The schema could have the same object identity,\n // so need to use the spread operator to kick React re-render.\n setSchema({ ...newSchema });\n })\n .catch(console.log);\n }, [medplum, props.resourceType]);\n\n const typeSchema = schema?.types?.[props.resourceType];\n if (!typeSchema) {\n return <Loader />;\n }\n\n const checkboxColumn = props.checkboxesEnabled;\n\n return (\n <div onContextMenu={(e) => killEvent(e)} data-testid=\"search-control\">\n <Table>\n <thead>\n <tr>\n {checkboxColumn && (\n <th>\n <input\n type=\"checkbox\"\n value=\"checked\"\n aria-label=\"all-checkbox\"\n data-testid=\"all-checkbox\"\n checked={isAllSelected()}\n onChange={(e) => handleAllCheckboxClick(e)}\n />\n </th>\n )}\n {fields.map((field) => (\n <th key={field.name}>{field.name}</th>\n ))}\n </tr>\n </thead>\n <tbody>\n {response?.data?.ResourceList?.map(\n (resource) =>\n resource && (\n <tr\n key={resource.id}\n data-testid=\"search-control-row\"\n onClick={(e) => handleRowClick(e, resource)}\n onAuxClick={(e) => handleRowClick(e, resource)}\n >\n {checkboxColumn && (\n <td>\n <input\n type=\"checkbox\"\n value=\"checked\"\n data-testid=\"row-checkbox\"\n aria-label={`Checkbox for ${resource.id}`}\n checked={!!selected[resource.id as string]}\n onChange={(e) => handleSingleCheckboxClick(e, resource.id as string)}\n />\n </td>\n )}\n {fields.map((field) => {\n return (\n <td key={field.name}>\n <FhirPathDisplay propertyType={field.propertyType} path={field.fhirPath} resource={resource} />\n </td>\n );\n })}\n </tr>\n )\n )}\n </tbody>\n </Table>\n {response?.data?.ResourceList?.length === 0 && <div data-testid=\"empty-search\">No results</div>}\n {outcome && (\n <div data-testid=\"search-error\">\n <pre style={{ textAlign: 'left' }}>{JSON.stringify(outcome, undefined, 2)}</pre>\n </div>\n )}\n {props.onBulk && (\n <Button onClick={() => (props.onBulk as (ids: string[]) => any)(Object.keys(selectedRef.current))}>\n Bulk...\n </Button>\n )}\n </div>\n );\n}\n\nexport const MemoizedFhirPathTable = React.memo(FhirPathTable);\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Parses an HTML form and returns the result as a JavaScript object.
|
|
3
3
|
* @param form The HTML form element.
|
|
4
|
+
* @returns Form values in key value pairs.
|
|
4
5
|
*/
|
|
5
6
|
function parseForm(form) {
|
|
6
7
|
const result = {};
|
|
@@ -21,8 +22,8 @@ function parseForm(form) {
|
|
|
21
22
|
* Parses an HTML input element.
|
|
22
23
|
* Sets the name/value pair in the result,
|
|
23
24
|
* but only if the element is enabled and checked.
|
|
24
|
-
* @param el The input element.
|
|
25
25
|
* @param result The result builder.
|
|
26
|
+
* @param el The input element.
|
|
26
27
|
*/
|
|
27
28
|
function parseInputElement(result, el) {
|
|
28
29
|
if (el.disabled) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormUtils.mjs","sources":["../../../src/Form/FormUtils.ts"],"sourcesContent":["/**\n * Parses an HTML form and returns the result as a JavaScript object.\n * @param form The HTML form element.\n */\nexport function parseForm(form: HTMLFormElement): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const element of Array.from(form.elements)) {\n if (element instanceof HTMLInputElement) {\n parseInputElement(result, element);\n } else if (element instanceof HTMLTextAreaElement) {\n result[element.name] = element.value;\n } else if (element instanceof HTMLSelectElement) {\n parseSelectElement(result, element);\n }\n }\n\n return result;\n}\n\n/**\n * Parses an HTML input element.\n * Sets the name/value pair in the result,\n * but only if the element is enabled and checked.\n * @param
|
|
1
|
+
{"version":3,"file":"FormUtils.mjs","sources":["../../../src/Form/FormUtils.ts"],"sourcesContent":["/**\n * Parses an HTML form and returns the result as a JavaScript object.\n * @param form The HTML form element.\n * @returns Form values in key value pairs.\n */\nexport function parseForm(form: HTMLFormElement): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const element of Array.from(form.elements)) {\n if (element instanceof HTMLInputElement) {\n parseInputElement(result, element);\n } else if (element instanceof HTMLTextAreaElement) {\n result[element.name] = element.value;\n } else if (element instanceof HTMLSelectElement) {\n parseSelectElement(result, element);\n }\n }\n\n return result;\n}\n\n/**\n * Parses an HTML input element.\n * Sets the name/value pair in the result,\n * but only if the element is enabled and checked.\n * @param result The result builder.\n * @param el The input element.\n */\nfunction parseInputElement(result: Record<string, string>, el: HTMLInputElement): void {\n if (el.disabled) {\n // Ignore disabled elements\n return;\n }\n\n if ((el.type === 'checkbox' || el.type === 'radio') && !el.checked) {\n // Ignore unchecked radio or checkbox elements\n return;\n }\n\n result[el.name] = el.value;\n}\n\n/**\n * Parses an HTML select element.\n * Sets the name/value pair if one is selected.\n * @param result The result builder.\n * @param el The select element.\n */\nfunction parseSelectElement(result: Record<string, string>, el: HTMLSelectElement): void {\n result[el.name] = el.value;\n}\n"],"names":[],"mappings":"AAAA;;;;AAIG;AACG,SAAU,SAAS,CAAC,IAAqB,EAAA;IAC7C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;QAC/C,IAAI,OAAO,YAAY,gBAAgB,EAAE;AACvC,YAAA,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACpC,SAAA;aAAM,IAAI,OAAO,YAAY,mBAAmB,EAAE;YACjD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;AACtC,SAAA;aAAM,IAAI,OAAO,YAAY,iBAAiB,EAAE;AAC/C,YAAA,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,SAAA;AACF,KAAA;AAED,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;AAMG;AACH,SAAS,iBAAiB,CAAC,MAA8B,EAAE,EAAoB,EAAA;IAC7E,IAAI,EAAE,CAAC,QAAQ,EAAE;;QAEf,OAAO;AACR,KAAA;AAED,IAAA,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,UAAU,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE;;QAElE,OAAO;AACR,KAAA;IAED,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;AAC7B,CAAC;AAED;;;;;AAKG;AACH,SAAS,kBAAkB,CAAC,MAA8B,EAAE,EAAqB,EAAA;IAC/E,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;AAC7B;;;;"}
|
|
@@ -37,9 +37,9 @@ function getGoogleClientId(clientId) {
|
|
|
37
37
|
}
|
|
38
38
|
if (typeof window !== 'undefined') {
|
|
39
39
|
const origin = window.location.protocol + '//' + window.location.host;
|
|
40
|
-
const authorizedOrigins = "
|
|
40
|
+
const authorizedOrigins = "http://localhost:3000,http://127.0.0.1:3000,http://localhost:6006,http://127.0.0.1:6006,https://app.medplum.com,https://docs.medplum.com,https://storybook.medplum.com,https://graphiql.medplum.com,https://www.medplum.com"?.split(',') ?? [];
|
|
41
41
|
if (authorizedOrigins.includes(origin)) {
|
|
42
|
-
return "
|
|
42
|
+
return "921088377005-3j1sa10vr6hj86jgmdfh2l53v3mp7lfi.apps.googleusercontent.com";
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoogleButton.mjs","sources":["../../../src/GoogleButton/GoogleButton.tsx"],"sourcesContent":["import { GoogleCredentialResponse } from '@medplum/core';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { createScriptTag } from '../utils/script';\n\ninterface GoogleApi {\n accounts: {\n id: {\n initialize: (args: any) => void;\n renderButton: (parent: HTMLElement, args: any) => void;\n };\n };\n}\n\ndeclare const google: GoogleApi;\n\nexport interface GoogleButtonProps {\n readonly googleClientId?: string;\n readonly handleGoogleCredential: (response: GoogleCredentialResponse) => void;\n}\n\nexport function GoogleButton(props: GoogleButtonProps): JSX.Element | null {\n const medplum = useMedplum();\n const { googleClientId, handleGoogleCredential } = props;\n const parentRef = useRef<HTMLDivElement>(null);\n const [scriptLoaded, setScriptLoaded] = useState<boolean>(typeof google !== 'undefined');\n const [initialized, setInitialized] = useState<boolean>(false);\n const [buttonRendered, setButtonRendered] = useState<boolean>(false);\n\n useEffect(() => {\n if (typeof google === 'undefined') {\n createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));\n return;\n }\n\n if (!initialized) {\n google.accounts.id.initialize({\n client_id: googleClientId,\n callback: handleGoogleCredential,\n });\n setInitialized(true);\n }\n\n if (parentRef.current && !buttonRendered) {\n google.accounts.id.renderButton(parentRef.current, {});\n setButtonRendered(true);\n }\n }, [medplum, googleClientId, initialized, scriptLoaded, parentRef, buttonRendered, handleGoogleCredential]);\n\n if (!googleClientId) {\n return null;\n }\n\n return <div ref={parentRef} />;\n}\n\nexport function getGoogleClientId(clientId: string | undefined): string | undefined {\n if (clientId) {\n return clientId;\n }\n\n if (typeof window !== 'undefined') {\n const origin = window.location.protocol + '//' + window.location.host;\n const authorizedOrigins = process.env.GOOGLE_AUTH_ORIGINS?.split(',') ?? [];\n if (authorizedOrigins.includes(origin)) {\n return process.env.GOOGLE_CLIENT_ID;\n }\n }\n\n return undefined;\n}\n"],"names":[],"mappings":";;;;AAqBM,SAAU,YAAY,CAAC,KAAwB,EAAA;AACnD,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,EAAE,cAAc,EAAE,sBAAsB,EAAE,GAAG,KAAK,CAAC;AACzD,IAAA,MAAM,SAAS,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;AAC/C,IAAA,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC;IACzF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC/D,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAErE,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,eAAe,CAAC,wCAAwC,EAAE,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YACvF,OAAO;AACR,SAAA;QAED,IAAI,CAAC,WAAW,EAAE;AAChB,YAAA,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC;AAC5B,gBAAA,SAAS,EAAE,cAAc;AACzB,gBAAA,QAAQ,EAAE,sBAAsB;AACjC,aAAA,CAAC,CAAC;YACH,cAAc,CAAC,IAAI,CAAC,CAAC;AACtB,SAAA;AAED,QAAA,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,cAAc,EAAE;AACxC,YAAA,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACvD,iBAAiB,CAAC,IAAI,CAAC,CAAC;AACzB,SAAA;AACH,KAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAE5G,IAAI,CAAC,cAAc,EAAE;AACnB,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;AAED,IAAA,OAAO,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAG,EAAE,SAAS,GAAI,CAAC;AACjC,CAAC;AAEK,SAAU,iBAAiB,CAAC,QAA4B,EAAA;AAC5D,IAAA,IAAI,QAAQ,EAAE;AACZ,QAAA,OAAO,QAAQ,CAAC;AACjB,KAAA;AAED,IAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;AACjC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACtE,QAAA,MAAM,iBAAiB,GAAG,
|
|
1
|
+
{"version":3,"file":"GoogleButton.mjs","sources":["../../../src/GoogleButton/GoogleButton.tsx"],"sourcesContent":["import { GoogleCredentialResponse } from '@medplum/core';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { createScriptTag } from '../utils/script';\n\ninterface GoogleApi {\n accounts: {\n id: {\n initialize: (args: any) => void;\n renderButton: (parent: HTMLElement, args: any) => void;\n };\n };\n}\n\ndeclare const google: GoogleApi;\n\nexport interface GoogleButtonProps {\n readonly googleClientId?: string;\n readonly handleGoogleCredential: (response: GoogleCredentialResponse) => void;\n}\n\nexport function GoogleButton(props: GoogleButtonProps): JSX.Element | null {\n const medplum = useMedplum();\n const { googleClientId, handleGoogleCredential } = props;\n const parentRef = useRef<HTMLDivElement>(null);\n const [scriptLoaded, setScriptLoaded] = useState<boolean>(typeof google !== 'undefined');\n const [initialized, setInitialized] = useState<boolean>(false);\n const [buttonRendered, setButtonRendered] = useState<boolean>(false);\n\n useEffect(() => {\n if (typeof google === 'undefined') {\n createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));\n return;\n }\n\n if (!initialized) {\n google.accounts.id.initialize({\n client_id: googleClientId,\n callback: handleGoogleCredential,\n });\n setInitialized(true);\n }\n\n if (parentRef.current && !buttonRendered) {\n google.accounts.id.renderButton(parentRef.current, {});\n setButtonRendered(true);\n }\n }, [medplum, googleClientId, initialized, scriptLoaded, parentRef, buttonRendered, handleGoogleCredential]);\n\n if (!googleClientId) {\n return null;\n }\n\n return <div ref={parentRef} />;\n}\n\nexport function getGoogleClientId(clientId: string | undefined): string | undefined {\n if (clientId) {\n return clientId;\n }\n\n if (typeof window !== 'undefined') {\n const origin = window.location.protocol + '//' + window.location.host;\n const authorizedOrigins = process.env.GOOGLE_AUTH_ORIGINS?.split(',') ?? [];\n if (authorizedOrigins.includes(origin)) {\n return process.env.GOOGLE_CLIENT_ID;\n }\n }\n\n return undefined;\n}\n"],"names":[],"mappings":";;;;AAqBM,SAAU,YAAY,CAAC,KAAwB,EAAA;AACnD,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,EAAE,cAAc,EAAE,sBAAsB,EAAE,GAAG,KAAK,CAAC;AACzD,IAAA,MAAM,SAAS,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;AAC/C,IAAA,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC;IACzF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC/D,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAErE,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,eAAe,CAAC,wCAAwC,EAAE,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YACvF,OAAO;AACR,SAAA;QAED,IAAI,CAAC,WAAW,EAAE;AAChB,YAAA,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC;AAC5B,gBAAA,SAAS,EAAE,cAAc;AACzB,gBAAA,QAAQ,EAAE,sBAAsB;AACjC,aAAA,CAAC,CAAC;YACH,cAAc,CAAC,IAAI,CAAC,CAAC;AACtB,SAAA;AAED,QAAA,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,cAAc,EAAE;AACxC,YAAA,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACvD,iBAAiB,CAAC,IAAI,CAAC,CAAC;AACzB,SAAA;AACH,KAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAE5G,IAAI,CAAC,cAAc,EAAE;AACnB,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;AAED,IAAA,OAAO,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAG,EAAE,SAAS,GAAI,CAAC;AACjC,CAAC;AAEK,SAAU,iBAAiB,CAAC,QAA4B,EAAA;AAC5D,IAAA,IAAI,QAAQ,EAAE;AACZ,QAAA,OAAO,QAAQ,CAAC;AACjB,KAAA;AAED,IAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;AACjC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACtE,QAAA,MAAM,iBAAiB,GAAG,6NAA+B,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;AAC5E,QAAA,IAAI,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AACtC,YAAA,OAAO,0EAA4B,CAAC;AACrC,SAAA;AACF,KAAA;AAED,IAAA,OAAO,SAAS,CAAC;AACnB;;;;"}
|
|
@@ -8,6 +8,8 @@ const reactContext = createContext(undefined);
|
|
|
8
8
|
* Medplum context includes:
|
|
9
9
|
* 1) medplum - Medplum client library
|
|
10
10
|
* 2) profile - The current user profile (if signed in)
|
|
11
|
+
* @param props The MedplumProvider React props.
|
|
12
|
+
* @returns The MedplumProvider React node.
|
|
11
13
|
*/
|
|
12
14
|
function MedplumProvider(props) {
|
|
13
15
|
const medplum = props.medplum;
|
|
@@ -42,6 +44,7 @@ function MedplumProvider(props) {
|
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
46
|
* Returns the MedplumContext instance.
|
|
47
|
+
* @returns The MedplumContext instance.
|
|
45
48
|
*/
|
|
46
49
|
function useMedplumContext() {
|
|
47
50
|
return useContext(reactContext);
|
|
@@ -49,6 +52,7 @@ function useMedplumContext() {
|
|
|
49
52
|
/**
|
|
50
53
|
* Returns the MedplumClient instance.
|
|
51
54
|
* This is a shortcut for useMedplumContext().medplum.
|
|
55
|
+
* @returns The MedplumClient instance.
|
|
52
56
|
*/
|
|
53
57
|
function useMedplum() {
|
|
54
58
|
return useMedplumContext().medplum;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MedplumProvider.mjs","sources":["../../../src/MedplumProvider/MedplumProvider.tsx"],"sourcesContent":["import { MedplumClient, ProfileResource } from '@medplum/core';\nimport { showNotification } from '@mantine/notifications';\nimport React, { createContext, useContext, useEffect, useState } from 'react';\n\nconst reactContext = createContext(undefined as MedplumContext | undefined);\n\nexport type MepdlumNavigateFunction = (path: string) => void;\n\nexport interface MedplumProviderProps {\n medplum: MedplumClient;\n navigate?: MepdlumNavigateFunction;\n children: React.ReactNode;\n}\n\nexport interface MedplumContext {\n medplum: MedplumClient;\n navigate: MepdlumNavigateFunction;\n profile?: ProfileResource;\n loading: boolean;\n}\n\n/**\n * The MedplumProvider component provides Medplum context state.\n *\n * Medplum context includes:\n * 1) medplum - Medplum client library\n * 2) profile - The current user profile (if signed in)\n */\nexport function MedplumProvider(props: MedplumProviderProps): JSX.Element {\n const medplum = props.medplum;\n const navigate = props.navigate || defaultNavigate;\n\n const [state, setState] = useState({\n profile: medplum.getProfile(),\n loading: false,\n });\n\n useEffect(() => {\n function eventListener(): void {\n setState({\n ...state,\n profile: medplum.getProfile(),\n });\n }\n\n medplum.addEventListener('change', eventListener);\n return () => medplum.removeEventListeneer('change', eventListener);\n }, [medplum, state]);\n\n useEffect(() => {\n function eventListener(): void {\n showNotification({ color: 'red', message: 'No connection to server', autoClose: false });\n }\n medplum.addEventListener('offline', eventListener);\n return () => medplum.removeEventListeneer('offline', eventListener);\n }, [medplum]);\n\n const medplumContext = {\n ...state,\n medplum,\n navigate,\n };\n\n return <reactContext.Provider value={medplumContext}>{props.children}</reactContext.Provider>;\n}\n\n/**\n * Returns the MedplumContext instance.\n */\nexport function useMedplumContext(): MedplumContext {\n return useContext(reactContext) as MedplumContext;\n}\n\n/**\n * Returns the MedplumClient instance.\n * This is a shortcut for useMedplumContext().medplum.\n */\nexport function useMedplum(): MedplumClient {\n return useMedplumContext().medplum;\n}\n\n/**\n * Returns the Medplum navigate function.\n * @returns The Medplum navigate function.\n */\nexport function useMedplumNavigate(): MepdlumNavigateFunction {\n return useMedplumContext().navigate;\n}\n\n/**\n * Returns the current Medplum user profile (if signed in).\n * This is a shortcut for useMedplumContext().profile.\n * @returns The current user profile.\n */\nexport function useMedplumProfile(): ProfileResource | undefined {\n return useMedplumContext().profile;\n}\n\n/**\n * The default \"navigate\" function which simply uses window.location.href.\n * @param path The path to navigate to.\n */\nfunction defaultNavigate(path: string): void {\n window.location.assign(path);\n}\n"],"names":[],"mappings":";;;AAIA,MAAM,YAAY,GAAG,aAAa,CAAC,SAAuC,CAAC,CAAC;AAiB5E
|
|
1
|
+
{"version":3,"file":"MedplumProvider.mjs","sources":["../../../src/MedplumProvider/MedplumProvider.tsx"],"sourcesContent":["import { MedplumClient, ProfileResource } from '@medplum/core';\nimport { showNotification } from '@mantine/notifications';\nimport React, { createContext, useContext, useEffect, useState } from 'react';\n\nconst reactContext = createContext(undefined as MedplumContext | undefined);\n\nexport type MepdlumNavigateFunction = (path: string) => void;\n\nexport interface MedplumProviderProps {\n medplum: MedplumClient;\n navigate?: MepdlumNavigateFunction;\n children: React.ReactNode;\n}\n\nexport interface MedplumContext {\n medplum: MedplumClient;\n navigate: MepdlumNavigateFunction;\n profile?: ProfileResource;\n loading: boolean;\n}\n\n/**\n * The MedplumProvider component provides Medplum context state.\n *\n * Medplum context includes:\n * 1) medplum - Medplum client library\n * 2) profile - The current user profile (if signed in)\n * @param props The MedplumProvider React props.\n * @returns The MedplumProvider React node.\n */\nexport function MedplumProvider(props: MedplumProviderProps): JSX.Element {\n const medplum = props.medplum;\n const navigate = props.navigate || defaultNavigate;\n\n const [state, setState] = useState({\n profile: medplum.getProfile(),\n loading: false,\n });\n\n useEffect(() => {\n function eventListener(): void {\n setState({\n ...state,\n profile: medplum.getProfile(),\n });\n }\n\n medplum.addEventListener('change', eventListener);\n return () => medplum.removeEventListeneer('change', eventListener);\n }, [medplum, state]);\n\n useEffect(() => {\n function eventListener(): void {\n showNotification({ color: 'red', message: 'No connection to server', autoClose: false });\n }\n medplum.addEventListener('offline', eventListener);\n return () => medplum.removeEventListeneer('offline', eventListener);\n }, [medplum]);\n\n const medplumContext = {\n ...state,\n medplum,\n navigate,\n };\n\n return <reactContext.Provider value={medplumContext}>{props.children}</reactContext.Provider>;\n}\n\n/**\n * Returns the MedplumContext instance.\n * @returns The MedplumContext instance.\n */\nexport function useMedplumContext(): MedplumContext {\n return useContext(reactContext) as MedplumContext;\n}\n\n/**\n * Returns the MedplumClient instance.\n * This is a shortcut for useMedplumContext().medplum.\n * @returns The MedplumClient instance.\n */\nexport function useMedplum(): MedplumClient {\n return useMedplumContext().medplum;\n}\n\n/**\n * Returns the Medplum navigate function.\n * @returns The Medplum navigate function.\n */\nexport function useMedplumNavigate(): MepdlumNavigateFunction {\n return useMedplumContext().navigate;\n}\n\n/**\n * Returns the current Medplum user profile (if signed in).\n * This is a shortcut for useMedplumContext().profile.\n * @returns The current user profile.\n */\nexport function useMedplumProfile(): ProfileResource | undefined {\n return useMedplumContext().profile;\n}\n\n/**\n * The default \"navigate\" function which simply uses window.location.href.\n * @param path The path to navigate to.\n */\nfunction defaultNavigate(path: string): void {\n window.location.assign(path);\n}\n"],"names":[],"mappings":";;;AAIA,MAAM,YAAY,GAAG,aAAa,CAAC,SAAuC,CAAC,CAAC;AAiB5E;;;;;;;;AAQG;AACG,SAAU,eAAe,CAAC,KAA2B,EAAA;AACzD,IAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;AAC9B,IAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,eAAe,CAAC;AAEnD,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC;AACjC,QAAA,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE;AAC7B,QAAA,OAAO,EAAE,KAAK;AACf,KAAA,CAAC,CAAC;IAEH,SAAS,CAAC,MAAK;AACb,QAAA,SAAS,aAAa,GAAA;AACpB,YAAA,QAAQ,CAAC;AACP,gBAAA,GAAG,KAAK;AACR,gBAAA,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE;AAC9B,aAAA,CAAC,CAAC;SACJ;AAED,QAAA,OAAO,CAAC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAClD,OAAO,MAAM,OAAO,CAAC,oBAAoB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AACrE,KAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAErB,SAAS,CAAC,MAAK;AACb,QAAA,SAAS,aAAa,GAAA;AACpB,YAAA,gBAAgB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,yBAAyB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;SAC1F;AACD,QAAA,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACnD,OAAO,MAAM,OAAO,CAAC,oBAAoB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AACtE,KAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;AAEd,IAAA,MAAM,cAAc,GAAG;AACrB,QAAA,GAAG,KAAK;QACR,OAAO;QACP,QAAQ;KACT,CAAC;AAEF,IAAA,OAAO,KAAC,CAAA,aAAA,CAAA,YAAY,CAAC,QAAQ,EAAC,EAAA,KAAK,EAAE,cAAc,EAAG,EAAA,KAAK,CAAC,QAAQ,CAAyB,CAAC;AAChG,CAAC;AAED;;;AAGG;SACa,iBAAiB,GAAA;AAC/B,IAAA,OAAO,UAAU,CAAC,YAAY,CAAmB,CAAC;AACpD,CAAC;AAED;;;;AAIG;SACa,UAAU,GAAA;AACxB,IAAA,OAAO,iBAAiB,EAAE,CAAC,OAAO,CAAC;AACrC,CAAC;AAED;;;AAGG;SACa,kBAAkB,GAAA;AAChC,IAAA,OAAO,iBAAiB,EAAE,CAAC,QAAQ,CAAC;AACtC,CAAC;AAED;;;;AAIG;SACa,iBAAiB,GAAA;AAC/B,IAAA,OAAO,iBAAiB,EAAE,CAAC,OAAO,CAAC;AACrC,CAAC;AAED;;;AAGG;AACH,SAAS,eAAe,CAAC,IAAY,EAAA;AACnC,IAAA,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/B;;;;"}
|
|
@@ -222,7 +222,8 @@ let nextId = 1;
|
|
|
222
222
|
* React needs unique IDs for components for rendering performance.
|
|
223
223
|
* All of the important components in the questionnaire builder have id properties for this:
|
|
224
224
|
* Questionnaire, QuestionnaireItem, and QuestionnaireItemAnswerOption.
|
|
225
|
-
* @
|
|
225
|
+
* @param existing Optional existing id which will update nextId.
|
|
226
|
+
* @returns A unique key.
|
|
226
227
|
*/
|
|
227
228
|
function generateId(existing) {
|
|
228
229
|
if (existing) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlanDefinitionBuilder.mjs","sources":["../../../src/PlanDefinitionBuilder/PlanDefinitionBuilder.tsx"],"sourcesContent":["import { Anchor, Button, createStyles, NativeSelect, Stack, TextInput } from '@mantine/core';\nimport { getReferenceString, IndexedStructureDefinition, PropertyType } from '@medplum/core';\nimport { ElementDefinition, PlanDefinition, PlanDefinitionAction, Reference, ResourceType } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Form } from '../Form/Form';\nimport { FormSection } from '../FormSection/FormSection';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { ReferenceDisplay } from '../ReferenceDisplay/ReferenceDisplay';\nimport { setPropertyValue } from '../ResourceForm/ResourceForm';\nimport { ResourceInput } from '../ResourceInput/ResourceInput';\nimport { getValueAndType, ResourcePropertyDisplay } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\nimport { ResourcePropertyInput } from '../ResourcePropertyInput/ResourcePropertyInput';\nimport { useResource } from '../useResource/useResource';\nimport { killEvent } from '../utils/dom';\n\nconst useStyles = createStyles((theme) => ({\n section: {\n position: 'relative',\n margin: '4px 4px 8px 0',\n padding: '6px 12px 16px 6px',\n border: `1.5px solid ${theme.colors.gray[1]}`,\n borderRadius: theme.radius.sm,\n transition: 'all 0.1s',\n },\n\n hovering: {\n border: `1.5px solid ${theme.colors.blue[5]}`,\n },\n\n editing: {\n border: `1.5px solid ${theme.colors.gray[1]}`,\n borderLeft: `4px solid ${theme.colors.blue[5]}`,\n },\n\n bottomActions: {\n position: 'absolute',\n right: 4,\n bottom: 0,\n fontSize: theme.fontSizes.xs,\n\n '& a': {\n marginLeft: 8,\n },\n },\n}));\n\nexport interface PlanDefinitionBuilderProps {\n value: PlanDefinition | Reference<PlanDefinition>;\n onSubmit: (result: PlanDefinition) => void;\n}\n\nexport function PlanDefinitionBuilder(props: PlanDefinitionBuilderProps): JSX.Element | null {\n const medplum = useMedplum();\n const defaultValue = useResource(props.value);\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>(undefined);\n const [selectedKey, setSelectedKey] = useState<string>();\n const [hoverKey, setHoverKey] = useState<string>();\n const [value, setValue] = useState<PlanDefinition>();\n\n function handleDocumentMouseOver(): void {\n setHoverKey(undefined);\n }\n\n function handleDocumentClick(): void {\n setSelectedKey(undefined);\n }\n\n const valueRef = useRef<PlanDefinition>();\n valueRef.current = value;\n\n useEffect(() => {\n medplum.requestSchema('PlanDefinition').then(setSchema).catch(console.log);\n }, [medplum]);\n\n useEffect(() => {\n setValue(ensurePlanDefinitionKeys(defaultValue ?? { resourceType: 'PlanDefinition' }));\n document.addEventListener('mouseover', handleDocumentMouseOver);\n document.addEventListener('click', handleDocumentClick);\n return () => {\n document.removeEventListener('mouseover', handleDocumentMouseOver);\n document.removeEventListener('click', handleDocumentClick);\n };\n }, [defaultValue]);\n\n if (!schema || !value) {\n return null;\n }\n\n function changeProperty(property: string, newValue: any): void {\n setValue({\n ...valueRef.current,\n [property]: newValue,\n } as PlanDefinition);\n }\n\n return (\n <div>\n <Form testid=\"questionnaire-form\" onSubmit={() => props.onSubmit(value)}>\n <TextInput\n label=\"Plan Title\"\n defaultValue={value.title}\n onChange={(e) => changeProperty('title', e.currentTarget.value)}\n />\n <ActionArrayBuilder\n actions={value.action || []}\n selectedKey={selectedKey}\n setSelectedKey={setSelectedKey}\n hoverKey={hoverKey}\n setHoverKey={setHoverKey}\n onChange={(x) => changeProperty('action', x)}\n />\n <Button type=\"submit\">Save</Button>\n </Form>\n </div>\n );\n}\n\ninterface ActionArrayBuilderProps {\n actions: PlanDefinitionAction[];\n selectedKey: string | undefined;\n setSelectedKey: (key: string | undefined) => void;\n hoverKey: string | undefined;\n setHoverKey: (key: string | undefined) => void;\n onChange: (actions: PlanDefinitionAction[]) => void;\n}\n\nfunction ActionArrayBuilder(props: ActionArrayBuilderProps): JSX.Element {\n const { classes } = useStyles();\n const actionsRef = useRef<PlanDefinitionAction[]>();\n actionsRef.current = props.actions;\n\n function changeAction(changedAction: PlanDefinitionAction): void {\n props.onChange(\n (actionsRef.current as PlanDefinition[]).map((i) => (i.id === changedAction.id ? changedAction : i))\n );\n }\n\n function addAction(addedAction: PlanDefinitionAction): void {\n props.onChange([...(actionsRef.current as PlanDefinition[]), addedAction]);\n props.setSelectedKey(addedAction.id);\n }\n\n function removeAction(removedAction: PlanDefinitionAction): void {\n props.onChange((actionsRef.current as PlanDefinition[]).filter((i) => i !== removedAction));\n }\n\n return (\n <div className={classes.section}>\n {props.actions.map((action) => (\n <div key={action.id}>\n <ActionBuilder\n action={action}\n selectedKey={props.selectedKey}\n setSelectedKey={props.setSelectedKey}\n hoverKey={props.hoverKey}\n setHoverKey={props.setHoverKey}\n onChange={changeAction}\n onRemove={() => removeAction(action)}\n />\n </div>\n ))}\n <div className={classes.bottomActions}>\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n killEvent(e);\n addAction({ id: generateId() });\n }}\n >\n Add action\n </Anchor>\n </div>\n </div>\n );\n}\n\ninterface ActionBuilderProps {\n action: PlanDefinitionAction;\n selectedKey: string | undefined;\n setSelectedKey: (key: string | undefined) => void;\n hoverKey: string | undefined;\n setHoverKey: (key: string | undefined) => void;\n onChange: (action: PlanDefinitionAction) => void;\n onRemove: () => void;\n}\n\nfunction ActionBuilder(props: ActionBuilderProps): JSX.Element {\n const { classes, cx } = useStyles();\n const { action } = props;\n const actionType = getInitialActionType(action);\n const editing = props.selectedKey === props.action.id;\n const hovering = props.hoverKey === props.action.id;\n\n function onClick(e: React.SyntheticEvent): void {\n e.stopPropagation();\n props.setSelectedKey(props.action.id);\n }\n\n function onHover(e: React.SyntheticEvent): void {\n killEvent(e);\n props.setHoverKey(props.action.id);\n }\n\n const className = cx(classes.section, {\n [classes.editing]: editing,\n [classes.hovering]: hovering && !editing,\n });\n\n return (\n <div data-testid={action.id} className={className} onClick={onClick} onMouseOver={onHover}>\n {editing ? (\n <ActionEditor\n action={action}\n actionType={actionType}\n onChange={props.onChange}\n selectedKey={props.selectedKey}\n setSelectedKey={props.setSelectedKey}\n hoverKey={props.hoverKey}\n setHoverKey={props.setHoverKey}\n onRemove={props.onRemove}\n />\n ) : (\n <ActionDisplay action={action} actionType={actionType} />\n )}\n <div className={classes.bottomActions}>\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n props.onRemove();\n }}\n >\n Remove\n </Anchor>\n </div>\n </div>\n );\n}\n\nconst timingProperty: ElementDefinition = {\n path: 'PlanDefinition.action.timing[x]',\n min: 0,\n max: '1',\n type: [{ code: 'dateTime' }, { code: 'Period' }, { code: 'Range' }, { code: 'Timing' }],\n};\n\ninterface ActionDisplayProps {\n action: PlanDefinitionAction;\n actionType: string | undefined;\n}\n\nfunction ActionDisplay(props: ActionDisplayProps): JSX.Element {\n const { action, actionType } = props;\n const [propertyValue, propertyType] = getActionTiming(action);\n return (\n <div>\n <div>\n {action.title || 'Untitled'} {actionType && `(${actionType})`}\n </div>\n {action.definitionCanonical && (\n <div>\n <ReferenceDisplay value={{ reference: action.definitionCanonical }} />\n </div>\n )}\n {propertyValue && (\n <div>\n <ResourcePropertyDisplay property={timingProperty} propertyType={propertyType} value={propertyValue} />\n </div>\n )}\n </div>\n );\n}\n\ninterface ActionEditorProps {\n action: PlanDefinitionAction;\n actionType: string | undefined;\n selectedKey: string | undefined;\n setSelectedKey: (key: string | undefined) => void;\n hoverKey: string | undefined;\n setHoverKey: (key: string | undefined) => void;\n onChange: (action: PlanDefinitionAction) => void;\n onRemove: () => void;\n}\n\nfunction ActionEditor(props: ActionEditorProps): JSX.Element {\n const { action } = props;\n const [actionType, setActionType] = useState<string | undefined>(props.actionType);\n\n function changeProperty(property: string, value: any): void {\n props.onChange({\n ...action,\n [property]: value,\n } as PlanDefinitionAction);\n }\n\n return (\n <Stack spacing=\"xl\">\n <TextInput\n name={`actionTitle-${action.id}`}\n label=\"Title\"\n defaultValue={action.title}\n onChange={(e) => changeProperty('title', e.currentTarget.value)}\n />\n <TextInput\n name={`actionDescription-${action.id}`}\n label=\"Description\"\n defaultValue={action.description}\n onChange={(e) => changeProperty('description', e.currentTarget.value)}\n />\n <NativeSelect\n label=\"Type of Action\"\n description=\"The type of the action to be performed.\"\n name={`actionType-${action.id}`}\n defaultValue={actionType}\n onChange={(e) => setActionType(e.currentTarget.value)}\n data={['', 'appointment', 'lab', 'questionnaire', 'task']}\n />\n {action.action && action.action.length > 0 && (\n <ActionArrayBuilder\n actions={action.action}\n selectedKey={props.selectedKey}\n setSelectedKey={props.setSelectedKey}\n hoverKey={props.hoverKey}\n setHoverKey={props.setHoverKey}\n onChange={(x) => changeProperty('action', x)}\n />\n )}\n {(() => {\n switch (actionType) {\n case 'appointment':\n return (\n <ActionResourceTypeBuilder\n title=\"Appointment\"\n description=\"The subject must schedule an appointment from the schedule.\"\n resourceType=\"Schedule\"\n action={action}\n onChange={props.onChange}\n />\n );\n case 'lab':\n return (\n <ActionResourceTypeBuilder\n title=\"Lab\"\n description=\"The subject must complete the following lab panel.\"\n resourceType=\"ActivityDefinition\"\n action={action}\n onChange={props.onChange}\n />\n );\n case 'questionnaire':\n return (\n <ActionResourceTypeBuilder\n title=\"Questionnaire\"\n description=\"The subject must complete the selected questionnaire.\"\n resourceType=\"Questionnaire\"\n action={action}\n onChange={props.onChange}\n />\n );\n case 'task':\n return (\n <ActionResourceTypeBuilder\n title=\"Task\"\n description=\"The subject must complete the following task.\"\n resourceType=\"ActivityDefinition\"\n action={action}\n onChange={props.onChange}\n />\n );\n default:\n return null;\n }\n })()}\n <FormSection title=\"Timing\" description=\"When the action should take place.\">\n <ActionTimingInput name={'timing-' + action.id} action={action} onChange={props.onChange} />\n </FormSection>\n </Stack>\n );\n}\n\ninterface ActionResourceTypeBuilderProps {\n action: PlanDefinitionAction;\n title: string;\n description: string;\n resourceType: ResourceType;\n onChange: (action: PlanDefinitionAction) => void;\n}\n\nfunction ActionResourceTypeBuilder(props: ActionResourceTypeBuilderProps): JSX.Element {\n const { id, definitionCanonical } = props.action;\n const reference = definitionCanonical?.startsWith(props.resourceType + '/')\n ? { reference: definitionCanonical }\n : undefined;\n return (\n <ResourceInput\n name={id as string}\n resourceType={props.resourceType}\n defaultValue={reference}\n loadOnFocus={true}\n onChange={(newValue) => {\n if (newValue) {\n props.onChange({ ...props.action, definitionCanonical: getReferenceString(newValue) });\n } else {\n props.onChange({ ...props.action, definitionCanonical: undefined });\n }\n }}\n />\n );\n}\n\ninterface ActionTimingInputProps {\n name: string;\n action: PlanDefinitionAction;\n onChange: (action: PlanDefinitionAction) => void;\n}\n\nfunction ActionTimingInput(props: ActionTimingInputProps): JSX.Element {\n const value = props.action;\n const key = 'timing';\n const [propertyValue, propertyType] = getActionTiming(value);\n return (\n <ResourcePropertyInput\n property={timingProperty}\n name=\"timing[x]\"\n defaultValue={propertyValue}\n defaultPropertyType={propertyType}\n onChange={(newValue: any, propName?: string) => {\n props.onChange(setPropertyValue(value, key, propName ?? key, timingProperty, newValue));\n }}\n />\n );\n}\n\nfunction getInitialActionType(action: PlanDefinitionAction): string | undefined {\n if (action.definitionCanonical?.startsWith('Schedule')) {\n return 'appointment';\n }\n\n if (action.definitionCanonical?.startsWith('Questionnaire/')) {\n return 'questionnaire';\n }\n\n if (action.definitionCanonical?.startsWith('ActivityDefinition/')) {\n return 'task';\n }\n\n return undefined;\n}\n\nfunction getActionTiming(action: PlanDefinitionAction): [any, PropertyType] {\n return getValueAndType({ type: 'PlanDefinitionAction', value: action }, 'timing');\n}\n\nlet nextId = 1;\n\n/**\n * Generates a unique ID.\n * React needs unique IDs for components for rendering performance.\n * All of the important components in the questionnaire builder have id properties for this:\n * Questionnaire, QuestionnaireItem, and QuestionnaireItemAnswerOption.\n * @return A unique key.\n */\nfunction generateId(existing?: string): string {\n if (existing) {\n if (existing.startsWith('id-')) {\n const existingNum = parseInt(existing.substring(3));\n if (!isNaN(existingNum)) {\n nextId = Math.max(nextId, existingNum + 1);\n }\n }\n return existing;\n }\n return 'id-' + nextId++;\n}\n\nfunction ensurePlanDefinitionKeys(planDefinition: PlanDefinition): PlanDefinition {\n return {\n ...planDefinition,\n action: ensurePlanDefinitionActionKeys(planDefinition.action),\n } as PlanDefinition;\n}\n\nfunction ensurePlanDefinitionActionKeys(\n actions: PlanDefinitionAction[] | undefined\n): PlanDefinitionAction[] | undefined {\n if (!actions) {\n return undefined;\n }\n return actions.map((action) => ({\n ...action,\n id: generateId(action.id),\n action: ensurePlanDefinitionActionKeys(action.action),\n }));\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAeA,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,KAAK,MAAM;AACzC,IAAA,OAAO,EAAE;AACP,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,MAAM,EAAE,eAAe;AACvB,QAAA,OAAO,EAAE,mBAAmB;QAC5B,MAAM,EAAE,CAAe,YAAA,EAAA,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAA;AAC7C,QAAA,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE;AAC7B,QAAA,UAAU,EAAE,UAAU;AACvB,KAAA;AAED,IAAA,QAAQ,EAAE;QACR,MAAM,EAAE,CAAe,YAAA,EAAA,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAA;AAC9C,KAAA;AAED,IAAA,OAAO,EAAE;QACP,MAAM,EAAE,CAAe,YAAA,EAAA,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAA;QAC7C,UAAU,EAAE,CAAa,UAAA,EAAA,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAA;AAChD,KAAA;AAED,IAAA,aAAa,EAAE;AACb,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,KAAK,EAAE,CAAC;AACR,QAAA,MAAM,EAAE,CAAC;AACT,QAAA,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE;AAE5B,QAAA,KAAK,EAAE;AACL,YAAA,UAAU,EAAE,CAAC;AACd,SAAA;AACF,KAAA;AACF,CAAA,CAAC,CAAC,CAAC;AAOE,SAAU,qBAAqB,CAAC,KAAiC,EAAA;AACrE,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAyC,SAAS,CAAC,CAAC;IACxF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,EAAU,CAAC;IACzD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,EAAU,CAAC;IACnD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAkB,CAAC;AAErD,IAAA,SAAS,uBAAuB,GAAA;QAC9B,WAAW,CAAC,SAAS,CAAC,CAAC;KACxB;AAED,IAAA,SAAS,mBAAmB,GAAA;QAC1B,cAAc,CAAC,SAAS,CAAC,CAAC;KAC3B;AAED,IAAA,MAAM,QAAQ,GAAG,MAAM,EAAkB,CAAC;AAC1C,IAAA,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IAEzB,SAAS,CAAC,MAAK;AACb,QAAA,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAC7E,KAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,SAAS,CAAC,MAAK;AACb,QAAA,QAAQ,CAAC,wBAAwB,CAAC,YAAY,IAAI,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC;AACvF,QAAA,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AAChE,QAAA,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AACxD,QAAA,OAAO,MAAK;AACV,YAAA,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AACnE,YAAA,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAC7D,SAAC,CAAC;AACJ,KAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAEnB,IAAA,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE;AACrB,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;AAED,IAAA,SAAS,cAAc,CAAC,QAAgB,EAAE,QAAa,EAAA;AACrD,QAAA,QAAQ,CAAC;YACP,GAAG,QAAQ,CAAC,OAAO;YACnB,CAAC,QAAQ,GAAG,QAAQ;AACH,SAAA,CAAC,CAAC;KACtB;AAED,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;AACE,QAAA,KAAA,CAAA,aAAA,CAAC,IAAI,EAAC,EAAA,MAAM,EAAC,oBAAoB,EAAC,QAAQ,EAAE,MAAM,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAA;AACrE,YAAA,KAAA,CAAA,aAAA,CAAC,SAAS,EAAA,EACR,KAAK,EAAC,YAAY,EAClB,YAAY,EAAE,KAAK,CAAC,KAAK,EACzB,QAAQ,EAAE,CAAC,CAAC,KAAK,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,EAC/D,CAAA;AACF,YAAA,KAAA,CAAA,aAAA,CAAC,kBAAkB,EACjB,EAAA,OAAO,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE,EAC3B,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,CAAC,CAAC,KAAK,cAAc,CAAC,QAAQ,EAAE,CAAC,CAAC,EAC5C,CAAA;YACF,KAAC,CAAA,aAAA,CAAA,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAc,EAAA,MAAA,CAAA,CAC9B,CACH,EACN;AACJ,CAAC;AAWD,SAAS,kBAAkB,CAAC,KAA8B,EAAA;AACxD,IAAA,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;AAChC,IAAA,MAAM,UAAU,GAAG,MAAM,EAA0B,CAAC;AACpD,IAAA,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAEnC,SAAS,YAAY,CAAC,aAAmC,EAAA;AACvD,QAAA,KAAK,CAAC,QAAQ,CACX,UAAU,CAAC,OAA4B,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,aAAa,CAAC,EAAE,GAAG,aAAa,GAAG,CAAC,CAAC,CAAC,CACrG,CAAC;KACH;IAED,SAAS,SAAS,CAAC,WAAiC,EAAA;AAClD,QAAA,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAI,UAAU,CAAC,OAA4B,EAAE,WAAW,CAAC,CAAC,CAAC;AAC3E,QAAA,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;KACtC;IAED,SAAS,YAAY,CAAC,aAAmC,EAAA;AACvD,QAAA,KAAK,CAAC,QAAQ,CAAE,UAAU,CAAC,OAA4B,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC;KAC7F;AAED,IAAA,QACE,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,OAAO,CAAC,OAAO,EAAA;AAC5B,QAAA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,MACxB,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAG,EAAE,MAAM,CAAC,EAAE,EAAA;YACjB,KAAC,CAAA,aAAA,CAAA,aAAa,IACZ,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,cAAc,EAAE,KAAK,CAAC,cAAc,EACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,YAAY,CAAC,MAAM,CAAC,EAAA,CACpC,CACE,CACP,CAAC;AACF,QAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,OAAO,CAAC,aAAa,EAAA;YACnC,KAAC,CAAA,aAAA,CAAA,MAAM,EACL,EAAA,IAAI,EAAC,GAAG,EACR,OAAO,EAAE,CAAC,CAAmB,KAAI;oBAC/B,SAAS,CAAC,CAAC,CAAC,CAAC;oBACb,SAAS,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;AAClC,iBAAC,EAGM,EAAA,YAAA,CAAA,CACL,CACF,EACN;AACJ,CAAC;AAYD,SAAS,aAAa,CAAC,KAAyB,EAAA;IAC9C,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC;AACpC,IAAA,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;AACzB,IAAA,MAAM,UAAU,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;IACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;IAEpD,SAAS,OAAO,CAAC,CAAuB,EAAA;QACtC,CAAC,CAAC,eAAe,EAAE,CAAC;QACpB,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;KACvC;IAED,SAAS,OAAO,CAAC,CAAuB,EAAA;QACtC,SAAS,CAAC,CAAC,CAAC,CAAC;QACb,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;KACpC;AAED,IAAA,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;AACpC,QAAA,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO;QAC1B,CAAC,OAAO,CAAC,QAAQ,GAAG,QAAQ,IAAI,CAAC,OAAO;AACzC,KAAA,CAAC,CAAC;AAEH,IAAA,QACE,KAAkB,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,aAAA,EAAA,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAA;AACtF,QAAA,OAAO,IACN,KAAC,CAAA,aAAA,CAAA,YAAY,EACX,EAAA,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,cAAc,EAAE,KAAK,CAAC,cAAc,EACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAA,CACxB,KAEF,KAAA,CAAA,aAAA,CAAC,aAAa,EAAC,EAAA,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAI,CAC1D;AACD,QAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,OAAO,CAAC,aAAa,EAAA;YACnC,KAAC,CAAA,aAAA,CAAA,MAAM,EACL,EAAA,IAAI,EAAC,GAAG,EACR,OAAO,EAAE,CAAC,CAAmB,KAAI;oBAC/B,CAAC,CAAC,cAAc,EAAE,CAAC;oBACnB,KAAK,CAAC,QAAQ,EAAE,CAAC;AACnB,iBAAC,EAGM,EAAA,QAAA,CAAA,CACL,CACF,EACN;AACJ,CAAC;AAED,MAAM,cAAc,GAAsB;AACxC,IAAA,IAAI,EAAE,iCAAiC;AACvC,IAAA,GAAG,EAAE,CAAC;AACN,IAAA,GAAG,EAAE,GAAG;IACR,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;CACxF,CAAC;AAOF,SAAS,aAAa,CAAC,KAAyB,EAAA;AAC9C,IAAA,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IACrC,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;AAC9D,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;AACE,QAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;YACG,MAAM,CAAC,KAAK,IAAI,UAAU;;AAAG,YAAA,UAAU,IAAI,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,CAAG,CACzD;QACL,MAAM,CAAC,mBAAmB,KACzB,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;AACE,YAAA,KAAA,CAAA,aAAA,CAAC,gBAAgB,EAAA,EAAC,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,mBAAmB,EAAE,EAAA,CAAI,CAClE,CACP;AACA,QAAA,aAAa,KACZ,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;AACE,YAAA,KAAA,CAAA,aAAA,CAAC,uBAAuB,EAAC,EAAA,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAA,CAAI,CACnG,CACP,CACG,EACN;AACJ,CAAC;AAaD,SAAS,YAAY,CAAC,KAAwB,EAAA;AAC5C,IAAA,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;AACzB,IAAA,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAqB,KAAK,CAAC,UAAU,CAAC,CAAC;AAEnF,IAAA,SAAS,cAAc,CAAC,QAAgB,EAAE,KAAU,EAAA;QAClD,KAAK,CAAC,QAAQ,CAAC;AACb,YAAA,GAAG,MAAM;YACT,CAAC,QAAQ,GAAG,KAAK;AACM,SAAA,CAAC,CAAC;KAC5B;AAED,IAAA,QACE,KAAC,CAAA,aAAA,CAAA,KAAK,EAAC,EAAA,OAAO,EAAC,IAAI,EAAA;AACjB,QAAA,KAAA,CAAA,aAAA,CAAC,SAAS,EACR,EAAA,IAAI,EAAE,CAAA,YAAA,EAAe,MAAM,CAAC,EAAE,CAAE,CAAA,EAChC,KAAK,EAAC,OAAO,EACb,YAAY,EAAE,MAAM,CAAC,KAAK,EAC1B,QAAQ,EAAE,CAAC,CAAC,KAAK,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,EAC/D,CAAA;AACF,QAAA,KAAA,CAAA,aAAA,CAAC,SAAS,EACR,EAAA,IAAI,EAAE,CAAA,kBAAA,EAAqB,MAAM,CAAC,EAAE,CAAE,CAAA,EACtC,KAAK,EAAC,aAAa,EACnB,YAAY,EAAE,MAAM,CAAC,WAAW,EAChC,QAAQ,EAAE,CAAC,CAAC,KAAK,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,EACrE,CAAA;QACF,KAAC,CAAA,aAAA,CAAA,YAAY,IACX,KAAK,EAAC,gBAAgB,EACtB,WAAW,EAAC,yCAAyC,EACrD,IAAI,EAAE,CAAc,WAAA,EAAA,MAAM,CAAC,EAAE,CAAE,CAAA,EAC/B,YAAY,EAAE,UAAU,EACxB,QAAQ,EAAE,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,EACrD,IAAI,EAAE,CAAC,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,CAAC,EACzD,CAAA;QACD,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,KACxC,KAAA,CAAA,aAAA,CAAC,kBAAkB,EAAA,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EACtB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,cAAc,EAAE,KAAK,CAAC,cAAc,EACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,QAAQ,EAAE,CAAC,CAAC,KAAK,cAAc,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAA,CAC5C,CACH;AACA,QAAA,CAAC,MAAK;AACL,YAAA,QAAQ,UAAU;AAChB,gBAAA,KAAK,aAAa;oBAChB,QACE,KAAC,CAAA,aAAA,CAAA,yBAAyB,EACxB,EAAA,KAAK,EAAC,aAAa,EACnB,WAAW,EAAC,6DAA6D,EACzE,YAAY,EAAC,UAAU,EACvB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,CAAA,EACF;AACJ,gBAAA,KAAK,KAAK;oBACR,QACE,KAAC,CAAA,aAAA,CAAA,yBAAyB,EACxB,EAAA,KAAK,EAAC,KAAK,EACX,WAAW,EAAC,oDAAoD,EAChE,YAAY,EAAC,oBAAoB,EACjC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,CAAA,EACF;AACJ,gBAAA,KAAK,eAAe;oBAClB,QACE,KAAC,CAAA,aAAA,CAAA,yBAAyB,EACxB,EAAA,KAAK,EAAC,eAAe,EACrB,WAAW,EAAC,uDAAuD,EACnE,YAAY,EAAC,eAAe,EAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,CAAA,EACF;AACJ,gBAAA,KAAK,MAAM;oBACT,QACE,KAAC,CAAA,aAAA,CAAA,yBAAyB,EACxB,EAAA,KAAK,EAAC,MAAM,EACZ,WAAW,EAAC,+CAA+C,EAC3D,YAAY,EAAC,oBAAoB,EACjC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,CAAA,EACF;AACJ,gBAAA;AACE,oBAAA,OAAO,IAAI,CAAC;AACf,aAAA;AACH,SAAC,GAAG;QACJ,KAAC,CAAA,aAAA,CAAA,WAAW,IAAC,KAAK,EAAC,QAAQ,EAAC,WAAW,EAAC,oCAAoC,EAAA;YAC1E,KAAC,CAAA,aAAA,CAAA,iBAAiB,IAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAI,CAAA,CAChF,CACR,EACR;AACJ,CAAC;AAUD,SAAS,yBAAyB,CAAC,KAAqC,EAAA;IACtE,MAAM,EAAE,EAAE,EAAE,mBAAmB,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;IACjD,MAAM,SAAS,GAAG,mBAAmB,EAAE,UAAU,CAAC,KAAK,CAAC,YAAY,GAAG,GAAG,CAAC;AACzE,UAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE;UAClC,SAAS,CAAC;IACd,QACE,KAAC,CAAA,aAAA,CAAA,aAAa,EACZ,EAAA,IAAI,EAAE,EAAY,EAClB,YAAY,EAAE,KAAK,CAAC,YAAY,EAChC,YAAY,EAAE,SAAS,EACvB,WAAW,EAAE,IAAI,EACjB,QAAQ,EAAE,CAAC,QAAQ,KAAI;AACrB,YAAA,IAAI,QAAQ,EAAE;AACZ,gBAAA,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,mBAAmB,EAAE,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxF,aAAA;AAAM,iBAAA;AACL,gBAAA,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,CAAC,CAAC;AACrE,aAAA;SACF,EAAA,CACD,EACF;AACJ,CAAC;AAQD,SAAS,iBAAiB,CAAC,KAA6B,EAAA;AACtD,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3B,MAAM,GAAG,GAAG,QAAQ,CAAC;IACrB,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAC7D,QACE,KAAC,CAAA,aAAA,CAAA,qBAAqB,EACpB,EAAA,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAC,WAAW,EAChB,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,YAAY,EACjC,QAAQ,EAAE,CAAC,QAAa,EAAE,QAAiB,KAAI;AAC7C,YAAA,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,IAAI,GAAG,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;SACzF,EAAA,CACD,EACF;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,MAA4B,EAAA;IACxD,IAAI,MAAM,CAAC,mBAAmB,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE;AACtD,QAAA,OAAO,aAAa,CAAC;AACtB,KAAA;IAED,IAAI,MAAM,CAAC,mBAAmB,EAAE,UAAU,CAAC,gBAAgB,CAAC,EAAE;AAC5D,QAAA,OAAO,eAAe,CAAC;AACxB,KAAA;IAED,IAAI,MAAM,CAAC,mBAAmB,EAAE,UAAU,CAAC,qBAAqB,CAAC,EAAE;AACjE,QAAA,OAAO,MAAM,CAAC;AACf,KAAA;AAED,IAAA,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,MAA4B,EAAA;AACnD,IAAA,OAAO,eAAe,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC;AACpF,CAAC;AAED,IAAI,MAAM,GAAG,CAAC,CAAC;AAEf;;;;;;AAMG;AACH,SAAS,UAAU,CAAC,QAAiB,EAAA;AACnC,IAAA,IAAI,QAAQ,EAAE;AACZ,QAAA,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;YAC9B,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,YAAA,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;gBACvB,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;AAC5C,aAAA;AACF,SAAA;AACD,QAAA,OAAO,QAAQ,CAAC;AACjB,KAAA;AACD,IAAA,OAAO,KAAK,GAAG,MAAM,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,wBAAwB,CAAC,cAA8B,EAAA;IAC9D,OAAO;AACL,QAAA,GAAG,cAAc;AACjB,QAAA,MAAM,EAAE,8BAA8B,CAAC,cAAc,CAAC,MAAM,CAAC;KAC5C,CAAC;AACtB,CAAC;AAED,SAAS,8BAA8B,CACrC,OAA2C,EAAA;IAE3C,IAAI,CAAC,OAAO,EAAE;AACZ,QAAA,OAAO,SAAS,CAAC;AAClB,KAAA;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM;AAC9B,QAAA,GAAG,MAAM;AACT,QAAA,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;AACzB,QAAA,MAAM,EAAE,8BAA8B,CAAC,MAAM,CAAC,MAAM,CAAC;AACtD,KAAA,CAAC,CAAC,CAAC;AACN;;;;"}
|
|
1
|
+
{"version":3,"file":"PlanDefinitionBuilder.mjs","sources":["../../../src/PlanDefinitionBuilder/PlanDefinitionBuilder.tsx"],"sourcesContent":["import { Anchor, Button, createStyles, NativeSelect, Stack, TextInput } from '@mantine/core';\nimport { getReferenceString, IndexedStructureDefinition, PropertyType } from '@medplum/core';\nimport { ElementDefinition, PlanDefinition, PlanDefinitionAction, Reference, ResourceType } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Form } from '../Form/Form';\nimport { FormSection } from '../FormSection/FormSection';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { ReferenceDisplay } from '../ReferenceDisplay/ReferenceDisplay';\nimport { setPropertyValue } from '../ResourceForm/ResourceForm';\nimport { ResourceInput } from '../ResourceInput/ResourceInput';\nimport { getValueAndType, ResourcePropertyDisplay } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\nimport { ResourcePropertyInput } from '../ResourcePropertyInput/ResourcePropertyInput';\nimport { useResource } from '../useResource/useResource';\nimport { killEvent } from '../utils/dom';\n\nconst useStyles = createStyles((theme) => ({\n section: {\n position: 'relative',\n margin: '4px 4px 8px 0',\n padding: '6px 12px 16px 6px',\n border: `1.5px solid ${theme.colors.gray[1]}`,\n borderRadius: theme.radius.sm,\n transition: 'all 0.1s',\n },\n\n hovering: {\n border: `1.5px solid ${theme.colors.blue[5]}`,\n },\n\n editing: {\n border: `1.5px solid ${theme.colors.gray[1]}`,\n borderLeft: `4px solid ${theme.colors.blue[5]}`,\n },\n\n bottomActions: {\n position: 'absolute',\n right: 4,\n bottom: 0,\n fontSize: theme.fontSizes.xs,\n\n '& a': {\n marginLeft: 8,\n },\n },\n}));\n\nexport interface PlanDefinitionBuilderProps {\n value: PlanDefinition | Reference<PlanDefinition>;\n onSubmit: (result: PlanDefinition) => void;\n}\n\nexport function PlanDefinitionBuilder(props: PlanDefinitionBuilderProps): JSX.Element | null {\n const medplum = useMedplum();\n const defaultValue = useResource(props.value);\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>(undefined);\n const [selectedKey, setSelectedKey] = useState<string>();\n const [hoverKey, setHoverKey] = useState<string>();\n const [value, setValue] = useState<PlanDefinition>();\n\n function handleDocumentMouseOver(): void {\n setHoverKey(undefined);\n }\n\n function handleDocumentClick(): void {\n setSelectedKey(undefined);\n }\n\n const valueRef = useRef<PlanDefinition>();\n valueRef.current = value;\n\n useEffect(() => {\n medplum.requestSchema('PlanDefinition').then(setSchema).catch(console.log);\n }, [medplum]);\n\n useEffect(() => {\n setValue(ensurePlanDefinitionKeys(defaultValue ?? { resourceType: 'PlanDefinition' }));\n document.addEventListener('mouseover', handleDocumentMouseOver);\n document.addEventListener('click', handleDocumentClick);\n return () => {\n document.removeEventListener('mouseover', handleDocumentMouseOver);\n document.removeEventListener('click', handleDocumentClick);\n };\n }, [defaultValue]);\n\n if (!schema || !value) {\n return null;\n }\n\n function changeProperty(property: string, newValue: any): void {\n setValue({\n ...valueRef.current,\n [property]: newValue,\n } as PlanDefinition);\n }\n\n return (\n <div>\n <Form testid=\"questionnaire-form\" onSubmit={() => props.onSubmit(value)}>\n <TextInput\n label=\"Plan Title\"\n defaultValue={value.title}\n onChange={(e) => changeProperty('title', e.currentTarget.value)}\n />\n <ActionArrayBuilder\n actions={value.action || []}\n selectedKey={selectedKey}\n setSelectedKey={setSelectedKey}\n hoverKey={hoverKey}\n setHoverKey={setHoverKey}\n onChange={(x) => changeProperty('action', x)}\n />\n <Button type=\"submit\">Save</Button>\n </Form>\n </div>\n );\n}\n\ninterface ActionArrayBuilderProps {\n actions: PlanDefinitionAction[];\n selectedKey: string | undefined;\n setSelectedKey: (key: string | undefined) => void;\n hoverKey: string | undefined;\n setHoverKey: (key: string | undefined) => void;\n onChange: (actions: PlanDefinitionAction[]) => void;\n}\n\nfunction ActionArrayBuilder(props: ActionArrayBuilderProps): JSX.Element {\n const { classes } = useStyles();\n const actionsRef = useRef<PlanDefinitionAction[]>();\n actionsRef.current = props.actions;\n\n function changeAction(changedAction: PlanDefinitionAction): void {\n props.onChange(\n (actionsRef.current as PlanDefinition[]).map((i) => (i.id === changedAction.id ? changedAction : i))\n );\n }\n\n function addAction(addedAction: PlanDefinitionAction): void {\n props.onChange([...(actionsRef.current as PlanDefinition[]), addedAction]);\n props.setSelectedKey(addedAction.id);\n }\n\n function removeAction(removedAction: PlanDefinitionAction): void {\n props.onChange((actionsRef.current as PlanDefinition[]).filter((i) => i !== removedAction));\n }\n\n return (\n <div className={classes.section}>\n {props.actions.map((action) => (\n <div key={action.id}>\n <ActionBuilder\n action={action}\n selectedKey={props.selectedKey}\n setSelectedKey={props.setSelectedKey}\n hoverKey={props.hoverKey}\n setHoverKey={props.setHoverKey}\n onChange={changeAction}\n onRemove={() => removeAction(action)}\n />\n </div>\n ))}\n <div className={classes.bottomActions}>\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n killEvent(e);\n addAction({ id: generateId() });\n }}\n >\n Add action\n </Anchor>\n </div>\n </div>\n );\n}\n\ninterface ActionBuilderProps {\n action: PlanDefinitionAction;\n selectedKey: string | undefined;\n setSelectedKey: (key: string | undefined) => void;\n hoverKey: string | undefined;\n setHoverKey: (key: string | undefined) => void;\n onChange: (action: PlanDefinitionAction) => void;\n onRemove: () => void;\n}\n\nfunction ActionBuilder(props: ActionBuilderProps): JSX.Element {\n const { classes, cx } = useStyles();\n const { action } = props;\n const actionType = getInitialActionType(action);\n const editing = props.selectedKey === props.action.id;\n const hovering = props.hoverKey === props.action.id;\n\n function onClick(e: React.SyntheticEvent): void {\n e.stopPropagation();\n props.setSelectedKey(props.action.id);\n }\n\n function onHover(e: React.SyntheticEvent): void {\n killEvent(e);\n props.setHoverKey(props.action.id);\n }\n\n const className = cx(classes.section, {\n [classes.editing]: editing,\n [classes.hovering]: hovering && !editing,\n });\n\n return (\n <div data-testid={action.id} className={className} onClick={onClick} onMouseOver={onHover}>\n {editing ? (\n <ActionEditor\n action={action}\n actionType={actionType}\n onChange={props.onChange}\n selectedKey={props.selectedKey}\n setSelectedKey={props.setSelectedKey}\n hoverKey={props.hoverKey}\n setHoverKey={props.setHoverKey}\n onRemove={props.onRemove}\n />\n ) : (\n <ActionDisplay action={action} actionType={actionType} />\n )}\n <div className={classes.bottomActions}>\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n props.onRemove();\n }}\n >\n Remove\n </Anchor>\n </div>\n </div>\n );\n}\n\nconst timingProperty: ElementDefinition = {\n path: 'PlanDefinition.action.timing[x]',\n min: 0,\n max: '1',\n type: [{ code: 'dateTime' }, { code: 'Period' }, { code: 'Range' }, { code: 'Timing' }],\n};\n\ninterface ActionDisplayProps {\n action: PlanDefinitionAction;\n actionType: string | undefined;\n}\n\nfunction ActionDisplay(props: ActionDisplayProps): JSX.Element {\n const { action, actionType } = props;\n const [propertyValue, propertyType] = getActionTiming(action);\n return (\n <div>\n <div>\n {action.title || 'Untitled'} {actionType && `(${actionType})`}\n </div>\n {action.definitionCanonical && (\n <div>\n <ReferenceDisplay value={{ reference: action.definitionCanonical }} />\n </div>\n )}\n {propertyValue && (\n <div>\n <ResourcePropertyDisplay property={timingProperty} propertyType={propertyType} value={propertyValue} />\n </div>\n )}\n </div>\n );\n}\n\ninterface ActionEditorProps {\n action: PlanDefinitionAction;\n actionType: string | undefined;\n selectedKey: string | undefined;\n setSelectedKey: (key: string | undefined) => void;\n hoverKey: string | undefined;\n setHoverKey: (key: string | undefined) => void;\n onChange: (action: PlanDefinitionAction) => void;\n onRemove: () => void;\n}\n\nfunction ActionEditor(props: ActionEditorProps): JSX.Element {\n const { action } = props;\n const [actionType, setActionType] = useState<string | undefined>(props.actionType);\n\n function changeProperty(property: string, value: any): void {\n props.onChange({\n ...action,\n [property]: value,\n } as PlanDefinitionAction);\n }\n\n return (\n <Stack spacing=\"xl\">\n <TextInput\n name={`actionTitle-${action.id}`}\n label=\"Title\"\n defaultValue={action.title}\n onChange={(e) => changeProperty('title', e.currentTarget.value)}\n />\n <TextInput\n name={`actionDescription-${action.id}`}\n label=\"Description\"\n defaultValue={action.description}\n onChange={(e) => changeProperty('description', e.currentTarget.value)}\n />\n <NativeSelect\n label=\"Type of Action\"\n description=\"The type of the action to be performed.\"\n name={`actionType-${action.id}`}\n defaultValue={actionType}\n onChange={(e) => setActionType(e.currentTarget.value)}\n data={['', 'appointment', 'lab', 'questionnaire', 'task']}\n />\n {action.action && action.action.length > 0 && (\n <ActionArrayBuilder\n actions={action.action}\n selectedKey={props.selectedKey}\n setSelectedKey={props.setSelectedKey}\n hoverKey={props.hoverKey}\n setHoverKey={props.setHoverKey}\n onChange={(x) => changeProperty('action', x)}\n />\n )}\n {(() => {\n switch (actionType) {\n case 'appointment':\n return (\n <ActionResourceTypeBuilder\n title=\"Appointment\"\n description=\"The subject must schedule an appointment from the schedule.\"\n resourceType=\"Schedule\"\n action={action}\n onChange={props.onChange}\n />\n );\n case 'lab':\n return (\n <ActionResourceTypeBuilder\n title=\"Lab\"\n description=\"The subject must complete the following lab panel.\"\n resourceType=\"ActivityDefinition\"\n action={action}\n onChange={props.onChange}\n />\n );\n case 'questionnaire':\n return (\n <ActionResourceTypeBuilder\n title=\"Questionnaire\"\n description=\"The subject must complete the selected questionnaire.\"\n resourceType=\"Questionnaire\"\n action={action}\n onChange={props.onChange}\n />\n );\n case 'task':\n return (\n <ActionResourceTypeBuilder\n title=\"Task\"\n description=\"The subject must complete the following task.\"\n resourceType=\"ActivityDefinition\"\n action={action}\n onChange={props.onChange}\n />\n );\n default:\n return null;\n }\n })()}\n <FormSection title=\"Timing\" description=\"When the action should take place.\">\n <ActionTimingInput name={'timing-' + action.id} action={action} onChange={props.onChange} />\n </FormSection>\n </Stack>\n );\n}\n\ninterface ActionResourceTypeBuilderProps {\n action: PlanDefinitionAction;\n title: string;\n description: string;\n resourceType: ResourceType;\n onChange: (action: PlanDefinitionAction) => void;\n}\n\nfunction ActionResourceTypeBuilder(props: ActionResourceTypeBuilderProps): JSX.Element {\n const { id, definitionCanonical } = props.action;\n const reference = definitionCanonical?.startsWith(props.resourceType + '/')\n ? { reference: definitionCanonical }\n : undefined;\n return (\n <ResourceInput\n name={id as string}\n resourceType={props.resourceType}\n defaultValue={reference}\n loadOnFocus={true}\n onChange={(newValue) => {\n if (newValue) {\n props.onChange({ ...props.action, definitionCanonical: getReferenceString(newValue) });\n } else {\n props.onChange({ ...props.action, definitionCanonical: undefined });\n }\n }}\n />\n );\n}\n\ninterface ActionTimingInputProps {\n name: string;\n action: PlanDefinitionAction;\n onChange: (action: PlanDefinitionAction) => void;\n}\n\nfunction ActionTimingInput(props: ActionTimingInputProps): JSX.Element {\n const value = props.action;\n const key = 'timing';\n const [propertyValue, propertyType] = getActionTiming(value);\n return (\n <ResourcePropertyInput\n property={timingProperty}\n name=\"timing[x]\"\n defaultValue={propertyValue}\n defaultPropertyType={propertyType}\n onChange={(newValue: any, propName?: string) => {\n props.onChange(setPropertyValue(value, key, propName ?? key, timingProperty, newValue));\n }}\n />\n );\n}\n\nfunction getInitialActionType(action: PlanDefinitionAction): string | undefined {\n if (action.definitionCanonical?.startsWith('Schedule')) {\n return 'appointment';\n }\n\n if (action.definitionCanonical?.startsWith('Questionnaire/')) {\n return 'questionnaire';\n }\n\n if (action.definitionCanonical?.startsWith('ActivityDefinition/')) {\n return 'task';\n }\n\n return undefined;\n}\n\nfunction getActionTiming(action: PlanDefinitionAction): [any, PropertyType] {\n return getValueAndType({ type: 'PlanDefinitionAction', value: action }, 'timing');\n}\n\nlet nextId = 1;\n\n/**\n * Generates a unique ID.\n * React needs unique IDs for components for rendering performance.\n * All of the important components in the questionnaire builder have id properties for this:\n * Questionnaire, QuestionnaireItem, and QuestionnaireItemAnswerOption.\n * @param existing Optional existing id which will update nextId.\n * @returns A unique key.\n */\nfunction generateId(existing?: string): string {\n if (existing) {\n if (existing.startsWith('id-')) {\n const existingNum = parseInt(existing.substring(3));\n if (!isNaN(existingNum)) {\n nextId = Math.max(nextId, existingNum + 1);\n }\n }\n return existing;\n }\n return 'id-' + nextId++;\n}\n\nfunction ensurePlanDefinitionKeys(planDefinition: PlanDefinition): PlanDefinition {\n return {\n ...planDefinition,\n action: ensurePlanDefinitionActionKeys(planDefinition.action),\n } as PlanDefinition;\n}\n\nfunction ensurePlanDefinitionActionKeys(\n actions: PlanDefinitionAction[] | undefined\n): PlanDefinitionAction[] | undefined {\n if (!actions) {\n return undefined;\n }\n return actions.map((action) => ({\n ...action,\n id: generateId(action.id),\n action: ensurePlanDefinitionActionKeys(action.action),\n }));\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -233,7 +233,8 @@ let nextId = 1;
|
|
|
233
233
|
/**
|
|
234
234
|
* Generates a link ID for an item.
|
|
235
235
|
* Link IDs are required properties on QuestionnaireItem objects.
|
|
236
|
-
* @
|
|
236
|
+
* @param prefix The link ID prefix string.
|
|
237
|
+
* @returns A unique link ID.
|
|
237
238
|
*/
|
|
238
239
|
function generateLinkId(prefix) {
|
|
239
240
|
return prefix + nextLinkId++;
|
|
@@ -243,7 +244,7 @@ function generateLinkId(prefix) {
|
|
|
243
244
|
* React needs unique IDs for components for rendering performance.
|
|
244
245
|
* All of the important components in the questionnaire builder have id properties for this:
|
|
245
246
|
* Questionnaire, QuestionnaireItem, and QuestionnaireItemAnswerOption.
|
|
246
|
-
* @
|
|
247
|
+
* @returns A unique key.
|
|
247
248
|
*/
|
|
248
249
|
function generateId() {
|
|
249
250
|
return 'id-' + nextId++;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuestionnaireBuilder.mjs","sources":["../../../src/QuestionnaireBuilder/QuestionnaireBuilder.tsx"],"sourcesContent":["import { Anchor, Button, createStyles, NativeSelect, Textarea, TextInput, Title } from '@mantine/core';\nimport { globalSchema, IndexedStructureDefinition, isResource as isResourceType } from '@medplum/core';\nimport { Questionnaire, QuestionnaireItem, QuestionnaireItemAnswerOption, Reference } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Form } from '../Form/Form';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { QuestionnaireFormItem } from '../QuestionnaireForm/QuestionnaireForm';\nimport { getValueAndType } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\nimport { ResourcePropertyInput } from '../ResourcePropertyInput/ResourcePropertyInput';\nimport { useResource } from '../useResource/useResource';\nimport { killEvent } from '../utils/dom';\nimport { isChoiceQuestion, QuestionnaireItemType } from '../utils/questionnaire';\n\nconst useStyles = createStyles((theme) => ({\n section: {\n position: 'relative',\n margin: '4px 4px 8px 0',\n padding: '6px 12px 16px 6px',\n border: `1.5px solid ${theme.colors.gray[1]}`,\n borderRadius: theme.radius.sm,\n transition: 'all 0.1s',\n },\n\n hovering: {\n border: `1.5px solid ${theme.colors.blue[5]}`,\n },\n\n editing: {\n border: `1.5px solid ${theme.colors.gray[1]}`,\n borderLeft: `4px solid ${theme.colors.blue[5]}`,\n },\n\n questionBody: {\n maxWidth: 600,\n },\n\n topActions: {\n position: 'absolute',\n right: 4,\n top: 1,\n padding: 4,\n color: theme.colors.gray[5],\n fontSize: theme.fontSizes.xs,\n },\n\n bottomActions: {\n position: 'absolute',\n right: 4,\n bottom: 0,\n fontSize: theme.fontSizes.xs,\n\n '& a': {\n marginLeft: 8,\n },\n },\n\n linkIdInput: {\n width: 100,\n marginBottom: 4,\n },\n\n typeSelect: {\n width: 100,\n },\n}));\n\nexport interface QuestionnaireBuilderProps {\n questionnaire: Questionnaire | Reference<Questionnaire>;\n onSubmit: (result: Questionnaire) => void;\n}\n\nexport function QuestionnaireBuilder(props: QuestionnaireBuilderProps): JSX.Element | null {\n const medplum = useMedplum();\n const defaultValue = useResource(props.questionnaire);\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n const [value, setValue] = useState<Questionnaire>();\n const [selectedKey, setSelectedKey] = useState<string>();\n const [hoverKey, setHoverKey] = useState<string>();\n\n function handleDocumentMouseOver(): void {\n setHoverKey(undefined);\n }\n\n function handleDocumentClick(): void {\n setSelectedKey(undefined);\n }\n\n useEffect(() => {\n medplum.requestSchema('Questionnaire').then(setSchema).catch(console.log);\n }, [medplum]);\n\n useEffect(() => {\n setValue(ensureQuestionnaireKeys(defaultValue ?? { resourceType: 'Questionnaire' }));\n document.addEventListener('mouseover', handleDocumentMouseOver);\n document.addEventListener('click', handleDocumentClick);\n return () => {\n document.removeEventListener('mouseover', handleDocumentMouseOver);\n document.removeEventListener('click', handleDocumentClick);\n };\n }, [defaultValue]);\n\n if (!schema || !value) {\n return null;\n }\n\n return (\n <div>\n <Form testid=\"questionnaire-form\" onSubmit={() => props.onSubmit(value)}>\n <ItemBuilder\n item={value}\n selectedKey={selectedKey}\n setSelectedKey={setSelectedKey}\n hoverKey={hoverKey}\n setHoverKey={setHoverKey}\n onChange={setValue}\n />\n <Button type=\"submit\">Save</Button>\n </Form>\n </div>\n );\n}\n\ninterface ItemBuilderProps<T extends Questionnaire | QuestionnaireItem> {\n item: T;\n selectedKey: string | undefined;\n setSelectedKey: (key: string | undefined) => void;\n hoverKey: string | undefined;\n setHoverKey: (key: string | undefined) => void;\n onChange: (item: T) => void;\n onRemove?: () => void;\n}\n\nfunction ItemBuilder<T extends Questionnaire | QuestionnaireItem>(props: ItemBuilderProps<T>): JSX.Element {\n const { classes, cx } = useStyles();\n const resource = props.item as Questionnaire;\n const item = props.item as QuestionnaireItem;\n const isResource = isResourceType(props.item);\n const isContainer = isResource || item.type === QuestionnaireItemType.group;\n const linkId = item.linkId ?? '[untitled]';\n const editing = props.selectedKey === props.item.id;\n const hovering = props.hoverKey === props.item.id;\n\n const itemRef = useRef<T>();\n itemRef.current = props.item;\n\n function onClick(e: React.SyntheticEvent): void {\n killEvent(e);\n props.setSelectedKey(props.item.id);\n }\n\n function onHover(e: React.SyntheticEvent): void {\n killEvent(e);\n props.setHoverKey(props.item.id);\n }\n\n function changeItem(changedItem: QuestionnaireItem): void {\n const curr = itemRef.current as T;\n props.onChange({\n ...curr,\n item: curr.item?.map((i) => (i.id === changedItem.id ? changedItem : i)),\n } as T);\n }\n\n function addItem(addedItem: QuestionnaireItem): void {\n props.onChange({\n ...props.item,\n item: [...(props.item?.item ?? []), addedItem],\n });\n }\n\n function removeItem(removedItem: QuestionnaireItem): void {\n props.onChange({\n ...props.item,\n item: props.item?.item?.filter((i) => i !== removedItem),\n });\n }\n\n function changeProperty(property: string, value: any): void {\n props.onChange({\n ...itemRef.current,\n [property]: value,\n } as T);\n }\n\n const className = cx(classes.section, {\n [classes.editing]: editing,\n [classes.hovering]: hovering && !editing,\n });\n\n return (\n <div data-testid={item.linkId} className={className} onClick={onClick} onMouseOver={onHover}>\n <div className={classes.questionBody}>\n {editing ? (\n <>\n {isResource && (\n <TextInput\n size=\"xl\"\n defaultValue={resource.title}\n onChange={(e) => changeProperty('title', e.currentTarget.value)}\n />\n )}\n {!isResource && (\n <Textarea\n autosize\n minRows={2}\n defaultValue={item.text}\n onChange={(e) => changeProperty('text', e.currentTarget.value)}\n />\n )}\n {isChoiceQuestion(item) && (\n <AnswerBuilder\n options={item.answerOption}\n onChange={(newOptions) => changeProperty('answerOption', newOptions)}\n />\n )}\n </>\n ) : (\n <>\n {resource.title && <Title>{resource.title}</Title>}\n {item.text && <div>{item.text}</div>}\n {!isContainer && <QuestionnaireFormItem item={item} answers={{}} onChange={() => undefined} />}\n </>\n )}\n </div>\n {item.item &&\n item.item.map((i) => (\n <div key={i.id}>\n <ItemBuilder\n item={i}\n selectedKey={props.selectedKey}\n setSelectedKey={props.setSelectedKey}\n hoverKey={props.hoverKey}\n setHoverKey={props.setHoverKey}\n onChange={changeItem}\n onRemove={() => removeItem(i)}\n />\n </div>\n ))}\n {!isContainer && (\n <div className={classes.topActions}>\n {editing ? (\n <>\n <TextInput\n size=\"xs\"\n className={classes.linkIdInput}\n defaultValue={item.linkId}\n onChange={(e) => changeProperty('linkId', e.currentTarget.value)}\n />\n {!isContainer && (\n <NativeSelect\n size=\"xs\"\n className={classes.typeSelect}\n defaultValue={item.type}\n onChange={(e) => changeProperty('type', e.currentTarget.value)}\n data={[\n { value: 'display', label: 'Display' },\n { value: 'boolean', label: 'Boolean' },\n { value: 'decimal', label: 'Decimal' },\n { value: 'integer', label: 'Integer' },\n { value: 'date', label: 'Date' },\n { value: 'dateTime', label: 'Date/Time' },\n { value: 'time', label: 'Time' },\n { value: 'string', label: 'String' },\n { value: 'text', label: 'Text' },\n { value: 'url', label: 'URL' },\n { value: 'choice', label: 'Choice' },\n { value: 'open-choice', label: 'Open Choice' },\n { value: 'attachment', label: 'Attachment' },\n { value: 'reference', label: 'Reference' },\n { value: 'quantity', label: 'Quantity' },\n ]}\n />\n )}\n </>\n ) : (\n <div>{linkId}</div>\n )}\n </div>\n )}\n <div className={classes.bottomActions}>\n {isContainer && (\n <>\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n addItem({\n id: generateId(),\n linkId: generateLinkId('q'),\n type: 'string',\n text: 'Question',\n } as QuestionnaireItem);\n }}\n >\n Add item\n </Anchor>\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n addItem({\n id: generateId(),\n linkId: generateLinkId('g'),\n type: 'group',\n text: 'Group',\n } as QuestionnaireItem);\n }}\n >\n Add group\n </Anchor>\n </>\n )}\n {editing && !isResource && (\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n if (props.onRemove) {\n props.onRemove();\n }\n }}\n >\n Remove\n </Anchor>\n )}\n </div>\n </div>\n );\n}\n\ninterface AnswerBuilderProps {\n options?: QuestionnaireItemAnswerOption[];\n onChange: (newOptions: QuestionnaireItemAnswerOption[]) => void;\n}\n\nfunction AnswerBuilder(props: AnswerBuilderProps): JSX.Element {\n const property = globalSchema.types['QuestionnaireItemAnswerOption'].properties['value[x]'];\n const options = props.options ?? [];\n return (\n <div>\n {options.map((option: QuestionnaireItemAnswerOption) => {\n const [propertyValue, propertyType] = getValueAndType(\n { type: 'QuestionnaireItemAnswerOption', value: option },\n 'value'\n );\n return (\n <div\n key={option.id}\n style={{\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '80%',\n }}\n >\n <div>\n <ResourcePropertyInput\n key={option.id}\n name=\"value[x]\"\n property={property}\n defaultPropertyType={propertyType}\n defaultValue={propertyValue}\n onChange={(newValue: any, propName?: string) => {\n const newOptions = [...options];\n const index = newOptions.findIndex((o) => o.id === option.id);\n newOptions[index] = { id: option.id, [propName as string]: newValue };\n props.onChange(newOptions);\n }}\n />\n </div>\n <div>\n <Anchor\n href=\"#\"\n onClick={(e: React.SyntheticEvent) => {\n killEvent(e);\n props.onChange(options.filter((o) => o.id !== option.id));\n }}\n >\n Remove\n </Anchor>\n </div>\n </div>\n );\n })}\n <Anchor\n href=\"#\"\n onClick={(e: React.SyntheticEvent) => {\n killEvent(e);\n props.onChange([\n ...options,\n {\n id: generateId(),\n },\n ]);\n }}\n >\n Add choice\n </Anchor>\n </div>\n );\n}\n\nlet nextLinkId = 1;\nlet nextId = 1;\n\n/**\n * Generates a link ID for an item.\n * Link IDs are required properties on QuestionnaireItem objects.\n * @return A unique link ID.\n */\nfunction generateLinkId(prefix: string): string {\n return prefix + nextLinkId++;\n}\n\n/**\n * Generates a unique ID.\n * React needs unique IDs for components for rendering performance.\n * All of the important components in the questionnaire builder have id properties for this:\n * Questionnaire, QuestionnaireItem, and QuestionnaireItemAnswerOption.\n * @return A unique key.\n */\nfunction generateId(): string {\n return 'id-' + nextId++;\n}\n\nfunction ensureQuestionnaireKeys(questionnaire: Questionnaire): Questionnaire {\n return {\n ...questionnaire,\n id: questionnaire.id || generateId(),\n item: ensureQuestionnaireItemKeys(questionnaire.item),\n } as Questionnaire;\n}\n\nfunction ensureQuestionnaireItemKeys(items: QuestionnaireItem[] | undefined): QuestionnaireItem[] | undefined {\n if (!items) {\n return undefined;\n }\n items.forEach((item) => {\n if (item.id?.match(/^id-\\d+$/)) {\n nextId = Math.max(nextId, parseInt(item.id.substring(3)) + 1);\n }\n if (item.linkId?.match(/^q\\d+$/)) {\n nextLinkId = Math.max(nextLinkId, parseInt(item.linkId.substring(1)) + 1);\n }\n });\n return items.map((item) => ({\n ...item,\n id: item.id || generateId(),\n item: ensureQuestionnaireItemKeys(item.item),\n answerOption: ensureQuestionnaireOptionKeys(item.answerOption),\n }));\n}\n\nfunction ensureQuestionnaireOptionKeys(\n options: QuestionnaireItemAnswerOption[] | undefined\n): QuestionnaireItemAnswerOption[] | undefined {\n if (!options) {\n return undefined;\n }\n return options.map((option) => ({\n ...option,\n id: option.id || generateId(),\n }));\n}\n"],"names":["isResource","isResourceType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"QuestionnaireBuilder.mjs","sources":["../../../src/QuestionnaireBuilder/QuestionnaireBuilder.tsx"],"sourcesContent":["import { Anchor, Button, createStyles, NativeSelect, Textarea, TextInput, Title } from '@mantine/core';\nimport { globalSchema, IndexedStructureDefinition, isResource as isResourceType } from '@medplum/core';\nimport { Questionnaire, QuestionnaireItem, QuestionnaireItemAnswerOption, Reference } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Form } from '../Form/Form';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { QuestionnaireFormItem } from '../QuestionnaireForm/QuestionnaireForm';\nimport { getValueAndType } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\nimport { ResourcePropertyInput } from '../ResourcePropertyInput/ResourcePropertyInput';\nimport { useResource } from '../useResource/useResource';\nimport { killEvent } from '../utils/dom';\nimport { isChoiceQuestion, QuestionnaireItemType } from '../utils/questionnaire';\n\nconst useStyles = createStyles((theme) => ({\n section: {\n position: 'relative',\n margin: '4px 4px 8px 0',\n padding: '6px 12px 16px 6px',\n border: `1.5px solid ${theme.colors.gray[1]}`,\n borderRadius: theme.radius.sm,\n transition: 'all 0.1s',\n },\n\n hovering: {\n border: `1.5px solid ${theme.colors.blue[5]}`,\n },\n\n editing: {\n border: `1.5px solid ${theme.colors.gray[1]}`,\n borderLeft: `4px solid ${theme.colors.blue[5]}`,\n },\n\n questionBody: {\n maxWidth: 600,\n },\n\n topActions: {\n position: 'absolute',\n right: 4,\n top: 1,\n padding: 4,\n color: theme.colors.gray[5],\n fontSize: theme.fontSizes.xs,\n },\n\n bottomActions: {\n position: 'absolute',\n right: 4,\n bottom: 0,\n fontSize: theme.fontSizes.xs,\n\n '& a': {\n marginLeft: 8,\n },\n },\n\n linkIdInput: {\n width: 100,\n marginBottom: 4,\n },\n\n typeSelect: {\n width: 100,\n },\n}));\n\nexport interface QuestionnaireBuilderProps {\n questionnaire: Questionnaire | Reference<Questionnaire>;\n onSubmit: (result: Questionnaire) => void;\n}\n\nexport function QuestionnaireBuilder(props: QuestionnaireBuilderProps): JSX.Element | null {\n const medplum = useMedplum();\n const defaultValue = useResource(props.questionnaire);\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n const [value, setValue] = useState<Questionnaire>();\n const [selectedKey, setSelectedKey] = useState<string>();\n const [hoverKey, setHoverKey] = useState<string>();\n\n function handleDocumentMouseOver(): void {\n setHoverKey(undefined);\n }\n\n function handleDocumentClick(): void {\n setSelectedKey(undefined);\n }\n\n useEffect(() => {\n medplum.requestSchema('Questionnaire').then(setSchema).catch(console.log);\n }, [medplum]);\n\n useEffect(() => {\n setValue(ensureQuestionnaireKeys(defaultValue ?? { resourceType: 'Questionnaire' }));\n document.addEventListener('mouseover', handleDocumentMouseOver);\n document.addEventListener('click', handleDocumentClick);\n return () => {\n document.removeEventListener('mouseover', handleDocumentMouseOver);\n document.removeEventListener('click', handleDocumentClick);\n };\n }, [defaultValue]);\n\n if (!schema || !value) {\n return null;\n }\n\n return (\n <div>\n <Form testid=\"questionnaire-form\" onSubmit={() => props.onSubmit(value)}>\n <ItemBuilder\n item={value}\n selectedKey={selectedKey}\n setSelectedKey={setSelectedKey}\n hoverKey={hoverKey}\n setHoverKey={setHoverKey}\n onChange={setValue}\n />\n <Button type=\"submit\">Save</Button>\n </Form>\n </div>\n );\n}\n\ninterface ItemBuilderProps<T extends Questionnaire | QuestionnaireItem> {\n item: T;\n selectedKey: string | undefined;\n setSelectedKey: (key: string | undefined) => void;\n hoverKey: string | undefined;\n setHoverKey: (key: string | undefined) => void;\n onChange: (item: T) => void;\n onRemove?: () => void;\n}\n\nfunction ItemBuilder<T extends Questionnaire | QuestionnaireItem>(props: ItemBuilderProps<T>): JSX.Element {\n const { classes, cx } = useStyles();\n const resource = props.item as Questionnaire;\n const item = props.item as QuestionnaireItem;\n const isResource = isResourceType(props.item);\n const isContainer = isResource || item.type === QuestionnaireItemType.group;\n const linkId = item.linkId ?? '[untitled]';\n const editing = props.selectedKey === props.item.id;\n const hovering = props.hoverKey === props.item.id;\n\n const itemRef = useRef<T>();\n itemRef.current = props.item;\n\n function onClick(e: React.SyntheticEvent): void {\n killEvent(e);\n props.setSelectedKey(props.item.id);\n }\n\n function onHover(e: React.SyntheticEvent): void {\n killEvent(e);\n props.setHoverKey(props.item.id);\n }\n\n function changeItem(changedItem: QuestionnaireItem): void {\n const curr = itemRef.current as T;\n props.onChange({\n ...curr,\n item: curr.item?.map((i) => (i.id === changedItem.id ? changedItem : i)),\n } as T);\n }\n\n function addItem(addedItem: QuestionnaireItem): void {\n props.onChange({\n ...props.item,\n item: [...(props.item?.item ?? []), addedItem],\n });\n }\n\n function removeItem(removedItem: QuestionnaireItem): void {\n props.onChange({\n ...props.item,\n item: props.item?.item?.filter((i) => i !== removedItem),\n });\n }\n\n function changeProperty(property: string, value: any): void {\n props.onChange({\n ...itemRef.current,\n [property]: value,\n } as T);\n }\n\n const className = cx(classes.section, {\n [classes.editing]: editing,\n [classes.hovering]: hovering && !editing,\n });\n\n return (\n <div data-testid={item.linkId} className={className} onClick={onClick} onMouseOver={onHover}>\n <div className={classes.questionBody}>\n {editing ? (\n <>\n {isResource && (\n <TextInput\n size=\"xl\"\n defaultValue={resource.title}\n onChange={(e) => changeProperty('title', e.currentTarget.value)}\n />\n )}\n {!isResource && (\n <Textarea\n autosize\n minRows={2}\n defaultValue={item.text}\n onChange={(e) => changeProperty('text', e.currentTarget.value)}\n />\n )}\n {isChoiceQuestion(item) && (\n <AnswerBuilder\n options={item.answerOption}\n onChange={(newOptions) => changeProperty('answerOption', newOptions)}\n />\n )}\n </>\n ) : (\n <>\n {resource.title && <Title>{resource.title}</Title>}\n {item.text && <div>{item.text}</div>}\n {!isContainer && <QuestionnaireFormItem item={item} answers={{}} onChange={() => undefined} />}\n </>\n )}\n </div>\n {item.item &&\n item.item.map((i) => (\n <div key={i.id}>\n <ItemBuilder\n item={i}\n selectedKey={props.selectedKey}\n setSelectedKey={props.setSelectedKey}\n hoverKey={props.hoverKey}\n setHoverKey={props.setHoverKey}\n onChange={changeItem}\n onRemove={() => removeItem(i)}\n />\n </div>\n ))}\n {!isContainer && (\n <div className={classes.topActions}>\n {editing ? (\n <>\n <TextInput\n size=\"xs\"\n className={classes.linkIdInput}\n defaultValue={item.linkId}\n onChange={(e) => changeProperty('linkId', e.currentTarget.value)}\n />\n {!isContainer && (\n <NativeSelect\n size=\"xs\"\n className={classes.typeSelect}\n defaultValue={item.type}\n onChange={(e) => changeProperty('type', e.currentTarget.value)}\n data={[\n { value: 'display', label: 'Display' },\n { value: 'boolean', label: 'Boolean' },\n { value: 'decimal', label: 'Decimal' },\n { value: 'integer', label: 'Integer' },\n { value: 'date', label: 'Date' },\n { value: 'dateTime', label: 'Date/Time' },\n { value: 'time', label: 'Time' },\n { value: 'string', label: 'String' },\n { value: 'text', label: 'Text' },\n { value: 'url', label: 'URL' },\n { value: 'choice', label: 'Choice' },\n { value: 'open-choice', label: 'Open Choice' },\n { value: 'attachment', label: 'Attachment' },\n { value: 'reference', label: 'Reference' },\n { value: 'quantity', label: 'Quantity' },\n ]}\n />\n )}\n </>\n ) : (\n <div>{linkId}</div>\n )}\n </div>\n )}\n <div className={classes.bottomActions}>\n {isContainer && (\n <>\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n addItem({\n id: generateId(),\n linkId: generateLinkId('q'),\n type: 'string',\n text: 'Question',\n } as QuestionnaireItem);\n }}\n >\n Add item\n </Anchor>\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n addItem({\n id: generateId(),\n linkId: generateLinkId('g'),\n type: 'group',\n text: 'Group',\n } as QuestionnaireItem);\n }}\n >\n Add group\n </Anchor>\n </>\n )}\n {editing && !isResource && (\n <Anchor\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n if (props.onRemove) {\n props.onRemove();\n }\n }}\n >\n Remove\n </Anchor>\n )}\n </div>\n </div>\n );\n}\n\ninterface AnswerBuilderProps {\n options?: QuestionnaireItemAnswerOption[];\n onChange: (newOptions: QuestionnaireItemAnswerOption[]) => void;\n}\n\nfunction AnswerBuilder(props: AnswerBuilderProps): JSX.Element {\n const property = globalSchema.types['QuestionnaireItemAnswerOption'].properties['value[x]'];\n const options = props.options ?? [];\n return (\n <div>\n {options.map((option: QuestionnaireItemAnswerOption) => {\n const [propertyValue, propertyType] = getValueAndType(\n { type: 'QuestionnaireItemAnswerOption', value: option },\n 'value'\n );\n return (\n <div\n key={option.id}\n style={{\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '80%',\n }}\n >\n <div>\n <ResourcePropertyInput\n key={option.id}\n name=\"value[x]\"\n property={property}\n defaultPropertyType={propertyType}\n defaultValue={propertyValue}\n onChange={(newValue: any, propName?: string) => {\n const newOptions = [...options];\n const index = newOptions.findIndex((o) => o.id === option.id);\n newOptions[index] = { id: option.id, [propName as string]: newValue };\n props.onChange(newOptions);\n }}\n />\n </div>\n <div>\n <Anchor\n href=\"#\"\n onClick={(e: React.SyntheticEvent) => {\n killEvent(e);\n props.onChange(options.filter((o) => o.id !== option.id));\n }}\n >\n Remove\n </Anchor>\n </div>\n </div>\n );\n })}\n <Anchor\n href=\"#\"\n onClick={(e: React.SyntheticEvent) => {\n killEvent(e);\n props.onChange([\n ...options,\n {\n id: generateId(),\n },\n ]);\n }}\n >\n Add choice\n </Anchor>\n </div>\n );\n}\n\nlet nextLinkId = 1;\nlet nextId = 1;\n\n/**\n * Generates a link ID for an item.\n * Link IDs are required properties on QuestionnaireItem objects.\n * @param prefix The link ID prefix string.\n * @returns A unique link ID.\n */\nfunction generateLinkId(prefix: string): string {\n return prefix + nextLinkId++;\n}\n\n/**\n * Generates a unique ID.\n * React needs unique IDs for components for rendering performance.\n * All of the important components in the questionnaire builder have id properties for this:\n * Questionnaire, QuestionnaireItem, and QuestionnaireItemAnswerOption.\n * @returns A unique key.\n */\nfunction generateId(): string {\n return 'id-' + nextId++;\n}\n\nfunction ensureQuestionnaireKeys(questionnaire: Questionnaire): Questionnaire {\n return {\n ...questionnaire,\n id: questionnaire.id || generateId(),\n item: ensureQuestionnaireItemKeys(questionnaire.item),\n } as Questionnaire;\n}\n\nfunction ensureQuestionnaireItemKeys(items: QuestionnaireItem[] | undefined): QuestionnaireItem[] | undefined {\n if (!items) {\n return undefined;\n }\n items.forEach((item) => {\n if (item.id?.match(/^id-\\d+$/)) {\n nextId = Math.max(nextId, parseInt(item.id.substring(3)) + 1);\n }\n if (item.linkId?.match(/^q\\d+$/)) {\n nextLinkId = Math.max(nextLinkId, parseInt(item.linkId.substring(1)) + 1);\n }\n });\n return items.map((item) => ({\n ...item,\n id: item.id || generateId(),\n item: ensureQuestionnaireItemKeys(item.item),\n answerOption: ensureQuestionnaireOptionKeys(item.answerOption),\n }));\n}\n\nfunction ensureQuestionnaireOptionKeys(\n options: QuestionnaireItemAnswerOption[] | undefined\n): QuestionnaireItemAnswerOption[] | undefined {\n if (!options) {\n return undefined;\n }\n return options.map((option) => ({\n ...option,\n id: option.id || generateId(),\n }));\n}\n"],"names":["isResource","isResourceType"],"mappings":"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"}
|