@medplum/react 1.0.1 → 1.0.3
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/CodeableConceptDisplay/CodeableConceptDisplay.d.ts +1 -1
- package/dist/cjs/ReferenceRangeEditor/ReferenceRangeEditor.d.ts +1 -1
- package/dist/cjs/index.d.ts +11 -0
- package/dist/cjs/index.js +399 -409
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +1 -1
- package/dist/cjs/index.min.js.map +1 -1
- package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.d.ts +1 -1
- package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.js +2 -14
- package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.js.map +1 -1
- package/dist/esm/CodingDisplay/CodingDisplay.js +2 -2
- package/dist/esm/CodingDisplay/CodingDisplay.js.map +1 -1
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.js +2 -15
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.js.map +1 -1
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.d.ts +1 -1
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.js +1 -0
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.js.map +1 -1
- package/dist/esm/ResourceTimeline/ResourceTimeline.js +1 -1
- package/dist/esm/ResourceTimeline/ResourceTimeline.js.map +1 -1
- package/dist/esm/auth/NewUserForm.js +1 -0
- package/dist/esm/auth/NewUserForm.js.map +1 -1
- package/dist/esm/index.d.ts +11 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +1 -1
- package/dist/esm/index.min.js.map +1 -1
- package/dist/esm/node_modules/tslib/tslib.es6.js.map +1 -1
- package/package.json +13 -13
package/dist/cjs/index.js
CHANGED
|
@@ -64,28 +64,6 @@
|
|
|
64
64
|
React.createElement(core$1.TextInput, { placeholder: "Postal Code", defaultValue: value.postalCode, onChange: (e) => setPostalCode(e.currentTarget.value) })));
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
function AttachmentDisplay(props) {
|
|
68
|
-
const value = props.value;
|
|
69
|
-
const { contentType, url, title } = value !== null && value !== void 0 ? value : {};
|
|
70
|
-
if (!url) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
return (React.createElement("div", { "data-testid": "attachment-display" },
|
|
74
|
-
(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image/')) && (React.createElement("img", { "data-testid": "attachment-image", style: { maxWidth: props.maxWidth }, src: url, alt: value === null || value === void 0 ? void 0 : value.title })),
|
|
75
|
-
(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('video/')) && (React.createElement("video", { "data-testid": "attachment-video", style: { maxWidth: props.maxWidth }, controls: true },
|
|
76
|
-
React.createElement("source", { type: contentType, src: url }))),
|
|
77
|
-
contentType === 'application/pdf' && !(title === null || title === void 0 ? void 0 : title.endsWith('.pdf')) && (React.createElement("div", { "data-testid": "attachment-pdf", style: { maxWidth: props.maxWidth, minHeight: 400 } },
|
|
78
|
-
React.createElement("iframe", { width: "100%", height: "400", src: url + '#navpanes=0', allowFullScreen: true, frameBorder: 0, seamless: true }))),
|
|
79
|
-
React.createElement("div", { "data-testid": "download-link", style: { padding: '2px 16px 16px 16px' } },
|
|
80
|
-
React.createElement("a", { href: value === null || value === void 0 ? void 0 : value.url, "data-testid": "attachment-details", target: "_blank", rel: "noopener noreferrer" }, (value === null || value === void 0 ? void 0 : value.title) || 'Download'))));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function AttachmentArrayDisplay(props) {
|
|
84
|
-
return (React.createElement("div", null, props.values &&
|
|
85
|
-
props.values.map((v, index) => (React.createElement("div", { key: 'attatchment-' + index },
|
|
86
|
-
React.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
67
|
const reactContext = React.createContext(undefined);
|
|
90
68
|
/**
|
|
91
69
|
* The MedplumProvider component provides Medplum context state.
|
|
@@ -132,6 +110,49 @@
|
|
|
132
110
|
return useMedplumContext().profile;
|
|
133
111
|
}
|
|
134
112
|
|
|
113
|
+
function AnnotationInput(props) {
|
|
114
|
+
const author = useMedplumProfile();
|
|
115
|
+
const [value, setValue] = React.useState(props.defaultValue || {});
|
|
116
|
+
const valueRef = React.useRef();
|
|
117
|
+
valueRef.current = value;
|
|
118
|
+
function setText(text) {
|
|
119
|
+
const newValue = text
|
|
120
|
+
? {
|
|
121
|
+
text,
|
|
122
|
+
authorReference: author && core.createReference(author),
|
|
123
|
+
time: new Date().toISOString(),
|
|
124
|
+
}
|
|
125
|
+
: {};
|
|
126
|
+
setValue(newValue);
|
|
127
|
+
if (props.onChange) {
|
|
128
|
+
props.onChange(newValue);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return (React.createElement(core$1.TextInput, { name: props.name, placeholder: "Annotation text", defaultValue: value.text, onChange: (e) => setText(e.currentTarget.value) }));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function AttachmentDisplay(props) {
|
|
135
|
+
const value = props.value;
|
|
136
|
+
const { contentType, url, title } = value !== null && value !== void 0 ? value : {};
|
|
137
|
+
if (!url) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
return (React.createElement("div", { "data-testid": "attachment-display" },
|
|
141
|
+
(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image/')) && (React.createElement("img", { "data-testid": "attachment-image", style: { maxWidth: props.maxWidth }, src: url, alt: value === null || value === void 0 ? void 0 : value.title })),
|
|
142
|
+
(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('video/')) && (React.createElement("video", { "data-testid": "attachment-video", style: { maxWidth: props.maxWidth }, controls: true },
|
|
143
|
+
React.createElement("source", { type: contentType, src: url }))),
|
|
144
|
+
contentType === 'application/pdf' && !(title === null || title === void 0 ? void 0 : title.endsWith('.pdf')) && (React.createElement("div", { "data-testid": "attachment-pdf", style: { maxWidth: props.maxWidth, minHeight: 400 } },
|
|
145
|
+
React.createElement("iframe", { width: "100%", height: "400", src: url + '#navpanes=0', allowFullScreen: true, frameBorder: 0, seamless: true }))),
|
|
146
|
+
React.createElement("div", { "data-testid": "download-link", style: { padding: '2px 16px 16px 16px' } },
|
|
147
|
+
React.createElement("a", { href: value === null || value === void 0 ? void 0 : value.url, "data-testid": "attachment-details", target: "_blank", rel: "noopener noreferrer" }, (value === null || value === void 0 ? void 0 : value.title) || 'Download'))));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function AttachmentArrayDisplay(props) {
|
|
151
|
+
return (React.createElement("div", null, props.values &&
|
|
152
|
+
props.values.map((v, index) => (React.createElement("div", { key: 'attatchment-' + index },
|
|
153
|
+
React.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
|
|
154
|
+
}
|
|
155
|
+
|
|
135
156
|
/**
|
|
136
157
|
* Kills a browser event.
|
|
137
158
|
* Prevents default behavior.
|
|
@@ -557,6 +578,7 @@
|
|
|
557
578
|
React.createElement(core$1.Group, { position: "center", p: "xl", style: { height: 70 } },
|
|
558
579
|
React.createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) => __awaiter(this, void 0, void 0, function* () {
|
|
559
580
|
try {
|
|
581
|
+
yield medplum.startPkce();
|
|
560
582
|
props.handleAuthResponse(yield medplum.startGoogleLogin({
|
|
561
583
|
googleClientId: response.clientId,
|
|
562
584
|
googleCredential: response.credential,
|
|
@@ -768,13 +790,6 @@
|
|
|
768
790
|
})()));
|
|
769
791
|
}
|
|
770
792
|
|
|
771
|
-
function CheckboxFormSection(props) {
|
|
772
|
-
return (React.createElement(core$1.Group, { noWrap: true },
|
|
773
|
-
React.createElement("div", null, props.children),
|
|
774
|
-
React.createElement("div", null,
|
|
775
|
-
React.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description }, (() => null)()))));
|
|
776
|
-
}
|
|
777
|
-
|
|
778
793
|
const DEFAULT_IGNORED_PROPERTIES = [
|
|
779
794
|
'meta',
|
|
780
795
|
'implicitRules',
|
|
@@ -785,116 +800,6 @@
|
|
|
785
800
|
'modifierExtension',
|
|
786
801
|
];
|
|
787
802
|
|
|
788
|
-
function FormSection(props) {
|
|
789
|
-
return (React.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description, error: getErrorsForInput(props.outcome, props.htmlFor) }, props.children));
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
const system = {
|
|
793
|
-
resourceType: 'Device',
|
|
794
|
-
id: 'system',
|
|
795
|
-
deviceName: [
|
|
796
|
-
{
|
|
797
|
-
name: 'System',
|
|
798
|
-
},
|
|
799
|
-
],
|
|
800
|
-
};
|
|
801
|
-
/**
|
|
802
|
-
* React Hook to use a FHIR reference.
|
|
803
|
-
* Handles the complexity of resolving references and caching resources.
|
|
804
|
-
* @param value The resource or reference to resource.
|
|
805
|
-
* @returns The resolved resource.
|
|
806
|
-
*/
|
|
807
|
-
function useResource(value) {
|
|
808
|
-
const medplum = useMedplum();
|
|
809
|
-
const [resource, setResource] = React.useState(getInitialResource(medplum, value));
|
|
810
|
-
React.useEffect(() => {
|
|
811
|
-
let subscribed = true;
|
|
812
|
-
if (!resource && value && 'reference' in value && value.reference) {
|
|
813
|
-
medplum
|
|
814
|
-
.readReference(value)
|
|
815
|
-
.then((r) => {
|
|
816
|
-
if (subscribed) {
|
|
817
|
-
setResource(r);
|
|
818
|
-
}
|
|
819
|
-
})
|
|
820
|
-
.catch(() => setResource(undefined));
|
|
821
|
-
}
|
|
822
|
-
return (() => (subscribed = false));
|
|
823
|
-
}, [medplum, resource, value]);
|
|
824
|
-
return resource;
|
|
825
|
-
}
|
|
826
|
-
/**
|
|
827
|
-
* Returns the initial resource value based on the input value.
|
|
828
|
-
* If the input value is a resource, returns the resource.
|
|
829
|
-
* If the input value is a reference to system, returns the system resource.
|
|
830
|
-
* If the input value is a reference to a resource available in the cache, returns the resource.
|
|
831
|
-
* Otherwise, returns undefined.
|
|
832
|
-
* @param medplum The medplum client.
|
|
833
|
-
* @param value The resource or reference to resource.
|
|
834
|
-
* @returns An initial resource if available; undefined otherwise.
|
|
835
|
-
*/
|
|
836
|
-
function getInitialResource(medplum, value) {
|
|
837
|
-
if (!value) {
|
|
838
|
-
return undefined;
|
|
839
|
-
}
|
|
840
|
-
if ('resourceType' in value) {
|
|
841
|
-
return value;
|
|
842
|
-
}
|
|
843
|
-
if ('reference' in value) {
|
|
844
|
-
if (value.reference === 'system') {
|
|
845
|
-
return system;
|
|
846
|
-
}
|
|
847
|
-
return medplum.getCachedReference(value);
|
|
848
|
-
}
|
|
849
|
-
return undefined;
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
function ResourceForm(props) {
|
|
853
|
-
const medplum = useMedplum();
|
|
854
|
-
const defaultValue = useResource(props.defaultValue);
|
|
855
|
-
const [schema, setSchema] = React.useState();
|
|
856
|
-
const [value, setValue] = React.useState();
|
|
857
|
-
React.useEffect(() => {
|
|
858
|
-
if (defaultValue) {
|
|
859
|
-
setValue(JSON.parse(JSON.stringify(defaultValue)));
|
|
860
|
-
medplum.requestSchema(defaultValue.resourceType).then(setSchema).catch(console.log);
|
|
861
|
-
}
|
|
862
|
-
}, [medplum, defaultValue]);
|
|
863
|
-
if (!schema || !value) {
|
|
864
|
-
return React.createElement("div", null, "Loading...");
|
|
865
|
-
}
|
|
866
|
-
return (React.createElement("form", { noValidate: true, autoComplete: "off", onSubmit: (e) => {
|
|
867
|
-
e.preventDefault();
|
|
868
|
-
if (props.onSubmit) {
|
|
869
|
-
props.onSubmit(value);
|
|
870
|
-
}
|
|
871
|
-
} },
|
|
872
|
-
React.createElement(core$1.Stack, { mb: "xl" },
|
|
873
|
-
React.createElement(FormSection, { title: "Resource Type", htmlFor: "resourceType", outcome: props.outcome },
|
|
874
|
-
React.createElement(core$1.TextInput, { name: "resourceType", defaultValue: value.resourceType, disabled: true })),
|
|
875
|
-
React.createElement(FormSection, { title: "ID", htmlFor: "id", outcome: props.outcome },
|
|
876
|
-
React.createElement(core$1.TextInput, { name: "id", defaultValue: value.id, disabled: true }))),
|
|
877
|
-
React.createElement(BackboneElementInput, { typeName: value.resourceType, defaultValue: value, outcome: props.outcome, onChange: setValue }),
|
|
878
|
-
React.createElement(core$1.Group, { position: "right", mt: "xl" },
|
|
879
|
-
React.createElement(core$1.Button, { type: "submit" }, "OK"),
|
|
880
|
-
props.onDelete && (React.createElement(core$1.Button, { variant: "outline", color: "red", type: "button", onClick: () => {
|
|
881
|
-
props.onDelete(value);
|
|
882
|
-
} }, "Delete")))));
|
|
883
|
-
}
|
|
884
|
-
function setPropertyValue(obj, key, propName, elementDefinition, value) {
|
|
885
|
-
const types = elementDefinition.type;
|
|
886
|
-
if (types.length > 1) {
|
|
887
|
-
for (const type of types) {
|
|
888
|
-
const compoundKey = key.replace('[x]', core.capitalize(type.code));
|
|
889
|
-
if (compoundKey in obj) {
|
|
890
|
-
delete obj[compoundKey];
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
obj[propName] = value;
|
|
895
|
-
return obj;
|
|
896
|
-
}
|
|
897
|
-
|
|
898
803
|
const useStyles$b = core$1.createStyles((theme) => ({
|
|
899
804
|
root: {
|
|
900
805
|
display: 'grid',
|
|
@@ -925,63 +830,12 @@
|
|
|
925
830
|
React.createElement("dd", null, props.children)));
|
|
926
831
|
}
|
|
927
832
|
|
|
928
|
-
function
|
|
929
|
-
|
|
930
|
-
const value = typedValue.value;
|
|
931
|
-
if (!value) {
|
|
932
|
-
return null;
|
|
933
|
-
}
|
|
934
|
-
const typeName = typedValue.type;
|
|
935
|
-
const typeSchema = core.globalSchema.types[typeName];
|
|
936
|
-
if (!typeSchema) {
|
|
937
|
-
return React.createElement("div", null,
|
|
938
|
-
typeName,
|
|
939
|
-
"\u00A0not implemented");
|
|
940
|
-
}
|
|
941
|
-
if (typeof value === 'object' &&
|
|
942
|
-
'name' in value &&
|
|
943
|
-
Object.keys(value).length === 1 &&
|
|
944
|
-
typeof value.name === 'string') {
|
|
945
|
-
// Special case for common BackboneElement pattern
|
|
946
|
-
// Where there is an object with a single property 'name'
|
|
947
|
-
// Just display the name value.
|
|
948
|
-
return React.createElement("div", null, value.name);
|
|
949
|
-
}
|
|
950
|
-
return (React.createElement(DescriptionList, { compact: props.compact }, Object.entries(typeSchema.properties).map((entry) => {
|
|
951
|
-
const key = entry[0];
|
|
952
|
-
if (DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
|
|
953
|
-
return null;
|
|
954
|
-
}
|
|
955
|
-
const property = entry[1];
|
|
956
|
-
const [propertyValue, propertyType] = getValueAndType(typedValue, key);
|
|
957
|
-
if (props.ignoreMissingValues &&
|
|
958
|
-
(!propertyValue || (Array.isArray(propertyValue) && propertyValue.length === 0))) {
|
|
959
|
-
return null;
|
|
960
|
-
}
|
|
961
|
-
return (React.createElement(DescriptionListEntry, { key: key, term: core.getPropertyDisplayName(key) },
|
|
962
|
-
React.createElement(ResourcePropertyDisplay, { property: property, propertyType: propertyType, value: propertyValue, ignoreMissingValues: props.ignoreMissingValues, link: props.link })));
|
|
963
|
-
})));
|
|
833
|
+
function CodeableConceptDisplay(props) {
|
|
834
|
+
return React.createElement(React.Fragment, null, core.formatCodeableConcept(props.value));
|
|
964
835
|
}
|
|
965
836
|
|
|
966
837
|
function CodingDisplay(props) {
|
|
967
|
-
|
|
968
|
-
return React.createElement(React.Fragment, null, ((_a = props.value) === null || _a === void 0 ? void 0 : _a.display) || ((_b = props.value) === null || _b === void 0 ? void 0 : _b.code));
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
function CodeableConceptDisplay(props) {
|
|
972
|
-
const value = props.value;
|
|
973
|
-
if (!value) {
|
|
974
|
-
return null;
|
|
975
|
-
}
|
|
976
|
-
if (value.text) {
|
|
977
|
-
return React.createElement(React.Fragment, null, value.text);
|
|
978
|
-
}
|
|
979
|
-
if (value.coding) {
|
|
980
|
-
return (React.createElement(React.Fragment, null, value.coding.map((coding, index) => (React.createElement(React.Fragment, { key: 'coding-' + index },
|
|
981
|
-
index > 0 && React.createElement(React.Fragment, null, ', '),
|
|
982
|
-
React.createElement(CodingDisplay, { value: coding }))))));
|
|
983
|
-
}
|
|
984
|
-
return null;
|
|
838
|
+
return React.createElement(React.Fragment, null, core.formatCoding(props.value));
|
|
985
839
|
}
|
|
986
840
|
|
|
987
841
|
function ContactPointDisplay(props) {
|
|
@@ -1211,25 +1065,159 @@
|
|
|
1211
1065
|
return [typedResult.value, typedResult.type];
|
|
1212
1066
|
}
|
|
1213
1067
|
|
|
1214
|
-
function
|
|
1215
|
-
const
|
|
1216
|
-
const
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1068
|
+
function BackboneElementDisplay(props) {
|
|
1069
|
+
const typedValue = props.value;
|
|
1070
|
+
const value = typedValue.value;
|
|
1071
|
+
if (!value) {
|
|
1072
|
+
return null;
|
|
1073
|
+
}
|
|
1074
|
+
const typeName = typedValue.type;
|
|
1075
|
+
const typeSchema = core.globalSchema.types[typeName];
|
|
1076
|
+
if (!typeSchema) {
|
|
1077
|
+
return React.createElement("div", null,
|
|
1078
|
+
typeName,
|
|
1079
|
+
"\u00A0not implemented");
|
|
1080
|
+
}
|
|
1081
|
+
if (typeof value === 'object' &&
|
|
1082
|
+
'name' in value &&
|
|
1083
|
+
Object.keys(value).length === 1 &&
|
|
1084
|
+
typeof value.name === 'string') {
|
|
1085
|
+
// Special case for common BackboneElement pattern
|
|
1086
|
+
// Where there is an object with a single property 'name'
|
|
1087
|
+
// Just display the name value.
|
|
1088
|
+
return React.createElement("div", null, value.name);
|
|
1089
|
+
}
|
|
1090
|
+
return (React.createElement(DescriptionList, { compact: props.compact }, Object.entries(typeSchema.properties).map((entry) => {
|
|
1091
|
+
const key = entry[0];
|
|
1092
|
+
if (DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
|
|
1093
|
+
return null;
|
|
1094
|
+
}
|
|
1095
|
+
const property = entry[1];
|
|
1096
|
+
const [propertyValue, propertyType] = getValueAndType(typedValue, key);
|
|
1097
|
+
if (props.ignoreMissingValues &&
|
|
1098
|
+
(!propertyValue || (Array.isArray(propertyValue) && propertyValue.length === 0))) {
|
|
1099
|
+
return null;
|
|
1100
|
+
}
|
|
1101
|
+
return (React.createElement(DescriptionListEntry, { key: key, term: core.getPropertyDisplayName(key) },
|
|
1102
|
+
React.createElement(ResourcePropertyDisplay, { property: property, propertyType: propertyType, value: propertyValue, ignoreMissingValues: props.ignoreMissingValues, link: props.link })));
|
|
1103
|
+
})));
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
function CheckboxFormSection(props) {
|
|
1107
|
+
return (React.createElement(core$1.Group, { noWrap: true },
|
|
1108
|
+
React.createElement("div", null, props.children),
|
|
1109
|
+
React.createElement("div", null,
|
|
1110
|
+
React.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description }, (() => null)()))));
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
function FormSection(props) {
|
|
1114
|
+
return (React.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description, error: getErrorsForInput(props.outcome, props.htmlFor) }, props.children));
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
const system = {
|
|
1118
|
+
resourceType: 'Device',
|
|
1119
|
+
id: 'system',
|
|
1120
|
+
deviceName: [
|
|
1121
|
+
{
|
|
1122
|
+
name: 'System',
|
|
1123
|
+
},
|
|
1124
|
+
],
|
|
1125
|
+
};
|
|
1126
|
+
/**
|
|
1127
|
+
* React Hook to use a FHIR reference.
|
|
1128
|
+
* Handles the complexity of resolving references and caching resources.
|
|
1129
|
+
* @param value The resource or reference to resource.
|
|
1130
|
+
* @returns The resolved resource.
|
|
1131
|
+
*/
|
|
1132
|
+
function useResource(value) {
|
|
1133
|
+
const medplum = useMedplum();
|
|
1134
|
+
const [resource, setResource] = React.useState(getInitialResource(medplum, value));
|
|
1135
|
+
React.useEffect(() => {
|
|
1136
|
+
let subscribed = true;
|
|
1137
|
+
if (!resource && value && 'reference' in value && value.reference) {
|
|
1138
|
+
medplum
|
|
1139
|
+
.readReference(value)
|
|
1140
|
+
.then((r) => {
|
|
1141
|
+
if (subscribed) {
|
|
1142
|
+
setResource(r);
|
|
1143
|
+
}
|
|
1144
|
+
})
|
|
1145
|
+
.catch(() => setResource(undefined));
|
|
1146
|
+
}
|
|
1147
|
+
return (() => (subscribed = false));
|
|
1148
|
+
}, [medplum, resource, value]);
|
|
1149
|
+
return resource;
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Returns the initial resource value based on the input value.
|
|
1153
|
+
* If the input value is a resource, returns the resource.
|
|
1154
|
+
* If the input value is a reference to system, returns the system resource.
|
|
1155
|
+
* If the input value is a reference to a resource available in the cache, returns the resource.
|
|
1156
|
+
* Otherwise, returns undefined.
|
|
1157
|
+
* @param medplum The medplum client.
|
|
1158
|
+
* @param value The resource or reference to resource.
|
|
1159
|
+
* @returns An initial resource if available; undefined otherwise.
|
|
1160
|
+
*/
|
|
1161
|
+
function getInitialResource(medplum, value) {
|
|
1162
|
+
if (!value) {
|
|
1163
|
+
return undefined;
|
|
1164
|
+
}
|
|
1165
|
+
if ('resourceType' in value) {
|
|
1166
|
+
return value;
|
|
1167
|
+
}
|
|
1168
|
+
if ('reference' in value) {
|
|
1169
|
+
if (value.reference === 'system') {
|
|
1170
|
+
return system;
|
|
1171
|
+
}
|
|
1172
|
+
return medplum.getCachedReference(value);
|
|
1173
|
+
}
|
|
1174
|
+
return undefined;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
function ResourceForm(props) {
|
|
1178
|
+
const medplum = useMedplum();
|
|
1179
|
+
const defaultValue = useResource(props.defaultValue);
|
|
1180
|
+
const [schema, setSchema] = React.useState();
|
|
1181
|
+
const [value, setValue] = React.useState();
|
|
1182
|
+
React.useEffect(() => {
|
|
1183
|
+
if (defaultValue) {
|
|
1184
|
+
setValue(JSON.parse(JSON.stringify(defaultValue)));
|
|
1185
|
+
medplum.requestSchema(defaultValue.resourceType).then(setSchema).catch(console.log);
|
|
1186
|
+
}
|
|
1187
|
+
}, [medplum, defaultValue]);
|
|
1188
|
+
if (!schema || !value) {
|
|
1189
|
+
return React.createElement("div", null, "Loading...");
|
|
1190
|
+
}
|
|
1191
|
+
return (React.createElement("form", { noValidate: true, autoComplete: "off", onSubmit: (e) => {
|
|
1192
|
+
e.preventDefault();
|
|
1193
|
+
if (props.onSubmit) {
|
|
1194
|
+
props.onSubmit(value);
|
|
1195
|
+
}
|
|
1196
|
+
} },
|
|
1197
|
+
React.createElement(core$1.Stack, { mb: "xl" },
|
|
1198
|
+
React.createElement(FormSection, { title: "Resource Type", htmlFor: "resourceType", outcome: props.outcome },
|
|
1199
|
+
React.createElement(core$1.TextInput, { name: "resourceType", defaultValue: value.resourceType, disabled: true })),
|
|
1200
|
+
React.createElement(FormSection, { title: "ID", htmlFor: "id", outcome: props.outcome },
|
|
1201
|
+
React.createElement(core$1.TextInput, { name: "id", defaultValue: value.id, disabled: true }))),
|
|
1202
|
+
React.createElement(BackboneElementInput, { typeName: value.resourceType, defaultValue: value, outcome: props.outcome, onChange: setValue }),
|
|
1203
|
+
React.createElement(core$1.Group, { position: "right", mt: "xl" },
|
|
1204
|
+
React.createElement(core$1.Button, { type: "submit" }, "OK"),
|
|
1205
|
+
props.onDelete && (React.createElement(core$1.Button, { variant: "outline", color: "red", type: "button", onClick: () => {
|
|
1206
|
+
props.onDelete(value);
|
|
1207
|
+
} }, "Delete")))));
|
|
1208
|
+
}
|
|
1209
|
+
function setPropertyValue(obj, key, propName, elementDefinition, value) {
|
|
1210
|
+
const types = elementDefinition.type;
|
|
1211
|
+
if (types.length > 1) {
|
|
1212
|
+
for (const type of types) {
|
|
1213
|
+
const compoundKey = key.replace('[x]', core.capitalize(type.code));
|
|
1214
|
+
if (compoundKey in obj) {
|
|
1215
|
+
delete obj[compoundKey];
|
|
1225
1216
|
}
|
|
1226
|
-
: {};
|
|
1227
|
-
setValue(newValue);
|
|
1228
|
-
if (props.onChange) {
|
|
1229
|
-
props.onChange(newValue);
|
|
1230
1217
|
}
|
|
1231
1218
|
}
|
|
1232
|
-
|
|
1219
|
+
obj[propName] = value;
|
|
1220
|
+
return obj;
|
|
1233
1221
|
}
|
|
1234
1222
|
|
|
1235
1223
|
function valueSetElementToAutocompleteItem(element) {
|
|
@@ -1994,49 +1982,177 @@
|
|
|
1994
1982
|
return (React.createElement(BackboneElementInput, { typeName: core.buildTypeName((_a = property.path) === null || _a === void 0 ? void 0 : _a.split('.')), defaultValue: value, onChange: props.onChange, outcome: props.outcome }));
|
|
1995
1983
|
}
|
|
1996
1984
|
}
|
|
1997
|
-
function getTargetTypes(property) {
|
|
1998
|
-
var _a, _b, _c;
|
|
1999
|
-
return (_c = (_b = (_a = property === null || property === void 0 ? void 0 : property.type) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.targetProfile) === null || _c === void 0 ? void 0 : _c.map((p) => p.split('/').pop());
|
|
1985
|
+
function getTargetTypes(property) {
|
|
1986
|
+
var _a, _b, _c;
|
|
1987
|
+
return (_c = (_b = (_a = property === null || property === void 0 ? void 0 : property.type) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.targetProfile) === null || _c === void 0 ? void 0 : _c.map((p) => p.split('/').pop());
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
function BackboneElementInput(props) {
|
|
1991
|
+
var _a;
|
|
1992
|
+
const [value, setValue] = React.useState((_a = props.defaultValue) !== null && _a !== void 0 ? _a : {});
|
|
1993
|
+
function setValueWrapper(newValue) {
|
|
1994
|
+
setValue(newValue);
|
|
1995
|
+
if (props.onChange) {
|
|
1996
|
+
props.onChange(newValue);
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
const typeName = props.typeName;
|
|
2000
|
+
const typeSchema = core.globalSchema.types[typeName];
|
|
2001
|
+
if (!typeSchema) {
|
|
2002
|
+
return React.createElement("div", null,
|
|
2003
|
+
typeName,
|
|
2004
|
+
"\u00A0not implemented");
|
|
2005
|
+
}
|
|
2006
|
+
const typedValue = { type: typeName, value };
|
|
2007
|
+
return (React.createElement(core$1.Stack, null, Object.entries(typeSchema.properties).map((entry) => {
|
|
2008
|
+
const key = entry[0];
|
|
2009
|
+
if (key === 'id' || DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
|
|
2010
|
+
return null;
|
|
2011
|
+
}
|
|
2012
|
+
const property = entry[1];
|
|
2013
|
+
if (!property.type) {
|
|
2014
|
+
return null;
|
|
2015
|
+
}
|
|
2016
|
+
const [propertyValue, propertyType] = getValueAndType(typedValue, key);
|
|
2017
|
+
if (property.type.length === 1 && property.type[0].code === 'boolean') {
|
|
2018
|
+
return (React.createElement(CheckboxFormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key },
|
|
2019
|
+
React.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
|
|
2020
|
+
setValueWrapper(setPropertyValue(value, key, propName !== null && propName !== void 0 ? propName : key, entry[1], newValue));
|
|
2021
|
+
} })));
|
|
2022
|
+
}
|
|
2023
|
+
return (React.createElement(FormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key, outcome: props.outcome },
|
|
2024
|
+
React.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
|
|
2025
|
+
setValueWrapper(setPropertyValue(value, key, propName !== null && propName !== void 0 ? propName : key, entry[1], newValue));
|
|
2026
|
+
} })));
|
|
2027
|
+
})));
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
const useStyles$a = core$1.createStyles((theme) => ({
|
|
2031
|
+
table: {
|
|
2032
|
+
width: 350,
|
|
2033
|
+
'& th': {
|
|
2034
|
+
fontWeight: 'normal',
|
|
2035
|
+
fontSize: 11,
|
|
2036
|
+
padding: 8,
|
|
2037
|
+
textAlign: 'center',
|
|
2038
|
+
},
|
|
2039
|
+
'& td': {
|
|
2040
|
+
padding: '2px 4px',
|
|
2041
|
+
},
|
|
2042
|
+
'& td button': {
|
|
2043
|
+
width: 44,
|
|
2044
|
+
height: 44,
|
|
2045
|
+
color: theme.colors[theme.primaryColor][5],
|
|
2046
|
+
fontSize: 16,
|
|
2047
|
+
fontWeight: 500,
|
|
2048
|
+
textAlign: 'center',
|
|
2049
|
+
padding: 0,
|
|
2050
|
+
backgroundColor: theme.colors[theme.primaryColor][0],
|
|
2051
|
+
border: 0,
|
|
2052
|
+
borderRadius: '50%',
|
|
2053
|
+
cursor: 'pointer',
|
|
2054
|
+
},
|
|
2055
|
+
'& td button:hover': {
|
|
2056
|
+
backgroundColor: theme.colors[theme.primaryColor][1],
|
|
2057
|
+
},
|
|
2058
|
+
'& td button:disabled': {
|
|
2059
|
+
backgroundColor: 'transparent',
|
|
2060
|
+
cursor: 'default',
|
|
2061
|
+
color: theme.colors.gray[4],
|
|
2062
|
+
fontWeight: 'normal',
|
|
2063
|
+
},
|
|
2064
|
+
},
|
|
2065
|
+
}));
|
|
2066
|
+
/**
|
|
2067
|
+
* Returns a month display string (e.g. "January 2020").
|
|
2068
|
+
* @param date Any date within the month.
|
|
2069
|
+
* @returns The month display string (e.g. "January 2020")
|
|
2070
|
+
*/
|
|
2071
|
+
function getMonthString(date) {
|
|
2072
|
+
return date.toLocaleString('default', { month: 'long' }) + ' ' + date.getFullYear();
|
|
2073
|
+
}
|
|
2074
|
+
function CalendarInput(props) {
|
|
2075
|
+
const { classes } = useStyles$a();
|
|
2076
|
+
const { onChangeMonth, onClick } = props;
|
|
2077
|
+
const [month, setMonth] = React.useState(getStartMonth);
|
|
2078
|
+
function moveMonth(delta) {
|
|
2079
|
+
setMonth((currMonth) => {
|
|
2080
|
+
const newMonth = new Date(currMonth.getTime());
|
|
2081
|
+
newMonth.setMonth(currMonth.getMonth() + delta);
|
|
2082
|
+
onChangeMonth(newMonth);
|
|
2083
|
+
return newMonth;
|
|
2084
|
+
});
|
|
2085
|
+
}
|
|
2086
|
+
const grid = React.useMemo(() => buildGrid(month, props.slots), [month, props.slots]);
|
|
2087
|
+
return (React.createElement("div", null,
|
|
2088
|
+
React.createElement(core$1.Group, { position: "apart", spacing: "xs", grow: true, noWrap: true },
|
|
2089
|
+
React.createElement("p", { style: { flex: 1 } }, getMonthString(month)),
|
|
2090
|
+
React.createElement(core$1.Group, { position: "right", spacing: "xs" },
|
|
2091
|
+
React.createElement(core$1.Button, { variant: "outline", "aria-label": "Previous month", onClick: () => moveMonth(-1) }, "<"),
|
|
2092
|
+
React.createElement(core$1.Button, { variant: "outline", "aria-label": "Next month", onClick: () => moveMonth(1) }, ">"))),
|
|
2093
|
+
React.createElement("table", { className: classes.table },
|
|
2094
|
+
React.createElement("thead", null,
|
|
2095
|
+
React.createElement("tr", null,
|
|
2096
|
+
React.createElement("th", null, "SUN"),
|
|
2097
|
+
React.createElement("th", null, "MON"),
|
|
2098
|
+
React.createElement("th", null, "TUE"),
|
|
2099
|
+
React.createElement("th", null, "WED"),
|
|
2100
|
+
React.createElement("th", null, "THU"),
|
|
2101
|
+
React.createElement("th", null, "FRI"),
|
|
2102
|
+
React.createElement("th", null, "SAT"))),
|
|
2103
|
+
React.createElement("tbody", null, grid.map((week, weekIndex) => (React.createElement("tr", { key: 'week-' + weekIndex }, week.map((day, dayIndex) => (React.createElement("td", { key: 'day-' + dayIndex }, day && (React.createElement(core$1.Button, { disabled: !day.available, onClick: () => onClick(day.date) }, day.date.getDate()))))))))))));
|
|
2104
|
+
}
|
|
2105
|
+
function getStartMonth() {
|
|
2106
|
+
const result = new Date();
|
|
2107
|
+
result.setDate(1);
|
|
2108
|
+
result.setHours(0, 0, 0, 0);
|
|
2109
|
+
return result;
|
|
2000
2110
|
}
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
props.onChange(newValue);
|
|
2009
|
-
}
|
|
2010
|
-
}
|
|
2011
|
-
const typeName = props.typeName;
|
|
2012
|
-
const typeSchema = core.globalSchema.types[typeName];
|
|
2013
|
-
if (!typeSchema) {
|
|
2014
|
-
return React.createElement("div", null,
|
|
2015
|
-
typeName,
|
|
2016
|
-
"\u00A0not implemented");
|
|
2111
|
+
function buildGrid(startDate, slots) {
|
|
2112
|
+
const d = new Date(startDate.getFullYear(), startDate.getMonth());
|
|
2113
|
+
const grid = [];
|
|
2114
|
+
let row = [];
|
|
2115
|
+
// Fill leading empty days
|
|
2116
|
+
for (let i = 0; i < d.getDay(); i++) {
|
|
2117
|
+
row.push(undefined);
|
|
2017
2118
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2119
|
+
while (d.getMonth() === startDate.getMonth()) {
|
|
2120
|
+
row.push({
|
|
2121
|
+
date: new Date(d.getTime()),
|
|
2122
|
+
available: isDayAvailable(d, slots),
|
|
2123
|
+
});
|
|
2124
|
+
if (d.getDay() === 6) {
|
|
2125
|
+
grid.push(row);
|
|
2126
|
+
row = [];
|
|
2023
2127
|
}
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2128
|
+
d.setDate(d.getDate() + 1);
|
|
2129
|
+
}
|
|
2130
|
+
// Fill trailing empty days
|
|
2131
|
+
if (d.getDay() !== 0) {
|
|
2132
|
+
for (let i = d.getDay(); i < 7; i++) {
|
|
2133
|
+
row.push(undefined);
|
|
2027
2134
|
}
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2135
|
+
grid.push(row);
|
|
2136
|
+
}
|
|
2137
|
+
return grid;
|
|
2138
|
+
}
|
|
2139
|
+
/**
|
|
2140
|
+
* Returns true if the given date is available for booking.
|
|
2141
|
+
* @param day The day to check.
|
|
2142
|
+
* @param slots The list of available slots.
|
|
2143
|
+
* @returns True if there are any available slots for the day.
|
|
2144
|
+
*/
|
|
2145
|
+
function isDayAvailable(day, slots) {
|
|
2146
|
+
// Note that slot start and end time may or may not be in UTC.
|
|
2147
|
+
for (const slot of slots) {
|
|
2148
|
+
const slotStart = new Date(slot.start);
|
|
2149
|
+
if (slotStart.getFullYear() === day.getFullYear() &&
|
|
2150
|
+
slotStart.getMonth() === day.getMonth() &&
|
|
2151
|
+
slotStart.getDate() === day.getDate()) {
|
|
2152
|
+
return true;
|
|
2034
2153
|
}
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
setValueWrapper(setPropertyValue(value, key, propName !== null && propName !== void 0 ? propName : key, entry[1], newValue));
|
|
2038
|
-
} })));
|
|
2039
|
-
})));
|
|
2154
|
+
}
|
|
2155
|
+
return false;
|
|
2040
2156
|
}
|
|
2041
2157
|
|
|
2042
2158
|
function ResourceName(props) {
|
|
@@ -2055,7 +2171,7 @@
|
|
|
2055
2171
|
React.createElement(ResourceName, { value: props.value, link: props.link })));
|
|
2056
2172
|
}
|
|
2057
2173
|
|
|
2058
|
-
const useStyles$
|
|
2174
|
+
const useStyles$9 = core$1.createStyles((theme) => ({
|
|
2059
2175
|
table: {
|
|
2060
2176
|
border: `0.1px solid ${theme.colors.gray[5]}`,
|
|
2061
2177
|
borderCollapse: 'collapse',
|
|
@@ -2116,7 +2232,7 @@
|
|
|
2116
2232
|
}
|
|
2117
2233
|
function ObservationTable(props) {
|
|
2118
2234
|
var _a;
|
|
2119
|
-
const { classes } = useStyles$
|
|
2235
|
+
const { classes } = useStyles$9();
|
|
2120
2236
|
return (React.createElement("table", { className: classes.table },
|
|
2121
2237
|
React.createElement("thead", null,
|
|
2122
2238
|
React.createElement("tr", null,
|
|
@@ -2127,7 +2243,7 @@
|
|
|
2127
2243
|
React.createElement("tbody", null, (_a = props.value) === null || _a === void 0 ? void 0 : _a.map((observation, index) => (React.createElement(ObservationRow, { key: 'obs-' + index, value: observation }))))));
|
|
2128
2244
|
}
|
|
2129
2245
|
function ObservationRow(props) {
|
|
2130
|
-
const { classes, cx } = useStyles$
|
|
2246
|
+
const { classes, cx } = useStyles$9();
|
|
2131
2247
|
const observation = useResource(props.value);
|
|
2132
2248
|
if (!observation) {
|
|
2133
2249
|
return null;
|
|
@@ -2144,20 +2260,8 @@
|
|
|
2144
2260
|
React.createElement("td", null, observation.interpretation && observation.interpretation.length > 0 && (React.createElement(CodeableConceptDisplay, { value: observation.interpretation[0] })))));
|
|
2145
2261
|
}
|
|
2146
2262
|
function ObservationValueDisplay(props) {
|
|
2147
|
-
var _a;
|
|
2148
2263
|
const obs = props.value;
|
|
2149
|
-
|
|
2150
|
-
return React.createElement(QuantityDisplay, { value: (_a = props.value) === null || _a === void 0 ? void 0 : _a.valueQuantity });
|
|
2151
|
-
}
|
|
2152
|
-
if (obs === null || obs === void 0 ? void 0 : obs.valueString) {
|
|
2153
|
-
return React.createElement(React.Fragment, null, obs.valueString);
|
|
2154
|
-
}
|
|
2155
|
-
if (obs && 'component' in obs && (obs === null || obs === void 0 ? void 0 : obs.component)) {
|
|
2156
|
-
return (React.createElement(React.Fragment, null, obs.component
|
|
2157
|
-
.map((component, index) => (React.createElement(ObservationValueDisplay, { key: `obs-${index}`, value: component })))
|
|
2158
|
-
.reduce((prev, curr) => [prev, ' / ', curr])));
|
|
2159
|
-
}
|
|
2160
|
-
return null;
|
|
2264
|
+
return React.createElement(React.Fragment, null, core.formatObservationValue(obs));
|
|
2161
2265
|
}
|
|
2162
2266
|
function ReferenceRangeDisplay(props) {
|
|
2163
2267
|
const range = props.value && props.value.length > 0 && props.value[0];
|
|
@@ -2181,7 +2285,7 @@
|
|
|
2181
2285
|
return code === 'AA' || code === 'LL' || code === 'HH' || code === 'A';
|
|
2182
2286
|
}
|
|
2183
2287
|
|
|
2184
|
-
const useStyles$
|
|
2288
|
+
const useStyles$8 = core$1.createStyles((theme) => ({
|
|
2185
2289
|
root: {
|
|
2186
2290
|
borderCollapse: 'collapse',
|
|
2187
2291
|
width: '100%',
|
|
@@ -2202,7 +2306,7 @@
|
|
|
2202
2306
|
},
|
|
2203
2307
|
}));
|
|
2204
2308
|
function ResourceDiffTable(props) {
|
|
2205
|
-
const { classes } = useStyles$
|
|
2309
|
+
const { classes } = useStyles$8();
|
|
2206
2310
|
const medplum = useMedplum();
|
|
2207
2311
|
const [schema, setSchema] = React.useState();
|
|
2208
2312
|
React.useEffect(() => {
|
|
@@ -2363,7 +2467,7 @@
|
|
|
2363
2467
|
return new Date(dateTime).getTime();
|
|
2364
2468
|
}
|
|
2365
2469
|
|
|
2366
|
-
const useStyles$
|
|
2470
|
+
const useStyles$7 = core$1.createStyles((theme) => ({
|
|
2367
2471
|
pinnedComment: {
|
|
2368
2472
|
backgroundColor: theme.colors.blue[0],
|
|
2369
2473
|
},
|
|
@@ -2516,7 +2620,7 @@
|
|
|
2516
2620
|
disallowClose: true,
|
|
2517
2621
|
});
|
|
2518
2622
|
}
|
|
2519
|
-
if (!resource
|
|
2623
|
+
if (!resource) {
|
|
2520
2624
|
return (React.createElement(core$1.Center, { style: { width: '100%', height: '100%' } },
|
|
2521
2625
|
React.createElement(core$1.Loader, null)));
|
|
2522
2626
|
}
|
|
@@ -2592,7 +2696,7 @@
|
|
|
2592
2696
|
}
|
|
2593
2697
|
function CommunicationTimelineItem(props) {
|
|
2594
2698
|
var _a, _b;
|
|
2595
|
-
const { classes } = useStyles$
|
|
2699
|
+
const { classes } = useStyles$7();
|
|
2596
2700
|
const routine = !props.resource.priority || props.resource.priority === 'routine';
|
|
2597
2701
|
const className = routine ? undefined : classes.pinnedComment;
|
|
2598
2702
|
return (React.createElement(TimelineItem, { resource: props.resource, profile: props.resource.sender, padding: true, className: className, popupMenuItems: React.createElement(TimelineItemPopupMenu, Object.assign({}, props)) },
|
|
@@ -3741,7 +3845,7 @@
|
|
|
3741
3845
|
this.browserEvent = browserEvent;
|
|
3742
3846
|
}
|
|
3743
3847
|
}
|
|
3744
|
-
const useStyles$
|
|
3848
|
+
const useStyles$6 = core$1.createStyles((theme) => ({
|
|
3745
3849
|
root: {
|
|
3746
3850
|
maxWidth: '100%',
|
|
3747
3851
|
overflow: 'auto',
|
|
@@ -3779,7 +3883,7 @@
|
|
|
3779
3883
|
*/
|
|
3780
3884
|
function SearchControl(props) {
|
|
3781
3885
|
var _a, _b, _c;
|
|
3782
|
-
const { classes } = useStyles$
|
|
3886
|
+
const { classes } = useStyles$6();
|
|
3783
3887
|
const medplum = useMedplum();
|
|
3784
3888
|
const [schemaLoaded, setSchemaLoaded] = React.useState(false);
|
|
3785
3889
|
const [outcome, setOutcome] = React.useState();
|
|
@@ -4154,7 +4258,7 @@
|
|
|
4154
4258
|
}) }));
|
|
4155
4259
|
}
|
|
4156
4260
|
|
|
4157
|
-
const useStyles$
|
|
4261
|
+
const useStyles$5 = core$1.createStyles((theme) => ({
|
|
4158
4262
|
section: {
|
|
4159
4263
|
position: 'relative',
|
|
4160
4264
|
margin: '4px 4px 8px 0',
|
|
@@ -4220,7 +4324,7 @@
|
|
|
4220
4324
|
React.createElement(core$1.Button, { type: "submit" }, "Save"))));
|
|
4221
4325
|
}
|
|
4222
4326
|
function ActionArrayBuilder(props) {
|
|
4223
|
-
const { classes } = useStyles$
|
|
4327
|
+
const { classes } = useStyles$5();
|
|
4224
4328
|
const actionsRef = React.useRef();
|
|
4225
4329
|
actionsRef.current = props.actions;
|
|
4226
4330
|
function changeAction(changedAction) {
|
|
@@ -4243,7 +4347,7 @@
|
|
|
4243
4347
|
} }, "Add action"))));
|
|
4244
4348
|
}
|
|
4245
4349
|
function ActionBuilder(props) {
|
|
4246
|
-
const { classes, cx } = useStyles$
|
|
4350
|
+
const { classes, cx } = useStyles$5();
|
|
4247
4351
|
const { action } = props;
|
|
4248
4352
|
const actionType = getInitialActionType(action);
|
|
4249
4353
|
const editing = props.selectedKey === props.action.id;
|
|
@@ -4664,7 +4768,7 @@
|
|
|
4664
4768
|
}
|
|
4665
4769
|
}
|
|
4666
4770
|
|
|
4667
|
-
const useStyles$
|
|
4771
|
+
const useStyles$4 = core$1.createStyles((theme) => ({
|
|
4668
4772
|
section: {
|
|
4669
4773
|
position: 'relative',
|
|
4670
4774
|
margin: '4px 4px 8px 0',
|
|
@@ -4743,7 +4847,7 @@
|
|
|
4743
4847
|
}
|
|
4744
4848
|
function ItemBuilder(props) {
|
|
4745
4849
|
var _a;
|
|
4746
|
-
const { classes, cx } = useStyles$
|
|
4850
|
+
const { classes, cx } = useStyles$4();
|
|
4747
4851
|
const resource = props.item;
|
|
4748
4852
|
const item = props.item;
|
|
4749
4853
|
const isResource = 'resourceType' in props.item;
|
|
@@ -4920,7 +5024,7 @@
|
|
|
4920
5024
|
return options.map((option) => (Object.assign(Object.assign({}, option), { id: option.id || generateId() })));
|
|
4921
5025
|
}
|
|
4922
5026
|
|
|
4923
|
-
const useStyles$
|
|
5027
|
+
const useStyles$3 = core$1.createStyles((theme) => ({
|
|
4924
5028
|
section: {
|
|
4925
5029
|
position: 'relative',
|
|
4926
5030
|
margin: '4px 4px 8px 0',
|
|
@@ -5004,6 +5108,7 @@
|
|
|
5004
5108
|
const currentGroupIndex = groups.findIndex((g) => g.id === groupId);
|
|
5005
5109
|
if (currentGroupIndex != -1) {
|
|
5006
5110
|
const currentGroup = Object.assign({}, groups[currentGroupIndex]);
|
|
5111
|
+
addedInterval = Object.assign(Object.assign({}, addedInterval), currentGroup.filters);
|
|
5007
5112
|
currentGroup.intervals = [...currentGroup.intervals, addedInterval];
|
|
5008
5113
|
groups[currentGroupIndex] = currentGroup;
|
|
5009
5114
|
}
|
|
@@ -5023,7 +5128,7 @@
|
|
|
5023
5128
|
}
|
|
5024
5129
|
function ReferenceRangeGroupEditor(props) {
|
|
5025
5130
|
const { intervalGroup, unit } = props;
|
|
5026
|
-
const { classes } = useStyles$
|
|
5131
|
+
const { classes } = useStyles$3();
|
|
5027
5132
|
return (React.createElement(core$1.Container, { "data-testid": intervalGroup.id, className: classes.section },
|
|
5028
5133
|
React.createElement(core$1.Stack, { spacing: 'lg' },
|
|
5029
5134
|
React.createElement(core$1.Group, { position: "right" },
|
|
@@ -5485,7 +5590,7 @@
|
|
|
5485
5590
|
}
|
|
5486
5591
|
}
|
|
5487
5592
|
|
|
5488
|
-
const useStyles$
|
|
5593
|
+
const useStyles$2 = core$1.createStyles((theme) => ({
|
|
5489
5594
|
container: {
|
|
5490
5595
|
overflowX: 'auto',
|
|
5491
5596
|
},
|
|
@@ -5534,7 +5639,7 @@
|
|
|
5534
5639
|
}));
|
|
5535
5640
|
function ResourceBlame(props) {
|
|
5536
5641
|
var _a, _b;
|
|
5537
|
-
const { classes } = useStyles$
|
|
5642
|
+
const { classes } = useStyles$2();
|
|
5538
5643
|
const medplum = useMedplum();
|
|
5539
5644
|
const [value, setValue] = React.useState(props.history);
|
|
5540
5645
|
React.useEffect(() => {
|
|
@@ -5590,7 +5695,7 @@
|
|
|
5590
5695
|
return `${count} ${count === 1 ? noun : noun + 's'} ago`;
|
|
5591
5696
|
}
|
|
5592
5697
|
|
|
5593
|
-
const useStyles$
|
|
5698
|
+
const useStyles$1 = core$1.createStyles((theme) => ({
|
|
5594
5699
|
removed: {
|
|
5595
5700
|
color: theme.colors.red[7],
|
|
5596
5701
|
textDecoration: 'line-through',
|
|
@@ -5612,7 +5717,7 @@
|
|
|
5612
5717
|
return (React.createElement("pre", { style: { color: 'gray' } }, deltas.map((delta, index) => (React.createElement(ChangeDiff, { key: 'delta' + index, delta: delta })))));
|
|
5613
5718
|
}
|
|
5614
5719
|
function ChangeDiff(props) {
|
|
5615
|
-
const { classes } = useStyles$
|
|
5720
|
+
const { classes } = useStyles$1();
|
|
5616
5721
|
return (React.createElement(React.Fragment, null,
|
|
5617
5722
|
"...",
|
|
5618
5723
|
React.createElement("br", null),
|
|
@@ -5666,134 +5771,6 @@
|
|
|
5666
5771
|
return `/${resource.resourceType}/${resource.id}/_history/${(_a = resource.meta) === null || _a === void 0 ? void 0 : _a.versionId}`;
|
|
5667
5772
|
}
|
|
5668
5773
|
|
|
5669
|
-
const useStyles$1 = core$1.createStyles((theme) => ({
|
|
5670
|
-
table: {
|
|
5671
|
-
width: 350,
|
|
5672
|
-
'& th': {
|
|
5673
|
-
fontWeight: 'normal',
|
|
5674
|
-
fontSize: 11,
|
|
5675
|
-
padding: 8,
|
|
5676
|
-
textAlign: 'center',
|
|
5677
|
-
},
|
|
5678
|
-
'& td': {
|
|
5679
|
-
padding: '2px 4px',
|
|
5680
|
-
},
|
|
5681
|
-
'& td button': {
|
|
5682
|
-
width: 44,
|
|
5683
|
-
height: 44,
|
|
5684
|
-
color: theme.colors[theme.primaryColor][5],
|
|
5685
|
-
fontSize: 16,
|
|
5686
|
-
fontWeight: 500,
|
|
5687
|
-
textAlign: 'center',
|
|
5688
|
-
padding: 0,
|
|
5689
|
-
backgroundColor: theme.colors[theme.primaryColor][0],
|
|
5690
|
-
border: 0,
|
|
5691
|
-
borderRadius: '50%',
|
|
5692
|
-
cursor: 'pointer',
|
|
5693
|
-
},
|
|
5694
|
-
'& td button:hover': {
|
|
5695
|
-
backgroundColor: theme.colors[theme.primaryColor][1],
|
|
5696
|
-
},
|
|
5697
|
-
'& td button:disabled': {
|
|
5698
|
-
backgroundColor: 'transparent',
|
|
5699
|
-
cursor: 'default',
|
|
5700
|
-
color: theme.colors.gray[4],
|
|
5701
|
-
fontWeight: 'normal',
|
|
5702
|
-
},
|
|
5703
|
-
},
|
|
5704
|
-
}));
|
|
5705
|
-
/**
|
|
5706
|
-
* Returns a month display string (e.g. "January 2020").
|
|
5707
|
-
* @param date Any date within the month.
|
|
5708
|
-
* @returns The month display string (e.g. "January 2020")
|
|
5709
|
-
*/
|
|
5710
|
-
function getMonthString(date) {
|
|
5711
|
-
return date.toLocaleString('default', { month: 'long' }) + ' ' + date.getFullYear();
|
|
5712
|
-
}
|
|
5713
|
-
function CalendarInput(props) {
|
|
5714
|
-
const { classes } = useStyles$1();
|
|
5715
|
-
const { onChangeMonth, onClick } = props;
|
|
5716
|
-
const [month, setMonth] = React.useState(getStartMonth);
|
|
5717
|
-
function moveMonth(delta) {
|
|
5718
|
-
setMonth((currMonth) => {
|
|
5719
|
-
const newMonth = new Date(currMonth.getTime());
|
|
5720
|
-
newMonth.setMonth(currMonth.getMonth() + delta);
|
|
5721
|
-
onChangeMonth(newMonth);
|
|
5722
|
-
return newMonth;
|
|
5723
|
-
});
|
|
5724
|
-
}
|
|
5725
|
-
const grid = React.useMemo(() => buildGrid(month, props.slots), [month, props.slots]);
|
|
5726
|
-
return (React.createElement("div", null,
|
|
5727
|
-
React.createElement(core$1.Group, { position: "apart", spacing: "xs", grow: true, noWrap: true },
|
|
5728
|
-
React.createElement("p", { style: { flex: 1 } }, getMonthString(month)),
|
|
5729
|
-
React.createElement(core$1.Group, { position: "right", spacing: "xs" },
|
|
5730
|
-
React.createElement(core$1.Button, { variant: "outline", "aria-label": "Previous month", onClick: () => moveMonth(-1) }, "<"),
|
|
5731
|
-
React.createElement(core$1.Button, { variant: "outline", "aria-label": "Next month", onClick: () => moveMonth(1) }, ">"))),
|
|
5732
|
-
React.createElement("table", { className: classes.table },
|
|
5733
|
-
React.createElement("thead", null,
|
|
5734
|
-
React.createElement("tr", null,
|
|
5735
|
-
React.createElement("th", null, "SUN"),
|
|
5736
|
-
React.createElement("th", null, "MON"),
|
|
5737
|
-
React.createElement("th", null, "TUE"),
|
|
5738
|
-
React.createElement("th", null, "WED"),
|
|
5739
|
-
React.createElement("th", null, "THU"),
|
|
5740
|
-
React.createElement("th", null, "FRI"),
|
|
5741
|
-
React.createElement("th", null, "SAT"))),
|
|
5742
|
-
React.createElement("tbody", null, grid.map((week, weekIndex) => (React.createElement("tr", { key: 'week-' + weekIndex }, week.map((day, dayIndex) => (React.createElement("td", { key: 'day-' + dayIndex }, day && (React.createElement(core$1.Button, { disabled: !day.available, onClick: () => onClick(day.date) }, day.date.getDate()))))))))))));
|
|
5743
|
-
}
|
|
5744
|
-
function getStartMonth() {
|
|
5745
|
-
const result = new Date();
|
|
5746
|
-
result.setDate(1);
|
|
5747
|
-
result.setHours(0, 0, 0, 0);
|
|
5748
|
-
return result;
|
|
5749
|
-
}
|
|
5750
|
-
function buildGrid(startDate, slots) {
|
|
5751
|
-
const d = new Date(startDate.getFullYear(), startDate.getMonth());
|
|
5752
|
-
const grid = [];
|
|
5753
|
-
let row = [];
|
|
5754
|
-
// Fill leading empty days
|
|
5755
|
-
for (let i = 0; i < d.getDay(); i++) {
|
|
5756
|
-
row.push(undefined);
|
|
5757
|
-
}
|
|
5758
|
-
while (d.getMonth() === startDate.getMonth()) {
|
|
5759
|
-
row.push({
|
|
5760
|
-
date: new Date(d.getTime()),
|
|
5761
|
-
available: isDayAvailable(d, slots),
|
|
5762
|
-
});
|
|
5763
|
-
if (d.getDay() === 6) {
|
|
5764
|
-
grid.push(row);
|
|
5765
|
-
row = [];
|
|
5766
|
-
}
|
|
5767
|
-
d.setDate(d.getDate() + 1);
|
|
5768
|
-
}
|
|
5769
|
-
// Fill trailing empty days
|
|
5770
|
-
if (d.getDay() !== 0) {
|
|
5771
|
-
for (let i = d.getDay(); i < 7; i++) {
|
|
5772
|
-
row.push(undefined);
|
|
5773
|
-
}
|
|
5774
|
-
grid.push(row);
|
|
5775
|
-
}
|
|
5776
|
-
return grid;
|
|
5777
|
-
}
|
|
5778
|
-
/**
|
|
5779
|
-
* Returns true if the given date is available for booking.
|
|
5780
|
-
* @param day The day to check.
|
|
5781
|
-
* @param slots The list of available slots.
|
|
5782
|
-
* @returns True if there are any available slots for the day.
|
|
5783
|
-
*/
|
|
5784
|
-
function isDayAvailable(day, slots) {
|
|
5785
|
-
// Note that slot start and end time may or may not be in UTC.
|
|
5786
|
-
for (const slot of slots) {
|
|
5787
|
-
const slotStart = new Date(slot.start);
|
|
5788
|
-
if (slotStart.getFullYear() === day.getFullYear() &&
|
|
5789
|
-
slotStart.getMonth() === day.getMonth() &&
|
|
5790
|
-
slotStart.getDate() === day.getDate()) {
|
|
5791
|
-
return true;
|
|
5792
|
-
}
|
|
5793
|
-
}
|
|
5794
|
-
return false;
|
|
5795
|
-
}
|
|
5796
|
-
|
|
5797
5774
|
const useStyles = core$1.createStyles((theme) => ({
|
|
5798
5775
|
container: {
|
|
5799
5776
|
display: 'flex',
|
|
@@ -5932,15 +5909,21 @@
|
|
|
5932
5909
|
|
|
5933
5910
|
exports.AddressDisplay = AddressDisplay;
|
|
5934
5911
|
exports.AddressInput = AddressInput;
|
|
5912
|
+
exports.AnnotationInput = AnnotationInput;
|
|
5935
5913
|
exports.AttachmentArrayDisplay = AttachmentArrayDisplay;
|
|
5936
5914
|
exports.AttachmentArrayInput = AttachmentArrayInput;
|
|
5937
5915
|
exports.AttachmentButton = AttachmentButton;
|
|
5916
|
+
exports.AttachmentDisplay = AttachmentDisplay;
|
|
5938
5917
|
exports.AttachmentInput = AttachmentInput;
|
|
5918
|
+
exports.BackboneElementDisplay = BackboneElementDisplay;
|
|
5939
5919
|
exports.BackboneElementInput = BackboneElementInput;
|
|
5920
|
+
exports.CalendarInput = CalendarInput;
|
|
5940
5921
|
exports.CheckboxFormSection = CheckboxFormSection;
|
|
5941
5922
|
exports.CodeInput = CodeInput;
|
|
5942
5923
|
exports.CodeableConceptDisplay = CodeableConceptDisplay;
|
|
5943
5924
|
exports.CodeableConceptInput = CodeableConceptInput;
|
|
5925
|
+
exports.CodingDisplay = CodingDisplay;
|
|
5926
|
+
exports.CodingInput = CodingInput;
|
|
5944
5927
|
exports.ContactDetailDisplay = ContactDetailDisplay;
|
|
5945
5928
|
exports.ContactDetailInput = ContactDetailInput;
|
|
5946
5929
|
exports.ContactPointDisplay = ContactPointDisplay;
|
|
@@ -5960,6 +5943,7 @@
|
|
|
5960
5943
|
exports.FormSection = FormSection;
|
|
5961
5944
|
exports.HumanNameDisplay = HumanNameDisplay;
|
|
5962
5945
|
exports.HumanNameInput = HumanNameInput;
|
|
5946
|
+
exports.IdentifierDisplay = IdentifierDisplay;
|
|
5963
5947
|
exports.IdentifierInput = IdentifierInput;
|
|
5964
5948
|
exports.Logo = Logo;
|
|
5965
5949
|
exports.MedplumLink = MedplumLink;
|
|
@@ -5969,11 +5953,14 @@
|
|
|
5969
5953
|
exports.ObservationTable = ObservationTable;
|
|
5970
5954
|
exports.PatientTimeline = PatientTimeline;
|
|
5971
5955
|
exports.PlanDefinitionBuilder = PlanDefinitionBuilder;
|
|
5956
|
+
exports.QuantityDisplay = QuantityDisplay;
|
|
5957
|
+
exports.QuantityInput = QuantityInput;
|
|
5972
5958
|
exports.QuestionnaireBuilder = QuestionnaireBuilder;
|
|
5973
5959
|
exports.QuestionnaireForm = QuestionnaireForm;
|
|
5974
5960
|
exports.QuestionnaireFormItem = QuestionnaireFormItem;
|
|
5975
5961
|
exports.RangeDisplay = RangeDisplay;
|
|
5976
5962
|
exports.RangeInput = RangeInput;
|
|
5963
|
+
exports.ReferenceDisplay = ReferenceDisplay;
|
|
5977
5964
|
exports.ReferenceInput = ReferenceInput;
|
|
5978
5965
|
exports.ReferenceRangeEditor = ReferenceRangeEditor;
|
|
5979
5966
|
exports.ReferenceRangeGroupEditor = ReferenceRangeGroupEditor;
|
|
@@ -6005,6 +5992,7 @@
|
|
|
6005
5992
|
exports.StatusBadge = StatusBadge;
|
|
6006
5993
|
exports.Timeline = Timeline;
|
|
6007
5994
|
exports.TimelineItem = TimelineItem;
|
|
5995
|
+
exports.TimingInput = TimingInput;
|
|
6008
5996
|
exports.addDateFilterBetween = addDateFilterBetween;
|
|
6009
5997
|
exports.addField = addField;
|
|
6010
5998
|
exports.addFilter = addFilter;
|
|
@@ -6025,10 +6013,12 @@
|
|
|
6025
6013
|
exports.deleteFilter = deleteFilter;
|
|
6026
6014
|
exports.getErrorsForInput = getErrorsForInput;
|
|
6027
6015
|
exports.getIssuesForExpression = getIssuesForExpression;
|
|
6016
|
+
exports.getMonthString = getMonthString;
|
|
6028
6017
|
exports.getOpString = getOpString;
|
|
6029
6018
|
exports.getRecaptcha = getRecaptcha;
|
|
6030
6019
|
exports.getSearchOperators = getSearchOperators;
|
|
6031
6020
|
exports.getSortField = getSortField;
|
|
6021
|
+
exports.getStartMonth = getStartMonth;
|
|
6032
6022
|
exports.getTimeString = getTimeString;
|
|
6033
6023
|
exports.getValueAndType = getValueAndType;
|
|
6034
6024
|
exports.initRecaptcha = initRecaptcha;
|