@medplum/react 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/DiagnosticReportDisplay/DiagnosticReportDisplay.d.ts +2 -0
- package/dist/cjs/DiagnosticReportDisplay/DiagnosticReportDisplay.stories.d.ts +1 -0
- package/dist/cjs/MedplumProvider/MedplumProvider.d.ts +8 -0
- package/dist/cjs/NoteDisplay/NoteDisplay.d.ts +6 -0
- package/dist/cjs/{ResourceDiffTable/ResourceDiffTable.stories.d.ts → NoteDisplay/NoteDisplay.stories.d.ts} +3 -1
- package/dist/cjs/QuantityInput/QuantityInput.d.ts +1 -0
- package/dist/cjs/QuantityInput/QuantityInput.stories.d.ts +7 -0
- package/dist/cjs/index.cjs +1160 -1095
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.min.cjs +1 -1
- package/dist/esm/AddressDisplay/AddressDisplay.mjs +2 -2
- package/dist/esm/AddressDisplay/AddressDisplay.mjs.map +1 -1
- package/dist/esm/AddressInput/AddressInput.mjs +9 -9
- package/dist/esm/AddressInput/AddressInput.mjs.map +1 -1
- package/dist/esm/AnnotationInput/AnnotationInput.mjs +2 -2
- package/dist/esm/AnnotationInput/AnnotationInput.mjs.map +1 -1
- package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.mjs +2 -2
- package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.mjs.map +1 -1
- package/dist/esm/AttachmentArrayDisplay/AttachmentArrayDisplay.mjs +4 -4
- package/dist/esm/AttachmentArrayDisplay/AttachmentArrayDisplay.mjs.map +1 -1
- package/dist/esm/AttachmentArrayInput/AttachmentArrayInput.mjs +19 -19
- package/dist/esm/AttachmentArrayInput/AttachmentArrayInput.mjs.map +1 -1
- package/dist/esm/AttachmentButton/AttachmentButton.mjs +3 -3
- package/dist/esm/AttachmentButton/AttachmentButton.mjs.map +1 -1
- package/dist/esm/AttachmentDisplay/AttachmentDisplay.mjs +9 -9
- package/dist/esm/AttachmentDisplay/AttachmentDisplay.mjs.map +1 -1
- package/dist/esm/AttachmentInput/AttachmentInput.mjs +5 -5
- package/dist/esm/AttachmentInput/AttachmentInput.mjs.map +1 -1
- package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.mjs +6 -6
- package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.mjs.map +1 -1
- package/dist/esm/BackboneElementInput/BackboneElementInput.mjs +7 -7
- package/dist/esm/BackboneElementInput/BackboneElementInput.mjs.map +1 -1
- package/dist/esm/CalendarInput/CalendarInput.mjs +18 -18
- package/dist/esm/CalendarInput/CalendarInput.mjs.map +1 -1
- package/dist/esm/CheckboxFormSection/CheckboxFormSection.mjs +5 -5
- package/dist/esm/CheckboxFormSection/CheckboxFormSection.mjs.map +1 -1
- package/dist/esm/CodeInput/CodeInput.mjs +2 -2
- package/dist/esm/CodeInput/CodeInput.mjs.map +1 -1
- package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.mjs +2 -2
- package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.mjs.map +1 -1
- package/dist/esm/CodeableConceptInput/CodeableConceptInput.mjs +2 -2
- package/dist/esm/CodeableConceptInput/CodeableConceptInput.mjs.map +1 -1
- package/dist/esm/CodingDisplay/CodingDisplay.mjs +2 -2
- package/dist/esm/CodingDisplay/CodingDisplay.mjs.map +1 -1
- package/dist/esm/CodingInput/CodingInput.mjs +2 -2
- package/dist/esm/CodingInput/CodingInput.mjs.map +1 -1
- package/dist/esm/ContactDetailDisplay/ContactDetailDisplay.mjs +3 -3
- package/dist/esm/ContactDetailDisplay/ContactDetailDisplay.mjs.map +1 -1
- package/dist/esm/ContactDetailInput/ContactDetailInput.mjs +4 -4
- package/dist/esm/ContactDetailInput/ContactDetailInput.mjs.map +1 -1
- package/dist/esm/ContactPointDisplay/ContactPointDisplay.mjs +2 -2
- package/dist/esm/ContactPointDisplay/ContactPointDisplay.mjs.map +1 -1
- package/dist/esm/ContactPointInput/ContactPointInput.mjs +5 -5
- package/dist/esm/ContactPointInput/ContactPointInput.mjs.map +1 -1
- package/dist/esm/Container/Container.mjs +2 -2
- package/dist/esm/Container/Container.mjs.map +1 -1
- package/dist/esm/DateTimeInput/DateTimeInput.mjs +2 -2
- package/dist/esm/DateTimeInput/DateTimeInput.mjs.map +1 -1
- package/dist/esm/DefaultResourceTimeline/DefaultResourceTimeline.mjs +2 -2
- package/dist/esm/DefaultResourceTimeline/DefaultResourceTimeline.mjs.map +1 -1
- package/dist/esm/DescriptionList/DescriptionList.mjs +5 -5
- package/dist/esm/DescriptionList/DescriptionList.mjs.map +1 -1
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.d.ts +2 -0
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.mjs +56 -52
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.mjs.map +1 -1
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.stories.d.ts +1 -0
- package/dist/esm/Document/Document.mjs +3 -3
- package/dist/esm/Document/Document.mjs.map +1 -1
- package/dist/esm/EncounterTimeline/EncounterTimeline.mjs +2 -2
- package/dist/esm/EncounterTimeline/EncounterTimeline.mjs.map +1 -1
- package/dist/esm/ErrorBoundary/ErrorBoundary.mjs +4 -4
- package/dist/esm/ErrorBoundary/ErrorBoundary.mjs.map +1 -1
- package/dist/esm/ExtensionInput/ExtensionInput.mjs +2 -2
- package/dist/esm/ExtensionInput/ExtensionInput.mjs.map +1 -1
- package/dist/esm/FhirPathDisplay/FhirPathDisplay.mjs +2 -2
- package/dist/esm/FhirPathDisplay/FhirPathDisplay.mjs.map +1 -1
- package/dist/esm/FhirPathTable/FhirPathTable.mjs +19 -19
- package/dist/esm/FhirPathTable/FhirPathTable.mjs.map +1 -1
- package/dist/esm/Form/Form.mjs +2 -2
- package/dist/esm/Form/Form.mjs.map +1 -1
- package/dist/esm/FormSection/FormSection.mjs +2 -2
- package/dist/esm/FormSection/FormSection.mjs.map +1 -1
- package/dist/esm/GoogleButton/GoogleButton.mjs +8 -6
- package/dist/esm/GoogleButton/GoogleButton.mjs.map +1 -1
- package/dist/esm/HumanNameDisplay/HumanNameDisplay.mjs +2 -2
- package/dist/esm/HumanNameDisplay/HumanNameDisplay.mjs.map +1 -1
- package/dist/esm/HumanNameInput/HumanNameInput.mjs +7 -7
- package/dist/esm/HumanNameInput/HumanNameInput.mjs.map +1 -1
- package/dist/esm/IdentifierDisplay/IdentifierDisplay.mjs +2 -2
- package/dist/esm/IdentifierDisplay/IdentifierDisplay.mjs.map +1 -1
- package/dist/esm/IdentifierInput/IdentifierInput.mjs +4 -4
- package/dist/esm/IdentifierInput/IdentifierInput.mjs.map +1 -1
- package/dist/esm/Logo/Logo.mjs +8 -8
- package/dist/esm/Logo/Logo.mjs.map +1 -1
- package/dist/esm/MedplumLink/MedplumLink.mjs +4 -4
- package/dist/esm/MedplumLink/MedplumLink.mjs.map +1 -1
- package/dist/esm/MedplumProvider/MedplumProvider.d.ts +8 -0
- package/dist/esm/MedplumProvider/MedplumProvider.mjs +19 -3
- package/dist/esm/MedplumProvider/MedplumProvider.mjs.map +1 -1
- package/dist/esm/MoneyDisplay/MoneyDisplay.mjs +2 -2
- package/dist/esm/MoneyDisplay/MoneyDisplay.mjs.map +1 -1
- package/dist/esm/MoneyInput/MoneyInput.mjs +4 -4
- package/dist/esm/MoneyInput/MoneyInput.mjs.map +1 -1
- package/dist/esm/NoteDisplay/NoteDisplay.d.ts +6 -0
- package/dist/esm/NoteDisplay/NoteDisplay.mjs +18 -0
- package/dist/esm/NoteDisplay/NoteDisplay.mjs.map +1 -0
- package/dist/esm/{ResourceDiffTable/ResourceDiffTable.stories.d.ts → NoteDisplay/NoteDisplay.stories.d.ts} +3 -1
- package/dist/esm/OperationOutcomeAlert/OperationOutcomeAlert.mjs +3 -3
- package/dist/esm/OperationOutcomeAlert/OperationOutcomeAlert.mjs.map +1 -1
- package/dist/esm/Panel/Panel.mjs +2 -2
- package/dist/esm/Panel/Panel.mjs.map +1 -1
- package/dist/esm/PatientTimeline/PatientTimeline.mjs +2 -2
- package/dist/esm/PatientTimeline/PatientTimeline.mjs.map +1 -1
- package/dist/esm/PeriodInput/PeriodInput.mjs +4 -4
- package/dist/esm/PeriodInput/PeriodInput.mjs.map +1 -1
- package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.mjs +34 -34
- package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.mjs.map +1 -1
- package/dist/esm/QuantityDisplay/QuantityDisplay.mjs +2 -2
- package/dist/esm/QuantityDisplay/QuantityDisplay.mjs.map +1 -1
- package/dist/esm/QuantityInput/QuantityInput.d.ts +1 -0
- package/dist/esm/QuantityInput/QuantityInput.mjs +14 -8
- package/dist/esm/QuantityInput/QuantityInput.mjs.map +1 -1
- package/dist/esm/QuantityInput/QuantityInput.stories.d.ts +7 -0
- package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.mjs +31 -31
- package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.mjs.map +1 -1
- package/dist/esm/QuestionnaireForm/QuestionnaireForm.mjs +33 -33
- package/dist/esm/QuestionnaireForm/QuestionnaireForm.mjs.map +1 -1
- package/dist/esm/RangeDisplay/RangeDisplay.mjs +2 -2
- package/dist/esm/RangeDisplay/RangeDisplay.mjs.map +1 -1
- package/dist/esm/RangeInput/RangeInput.mjs +4 -4
- package/dist/esm/RangeInput/RangeInput.mjs.map +1 -1
- package/dist/esm/RatioDisplay/RatioDisplay.mjs +4 -4
- package/dist/esm/RatioDisplay/RatioDisplay.mjs.map +1 -1
- package/dist/esm/RatioInput/RatioInput.mjs +4 -4
- package/dist/esm/RatioInput/RatioInput.mjs.map +1 -1
- package/dist/esm/ReferenceDisplay/ReferenceDisplay.mjs +3 -3
- package/dist/esm/ReferenceDisplay/ReferenceDisplay.mjs.map +1 -1
- package/dist/esm/ReferenceInput/ReferenceInput.mjs +4 -4
- package/dist/esm/ReferenceInput/ReferenceInput.mjs.map +1 -1
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.mjs +31 -31
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.mjs.map +1 -1
- package/dist/esm/RequestGroupDisplay/RequestGroupDisplay.mjs +15 -15
- package/dist/esm/RequestGroupDisplay/RequestGroupDisplay.mjs.map +1 -1
- package/dist/esm/ResourceArrayDisplay/ResourceArrayDisplay.mjs +3 -3
- package/dist/esm/ResourceArrayDisplay/ResourceArrayDisplay.mjs.map +1 -1
- package/dist/esm/ResourceArrayInput/ResourceArrayInput.mjs +18 -18
- package/dist/esm/ResourceArrayInput/ResourceArrayInput.mjs.map +1 -1
- package/dist/esm/ResourceAvatar/ResourceAvatar.mjs +4 -4
- package/dist/esm/ResourceAvatar/ResourceAvatar.mjs.map +1 -1
- package/dist/esm/ResourceBadge/ResourceBadge.mjs +4 -4
- package/dist/esm/ResourceBadge/ResourceBadge.mjs.map +1 -1
- package/dist/esm/ResourceBlame/ResourceBlame.mjs +13 -13
- package/dist/esm/ResourceBlame/ResourceBlame.mjs.map +1 -1
- package/dist/esm/ResourceDiff/ResourceDiff.mjs +7 -7
- package/dist/esm/ResourceDiff/ResourceDiff.mjs.map +1 -1
- package/dist/esm/ResourceDiffTable/ResourceDiffTable.mjs +18 -18
- package/dist/esm/ResourceDiffTable/ResourceDiffTable.mjs.map +1 -1
- package/dist/esm/ResourceForm/ResourceForm.mjs +12 -12
- package/dist/esm/ResourceForm/ResourceForm.mjs.map +1 -1
- package/dist/esm/ResourceHistoryTable/ResourceHistoryTable.mjs +17 -17
- package/dist/esm/ResourceHistoryTable/ResourceHistoryTable.mjs.map +1 -1
- package/dist/esm/ResourceInput/ResourceInput.mjs +8 -8
- package/dist/esm/ResourceInput/ResourceInput.mjs.map +1 -1
- package/dist/esm/ResourceName/ResourceName.mjs +2 -2
- package/dist/esm/ResourceName/ResourceName.mjs.map +1 -1
- package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.mjs +26 -26
- package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.mjs.map +1 -1
- package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.mjs +34 -34
- package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.mjs.map +1 -1
- package/dist/esm/ResourceTable/ResourceTable.mjs +2 -2
- package/dist/esm/ResourceTable/ResourceTable.mjs.map +1 -1
- package/dist/esm/ResourceTimeline/ResourceTimeline.mjs +49 -50
- package/dist/esm/ResourceTimeline/ResourceTimeline.mjs.map +1 -1
- package/dist/esm/Scheduler/Scheduler.mjs +22 -22
- package/dist/esm/Scheduler/Scheduler.mjs.map +1 -1
- package/dist/esm/SearchControl/SearchControl.mjs +49 -49
- package/dist/esm/SearchControl/SearchControl.mjs.map +1 -1
- package/dist/esm/SearchControl/SearchUtils.mjs +4 -4
- package/dist/esm/SearchControl/SearchUtils.mjs.map +1 -1
- package/dist/esm/SearchFieldEditor/SearchFieldEditor.mjs +25 -25
- package/dist/esm/SearchFieldEditor/SearchFieldEditor.mjs.map +1 -1
- package/dist/esm/SearchFilterEditor/SearchFilterEditor.mjs +37 -37
- package/dist/esm/SearchFilterEditor/SearchFilterEditor.mjs.map +1 -1
- package/dist/esm/SearchFilterValueDialog/SearchFilterValueDialog.mjs +6 -6
- package/dist/esm/SearchFilterValueDialog/SearchFilterValueDialog.mjs.map +1 -1
- package/dist/esm/SearchFilterValueDisplay/SearchFilterValueDisplay.mjs +4 -4
- package/dist/esm/SearchFilterValueDisplay/SearchFilterValueDisplay.mjs.map +1 -1
- package/dist/esm/SearchFilterValueInput/SearchFilterValueInput.mjs +8 -8
- package/dist/esm/SearchFilterValueInput/SearchFilterValueInput.mjs.map +1 -1
- package/dist/esm/SearchPopupMenu/SearchPopupMenu.mjs +62 -62
- package/dist/esm/SearchPopupMenu/SearchPopupMenu.mjs.map +1 -1
- package/dist/esm/ServiceRequestTimeline/ServiceRequestTimeline.mjs +2 -2
- package/dist/esm/ServiceRequestTimeline/ServiceRequestTimeline.mjs.map +1 -1
- package/dist/esm/StatusBadge/StatusBadge.mjs +2 -2
- package/dist/esm/StatusBadge/StatusBadge.mjs.map +1 -1
- package/dist/esm/Timeline/Timeline.mjs +20 -20
- package/dist/esm/Timeline/Timeline.mjs.map +1 -1
- package/dist/esm/TimingInput/TimingInput.mjs +19 -19
- package/dist/esm/TimingInput/TimingInput.mjs.map +1 -1
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.mjs +2 -2
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.mjs.map +1 -1
- package/dist/esm/auth/AuthenticationForm.mjs +22 -22
- package/dist/esm/auth/AuthenticationForm.mjs.map +1 -1
- package/dist/esm/auth/ChooseProfileForm.mjs +11 -11
- package/dist/esm/auth/ChooseProfileForm.mjs.map +1 -1
- package/dist/esm/auth/ChooseScopeForm.mjs +9 -9
- package/dist/esm/auth/ChooseScopeForm.mjs.map +1 -1
- package/dist/esm/auth/MfaForm.mjs +12 -12
- package/dist/esm/auth/MfaForm.mjs.map +1 -1
- package/dist/esm/auth/NewProjectForm.mjs +12 -12
- package/dist/esm/auth/NewProjectForm.mjs.map +1 -1
- package/dist/esm/auth/NewUserForm.mjs +22 -22
- package/dist/esm/auth/NewUserForm.mjs.map +1 -1
- package/dist/esm/auth/RegisterForm.mjs +5 -5
- package/dist/esm/auth/RegisterForm.mjs.map +1 -1
- package/dist/esm/auth/SignInForm.mjs +8 -8
- package/dist/esm/auth/SignInForm.mjs.map +1 -1
- package/dist/esm/index.min.mjs +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons/icons-react/dist/index.esm.mjs +6 -0
- package/dist/esm/node_modules/@tabler/icons/icons-react/dist/index.esm.mjs.map +1 -0
- package/dist/esm/useResource/useResource.mjs +3 -0
- package/dist/esm/useResource/useResource.mjs.map +1 -1
- package/package.json +9 -14
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@medplum/core'), require('react'), require('@mantine/core'), require('@
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', '@medplum/core', 'react', '@mantine/core', '@
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.medplum = global.medplum || {}, global.medplum.react = {}), global.medplum.core, global.React, global.mantine.core, global.
|
|
5
|
-
})(this, (function (exports, core,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@medplum/core'), require('react'), require('@mantine/core'), require('@mantine/notifications')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', '@medplum/core', 'react', '@mantine/core', '@mantine/notifications'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.medplum = global.medplum || {}, global.medplum.react = {}), global.medplum.core, global.React, global.mantine.core, global.mantine.notifications));
|
|
5
|
+
})(this, (function (exports, core, e, core$1, notifications) { 'use strict';
|
|
6
|
+
|
|
7
|
+
function _interopNamespaceDefault(e) {
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var e__namespace = /*#__PURE__*/_interopNamespaceDefault(e);
|
|
6
25
|
|
|
7
26
|
function AddressDisplay(props) {
|
|
8
27
|
const address = props.value;
|
|
9
28
|
if (!address) {
|
|
10
29
|
return null;
|
|
11
30
|
}
|
|
12
|
-
return
|
|
31
|
+
return e.createElement(e.Fragment, null, core.formatAddress(address));
|
|
13
32
|
}
|
|
14
33
|
|
|
15
34
|
function getLine(address, index) {
|
|
@@ -24,8 +43,8 @@
|
|
|
24
43
|
return { ...address, line };
|
|
25
44
|
}
|
|
26
45
|
function AddressInput(props) {
|
|
27
|
-
const [value, setValue] =
|
|
28
|
-
const valueRef =
|
|
46
|
+
const [value, setValue] = e.useState(props.defaultValue || {});
|
|
47
|
+
const valueRef = e.useRef();
|
|
29
48
|
valueRef.current = value;
|
|
30
49
|
function setValueWrapper(newValue) {
|
|
31
50
|
setValue(newValue);
|
|
@@ -54,17 +73,17 @@
|
|
|
54
73
|
function setPostalCode(postalCode) {
|
|
55
74
|
setValueWrapper({ ...valueRef.current, postalCode });
|
|
56
75
|
}
|
|
57
|
-
return (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
76
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
77
|
+
e.createElement(core$1.NativeSelect, { "data-testid": "address-use", defaultValue: value?.use, onChange: (e) => setUse(e.currentTarget.value), data: ['', 'home', 'work', 'temp', 'old', 'billing'] }),
|
|
78
|
+
e.createElement(core$1.NativeSelect, { "data-testid": "address-type", defaultValue: value?.type, onChange: (e) => setType(e.currentTarget.value), data: ['', 'postal', 'physical', 'both'] }),
|
|
79
|
+
e.createElement(core$1.TextInput, { placeholder: "Line 1", defaultValue: getLine(value, 0), onChange: (e) => setLine1(e.currentTarget.value) }),
|
|
80
|
+
e.createElement(core$1.TextInput, { placeholder: "Line 2", defaultValue: getLine(value, 1), onChange: (e) => setLine2(e.currentTarget.value) }),
|
|
81
|
+
e.createElement(core$1.TextInput, { placeholder: "City", defaultValue: value.city, onChange: (e) => setCity(e.currentTarget.value) }),
|
|
82
|
+
e.createElement(core$1.TextInput, { placeholder: "State", defaultValue: value.state, onChange: (e) => setState(e.currentTarget.value) }),
|
|
83
|
+
e.createElement(core$1.TextInput, { placeholder: "Postal Code", defaultValue: value.postalCode, onChange: (e) => setPostalCode(e.currentTarget.value) })));
|
|
65
84
|
}
|
|
66
85
|
|
|
67
|
-
const reactContext =
|
|
86
|
+
const reactContext = e.createContext(undefined);
|
|
68
87
|
/**
|
|
69
88
|
* The MedplumProvider component provides Medplum context state.
|
|
70
89
|
*
|
|
@@ -74,11 +93,12 @@
|
|
|
74
93
|
*/
|
|
75
94
|
function MedplumProvider(props) {
|
|
76
95
|
const medplum = props.medplum;
|
|
77
|
-
const
|
|
96
|
+
const navigate = props.navigate || defaultNavigate;
|
|
97
|
+
const [state, setState] = e.useState({
|
|
78
98
|
profile: medplum.getProfile(),
|
|
79
99
|
loading: false,
|
|
80
100
|
});
|
|
81
|
-
|
|
101
|
+
e.useEffect(() => {
|
|
82
102
|
function eventListener() {
|
|
83
103
|
setState({
|
|
84
104
|
...state,
|
|
@@ -91,14 +111,15 @@
|
|
|
91
111
|
const medplumContext = {
|
|
92
112
|
...state,
|
|
93
113
|
medplum,
|
|
114
|
+
navigate,
|
|
94
115
|
};
|
|
95
|
-
return
|
|
116
|
+
return e.createElement(reactContext.Provider, { value: medplumContext }, props.children);
|
|
96
117
|
}
|
|
97
118
|
/**
|
|
98
119
|
* Returns the MedplumContext instance.
|
|
99
120
|
*/
|
|
100
121
|
function useMedplumContext() {
|
|
101
|
-
return
|
|
122
|
+
return e.useContext(reactContext);
|
|
102
123
|
}
|
|
103
124
|
/**
|
|
104
125
|
* Returns the MedplumClient instance.
|
|
@@ -107,6 +128,13 @@
|
|
|
107
128
|
function useMedplum() {
|
|
108
129
|
return useMedplumContext().medplum;
|
|
109
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Returns the Medplum navigate function.
|
|
133
|
+
* @returns The Medplum navigate function.
|
|
134
|
+
*/
|
|
135
|
+
function useMedplumNavigate() {
|
|
136
|
+
return useMedplumContext().navigate;
|
|
137
|
+
}
|
|
110
138
|
/**
|
|
111
139
|
* Returns the current Medplum user profile (if signed in).
|
|
112
140
|
* This is a shortcut for useMedplumContext().profile.
|
|
@@ -115,11 +143,18 @@
|
|
|
115
143
|
function useMedplumProfile() {
|
|
116
144
|
return useMedplumContext().profile;
|
|
117
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* The default "navigate" function which simply uses window.location.href.
|
|
148
|
+
* @param path The path to navigate to.
|
|
149
|
+
*/
|
|
150
|
+
function defaultNavigate(path) {
|
|
151
|
+
window.location.assign(path);
|
|
152
|
+
}
|
|
118
153
|
|
|
119
154
|
function AnnotationInput(props) {
|
|
120
155
|
const author = useMedplumProfile();
|
|
121
|
-
const [value, setValue] =
|
|
122
|
-
const valueRef =
|
|
156
|
+
const [value, setValue] = e.useState(props.defaultValue || {});
|
|
157
|
+
const valueRef = e.useRef();
|
|
123
158
|
valueRef.current = value;
|
|
124
159
|
function setText(text) {
|
|
125
160
|
const newValue = text
|
|
@@ -134,7 +169,7 @@
|
|
|
134
169
|
props.onChange(newValue);
|
|
135
170
|
}
|
|
136
171
|
}
|
|
137
|
-
return (
|
|
172
|
+
return (e.createElement(core$1.TextInput, { name: props.name, placeholder: "Annotation text", defaultValue: value.text, onChange: (e) => setText(e.currentTarget.value) }));
|
|
138
173
|
}
|
|
139
174
|
|
|
140
175
|
/**
|
|
@@ -172,23 +207,23 @@
|
|
|
172
207
|
function AsyncAutocomplete(props) {
|
|
173
208
|
const { defaultValue, toKey, toOption, loadOptions, onChange, onCreate, ...rest } = props;
|
|
174
209
|
const defaultItems = toDefaultItems(defaultValue);
|
|
175
|
-
const inputRef =
|
|
176
|
-
const [lastValue, setLastValue] =
|
|
177
|
-
const [timer, setTimer] =
|
|
178
|
-
const [abortController, setAbortController] =
|
|
179
|
-
const [autoSubmit, setAutoSubmit] =
|
|
180
|
-
const [options, setOptions] =
|
|
181
|
-
const lastValueRef =
|
|
210
|
+
const inputRef = e.useRef(null);
|
|
211
|
+
const [lastValue, setLastValue] = e.useState(undefined);
|
|
212
|
+
const [timer, setTimer] = e.useState();
|
|
213
|
+
const [abortController, setAbortController] = e.useState();
|
|
214
|
+
const [autoSubmit, setAutoSubmit] = e.useState();
|
|
215
|
+
const [options, setOptions] = e.useState(defaultItems?.map(toOption));
|
|
216
|
+
const lastValueRef = e.useRef();
|
|
182
217
|
lastValueRef.current = lastValue;
|
|
183
|
-
const timerRef =
|
|
218
|
+
const timerRef = e.useRef();
|
|
184
219
|
timerRef.current = timer;
|
|
185
|
-
const abortControllerRef =
|
|
220
|
+
const abortControllerRef = e.useRef();
|
|
186
221
|
abortControllerRef.current = abortController;
|
|
187
|
-
const autoSubmitRef =
|
|
222
|
+
const autoSubmitRef = e.useRef();
|
|
188
223
|
autoSubmitRef.current = autoSubmit;
|
|
189
|
-
const optionsRef =
|
|
224
|
+
const optionsRef = e.useRef();
|
|
190
225
|
optionsRef.current = options;
|
|
191
|
-
const handleTimer =
|
|
226
|
+
const handleTimer = e.useCallback(() => {
|
|
192
227
|
setTimer(undefined);
|
|
193
228
|
const value = inputRef.current?.value?.trim() || '';
|
|
194
229
|
if (value === lastValueRef.current) {
|
|
@@ -213,7 +248,7 @@
|
|
|
213
248
|
})
|
|
214
249
|
.catch(console.log);
|
|
215
250
|
}, [loadOptions, onChange, toOption]);
|
|
216
|
-
const handleSearchChange =
|
|
251
|
+
const handleSearchChange = e.useCallback(() => {
|
|
217
252
|
if (abortControllerRef.current) {
|
|
218
253
|
abortControllerRef.current.abort();
|
|
219
254
|
setAbortController(undefined);
|
|
@@ -224,7 +259,7 @@
|
|
|
224
259
|
const newTimer = window.setTimeout(() => handleTimer(), 100);
|
|
225
260
|
setTimer(newTimer);
|
|
226
261
|
}, [handleTimer]);
|
|
227
|
-
const handleChange =
|
|
262
|
+
const handleChange = e.useCallback((values) => {
|
|
228
263
|
const result = [];
|
|
229
264
|
for (const value of values) {
|
|
230
265
|
let item = optionsRef.current?.find((option) => option.value === value)?.resource;
|
|
@@ -235,7 +270,7 @@
|
|
|
235
270
|
}
|
|
236
271
|
onChange(result);
|
|
237
272
|
}, [onChange, onCreate]);
|
|
238
|
-
const handleKeyDown =
|
|
273
|
+
const handleKeyDown = e.useCallback((e) => {
|
|
239
274
|
if (e.key === 'Enter') {
|
|
240
275
|
if (!timerRef.current && !abortControllerRef.current) {
|
|
241
276
|
killEvent(e);
|
|
@@ -251,20 +286,20 @@
|
|
|
251
286
|
}
|
|
252
287
|
}
|
|
253
288
|
}, [handleChange]);
|
|
254
|
-
const handleCreate =
|
|
289
|
+
const handleCreate = e.useCallback((input) => {
|
|
255
290
|
const option = toOption(onCreate(input));
|
|
256
291
|
setOptions([...optionsRef.current, option]);
|
|
257
292
|
return option;
|
|
258
293
|
}, [onCreate, setOptions, toOption]);
|
|
259
|
-
const handleFilter =
|
|
260
|
-
|
|
294
|
+
const handleFilter = e.useCallback((_value, selected) => !selected, []);
|
|
295
|
+
e.useEffect(() => {
|
|
261
296
|
return () => {
|
|
262
297
|
if (abortControllerRef.current) {
|
|
263
298
|
abortControllerRef.current.abort();
|
|
264
299
|
}
|
|
265
300
|
};
|
|
266
301
|
}, []);
|
|
267
|
-
return (
|
|
302
|
+
return (e.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 ? e.createElement(core$1.Loader, { size: 16 }) : null, filter: handleFilter }));
|
|
268
303
|
}
|
|
269
304
|
function toDefaultItems(defaultValue) {
|
|
270
305
|
if (!defaultValue) {
|
|
@@ -282,25 +317,27 @@
|
|
|
282
317
|
if (!url) {
|
|
283
318
|
return null;
|
|
284
319
|
}
|
|
285
|
-
return (
|
|
286
|
-
contentType?.startsWith('image/') && (
|
|
287
|
-
contentType?.startsWith('video/') && (
|
|
288
|
-
|
|
289
|
-
contentType === 'application/pdf' && !title?.endsWith('.pdf') && (
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
320
|
+
return (e.createElement("div", { "data-testid": "attachment-display" },
|
|
321
|
+
contentType?.startsWith('image/') && (e.createElement("img", { "data-testid": "attachment-image", style: { maxWidth: props.maxWidth }, src: url, alt: value?.title })),
|
|
322
|
+
contentType?.startsWith('video/') && (e.createElement("video", { "data-testid": "attachment-video", style: { maxWidth: props.maxWidth }, controls: true },
|
|
323
|
+
e.createElement("source", { type: contentType, src: url }))),
|
|
324
|
+
contentType === 'application/pdf' && !title?.endsWith('.pdf') && (e.createElement("div", { "data-testid": "attachment-pdf", style: { maxWidth: props.maxWidth, minHeight: 400 } },
|
|
325
|
+
e.createElement("iframe", { width: "100%", height: "400", src: url + '#navpanes=0', allowFullScreen: true, frameBorder: 0, seamless: true }))),
|
|
326
|
+
e.createElement("div", { "data-testid": "download-link", style: { padding: '2px 16px 16px 16px' } },
|
|
327
|
+
e.createElement(core$1.Anchor, { href: value?.url, "data-testid": "attachment-details", target: "_blank", rel: "noopener noreferrer" }, value?.title || 'Download'))));
|
|
293
328
|
}
|
|
294
329
|
|
|
295
330
|
function AttachmentArrayDisplay(props) {
|
|
296
|
-
return (
|
|
297
|
-
props.values.map((v, index) => (
|
|
298
|
-
|
|
331
|
+
return (e.createElement("div", null, props.values &&
|
|
332
|
+
props.values.map((v, index) => (e.createElement("div", { key: 'attatchment-' + index },
|
|
333
|
+
e.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
|
|
299
334
|
}
|
|
300
335
|
|
|
336
|
+
function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var r in o)Object.prototype.hasOwnProperty.call(o,r)&&(e[r]=o[r]);}return e},t.apply(this,arguments)}function o(e,t){if(null==e)return {};var o,r,n=function(e,t){if(null==e)return {};var o,r,n={},l=Object.keys(e);for(r=0;r<l.length;r++)o=l[r],t.indexOf(o)>=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)o=l[r],t.indexOf(o)>=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o]);}return n}var te=["size","color","stroke"];function oe(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,te);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-adjustments-horizontal",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("circle",{cx:14,cy:6,r:2}),e__namespace.createElement("line",{x1:4,y1:6,x2:12,y2:6}),e__namespace.createElement("line",{x1:16,y1:6,x2:20,y2:6}),e__namespace.createElement("circle",{cx:8,cy:12,r:2}),e__namespace.createElement("line",{x1:4,y1:12,x2:6,y2:12}),e__namespace.createElement("line",{x1:10,y1:12,x2:20,y2:12}),e__namespace.createElement("circle",{cx:17,cy:18,r:2}),e__namespace.createElement("line",{x1:4,y1:18,x2:15,y2:18}),e__namespace.createElement("line",{x1:19,y1:18,x2:20,y2:18}))}var Ne=["size","color","stroke"];function We(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,Ne);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-alert-circle",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("circle",{cx:12,cy:12,r:9}),e__namespace.createElement("line",{x1:12,y1:8,x2:12,y2:12}),e__namespace.createElement("line",{x1:12,y1:16,x2:12.01,y2:16}))}var Gv=["size","color","stroke"];function Jv(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,Gv);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-bleach-off",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M5 19h14m1.986 -1.977a2.001 2.001 0 0 0 -.146 -.773l-7.1 -12.25a2 2 0 0 0 -3.5 0l-.815 1.405m-1.488 2.568l-4.797 8.277a2 2 0 0 0 1.75 2.75"}),e__namespace.createElement("path",{d:"M3 3l18 18"}))}var Kv=["size","color","stroke"];function Qv(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,Kv);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-bleach",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"}))}var zw=["size","color","stroke"];function bw(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,zw);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-box-multiple",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("rect",{x:7,y:3,width:14,height:14,rx:2}),e__namespace.createElement("path",{d:"M17 17v2a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h2"}))}var Gw=["size","color","stroke"];function Jw(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,Gw);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-brackets-contain",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M7 4h-4v16h4"}),e__namespace.createElement("path",{d:"M17 4h4v16h-4"}),e__namespace.createElement("path",{d:"M8 16h.01"}),e__namespace.createElement("path",{d:"M12 16h.01"}),e__namespace.createElement("path",{d:"M16 16h.01"}))}var yC=["size","color","stroke"];function CC(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,yC);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-bucket-off",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M5.029 5.036c-.655 .58 -1.029 1.25 -1.029 1.964c0 2.033 3.033 3.712 6.96 3.967m3.788 -.21c3.064 -.559 5.252 -2.029 5.252 -3.757c0 -2.21 -3.582 -4 -8 -4c-1.605 0 -3.1 .236 -4.352 .643"}),e__namespace.createElement("path",{d:"M4 7c0 .664 .088 1.324 .263 1.965l2.737 10.035c.5 1.5 2.239 2 5 2s4.5 -.5 5 -2c.1 -.3 .252 -.812 .457 -1.535m.862 -3.146c.262 -.975 .735 -2.76 1.418 -5.354a7.45 7.45 0 0 0 .263 -1.965"}),e__namespace.createElement("path",{d:"M3 3l18 18"}))}var jC=["size","color","stroke"];function BC(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,jC);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-bucket",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("ellipse",{cx:12,cy:7,rx:8,ry:4}),e__namespace.createElement("path",{d:"M4 7c0 .664 .088 1.324 .263 1.965l2.737 10.035c.5 1.5 2.239 2 5 2s4.5 -.5 5 -2c.333 -1 1.246 -4.345 2.737 -10.035a7.45 7.45 0 0 0 .263 -1.965"}))}var fB=["size","color","stroke"];function zB(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,fB);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-calendar",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("rect",{x:4,y:5,width:16,height:16,rx:2}),e__namespace.createElement("line",{x1:16,y1:3,x2:16,y2:7}),e__namespace.createElement("line",{x1:8,y1:3,x2:8,y2:7}),e__namespace.createElement("line",{x1:4,y1:11,x2:20,y2:11}),e__namespace.createElement("line",{x1:11,y1:15,x2:12,y2:15}),e__namespace.createElement("line",{x1:12,y1:15,x2:12,y2:18}))}var AW=["size","color","stroke"];function DW(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,AW);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-check",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M5 12l5 5l10 -10"}))}var FW=["size","color","stroke"];function GW(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,FW);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-checkbox",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("polyline",{points:"9 11 12 14 20 6"}),e__namespace.createElement("path",{d:"M20 12v6a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h9"}))}var SP=["size","color","stroke"];function IP(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,SP);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-circle-minus",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("circle",{cx:12,cy:12,r:9}),e__namespace.createElement("line",{x1:9,y1:12,x2:15,y2:12}))}var aS=["size","color","stroke"];function iS(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,aS);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-circle-plus",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("circle",{cx:12,cy:12,r:9}),e__namespace.createElement("line",{x1:9,y1:12,x2:15,y2:12}),e__namespace.createElement("line",{x1:12,y1:9,x2:12,y2:15}))}var VA=["size","color","stroke"];function XA(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,VA);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-cloud-upload",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M7 18a4.6 4.4 0 0 1 0 -9a5 4.5 0 0 1 11 2h1a3.5 3.5 0 0 1 0 7h-1"}),e__namespace.createElement("polyline",{points:"9 15 12 12 15 15"}),e__namespace.createElement("line",{x1:12,y1:12,x2:12,y2:21}))}var cF=["size","color","stroke"];function sF(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,cF);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-columns",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("line",{x1:4,y1:6,x2:9.5,y2:6}),e__namespace.createElement("line",{x1:4,y1:10,x2:9.5,y2:10}),e__namespace.createElement("line",{x1:4,y1:14,x2:9.5,y2:14}),e__namespace.createElement("line",{x1:4,y1:18,x2:9.5,y2:18}),e__namespace.createElement("line",{x1:14.5,y1:6,x2:20,y2:6}),e__namespace.createElement("line",{x1:14.5,y1:10,x2:20,y2:10}),e__namespace.createElement("line",{x1:14.5,y1:14,x2:20,y2:14}),e__namespace.createElement("line",{x1:14.5,y1:18,x2:20,y2:18}))}var jK=["size","color","stroke"];function BK(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,jK);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-currency-dollar",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M16.7 8a3 3 0 0 0 -2.7 -2h-4a3 3 0 0 0 0 6h4a3 3 0 0 1 0 6h-4a3 3 0 0 1 -2.7 -2"}),e__namespace.createElement("path",{d:"M12 3v3m0 12v3"}))}var jX=["size","color","stroke"];function BX(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,jX);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-dots",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("circle",{cx:5,cy:12,r:1}),e__namespace.createElement("circle",{cx:12,cy:12,r:1}),e__namespace.createElement("circle",{cx:19,cy:12,r:1}))}var yY=["size","color","stroke"];function CY(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,yY);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-edit",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"}),e__namespace.createElement("path",{d:"M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"}),e__namespace.createElement("path",{d:"M16 5l3 3"}))}var oZ=["size","color","stroke"];function rZ(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,oZ);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-equal-not",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M5 10h14"}),e__namespace.createElement("path",{d:"M5 14h14"}),e__namespace.createElement("path",{d:"M5 19l14 -14"}))}var nZ=["size","color","stroke"];function lZ(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,nZ);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-equal",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M5 10h14"}),e__namespace.createElement("path",{d:"M5 14h14"}))}var j$=["size","color","stroke"];function B$(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,j$);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-file-alert",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M14 3v4a1 1 0 0 0 1 1h4"}),e__namespace.createElement("path",{d:"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"}),e__namespace.createElement("line",{x1:12,y1:17,x2:12.01,y2:17}),e__namespace.createElement("line",{x1:12,y1:11,x2:12,y2:14}))}var V_=["size","color","stroke"];function X_(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,V_);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-file-plus",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M14 3v4a1 1 0 0 0 1 1h4"}),e__namespace.createElement("path",{d:"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"}),e__namespace.createElement("line",{x1:12,y1:11,x2:12,y2:17}),e__namespace.createElement("line",{x1:9,y1:14,x2:15,y2:14}))}var Q0=["size","color","stroke"];function R0(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,Q0);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-filter",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M5.5 5h13a1 1 0 0 1 .5 1.5l-5 5.5l0 7l-4 -3l0 -4l-5 -5.5a1 1 0 0 1 .5 -1.5"}))}var Wae=["size","color","stroke"];function qae(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,Wae);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-list-details",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M13 5h8"}),e__namespace.createElement("path",{d:"M13 9h5"}),e__namespace.createElement("path",{d:"M13 15h8"}),e__namespace.createElement("path",{d:"M13 19h5"}),e__namespace.createElement("rect",{x:3,y:4,width:6,height:6,rx:1}),e__namespace.createElement("rect",{x:3,y:14,width:6,height:6,rx:1}))}var yse=["size","color","stroke"];function Cse(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,yse);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-math-greater",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M5 18l14 -6l-14 -6"}))}var Ose=["size","color","stroke"];function Pse(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,Ose);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-math-lower",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M19 18l-14 -6l14 -6"}))}var bde=["size","color","stroke"];function Lde(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,bde);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-message",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M4 21v-13a3 3 0 0 1 3 -3h10a3 3 0 0 1 3 3v6a3 3 0 0 1 -3 3h-9l-4 4"}),e__namespace.createElement("line",{x1:8,y1:9,x2:16,y2:9}),e__namespace.createElement("line",{x1:8,y1:13,x2:14,y2:13}))}var pge=["size","color","stroke"];function Ege(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,pge);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-pin",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M15 4.5l-4 4l-4 1.5l-1.5 1.5l7 7l1.5 -1.5l1.5 -4l4 -4"}),e__namespace.createElement("line",{x1:9,y1:15,x2:4.5,y2:19.5}),e__namespace.createElement("line",{x1:14.5,y1:4,x2:20,y2:9.5}))}var Mge=["size","color","stroke"];function xge(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,Mge);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-pinned-off",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("line",{x1:3,y1:3,x2:21,y2:21}),e__namespace.createElement("path",{d:"M15 4.5l-3.249 3.249m-2.57 1.433l-2.181 .818l-1.5 1.5l7 7l1.5 -1.5l.82 -2.186m1.43 -2.563l3.25 -3.251"}),e__namespace.createElement("line",{x1:9,y1:15,x2:4.5,y2:19.5}),e__namespace.createElement("line",{x1:14.5,y1:4,x2:20,y2:9.5}))}var jje=["size","color","stroke"];function Bje(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,jje);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-settings",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"}),e__namespace.createElement("circle",{cx:12,cy:12,r:3}))}var aNe=["size","color","stroke"];function iNe(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,aNe);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-sort-ascending",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("line",{x1:4,y1:6,x2:11,y2:6}),e__namespace.createElement("line",{x1:4,y1:12,x2:11,y2:12}),e__namespace.createElement("line",{x1:4,y1:18,x2:13,y2:18}),e__namespace.createElement("polyline",{points:"15 9 18 6 21 9"}),e__namespace.createElement("line",{x1:18,y1:6,x2:18,y2:18}))}var kNe=["size","color","stroke"];function wNe(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,kNe);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-sort-descending",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("line",{x1:4,y1:6,x2:13,y2:6}),e__namespace.createElement("line",{x1:4,y1:12,x2:11,y2:12}),e__namespace.createElement("line",{x1:4,y1:18,x2:11,y2:18}),e__namespace.createElement("polyline",{points:"15 15 18 18 21 15"}),e__namespace.createElement("line",{x1:18,y1:6,x2:18,y2:18}))}var QSe=["size","color","stroke"];function RSe(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,QSe);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-square",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("rect",{x:4,y:4,width:16,height:16,rx:2}))}var $Ae=["size","color","stroke"];function _Ae(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,$Ae);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-table-export",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("path",{d:"M11.5 20h-5.5a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v7.5m-16 -3.5h16m-10 -6v16m4 -1h7m-3 -3l3 3l-3 3"}))}var fKe=["size","color","stroke"];function zKe(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,fKe);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-trash",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("line",{x1:4,y1:7,x2:20,y2:7}),e__namespace.createElement("line",{x1:10,y1:11,x2:10,y2:17}),e__namespace.createElement("line",{x1:14,y1:11,x2:14,y2:17}),e__namespace.createElement("path",{d:"M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"}),e__namespace.createElement("path",{d:"M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"}))}var WXe=["size","color","stroke"];function qXe(r){var n=r.size,l=void 0===n?24:n,a=r.color,i=void 0===a?"currentColor":a,c=r.stroke,s=void 0===c?2:c,h=o(r,WXe);return e__namespace.createElement("svg",t({xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-x",width:l,height:l,viewBox:"0 0 24 24",strokeWidth:s,stroke:i,fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},h),e__namespace.createElement("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),e__namespace.createElement("line",{x1:18,y1:6,x2:6,y2:18}),e__namespace.createElement("line",{x1:6,y1:6,x2:18,y2:18}))}
|
|
337
|
+
|
|
301
338
|
function AttachmentButton(props) {
|
|
302
339
|
const medplum = useMedplum();
|
|
303
|
-
const fileInputRef =
|
|
340
|
+
const fileInputRef = e.useRef(null);
|
|
304
341
|
function onClick(e) {
|
|
305
342
|
killEvent(e);
|
|
306
343
|
fileInputRef.current?.click();
|
|
@@ -343,14 +380,14 @@
|
|
|
343
380
|
alert(outcome?.issue?.[0]?.details?.text);
|
|
344
381
|
});
|
|
345
382
|
}
|
|
346
|
-
return (
|
|
347
|
-
|
|
383
|
+
return (e.createElement(e.Fragment, null,
|
|
384
|
+
e.createElement("input", { type: "file", "data-testid": "upload-file-input", style: { display: 'none' }, ref: fileInputRef, onChange: (e) => onFileChange(e) }),
|
|
348
385
|
props.children({ onClick })));
|
|
349
386
|
}
|
|
350
387
|
|
|
351
388
|
function AttachmentArrayInput(props) {
|
|
352
|
-
const [values, setValues] =
|
|
353
|
-
const valuesRef =
|
|
389
|
+
const [values, setValues] = e.useState(props.defaultValue ?? []);
|
|
390
|
+
const valuesRef = e.useRef();
|
|
354
391
|
valuesRef.current = values;
|
|
355
392
|
function setValuesWrapper(newValues) {
|
|
356
393
|
setValues(newValues);
|
|
@@ -358,33 +395,33 @@
|
|
|
358
395
|
props.onChange(newValues);
|
|
359
396
|
}
|
|
360
397
|
}
|
|
361
|
-
return (
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
values.map((v, index) => (
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
398
|
+
return (e.createElement("table", { style: { width: '100%' } },
|
|
399
|
+
e.createElement("colgroup", null,
|
|
400
|
+
e.createElement("col", { width: "97%" }),
|
|
401
|
+
e.createElement("col", { width: "3%" })),
|
|
402
|
+
e.createElement("tbody", null,
|
|
403
|
+
values.map((v, index) => (e.createElement("tr", { key: `${index}-${values.length}` },
|
|
404
|
+
e.createElement("td", null,
|
|
405
|
+
e.createElement(AttachmentDisplay, { value: v, maxWidth: 200 })),
|
|
406
|
+
e.createElement("td", null,
|
|
407
|
+
e.createElement(core$1.ActionIcon, { title: "Remove", size: "sm", onClick: (e) => {
|
|
371
408
|
killEvent(e);
|
|
372
409
|
const copy = values.slice();
|
|
373
410
|
copy.splice(index, 1);
|
|
374
411
|
setValuesWrapper(copy);
|
|
375
412
|
} },
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
413
|
+
e.createElement(IP, null)))))),
|
|
414
|
+
e.createElement("tr", null,
|
|
415
|
+
e.createElement("td", null),
|
|
416
|
+
e.createElement("td", null,
|
|
417
|
+
e.createElement(AttachmentButton, { onUpload: (attachment) => {
|
|
381
418
|
setValuesWrapper([...valuesRef.current, attachment]);
|
|
382
|
-
} }, (props) => (
|
|
383
|
-
|
|
419
|
+
} }, (props) => (e.createElement(core$1.ActionIcon, { ...props, title: "Add", size: "sm", color: "green" },
|
|
420
|
+
e.createElement(XA, { size: 16 })))))))));
|
|
384
421
|
}
|
|
385
422
|
|
|
386
423
|
function AttachmentInput(props) {
|
|
387
|
-
const [value, setValue] =
|
|
424
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
388
425
|
function setValueWrapper(newValue) {
|
|
389
426
|
setValue(newValue);
|
|
390
427
|
if (props.onChange) {
|
|
@@ -392,17 +429,17 @@
|
|
|
392
429
|
}
|
|
393
430
|
}
|
|
394
431
|
if (value) {
|
|
395
|
-
return (
|
|
396
|
-
|
|
397
|
-
|
|
432
|
+
return (e.createElement(e.Fragment, null,
|
|
433
|
+
e.createElement(AttachmentDisplay, { value: value, maxWidth: 200 }),
|
|
434
|
+
e.createElement(core$1.Button, { onClick: (e) => {
|
|
398
435
|
killEvent(e);
|
|
399
436
|
setValueWrapper(undefined);
|
|
400
437
|
} }, "Remove")));
|
|
401
438
|
}
|
|
402
|
-
return (
|
|
439
|
+
return (e.createElement(AttachmentButton, { onUpload: setValueWrapper }, (props) => e.createElement(core$1.Button, { ...props }, "Upload...")));
|
|
403
440
|
}
|
|
404
441
|
|
|
405
|
-
const useStyles$
|
|
442
|
+
const useStyles$e = core$1.createStyles(() => ({
|
|
406
443
|
root: {
|
|
407
444
|
'@media (max-width: 800px)': {
|
|
408
445
|
paddingLeft: 4,
|
|
@@ -412,11 +449,11 @@
|
|
|
412
449
|
}));
|
|
413
450
|
function Container(props) {
|
|
414
451
|
const { children, ...others } = props;
|
|
415
|
-
const { classes } = useStyles$
|
|
416
|
-
return (
|
|
452
|
+
const { classes } = useStyles$e();
|
|
453
|
+
return (e.createElement(core$1.Container, { className: classes.root, ...others }, children));
|
|
417
454
|
}
|
|
418
455
|
|
|
419
|
-
const useStyles$
|
|
456
|
+
const useStyles$d = core$1.createStyles((theme, { width, fill }) => ({
|
|
420
457
|
paper: {
|
|
421
458
|
maxWidth: width,
|
|
422
459
|
margin: `${theme.spacing.xl}px auto`,
|
|
@@ -441,14 +478,14 @@
|
|
|
441
478
|
};
|
|
442
479
|
function Panel(props) {
|
|
443
480
|
const { className, children, width, fill, unstyled, ...others } = core$1.useComponentDefaultProps('Panel', defaultProps$1, props);
|
|
444
|
-
const { classes, cx } = useStyles$
|
|
445
|
-
return (
|
|
481
|
+
const { classes, cx } = useStyles$d({ width, fill }, { name: 'Panel', unstyled });
|
|
482
|
+
return (e.createElement(core$1.Paper, { className: cx(classes.paper, className), ...others }, children));
|
|
446
483
|
}
|
|
447
484
|
|
|
448
485
|
function Document(props) {
|
|
449
486
|
const { children, ...others } = props;
|
|
450
|
-
return (
|
|
451
|
-
|
|
487
|
+
return (e.createElement(Container, null,
|
|
488
|
+
e.createElement(Panel, { ...others }, children)));
|
|
452
489
|
}
|
|
453
490
|
|
|
454
491
|
/**
|
|
@@ -499,7 +536,7 @@
|
|
|
499
536
|
}
|
|
500
537
|
|
|
501
538
|
function Form(props) {
|
|
502
|
-
return (
|
|
539
|
+
return (e.createElement("form", { style: props.style, "data-testid": props.testid, onSubmit: (e) => {
|
|
503
540
|
e.preventDefault();
|
|
504
541
|
const formData = parseForm(e.target);
|
|
505
542
|
if (props.onSubmit) {
|
|
@@ -509,13 +546,13 @@
|
|
|
509
546
|
}
|
|
510
547
|
|
|
511
548
|
function Logo(props) {
|
|
512
|
-
return (
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
549
|
+
return (e.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 491 491", style: { width: props.size, height: props.size } },
|
|
550
|
+
e.createElement("title", null, "Medplum Logo"),
|
|
551
|
+
e.createElement("path", { fill: props.fill || '#ad7136', d: "M282 67c6-16 16-29 29-40L289 0c-22 17-37 41-43 68l17 23 19-24z" }),
|
|
552
|
+
e.createElement("path", { fill: props.fill || '#946af9', d: "M311 63c-17 0-33 4-48 11-16-7-32-11-49-11-87 0-158 96-158 214s71 214 158 214c17 0 33-4 49-11 15 7 31 11 48 11 87 0 158-96 158-214S398 63 311 63z" }),
|
|
553
|
+
e.createElement("path", { fill: props.fill || '#7857c5', d: "M231 489l-17 2c-87 0-158-96-158-214S127 63 214 63l17 1c-39 12-70 102-70 213s31 201 70 212z" }),
|
|
554
|
+
e.createElement("path", { fill: props.fill || '#40bc26', d: "M207 220a176 176 0 01-177 43A176 176 0 01251 43l1 5c17 59 2 125-45 172z" }),
|
|
555
|
+
e.createElement("path", { fill: props.fill || '#33961e', d: "M252 48A421 421 0 0057 270l-27-7A176 176 0 01251 43l1 5z" })));
|
|
519
556
|
}
|
|
520
557
|
|
|
521
558
|
function getErrorsForInput(outcome, expression) {
|
|
@@ -548,8 +585,8 @@
|
|
|
548
585
|
|
|
549
586
|
function NewProjectForm(props) {
|
|
550
587
|
const medplum = useMedplum();
|
|
551
|
-
const [outcome, setOutcome] =
|
|
552
|
-
return (
|
|
588
|
+
const [outcome, setOutcome] = e.useState();
|
|
589
|
+
return (e.createElement(Form, { style: { maxWidth: 400 }, onSubmit: async (formData) => {
|
|
553
590
|
try {
|
|
554
591
|
props.handleAuthResponse(await medplum.startNewProject({
|
|
555
592
|
login: props.login,
|
|
@@ -560,20 +597,20 @@
|
|
|
560
597
|
setOutcome(err);
|
|
561
598
|
}
|
|
562
599
|
} },
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
600
|
+
e.createElement(core$1.Center, { sx: { flexDirection: 'column' } },
|
|
601
|
+
e.createElement(Logo, { size: 32 }),
|
|
602
|
+
e.createElement(core$1.Title, null, "Create project")),
|
|
603
|
+
e.createElement(core$1.Stack, { spacing: "xl" },
|
|
604
|
+
e.createElement(core$1.TextInput, { name: "projectName", label: "Project Name", placeholder: "My Project", required: true, autoFocus: true, error: getErrorsForInput(outcome, 'firstName') }),
|
|
605
|
+
e.createElement(core$1.Text, { color: "dimmed", size: "xs" },
|
|
569
606
|
"By clicking submit you agree to the Medplum",
|
|
570
607
|
' ',
|
|
571
|
-
|
|
608
|
+
e.createElement(core$1.Anchor, { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
|
|
572
609
|
' and ',
|
|
573
|
-
|
|
610
|
+
e.createElement(core$1.Anchor, { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
574
611
|
".")),
|
|
575
|
-
|
|
576
|
-
|
|
612
|
+
e.createElement(core$1.Group, { position: "right", mt: "xl", noWrap: true },
|
|
613
|
+
e.createElement(core$1.Button, { type: "submit" }, "Create project"))));
|
|
577
614
|
}
|
|
578
615
|
|
|
579
616
|
/**
|
|
@@ -592,11 +629,11 @@
|
|
|
592
629
|
function GoogleButton(props) {
|
|
593
630
|
const medplum = useMedplum();
|
|
594
631
|
const { googleClientId, handleGoogleCredential } = props;
|
|
595
|
-
const parentRef =
|
|
596
|
-
const [scriptLoaded, setScriptLoaded] =
|
|
597
|
-
const [initialized, setInitialized] =
|
|
598
|
-
const [buttonRendered, setButtonRendered] =
|
|
599
|
-
|
|
632
|
+
const parentRef = e.useRef(null);
|
|
633
|
+
const [scriptLoaded, setScriptLoaded] = e.useState(typeof google !== 'undefined');
|
|
634
|
+
const [initialized, setInitialized] = e.useState(false);
|
|
635
|
+
const [buttonRendered, setButtonRendered] = e.useState(false);
|
|
636
|
+
e.useEffect(() => {
|
|
600
637
|
if (typeof google === 'undefined') {
|
|
601
638
|
createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));
|
|
602
639
|
return;
|
|
@@ -616,16 +653,18 @@
|
|
|
616
653
|
if (!googleClientId) {
|
|
617
654
|
return null;
|
|
618
655
|
}
|
|
619
|
-
return
|
|
656
|
+
return e.createElement("div", { ref: parentRef });
|
|
620
657
|
}
|
|
621
658
|
function getGoogleClientId(clientId) {
|
|
622
659
|
if (clientId) {
|
|
623
660
|
return clientId;
|
|
624
661
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
662
|
+
if (typeof window !== 'undefined') {
|
|
663
|
+
const origin = window.location.protocol + '//' + window.location.host;
|
|
664
|
+
const authorizedOrigins = "undefined"?.split(',') ?? [];
|
|
665
|
+
if (authorizedOrigins.includes(origin)) {
|
|
666
|
+
return "undefined";
|
|
667
|
+
}
|
|
629
668
|
}
|
|
630
669
|
return undefined;
|
|
631
670
|
}
|
|
@@ -634,7 +673,7 @@
|
|
|
634
673
|
if (!props.issues) {
|
|
635
674
|
return null;
|
|
636
675
|
}
|
|
637
|
-
return (
|
|
676
|
+
return (e.createElement(core$1.Alert, { icon: e.createElement(We, { size: 16 }), color: "red" }, props.issues.map((issue) => (e.createElement("div", { "data-testid": "text-field-error", key: issue.details?.text }, issue.details?.text)))));
|
|
638
677
|
}
|
|
639
678
|
|
|
640
679
|
/**
|
|
@@ -669,10 +708,10 @@
|
|
|
669
708
|
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
670
709
|
const recaptchaSiteKey = props.recaptchaSiteKey;
|
|
671
710
|
const medplum = useMedplum();
|
|
672
|
-
const [outcome, setOutcome] =
|
|
711
|
+
const [outcome, setOutcome] = e.useState();
|
|
673
712
|
const issues = getIssuesForExpression(outcome, undefined);
|
|
674
|
-
|
|
675
|
-
return (
|
|
713
|
+
e.useEffect(() => initRecaptcha(recaptchaSiteKey), [recaptchaSiteKey]);
|
|
714
|
+
return (e.createElement(Form, { style: { maxWidth: 400 }, onSubmit: async (formData) => {
|
|
676
715
|
try {
|
|
677
716
|
const recaptchaToken = await getRecaptcha(recaptchaSiteKey);
|
|
678
717
|
props.handleAuthResponse(await medplum.startNewUser({
|
|
@@ -690,11 +729,11 @@
|
|
|
690
729
|
setOutcome(err);
|
|
691
730
|
}
|
|
692
731
|
} },
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
googleClientId && (
|
|
696
|
-
|
|
697
|
-
|
|
732
|
+
e.createElement(core$1.Center, { sx: { flexDirection: 'column' } }, props.children),
|
|
733
|
+
e.createElement(OperationOutcomeAlert, { issues: issues }),
|
|
734
|
+
googleClientId && (e.createElement(e.Fragment, null,
|
|
735
|
+
e.createElement(core$1.Group, { position: "center", p: "xl", style: { height: 70 } },
|
|
736
|
+
e.createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: async (response) => {
|
|
698
737
|
try {
|
|
699
738
|
props.handleAuthResponse(await medplum.startGoogleLogin({
|
|
700
739
|
googleClientId: response.clientId,
|
|
@@ -706,37 +745,37 @@
|
|
|
706
745
|
setOutcome(err);
|
|
707
746
|
}
|
|
708
747
|
} })),
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
748
|
+
e.createElement(core$1.Divider, { label: "or", labelPosition: "center", my: "lg" }))),
|
|
749
|
+
e.createElement(core$1.Stack, { spacing: "xl" },
|
|
750
|
+
e.createElement(core$1.TextInput, { name: "firstName", type: "text", label: "First name", placeholder: "First name", required: true, autoFocus: true, error: getErrorsForInput(outcome, 'firstName') }),
|
|
751
|
+
e.createElement(core$1.TextInput, { name: "lastName", type: "text", label: "Last name", placeholder: "Last name", required: true, error: getErrorsForInput(outcome, 'lastName') }),
|
|
752
|
+
e.createElement(core$1.TextInput, { name: "email", type: "email", label: "Email", placeholder: "name@domain.com", required: true, error: getErrorsForInput(outcome, 'email') }),
|
|
753
|
+
e.createElement(core$1.PasswordInput, { name: "password", label: "Password", autoComplete: "off", required: true, error: getErrorsForInput(outcome, 'password') }),
|
|
754
|
+
e.createElement(core$1.Text, { color: "dimmed", size: "xs" },
|
|
716
755
|
"By clicking submit you agree to the Medplum",
|
|
717
756
|
' ',
|
|
718
|
-
|
|
757
|
+
e.createElement(core$1.Anchor, { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
|
|
719
758
|
' and ',
|
|
720
|
-
|
|
759
|
+
e.createElement(core$1.Anchor, { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
721
760
|
"."),
|
|
722
|
-
|
|
761
|
+
e.createElement(core$1.Text, { color: "dimmed", size: "xs" },
|
|
723
762
|
"This site is protected by reCAPTCHA and the Google",
|
|
724
763
|
' ',
|
|
725
|
-
|
|
764
|
+
e.createElement(core$1.Anchor, { href: "https://policies.google.com/privacy" }, "Privacy\u00A0Policy"),
|
|
726
765
|
' and ',
|
|
727
|
-
|
|
766
|
+
e.createElement(core$1.Anchor, { href: "https://policies.google.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
728
767
|
" apply.")),
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
768
|
+
e.createElement(core$1.Group, { position: "apart", mt: "xl", noWrap: true },
|
|
769
|
+
e.createElement(core$1.Checkbox, { name: "remember", label: "Remember me", size: "xs" }),
|
|
770
|
+
e.createElement(core$1.Button, { type: "submit" }, "Create account"))));
|
|
732
771
|
}
|
|
733
772
|
|
|
734
773
|
function RegisterForm(props) {
|
|
735
774
|
const { type, projectId, googleClientId, recaptchaSiteKey, onSuccess } = props;
|
|
736
775
|
const medplum = useMedplum();
|
|
737
|
-
const [login, setLogin] =
|
|
738
|
-
const [outcome, setOutcome] =
|
|
739
|
-
|
|
776
|
+
const [login, setLogin] = e.useState(undefined);
|
|
777
|
+
const [outcome, setOutcome] = e.useState();
|
|
778
|
+
e.useEffect(() => {
|
|
740
779
|
if (type === 'patient' && login) {
|
|
741
780
|
medplum
|
|
742
781
|
.startNewPatient({ login, projectId: projectId })
|
|
@@ -756,26 +795,26 @@
|
|
|
756
795
|
setLogin(response.login);
|
|
757
796
|
}
|
|
758
797
|
}
|
|
759
|
-
return (
|
|
760
|
-
outcome &&
|
|
761
|
-
!login && (
|
|
762
|
-
login && type === 'project' &&
|
|
798
|
+
return (e.createElement(Document, { width: 450 },
|
|
799
|
+
outcome && e.createElement("pre", null, JSON.stringify(outcome, null, 2)),
|
|
800
|
+
!login && (e.createElement(NewUserForm, { projectId: projectId, googleClientId: googleClientId, recaptchaSiteKey: recaptchaSiteKey, handleAuthResponse: handleAuthResponse }, props.children)),
|
|
801
|
+
login && type === 'project' && e.createElement(NewProjectForm, { login: login, handleAuthResponse: handleAuthResponse })));
|
|
763
802
|
}
|
|
764
803
|
|
|
765
804
|
function AuthenticationForm(props) {
|
|
766
|
-
const [email, setEmail] =
|
|
805
|
+
const [email, setEmail] = e.useState();
|
|
767
806
|
if (!email) {
|
|
768
|
-
return
|
|
807
|
+
return e.createElement(EmailForm, { setEmail: setEmail, ...props });
|
|
769
808
|
}
|
|
770
809
|
else {
|
|
771
|
-
return
|
|
810
|
+
return e.createElement(PasswordForm, { email: email, ...props });
|
|
772
811
|
}
|
|
773
812
|
}
|
|
774
813
|
function EmailForm(props) {
|
|
775
814
|
const { setEmail, onRegister, handleAuthResponse, children, ...baseLoginRequest } = props;
|
|
776
815
|
const medplum = useMedplum();
|
|
777
816
|
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
778
|
-
const isExternalAuth =
|
|
817
|
+
const isExternalAuth = e.useCallback(async (authMethod) => {
|
|
779
818
|
if (!authMethod.authorizeUrl) {
|
|
780
819
|
return false;
|
|
781
820
|
}
|
|
@@ -788,13 +827,13 @@
|
|
|
788
827
|
window.location.assign(url.toString());
|
|
789
828
|
return true;
|
|
790
829
|
}, [medplum, baseLoginRequest]);
|
|
791
|
-
const handleSubmit =
|
|
830
|
+
const handleSubmit = e.useCallback(async (formData) => {
|
|
792
831
|
const authMethod = await medplum.post('auth/method', { email: formData.email });
|
|
793
832
|
if (!(await isExternalAuth(authMethod))) {
|
|
794
833
|
setEmail(formData.email);
|
|
795
834
|
}
|
|
796
835
|
}, [medplum, isExternalAuth, setEmail]);
|
|
797
|
-
const handleGoogleCredential =
|
|
836
|
+
const handleGoogleCredential = e.useCallback(async (response) => {
|
|
798
837
|
const authResponse = await medplum.startGoogleLogin({
|
|
799
838
|
...baseLoginRequest,
|
|
800
839
|
googleCredential: response.credential,
|
|
@@ -803,23 +842,23 @@
|
|
|
803
842
|
handleAuthResponse(authResponse);
|
|
804
843
|
}
|
|
805
844
|
}, [medplum, baseLoginRequest, isExternalAuth, handleAuthResponse]);
|
|
806
|
-
return (
|
|
807
|
-
|
|
808
|
-
googleClientId && (
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
onRegister && (
|
|
815
|
-
|
|
845
|
+
return (e.createElement(Form, { style: { maxWidth: 400 }, onSubmit: handleSubmit },
|
|
846
|
+
e.createElement(core$1.Center, { sx: { flexDirection: 'column' } }, children),
|
|
847
|
+
googleClientId && (e.createElement(e.Fragment, null,
|
|
848
|
+
e.createElement(core$1.Group, { position: "center", p: "xl", style: { height: 70 } },
|
|
849
|
+
e.createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: handleGoogleCredential })),
|
|
850
|
+
e.createElement(core$1.Divider, { label: "or", labelPosition: "center", my: "lg" }))),
|
|
851
|
+
e.createElement(core$1.TextInput, { name: "email", type: "email", label: "Email", placeholder: "name@domain.com", required: true, autoFocus: true }),
|
|
852
|
+
e.createElement(core$1.Group, { position: "apart", mt: "xl", spacing: 0, noWrap: true },
|
|
853
|
+
onRegister && (e.createElement(core$1.Anchor, { component: "button", type: "button", color: "dimmed", onClick: onRegister, size: "xs" }, "Register")),
|
|
854
|
+
e.createElement(core$1.Button, { type: "submit" }, "Next"))));
|
|
816
855
|
}
|
|
817
856
|
function PasswordForm(props) {
|
|
818
857
|
const { onForgotPassword, handleAuthResponse, children, ...baseLoginRequest } = props;
|
|
819
858
|
const medplum = useMedplum();
|
|
820
|
-
const [outcome, setOutcome] =
|
|
859
|
+
const [outcome, setOutcome] = e.useState();
|
|
821
860
|
const issues = getIssuesForExpression(outcome, undefined);
|
|
822
|
-
const handleSubmit =
|
|
861
|
+
const handleSubmit = e.useCallback((formData) => {
|
|
823
862
|
medplum
|
|
824
863
|
.startLogin({
|
|
825
864
|
...baseLoginRequest,
|
|
@@ -829,24 +868,24 @@
|
|
|
829
868
|
.then(handleAuthResponse)
|
|
830
869
|
.catch(setOutcome);
|
|
831
870
|
}, [medplum, baseLoginRequest, handleAuthResponse]);
|
|
832
|
-
return (
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
onForgotPassword && (
|
|
839
|
-
|
|
840
|
-
|
|
871
|
+
return (e.createElement(Form, { style: { maxWidth: 400 }, onSubmit: handleSubmit },
|
|
872
|
+
e.createElement(core$1.Center, { sx: { flexDirection: 'column' } }, children),
|
|
873
|
+
e.createElement(OperationOutcomeAlert, { issues: issues }),
|
|
874
|
+
e.createElement(core$1.Stack, { spacing: "xl" },
|
|
875
|
+
e.createElement(core$1.PasswordInput, { name: "password", type: "password", label: "Password", autoComplete: "off", required: true, error: getErrorsForInput(outcome, 'password') })),
|
|
876
|
+
e.createElement(core$1.Group, { position: "apart", mt: "xl", spacing: 0, noWrap: true },
|
|
877
|
+
onForgotPassword && (e.createElement(core$1.Anchor, { component: "button", type: "button", color: "dimmed", onClick: onForgotPassword, size: "xs" }, "Forgot password")),
|
|
878
|
+
e.createElement(core$1.Checkbox, { id: "remember", name: "remember", label: "Remember me", size: "xs", sx: { lineHeight: 1 } }),
|
|
879
|
+
e.createElement(core$1.Button, { type: "submit" }, "Sign in"))));
|
|
841
880
|
}
|
|
842
881
|
|
|
843
882
|
function ChooseProfileForm(props) {
|
|
844
883
|
const medplum = useMedplum();
|
|
845
|
-
return (
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
props.memberships.map((membership) => (
|
|
884
|
+
return (e.createElement(core$1.Stack, null,
|
|
885
|
+
e.createElement(core$1.Center, { sx: { flexDirection: 'column' } },
|
|
886
|
+
e.createElement(Logo, { size: 32 }),
|
|
887
|
+
e.createElement(core$1.Title, null, "Choose profile")),
|
|
888
|
+
props.memberships.map((membership) => (e.createElement(core$1.UnstyledButton, { key: membership.id, onClick: () => {
|
|
850
889
|
medplum
|
|
851
890
|
.post('auth/profile', {
|
|
852
891
|
login: props.login,
|
|
@@ -855,16 +894,16 @@
|
|
|
855
894
|
.then(props.handleAuthResponse)
|
|
856
895
|
.catch(console.log);
|
|
857
896
|
} },
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
897
|
+
e.createElement(core$1.Group, null,
|
|
898
|
+
e.createElement(core$1.Avatar, { radius: "xl" }),
|
|
899
|
+
e.createElement("div", { style: { flex: 1 } },
|
|
900
|
+
e.createElement(core$1.Text, { size: "sm", weight: 500 }, membership.profile?.display),
|
|
901
|
+
e.createElement(core$1.Text, { color: "dimmed", size: "xs" }, membership.project?.display))))))));
|
|
863
902
|
}
|
|
864
903
|
|
|
865
904
|
function ChooseScopeForm(props) {
|
|
866
905
|
const medplum = useMedplum();
|
|
867
|
-
return (
|
|
906
|
+
return (e.createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => {
|
|
868
907
|
medplum
|
|
869
908
|
.post('auth/scope', {
|
|
870
909
|
login: props.login,
|
|
@@ -873,19 +912,19 @@
|
|
|
873
912
|
.then(props.handleAuthResponse)
|
|
874
913
|
.catch(console.log);
|
|
875
914
|
} },
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
915
|
+
e.createElement(core$1.Stack, null,
|
|
916
|
+
e.createElement(core$1.Center, { sx: { flexDirection: 'column' } },
|
|
917
|
+
e.createElement(Logo, { size: 32 }),
|
|
918
|
+
e.createElement(core$1.Title, null, "Choose scope")),
|
|
919
|
+
e.createElement(core$1.Stack, null, (props.scope || 'openid').split(' ').map((scopeName) => (e.createElement(core$1.Checkbox, { key: scopeName, id: scopeName, name: scopeName, label: scopeName, defaultChecked: true })))),
|
|
920
|
+
e.createElement(core$1.Group, { position: "right", mt: "xl" },
|
|
921
|
+
e.createElement(core$1.Button, { type: "submit" }, "Set scope")))));
|
|
883
922
|
}
|
|
884
923
|
|
|
885
924
|
function MfaForm(props) {
|
|
886
925
|
const medplum = useMedplum();
|
|
887
|
-
const [errorMessage, setErrorMessage] =
|
|
888
|
-
return (
|
|
926
|
+
const [errorMessage, setErrorMessage] = e.useState(undefined);
|
|
927
|
+
return (e.createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => {
|
|
889
928
|
setErrorMessage(undefined);
|
|
890
929
|
medplum
|
|
891
930
|
.post('auth/mfa/verify', {
|
|
@@ -895,15 +934,15 @@
|
|
|
895
934
|
.then(props.handleAuthResponse)
|
|
896
935
|
.catch((err) => setErrorMessage(core.normalizeErrorString(err)));
|
|
897
936
|
} },
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
errorMessage && (
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
937
|
+
e.createElement(core$1.Stack, null,
|
|
938
|
+
e.createElement(core$1.Center, { sx: { flexDirection: 'column' } },
|
|
939
|
+
e.createElement(Logo, { size: 32 }),
|
|
940
|
+
e.createElement(core$1.Title, null, "Enter MFA code")),
|
|
941
|
+
errorMessage && (e.createElement(core$1.Alert, { icon: e.createElement(We, { size: 16 }), title: "Error", color: "red" }, errorMessage)),
|
|
942
|
+
e.createElement(core$1.Stack, null,
|
|
943
|
+
e.createElement(core$1.TextInput, { name: "token", label: "MFA code", required: true })),
|
|
944
|
+
e.createElement(core$1.Group, { position: "right", mt: "xl" },
|
|
945
|
+
e.createElement(core$1.Button, { type: "submit" }, "Submit code")))));
|
|
907
946
|
}
|
|
908
947
|
|
|
909
948
|
/**
|
|
@@ -919,10 +958,10 @@
|
|
|
919
958
|
function SignInForm(props) {
|
|
920
959
|
const { chooseScopes, onSuccess, onForgotPassword, onRegister, onCode, ...baseLoginRequest } = props;
|
|
921
960
|
const medplum = useMedplum();
|
|
922
|
-
const [login, setLogin] =
|
|
923
|
-
const [mfaRequired, setAuthenticatorRequired] =
|
|
924
|
-
const [memberships, setMemberships] =
|
|
925
|
-
const handleCode =
|
|
961
|
+
const [login, setLogin] = e.useState(undefined);
|
|
962
|
+
const [mfaRequired, setAuthenticatorRequired] = e.useState(false);
|
|
963
|
+
const [memberships, setMemberships] = e.useState(undefined);
|
|
964
|
+
const handleCode = e.useCallback((code) => {
|
|
926
965
|
if (onCode) {
|
|
927
966
|
onCode(code);
|
|
928
967
|
}
|
|
@@ -937,7 +976,7 @@
|
|
|
937
976
|
.catch(console.log);
|
|
938
977
|
}
|
|
939
978
|
}, [medplum, onCode, onSuccess]);
|
|
940
|
-
const handleAuthResponse =
|
|
979
|
+
const handleAuthResponse = e.useCallback((response) => {
|
|
941
980
|
setAuthenticatorRequired(!!response.mfaRequired);
|
|
942
981
|
if (response.login) {
|
|
943
982
|
setLogin(response.login);
|
|
@@ -954,10 +993,10 @@
|
|
|
954
993
|
}
|
|
955
994
|
}
|
|
956
995
|
}, [chooseScopes, handleCode]);
|
|
957
|
-
const handleScopeResponse =
|
|
996
|
+
const handleScopeResponse = e.useCallback((response) => {
|
|
958
997
|
handleCode(response.code);
|
|
959
998
|
}, [handleCode]);
|
|
960
|
-
|
|
999
|
+
e.useEffect(() => {
|
|
961
1000
|
if (props.login) {
|
|
962
1001
|
medplum
|
|
963
1002
|
.get('auth/login/' + props.login)
|
|
@@ -965,24 +1004,24 @@
|
|
|
965
1004
|
.catch(console.error);
|
|
966
1005
|
}
|
|
967
1006
|
}, [medplum, props, handleAuthResponse]);
|
|
968
|
-
return (
|
|
1007
|
+
return (e.createElement(Document, { width: 450 }, (() => {
|
|
969
1008
|
if (!login) {
|
|
970
|
-
return (
|
|
1009
|
+
return (e.createElement(AuthenticationForm, { onForgotPassword: onForgotPassword, onRegister: onRegister, handleAuthResponse: handleAuthResponse, ...baseLoginRequest }, props.children));
|
|
971
1010
|
}
|
|
972
1011
|
else if (mfaRequired) {
|
|
973
|
-
return
|
|
1012
|
+
return e.createElement(MfaForm, { login: login, handleAuthResponse: handleAuthResponse });
|
|
974
1013
|
}
|
|
975
1014
|
else if (memberships) {
|
|
976
|
-
return
|
|
1015
|
+
return e.createElement(ChooseProfileForm, { login: login, memberships: memberships, handleAuthResponse: handleAuthResponse });
|
|
977
1016
|
}
|
|
978
1017
|
else if (props.projectId === 'new') {
|
|
979
|
-
return
|
|
1018
|
+
return e.createElement(NewProjectForm, { login: login, handleAuthResponse: handleAuthResponse });
|
|
980
1019
|
}
|
|
981
1020
|
else if (props.chooseScopes) {
|
|
982
|
-
return
|
|
1021
|
+
return e.createElement(ChooseScopeForm, { login: login, scope: props.scope, handleAuthResponse: handleScopeResponse });
|
|
983
1022
|
}
|
|
984
1023
|
else {
|
|
985
|
-
return
|
|
1024
|
+
return e.createElement("div", null, "Success");
|
|
986
1025
|
}
|
|
987
1026
|
})()));
|
|
988
1027
|
}
|
|
@@ -997,7 +1036,7 @@
|
|
|
997
1036
|
'modifierExtension',
|
|
998
1037
|
];
|
|
999
1038
|
|
|
1000
|
-
const useStyles$
|
|
1039
|
+
const useStyles$c = core$1.createStyles((theme) => ({
|
|
1001
1040
|
root: {
|
|
1002
1041
|
display: 'grid',
|
|
1003
1042
|
gridTemplateColumns: '30% 70%',
|
|
@@ -1018,21 +1057,21 @@
|
|
|
1018
1057
|
}));
|
|
1019
1058
|
function DescriptionList(props) {
|
|
1020
1059
|
const { children, compact } = props;
|
|
1021
|
-
const { classes, cx } = useStyles$
|
|
1022
|
-
return
|
|
1060
|
+
const { classes, cx } = useStyles$c();
|
|
1061
|
+
return e.createElement("dl", { className: cx(classes.root, { [classes.compact]: compact }) }, children);
|
|
1023
1062
|
}
|
|
1024
1063
|
function DescriptionListEntry(props) {
|
|
1025
|
-
return (
|
|
1026
|
-
|
|
1027
|
-
|
|
1064
|
+
return (e.createElement(e.Fragment, null,
|
|
1065
|
+
e.createElement("dt", null, props.term),
|
|
1066
|
+
e.createElement("dd", null, props.children)));
|
|
1028
1067
|
}
|
|
1029
1068
|
|
|
1030
1069
|
function CodeableConceptDisplay(props) {
|
|
1031
|
-
return
|
|
1070
|
+
return e.createElement(e.Fragment, null, core.formatCodeableConcept(props.value));
|
|
1032
1071
|
}
|
|
1033
1072
|
|
|
1034
1073
|
function CodingDisplay(props) {
|
|
1035
|
-
return
|
|
1074
|
+
return e.createElement(e.Fragment, null, core.formatCoding(props.value));
|
|
1036
1075
|
}
|
|
1037
1076
|
|
|
1038
1077
|
function ContactPointDisplay(props) {
|
|
@@ -1057,7 +1096,7 @@
|
|
|
1057
1096
|
}
|
|
1058
1097
|
builder.push(']');
|
|
1059
1098
|
}
|
|
1060
|
-
return
|
|
1099
|
+
return e.createElement(e.Fragment, null, builder.join('').trim());
|
|
1061
1100
|
}
|
|
1062
1101
|
|
|
1063
1102
|
function ContactDetailDisplay(props) {
|
|
@@ -1065,10 +1104,10 @@
|
|
|
1065
1104
|
if (!contactDetail) {
|
|
1066
1105
|
return null;
|
|
1067
1106
|
}
|
|
1068
|
-
return (
|
|
1107
|
+
return (e.createElement(e.Fragment, null,
|
|
1069
1108
|
contactDetail.name,
|
|
1070
1109
|
contactDetail.name && ': ',
|
|
1071
|
-
contactDetail.telecom?.map((telecom, index) => (
|
|
1110
|
+
contactDetail.telecom?.map((telecom, index) => (e.createElement(ContactPointDisplay, { key: 'telecom-' + index, value: telecom })))));
|
|
1072
1111
|
}
|
|
1073
1112
|
|
|
1074
1113
|
function HumanNameDisplay(props) {
|
|
@@ -1076,26 +1115,26 @@
|
|
|
1076
1115
|
if (!name) {
|
|
1077
1116
|
return null;
|
|
1078
1117
|
}
|
|
1079
|
-
return
|
|
1118
|
+
return e.createElement(e.Fragment, null, core.formatHumanName(name, props.options));
|
|
1080
1119
|
}
|
|
1081
1120
|
|
|
1082
1121
|
function IdentifierDisplay(props) {
|
|
1083
|
-
return (
|
|
1122
|
+
return (e.createElement("div", null,
|
|
1084
1123
|
props.value?.system,
|
|
1085
1124
|
": ",
|
|
1086
1125
|
props.value?.value));
|
|
1087
1126
|
}
|
|
1088
1127
|
|
|
1089
1128
|
function MoneyDisplay(props) {
|
|
1090
|
-
return
|
|
1129
|
+
return e.createElement(e.Fragment, null, core.formatMoney(props.value));
|
|
1091
1130
|
}
|
|
1092
1131
|
|
|
1093
1132
|
function QuantityDisplay(props) {
|
|
1094
|
-
return
|
|
1133
|
+
return e.createElement(e.Fragment, null, core.formatQuantity(props.value));
|
|
1095
1134
|
}
|
|
1096
1135
|
|
|
1097
1136
|
function RangeDisplay(props) {
|
|
1098
|
-
return
|
|
1137
|
+
return e.createElement(e.Fragment, null, core.formatRange(props.value));
|
|
1099
1138
|
}
|
|
1100
1139
|
|
|
1101
1140
|
function RatioDisplay(props) {
|
|
@@ -1103,20 +1142,20 @@
|
|
|
1103
1142
|
if (!value) {
|
|
1104
1143
|
return null;
|
|
1105
1144
|
}
|
|
1106
|
-
return (
|
|
1107
|
-
|
|
1145
|
+
return (e.createElement(e.Fragment, null,
|
|
1146
|
+
e.createElement(QuantityDisplay, { value: value.numerator }),
|
|
1108
1147
|
"\u00A0/\u00A0",
|
|
1109
|
-
|
|
1148
|
+
e.createElement(QuantityDisplay, { value: value.denominator })));
|
|
1110
1149
|
}
|
|
1111
1150
|
|
|
1112
1151
|
function MedplumLink(props) {
|
|
1113
|
-
const navigate =
|
|
1152
|
+
const navigate = useMedplumNavigate();
|
|
1114
1153
|
const { to, suffix, label, onClick, children, ...rest } = props;
|
|
1115
1154
|
let href = getHref(to);
|
|
1116
1155
|
if (suffix) {
|
|
1117
1156
|
href += '/' + suffix;
|
|
1118
1157
|
}
|
|
1119
|
-
return (
|
|
1158
|
+
return (e.createElement(core$1.Anchor, { href: href, "aria-label": label, onClick: (e) => {
|
|
1120
1159
|
killEvent(e);
|
|
1121
1160
|
if (onClick) {
|
|
1122
1161
|
onClick();
|
|
@@ -1161,10 +1200,10 @@
|
|
|
1161
1200
|
// The "link" prop defaults to "true"; undefined is treated as "true"
|
|
1162
1201
|
// To disable the link, it must be explicitly "false"
|
|
1163
1202
|
if (props.link !== false && props.value.reference) {
|
|
1164
|
-
return
|
|
1203
|
+
return e.createElement(MedplumLink, { to: props.value }, displayString);
|
|
1165
1204
|
}
|
|
1166
1205
|
else {
|
|
1167
|
-
return
|
|
1206
|
+
return e.createElement(e.Fragment, null, displayString);
|
|
1168
1207
|
}
|
|
1169
1208
|
}
|
|
1170
1209
|
|
|
@@ -1172,21 +1211,21 @@
|
|
|
1172
1211
|
const property = props.property;
|
|
1173
1212
|
const values = props.values ?? [];
|
|
1174
1213
|
const propertyType = property.type?.[0]?.code;
|
|
1175
|
-
return (
|
|
1176
|
-
|
|
1214
|
+
return (e.createElement(e.Fragment, null, values.map((v, index) => (e.createElement("div", { key: `${index}-${values.length}` },
|
|
1215
|
+
e.createElement(ResourcePropertyDisplay, { arrayElement: true, property: property, propertyType: propertyType, value: v, ignoreMissingValues: props.ignoreMissingValues, link: props.link }))))));
|
|
1177
1216
|
}
|
|
1178
1217
|
|
|
1179
1218
|
function ResourcePropertyDisplay(props) {
|
|
1180
1219
|
const { property, propertyType, value } = props;
|
|
1181
1220
|
if (property?.max === '*' && !props.arrayElement) {
|
|
1182
1221
|
if (propertyType === 'Attachment') {
|
|
1183
|
-
return
|
|
1222
|
+
return e.createElement(AttachmentArrayDisplay, { values: value, maxWidth: props.maxWidth });
|
|
1184
1223
|
}
|
|
1185
|
-
return (
|
|
1224
|
+
return (e.createElement(ResourceArrayDisplay, { property: property, values: value, ignoreMissingValues: props.ignoreMissingValues, link: props.link }));
|
|
1186
1225
|
}
|
|
1187
1226
|
switch (propertyType) {
|
|
1188
1227
|
case core.PropertyType.boolean:
|
|
1189
|
-
return
|
|
1228
|
+
return e.createElement(e.Fragment, null, value === undefined ? '' : Boolean(value).toString());
|
|
1190
1229
|
case core.PropertyType.SystemString:
|
|
1191
1230
|
case core.PropertyType.code:
|
|
1192
1231
|
case core.PropertyType.date:
|
|
@@ -1196,55 +1235,55 @@
|
|
|
1196
1235
|
case core.PropertyType.unsignedInt:
|
|
1197
1236
|
case core.PropertyType.uri:
|
|
1198
1237
|
case core.PropertyType.url:
|
|
1199
|
-
return
|
|
1238
|
+
return e.createElement(e.Fragment, null, value);
|
|
1200
1239
|
case core.PropertyType.canonical:
|
|
1201
|
-
return
|
|
1240
|
+
return e.createElement(ReferenceDisplay, { value: { reference: value }, link: props.link });
|
|
1202
1241
|
case core.PropertyType.dateTime:
|
|
1203
1242
|
case core.PropertyType.instant:
|
|
1204
|
-
return
|
|
1243
|
+
return e.createElement(e.Fragment, null, core.formatDateTime(value));
|
|
1205
1244
|
case core.PropertyType.markdown:
|
|
1206
|
-
return
|
|
1245
|
+
return e.createElement("pre", null, value);
|
|
1207
1246
|
case core.PropertyType.Address:
|
|
1208
|
-
return
|
|
1247
|
+
return e.createElement(AddressDisplay, { value: value });
|
|
1209
1248
|
case core.PropertyType.Annotation:
|
|
1210
|
-
return
|
|
1249
|
+
return e.createElement(e.Fragment, null, value?.text);
|
|
1211
1250
|
case core.PropertyType.Attachment:
|
|
1212
|
-
return
|
|
1251
|
+
return e.createElement(AttachmentDisplay, { value: value, maxWidth: props.maxWidth });
|
|
1213
1252
|
case core.PropertyType.CodeableConcept:
|
|
1214
|
-
return
|
|
1253
|
+
return e.createElement(CodeableConceptDisplay, { value: value });
|
|
1215
1254
|
case core.PropertyType.Coding:
|
|
1216
|
-
return
|
|
1255
|
+
return e.createElement(CodingDisplay, { value: value });
|
|
1217
1256
|
case core.PropertyType.ContactDetail:
|
|
1218
|
-
return
|
|
1257
|
+
return e.createElement(ContactDetailDisplay, { value: value });
|
|
1219
1258
|
case core.PropertyType.ContactPoint:
|
|
1220
|
-
return
|
|
1259
|
+
return e.createElement(ContactPointDisplay, { value: value });
|
|
1221
1260
|
case core.PropertyType.HumanName:
|
|
1222
|
-
return
|
|
1261
|
+
return e.createElement(HumanNameDisplay, { value: value });
|
|
1223
1262
|
case core.PropertyType.Identifier:
|
|
1224
|
-
return
|
|
1263
|
+
return e.createElement(IdentifierDisplay, { value: value });
|
|
1225
1264
|
case core.PropertyType.Money:
|
|
1226
|
-
return
|
|
1265
|
+
return e.createElement(MoneyDisplay, { value: value });
|
|
1227
1266
|
case core.PropertyType.Period:
|
|
1228
|
-
return
|
|
1267
|
+
return e.createElement(e.Fragment, null, core.formatPeriod(value));
|
|
1229
1268
|
case core.PropertyType.Quantity:
|
|
1230
1269
|
case core.PropertyType.Duration:
|
|
1231
|
-
return
|
|
1270
|
+
return e.createElement(QuantityDisplay, { value: value });
|
|
1232
1271
|
case core.PropertyType.Range:
|
|
1233
|
-
return
|
|
1272
|
+
return e.createElement(RangeDisplay, { value: value });
|
|
1234
1273
|
case core.PropertyType.Ratio:
|
|
1235
|
-
return
|
|
1274
|
+
return e.createElement(RatioDisplay, { value: value });
|
|
1236
1275
|
case core.PropertyType.Reference:
|
|
1237
|
-
return
|
|
1276
|
+
return e.createElement(ReferenceDisplay, { value: value, link: props.link });
|
|
1238
1277
|
case core.PropertyType.Timing:
|
|
1239
|
-
return
|
|
1278
|
+
return e.createElement(e.Fragment, null, core.formatTiming(value));
|
|
1240
1279
|
case core.PropertyType.Dosage:
|
|
1241
1280
|
case core.PropertyType.UsageContext:
|
|
1242
|
-
return (
|
|
1281
|
+
return (e.createElement(BackboneElementDisplay, { value: { type: propertyType, value }, compact: true, ignoreMissingValues: props.ignoreMissingValues }));
|
|
1243
1282
|
default:
|
|
1244
1283
|
if (!property?.path) {
|
|
1245
1284
|
throw Error(`Displaying property of type ${props.propertyType} requires element definition path`);
|
|
1246
1285
|
}
|
|
1247
|
-
return (
|
|
1286
|
+
return (e.createElement(BackboneElementDisplay, { value: { type: core.getElementDefinitionTypeName(property), value }, compact: true, ignoreMissingValues: props.ignoreMissingValues }));
|
|
1248
1287
|
}
|
|
1249
1288
|
}
|
|
1250
1289
|
/**
|
|
@@ -1277,7 +1316,7 @@
|
|
|
1277
1316
|
const typeName = typedValue.type;
|
|
1278
1317
|
const typeSchema = core.globalSchema.types[typeName];
|
|
1279
1318
|
if (!typeSchema) {
|
|
1280
|
-
return
|
|
1319
|
+
return e.createElement("div", null,
|
|
1281
1320
|
typeName,
|
|
1282
1321
|
"\u00A0not implemented");
|
|
1283
1322
|
}
|
|
@@ -1288,9 +1327,9 @@
|
|
|
1288
1327
|
// Special case for common BackboneElement pattern
|
|
1289
1328
|
// Where there is an object with a single property 'name'
|
|
1290
1329
|
// Just display the name value.
|
|
1291
|
-
return
|
|
1330
|
+
return e.createElement("div", null, value.name);
|
|
1292
1331
|
}
|
|
1293
|
-
return (
|
|
1332
|
+
return (e.createElement(DescriptionList, { compact: props.compact }, Object.entries(typeSchema.properties).map((entry) => {
|
|
1294
1333
|
const key = entry[0];
|
|
1295
1334
|
if (DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
|
|
1296
1335
|
return null;
|
|
@@ -1304,20 +1343,20 @@
|
|
|
1304
1343
|
(!propertyValue || (Array.isArray(propertyValue) && propertyValue.length === 0))) {
|
|
1305
1344
|
return null;
|
|
1306
1345
|
}
|
|
1307
|
-
return (
|
|
1308
|
-
|
|
1346
|
+
return (e.createElement(DescriptionListEntry, { key: key, term: core.getPropertyDisplayName(key) },
|
|
1347
|
+
e.createElement(ResourcePropertyDisplay, { property: property, propertyType: propertyType, value: propertyValue, ignoreMissingValues: props.ignoreMissingValues, link: props.link })));
|
|
1309
1348
|
})));
|
|
1310
1349
|
}
|
|
1311
1350
|
|
|
1312
1351
|
function CheckboxFormSection(props) {
|
|
1313
|
-
return (
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1352
|
+
return (e.createElement(core$1.Group, { noWrap: true },
|
|
1353
|
+
e.createElement("div", null, props.children),
|
|
1354
|
+
e.createElement("div", null,
|
|
1355
|
+
e.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description }, (() => null)()))));
|
|
1317
1356
|
}
|
|
1318
1357
|
|
|
1319
1358
|
function FormSection(props) {
|
|
1320
|
-
return (
|
|
1359
|
+
return (e.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description, error: getErrorsForInput(props.outcome, props.htmlFor) }, props.children));
|
|
1321
1360
|
}
|
|
1322
1361
|
|
|
1323
1362
|
const system = {
|
|
@@ -1337,8 +1376,11 @@
|
|
|
1337
1376
|
*/
|
|
1338
1377
|
function useResource(value) {
|
|
1339
1378
|
const medplum = useMedplum();
|
|
1340
|
-
const [resource, setResource] =
|
|
1341
|
-
|
|
1379
|
+
const [resource, setResource] = e.useState(getInitialResource(medplum, value));
|
|
1380
|
+
e.useEffect(() => {
|
|
1381
|
+
setResource(getInitialResource(medplum, value));
|
|
1382
|
+
}, [medplum, value]);
|
|
1383
|
+
e.useEffect(() => {
|
|
1342
1384
|
let subscribed = true;
|
|
1343
1385
|
if (!resource && value && 'reference' in value && value.reference) {
|
|
1344
1386
|
medplum
|
|
@@ -1383,32 +1425,32 @@
|
|
|
1383
1425
|
function ResourceForm(props) {
|
|
1384
1426
|
const medplum = useMedplum();
|
|
1385
1427
|
const defaultValue = useResource(props.defaultValue);
|
|
1386
|
-
const [schema, setSchema] =
|
|
1387
|
-
const [value, setValue] =
|
|
1388
|
-
|
|
1428
|
+
const [schema, setSchema] = e.useState();
|
|
1429
|
+
const [value, setValue] = e.useState();
|
|
1430
|
+
e.useEffect(() => {
|
|
1389
1431
|
if (defaultValue) {
|
|
1390
1432
|
setValue(JSON.parse(JSON.stringify(defaultValue)));
|
|
1391
1433
|
medplum.requestSchema(defaultValue.resourceType).then(setSchema).catch(console.log);
|
|
1392
1434
|
}
|
|
1393
1435
|
}, [medplum, defaultValue]);
|
|
1394
1436
|
if (!schema || !value) {
|
|
1395
|
-
return
|
|
1437
|
+
return e.createElement("div", null, "Loading...");
|
|
1396
1438
|
}
|
|
1397
|
-
return (
|
|
1439
|
+
return (e.createElement("form", { noValidate: true, autoComplete: "off", onSubmit: (e) => {
|
|
1398
1440
|
e.preventDefault();
|
|
1399
1441
|
if (props.onSubmit) {
|
|
1400
1442
|
props.onSubmit(value);
|
|
1401
1443
|
}
|
|
1402
1444
|
} },
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
props.onDelete && (
|
|
1445
|
+
e.createElement(core$1.Stack, { mb: "xl" },
|
|
1446
|
+
e.createElement(FormSection, { title: "Resource Type", htmlFor: "resourceType", outcome: props.outcome },
|
|
1447
|
+
e.createElement(core$1.TextInput, { name: "resourceType", defaultValue: value.resourceType, disabled: true })),
|
|
1448
|
+
e.createElement(FormSection, { title: "ID", htmlFor: "id", outcome: props.outcome },
|
|
1449
|
+
e.createElement(core$1.TextInput, { name: "id", defaultValue: value.id, disabled: true }))),
|
|
1450
|
+
e.createElement(BackboneElementInput, { typeName: value.resourceType, defaultValue: value, outcome: props.outcome, onChange: setValue }),
|
|
1451
|
+
e.createElement(core$1.Group, { position: "right", mt: "xl" },
|
|
1452
|
+
e.createElement(core$1.Button, { type: "submit" }, "OK"),
|
|
1453
|
+
props.onDelete && (e.createElement(core$1.Button, { variant: "outline", color: "red", type: "button", onClick: () => {
|
|
1412
1454
|
props.onDelete(value);
|
|
1413
1455
|
} }, "Delete")))));
|
|
1414
1456
|
}
|
|
@@ -1445,7 +1487,7 @@
|
|
|
1445
1487
|
function ValueSetAutocomplete(props) {
|
|
1446
1488
|
const medplum = useMedplum();
|
|
1447
1489
|
const { elementDefinition, ...rest } = props;
|
|
1448
|
-
const loadValues =
|
|
1490
|
+
const loadValues = e.useCallback(async (input, signal) => {
|
|
1449
1491
|
const system = elementDefinition.binding?.valueSet;
|
|
1450
1492
|
const valueSet = await medplum.searchValueSet(system, input, { signal });
|
|
1451
1493
|
const valueSetElements = valueSet.expansion?.contains;
|
|
@@ -1457,14 +1499,14 @@
|
|
|
1457
1499
|
}
|
|
1458
1500
|
return newData;
|
|
1459
1501
|
}, [medplum, elementDefinition]);
|
|
1460
|
-
return (
|
|
1502
|
+
return (e.createElement(AsyncAutocomplete, { ...rest, creatable: true, clearable: true, toKey: toKey, toOption: toOption, loadOptions: loadValues, getCreateLabel: (query) => `+ Create ${query}`, onCreate: createValue }));
|
|
1461
1503
|
}
|
|
1462
1504
|
function getDisplay(item) {
|
|
1463
1505
|
return item.display || item.code || '';
|
|
1464
1506
|
}
|
|
1465
1507
|
|
|
1466
1508
|
function CodeableConceptInput(props) {
|
|
1467
|
-
const [value, setValue] =
|
|
1509
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1468
1510
|
function handleChange(newValues) {
|
|
1469
1511
|
const newConcept = valueSetElementToCodeableConcept(newValues);
|
|
1470
1512
|
setValue(newConcept);
|
|
@@ -1472,7 +1514,7 @@
|
|
|
1472
1514
|
props.onChange(newConcept);
|
|
1473
1515
|
}
|
|
1474
1516
|
}
|
|
1475
|
-
return (
|
|
1517
|
+
return (e.createElement(ValueSetAutocomplete, { elementDefinition: props.property, name: props.name, placeholder: props.placeholder, defaultValue: value && codeableConceptToValueSetElement(value), onChange: handleChange }));
|
|
1476
1518
|
}
|
|
1477
1519
|
function codeableConceptToValueSetElement(concept) {
|
|
1478
1520
|
return concept.coding?.map((c) => ({
|
|
@@ -1495,7 +1537,7 @@
|
|
|
1495
1537
|
}
|
|
1496
1538
|
|
|
1497
1539
|
function CodeInput(props) {
|
|
1498
|
-
const [value, setValue] =
|
|
1540
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1499
1541
|
function handleChange(newValues) {
|
|
1500
1542
|
const newValue = newValues[0];
|
|
1501
1543
|
const newCode = valueSetElementToCode(newValue);
|
|
@@ -1504,7 +1546,7 @@
|
|
|
1504
1546
|
props.onChange(newCode);
|
|
1505
1547
|
}
|
|
1506
1548
|
}
|
|
1507
|
-
return (
|
|
1549
|
+
return (e.createElement(ValueSetAutocomplete, { elementDefinition: props.property, name: props.name, placeholder: props.placeholder, defaultValue: codeToValueSetElement(value), onChange: handleChange }));
|
|
1508
1550
|
}
|
|
1509
1551
|
function codeToValueSetElement(code) {
|
|
1510
1552
|
return code ? { code } : undefined;
|
|
@@ -1514,7 +1556,7 @@
|
|
|
1514
1556
|
}
|
|
1515
1557
|
|
|
1516
1558
|
function CodingInput(props) {
|
|
1517
|
-
const [value, setValue] =
|
|
1559
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1518
1560
|
function handleChange(newValues) {
|
|
1519
1561
|
const newValue = newValues[0];
|
|
1520
1562
|
const newConcept = newValue && valueSetElementToCoding(newValue);
|
|
@@ -1523,7 +1565,7 @@
|
|
|
1523
1565
|
props.onChange(newConcept);
|
|
1524
1566
|
}
|
|
1525
1567
|
}
|
|
1526
|
-
return (
|
|
1568
|
+
return (e.createElement(ValueSetAutocomplete, { elementDefinition: props.property, name: props.name, placeholder: props.placeholder, defaultValue: value && codingToValueSetElement(value), onChange: handleChange }));
|
|
1527
1569
|
}
|
|
1528
1570
|
function codingToValueSetElement(coding) {
|
|
1529
1571
|
return {
|
|
@@ -1541,8 +1583,8 @@
|
|
|
1541
1583
|
}
|
|
1542
1584
|
|
|
1543
1585
|
function ContactPointInput(props) {
|
|
1544
|
-
const [contactPoint, setContactPoint] =
|
|
1545
|
-
const ref =
|
|
1586
|
+
const [contactPoint, setContactPoint] = e.useState(props.defaultValue);
|
|
1587
|
+
const ref = e.useRef();
|
|
1546
1588
|
ref.current = contactPoint;
|
|
1547
1589
|
function setContactPointWrapper(newValue) {
|
|
1548
1590
|
if (newValue && Object.keys(newValue).length === 0) {
|
|
@@ -1574,15 +1616,15 @@
|
|
|
1574
1616
|
}
|
|
1575
1617
|
setContactPointWrapper(newValue);
|
|
1576
1618
|
}
|
|
1577
|
-
return (
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1619
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1620
|
+
e.createElement(core$1.NativeSelect, { "data-testid": "system", defaultValue: contactPoint?.system, onChange: (e) => setSystem(e.currentTarget.value), data: ['', 'email', 'phone', 'fax', 'pager', 'sms', 'other'] }),
|
|
1621
|
+
e.createElement(core$1.NativeSelect, { "data-testid": "use", defaultValue: contactPoint?.use, onChange: (e) => setUse(e.currentTarget.value), data: ['', 'home', 'work', 'temp', 'old', 'mobile'] }),
|
|
1622
|
+
e.createElement(core$1.TextInput, { placeholder: "Value", defaultValue: contactPoint?.value, onChange: (e) => setValue(e.currentTarget.value) })));
|
|
1581
1623
|
}
|
|
1582
1624
|
|
|
1583
1625
|
function ContactDetailInput(props) {
|
|
1584
|
-
const [contactPoint, setContactDetail] =
|
|
1585
|
-
const ref =
|
|
1626
|
+
const [contactPoint, setContactDetail] = e.useState(props.defaultValue);
|
|
1627
|
+
const ref = e.useRef();
|
|
1586
1628
|
ref.current = contactPoint;
|
|
1587
1629
|
function setContactDetailWrapper(newValue) {
|
|
1588
1630
|
setContactDetail(newValue);
|
|
@@ -1604,9 +1646,9 @@
|
|
|
1604
1646
|
}
|
|
1605
1647
|
setContactDetailWrapper(newValue);
|
|
1606
1648
|
}
|
|
1607
|
-
return (
|
|
1608
|
-
|
|
1609
|
-
|
|
1649
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1650
|
+
e.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) }),
|
|
1651
|
+
e.createElement(ContactPointInput, { name: props.name + '-telecom', defaultValue: contactPoint?.telecom?.[0], onChange: setTelecom })));
|
|
1610
1652
|
}
|
|
1611
1653
|
|
|
1612
1654
|
/**
|
|
@@ -1618,7 +1660,7 @@
|
|
|
1618
1660
|
* @returns The JSX element to render.
|
|
1619
1661
|
*/
|
|
1620
1662
|
function DateTimeInput(props) {
|
|
1621
|
-
return (
|
|
1663
|
+
return (e.createElement(core$1.TextInput, { id: props.name, name: props.name, "data-testid": props.name, placeholder: props.placeholder, type: getInputType(), defaultValue: convertIsoToLocal(props.defaultValue), error: getErrorsForInput(props.outcome, props.name), onChange: (e) => {
|
|
1622
1664
|
if (props.onChange) {
|
|
1623
1665
|
const newValue = e.currentTarget.value;
|
|
1624
1666
|
props.onChange(convertLocalToIso(newValue));
|
|
@@ -1673,7 +1715,7 @@
|
|
|
1673
1715
|
}
|
|
1674
1716
|
|
|
1675
1717
|
function ExtensionInput(props) {
|
|
1676
|
-
return (
|
|
1718
|
+
return (e.createElement(core$1.JsonInput, { id: props.name, name: props.name, "data-testid": "extension-input", defaultValue: core.stringify(props.defaultValue), onChange: (newValue) => {
|
|
1677
1719
|
if (props.onChange) {
|
|
1678
1720
|
props.onChange(JSON.parse(newValue));
|
|
1679
1721
|
}
|
|
@@ -1681,8 +1723,8 @@
|
|
|
1681
1723
|
}
|
|
1682
1724
|
|
|
1683
1725
|
function HumanNameInput(props) {
|
|
1684
|
-
const [value, setValue] =
|
|
1685
|
-
const valueRef =
|
|
1726
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1727
|
+
const valueRef = e.useRef();
|
|
1686
1728
|
valueRef.current = value;
|
|
1687
1729
|
function setValueWrapper(newValue) {
|
|
1688
1730
|
setValue(newValue);
|
|
@@ -1717,25 +1759,25 @@
|
|
|
1717
1759
|
suffix: suffix ? suffix.split(' ') : undefined,
|
|
1718
1760
|
});
|
|
1719
1761
|
}
|
|
1720
|
-
return (
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1762
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1763
|
+
e.createElement(core$1.NativeSelect, { defaultValue: value?.use, "data-testid": "use", onChange: (e) => setUse(e.currentTarget.value), data: ['', 'temp', 'old', 'usual', 'official', 'nickname', 'anonymous', 'maiden'] }),
|
|
1764
|
+
e.createElement(core$1.TextInput, { placeholder: "Prefix", defaultValue: value?.prefix?.join(' '), onChange: (e) => setPrefix(e.currentTarget.value) }),
|
|
1765
|
+
e.createElement(core$1.TextInput, { placeholder: "Given", defaultValue: value?.given?.join(' '), onChange: (e) => setGiven(e.currentTarget.value) }),
|
|
1766
|
+
e.createElement(core$1.TextInput, { placeholder: "Family", defaultValue: value?.family, onChange: (e) => setFamily(e.currentTarget.value) }),
|
|
1767
|
+
e.createElement(core$1.TextInput, { placeholder: "Suffix", defaultValue: value?.suffix?.join(' '), onChange: (e) => setSuffix(e.currentTarget.value) })));
|
|
1726
1768
|
}
|
|
1727
1769
|
|
|
1728
1770
|
function IdentifierInput(props) {
|
|
1729
|
-
const [value, setValue] =
|
|
1771
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1730
1772
|
function setValueWrapper(newValue) {
|
|
1731
1773
|
setValue(newValue);
|
|
1732
1774
|
if (props.onChange) {
|
|
1733
1775
|
props.onChange(newValue);
|
|
1734
1776
|
}
|
|
1735
1777
|
}
|
|
1736
|
-
return (
|
|
1737
|
-
|
|
1738
|
-
|
|
1778
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1779
|
+
e.createElement(core$1.TextInput, { placeholder: "System", defaultValue: value?.system, onChange: (e) => setValueWrapper({ ...value, system: e.currentTarget.value }) }),
|
|
1780
|
+
e.createElement(core$1.TextInput, { placeholder: "Value", defaultValue: value?.value, onChange: (e) => setValueWrapper({ ...value, value: e.currentTarget.value }) })));
|
|
1739
1781
|
}
|
|
1740
1782
|
|
|
1741
1783
|
/*
|
|
@@ -1755,26 +1797,26 @@
|
|
|
1755
1797
|
const data = ['USD', 'EUR', 'CAD', 'GBP', 'AUD'];
|
|
1756
1798
|
function MoneyInput(props) {
|
|
1757
1799
|
const { onChange } = props;
|
|
1758
|
-
const [value, setValue] =
|
|
1759
|
-
const setValueWrapper =
|
|
1800
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1801
|
+
const setValueWrapper = e.useCallback((newValue) => {
|
|
1760
1802
|
setValue(newValue);
|
|
1761
1803
|
if (onChange) {
|
|
1762
1804
|
onChange(newValue);
|
|
1763
1805
|
}
|
|
1764
1806
|
}, [onChange]);
|
|
1765
|
-
const handleCurrencyChange =
|
|
1807
|
+
const handleCurrencyChange = e.useCallback((e) => {
|
|
1766
1808
|
setValueWrapper({
|
|
1767
1809
|
...value,
|
|
1768
1810
|
currency: e.currentTarget.value,
|
|
1769
1811
|
});
|
|
1770
1812
|
}, [value, setValueWrapper]);
|
|
1771
|
-
const handleValueChange =
|
|
1813
|
+
const handleValueChange = e.useCallback((e) => {
|
|
1772
1814
|
setValueWrapper({
|
|
1773
1815
|
...value,
|
|
1774
1816
|
value: e.currentTarget.valueAsNumber,
|
|
1775
1817
|
});
|
|
1776
1818
|
}, [value, setValueWrapper]);
|
|
1777
|
-
const select = (
|
|
1819
|
+
const select = (e.createElement(core$1.NativeSelect, { defaultValue: value?.currency, data: data, styles: {
|
|
1778
1820
|
input: {
|
|
1779
1821
|
fontWeight: 500,
|
|
1780
1822
|
borderTopLeftRadius: 0,
|
|
@@ -1782,40 +1824,46 @@
|
|
|
1782
1824
|
width: 92,
|
|
1783
1825
|
},
|
|
1784
1826
|
}, onChange: handleCurrencyChange }));
|
|
1785
|
-
return (
|
|
1827
|
+
return (e.createElement(core$1.TextInput, { type: "number", label: props.label, placeholder: props.placeholder || 'Value', defaultValue: value?.value?.toString() || 'USD', icon: e.createElement(BK, { size: 14 }), rightSection: select, rightSectionWidth: 92, onChange: handleValueChange }));
|
|
1786
1828
|
}
|
|
1787
1829
|
|
|
1788
1830
|
function PeriodInput(props) {
|
|
1789
|
-
const [value, setValue] =
|
|
1831
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1790
1832
|
function setValueWrapper(newValue) {
|
|
1791
1833
|
setValue(newValue);
|
|
1792
1834
|
if (props.onChange) {
|
|
1793
1835
|
props.onChange(newValue);
|
|
1794
1836
|
}
|
|
1795
1837
|
}
|
|
1796
|
-
return (
|
|
1797
|
-
|
|
1798
|
-
|
|
1838
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1839
|
+
e.createElement(DateTimeInput, { name: props.name + '.start', placeholder: "Start", defaultValue: value?.start, onChange: (newValue) => setValueWrapper({ ...value, start: newValue }) }),
|
|
1840
|
+
e.createElement(DateTimeInput, { name: props.name + '.end', placeholder: "End", defaultValue: value?.end, onChange: (newValue) => setValueWrapper({ ...value, end: newValue }) })));
|
|
1799
1841
|
}
|
|
1800
1842
|
|
|
1801
1843
|
function QuantityInput(props) {
|
|
1802
|
-
const [value, setValue] =
|
|
1844
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1803
1845
|
function setValueWrapper(newValue) {
|
|
1804
1846
|
setValue(newValue);
|
|
1805
1847
|
if (props.onChange) {
|
|
1806
1848
|
props.onChange(newValue);
|
|
1807
1849
|
}
|
|
1808
1850
|
}
|
|
1809
|
-
return (
|
|
1810
|
-
|
|
1851
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1852
|
+
e.createElement(core$1.NativeSelect, { style: { width: 80 }, "data-testid": props.name + '-comparator', defaultValue: value?.comparator, data: ['', '<', '<=', '>=', '>'], onChange: (e) => setValueWrapper({
|
|
1811
1853
|
...value,
|
|
1812
1854
|
comparator: e.currentTarget.value,
|
|
1813
1855
|
}) }),
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1856
|
+
e.createElement(core$1.TextInput, { id: props.name, name: props.name, "data-testid": props.name + '-value', type: "number", placeholder: "Value", defaultValue: value?.value, step: "any", onWheel: (e) => {
|
|
1857
|
+
if (props.disableWheel) {
|
|
1858
|
+
e.currentTarget.blur();
|
|
1859
|
+
}
|
|
1860
|
+
}, onChange: (e) => {
|
|
1861
|
+
setValueWrapper({
|
|
1862
|
+
...value,
|
|
1863
|
+
value: tryParseNumber(e.currentTarget.value),
|
|
1864
|
+
});
|
|
1865
|
+
} }),
|
|
1866
|
+
e.createElement(core$1.TextInput, { placeholder: "Unit", "data-testid": props.name + '-unit', defaultValue: value?.unit, onChange: (e) => setValueWrapper({
|
|
1819
1867
|
...value,
|
|
1820
1868
|
unit: e.currentTarget.value,
|
|
1821
1869
|
}) })));
|
|
@@ -1834,19 +1882,19 @@
|
|
|
1834
1882
|
* @returns Range input element.
|
|
1835
1883
|
*/
|
|
1836
1884
|
function RangeInput(props) {
|
|
1837
|
-
const [value, setValue] =
|
|
1885
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1838
1886
|
function setValueWrapper(newValue) {
|
|
1839
1887
|
setValue(newValue);
|
|
1840
1888
|
if (props.onChange) {
|
|
1841
1889
|
props.onChange(newValue);
|
|
1842
1890
|
}
|
|
1843
1891
|
}
|
|
1844
|
-
return (
|
|
1845
|
-
|
|
1892
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1893
|
+
e.createElement(QuantityInput, { name: props.name + '-low', defaultValue: value?.low, onChange: (v) => setValueWrapper({
|
|
1846
1894
|
...value,
|
|
1847
1895
|
low: v,
|
|
1848
1896
|
}) }),
|
|
1849
|
-
|
|
1897
|
+
e.createElement(QuantityInput, { name: props.name + '-high', defaultValue: value?.high, onChange: (v) => setValueWrapper({
|
|
1850
1898
|
...value,
|
|
1851
1899
|
high: v,
|
|
1852
1900
|
}) })));
|
|
@@ -1859,19 +1907,19 @@
|
|
|
1859
1907
|
* @returns Ratio input element.
|
|
1860
1908
|
*/
|
|
1861
1909
|
function RatioInput(props) {
|
|
1862
|
-
const [value, setValue] =
|
|
1910
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
1863
1911
|
function setValueWrapper(newValue) {
|
|
1864
1912
|
setValue(newValue);
|
|
1865
1913
|
if (props.onChange) {
|
|
1866
1914
|
props.onChange(newValue);
|
|
1867
1915
|
}
|
|
1868
1916
|
}
|
|
1869
|
-
return (
|
|
1870
|
-
|
|
1917
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
1918
|
+
e.createElement(QuantityInput, { name: props.name + '-numerator', defaultValue: value?.numerator, onChange: (v) => setValueWrapper({
|
|
1871
1919
|
...value,
|
|
1872
1920
|
numerator: v,
|
|
1873
1921
|
}) }),
|
|
1874
|
-
|
|
1922
|
+
e.createElement(QuantityInput, { name: props.name + '-denominator', defaultValue: value?.denominator, onChange: (v) => setValueWrapper({
|
|
1875
1923
|
...value,
|
|
1876
1924
|
denominator: v,
|
|
1877
1925
|
}) })));
|
|
@@ -1886,10 +1934,10 @@
|
|
|
1886
1934
|
delete avatarProps.value;
|
|
1887
1935
|
delete avatarProps.link;
|
|
1888
1936
|
if (props.link) {
|
|
1889
|
-
return (
|
|
1890
|
-
|
|
1937
|
+
return (e.createElement(MedplumLink, { to: resource },
|
|
1938
|
+
e.createElement(core$1.Avatar, { src: imageUrl, alt: text, radius: radius, ...avatarProps })));
|
|
1891
1939
|
}
|
|
1892
|
-
return
|
|
1940
|
+
return e.createElement(core$1.Avatar, { src: imageUrl, alt: text, radius: radius, ...avatarProps });
|
|
1893
1941
|
}
|
|
1894
1942
|
|
|
1895
1943
|
/**
|
|
@@ -1912,10 +1960,10 @@
|
|
|
1912
1960
|
function ResourceInput(props) {
|
|
1913
1961
|
const medplum = useMedplum();
|
|
1914
1962
|
const defaultValue = useResource(props.defaultValue);
|
|
1915
|
-
const [value, setValue] =
|
|
1916
|
-
const [loading, setLoading] =
|
|
1917
|
-
const [data, setData] =
|
|
1918
|
-
|
|
1963
|
+
const [value, setValue] = e.useState(defaultValue ? core.getDisplayString(defaultValue) : '');
|
|
1964
|
+
const [loading, setLoading] = e.useState(false);
|
|
1965
|
+
const [data, setData] = e.useState([]);
|
|
1966
|
+
e.useEffect(() => {
|
|
1919
1967
|
if (defaultValue) {
|
|
1920
1968
|
setValue(core.getDisplayString(defaultValue));
|
|
1921
1969
|
}
|
|
@@ -1942,25 +1990,25 @@
|
|
|
1942
1990
|
props.onChange(item.resource);
|
|
1943
1991
|
}
|
|
1944
1992
|
}
|
|
1945
|
-
return (
|
|
1993
|
+
return (e.createElement(core$1.Autocomplete, { itemComponent: ItemComponent, value: value, data: data, placeholder: props.placeholder, onFocus: () => loadValues(value), onChange: handleChange, onItemSubmit: handleSelect, rightSection: loading ? e.createElement(core$1.Loader, { size: 16 }) : null }));
|
|
1946
1994
|
}
|
|
1947
|
-
const ItemComponent =
|
|
1948
|
-
return (
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1995
|
+
const ItemComponent = e.forwardRef(({ value, resource, ...others }, ref) => {
|
|
1996
|
+
return (e.createElement("div", { ref: ref, ...others },
|
|
1997
|
+
e.createElement(core$1.Group, { noWrap: true },
|
|
1998
|
+
e.createElement(ResourceAvatar, { value: resource }),
|
|
1999
|
+
e.createElement("div", null,
|
|
2000
|
+
e.createElement(core$1.Text, null, value),
|
|
2001
|
+
e.createElement(core$1.Text, { size: "xs", color: "dimmed" }, resource.birthDate)))));
|
|
1954
2002
|
});
|
|
1955
2003
|
|
|
1956
2004
|
function ReferenceInput(props) {
|
|
1957
2005
|
const targetTypes = getTargetTypes$1(props.targetTypes);
|
|
1958
2006
|
const initialResourceType = getInitialResourceType(props.defaultValue, targetTypes);
|
|
1959
|
-
const [value, setValue] =
|
|
1960
|
-
const [resourceType, setResourceType] =
|
|
1961
|
-
const valueRef =
|
|
2007
|
+
const [value, setValue] = e.useState(props.defaultValue);
|
|
2008
|
+
const [resourceType, setResourceType] = e.useState(initialResourceType);
|
|
2009
|
+
const valueRef = e.useRef();
|
|
1962
2010
|
valueRef.current = value;
|
|
1963
|
-
const resourceTypeRef =
|
|
2011
|
+
const resourceTypeRef = e.useRef();
|
|
1964
2012
|
resourceTypeRef.current = resourceType;
|
|
1965
2013
|
function setValueHelper(newValue) {
|
|
1966
2014
|
setValue(newValue);
|
|
@@ -1968,9 +2016,9 @@
|
|
|
1968
2016
|
props.onChange(newValue);
|
|
1969
2017
|
}
|
|
1970
2018
|
}
|
|
1971
|
-
return (
|
|
1972
|
-
targetTypes ? (
|
|
1973
|
-
|
|
2019
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
2020
|
+
targetTypes ? (e.createElement(core$1.NativeSelect, { "data-testid": "reference-input-resource-type-select", defaultValue: resourceType, onChange: (e) => setResourceType(e.currentTarget.value), data: targetTypes })) : (e.createElement(core$1.TextInput, { "data-testid": "reference-input-resource-type-input", defaultValue: resourceType, onChange: (e) => setResourceType(e.currentTarget.value) })),
|
|
2021
|
+
e.createElement(ResourceInput, { resourceType: resourceType, name: props.name + '-id', placeholder: props.placeholder, defaultValue: value, onChange: (item) => {
|
|
1974
2022
|
setValueHelper(item ? core.createReference(item) : undefined);
|
|
1975
2023
|
} })));
|
|
1976
2024
|
}
|
|
@@ -1992,8 +2040,8 @@
|
|
|
1992
2040
|
}
|
|
1993
2041
|
|
|
1994
2042
|
function ResourceArrayInput(props) {
|
|
1995
|
-
const [values, setValues] =
|
|
1996
|
-
const valuesRef =
|
|
2043
|
+
const [values, setValues] = e.useState(props.defaultValue && Array.isArray(props.defaultValue) ? props.defaultValue : []);
|
|
2044
|
+
const valuesRef = e.useRef();
|
|
1997
2045
|
valuesRef.current = values;
|
|
1998
2046
|
function setValuesWrapper(newValues) {
|
|
1999
2047
|
setValues(newValues);
|
|
@@ -2001,49 +2049,49 @@
|
|
|
2001
2049
|
props.onChange(newValues);
|
|
2002
2050
|
}
|
|
2003
2051
|
}
|
|
2004
|
-
return (
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
values.map((v, index) => (
|
|
2010
|
-
|
|
2011
|
-
|
|
2052
|
+
return (e.createElement("table", { style: { width: '100%', borderCollapse: 'collapse' } },
|
|
2053
|
+
e.createElement("colgroup", null,
|
|
2054
|
+
e.createElement("col", { width: "97%" }),
|
|
2055
|
+
e.createElement("col", { width: "3%" })),
|
|
2056
|
+
e.createElement("tbody", null,
|
|
2057
|
+
values.map((v, index) => (e.createElement("tr", { key: `${index}-${values.length}` },
|
|
2058
|
+
e.createElement("td", null,
|
|
2059
|
+
e.createElement(ResourcePropertyInput, { arrayElement: true, property: props.property, name: props.name + '.' + index, defaultValue: v, onChange: (newValue) => {
|
|
2012
2060
|
const copy = [...valuesRef.current];
|
|
2013
2061
|
copy[index] = newValue;
|
|
2014
2062
|
setValuesWrapper(copy);
|
|
2015
2063
|
} })),
|
|
2016
|
-
|
|
2017
|
-
|
|
2064
|
+
e.createElement("td", { style: { textAlign: 'right' } },
|
|
2065
|
+
e.createElement(core$1.ActionIcon, { title: "Remove", size: "sm", onClick: (e) => {
|
|
2018
2066
|
killEvent(e);
|
|
2019
2067
|
const copy = [...valuesRef.current];
|
|
2020
2068
|
copy.splice(index, 1);
|
|
2021
2069
|
setValuesWrapper(copy);
|
|
2022
2070
|
} },
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2071
|
+
e.createElement(IP, null)))))),
|
|
2072
|
+
e.createElement("tr", null,
|
|
2073
|
+
e.createElement("td", null),
|
|
2074
|
+
e.createElement("td", { style: { textAlign: 'right' } },
|
|
2075
|
+
e.createElement(core$1.ActionIcon, { title: "Add", size: "sm", color: "green", onClick: (e) => {
|
|
2028
2076
|
killEvent(e);
|
|
2029
2077
|
const copy = [...valuesRef.current];
|
|
2030
2078
|
copy.push(undefined);
|
|
2031
2079
|
setValuesWrapper(copy);
|
|
2032
2080
|
} },
|
|
2033
|
-
|
|
2081
|
+
e.createElement(iS, null)))))));
|
|
2034
2082
|
}
|
|
2035
2083
|
|
|
2036
2084
|
const daysOfWeek = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
|
|
2037
2085
|
function TimingInput(props) {
|
|
2038
|
-
const [value, setValue] =
|
|
2039
|
-
const [open, setOpen] =
|
|
2040
|
-
const valueRef =
|
|
2086
|
+
const [value, setValue] = e.useState(props.defaultValue || {});
|
|
2087
|
+
const [open, setOpen] = e.useState(false);
|
|
2088
|
+
const valueRef = e.useRef();
|
|
2041
2089
|
valueRef.current = value;
|
|
2042
|
-
return (
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2090
|
+
return (e.createElement(e.Fragment, null,
|
|
2091
|
+
e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
2092
|
+
e.createElement("span", null, core.formatTiming(valueRef.current) || 'No repeat'),
|
|
2093
|
+
e.createElement(core$1.Button, { onClick: () => setOpen(true) }, "Edit")),
|
|
2094
|
+
e.createElement(TimingEditorDialog, { visible: open, defaultValue: valueRef.current, onOk: (newValue) => {
|
|
2047
2095
|
if (props.onChange) {
|
|
2048
2096
|
props.onChange(newValue);
|
|
2049
2097
|
}
|
|
@@ -2052,8 +2100,8 @@
|
|
|
2052
2100
|
}, onCancel: () => setOpen(false) })));
|
|
2053
2101
|
}
|
|
2054
2102
|
function TimingEditorDialog(props) {
|
|
2055
|
-
const [value, setValue] =
|
|
2056
|
-
const valueRef =
|
|
2103
|
+
const [value, setValue] = e.useState(props.defaultValue || {});
|
|
2104
|
+
const valueRef = e.useRef();
|
|
2057
2105
|
valueRef.current = value;
|
|
2058
2106
|
function setStart(newStart) {
|
|
2059
2107
|
setValue({ ...valueRef.current, event: [newStart] });
|
|
@@ -2087,24 +2135,24 @@
|
|
|
2087
2135
|
setRepeat({ ...valueRef.current?.repeat, dayOfWeek: existing.filter((d) => d !== day) });
|
|
2088
2136
|
}
|
|
2089
2137
|
}
|
|
2090
|
-
return (
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2138
|
+
return (e.createElement(core$1.Modal, { title: "Timing", closeButtonLabel: "Close", opened: props.visible, onClose: () => props.onCancel() },
|
|
2139
|
+
e.createElement("div", { style: { padding: '5px 20px', textAlign: 'left' } },
|
|
2140
|
+
e.createElement(FormSection, { title: "Starts on", htmlFor: 'timing-dialog-start' },
|
|
2141
|
+
e.createElement(DateTimeInput, { name: 'timing-dialog-start', onChange: (newValue) => setStart(newValue) })),
|
|
2142
|
+
e.createElement(FormSection, { title: "Repeat every", htmlFor: 'timing-dialog-period' },
|
|
2143
|
+
e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
2144
|
+
e.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)) }),
|
|
2145
|
+
e.createElement(core$1.NativeSelect, { id: "timing-dialog-periodUnit", name: "timing-dialog-periodUnit", defaultValue: value?.repeat?.periodUnit, onChange: (e) => setPeriodUnit(e.currentTarget.value), data: [
|
|
2098
2146
|
{ label: 'day', value: 'd' },
|
|
2099
2147
|
{ label: 'week', value: 'wk' },
|
|
2100
2148
|
{ label: 'month', value: 'mo' },
|
|
2101
2149
|
{ label: 'year', value: 'a' },
|
|
2102
2150
|
] }))),
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2151
|
+
e.createElement(FormSection, { title: "Repeat on" },
|
|
2152
|
+
e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true }, daysOfWeek.map((day) => (e.createElement(e.Fragment, { key: day },
|
|
2153
|
+
e.createElement("label", { htmlFor: 'timing-dialog-repeat-' + day }, day.charAt(0).toUpperCase()),
|
|
2154
|
+
e.createElement(core$1.Checkbox, { id: 'timing-dialog-repeat-' + day, name: 'timing-dialog-repeat-' + day, onChange: (e) => setDayOfWeek(day, e.currentTarget.checked) }))))))),
|
|
2155
|
+
e.createElement(core$1.Button, { onClick: () => props.onOk(value) }, "OK")));
|
|
2108
2156
|
}
|
|
2109
2157
|
|
|
2110
2158
|
function ResourcePropertyInput(props) {
|
|
@@ -2114,16 +2162,16 @@
|
|
|
2114
2162
|
const value = props.defaultValue;
|
|
2115
2163
|
if (property.max === '*' && !props.arrayElement) {
|
|
2116
2164
|
if (propertyType === 'Attachment') {
|
|
2117
|
-
return
|
|
2165
|
+
return e.createElement(AttachmentArrayInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2118
2166
|
}
|
|
2119
|
-
return
|
|
2167
|
+
return e.createElement(ResourceArrayInput, { property: property, name: name, defaultValue: value, onChange: props.onChange });
|
|
2120
2168
|
}
|
|
2121
2169
|
const propertyTypes = property.type;
|
|
2122
2170
|
if (propertyTypes.length > 1) {
|
|
2123
|
-
return
|
|
2171
|
+
return e.createElement(ElementDefinitionInputSelector, { elementDefinitionTypes: propertyTypes, ...props });
|
|
2124
2172
|
}
|
|
2125
2173
|
else {
|
|
2126
|
-
return
|
|
2174
|
+
return e.createElement(ElementDefinitionTypeInput, { elementDefinitionType: propertyTypes[0], ...props });
|
|
2127
2175
|
}
|
|
2128
2176
|
}
|
|
2129
2177
|
function ElementDefinitionInputSelector(props) {
|
|
@@ -2135,15 +2183,15 @@
|
|
|
2135
2183
|
if (!initialPropertyType) {
|
|
2136
2184
|
initialPropertyType = propertyTypes[0];
|
|
2137
2185
|
}
|
|
2138
|
-
const [selectedType, setSelectedType] =
|
|
2139
|
-
return (
|
|
2140
|
-
|
|
2186
|
+
const [selectedType, setSelectedType] = e.useState(initialPropertyType);
|
|
2187
|
+
return (e.createElement(core$1.Group, { spacing: "xs", grow: true, noWrap: true },
|
|
2188
|
+
e.createElement(core$1.NativeSelect, { style: { width: '200px' }, defaultValue: selectedType?.code, onChange: (e) => {
|
|
2141
2189
|
setSelectedType(propertyTypes.find((type) => type.code === e.currentTarget.value));
|
|
2142
2190
|
}, data: propertyTypes.map((type) => ({
|
|
2143
2191
|
value: type.code,
|
|
2144
2192
|
label: type.code,
|
|
2145
2193
|
})) }),
|
|
2146
|
-
|
|
2194
|
+
e.createElement(ElementDefinitionTypeInput, { ...props, elementDefinitionType: selectedType, onChange: (newValue) => {
|
|
2147
2195
|
if (props.onChange) {
|
|
2148
2196
|
props.onChange(newValue, props.name.replace('[x]', core.capitalize(selectedType.code)));
|
|
2149
2197
|
}
|
|
@@ -2163,39 +2211,39 @@
|
|
|
2163
2211
|
case core.PropertyType.time:
|
|
2164
2212
|
case core.PropertyType.uri:
|
|
2165
2213
|
case core.PropertyType.url:
|
|
2166
|
-
return (
|
|
2214
|
+
return (e.createElement(core$1.TextInput, { id: name, name: name, "data-testid": name, defaultValue: value, onChange: (e) => {
|
|
2167
2215
|
if (props.onChange) {
|
|
2168
2216
|
props.onChange(e.currentTarget.value);
|
|
2169
2217
|
}
|
|
2170
2218
|
}, error: getErrorsForInput(props.outcome, name) }));
|
|
2171
2219
|
case core.PropertyType.date:
|
|
2172
|
-
return (
|
|
2220
|
+
return (e.createElement(core$1.TextInput, { type: "date", id: name, name: name, "data-testid": name, defaultValue: value, onChange: (e) => {
|
|
2173
2221
|
if (props.onChange) {
|
|
2174
2222
|
props.onChange(e.currentTarget.value);
|
|
2175
2223
|
}
|
|
2176
2224
|
}, error: getErrorsForInput(props.outcome, name) }));
|
|
2177
2225
|
case core.PropertyType.dateTime:
|
|
2178
2226
|
case core.PropertyType.instant:
|
|
2179
|
-
return
|
|
2227
|
+
return e.createElement(DateTimeInput, { name: name, defaultValue: value, onChange: props.onChange, outcome: props.outcome });
|
|
2180
2228
|
case core.PropertyType.decimal:
|
|
2181
2229
|
case core.PropertyType.integer:
|
|
2182
2230
|
case core.PropertyType.positiveInt:
|
|
2183
2231
|
case core.PropertyType.unsignedInt:
|
|
2184
|
-
return (
|
|
2232
|
+
return (e.createElement(core$1.TextInput, { type: "number", step: propertyType === core.PropertyType.decimal ? 'any' : '1', id: name, name: name, "data-testid": name, defaultValue: value, onChange: (e) => {
|
|
2185
2233
|
if (props.onChange) {
|
|
2186
2234
|
props.onChange(e.currentTarget.valueAsNumber);
|
|
2187
2235
|
}
|
|
2188
2236
|
} }));
|
|
2189
2237
|
case core.PropertyType.code:
|
|
2190
|
-
return
|
|
2238
|
+
return e.createElement(CodeInput, { property: property, name: name, defaultValue: value, onChange: props.onChange });
|
|
2191
2239
|
case core.PropertyType.boolean:
|
|
2192
|
-
return (
|
|
2240
|
+
return (e.createElement(core$1.Checkbox, { id: name, name: name, "data-testid": name, defaultChecked: !!value, onChange: (e) => {
|
|
2193
2241
|
if (props.onChange) {
|
|
2194
2242
|
props.onChange(e.currentTarget.checked);
|
|
2195
2243
|
}
|
|
2196
2244
|
} }));
|
|
2197
2245
|
case core.PropertyType.markdown:
|
|
2198
|
-
return (
|
|
2246
|
+
return (e.createElement(core$1.Textarea, { id: name, name: name, "data-testid": name, defaultValue: value, onChange: (e) => {
|
|
2199
2247
|
if (props.onChange) {
|
|
2200
2248
|
props.onChange(e.currentTarget.value);
|
|
2201
2249
|
}
|
|
@@ -2203,45 +2251,45 @@
|
|
|
2203
2251
|
// 2.24.0.2 Complex Types
|
|
2204
2252
|
// https://www.hl7.org/fhir/datatypes.html#complex
|
|
2205
2253
|
case core.PropertyType.Address:
|
|
2206
|
-
return
|
|
2254
|
+
return e.createElement(AddressInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2207
2255
|
case core.PropertyType.Annotation:
|
|
2208
|
-
return
|
|
2256
|
+
return e.createElement(AnnotationInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2209
2257
|
case core.PropertyType.Attachment:
|
|
2210
|
-
return
|
|
2258
|
+
return e.createElement(AttachmentInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2211
2259
|
case core.PropertyType.CodeableConcept:
|
|
2212
|
-
return
|
|
2260
|
+
return e.createElement(CodeableConceptInput, { property: property, name: name, defaultValue: value, onChange: props.onChange });
|
|
2213
2261
|
case core.PropertyType.Coding:
|
|
2214
|
-
return
|
|
2262
|
+
return e.createElement(CodingInput, { property: property, name: name, defaultValue: value, onChange: props.onChange });
|
|
2215
2263
|
case core.PropertyType.ContactDetail:
|
|
2216
|
-
return
|
|
2264
|
+
return e.createElement(ContactDetailInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2217
2265
|
case core.PropertyType.ContactPoint:
|
|
2218
|
-
return
|
|
2266
|
+
return e.createElement(ContactPointInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2219
2267
|
case core.PropertyType.Extension:
|
|
2220
|
-
return
|
|
2268
|
+
return e.createElement(ExtensionInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2221
2269
|
case core.PropertyType.HumanName:
|
|
2222
|
-
return
|
|
2270
|
+
return e.createElement(HumanNameInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2223
2271
|
case core.PropertyType.Identifier:
|
|
2224
|
-
return
|
|
2272
|
+
return e.createElement(IdentifierInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2225
2273
|
case core.PropertyType.Money:
|
|
2226
|
-
return
|
|
2274
|
+
return e.createElement(MoneyInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2227
2275
|
case core.PropertyType.Period:
|
|
2228
|
-
return
|
|
2276
|
+
return e.createElement(PeriodInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2229
2277
|
case core.PropertyType.Duration:
|
|
2230
2278
|
case core.PropertyType.Quantity:
|
|
2231
|
-
return
|
|
2279
|
+
return e.createElement(QuantityInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2232
2280
|
case core.PropertyType.Range:
|
|
2233
|
-
return
|
|
2281
|
+
return e.createElement(RangeInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2234
2282
|
case core.PropertyType.Ratio:
|
|
2235
|
-
return
|
|
2283
|
+
return e.createElement(RatioInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2236
2284
|
case core.PropertyType.Reference:
|
|
2237
|
-
return (
|
|
2285
|
+
return (e.createElement(ReferenceInput, { name: name, defaultValue: value, targetTypes: getTargetTypes(property), onChange: props.onChange }));
|
|
2238
2286
|
case core.PropertyType.Timing:
|
|
2239
|
-
return
|
|
2287
|
+
return e.createElement(TimingInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2240
2288
|
case core.PropertyType.Dosage:
|
|
2241
2289
|
case core.PropertyType.UsageContext:
|
|
2242
|
-
return (
|
|
2290
|
+
return (e.createElement(BackboneElementInput, { typeName: propertyType, defaultValue: value, onChange: props.onChange, outcome: props.outcome }));
|
|
2243
2291
|
default:
|
|
2244
|
-
return (
|
|
2292
|
+
return (e.createElement(BackboneElementInput, { typeName: core.getElementDefinitionTypeName(property), defaultValue: value, onChange: props.onChange, outcome: props.outcome }));
|
|
2245
2293
|
}
|
|
2246
2294
|
}
|
|
2247
2295
|
function getTargetTypes(property) {
|
|
@@ -2249,7 +2297,7 @@
|
|
|
2249
2297
|
}
|
|
2250
2298
|
|
|
2251
2299
|
function BackboneElementInput(props) {
|
|
2252
|
-
const [value, setValue] =
|
|
2300
|
+
const [value, setValue] = e.useState(props.defaultValue ?? {});
|
|
2253
2301
|
function setValueWrapper(newValue) {
|
|
2254
2302
|
setValue(newValue);
|
|
2255
2303
|
if (props.onChange) {
|
|
@@ -2259,12 +2307,12 @@
|
|
|
2259
2307
|
const typeName = props.typeName;
|
|
2260
2308
|
const typeSchema = core.globalSchema.types[typeName];
|
|
2261
2309
|
if (!typeSchema) {
|
|
2262
|
-
return
|
|
2310
|
+
return e.createElement("div", null,
|
|
2263
2311
|
typeName,
|
|
2264
2312
|
"\u00A0not implemented");
|
|
2265
2313
|
}
|
|
2266
2314
|
const typedValue = { type: typeName, value };
|
|
2267
|
-
return (
|
|
2315
|
+
return (e.createElement(core$1.Stack, null, Object.entries(typeSchema.properties).map((entry) => {
|
|
2268
2316
|
const key = entry[0];
|
|
2269
2317
|
if (key === 'id' || DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
|
|
2270
2318
|
return null;
|
|
@@ -2275,19 +2323,19 @@
|
|
|
2275
2323
|
}
|
|
2276
2324
|
const [propertyValue, propertyType] = getValueAndType(typedValue, key);
|
|
2277
2325
|
if (property.type.length === 1 && property.type[0].code === 'boolean') {
|
|
2278
|
-
return (
|
|
2279
|
-
|
|
2326
|
+
return (e.createElement(CheckboxFormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key },
|
|
2327
|
+
e.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
|
|
2280
2328
|
setValueWrapper(setPropertyValue(value, key, propName ?? key, entry[1], newValue));
|
|
2281
2329
|
} })));
|
|
2282
2330
|
}
|
|
2283
|
-
return (
|
|
2284
|
-
|
|
2331
|
+
return (e.createElement(FormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key, outcome: props.outcome },
|
|
2332
|
+
e.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
|
|
2285
2333
|
setValueWrapper(setPropertyValue(value, key, propName ?? key, entry[1], newValue));
|
|
2286
2334
|
} })));
|
|
2287
2335
|
})));
|
|
2288
2336
|
}
|
|
2289
2337
|
|
|
2290
|
-
const useStyles$
|
|
2338
|
+
const useStyles$b = core$1.createStyles((theme) => ({
|
|
2291
2339
|
table: {
|
|
2292
2340
|
width: 350,
|
|
2293
2341
|
'& th': {
|
|
@@ -2332,9 +2380,9 @@
|
|
|
2332
2380
|
return date.toLocaleString('default', { month: 'long' }) + ' ' + date.getFullYear();
|
|
2333
2381
|
}
|
|
2334
2382
|
function CalendarInput(props) {
|
|
2335
|
-
const { classes } = useStyles$
|
|
2383
|
+
const { classes } = useStyles$b();
|
|
2336
2384
|
const { onChangeMonth, onClick } = props;
|
|
2337
|
-
const [month, setMonth] =
|
|
2385
|
+
const [month, setMonth] = e.useState(getStartMonth);
|
|
2338
2386
|
function moveMonth(delta) {
|
|
2339
2387
|
setMonth((currMonth) => {
|
|
2340
2388
|
const newMonth = new Date(currMonth.getTime());
|
|
@@ -2343,24 +2391,24 @@
|
|
|
2343
2391
|
return newMonth;
|
|
2344
2392
|
});
|
|
2345
2393
|
}
|
|
2346
|
-
const grid =
|
|
2347
|
-
return (
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2394
|
+
const grid = e.useMemo(() => buildGrid(month, props.slots), [month, props.slots]);
|
|
2395
|
+
return (e.createElement("div", null,
|
|
2396
|
+
e.createElement(core$1.Group, { position: "apart", spacing: "xs", grow: true, noWrap: true },
|
|
2397
|
+
e.createElement("p", { style: { flex: 1 } }, getMonthString(month)),
|
|
2398
|
+
e.createElement(core$1.Group, { position: "right", spacing: "xs" },
|
|
2399
|
+
e.createElement(core$1.Button, { variant: "outline", "aria-label": "Previous month", onClick: () => moveMonth(-1) }, "<"),
|
|
2400
|
+
e.createElement(core$1.Button, { variant: "outline", "aria-label": "Next month", onClick: () => moveMonth(1) }, ">"))),
|
|
2401
|
+
e.createElement("table", { className: classes.table },
|
|
2402
|
+
e.createElement("thead", null,
|
|
2403
|
+
e.createElement("tr", null,
|
|
2404
|
+
e.createElement("th", null, "SUN"),
|
|
2405
|
+
e.createElement("th", null, "MON"),
|
|
2406
|
+
e.createElement("th", null, "TUE"),
|
|
2407
|
+
e.createElement("th", null, "WED"),
|
|
2408
|
+
e.createElement("th", null, "THU"),
|
|
2409
|
+
e.createElement("th", null, "FRI"),
|
|
2410
|
+
e.createElement("th", null, "SAT"))),
|
|
2411
|
+
e.createElement("tbody", null, grid.map((week, weekIndex) => (e.createElement("tr", { key: 'week-' + weekIndex }, week.map((day, dayIndex) => (e.createElement("td", { key: 'day-' + dayIndex }, day && (e.createElement(core$1.Button, { disabled: !day.available, onClick: () => onClick(day.date) }, day.date.getDate()))))))))))));
|
|
2364
2412
|
}
|
|
2365
2413
|
function getStartMonth() {
|
|
2366
2414
|
const result = new Date();
|
|
@@ -2415,6 +2463,19 @@
|
|
|
2415
2463
|
return false;
|
|
2416
2464
|
}
|
|
2417
2465
|
|
|
2466
|
+
const useStyles$a = core$1.createStyles((theme) => ({
|
|
2467
|
+
noteBody: { fontSize: theme.fontSizes.sm },
|
|
2468
|
+
noteCite: { fontSize: theme.fontSizes.xs, marginBlockStart: 3 },
|
|
2469
|
+
noteRoot: { padding: 5 },
|
|
2470
|
+
}));
|
|
2471
|
+
function NoteDisplay({ value }) {
|
|
2472
|
+
const { classes } = useStyles$a();
|
|
2473
|
+
if (!value) {
|
|
2474
|
+
return null;
|
|
2475
|
+
}
|
|
2476
|
+
return (e.createElement(core$1.Stack, { justify: "flex-start", spacing: "xs" }, value.map((note, index) => note.text && (e.createElement(core$1.Blockquote, { key: `note-${index}`, classNames: { cite: classes.noteCite, body: classes.noteBody, root: classes.noteRoot }, cite: note.authorReference?.display || note.authorString, icon: null }, note.text)))));
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2418
2479
|
function ResourceName(props) {
|
|
2419
2480
|
const { value, link, ...rest } = props;
|
|
2420
2481
|
const resource = useResource(value);
|
|
@@ -2422,13 +2483,13 @@
|
|
|
2422
2483
|
return null;
|
|
2423
2484
|
}
|
|
2424
2485
|
const text = core.getDisplayString(resource);
|
|
2425
|
-
return link ? (
|
|
2486
|
+
return link ? (e.createElement(MedplumLink, { to: resource, ...rest }, text)) : (e.createElement(core$1.Text, { component: "span", ...rest }, text));
|
|
2426
2487
|
}
|
|
2427
2488
|
|
|
2428
2489
|
function ResourceBadge(props) {
|
|
2429
|
-
return (
|
|
2430
|
-
|
|
2431
|
-
|
|
2490
|
+
return (e.createElement(core$1.Group, { spacing: "xs" },
|
|
2491
|
+
e.createElement(ResourceAvatar, { size: 24, radius: 12, value: props.value, link: props.link }),
|
|
2492
|
+
e.createElement(ResourceName, { value: props.value, link: props.link })));
|
|
2432
2493
|
}
|
|
2433
2494
|
|
|
2434
2495
|
/*
|
|
@@ -2486,7 +2547,7 @@
|
|
|
2486
2547
|
stat: 'red',
|
|
2487
2548
|
};
|
|
2488
2549
|
function StatusBadge(props) {
|
|
2489
|
-
return
|
|
2550
|
+
return e.createElement(core$1.Badge, { color: statusToColor[props.status] }, props.status);
|
|
2490
2551
|
}
|
|
2491
2552
|
|
|
2492
2553
|
const useStyles$9 = core$1.createStyles((theme) => ({
|
|
@@ -2507,6 +2568,9 @@
|
|
|
2507
2568
|
border: `0.1px solid ${theme.colors.red[5]}`,
|
|
2508
2569
|
},
|
|
2509
2570
|
},
|
|
2571
|
+
noteBody: { fontSize: theme.fontSizes.sm },
|
|
2572
|
+
noteCite: { fontSize: theme.fontSizes.xs, marginBlockStart: 3 },
|
|
2573
|
+
noteRoot: { padding: 5 },
|
|
2510
2574
|
}));
|
|
2511
2575
|
function DiagnosticReportDisplay(props) {
|
|
2512
2576
|
const diagnosticReport = useResource(props.value);
|
|
@@ -2514,51 +2578,46 @@
|
|
|
2514
2578
|
if (!diagnosticReport) {
|
|
2515
2579
|
return null;
|
|
2516
2580
|
}
|
|
2517
|
-
|
|
2581
|
+
const specimenNotes = specimen?.note || [];
|
|
2518
2582
|
if (diagnosticReport.presentedForm && diagnosticReport.presentedForm.length > 0) {
|
|
2519
2583
|
const pf = diagnosticReport.presentedForm[0];
|
|
2520
2584
|
if (pf.contentType?.startsWith('text/plain') && pf.data) {
|
|
2521
|
-
|
|
2522
|
-
}
|
|
2523
|
-
}
|
|
2524
|
-
if (specimen?.note) {
|
|
2525
|
-
for (const note of specimen.note) {
|
|
2526
|
-
textContent += note.text + '\n\n';
|
|
2585
|
+
specimenNotes.push({ text: window.atob(pf.data) });
|
|
2527
2586
|
}
|
|
2528
2587
|
}
|
|
2529
|
-
return (
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
diagnosticReport.subject && (
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2588
|
+
return (e.createElement(core$1.Stack, null,
|
|
2589
|
+
e.createElement(core$1.Title, null, "Diagnostic Report"),
|
|
2590
|
+
e.createElement(core$1.Group, { mt: "md", spacing: 30 },
|
|
2591
|
+
diagnosticReport.subject && (e.createElement("div", null,
|
|
2592
|
+
e.createElement(core$1.Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Subject"),
|
|
2593
|
+
e.createElement(core$1.Text, null,
|
|
2594
|
+
e.createElement(ResourceBadge, { value: diagnosticReport.subject, link: true })))),
|
|
2536
2595
|
diagnosticReport.resultsInterpreter &&
|
|
2537
|
-
diagnosticReport.resultsInterpreter.map((interpreter) => (
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
diagnosticReport.issued && (
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
diagnosticReport.status && (
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
diagnosticReport.result &&
|
|
2548
|
-
|
|
2596
|
+
diagnosticReport.resultsInterpreter.map((interpreter) => (e.createElement("div", { key: interpreter.reference },
|
|
2597
|
+
e.createElement(core$1.Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Interpreter"),
|
|
2598
|
+
e.createElement(core$1.Text, null,
|
|
2599
|
+
e.createElement(ResourceBadge, { value: interpreter, link: true }))))),
|
|
2600
|
+
diagnosticReport.issued && (e.createElement("div", null,
|
|
2601
|
+
e.createElement(core$1.Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Issued"),
|
|
2602
|
+
e.createElement(core$1.Text, null, core.formatDateTime(diagnosticReport.issued)))),
|
|
2603
|
+
diagnosticReport.status && (e.createElement("div", null,
|
|
2604
|
+
e.createElement(core$1.Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Status"),
|
|
2605
|
+
e.createElement(core$1.Text, null, core.capitalize(diagnosticReport.status))))),
|
|
2606
|
+
diagnosticReport.result && (e.createElement(ObservationTable, { hideObservationNotes: props.hideObservationNotes, value: diagnosticReport.result })),
|
|
2607
|
+
specimenNotes.length > 0 && e.createElement(NoteDisplay, { value: specimenNotes })));
|
|
2549
2608
|
}
|
|
2550
2609
|
function ObservationTable(props) {
|
|
2551
2610
|
const { classes } = useStyles$9();
|
|
2552
|
-
return (
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2611
|
+
return (e.createElement("table", { className: classes.table },
|
|
2612
|
+
e.createElement("thead", null,
|
|
2613
|
+
e.createElement("tr", null,
|
|
2614
|
+
e.createElement("th", null, "Test"),
|
|
2615
|
+
e.createElement("th", null, "Value"),
|
|
2616
|
+
e.createElement("th", null, "Reference Range"),
|
|
2617
|
+
e.createElement("th", null, "Interpretation"),
|
|
2618
|
+
e.createElement("th", null, "Category"),
|
|
2619
|
+
e.createElement("th", null, "Status"))),
|
|
2620
|
+
e.createElement("tbody", null, props.value?.map((observation, index) => (e.createElement(ObservationRow, { key: `obs-${index}-${observation.id}`, hideObservationNotes: props.hideObservationNotes, value: observation }))))));
|
|
2562
2621
|
}
|
|
2563
2622
|
function ObservationRow(props) {
|
|
2564
2623
|
const { classes, cx } = useStyles$9();
|
|
@@ -2566,23 +2625,28 @@
|
|
|
2566
2625
|
if (!observation) {
|
|
2567
2626
|
return null;
|
|
2568
2627
|
}
|
|
2628
|
+
const displayNotes = !props.hideObservationNotes && observation?.note;
|
|
2569
2629
|
const critical = isCritical(observation);
|
|
2570
|
-
return (
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2630
|
+
return (e.createElement(e.Fragment, null,
|
|
2631
|
+
e.createElement("tr", { className: cx({ [classes.criticalRow]: critical }) },
|
|
2632
|
+
e.createElement("td", { rowSpan: displayNotes ? 2 : 1 },
|
|
2633
|
+
e.createElement(MedplumLink, { to: observation },
|
|
2634
|
+
e.createElement(CodeableConceptDisplay, { value: observation.code }))),
|
|
2635
|
+
e.createElement("td", null,
|
|
2636
|
+
e.createElement(ObservationValueDisplay, { value: observation })),
|
|
2637
|
+
e.createElement("td", null,
|
|
2638
|
+
e.createElement(ReferenceRangeDisplay, { value: observation.referenceRange })),
|
|
2639
|
+
e.createElement("td", null, observation.interpretation && observation.interpretation.length > 0 && (e.createElement(CodeableConceptDisplay, { value: observation.interpretation[0] }))),
|
|
2640
|
+
e.createElement("td", null, observation.category && observation.category.length > 0 && (e.createElement("ul", null, observation.category.map((concept, index) => (e.createElement("li", { key: `category-${index}` },
|
|
2641
|
+
e.createElement(CodeableConceptDisplay, { value: concept }))))))),
|
|
2642
|
+
e.createElement("td", null, observation.status && e.createElement(StatusBadge, { status: observation.status }))),
|
|
2643
|
+
displayNotes && (e.createElement("tr", null,
|
|
2644
|
+
e.createElement("td", { colSpan: 5 },
|
|
2645
|
+
e.createElement(NoteDisplay, { value: observation.note }))))));
|
|
2582
2646
|
}
|
|
2583
2647
|
function ObservationValueDisplay(props) {
|
|
2584
2648
|
const obs = props.value;
|
|
2585
|
-
return
|
|
2649
|
+
return e.createElement(e.Fragment, null, core.formatObservationValue(obs));
|
|
2586
2650
|
}
|
|
2587
2651
|
function ReferenceRangeDisplay(props) {
|
|
2588
2652
|
const range = props.value && props.value.length > 0 && props.value[0];
|
|
@@ -2590,9 +2654,9 @@
|
|
|
2590
2654
|
return null;
|
|
2591
2655
|
}
|
|
2592
2656
|
if (range.text) {
|
|
2593
|
-
return
|
|
2657
|
+
return e.createElement(e.Fragment, null, range.text);
|
|
2594
2658
|
}
|
|
2595
|
-
return
|
|
2659
|
+
return e.createElement(RangeDisplay, { value: range });
|
|
2596
2660
|
}
|
|
2597
2661
|
/**
|
|
2598
2662
|
* Returns true if the observation is critical.
|
|
@@ -2628,8 +2692,8 @@
|
|
|
2628
2692
|
function ResourceDiffTable(props) {
|
|
2629
2693
|
const { classes } = useStyles$8();
|
|
2630
2694
|
const medplum = useMedplum();
|
|
2631
|
-
const [schema, setSchema] =
|
|
2632
|
-
|
|
2695
|
+
const [schema, setSchema] = e.useState();
|
|
2696
|
+
e.useEffect(() => {
|
|
2633
2697
|
medplum.requestSchema(props.original.resourceType).then(setSchema).catch(console.log);
|
|
2634
2698
|
}, [medplum, props.original.resourceType]);
|
|
2635
2699
|
if (!schema) {
|
|
@@ -2639,17 +2703,17 @@
|
|
|
2639
2703
|
if (!typeSchema) {
|
|
2640
2704
|
return null;
|
|
2641
2705
|
}
|
|
2642
|
-
return (
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2706
|
+
return (e.createElement("table", { className: classes.root },
|
|
2707
|
+
e.createElement("colgroup", null,
|
|
2708
|
+
e.createElement("col", { style: { width: '30%' } }),
|
|
2709
|
+
e.createElement("col", { style: { width: '35%' } }),
|
|
2710
|
+
e.createElement("col", { style: { width: '35%' } })),
|
|
2711
|
+
e.createElement("thead", null,
|
|
2712
|
+
e.createElement("tr", null,
|
|
2713
|
+
e.createElement("th", null, "Property"),
|
|
2714
|
+
e.createElement("th", null, "Before"),
|
|
2715
|
+
e.createElement("th", null, "After"))),
|
|
2716
|
+
e.createElement("tbody", null, Object.entries(typeSchema.properties).map((entry) => {
|
|
2653
2717
|
const key = entry[0];
|
|
2654
2718
|
if (key === 'id' || key === 'meta') {
|
|
2655
2719
|
return null;
|
|
@@ -2663,12 +2727,12 @@
|
|
|
2663
2727
|
if (core.stringify(originalPropertyValue) === core.stringify(revisedPropertyValue)) {
|
|
2664
2728
|
return null;
|
|
2665
2729
|
}
|
|
2666
|
-
return (
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2730
|
+
return (e.createElement("tr", { key: key },
|
|
2731
|
+
e.createElement("td", null, core.getPropertyDisplayName(key)),
|
|
2732
|
+
e.createElement("td", { className: classes.removed },
|
|
2733
|
+
e.createElement(ResourcePropertyDisplay, { property: property, propertyType: originalPropertyType, value: originalPropertyValue, ignoreMissingValues: true })),
|
|
2734
|
+
e.createElement("td", { className: classes.added },
|
|
2735
|
+
e.createElement(ResourcePropertyDisplay, { property: property, propertyType: revisedPropertyType, value: revisedPropertyValue, ignoreMissingValues: true }))));
|
|
2672
2736
|
}))));
|
|
2673
2737
|
}
|
|
2674
2738
|
function isEmpty(value) {
|
|
@@ -2680,8 +2744,8 @@
|
|
|
2680
2744
|
function ResourceTable(props) {
|
|
2681
2745
|
const medplum = useMedplum();
|
|
2682
2746
|
const value = useResource(props.value);
|
|
2683
|
-
const [schema, setSchema] =
|
|
2684
|
-
|
|
2747
|
+
const [schema, setSchema] = e.useState();
|
|
2748
|
+
e.useEffect(() => {
|
|
2685
2749
|
if (value) {
|
|
2686
2750
|
medplum.requestSchema(value.resourceType).then(setSchema).catch(console.log);
|
|
2687
2751
|
}
|
|
@@ -2689,14 +2753,14 @@
|
|
|
2689
2753
|
if (!schema || !value) {
|
|
2690
2754
|
return null;
|
|
2691
2755
|
}
|
|
2692
|
-
return (
|
|
2756
|
+
return (e.createElement(BackboneElementDisplay, { value: { type: value.resourceType, value }, ignoreMissingValues: props.ignoreMissingValues }));
|
|
2693
2757
|
}
|
|
2694
2758
|
|
|
2695
2759
|
/**
|
|
2696
2760
|
* ErrorBoundary is a React component that handles errors in its child components.
|
|
2697
2761
|
* See: https://reactjs.org/docs/error-boundaries.html
|
|
2698
2762
|
*/
|
|
2699
|
-
class ErrorBoundary extends
|
|
2763
|
+
class ErrorBoundary extends e.Component {
|
|
2700
2764
|
constructor(props) {
|
|
2701
2765
|
super(props);
|
|
2702
2766
|
this.state = {};
|
|
@@ -2709,36 +2773,36 @@
|
|
|
2709
2773
|
}
|
|
2710
2774
|
render() {
|
|
2711
2775
|
if (this.state.error) {
|
|
2712
|
-
return (
|
|
2776
|
+
return (e.createElement(core$1.Alert, { icon: e.createElement(We, { size: 16 }), title: "Something went wrong", color: "red" }, core.normalizeErrorString(this.state.error)));
|
|
2713
2777
|
}
|
|
2714
2778
|
return this.props.children;
|
|
2715
2779
|
}
|
|
2716
2780
|
}
|
|
2717
2781
|
|
|
2718
2782
|
function Timeline(props) {
|
|
2719
|
-
return
|
|
2783
|
+
return e.createElement(Container, null, props.children);
|
|
2720
2784
|
}
|
|
2721
2785
|
function TimelineItem(props) {
|
|
2722
2786
|
const { resource, profile, padding, popupMenuItems, ...others } = props;
|
|
2723
2787
|
const author = profile ?? resource.meta?.author;
|
|
2724
|
-
return (
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
popupMenuItems && (
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2788
|
+
return (e.createElement(Panel, { "data-testid": "timeline-item", fill: true, ...others },
|
|
2789
|
+
e.createElement(core$1.Group, { position: "apart", spacing: 8, mx: "xs", my: "sm" },
|
|
2790
|
+
e.createElement(ResourceAvatar, { value: author, link: true, size: "md" }),
|
|
2791
|
+
e.createElement("div", { style: { flex: 1 } },
|
|
2792
|
+
e.createElement(core$1.Text, { size: "sm" },
|
|
2793
|
+
e.createElement(ResourceName, { color: "dark", weight: 500, value: author, link: true })),
|
|
2794
|
+
e.createElement(core$1.Text, { size: "xs" },
|
|
2795
|
+
e.createElement(MedplumLink, { color: "dimmed", to: props.resource }, core.formatDateTime(props.resource.meta?.lastUpdated)),
|
|
2796
|
+
e.createElement(core$1.Text, { component: "span", color: "dimmed", mx: 8 }, "\u00B7"),
|
|
2797
|
+
e.createElement(MedplumLink, { color: "dimmed", to: props.resource }, props.resource.resourceType))),
|
|
2798
|
+
popupMenuItems && (e.createElement(core$1.Menu, { position: "bottom-end", shadow: "md", width: 200 },
|
|
2799
|
+
e.createElement(core$1.Menu.Target, null,
|
|
2800
|
+
e.createElement(core$1.ActionIcon, { radius: "xl", "aria-label": `Actions for ${core.getReferenceString(props.resource)}` },
|
|
2801
|
+
e.createElement(BX, null))),
|
|
2738
2802
|
popupMenuItems))),
|
|
2739
|
-
|
|
2740
|
-
padding &&
|
|
2741
|
-
!padding &&
|
|
2803
|
+
e.createElement(ErrorBoundary, null,
|
|
2804
|
+
padding && e.createElement("div", { style: { padding: '0 16px 16px 16px' } }, props.children),
|
|
2805
|
+
!padding && e.createElement(e.Fragment, null, props.children))));
|
|
2742
2806
|
}
|
|
2743
2807
|
|
|
2744
2808
|
/**
|
|
@@ -2792,17 +2856,17 @@
|
|
|
2792
2856
|
},
|
|
2793
2857
|
}));
|
|
2794
2858
|
function ResourceTimeline(props) {
|
|
2795
|
-
const navigate = reactRouterDom.useNavigate();
|
|
2796
2859
|
const medplum = useMedplum();
|
|
2860
|
+
const navigate = useMedplumNavigate();
|
|
2797
2861
|
const sender = medplum.getProfile();
|
|
2798
|
-
const inputRef =
|
|
2862
|
+
const inputRef = e.useRef(null);
|
|
2799
2863
|
const resource = useResource(props.value);
|
|
2800
|
-
const [history, setHistory] =
|
|
2801
|
-
const [items, setItems] =
|
|
2864
|
+
const [history, setHistory] = e.useState();
|
|
2865
|
+
const [items, setItems] = e.useState([]);
|
|
2802
2866
|
const loadTimelineResources = props.loadTimelineResources;
|
|
2803
|
-
const itemsRef =
|
|
2867
|
+
const itemsRef = e.useRef(items);
|
|
2804
2868
|
itemsRef.current = items;
|
|
2805
|
-
const loadTimeline =
|
|
2869
|
+
const loadTimeline = e.useCallback(() => {
|
|
2806
2870
|
if (!resource) {
|
|
2807
2871
|
setItems([]);
|
|
2808
2872
|
setHistory({});
|
|
@@ -2810,7 +2874,7 @@
|
|
|
2810
2874
|
}
|
|
2811
2875
|
loadTimelineResources(medplum, resource).then(handleBatchResponse).catch(console.log);
|
|
2812
2876
|
}, [medplum, resource, loadTimelineResources]);
|
|
2813
|
-
|
|
2877
|
+
e.useEffect(() => {
|
|
2814
2878
|
loadTimeline();
|
|
2815
2879
|
}, [loadTimeline]);
|
|
2816
2880
|
/**
|
|
@@ -2880,7 +2944,7 @@
|
|
|
2880
2944
|
color: 'teal',
|
|
2881
2945
|
title: 'Upload complete',
|
|
2882
2946
|
message: '',
|
|
2883
|
-
icon:
|
|
2947
|
+
icon: e.createElement(DW, { size: 16 }),
|
|
2884
2948
|
autoClose: 2000,
|
|
2885
2949
|
}))
|
|
2886
2950
|
.catch((reason) => notifications.updateNotification({
|
|
@@ -2888,7 +2952,7 @@
|
|
|
2888
2952
|
color: 'red',
|
|
2889
2953
|
title: 'Upload error',
|
|
2890
2954
|
message: core.normalizeErrorString(reason),
|
|
2891
|
-
icon:
|
|
2955
|
+
icon: e.createElement(B$, { size: 16 }),
|
|
2892
2956
|
autoClose: 2000,
|
|
2893
2957
|
}));
|
|
2894
2958
|
}
|
|
@@ -2934,12 +2998,12 @@
|
|
|
2934
2998
|
});
|
|
2935
2999
|
}
|
|
2936
3000
|
if (!resource) {
|
|
2937
|
-
return (
|
|
2938
|
-
|
|
3001
|
+
return (e.createElement(core$1.Center, { style: { width: '100%', height: '100%' } },
|
|
3002
|
+
e.createElement(core$1.Loader, null)));
|
|
2939
3003
|
}
|
|
2940
|
-
return (
|
|
2941
|
-
props.createCommunication && (
|
|
2942
|
-
|
|
3004
|
+
return (e.createElement(Timeline, null,
|
|
3005
|
+
props.createCommunication && (e.createElement(Panel, null,
|
|
3006
|
+
e.createElement(Form, { testid: "timeline-form", onSubmit: (formData) => {
|
|
2943
3007
|
createComment(formData.text);
|
|
2944
3008
|
const input = inputRef.current;
|
|
2945
3009
|
if (input) {
|
|
@@ -2947,55 +3011,55 @@
|
|
|
2947
3011
|
input.focus();
|
|
2948
3012
|
}
|
|
2949
3013
|
} },
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
3014
|
+
e.createElement(core$1.Group, { spacing: "xs", noWrap: true, style: { width: '100%' } },
|
|
3015
|
+
e.createElement(ResourceAvatar, { value: sender }),
|
|
3016
|
+
e.createElement(core$1.TextInput, { name: "text", ref: inputRef, placeholder: "Add comment", style: { width: '100%', maxWidth: 300 } }),
|
|
3017
|
+
e.createElement(core$1.ActionIcon, { type: "submit", radius: "xl", color: "blue", variant: "filled" },
|
|
3018
|
+
e.createElement(Lde, { size: 16 })),
|
|
3019
|
+
e.createElement(AttachmentButton, { onUpload: createMedia, onUploadStart: onUploadStart, onUploadProgress: onUploadProgress }, (props) => (e.createElement(core$1.ActionIcon, { ...props, radius: "xl", color: "blue", variant: "filled" },
|
|
3020
|
+
e.createElement(XA, { size: 16 })))))))),
|
|
2957
3021
|
items.map((item) => {
|
|
2958
3022
|
const key = `${item.resourceType}/${item.id}/${item.meta?.versionId}`;
|
|
2959
3023
|
if (item.resourceType === resource.resourceType && item.id === resource.id) {
|
|
2960
|
-
return (
|
|
3024
|
+
return (e.createElement(HistoryTimelineItem, { key: key, history: history, resource: item, onDetails: onVersionDetails }));
|
|
2961
3025
|
}
|
|
2962
3026
|
switch (item.resourceType) {
|
|
2963
3027
|
case 'AuditEvent':
|
|
2964
|
-
return
|
|
3028
|
+
return e.createElement(AuditEventTimelineItem, { key: key, resource: item, onDetails: onDetails });
|
|
2965
3029
|
case 'Communication':
|
|
2966
|
-
return (
|
|
3030
|
+
return (e.createElement(CommunicationTimelineItem, { key: key, resource: item, onPin: item.priority !== 'stat' ? onPin : undefined, onUnpin: item.priority === 'stat' ? onUnpin : undefined, onDetails: onDetails, onEdit: onEdit, onDelete: onDelete }));
|
|
2967
3031
|
case 'DiagnosticReport':
|
|
2968
|
-
return (
|
|
3032
|
+
return (e.createElement(DiagnosticReportTimelineItem, { key: key, resource: item, onDetails: onDetails, onEdit: onEdit, onDelete: onDelete }));
|
|
2969
3033
|
case 'Media':
|
|
2970
|
-
return (
|
|
3034
|
+
return (e.createElement(MediaTimelineItem, { key: key, resource: item, onDetails: onDetails, onEdit: onEdit, onDelete: onDelete }));
|
|
2971
3035
|
default:
|
|
2972
|
-
return (
|
|
2973
|
-
|
|
3036
|
+
return (e.createElement(TimelineItem, { key: key, resource: item, padding: true },
|
|
3037
|
+
e.createElement(ResourceTable, { value: item, ignoreMissingValues: true })));
|
|
2974
3038
|
}
|
|
2975
3039
|
})));
|
|
2976
3040
|
}
|
|
2977
3041
|
function TimelineItemPopupMenu(props) {
|
|
2978
|
-
return (
|
|
2979
|
-
|
|
2980
|
-
props.onPin && (
|
|
2981
|
-
props.onUnpin && (
|
|
2982
|
-
props.onDetails && (
|
|
2983
|
-
props.onEdit && (
|
|
2984
|
-
props.onDelete && (
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
3042
|
+
return (e.createElement(core$1.Menu.Dropdown, null,
|
|
3043
|
+
e.createElement(core$1.Menu.Label, null, "Resource"),
|
|
3044
|
+
props.onPin && (e.createElement(core$1.Menu.Item, { icon: e.createElement(Ege, { size: 14 }), onClick: () => props.onPin(props.resource), "aria-label": `Pin ${core.getReferenceString(props.resource)}` }, "Pin")),
|
|
3045
|
+
props.onUnpin && (e.createElement(core$1.Menu.Item, { icon: e.createElement(xge, { size: 14 }), onClick: () => props.onUnpin(props.resource), "aria-label": `Unpin ${core.getReferenceString(props.resource)}` }, "Unpin")),
|
|
3046
|
+
props.onDetails && (e.createElement(core$1.Menu.Item, { icon: e.createElement(qae, { size: 14 }), onClick: () => props.onDetails(props.resource), "aria-label": `Details ${core.getReferenceString(props.resource)}` }, "Details")),
|
|
3047
|
+
props.onEdit && (e.createElement(core$1.Menu.Item, { icon: e.createElement(CY, { size: 14 }), onClick: () => props.onEdit(props.resource), "aria-label": `Edit ${core.getReferenceString(props.resource)}` }, "Edit")),
|
|
3048
|
+
props.onDelete && (e.createElement(e.Fragment, null,
|
|
3049
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
3050
|
+
e.createElement(core$1.Menu.Label, null, "Danger zone"),
|
|
3051
|
+
e.createElement(core$1.Menu.Item, { color: "red", icon: e.createElement(zKe, { size: 14 }), onClick: () => props.onDelete(props.resource), "aria-label": `Delete ${core.getReferenceString(props.resource)}` }, "Delete")))));
|
|
2988
3052
|
}
|
|
2989
3053
|
function HistoryTimelineItem(props) {
|
|
2990
3054
|
const previous = getPrevious(props.history, props.resource);
|
|
2991
3055
|
if (previous) {
|
|
2992
|
-
return (
|
|
2993
|
-
|
|
3056
|
+
return (e.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: e.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
3057
|
+
e.createElement(ResourceDiffTable, { original: previous, revised: props.resource })));
|
|
2994
3058
|
}
|
|
2995
3059
|
else {
|
|
2996
|
-
return (
|
|
2997
|
-
|
|
2998
|
-
|
|
3060
|
+
return (e.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: e.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
3061
|
+
e.createElement("h3", null, "Created"),
|
|
3062
|
+
e.createElement(ResourceTable, { value: props.resource, ignoreMissingValues: true })));
|
|
2999
3063
|
}
|
|
3000
3064
|
}
|
|
3001
3065
|
function getPrevious(history, version) {
|
|
@@ -3010,8 +3074,8 @@
|
|
|
3010
3074
|
const { classes } = useStyles$7();
|
|
3011
3075
|
const routine = !props.resource.priority || props.resource.priority === 'routine';
|
|
3012
3076
|
const className = routine ? undefined : classes.pinnedComment;
|
|
3013
|
-
return (
|
|
3014
|
-
|
|
3077
|
+
return (e.createElement(TimelineItem, { resource: props.resource, profile: props.resource.sender, padding: true, className: className, popupMenuItems: e.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
3078
|
+
e.createElement("p", null, props.resource.payload?.[0]?.contentString)));
|
|
3015
3079
|
}
|
|
3016
3080
|
function MediaTimelineItem(props) {
|
|
3017
3081
|
const contentType = props.resource.content?.contentType;
|
|
@@ -3019,17 +3083,17 @@
|
|
|
3019
3083
|
!contentType.startsWith('image/') &&
|
|
3020
3084
|
!contentType.startsWith('video/') &&
|
|
3021
3085
|
contentType !== 'application/pdf';
|
|
3022
|
-
return (
|
|
3023
|
-
|
|
3086
|
+
return (e.createElement(TimelineItem, { resource: props.resource, padding: !!padding, popupMenuItems: e.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
3087
|
+
e.createElement(AttachmentDisplay, { value: props.resource.content })));
|
|
3024
3088
|
}
|
|
3025
3089
|
function AuditEventTimelineItem(props) {
|
|
3026
|
-
return (
|
|
3027
|
-
|
|
3028
|
-
|
|
3090
|
+
return (e.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: e.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
3091
|
+
e.createElement(core$1.ScrollArea, null,
|
|
3092
|
+
e.createElement("pre", null, props.resource.outcomeDesc))));
|
|
3029
3093
|
}
|
|
3030
3094
|
function DiagnosticReportTimelineItem(props) {
|
|
3031
|
-
return (
|
|
3032
|
-
|
|
3095
|
+
return (e.createElement(TimelineItem, { resource: props.resource, padding: true, popupMenuItems: e.createElement(TimelineItemPopupMenu, { ...props }) },
|
|
3096
|
+
e.createElement(DiagnosticReportDisplay, { value: props.resource })));
|
|
3033
3097
|
}
|
|
3034
3098
|
function getProgressMessage(e) {
|
|
3035
3099
|
if (e.lengthComputable) {
|
|
@@ -3047,7 +3111,7 @@
|
|
|
3047
3111
|
}
|
|
3048
3112
|
|
|
3049
3113
|
function DefaultResourceTimeline(props) {
|
|
3050
|
-
return (
|
|
3114
|
+
return (e.createElement(ResourceTimeline, { value: props.resource, loadTimelineResources: async (medplum, resource) => {
|
|
3051
3115
|
return Promise.all([
|
|
3052
3116
|
medplum.readHistory(resource.resourceType, resource.id),
|
|
3053
3117
|
medplum.search('AuditEvent', '_sort=-_lastUpdated&entity=' + core.getReferenceString(resource)),
|
|
@@ -3056,7 +3120,7 @@
|
|
|
3056
3120
|
}
|
|
3057
3121
|
|
|
3058
3122
|
function EncounterTimeline(props) {
|
|
3059
|
-
return (
|
|
3123
|
+
return (e.createElement(ResourceTimeline, { value: props.encounter, loadTimelineResources: async (medplum, resource) => {
|
|
3060
3124
|
return Promise.all([
|
|
3061
3125
|
medplum.readHistory('Encounter', resource.id),
|
|
3062
3126
|
medplum.search('Communication', 'encounter=' + core.getReferenceString(resource)),
|
|
@@ -3095,7 +3159,7 @@
|
|
|
3095
3159
|
Received ${value.length} elements \
|
|
3096
3160
|
[${JSON.stringify(value, null, 2)}]`);
|
|
3097
3161
|
}
|
|
3098
|
-
return
|
|
3162
|
+
return e.createElement(ResourcePropertyDisplay, { value: value[0] || '', propertyType: props.propertyType });
|
|
3099
3163
|
}
|
|
3100
3164
|
|
|
3101
3165
|
const searchParamToOperators = {
|
|
@@ -3544,7 +3608,7 @@
|
|
|
3544
3608
|
if (!value) {
|
|
3545
3609
|
return null;
|
|
3546
3610
|
}
|
|
3547
|
-
return (
|
|
3611
|
+
return (e.createElement(ResourcePropertyDisplay, { property: elementDefinition, propertyType: propertyType, value: value, maxWidth: 200, ignoreMissingValues: true, link: false }));
|
|
3548
3612
|
}
|
|
3549
3613
|
/**
|
|
3550
3614
|
* Returns a fragment to be displayed in the search table for a search parameter.
|
|
@@ -3559,18 +3623,18 @@
|
|
|
3559
3623
|
return null;
|
|
3560
3624
|
}
|
|
3561
3625
|
if (elementDefinition) {
|
|
3562
|
-
return (
|
|
3626
|
+
return (e.createElement(ResourcePropertyDisplay, { propertyType: value[0].type, value: value[0].value, maxWidth: 200, ignoreMissingValues: true, link: false }));
|
|
3563
3627
|
}
|
|
3564
|
-
return (
|
|
3628
|
+
return (e.createElement(e.Fragment, null, value.map((v, index) => (e.createElement("span", { key: `${index}-${value.length}` }, typeof v === 'object' ? JSON.stringify(v) : v)))));
|
|
3565
3629
|
}
|
|
3566
3630
|
|
|
3567
3631
|
function SearchFieldEditor(props) {
|
|
3568
|
-
const [state, setState] =
|
|
3632
|
+
const [state, setState] = e.useState({
|
|
3569
3633
|
search: JSON.parse(core.stringify(props.search)),
|
|
3570
3634
|
});
|
|
3571
|
-
const availableRef =
|
|
3572
|
-
const selectedRef =
|
|
3573
|
-
|
|
3635
|
+
const availableRef = e.useRef(null);
|
|
3636
|
+
const selectedRef = e.useRef(null);
|
|
3637
|
+
e.useEffect(() => {
|
|
3574
3638
|
setState({ search: props.search });
|
|
3575
3639
|
}, [props.search]);
|
|
3576
3640
|
/**
|
|
@@ -3702,30 +3766,30 @@
|
|
|
3702
3766
|
const available = getFieldsList(typeDef)
|
|
3703
3767
|
.filter((field) => !selected?.includes(field))
|
|
3704
3768
|
.sort();
|
|
3705
|
-
return (
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3769
|
+
return (e.createElement(core$1.Modal, { title: "Fields", closeButtonLabel: "Close", opened: props.visible, onClose: props.onCancel },
|
|
3770
|
+
e.createElement("div", null,
|
|
3771
|
+
e.createElement("table", { style: { margin: 'auto' } },
|
|
3772
|
+
e.createElement("thead", null,
|
|
3773
|
+
e.createElement("tr", null,
|
|
3774
|
+
e.createElement("th", { colSpan: 2, align: "center" }, "Available"),
|
|
3775
|
+
e.createElement("th", { colSpan: 2, align: "center" }, "Selected"))),
|
|
3776
|
+
e.createElement("tbody", null,
|
|
3777
|
+
e.createElement("tr", null,
|
|
3778
|
+
e.createElement("td", { colSpan: 2, align: "center" },
|
|
3779
|
+
e.createElement("select", { ref: availableRef, size: 15, tabIndex: 1, style: { width: '200px' }, onKeyDown: (e) => handleAvailableKeyDown(e), onDoubleClick: () => handleAvailableDoubleClick(), "data-testid": "available" }, available.map((key) => (e.createElement("option", { key: key, value: key }, buildFieldNameString(key)))))),
|
|
3780
|
+
e.createElement("td", { colSpan: 2, align: "center" },
|
|
3781
|
+
e.createElement("select", { ref: selectedRef, size: 15, tabIndex: 4, style: { width: '200px' }, onKeyDown: (e) => handleSelectedKeyDown(e), onDoubleClick: () => handleSelectedDoubleClick(), "data-testid": "selected" }, selected.map((key) => (e.createElement("option", { key: key, value: key }, buildFieldNameString(key)))))))),
|
|
3782
|
+
e.createElement("tfoot", null,
|
|
3783
|
+
e.createElement("tr", null,
|
|
3784
|
+
e.createElement("td", { align: "center" },
|
|
3785
|
+
e.createElement(core$1.Button, { compact: true, variant: "outline", onClick: onAddField }, "Add")),
|
|
3786
|
+
e.createElement("td", { align: "center" },
|
|
3787
|
+
e.createElement(core$1.Button, { compact: true, variant: "outline", onClick: onRemoveField }, "Remove")),
|
|
3788
|
+
e.createElement("td", { align: "center" },
|
|
3789
|
+
e.createElement(core$1.Button, { compact: true, variant: "outline", onClick: onMoveUp }, "Up")),
|
|
3790
|
+
e.createElement("td", { align: "center" },
|
|
3791
|
+
e.createElement(core$1.Button, { compact: true, variant: "outline", onClick: onMoveDown }, "Down")))))),
|
|
3792
|
+
e.createElement(core$1.Button, { onClick: () => props.onOk(state.search) }, "OK")));
|
|
3729
3793
|
}
|
|
3730
3794
|
/**
|
|
3731
3795
|
* Returns a list of fields/columns available for a type.
|
|
@@ -3761,14 +3825,14 @@
|
|
|
3761
3825
|
const searchParam = core.globalSchema.types[resourceType]?.searchParams?.[filter.code];
|
|
3762
3826
|
if (searchParam) {
|
|
3763
3827
|
if (searchParam.type === 'reference') {
|
|
3764
|
-
return
|
|
3828
|
+
return e.createElement(ResourceName, { value: { reference: filter.value } });
|
|
3765
3829
|
}
|
|
3766
3830
|
const searchParamDetails = core.getSearchParameterDetails(resourceType, searchParam);
|
|
3767
3831
|
if (filter.code === '_lastUpdated' || searchParamDetails.type === core.SearchParameterType.DATETIME) {
|
|
3768
|
-
return
|
|
3832
|
+
return e.createElement(e.Fragment, null, core.formatDateTime(filter.value));
|
|
3769
3833
|
}
|
|
3770
3834
|
}
|
|
3771
|
-
return
|
|
3835
|
+
return e.createElement(e.Fragment, null, filter.value);
|
|
3772
3836
|
}
|
|
3773
3837
|
|
|
3774
3838
|
function SearchFilterValueInput(props) {
|
|
@@ -3776,7 +3840,7 @@
|
|
|
3776
3840
|
const name = 'filter-value';
|
|
3777
3841
|
switch (details.type) {
|
|
3778
3842
|
case core.SearchParameterType.REFERENCE:
|
|
3779
|
-
return (
|
|
3843
|
+
return (e.createElement(ReferenceInput, { name: name, defaultValue: { reference: props.defaultValue }, targetTypes: props.searchParam?.target, onChange: (newReference) => {
|
|
3780
3844
|
if (newReference) {
|
|
3781
3845
|
props.onChange(newReference.reference);
|
|
3782
3846
|
}
|
|
@@ -3785,15 +3849,15 @@
|
|
|
3785
3849
|
}
|
|
3786
3850
|
} }));
|
|
3787
3851
|
case core.SearchParameterType.BOOLEAN:
|
|
3788
|
-
return (
|
|
3852
|
+
return (e.createElement(core$1.Checkbox, { name: name, "data-testid": name, defaultChecked: props.defaultValue === 'true', onChange: (e) => props.onChange(e.currentTarget.checked.toString()) }));
|
|
3789
3853
|
case core.SearchParameterType.DATE:
|
|
3790
|
-
return (
|
|
3854
|
+
return (e.createElement(core$1.TextInput, { type: "date", name: name, "data-testid": name, defaultValue: props.defaultValue, onChange: (e) => props.onChange(e.currentTarget.value) }));
|
|
3791
3855
|
case core.SearchParameterType.DATETIME:
|
|
3792
|
-
return
|
|
3856
|
+
return e.createElement(DateTimeInput, { name: name, defaultValue: props.defaultValue, onChange: props.onChange });
|
|
3793
3857
|
case core.SearchParameterType.NUMBER:
|
|
3794
|
-
return (
|
|
3858
|
+
return (e.createElement(core$1.TextInput, { type: "number", name: name, "data-testid": name, defaultValue: props.defaultValue, onChange: (e) => props.onChange(e.currentTarget.value) }));
|
|
3795
3859
|
case core.SearchParameterType.QUANTITY:
|
|
3796
|
-
return (
|
|
3860
|
+
return (e.createElement(QuantityInput, { name: name, defaultValue: tryParseQuantity(props.defaultValue), onChange: (newQuantity) => {
|
|
3797
3861
|
if (newQuantity) {
|
|
3798
3862
|
props.onChange(`${newQuantity.value}`);
|
|
3799
3863
|
}
|
|
@@ -3802,7 +3866,7 @@
|
|
|
3802
3866
|
}
|
|
3803
3867
|
} }));
|
|
3804
3868
|
default:
|
|
3805
|
-
return (
|
|
3869
|
+
return (e.createElement(core$1.TextInput, { name: name, "data-testid": name, defaultValue: props.defaultValue, autoFocus: props.autoFocus, onChange: (e) => props.onChange(e.currentTarget.value), placeholder: "Search value" }));
|
|
3806
3870
|
}
|
|
3807
3871
|
}
|
|
3808
3872
|
function tryParseQuantity(value) {
|
|
@@ -3820,11 +3884,11 @@
|
|
|
3820
3884
|
}
|
|
3821
3885
|
|
|
3822
3886
|
function SearchFilterEditor(props) {
|
|
3823
|
-
const [search, setSearch] =
|
|
3824
|
-
const [editingIndex, setEditingIndex] =
|
|
3825
|
-
const searchRef =
|
|
3887
|
+
const [search, setSearch] = e.useState(JSON.parse(core.stringify(props.search)));
|
|
3888
|
+
const [editingIndex, setEditingIndex] = e.useState(-1);
|
|
3889
|
+
const searchRef = e.useRef(search);
|
|
3826
3890
|
searchRef.current = search;
|
|
3827
|
-
|
|
3891
|
+
e.useEffect(() => {
|
|
3828
3892
|
setSearch(JSON.parse(core.stringify(props.search)));
|
|
3829
3893
|
}, [props.search]);
|
|
3830
3894
|
function onAddFilter(filter) {
|
|
@@ -3836,24 +3900,24 @@
|
|
|
3836
3900
|
const resourceType = props.search.resourceType;
|
|
3837
3901
|
const searchParams = core.globalSchema.types[resourceType].searchParams;
|
|
3838
3902
|
const filters = search.filters || [];
|
|
3839
|
-
return (
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3903
|
+
return (e.createElement(core$1.Modal, { title: "Filters", closeButtonLabel: "Close", size: 900, opened: props.visible, onClose: props.onCancel },
|
|
3904
|
+
e.createElement("div", null,
|
|
3905
|
+
e.createElement("table", null,
|
|
3906
|
+
e.createElement("colgroup", null,
|
|
3907
|
+
e.createElement("col", { style: { width: 200 } }),
|
|
3908
|
+
e.createElement("col", { style: { width: 200 } }),
|
|
3909
|
+
e.createElement("col", { style: { width: 380 } }),
|
|
3910
|
+
e.createElement("col", { style: { width: 120 } })),
|
|
3911
|
+
e.createElement("thead", null,
|
|
3912
|
+
e.createElement("tr", null,
|
|
3913
|
+
e.createElement("th", null, "Field"),
|
|
3914
|
+
e.createElement("th", null, "Operation"),
|
|
3915
|
+
e.createElement("th", null, "Value"),
|
|
3916
|
+
e.createElement("th", null, "Actions"))),
|
|
3917
|
+
e.createElement("tbody", null,
|
|
3854
3918
|
filters.map((filter, index) => {
|
|
3855
3919
|
if (index === editingIndex) {
|
|
3856
|
-
return (
|
|
3920
|
+
return (e.createElement(FilterRowInput, { key: `filter-${index}-${filters.length}-input`, resourceType: resourceType, searchParams: searchParams, defaultValue: filter, okText: "Save", onOk: (newFilter) => {
|
|
3857
3921
|
const newFilters = [...filters];
|
|
3858
3922
|
newFilters[index] = newFilter;
|
|
3859
3923
|
setSearch(setFilters(searchRef.current, newFilters));
|
|
@@ -3861,27 +3925,27 @@
|
|
|
3861
3925
|
}, onCancel: () => setEditingIndex(-1) }));
|
|
3862
3926
|
}
|
|
3863
3927
|
else {
|
|
3864
|
-
return (
|
|
3928
|
+
return (e.createElement(FilterRowDisplay, { key: `filter-${index}-${filters.length}-display`, resourceType: resourceType, searchParams: searchParams, filter: filter, onEdit: () => setEditingIndex(index), onDelete: () => setSearch(deleteFilter(searchRef.current, index)) }));
|
|
3865
3929
|
}
|
|
3866
3930
|
}),
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3931
|
+
e.createElement(FilterRowInput, { resourceType: resourceType, searchParams: searchParams, okText: "Add", onOk: onAddFilter })))),
|
|
3932
|
+
e.createElement(core$1.Group, { position: "right", mt: "xl" },
|
|
3933
|
+
e.createElement(core$1.Button, { onClick: () => props.onOk(searchRef.current) }, "OK"))));
|
|
3870
3934
|
}
|
|
3871
3935
|
function FilterRowDisplay(props) {
|
|
3872
3936
|
const { filter } = props;
|
|
3873
|
-
return (
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3937
|
+
return (e.createElement("tr", null,
|
|
3938
|
+
e.createElement("td", null, buildFieldNameString(filter.code)),
|
|
3939
|
+
e.createElement("td", null, getOpString(filter.operator)),
|
|
3940
|
+
e.createElement("td", null,
|
|
3941
|
+
e.createElement(SearchFilterValueDisplay, { resourceType: props.resourceType, filter: filter })),
|
|
3942
|
+
e.createElement("td", null,
|
|
3943
|
+
e.createElement(core$1.Button, { compact: true, variant: "outline", onClick: props.onEdit }, "Edit"),
|
|
3944
|
+
e.createElement(core$1.Button, { compact: true, variant: "outline", onClick: props.onDelete }, "Delete"))));
|
|
3881
3945
|
}
|
|
3882
3946
|
function FilterRowInput(props) {
|
|
3883
|
-
const [value, setValue] =
|
|
3884
|
-
const valueRef =
|
|
3947
|
+
const [value, setValue] = e.useState(props.defaultValue ?? {});
|
|
3948
|
+
const valueRef = e.useRef(value);
|
|
3885
3949
|
valueRef.current = value;
|
|
3886
3950
|
function setFilterCode(newCode) {
|
|
3887
3951
|
setValue({ ...valueRef.current, code: newCode });
|
|
@@ -3894,32 +3958,32 @@
|
|
|
3894
3958
|
}
|
|
3895
3959
|
const searchParam = props.searchParams[value.code];
|
|
3896
3960
|
const operators = searchParam && getSearchOperators(searchParam);
|
|
3897
|
-
return (
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
value.code && value.operator && value.value && (
|
|
3961
|
+
return (e.createElement("tr", null,
|
|
3962
|
+
e.createElement("td", null,
|
|
3963
|
+
e.createElement(core$1.NativeSelect, { "data-testid": "filter-field", defaultValue: valueRef.current.code, onChange: (e) => setFilterCode(e.currentTarget.value), data: Object.keys(props.searchParams).map((param) => ({ value: param, label: buildFieldNameString(param) })) })),
|
|
3964
|
+
e.createElement("td", null, operators && (e.createElement(core$1.NativeSelect, { "data-testid": "filter-operation", defaultValue: value.operator, onChange: (e) => setFilterOperator(e.currentTarget.value), data: ['', ...operators.map((op) => ({ value: op, label: getOpString(op) }))] }))),
|
|
3965
|
+
e.createElement("td", null, searchParam && value.operator && (e.createElement(SearchFilterValueInput, { resourceType: props.resourceType, searchParam: searchParam, defaultValue: value.value, onChange: setFilterValue }))),
|
|
3966
|
+
e.createElement("td", null,
|
|
3967
|
+
value.code && value.operator && value.value && (e.createElement(core$1.Button, { compact: true, variant: "outline", onClick: () => {
|
|
3904
3968
|
props.onOk(valueRef.current);
|
|
3905
3969
|
setValue({});
|
|
3906
3970
|
} }, props.okText)),
|
|
3907
|
-
props.onCancel && (
|
|
3971
|
+
props.onCancel && (e.createElement(core$1.Button, { compact: true, variant: "outline", onClick: props.onCancel }, "Cancel")))));
|
|
3908
3972
|
}
|
|
3909
3973
|
|
|
3910
3974
|
function SearchFilterValueDialog(props) {
|
|
3911
|
-
const [value, setValue] =
|
|
3975
|
+
const [value, setValue] = e.useState(props.defaultValue ?? '');
|
|
3912
3976
|
if (!props.visible || !props.searchParam || !props.filter) {
|
|
3913
3977
|
return null;
|
|
3914
3978
|
}
|
|
3915
3979
|
function onOk() {
|
|
3916
3980
|
props.onOk({ ...props.filter, value });
|
|
3917
3981
|
}
|
|
3918
|
-
return (
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3982
|
+
return (e.createElement(core$1.Modal, { title: props.title, size: "xl", opened: props.visible, onClose: props.onCancel },
|
|
3983
|
+
e.createElement("div", { style: { width: 500 } },
|
|
3984
|
+
e.createElement(Form, { onSubmit: onOk },
|
|
3985
|
+
e.createElement(SearchFilterValueInput, { resourceType: props.resourceType, searchParam: props.searchParam, defaultValue: value, autoFocus: true, onChange: setValue }))),
|
|
3986
|
+
e.createElement(core$1.Button, { onClick: onOk }, "OK")));
|
|
3923
3987
|
}
|
|
3924
3988
|
|
|
3925
3989
|
function SearchPopupMenu(props) {
|
|
@@ -3940,26 +4004,26 @@
|
|
|
3940
4004
|
}
|
|
3941
4005
|
// If there is only one search parameter, then show it directly
|
|
3942
4006
|
if (props.searchParams.length === 1) {
|
|
3943
|
-
return (
|
|
4007
|
+
return (e.createElement(SearchParameterSubMenu, { search: props.search, searchParam: props.searchParams[0], onSort: onSort, onPrompt: onPrompt, onChange: onChange, onClear: onClear }));
|
|
3944
4008
|
}
|
|
3945
4009
|
// Otherwise, show a menu, with each search parameter as a sub menu
|
|
3946
|
-
return (
|
|
4010
|
+
return (e.createElement(core$1.Menu.Dropdown, null, props.searchParams.map((searchParam) => (e.createElement(core$1.Menu.Item, { key: searchParam.code }, buildFieldNameString(searchParam.code))))));
|
|
3947
4011
|
}
|
|
3948
4012
|
function SearchParameterSubMenu(props) {
|
|
3949
4013
|
switch (props.searchParam.type) {
|
|
3950
4014
|
case 'date':
|
|
3951
|
-
return
|
|
4015
|
+
return e.createElement(DateFilterSubMenu, { ...props });
|
|
3952
4016
|
case 'number':
|
|
3953
4017
|
case 'quantity':
|
|
3954
|
-
return
|
|
4018
|
+
return e.createElement(NumericFilterSubMenu, { ...props });
|
|
3955
4019
|
case 'reference':
|
|
3956
|
-
return
|
|
4020
|
+
return e.createElement(ReferenceFilterSubMenu, { ...props });
|
|
3957
4021
|
case 'string':
|
|
3958
4022
|
case 'token':
|
|
3959
4023
|
case 'uri':
|
|
3960
|
-
return
|
|
4024
|
+
return e.createElement(TextFilterSubMenu, { ...props });
|
|
3961
4025
|
default:
|
|
3962
|
-
return
|
|
4026
|
+
return e.createElement(e.Fragment, null,
|
|
3963
4027
|
"Unknown search param type: ",
|
|
3964
4028
|
props.searchParam.type);
|
|
3965
4029
|
}
|
|
@@ -3967,72 +4031,72 @@
|
|
|
3967
4031
|
function DateFilterSubMenu(props) {
|
|
3968
4032
|
const { searchParam } = props;
|
|
3969
4033
|
const code = searchParam.code;
|
|
3970
|
-
return (
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
4034
|
+
return (e.createElement(core$1.Menu.Dropdown, null,
|
|
4035
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(iNe, { size: 14 }), onClick: () => props.onSort(searchParam, false) }, "Sort Oldest to Newest"),
|
|
4036
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(wNe, { size: 14 }), onClick: () => props.onSort(searchParam, true) }, "Sort Newest to Oldest"),
|
|
4037
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4038
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(lZ, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.EQUALS) }, "Equals..."),
|
|
4039
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(rZ, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.NOT_EQUALS) }, "Does not equal..."),
|
|
4040
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4041
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(Pse, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.ENDS_BEFORE) }, "Before..."),
|
|
4042
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(Cse, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.STARTS_AFTER) }, "After..."),
|
|
4043
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(Jw, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.EQUALS) }, "Between..."),
|
|
4044
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4045
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(zB, { size: 14 }), onClick: () => props.onChange(addTomorrowFilter(props.search, code)) }, "Tomorrow"),
|
|
4046
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(zB, { size: 14 }), onClick: () => props.onChange(addTodayFilter(props.search, code)) }, "Today"),
|
|
4047
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(zB, { size: 14 }), onClick: () => props.onChange(addYesterdayFilter(props.search, code)) }, "Yesterday"),
|
|
4048
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4049
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(zB, { size: 14 }), onClick: () => props.onChange(addNextMonthFilter(props.search, code)) }, "Next Month"),
|
|
4050
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(zB, { size: 14 }), onClick: () => props.onChange(addThisMonthFilter(props.search, code)) }, "This Month"),
|
|
4051
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(zB, { size: 14 }), onClick: () => props.onChange(addLastMonthFilter(props.search, code)) }, "Last Month"),
|
|
4052
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4053
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(zB, { size: 14 }), onClick: () => props.onChange(addYearToDateFilter(props.search, code)) }, "Year to date"),
|
|
4054
|
+
e.createElement(CommonMenuItems, { ...props })));
|
|
3991
4055
|
}
|
|
3992
4056
|
function NumericFilterSubMenu(props) {
|
|
3993
4057
|
const { searchParam } = props;
|
|
3994
|
-
return (
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4058
|
+
return (e.createElement(core$1.Menu.Dropdown, null,
|
|
4059
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(iNe, { size: 14 }), onClick: () => props.onSort(searchParam, false) }, "Sort Smallest to Largest"),
|
|
4060
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(wNe, { size: 14 }), onClick: () => props.onSort(searchParam, true) }, "Sort Largest to Smallest"),
|
|
4061
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4062
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(lZ, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.EQUALS) }, "Equals..."),
|
|
4063
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(rZ, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.NOT_EQUALS) }, "Does not equal..."),
|
|
4064
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4065
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(Cse, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.GREATER_THAN) }, "Greater than..."),
|
|
4066
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(Bje, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.GREATER_THAN_OR_EQUALS) }, "Greater than or equal to..."),
|
|
4067
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(Pse, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.LESS_THAN) }, "Less than..."),
|
|
4068
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(Bje, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.LESS_THAN_OR_EQUALS) }, "Less than or equal to..."),
|
|
4069
|
+
e.createElement(CommonMenuItems, { ...props })));
|
|
4006
4070
|
}
|
|
4007
4071
|
function ReferenceFilterSubMenu(props) {
|
|
4008
4072
|
const { searchParam } = props;
|
|
4009
|
-
return (
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4073
|
+
return (e.createElement(core$1.Menu.Dropdown, null,
|
|
4074
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(lZ, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.EQUALS) }, "Equals..."),
|
|
4075
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(rZ, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.NOT) }, "Does not equal..."),
|
|
4076
|
+
e.createElement(CommonMenuItems, { ...props })));
|
|
4013
4077
|
}
|
|
4014
4078
|
function TextFilterSubMenu(props) {
|
|
4015
4079
|
const { searchParam } = props;
|
|
4016
|
-
return (
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4080
|
+
return (e.createElement(core$1.Menu.Dropdown, null,
|
|
4081
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(iNe, { size: 14 }), onClick: () => props.onSort(searchParam, false) }, "Sort A to Z"),
|
|
4082
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(wNe, { size: 14 }), onClick: () => props.onSort(searchParam, true) }, "Sort Z to A"),
|
|
4083
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4084
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(lZ, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.EQUALS) }, "Equals..."),
|
|
4085
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(rZ, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.NOT) }, "Does not equal..."),
|
|
4086
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4087
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(BC, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.CONTAINS) }, "Contains..."),
|
|
4088
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(CC, { size: 14 }), onClick: () => props.onPrompt(searchParam, core.Operator.EQUALS) }, "Does not contain..."),
|
|
4089
|
+
e.createElement(CommonMenuItems, { ...props })));
|
|
4026
4090
|
}
|
|
4027
4091
|
function CommonMenuItems(props) {
|
|
4028
4092
|
const { searchParam } = props;
|
|
4029
4093
|
const code = searchParam.code;
|
|
4030
|
-
return (
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4094
|
+
return (e.createElement(e.Fragment, null,
|
|
4095
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4096
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(Qv, { size: 14 }), onClick: () => props.onChange(addMissingFilter(props.search, code)) }, "Missing"),
|
|
4097
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(Jv, { size: 14 }), onClick: () => props.onChange(addMissingFilter(props.search, code, false)) }, "Not missing"),
|
|
4098
|
+
e.createElement(core$1.Menu.Divider, null),
|
|
4099
|
+
e.createElement(core$1.Menu.Item, { icon: e.createElement(qXe, { size: 14 }), onClick: () => props.onClear(searchParam) }, "Clear filters")));
|
|
4036
4100
|
}
|
|
4037
4101
|
|
|
4038
4102
|
/**
|
|
@@ -4184,18 +4248,18 @@
|
|
|
4184
4248
|
function SearchControl(props) {
|
|
4185
4249
|
const { classes } = useStyles$6();
|
|
4186
4250
|
const medplum = useMedplum();
|
|
4187
|
-
const [schemaLoaded, setSchemaLoaded] =
|
|
4188
|
-
const [outcome, setOutcome] =
|
|
4251
|
+
const [schemaLoaded, setSchemaLoaded] = e.useState(false);
|
|
4252
|
+
const [outcome, setOutcome] = e.useState();
|
|
4189
4253
|
const { search, onLoad } = props;
|
|
4190
|
-
const [state, setState] =
|
|
4254
|
+
const [state, setState] = e.useState({
|
|
4191
4255
|
selected: {},
|
|
4192
4256
|
fieldEditorVisible: false,
|
|
4193
4257
|
filterEditorVisible: false,
|
|
4194
4258
|
filterDialogVisible: false,
|
|
4195
4259
|
});
|
|
4196
|
-
const stateRef =
|
|
4260
|
+
const stateRef = e.useRef(state);
|
|
4197
4261
|
stateRef.current = state;
|
|
4198
|
-
|
|
4262
|
+
e.useEffect(() => {
|
|
4199
4263
|
setOutcome(undefined);
|
|
4200
4264
|
medplum
|
|
4201
4265
|
.search(search.resourceType, core.formatSearchQuery({ ...search, total: 'accurate', fields: undefined }))
|
|
@@ -4282,7 +4346,7 @@
|
|
|
4282
4346
|
props.onAuxClick(new SearchClickEvent(resource, e));
|
|
4283
4347
|
}
|
|
4284
4348
|
}
|
|
4285
|
-
|
|
4349
|
+
e.useEffect(() => {
|
|
4286
4350
|
setSchemaLoaded(false);
|
|
4287
4351
|
medplum
|
|
4288
4352
|
.requestSchema(props.search.resourceType)
|
|
@@ -4291,8 +4355,8 @@
|
|
|
4291
4355
|
}, [medplum, props.search.resourceType]);
|
|
4292
4356
|
const typeSchema = schemaLoaded && core.globalSchema?.types?.[props.search.resourceType];
|
|
4293
4357
|
if (!typeSchema) {
|
|
4294
|
-
return (
|
|
4295
|
-
|
|
4358
|
+
return (e.createElement(core$1.Center, { style: { width: '100%', height: '100%' } },
|
|
4359
|
+
e.createElement(core$1.Loader, null)));
|
|
4296
4360
|
}
|
|
4297
4361
|
const checkboxColumn = props.checkboxesEnabled;
|
|
4298
4362
|
const fields = getFieldDefinitions(search);
|
|
@@ -4304,36 +4368,36 @@
|
|
|
4304
4368
|
const buttonColor = 'gray';
|
|
4305
4369
|
const iconSize = 16;
|
|
4306
4370
|
const isMobile = window.innerWidth < 768;
|
|
4307
|
-
return (
|
|
4308
|
-
!props.hideToolbar && (
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
props.onNew && (
|
|
4313
|
-
!isMobile && props.onExport && (
|
|
4314
|
-
!isMobile && props.onDelete && (
|
|
4315
|
-
!isMobile && props.onBulk && (
|
|
4316
|
-
lastResult && (
|
|
4371
|
+
return (e.createElement("div", { className: classes.root, "data-testid": "search-control" },
|
|
4372
|
+
!props.hideToolbar && (e.createElement(core$1.Group, { position: "apart", mb: "xl" },
|
|
4373
|
+
e.createElement(core$1.Group, { spacing: 2 },
|
|
4374
|
+
e.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: e.createElement(R0, { size: iconSize }), onClick: () => setState({ ...stateRef.current, fieldEditorVisible: true }) }, "Fields"),
|
|
4375
|
+
e.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: e.createElement(sF, { size: iconSize }), onClick: () => setState({ ...stateRef.current, filterEditorVisible: true }) }, "Filters"),
|
|
4376
|
+
props.onNew && (e.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: e.createElement(X_, { size: iconSize }), onClick: props.onNew }, "New...")),
|
|
4377
|
+
!isMobile && props.onExport && (e.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: e.createElement(_Ae, { size: iconSize }), onClick: props.onExport }, "Export...")),
|
|
4378
|
+
!isMobile && props.onDelete && (e.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: e.createElement(zKe, { size: iconSize }), onClick: () => props.onDelete(Object.keys(state.selected)) }, "Delete...")),
|
|
4379
|
+
!isMobile && props.onBulk && (e.createElement(core$1.Button, { compact: true, variant: buttonVariant, color: buttonColor, leftIcon: e.createElement(bw, { size: iconSize }), onClick: () => props.onBulk(Object.keys(state.selected)) }, "Bulk..."))),
|
|
4380
|
+
lastResult && (e.createElement(core$1.Text, { size: "xs", color: "dimmed" },
|
|
4317
4381
|
getStart$1(search, lastResult.total),
|
|
4318
4382
|
"-",
|
|
4319
4383
|
getEnd$1(search, lastResult.total),
|
|
4320
4384
|
" of",
|
|
4321
4385
|
' ',
|
|
4322
4386
|
lastResult.total?.toLocaleString())))),
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
checkboxColumn && (
|
|
4327
|
-
|
|
4328
|
-
fields.map((field) => (
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4387
|
+
e.createElement(core$1.Table, { className: classes.table },
|
|
4388
|
+
e.createElement("thead", null,
|
|
4389
|
+
e.createElement("tr", null,
|
|
4390
|
+
checkboxColumn && (e.createElement("th", null,
|
|
4391
|
+
e.createElement("input", { type: "checkbox", value: "checked", "aria-label": "all-checkbox", "data-testid": "all-checkbox", checked: isAllSelected(), onChange: (e) => handleAllCheckboxClick(e) }))),
|
|
4392
|
+
fields.map((field) => (e.createElement("th", { key: field.name },
|
|
4393
|
+
e.createElement(core$1.Menu, { shadow: "md", width: 240, position: "bottom-end" },
|
|
4394
|
+
e.createElement(core$1.Menu.Target, null,
|
|
4395
|
+
e.createElement(core$1.UnstyledButton, { className: classes.control },
|
|
4396
|
+
e.createElement(core$1.Group, { position: "apart", noWrap: true },
|
|
4397
|
+
e.createElement(core$1.Text, { weight: 500, size: "sm" }, buildFieldNameString(field.name)),
|
|
4398
|
+
e.createElement(core$1.Center, { className: classes.icon },
|
|
4399
|
+
e.createElement(oe, { size: 14, stroke: 1.5 }))))),
|
|
4400
|
+
e.createElement(SearchPopupMenu, { search: props.search, searchParams: field.searchParams, onPrompt: (searchParam, filter) => {
|
|
4337
4401
|
setState({
|
|
4338
4402
|
...stateRef.current,
|
|
4339
4403
|
filterDialogVisible: true,
|
|
@@ -4343,18 +4407,18 @@
|
|
|
4343
4407
|
}, onChange: (result) => {
|
|
4344
4408
|
emitSearchChange(result);
|
|
4345
4409
|
} })))))),
|
|
4346
|
-
!props.hideFilters && (
|
|
4347
|
-
checkboxColumn &&
|
|
4348
|
-
fields.map((field) => (
|
|
4349
|
-
|
|
4350
|
-
checkboxColumn && (
|
|
4351
|
-
|
|
4352
|
-
fields.map((field) => (
|
|
4353
|
-
resources?.length === 0 && (
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
lastResult?.total !== undefined && lastResult.total > 0 && (
|
|
4357
|
-
|
|
4410
|
+
!props.hideFilters && (e.createElement("tr", null,
|
|
4411
|
+
checkboxColumn && e.createElement("th", null),
|
|
4412
|
+
fields.map((field) => (e.createElement("th", { key: field.name }, field.searchParams && (e.createElement(FilterDescription, { resourceType: resourceType, searchParams: field.searchParams, filters: props.search.filters })))))))),
|
|
4413
|
+
e.createElement("tbody", null, resources?.map((resource) => resource && (e.createElement("tr", { key: resource.id, className: classes.tr, "data-testid": "search-control-row", onClick: (e) => handleRowClick(e, resource), onAuxClick: (e) => handleRowClick(e, resource) },
|
|
4414
|
+
checkboxColumn && (e.createElement("td", null,
|
|
4415
|
+
e.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) }))),
|
|
4416
|
+
fields.map((field) => (e.createElement("td", { key: field.name }, renderValue(resource, field))))))))),
|
|
4417
|
+
resources?.length === 0 && (e.createElement(Container, null,
|
|
4418
|
+
e.createElement(core$1.Center, null,
|
|
4419
|
+
e.createElement(core$1.Text, { size: "xl", color: "dimmed" }, "No results")))),
|
|
4420
|
+
lastResult?.total !== undefined && lastResult.total > 0 && (e.createElement(core$1.Center, { m: "md", p: "md" },
|
|
4421
|
+
e.createElement(core$1.Pagination, { page: getPage(search), total: getTotalPages(search, lastResult.total), onChange: (newPage) => emitSearchChange(setPage(search, newPage)), getItemAriaLabel: (page) => {
|
|
4358
4422
|
switch (page) {
|
|
4359
4423
|
case 'prev':
|
|
4360
4424
|
return 'Previous page';
|
|
@@ -4364,9 +4428,9 @@
|
|
|
4364
4428
|
return undefined;
|
|
4365
4429
|
}
|
|
4366
4430
|
} }))),
|
|
4367
|
-
outcome && (
|
|
4368
|
-
|
|
4369
|
-
|
|
4431
|
+
outcome && (e.createElement("div", { "data-testid": "search-error" },
|
|
4432
|
+
e.createElement("pre", { style: { textAlign: 'left' } }, JSON.stringify(outcome, undefined, 2)))),
|
|
4433
|
+
e.createElement(SearchFieldEditor, { search: props.search, visible: stateRef.current.fieldEditorVisible, onOk: (result) => {
|
|
4370
4434
|
emitSearchChange(result);
|
|
4371
4435
|
setState({
|
|
4372
4436
|
...stateRef.current,
|
|
@@ -4378,7 +4442,7 @@
|
|
|
4378
4442
|
fieldEditorVisible: false,
|
|
4379
4443
|
});
|
|
4380
4444
|
} }),
|
|
4381
|
-
|
|
4445
|
+
e.createElement(SearchFilterEditor, { search: props.search, visible: stateRef.current.filterEditorVisible, onOk: (result) => {
|
|
4382
4446
|
emitSearchChange(result);
|
|
4383
4447
|
setState({
|
|
4384
4448
|
...stateRef.current,
|
|
@@ -4390,7 +4454,7 @@
|
|
|
4390
4454
|
filterEditorVisible: false,
|
|
4391
4455
|
});
|
|
4392
4456
|
} }),
|
|
4393
|
-
|
|
4457
|
+
e.createElement(SearchFilterValueDialog, { key: state.filterDialogSearchParam?.code, visible: stateRef.current.filterDialogVisible, title: 'Input', resourceType: resourceType, searchParam: state.filterDialogSearchParam, filter: state.filterDialogFilter, defaultValue: '', onOk: (filter) => {
|
|
4394
4458
|
emitSearchChange(addFilter(props.search, filter.code, filter.operator, filter.value));
|
|
4395
4459
|
setState({
|
|
4396
4460
|
...stateRef.current,
|
|
@@ -4403,16 +4467,16 @@
|
|
|
4403
4467
|
});
|
|
4404
4468
|
} })));
|
|
4405
4469
|
}
|
|
4406
|
-
const MemoizedSearchControl =
|
|
4470
|
+
const MemoizedSearchControl = e.memo(SearchControl);
|
|
4407
4471
|
function FilterDescription(props) {
|
|
4408
4472
|
const filters = (props.filters ?? []).filter((f) => props.searchParams.find((p) => p.code === f.code));
|
|
4409
4473
|
if (filters.length === 0) {
|
|
4410
|
-
return
|
|
4474
|
+
return e.createElement("span", null, "no filters");
|
|
4411
4475
|
}
|
|
4412
|
-
return (
|
|
4476
|
+
return (e.createElement(e.Fragment, null, filters.map((filter, index) => (e.createElement("div", { key: `filter-${index}-${filters.length}` },
|
|
4413
4477
|
getOpString(filter.operator),
|
|
4414
4478
|
"\u00A0",
|
|
4415
|
-
|
|
4479
|
+
e.createElement(SearchFilterValueDisplay, { resourceType: props.resourceType, filter: filter }))))));
|
|
4416
4480
|
}
|
|
4417
4481
|
function getPage(search) {
|
|
4418
4482
|
return Math.floor((search.offset || 0) / (search.count || core.DEFAULT_SEARCH_COUNT)) + 1;
|
|
@@ -4433,16 +4497,16 @@
|
|
|
4433
4497
|
*/
|
|
4434
4498
|
function FhirPathTable(props) {
|
|
4435
4499
|
const medplum = useMedplum();
|
|
4436
|
-
const [schema, setSchema] =
|
|
4437
|
-
const [outcome, setOutcome] =
|
|
4500
|
+
const [schema, setSchema] = e.useState();
|
|
4501
|
+
const [outcome, setOutcome] = e.useState();
|
|
4438
4502
|
const { query, fields } = props;
|
|
4439
|
-
const [response, setResponse] =
|
|
4440
|
-
const [selected, setSelected] =
|
|
4441
|
-
const responseRef =
|
|
4503
|
+
const [response, setResponse] = e.useState();
|
|
4504
|
+
const [selected, setSelected] = e.useState({});
|
|
4505
|
+
const responseRef = e.useRef();
|
|
4442
4506
|
responseRef.current = response;
|
|
4443
|
-
const selectedRef =
|
|
4507
|
+
const selectedRef = e.useRef({});
|
|
4444
4508
|
selectedRef.current = selected;
|
|
4445
|
-
|
|
4509
|
+
e.useEffect(() => {
|
|
4446
4510
|
setOutcome(undefined);
|
|
4447
4511
|
medplum.graphql(query).then(setResponse).catch(setOutcome);
|
|
4448
4512
|
}, [medplum, query]);
|
|
@@ -4499,7 +4563,7 @@
|
|
|
4499
4563
|
props.onAuxClick(new SearchClickEvent(resource, e));
|
|
4500
4564
|
}
|
|
4501
4565
|
}
|
|
4502
|
-
|
|
4566
|
+
e.useEffect(() => {
|
|
4503
4567
|
medplum
|
|
4504
4568
|
.requestSchema(props.resourceType)
|
|
4505
4569
|
.then((newSchema) => {
|
|
@@ -4511,32 +4575,32 @@
|
|
|
4511
4575
|
}, [medplum, props.resourceType]);
|
|
4512
4576
|
const typeSchema = schema?.types?.[props.resourceType];
|
|
4513
4577
|
if (!typeSchema) {
|
|
4514
|
-
return
|
|
4578
|
+
return e.createElement(core$1.Loader, null);
|
|
4515
4579
|
}
|
|
4516
4580
|
const checkboxColumn = props.checkboxesEnabled;
|
|
4517
|
-
return (
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
checkboxColumn && (
|
|
4522
|
-
|
|
4523
|
-
fields.map((field) => (
|
|
4524
|
-
|
|
4525
|
-
checkboxColumn && (
|
|
4526
|
-
|
|
4581
|
+
return (e.createElement("div", { onContextMenu: (e) => killEvent(e), "data-testid": "search-control" },
|
|
4582
|
+
e.createElement(core$1.Table, null,
|
|
4583
|
+
e.createElement("thead", null,
|
|
4584
|
+
e.createElement("tr", null,
|
|
4585
|
+
checkboxColumn && (e.createElement("th", null,
|
|
4586
|
+
e.createElement("input", { type: "checkbox", value: "checked", "aria-label": "all-checkbox", "data-testid": "all-checkbox", checked: isAllSelected(), onChange: (e) => handleAllCheckboxClick(e) }))),
|
|
4587
|
+
fields.map((field) => (e.createElement("th", { key: field.name }, field.name))))),
|
|
4588
|
+
e.createElement("tbody", null, response?.data?.ResourceList?.map((resource) => resource && (e.createElement("tr", { key: resource.id, "data-testid": "search-control-row", onClick: (e) => handleRowClick(e, resource), onAuxClick: (e) => handleRowClick(e, resource) },
|
|
4589
|
+
checkboxColumn && (e.createElement("td", null,
|
|
4590
|
+
e.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) }))),
|
|
4527
4591
|
fields.map((field) => {
|
|
4528
|
-
return (
|
|
4529
|
-
|
|
4592
|
+
return (e.createElement("td", { key: field.name },
|
|
4593
|
+
e.createElement(FhirPathDisplay, { propertyType: field.propertyType, path: field.fhirPath, resource: resource })));
|
|
4530
4594
|
})))))),
|
|
4531
|
-
response?.data?.ResourceList?.length === 0 &&
|
|
4532
|
-
outcome && (
|
|
4533
|
-
|
|
4534
|
-
props.onBulk && (
|
|
4595
|
+
response?.data?.ResourceList?.length === 0 && e.createElement("div", { "data-testid": "empty-search" }, "No results"),
|
|
4596
|
+
outcome && (e.createElement("div", { "data-testid": "search-error" },
|
|
4597
|
+
e.createElement("pre", { style: { textAlign: 'left' } }, JSON.stringify(outcome, undefined, 2)))),
|
|
4598
|
+
props.onBulk && (e.createElement(core$1.Button, { onClick: () => props.onBulk(Object.keys(selectedRef.current)) }, "Bulk..."))));
|
|
4535
4599
|
}
|
|
4536
|
-
const MemoizedFhirPathTable =
|
|
4600
|
+
const MemoizedFhirPathTable = e.memo(FhirPathTable);
|
|
4537
4601
|
|
|
4538
4602
|
function PatientTimeline(props) {
|
|
4539
|
-
const loadTimelineResources =
|
|
4603
|
+
const loadTimelineResources = e.useCallback((medplum, resource) => {
|
|
4540
4604
|
return Promise.all([
|
|
4541
4605
|
medplum.readHistory('Patient', resource.id),
|
|
4542
4606
|
medplum.search('Communication', 'subject=' + core.getReferenceString(resource)),
|
|
@@ -4547,7 +4611,7 @@
|
|
|
4547
4611
|
medplum.search('ServiceRequest', 'subject=' + core.getReferenceString(resource)),
|
|
4548
4612
|
]);
|
|
4549
4613
|
}, []);
|
|
4550
|
-
return (
|
|
4614
|
+
return (e.createElement(ResourceTimeline, { value: props.patient, loadTimelineResources: loadTimelineResources, createCommunication: (resource, sender, text) => ({
|
|
4551
4615
|
resourceType: 'Communication',
|
|
4552
4616
|
status: 'completed',
|
|
4553
4617
|
subject: core.createReference(resource),
|
|
@@ -4593,22 +4657,22 @@
|
|
|
4593
4657
|
function PlanDefinitionBuilder(props) {
|
|
4594
4658
|
const medplum = useMedplum();
|
|
4595
4659
|
const defaultValue = useResource(props.value);
|
|
4596
|
-
const [schema, setSchema] =
|
|
4597
|
-
const [selectedKey, setSelectedKey] =
|
|
4598
|
-
const [hoverKey, setHoverKey] =
|
|
4599
|
-
const [value, setValue] =
|
|
4660
|
+
const [schema, setSchema] = e.useState(undefined);
|
|
4661
|
+
const [selectedKey, setSelectedKey] = e.useState();
|
|
4662
|
+
const [hoverKey, setHoverKey] = e.useState();
|
|
4663
|
+
const [value, setValue] = e.useState();
|
|
4600
4664
|
function handleDocumentMouseOver() {
|
|
4601
4665
|
setHoverKey(undefined);
|
|
4602
4666
|
}
|
|
4603
4667
|
function handleDocumentClick() {
|
|
4604
4668
|
setSelectedKey(undefined);
|
|
4605
4669
|
}
|
|
4606
|
-
const valueRef =
|
|
4670
|
+
const valueRef = e.useRef();
|
|
4607
4671
|
valueRef.current = value;
|
|
4608
|
-
|
|
4672
|
+
e.useEffect(() => {
|
|
4609
4673
|
medplum.requestSchema('PlanDefinition').then(setSchema).catch(console.log);
|
|
4610
4674
|
}, [medplum]);
|
|
4611
|
-
|
|
4675
|
+
e.useEffect(() => {
|
|
4612
4676
|
setValue(ensurePlanDefinitionKeys(defaultValue ?? { resourceType: 'PlanDefinition' }));
|
|
4613
4677
|
document.addEventListener('mouseover', handleDocumentMouseOver);
|
|
4614
4678
|
document.addEventListener('click', handleDocumentClick);
|
|
@@ -4626,15 +4690,15 @@
|
|
|
4626
4690
|
[property]: newValue,
|
|
4627
4691
|
});
|
|
4628
4692
|
}
|
|
4629
|
-
return (
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4693
|
+
return (e.createElement("div", null,
|
|
4694
|
+
e.createElement(Form, { testid: "questionnaire-form", onSubmit: () => props.onSubmit(value) },
|
|
4695
|
+
e.createElement(core$1.TextInput, { label: "Plan Title", defaultValue: value.title, onChange: (e) => changeProperty('title', e.currentTarget.value) }),
|
|
4696
|
+
e.createElement(ActionArrayBuilder, { actions: value.action || [], selectedKey: selectedKey, setSelectedKey: setSelectedKey, hoverKey: hoverKey, setHoverKey: setHoverKey, onChange: (x) => changeProperty('action', x) }),
|
|
4697
|
+
e.createElement(core$1.Button, { type: "submit" }, "Save"))));
|
|
4634
4698
|
}
|
|
4635
4699
|
function ActionArrayBuilder(props) {
|
|
4636
4700
|
const { classes } = useStyles$5();
|
|
4637
|
-
const actionsRef =
|
|
4701
|
+
const actionsRef = e.useRef();
|
|
4638
4702
|
actionsRef.current = props.actions;
|
|
4639
4703
|
function changeAction(changedAction) {
|
|
4640
4704
|
props.onChange(actionsRef.current.map((i) => (i.id === changedAction.id ? changedAction : i)));
|
|
@@ -4646,11 +4710,11 @@
|
|
|
4646
4710
|
function removeAction(removedAction) {
|
|
4647
4711
|
props.onChange(actionsRef.current.filter((i) => i !== removedAction));
|
|
4648
4712
|
}
|
|
4649
|
-
return (
|
|
4650
|
-
props.actions.map((action) => (
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4713
|
+
return (e.createElement("div", { className: classes.section },
|
|
4714
|
+
props.actions.map((action) => (e.createElement("div", { key: action.id },
|
|
4715
|
+
e.createElement(ActionBuilder, { action: action, selectedKey: props.selectedKey, setSelectedKey: props.setSelectedKey, hoverKey: props.hoverKey, setHoverKey: props.setHoverKey, onChange: changeAction, onRemove: () => removeAction(action) })))),
|
|
4716
|
+
e.createElement("div", { className: classes.bottomActions },
|
|
4717
|
+
e.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
4654
4718
|
killEvent(e);
|
|
4655
4719
|
addAction({ id: generateId$1() });
|
|
4656
4720
|
} }, "Add action"))));
|
|
@@ -4673,10 +4737,10 @@
|
|
|
4673
4737
|
[classes.editing]: editing,
|
|
4674
4738
|
[classes.hovering]: hovering && !editing,
|
|
4675
4739
|
});
|
|
4676
|
-
return (
|
|
4677
|
-
editing ? (
|
|
4678
|
-
|
|
4679
|
-
|
|
4740
|
+
return (e.createElement("div", { "data-testid": action.id, className: className, onClick: onClick, onMouseOver: onHover },
|
|
4741
|
+
editing ? (e.createElement(ActionEditor, { action: action, actionType: actionType, onChange: props.onChange, selectedKey: props.selectedKey, setSelectedKey: props.setSelectedKey, hoverKey: props.hoverKey, setHoverKey: props.setHoverKey, onRemove: props.onRemove })) : (e.createElement(ActionDisplay, { action: action, actionType: actionType })),
|
|
4742
|
+
e.createElement("div", { className: classes.bottomActions },
|
|
4743
|
+
e.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
4680
4744
|
e.preventDefault();
|
|
4681
4745
|
props.onRemove();
|
|
4682
4746
|
} }, "Remove"))));
|
|
@@ -4690,53 +4754,53 @@
|
|
|
4690
4754
|
function ActionDisplay(props) {
|
|
4691
4755
|
const { action, actionType } = props;
|
|
4692
4756
|
const [propertyValue, propertyType] = getActionTiming(action);
|
|
4693
|
-
return (
|
|
4694
|
-
|
|
4757
|
+
return (e.createElement("div", null,
|
|
4758
|
+
e.createElement("div", null,
|
|
4695
4759
|
action.title || 'Untitled',
|
|
4696
4760
|
" ",
|
|
4697
4761
|
actionType && `(${actionType})`),
|
|
4698
|
-
action.definitionCanonical && (
|
|
4699
|
-
|
|
4700
|
-
propertyValue && (
|
|
4701
|
-
|
|
4762
|
+
action.definitionCanonical && (e.createElement("div", null,
|
|
4763
|
+
e.createElement(ReferenceDisplay, { value: { reference: action.definitionCanonical } }))),
|
|
4764
|
+
propertyValue && (e.createElement("div", null,
|
|
4765
|
+
e.createElement(ResourcePropertyDisplay, { property: timingProperty, propertyType: propertyType, value: propertyValue })))));
|
|
4702
4766
|
}
|
|
4703
4767
|
function ActionEditor(props) {
|
|
4704
4768
|
const { action } = props;
|
|
4705
|
-
const [actionType, setActionType] =
|
|
4769
|
+
const [actionType, setActionType] = e.useState(props.actionType);
|
|
4706
4770
|
function changeProperty(property, value) {
|
|
4707
4771
|
props.onChange({
|
|
4708
4772
|
...action,
|
|
4709
4773
|
[property]: value,
|
|
4710
4774
|
});
|
|
4711
4775
|
}
|
|
4712
|
-
return (
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
action.action && action.action.length > 0 && (
|
|
4776
|
+
return (e.createElement(core$1.Stack, { spacing: "xl" },
|
|
4777
|
+
e.createElement(core$1.TextInput, { name: `actionTitle-${action.id}`, label: "Title", defaultValue: action.title, onChange: (e) => changeProperty('title', e.currentTarget.value) }),
|
|
4778
|
+
e.createElement(core$1.TextInput, { name: `actionDescription-${action.id}`, label: "Description", defaultValue: action.description, onChange: (e) => changeProperty('description', e.currentTarget.value) }),
|
|
4779
|
+
e.createElement(core$1.NativeSelect, { label: "Type of Action", description: "The type of the action to be performed.", name: `actionType-${action.id}`, defaultValue: actionType, onChange: (e) => setActionType(e.currentTarget.value), data: ['', 'appointment', 'lab', 'questionnaire', 'task'] }),
|
|
4780
|
+
action.action && action.action.length > 0 && (e.createElement(ActionArrayBuilder, { actions: action.action, selectedKey: props.selectedKey, setSelectedKey: props.setSelectedKey, hoverKey: props.hoverKey, setHoverKey: props.setHoverKey, onChange: (x) => changeProperty('action', x) })),
|
|
4717
4781
|
(() => {
|
|
4718
4782
|
switch (actionType) {
|
|
4719
4783
|
case 'appointment':
|
|
4720
|
-
return (
|
|
4784
|
+
return (e.createElement(ActionResourceTypeBuilder, { title: "Appointment", description: "The subject must schedule an appointment from the schedule.", resourceType: "Schedule", action: action, onChange: props.onChange }));
|
|
4721
4785
|
case 'lab':
|
|
4722
|
-
return (
|
|
4786
|
+
return (e.createElement(ActionResourceTypeBuilder, { title: "Lab", description: "The subject must complete the following lab panel.", resourceType: "ActivityDefinition", action: action, onChange: props.onChange }));
|
|
4723
4787
|
case 'questionnaire':
|
|
4724
|
-
return (
|
|
4788
|
+
return (e.createElement(ActionResourceTypeBuilder, { title: "Questionnaire", description: "The subject must complete the selected questionnaire.", resourceType: "Questionnaire", action: action, onChange: props.onChange }));
|
|
4725
4789
|
case 'task':
|
|
4726
|
-
return (
|
|
4790
|
+
return (e.createElement(ActionResourceTypeBuilder, { title: "Task", description: "The subject must complete the following task.", resourceType: "ActivityDefinition", action: action, onChange: props.onChange }));
|
|
4727
4791
|
default:
|
|
4728
4792
|
return null;
|
|
4729
4793
|
}
|
|
4730
4794
|
})(),
|
|
4731
|
-
|
|
4732
|
-
|
|
4795
|
+
e.createElement(FormSection, { title: "Timing", description: "When the action should take place." },
|
|
4796
|
+
e.createElement(ActionTimingInput, { name: 'timing-' + action.id, action: action, onChange: props.onChange }))));
|
|
4733
4797
|
}
|
|
4734
4798
|
function ActionResourceTypeBuilder(props) {
|
|
4735
4799
|
const { id, definitionCanonical } = props.action;
|
|
4736
4800
|
const reference = definitionCanonical?.startsWith(props.resourceType + '/')
|
|
4737
4801
|
? { reference: definitionCanonical }
|
|
4738
4802
|
: undefined;
|
|
4739
|
-
return (
|
|
4803
|
+
return (e.createElement(ResourceInput, { name: id, resourceType: props.resourceType, defaultValue: reference, loadOnFocus: true, onChange: (newValue) => {
|
|
4740
4804
|
if (newValue) {
|
|
4741
4805
|
props.onChange({ ...props.action, definitionCanonical: core.getReferenceString(newValue) });
|
|
4742
4806
|
}
|
|
@@ -4749,7 +4813,7 @@
|
|
|
4749
4813
|
const value = props.action;
|
|
4750
4814
|
const key = 'timing';
|
|
4751
4815
|
const [propertyValue, propertyType] = getActionTiming(value);
|
|
4752
|
-
return (
|
|
4816
|
+
return (e.createElement(ResourcePropertyInput, { property: timingProperty, name: "timing[x]", defaultValue: propertyValue, defaultPropertyType: propertyType, onChange: (newValue, propName) => {
|
|
4753
4817
|
props.onChange(setPropertyValue(value, key, propName ?? key, timingProperty, newValue));
|
|
4754
4818
|
} }));
|
|
4755
4819
|
}
|
|
@@ -4832,24 +4896,23 @@
|
|
|
4832
4896
|
function QuestionnaireForm(props) {
|
|
4833
4897
|
const medplum = useMedplum();
|
|
4834
4898
|
const source = medplum.getProfile();
|
|
4835
|
-
const [schema, setSchema] =
|
|
4899
|
+
const [schema, setSchema] = e.useState();
|
|
4836
4900
|
const questionnaire = useResource(props.questionnaire);
|
|
4837
|
-
const [response, setResponse] =
|
|
4838
|
-
const [answers, setAnswers] =
|
|
4839
|
-
|
|
4901
|
+
const [response, setResponse] = e.useState();
|
|
4902
|
+
const [answers, setAnswers] = e.useState({});
|
|
4903
|
+
e.useEffect(() => {
|
|
4840
4904
|
medplum
|
|
4841
4905
|
.requestSchema('Questionnaire')
|
|
4842
4906
|
.then(() => medplum.requestSchema('QuestionnaireResponse'))
|
|
4843
4907
|
.then(setSchema)
|
|
4844
4908
|
.catch(console.log);
|
|
4845
4909
|
}, [medplum]);
|
|
4846
|
-
|
|
4910
|
+
e.useEffect(() => {
|
|
4847
4911
|
setResponse(questionnaire ? buildInitialResponse(questionnaire) : undefined);
|
|
4848
4912
|
}, [questionnaire]);
|
|
4849
4913
|
function setItems(newResponseItems) {
|
|
4850
4914
|
const newResponse = {
|
|
4851
4915
|
resourceType: 'QuestionnaireResponse',
|
|
4852
|
-
status: 'completed',
|
|
4853
4916
|
item: newResponseItems,
|
|
4854
4917
|
};
|
|
4855
4918
|
setResponse(newResponse);
|
|
@@ -4858,7 +4921,7 @@
|
|
|
4858
4921
|
if (!schema || !questionnaire) {
|
|
4859
4922
|
return null;
|
|
4860
4923
|
}
|
|
4861
|
-
return (
|
|
4924
|
+
return (e.createElement(Form, { testid: "questionnaire-form", onSubmit: () => {
|
|
4862
4925
|
if (props.onSubmit && response) {
|
|
4863
4926
|
props.onSubmit({
|
|
4864
4927
|
...response,
|
|
@@ -4866,43 +4929,44 @@
|
|
|
4866
4929
|
subject: props.subject,
|
|
4867
4930
|
source: core.createReference(source),
|
|
4868
4931
|
authored: new Date().toISOString(),
|
|
4932
|
+
status: 'completed',
|
|
4869
4933
|
});
|
|
4870
4934
|
}
|
|
4871
4935
|
} },
|
|
4872
|
-
questionnaire.title &&
|
|
4873
|
-
questionnaire.item && (
|
|
4874
|
-
|
|
4875
|
-
|
|
4936
|
+
questionnaire.title && e.createElement(core$1.Title, null, questionnaire.title),
|
|
4937
|
+
questionnaire.item && (e.createElement(QuestionnaireFormItemArray, { items: questionnaire.item, answers: answers, onChange: setItems })),
|
|
4938
|
+
e.createElement(core$1.Group, { position: "right", mt: "xl" },
|
|
4939
|
+
e.createElement(core$1.Button, { type: "submit" }, props.submitButtonText || 'OK'))));
|
|
4876
4940
|
}
|
|
4877
4941
|
function QuestionnaireFormItemArray(props) {
|
|
4878
|
-
const [responseItems, setResponseItems] =
|
|
4942
|
+
const [responseItems, setResponseItems] = e.useState(buildInitialResponseItems(props.items));
|
|
4879
4943
|
function setResponseItem(index, newResponseItem) {
|
|
4880
4944
|
const newResponseItems = responseItems.slice();
|
|
4881
4945
|
newResponseItems[index] = newResponseItem;
|
|
4882
4946
|
setResponseItems(newResponseItems);
|
|
4883
4947
|
props.onChange(newResponseItems);
|
|
4884
4948
|
}
|
|
4885
|
-
return (
|
|
4949
|
+
return (e.createElement(core$1.Stack, null, props.items.map((item, index) => {
|
|
4886
4950
|
if (!isQuestionEnabled(item, props.answers)) {
|
|
4887
4951
|
return null;
|
|
4888
4952
|
}
|
|
4889
4953
|
if (item.type === exports.QuestionnaireItemType.display) {
|
|
4890
|
-
return
|
|
4954
|
+
return e.createElement("p", { key: item.linkId }, item.text);
|
|
4891
4955
|
}
|
|
4892
4956
|
if (item.type === exports.QuestionnaireItemType.group) {
|
|
4893
|
-
return (
|
|
4957
|
+
return (e.createElement(QuestionnaireFormItem, { key: item.linkId, item: item, answers: props.answers, onChange: (newResponseItem) => setResponseItem(index, newResponseItem) }));
|
|
4894
4958
|
}
|
|
4895
4959
|
if (item.type === exports.QuestionnaireItemType.boolean) {
|
|
4896
4960
|
const initial = item.initial && item.initial.length > 0 ? item.initial[0] : undefined;
|
|
4897
|
-
return (
|
|
4898
|
-
|
|
4961
|
+
return (e.createElement(CheckboxFormSection, { key: item.linkId, title: item.text, htmlFor: item.linkId },
|
|
4962
|
+
e.createElement(core$1.Checkbox, { id: item.linkId, name: item.linkId, defaultChecked: initial?.valueBoolean, onChange: (e) => setResponseItem(index, {
|
|
4899
4963
|
linkId: item.linkId,
|
|
4900
4964
|
text: item.text,
|
|
4901
4965
|
answer: [{ valueBoolean: e.currentTarget.checked }],
|
|
4902
4966
|
}) })));
|
|
4903
4967
|
}
|
|
4904
|
-
return (
|
|
4905
|
-
|
|
4968
|
+
return (e.createElement(FormSection, { key: item.linkId, htmlFor: item.linkId, title: item.text || '' },
|
|
4969
|
+
e.createElement(QuestionnaireFormItem, { item: item, answers: props.answers, onChange: (newResponseItem) => setResponseItem(index, newResponseItem) })));
|
|
4906
4970
|
})));
|
|
4907
4971
|
}
|
|
4908
4972
|
function QuestionnaireFormItem(props) {
|
|
@@ -4932,39 +4996,39 @@
|
|
|
4932
4996
|
}
|
|
4933
4997
|
switch (type) {
|
|
4934
4998
|
case exports.QuestionnaireItemType.group:
|
|
4935
|
-
return (
|
|
4936
|
-
|
|
4937
|
-
item.item && (
|
|
4999
|
+
return (e.createElement("div", null,
|
|
5000
|
+
e.createElement("h3", null, item.text),
|
|
5001
|
+
item.item && (e.createElement(QuestionnaireFormItemArray, { items: item.item, answers: props.answers, onChange: onChangeItem }))));
|
|
4938
5002
|
case exports.QuestionnaireItemType.boolean:
|
|
4939
|
-
return (
|
|
5003
|
+
return (e.createElement(core$1.Checkbox, { id: name, name: name, defaultChecked: initial?.valueBoolean, onChange: (e) => onChangeAnswer({ valueBoolean: e.currentTarget.checked }) }));
|
|
4940
5004
|
case exports.QuestionnaireItemType.decimal:
|
|
4941
|
-
return (
|
|
5005
|
+
return (e.createElement(core$1.TextInput, { type: "number", step: "any", id: name, name: name, defaultValue: initial?.valueDecimal, onChange: (e) => onChangeAnswer({ valueDecimal: e.currentTarget.valueAsNumber }) }));
|
|
4942
5006
|
case exports.QuestionnaireItemType.integer:
|
|
4943
|
-
return (
|
|
5007
|
+
return (e.createElement(core$1.TextInput, { type: "number", step: 1, id: name, name: name, defaultValue: initial?.valueInteger, onChange: (e) => onChangeAnswer({ valueInteger: e.currentTarget.valueAsNumber }) }));
|
|
4944
5008
|
case exports.QuestionnaireItemType.date:
|
|
4945
|
-
return (
|
|
5009
|
+
return (e.createElement(core$1.TextInput, { type: "date", id: name, name: name, defaultValue: initial?.valueDate, onChange: (e) => onChangeAnswer({ valueDate: e.currentTarget.value }) }));
|
|
4946
5010
|
case exports.QuestionnaireItemType.dateTime:
|
|
4947
|
-
return (
|
|
5011
|
+
return (e.createElement(DateTimeInput, { name: name, defaultValue: initial?.valueDateTime, onChange: (newValue) => onChangeAnswer({ valueDateTime: newValue }) }));
|
|
4948
5012
|
case exports.QuestionnaireItemType.time:
|
|
4949
|
-
return (
|
|
5013
|
+
return (e.createElement(core$1.TextInput, { type: "time", id: name, name: name, defaultValue: initial?.valueTime, onChange: (e) => onChangeAnswer({ valueTime: e.currentTarget.value }) }));
|
|
4950
5014
|
case exports.QuestionnaireItemType.string:
|
|
4951
5015
|
case exports.QuestionnaireItemType.url:
|
|
4952
|
-
return (
|
|
5016
|
+
return (e.createElement(core$1.TextInput, { id: name, name: name, defaultValue: initial?.valueString, onChange: (e) => onChangeAnswer({ valueString: e.currentTarget.value }) }));
|
|
4953
5017
|
case exports.QuestionnaireItemType.text:
|
|
4954
|
-
return (
|
|
5018
|
+
return (e.createElement(core$1.Textarea, { id: name, name: name, defaultValue: initial?.valueString, onChange: (e) => onChangeAnswer({ valueString: e.currentTarget.value }) }));
|
|
4955
5019
|
case exports.QuestionnaireItemType.attachment:
|
|
4956
|
-
return (
|
|
5020
|
+
return (e.createElement(AttachmentInput, { name: name, defaultValue: initial?.valueAttachment, onChange: (newValue) => onChangeAnswer({ valueAttachment: newValue }) }));
|
|
4957
5021
|
case exports.QuestionnaireItemType.reference:
|
|
4958
|
-
return (
|
|
5022
|
+
return (e.createElement(ReferenceInput, { name: name, defaultValue: initial?.valueReference, onChange: (newValue) => onChangeAnswer({ valueReference: newValue }) }));
|
|
4959
5023
|
case exports.QuestionnaireItemType.quantity:
|
|
4960
|
-
return (
|
|
5024
|
+
return (e.createElement(QuantityInput, { name: name, defaultValue: initial?.valueQuantity, onChange: (newValue) => onChangeAnswer({ valueQuantity: newValue }), disableWheel: true }));
|
|
4961
5025
|
case exports.QuestionnaireItemType.choice:
|
|
4962
5026
|
case exports.QuestionnaireItemType.openChoice:
|
|
4963
5027
|
if (isDropDownChoice(item)) {
|
|
4964
|
-
return (
|
|
5028
|
+
return (e.createElement(QuestionnaireChoiceDropDownInput, { name: name, item: item, initial: initial, onChangeAnswer: onChangeAnswer }));
|
|
4965
5029
|
}
|
|
4966
5030
|
else {
|
|
4967
|
-
return (
|
|
5031
|
+
return (e.createElement(QuestionnaireChoiceRadioInput, { name: name, item: item, initial: initial, onChangeAnswer: onChangeAnswer }));
|
|
4968
5032
|
}
|
|
4969
5033
|
}
|
|
4970
5034
|
return null;
|
|
@@ -4979,7 +5043,7 @@
|
|
|
4979
5043
|
data.push(typedValueToString(optionValue));
|
|
4980
5044
|
}
|
|
4981
5045
|
}
|
|
4982
|
-
return (
|
|
5046
|
+
return (e.createElement(core$1.NativeSelect, { id: name, name: name, onChange: (e) => {
|
|
4983
5047
|
const index = e.currentTarget.selectedIndex;
|
|
4984
5048
|
if (index === 0) {
|
|
4985
5049
|
props.onChangeAnswer({});
|
|
@@ -5020,14 +5084,14 @@
|
|
|
5020
5084
|
options.push([optionName, optionValue]);
|
|
5021
5085
|
}
|
|
5022
5086
|
}
|
|
5023
|
-
return (
|
|
5087
|
+
return (e.createElement(core$1.Radio.Group, { name: name, orientation: "vertical", defaultValue: defaultValue, onChange: (newValue) => {
|
|
5024
5088
|
const option = options.find((option) => option[0] === newValue);
|
|
5025
5089
|
if (option) {
|
|
5026
5090
|
const optionValue = option[1];
|
|
5027
5091
|
const propertyName = 'value' + core.capitalize(optionValue.type);
|
|
5028
5092
|
onChangeAnswer({ [propertyName]: optionValue.value });
|
|
5029
5093
|
}
|
|
5030
|
-
} }, options.map(([optionName, optionValue]) => (
|
|
5094
|
+
} }, options.map(([optionName, optionValue]) => (e.createElement(core$1.Radio, { key: optionName, id: optionName, value: optionName, label: e.createElement(ResourcePropertyDisplay, { property: valueElementDefinition, propertyType: optionValue.type, value: optionValue.value }) })))));
|
|
5031
5095
|
}
|
|
5032
5096
|
function buildInitialResponse(questionnaire) {
|
|
5033
5097
|
const response = {
|
|
@@ -5134,20 +5198,20 @@
|
|
|
5134
5198
|
function QuestionnaireBuilder(props) {
|
|
5135
5199
|
const medplum = useMedplum();
|
|
5136
5200
|
const defaultValue = useResource(props.questionnaire);
|
|
5137
|
-
const [schema, setSchema] =
|
|
5138
|
-
const [value, setValue] =
|
|
5139
|
-
const [selectedKey, setSelectedKey] =
|
|
5140
|
-
const [hoverKey, setHoverKey] =
|
|
5201
|
+
const [schema, setSchema] = e.useState();
|
|
5202
|
+
const [value, setValue] = e.useState();
|
|
5203
|
+
const [selectedKey, setSelectedKey] = e.useState();
|
|
5204
|
+
const [hoverKey, setHoverKey] = e.useState();
|
|
5141
5205
|
function handleDocumentMouseOver() {
|
|
5142
5206
|
setHoverKey(undefined);
|
|
5143
5207
|
}
|
|
5144
5208
|
function handleDocumentClick() {
|
|
5145
5209
|
setSelectedKey(undefined);
|
|
5146
5210
|
}
|
|
5147
|
-
|
|
5211
|
+
e.useEffect(() => {
|
|
5148
5212
|
medplum.requestSchema('Questionnaire').then(setSchema).catch(console.log);
|
|
5149
5213
|
}, [medplum]);
|
|
5150
|
-
|
|
5214
|
+
e.useEffect(() => {
|
|
5151
5215
|
setValue(ensureQuestionnaireKeys(defaultValue ?? { resourceType: 'Questionnaire' }));
|
|
5152
5216
|
document.addEventListener('mouseover', handleDocumentMouseOver);
|
|
5153
5217
|
document.addEventListener('click', handleDocumentClick);
|
|
@@ -5159,10 +5223,10 @@
|
|
|
5159
5223
|
if (!schema || !value) {
|
|
5160
5224
|
return null;
|
|
5161
5225
|
}
|
|
5162
|
-
return (
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5226
|
+
return (e.createElement("div", null,
|
|
5227
|
+
e.createElement(Form, { testid: "questionnaire-form", onSubmit: () => props.onSubmit(value) },
|
|
5228
|
+
e.createElement(ItemBuilder, { item: value, selectedKey: selectedKey, setSelectedKey: setSelectedKey, hoverKey: hoverKey, setHoverKey: setHoverKey, onChange: setValue }),
|
|
5229
|
+
e.createElement(core$1.Button, { type: "submit" }, "Save"))));
|
|
5166
5230
|
}
|
|
5167
5231
|
function ItemBuilder(props) {
|
|
5168
5232
|
const { classes, cx } = useStyles$4();
|
|
@@ -5173,7 +5237,7 @@
|
|
|
5173
5237
|
const linkId = item.linkId ?? '[untitled]';
|
|
5174
5238
|
const editing = props.selectedKey === props.item.id;
|
|
5175
5239
|
const hovering = props.hoverKey === props.item.id;
|
|
5176
|
-
const itemRef =
|
|
5240
|
+
const itemRef = e.useRef();
|
|
5177
5241
|
itemRef.current = props.item;
|
|
5178
5242
|
function onClick(e) {
|
|
5179
5243
|
killEvent(e);
|
|
@@ -5212,20 +5276,20 @@
|
|
|
5212
5276
|
[classes.editing]: editing,
|
|
5213
5277
|
[classes.hovering]: hovering && !editing,
|
|
5214
5278
|
});
|
|
5215
|
-
return (
|
|
5216
|
-
|
|
5217
|
-
isResource && (
|
|
5218
|
-
!isResource && (
|
|
5219
|
-
isChoiceQuestion(item) && (
|
|
5220
|
-
resource.title &&
|
|
5221
|
-
item.text &&
|
|
5222
|
-
!isContainer &&
|
|
5279
|
+
return (e.createElement("div", { "data-testid": item.linkId, className: className, onClick: onClick, onMouseOver: onHover },
|
|
5280
|
+
e.createElement("div", { className: classes.questionBody }, editing ? (e.createElement(e.Fragment, null,
|
|
5281
|
+
isResource && (e.createElement(core$1.TextInput, { size: "xl", defaultValue: resource.title, onChange: (e) => changeProperty('title', e.currentTarget.value) })),
|
|
5282
|
+
!isResource && (e.createElement(core$1.Textarea, { autosize: true, minRows: 2, defaultValue: item.text, onChange: (e) => changeProperty('text', e.currentTarget.value) })),
|
|
5283
|
+
isChoiceQuestion(item) && (e.createElement(AnswerBuilder, { options: item.answerOption, onChange: (newOptions) => changeProperty('answerOption', newOptions) })))) : (e.createElement(e.Fragment, null,
|
|
5284
|
+
resource.title && e.createElement(core$1.Title, null, resource.title),
|
|
5285
|
+
item.text && e.createElement("div", null, item.text),
|
|
5286
|
+
!isContainer && e.createElement(QuestionnaireFormItem, { item: item, answers: {}, onChange: () => undefined })))),
|
|
5223
5287
|
item.item &&
|
|
5224
|
-
item.item.map((i) => (
|
|
5225
|
-
|
|
5226
|
-
!isContainer && (
|
|
5227
|
-
|
|
5228
|
-
!isContainer && (
|
|
5288
|
+
item.item.map((i) => (e.createElement("div", { key: i.id },
|
|
5289
|
+
e.createElement(ItemBuilder, { item: i, selectedKey: props.selectedKey, setSelectedKey: props.setSelectedKey, hoverKey: props.hoverKey, setHoverKey: props.setHoverKey, onChange: changeItem, onRemove: () => removeItem(i) })))),
|
|
5290
|
+
!isContainer && (e.createElement("div", { className: classes.topActions }, editing ? (e.createElement(e.Fragment, null,
|
|
5291
|
+
e.createElement(core$1.TextInput, { size: "xs", className: classes.linkIdInput, defaultValue: item.linkId, onChange: (e) => changeProperty('linkId', e.currentTarget.value) }),
|
|
5292
|
+
!isContainer && (e.createElement(core$1.NativeSelect, { size: "xs", className: classes.typeSelect, defaultValue: item.type, onChange: (e) => changeProperty('type', e.currentTarget.value), data: [
|
|
5229
5293
|
{ value: 'display', label: 'Display' },
|
|
5230
5294
|
{ value: 'boolean', label: 'Boolean' },
|
|
5231
5295
|
{ value: 'decimal', label: 'Decimal' },
|
|
@@ -5241,10 +5305,10 @@
|
|
|
5241
5305
|
{ value: 'attachment', label: 'Attachment' },
|
|
5242
5306
|
{ value: 'reference', label: 'Reference' },
|
|
5243
5307
|
{ value: 'quantity', label: 'Quantity' },
|
|
5244
|
-
] })))) : (
|
|
5245
|
-
|
|
5246
|
-
isContainer && (
|
|
5247
|
-
|
|
5308
|
+
] })))) : (e.createElement("div", null, linkId)))),
|
|
5309
|
+
e.createElement("div", { className: classes.bottomActions },
|
|
5310
|
+
isContainer && (e.createElement(e.Fragment, null,
|
|
5311
|
+
e.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
5248
5312
|
e.preventDefault();
|
|
5249
5313
|
addItem({
|
|
5250
5314
|
id: generateId(),
|
|
@@ -5253,7 +5317,7 @@
|
|
|
5253
5317
|
text: 'Question',
|
|
5254
5318
|
});
|
|
5255
5319
|
} }, "Add item"),
|
|
5256
|
-
|
|
5320
|
+
e.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
5257
5321
|
e.preventDefault();
|
|
5258
5322
|
addItem({
|
|
5259
5323
|
id: generateId(),
|
|
@@ -5262,7 +5326,7 @@
|
|
|
5262
5326
|
text: 'Group',
|
|
5263
5327
|
});
|
|
5264
5328
|
} }, "Add group"))),
|
|
5265
|
-
editing && !isResource && (
|
|
5329
|
+
editing && !isResource && (e.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
5266
5330
|
e.preventDefault();
|
|
5267
5331
|
if (props.onRemove) {
|
|
5268
5332
|
props.onRemove();
|
|
@@ -5272,30 +5336,30 @@
|
|
|
5272
5336
|
function AnswerBuilder(props) {
|
|
5273
5337
|
const property = core.globalSchema.types['QuestionnaireItemAnswerOption'].properties['value[x]'];
|
|
5274
5338
|
const options = props.options ?? [];
|
|
5275
|
-
return (
|
|
5339
|
+
return (e.createElement("div", null,
|
|
5276
5340
|
options.map((option) => {
|
|
5277
5341
|
const [propertyValue, propertyType] = getValueAndType({ type: 'QuestionnaireItemAnswerOption', value: option }, 'value');
|
|
5278
|
-
return (
|
|
5342
|
+
return (e.createElement("div", { key: option.id, style: {
|
|
5279
5343
|
display: 'flex',
|
|
5280
5344
|
flexDirection: 'row',
|
|
5281
5345
|
justifyContent: 'space-between',
|
|
5282
5346
|
alignItems: 'center',
|
|
5283
5347
|
width: '80%',
|
|
5284
5348
|
} },
|
|
5285
|
-
|
|
5286
|
-
|
|
5349
|
+
e.createElement("div", null,
|
|
5350
|
+
e.createElement(ResourcePropertyInput, { key: option.id, name: "value[x]", property: property, defaultPropertyType: propertyType, defaultValue: propertyValue, onChange: (newValue, propName) => {
|
|
5287
5351
|
const newOptions = [...options];
|
|
5288
5352
|
const index = newOptions.findIndex((o) => o.id === option.id);
|
|
5289
5353
|
newOptions[index] = { id: option.id, [propName]: newValue };
|
|
5290
5354
|
props.onChange(newOptions);
|
|
5291
5355
|
} })),
|
|
5292
|
-
|
|
5293
|
-
|
|
5356
|
+
e.createElement("div", null,
|
|
5357
|
+
e.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
5294
5358
|
killEvent(e);
|
|
5295
5359
|
props.onChange(options.filter((o) => o.id !== option.id));
|
|
5296
5360
|
} }, "Remove"))));
|
|
5297
5361
|
}),
|
|
5298
|
-
|
|
5362
|
+
e.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
5299
5363
|
killEvent(e);
|
|
5300
5364
|
props.onChange([
|
|
5301
5365
|
...options,
|
|
@@ -5382,23 +5446,23 @@
|
|
|
5382
5446
|
function ReferenceRangeEditor(props) {
|
|
5383
5447
|
props = Object.assign(defaultProps, props);
|
|
5384
5448
|
const defaultDefinition = props.definition;
|
|
5385
|
-
const [intervalGroups, setIntervalGroups] =
|
|
5386
|
-
const [groupId, setGroupId] =
|
|
5387
|
-
const [intervalId, setIntervalId] =
|
|
5388
|
-
|
|
5449
|
+
const [intervalGroups, setIntervalGroups] = e.useState([]);
|
|
5450
|
+
const [groupId, setGroupId] = e.useState(1);
|
|
5451
|
+
const [intervalId, setIntervalId] = e.useState(1);
|
|
5452
|
+
e.useEffect(() => {
|
|
5389
5453
|
const definition = ensureQualifiedIntervalKeys(defaultDefinition, setIntervalId);
|
|
5390
5454
|
setIntervalGroups(groupQualifiedIntervals(definition.qualifiedInterval || [], setGroupId));
|
|
5391
5455
|
}, [defaultDefinition]);
|
|
5392
|
-
return (
|
|
5393
|
-
|
|
5394
|
-
|
|
5456
|
+
return (e.createElement(Form, { testid: "reference-range-editor", onSubmit: submitDefinition },
|
|
5457
|
+
e.createElement(core$1.Stack, null, intervalGroups.map((intervalGroup) => (e.createElement(ReferenceRangeGroupEditor, { unit: getUnitString(defaultDefinition.quantitativeDetails?.unit), onChange: changeInterval, onAdd: addInterval, onRemove: removeInterval, onRemoveGroup: removeGroup, key: `group-${intervalGroup.id}`, intervalGroup: intervalGroup })))),
|
|
5458
|
+
e.createElement(core$1.ActionIcon, { title: "Add Group", size: "sm", onClick: (e) => {
|
|
5395
5459
|
killEvent(e);
|
|
5396
5460
|
addGroup({ id: `group-id-${groupId}`, filters: {}, intervals: [] });
|
|
5397
5461
|
setGroupId((id) => id + 1);
|
|
5398
5462
|
} },
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5463
|
+
e.createElement(iS, null)),
|
|
5464
|
+
e.createElement(core$1.Group, { position: "right" },
|
|
5465
|
+
e.createElement(core$1.Button, { type: "submit" }, "Save"))));
|
|
5402
5466
|
/**
|
|
5403
5467
|
* Submit qualified intervals
|
|
5404
5468
|
*/
|
|
@@ -5462,31 +5526,31 @@
|
|
|
5462
5526
|
function ReferenceRangeGroupEditor(props) {
|
|
5463
5527
|
const { intervalGroup, unit } = props;
|
|
5464
5528
|
const { classes } = useStyles$3();
|
|
5465
|
-
return (
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5529
|
+
return (e.createElement(Container, { "data-testid": intervalGroup.id, className: classes.section },
|
|
5530
|
+
e.createElement(core$1.Stack, { spacing: 'lg' },
|
|
5531
|
+
e.createElement(core$1.Group, { position: "right" },
|
|
5532
|
+
e.createElement(core$1.ActionIcon, { title: "Remove Group", "data-testid": `remove-group-button-${intervalGroup.id}`, key: `remove-group-button-${intervalGroup.id}`, size: "sm", onClick: (e) => {
|
|
5469
5533
|
killEvent(e);
|
|
5470
5534
|
props.onRemoveGroup(intervalGroup);
|
|
5471
5535
|
} },
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
intervalGroup.intervals.map((interval) => (
|
|
5476
|
-
|
|
5477
|
-
|
|
5536
|
+
e.createElement(IP, null))),
|
|
5537
|
+
e.createElement(ReferenceRangeGroupFilters, { intervalGroup: intervalGroup, onChange: props.onChange }),
|
|
5538
|
+
e.createElement(core$1.Divider, null),
|
|
5539
|
+
intervalGroup.intervals.map((interval) => (e.createElement(core$1.Stack, { key: `interval-${interval.id}`, spacing: 'xs' },
|
|
5540
|
+
e.createElement(core$1.Group, null,
|
|
5541
|
+
e.createElement(core$1.TextInput, { key: `condition-${interval.id}`, "data-testid": `condition-${interval.id}`, defaultValue: interval.condition, label: 'Condition: ', size: 'sm', onChange: (e) => {
|
|
5478
5542
|
killEvent(e);
|
|
5479
5543
|
props.onChange(intervalGroup.id, { ...interval, condition: e.currentTarget.value.trim() });
|
|
5480
5544
|
} }),
|
|
5481
|
-
|
|
5545
|
+
e.createElement(core$1.ActionIcon, { title: "Remove Interval", size: "sm", key: `remove-interval-${interval.id}`, "data-testid": `remove-interval-${interval.id}`, onClick: (e) => {
|
|
5482
5546
|
killEvent(e);
|
|
5483
5547
|
props.onRemove(intervalGroup.id, interval);
|
|
5484
5548
|
} },
|
|
5485
|
-
|
|
5486
|
-
|
|
5549
|
+
e.createElement(IP, null))),
|
|
5550
|
+
e.createElement(RangeInput, { onChange: (range) => {
|
|
5487
5551
|
props.onChange(intervalGroup.id, { ...interval, range });
|
|
5488
5552
|
}, key: `range-${interval.id}`, name: `range-${interval.id}`, defaultValue: interval.range })))),
|
|
5489
|
-
|
|
5553
|
+
e.createElement(core$1.ActionIcon, { title: "Add Interval", size: "sm", onClick: (e) => {
|
|
5490
5554
|
killEvent(e);
|
|
5491
5555
|
props.onAdd(intervalGroup.id, {
|
|
5492
5556
|
range: {
|
|
@@ -5495,7 +5559,7 @@
|
|
|
5495
5559
|
},
|
|
5496
5560
|
});
|
|
5497
5561
|
} },
|
|
5498
|
-
|
|
5562
|
+
e.createElement(iS, null)))));
|
|
5499
5563
|
}
|
|
5500
5564
|
/**
|
|
5501
5565
|
* Render the "filters" section of the IntervalGroup. Also populates some initial
|
|
@@ -5515,9 +5579,9 @@
|
|
|
5515
5579
|
};
|
|
5516
5580
|
}
|
|
5517
5581
|
}
|
|
5518
|
-
return (
|
|
5519
|
-
|
|
5520
|
-
|
|
5582
|
+
return (e.createElement(core$1.Stack, { style: { maxWidth: '50%' } },
|
|
5583
|
+
e.createElement(core$1.Group, null,
|
|
5584
|
+
e.createElement(core$1.NativeSelect, { data: ['', 'male', 'female'], label: "Gender:", defaultValue: intervalGroup.filters.gender || '', onChange: (e) => {
|
|
5521
5585
|
for (const interval of intervalGroup.intervals) {
|
|
5522
5586
|
let newGender = e.currentTarget?.value;
|
|
5523
5587
|
if (newGender === '') {
|
|
@@ -5529,15 +5593,15 @@
|
|
|
5529
5593
|
});
|
|
5530
5594
|
}
|
|
5531
5595
|
} })),
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5596
|
+
e.createElement(core$1.Group, { spacing: 'xs' },
|
|
5597
|
+
e.createElement(core$1.Text, { component: "label", htmlFor: `div-age-${intervalGroup.id}` }, "Age:"),
|
|
5598
|
+
e.createElement("div", { id: `div-age-${intervalGroup.id}` },
|
|
5599
|
+
e.createElement(RangeInput, { key: `age-${intervalGroup.id}`, name: `age-${intervalGroup.id}`, defaultValue: intervalGroup.filters['age'], onChange: (ageRange) => {
|
|
5536
5600
|
for (const interval of intervalGroup.intervals) {
|
|
5537
5601
|
onChange(intervalGroup.id, { ...interval, age: ageRange });
|
|
5538
5602
|
}
|
|
5539
5603
|
} }))),
|
|
5540
|
-
|
|
5604
|
+
e.createElement(core$1.NativeSelect, { data: ['', 'pre-puberty', 'follicular', 'midcycle', 'luteal', 'postmenopausal'], label: "Endocrine:", defaultValue: intervalGroup.filters.context?.text || '', onChange: (e) => {
|
|
5541
5605
|
for (const interval of intervalGroup.intervals) {
|
|
5542
5606
|
let newEndocrine = e.currentTarget?.value;
|
|
5543
5607
|
if (newEndocrine === '') {
|
|
@@ -5630,9 +5694,9 @@
|
|
|
5630
5694
|
function RequestGroupDisplay(props) {
|
|
5631
5695
|
const medplum = useMedplum();
|
|
5632
5696
|
const requestGroup = useResource(props.value);
|
|
5633
|
-
const [startedLoading, setStartedLoading] =
|
|
5634
|
-
const [responseBundle, setResponseBundle] =
|
|
5635
|
-
|
|
5697
|
+
const [startedLoading, setStartedLoading] = e.useState(false);
|
|
5698
|
+
const [responseBundle, setResponseBundle] = e.useState();
|
|
5699
|
+
e.useEffect(() => {
|
|
5636
5700
|
if (requestGroup && !startedLoading) {
|
|
5637
5701
|
medplum.executeBatch(buildBatchRequest(requestGroup)).then(setResponseBundle).catch(console.log);
|
|
5638
5702
|
setStartedLoading(true);
|
|
@@ -5641,26 +5705,26 @@
|
|
|
5641
5705
|
if (!requestGroup || !responseBundle) {
|
|
5642
5706
|
return null;
|
|
5643
5707
|
}
|
|
5644
|
-
return (
|
|
5708
|
+
return (e.createElement(core$1.Grid, null, requestGroup.action?.map((action, index) => {
|
|
5645
5709
|
const task = action.resource && findBundleEntry(action.resource);
|
|
5646
5710
|
const taskInput = task?.input?.[0]?.valueReference;
|
|
5647
5711
|
const taskOutput = task?.output?.[0]?.valueReference;
|
|
5648
|
-
return (
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
action.description &&
|
|
5653
|
-
|
|
5712
|
+
return (e.createElement(e.Fragment, { key: `action-${index}` },
|
|
5713
|
+
e.createElement(core$1.Grid.Col, { span: 1, p: "md" }, task?.status === 'completed' ? e.createElement(GW, null) : e.createElement(RSe, { color: "gray" })),
|
|
5714
|
+
e.createElement(core$1.Grid.Col, { span: 9, p: "xs" },
|
|
5715
|
+
e.createElement(core$1.Text, { weight: 500 }, action.title),
|
|
5716
|
+
action.description && e.createElement("div", null, action.description),
|
|
5717
|
+
e.createElement("div", null,
|
|
5654
5718
|
"Last edited by\u00A0",
|
|
5655
|
-
|
|
5719
|
+
e.createElement(ResourceName, { value: task?.meta?.author }),
|
|
5656
5720
|
"\u00A0on\u00A0",
|
|
5657
5721
|
core.formatDateTime(task?.meta?.lastUpdated)),
|
|
5658
|
-
|
|
5722
|
+
e.createElement("div", null,
|
|
5659
5723
|
"Status: ",
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
taskInput && !taskOutput &&
|
|
5663
|
-
taskInput && taskOutput && (
|
|
5724
|
+
e.createElement(StatusBadge, { status: task?.status || 'unknown' }))),
|
|
5725
|
+
e.createElement(core$1.Grid.Col, { span: 2, p: "md" },
|
|
5726
|
+
taskInput && !taskOutput && e.createElement(core$1.Button, { onClick: () => props.onStart(task, taskInput) }, "Start"),
|
|
5727
|
+
taskInput && taskOutput && (e.createElement(core$1.Button, { onClick: () => props.onEdit(task, taskInput, taskOutput) }, "Edit")))));
|
|
5664
5728
|
})));
|
|
5665
5729
|
function buildBatchRequest(request) {
|
|
5666
5730
|
const batchEntries = [];
|
|
@@ -5920,28 +5984,28 @@
|
|
|
5920
5984
|
function ResourceBlame(props) {
|
|
5921
5985
|
const { classes } = useStyles$2();
|
|
5922
5986
|
const medplum = useMedplum();
|
|
5923
|
-
const [value, setValue] =
|
|
5924
|
-
|
|
5987
|
+
const [value, setValue] = e.useState(props.history);
|
|
5988
|
+
e.useEffect(() => {
|
|
5925
5989
|
if (!props.history && props.resourceType && props.id) {
|
|
5926
5990
|
medplum.readHistory(props.resourceType, props.id).then(setValue).catch(console.log);
|
|
5927
5991
|
}
|
|
5928
5992
|
}, [medplum, props.history, props.resourceType, props.id]);
|
|
5929
5993
|
if (!value) {
|
|
5930
|
-
return
|
|
5994
|
+
return e.createElement("div", null, "Loading...");
|
|
5931
5995
|
}
|
|
5932
5996
|
const resource = value.entry?.[0]?.resource;
|
|
5933
5997
|
const table = blame(value);
|
|
5934
|
-
return (
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
row.span > 0 && (
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5998
|
+
return (e.createElement("div", { className: classes.container },
|
|
5999
|
+
e.createElement("table", { className: classes.root },
|
|
6000
|
+
e.createElement("tbody", null, table.map((row, index) => (e.createElement("tr", { key: 'row-' + index, className: row.span > 0 ? classes.startRow : classes.normalRow },
|
|
6001
|
+
row.span > 0 && (e.createElement(e.Fragment, null,
|
|
6002
|
+
e.createElement("td", { className: classes.author, rowSpan: row.span },
|
|
6003
|
+
e.createElement(ResourceBadge, { value: row.meta.author, link: true })),
|
|
6004
|
+
e.createElement("td", { className: classes.dateTime, rowSpan: row.span },
|
|
6005
|
+
e.createElement(MedplumLink, { to: getVersionUrl$1(resource, row.meta.versionId) }, getTimeString(row.meta.lastUpdated))))),
|
|
6006
|
+
e.createElement("td", { className: classes.lineNumber }, index + 1),
|
|
6007
|
+
e.createElement("td", { className: classes.line },
|
|
6008
|
+
e.createElement("pre", { className: classes.pre }, row.value)))))))));
|
|
5945
6009
|
}
|
|
5946
6010
|
function getVersionUrl$1(resource, versionId) {
|
|
5947
6011
|
return `/${resource.resourceType}/${resource.id}/_history/${versionId}`;
|
|
@@ -5993,23 +6057,23 @@
|
|
|
5993
6057
|
const original = core.stringify(originalResource, true).match(/[^\r\n]+/g);
|
|
5994
6058
|
const revised = core.stringify(revisedResource, true).match(/[^\r\n]+/g);
|
|
5995
6059
|
const deltas = diff(original, revised);
|
|
5996
|
-
return (
|
|
6060
|
+
return (e.createElement("pre", { style: { color: 'gray' } }, deltas.map((delta, index) => (e.createElement(ChangeDiff, { key: 'delta' + index, delta: delta })))));
|
|
5997
6061
|
}
|
|
5998
6062
|
function ChangeDiff(props) {
|
|
5999
6063
|
const { classes } = useStyles$1();
|
|
6000
|
-
return (
|
|
6064
|
+
return (e.createElement(e.Fragment, null,
|
|
6001
6065
|
"...",
|
|
6002
|
-
|
|
6003
|
-
props.delta.original.lines.length > 0 && (
|
|
6004
|
-
props.delta.revised.lines.length > 0 && (
|
|
6066
|
+
e.createElement("br", null),
|
|
6067
|
+
props.delta.original.lines.length > 0 && (e.createElement("div", { className: classes.removed }, props.delta.original.lines.join('\n'))),
|
|
6068
|
+
props.delta.revised.lines.length > 0 && (e.createElement("div", { className: classes.added }, props.delta.revised.lines.join('\n'))),
|
|
6005
6069
|
"...",
|
|
6006
|
-
|
|
6070
|
+
e.createElement("br", null)));
|
|
6007
6071
|
}
|
|
6008
6072
|
|
|
6009
6073
|
function ResourceHistoryTable(props) {
|
|
6010
6074
|
const medplum = useMedplum();
|
|
6011
|
-
const [value, setValue] =
|
|
6012
|
-
|
|
6075
|
+
const [value, setValue] = e.useState(props.history);
|
|
6076
|
+
e.useEffect(() => {
|
|
6013
6077
|
if (!props.history && props.resourceType && props.id) {
|
|
6014
6078
|
medplum
|
|
6015
6079
|
.readHistory(props.resourceType, props.id)
|
|
@@ -6018,29 +6082,29 @@
|
|
|
6018
6082
|
}
|
|
6019
6083
|
}, [medplum, props.history, props.resourceType, props.id]);
|
|
6020
6084
|
if (!value) {
|
|
6021
|
-
return
|
|
6085
|
+
return e.createElement("div", null, "Loading...");
|
|
6022
6086
|
}
|
|
6023
|
-
return (
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6087
|
+
return (e.createElement(core$1.Table, { withBorder: true, withColumnBorders: true },
|
|
6088
|
+
e.createElement("thead", null,
|
|
6089
|
+
e.createElement("tr", null,
|
|
6090
|
+
e.createElement("th", null, "Author"),
|
|
6091
|
+
e.createElement("th", null, "Date"),
|
|
6092
|
+
e.createElement("th", null, "Version"))),
|
|
6093
|
+
e.createElement("tbody", null, value.entry?.map((entry, index) => (e.createElement(HistoryRow, { key: 'entry-' + index, entry: entry }))))));
|
|
6030
6094
|
}
|
|
6031
6095
|
function HistoryRow(props) {
|
|
6032
6096
|
const { response, resource } = props.entry;
|
|
6033
6097
|
if (resource) {
|
|
6034
|
-
return (
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6098
|
+
return (e.createElement("tr", null,
|
|
6099
|
+
e.createElement("td", null,
|
|
6100
|
+
e.createElement(ResourceBadge, { value: resource.meta?.author, link: true })),
|
|
6101
|
+
e.createElement("td", null, core.formatDateTime(resource.meta?.lastUpdated)),
|
|
6102
|
+
e.createElement("td", null,
|
|
6103
|
+
e.createElement(MedplumLink, { to: getVersionUrl(resource) }, resource.meta?.versionId))));
|
|
6040
6104
|
}
|
|
6041
6105
|
else {
|
|
6042
|
-
return (
|
|
6043
|
-
|
|
6106
|
+
return (e.createElement("tr", null,
|
|
6107
|
+
e.createElement("td", { colSpan: 3 }, core.normalizeErrorString(response?.outcome))));
|
|
6044
6108
|
}
|
|
6045
6109
|
}
|
|
6046
6110
|
function getVersionUrl(resource) {
|
|
@@ -6067,14 +6131,14 @@
|
|
|
6067
6131
|
const medplum = useMedplum();
|
|
6068
6132
|
const schedule = useResource(props.schedule);
|
|
6069
6133
|
const questionnaire = useResource(props.questionnaire);
|
|
6070
|
-
const [slots, setSlots] =
|
|
6071
|
-
const slotsRef =
|
|
6134
|
+
const [slots, setSlots] = e.useState();
|
|
6135
|
+
const slotsRef = e.useRef();
|
|
6072
6136
|
slotsRef.current = slots;
|
|
6073
|
-
const [month, setMonth] =
|
|
6074
|
-
const [date, setDate] =
|
|
6075
|
-
const [slot, setSlot] =
|
|
6076
|
-
const [response, setResponse] =
|
|
6077
|
-
|
|
6137
|
+
const [month, setMonth] = e.useState(getStartMonth());
|
|
6138
|
+
const [date, setDate] = e.useState();
|
|
6139
|
+
const [slot, setSlot] = e.useState();
|
|
6140
|
+
const [response, setResponse] = e.useState();
|
|
6141
|
+
e.useEffect(() => {
|
|
6078
6142
|
if (schedule) {
|
|
6079
6143
|
setSlots([]);
|
|
6080
6144
|
medplum
|
|
@@ -6095,30 +6159,30 @@
|
|
|
6095
6159
|
return null;
|
|
6096
6160
|
}
|
|
6097
6161
|
const actor = schedule.actor?.[0];
|
|
6098
|
-
return (
|
|
6099
|
-
|
|
6100
|
-
actor &&
|
|
6101
|
-
actor && (
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
date &&
|
|
6105
|
-
slot &&
|
|
6106
|
-
|
|
6107
|
-
!date && (
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
date && !slot && (
|
|
6111
|
-
|
|
6112
|
-
|
|
6162
|
+
return (e.createElement("div", { className: classes.container, "data-testid": "scheduler" },
|
|
6163
|
+
e.createElement("div", { className: classes.info },
|
|
6164
|
+
actor && e.createElement(ResourceAvatar, { value: actor, size: "xl" }),
|
|
6165
|
+
actor && (e.createElement(core$1.Text, { size: "xl", weight: 500 },
|
|
6166
|
+
e.createElement(ResourceName, { value: actor }))),
|
|
6167
|
+
e.createElement("p", null, "1 hour"),
|
|
6168
|
+
date && e.createElement("p", null, date.toLocaleDateString()),
|
|
6169
|
+
slot && e.createElement("p", null, formatTime(new Date(slot.start)))),
|
|
6170
|
+
e.createElement("div", { className: classes.selection },
|
|
6171
|
+
!date && (e.createElement("div", null,
|
|
6172
|
+
e.createElement("h3", null, "Select date"),
|
|
6173
|
+
e.createElement(CalendarInput, { slots: slots, onChangeMonth: setMonth, onClick: setDate }))),
|
|
6174
|
+
date && !slot && (e.createElement("div", null,
|
|
6175
|
+
e.createElement("h3", null, "Select time"),
|
|
6176
|
+
e.createElement(core$1.Stack, null, slots.map((s) => {
|
|
6113
6177
|
const slotStart = new Date(s.start);
|
|
6114
6178
|
return (slotStart.getTime() > date.getTime() &&
|
|
6115
|
-
slotStart.getTime() < date.getTime() + 24 * 3600 * 1000 && (
|
|
6116
|
-
|
|
6179
|
+
slotStart.getTime() < date.getTime() + 24 * 3600 * 1000 && (e.createElement("div", { key: s.id },
|
|
6180
|
+
e.createElement(core$1.Button, { variant: "outline", style: { width: 150 }, onClick: () => setSlot(s) }, formatTime(slotStart)))));
|
|
6117
6181
|
})))),
|
|
6118
|
-
date && slot && !response && (
|
|
6119
|
-
date && slot && response && (
|
|
6120
|
-
|
|
6121
|
-
|
|
6182
|
+
date && slot && !response && (e.createElement(QuestionnaireForm, { questionnaire: questionnaire, submitButtonText: 'Next', onSubmit: setResponse })),
|
|
6183
|
+
date && slot && response && (e.createElement("div", null,
|
|
6184
|
+
e.createElement("h3", null, "You're all set!"),
|
|
6185
|
+
e.createElement("p", null, "Check your email for a calendar invite."))))));
|
|
6122
6186
|
}
|
|
6123
6187
|
function getStart(month) {
|
|
6124
6188
|
return formatSlotInstant(month.getTime());
|
|
@@ -6134,7 +6198,7 @@
|
|
|
6134
6198
|
}
|
|
6135
6199
|
|
|
6136
6200
|
function ServiceRequestTimeline(props) {
|
|
6137
|
-
return (
|
|
6201
|
+
return (e.createElement(ResourceTimeline, { value: props.serviceRequest, loadTimelineResources: async (medplum, resource) => {
|
|
6138
6202
|
return Promise.all([
|
|
6139
6203
|
medplum.readHistory('ServiceRequest', resource.id),
|
|
6140
6204
|
medplum.search('Communication', 'based-on=' + core.getReferenceString(resource)),
|
|
@@ -6294,6 +6358,7 @@
|
|
|
6294
6358
|
exports.toggleSort = toggleSort;
|
|
6295
6359
|
exports.useMedplum = useMedplum;
|
|
6296
6360
|
exports.useMedplumContext = useMedplumContext;
|
|
6361
|
+
exports.useMedplumNavigate = useMedplumNavigate;
|
|
6297
6362
|
exports.useMedplumProfile = useMedplumProfile;
|
|
6298
6363
|
exports.useResource = useResource;
|
|
6299
6364
|
|