@medplum/react 0.9.25 → 0.9.28
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.js +282 -152
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +1 -1
- package/dist/cjs/index.min.js.map +1 -1
- package/dist/cjs/styles.css +83 -79
- package/dist/{types → esm}/AddressDisplay.d.ts +0 -0
- package/dist/esm/AddressDisplay.js +13 -0
- package/dist/esm/AddressDisplay.js.map +1 -0
- package/dist/{types → esm}/AddressInput.d.ts +0 -0
- package/dist/esm/AddressInput.js +69 -0
- package/dist/esm/AddressInput.js.map +1 -0
- package/dist/{types → esm}/AnnotationInput.d.ts +0 -0
- package/dist/esm/AnnotationInput.js +28 -0
- package/dist/esm/AnnotationInput.js.map +1 -0
- package/dist/{types → esm}/AttachmentArrayDisplay.d.ts +0 -0
- package/dist/esm/AttachmentArrayDisplay.js +11 -0
- package/dist/esm/AttachmentArrayDisplay.js.map +1 -0
- package/dist/{types → esm}/AttachmentArrayInput.d.ts +0 -0
- package/dist/esm/AttachmentArrayInput.js +42 -0
- package/dist/esm/AttachmentArrayInput.js.map +1 -0
- package/dist/{types → esm}/AttachmentDisplay.d.ts +0 -0
- package/dist/esm/AttachmentDisplay.js +20 -0
- package/dist/esm/AttachmentDisplay.js.map +1 -0
- package/dist/{types → esm}/AttachmentInput.d.ts +0 -0
- package/dist/esm/AttachmentInput.js +27 -0
- package/dist/esm/AttachmentInput.js.map +1 -0
- package/dist/{types → esm}/Autocomplete.d.ts +1 -0
- package/dist/esm/Autocomplete.js +280 -0
- package/dist/esm/Autocomplete.js.map +1 -0
- package/dist/{types → esm}/Avatar.d.ts +0 -0
- package/dist/esm/Avatar.js +24 -0
- package/dist/esm/Avatar.js.map +1 -0
- package/dist/{types → esm}/BackboneElementDisplay.d.ts +0 -0
- package/dist/esm/BackboneElementDisplay.js +43 -0
- package/dist/esm/BackboneElementDisplay.js.map +1 -0
- package/dist/{types → esm}/BackboneElementInput.d.ts +0 -0
- package/dist/esm/BackboneElementInput.js +51 -0
- package/dist/esm/BackboneElementInput.js.map +1 -0
- package/dist/{types → esm}/Button.d.ts +0 -0
- package/dist/esm/Button.js +13 -0
- package/dist/esm/Button.js.map +1 -0
- package/dist/{types → esm}/CalendarInput.d.ts +0 -0
- package/dist/esm/CalendarInput.js +96 -0
- package/dist/esm/CalendarInput.js.map +1 -0
- package/dist/{types → esm}/Checkbox.d.ts +0 -0
- package/dist/esm/Checkbox.js +13 -0
- package/dist/esm/Checkbox.js.map +1 -0
- package/dist/{types → esm}/CheckboxFormSection.d.ts +0 -0
- package/dist/esm/CheckboxFormSection.js +12 -0
- package/dist/esm/CheckboxFormSection.js.map +1 -0
- package/dist/{types → esm}/CodeInput.d.ts +0 -0
- package/dist/esm/CodeInput.js +28 -0
- package/dist/esm/CodeInput.js.map +1 -0
- package/dist/{types → esm}/CodeableConceptDisplay.d.ts +0 -0
- package/dist/esm/CodeableConceptDisplay.js +21 -0
- package/dist/esm/CodeableConceptDisplay.js.map +1 -0
- package/dist/{types → esm}/CodeableConceptInput.d.ts +0 -0
- package/dist/esm/CodeableConceptInput.js +52 -0
- package/dist/esm/CodeableConceptInput.js.map +1 -0
- package/dist/{types → esm}/CodingDisplay.d.ts +0 -0
- package/dist/esm/CodingDisplay.js +9 -0
- package/dist/esm/CodingDisplay.js.map +1 -0
- package/dist/{types → esm}/CodingInput.d.ts +0 -0
- package/dist/esm/CodingInput.js +30 -0
- package/dist/esm/CodingInput.js.map +1 -0
- package/dist/{types → esm}/ContactDetailDisplay.d.ts +0 -0
- package/dist/esm/ContactDetailDisplay.js +17 -0
- package/dist/esm/ContactDetailDisplay.js.map +1 -0
- package/dist/{types → esm}/ContactDetailInput.d.ts +0 -0
- package/dist/esm/ContactDetailInput.js +37 -0
- package/dist/esm/ContactDetailInput.js.map +1 -0
- package/dist/{types → esm}/ContactPointDisplay.d.ts +0 -0
- package/dist/esm/ContactPointDisplay.js +29 -0
- package/dist/esm/ContactPointDisplay.js.map +1 -0
- package/dist/{types → esm}/ContactPointInput.d.ts +0 -0
- package/dist/esm/ContactPointInput.js +60 -0
- package/dist/esm/ContactPointInput.js.map +1 -0
- package/dist/{types → esm}/DateTimeInput.d.ts +0 -0
- package/dist/esm/DateTimeInput.js +60 -0
- package/dist/esm/DateTimeInput.js.map +1 -0
- package/dist/{types → esm}/DefaultResourceTimeline.d.ts +0 -0
- package/dist/esm/DefaultResourceTimeline.js +27 -0
- package/dist/esm/DefaultResourceTimeline.js.map +1 -0
- package/dist/{types → esm}/DescriptionList.d.ts +0 -0
- package/dist/esm/DescriptionList.js +13 -0
- package/dist/esm/DescriptionList.js.map +1 -0
- package/dist/{types → esm}/DiagnosticReportDisplay.d.ts +0 -0
- package/dist/esm/DiagnosticReportDisplay.js +101 -0
- package/dist/esm/DiagnosticReportDisplay.js.map +1 -0
- package/dist/{types → esm}/Dialog.d.ts +0 -0
- package/dist/esm/Dialog.js +43 -0
- package/dist/esm/Dialog.js.map +1 -0
- package/dist/{types → esm}/Document.d.ts +0 -0
- package/dist/esm/Document.js +9 -0
- package/dist/esm/Document.js.map +1 -0
- package/dist/{types → esm}/EncounterTimeline.d.ts +0 -0
- package/dist/esm/EncounterTimeline.js +47 -0
- package/dist/esm/EncounterTimeline.js.map +1 -0
- package/dist/{types → esm}/ErrorBoundary.d.ts +0 -0
- package/dist/esm/ErrorBoundary.js +27 -0
- package/dist/esm/ErrorBoundary.js.map +1 -0
- package/dist/{types → esm}/ExtensionInput.d.ts +0 -0
- package/dist/esm/ExtensionInput.js +14 -0
- package/dist/esm/ExtensionInput.js.map +1 -0
- package/dist/{types → esm}/FhirPathDisplay.d.ts +0 -0
- package/dist/esm/FhirPathDisplay.js +23 -0
- package/dist/esm/FhirPathDisplay.js.map +1 -0
- package/dist/{types → esm}/FhirPathTable.d.ts +0 -0
- package/dist/esm/FhirPathTable.js +117 -0
- package/dist/esm/FhirPathTable.js.map +1 -0
- package/dist/{types → esm}/FooterLinks.d.ts +0 -0
- package/dist/esm/FooterLinks.js +8 -0
- package/dist/esm/FooterLinks.js.map +1 -0
- package/dist/{types → esm}/Form.d.ts +0 -0
- package/dist/esm/Form.js +15 -0
- package/dist/esm/Form.js.map +1 -0
- package/dist/{types → esm}/FormSection.d.ts +0 -0
- package/dist/esm/FormSection.js +18 -0
- package/dist/esm/FormSection.js.map +1 -0
- package/dist/{types → esm}/FormUtils.d.ts +0 -0
- package/dist/esm/FormUtils.js +49 -0
- package/dist/esm/FormUtils.js.map +1 -0
- package/dist/{types → esm}/GoogleButton.d.ts +0 -0
- package/dist/esm/GoogleButton.js +48 -0
- package/dist/esm/GoogleButton.js.map +1 -0
- package/dist/{types → esm}/Header.d.ts +0 -0
- package/dist/esm/Header.js +95 -0
- package/dist/esm/Header.js.map +1 -0
- package/dist/{types → esm}/HeaderSearchInput.d.ts +0 -0
- package/dist/esm/HeaderSearchInput.js +181 -0
- package/dist/esm/HeaderSearchInput.js.map +1 -0
- package/dist/{types → esm}/HumanNameDisplay.d.ts +0 -0
- package/dist/esm/HumanNameDisplay.js +13 -0
- package/dist/esm/HumanNameDisplay.js.map +1 -0
- package/dist/{types → esm}/HumanNameInput.d.ts +0 -0
- package/dist/esm/HumanNameInput.js +49 -0
- package/dist/esm/HumanNameInput.js.map +1 -0
- package/dist/{types → esm}/IdentifierDisplay.d.ts +0 -0
- package/dist/esm/IdentifierDisplay.js +12 -0
- package/dist/esm/IdentifierDisplay.js.map +1 -0
- package/dist/{types → esm}/IdentifierInput.d.ts +0 -0
- package/dist/esm/IdentifierInput.js +19 -0
- package/dist/esm/IdentifierInput.js.map +1 -0
- package/dist/{types → esm}/Input.d.ts +0 -0
- package/dist/esm/Input.js +26 -0
- package/dist/esm/Input.js.map +1 -0
- package/dist/{types → esm}/InputRow.d.ts +0 -0
- package/dist/esm/InputRow.js +8 -0
- package/dist/esm/InputRow.js.map +1 -0
- package/dist/{types → esm}/Loading.d.ts +0 -0
- package/dist/esm/Loading.js +11 -0
- package/dist/esm/Loading.js.map +1 -0
- package/dist/{types → esm}/Logo.d.ts +0 -0
- package/dist/esm/Logo.js +14 -0
- package/dist/esm/Logo.js.map +1 -0
- package/dist/{types → esm}/MedplumLink.d.ts +0 -0
- package/dist/esm/MedplumLink.js +34 -0
- package/dist/esm/MedplumLink.js.map +1 -0
- package/dist/{types → esm}/MedplumProvider.d.ts +0 -0
- package/dist/esm/MedplumProvider.js +50 -0
- package/dist/esm/MedplumProvider.js.map +1 -0
- package/dist/{types → esm}/MenuItem.d.ts +0 -0
- package/dist/esm/MenuItem.js +8 -0
- package/dist/esm/MenuItem.js.map +1 -0
- package/dist/{types → esm}/MenuSeparator.d.ts +0 -0
- package/dist/esm/MenuSeparator.js +8 -0
- package/dist/esm/MenuSeparator.js.map +1 -0
- package/dist/{types → esm}/PatientTimeline.d.ts +0 -0
- package/dist/esm/PatientTimeline.js +40 -0
- package/dist/esm/PatientTimeline.js.map +1 -0
- package/dist/{types → esm}/PeriodInput.d.ts +0 -0
- package/dist/esm/PeriodInput.js +19 -0
- package/dist/esm/PeriodInput.js.map +1 -0
- package/dist/{types → esm}/PlanDefinitionBuilder.d.ts +0 -0
- package/dist/esm/PlanDefinitionBuilder.js +224 -0
- package/dist/esm/PlanDefinitionBuilder.js.map +1 -0
- package/dist/{types → esm}/Popup.d.ts +0 -0
- package/dist/esm/Popup.js +64 -0
- package/dist/esm/Popup.js.map +1 -0
- package/dist/{types → esm}/QuantityDisplay.d.ts +0 -0
- package/dist/esm/QuantityDisplay.js +28 -0
- package/dist/esm/QuantityDisplay.js.map +1 -0
- package/dist/{types → esm}/QuantityInput.d.ts +0 -0
- package/dist/esm/QuantityInput.js +33 -0
- package/dist/esm/QuantityInput.js.map +1 -0
- package/dist/{types → esm}/QuestionnaireBuilder.d.ts +0 -0
- package/dist/esm/QuestionnaireBuilder.js +217 -0
- package/dist/esm/QuestionnaireBuilder.js.map +1 -0
- package/dist/{types → esm}/QuestionnaireForm.d.ts +0 -0
- package/dist/esm/QuestionnaireForm.js +218 -0
- package/dist/esm/QuestionnaireForm.js.map +1 -0
- package/dist/{types → esm}/QuestionnaireUtils.d.ts +0 -0
- package/dist/esm/QuestionnaireUtils.js +103 -0
- package/dist/esm/QuestionnaireUtils.js.map +1 -0
- package/dist/{types → esm}/RangeDisplay.d.ts +0 -0
- package/dist/esm/RangeDisplay.js +21 -0
- package/dist/esm/RangeDisplay.js.map +1 -0
- package/dist/{types → esm}/RangeInput.d.ts +0 -0
- package/dist/esm/RangeInput.js +25 -0
- package/dist/esm/RangeInput.js.map +1 -0
- package/dist/{types → esm}/RatioDisplay.d.ts +0 -0
- package/dist/esm/RatioDisplay.js +16 -0
- package/dist/esm/RatioDisplay.js.map +1 -0
- package/dist/{types → esm}/RatioInput.d.ts +0 -0
- package/dist/esm/RatioInput.js +25 -0
- package/dist/esm/RatioInput.js.map +1 -0
- package/dist/{types → esm}/ReferenceDisplay.d.ts +0 -0
- package/dist/esm/ReferenceDisplay.js +21 -0
- package/dist/esm/ReferenceDisplay.js.map +1 -0
- package/dist/{types → esm}/ReferenceInput.d.ts +0 -0
- package/dist/esm/ReferenceInput.js +42 -0
- package/dist/esm/ReferenceInput.js.map +1 -0
- package/dist/{types → esm}/RegisterForm.d.ts +0 -0
- package/dist/esm/RegisterForm.js +121 -0
- package/dist/esm/RegisterForm.js.map +1 -0
- package/dist/{types → esm}/RequestGroupDisplay.d.ts +0 -0
- package/dist/esm/RequestGroupDisplay.js +72 -0
- package/dist/esm/RequestGroupDisplay.js.map +1 -0
- package/dist/{types → esm}/ResourceArrayDisplay.d.ts +0 -0
- package/dist/esm/ResourceArrayDisplay.js +14 -0
- package/dist/esm/ResourceArrayDisplay.js.map +1 -0
- package/dist/{types → esm}/ResourceArrayInput.d.ts +0 -0
- package/dist/esm/ResourceArrayInput.js +47 -0
- package/dist/esm/ResourceArrayInput.js.map +1 -0
- package/dist/{types → esm}/ResourceBadge.d.ts +0 -0
- package/dist/esm/ResourceBadge.js +13 -0
- package/dist/esm/ResourceBadge.js.map +1 -0
- package/dist/{types → esm}/ResourceBlame.d.ts +0 -0
- package/dist/esm/ResourceBlame.js +65 -0
- package/dist/esm/ResourceBlame.js.map +1 -0
- package/dist/{types → esm}/ResourceDiff.d.ts +0 -0
- package/dist/esm/ResourceDiff.js +28 -0
- package/dist/esm/ResourceDiff.js.map +1 -0
- package/dist/{types → esm}/ResourceDiffTable.d.ts +0 -0
- package/dist/esm/ResourceDiffTable.js +58 -0
- package/dist/esm/ResourceDiffTable.js.map +1 -0
- package/dist/{types → esm}/ResourceForm.d.ts +0 -0
- package/dist/esm/ResourceForm.js +55 -0
- package/dist/esm/ResourceForm.js.map +1 -0
- package/dist/{types → esm}/ResourceHistoryTable.d.ts +0 -0
- package/dist/esm/ResourceHistoryTable.js +45 -0
- package/dist/esm/ResourceHistoryTable.js.map +1 -0
- package/dist/{types → esm}/ResourceInput.d.ts +1 -0
- package/dist/esm/ResourceInput.js +41 -0
- package/dist/esm/ResourceInput.js.map +1 -0
- package/dist/{types → esm}/ResourceName.d.ts +0 -0
- package/dist/esm/ResourceName.js +16 -0
- package/dist/esm/ResourceName.js.map +1 -0
- package/dist/{types → esm}/ResourcePropertyDisplay.d.ts +0 -0
- package/dist/esm/ResourcePropertyDisplay.js +107 -0
- package/dist/esm/ResourcePropertyDisplay.js.map +1 -0
- package/dist/{types → esm}/ResourcePropertyInput.d.ts +0 -0
- package/dist/esm/ResourcePropertyInput.js +154 -0
- package/dist/esm/ResourcePropertyInput.js.map +1 -0
- package/dist/{types → esm}/ResourceTable.d.ts +0 -0
- package/dist/esm/ResourceTable.js +22 -0
- package/dist/esm/ResourceTable.js.map +1 -0
- package/dist/{types → esm}/ResourceTimeline.d.ts +0 -0
- package/dist/esm/ResourceTimeline.js +221 -0
- package/dist/esm/ResourceTimeline.js.map +1 -0
- package/dist/{types → esm}/Scheduler.d.ts +0 -0
- package/dist/esm/Scheduler.js +82 -0
- package/dist/esm/Scheduler.js.map +1 -0
- package/dist/{types → esm}/Scrollable.d.ts +0 -0
- package/dist/esm/Scrollable.js +12 -0
- package/dist/esm/Scrollable.js.map +1 -0
- package/dist/{types → esm}/SearchControl.d.ts +0 -0
- package/dist/esm/SearchControl.js +268 -0
- package/dist/esm/SearchControl.js.map +1 -0
- package/dist/{types → esm}/SearchControlField.d.ts +0 -0
- package/dist/esm/SearchControlField.js +98 -0
- package/dist/esm/SearchControlField.js.map +1 -0
- package/dist/{types → esm}/SearchFieldEditor.d.ts +0 -0
- package/dist/esm/SearchFieldEditor.js +192 -0
- package/dist/esm/SearchFieldEditor.js.map +1 -0
- package/dist/{types → esm}/SearchFilterEditor.d.ts +0 -0
- package/dist/esm/SearchFilterEditor.js +103 -0
- package/dist/esm/SearchFilterEditor.js.map +1 -0
- package/dist/{types → esm}/SearchFilterValueDialog.d.ts +0 -0
- package/dist/esm/SearchFilterValueDialog.js +22 -0
- package/dist/esm/SearchFilterValueDialog.js.map +1 -0
- package/dist/{types → esm}/SearchFilterValueDisplay.d.ts +0 -0
- package/dist/esm/SearchFilterValueDisplay.js +22 -0
- package/dist/esm/SearchFilterValueDisplay.js.map +1 -0
- package/dist/{types → esm}/SearchFilterValueInput.d.ts +0 -0
- package/dist/esm/SearchFilterValueInput.js +59 -0
- package/dist/esm/SearchFilterValueInput.js.map +1 -0
- package/dist/{types → esm}/SearchPopupMenu.d.ts +0 -0
- package/dist/esm/SearchPopupMenu.js +135 -0
- package/dist/esm/SearchPopupMenu.js.map +1 -0
- package/dist/{types → esm}/SearchUtils.d.ts +0 -0
- package/dist/esm/SearchUtils.js +487 -0
- package/dist/esm/SearchUtils.js.map +1 -0
- package/dist/{types → esm}/Select.d.ts +0 -0
- package/dist/esm/Select.js +16 -0
- package/dist/esm/Select.js.map +1 -0
- package/dist/{types → esm}/ServiceRequestTimeline.d.ts +0 -0
- package/dist/esm/ServiceRequestTimeline.js +53 -0
- package/dist/esm/ServiceRequestTimeline.js.map +1 -0
- package/dist/{types → esm}/SignInForm.d.ts +0 -0
- package/dist/esm/SignInForm.js +130 -0
- package/dist/esm/SignInForm.js.map +1 -0
- package/dist/{types → esm}/StatusBadge.d.ts +0 -0
- package/dist/esm/StatusBadge.js +8 -0
- package/dist/esm/StatusBadge.js.map +1 -0
- package/dist/{types → esm}/SubMenu.d.ts +0 -0
- package/dist/esm/SubMenu.js +38 -0
- package/dist/esm/SubMenu.js.map +1 -0
- package/dist/{types → esm}/Tab.d.ts +0 -0
- package/dist/esm/Tab.js +19 -0
- package/dist/esm/Tab.js.map +1 -0
- package/dist/{types → esm}/TabList.d.ts +0 -0
- package/dist/esm/TabList.js +23 -0
- package/dist/esm/TabList.js.map +1 -0
- package/dist/{types → esm}/TabPanel.d.ts +0 -0
- package/dist/esm/TabPanel.js +8 -0
- package/dist/esm/TabPanel.js.map +1 -0
- package/dist/{types → esm}/TabSwitch.d.ts +0 -0
- package/dist/esm/TabSwitch.js +16 -0
- package/dist/esm/TabSwitch.js.map +1 -0
- package/dist/{types → esm}/TextArea.d.ts +0 -0
- package/dist/esm/TextArea.js +16 -0
- package/dist/esm/TextArea.js.map +1 -0
- package/dist/{types → esm}/Timeline.d.ts +0 -0
- package/dist/esm/Timeline.js +48 -0
- package/dist/esm/Timeline.js.map +1 -0
- package/dist/esm/TimingInput.d.ts +8 -0
- package/dist/esm/TimingInput.js +90 -0
- package/dist/esm/TimingInput.js.map +1 -0
- package/dist/{types → esm}/TitleBar.d.ts +0 -0
- package/dist/esm/TitleBar.js +8 -0
- package/dist/esm/TitleBar.js.map +1 -0
- package/dist/{types → esm}/UploadButton.d.ts +0 -0
- package/dist/esm/UploadButton.js +55 -0
- package/dist/esm/UploadButton.js.map +1 -0
- package/dist/{types → esm}/constants.d.ts +0 -0
- package/dist/esm/constants.js +12 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/{types → esm}/index.d.ts +0 -1
- package/dist/esm/index.js +86 -5814
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +1 -1
- package/dist/esm/index.min.js.map +1 -1
- package/dist/esm/node_modules/tslib/tslib.es6.js +27 -0
- package/dist/esm/node_modules/tslib/tslib.es6.js.map +1 -0
- package/dist/{types → esm}/stories/AddressInput.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/AttachmentArrayInput.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/AttachmentInput.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Autocomplete.stories.d.ts +1 -0
- package/dist/{types → esm}/stories/Avatar.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Button.stories.d.ts +0 -0
- package/dist/esm/stories/CodeableConceptDisplay.stories.d.ts +8 -0
- package/dist/{types → esm}/stories/DiagnosticReportDisplay.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Dialog.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/EncounterTimeline.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/FhirPathDisplay.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/FormSection.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Header.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Input.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Loading.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Logo.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/PatientTimeline.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/PlanDefinitionBuilder.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/QuestionnaireBuilder.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/QuestionnaireForm.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/ReferenceInput.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/RegisterForm.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/RequestGroupDisplay.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/ResourceBlame.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/ResourceForm.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/ResourceHistoryTable.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/ResourceTable.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Scheduler.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/SearchControl.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Select.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/SignInForm.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/StatusBadge.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Tabs.stories.d.ts +0 -0
- package/dist/{types → esm}/stories/Timeline.stories.d.ts +0 -0
- package/dist/esm/stories/TimingInput.stories.d.ts +6 -0
- package/dist/{types → esm}/stories/UploadButton.stories.d.ts +0 -0
- package/dist/esm/styles.css +83 -79
- package/dist/{types → esm}/test.setup.d.ts +0 -0
- package/dist/{types → esm}/useResource.d.ts +0 -0
- package/dist/esm/useResource.js +65 -0
- package/dist/esm/useResource.js.map +1 -0
- package/dist/{types → esm}/utils/blame.d.ts +0 -0
- package/dist/esm/utils/blame.js +74 -0
- package/dist/esm/utils/blame.js.map +1 -0
- package/dist/{types → esm}/utils/date.d.ts +0 -0
- package/dist/esm/utils/date.js +48 -0
- package/dist/esm/utils/date.js.map +1 -0
- package/dist/{types → esm}/utils/diff.d.ts +0 -0
- package/dist/esm/utils/diff.js +118 -0
- package/dist/esm/utils/diff.js.map +1 -0
- package/dist/{types → esm}/utils/dom.d.ts +0 -0
- package/dist/esm/utils/dom.js +34 -0
- package/dist/esm/utils/dom.js.map +1 -0
- package/dist/{types → esm}/utils/outcomes.d.ts +0 -0
- package/dist/esm/utils/outcomes.js +7 -0
- package/dist/esm/utils/outcomes.js.map +1 -0
- package/dist/{types → esm}/utils/recaptcha.d.ts +0 -0
- package/dist/esm/utils/recaptcha.js +27 -0
- package/dist/esm/utils/recaptcha.js.map +1 -0
- package/dist/{types → esm}/utils.d.ts +0 -0
- package/dist/esm/utils.js +15 -0
- package/dist/esm/utils.js.map +1 -0
- package/package.json +7 -7
- package/stats.html +4034 -0
- package/dist/types/DateTimeDisplay.d.ts +0 -5
- package/dist/types/PeriodDisplay.d.ts +0 -6
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses an HTML form and returns the result as a JavaScript object.
|
|
3
|
+
* @param form The HTML form element.
|
|
4
|
+
*/
|
|
5
|
+
function parseForm(form) {
|
|
6
|
+
const result = {};
|
|
7
|
+
for (const element of Array.from(form.elements)) {
|
|
8
|
+
if (element instanceof HTMLInputElement) {
|
|
9
|
+
parseInputElement(result, element);
|
|
10
|
+
}
|
|
11
|
+
else if (element instanceof HTMLTextAreaElement) {
|
|
12
|
+
result[element.name] = element.value;
|
|
13
|
+
}
|
|
14
|
+
else if (element instanceof HTMLSelectElement) {
|
|
15
|
+
parseSelectElement(result, element);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parses an HTML input element.
|
|
22
|
+
* Sets the name/value pair in the result,
|
|
23
|
+
* but only if the element is enabled and checked.
|
|
24
|
+
* @param el The input element.
|
|
25
|
+
* @param result The result builder.
|
|
26
|
+
*/
|
|
27
|
+
function parseInputElement(result, el) {
|
|
28
|
+
if (el.disabled) {
|
|
29
|
+
// Ignore disabled elements
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if ((el.type === 'checkbox' || el.type === 'radio') && !el.checked) {
|
|
33
|
+
// Ignore unchecked radio or checkbox elements
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
result[el.name] = el.value;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Parses an HTML select element.
|
|
40
|
+
* Sets the name/value pair if one is selected.
|
|
41
|
+
* @param result The result builder.
|
|
42
|
+
* @param el The select element.
|
|
43
|
+
*/
|
|
44
|
+
function parseSelectElement(result, el) {
|
|
45
|
+
result[el.name] = el.value;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { parseForm };
|
|
49
|
+
//# sourceMappingURL=FormUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormUtils.js","sources":["../../src/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 el The input element.\n * @param result The result builder.\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;;;AAGG;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;;;;"}
|
|
File without changes
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React, { useRef, useState, useEffect } from 'react';
|
|
2
|
+
import { useMedplum } from './MedplumProvider.js';
|
|
3
|
+
import { createScriptTag } from './utils.js';
|
|
4
|
+
|
|
5
|
+
function GoogleButton(props) {
|
|
6
|
+
const medplum = useMedplum();
|
|
7
|
+
const { googleClientId, handleGoogleCredential } = props;
|
|
8
|
+
const parentRef = useRef(null);
|
|
9
|
+
const [scriptLoaded, setScriptLoaded] = useState(typeof google !== 'undefined');
|
|
10
|
+
const [initialized, setInitialized] = useState(false);
|
|
11
|
+
const [buttonRendered, setButtonRendered] = useState(false);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (typeof google === 'undefined') {
|
|
14
|
+
createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (!initialized) {
|
|
18
|
+
google.accounts.id.initialize({
|
|
19
|
+
client_id: googleClientId,
|
|
20
|
+
callback: handleGoogleCredential,
|
|
21
|
+
});
|
|
22
|
+
setInitialized(true);
|
|
23
|
+
}
|
|
24
|
+
if (parentRef.current && !buttonRendered) {
|
|
25
|
+
google.accounts.id.renderButton(parentRef.current, {});
|
|
26
|
+
setButtonRendered(true);
|
|
27
|
+
}
|
|
28
|
+
}, [medplum, googleClientId, initialized, scriptLoaded, parentRef, buttonRendered, handleGoogleCredential]);
|
|
29
|
+
if (!googleClientId) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return React.createElement("div", { ref: parentRef });
|
|
33
|
+
}
|
|
34
|
+
function getGoogleClientId(clientId) {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
if (clientId) {
|
|
37
|
+
return clientId;
|
|
38
|
+
}
|
|
39
|
+
const origin = window.location.protocol + '//' + window.location.host;
|
|
40
|
+
const authorizedOrigins = (_b = (_a = "http://localhost:3000,http://localhost:6006,https://app.medplum.com,https://docs.medplum.com") === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
|
|
41
|
+
if (authorizedOrigins.includes(origin)) {
|
|
42
|
+
return "921088377005-3j1sa10vr6hj86jgmdfh2l53v3mp7lfi.apps.googleusercontent.com";
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { GoogleButton, getGoogleClientId };
|
|
48
|
+
//# sourceMappingURL=GoogleButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoogleButton.js","sources":["../../src/GoogleButton.tsx"],"sourcesContent":["import { GoogleCredentialResponse } from '@medplum/core';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { useMedplum } from './MedplumProvider';\nimport { createScriptTag } from './utils';\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 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 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,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACtE,IAAA,MAAM,iBAAiB,GAAG,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,8FAA+B,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,KAAK,CAAC,GAAG,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,EAAE,CAAC;AAC5E,IAAA,IAAI,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AACtC,QAAA,OAAO,0EAA4B,CAAC;AACrC,KAAA;AAED,IAAA,OAAO,SAAS,CAAC;AACnB;;;;"}
|
|
File without changes
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { getReferenceString } from '@medplum/core';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { useNavigate, useLocation } from 'react-router-dom';
|
|
4
|
+
import { Avatar } from './Avatar.js';
|
|
5
|
+
import { Button } from './Button.js';
|
|
6
|
+
import { HeaderSearchInput } from './HeaderSearchInput.js';
|
|
7
|
+
import { HumanNameDisplay } from './HumanNameDisplay.js';
|
|
8
|
+
import { MedplumLink } from './MedplumLink.js';
|
|
9
|
+
import { useMedplumContext } from './MedplumProvider.js';
|
|
10
|
+
import { Popup } from './Popup.js';
|
|
11
|
+
|
|
12
|
+
function Header(props) {
|
|
13
|
+
var _a, _b, _c, _d, _e, _f;
|
|
14
|
+
const navigate = useNavigate();
|
|
15
|
+
const location = useLocation();
|
|
16
|
+
const context = useMedplumContext();
|
|
17
|
+
const medplum = context.medplum;
|
|
18
|
+
const logins = medplum.getLogins();
|
|
19
|
+
const [userMenuVisible, setUserMenuVisible] = useState(false);
|
|
20
|
+
const [sidebarVisible, setSidebarVisible] = useState(false);
|
|
21
|
+
return (React.createElement(React.Fragment, null,
|
|
22
|
+
React.createElement("header", { role: "banner", "data-testid": "header", style: { background: props.bgColor } },
|
|
23
|
+
React.createElement("div", null,
|
|
24
|
+
React.createElement(MedplumLink, { label: "Toggle sidebar", testid: "header-menu-button", onClick: () => setSidebarVisible(!sidebarVisible) },
|
|
25
|
+
React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", style: { width: 20, height: 20, verticalAlign: 'text-top' }, viewBox: "0 0 20 20", fill: "currentColor" },
|
|
26
|
+
React.createElement("path", { fillRule: "evenodd", d: "M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z", clipRule: "evenodd" }))),
|
|
27
|
+
React.createElement(MedplumLink, { id: "medplum-header-logo", testid: "header-logo", onClick: props.onLogo }, props.title || 'Medplum'),
|
|
28
|
+
context.profile && (React.createElement(HeaderSearchInput, { key: `header-input-${location.pathname}`, name: "search", className: "medplum-nav-search-container", placeholder: "Search", onChange: (resource) => navigate(`/${resource.resourceType}/${resource.id}`) }))),
|
|
29
|
+
context.profile && (React.createElement("div", { className: "medplum-nav-menu-container" },
|
|
30
|
+
React.createElement(MedplumLink, { testid: "header-profile-menu-button", onClick: () => setUserMenuVisible(true) },
|
|
31
|
+
React.createElement(Avatar, { size: "small", color: "#f68d42", value: context.profile })),
|
|
32
|
+
React.createElement(Popup, { visible: userMenuVisible, autoClose: true, activeClassName: "medplum-nav-menu-popover", onClose: () => setUserMenuVisible(false) },
|
|
33
|
+
React.createElement("div", { className: "medplum-nav-menu" },
|
|
34
|
+
React.createElement("div", { style: { margin: 'auto', padding: '8px' } },
|
|
35
|
+
React.createElement(Avatar, { size: "large", value: context.profile })),
|
|
36
|
+
React.createElement("div", { style: { margin: 'auto', padding: '8px' } },
|
|
37
|
+
React.createElement("div", { style: { margin: '4px auto 4px auto', fontWeight: 'bold' } },
|
|
38
|
+
React.createElement(HumanNameDisplay, { value: (_b = (_a = context.profile) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b[0] })),
|
|
39
|
+
React.createElement("div", { style: { margin: '4px auto 4px auto' } }, (_d = (_c = medplum.getActiveLogin()) === null || _c === void 0 ? void 0 : _c.project) === null || _d === void 0 ? void 0 : _d.display),
|
|
40
|
+
React.createElement(Button, { testid: "header-profile-link", onClick: () => {
|
|
41
|
+
setUserMenuVisible(false);
|
|
42
|
+
if (props.onProfile) {
|
|
43
|
+
props.onProfile();
|
|
44
|
+
}
|
|
45
|
+
} }, "Manage your account")),
|
|
46
|
+
logins.length > 1 && (React.createElement("div", null,
|
|
47
|
+
React.createElement("hr", null),
|
|
48
|
+
logins.map((login) => {
|
|
49
|
+
var _a, _b, _c, _d;
|
|
50
|
+
return ((_a = login.profile) === null || _a === void 0 ? void 0 : _a.reference) !== getReferenceString(context.profile) && (React.createElement("div", { className: "medplum-nav-menu-profile", key: (_b = login.profile) === null || _b === void 0 ? void 0 : _b.reference, onClick: () => {
|
|
51
|
+
medplum.setActiveLogin(login);
|
|
52
|
+
setUserMenuVisible(false);
|
|
53
|
+
window.location.reload();
|
|
54
|
+
} },
|
|
55
|
+
React.createElement("div", { className: "medplum-nav-menu-profile-icon" },
|
|
56
|
+
React.createElement(Avatar, null)),
|
|
57
|
+
React.createElement("div", { className: "medplum-nav-menu-profile-label" }, (_c = login.profile) === null || _c === void 0 ? void 0 :
|
|
58
|
+
_c.display,
|
|
59
|
+
React.createElement("div", { className: "medplum-nav-menu-profile-help-text" }, (_d = login.project) === null || _d === void 0 ? void 0 : _d.display))));
|
|
60
|
+
}))),
|
|
61
|
+
React.createElement("hr", null),
|
|
62
|
+
React.createElement("div", { style: { margin: 'auto', padding: '8px' } },
|
|
63
|
+
React.createElement(Button, { testid: "header-add-account-button", onClick: () => {
|
|
64
|
+
navigate('/signin');
|
|
65
|
+
} }, "Add another account")),
|
|
66
|
+
React.createElement("hr", null),
|
|
67
|
+
React.createElement("div", { style: { margin: 'auto', padding: '8px' } },
|
|
68
|
+
React.createElement(Button, { testid: "header-signout-button", onClick: () => {
|
|
69
|
+
setUserMenuVisible(false);
|
|
70
|
+
if (props.onSignOut) {
|
|
71
|
+
props.onSignOut();
|
|
72
|
+
}
|
|
73
|
+
} }, "Sign out of all accounts")),
|
|
74
|
+
React.createElement("hr", null),
|
|
75
|
+
React.createElement("div", { style: { margin: 'auto', padding: '8px', fontSize: '12px' } },
|
|
76
|
+
React.createElement("a", { href: "https://www.medplum.com/terms" }, "Terms"),
|
|
77
|
+
React.createElement("a", { href: "https://www.medplum.com/privacy" }, "Privacy"))))))),
|
|
78
|
+
React.createElement(Popup, { modal: true, autoClose: true, visible: sidebarVisible, activeClassName: "medplum-sidebar active", inactiveClassName: "medplum-sidebar", onClose: () => setSidebarVisible(false) }, (_f = (_e = props.config) === null || _e === void 0 ? void 0 : _e.menu) === null || _f === void 0 ? void 0 :
|
|
79
|
+
_f.map((menu, index) => {
|
|
80
|
+
var _a, _b, _c;
|
|
81
|
+
return (React.createElement(React.Fragment, { key: `menu-${index}-${(_b = (_a = props.config) === null || _a === void 0 ? void 0 : _a.menu) === null || _b === void 0 ? void 0 : _b.length}` },
|
|
82
|
+
React.createElement("h5", null, menu.title),
|
|
83
|
+
React.createElement("ul", null, (_c = menu.link) === null || _c === void 0 ? void 0 : _c.map((link) => (React.createElement("li", { key: link.target },
|
|
84
|
+
React.createElement(MedplumLink, { to: link.target }, link.name)))))));
|
|
85
|
+
}),
|
|
86
|
+
React.createElement("h5", null, "Settings"),
|
|
87
|
+
React.createElement("ul", null,
|
|
88
|
+
React.createElement("li", null,
|
|
89
|
+
React.createElement(MedplumLink, { to: context.profile }, "Profile")),
|
|
90
|
+
React.createElement("li", null,
|
|
91
|
+
React.createElement(MedplumLink, { to: "/changepassword" }, "Change password"))))));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { Header };
|
|
95
|
+
//# sourceMappingURL=Header.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Header.js","sources":["../../src/Header.tsx"],"sourcesContent":["import { getReferenceString, ProfileResource } from '@medplum/core';\nimport { HumanName, UserConfiguration } from '@medplum/fhirtypes';\nimport React, { useState } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { Avatar } from './Avatar';\nimport { Button } from './Button';\nimport { HeaderSearchInput, HeaderSearchTypes } from './HeaderSearchInput';\nimport { HumanNameDisplay } from './HumanNameDisplay';\nimport { MedplumLink } from './MedplumLink';\nimport { useMedplumContext } from './MedplumProvider';\nimport { Popup } from './Popup';\nimport './Header.css';\n\nexport interface HeaderProps {\n readonly title?: string;\n readonly bgColor?: string;\n readonly onLogo?: () => void;\n readonly onProfile?: () => void;\n readonly onSignOut?: () => void;\n readonly config?: UserConfiguration;\n}\n\nexport function Header(props: HeaderProps): JSX.Element {\n const navigate = useNavigate();\n const location = useLocation();\n const context = useMedplumContext();\n const medplum = context.medplum;\n const logins = medplum.getLogins();\n const [userMenuVisible, setUserMenuVisible] = useState(false);\n const [sidebarVisible, setSidebarVisible] = useState(false);\n\n return (\n <>\n <header role=\"banner\" data-testid=\"header\" style={{ background: props.bgColor }}>\n <div>\n <MedplumLink\n label=\"Toggle sidebar\"\n testid=\"header-menu-button\"\n onClick={() => setSidebarVisible(!sidebarVisible)}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ width: 20, height: 20, verticalAlign: 'text-top' }}\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </MedplumLink>\n <MedplumLink id=\"medplum-header-logo\" testid=\"header-logo\" onClick={props.onLogo}>\n {props.title || 'Medplum'}\n </MedplumLink>\n {context.profile && (\n <HeaderSearchInput\n key={`header-input-${location.pathname}`}\n name=\"search\"\n className=\"medplum-nav-search-container\"\n placeholder=\"Search\"\n onChange={(resource: HeaderSearchTypes) => navigate(`/${resource.resourceType}/${resource.id}`)}\n />\n )}\n </div>\n {context.profile && (\n <div className=\"medplum-nav-menu-container\">\n <MedplumLink testid=\"header-profile-menu-button\" onClick={() => setUserMenuVisible(true)}>\n <Avatar size=\"small\" color=\"#f68d42\" value={context.profile} />\n </MedplumLink>\n <Popup\n visible={userMenuVisible}\n autoClose={true}\n activeClassName=\"medplum-nav-menu-popover\"\n onClose={() => setUserMenuVisible(false)}\n >\n <div className=\"medplum-nav-menu\">\n <div style={{ margin: 'auto', padding: '8px' }}>\n <Avatar size=\"large\" value={context.profile} />\n </div>\n <div style={{ margin: 'auto', padding: '8px' }}>\n <div style={{ margin: '4px auto 4px auto', fontWeight: 'bold' }}>\n <HumanNameDisplay value={context.profile?.name?.[0] as HumanName} />\n </div>\n <div style={{ margin: '4px auto 4px auto' }}>{medplum.getActiveLogin()?.project?.display}</div>\n <Button\n testid=\"header-profile-link\"\n onClick={() => {\n setUserMenuVisible(false);\n if (props.onProfile) {\n props.onProfile();\n }\n }}\n >\n Manage your account\n </Button>\n </div>\n {logins.length > 1 && (\n <div>\n <hr />\n {logins.map(\n (login) =>\n login.profile?.reference !== getReferenceString(context.profile as ProfileResource) && (\n <div\n className=\"medplum-nav-menu-profile\"\n key={login.profile?.reference}\n onClick={() => {\n medplum.setActiveLogin(login);\n setUserMenuVisible(false);\n window.location.reload();\n }}\n >\n <div className=\"medplum-nav-menu-profile-icon\">\n <Avatar />\n </div>\n <div className=\"medplum-nav-menu-profile-label\">\n {login.profile?.display}\n <div className=\"medplum-nav-menu-profile-help-text\">{login.project?.display}</div>\n </div>\n </div>\n )\n )}\n </div>\n )}\n <hr />\n <div style={{ margin: 'auto', padding: '8px' }}>\n <Button\n testid=\"header-add-account-button\"\n onClick={() => {\n navigate('/signin');\n }}\n >\n Add another account\n </Button>\n </div>\n <hr />\n <div style={{ margin: 'auto', padding: '8px' }}>\n <Button\n testid=\"header-signout-button\"\n onClick={() => {\n setUserMenuVisible(false);\n if (props.onSignOut) {\n props.onSignOut();\n }\n }}\n >\n Sign out of all accounts\n </Button>\n </div>\n <hr />\n <div style={{ margin: 'auto', padding: '8px', fontSize: '12px' }}>\n <a href=\"https://www.medplum.com/terms\">Terms</a>\n <a href=\"https://www.medplum.com/privacy\">Privacy</a>\n </div>\n </div>\n </Popup>\n </div>\n )}\n </header>\n <Popup\n modal={true}\n autoClose={true}\n visible={sidebarVisible}\n activeClassName=\"medplum-sidebar active\"\n inactiveClassName=\"medplum-sidebar\"\n onClose={() => setSidebarVisible(false)}\n >\n {props.config?.menu?.map((menu, index) => (\n <React.Fragment key={`menu-${index}-${props.config?.menu?.length}`}>\n <h5>{menu.title}</h5>\n <ul>\n {menu.link?.map((link) => (\n <li key={link.target}>\n <MedplumLink to={link.target}>{link.name}</MedplumLink>\n </li>\n ))}\n </ul>\n </React.Fragment>\n ))}\n <h5>Settings</h5>\n <ul>\n <li>\n <MedplumLink to={context.profile}>Profile</MedplumLink>\n </li>\n <li>\n <MedplumLink to=\"/changepassword\">Change password</MedplumLink>\n </li>\n </ul>\n </Popup>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
File without changes
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { __awaiter } from './node_modules/tslib/tslib.es6.js';
|
|
2
|
+
import { isUUID, formatHumanName } from '@medplum/core';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Autocomplete } from './Autocomplete.js';
|
|
5
|
+
import { Avatar } from './Avatar.js';
|
|
6
|
+
import { useMedplum } from './MedplumProvider.js';
|
|
7
|
+
import { ResourceName } from './ResourceName.js';
|
|
8
|
+
|
|
9
|
+
function HeaderSearchInput(props) {
|
|
10
|
+
const medplum = useMedplum();
|
|
11
|
+
return (React.createElement(Autocomplete, { loadOptions: (input, signal) => __awaiter(this, void 0, void 0, function* () {
|
|
12
|
+
return getResourcesFromResponse((yield medplum.graphql(buildGraphQLQuery(input), undefined, undefined, { signal })), input);
|
|
13
|
+
}), getId: (item) => {
|
|
14
|
+
return item.id;
|
|
15
|
+
}, getIcon: (item) => React.createElement(Avatar, { value: item }), getDisplay: (item) => React.createElement(ResourceName, { value: item }), getHelpText: (item) => {
|
|
16
|
+
var _a;
|
|
17
|
+
if (item.resourceType === 'Patient' && item.birthDate) {
|
|
18
|
+
return 'DoB: ' + item.birthDate;
|
|
19
|
+
}
|
|
20
|
+
return (_a = item.subject) === null || _a === void 0 ? void 0 : _a.display;
|
|
21
|
+
}, name: props.name, className: props.className, placeholder: props.placeholder, onChange: (items) => props.onChange(items[0]) }));
|
|
22
|
+
}
|
|
23
|
+
function buildGraphQLQuery(input) {
|
|
24
|
+
const escaped = JSON.stringify(input);
|
|
25
|
+
if (isUUID(input)) {
|
|
26
|
+
return `{
|
|
27
|
+
Patients1: PatientList(_id: ${escaped}, _count: 1) {
|
|
28
|
+
resourceType
|
|
29
|
+
id
|
|
30
|
+
identifier {
|
|
31
|
+
system
|
|
32
|
+
value
|
|
33
|
+
}
|
|
34
|
+
name {
|
|
35
|
+
given
|
|
36
|
+
family
|
|
37
|
+
}
|
|
38
|
+
birthDate
|
|
39
|
+
}
|
|
40
|
+
ServiceRequestList(_id: ${escaped}, _count: 1) {
|
|
41
|
+
resourceType
|
|
42
|
+
id
|
|
43
|
+
identifier {
|
|
44
|
+
system
|
|
45
|
+
value
|
|
46
|
+
}
|
|
47
|
+
subject {
|
|
48
|
+
display
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}`.replace(/\s+/g, ' ');
|
|
52
|
+
}
|
|
53
|
+
return `{
|
|
54
|
+
Patients1: PatientList(name: ${escaped}, _count: 5) {
|
|
55
|
+
resourceType
|
|
56
|
+
id
|
|
57
|
+
identifier {
|
|
58
|
+
system
|
|
59
|
+
value
|
|
60
|
+
}
|
|
61
|
+
name {
|
|
62
|
+
given
|
|
63
|
+
family
|
|
64
|
+
}
|
|
65
|
+
birthDate
|
|
66
|
+
}
|
|
67
|
+
Patients2: PatientList(identifier: ${escaped}, _count: 5) {
|
|
68
|
+
resourceType
|
|
69
|
+
id
|
|
70
|
+
identifier {
|
|
71
|
+
system
|
|
72
|
+
value
|
|
73
|
+
}
|
|
74
|
+
name {
|
|
75
|
+
given
|
|
76
|
+
family
|
|
77
|
+
}
|
|
78
|
+
birthDate
|
|
79
|
+
}
|
|
80
|
+
ServiceRequestList(identifier: ${escaped}, _count: 5) {
|
|
81
|
+
resourceType
|
|
82
|
+
id
|
|
83
|
+
identifier {
|
|
84
|
+
system
|
|
85
|
+
value
|
|
86
|
+
}
|
|
87
|
+
subject {
|
|
88
|
+
display
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}`.replace(/\s+/g, ' ');
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns a de-duped and sorted list of resources from the search response.
|
|
95
|
+
* The search request is actually 3+ separate searches, which can include duplicates.
|
|
96
|
+
* This function combines the results, de-dupes, and sorts by relevance.
|
|
97
|
+
* @param response The response from a search query.
|
|
98
|
+
* @param query The user entered search query.
|
|
99
|
+
* @returns The resources to display in the autocomplete.
|
|
100
|
+
*/
|
|
101
|
+
function getResourcesFromResponse(response, query) {
|
|
102
|
+
const resources = [];
|
|
103
|
+
if (response.data.Patients1) {
|
|
104
|
+
resources.push(...response.data.Patients1);
|
|
105
|
+
}
|
|
106
|
+
if (response.data.Patients2) {
|
|
107
|
+
resources.push(...response.data.Patients2);
|
|
108
|
+
}
|
|
109
|
+
if (response.data.ServiceRequestList) {
|
|
110
|
+
resources.push(...response.data.ServiceRequestList);
|
|
111
|
+
}
|
|
112
|
+
return sortByRelevance(dedupeResources(resources), query).slice(0, 5);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Removes duplicate resources from an array by ID.
|
|
116
|
+
* @param resources The array of resources with possible duplicates.
|
|
117
|
+
* @returns The array of resources with no duplicates.
|
|
118
|
+
*/
|
|
119
|
+
function dedupeResources(resources) {
|
|
120
|
+
const ids = new Set();
|
|
121
|
+
const result = [];
|
|
122
|
+
for (const resource of resources) {
|
|
123
|
+
if (!ids.has(resource.id)) {
|
|
124
|
+
ids.add(resource.id);
|
|
125
|
+
result.push(resource);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Sorts an array of resources by relevance.
|
|
132
|
+
* @param resources The candidate resources.
|
|
133
|
+
* @param query The user entered search string.
|
|
134
|
+
* @returns The sorted array of resources.
|
|
135
|
+
*/
|
|
136
|
+
function sortByRelevance(resources, query) {
|
|
137
|
+
return resources.sort((a, b) => {
|
|
138
|
+
return getResourceScore(b, query) - getResourceScore(a, query);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Calculates a relevance score of a candidate resource.
|
|
143
|
+
* Higher scores are better.
|
|
144
|
+
* @param resource The candidate resource.
|
|
145
|
+
* @param query The user entered search string.
|
|
146
|
+
* @returns The relevance score of the candidate resource.
|
|
147
|
+
*/
|
|
148
|
+
function getResourceScore(resource, query) {
|
|
149
|
+
let bestScore = 0;
|
|
150
|
+
if (resource.identifier) {
|
|
151
|
+
for (const identifier of resource.identifier) {
|
|
152
|
+
bestScore = Math.max(bestScore, getStringScore(identifier.value, query));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (resource.resourceType === 'Patient' && resource.name) {
|
|
156
|
+
for (const name of resource.name) {
|
|
157
|
+
bestScore = Math.max(bestScore, getStringScore(formatHumanName(name), query));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return bestScore;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Calculates a relevance score of a candidate display string.
|
|
164
|
+
* Higher scores are better.
|
|
165
|
+
* @param str The candidate display string.
|
|
166
|
+
* @param query The user entered search string.
|
|
167
|
+
* @returns The relevance score of the candidate string.
|
|
168
|
+
*/
|
|
169
|
+
function getStringScore(str, query) {
|
|
170
|
+
if (!str) {
|
|
171
|
+
return 0;
|
|
172
|
+
}
|
|
173
|
+
const index = str.toLowerCase().indexOf(query.toLowerCase());
|
|
174
|
+
if (index < 0) {
|
|
175
|
+
return 0;
|
|
176
|
+
}
|
|
177
|
+
return 100 - index;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export { HeaderSearchInput };
|
|
181
|
+
//# sourceMappingURL=HeaderSearchInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeaderSearchInput.js","sources":["../../src/HeaderSearchInput.tsx"],"sourcesContent":["import { formatHumanName, isUUID } from '@medplum/core';\nimport { Patient, ServiceRequest } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Autocomplete } from './Autocomplete';\nimport { Avatar } from './Avatar';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceName } from './ResourceName';\n\nexport type HeaderSearchTypes = Patient | ServiceRequest;\n\nexport interface HeaderSearchInputProps {\n readonly name: string;\n readonly className?: string;\n readonly placeholder?: string;\n readonly onChange: (value: HeaderSearchTypes) => void;\n}\n\ninterface SearchGraphQLResponse {\n readonly data: {\n readonly Patients1: Patient[] | undefined;\n readonly Patients2: Patient[] | undefined;\n readonly ServiceRequestList: ServiceRequest[] | undefined;\n };\n}\n\nexport function HeaderSearchInput(props: HeaderSearchInputProps): JSX.Element {\n const medplum = useMedplum();\n return (\n <Autocomplete\n loadOptions={async (input: string, signal: AbortSignal): Promise<HeaderSearchTypes[]> => {\n return getResourcesFromResponse(\n (await medplum.graphql(buildGraphQLQuery(input), undefined, undefined, { signal })) as SearchGraphQLResponse,\n input\n );\n }}\n getId={(item: HeaderSearchTypes) => {\n return item.id as string;\n }}\n getIcon={(item: HeaderSearchTypes) => <Avatar value={item} />}\n getDisplay={(item: HeaderSearchTypes) => <ResourceName value={item} />}\n getHelpText={(item: HeaderSearchTypes) => {\n if (item.resourceType === 'Patient' && item.birthDate) {\n return 'DoB: ' + item.birthDate;\n }\n return (item as ServiceRequest).subject?.display;\n }}\n name={props.name}\n className={props.className}\n placeholder={props.placeholder}\n onChange={(items: HeaderSearchTypes[]) => props.onChange(items[0])}\n />\n );\n}\n\nfunction buildGraphQLQuery(input: string): string {\n const escaped = JSON.stringify(input);\n if (isUUID(input)) {\n return `{\n Patients1: PatientList(_id: ${escaped}, _count: 1) {\n resourceType\n id\n identifier {\n system\n value\n }\n name {\n given\n family\n }\n birthDate\n }\n ServiceRequestList(_id: ${escaped}, _count: 1) {\n resourceType\n id\n identifier {\n system\n value\n }\n subject {\n display\n }\n }\n }`.replace(/\\s+/g, ' ');\n }\n return `{\n Patients1: PatientList(name: ${escaped}, _count: 5) {\n resourceType\n id\n identifier {\n system\n value\n }\n name {\n given\n family\n }\n birthDate\n }\n Patients2: PatientList(identifier: ${escaped}, _count: 5) {\n resourceType\n id\n identifier {\n system\n value\n }\n name {\n given\n family\n }\n birthDate\n }\n ServiceRequestList(identifier: ${escaped}, _count: 5) {\n resourceType\n id\n identifier {\n system\n value\n }\n subject {\n display\n }\n }\n }`.replace(/\\s+/g, ' ');\n}\n\n/**\n * Returns a de-duped and sorted list of resources from the search response.\n * The search request is actually 3+ separate searches, which can include duplicates.\n * This function combines the results, de-dupes, and sorts by relevance.\n * @param response The response from a search query.\n * @param query The user entered search query.\n * @returns The resources to display in the autocomplete.\n */\nfunction getResourcesFromResponse(response: SearchGraphQLResponse, query: string): HeaderSearchTypes[] {\n const resources = [];\n if (response.data.Patients1) {\n resources.push(...response.data.Patients1);\n }\n if (response.data.Patients2) {\n resources.push(...response.data.Patients2);\n }\n if (response.data.ServiceRequestList) {\n resources.push(...response.data.ServiceRequestList);\n }\n return sortByRelevance(dedupeResources(resources), query).slice(0, 5);\n}\n\n/**\n * Removes duplicate resources from an array by ID.\n * @param resources The array of resources with possible duplicates.\n * @returns The array of resources with no duplicates.\n */\nfunction dedupeResources(resources: HeaderSearchTypes[]): HeaderSearchTypes[] {\n const ids = new Set<string>();\n const result = [];\n\n for (const resource of resources) {\n if (!ids.has(resource.id as string)) {\n ids.add(resource.id as string);\n result.push(resource);\n }\n }\n\n return result;\n}\n\n/**\n * Sorts an array of resources by relevance.\n * @param resources The candidate resources.\n * @param query The user entered search string.\n * @returns The sorted array of resources.\n */\nfunction sortByRelevance(resources: HeaderSearchTypes[], query: string): HeaderSearchTypes[] {\n return resources.sort((a: HeaderSearchTypes, b: HeaderSearchTypes) => {\n return getResourceScore(b, query) - getResourceScore(a, query);\n });\n}\n\n/**\n * Calculates a relevance score of a candidate resource.\n * Higher scores are better.\n * @param resource The candidate resource.\n * @param query The user entered search string.\n * @returns The relevance score of the candidate resource.\n */\nfunction getResourceScore(resource: HeaderSearchTypes, query: string): number {\n let bestScore = 0;\n\n if (resource.identifier) {\n for (const identifier of resource.identifier) {\n bestScore = Math.max(bestScore, getStringScore(identifier.value, query));\n }\n }\n\n if (resource.resourceType === 'Patient' && resource.name) {\n for (const name of resource.name) {\n bestScore = Math.max(bestScore, getStringScore(formatHumanName(name), query));\n }\n }\n\n return bestScore;\n}\n\n/**\n * Calculates a relevance score of a candidate display string.\n * Higher scores are better.\n * @param str The candidate display string.\n * @param query The user entered search string.\n * @returns The relevance score of the candidate string.\n */\nfunction getStringScore(str: string | undefined, query: string): number {\n if (!str) {\n return 0;\n }\n const index = str.toLowerCase().indexOf(query.toLowerCase());\n if (index < 0) {\n return 0;\n }\n return 100 - index;\n}\n"],"names":[],"mappings":"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"}
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { formatHumanName } from '@medplum/core';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
function HumanNameDisplay(props) {
|
|
5
|
+
const name = props.value;
|
|
6
|
+
if (!name) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
return React.createElement(React.Fragment, null, formatHumanName(name, props.options));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { HumanNameDisplay };
|
|
13
|
+
//# sourceMappingURL=HumanNameDisplay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HumanNameDisplay.js","sources":["../../src/HumanNameDisplay.tsx"],"sourcesContent":["import { formatHumanName, HumanNameFormatOptions } from '@medplum/core';\nimport { HumanName } from '@medplum/fhirtypes';\nimport React from 'react';\n\nexport interface HumanNameDisplayProps {\n value?: HumanName;\n options?: HumanNameFormatOptions;\n}\n\nexport function HumanNameDisplay(props: HumanNameDisplayProps): JSX.Element | null {\n const name = props.value;\n if (!name) {\n return null;\n }\n\n return <>{formatHumanName(name, props.options)}</>;\n}\n"],"names":[],"mappings":";;;AASM,SAAU,gBAAgB,CAAC,KAA4B,EAAA;AAC3D,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;IACzB,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;IAED,OAAO,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAI,CAAC;AACrD;;;;"}
|
|
File without changes
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React, { useState, useRef } from 'react';
|
|
2
|
+
import { Input } from './Input.js';
|
|
3
|
+
import { InputRow } from './InputRow.js';
|
|
4
|
+
import { Select } from './Select.js';
|
|
5
|
+
|
|
6
|
+
function HumanNameInput(props) {
|
|
7
|
+
var _a, _b, _c;
|
|
8
|
+
const [value, setValue] = useState(props.defaultValue);
|
|
9
|
+
const valueRef = useRef();
|
|
10
|
+
valueRef.current = value;
|
|
11
|
+
function setValueWrapper(newValue) {
|
|
12
|
+
setValue(newValue);
|
|
13
|
+
if (props.onChange) {
|
|
14
|
+
props.onChange(newValue);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function setUse(use) {
|
|
18
|
+
setValueWrapper(Object.assign(Object.assign({}, valueRef.current), { use: use ? use : undefined }));
|
|
19
|
+
}
|
|
20
|
+
function setPrefix(prefix) {
|
|
21
|
+
setValueWrapper(Object.assign(Object.assign({}, valueRef.current), { prefix: prefix ? prefix.split(' ') : undefined }));
|
|
22
|
+
}
|
|
23
|
+
function setGiven(given) {
|
|
24
|
+
setValueWrapper(Object.assign(Object.assign({}, valueRef.current), { given: given ? given.split(' ') : undefined }));
|
|
25
|
+
}
|
|
26
|
+
function setFamily(family) {
|
|
27
|
+
setValueWrapper(Object.assign(Object.assign({}, valueRef.current), { family: family ? family : undefined }));
|
|
28
|
+
}
|
|
29
|
+
function setSuffix(suffix) {
|
|
30
|
+
setValueWrapper(Object.assign(Object.assign({}, valueRef.current), { suffix: suffix ? suffix.split(' ') : undefined }));
|
|
31
|
+
}
|
|
32
|
+
return (React.createElement(InputRow, null,
|
|
33
|
+
React.createElement(Select, { defaultValue: value === null || value === void 0 ? void 0 : value.use, onChange: setUse, testid: "use" },
|
|
34
|
+
React.createElement("option", null),
|
|
35
|
+
React.createElement("option", null, "usual"),
|
|
36
|
+
React.createElement("option", null, "official"),
|
|
37
|
+
React.createElement("option", null, "temp"),
|
|
38
|
+
React.createElement("option", null, "nickname"),
|
|
39
|
+
React.createElement("option", null, "anonymous"),
|
|
40
|
+
React.createElement("option", null, "old"),
|
|
41
|
+
React.createElement("option", null, "maiden")),
|
|
42
|
+
React.createElement(Input, { placeholder: "Prefix", defaultValue: (_a = value === null || value === void 0 ? void 0 : value.prefix) === null || _a === void 0 ? void 0 : _a.join(' '), onChange: setPrefix }),
|
|
43
|
+
React.createElement(Input, { placeholder: "Given", defaultValue: (_b = value === null || value === void 0 ? void 0 : value.given) === null || _b === void 0 ? void 0 : _b.join(' '), onChange: setGiven }),
|
|
44
|
+
React.createElement(Input, { placeholder: "Family", defaultValue: value === null || value === void 0 ? void 0 : value.family, onChange: setFamily }),
|
|
45
|
+
React.createElement(Input, { placeholder: "Suffix", defaultValue: (_c = value === null || value === void 0 ? void 0 : value.suffix) === null || _c === void 0 ? void 0 : _c.join(' '), onChange: setSuffix })));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { HumanNameInput };
|
|
49
|
+
//# sourceMappingURL=HumanNameInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HumanNameInput.js","sources":["../../src/HumanNameInput.tsx"],"sourcesContent":["import { HumanName } from '@medplum/fhirtypes';\nimport React, { useRef, useState } from 'react';\nimport { Input } from './Input';\nimport { InputRow } from './InputRow';\nimport { Select } from './Select';\n\nexport interface HumanNameInputProps {\n name: string;\n defaultValue?: HumanName;\n onChange?: (value: HumanName) => void;\n}\n\nexport function HumanNameInput(props: HumanNameInputProps): JSX.Element {\n const [value, setValue] = useState<HumanName | undefined>(props.defaultValue);\n\n const valueRef = useRef<HumanName>();\n valueRef.current = value;\n\n function setValueWrapper(newValue: HumanName): void {\n setValue(newValue);\n if (props.onChange) {\n props.onChange(newValue);\n }\n }\n\n function setUse(use: string): void {\n setValueWrapper({ ...valueRef.current, use: use ? use : undefined });\n }\n\n function setPrefix(prefix: string): void {\n setValueWrapper({\n ...valueRef.current,\n prefix: prefix ? prefix.split(' ') : undefined,\n });\n }\n\n function setGiven(given: string): void {\n setValueWrapper({\n ...valueRef.current,\n given: given ? given.split(' ') : undefined,\n });\n }\n\n function setFamily(family: string): void {\n setValueWrapper({\n ...valueRef.current,\n family: family ? family : undefined,\n });\n }\n\n function setSuffix(suffix: string): void {\n setValueWrapper({\n ...valueRef.current,\n suffix: suffix ? suffix.split(' ') : undefined,\n });\n }\n\n return (\n <InputRow>\n <Select defaultValue={value?.use} onChange={setUse} testid=\"use\">\n <option></option>\n <option>usual</option>\n <option>official</option>\n <option>temp</option>\n <option>nickname</option>\n <option>anonymous</option>\n <option>old</option>\n <option>maiden</option>\n </Select>\n <Input placeholder=\"Prefix\" defaultValue={value?.prefix?.join(' ')} onChange={setPrefix} />\n <Input placeholder=\"Given\" defaultValue={value?.given?.join(' ')} onChange={setGiven} />\n <Input placeholder=\"Family\" defaultValue={value?.family} onChange={setFamily} />\n <Input placeholder=\"Suffix\" defaultValue={value?.suffix?.join(' ')} onChange={setSuffix} />\n </InputRow>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
function IdentifierDisplay(props) {
|
|
4
|
+
var _a, _b;
|
|
5
|
+
return (React.createElement("div", null, (_a = props.value) === null || _a === void 0 ? void 0 :
|
|
6
|
+
_a.system,
|
|
7
|
+
": ", (_b = props.value) === null || _b === void 0 ? void 0 :
|
|
8
|
+
_b.value));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { IdentifierDisplay };
|
|
12
|
+
//# sourceMappingURL=IdentifierDisplay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IdentifierDisplay.js","sources":["../../src/IdentifierDisplay.tsx"],"sourcesContent":["import { Identifier } from '@medplum/fhirtypes';\nimport React from 'react';\n\nexport interface IdentifierDisplayProps {\n value?: Identifier;\n}\n\nexport function IdentifierDisplay(props: IdentifierDisplayProps): JSX.Element {\n return (\n <div>\n {props.value?.system}: {props.value?.value}\n </div>\n );\n}\n"],"names":[],"mappings":";;AAOM,SAAU,iBAAiB,CAAC,KAA6B,EAAA;;AAC7D,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA,EACG,CAAA,EAAA,GAAA,KAAK,CAAC,KAAK,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA;WAAE,MAAM;cAAI,CAAA,EAAA,GAAA,KAAK,CAAC,KAAK,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA;WAAE,KAAK,CACtC,EACN;AACJ;;;;"}
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Input } from './Input.js';
|
|
3
|
+
import { InputRow } from './InputRow.js';
|
|
4
|
+
|
|
5
|
+
function IdentifierInput(props) {
|
|
6
|
+
const [value, setValue] = useState(props.defaultValue);
|
|
7
|
+
function setValueWrapper(newValue) {
|
|
8
|
+
setValue(newValue);
|
|
9
|
+
if (props.onChange) {
|
|
10
|
+
props.onChange(newValue);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return (React.createElement(InputRow, null,
|
|
14
|
+
React.createElement(Input, { placeholder: "System", defaultValue: value === null || value === void 0 ? void 0 : value.system, onChange: (newValue) => setValueWrapper(Object.assign(Object.assign({}, value), { system: newValue })) }),
|
|
15
|
+
React.createElement(Input, { placeholder: "Value", defaultValue: value === null || value === void 0 ? void 0 : value.value, onChange: (newValue) => setValueWrapper(Object.assign(Object.assign({}, value), { value: newValue })) })));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { IdentifierInput };
|
|
19
|
+
//# sourceMappingURL=IdentifierInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IdentifierInput.js","sources":["../../src/IdentifierInput.tsx"],"sourcesContent":["import { Identifier } from '@medplum/fhirtypes';\nimport React, { useState } from 'react';\nimport { Input } from './Input';\nimport { InputRow } from './InputRow';\n\nexport interface IdentifierInputProps {\n name: string;\n defaultValue?: Identifier;\n onChange?: (value: Identifier) => void;\n}\n\nexport function IdentifierInput(props: IdentifierInputProps): JSX.Element {\n const [value, setValue] = useState(props.defaultValue);\n\n function setValueWrapper(newValue: Identifier): void {\n setValue(newValue);\n if (props.onChange) {\n props.onChange(newValue);\n }\n }\n\n return (\n <InputRow>\n <Input\n placeholder=\"System\"\n defaultValue={value?.system}\n onChange={(newValue) => setValueWrapper({ ...value, system: newValue })}\n />\n <Input\n placeholder=\"Value\"\n defaultValue={value?.value}\n onChange={(newValue) => setValueWrapper({ ...value, value: newValue })}\n />\n </InputRow>\n );\n}\n"],"names":[],"mappings":";;;;AAWM,SAAU,eAAe,CAAC,KAA2B,EAAA;AACzD,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAEvD,SAAS,eAAe,CAAC,QAAoB,EAAA;QAC3C,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnB,IAAI,KAAK,CAAC,QAAQ,EAAE;AAClB,YAAA,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC1B,SAAA;KACF;IAED,QACE,oBAAC,QAAQ,EAAA,IAAA;AACP,QAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAA,EACJ,WAAW,EAAC,QAAQ,EACpB,YAAY,EAAE,KAAK,KAAA,IAAA,IAAL,KAAK,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAL,KAAK,CAAE,MAAM,EAC3B,QAAQ,EAAE,CAAC,QAAQ,KAAK,eAAe,CAAM,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,KAAK,CAAE,EAAA,EAAA,MAAM,EAAE,QAAQ,IAAG,EACvE,CAAA;AACF,QAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAA,EACJ,WAAW,EAAC,OAAO,EACnB,YAAY,EAAE,KAAK,aAAL,KAAK,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAL,KAAK,CAAE,KAAK,EAC1B,QAAQ,EAAE,CAAC,QAAQ,KAAK,eAAe,CAAM,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,KAAK,CAAE,EAAA,EAAA,KAAK,EAAE,QAAQ,EAAA,CAAA,CAAG,EACtE,CAAA,CACO,EACX;AACJ;;;;"}
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { getIssuesForExpression } from './utils/outcomes.js';
|
|
3
|
+
|
|
4
|
+
function Input(props) {
|
|
5
|
+
const className = 'medplum-input';
|
|
6
|
+
const issues = getIssuesForExpression(props.outcome, props.name);
|
|
7
|
+
const invalid = issues && issues.length > 0;
|
|
8
|
+
return (React.createElement("input", { id: props.name, name: props.name, type: getInputType(props.type), size: props.size, step: props.step, className: className, style: props.style, defaultValue: props.defaultValue || '', required: props.required, autoCapitalize: props.autoCapitalize, autoComplete: props.autoComplete, autoFocus: props.autoFocus, ref: props.inputRef, "aria-invalid": invalid, "aria-describedby": invalid ? props.name + '-errors' : '', placeholder: props.placeholder, "data-testid": props.testid, disabled: props.disabled, onChange: (e) => {
|
|
9
|
+
if (props.onChange) {
|
|
10
|
+
props.onChange(e.currentTarget.value);
|
|
11
|
+
}
|
|
12
|
+
} }));
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Returns the input type for the requested type.
|
|
16
|
+
* JSDOM does not support many of the valid <input> type attributes.
|
|
17
|
+
* For example, it won't fire change events for <input type="datetime-local">.
|
|
18
|
+
* @param requestedType The optional type as requested by the parent component.
|
|
19
|
+
*/
|
|
20
|
+
function getInputType(requestedType) {
|
|
21
|
+
const result = requestedType || 'text';
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { Input };
|
|
26
|
+
//# sourceMappingURL=Input.js.map
|