@medplum/react 1.0.4 → 1.0.6
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/README.md +2 -1
- package/dist/cjs/AsyncAutocomplete/AsyncAutocomplete.d.ts +14 -0
- package/dist/cjs/DiagnosticReportDisplay/DiagnosticReportDisplay.stories.d.ts +1 -0
- package/dist/cjs/FhirPathTable/FhirPathTable.d.ts +2 -2
- package/dist/cjs/MoneyDisplay/MoneyDisplay.d.ts +6 -0
- package/dist/cjs/MoneyInput/MoneyInput.d.ts +10 -0
- package/dist/cjs/MoneyInput/MoneyInput.stories.d.ts +6 -0
- package/dist/cjs/ValueSetAutocomplete/ValueSetAutocomplete.d.ts +3 -6
- package/dist/cjs/auth/ChooseProfileForm.d.ts +2 -1
- package/dist/cjs/auth/ChooseScopeForm.d.ts +2 -1
- package/dist/cjs/auth/MfaForm.d.ts +7 -0
- package/dist/cjs/auth/SignInForm.d.ts +10 -0
- package/dist/cjs/{index.js → index.cjs} +860 -642
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.min.cjs +1 -0
- package/dist/cjs/stories/referenceLab.d.ts +3 -1
- package/dist/esm/AddressDisplay/{AddressDisplay.js → AddressDisplay.mjs} +1 -1
- package/dist/esm/AddressDisplay/AddressDisplay.mjs.map +1 -0
- package/dist/esm/AddressInput/{AddressInput.js → AddressInput.mjs} +9 -9
- package/dist/esm/AddressInput/AddressInput.mjs.map +1 -0
- package/dist/esm/AnnotationInput/{AnnotationInput.js → AnnotationInput.mjs} +2 -2
- package/dist/esm/AnnotationInput/AnnotationInput.mjs.map +1 -0
- package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.d.ts +14 -0
- package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.mjs +113 -0
- package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.mjs.map +1 -0
- package/dist/esm/AttachmentArrayDisplay/{AttachmentArrayDisplay.js → AttachmentArrayDisplay.mjs} +2 -2
- package/dist/esm/AttachmentArrayDisplay/AttachmentArrayDisplay.mjs.map +1 -0
- package/dist/esm/AttachmentArrayInput/{AttachmentArrayInput.js → AttachmentArrayInput.mjs} +6 -7
- package/dist/esm/AttachmentArrayInput/AttachmentArrayInput.mjs.map +1 -0
- package/dist/esm/AttachmentButton/{AttachmentButton.js → AttachmentButton.mjs} +5 -7
- package/dist/esm/AttachmentButton/AttachmentButton.mjs.map +1 -0
- package/dist/esm/AttachmentDisplay/AttachmentDisplay.mjs +21 -0
- package/dist/esm/AttachmentDisplay/AttachmentDisplay.mjs.map +1 -0
- package/dist/esm/AttachmentInput/{AttachmentInput.js → AttachmentInput.mjs} +5 -5
- package/dist/esm/AttachmentInput/AttachmentInput.mjs.map +1 -0
- package/dist/esm/BackboneElementDisplay/{BackboneElementDisplay.js → BackboneElementDisplay.mjs} +4 -4
- package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.mjs.map +1 -0
- package/dist/esm/BackboneElementInput/{BackboneElementInput.js → BackboneElementInput.mjs} +10 -11
- package/dist/esm/BackboneElementInput/BackboneElementInput.mjs.map +1 -0
- package/dist/esm/CalendarInput/{CalendarInput.js → CalendarInput.mjs} +1 -1
- package/dist/esm/CalendarInput/CalendarInput.mjs.map +1 -0
- package/dist/esm/CheckboxFormSection/{CheckboxFormSection.js → CheckboxFormSection.mjs} +1 -1
- package/dist/esm/CheckboxFormSection/CheckboxFormSection.mjs.map +1 -0
- package/dist/esm/CodeInput/{CodeInput.js → CodeInput.mjs} +6 -5
- package/dist/esm/CodeInput/CodeInput.mjs.map +1 -0
- package/dist/esm/CodeableConceptDisplay/{CodeableConceptDisplay.js → CodeableConceptDisplay.mjs} +1 -1
- package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.mjs.map +1 -0
- package/dist/esm/CodeableConceptInput/CodeableConceptInput.mjs +36 -0
- package/dist/esm/CodeableConceptInput/CodeableConceptInput.mjs.map +1 -0
- package/dist/esm/CodingDisplay/{CodingDisplay.js → CodingDisplay.mjs} +1 -1
- package/dist/esm/CodingDisplay/CodingDisplay.mjs.map +1 -0
- package/dist/esm/CodingInput/{CodingInput.js → CodingInput.mjs} +5 -4
- package/dist/esm/CodingInput/CodingInput.mjs.map +1 -0
- package/dist/esm/ContactDetailDisplay/{ContactDetailDisplay.js → ContactDetailDisplay.mjs} +4 -5
- package/dist/esm/ContactDetailDisplay/ContactDetailDisplay.mjs.map +1 -0
- package/dist/esm/ContactDetailInput/{ContactDetailInput.js → ContactDetailInput.mjs} +6 -7
- package/dist/esm/ContactDetailInput/ContactDetailInput.mjs.map +1 -0
- package/dist/esm/ContactPointDisplay/{ContactPointDisplay.js → ContactPointDisplay.mjs} +1 -1
- package/dist/esm/ContactPointDisplay/ContactPointDisplay.mjs.map +1 -0
- package/dist/esm/ContactPointInput/{ContactPointInput.js → ContactPointInput.mjs} +7 -7
- package/dist/esm/ContactPointInput/ContactPointInput.mjs.map +1 -0
- package/dist/esm/Container/{Container.js → Container.mjs} +3 -4
- package/dist/esm/Container/Container.mjs.map +1 -0
- package/dist/esm/DateTimeInput/{DateTimeInput.js → DateTimeInput.mjs} +2 -2
- package/dist/esm/DateTimeInput/DateTimeInput.mjs.map +1 -0
- package/dist/esm/DefaultResourceTimeline/{DefaultResourceTimeline.js → DefaultResourceTimeline.mjs} +2 -2
- package/dist/esm/DefaultResourceTimeline/DefaultResourceTimeline.mjs.map +1 -0
- package/dist/esm/DescriptionList/{DescriptionList.js → DescriptionList.mjs} +1 -1
- package/dist/esm/DescriptionList/DescriptionList.mjs.map +1 -0
- package/dist/esm/DiagnosticReportDisplay/{DiagnosticReportDisplay.js → DiagnosticReportDisplay.mjs} +19 -16
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.mjs.map +1 -0
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.stories.d.ts +1 -0
- package/dist/esm/Document/Document.mjs +12 -0
- package/dist/esm/Document/Document.mjs.map +1 -0
- package/dist/esm/EncounterTimeline/{EncounterTimeline.js → EncounterTimeline.mjs} +2 -2
- package/dist/esm/EncounterTimeline/EncounterTimeline.mjs.map +1 -0
- package/dist/esm/ErrorBoundary/{ErrorBoundary.js → ErrorBoundary.mjs} +1 -1
- package/dist/esm/ErrorBoundary/ErrorBoundary.mjs.map +1 -0
- package/dist/esm/ExtensionInput/{ExtensionInput.js → ExtensionInput.mjs} +1 -1
- package/dist/esm/ExtensionInput/ExtensionInput.mjs.map +1 -0
- package/dist/esm/FhirPathDisplay/{FhirPathDisplay.js → FhirPathDisplay.mjs} +2 -2
- package/dist/esm/FhirPathDisplay/FhirPathDisplay.mjs.map +1 -0
- package/dist/esm/FhirPathTable/FhirPathTable.d.ts +2 -2
- package/dist/esm/FhirPathTable/{FhirPathTable.js → FhirPathTable.mjs} +14 -17
- package/dist/esm/FhirPathTable/FhirPathTable.mjs.map +1 -0
- package/dist/esm/Form/{Form.js → Form.mjs} +2 -2
- package/dist/esm/Form/Form.mjs.map +1 -0
- package/dist/esm/Form/{FormUtils.js → FormUtils.mjs} +1 -1
- package/dist/esm/Form/FormUtils.mjs.map +1 -0
- package/dist/esm/FormSection/{FormSection.js → FormSection.mjs} +2 -2
- package/dist/esm/FormSection/FormSection.mjs.map +1 -0
- package/dist/esm/GoogleButton/{GoogleButton.js → GoogleButton.mjs} +4 -5
- package/dist/esm/GoogleButton/GoogleButton.mjs.map +1 -0
- package/dist/esm/HumanNameDisplay/{HumanNameDisplay.js → HumanNameDisplay.mjs} +1 -1
- package/dist/esm/HumanNameDisplay/HumanNameDisplay.mjs.map +1 -0
- package/dist/esm/HumanNameInput/HumanNameInput.mjs +50 -0
- package/dist/esm/HumanNameInput/HumanNameInput.mjs.map +1 -0
- package/dist/esm/IdentifierDisplay/IdentifierDisplay.mjs +11 -0
- package/dist/esm/IdentifierDisplay/IdentifierDisplay.mjs.map +1 -0
- package/dist/esm/IdentifierInput/{IdentifierInput.js → IdentifierInput.mjs} +3 -3
- package/dist/esm/IdentifierInput/IdentifierInput.mjs.map +1 -0
- package/dist/esm/Logo/{Logo.js → Logo.mjs} +1 -1
- package/dist/esm/Logo/Logo.mjs.map +1 -0
- package/dist/esm/MedplumLink/{MedplumLink.js → MedplumLink.mjs} +5 -6
- package/dist/esm/MedplumLink/MedplumLink.mjs.map +1 -0
- package/dist/esm/MedplumProvider/{MedplumProvider.js → MedplumProvider.mjs} +9 -3
- package/dist/esm/MedplumProvider/MedplumProvider.mjs.map +1 -0
- package/dist/esm/MoneyDisplay/MoneyDisplay.d.ts +6 -0
- package/dist/esm/MoneyDisplay/MoneyDisplay.mjs +9 -0
- package/dist/esm/MoneyDisplay/MoneyDisplay.mjs.map +1 -0
- package/dist/esm/MoneyInput/MoneyInput.d.ts +10 -0
- package/dist/esm/MoneyInput/MoneyInput.mjs +53 -0
- package/dist/esm/MoneyInput/MoneyInput.mjs.map +1 -0
- package/dist/esm/MoneyInput/MoneyInput.stories.d.ts +6 -0
- package/dist/esm/Panel/{Panel.js → Panel.mjs} +3 -4
- package/dist/esm/Panel/Panel.mjs.map +1 -0
- package/dist/esm/PatientTimeline/{PatientTimeline.js → PatientTimeline.mjs} +2 -2
- package/dist/esm/PatientTimeline/PatientTimeline.mjs.map +1 -0
- package/dist/esm/PeriodInput/{PeriodInput.js → PeriodInput.mjs} +4 -4
- package/dist/esm/PeriodInput/PeriodInput.mjs.map +1 -0
- package/dist/esm/PlanDefinitionBuilder/{PlanDefinitionBuilder.js → PlanDefinitionBuilder.mjs} +36 -24
- package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.mjs.map +1 -0
- package/dist/esm/QuantityDisplay/{QuantityDisplay.js → QuantityDisplay.mjs} +1 -1
- package/dist/esm/QuantityDisplay/QuantityDisplay.mjs.map +1 -0
- package/dist/esm/QuantityInput/{QuantityInput.js → QuantityInput.mjs} +13 -5
- package/dist/esm/QuantityInput/QuantityInput.mjs.map +1 -0
- package/dist/esm/QuestionnaireBuilder/{QuestionnaireBuilder.js → QuestionnaireBuilder.mjs} +45 -27
- package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.mjs.map +1 -0
- package/dist/esm/QuestionnaireForm/{QuestionnaireForm.js → QuestionnaireForm.mjs} +37 -36
- package/dist/esm/QuestionnaireForm/QuestionnaireForm.mjs.map +1 -0
- package/dist/esm/RangeDisplay/{RangeDisplay.js → RangeDisplay.mjs} +1 -1
- package/dist/esm/RangeDisplay/RangeDisplay.mjs.map +1 -0
- package/dist/esm/RangeInput/{RangeInput.js → RangeInput.mjs} +10 -4
- package/dist/esm/RangeInput/RangeInput.mjs.map +1 -0
- package/dist/esm/RatioDisplay/{RatioDisplay.js → RatioDisplay.mjs} +2 -2
- package/dist/esm/RatioDisplay/RatioDisplay.mjs.map +1 -0
- package/dist/esm/RatioInput/{RatioInput.js → RatioInput.mjs} +10 -4
- package/dist/esm/RatioInput/RatioInput.mjs.map +1 -0
- package/dist/esm/ReferenceDisplay/{ReferenceDisplay.js → ReferenceDisplay.mjs} +2 -2
- package/dist/esm/ReferenceDisplay/ReferenceDisplay.mjs.map +1 -0
- package/dist/esm/ReferenceInput/{ReferenceInput.js → ReferenceInput.mjs} +10 -5
- package/dist/esm/ReferenceInput/ReferenceInput.mjs.map +1 -0
- package/dist/esm/ReferenceRangeEditor/{ReferenceRangeEditor.js → ReferenceRangeEditor.mjs} +44 -38
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.mjs.map +1 -0
- package/dist/esm/RequestGroupDisplay/{RequestGroupDisplay.js → RequestGroupDisplay.mjs} +14 -17
- package/dist/esm/RequestGroupDisplay/RequestGroupDisplay.mjs.map +1 -0
- package/dist/esm/ResourceArrayDisplay/{ResourceArrayDisplay.js → ResourceArrayDisplay.mjs} +4 -5
- package/dist/esm/ResourceArrayDisplay/ResourceArrayDisplay.mjs.map +1 -0
- package/dist/esm/ResourceArrayInput/{ResourceArrayInput.js → ResourceArrayInput.mjs} +3 -3
- package/dist/esm/ResourceArrayInput/ResourceArrayInput.mjs.map +1 -0
- package/dist/esm/ResourceAvatar/ResourceAvatar.mjs +23 -0
- package/dist/esm/ResourceAvatar/ResourceAvatar.mjs.map +1 -0
- package/dist/esm/ResourceBadge/{ResourceBadge.js → ResourceBadge.mjs} +3 -3
- package/dist/esm/ResourceBadge/ResourceBadge.mjs.map +1 -0
- package/dist/esm/ResourceBlame/{ResourceBlame.js → ResourceBlame.mjs} +6 -7
- package/dist/esm/ResourceBlame/ResourceBlame.mjs.map +1 -0
- package/dist/esm/ResourceDiff/{ResourceDiff.js → ResourceDiff.mjs} +4 -4
- package/dist/esm/ResourceDiff/ResourceDiff.mjs.map +1 -0
- package/dist/esm/ResourceDiffTable/{ResourceDiffTable.js → ResourceDiffTable.mjs} +3 -3
- package/dist/esm/ResourceDiffTable/ResourceDiffTable.mjs.map +1 -0
- package/dist/esm/ResourceForm/{ResourceForm.js → ResourceForm.mjs} +5 -5
- package/dist/esm/ResourceForm/ResourceForm.mjs.map +1 -0
- package/dist/esm/ResourceHistoryTable/{ResourceHistoryTable.js → ResourceHistoryTable.mjs} +10 -13
- package/dist/esm/ResourceHistoryTable/ResourceHistoryTable.mjs.map +1 -0
- package/dist/esm/ResourceInput/{ResourceInput.js → ResourceInput.mjs} +19 -25
- package/dist/esm/ResourceInput/ResourceInput.mjs.map +1 -0
- package/dist/esm/ResourceName/ResourceName.mjs +18 -0
- package/dist/esm/ResourceName/ResourceName.mjs.map +1 -0
- package/dist/esm/ResourcePropertyDisplay/{ResourcePropertyDisplay.js → ResourcePropertyDisplay.mjs} +23 -21
- package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.mjs.map +1 -0
- package/dist/esm/ResourcePropertyInput/{ResourcePropertyInput.js → ResourcePropertyInput.mjs} +34 -34
- package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.mjs.map +1 -0
- package/dist/esm/ResourceTable/{ResourceTable.js → ResourceTable.mjs} +4 -4
- package/dist/esm/ResourceTable/ResourceTable.mjs.map +1 -0
- package/dist/esm/ResourceTimeline/{ResourceTimeline.js → ResourceTimeline.mjs} +26 -30
- package/dist/esm/ResourceTimeline/ResourceTimeline.mjs.map +1 -0
- package/dist/esm/Scheduler/{Scheduler.js → Scheduler.mjs} +8 -9
- package/dist/esm/Scheduler/Scheduler.mjs.map +1 -0
- package/dist/esm/SearchControl/{SearchControl.js → SearchControl.mjs} +66 -50
- package/dist/esm/SearchControl/SearchControl.mjs.map +1 -0
- package/dist/esm/SearchControl/{SearchControlField.js → SearchControlField.mjs} +3 -4
- package/dist/esm/SearchControl/SearchControlField.mjs.map +1 -0
- package/dist/esm/SearchControl/{SearchUtils.js → SearchUtils.mjs} +34 -17
- package/dist/esm/SearchControl/SearchUtils.mjs.map +1 -0
- package/dist/esm/SearchFieldEditor/{SearchFieldEditor.js → SearchFieldEditor.mjs} +28 -21
- package/dist/esm/SearchFieldEditor/SearchFieldEditor.mjs.map +1 -0
- package/dist/esm/SearchFilterEditor/{SearchFilterEditor.js → SearchFilterEditor.mjs} +8 -9
- package/dist/esm/SearchFilterEditor/SearchFilterEditor.mjs.map +1 -0
- package/dist/esm/SearchFilterValueDialog/{SearchFilterValueDialog.js → SearchFilterValueDialog.mjs} +5 -6
- package/dist/esm/SearchFilterValueDialog/SearchFilterValueDialog.mjs.map +1 -0
- package/dist/esm/SearchFilterValueDisplay/{SearchFilterValueDisplay.js → SearchFilterValueDisplay.mjs} +3 -4
- package/dist/esm/SearchFilterValueDisplay/SearchFilterValueDisplay.mjs.map +1 -0
- package/dist/esm/SearchFilterValueInput/{SearchFilterValueInput.js → SearchFilterValueInput.mjs} +5 -6
- package/dist/esm/SearchFilterValueInput/SearchFilterValueInput.mjs.map +1 -0
- package/dist/esm/SearchPopupMenu/{SearchPopupMenu.js → SearchPopupMenu.mjs} +10 -10
- package/dist/esm/SearchPopupMenu/SearchPopupMenu.mjs.map +1 -0
- package/dist/esm/ServiceRequestTimeline/{ServiceRequestTimeline.js → ServiceRequestTimeline.mjs} +2 -2
- package/dist/esm/ServiceRequestTimeline/ServiceRequestTimeline.mjs.map +1 -0
- package/dist/esm/StatusBadge/{StatusBadge.js → StatusBadge.mjs} +3 -2
- package/dist/esm/StatusBadge/StatusBadge.mjs.map +1 -0
- package/dist/esm/Timeline/{Timeline.js → Timeline.mjs} +11 -13
- package/dist/esm/Timeline/Timeline.mjs.map +1 -0
- package/dist/esm/TimingInput/{TimingInput.js → TimingInput.mjs} +13 -18
- package/dist/esm/TimingInput/TimingInput.mjs.map +1 -0
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.d.ts +3 -6
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.mjs +43 -0
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.mjs.map +1 -0
- package/dist/esm/auth/{AuthenticationForm.js → AuthenticationForm.mjs} +21 -19
- package/dist/esm/auth/AuthenticationForm.mjs.map +1 -0
- package/dist/esm/auth/ChooseProfileForm.d.ts +2 -1
- package/dist/esm/auth/ChooseProfileForm.mjs +29 -0
- package/dist/esm/auth/ChooseProfileForm.mjs.map +1 -0
- package/dist/esm/auth/ChooseScopeForm.d.ts +2 -1
- package/dist/esm/auth/{ChooseScopeForm.js → ChooseScopeForm.mjs} +4 -4
- package/dist/esm/auth/ChooseScopeForm.mjs.map +1 -0
- package/dist/esm/auth/MfaForm.d.ts +7 -0
- package/dist/esm/auth/MfaForm.mjs +34 -0
- package/dist/esm/auth/MfaForm.mjs.map +1 -0
- package/dist/esm/auth/{NewProjectForm.js → NewProjectForm.mjs} +8 -9
- package/dist/esm/auth/NewProjectForm.mjs.map +1 -0
- package/dist/esm/auth/{NewUserForm.js → NewUserForm.mjs} +15 -19
- package/dist/esm/auth/NewUserForm.mjs.map +1 -0
- package/dist/esm/auth/{RegisterForm.js → RegisterForm.mjs} +5 -5
- package/dist/esm/auth/RegisterForm.mjs.map +1 -0
- package/dist/esm/auth/SignInForm.d.ts +10 -0
- package/dist/esm/auth/{SignInForm.js → SignInForm.mjs} +25 -10
- package/dist/esm/auth/SignInForm.mjs.map +1 -0
- package/dist/esm/{constants.js → constants.mjs} +1 -1
- package/dist/esm/constants.mjs.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.min.mjs +1 -0
- package/dist/esm/{index.js → index.mjs} +88 -85
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/stories/referenceLab.d.ts +3 -1
- package/dist/esm/useResource/{useResource.js → useResource.mjs} +2 -2
- package/dist/esm/useResource/useResource.mjs.map +1 -0
- package/dist/esm/utils/{blame.js → blame.mjs} +6 -9
- package/dist/esm/utils/blame.mjs.map +1 -0
- package/dist/esm/utils/{date.js → date.mjs} +2 -3
- package/dist/esm/utils/date.mjs.map +1 -0
- package/dist/esm/utils/{diff.js → diff.mjs} +1 -1
- package/dist/esm/utils/diff.mjs.map +1 -0
- package/dist/esm/utils/{dom.js → dom.mjs} +1 -1
- package/dist/esm/utils/dom.mjs.map +1 -0
- package/dist/esm/utils/outcomes.mjs +30 -0
- package/dist/esm/utils/outcomes.mjs.map +1 -0
- package/dist/esm/utils/{questionnaire.js → questionnaire.mjs} +1 -1
- package/dist/esm/utils/questionnaire.mjs.map +1 -0
- package/dist/esm/utils/{recaptcha.js → recaptcha.mjs} +5 -6
- package/dist/esm/utils/recaptcha.mjs.map +1 -0
- package/dist/esm/utils/{script.js → script.mjs} +1 -1
- package/dist/esm/utils/script.mjs.map +1 -0
- package/package.json +22 -22
- package/rollup.config.mjs +6 -7
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/index.min.js +0 -2
- package/dist/cjs/index.min.js.map +0 -1
- package/dist/esm/AddressDisplay/AddressDisplay.js.map +0 -1
- package/dist/esm/AddressInput/AddressInput.js.map +0 -1
- package/dist/esm/AnnotationInput/AnnotationInput.js.map +0 -1
- package/dist/esm/AttachmentArrayDisplay/AttachmentArrayDisplay.js.map +0 -1
- package/dist/esm/AttachmentArrayInput/AttachmentArrayInput.js.map +0 -1
- package/dist/esm/AttachmentButton/AttachmentButton.js.map +0 -1
- package/dist/esm/AttachmentDisplay/AttachmentDisplay.js +0 -21
- package/dist/esm/AttachmentDisplay/AttachmentDisplay.js.map +0 -1
- package/dist/esm/AttachmentInput/AttachmentInput.js.map +0 -1
- package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.js.map +0 -1
- package/dist/esm/BackboneElementInput/BackboneElementInput.js.map +0 -1
- package/dist/esm/CalendarInput/CalendarInput.js.map +0 -1
- package/dist/esm/CheckboxFormSection/CheckboxFormSection.js.map +0 -1
- package/dist/esm/CodeInput/CodeInput.js.map +0 -1
- package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.js.map +0 -1
- package/dist/esm/CodeableConceptInput/CodeableConceptInput.js +0 -37
- package/dist/esm/CodeableConceptInput/CodeableConceptInput.js.map +0 -1
- package/dist/esm/CodingDisplay/CodingDisplay.js.map +0 -1
- package/dist/esm/CodingInput/CodingInput.js.map +0 -1
- package/dist/esm/ContactDetailDisplay/ContactDetailDisplay.js.map +0 -1
- package/dist/esm/ContactDetailInput/ContactDetailInput.js.map +0 -1
- package/dist/esm/ContactPointDisplay/ContactPointDisplay.js.map +0 -1
- package/dist/esm/ContactPointInput/ContactPointInput.js.map +0 -1
- package/dist/esm/Container/Container.js.map +0 -1
- package/dist/esm/DateTimeInput/DateTimeInput.js.map +0 -1
- package/dist/esm/DefaultResourceTimeline/DefaultResourceTimeline.js.map +0 -1
- package/dist/esm/DescriptionList/DescriptionList.js.map +0 -1
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.js.map +0 -1
- package/dist/esm/Document/Document.js +0 -13
- package/dist/esm/Document/Document.js.map +0 -1
- package/dist/esm/EncounterTimeline/EncounterTimeline.js.map +0 -1
- package/dist/esm/ErrorBoundary/ErrorBoundary.js.map +0 -1
- package/dist/esm/ExtensionInput/ExtensionInput.js.map +0 -1
- package/dist/esm/FhirPathDisplay/FhirPathDisplay.js.map +0 -1
- package/dist/esm/FhirPathTable/FhirPathTable.js.map +0 -1
- package/dist/esm/Form/Form.js.map +0 -1
- package/dist/esm/Form/FormUtils.js.map +0 -1
- package/dist/esm/FormSection/FormSection.js.map +0 -1
- package/dist/esm/GoogleButton/GoogleButton.js.map +0 -1
- package/dist/esm/HumanNameDisplay/HumanNameDisplay.js.map +0 -1
- package/dist/esm/HumanNameInput/HumanNameInput.js +0 -39
- package/dist/esm/HumanNameInput/HumanNameInput.js.map +0 -1
- package/dist/esm/IdentifierDisplay/IdentifierDisplay.js +0 -12
- package/dist/esm/IdentifierDisplay/IdentifierDisplay.js.map +0 -1
- package/dist/esm/IdentifierInput/IdentifierInput.js.map +0 -1
- package/dist/esm/Logo/Logo.js.map +0 -1
- package/dist/esm/MedplumLink/MedplumLink.js.map +0 -1
- package/dist/esm/MedplumProvider/MedplumProvider.js.map +0 -1
- package/dist/esm/Panel/Panel.js.map +0 -1
- package/dist/esm/PatientTimeline/PatientTimeline.js.map +0 -1
- package/dist/esm/PeriodInput/PeriodInput.js.map +0 -1
- package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.js.map +0 -1
- package/dist/esm/QuantityDisplay/QuantityDisplay.js.map +0 -1
- package/dist/esm/QuantityInput/QuantityInput.js.map +0 -1
- package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.js.map +0 -1
- package/dist/esm/QuestionnaireForm/QuestionnaireForm.js.map +0 -1
- package/dist/esm/RangeDisplay/RangeDisplay.js.map +0 -1
- package/dist/esm/RangeInput/RangeInput.js.map +0 -1
- package/dist/esm/RatioDisplay/RatioDisplay.js.map +0 -1
- package/dist/esm/RatioInput/RatioInput.js.map +0 -1
- package/dist/esm/ReferenceDisplay/ReferenceDisplay.js.map +0 -1
- package/dist/esm/ReferenceInput/ReferenceInput.js.map +0 -1
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.js.map +0 -1
- package/dist/esm/RequestGroupDisplay/RequestGroupDisplay.js.map +0 -1
- package/dist/esm/ResourceArrayDisplay/ResourceArrayDisplay.js.map +0 -1
- package/dist/esm/ResourceArrayInput/ResourceArrayInput.js.map +0 -1
- package/dist/esm/ResourceAvatar/ResourceAvatar.js +0 -24
- package/dist/esm/ResourceAvatar/ResourceAvatar.js.map +0 -1
- package/dist/esm/ResourceBadge/ResourceBadge.js.map +0 -1
- package/dist/esm/ResourceBlame/ResourceBlame.js.map +0 -1
- package/dist/esm/ResourceDiff/ResourceDiff.js.map +0 -1
- package/dist/esm/ResourceDiffTable/ResourceDiffTable.js.map +0 -1
- package/dist/esm/ResourceForm/ResourceForm.js.map +0 -1
- package/dist/esm/ResourceHistoryTable/ResourceHistoryTable.js.map +0 -1
- package/dist/esm/ResourceInput/ResourceInput.js.map +0 -1
- package/dist/esm/ResourceName/ResourceName.js +0 -19
- package/dist/esm/ResourceName/ResourceName.js.map +0 -1
- package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.js.map +0 -1
- package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.js.map +0 -1
- package/dist/esm/ResourceTable/ResourceTable.js.map +0 -1
- package/dist/esm/ResourceTimeline/ResourceTimeline.js.map +0 -1
- package/dist/esm/Scheduler/Scheduler.js.map +0 -1
- package/dist/esm/SearchControl/SearchControl.js.map +0 -1
- package/dist/esm/SearchControl/SearchControlField.js.map +0 -1
- package/dist/esm/SearchControl/SearchUtils.js.map +0 -1
- package/dist/esm/SearchFieldEditor/SearchFieldEditor.js.map +0 -1
- package/dist/esm/SearchFilterEditor/SearchFilterEditor.js.map +0 -1
- package/dist/esm/SearchFilterValueDialog/SearchFilterValueDialog.js.map +0 -1
- package/dist/esm/SearchFilterValueDisplay/SearchFilterValueDisplay.js.map +0 -1
- package/dist/esm/SearchFilterValueInput/SearchFilterValueInput.js.map +0 -1
- package/dist/esm/SearchPopupMenu/SearchPopupMenu.js.map +0 -1
- package/dist/esm/ServiceRequestTimeline/ServiceRequestTimeline.js.map +0 -1
- package/dist/esm/StatusBadge/StatusBadge.js.map +0 -1
- package/dist/esm/Timeline/Timeline.js.map +0 -1
- package/dist/esm/TimingInput/TimingInput.js.map +0 -1
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.js +0 -65
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.js.map +0 -1
- package/dist/esm/auth/AuthenticationForm.js.map +0 -1
- package/dist/esm/auth/ChooseProfileForm.js +0 -32
- package/dist/esm/auth/ChooseProfileForm.js.map +0 -1
- package/dist/esm/auth/ChooseScopeForm.js.map +0 -1
- package/dist/esm/auth/NewProjectForm.js.map +0 -1
- package/dist/esm/auth/NewUserForm.js.map +0 -1
- package/dist/esm/auth/RegisterForm.js.map +0 -1
- package/dist/esm/auth/SignInForm.js.map +0 -1
- package/dist/esm/constants.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/index.min.js +0 -2
- package/dist/esm/index.min.js.map +0 -1
- package/dist/esm/node_modules/tslib/tslib.es6.js +0 -39
- package/dist/esm/node_modules/tslib/tslib.es6.js.map +0 -1
- package/dist/esm/useResource/useResource.js.map +0 -1
- package/dist/esm/utils/blame.js.map +0 -1
- package/dist/esm/utils/date.js.map +0 -1
- package/dist/esm/utils/diff.js.map +0 -1
- package/dist/esm/utils/dom.js.map +0 -1
- package/dist/esm/utils/outcomes.js +0 -29
- package/dist/esm/utils/outcomes.js.map +0 -1
- package/dist/esm/utils/questionnaire.js.map +0 -1
- package/dist/esm/utils/recaptcha.js.map +0 -1
- package/dist/esm/utils/script.js.map +0 -1
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
line.push('');
|
|
22
22
|
}
|
|
23
23
|
line[index] = str;
|
|
24
|
-
return
|
|
24
|
+
return { ...address, line };
|
|
25
25
|
}
|
|
26
26
|
function AddressInput(props) {
|
|
27
27
|
const [value, setValue] = React.useState(props.defaultValue || {});
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
function setUse(use) {
|
|
37
|
-
setValueWrapper(
|
|
37
|
+
setValueWrapper({ ...valueRef.current, use });
|
|
38
38
|
}
|
|
39
39
|
function setType(type) {
|
|
40
|
-
setValueWrapper(
|
|
40
|
+
setValueWrapper({ ...valueRef.current, type });
|
|
41
41
|
}
|
|
42
42
|
function setLine1(line1) {
|
|
43
43
|
setValueWrapper(setLine(valueRef.current || {}, 0, line1));
|
|
@@ -46,17 +46,17 @@
|
|
|
46
46
|
setValueWrapper(setLine(valueRef.current || {}, 1, line2));
|
|
47
47
|
}
|
|
48
48
|
function setCity(city) {
|
|
49
|
-
setValueWrapper(
|
|
49
|
+
setValueWrapper({ ...valueRef.current, city });
|
|
50
50
|
}
|
|
51
51
|
function setState(state) {
|
|
52
|
-
setValueWrapper(
|
|
52
|
+
setValueWrapper({ ...valueRef.current, state });
|
|
53
53
|
}
|
|
54
54
|
function setPostalCode(postalCode) {
|
|
55
|
-
setValueWrapper(
|
|
55
|
+
setValueWrapper({ ...valueRef.current, postalCode });
|
|
56
56
|
}
|
|
57
57
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
58
|
-
React.createElement(core$1.NativeSelect, { "data-testid": "address-use", defaultValue: value
|
|
59
|
-
React.createElement(core$1.NativeSelect, { "data-testid": "address-type", defaultValue: value
|
|
58
|
+
React.createElement(core$1.NativeSelect, { "data-testid": "address-use", defaultValue: value?.use, onChange: (e) => setUse(e.currentTarget.value), data: ['', 'home', 'work', 'temp', 'old', 'billing'] }),
|
|
59
|
+
React.createElement(core$1.NativeSelect, { "data-testid": "address-type", defaultValue: value?.type, onChange: (e) => setType(e.currentTarget.value), data: ['', 'postal', 'physical', 'both'] }),
|
|
60
60
|
React.createElement(core$1.TextInput, { placeholder: "Line 1", defaultValue: getLine(value, 0), onChange: (e) => setLine1(e.currentTarget.value) }),
|
|
61
61
|
React.createElement(core$1.TextInput, { placeholder: "Line 2", defaultValue: getLine(value, 1), onChange: (e) => setLine2(e.currentTarget.value) }),
|
|
62
62
|
React.createElement(core$1.TextInput, { placeholder: "City", defaultValue: value.city, onChange: (e) => setCity(e.currentTarget.value) }),
|
|
@@ -80,12 +80,18 @@
|
|
|
80
80
|
});
|
|
81
81
|
React.useEffect(() => {
|
|
82
82
|
function eventListener() {
|
|
83
|
-
setState(
|
|
83
|
+
setState({
|
|
84
|
+
...state,
|
|
85
|
+
profile: medplum.getProfile(),
|
|
86
|
+
});
|
|
84
87
|
}
|
|
85
88
|
medplum.addEventListener('change', eventListener);
|
|
86
89
|
return () => medplum.removeEventListeneer('change', eventListener);
|
|
87
90
|
}, [medplum, state]);
|
|
88
|
-
const medplumContext =
|
|
91
|
+
const medplumContext = {
|
|
92
|
+
...state,
|
|
93
|
+
medplum,
|
|
94
|
+
};
|
|
89
95
|
return React.createElement(reactContext.Provider, { value: medplumContext }, props.children);
|
|
90
96
|
}
|
|
91
97
|
/**
|
|
@@ -131,28 +137,6 @@
|
|
|
131
137
|
return (React.createElement(core$1.TextInput, { name: props.name, placeholder: "Annotation text", defaultValue: value.text, onChange: (e) => setText(e.currentTarget.value) }));
|
|
132
138
|
}
|
|
133
139
|
|
|
134
|
-
function AttachmentDisplay(props) {
|
|
135
|
-
const value = props.value;
|
|
136
|
-
const { contentType, url, title } = value !== null && value !== void 0 ? value : {};
|
|
137
|
-
if (!url) {
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
return (React.createElement("div", { "data-testid": "attachment-display" },
|
|
141
|
-
(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image/')) && (React.createElement("img", { "data-testid": "attachment-image", style: { maxWidth: props.maxWidth }, src: url, alt: value === null || value === void 0 ? void 0 : value.title })),
|
|
142
|
-
(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('video/')) && (React.createElement("video", { "data-testid": "attachment-video", style: { maxWidth: props.maxWidth }, controls: true },
|
|
143
|
-
React.createElement("source", { type: contentType, src: url }))),
|
|
144
|
-
contentType === 'application/pdf' && !(title === null || title === void 0 ? void 0 : title.endsWith('.pdf')) && (React.createElement("div", { "data-testid": "attachment-pdf", style: { maxWidth: props.maxWidth, minHeight: 400 } },
|
|
145
|
-
React.createElement("iframe", { width: "100%", height: "400", src: url + '#navpanes=0', allowFullScreen: true, frameBorder: 0, seamless: true }))),
|
|
146
|
-
React.createElement("div", { "data-testid": "download-link", style: { padding: '2px 16px 16px 16px' } },
|
|
147
|
-
React.createElement(core$1.Anchor, { href: value === null || value === void 0 ? void 0 : value.url, "data-testid": "attachment-details", target: "_blank", rel: "noopener noreferrer" }, (value === null || value === void 0 ? void 0 : value.title) || 'Download'))));
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function AttachmentArrayDisplay(props) {
|
|
151
|
-
return (React.createElement("div", null, props.values &&
|
|
152
|
-
props.values.map((v, index) => (React.createElement("div", { key: 'attatchment-' + index },
|
|
153
|
-
React.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
|
|
154
|
-
}
|
|
155
|
-
|
|
156
140
|
/**
|
|
157
141
|
* Kills a browser event.
|
|
158
142
|
* Prevents default behavior.
|
|
@@ -185,13 +169,141 @@
|
|
|
185
169
|
return el instanceof HTMLInputElement && el.type === 'checkbox';
|
|
186
170
|
}
|
|
187
171
|
|
|
172
|
+
function AsyncAutocomplete(props) {
|
|
173
|
+
const { defaultValue, toKey, toOption, loadOptions, onChange, onCreate, ...rest } = props;
|
|
174
|
+
const defaultItems = toDefaultItems(defaultValue);
|
|
175
|
+
const inputRef = React.useRef(null);
|
|
176
|
+
const [lastValue, setLastValue] = React.useState(undefined);
|
|
177
|
+
const [timer, setTimer] = React.useState();
|
|
178
|
+
const [abortController, setAbortController] = React.useState();
|
|
179
|
+
const [autoSubmit, setAutoSubmit] = React.useState();
|
|
180
|
+
const [options, setOptions] = React.useState(defaultItems?.map(toOption));
|
|
181
|
+
const lastValueRef = React.useRef();
|
|
182
|
+
lastValueRef.current = lastValue;
|
|
183
|
+
const timerRef = React.useRef();
|
|
184
|
+
timerRef.current = timer;
|
|
185
|
+
const abortControllerRef = React.useRef();
|
|
186
|
+
abortControllerRef.current = abortController;
|
|
187
|
+
const autoSubmitRef = React.useRef();
|
|
188
|
+
autoSubmitRef.current = autoSubmit;
|
|
189
|
+
const optionsRef = React.useRef();
|
|
190
|
+
optionsRef.current = options;
|
|
191
|
+
const handleTimer = React.useCallback(() => {
|
|
192
|
+
setTimer(undefined);
|
|
193
|
+
const value = inputRef.current?.value?.trim() || '';
|
|
194
|
+
if (value === lastValueRef.current) {
|
|
195
|
+
// Nothing has changed, move on
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
setLastValue(value);
|
|
199
|
+
const newAbortController = new AbortController();
|
|
200
|
+
setAbortController(newAbortController);
|
|
201
|
+
loadOptions(value, newAbortController.signal)
|
|
202
|
+
.then((newValues) => {
|
|
203
|
+
if (!newAbortController.signal.aborted) {
|
|
204
|
+
setOptions(newValues.map(toOption));
|
|
205
|
+
setAbortController(undefined);
|
|
206
|
+
if (autoSubmitRef.current) {
|
|
207
|
+
if (newValues.length > 0) {
|
|
208
|
+
onChange(newValues.slice(0, 1));
|
|
209
|
+
}
|
|
210
|
+
setAutoSubmit(false);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
.catch(console.log);
|
|
215
|
+
}, [loadOptions, onChange, toOption]);
|
|
216
|
+
const handleSearchChange = React.useCallback(() => {
|
|
217
|
+
if (abortControllerRef.current) {
|
|
218
|
+
abortControllerRef.current.abort();
|
|
219
|
+
setAbortController(undefined);
|
|
220
|
+
}
|
|
221
|
+
if (timerRef.current !== undefined) {
|
|
222
|
+
window.clearTimeout(timerRef.current);
|
|
223
|
+
}
|
|
224
|
+
const newTimer = window.setTimeout(() => handleTimer(), 100);
|
|
225
|
+
setTimer(newTimer);
|
|
226
|
+
}, [handleTimer]);
|
|
227
|
+
const handleChange = React.useCallback((values) => {
|
|
228
|
+
const result = [];
|
|
229
|
+
for (const value of values) {
|
|
230
|
+
let item = optionsRef.current?.find((option) => option.value === value)?.resource;
|
|
231
|
+
if (!item) {
|
|
232
|
+
item = onCreate(value);
|
|
233
|
+
}
|
|
234
|
+
result.push(item);
|
|
235
|
+
}
|
|
236
|
+
onChange(result);
|
|
237
|
+
}, [onChange, onCreate]);
|
|
238
|
+
const handleKeyDown = React.useCallback((e) => {
|
|
239
|
+
if (e.key === 'Enter') {
|
|
240
|
+
if (!timerRef.current && !abortControllerRef.current) {
|
|
241
|
+
killEvent(e);
|
|
242
|
+
if (optionsRef.current && optionsRef.current.length > 0) {
|
|
243
|
+
setOptions(optionsRef.current.slice(0, 1));
|
|
244
|
+
handleChange([optionsRef.current[0].value]);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
// The user pressed enter, but we don't have results yet.
|
|
249
|
+
// We need to wait for the results to come in.
|
|
250
|
+
setAutoSubmit(true);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}, [handleChange]);
|
|
254
|
+
const handleCreate = React.useCallback((input) => {
|
|
255
|
+
const option = toOption(onCreate(input));
|
|
256
|
+
setOptions([...optionsRef.current, option]);
|
|
257
|
+
return option;
|
|
258
|
+
}, [onCreate, setOptions, toOption]);
|
|
259
|
+
const handleFilter = React.useCallback((_value, selected) => !selected, []);
|
|
260
|
+
React.useEffect(() => {
|
|
261
|
+
return () => {
|
|
262
|
+
if (abortControllerRef.current) {
|
|
263
|
+
abortControllerRef.current.abort();
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}, []);
|
|
267
|
+
return (React.createElement(core$1.MultiSelect, { ...rest, ref: inputRef, defaultValue: defaultItems.map(toKey), searchable: true, onKeyDown: handleKeyDown, onSearchChange: handleSearchChange, data: options, onFocus: handleTimer, onChange: handleChange, onCreate: handleCreate, rightSectionWidth: 40, rightSection: abortController ? React.createElement(core$1.Loader, { size: 16 }) : null, filter: handleFilter }));
|
|
268
|
+
}
|
|
269
|
+
function toDefaultItems(defaultValue) {
|
|
270
|
+
if (!defaultValue) {
|
|
271
|
+
return [];
|
|
272
|
+
}
|
|
273
|
+
if (Array.isArray(defaultValue)) {
|
|
274
|
+
return defaultValue;
|
|
275
|
+
}
|
|
276
|
+
return [defaultValue];
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function AttachmentDisplay(props) {
|
|
280
|
+
const value = props.value;
|
|
281
|
+
const { contentType, url, title } = value ?? {};
|
|
282
|
+
if (!url) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
return (React.createElement("div", { "data-testid": "attachment-display" },
|
|
286
|
+
contentType?.startsWith('image/') && (React.createElement("img", { "data-testid": "attachment-image", style: { maxWidth: props.maxWidth }, src: url, alt: value?.title })),
|
|
287
|
+
contentType?.startsWith('video/') && (React.createElement("video", { "data-testid": "attachment-video", style: { maxWidth: props.maxWidth }, controls: true },
|
|
288
|
+
React.createElement("source", { type: contentType, src: url }))),
|
|
289
|
+
contentType === 'application/pdf' && !title?.endsWith('.pdf') && (React.createElement("div", { "data-testid": "attachment-pdf", style: { maxWidth: props.maxWidth, minHeight: 400 } },
|
|
290
|
+
React.createElement("iframe", { width: "100%", height: "400", src: url + '#navpanes=0', allowFullScreen: true, frameBorder: 0, seamless: true }))),
|
|
291
|
+
React.createElement("div", { "data-testid": "download-link", style: { padding: '2px 16px 16px 16px' } },
|
|
292
|
+
React.createElement(core$1.Anchor, { href: value?.url, "data-testid": "attachment-details", target: "_blank", rel: "noopener noreferrer" }, value?.title || 'Download'))));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function AttachmentArrayDisplay(props) {
|
|
296
|
+
return (React.createElement("div", null, props.values &&
|
|
297
|
+
props.values.map((v, index) => (React.createElement("div", { key: 'attatchment-' + index },
|
|
298
|
+
React.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
|
|
299
|
+
}
|
|
300
|
+
|
|
188
301
|
function AttachmentButton(props) {
|
|
189
302
|
const medplum = useMedplum();
|
|
190
303
|
const fileInputRef = React.useRef(null);
|
|
191
304
|
function onClick(e) {
|
|
192
|
-
var _a;
|
|
193
305
|
killEvent(e);
|
|
194
|
-
|
|
306
|
+
fileInputRef.current?.click();
|
|
195
307
|
}
|
|
196
308
|
function onFileChange(e) {
|
|
197
309
|
killEvent(e);
|
|
@@ -228,8 +340,7 @@
|
|
|
228
340
|
});
|
|
229
341
|
})
|
|
230
342
|
.catch((outcome) => {
|
|
231
|
-
|
|
232
|
-
alert((_c = (_b = (_a = outcome === null || outcome === void 0 ? void 0 : outcome.issue) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.details) === null || _c === void 0 ? void 0 : _c.text);
|
|
343
|
+
alert(outcome?.issue?.[0]?.details?.text);
|
|
233
344
|
});
|
|
234
345
|
}
|
|
235
346
|
return (React.createElement(React.Fragment, null,
|
|
@@ -238,8 +349,7 @@
|
|
|
238
349
|
}
|
|
239
350
|
|
|
240
351
|
function AttachmentArrayInput(props) {
|
|
241
|
-
|
|
242
|
-
const [values, setValues] = React.useState((_a = props.defaultValue) !== null && _a !== void 0 ? _a : []);
|
|
352
|
+
const [values, setValues] = React.useState(props.defaultValue ?? []);
|
|
243
353
|
const valuesRef = React.useRef();
|
|
244
354
|
valuesRef.current = values;
|
|
245
355
|
function setValuesWrapper(newValues) {
|
|
@@ -269,7 +379,7 @@
|
|
|
269
379
|
React.createElement("td", null,
|
|
270
380
|
React.createElement(AttachmentButton, { onUpload: (attachment) => {
|
|
271
381
|
setValuesWrapper([...valuesRef.current, attachment]);
|
|
272
|
-
} }, (props) => (React.createElement(core$1.ActionIcon,
|
|
382
|
+
} }, (props) => (React.createElement(core$1.ActionIcon, { ...props, title: "Add", size: "sm", color: "green" },
|
|
273
383
|
React.createElement(icons.IconCloudUpload, { size: 16 })))))))));
|
|
274
384
|
}
|
|
275
385
|
|
|
@@ -289,44 +399,7 @@
|
|
|
289
399
|
setValueWrapper(undefined);
|
|
290
400
|
} }, "Remove")));
|
|
291
401
|
}
|
|
292
|
-
return (React.createElement(AttachmentButton, { onUpload: setValueWrapper }, (props) => React.createElement(core$1.Button,
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/******************************************************************************
|
|
296
|
-
Copyright (c) Microsoft Corporation.
|
|
297
|
-
|
|
298
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
299
|
-
purpose with or without fee is hereby granted.
|
|
300
|
-
|
|
301
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
302
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
303
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
304
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
305
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
306
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
307
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
308
|
-
***************************************************************************** */
|
|
309
|
-
|
|
310
|
-
function __rest(s, e) {
|
|
311
|
-
var t = {};
|
|
312
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
313
|
-
t[p] = s[p];
|
|
314
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
315
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
316
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
317
|
-
t[p[i]] = s[p[i]];
|
|
318
|
-
}
|
|
319
|
-
return t;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
323
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
324
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
325
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
326
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
327
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
328
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
329
|
-
});
|
|
402
|
+
return (React.createElement(AttachmentButton, { onUpload: setValueWrapper }, (props) => React.createElement(core$1.Button, { ...props }, "Upload...")));
|
|
330
403
|
}
|
|
331
404
|
|
|
332
405
|
const useStyles$d = core$1.createStyles(() => ({
|
|
@@ -338,9 +411,9 @@
|
|
|
338
411
|
},
|
|
339
412
|
}));
|
|
340
413
|
function Container(props) {
|
|
341
|
-
const { children
|
|
414
|
+
const { children, ...others } = props;
|
|
342
415
|
const { classes } = useStyles$d();
|
|
343
|
-
return (React.createElement(core$1.Container,
|
|
416
|
+
return (React.createElement(core$1.Container, { className: classes.root, ...others }, children));
|
|
344
417
|
}
|
|
345
418
|
|
|
346
419
|
const useStyles$c = core$1.createStyles((theme, { width, fill }) => ({
|
|
@@ -367,15 +440,15 @@
|
|
|
367
440
|
withBorder: true,
|
|
368
441
|
};
|
|
369
442
|
function Panel(props) {
|
|
370
|
-
const
|
|
443
|
+
const { className, children, width, fill, unstyled, ...others } = core$1.useComponentDefaultProps('Panel', defaultProps$1, props);
|
|
371
444
|
const { classes, cx } = useStyles$c({ width, fill }, { name: 'Panel', unstyled });
|
|
372
|
-
return (React.createElement(core$1.Paper,
|
|
445
|
+
return (React.createElement(core$1.Paper, { className: cx(classes.paper, className), ...others }, children));
|
|
373
446
|
}
|
|
374
447
|
|
|
375
448
|
function Document(props) {
|
|
376
|
-
const { children
|
|
449
|
+
const { children, ...others } = props;
|
|
377
450
|
return (React.createElement(Container, null,
|
|
378
|
-
React.createElement(Panel,
|
|
451
|
+
React.createElement(Panel, { ...others }, children)));
|
|
379
452
|
}
|
|
380
453
|
|
|
381
454
|
/**
|
|
@@ -446,12 +519,13 @@
|
|
|
446
519
|
}
|
|
447
520
|
|
|
448
521
|
function getErrorsForInput(outcome, expression) {
|
|
449
|
-
|
|
450
|
-
|
|
522
|
+
return outcome?.issue
|
|
523
|
+
?.filter((issue) => isExpressionMatch(issue.expression?.[0], expression))
|
|
524
|
+
?.map((issue) => issue.details?.text)
|
|
525
|
+
?.join('\n');
|
|
451
526
|
}
|
|
452
527
|
function getIssuesForExpression(outcome, expression) {
|
|
453
|
-
|
|
454
|
-
return (_a = outcome === null || outcome === void 0 ? void 0 : outcome.issue) === null || _a === void 0 ? void 0 : _a.filter((issue) => { var _a; return isExpressionMatch((_a = issue.expression) === null || _a === void 0 ? void 0 : _a[0], expression); });
|
|
528
|
+
return outcome?.issue?.filter((issue) => isExpressionMatch(issue.expression?.[0], expression));
|
|
455
529
|
}
|
|
456
530
|
function isExpressionMatch(expr1, expr2) {
|
|
457
531
|
// Expression can be either "fieldName" or "resourceType.fieldName"
|
|
@@ -475,9 +549,9 @@
|
|
|
475
549
|
function NewProjectForm(props) {
|
|
476
550
|
const medplum = useMedplum();
|
|
477
551
|
const [outcome, setOutcome] = React.useState();
|
|
478
|
-
return (React.createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) =>
|
|
552
|
+
return (React.createElement(Form, { style: { maxWidth: 400 }, onSubmit: async (formData) => {
|
|
479
553
|
try {
|
|
480
|
-
props.handleAuthResponse(
|
|
554
|
+
props.handleAuthResponse(await medplum.startNewProject({
|
|
481
555
|
login: props.login,
|
|
482
556
|
projectName: formData.projectName,
|
|
483
557
|
}));
|
|
@@ -485,7 +559,7 @@
|
|
|
485
559
|
catch (err) {
|
|
486
560
|
setOutcome(err);
|
|
487
561
|
}
|
|
488
|
-
}
|
|
562
|
+
} },
|
|
489
563
|
React.createElement(core$1.Center, { sx: { flexDirection: 'column' } },
|
|
490
564
|
React.createElement(Logo, { size: 32 }),
|
|
491
565
|
React.createElement(core$1.Title, null, "Create project")),
|
|
@@ -545,12 +619,11 @@
|
|
|
545
619
|
return React.createElement("div", { ref: parentRef });
|
|
546
620
|
}
|
|
547
621
|
function getGoogleClientId(clientId) {
|
|
548
|
-
var _a, _b;
|
|
549
622
|
if (clientId) {
|
|
550
623
|
return clientId;
|
|
551
624
|
}
|
|
552
625
|
const origin = window.location.protocol + '//' + window.location.host;
|
|
553
|
-
const authorizedOrigins =
|
|
626
|
+
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(',') ?? [];
|
|
554
627
|
if (authorizedOrigins.includes(origin)) {
|
|
555
628
|
return "921088377005-3j1sa10vr6hj86jgmdfh2l53v3mp7lfi.apps.googleusercontent.com";
|
|
556
629
|
}
|
|
@@ -574,14 +647,14 @@
|
|
|
574
647
|
*/
|
|
575
648
|
function getRecaptcha(siteKey) {
|
|
576
649
|
return new Promise((resolve, reject) => {
|
|
577
|
-
grecaptcha.ready(() =>
|
|
650
|
+
grecaptcha.ready(async () => {
|
|
578
651
|
try {
|
|
579
|
-
resolve(
|
|
652
|
+
resolve(await grecaptcha.execute(siteKey, { action: 'submit' }));
|
|
580
653
|
}
|
|
581
654
|
catch (err) {
|
|
582
655
|
reject(err);
|
|
583
656
|
}
|
|
584
|
-
})
|
|
657
|
+
});
|
|
585
658
|
});
|
|
586
659
|
}
|
|
587
660
|
|
|
@@ -592,10 +665,10 @@
|
|
|
592
665
|
const [outcome, setOutcome] = React.useState();
|
|
593
666
|
const issues = getIssuesForExpression(outcome, undefined);
|
|
594
667
|
React.useEffect(() => initRecaptcha(recaptchaSiteKey), [recaptchaSiteKey]);
|
|
595
|
-
return (React.createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) =>
|
|
668
|
+
return (React.createElement(Form, { style: { maxWidth: 400 }, onSubmit: async (formData) => {
|
|
596
669
|
try {
|
|
597
|
-
const recaptchaToken =
|
|
598
|
-
props.handleAuthResponse(
|
|
670
|
+
const recaptchaToken = await getRecaptcha(recaptchaSiteKey);
|
|
671
|
+
props.handleAuthResponse(await medplum.startNewUser({
|
|
599
672
|
projectId: props.projectId,
|
|
600
673
|
firstName: formData.firstName,
|
|
601
674
|
lastName: formData.lastName,
|
|
@@ -609,18 +682,15 @@
|
|
|
609
682
|
catch (err) {
|
|
610
683
|
setOutcome(err);
|
|
611
684
|
}
|
|
612
|
-
}
|
|
685
|
+
} },
|
|
613
686
|
React.createElement(core$1.Center, { sx: { flexDirection: 'column' } }, props.children),
|
|
614
|
-
issues && (React.createElement(core$1.Alert, { icon: React.createElement(icons.IconAlertCircle, { size: 16 }), color: "red" }, issues.map((issue) => {
|
|
615
|
-
var _a, _b;
|
|
616
|
-
return (React.createElement("div", { "data-testid": "text-field-error", key: (_a = issue.details) === null || _a === void 0 ? void 0 : _a.text }, (_b = issue.details) === null || _b === void 0 ? void 0 : _b.text));
|
|
617
|
-
}))),
|
|
687
|
+
issues && (React.createElement(core$1.Alert, { icon: React.createElement(icons.IconAlertCircle, { size: 16 }), color: "red" }, issues.map((issue) => (React.createElement("div", { "data-testid": "text-field-error", key: issue.details?.text }, issue.details?.text))))),
|
|
618
688
|
googleClientId && (React.createElement(React.Fragment, null,
|
|
619
689
|
React.createElement(core$1.Group, { position: "center", p: "xl", style: { height: 70 } },
|
|
620
|
-
React.createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) =>
|
|
690
|
+
React.createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: async (response) => {
|
|
621
691
|
try {
|
|
622
|
-
|
|
623
|
-
props.handleAuthResponse(
|
|
692
|
+
await medplum.startPkce();
|
|
693
|
+
props.handleAuthResponse(await medplum.startGoogleLogin({
|
|
624
694
|
googleClientId: response.clientId,
|
|
625
695
|
googleCredential: response.credential,
|
|
626
696
|
createUser: true,
|
|
@@ -629,7 +699,7 @@
|
|
|
629
699
|
catch (err) {
|
|
630
700
|
setOutcome(err);
|
|
631
701
|
}
|
|
632
|
-
}
|
|
702
|
+
} })),
|
|
633
703
|
React.createElement(core$1.Divider, { label: "or", labelPosition: "center", my: "lg" }))),
|
|
634
704
|
React.createElement(core$1.Stack, { spacing: "xl" },
|
|
635
705
|
React.createElement(core$1.TextInput, { name: "firstName", type: "text", label: "First name", placeholder: "First name", required: true, autoFocus: true, error: getErrorsForInput(outcome, 'firstName') }),
|
|
@@ -687,34 +757,37 @@
|
|
|
687
757
|
}
|
|
688
758
|
|
|
689
759
|
function AuthenticationForm(props) {
|
|
690
|
-
const { generatePkce, onForgotPassword, onRegister, handleAuthResponse, children
|
|
760
|
+
const { generatePkce, onForgotPassword, onRegister, handleAuthResponse, children, ...baseLoginRequest } = props;
|
|
691
761
|
const medplum = useMedplum();
|
|
692
762
|
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
693
763
|
const [outcome, setOutcome] = React.useState();
|
|
694
764
|
const issues = getIssuesForExpression(outcome, undefined);
|
|
695
|
-
function startPkce() {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
}
|
|
700
|
-
});
|
|
765
|
+
async function startPkce() {
|
|
766
|
+
if (generatePkce) {
|
|
767
|
+
await medplum.startPkce();
|
|
768
|
+
}
|
|
701
769
|
}
|
|
702
770
|
return (React.createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => {
|
|
703
771
|
startPkce()
|
|
704
|
-
.then(() => medplum.startLogin(
|
|
772
|
+
.then(() => medplum.startLogin({
|
|
773
|
+
...baseLoginRequest,
|
|
774
|
+
email: formData.email,
|
|
775
|
+
password: formData.password,
|
|
776
|
+
remember: formData.remember === 'on',
|
|
777
|
+
}))
|
|
705
778
|
.then(handleAuthResponse)
|
|
706
779
|
.catch(setOutcome);
|
|
707
780
|
} },
|
|
708
781
|
React.createElement(core$1.Center, { sx: { flexDirection: 'column' } }, children),
|
|
709
|
-
issues && (React.createElement(core$1.Alert, { icon: React.createElement(icons.IconAlertCircle, { size: 16 }), color: "red" }, issues.map((issue) => {
|
|
710
|
-
var _a, _b;
|
|
711
|
-
return (React.createElement("div", { "data-testid": "text-field-error", key: (_a = issue.details) === null || _a === void 0 ? void 0 : _a.text }, (_b = issue.details) === null || _b === void 0 ? void 0 : _b.text));
|
|
712
|
-
}))),
|
|
782
|
+
issues && (React.createElement(core$1.Alert, { icon: React.createElement(icons.IconAlertCircle, { size: 16 }), color: "red" }, issues.map((issue) => (React.createElement("div", { "data-testid": "text-field-error", key: issue.details?.text }, issue.details?.text))))),
|
|
713
783
|
googleClientId && (React.createElement(React.Fragment, null,
|
|
714
784
|
React.createElement(core$1.Group, { position: "center", p: "xl", style: { height: 70 } },
|
|
715
785
|
React.createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) => {
|
|
716
786
|
startPkce()
|
|
717
|
-
.then(() => medplum.startGoogleLogin(
|
|
787
|
+
.then(() => medplum.startGoogleLogin({
|
|
788
|
+
...baseLoginRequest,
|
|
789
|
+
googleCredential: response.credential,
|
|
790
|
+
}))
|
|
718
791
|
.then(props.handleAuthResponse)
|
|
719
792
|
.catch(setOutcome);
|
|
720
793
|
} })),
|
|
@@ -735,23 +808,20 @@
|
|
|
735
808
|
React.createElement(core$1.Center, { sx: { flexDirection: 'column' } },
|
|
736
809
|
React.createElement(Logo, { size: 32 }),
|
|
737
810
|
React.createElement(core$1.Title, null, "Choose profile")),
|
|
738
|
-
props.memberships.map((membership) => {
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
React.createElement(
|
|
750
|
-
React.createElement(core$1.
|
|
751
|
-
React.createElement(
|
|
752
|
-
React.createElement(core$1.Text, { size: "sm", weight: 500 }, (_a = membership.profile) === null || _a === void 0 ? void 0 : _a.display),
|
|
753
|
-
React.createElement(core$1.Text, { color: "dimmed", size: "xs" }, (_b = membership.project) === null || _b === void 0 ? void 0 : _b.display)))));
|
|
754
|
-
})));
|
|
811
|
+
props.memberships.map((membership) => (React.createElement(core$1.UnstyledButton, { key: membership.id, onClick: () => {
|
|
812
|
+
medplum
|
|
813
|
+
.post('auth/profile', {
|
|
814
|
+
login: props.login,
|
|
815
|
+
profile: membership.id,
|
|
816
|
+
})
|
|
817
|
+
.then(props.handleAuthResponse)
|
|
818
|
+
.catch(console.log);
|
|
819
|
+
} },
|
|
820
|
+
React.createElement(core$1.Group, null,
|
|
821
|
+
React.createElement(core$1.Avatar, { radius: "xl" }),
|
|
822
|
+
React.createElement("div", { style: { flex: 1 } },
|
|
823
|
+
React.createElement(core$1.Text, { size: "sm", weight: 500 }, membership.profile?.display),
|
|
824
|
+
React.createElement(core$1.Text, { color: "dimmed", size: "xs" }, membership.project?.display))))))));
|
|
755
825
|
}
|
|
756
826
|
|
|
757
827
|
function ChooseScopeForm(props) {
|
|
@@ -774,12 +844,48 @@
|
|
|
774
844
|
React.createElement(core$1.Button, { type: "submit" }, "Set scope")))));
|
|
775
845
|
}
|
|
776
846
|
|
|
847
|
+
function MfaForm(props) {
|
|
848
|
+
const medplum = useMedplum();
|
|
849
|
+
const [errorMessage, setErrorMessage] = React.useState(undefined);
|
|
850
|
+
return (React.createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => {
|
|
851
|
+
setErrorMessage(undefined);
|
|
852
|
+
medplum
|
|
853
|
+
.post('auth/mfa/verify', {
|
|
854
|
+
login: props.login,
|
|
855
|
+
token: formData.token,
|
|
856
|
+
})
|
|
857
|
+
.then(props.handleAuthResponse)
|
|
858
|
+
.catch((err) => setErrorMessage(core.normalizeErrorString(err)));
|
|
859
|
+
} },
|
|
860
|
+
React.createElement(core$1.Stack, null,
|
|
861
|
+
React.createElement(core$1.Center, { sx: { flexDirection: 'column' } },
|
|
862
|
+
React.createElement(Logo, { size: 32 }),
|
|
863
|
+
React.createElement(core$1.Title, null, "Enter MFA code")),
|
|
864
|
+
errorMessage && (React.createElement(core$1.Alert, { icon: React.createElement(icons.IconAlertCircle, { size: 16 }), title: "Error", color: "red" }, errorMessage)),
|
|
865
|
+
React.createElement(core$1.Stack, null,
|
|
866
|
+
React.createElement(core$1.TextInput, { name: "token", label: "MFA code", required: true })),
|
|
867
|
+
React.createElement(core$1.Group, { position: "right", mt: "xl" },
|
|
868
|
+
React.createElement(core$1.Button, { type: "submit" }, "Submit code")))));
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* The SignInForm component allows users to sign in to Medplum.
|
|
873
|
+
*
|
|
874
|
+
* "Signing in" is a multi-step process:
|
|
875
|
+
* 1) Authentication - identify the user
|
|
876
|
+
* 2) MFA - If MFA is enabled, prompt for MFA code
|
|
877
|
+
* 3) Choose profile - If the user has multiple profiles, prompt to choose one
|
|
878
|
+
* 4) Choose scope - If the user has multiple scopes, prompt to choose one
|
|
879
|
+
* 5) Success - Return to the caller with either a code or a redirect
|
|
880
|
+
*/
|
|
777
881
|
function SignInForm(props) {
|
|
778
|
-
const { chooseScopes, onSuccess, onForgotPassword, onRegister, onCode
|
|
882
|
+
const { chooseScopes, onSuccess, onForgotPassword, onRegister, onCode, ...baseLoginRequest } = props;
|
|
779
883
|
const medplum = useMedplum();
|
|
780
884
|
const [login, setLogin] = React.useState(undefined);
|
|
885
|
+
const [mfaRequired, setAuthenticatorRequired] = React.useState(false);
|
|
781
886
|
const [memberships, setMemberships] = React.useState(undefined);
|
|
782
887
|
function handleAuthResponse(response) {
|
|
888
|
+
setAuthenticatorRequired(!!response.mfaRequired);
|
|
783
889
|
if (response.login) {
|
|
784
890
|
setLogin(response.login);
|
|
785
891
|
}
|
|
@@ -815,7 +921,10 @@
|
|
|
815
921
|
}
|
|
816
922
|
return (React.createElement(Document, { width: 450 }, (() => {
|
|
817
923
|
if (!login) {
|
|
818
|
-
return (React.createElement(AuthenticationForm,
|
|
924
|
+
return (React.createElement(AuthenticationForm, { generatePkce: !onCode, onForgotPassword: onForgotPassword, onRegister: onRegister, handleAuthResponse: handleAuthResponse, ...baseLoginRequest }, props.children));
|
|
925
|
+
}
|
|
926
|
+
else if (mfaRequired) {
|
|
927
|
+
return React.createElement(MfaForm, { login: login, handleAuthResponse: handleAuthResponse });
|
|
819
928
|
}
|
|
820
929
|
else if (memberships) {
|
|
821
930
|
return React.createElement(ChooseProfileForm, { login: login, memberships: memberships, handleAuthResponse: handleAuthResponse });
|
|
@@ -906,15 +1015,14 @@
|
|
|
906
1015
|
}
|
|
907
1016
|
|
|
908
1017
|
function ContactDetailDisplay(props) {
|
|
909
|
-
var _a;
|
|
910
1018
|
const contactDetail = props.value;
|
|
911
1019
|
if (!contactDetail) {
|
|
912
1020
|
return null;
|
|
913
1021
|
}
|
|
914
1022
|
return (React.createElement(React.Fragment, null,
|
|
915
1023
|
contactDetail.name,
|
|
916
|
-
contactDetail.name && ': ',
|
|
917
|
-
|
|
1024
|
+
contactDetail.name && ': ',
|
|
1025
|
+
contactDetail.telecom?.map((telecom, index) => (React.createElement(ContactPointDisplay, { key: 'telecom-' + index, value: telecom })))));
|
|
918
1026
|
}
|
|
919
1027
|
|
|
920
1028
|
function HumanNameDisplay(props) {
|
|
@@ -926,11 +1034,14 @@
|
|
|
926
1034
|
}
|
|
927
1035
|
|
|
928
1036
|
function IdentifierDisplay(props) {
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
1037
|
+
return (React.createElement("div", null,
|
|
1038
|
+
props.value?.system,
|
|
1039
|
+
": ",
|
|
1040
|
+
props.value?.value));
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
function MoneyDisplay(props) {
|
|
1044
|
+
return React.createElement(React.Fragment, null, core.formatMoney(props.value));
|
|
934
1045
|
}
|
|
935
1046
|
|
|
936
1047
|
function QuantityDisplay(props) {
|
|
@@ -954,12 +1065,12 @@
|
|
|
954
1065
|
|
|
955
1066
|
function MedplumLink(props) {
|
|
956
1067
|
const navigate = reactRouterDom.useNavigate();
|
|
957
|
-
const { to, suffix, label, onClick, children
|
|
1068
|
+
const { to, suffix, label, onClick, children, ...rest } = props;
|
|
958
1069
|
let href = getHref(to);
|
|
959
1070
|
if (suffix) {
|
|
960
1071
|
href += '/' + suffix;
|
|
961
1072
|
}
|
|
962
|
-
return (React.createElement(core$1.Anchor,
|
|
1073
|
+
return (React.createElement(core$1.Anchor, { href: href, "aria-label": label, onClick: (e) => {
|
|
963
1074
|
killEvent(e);
|
|
964
1075
|
if (onClick) {
|
|
965
1076
|
onClick();
|
|
@@ -967,7 +1078,7 @@
|
|
|
967
1078
|
else if (to) {
|
|
968
1079
|
navigate(href);
|
|
969
1080
|
}
|
|
970
|
-
}
|
|
1081
|
+
}, ...rest }, children));
|
|
971
1082
|
}
|
|
972
1083
|
function getHref(to) {
|
|
973
1084
|
if (to) {
|
|
@@ -1012,18 +1123,16 @@
|
|
|
1012
1123
|
}
|
|
1013
1124
|
|
|
1014
1125
|
function ResourceArrayDisplay(props) {
|
|
1015
|
-
var _a, _b, _c;
|
|
1016
1126
|
const property = props.property;
|
|
1017
|
-
const values =
|
|
1018
|
-
const propertyType =
|
|
1127
|
+
const values = props.values ?? [];
|
|
1128
|
+
const propertyType = property.type?.[0]?.code;
|
|
1019
1129
|
return (React.createElement(React.Fragment, null, values.map((v, index) => (React.createElement("div", { key: `${index}-${values.length}` },
|
|
1020
1130
|
React.createElement(ResourcePropertyDisplay, { arrayElement: true, property: property, propertyType: propertyType, value: v, ignoreMissingValues: props.ignoreMissingValues, link: props.link }))))));
|
|
1021
1131
|
}
|
|
1022
1132
|
|
|
1023
1133
|
function ResourcePropertyDisplay(props) {
|
|
1024
|
-
var _a;
|
|
1025
1134
|
const { property, propertyType, value } = props;
|
|
1026
|
-
if (
|
|
1135
|
+
if (property?.max === '*' && !props.arrayElement) {
|
|
1027
1136
|
if (propertyType === 'Attachment') {
|
|
1028
1137
|
return React.createElement(AttachmentArrayDisplay, { values: value, maxWidth: props.maxWidth });
|
|
1029
1138
|
}
|
|
@@ -1052,7 +1161,7 @@
|
|
|
1052
1161
|
case core.PropertyType.Address:
|
|
1053
1162
|
return React.createElement(AddressDisplay, { value: value });
|
|
1054
1163
|
case core.PropertyType.Annotation:
|
|
1055
|
-
return React.createElement(React.Fragment, null, value
|
|
1164
|
+
return React.createElement(React.Fragment, null, value?.text);
|
|
1056
1165
|
case core.PropertyType.Attachment:
|
|
1057
1166
|
return React.createElement(AttachmentDisplay, { value: value, maxWidth: props.maxWidth });
|
|
1058
1167
|
case core.PropertyType.CodeableConcept:
|
|
@@ -1067,6 +1176,8 @@
|
|
|
1067
1176
|
return React.createElement(HumanNameDisplay, { value: value });
|
|
1068
1177
|
case core.PropertyType.Identifier:
|
|
1069
1178
|
return React.createElement(IdentifierDisplay, { value: value });
|
|
1179
|
+
case core.PropertyType.Money:
|
|
1180
|
+
return React.createElement(MoneyDisplay, { value: value });
|
|
1070
1181
|
case core.PropertyType.Period:
|
|
1071
1182
|
return React.createElement(React.Fragment, null, core.formatPeriod(value));
|
|
1072
1183
|
case core.PropertyType.Quantity:
|
|
@@ -1084,10 +1195,10 @@
|
|
|
1084
1195
|
case core.PropertyType.UsageContext:
|
|
1085
1196
|
return (React.createElement(BackboneElementDisplay, { value: { type: propertyType, value }, compact: true, ignoreMissingValues: props.ignoreMissingValues }));
|
|
1086
1197
|
default:
|
|
1087
|
-
if (!
|
|
1198
|
+
if (!property?.path) {
|
|
1088
1199
|
throw Error(`Displaying property of type ${props.propertyType} requires element definition path`);
|
|
1089
1200
|
}
|
|
1090
|
-
return (React.createElement(BackboneElementDisplay, { value: { type: core.buildTypeName(
|
|
1201
|
+
return (React.createElement(BackboneElementDisplay, { value: { type: core.buildTypeName(property?.path?.split('.')), value }, compact: true, ignoreMissingValues: props.ignoreMissingValues }));
|
|
1091
1202
|
}
|
|
1092
1203
|
}
|
|
1093
1204
|
/**
|
|
@@ -1269,59 +1380,38 @@
|
|
|
1269
1380
|
return obj;
|
|
1270
1381
|
}
|
|
1271
1382
|
|
|
1272
|
-
function
|
|
1383
|
+
function toKey(element) {
|
|
1384
|
+
return element.code;
|
|
1385
|
+
}
|
|
1386
|
+
function toOption(element) {
|
|
1273
1387
|
return {
|
|
1274
1388
|
value: element.code,
|
|
1275
1389
|
label: getDisplay(element),
|
|
1276
|
-
element,
|
|
1390
|
+
resource: element,
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
function createValue(input) {
|
|
1394
|
+
return {
|
|
1395
|
+
code: input,
|
|
1396
|
+
display: input,
|
|
1277
1397
|
};
|
|
1278
1398
|
}
|
|
1279
1399
|
function ValueSetAutocomplete(props) {
|
|
1280
1400
|
const medplum = useMedplum();
|
|
1281
|
-
const {
|
|
1282
|
-
const
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
var _a, _b;
|
|
1288
|
-
const system = (_a = property.binding) === null || _a === void 0 ? void 0 : _a.valueSet;
|
|
1289
|
-
const valueSet = yield medplum.searchValueSet(system, input);
|
|
1290
|
-
const valueSetElements = (_b = valueSet.expansion) === null || _b === void 0 ? void 0 : _b.contains;
|
|
1291
|
-
const newData = [...dataRef.current];
|
|
1401
|
+
const { elementDefinition, ...rest } = props;
|
|
1402
|
+
const loadValues = React.useCallback(async (input, signal) => {
|
|
1403
|
+
const system = elementDefinition.binding?.valueSet;
|
|
1404
|
+
const valueSet = await medplum.searchValueSet(system, input, { signal });
|
|
1405
|
+
const valueSetElements = valueSet.expansion?.contains;
|
|
1406
|
+
const newData = [];
|
|
1292
1407
|
for (const valueSetElement of valueSetElements) {
|
|
1293
|
-
if (valueSetElement.code && !newData.some((item) => item.
|
|
1294
|
-
newData.push(
|
|
1408
|
+
if (valueSetElement.code && !newData.some((item) => item.code === valueSetElement.code)) {
|
|
1409
|
+
newData.push(valueSetElement);
|
|
1295
1410
|
}
|
|
1296
1411
|
}
|
|
1297
|
-
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
setTextValues(values);
|
|
1301
|
-
const textValue = values[0];
|
|
1302
|
-
let currentItem = undefined;
|
|
1303
|
-
if (textValue) {
|
|
1304
|
-
currentItem = dataRef.current.find((item) => item.value === values[0]);
|
|
1305
|
-
if (!currentItem) {
|
|
1306
|
-
const newElement = { code: textValue, display: textValue };
|
|
1307
|
-
currentItem = valueSetElementToAutocompleteItem(newElement);
|
|
1308
|
-
setData([...dataRef.current, currentItem]);
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
if (props.onChange) {
|
|
1312
|
-
props.onChange(currentItem === null || currentItem === void 0 ? void 0 : currentItem.element);
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
React.useEffect(() => {
|
|
1316
|
-
loadValues('').catch(console.log);
|
|
1317
|
-
}, [loadValues]);
|
|
1318
|
-
return (React.createElement(core$1.MultiSelect, { data: data, placeholder: props.placeholder, searchable: true, creatable: true, clearable: true, value: textValues, filter: (value, selected, item) => {
|
|
1319
|
-
var _a, _b;
|
|
1320
|
-
return !!(textValues.length === 0 &&
|
|
1321
|
-
!selected &&
|
|
1322
|
-
(((_a = item.element.display) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(value.toLowerCase().trim())) ||
|
|
1323
|
-
((_b = item.element.code) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes(value.toLowerCase().trim()))));
|
|
1324
|
-
}, onChange: handleChange, getCreateLabel: (query) => `+ Create ${query}`, onCreate: (query) => valueSetElementToAutocompleteItem({ code: query, display: query }) }));
|
|
1412
|
+
return newData;
|
|
1413
|
+
}, [medplum, elementDefinition]);
|
|
1414
|
+
return (React.createElement(AsyncAutocomplete, { ...rest, creatable: true, clearable: true, toKey: toKey, toOption: toOption, loadOptions: loadValues, getCreateLabel: (query) => `+ Create ${query}`, onCreate: createValue }));
|
|
1325
1415
|
}
|
|
1326
1416
|
function getDisplay(item) {
|
|
1327
1417
|
return item.display || item.code || '';
|
|
@@ -1329,64 +1419,65 @@
|
|
|
1329
1419
|
|
|
1330
1420
|
function CodeableConceptInput(props) {
|
|
1331
1421
|
const [value, setValue] = React.useState(props.defaultValue);
|
|
1332
|
-
function handleChange(
|
|
1333
|
-
const newConcept =
|
|
1422
|
+
function handleChange(newValues) {
|
|
1423
|
+
const newConcept = valueSetElementToCodeableConcept(newValues);
|
|
1334
1424
|
setValue(newConcept);
|
|
1335
1425
|
if (props.onChange) {
|
|
1336
1426
|
props.onChange(newConcept);
|
|
1337
1427
|
}
|
|
1338
1428
|
}
|
|
1339
|
-
return (React.createElement(ValueSetAutocomplete, {
|
|
1429
|
+
return (React.createElement(ValueSetAutocomplete, { elementDefinition: props.property, name: props.name, placeholder: props.placeholder, defaultValue: value && codeableConceptToValueSetElement(value), onChange: handleChange }));
|
|
1340
1430
|
}
|
|
1341
1431
|
function codeableConceptToValueSetElement(concept) {
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
};
|
|
1432
|
+
return concept.coding?.map((c) => ({
|
|
1433
|
+
system: c.system,
|
|
1434
|
+
code: c.code,
|
|
1435
|
+
display: c.display,
|
|
1436
|
+
}));
|
|
1348
1437
|
}
|
|
1349
|
-
function valueSetElementToCodeableConcept(
|
|
1438
|
+
function valueSetElementToCodeableConcept(elements) {
|
|
1439
|
+
if (elements.length === 0) {
|
|
1440
|
+
return undefined;
|
|
1441
|
+
}
|
|
1350
1442
|
return {
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
display: element.display,
|
|
1357
|
-
},
|
|
1358
|
-
],
|
|
1443
|
+
coding: elements.map((e) => ({
|
|
1444
|
+
system: e.system,
|
|
1445
|
+
code: e.code,
|
|
1446
|
+
display: e.display,
|
|
1447
|
+
})),
|
|
1359
1448
|
};
|
|
1360
1449
|
}
|
|
1361
1450
|
|
|
1362
1451
|
function CodeInput(props) {
|
|
1363
1452
|
const [value, setValue] = React.useState(props.defaultValue);
|
|
1364
|
-
function handleChange(
|
|
1453
|
+
function handleChange(newValues) {
|
|
1454
|
+
const newValue = newValues[0];
|
|
1365
1455
|
const newCode = valueSetElementToCode(newValue);
|
|
1366
1456
|
setValue(newCode);
|
|
1367
1457
|
if (props.onChange) {
|
|
1368
1458
|
props.onChange(newCode);
|
|
1369
1459
|
}
|
|
1370
1460
|
}
|
|
1371
|
-
return (React.createElement(ValueSetAutocomplete, {
|
|
1461
|
+
return (React.createElement(ValueSetAutocomplete, { elementDefinition: props.property, name: props.name, placeholder: props.placeholder, defaultValue: codeToValueSetElement(value), onChange: handleChange }));
|
|
1372
1462
|
}
|
|
1373
1463
|
function codeToValueSetElement(code) {
|
|
1374
1464
|
return code ? { code } : undefined;
|
|
1375
1465
|
}
|
|
1376
1466
|
function valueSetElementToCode(element) {
|
|
1377
|
-
return element
|
|
1467
|
+
return element?.code;
|
|
1378
1468
|
}
|
|
1379
1469
|
|
|
1380
1470
|
function CodingInput(props) {
|
|
1381
1471
|
const [value, setValue] = React.useState(props.defaultValue);
|
|
1382
|
-
function handleChange(
|
|
1472
|
+
function handleChange(newValues) {
|
|
1473
|
+
const newValue = newValues[0];
|
|
1383
1474
|
const newConcept = newValue && valueSetElementToCoding(newValue);
|
|
1384
1475
|
setValue(newConcept);
|
|
1385
1476
|
if (props.onChange) {
|
|
1386
1477
|
props.onChange(newConcept);
|
|
1387
1478
|
}
|
|
1388
1479
|
}
|
|
1389
|
-
return (React.createElement(ValueSetAutocomplete, {
|
|
1480
|
+
return (React.createElement(ValueSetAutocomplete, { elementDefinition: props.property, name: props.name, placeholder: props.placeholder, defaultValue: value && codingToValueSetElement(value), onChange: handleChange }));
|
|
1390
1481
|
}
|
|
1391
1482
|
function codingToValueSetElement(coding) {
|
|
1392
1483
|
return {
|
|
@@ -1417,34 +1508,33 @@
|
|
|
1417
1508
|
}
|
|
1418
1509
|
}
|
|
1419
1510
|
function setSystem(system) {
|
|
1420
|
-
const newValue =
|
|
1511
|
+
const newValue = { ...ref.current, system };
|
|
1421
1512
|
if (!system) {
|
|
1422
1513
|
delete newValue.system;
|
|
1423
1514
|
}
|
|
1424
1515
|
setContactPointWrapper(newValue);
|
|
1425
1516
|
}
|
|
1426
1517
|
function setUse(use) {
|
|
1427
|
-
const newValue =
|
|
1518
|
+
const newValue = { ...ref.current, use };
|
|
1428
1519
|
if (!use) {
|
|
1429
1520
|
delete newValue.use;
|
|
1430
1521
|
}
|
|
1431
1522
|
setContactPointWrapper(newValue);
|
|
1432
1523
|
}
|
|
1433
1524
|
function setValue(value) {
|
|
1434
|
-
const newValue =
|
|
1525
|
+
const newValue = { ...ref.current, value };
|
|
1435
1526
|
if (!value) {
|
|
1436
1527
|
delete newValue.value;
|
|
1437
1528
|
}
|
|
1438
1529
|
setContactPointWrapper(newValue);
|
|
1439
1530
|
}
|
|
1440
1531
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1441
|
-
React.createElement(core$1.NativeSelect, { "data-testid": "system", defaultValue: contactPoint
|
|
1442
|
-
React.createElement(core$1.NativeSelect, { "data-testid": "use", defaultValue: contactPoint
|
|
1443
|
-
React.createElement(core$1.TextInput, { placeholder: "Value", defaultValue: contactPoint
|
|
1532
|
+
React.createElement(core$1.NativeSelect, { "data-testid": "system", defaultValue: contactPoint?.system, onChange: (e) => setSystem(e.currentTarget.value), data: ['', 'email', 'phone', 'fax', 'pager', 'sms', 'other'] }),
|
|
1533
|
+
React.createElement(core$1.NativeSelect, { "data-testid": "use", defaultValue: contactPoint?.use, onChange: (e) => setUse(e.currentTarget.value), data: ['', 'home', 'work', 'temp', 'old', 'mobile'] }),
|
|
1534
|
+
React.createElement(core$1.TextInput, { placeholder: "Value", defaultValue: contactPoint?.value, onChange: (e) => setValue(e.currentTarget.value) })));
|
|
1444
1535
|
}
|
|
1445
1536
|
|
|
1446
1537
|
function ContactDetailInput(props) {
|
|
1447
|
-
var _a;
|
|
1448
1538
|
const [contactPoint, setContactDetail] = React.useState(props.defaultValue);
|
|
1449
1539
|
const ref = React.useRef();
|
|
1450
1540
|
ref.current = contactPoint;
|
|
@@ -1455,22 +1545,22 @@
|
|
|
1455
1545
|
}
|
|
1456
1546
|
}
|
|
1457
1547
|
function setName(name) {
|
|
1458
|
-
const newValue =
|
|
1548
|
+
const newValue = { ...ref.current, name };
|
|
1459
1549
|
if (!name) {
|
|
1460
1550
|
delete newValue.name;
|
|
1461
1551
|
}
|
|
1462
1552
|
setContactDetailWrapper(newValue);
|
|
1463
1553
|
}
|
|
1464
1554
|
function setTelecom(telecom) {
|
|
1465
|
-
const newValue =
|
|
1555
|
+
const newValue = { ...ref.current, telecom: telecom && [telecom] };
|
|
1466
1556
|
if (!telecom) {
|
|
1467
1557
|
delete newValue.telecom;
|
|
1468
1558
|
}
|
|
1469
1559
|
setContactDetailWrapper(newValue);
|
|
1470
1560
|
}
|
|
1471
1561
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1472
|
-
React.createElement(core$1.TextInput, { "data-testid": props.name + '-name', name: props.name + '-name', placeholder: "Name", style: { width: 180 }, defaultValue: contactPoint
|
|
1473
|
-
React.createElement(ContactPointInput, { name: props.name + '-telecom', defaultValue:
|
|
1562
|
+
React.createElement(core$1.TextInput, { "data-testid": props.name + '-name', name: props.name + '-name', placeholder: "Name", style: { width: 180 }, defaultValue: contactPoint?.name, onChange: (e) => setName(e.currentTarget.value) }),
|
|
1563
|
+
React.createElement(ContactPointInput, { name: props.name + '-telecom', defaultValue: contactPoint?.telecom?.[0], onChange: setTelecom })));
|
|
1474
1564
|
}
|
|
1475
1565
|
|
|
1476
1566
|
/**
|
|
@@ -1545,7 +1635,6 @@
|
|
|
1545
1635
|
}
|
|
1546
1636
|
|
|
1547
1637
|
function HumanNameInput(props) {
|
|
1548
|
-
var _a, _b, _c;
|
|
1549
1638
|
const [value, setValue] = React.useState(props.defaultValue);
|
|
1550
1639
|
const valueRef = React.useRef();
|
|
1551
1640
|
valueRef.current = value;
|
|
@@ -1556,26 +1645,38 @@
|
|
|
1556
1645
|
}
|
|
1557
1646
|
}
|
|
1558
1647
|
function setUse(use) {
|
|
1559
|
-
setValueWrapper(
|
|
1648
|
+
setValueWrapper({ ...valueRef.current, use: use ? use : undefined });
|
|
1560
1649
|
}
|
|
1561
1650
|
function setPrefix(prefix) {
|
|
1562
|
-
setValueWrapper(
|
|
1651
|
+
setValueWrapper({
|
|
1652
|
+
...valueRef.current,
|
|
1653
|
+
prefix: prefix ? prefix.split(' ') : undefined,
|
|
1654
|
+
});
|
|
1563
1655
|
}
|
|
1564
1656
|
function setGiven(given) {
|
|
1565
|
-
setValueWrapper(
|
|
1657
|
+
setValueWrapper({
|
|
1658
|
+
...valueRef.current,
|
|
1659
|
+
given: given ? given.split(' ') : undefined,
|
|
1660
|
+
});
|
|
1566
1661
|
}
|
|
1567
1662
|
function setFamily(family) {
|
|
1568
|
-
setValueWrapper(
|
|
1663
|
+
setValueWrapper({
|
|
1664
|
+
...valueRef.current,
|
|
1665
|
+
family: family ? family : undefined,
|
|
1666
|
+
});
|
|
1569
1667
|
}
|
|
1570
1668
|
function setSuffix(suffix) {
|
|
1571
|
-
setValueWrapper(
|
|
1669
|
+
setValueWrapper({
|
|
1670
|
+
...valueRef.current,
|
|
1671
|
+
suffix: suffix ? suffix.split(' ') : undefined,
|
|
1672
|
+
});
|
|
1572
1673
|
}
|
|
1573
1674
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1574
|
-
React.createElement(core$1.NativeSelect, { defaultValue: value
|
|
1575
|
-
React.createElement(core$1.TextInput, { placeholder: "Prefix", defaultValue:
|
|
1576
|
-
React.createElement(core$1.TextInput, { placeholder: "Given", defaultValue:
|
|
1577
|
-
React.createElement(core$1.TextInput, { placeholder: "Family", defaultValue: value
|
|
1578
|
-
React.createElement(core$1.TextInput, { placeholder: "Suffix", defaultValue:
|
|
1675
|
+
React.createElement(core$1.NativeSelect, { defaultValue: value?.use, "data-testid": "use", onChange: (e) => setUse(e.currentTarget.value), data: ['', 'temp', 'old', 'usual', 'official', 'nickname', 'anonymous', 'maiden'] }),
|
|
1676
|
+
React.createElement(core$1.TextInput, { placeholder: "Prefix", defaultValue: value?.prefix?.join(' '), onChange: (e) => setPrefix(e.currentTarget.value) }),
|
|
1677
|
+
React.createElement(core$1.TextInput, { placeholder: "Given", defaultValue: value?.given?.join(' '), onChange: (e) => setGiven(e.currentTarget.value) }),
|
|
1678
|
+
React.createElement(core$1.TextInput, { placeholder: "Family", defaultValue: value?.family, onChange: (e) => setFamily(e.currentTarget.value) }),
|
|
1679
|
+
React.createElement(core$1.TextInput, { placeholder: "Suffix", defaultValue: value?.suffix?.join(' '), onChange: (e) => setSuffix(e.currentTarget.value) })));
|
|
1579
1680
|
}
|
|
1580
1681
|
|
|
1581
1682
|
function IdentifierInput(props) {
|
|
@@ -1587,8 +1688,55 @@
|
|
|
1587
1688
|
}
|
|
1588
1689
|
}
|
|
1589
1690
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1590
|
-
React.createElement(core$1.TextInput, { placeholder: "System", defaultValue: value
|
|
1591
|
-
React.createElement(core$1.TextInput, { placeholder: "Value", defaultValue: value
|
|
1691
|
+
React.createElement(core$1.TextInput, { placeholder: "System", defaultValue: value?.system, onChange: (e) => setValueWrapper({ ...value, system: e.currentTarget.value }) }),
|
|
1692
|
+
React.createElement(core$1.TextInput, { placeholder: "Value", defaultValue: value?.value, onChange: (e) => setValueWrapper({ ...value, value: e.currentTarget.value }) })));
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
/*
|
|
1696
|
+
* Based on: https://github.com/mantinedev/ui.mantine.dev/blob/master/components/CurrencyInput/CurrencyInput.tsx
|
|
1697
|
+
*/
|
|
1698
|
+
/**
|
|
1699
|
+
* List of currencies.
|
|
1700
|
+
*
|
|
1701
|
+
* Full list of currencies:
|
|
1702
|
+
* https://www.hl7.org/fhir/valueset-currencies.html
|
|
1703
|
+
*
|
|
1704
|
+
* Latest browsers can report list of supported currencies, but it's not widely supported:
|
|
1705
|
+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf
|
|
1706
|
+
*
|
|
1707
|
+
* Using a short list for simplicity for now.
|
|
1708
|
+
*/
|
|
1709
|
+
const data = ['USD', 'EUR', 'CAD', 'GBP', 'AUD'];
|
|
1710
|
+
function MoneyInput(props) {
|
|
1711
|
+
const { onChange } = props;
|
|
1712
|
+
const [value, setValue] = React.useState(props.defaultValue);
|
|
1713
|
+
const setValueWrapper = React.useCallback((newValue) => {
|
|
1714
|
+
setValue(newValue);
|
|
1715
|
+
if (onChange) {
|
|
1716
|
+
onChange(newValue);
|
|
1717
|
+
}
|
|
1718
|
+
}, [onChange]);
|
|
1719
|
+
const handleCurrencyChange = React.useCallback((e) => {
|
|
1720
|
+
setValueWrapper({
|
|
1721
|
+
...value,
|
|
1722
|
+
currency: e.currentTarget.value,
|
|
1723
|
+
});
|
|
1724
|
+
}, [value, setValueWrapper]);
|
|
1725
|
+
const handleValueChange = React.useCallback((e) => {
|
|
1726
|
+
setValueWrapper({
|
|
1727
|
+
...value,
|
|
1728
|
+
value: e.currentTarget.valueAsNumber,
|
|
1729
|
+
});
|
|
1730
|
+
}, [value, setValueWrapper]);
|
|
1731
|
+
const select = (React.createElement(core$1.NativeSelect, { defaultValue: value?.currency, data: data, styles: {
|
|
1732
|
+
input: {
|
|
1733
|
+
fontWeight: 500,
|
|
1734
|
+
borderTopLeftRadius: 0,
|
|
1735
|
+
borderBottomLeftRadius: 0,
|
|
1736
|
+
width: 92,
|
|
1737
|
+
},
|
|
1738
|
+
}, onChange: handleCurrencyChange }));
|
|
1739
|
+
return (React.createElement(core$1.TextInput, { type: "number", label: props.label, placeholder: props.placeholder || 'Value', defaultValue: value?.value?.toString() || 'USD', icon: React.createElement(icons.IconCurrencyDollar, { size: 14 }), rightSection: select, rightSectionWidth: 92, onChange: handleValueChange }));
|
|
1592
1740
|
}
|
|
1593
1741
|
|
|
1594
1742
|
function PeriodInput(props) {
|
|
@@ -1600,12 +1748,11 @@
|
|
|
1600
1748
|
}
|
|
1601
1749
|
}
|
|
1602
1750
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1603
|
-
React.createElement(DateTimeInput, { name: props.name + '.start', placeholder: "Start", defaultValue: value
|
|
1604
|
-
React.createElement(DateTimeInput, { name: props.name + '.end', placeholder: "End", defaultValue: value
|
|
1751
|
+
React.createElement(DateTimeInput, { name: props.name + '.start', placeholder: "Start", defaultValue: value?.start, onChange: (newValue) => setValueWrapper({ ...value, start: newValue }) }),
|
|
1752
|
+
React.createElement(DateTimeInput, { name: props.name + '.end', placeholder: "End", defaultValue: value?.end, onChange: (newValue) => setValueWrapper({ ...value, end: newValue }) })));
|
|
1605
1753
|
}
|
|
1606
1754
|
|
|
1607
1755
|
function QuantityInput(props) {
|
|
1608
|
-
var _a;
|
|
1609
1756
|
const [value, setValue] = React.useState(props.defaultValue);
|
|
1610
1757
|
function setValueWrapper(newValue) {
|
|
1611
1758
|
setValue(newValue);
|
|
@@ -1614,9 +1761,18 @@
|
|
|
1614
1761
|
}
|
|
1615
1762
|
}
|
|
1616
1763
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1617
|
-
React.createElement(core$1.NativeSelect, { style: { width: 80 }, "data-testid": props.name + '-comparator', defaultValue: value
|
|
1618
|
-
|
|
1619
|
-
|
|
1764
|
+
React.createElement(core$1.NativeSelect, { style: { width: 80 }, "data-testid": props.name + '-comparator', defaultValue: value?.comparator, data: ['', '<', '<=', '>=', '>'], onChange: (e) => setValueWrapper({
|
|
1765
|
+
...value,
|
|
1766
|
+
comparator: e.currentTarget.value,
|
|
1767
|
+
}) }),
|
|
1768
|
+
React.createElement(core$1.TextInput, { id: props.name, name: props.name, "data-testid": props.name + '-value', type: "number", step: "any", placeholder: "Value", defaultValue: value?.value?.toString(), onChange: (e) => setValueWrapper({
|
|
1769
|
+
...value,
|
|
1770
|
+
value: tryParseNumber(e.currentTarget.value),
|
|
1771
|
+
}) }),
|
|
1772
|
+
React.createElement(core$1.TextInput, { placeholder: "Unit", "data-testid": props.name + '-unit', defaultValue: value?.unit, onChange: (e) => setValueWrapper({
|
|
1773
|
+
...value,
|
|
1774
|
+
unit: e.currentTarget.value,
|
|
1775
|
+
}) })));
|
|
1620
1776
|
}
|
|
1621
1777
|
function tryParseNumber(str) {
|
|
1622
1778
|
if (!str) {
|
|
@@ -1640,8 +1796,14 @@
|
|
|
1640
1796
|
}
|
|
1641
1797
|
}
|
|
1642
1798
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1643
|
-
React.createElement(QuantityInput, { name: props.name + '-low', defaultValue: value
|
|
1644
|
-
|
|
1799
|
+
React.createElement(QuantityInput, { name: props.name + '-low', defaultValue: value?.low, onChange: (v) => setValueWrapper({
|
|
1800
|
+
...value,
|
|
1801
|
+
low: v,
|
|
1802
|
+
}) }),
|
|
1803
|
+
React.createElement(QuantityInput, { name: props.name + '-high', defaultValue: value?.high, onChange: (v) => setValueWrapper({
|
|
1804
|
+
...value,
|
|
1805
|
+
high: v,
|
|
1806
|
+
}) })));
|
|
1645
1807
|
}
|
|
1646
1808
|
|
|
1647
1809
|
/**
|
|
@@ -1659,24 +1821,29 @@
|
|
|
1659
1821
|
}
|
|
1660
1822
|
}
|
|
1661
1823
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1662
|
-
React.createElement(QuantityInput, { name: props.name + '-numerator', defaultValue: value
|
|
1663
|
-
|
|
1824
|
+
React.createElement(QuantityInput, { name: props.name + '-numerator', defaultValue: value?.numerator, onChange: (v) => setValueWrapper({
|
|
1825
|
+
...value,
|
|
1826
|
+
numerator: v,
|
|
1827
|
+
}) }),
|
|
1828
|
+
React.createElement(QuantityInput, { name: props.name + '-denominator', defaultValue: value?.denominator, onChange: (v) => setValueWrapper({
|
|
1829
|
+
...value,
|
|
1830
|
+
denominator: v,
|
|
1831
|
+
}) })));
|
|
1664
1832
|
}
|
|
1665
1833
|
|
|
1666
1834
|
function ResourceAvatar(props) {
|
|
1667
|
-
var _a, _b, _c;
|
|
1668
1835
|
const resource = useResource(props.value);
|
|
1669
|
-
const text = resource ? core.getDisplayString(resource) :
|
|
1670
|
-
const imageUrl = (
|
|
1671
|
-
const radius =
|
|
1672
|
-
const avatarProps =
|
|
1836
|
+
const text = resource ? core.getDisplayString(resource) : props.alt ?? '';
|
|
1837
|
+
const imageUrl = (resource && core.getImageSrc(resource)) ?? props.src;
|
|
1838
|
+
const radius = props.radius ?? 'xl';
|
|
1839
|
+
const avatarProps = { ...props };
|
|
1673
1840
|
delete avatarProps.value;
|
|
1674
1841
|
delete avatarProps.link;
|
|
1675
1842
|
if (props.link) {
|
|
1676
1843
|
return (React.createElement(MedplumLink, { to: resource },
|
|
1677
|
-
React.createElement(core$1.Avatar,
|
|
1844
|
+
React.createElement(core$1.Avatar, { src: imageUrl, alt: text, radius: radius, ...avatarProps })));
|
|
1678
1845
|
}
|
|
1679
|
-
return React.createElement(core$1.Avatar,
|
|
1846
|
+
return React.createElement(core$1.Avatar, { src: imageUrl, alt: text, radius: radius, ...avatarProps });
|
|
1680
1847
|
}
|
|
1681
1848
|
|
|
1682
1849
|
/**
|
|
@@ -1694,7 +1861,7 @@
|
|
|
1694
1861
|
Observation: 'code',
|
|
1695
1862
|
RequestGroup: '_id',
|
|
1696
1863
|
ActivityDefinition: 'name',
|
|
1697
|
-
User: 'email',
|
|
1864
|
+
User: 'email:contains',
|
|
1698
1865
|
};
|
|
1699
1866
|
function ResourceInput(props) {
|
|
1700
1867
|
const medplum = useMedplum();
|
|
@@ -1707,24 +1874,20 @@
|
|
|
1707
1874
|
setValue(core.getDisplayString(defaultValue));
|
|
1708
1875
|
}
|
|
1709
1876
|
}, [defaultValue, setValue]);
|
|
1710
|
-
function loadValues(input) {
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
_count: '10',
|
|
1717
|
-
});
|
|
1718
|
-
const resources = yield medplum.searchResources(props.resourceType, searchParams);
|
|
1719
|
-
setData(resources.map((resource) => ({ value: core.getDisplayString(resource), resource })));
|
|
1720
|
-
setLoading(false);
|
|
1877
|
+
async function loadValues(input) {
|
|
1878
|
+
setLoading(true);
|
|
1879
|
+
const searchCode = SEARCH_CODES[props.resourceType] || 'name';
|
|
1880
|
+
const searchParams = new URLSearchParams({
|
|
1881
|
+
[searchCode]: input,
|
|
1882
|
+
_count: '10',
|
|
1721
1883
|
});
|
|
1884
|
+
const resources = await medplum.searchResources(props.resourceType, searchParams);
|
|
1885
|
+
setData(resources.map((resource) => ({ value: core.getDisplayString(resource), resource })));
|
|
1886
|
+
setLoading(false);
|
|
1722
1887
|
}
|
|
1723
|
-
function handleChange(val) {
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
return loadValues(val);
|
|
1727
|
-
});
|
|
1888
|
+
async function handleChange(val) {
|
|
1889
|
+
setValue(val);
|
|
1890
|
+
return loadValues(val);
|
|
1728
1891
|
}
|
|
1729
1892
|
function handleSelect(item) {
|
|
1730
1893
|
setValue(item.value);
|
|
@@ -1735,9 +1898,8 @@
|
|
|
1735
1898
|
}
|
|
1736
1899
|
return (React.createElement(core$1.Autocomplete, { itemComponent: ItemComponent, value: value, data: data, placeholder: props.placeholder, onFocus: () => loadValues(value), onChange: handleChange, onItemSubmit: handleSelect, rightSection: loading ? React.createElement(core$1.Loader, { size: 16 }) : null }));
|
|
1737
1900
|
}
|
|
1738
|
-
const ItemComponent = React.forwardRef((
|
|
1739
|
-
|
|
1740
|
-
return (React.createElement("div", Object.assign({ ref: ref }, others),
|
|
1901
|
+
const ItemComponent = React.forwardRef(({ value, resource, ...others }, ref) => {
|
|
1902
|
+
return (React.createElement("div", { ref: ref, ...others },
|
|
1741
1903
|
React.createElement(core$1.Group, { noWrap: true },
|
|
1742
1904
|
React.createElement(ResourceAvatar, { value: resource }),
|
|
1743
1905
|
React.createElement("div", null,
|
|
@@ -1746,7 +1908,7 @@
|
|
|
1746
1908
|
});
|
|
1747
1909
|
|
|
1748
1910
|
function ReferenceInput(props) {
|
|
1749
|
-
const targetTypes = props.targetTypes;
|
|
1911
|
+
const targetTypes = getTargetTypes$1(props.targetTypes);
|
|
1750
1912
|
const initialResourceType = getInitialResourceType(props.defaultValue, targetTypes);
|
|
1751
1913
|
const [value, setValue] = React.useState(props.defaultValue);
|
|
1752
1914
|
const [resourceType, setResourceType] = React.useState(initialResourceType);
|
|
@@ -1766,9 +1928,14 @@
|
|
|
1766
1928
|
setValueHelper(item ? core.createReference(item) : undefined);
|
|
1767
1929
|
} })));
|
|
1768
1930
|
}
|
|
1931
|
+
function getTargetTypes$1(targetTypes) {
|
|
1932
|
+
if (!targetTypes || targetTypes.length === 0 || (targetTypes.length === 1 && targetTypes[0] === 'Resource')) {
|
|
1933
|
+
return undefined;
|
|
1934
|
+
}
|
|
1935
|
+
return targetTypes;
|
|
1936
|
+
}
|
|
1769
1937
|
function getInitialResourceType(defaultValue, targetTypes) {
|
|
1770
|
-
|
|
1771
|
-
const defaultValueResourceType = (_a = defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.reference) === null || _a === void 0 ? void 0 : _a.split('/')[0];
|
|
1938
|
+
const defaultValueResourceType = defaultValue?.reference?.split('/')[0];
|
|
1772
1939
|
if (defaultValueResourceType) {
|
|
1773
1940
|
return defaultValueResourceType;
|
|
1774
1941
|
}
|
|
@@ -1839,23 +2006,20 @@
|
|
|
1839
2006
|
}, onCancel: () => setOpen(false) })));
|
|
1840
2007
|
}
|
|
1841
2008
|
function TimingEditorDialog(props) {
|
|
1842
|
-
var _a, _b;
|
|
1843
2009
|
const [value, setValue] = React.useState(props.defaultValue || {});
|
|
1844
2010
|
const valueRef = React.useRef();
|
|
1845
2011
|
valueRef.current = value;
|
|
1846
2012
|
function setStart(newStart) {
|
|
1847
|
-
setValue(
|
|
2013
|
+
setValue({ ...valueRef.current, event: [newStart] });
|
|
1848
2014
|
}
|
|
1849
2015
|
function setRepeat(repeat) {
|
|
1850
|
-
setValue(
|
|
2016
|
+
setValue({ ...valueRef.current, repeat });
|
|
1851
2017
|
}
|
|
1852
2018
|
function setPeriod(newPeriod) {
|
|
1853
|
-
|
|
1854
|
-
setRepeat(Object.assign(Object.assign({}, (_a = valueRef.current) === null || _a === void 0 ? void 0 : _a.repeat), { period: newPeriod }));
|
|
2019
|
+
setRepeat({ ...valueRef.current?.repeat, period: newPeriod });
|
|
1855
2020
|
}
|
|
1856
2021
|
function setPeriodUnit(newPeriodUnit) {
|
|
1857
|
-
|
|
1858
|
-
setRepeat(Object.assign(Object.assign({}, (_a = valueRef.current) === null || _a === void 0 ? void 0 : _a.repeat), { periodUnit: newPeriodUnit }));
|
|
2022
|
+
setRepeat({ ...valueRef.current?.repeat, periodUnit: newPeriodUnit });
|
|
1859
2023
|
}
|
|
1860
2024
|
function setDayOfWeek(day, enabled) {
|
|
1861
2025
|
if (enabled) {
|
|
@@ -1866,17 +2030,15 @@
|
|
|
1866
2030
|
}
|
|
1867
2031
|
}
|
|
1868
2032
|
function addDayOfWeek(day) {
|
|
1869
|
-
|
|
1870
|
-
const existing = ((_b = (_a = valueRef.current) === null || _a === void 0 ? void 0 : _a.repeat) === null || _b === void 0 ? void 0 : _b.dayOfWeek) || [];
|
|
2033
|
+
const existing = valueRef.current?.repeat?.dayOfWeek || [];
|
|
1871
2034
|
if (!existing.includes(day)) {
|
|
1872
|
-
setRepeat(
|
|
2035
|
+
setRepeat({ ...valueRef.current?.repeat, dayOfWeek: [...existing, day] });
|
|
1873
2036
|
}
|
|
1874
2037
|
}
|
|
1875
2038
|
function removeDayOfWeek(day) {
|
|
1876
|
-
|
|
1877
|
-
const existing = ((_b = (_a = valueRef.current) === null || _a === void 0 ? void 0 : _a.repeat) === null || _b === void 0 ? void 0 : _b.dayOfWeek) || [];
|
|
2039
|
+
const existing = valueRef.current?.repeat?.dayOfWeek || [];
|
|
1878
2040
|
if (existing.includes(day)) {
|
|
1879
|
-
setRepeat(
|
|
2041
|
+
setRepeat({ ...valueRef.current?.repeat, dayOfWeek: existing.filter((d) => d !== day) });
|
|
1880
2042
|
}
|
|
1881
2043
|
}
|
|
1882
2044
|
return (React.createElement(core$1.Modal, { title: "Timing", closeButtonLabel: "Close", opened: props.visible, onClose: () => props.onCancel() },
|
|
@@ -1885,8 +2047,8 @@
|
|
|
1885
2047
|
React.createElement(DateTimeInput, { name: 'timing-dialog-start', onChange: (newValue) => setStart(newValue) })),
|
|
1886
2048
|
React.createElement(FormSection, { title: "Repeat every", htmlFor: 'timing-dialog-period' },
|
|
1887
2049
|
React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1888
|
-
React.createElement(core$1.TextInput, { type: "number", step: 1, id: "timing-dialog-period", name: "timing-dialog-period", defaultValue:
|
|
1889
|
-
React.createElement(core$1.NativeSelect, { id: "timing-dialog-periodUnit", name: "timing-dialog-periodUnit", defaultValue:
|
|
2050
|
+
React.createElement(core$1.TextInput, { type: "number", step: 1, id: "timing-dialog-period", name: "timing-dialog-period", defaultValue: value?.repeat?.period, onChange: (e) => setPeriod(parseInt(e.currentTarget.value)) }),
|
|
2051
|
+
React.createElement(core$1.NativeSelect, { id: "timing-dialog-periodUnit", name: "timing-dialog-periodUnit", defaultValue: value?.repeat?.periodUnit, onChange: (e) => setPeriodUnit(e.currentTarget.value), data: [
|
|
1890
2052
|
{ label: 'day', value: 'd' },
|
|
1891
2053
|
{ label: 'week', value: 'wk' },
|
|
1892
2054
|
{ label: 'month', value: 'mo' },
|
|
@@ -1900,9 +2062,8 @@
|
|
|
1900
2062
|
}
|
|
1901
2063
|
|
|
1902
2064
|
function ResourcePropertyInput(props) {
|
|
1903
|
-
var _a, _b, _c;
|
|
1904
2065
|
const property = props.property;
|
|
1905
|
-
const propertyType =
|
|
2066
|
+
const propertyType = props.defaultPropertyType ?? property.type?.[0]?.code;
|
|
1906
2067
|
const name = props.name;
|
|
1907
2068
|
const value = props.defaultValue;
|
|
1908
2069
|
if (property.max === '*' && !props.arrayElement) {
|
|
@@ -1913,10 +2074,10 @@
|
|
|
1913
2074
|
}
|
|
1914
2075
|
const propertyTypes = property.type;
|
|
1915
2076
|
if (propertyTypes.length > 1) {
|
|
1916
|
-
return React.createElement(ElementDefinitionInputSelector,
|
|
2077
|
+
return React.createElement(ElementDefinitionInputSelector, { elementDefinitionTypes: propertyTypes, ...props });
|
|
1917
2078
|
}
|
|
1918
2079
|
else {
|
|
1919
|
-
return React.createElement(ElementDefinitionTypeInput,
|
|
2080
|
+
return React.createElement(ElementDefinitionTypeInput, { elementDefinitionType: propertyTypes[0], ...props });
|
|
1920
2081
|
}
|
|
1921
2082
|
}
|
|
1922
2083
|
function ElementDefinitionInputSelector(props) {
|
|
@@ -1930,20 +2091,19 @@
|
|
|
1930
2091
|
}
|
|
1931
2092
|
const [selectedType, setSelectedType] = React.useState(initialPropertyType);
|
|
1932
2093
|
return (React.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1933
|
-
React.createElement(core$1.NativeSelect, { style: { width: '200px' }, defaultValue: selectedType
|
|
2094
|
+
React.createElement(core$1.NativeSelect, { style: { width: '200px' }, defaultValue: selectedType?.code, onChange: (e) => {
|
|
1934
2095
|
setSelectedType(propertyTypes.find((type) => type.code === e.currentTarget.value));
|
|
1935
2096
|
}, data: propertyTypes.map((type) => ({
|
|
1936
2097
|
value: type.code,
|
|
1937
2098
|
label: type.code,
|
|
1938
2099
|
})) }),
|
|
1939
|
-
React.createElement(ElementDefinitionTypeInput,
|
|
2100
|
+
React.createElement(ElementDefinitionTypeInput, { ...props, elementDefinitionType: selectedType, onChange: (newValue) => {
|
|
1940
2101
|
if (props.onChange) {
|
|
1941
2102
|
props.onChange(newValue, props.name.replace('[x]', core.capitalize(selectedType.code)));
|
|
1942
2103
|
}
|
|
1943
|
-
} })))
|
|
2104
|
+
} })));
|
|
1944
2105
|
}
|
|
1945
2106
|
function ElementDefinitionTypeInput(props) {
|
|
1946
|
-
var _a;
|
|
1947
2107
|
const property = props.property;
|
|
1948
2108
|
const propertyType = props.elementDefinitionType.code;
|
|
1949
2109
|
const name = props.name;
|
|
@@ -2016,6 +2176,8 @@
|
|
|
2016
2176
|
return React.createElement(HumanNameInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2017
2177
|
case core.PropertyType.Identifier:
|
|
2018
2178
|
return React.createElement(IdentifierInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2179
|
+
case core.PropertyType.Money:
|
|
2180
|
+
return React.createElement(MoneyInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2019
2181
|
case core.PropertyType.Period:
|
|
2020
2182
|
return React.createElement(PeriodInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2021
2183
|
case core.PropertyType.Duration:
|
|
@@ -2033,17 +2195,15 @@
|
|
|
2033
2195
|
case core.PropertyType.UsageContext:
|
|
2034
2196
|
return (React.createElement(BackboneElementInput, { typeName: propertyType, defaultValue: value, onChange: props.onChange, outcome: props.outcome }));
|
|
2035
2197
|
default:
|
|
2036
|
-
return (React.createElement(BackboneElementInput, { typeName: core.buildTypeName(
|
|
2198
|
+
return (React.createElement(BackboneElementInput, { typeName: core.buildTypeName(property.path?.split('.')), defaultValue: value, onChange: props.onChange, outcome: props.outcome }));
|
|
2037
2199
|
}
|
|
2038
2200
|
}
|
|
2039
2201
|
function getTargetTypes(property) {
|
|
2040
|
-
|
|
2041
|
-
return (_c = (_b = (_a = property === null || property === void 0 ? void 0 : property.type) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.targetProfile) === null || _c === void 0 ? void 0 : _c.map((p) => p.split('/').pop());
|
|
2202
|
+
return property?.type?.[0]?.targetProfile?.map((p) => p.split('/').pop());
|
|
2042
2203
|
}
|
|
2043
2204
|
|
|
2044
2205
|
function BackboneElementInput(props) {
|
|
2045
|
-
|
|
2046
|
-
const [value, setValue] = React.useState((_a = props.defaultValue) !== null && _a !== void 0 ? _a : {});
|
|
2206
|
+
const [value, setValue] = React.useState(props.defaultValue ?? {});
|
|
2047
2207
|
function setValueWrapper(newValue) {
|
|
2048
2208
|
setValue(newValue);
|
|
2049
2209
|
if (props.onChange) {
|
|
@@ -2071,12 +2231,12 @@
|
|
|
2071
2231
|
if (property.type.length === 1 && property.type[0].code === 'boolean') {
|
|
2072
2232
|
return (React.createElement(CheckboxFormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key },
|
|
2073
2233
|
React.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
|
|
2074
|
-
setValueWrapper(setPropertyValue(value, key, propName
|
|
2234
|
+
setValueWrapper(setPropertyValue(value, key, propName ?? key, entry[1], newValue));
|
|
2075
2235
|
} })));
|
|
2076
2236
|
}
|
|
2077
2237
|
return (React.createElement(FormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key, outcome: props.outcome },
|
|
2078
2238
|
React.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
|
|
2079
|
-
setValueWrapper(setPropertyValue(value, key, propName
|
|
2239
|
+
setValueWrapper(setPropertyValue(value, key, propName ?? key, entry[1], newValue));
|
|
2080
2240
|
} })));
|
|
2081
2241
|
})));
|
|
2082
2242
|
}
|
|
@@ -2210,13 +2370,13 @@
|
|
|
2210
2370
|
}
|
|
2211
2371
|
|
|
2212
2372
|
function ResourceName(props) {
|
|
2213
|
-
const { value, link
|
|
2373
|
+
const { value, link, ...rest } = props;
|
|
2214
2374
|
const resource = useResource(value);
|
|
2215
2375
|
if (!resource) {
|
|
2216
2376
|
return null;
|
|
2217
2377
|
}
|
|
2218
2378
|
const text = core.getDisplayString(resource);
|
|
2219
|
-
return link ? (React.createElement(MedplumLink,
|
|
2379
|
+
return link ? (React.createElement(MedplumLink, { to: resource, ...rest }, text)) : (React.createElement(core$1.Text, { component: "span", ...rest }, text));
|
|
2220
2380
|
}
|
|
2221
2381
|
|
|
2222
2382
|
function ResourceBadge(props) {
|
|
@@ -2225,6 +2385,64 @@
|
|
|
2225
2385
|
React.createElement(ResourceName, { value: props.value, link: props.link })));
|
|
2226
2386
|
}
|
|
2227
2387
|
|
|
2388
|
+
/*
|
|
2389
|
+
* Request status: https://hl7.org/fhir/valueset-request-status.html
|
|
2390
|
+
* draft, active, on-hold, revoked, completed, entered-in-error, unknown
|
|
2391
|
+
*
|
|
2392
|
+
* Publication status: https://hl7.org/fhir/valueset-publication-status.html
|
|
2393
|
+
* draft, active, retired, unknown
|
|
2394
|
+
*
|
|
2395
|
+
* Observation status: https://www.hl7.org/fhir/valueset-observation-status.html
|
|
2396
|
+
* registered, preliminary, final, amended, corrected, cancelled, entered-in-error, unknown
|
|
2397
|
+
*
|
|
2398
|
+
* DiagnosticReport status: https://hl7.org/fhir/valueset-diagnostic-report-status.html
|
|
2399
|
+
* registered, preliminary, final, amended, corrected, appended, cancelled, entered-in-error, unknown
|
|
2400
|
+
*
|
|
2401
|
+
* Task status: https://hl7.org/fhir/valueset-task-status.html
|
|
2402
|
+
* draft, requested, received, accepted, rejected, ready, cancelled, in-progress, on-hold, failed, completed, entered-in-error
|
|
2403
|
+
*
|
|
2404
|
+
* Appointment status: https://www.hl7.org/fhir/valueset-appointmentstatus.html
|
|
2405
|
+
* proposed, pending, booked, arrived, fulfilled, cancelled, noshow, entered-in-error, chcked-in, waitlist
|
|
2406
|
+
*/
|
|
2407
|
+
const statusToColor = {
|
|
2408
|
+
draft: 'blue',
|
|
2409
|
+
active: 'blue',
|
|
2410
|
+
'on-hold': 'yellow',
|
|
2411
|
+
revoked: 'red',
|
|
2412
|
+
completed: 'green',
|
|
2413
|
+
'entered-in-error': 'red',
|
|
2414
|
+
unknown: 'gray',
|
|
2415
|
+
retired: 'gray',
|
|
2416
|
+
registered: 'blue',
|
|
2417
|
+
preliminary: 'blue',
|
|
2418
|
+
final: 'green',
|
|
2419
|
+
amended: 'yellow',
|
|
2420
|
+
corrected: 'yellow',
|
|
2421
|
+
cancelled: 'red',
|
|
2422
|
+
requested: 'blue',
|
|
2423
|
+
received: 'blue',
|
|
2424
|
+
accepted: 'blue',
|
|
2425
|
+
rejected: 'red',
|
|
2426
|
+
ready: 'blue',
|
|
2427
|
+
'in-progress': 'blue',
|
|
2428
|
+
failed: 'red',
|
|
2429
|
+
proposed: 'blue',
|
|
2430
|
+
pending: 'blue',
|
|
2431
|
+
booked: 'blue',
|
|
2432
|
+
arrived: 'blue',
|
|
2433
|
+
fulfilled: 'green',
|
|
2434
|
+
noshow: 'red',
|
|
2435
|
+
'checked-in': 'blue',
|
|
2436
|
+
waitlist: 'gray',
|
|
2437
|
+
routine: 'gray',
|
|
2438
|
+
urgent: 'red',
|
|
2439
|
+
asap: 'red',
|
|
2440
|
+
stat: 'red',
|
|
2441
|
+
};
|
|
2442
|
+
function StatusBadge(props) {
|
|
2443
|
+
return React.createElement(core$1.Badge, { color: statusToColor[props.status] }, props.status);
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2228
2446
|
const useStyles$9 = core$1.createStyles((theme) => ({
|
|
2229
2447
|
table: {
|
|
2230
2448
|
border: `0.1px solid ${theme.colors.gray[5]}`,
|
|
@@ -2245,20 +2463,19 @@
|
|
|
2245
2463
|
},
|
|
2246
2464
|
}));
|
|
2247
2465
|
function DiagnosticReportDisplay(props) {
|
|
2248
|
-
var _a, _b;
|
|
2249
2466
|
const diagnosticReport = useResource(props.value);
|
|
2250
|
-
const specimen = useResource(
|
|
2467
|
+
const specimen = useResource(diagnosticReport?.specimen?.[0]);
|
|
2251
2468
|
if (!diagnosticReport) {
|
|
2252
2469
|
return null;
|
|
2253
2470
|
}
|
|
2254
2471
|
let textContent = '';
|
|
2255
2472
|
if (diagnosticReport.presentedForm && diagnosticReport.presentedForm.length > 0) {
|
|
2256
2473
|
const pf = diagnosticReport.presentedForm[0];
|
|
2257
|
-
if (
|
|
2474
|
+
if (pf.contentType?.startsWith('text/plain') && pf.data) {
|
|
2258
2475
|
textContent = window.atob(pf.data);
|
|
2259
2476
|
}
|
|
2260
2477
|
}
|
|
2261
|
-
if (specimen
|
|
2478
|
+
if (specimen?.note) {
|
|
2262
2479
|
for (const note of specimen.note) {
|
|
2263
2480
|
textContent += note.text + '\n\n';
|
|
2264
2481
|
}
|
|
@@ -2285,7 +2502,6 @@
|
|
|
2285
2502
|
textContent && React.createElement("pre", null, textContent.trim())));
|
|
2286
2503
|
}
|
|
2287
2504
|
function ObservationTable(props) {
|
|
2288
|
-
var _a;
|
|
2289
2505
|
const { classes } = useStyles$9();
|
|
2290
2506
|
return (React.createElement("table", { className: classes.table },
|
|
2291
2507
|
React.createElement("thead", null,
|
|
@@ -2293,8 +2509,10 @@
|
|
|
2293
2509
|
React.createElement("th", null, "Test"),
|
|
2294
2510
|
React.createElement("th", null, "Value"),
|
|
2295
2511
|
React.createElement("th", null, "Reference Range"),
|
|
2296
|
-
React.createElement("th", null, "Interpretation")
|
|
2297
|
-
|
|
2512
|
+
React.createElement("th", null, "Interpretation"),
|
|
2513
|
+
React.createElement("th", null, "Category"),
|
|
2514
|
+
React.createElement("th", null, "Status"))),
|
|
2515
|
+
React.createElement("tbody", null, props.value?.map((observation, index) => (React.createElement(ObservationRow, { key: 'obs-' + index, value: observation }))))));
|
|
2298
2516
|
}
|
|
2299
2517
|
function ObservationRow(props) {
|
|
2300
2518
|
const { classes, cx } = useStyles$9();
|
|
@@ -2311,7 +2529,10 @@
|
|
|
2311
2529
|
React.createElement(ObservationValueDisplay, { value: observation })),
|
|
2312
2530
|
React.createElement("td", null,
|
|
2313
2531
|
React.createElement(ReferenceRangeDisplay, { value: observation.referenceRange })),
|
|
2314
|
-
React.createElement("td", null, observation.interpretation && observation.interpretation.length > 0 && (React.createElement(CodeableConceptDisplay, { value: observation.interpretation[0] })))
|
|
2532
|
+
React.createElement("td", null, observation.interpretation && observation.interpretation.length > 0 && (React.createElement(CodeableConceptDisplay, { value: observation.interpretation[0] }))),
|
|
2533
|
+
React.createElement("td", null, observation.category && observation.category.length > 0 && (React.createElement("ul", null, observation.category.map((concept, index) => (React.createElement("li", { key: `category-${index}` },
|
|
2534
|
+
React.createElement(CodeableConceptDisplay, { value: concept }))))))),
|
|
2535
|
+
React.createElement("td", null, observation.status && React.createElement(StatusBadge, { status: observation.status }))));
|
|
2315
2536
|
}
|
|
2316
2537
|
function ObservationValueDisplay(props) {
|
|
2317
2538
|
const obs = props.value;
|
|
@@ -2334,8 +2555,7 @@
|
|
|
2334
2555
|
* @returns True if the FHIR observation is a critical value.
|
|
2335
2556
|
*/
|
|
2336
2557
|
function isCritical(observation) {
|
|
2337
|
-
|
|
2338
|
-
const code = (_d = (_c = (_b = (_a = observation.interpretation) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.coding) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.code;
|
|
2558
|
+
const code = observation.interpretation?.[0]?.coding?.[0]?.code;
|
|
2339
2559
|
return code === 'AA' || code === 'LL' || code === 'HH' || code === 'A';
|
|
2340
2560
|
}
|
|
2341
2561
|
|
|
@@ -2453,17 +2673,16 @@
|
|
|
2453
2673
|
return React.createElement(Container, null, props.children);
|
|
2454
2674
|
}
|
|
2455
2675
|
function TimelineItem(props) {
|
|
2456
|
-
|
|
2457
|
-
const
|
|
2458
|
-
|
|
2459
|
-
return (React.createElement(Panel, Object.assign({ "data-testid": "timeline-item", fill: true }, others),
|
|
2676
|
+
const { resource, profile, padding, popupMenuItems, ...others } = props;
|
|
2677
|
+
const author = profile ?? resource.meta?.author;
|
|
2678
|
+
return (React.createElement(Panel, { "data-testid": "timeline-item", fill: true, ...others },
|
|
2460
2679
|
React.createElement(core$1.Group, { position: "apart", spacing: 8, mx: "xs", my: "sm" },
|
|
2461
2680
|
React.createElement(ResourceAvatar, { value: author, link: true, size: "md" }),
|
|
2462
2681
|
React.createElement("div", { style: { flex: 1 } },
|
|
2463
2682
|
React.createElement(core$1.Text, { size: "sm" },
|
|
2464
2683
|
React.createElement(ResourceName, { color: "dark", weight: 500, value: author, link: true })),
|
|
2465
2684
|
React.createElement(core$1.Text, { size: "xs" },
|
|
2466
|
-
React.createElement(MedplumLink, { color: "dimmed", to: props.resource }, core.formatDateTime(
|
|
2685
|
+
React.createElement(MedplumLink, { color: "dimmed", to: props.resource }, core.formatDateTime(props.resource.meta?.lastUpdated)),
|
|
2467
2686
|
React.createElement(core$1.Text, { component: "span", color: "dimmed", mx: 8 }, "\u00B7"),
|
|
2468
2687
|
React.createElement(MedplumLink, { color: "dimmed", to: props.resource }, props.resource.resourceType))),
|
|
2469
2688
|
popupMenuItems && (React.createElement(core$1.Menu, { position: "bottom-end", shadow: "md", width: 200 },
|
|
@@ -2502,7 +2721,6 @@
|
|
|
2502
2721
|
return 0;
|
|
2503
2722
|
}
|
|
2504
2723
|
function getTime(resource) {
|
|
2505
|
-
var _a;
|
|
2506
2724
|
if (resource.resourceType === 'Communication' && resource.sent) {
|
|
2507
2725
|
return new Date(resource.sent).getTime();
|
|
2508
2726
|
}
|
|
@@ -2515,7 +2733,7 @@
|
|
|
2515
2733
|
if (resource.resourceType === 'DocumentReference' && resource.date) {
|
|
2516
2734
|
return new Date(resource.date).getTime();
|
|
2517
2735
|
}
|
|
2518
|
-
const dateTime =
|
|
2736
|
+
const dateTime = resource.meta?.lastUpdated;
|
|
2519
2737
|
if (!dateTime) {
|
|
2520
2738
|
return 0;
|
|
2521
2739
|
}
|
|
@@ -2634,7 +2852,7 @@
|
|
|
2634
2852
|
}));
|
|
2635
2853
|
}
|
|
2636
2854
|
function setPriority(communication, priority) {
|
|
2637
|
-
return medplum.updateResource(
|
|
2855
|
+
return medplum.updateResource({ ...communication, priority });
|
|
2638
2856
|
}
|
|
2639
2857
|
function onPin(communication) {
|
|
2640
2858
|
setPriority(communication, 'stat').then(loadTimeline).catch(console.log);
|
|
@@ -2652,8 +2870,7 @@
|
|
|
2652
2870
|
navigate(`/${timelineItem.resourceType}/${timelineItem.id}/delete`);
|
|
2653
2871
|
}
|
|
2654
2872
|
function onVersionDetails(version) {
|
|
2655
|
-
|
|
2656
|
-
navigate(`/${version.resourceType}/${version.id}/_history/${(_a = version.meta) === null || _a === void 0 ? void 0 : _a.versionId}`);
|
|
2873
|
+
navigate(`/${version.resourceType}/${version.id}/_history/${version.meta?.versionId}`);
|
|
2657
2874
|
}
|
|
2658
2875
|
function onUploadStart() {
|
|
2659
2876
|
notifications.showNotification({
|
|
@@ -2694,12 +2911,11 @@
|
|
|
2694
2911
|
React.createElement(core$1.TextInput, { name: "text", ref: inputRef, placeholder: "Add comment", style: { width: '100%', maxWidth: 300 } }),
|
|
2695
2912
|
React.createElement(core$1.ActionIcon, { type: "submit", radius: "xl", color: "blue", variant: "filled" },
|
|
2696
2913
|
React.createElement(icons.IconMessage, { size: 16 })),
|
|
2697
|
-
React.createElement(AttachmentButton, { onUpload: createMedia, onUploadStart: onUploadStart, onUploadProgress: onUploadProgress }, (props) => (React.createElement(core$1.ActionIcon,
|
|
2914
|
+
React.createElement(AttachmentButton, { onUpload: createMedia, onUploadStart: onUploadStart, onUploadProgress: onUploadProgress }, (props) => (React.createElement(core$1.ActionIcon, { ...props, radius: "xl", color: "blue", variant: "filled" },
|
|
2698
2915
|
React.createElement(icons.IconCloudUpload, { size: 16 })))))))),
|
|
2699
2916
|
items.map((item) => {
|
|
2700
|
-
var _a;
|
|
2701
2917
|
if (item.resourceType === resource.resourceType && item.id === resource.id) {
|
|
2702
|
-
return (React.createElement(HistoryTimelineItem, { key:
|
|
2918
|
+
return (React.createElement(HistoryTimelineItem, { key: item.meta?.versionId, history: history, resource: item, onDetails: onVersionDetails }));
|
|
2703
2919
|
}
|
|
2704
2920
|
const key = `${item.resourceType}/${item.id}`;
|
|
2705
2921
|
switch (item.resourceType) {
|
|
@@ -2732,48 +2948,46 @@
|
|
|
2732
2948
|
function HistoryTimelineItem(props) {
|
|
2733
2949
|
const previous = getPrevious(props.history, props.resource);
|
|
2734
2950
|
if (previous) {
|
|
2735
|
-
return (React.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: React.createElement(TimelineItemPopupMenu,
|
|
2951
|
+
return (React.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: React.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
2736
2952
|
React.createElement(ResourceDiffTable, { original: previous, revised: props.resource })));
|
|
2737
2953
|
}
|
|
2738
2954
|
else {
|
|
2739
|
-
return (React.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: React.createElement(TimelineItemPopupMenu,
|
|
2955
|
+
return (React.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: React.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
2740
2956
|
React.createElement("h3", null, "Created"),
|
|
2741
2957
|
React.createElement(ResourceTable, { value: props.resource, ignoreMissingValues: true })));
|
|
2742
2958
|
}
|
|
2743
2959
|
}
|
|
2744
2960
|
function getPrevious(history, version) {
|
|
2745
2961
|
const entries = history.entry;
|
|
2746
|
-
const index = entries.findIndex((entry) =>
|
|
2962
|
+
const index = entries.findIndex((entry) => entry.resource?.meta?.versionId === version.meta?.versionId);
|
|
2747
2963
|
if (index >= entries.length - 1) {
|
|
2748
2964
|
return undefined;
|
|
2749
2965
|
}
|
|
2750
2966
|
return entries[index + 1].resource;
|
|
2751
2967
|
}
|
|
2752
2968
|
function CommunicationTimelineItem(props) {
|
|
2753
|
-
var _a, _b;
|
|
2754
2969
|
const { classes } = useStyles$7();
|
|
2755
2970
|
const routine = !props.resource.priority || props.resource.priority === 'routine';
|
|
2756
2971
|
const className = routine ? undefined : classes.pinnedComment;
|
|
2757
|
-
return (React.createElement(TimelineItem, { resource: props.resource, profile: props.resource.sender, padding: true, className: className, popupMenuItems: React.createElement(TimelineItemPopupMenu,
|
|
2758
|
-
React.createElement("p", null,
|
|
2972
|
+
return (React.createElement(TimelineItem, { resource: props.resource, profile: props.resource.sender, padding: true, className: className, popupMenuItems: React.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
2973
|
+
React.createElement("p", null, props.resource.payload?.[0]?.contentString)));
|
|
2759
2974
|
}
|
|
2760
2975
|
function MediaTimelineItem(props) {
|
|
2761
|
-
|
|
2762
|
-
const contentType = (_a = props.resource.content) === null || _a === void 0 ? void 0 : _a.contentType;
|
|
2976
|
+
const contentType = props.resource.content?.contentType;
|
|
2763
2977
|
const padding = contentType &&
|
|
2764
2978
|
!contentType.startsWith('image/') &&
|
|
2765
2979
|
!contentType.startsWith('video/') &&
|
|
2766
2980
|
contentType !== 'application/pdf';
|
|
2767
|
-
return (React.createElement(TimelineItem, { resource: props.resource, padding: !!padding, popupMenuItems: React.createElement(TimelineItemPopupMenu,
|
|
2981
|
+
return (React.createElement(TimelineItem, { resource: props.resource, padding: !!padding, popupMenuItems: React.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
2768
2982
|
React.createElement(AttachmentDisplay, { value: props.resource.content })));
|
|
2769
2983
|
}
|
|
2770
2984
|
function AuditEventTimelineItem(props) {
|
|
2771
|
-
return (React.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: React.createElement(TimelineItemPopupMenu,
|
|
2985
|
+
return (React.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: React.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
2772
2986
|
React.createElement(core$1.ScrollArea, null,
|
|
2773
2987
|
React.createElement("pre", null, props.resource.outcomeDesc))));
|
|
2774
2988
|
}
|
|
2775
2989
|
function DiagnosticReportTimelineItem(props) {
|
|
2776
|
-
return (React.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: React.createElement(TimelineItemPopupMenu,
|
|
2990
|
+
return (React.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: React.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
2777
2991
|
React.createElement(DiagnosticReportDisplay, { value: props.resource })));
|
|
2778
2992
|
}
|
|
2779
2993
|
function getProgressMessage(e) {
|
|
@@ -2943,7 +3157,12 @@
|
|
|
2943
3157
|
* @param {Array} filters The new filters.
|
|
2944
3158
|
*/
|
|
2945
3159
|
function setFilters(definition, filters) {
|
|
2946
|
-
return
|
|
3160
|
+
return {
|
|
3161
|
+
...definition,
|
|
3162
|
+
filters: filters,
|
|
3163
|
+
offset: 0,
|
|
3164
|
+
name: undefined,
|
|
3165
|
+
};
|
|
2947
3166
|
}
|
|
2948
3167
|
/**
|
|
2949
3168
|
* Clears all of the filters.
|
|
@@ -2992,7 +3211,11 @@
|
|
|
2992
3211
|
newFields.push(...definition.fields);
|
|
2993
3212
|
}
|
|
2994
3213
|
newFields.push(field);
|
|
2995
|
-
return
|
|
3214
|
+
return {
|
|
3215
|
+
...definition,
|
|
3216
|
+
fields: newFields,
|
|
3217
|
+
name: undefined,
|
|
3218
|
+
};
|
|
2996
3219
|
}
|
|
2997
3220
|
/**
|
|
2998
3221
|
* Deletes a filter at the specified index.
|
|
@@ -3005,7 +3228,11 @@
|
|
|
3005
3228
|
}
|
|
3006
3229
|
const newFilters = [...definition.filters];
|
|
3007
3230
|
newFilters.splice(index, 1);
|
|
3008
|
-
return
|
|
3231
|
+
return {
|
|
3232
|
+
...definition,
|
|
3233
|
+
filters: newFilters,
|
|
3234
|
+
name: undefined,
|
|
3235
|
+
};
|
|
3009
3236
|
}
|
|
3010
3237
|
/**
|
|
3011
3238
|
* Adds a filter that constrains the specified field to "yesterday".
|
|
@@ -3149,7 +3376,11 @@
|
|
|
3149
3376
|
if (definition.offset === offset) {
|
|
3150
3377
|
return definition;
|
|
3151
3378
|
}
|
|
3152
|
-
return
|
|
3379
|
+
return {
|
|
3380
|
+
...definition,
|
|
3381
|
+
offset,
|
|
3382
|
+
name: undefined,
|
|
3383
|
+
};
|
|
3153
3384
|
}
|
|
3154
3385
|
/**
|
|
3155
3386
|
* Creates a new search request with the search offset at the specified page.
|
|
@@ -3158,8 +3389,7 @@
|
|
|
3158
3389
|
* @return The new search definition.
|
|
3159
3390
|
*/
|
|
3160
3391
|
function setPage(definition, page) {
|
|
3161
|
-
|
|
3162
|
-
const count = (_a = definition.count) !== null && _a !== void 0 ? _a : core.DEFAULT_SEARCH_COUNT;
|
|
3392
|
+
const count = definition.count ?? core.DEFAULT_SEARCH_COUNT;
|
|
3163
3393
|
const newOffset = (page - 1) * count;
|
|
3164
3394
|
return setOffset(definition, newOffset);
|
|
3165
3395
|
}
|
|
@@ -3173,12 +3403,16 @@
|
|
|
3173
3403
|
if (sort === getSortField(definition) && desc !== undefined && desc === isSortDescending(definition)) {
|
|
3174
3404
|
return definition;
|
|
3175
3405
|
}
|
|
3176
|
-
return
|
|
3406
|
+
return {
|
|
3407
|
+
...definition,
|
|
3408
|
+
sortRules: [
|
|
3177
3409
|
{
|
|
3178
3410
|
code: sort,
|
|
3179
3411
|
descending: !!desc,
|
|
3180
3412
|
},
|
|
3181
|
-
],
|
|
3413
|
+
],
|
|
3414
|
+
name: undefined,
|
|
3415
|
+
};
|
|
3182
3416
|
}
|
|
3183
3417
|
/**
|
|
3184
3418
|
* Toggles the sort of the search by key.
|
|
@@ -3224,8 +3458,7 @@
|
|
|
3224
3458
|
* @return {string} A display string for the operation.
|
|
3225
3459
|
*/
|
|
3226
3460
|
function getOpString(op) {
|
|
3227
|
-
|
|
3228
|
-
return (_a = operatorNames[op]) !== null && _a !== void 0 ? _a : '';
|
|
3461
|
+
return operatorNames[op] ?? '';
|
|
3229
3462
|
}
|
|
3230
3463
|
/**
|
|
3231
3464
|
* Returns a field display name.
|
|
@@ -3266,16 +3499,15 @@
|
|
|
3266
3499
|
* @returns The fragment to display.
|
|
3267
3500
|
*/
|
|
3268
3501
|
function renderValue(resource, field) {
|
|
3269
|
-
var _a, _b;
|
|
3270
3502
|
const key = field.name;
|
|
3271
3503
|
if (key === 'id') {
|
|
3272
3504
|
return resource.id;
|
|
3273
3505
|
}
|
|
3274
3506
|
if (key === 'meta.versionId') {
|
|
3275
|
-
return
|
|
3507
|
+
return resource.meta?.versionId;
|
|
3276
3508
|
}
|
|
3277
3509
|
if (key === '_lastUpdated') {
|
|
3278
|
-
return core.formatDateTime(
|
|
3510
|
+
return core.formatDateTime(resource.meta?.lastUpdated);
|
|
3279
3511
|
}
|
|
3280
3512
|
// Priority 1: ElementDefinition by exact match
|
|
3281
3513
|
if (field.elementDefinition && `${resource.resourceType}.${field.name}` === field.elementDefinition.path) {
|
|
@@ -3295,8 +3527,7 @@
|
|
|
3295
3527
|
* @returns A React element or null.
|
|
3296
3528
|
*/
|
|
3297
3529
|
function renderPropertyValue(resource, elementDefinition) {
|
|
3298
|
-
|
|
3299
|
-
const path = ((_c = (_b = (_a = elementDefinition.path) === null || _a === void 0 ? void 0 : _a.split('.')) === null || _b === void 0 ? void 0 : _b.pop()) === null || _c === void 0 ? void 0 : _c.replaceAll('[x]', '')) || '';
|
|
3530
|
+
const path = elementDefinition.path?.split('.')?.pop()?.replaceAll('[x]', '') || '';
|
|
3300
3531
|
const [value, propertyType] = getValueAndType({ type: resource.resourceType, value: resource }, path);
|
|
3301
3532
|
if (!value) {
|
|
3302
3533
|
return null;
|
|
@@ -3322,7 +3553,6 @@
|
|
|
3322
3553
|
}
|
|
3323
3554
|
|
|
3324
3555
|
function SearchFieldEditor(props) {
|
|
3325
|
-
var _a;
|
|
3326
3556
|
const [state, setState] = React.useState({
|
|
3327
3557
|
search: JSON.parse(core.stringify(props.search)),
|
|
3328
3558
|
});
|
|
@@ -3372,13 +3602,15 @@
|
|
|
3372
3602
|
* Moves the "available" selection into the "selected" list.
|
|
3373
3603
|
*/
|
|
3374
3604
|
function onAddField() {
|
|
3375
|
-
|
|
3376
|
-
const
|
|
3377
|
-
const key = (_b = availableRef.current) === null || _b === void 0 ? void 0 : _b.value;
|
|
3605
|
+
const currentField = state.search.fields ?? [];
|
|
3606
|
+
const key = availableRef.current?.value;
|
|
3378
3607
|
if (key) {
|
|
3379
3608
|
const newFields = [...currentField, key];
|
|
3380
3609
|
setState({
|
|
3381
|
-
search:
|
|
3610
|
+
search: {
|
|
3611
|
+
...state.search,
|
|
3612
|
+
fields: newFields,
|
|
3613
|
+
},
|
|
3382
3614
|
});
|
|
3383
3615
|
}
|
|
3384
3616
|
}
|
|
@@ -3387,14 +3619,16 @@
|
|
|
3387
3619
|
* Moves the "selected" selection into the "available" list.
|
|
3388
3620
|
*/
|
|
3389
3621
|
function onRemoveField() {
|
|
3390
|
-
|
|
3391
|
-
const
|
|
3392
|
-
const key = (_b = selectedRef.current) === null || _b === void 0 ? void 0 : _b.value;
|
|
3622
|
+
const currentField = state.search.fields ?? [];
|
|
3623
|
+
const key = selectedRef.current?.value;
|
|
3393
3624
|
if (key) {
|
|
3394
3625
|
const newFields = [...currentField];
|
|
3395
3626
|
newFields.splice(newFields.indexOf(key), 1);
|
|
3396
3627
|
setState({
|
|
3397
|
-
search:
|
|
3628
|
+
search: {
|
|
3629
|
+
...state.search,
|
|
3630
|
+
fields: newFields,
|
|
3631
|
+
},
|
|
3398
3632
|
});
|
|
3399
3633
|
}
|
|
3400
3634
|
}
|
|
@@ -3403,15 +3637,17 @@
|
|
|
3403
3637
|
* Moves the selection up one position in the list.
|
|
3404
3638
|
*/
|
|
3405
3639
|
function onMoveUp() {
|
|
3406
|
-
|
|
3407
|
-
const
|
|
3408
|
-
const field = (_b = selectedRef.current) === null || _b === void 0 ? void 0 : _b.value;
|
|
3640
|
+
const currentField = state.search.fields ?? [];
|
|
3641
|
+
const field = selectedRef.current?.value;
|
|
3409
3642
|
if (field) {
|
|
3410
3643
|
const newFields = [...currentField];
|
|
3411
3644
|
const index = newFields.indexOf(field);
|
|
3412
3645
|
swapFields(newFields, index, index - 1);
|
|
3413
3646
|
setState({
|
|
3414
|
-
search:
|
|
3647
|
+
search: {
|
|
3648
|
+
...state.search,
|
|
3649
|
+
fields: newFields,
|
|
3650
|
+
},
|
|
3415
3651
|
});
|
|
3416
3652
|
}
|
|
3417
3653
|
}
|
|
@@ -3420,15 +3656,17 @@
|
|
|
3420
3656
|
* Moves the selection down one position in the list.
|
|
3421
3657
|
*/
|
|
3422
3658
|
function onMoveDown() {
|
|
3423
|
-
|
|
3424
|
-
const
|
|
3425
|
-
const field = (_b = selectedRef.current) === null || _b === void 0 ? void 0 : _b.value;
|
|
3659
|
+
const currentField = state.search.fields ?? [];
|
|
3660
|
+
const field = selectedRef.current?.value;
|
|
3426
3661
|
if (field) {
|
|
3427
3662
|
const newFields = [...currentField];
|
|
3428
3663
|
const index = newFields.indexOf(field);
|
|
3429
3664
|
swapFields(newFields, index, index + 1);
|
|
3430
3665
|
setState({
|
|
3431
|
-
search:
|
|
3666
|
+
search: {
|
|
3667
|
+
...state.search,
|
|
3668
|
+
fields: newFields,
|
|
3669
|
+
},
|
|
3432
3670
|
});
|
|
3433
3671
|
}
|
|
3434
3672
|
}
|
|
@@ -3448,9 +3686,9 @@
|
|
|
3448
3686
|
}
|
|
3449
3687
|
const resourceType = props.search.resourceType;
|
|
3450
3688
|
const typeDef = core.globalSchema.types[resourceType];
|
|
3451
|
-
const selected =
|
|
3689
|
+
const selected = state.search.fields ?? [];
|
|
3452
3690
|
const available = getFieldsList(typeDef)
|
|
3453
|
-
.filter((field) => !
|
|
3691
|
+
.filter((field) => !selected?.includes(field))
|
|
3454
3692
|
.sort();
|
|
3455
3693
|
return (React.createElement(core$1.Modal, { title: "Fields", closeButtonLabel: "Close", opened: props.visible, onClose: props.onCancel },
|
|
3456
3694
|
React.createElement("div", null,
|
|
@@ -3507,9 +3745,8 @@
|
|
|
3507
3745
|
}
|
|
3508
3746
|
|
|
3509
3747
|
function SearchFilterValueDisplay(props) {
|
|
3510
|
-
var _a, _b;
|
|
3511
3748
|
const { resourceType, filter } = props;
|
|
3512
|
-
const searchParam =
|
|
3749
|
+
const searchParam = core.globalSchema.types[resourceType]?.searchParams?.[filter.code];
|
|
3513
3750
|
if (searchParam) {
|
|
3514
3751
|
if (searchParam.type === 'reference') {
|
|
3515
3752
|
return React.createElement(ResourceName, { value: { reference: filter.value } });
|
|
@@ -3523,12 +3760,11 @@
|
|
|
3523
3760
|
}
|
|
3524
3761
|
|
|
3525
3762
|
function SearchFilterValueInput(props) {
|
|
3526
|
-
var _a;
|
|
3527
3763
|
const details = core.getSearchParameterDetails(props.resourceType, props.searchParam);
|
|
3528
3764
|
const name = 'filter-value';
|
|
3529
3765
|
switch (details.type) {
|
|
3530
3766
|
case core.SearchParameterType.REFERENCE:
|
|
3531
|
-
return (React.createElement(ReferenceInput, { name: name, defaultValue: { reference: props.defaultValue }, targetTypes:
|
|
3767
|
+
return (React.createElement(ReferenceInput, { name: name, defaultValue: { reference: props.defaultValue }, targetTypes: props.searchParam?.target, onChange: (newReference) => {
|
|
3532
3768
|
if (newReference) {
|
|
3533
3769
|
props.onChange(newReference.reference);
|
|
3534
3770
|
}
|
|
@@ -3632,18 +3868,17 @@
|
|
|
3632
3868
|
React.createElement(core$1.Button, { compact: true, variant: "outline", onClick: props.onDelete }, "Delete"))));
|
|
3633
3869
|
}
|
|
3634
3870
|
function FilterRowInput(props) {
|
|
3635
|
-
|
|
3636
|
-
const [value, setValue] = React.useState((_a = props.defaultValue) !== null && _a !== void 0 ? _a : {});
|
|
3871
|
+
const [value, setValue] = React.useState(props.defaultValue ?? {});
|
|
3637
3872
|
const valueRef = React.useRef(value);
|
|
3638
3873
|
valueRef.current = value;
|
|
3639
3874
|
function setFilterCode(newCode) {
|
|
3640
|
-
setValue(
|
|
3875
|
+
setValue({ ...valueRef.current, code: newCode });
|
|
3641
3876
|
}
|
|
3642
3877
|
function setFilterOperator(newOperator) {
|
|
3643
|
-
setValue(
|
|
3878
|
+
setValue({ ...valueRef.current, operator: newOperator });
|
|
3644
3879
|
}
|
|
3645
3880
|
function setFilterValue(newFilterValue) {
|
|
3646
|
-
setValue(
|
|
3881
|
+
setValue({ ...valueRef.current, value: newFilterValue });
|
|
3647
3882
|
}
|
|
3648
3883
|
const searchParam = props.searchParams[value.code];
|
|
3649
3884
|
const operators = searchParam && getSearchOperators(searchParam);
|
|
@@ -3661,13 +3896,12 @@
|
|
|
3661
3896
|
}
|
|
3662
3897
|
|
|
3663
3898
|
function SearchFilterValueDialog(props) {
|
|
3664
|
-
|
|
3665
|
-
const [value, setValue] = React.useState((_a = props.defaultValue) !== null && _a !== void 0 ? _a : '');
|
|
3899
|
+
const [value, setValue] = React.useState(props.defaultValue ?? '');
|
|
3666
3900
|
if (!props.visible || !props.searchParam || !props.filter) {
|
|
3667
3901
|
return null;
|
|
3668
3902
|
}
|
|
3669
3903
|
function onOk() {
|
|
3670
|
-
props.onOk(
|
|
3904
|
+
props.onOk({ ...props.filter, value });
|
|
3671
3905
|
}
|
|
3672
3906
|
return (React.createElement(core$1.Modal, { title: props.title, size: "xl", opened: props.visible, onClose: props.onCancel },
|
|
3673
3907
|
React.createElement("div", { style: { width: 500 } },
|
|
@@ -3702,16 +3936,16 @@
|
|
|
3702
3936
|
function SearchParameterSubMenu(props) {
|
|
3703
3937
|
switch (props.searchParam.type) {
|
|
3704
3938
|
case 'date':
|
|
3705
|
-
return React.createElement(DateFilterSubMenu,
|
|
3939
|
+
return React.createElement(DateFilterSubMenu, { ...props });
|
|
3706
3940
|
case 'number':
|
|
3707
3941
|
case 'quantity':
|
|
3708
|
-
return React.createElement(NumericFilterSubMenu,
|
|
3942
|
+
return React.createElement(NumericFilterSubMenu, { ...props });
|
|
3709
3943
|
case 'reference':
|
|
3710
|
-
return React.createElement(ReferenceFilterSubMenu,
|
|
3944
|
+
return React.createElement(ReferenceFilterSubMenu, { ...props });
|
|
3711
3945
|
case 'string':
|
|
3712
3946
|
case 'token':
|
|
3713
3947
|
case 'uri':
|
|
3714
|
-
return React.createElement(TextFilterSubMenu,
|
|
3948
|
+
return React.createElement(TextFilterSubMenu, { ...props });
|
|
3715
3949
|
default:
|
|
3716
3950
|
return React.createElement(React.Fragment, null,
|
|
3717
3951
|
"Unknown search param type: ",
|
|
@@ -3741,7 +3975,7 @@
|
|
|
3741
3975
|
React.createElement(core$1.Menu.Item, { icon: React.createElement(icons.IconCalendar, { size: 14 }), onClick: () => props.onChange(addLastMonthFilter(props.search, code)) }, "Last Month"),
|
|
3742
3976
|
React.createElement(core$1.Menu.Divider, null),
|
|
3743
3977
|
React.createElement(core$1.Menu.Item, { icon: React.createElement(icons.IconCalendar, { size: 14 }), onClick: () => props.onChange(addYearToDateFilter(props.search, code)) }, "Year to date"),
|
|
3744
|
-
React.createElement(CommonMenuItems,
|
|
3978
|
+
React.createElement(CommonMenuItems, { ...props })));
|
|
3745
3979
|
}
|
|
3746
3980
|
function NumericFilterSubMenu(props) {
|
|
3747
3981
|
const { searchParam } = props;
|
|
@@ -3756,14 +3990,14 @@
|
|
|
3756
3990
|
React.createElement(core$1.Menu.Item, { icon: React.createElement(icons.IconSettings, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.GREATER_THAN_OR_EQUALS) }, "Greater than or equal to..."),
|
|
3757
3991
|
React.createElement(core$1.Menu.Item, { icon: React.createElement(icons.IconMathLower, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.LESS_THAN) }, "Less than..."),
|
|
3758
3992
|
React.createElement(core$1.Menu.Item, { icon: React.createElement(icons.IconSettings, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.LESS_THAN_OR_EQUALS) }, "Less than or equal to..."),
|
|
3759
|
-
React.createElement(CommonMenuItems,
|
|
3993
|
+
React.createElement(CommonMenuItems, { ...props })));
|
|
3760
3994
|
}
|
|
3761
3995
|
function ReferenceFilterSubMenu(props) {
|
|
3762
3996
|
const { searchParam } = props;
|
|
3763
3997
|
return (React.createElement(core$1.Menu.Dropdown, null,
|
|
3764
3998
|
React.createElement(core$1.Menu.Item, { icon: React.createElement(icons.IconEqual, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.EQUALS) }, "Equals..."),
|
|
3765
3999
|
React.createElement(core$1.Menu.Item, { icon: React.createElement(icons.IconEqualNot, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.NOT) }, "Does not equal..."),
|
|
3766
|
-
React.createElement(CommonMenuItems,
|
|
4000
|
+
React.createElement(CommonMenuItems, { ...props })));
|
|
3767
4001
|
}
|
|
3768
4002
|
function TextFilterSubMenu(props) {
|
|
3769
4003
|
const { searchParam } = props;
|
|
@@ -3776,7 +4010,7 @@
|
|
|
3776
4010
|
React.createElement(core$1.Menu.Divider, null),
|
|
3777
4011
|
React.createElement(core$1.Menu.Item, { icon: React.createElement(icons.IconBucket, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.CONTAINS) }, "Contains..."),
|
|
3778
4012
|
React.createElement(core$1.Menu.Item, { icon: React.createElement(icons.IconBucketOff, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.EQUALS) }, "Does not contain..."),
|
|
3779
|
-
React.createElement(CommonMenuItems,
|
|
4013
|
+
React.createElement(CommonMenuItems, { ...props })));
|
|
3780
4014
|
}
|
|
3781
4015
|
function CommonMenuItems(props) {
|
|
3782
4016
|
const { searchParam } = props;
|
|
@@ -3810,7 +4044,6 @@
|
|
|
3810
4044
|
* @returns The field definition.
|
|
3811
4045
|
*/
|
|
3812
4046
|
function getFieldDefinition(resourceType, name) {
|
|
3813
|
-
var _a;
|
|
3814
4047
|
if (name === '_lastUpdated') {
|
|
3815
4048
|
return {
|
|
3816
4049
|
name: '_lastUpdated',
|
|
@@ -3843,7 +4076,7 @@
|
|
|
3843
4076
|
}
|
|
3844
4077
|
const typeSchema = core.globalSchema.types[resourceType];
|
|
3845
4078
|
const exactElementDefinition = typeSchema.properties[name];
|
|
3846
|
-
const exactSearchParam =
|
|
4079
|
+
const exactSearchParam = typeSchema.searchParams?.[name.toLowerCase()];
|
|
3847
4080
|
// Best case: Exact match of element definition or search parameter.
|
|
3848
4081
|
// Examples: ServiceRequest.subject, Patient.name, Patient.birthDate
|
|
3849
4082
|
// In this case, we only show the one search parameter.
|
|
@@ -3858,7 +4091,7 @@
|
|
|
3858
4091
|
let searchParams = undefined;
|
|
3859
4092
|
if (typeSchema.searchParams) {
|
|
3860
4093
|
const path = `${resourceType}.${name.replaceAll('[x]', '')}`;
|
|
3861
|
-
searchParams = Object.values(typeSchema.searchParams).filter((p) =>
|
|
4094
|
+
searchParams = Object.values(typeSchema.searchParams).filter((p) => p.expression?.includes(path));
|
|
3862
4095
|
if (searchParams.length === 0) {
|
|
3863
4096
|
searchParams = undefined;
|
|
3864
4097
|
}
|
|
@@ -3937,7 +4170,6 @@
|
|
|
3937
4170
|
* It does not include the field editor, filter editor, pagination buttons.
|
|
3938
4171
|
*/
|
|
3939
4172
|
function SearchControl(props) {
|
|
3940
|
-
var _a, _b, _c;
|
|
3941
4173
|
const { classes } = useStyles$6();
|
|
3942
4174
|
const medplum = useMedplum();
|
|
3943
4175
|
const [schemaLoaded, setSchemaLoaded] = React.useState(false);
|
|
@@ -3954,15 +4186,15 @@
|
|
|
3954
4186
|
React.useEffect(() => {
|
|
3955
4187
|
setOutcome(undefined);
|
|
3956
4188
|
medplum
|
|
3957
|
-
.search(search.resourceType, core.formatSearchQuery(
|
|
4189
|
+
.search(search.resourceType, core.formatSearchQuery({ ...search, total: 'accurate', fields: undefined }))
|
|
3958
4190
|
.then((response) => {
|
|
3959
|
-
setState(
|
|
4191
|
+
setState({ ...stateRef.current, searchResponse: response });
|
|
3960
4192
|
if (onLoad) {
|
|
3961
4193
|
onLoad(new SearchLoadEvent(response));
|
|
3962
4194
|
}
|
|
3963
4195
|
})
|
|
3964
4196
|
.catch((reason) => {
|
|
3965
|
-
setState(
|
|
4197
|
+
setState({ ...stateRef.current, searchResponse: undefined });
|
|
3966
4198
|
setOutcome(reason);
|
|
3967
4199
|
});
|
|
3968
4200
|
}, [medplum, search, onLoad]);
|
|
@@ -3970,40 +4202,37 @@
|
|
|
3970
4202
|
e.stopPropagation();
|
|
3971
4203
|
const el = e.target;
|
|
3972
4204
|
const checked = el.checked;
|
|
3973
|
-
const newSelected =
|
|
4205
|
+
const newSelected = { ...stateRef.current.selected };
|
|
3974
4206
|
if (checked) {
|
|
3975
4207
|
newSelected[id] = true;
|
|
3976
4208
|
}
|
|
3977
4209
|
else {
|
|
3978
4210
|
delete newSelected[id];
|
|
3979
4211
|
}
|
|
3980
|
-
setState(
|
|
4212
|
+
setState({ ...stateRef.current, selected: newSelected });
|
|
3981
4213
|
}
|
|
3982
4214
|
function handleAllCheckboxClick(e) {
|
|
3983
|
-
var _a;
|
|
3984
4215
|
e.stopPropagation();
|
|
3985
4216
|
const el = e.target;
|
|
3986
4217
|
const checked = el.checked;
|
|
3987
4218
|
const newSelected = {};
|
|
3988
|
-
const searchResponse =
|
|
3989
|
-
if (checked &&
|
|
4219
|
+
const searchResponse = stateRef.current?.searchResponse;
|
|
4220
|
+
if (checked && searchResponse?.entry) {
|
|
3990
4221
|
searchResponse.entry.forEach((entry) => {
|
|
3991
|
-
|
|
3992
|
-
if ((_a = entry.resource) === null || _a === void 0 ? void 0 : _a.id) {
|
|
4222
|
+
if (entry.resource?.id) {
|
|
3993
4223
|
newSelected[entry.resource.id] = true;
|
|
3994
4224
|
}
|
|
3995
4225
|
});
|
|
3996
4226
|
}
|
|
3997
|
-
setState(
|
|
4227
|
+
setState({ ...stateRef.current, selected: newSelected });
|
|
3998
4228
|
}
|
|
3999
4229
|
function isAllSelected() {
|
|
4000
|
-
var _a, _b;
|
|
4001
4230
|
const state = stateRef.current;
|
|
4002
|
-
if (!
|
|
4231
|
+
if (!state.searchResponse?.entry || state.searchResponse.entry.length === 0) {
|
|
4003
4232
|
return false;
|
|
4004
4233
|
}
|
|
4005
4234
|
for (const e of state.searchResponse.entry) {
|
|
4006
|
-
if (
|
|
4235
|
+
if (e.resource?.id && !state.selected[e.resource.id]) {
|
|
4007
4236
|
return false;
|
|
4008
4237
|
}
|
|
4009
4238
|
}
|
|
@@ -4048,7 +4277,7 @@
|
|
|
4048
4277
|
.then(() => setSchemaLoaded(true))
|
|
4049
4278
|
.catch(console.log);
|
|
4050
4279
|
}, [medplum, props.search.resourceType]);
|
|
4051
|
-
const typeSchema = schemaLoaded &&
|
|
4280
|
+
const typeSchema = schemaLoaded && core.globalSchema?.types?.[props.search.resourceType];
|
|
4052
4281
|
if (!typeSchema) {
|
|
4053
4282
|
return (React.createElement(core$1.Center, { style: { width: '100%', height: '100%' } },
|
|
4054
4283
|
React.createElement(core$1.Loader, null)));
|
|
@@ -4057,8 +4286,8 @@
|
|
|
4057
4286
|
const fields = getFieldDefinitions(search);
|
|
4058
4287
|
const resourceType = search.resourceType;
|
|
4059
4288
|
const lastResult = state.searchResponse;
|
|
4060
|
-
const entries = lastResult
|
|
4061
|
-
const resources = entries
|
|
4289
|
+
const entries = lastResult?.entry;
|
|
4290
|
+
const resources = entries?.map((e) => e.resource);
|
|
4062
4291
|
const buttonVariant = 'subtle';
|
|
4063
4292
|
const buttonColor = 'gray';
|
|
4064
4293
|
const iconSize = 16;
|
|
@@ -4066,8 +4295,8 @@
|
|
|
4066
4295
|
return (React.createElement("div", { className: classes.root, "data-testid": "search-control" },
|
|
4067
4296
|
!props.hideToolbar && (React.createElement(core$1.Group, { position: "apart", mb: "xl" },
|
|
4068
4297
|
React.createElement(core$1.Group, { spacing: 2 },
|
|
4069
|
-
React.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: React.createElement(icons.IconFilter, { size: iconSize }), onClick: () => setState(
|
|
4070
|
-
React.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: React.createElement(icons.IconColumns, { size: iconSize }), onClick: () => setState(
|
|
4298
|
+
React.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: React.createElement(icons.IconFilter, { size: iconSize }), onClick: () => setState({ ...stateRef.current, fieldEditorVisible: true }) }, "Fields"),
|
|
4299
|
+
React.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: React.createElement(icons.IconColumns, { size: iconSize }), onClick: () => setState({ ...stateRef.current, filterEditorVisible: true }) }, "Filters"),
|
|
4071
4300
|
props.onNew && (React.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: React.createElement(icons.IconFilePlus, { size: iconSize }), onClick: props.onNew }, "New...")),
|
|
4072
4301
|
!isMobile && props.onExport && (React.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: React.createElement(icons.IconTableExport, { size: iconSize }), onClick: props.onExport }, "Export...")),
|
|
4073
4302
|
!isMobile && props.onDelete && (React.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: React.createElement(icons.IconTrash, { size: iconSize }), onClick: () => props.onDelete(Object.keys(state.selected)) }, "Delete...")),
|
|
@@ -4077,8 +4306,8 @@
|
|
|
4077
4306
|
"-",
|
|
4078
4307
|
getEnd$1(search, lastResult.total),
|
|
4079
4308
|
" of",
|
|
4080
|
-
' ',
|
|
4081
|
-
|
|
4309
|
+
' ',
|
|
4310
|
+
lastResult.total?.toLocaleString())))),
|
|
4082
4311
|
React.createElement(core$1.Table, { className: classes.table },
|
|
4083
4312
|
React.createElement("thead", null,
|
|
4084
4313
|
React.createElement("tr", null,
|
|
@@ -4093,21 +4322,26 @@
|
|
|
4093
4322
|
React.createElement(core$1.Center, { className: classes.icon },
|
|
4094
4323
|
React.createElement(icons.IconAdjustmentsHorizontal, { size: 14, stroke: 1.5 }))))),
|
|
4095
4324
|
React.createElement(SearchPopupMenu, { search: props.search, searchParams: field.searchParams, onPrompt: (searchParam, filter) => {
|
|
4096
|
-
setState(
|
|
4325
|
+
setState({
|
|
4326
|
+
...stateRef.current,
|
|
4327
|
+
filterDialogVisible: true,
|
|
4328
|
+
filterDialogSearchParam: searchParam,
|
|
4329
|
+
filterDialogFilter: filter,
|
|
4330
|
+
});
|
|
4097
4331
|
}, onChange: (result) => {
|
|
4098
4332
|
emitSearchChange(result);
|
|
4099
4333
|
} })))))),
|
|
4100
4334
|
!props.hideFilters && (React.createElement("tr", null,
|
|
4101
4335
|
checkboxColumn && React.createElement("th", null),
|
|
4102
4336
|
fields.map((field) => (React.createElement("th", { key: field.name }, field.searchParams && (React.createElement(FilterDescription, { resourceType: resourceType, searchParams: field.searchParams, filters: props.search.filters })))))))),
|
|
4103
|
-
React.createElement("tbody", null, resources
|
|
4337
|
+
React.createElement("tbody", null, resources?.map((resource) => resource && (React.createElement("tr", { key: resource.id, className: classes.tr, "data-testid": "search-control-row", onClick: (e) => handleRowClick(e, resource), onAuxClick: (e) => handleRowClick(e, resource) },
|
|
4104
4338
|
checkboxColumn && (React.createElement("td", null,
|
|
4105
4339
|
React.createElement("input", { type: "checkbox", value: "checked", "data-testid": "row-checkbox", "aria-label": `Checkbox for ${resource.id}`, checked: !!state.selected[resource.id], onChange: (e) => handleSingleCheckboxClick(e, resource.id) }))),
|
|
4106
4340
|
fields.map((field) => (React.createElement("td", { key: field.name }, renderValue(resource, field))))))))),
|
|
4107
|
-
|
|
4341
|
+
resources?.length === 0 && (React.createElement(Container, null,
|
|
4108
4342
|
React.createElement(core$1.Center, null,
|
|
4109
4343
|
React.createElement(core$1.Text, { size: "xl", color: "dimmed" }, "No results")))),
|
|
4110
|
-
|
|
4344
|
+
lastResult?.total !== undefined && lastResult.total > 0 && (React.createElement(core$1.Center, { m: "md", p: "md" },
|
|
4111
4345
|
React.createElement(core$1.Pagination, { page: getPage(search), total: getTotalPages(search, lastResult.total), onChange: (newPage) => emitSearchChange(setPage(search, newPage)), getItemAriaLabel: (page) => {
|
|
4112
4346
|
switch (page) {
|
|
4113
4347
|
case 'prev':
|
|
@@ -4122,27 +4356,44 @@
|
|
|
4122
4356
|
React.createElement("pre", { style: { textAlign: 'left' } }, JSON.stringify(outcome, undefined, 2)))),
|
|
4123
4357
|
React.createElement(SearchFieldEditor, { search: props.search, visible: stateRef.current.fieldEditorVisible, onOk: (result) => {
|
|
4124
4358
|
emitSearchChange(result);
|
|
4125
|
-
setState(
|
|
4359
|
+
setState({
|
|
4360
|
+
...stateRef.current,
|
|
4361
|
+
fieldEditorVisible: false,
|
|
4362
|
+
});
|
|
4126
4363
|
}, onCancel: () => {
|
|
4127
|
-
setState(
|
|
4364
|
+
setState({
|
|
4365
|
+
...stateRef.current,
|
|
4366
|
+
fieldEditorVisible: false,
|
|
4367
|
+
});
|
|
4128
4368
|
} }),
|
|
4129
4369
|
React.createElement(SearchFilterEditor, { search: props.search, visible: stateRef.current.filterEditorVisible, onOk: (result) => {
|
|
4130
4370
|
emitSearchChange(result);
|
|
4131
|
-
setState(
|
|
4371
|
+
setState({
|
|
4372
|
+
...stateRef.current,
|
|
4373
|
+
filterEditorVisible: false,
|
|
4374
|
+
});
|
|
4132
4375
|
}, onCancel: () => {
|
|
4133
|
-
setState(
|
|
4376
|
+
setState({
|
|
4377
|
+
...stateRef.current,
|
|
4378
|
+
filterEditorVisible: false,
|
|
4379
|
+
});
|
|
4134
4380
|
} }),
|
|
4135
|
-
React.createElement(SearchFilterValueDialog, { key:
|
|
4381
|
+
React.createElement(SearchFilterValueDialog, { key: state.filterDialogSearchParam?.code, visible: stateRef.current.filterDialogVisible, title: 'Input', resourceType: resourceType, searchParam: state.filterDialogSearchParam, filter: state.filterDialogFilter, defaultValue: '', onOk: (filter) => {
|
|
4136
4382
|
emitSearchChange(addFilter(props.search, filter.code, filter.operator, filter.value));
|
|
4137
|
-
setState(
|
|
4383
|
+
setState({
|
|
4384
|
+
...stateRef.current,
|
|
4385
|
+
filterDialogVisible: false,
|
|
4386
|
+
});
|
|
4138
4387
|
}, onCancel: () => {
|
|
4139
|
-
setState(
|
|
4388
|
+
setState({
|
|
4389
|
+
...stateRef.current,
|
|
4390
|
+
filterDialogVisible: false,
|
|
4391
|
+
});
|
|
4140
4392
|
} })));
|
|
4141
4393
|
}
|
|
4142
4394
|
const MemoizedSearchControl = React.memo(SearchControl);
|
|
4143
4395
|
function FilterDescription(props) {
|
|
4144
|
-
|
|
4145
|
-
const filters = ((_a = props.filters) !== null && _a !== void 0 ? _a : []).filter((f) => props.searchParams.find((p) => p.code === f.code));
|
|
4396
|
+
const filters = (props.filters ?? []).filter((f) => props.searchParams.find((p) => p.code === f.code));
|
|
4146
4397
|
if (filters.length === 0) {
|
|
4147
4398
|
return React.createElement("span", null, "no filters");
|
|
4148
4399
|
}
|
|
@@ -4159,19 +4410,16 @@
|
|
|
4159
4410
|
return Math.ceil(total / pageSize);
|
|
4160
4411
|
}
|
|
4161
4412
|
function getStart$1(search, total) {
|
|
4162
|
-
|
|
4163
|
-
return Math.min(total, ((_a = search.offset) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
4413
|
+
return Math.min(total, (search.offset ?? 0) + 1);
|
|
4164
4414
|
}
|
|
4165
4415
|
function getEnd$1(search, total) {
|
|
4166
|
-
|
|
4167
|
-
return Math.min(total, (((_a = search.offset) !== null && _a !== void 0 ? _a : 0) + 1) * ((_b = search.count) !== null && _b !== void 0 ? _b : core.DEFAULT_SEARCH_COUNT));
|
|
4416
|
+
return Math.min(total, ((search.offset ?? 0) + 1) * (search.count ?? core.DEFAULT_SEARCH_COUNT));
|
|
4168
4417
|
}
|
|
4169
4418
|
|
|
4170
4419
|
/**
|
|
4171
4420
|
* The FhirPathTable component represents the embeddable search table control.
|
|
4172
4421
|
*/
|
|
4173
4422
|
function FhirPathTable(props) {
|
|
4174
|
-
var _a, _b, _c, _d, _e;
|
|
4175
4423
|
const medplum = useMedplum();
|
|
4176
4424
|
const [schema, setSchema] = React.useState();
|
|
4177
4425
|
const [outcome, setOutcome] = React.useState();
|
|
@@ -4190,7 +4438,7 @@
|
|
|
4190
4438
|
e.stopPropagation();
|
|
4191
4439
|
const el = e.target;
|
|
4192
4440
|
const checked = el.checked;
|
|
4193
|
-
const newSelected =
|
|
4441
|
+
const newSelected = { ...selectedRef.current };
|
|
4194
4442
|
if (checked) {
|
|
4195
4443
|
newSelected[id] = true;
|
|
4196
4444
|
}
|
|
@@ -4200,15 +4448,14 @@
|
|
|
4200
4448
|
setSelected(newSelected);
|
|
4201
4449
|
}
|
|
4202
4450
|
function handleAllCheckboxClick(e) {
|
|
4203
|
-
var _a, _b;
|
|
4204
4451
|
e.stopPropagation();
|
|
4205
4452
|
const el = e.target;
|
|
4206
4453
|
const checked = el.checked;
|
|
4207
4454
|
const newSelected = {};
|
|
4208
|
-
const resources =
|
|
4455
|
+
const resources = responseRef.current?.data?.ResourceList;
|
|
4209
4456
|
if (checked && resources) {
|
|
4210
4457
|
resources.forEach((resource) => {
|
|
4211
|
-
if (resource
|
|
4458
|
+
if (resource?.id) {
|
|
4212
4459
|
newSelected[resource.id] = true;
|
|
4213
4460
|
}
|
|
4214
4461
|
});
|
|
@@ -4216,13 +4463,12 @@
|
|
|
4216
4463
|
setSelected(newSelected);
|
|
4217
4464
|
}
|
|
4218
4465
|
function isAllSelected() {
|
|
4219
|
-
|
|
4220
|
-
const resources = (_b = (_a = responseRef.current) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.ResourceList;
|
|
4466
|
+
const resources = responseRef.current?.data?.ResourceList;
|
|
4221
4467
|
if (!resources || resources.length === 0) {
|
|
4222
4468
|
return false;
|
|
4223
4469
|
}
|
|
4224
4470
|
for (const resource of resources) {
|
|
4225
|
-
if (
|
|
4471
|
+
if (resource?.id && !selectedRef.current[resource.id]) {
|
|
4226
4472
|
return false;
|
|
4227
4473
|
}
|
|
4228
4474
|
}
|
|
@@ -4247,11 +4493,11 @@
|
|
|
4247
4493
|
.then((newSchema) => {
|
|
4248
4494
|
// The schema could have the same object identity,
|
|
4249
4495
|
// so need to use the spread operator to kick React re-render.
|
|
4250
|
-
setSchema(
|
|
4496
|
+
setSchema({ ...newSchema });
|
|
4251
4497
|
})
|
|
4252
4498
|
.catch(console.log);
|
|
4253
4499
|
}, [medplum, props.resourceType]);
|
|
4254
|
-
const typeSchema =
|
|
4500
|
+
const typeSchema = schema?.types?.[props.resourceType];
|
|
4255
4501
|
if (!typeSchema) {
|
|
4256
4502
|
return React.createElement(core$1.Loader, null);
|
|
4257
4503
|
}
|
|
@@ -4263,14 +4509,14 @@
|
|
|
4263
4509
|
checkboxColumn && (React.createElement("th", null,
|
|
4264
4510
|
React.createElement("input", { type: "checkbox", value: "checked", "aria-label": "all-checkbox", "data-testid": "all-checkbox", checked: isAllSelected(), onChange: (e) => handleAllCheckboxClick(e) }))),
|
|
4265
4511
|
fields.map((field) => (React.createElement("th", { key: field.name }, field.name))))),
|
|
4266
|
-
React.createElement("tbody", null,
|
|
4512
|
+
React.createElement("tbody", null, response?.data?.ResourceList?.map((resource) => resource && (React.createElement("tr", { key: resource.id, "data-testid": "search-control-row", onClick: (e) => handleRowClick(e, resource), onAuxClick: (e) => handleRowClick(e, resource) },
|
|
4267
4513
|
checkboxColumn && (React.createElement("td", null,
|
|
4268
4514
|
React.createElement("input", { type: "checkbox", value: "checked", "data-testid": "row-checkbox", "aria-label": `Checkbox for ${resource.id}`, checked: !!selected[resource.id], onChange: (e) => handleSingleCheckboxClick(e, resource.id) }))),
|
|
4269
4515
|
fields.map((field) => {
|
|
4270
4516
|
return (React.createElement("td", { key: field.name },
|
|
4271
4517
|
React.createElement(FhirPathDisplay, { propertyType: field.propertyType, path: field.fhirPath, resource: resource })));
|
|
4272
4518
|
})))))),
|
|
4273
|
-
|
|
4519
|
+
response?.data?.ResourceList?.length === 0 && React.createElement("div", { "data-testid": "empty-search" }, "No results"),
|
|
4274
4520
|
outcome && (React.createElement("div", { "data-testid": "search-error" },
|
|
4275
4521
|
React.createElement("pre", { style: { textAlign: 'left' } }, JSON.stringify(outcome, undefined, 2)))),
|
|
4276
4522
|
props.onBulk && (React.createElement(core$1.Button, { onClick: () => props.onBulk(Object.keys(selectedRef.current)) }, "Bulk..."))));
|
|
@@ -4358,7 +4604,7 @@
|
|
|
4358
4604
|
medplum.requestSchema('PlanDefinition').then(setSchema).catch(console.log);
|
|
4359
4605
|
}, [medplum]);
|
|
4360
4606
|
React.useEffect(() => {
|
|
4361
|
-
setValue(ensurePlanDefinitionKeys(defaultValue
|
|
4607
|
+
setValue(ensurePlanDefinitionKeys(defaultValue ?? { resourceType: 'PlanDefinition' }));
|
|
4362
4608
|
document.addEventListener('mouseover', handleDocumentMouseOver);
|
|
4363
4609
|
document.addEventListener('click', handleDocumentClick);
|
|
4364
4610
|
return () => {
|
|
@@ -4370,7 +4616,10 @@
|
|
|
4370
4616
|
return null;
|
|
4371
4617
|
}
|
|
4372
4618
|
function changeProperty(property, newValue) {
|
|
4373
|
-
setValue(
|
|
4619
|
+
setValue({
|
|
4620
|
+
...valueRef.current,
|
|
4621
|
+
[property]: newValue,
|
|
4622
|
+
});
|
|
4374
4623
|
}
|
|
4375
4624
|
return (React.createElement("div", null,
|
|
4376
4625
|
React.createElement(Form, { testid: "questionnaire-form", onSubmit: () => props.onSubmit(value) },
|
|
@@ -4450,7 +4699,10 @@
|
|
|
4450
4699
|
const { action } = props;
|
|
4451
4700
|
const [actionType, setActionType] = React.useState(props.actionType);
|
|
4452
4701
|
function changeProperty(property, value) {
|
|
4453
|
-
props.onChange(
|
|
4702
|
+
props.onChange({
|
|
4703
|
+
...action,
|
|
4704
|
+
[property]: value,
|
|
4705
|
+
});
|
|
4454
4706
|
}
|
|
4455
4707
|
return (React.createElement(core$1.Stack, { spacing: "xl" },
|
|
4456
4708
|
React.createElement(core$1.TextInput, { name: `actionTitle-${action.id}`, label: "Title", defaultValue: action.title, onChange: (e) => changeProperty('title', e.currentTarget.value) }),
|
|
@@ -4476,15 +4728,15 @@
|
|
|
4476
4728
|
}
|
|
4477
4729
|
function ActionResourceTypeBuilder(props) {
|
|
4478
4730
|
const { id, definitionCanonical } = props.action;
|
|
4479
|
-
const reference =
|
|
4731
|
+
const reference = definitionCanonical?.startsWith(props.resourceType + '/')
|
|
4480
4732
|
? { reference: definitionCanonical }
|
|
4481
4733
|
: undefined;
|
|
4482
4734
|
return (React.createElement(ResourceInput, { name: id, resourceType: props.resourceType, defaultValue: reference, loadOnFocus: true, onChange: (newValue) => {
|
|
4483
4735
|
if (newValue) {
|
|
4484
|
-
props.onChange(
|
|
4736
|
+
props.onChange({ ...props.action, definitionCanonical: core.getReferenceString(newValue) });
|
|
4485
4737
|
}
|
|
4486
4738
|
else {
|
|
4487
|
-
props.onChange(
|
|
4739
|
+
props.onChange({ ...props.action, definitionCanonical: undefined });
|
|
4488
4740
|
}
|
|
4489
4741
|
} }));
|
|
4490
4742
|
}
|
|
@@ -4493,18 +4745,17 @@
|
|
|
4493
4745
|
const key = 'timing';
|
|
4494
4746
|
const [propertyValue, propertyType] = getActionTiming(value);
|
|
4495
4747
|
return (React.createElement(ResourcePropertyInput, { property: timingProperty, name: "timing[x]", defaultValue: propertyValue, defaultPropertyType: propertyType, onChange: (newValue, propName) => {
|
|
4496
|
-
props.onChange(setPropertyValue(value, key, propName
|
|
4748
|
+
props.onChange(setPropertyValue(value, key, propName ?? key, timingProperty, newValue));
|
|
4497
4749
|
} }));
|
|
4498
4750
|
}
|
|
4499
4751
|
function getInitialActionType(action) {
|
|
4500
|
-
|
|
4501
|
-
if ((_a = action.definitionCanonical) === null || _a === void 0 ? void 0 : _a.startsWith('Schedule')) {
|
|
4752
|
+
if (action.definitionCanonical?.startsWith('Schedule')) {
|
|
4502
4753
|
return 'appointment';
|
|
4503
4754
|
}
|
|
4504
|
-
if (
|
|
4755
|
+
if (action.definitionCanonical?.startsWith('Questionnaire/')) {
|
|
4505
4756
|
return 'questionnaire';
|
|
4506
4757
|
}
|
|
4507
|
-
if (
|
|
4758
|
+
if (action.definitionCanonical?.startsWith('ActivityDefinition/')) {
|
|
4508
4759
|
return 'task';
|
|
4509
4760
|
}
|
|
4510
4761
|
return undefined;
|
|
@@ -4533,13 +4784,20 @@
|
|
|
4533
4784
|
return 'id-' + nextId$1++;
|
|
4534
4785
|
}
|
|
4535
4786
|
function ensurePlanDefinitionKeys(planDefinition) {
|
|
4536
|
-
return
|
|
4787
|
+
return {
|
|
4788
|
+
...planDefinition,
|
|
4789
|
+
action: ensurePlanDefinitionActionKeys(planDefinition.action),
|
|
4790
|
+
};
|
|
4537
4791
|
}
|
|
4538
4792
|
function ensurePlanDefinitionActionKeys(actions) {
|
|
4539
4793
|
if (!actions) {
|
|
4540
4794
|
return undefined;
|
|
4541
4795
|
}
|
|
4542
|
-
return actions.map((action) => (
|
|
4796
|
+
return actions.map((action) => ({
|
|
4797
|
+
...action,
|
|
4798
|
+
id: generateId$1(action.id),
|
|
4799
|
+
action: ensurePlanDefinitionActionKeys(action.action),
|
|
4800
|
+
}));
|
|
4543
4801
|
}
|
|
4544
4802
|
|
|
4545
4803
|
exports.QuestionnaireItemType = void 0;
|
|
@@ -4586,6 +4844,7 @@
|
|
|
4586
4844
|
function setItems(newResponseItems) {
|
|
4587
4845
|
const newResponse = {
|
|
4588
4846
|
resourceType: 'QuestionnaireResponse',
|
|
4847
|
+
status: 'completed',
|
|
4589
4848
|
item: newResponseItems,
|
|
4590
4849
|
};
|
|
4591
4850
|
setResponse(newResponse);
|
|
@@ -4596,7 +4855,13 @@
|
|
|
4596
4855
|
}
|
|
4597
4856
|
return (React.createElement(Form, { testid: "questionnaire-form", onSubmit: () => {
|
|
4598
4857
|
if (props.onSubmit && response) {
|
|
4599
|
-
props.onSubmit(
|
|
4858
|
+
props.onSubmit({
|
|
4859
|
+
...response,
|
|
4860
|
+
questionnaire: core.getReferenceString(questionnaire),
|
|
4861
|
+
subject: props.subject,
|
|
4862
|
+
source: core.createReference(source),
|
|
4863
|
+
authored: new Date().toISOString(),
|
|
4864
|
+
});
|
|
4600
4865
|
}
|
|
4601
4866
|
} },
|
|
4602
4867
|
questionnaire.title && React.createElement(core$1.Title, null, questionnaire.title),
|
|
@@ -4625,7 +4890,7 @@
|
|
|
4625
4890
|
if (item.type === exports.QuestionnaireItemType.boolean) {
|
|
4626
4891
|
const initial = item.initial && item.initial.length > 0 ? item.initial[0] : undefined;
|
|
4627
4892
|
return (React.createElement(CheckboxFormSection, { key: item.linkId, title: item.text, htmlFor: item.linkId },
|
|
4628
|
-
React.createElement(core$1.Checkbox, { id: item.linkId, name: item.linkId, defaultChecked: initial
|
|
4893
|
+
React.createElement(core$1.Checkbox, { id: item.linkId, name: item.linkId, defaultChecked: initial?.valueBoolean, onChange: (e) => setResponseItem(index, {
|
|
4629
4894
|
linkId: item.linkId,
|
|
4630
4895
|
text: item.text,
|
|
4631
4896
|
answer: [{ valueBoolean: e.currentTarget.checked }],
|
|
@@ -4666,28 +4931,28 @@
|
|
|
4666
4931
|
React.createElement("h3", null, item.text),
|
|
4667
4932
|
item.item && (React.createElement(QuestionnaireFormItemArray, { items: item.item, answers: props.answers, onChange: onChangeItem }))));
|
|
4668
4933
|
case exports.QuestionnaireItemType.boolean:
|
|
4669
|
-
return (React.createElement(core$1.Checkbox, { id: name, name: name, defaultChecked: initial
|
|
4934
|
+
return (React.createElement(core$1.Checkbox, { id: name, name: name, defaultChecked: initial?.valueBoolean, onChange: (e) => onChangeAnswer({ valueBoolean: e.currentTarget.checked }) }));
|
|
4670
4935
|
case exports.QuestionnaireItemType.decimal:
|
|
4671
|
-
return (React.createElement(core$1.TextInput, { type: "number", step: "any", id: name, name: name, defaultValue: initial
|
|
4936
|
+
return (React.createElement(core$1.TextInput, { type: "number", step: "any", id: name, name: name, defaultValue: initial?.valueDecimal, onChange: (e) => onChangeAnswer({ valueDecimal: e.currentTarget.valueAsNumber }) }));
|
|
4672
4937
|
case exports.QuestionnaireItemType.integer:
|
|
4673
|
-
return (React.createElement(core$1.TextInput, { type: "number", step: 1, id: name, name: name, defaultValue: initial
|
|
4938
|
+
return (React.createElement(core$1.TextInput, { type: "number", step: 1, id: name, name: name, defaultValue: initial?.valueInteger, onChange: (e) => onChangeAnswer({ valueInteger: e.currentTarget.valueAsNumber }) }));
|
|
4674
4939
|
case exports.QuestionnaireItemType.date:
|
|
4675
|
-
return (React.createElement(core$1.TextInput, { type: "date", id: name, name: name, defaultValue: initial
|
|
4940
|
+
return (React.createElement(core$1.TextInput, { type: "date", id: name, name: name, defaultValue: initial?.valueDate, onChange: (e) => onChangeAnswer({ valueDate: e.currentTarget.value }) }));
|
|
4676
4941
|
case exports.QuestionnaireItemType.dateTime:
|
|
4677
|
-
return (React.createElement(DateTimeInput, { name: name, defaultValue: initial
|
|
4942
|
+
return (React.createElement(DateTimeInput, { name: name, defaultValue: initial?.valueDateTime, onChange: (newValue) => onChangeAnswer({ valueDateTime: newValue }) }));
|
|
4678
4943
|
case exports.QuestionnaireItemType.time:
|
|
4679
|
-
return (React.createElement(core$1.TextInput, { type: "time", id: name, name: name, defaultValue: initial
|
|
4944
|
+
return (React.createElement(core$1.TextInput, { type: "time", id: name, name: name, defaultValue: initial?.valueTime, onChange: (e) => onChangeAnswer({ valueTime: e.currentTarget.value }) }));
|
|
4680
4945
|
case exports.QuestionnaireItemType.string:
|
|
4681
4946
|
case exports.QuestionnaireItemType.url:
|
|
4682
|
-
return (React.createElement(core$1.TextInput, { id: name, name: name, defaultValue: initial
|
|
4947
|
+
return (React.createElement(core$1.TextInput, { id: name, name: name, defaultValue: initial?.valueString, onChange: (e) => onChangeAnswer({ valueString: e.currentTarget.value }) }));
|
|
4683
4948
|
case exports.QuestionnaireItemType.text:
|
|
4684
|
-
return (React.createElement(core$1.Textarea, { id: name, name: name, defaultValue: initial
|
|
4949
|
+
return (React.createElement(core$1.Textarea, { id: name, name: name, defaultValue: initial?.valueString, onChange: (e) => onChangeAnswer({ valueString: e.currentTarget.value }) }));
|
|
4685
4950
|
case exports.QuestionnaireItemType.attachment:
|
|
4686
|
-
return (React.createElement(AttachmentInput, { name: name, defaultValue: initial
|
|
4951
|
+
return (React.createElement(AttachmentInput, { name: name, defaultValue: initial?.valueAttachment, onChange: (newValue) => onChangeAnswer({ valueAttachment: newValue }) }));
|
|
4687
4952
|
case exports.QuestionnaireItemType.reference:
|
|
4688
|
-
return (React.createElement(ReferenceInput, { name: name, defaultValue: initial
|
|
4953
|
+
return (React.createElement(ReferenceInput, { name: name, defaultValue: initial?.valueReference, onChange: (newValue) => onChangeAnswer({ valueReference: newValue }) }));
|
|
4689
4954
|
case exports.QuestionnaireItemType.quantity:
|
|
4690
|
-
return (React.createElement(QuantityInput, { name: name, defaultValue: initial
|
|
4955
|
+
return (React.createElement(QuantityInput, { name: name, defaultValue: initial?.valueQuantity, onChange: (newValue) => onChangeAnswer({ valueQuantity: newValue }) }));
|
|
4691
4956
|
case exports.QuestionnaireItemType.choice:
|
|
4692
4957
|
case exports.QuestionnaireItemType.openChoice:
|
|
4693
4958
|
if (isDropDownChoice(item)) {
|
|
@@ -4768,30 +5033,24 @@
|
|
|
4768
5033
|
return response;
|
|
4769
5034
|
}
|
|
4770
5035
|
function buildInitialResponseItems(items) {
|
|
4771
|
-
|
|
4772
|
-
return (_a = items === null || items === void 0 ? void 0 : items.map(buildInitialResponseItem)) !== null && _a !== void 0 ? _a : [];
|
|
5036
|
+
return items?.map(buildInitialResponseItem) ?? [];
|
|
4773
5037
|
}
|
|
4774
5038
|
function buildInitialResponseItem(item) {
|
|
4775
|
-
var _a, _b;
|
|
4776
5039
|
return {
|
|
4777
5040
|
linkId: item.linkId,
|
|
4778
5041
|
text: item.text,
|
|
4779
5042
|
item: buildInitialResponseItems(item.item),
|
|
4780
|
-
answer:
|
|
5043
|
+
answer: item.initial?.map(buildInitialResponseAnswer) ?? [],
|
|
4781
5044
|
};
|
|
4782
5045
|
}
|
|
4783
5046
|
function buildInitialResponseAnswer(answer) {
|
|
4784
5047
|
// This works because QuestionnaireItemInitial and QuestionnaireResponseItemAnswer
|
|
4785
5048
|
// have the same properties.
|
|
4786
|
-
return
|
|
5049
|
+
return { ...answer };
|
|
4787
5050
|
}
|
|
4788
5051
|
function isDropDownChoice(item) {
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
var _a, _b, _c;
|
|
4792
|
-
return e.url === 'http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl' &&
|
|
4793
|
-
((_c = (_b = (_a = e.valueCodeableConcept) === null || _a === void 0 ? void 0 : _a.coding) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.code) === 'drop-down';
|
|
4794
|
-
}));
|
|
5052
|
+
return !!item.extension?.some((e) => e.url === 'http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl' &&
|
|
5053
|
+
e.valueCodeableConcept?.coding?.[0]?.code === 'drop-down');
|
|
4795
5054
|
}
|
|
4796
5055
|
function isQuestionEnabled(item, answers) {
|
|
4797
5056
|
if (!item.enableWhen) {
|
|
@@ -4884,7 +5143,7 @@
|
|
|
4884
5143
|
medplum.requestSchema('Questionnaire').then(setSchema).catch(console.log);
|
|
4885
5144
|
}, [medplum]);
|
|
4886
5145
|
React.useEffect(() => {
|
|
4887
|
-
setValue(ensureQuestionnaireKeys(defaultValue
|
|
5146
|
+
setValue(ensureQuestionnaireKeys(defaultValue ?? { resourceType: 'Questionnaire' }));
|
|
4888
5147
|
document.addEventListener('mouseover', handleDocumentMouseOver);
|
|
4889
5148
|
document.addEventListener('click', handleDocumentClick);
|
|
4890
5149
|
return () => {
|
|
@@ -4901,13 +5160,12 @@
|
|
|
4901
5160
|
React.createElement(core$1.Button, { type: "submit" }, "Save"))));
|
|
4902
5161
|
}
|
|
4903
5162
|
function ItemBuilder(props) {
|
|
4904
|
-
var _a;
|
|
4905
5163
|
const { classes, cx } = useStyles$4();
|
|
4906
5164
|
const resource = props.item;
|
|
4907
5165
|
const item = props.item;
|
|
4908
5166
|
const isResource = 'resourceType' in props.item;
|
|
4909
5167
|
const isContainer = isResource || item.type === exports.QuestionnaireItemType.group;
|
|
4910
|
-
const linkId =
|
|
5168
|
+
const linkId = item.linkId ?? '[untitled]';
|
|
4911
5169
|
const editing = props.selectedKey === props.item.id;
|
|
4912
5170
|
const hovering = props.hoverKey === props.item.id;
|
|
4913
5171
|
const itemRef = React.useRef();
|
|
@@ -4921,20 +5179,29 @@
|
|
|
4921
5179
|
props.setHoverKey(props.item.id);
|
|
4922
5180
|
}
|
|
4923
5181
|
function changeItem(changedItem) {
|
|
4924
|
-
var _a;
|
|
4925
5182
|
const curr = itemRef.current;
|
|
4926
|
-
props.onChange(
|
|
5183
|
+
props.onChange({
|
|
5184
|
+
...curr,
|
|
5185
|
+
item: curr.item?.map((i) => (i.id === changedItem.id ? changedItem : i)),
|
|
5186
|
+
});
|
|
4927
5187
|
}
|
|
4928
5188
|
function addItem(addedItem) {
|
|
4929
|
-
|
|
4930
|
-
|
|
5189
|
+
props.onChange({
|
|
5190
|
+
...props.item,
|
|
5191
|
+
item: [...(props.item?.item ?? []), addedItem],
|
|
5192
|
+
});
|
|
4931
5193
|
}
|
|
4932
5194
|
function removeItem(removedItem) {
|
|
4933
|
-
|
|
4934
|
-
|
|
5195
|
+
props.onChange({
|
|
5196
|
+
...props.item,
|
|
5197
|
+
item: props.item?.item?.filter((i) => i !== removedItem),
|
|
5198
|
+
});
|
|
4935
5199
|
}
|
|
4936
5200
|
function changeProperty(property, value) {
|
|
4937
|
-
props.onChange(
|
|
5201
|
+
props.onChange({
|
|
5202
|
+
...itemRef.current,
|
|
5203
|
+
[property]: value,
|
|
5204
|
+
});
|
|
4938
5205
|
}
|
|
4939
5206
|
const className = cx(classes.section, {
|
|
4940
5207
|
[classes.editing]: editing,
|
|
@@ -4998,9 +5265,8 @@
|
|
|
4998
5265
|
} }, "Remove")))));
|
|
4999
5266
|
}
|
|
5000
5267
|
function AnswerBuilder(props) {
|
|
5001
|
-
var _a;
|
|
5002
5268
|
const property = core.globalSchema.types['QuestionnaireItemAnswerOption'].properties['value[x]'];
|
|
5003
|
-
const options =
|
|
5269
|
+
const options = props.options ?? [];
|
|
5004
5270
|
return (React.createElement("div", null,
|
|
5005
5271
|
options.map((option) => {
|
|
5006
5272
|
const [propertyValue, propertyType] = getValueAndType({ type: 'QuestionnaireItemAnswerOption', value: option }, 'value');
|
|
@@ -5055,28 +5321,39 @@
|
|
|
5055
5321
|
return 'id-' + nextId++;
|
|
5056
5322
|
}
|
|
5057
5323
|
function ensureQuestionnaireKeys(questionnaire) {
|
|
5058
|
-
return
|
|
5324
|
+
return {
|
|
5325
|
+
...questionnaire,
|
|
5326
|
+
id: questionnaire.id || generateId(),
|
|
5327
|
+
item: ensureQuestionnaireItemKeys(questionnaire.item),
|
|
5328
|
+
};
|
|
5059
5329
|
}
|
|
5060
5330
|
function ensureQuestionnaireItemKeys(items) {
|
|
5061
5331
|
if (!items) {
|
|
5062
5332
|
return undefined;
|
|
5063
5333
|
}
|
|
5064
5334
|
items.forEach((item) => {
|
|
5065
|
-
|
|
5066
|
-
if ((_a = item.id) === null || _a === void 0 ? void 0 : _a.match(/^id-\d+$/)) {
|
|
5335
|
+
if (item.id?.match(/^id-\d+$/)) {
|
|
5067
5336
|
nextId = Math.max(nextId, parseInt(item.id.substring(3)) + 1);
|
|
5068
5337
|
}
|
|
5069
|
-
if (
|
|
5338
|
+
if (item.linkId?.match(/^q\d+$/)) {
|
|
5070
5339
|
nextLinkId = Math.max(nextLinkId, parseInt(item.linkId.substring(1)) + 1);
|
|
5071
5340
|
}
|
|
5072
5341
|
});
|
|
5073
|
-
return items.map((item) => (
|
|
5342
|
+
return items.map((item) => ({
|
|
5343
|
+
...item,
|
|
5344
|
+
id: item.id || generateId(),
|
|
5345
|
+
item: ensureQuestionnaireItemKeys(item.item),
|
|
5346
|
+
answerOption: ensureQuestionnaireOptionKeys(item.answerOption),
|
|
5347
|
+
}));
|
|
5074
5348
|
}
|
|
5075
5349
|
function ensureQuestionnaireOptionKeys(options) {
|
|
5076
5350
|
if (!options) {
|
|
5077
5351
|
return undefined;
|
|
5078
5352
|
}
|
|
5079
|
-
return options.map((option) => (
|
|
5353
|
+
return options.map((option) => ({
|
|
5354
|
+
...option,
|
|
5355
|
+
id: option.id || generateId(),
|
|
5356
|
+
}));
|
|
5080
5357
|
}
|
|
5081
5358
|
|
|
5082
5359
|
const useStyles$3 = core$1.createStyles((theme) => ({
|
|
@@ -5108,10 +5385,7 @@
|
|
|
5108
5385
|
setIntervalGroups(groupQualifiedIntervals(definition.qualifiedInterval || [], setGroupId));
|
|
5109
5386
|
}, [defaultDefinition]);
|
|
5110
5387
|
return (React.createElement(Form, { testid: "reference-range-editor", onSubmit: submitDefinition },
|
|
5111
|
-
React.createElement(core$1.Stack, null, intervalGroups.map((intervalGroup) => {
|
|
5112
|
-
var _a;
|
|
5113
|
-
return (React.createElement(ReferenceRangeGroupEditor, { unit: getUnitString((_a = defaultDefinition.quantitativeDetails) === null || _a === void 0 ? void 0 : _a.unit), onChange: changeInterval, onAdd: addInterval, onRemove: removeInterval, onRemoveGroup: removeGroup, key: `group-${intervalGroup.id}`, intervalGroup: intervalGroup }));
|
|
5114
|
-
})),
|
|
5388
|
+
React.createElement(core$1.Stack, null, intervalGroups.map((intervalGroup) => (React.createElement(ReferenceRangeGroupEditor, { unit: getUnitString(defaultDefinition.quantitativeDetails?.unit), onChange: changeInterval, onAdd: addInterval, onRemove: removeInterval, onRemoveGroup: removeGroup, key: `group-${intervalGroup.id}`, intervalGroup: intervalGroup })))),
|
|
5115
5389
|
React.createElement(core$1.ActionIcon, { title: "Add Group", size: "sm", onClick: (e) => {
|
|
5116
5390
|
killEvent(e);
|
|
5117
5391
|
addGroup({ id: `group-id-${groupId}`, filters: {}, intervals: [] });
|
|
@@ -5127,7 +5401,7 @@
|
|
|
5127
5401
|
const qualifiedInterval = intervalGroups
|
|
5128
5402
|
.flatMap((group) => group.intervals)
|
|
5129
5403
|
.filter((interval) => !isEmptyInterval(interval));
|
|
5130
|
-
props.onSubmit(
|
|
5404
|
+
props.onSubmit({ ...defaultDefinition, qualifiedInterval });
|
|
5131
5405
|
}
|
|
5132
5406
|
/**
|
|
5133
5407
|
* Add Remove Interval Groups
|
|
@@ -5143,11 +5417,10 @@
|
|
|
5143
5417
|
*/
|
|
5144
5418
|
function changeInterval(groupId, changedInterval) {
|
|
5145
5419
|
setIntervalGroups((groups) => {
|
|
5146
|
-
var _a, _b;
|
|
5147
5420
|
groups = [...groups];
|
|
5148
5421
|
const currentGroup = groups.find((g) => g.id === groupId);
|
|
5149
|
-
const index =
|
|
5150
|
-
if (index !== undefined &&
|
|
5422
|
+
const index = currentGroup?.intervals?.findIndex((interval) => interval.id === changedInterval.id);
|
|
5423
|
+
if (index !== undefined && currentGroup?.intervals?.[index]) {
|
|
5151
5424
|
currentGroup.intervals[index] = changedInterval;
|
|
5152
5425
|
}
|
|
5153
5426
|
return groups;
|
|
@@ -5162,8 +5435,8 @@
|
|
|
5162
5435
|
groups = [...groups];
|
|
5163
5436
|
const currentGroupIndex = groups.findIndex((g) => g.id === groupId);
|
|
5164
5437
|
if (currentGroupIndex != -1) {
|
|
5165
|
-
const currentGroup =
|
|
5166
|
-
addedInterval =
|
|
5438
|
+
const currentGroup = { ...groups[currentGroupIndex] };
|
|
5439
|
+
addedInterval = { ...addedInterval, ...currentGroup.filters };
|
|
5167
5440
|
currentGroup.intervals = [...currentGroup.intervals, addedInterval];
|
|
5168
5441
|
groups[currentGroupIndex] = currentGroup;
|
|
5169
5442
|
}
|
|
@@ -5198,7 +5471,7 @@
|
|
|
5198
5471
|
React.createElement(core$1.Group, null,
|
|
5199
5472
|
React.createElement(core$1.TextInput, { key: `condition-${interval.id}`, "data-testid": `condition-${interval.id}`, defaultValue: interval.condition, label: 'Condition: ', size: 'sm', onChange: (e) => {
|
|
5200
5473
|
killEvent(e);
|
|
5201
|
-
props.onChange(intervalGroup.id,
|
|
5474
|
+
props.onChange(intervalGroup.id, { ...interval, condition: e.currentTarget.value.trim() });
|
|
5202
5475
|
} }),
|
|
5203
5476
|
React.createElement(core$1.ActionIcon, { title: "Remove Interval", size: "sm", key: `remove-interval-${interval.id}`, "data-testid": `remove-interval-${interval.id}`, onClick: (e) => {
|
|
5204
5477
|
killEvent(e);
|
|
@@ -5206,7 +5479,7 @@
|
|
|
5206
5479
|
} },
|
|
5207
5480
|
React.createElement(icons.IconCircleMinus, null))),
|
|
5208
5481
|
React.createElement(RangeInput, { onChange: (range) => {
|
|
5209
|
-
props.onChange(intervalGroup.id,
|
|
5482
|
+
props.onChange(intervalGroup.id, { ...interval, range });
|
|
5210
5483
|
}, key: `range-${interval.id}`, name: `range-${interval.id}`, defaultValue: interval.range })))),
|
|
5211
5484
|
React.createElement(core$1.ActionIcon, { title: "Add Interval", size: "sm", onClick: (e) => {
|
|
5212
5485
|
killEvent(e);
|
|
@@ -5223,27 +5496,32 @@
|
|
|
5223
5496
|
* Render the "filters" section of the IntervalGroup. Also populates some initial
|
|
5224
5497
|
*/
|
|
5225
5498
|
function ReferenceRangeGroupFilters(props) {
|
|
5226
|
-
var _a, _b;
|
|
5227
5499
|
const { intervalGroup, onChange } = props;
|
|
5228
5500
|
// Pre-populate the units of the age filter
|
|
5229
5501
|
if (!intervalGroup.filters.age) {
|
|
5230
5502
|
intervalGroup.filters.age = {};
|
|
5231
5503
|
}
|
|
5232
5504
|
for (const key of ['low', 'high']) {
|
|
5233
|
-
if (!
|
|
5234
|
-
intervalGroup.filters.age[key] =
|
|
5505
|
+
if (!intervalGroup.filters.age[key]?.unit) {
|
|
5506
|
+
intervalGroup.filters.age[key] = {
|
|
5507
|
+
...intervalGroup.filters.age[key],
|
|
5508
|
+
unit: 'years',
|
|
5509
|
+
system: 'http://unitsofmeasure.org',
|
|
5510
|
+
};
|
|
5235
5511
|
}
|
|
5236
5512
|
}
|
|
5237
5513
|
return (React.createElement(core$1.Stack, { style: { maxWidth: '50%' } },
|
|
5238
5514
|
React.createElement(core$1.Group, null,
|
|
5239
5515
|
React.createElement(core$1.NativeSelect, { data: ['', 'male', 'female'], label: "Gender:", defaultValue: intervalGroup.filters.gender || '', onChange: (e) => {
|
|
5240
|
-
var _a;
|
|
5241
5516
|
for (const interval of intervalGroup.intervals) {
|
|
5242
|
-
let newGender =
|
|
5517
|
+
let newGender = e.currentTarget?.value;
|
|
5243
5518
|
if (newGender === '') {
|
|
5244
5519
|
newGender = undefined;
|
|
5245
5520
|
}
|
|
5246
|
-
onChange(intervalGroup.id,
|
|
5521
|
+
onChange(intervalGroup.id, {
|
|
5522
|
+
...interval,
|
|
5523
|
+
gender: newGender,
|
|
5524
|
+
});
|
|
5247
5525
|
}
|
|
5248
5526
|
} })),
|
|
5249
5527
|
React.createElement(core$1.Group, { spacing: 'xs' },
|
|
@@ -5251,24 +5529,26 @@
|
|
|
5251
5529
|
React.createElement("div", { id: `div-age-${intervalGroup.id}` },
|
|
5252
5530
|
React.createElement(RangeInput, { key: `age-${intervalGroup.id}`, name: `age-${intervalGroup.id}`, defaultValue: intervalGroup.filters['age'], onChange: (ageRange) => {
|
|
5253
5531
|
for (const interval of intervalGroup.intervals) {
|
|
5254
|
-
onChange(intervalGroup.id,
|
|
5532
|
+
onChange(intervalGroup.id, { ...interval, age: ageRange });
|
|
5255
5533
|
}
|
|
5256
5534
|
} }))),
|
|
5257
|
-
React.createElement(core$1.NativeSelect, { data: ['', 'pre-puberty', 'follicular', 'midcycle', 'luteal', 'postmenopausal'], label: "Endocrine:", defaultValue:
|
|
5258
|
-
var _a;
|
|
5535
|
+
React.createElement(core$1.NativeSelect, { data: ['', 'pre-puberty', 'follicular', 'midcycle', 'luteal', 'postmenopausal'], label: "Endocrine:", defaultValue: intervalGroup.filters.context?.text || '', onChange: (e) => {
|
|
5259
5536
|
for (const interval of intervalGroup.intervals) {
|
|
5260
|
-
let newEndocrine =
|
|
5537
|
+
let newEndocrine = e.currentTarget?.value;
|
|
5261
5538
|
if (newEndocrine === '') {
|
|
5262
5539
|
newEndocrine = undefined;
|
|
5263
|
-
onChange(intervalGroup.id,
|
|
5540
|
+
onChange(intervalGroup.id, { ...interval, context: undefined });
|
|
5264
5541
|
}
|
|
5265
5542
|
else {
|
|
5266
|
-
onChange(intervalGroup.id,
|
|
5543
|
+
onChange(intervalGroup.id, {
|
|
5544
|
+
...interval,
|
|
5545
|
+
context: {
|
|
5267
5546
|
text: newEndocrine,
|
|
5268
5547
|
coding: [
|
|
5269
5548
|
{ code: newEndocrine, system: 'http://terminology.hl7.org/CodeSystem/referencerange-meaning' },
|
|
5270
5549
|
],
|
|
5271
|
-
}
|
|
5550
|
+
},
|
|
5551
|
+
});
|
|
5272
5552
|
}
|
|
5273
5553
|
}
|
|
5274
5554
|
} })));
|
|
@@ -5283,15 +5563,20 @@
|
|
|
5283
5563
|
const intervals = definition.qualifiedInterval || [];
|
|
5284
5564
|
// Set the nextId to the max of any existing numeric id
|
|
5285
5565
|
let nextId = Math.max(...intervals.map((interval) => {
|
|
5286
|
-
|
|
5287
|
-
const existingNum = parseInt(((_a = interval.id) === null || _a === void 0 ? void 0 : _a.substring(3)) || '');
|
|
5566
|
+
const existingNum = parseInt(interval.id?.substring(3) || '');
|
|
5288
5567
|
return !isNaN(existingNum) ? existingNum : Number.NEGATIVE_INFINITY;
|
|
5289
5568
|
})) + 1;
|
|
5290
5569
|
if (!Number.isFinite(nextId)) {
|
|
5291
5570
|
nextId = 1;
|
|
5292
5571
|
}
|
|
5293
5572
|
// If an interval doesn't have an id, set it to the nextId
|
|
5294
|
-
definition =
|
|
5573
|
+
definition = {
|
|
5574
|
+
...definition,
|
|
5575
|
+
qualifiedInterval: intervals.map((interval) => ({
|
|
5576
|
+
...interval,
|
|
5577
|
+
id: interval.id || `id-${nextId++}`,
|
|
5578
|
+
})),
|
|
5579
|
+
};
|
|
5295
5580
|
setIntervalId(nextId);
|
|
5296
5581
|
return definition;
|
|
5297
5582
|
}
|
|
@@ -5321,13 +5606,12 @@
|
|
|
5321
5606
|
* @return A "group key" that corresponds to the value of the interval filter properties.
|
|
5322
5607
|
*/
|
|
5323
5608
|
function generateGroupKey(interval) {
|
|
5324
|
-
var _a, _b;
|
|
5325
5609
|
const results = [
|
|
5326
5610
|
`gender=${interval.gender}`,
|
|
5327
5611
|
`age=${core.formatRange(interval.age)}`,
|
|
5328
5612
|
`gestationalAge=${core.formatRange(interval.gestationalAge)}`,
|
|
5329
|
-
`context=${
|
|
5330
|
-
`appliesTo=${
|
|
5613
|
+
`context=${interval.context?.text}`,
|
|
5614
|
+
`appliesTo=${interval.appliesTo?.map((c) => c.text).join('+')}`,
|
|
5331
5615
|
];
|
|
5332
5616
|
return results.join(':');
|
|
5333
5617
|
}
|
|
@@ -5335,69 +5619,10 @@
|
|
|
5335
5619
|
return unit && (core.getCodeBySystem(unit, 'http://unitsofmeasure.org') || unit.text);
|
|
5336
5620
|
}
|
|
5337
5621
|
function isEmptyInterval(interval) {
|
|
5338
|
-
|
|
5339
|
-
return ((_b = (_a = interval.range) === null || _a === void 0 ? void 0 : _a.low) === null || _b === void 0 ? void 0 : _b.value) === undefined && ((_d = (_c = interval.range) === null || _c === void 0 ? void 0 : _c.high) === null || _d === void 0 ? void 0 : _d.value) === undefined;
|
|
5340
|
-
}
|
|
5341
|
-
|
|
5342
|
-
/*
|
|
5343
|
-
* Request status: https://hl7.org/fhir/valueset-request-status.html
|
|
5344
|
-
* draft, active, on-hold, revoked, completed, entered-in-error, unknown
|
|
5345
|
-
*
|
|
5346
|
-
* Publication status: https://hl7.org/fhir/valueset-publication-status.html
|
|
5347
|
-
* draft, active, retired, unknown
|
|
5348
|
-
*
|
|
5349
|
-
* Observation status: https://www.hl7.org/fhir/valueset-observation-status.html
|
|
5350
|
-
* registered, preliminary, final, amended, cancelled, entered-in-error, unknown
|
|
5351
|
-
*
|
|
5352
|
-
* DiagnosticReport status: https://hl7.org/fhir/valueset-diagnostic-report-status.html
|
|
5353
|
-
* registered, preliminary, final, amended, corrected, appended, cancelled, entered-in-error, unknown
|
|
5354
|
-
*
|
|
5355
|
-
* Task status: https://hl7.org/fhir/valueset-task-status.html
|
|
5356
|
-
* draft, requested, received, accepted, rejected, ready, cancelled, in-progress, on-hold, failed, completed, entered-in-error
|
|
5357
|
-
*
|
|
5358
|
-
* Appointment status: https://www.hl7.org/fhir/valueset-appointmentstatus.html
|
|
5359
|
-
* proposed, pending, booked, arrived, fulfilled, cancelled, noshow, entered-in-error, chcked-in, waitlist
|
|
5360
|
-
*/
|
|
5361
|
-
const statusToColor = {
|
|
5362
|
-
draft: 'blue',
|
|
5363
|
-
active: 'blue',
|
|
5364
|
-
'on-hold': 'yellow',
|
|
5365
|
-
revoked: 'red',
|
|
5366
|
-
completed: 'green',
|
|
5367
|
-
'entered-in-error': 'red',
|
|
5368
|
-
unknown: 'gray',
|
|
5369
|
-
retired: 'gray',
|
|
5370
|
-
registered: 'blue',
|
|
5371
|
-
preliminary: 'blue',
|
|
5372
|
-
final: 'green',
|
|
5373
|
-
amended: 'yellow',
|
|
5374
|
-
cancelled: 'red',
|
|
5375
|
-
requested: 'blue',
|
|
5376
|
-
received: 'blue',
|
|
5377
|
-
accepted: 'blue',
|
|
5378
|
-
rejected: 'red',
|
|
5379
|
-
ready: 'blue',
|
|
5380
|
-
'in-progress': 'blue',
|
|
5381
|
-
failed: 'red',
|
|
5382
|
-
proposed: 'blue',
|
|
5383
|
-
pending: 'blue',
|
|
5384
|
-
booked: 'blue',
|
|
5385
|
-
arrived: 'blue',
|
|
5386
|
-
fulfilled: 'green',
|
|
5387
|
-
noshow: 'red',
|
|
5388
|
-
'checked-in': 'blue',
|
|
5389
|
-
waitlist: 'gray',
|
|
5390
|
-
routine: 'gray',
|
|
5391
|
-
urgent: 'red',
|
|
5392
|
-
asap: 'red',
|
|
5393
|
-
stat: 'red',
|
|
5394
|
-
};
|
|
5395
|
-
function StatusBadge(props) {
|
|
5396
|
-
return React.createElement(core$1.Badge, { color: statusToColor[props.status] }, props.status);
|
|
5622
|
+
return interval.range?.low?.value === undefined && interval.range?.high?.value === undefined;
|
|
5397
5623
|
}
|
|
5398
5624
|
|
|
5399
5625
|
function RequestGroupDisplay(props) {
|
|
5400
|
-
var _a;
|
|
5401
5626
|
const medplum = useMedplum();
|
|
5402
5627
|
const requestGroup = useResource(props.value);
|
|
5403
5628
|
const [startedLoading, setStartedLoading] = React.useState(false);
|
|
@@ -5411,34 +5636,32 @@
|
|
|
5411
5636
|
if (!requestGroup || !responseBundle) {
|
|
5412
5637
|
return null;
|
|
5413
5638
|
}
|
|
5414
|
-
return (React.createElement(core$1.Grid, null,
|
|
5415
|
-
var _a, _b, _c, _d, _e, _f;
|
|
5639
|
+
return (React.createElement(core$1.Grid, null, requestGroup.action?.map((action, index) => {
|
|
5416
5640
|
const task = action.resource && findBundleEntry(action.resource);
|
|
5417
|
-
const taskInput =
|
|
5418
|
-
const taskOutput =
|
|
5641
|
+
const taskInput = task?.input?.[0]?.valueReference;
|
|
5642
|
+
const taskOutput = task?.output?.[0]?.valueReference;
|
|
5419
5643
|
return (React.createElement(React.Fragment, { key: `action-${index}` },
|
|
5420
|
-
React.createElement(core$1.Grid.Col, { span: 1, p: "md" },
|
|
5644
|
+
React.createElement(core$1.Grid.Col, { span: 1, p: "md" }, task?.status === 'completed' ? React.createElement(icons.IconCheckbox, null) : React.createElement(icons.IconSquare, { color: "gray" })),
|
|
5421
5645
|
React.createElement(core$1.Grid.Col, { span: 9, p: "xs" },
|
|
5422
5646
|
React.createElement(core$1.Text, { weight: 500 }, action.title),
|
|
5423
5647
|
action.description && React.createElement("div", null, action.description),
|
|
5424
5648
|
React.createElement("div", null,
|
|
5425
5649
|
"Last edited by\u00A0",
|
|
5426
|
-
React.createElement(ResourceName, { value:
|
|
5650
|
+
React.createElement(ResourceName, { value: task?.meta?.author }),
|
|
5427
5651
|
"\u00A0on\u00A0",
|
|
5428
|
-
core.formatDateTime(
|
|
5652
|
+
core.formatDateTime(task?.meta?.lastUpdated)),
|
|
5429
5653
|
React.createElement("div", null,
|
|
5430
5654
|
"Status: ",
|
|
5431
|
-
React.createElement(StatusBadge, { status:
|
|
5655
|
+
React.createElement(StatusBadge, { status: task?.status || 'unknown' }))),
|
|
5432
5656
|
React.createElement(core$1.Grid.Col, { span: 2, p: "md" },
|
|
5433
5657
|
taskInput && !taskOutput && React.createElement(core$1.Button, { onClick: () => props.onStart(task, taskInput) }, "Start"),
|
|
5434
5658
|
taskInput && taskOutput && (React.createElement(core$1.Button, { onClick: () => props.onEdit(task, taskInput, taskOutput) }, "Edit")))));
|
|
5435
5659
|
})));
|
|
5436
5660
|
function buildBatchRequest(request) {
|
|
5437
|
-
var _a;
|
|
5438
5661
|
const batchEntries = [];
|
|
5439
5662
|
if (request.action) {
|
|
5440
5663
|
for (const action of request.action) {
|
|
5441
|
-
if (
|
|
5664
|
+
if (action.resource?.reference) {
|
|
5442
5665
|
batchEntries.push({ request: { method: 'GET', url: action.resource.reference } });
|
|
5443
5666
|
}
|
|
5444
5667
|
}
|
|
@@ -5450,7 +5673,7 @@
|
|
|
5450
5673
|
};
|
|
5451
5674
|
}
|
|
5452
5675
|
function findBundleEntry(reference) {
|
|
5453
|
-
for (const entry of responseBundle
|
|
5676
|
+
for (const entry of responseBundle?.entry) {
|
|
5454
5677
|
if (entry.resource && reference.reference === core.getReferenceString(entry.resource)) {
|
|
5455
5678
|
return entry.resource;
|
|
5456
5679
|
}
|
|
@@ -5579,13 +5802,10 @@
|
|
|
5579
5802
|
// Convert to array of array of lines
|
|
5580
5803
|
const versions = history.entry
|
|
5581
5804
|
.filter((entry) => !!entry.resource)
|
|
5582
|
-
.map((entry) => {
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
lines: core.stringify(entry.resource, true).match(/[^\r\n]+/g),
|
|
5587
|
-
});
|
|
5588
|
-
})
|
|
5805
|
+
.map((entry) => ({
|
|
5806
|
+
meta: entry.resource?.meta,
|
|
5807
|
+
lines: core.stringify(entry.resource, true).match(/[^\r\n]+/g),
|
|
5808
|
+
}))
|
|
5589
5809
|
.sort((a, b) => a.meta.lastUpdated.localeCompare(b.meta.lastUpdated));
|
|
5590
5810
|
// Start with array of lines from the first version
|
|
5591
5811
|
const table = versions[0].lines.map((line) => ({
|
|
@@ -5693,7 +5913,6 @@
|
|
|
5693
5913
|
},
|
|
5694
5914
|
}));
|
|
5695
5915
|
function ResourceBlame(props) {
|
|
5696
|
-
var _a, _b;
|
|
5697
5916
|
const { classes } = useStyles$2();
|
|
5698
5917
|
const medplum = useMedplum();
|
|
5699
5918
|
const [value, setValue] = React.useState(props.history);
|
|
@@ -5705,7 +5924,7 @@
|
|
|
5705
5924
|
if (!value) {
|
|
5706
5925
|
return React.createElement("div", null, "Loading...");
|
|
5707
5926
|
}
|
|
5708
|
-
const resource =
|
|
5927
|
+
const resource = value.entry?.[0]?.resource;
|
|
5709
5928
|
const table = blame(value);
|
|
5710
5929
|
return (React.createElement("div", { className: classes.container },
|
|
5711
5930
|
React.createElement("table", { className: classes.root },
|
|
@@ -5763,8 +5982,8 @@
|
|
|
5763
5982
|
let originalResource = props.original;
|
|
5764
5983
|
let revisedResource = props.revised;
|
|
5765
5984
|
if (props.ignoreMeta) {
|
|
5766
|
-
originalResource =
|
|
5767
|
-
revisedResource =
|
|
5985
|
+
originalResource = { ...originalResource, meta: undefined };
|
|
5986
|
+
revisedResource = { ...revisedResource, meta: undefined };
|
|
5768
5987
|
}
|
|
5769
5988
|
const original = core.stringify(originalResource, true).match(/[^\r\n]+/g);
|
|
5770
5989
|
const revised = core.stringify(revisedResource, true).match(/[^\r\n]+/g);
|
|
@@ -5783,7 +6002,6 @@
|
|
|
5783
6002
|
}
|
|
5784
6003
|
|
|
5785
6004
|
function ResourceHistoryTable(props) {
|
|
5786
|
-
var _a;
|
|
5787
6005
|
const medplum = useMedplum();
|
|
5788
6006
|
const [value, setValue] = React.useState(props.history);
|
|
5789
6007
|
React.useEffect(() => {
|
|
@@ -5803,27 +6021,25 @@
|
|
|
5803
6021
|
React.createElement("th", null, "Author"),
|
|
5804
6022
|
React.createElement("th", null, "Date"),
|
|
5805
6023
|
React.createElement("th", null, "Version"))),
|
|
5806
|
-
React.createElement("tbody", null,
|
|
6024
|
+
React.createElement("tbody", null, value.entry?.map((entry, index) => (React.createElement(HistoryRow, { key: 'entry-' + index, entry: entry }))))));
|
|
5807
6025
|
}
|
|
5808
6026
|
function HistoryRow(props) {
|
|
5809
|
-
var _a, _b, _c;
|
|
5810
6027
|
const { response, resource } = props.entry;
|
|
5811
6028
|
if (resource) {
|
|
5812
6029
|
return (React.createElement("tr", null,
|
|
5813
6030
|
React.createElement("td", null,
|
|
5814
|
-
React.createElement(ResourceBadge, { value:
|
|
5815
|
-
React.createElement("td", null, core.formatDateTime(
|
|
6031
|
+
React.createElement(ResourceBadge, { value: resource.meta?.author, link: true })),
|
|
6032
|
+
React.createElement("td", null, core.formatDateTime(resource.meta?.lastUpdated)),
|
|
5816
6033
|
React.createElement("td", null,
|
|
5817
|
-
React.createElement(MedplumLink, { to: getVersionUrl(resource) },
|
|
6034
|
+
React.createElement(MedplumLink, { to: getVersionUrl(resource) }, resource.meta?.versionId))));
|
|
5818
6035
|
}
|
|
5819
6036
|
else {
|
|
5820
6037
|
return (React.createElement("tr", null,
|
|
5821
|
-
React.createElement("td", { colSpan: 3 }, core.normalizeErrorString(response
|
|
6038
|
+
React.createElement("td", { colSpan: 3 }, core.normalizeErrorString(response?.outcome))));
|
|
5822
6039
|
}
|
|
5823
6040
|
}
|
|
5824
6041
|
function getVersionUrl(resource) {
|
|
5825
|
-
|
|
5826
|
-
return `/${resource.resourceType}/${resource.id}/_history/${(_a = resource.meta) === null || _a === void 0 ? void 0 : _a.versionId}`;
|
|
6042
|
+
return `/${resource.resourceType}/${resource.id}/_history/${resource.meta?.versionId}`;
|
|
5827
6043
|
}
|
|
5828
6044
|
|
|
5829
6045
|
const useStyles = core$1.createStyles((theme) => ({
|
|
@@ -5842,7 +6058,6 @@
|
|
|
5842
6058
|
},
|
|
5843
6059
|
}));
|
|
5844
6060
|
function Scheduler(props) {
|
|
5845
|
-
var _a;
|
|
5846
6061
|
const { classes } = useStyles();
|
|
5847
6062
|
const medplum = useMedplum();
|
|
5848
6063
|
const schedule = useResource(props.schedule);
|
|
@@ -5874,7 +6089,7 @@
|
|
|
5874
6089
|
if (!schedule || !slots || !questionnaire) {
|
|
5875
6090
|
return null;
|
|
5876
6091
|
}
|
|
5877
|
-
const actor =
|
|
6092
|
+
const actor = schedule.actor?.[0];
|
|
5878
6093
|
return (React.createElement("div", { className: classes.container, "data-testid": "scheduler" },
|
|
5879
6094
|
React.createElement("div", { className: classes.info },
|
|
5880
6095
|
actor && React.createElement(ResourceAvatar, { value: actor, size: "xl" }),
|
|
@@ -5965,6 +6180,7 @@
|
|
|
5965
6180
|
exports.AddressDisplay = AddressDisplay;
|
|
5966
6181
|
exports.AddressInput = AddressInput;
|
|
5967
6182
|
exports.AnnotationInput = AnnotationInput;
|
|
6183
|
+
exports.AsyncAutocomplete = AsyncAutocomplete;
|
|
5968
6184
|
exports.AttachmentArrayDisplay = AttachmentArrayDisplay;
|
|
5969
6185
|
exports.AttachmentArrayInput = AttachmentArrayInput;
|
|
5970
6186
|
exports.AttachmentButton = AttachmentButton;
|
|
@@ -6006,6 +6222,8 @@
|
|
|
6006
6222
|
exports.MedplumProvider = MedplumProvider;
|
|
6007
6223
|
exports.MemoizedFhirPathTable = MemoizedFhirPathTable;
|
|
6008
6224
|
exports.MemoizedSearchControl = MemoizedSearchControl;
|
|
6225
|
+
exports.MoneyDisplay = MoneyDisplay;
|
|
6226
|
+
exports.MoneyInput = MoneyInput;
|
|
6009
6227
|
exports.ObservationTable = ObservationTable;
|
|
6010
6228
|
exports.Panel = Panel;
|
|
6011
6229
|
exports.PatientTimeline = PatientTimeline;
|
|
@@ -6097,4 +6315,4 @@
|
|
|
6097
6315
|
exports.useResource = useResource;
|
|
6098
6316
|
|
|
6099
6317
|
}));
|
|
6100
|
-
//# sourceMappingURL=index.
|
|
6318
|
+
//# sourceMappingURL=index.cjs.map
|