@medplum/react 1.0.3 → 1.0.5
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/AsyncAutocomplete/AsyncAutocomplete.d.ts +14 -0
- package/dist/cjs/Container/Container.d.ts +3 -0
- package/dist/cjs/DiagnosticReportDisplay/DiagnosticReportDisplay.stories.d.ts +1 -0
- package/dist/cjs/Document/Document.d.ts +3 -6
- package/dist/cjs/FhirPathTable/FhirPathTable.d.ts +2 -2
- package/dist/cjs/Panel/Panel.d.ts +11 -0
- package/dist/cjs/Timeline/Timeline.d.ts +2 -4
- package/dist/cjs/ValueSetAutocomplete/ValueSetAutocomplete.d.ts +3 -6
- package/dist/cjs/auth/ChooseProfileForm.d.ts +2 -1
- package/dist/cjs/auth/ChooseScopeForm.d.ts +2 -1
- package/dist/cjs/auth/MfaForm.d.ts +7 -0
- package/dist/cjs/auth/OktaButton.d.ts +5 -0
- package/dist/cjs/auth/SignInForm.d.ts +10 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +410 -215
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +1 -1
- package/dist/cjs/index.min.js.map +1 -1
- package/dist/cjs/stories/referenceLab.d.ts +3 -1
- package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.d.ts +14 -0
- package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.js +116 -0
- package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.js.map +1 -0
- package/dist/esm/AttachmentDisplay/AttachmentDisplay.js +2 -1
- package/dist/esm/AttachmentDisplay/AttachmentDisplay.js.map +1 -1
- package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.js +3 -0
- package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.js.map +1 -1
- package/dist/esm/CodeInput/CodeInput.js +3 -2
- package/dist/esm/CodeInput/CodeInput.js.map +1 -1
- package/dist/esm/CodeableConceptInput/CodeableConceptInput.js +18 -18
- package/dist/esm/CodeableConceptInput/CodeableConceptInput.js.map +1 -1
- package/dist/esm/CodingInput/CodingInput.js +3 -2
- package/dist/esm/CodingInput/CodingInput.js.map +1 -1
- package/dist/esm/Container/Container.d.ts +3 -0
- package/dist/esm/Container/Container.js +20 -0
- package/dist/esm/Container/Container.js.map +1 -0
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.js +8 -2
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.js.map +1 -1
- package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.stories.d.ts +1 -0
- package/dist/esm/Document/Document.d.ts +3 -6
- package/dist/esm/Document/Document.js +5 -6
- package/dist/esm/Document/Document.js.map +1 -1
- package/dist/esm/FhirPathTable/FhirPathTable.d.ts +2 -2
- package/dist/esm/FhirPathTable/FhirPathTable.js.map +1 -1
- package/dist/esm/Panel/Panel.d.ts +11 -0
- package/dist/esm/Panel/Panel.js +35 -0
- package/dist/esm/Panel/Panel.js.map +1 -0
- package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.js +3 -3
- package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.js.map +1 -1
- package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.js +6 -6
- package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.js.map +1 -1
- package/dist/esm/QuestionnaireForm/QuestionnaireForm.js +1 -0
- package/dist/esm/QuestionnaireForm/QuestionnaireForm.js.map +1 -1
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.js +4 -3
- package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.js.map +1 -1
- package/dist/esm/ResourceInput/ResourceInput.js +2 -1
- package/dist/esm/ResourceInput/ResourceInput.js.map +1 -1
- package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.js +4 -0
- package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.js.map +1 -1
- package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.js +4 -0
- package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.js.map +1 -1
- package/dist/esm/ResourceTimeline/ResourceTimeline.js +3 -2
- package/dist/esm/ResourceTimeline/ResourceTimeline.js.map +1 -1
- package/dist/esm/SearchControl/SearchControl.js +2 -1
- package/dist/esm/SearchControl/SearchControl.js.map +1 -1
- package/dist/esm/StatusBadge/StatusBadge.js +2 -1
- package/dist/esm/StatusBadge/StatusBadge.js.map +1 -1
- package/dist/esm/Timeline/Timeline.d.ts +2 -4
- package/dist/esm/Timeline/Timeline.js +14 -10
- package/dist/esm/Timeline/Timeline.js.map +1 -1
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.d.ts +3 -6
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.js +24 -44
- package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.js.map +1 -1
- package/dist/esm/auth/AuthenticationForm.js +2 -2
- package/dist/esm/auth/AuthenticationForm.js.map +1 -1
- package/dist/esm/auth/ChooseProfileForm.d.ts +2 -1
- package/dist/esm/auth/ChooseProfileForm.js.map +1 -1
- package/dist/esm/auth/ChooseScopeForm.d.ts +2 -1
- package/dist/esm/auth/ChooseScopeForm.js.map +1 -1
- package/dist/esm/auth/MfaForm.d.ts +7 -0
- package/dist/esm/auth/MfaForm.js +34 -0
- package/dist/esm/auth/MfaForm.js.map +1 -0
- package/dist/esm/auth/NewProjectForm.js +5 -4
- package/dist/esm/auth/NewProjectForm.js.map +1 -1
- package/dist/esm/auth/NewUserForm.js +7 -6
- package/dist/esm/auth/NewUserForm.js.map +1 -1
- package/dist/esm/auth/OktaButton.d.ts +5 -0
- package/dist/esm/auth/SignInForm.d.ts +10 -0
- package/dist/esm/auth/SignInForm.js +16 -0
- package/dist/esm/auth/SignInForm.js.map +1 -1
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +3 -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/stories/referenceLab.d.ts +3 -1
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -131,26 +131,41 @@
|
|
|
131
131
|
return (React.createElement(core$1.TextInput, { name: props.name, placeholder: "Annotation text", defaultValue: value.text, onChange: (e) => setText(e.currentTarget.value) }));
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
134
|
+
/******************************************************************************
|
|
135
|
+
Copyright (c) Microsoft Corporation.
|
|
136
|
+
|
|
137
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
138
|
+
purpose with or without fee is hereby granted.
|
|
139
|
+
|
|
140
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
141
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
142
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
143
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
144
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
145
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
146
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
147
|
+
***************************************************************************** */
|
|
148
|
+
|
|
149
|
+
function __rest(s, e) {
|
|
150
|
+
var t = {};
|
|
151
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
152
|
+
t[p] = s[p];
|
|
153
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
154
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
155
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
156
|
+
t[p[i]] = s[p[i]];
|
|
157
|
+
}
|
|
158
|
+
return t;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
162
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
163
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
164
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
165
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
166
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
167
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
168
|
+
});
|
|
154
169
|
}
|
|
155
170
|
|
|
156
171
|
/**
|
|
@@ -185,6 +200,137 @@
|
|
|
185
200
|
return el instanceof HTMLInputElement && el.type === 'checkbox';
|
|
186
201
|
}
|
|
187
202
|
|
|
203
|
+
function AsyncAutocomplete(props) {
|
|
204
|
+
const { defaultValue, toKey, toOption, loadOptions, onChange, onCreate } = props, rest = __rest(props, ["defaultValue", "toKey", "toOption", "loadOptions", "onChange", "onCreate"]);
|
|
205
|
+
const defaultItems = toDefaultItems(defaultValue);
|
|
206
|
+
const inputRef = React.useRef(null);
|
|
207
|
+
const [lastValue, setLastValue] = React.useState(undefined);
|
|
208
|
+
const [timer, setTimer] = React.useState();
|
|
209
|
+
const [abortController, setAbortController] = React.useState();
|
|
210
|
+
const [autoSubmit, setAutoSubmit] = React.useState();
|
|
211
|
+
const [options, setOptions] = React.useState(defaultItems === null || defaultItems === void 0 ? void 0 : defaultItems.map(toOption));
|
|
212
|
+
const lastValueRef = React.useRef();
|
|
213
|
+
lastValueRef.current = lastValue;
|
|
214
|
+
const timerRef = React.useRef();
|
|
215
|
+
timerRef.current = timer;
|
|
216
|
+
const abortControllerRef = React.useRef();
|
|
217
|
+
abortControllerRef.current = abortController;
|
|
218
|
+
const autoSubmitRef = React.useRef();
|
|
219
|
+
autoSubmitRef.current = autoSubmit;
|
|
220
|
+
const optionsRef = React.useRef();
|
|
221
|
+
optionsRef.current = options;
|
|
222
|
+
const handleTimer = React.useCallback(() => {
|
|
223
|
+
var _a, _b;
|
|
224
|
+
setTimer(undefined);
|
|
225
|
+
const value = ((_b = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.trim()) || '';
|
|
226
|
+
if (value === lastValueRef.current) {
|
|
227
|
+
// Nothing has changed, move on
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
setLastValue(value);
|
|
231
|
+
const newAbortController = new AbortController();
|
|
232
|
+
setAbortController(newAbortController);
|
|
233
|
+
loadOptions(value, newAbortController.signal)
|
|
234
|
+
.then((newValues) => {
|
|
235
|
+
if (!newAbortController.signal.aborted) {
|
|
236
|
+
setOptions(newValues.map(toOption));
|
|
237
|
+
setAbortController(undefined);
|
|
238
|
+
if (autoSubmitRef.current) {
|
|
239
|
+
if (newValues.length > 0) {
|
|
240
|
+
onChange(newValues.slice(0, 1));
|
|
241
|
+
}
|
|
242
|
+
setAutoSubmit(false);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
.catch(console.log);
|
|
247
|
+
}, [loadOptions, onChange, toOption]);
|
|
248
|
+
const handleSearchChange = React.useCallback(() => {
|
|
249
|
+
if (abortControllerRef.current) {
|
|
250
|
+
abortControllerRef.current.abort();
|
|
251
|
+
setAbortController(undefined);
|
|
252
|
+
}
|
|
253
|
+
if (timerRef.current !== undefined) {
|
|
254
|
+
window.clearTimeout(timerRef.current);
|
|
255
|
+
}
|
|
256
|
+
const newTimer = window.setTimeout(() => handleTimer(), 100);
|
|
257
|
+
setTimer(newTimer);
|
|
258
|
+
}, [handleTimer]);
|
|
259
|
+
const handleChange = React.useCallback((values) => {
|
|
260
|
+
var _a, _b;
|
|
261
|
+
const result = [];
|
|
262
|
+
for (const value of values) {
|
|
263
|
+
let item = (_b = (_a = optionsRef.current) === null || _a === void 0 ? void 0 : _a.find((option) => option.value === value)) === null || _b === void 0 ? void 0 : _b.resource;
|
|
264
|
+
if (!item) {
|
|
265
|
+
item = onCreate(value);
|
|
266
|
+
}
|
|
267
|
+
result.push(item);
|
|
268
|
+
}
|
|
269
|
+
onChange(result);
|
|
270
|
+
}, [onChange, onCreate]);
|
|
271
|
+
const handleKeyDown = React.useCallback((e) => {
|
|
272
|
+
if (e.key === 'Enter') {
|
|
273
|
+
if (!timerRef.current && !abortControllerRef.current) {
|
|
274
|
+
killEvent(e);
|
|
275
|
+
if (optionsRef.current && optionsRef.current.length > 0) {
|
|
276
|
+
setOptions(optionsRef.current.slice(0, 1));
|
|
277
|
+
handleChange([optionsRef.current[0].value]);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
// The user pressed enter, but we don't have results yet.
|
|
282
|
+
// We need to wait for the results to come in.
|
|
283
|
+
setAutoSubmit(true);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}, [handleChange]);
|
|
287
|
+
const handleCreate = React.useCallback((input) => {
|
|
288
|
+
const option = toOption(onCreate(input));
|
|
289
|
+
setOptions([...optionsRef.current, option]);
|
|
290
|
+
return option;
|
|
291
|
+
}, [onCreate, setOptions, toOption]);
|
|
292
|
+
const handleFilter = React.useCallback((_value, selected) => !selected, []);
|
|
293
|
+
React.useEffect(() => {
|
|
294
|
+
return () => {
|
|
295
|
+
if (abortControllerRef.current) {
|
|
296
|
+
abortControllerRef.current.abort();
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
}, []);
|
|
300
|
+
return (React.createElement(core$1.MultiSelect, Object.assign({}, rest, { ref: inputRef, defaultValue: defaultItems.map(toKey), searchable: true, onKeyDown: handleKeyDown, onSearchChange: handleSearchChange, data: options, onFocus: handleTimer, onChange: handleChange, onCreate: handleCreate, rightSectionWidth: 40, rightSection: abortController ? React.createElement(core$1.Loader, { size: 16 }) : null, filter: handleFilter })));
|
|
301
|
+
}
|
|
302
|
+
function toDefaultItems(defaultValue) {
|
|
303
|
+
if (!defaultValue) {
|
|
304
|
+
return [];
|
|
305
|
+
}
|
|
306
|
+
if (Array.isArray(defaultValue)) {
|
|
307
|
+
return defaultValue;
|
|
308
|
+
}
|
|
309
|
+
return [defaultValue];
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function AttachmentDisplay(props) {
|
|
313
|
+
const value = props.value;
|
|
314
|
+
const { contentType, url, title } = value !== null && value !== void 0 ? value : {};
|
|
315
|
+
if (!url) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
return (React.createElement("div", { "data-testid": "attachment-display" },
|
|
319
|
+
(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 })),
|
|
320
|
+
(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('video/')) && (React.createElement("video", { "data-testid": "attachment-video", style: { maxWidth: props.maxWidth }, controls: true },
|
|
321
|
+
React.createElement("source", { type: contentType, src: url }))),
|
|
322
|
+
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 } },
|
|
323
|
+
React.createElement("iframe", { width: "100%", height: "400", src: url + '#navpanes=0', allowFullScreen: true, frameBorder: 0, seamless: true }))),
|
|
324
|
+
React.createElement("div", { "data-testid": "download-link", style: { padding: '2px 16px 16px 16px' } },
|
|
325
|
+
React.createElement(core$1.Anchor, { href: value === null || value === void 0 ? void 0 : value.url, "data-testid": "attachment-details", target: "_blank", rel: "noopener noreferrer" }, (value === null || value === void 0 ? void 0 : value.title) || 'Download'))));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function AttachmentArrayDisplay(props) {
|
|
329
|
+
return (React.createElement("div", null, props.values &&
|
|
330
|
+
props.values.map((v, index) => (React.createElement("div", { key: 'attatchment-' + index },
|
|
331
|
+
React.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
|
|
332
|
+
}
|
|
333
|
+
|
|
188
334
|
function AttachmentButton(props) {
|
|
189
335
|
const medplum = useMedplum();
|
|
190
336
|
const fileInputRef = React.useRef(null);
|
|
@@ -292,50 +438,53 @@
|
|
|
292
438
|
return (React.createElement(AttachmentButton, { onUpload: setValueWrapper }, (props) => React.createElement(core$1.Button, Object.assign({}, props), "Upload...")));
|
|
293
439
|
}
|
|
294
440
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
441
|
+
const useStyles$d = core$1.createStyles(() => ({
|
|
442
|
+
root: {
|
|
443
|
+
'@media (max-width: 800px)': {
|
|
444
|
+
paddingLeft: 4,
|
|
445
|
+
paddingRight: 4,
|
|
446
|
+
},
|
|
447
|
+
},
|
|
448
|
+
}));
|
|
449
|
+
function Container(props) {
|
|
450
|
+
const { children } = props, others = __rest(props, ["children"]);
|
|
451
|
+
const { classes } = useStyles$d();
|
|
452
|
+
return (React.createElement(core$1.Container, Object.assign({ className: classes.root }, others), children));
|
|
302
453
|
}
|
|
303
454
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
338
|
-
});
|
|
455
|
+
const useStyles$c = core$1.createStyles((theme, { width, fill }) => ({
|
|
456
|
+
paper: {
|
|
457
|
+
maxWidth: width,
|
|
458
|
+
margin: `${theme.spacing.xl}px auto`,
|
|
459
|
+
padding: fill ? 0 : theme.spacing.md,
|
|
460
|
+
'@media (max-width: 800px)': {
|
|
461
|
+
padding: fill ? 0 : 8,
|
|
462
|
+
},
|
|
463
|
+
'& img': {
|
|
464
|
+
width: '100%',
|
|
465
|
+
maxWidth: '100%',
|
|
466
|
+
},
|
|
467
|
+
'& video': {
|
|
468
|
+
width: '100%',
|
|
469
|
+
maxWidth: '100%',
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
}));
|
|
473
|
+
const defaultProps$1 = {
|
|
474
|
+
shadow: 'xs',
|
|
475
|
+
radius: 'md',
|
|
476
|
+
withBorder: true,
|
|
477
|
+
};
|
|
478
|
+
function Panel(props) {
|
|
479
|
+
const _a = core$1.useComponentDefaultProps('Panel', defaultProps$1, props), { className, children, width, fill, unstyled } = _a, others = __rest(_a, ["className", "children", "width", "fill", "unstyled"]);
|
|
480
|
+
const { classes, cx } = useStyles$c({ width, fill }, { name: 'Panel', unstyled });
|
|
481
|
+
return (React.createElement(core$1.Paper, Object.assign({ className: cx(classes.paper, className) }, others), children));
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function Document(props) {
|
|
485
|
+
const { children } = props, others = __rest(props, ["children"]);
|
|
486
|
+
return (React.createElement(Container, null,
|
|
487
|
+
React.createElement(Panel, Object.assign({}, others), children)));
|
|
339
488
|
}
|
|
340
489
|
|
|
341
490
|
/**
|
|
@@ -452,10 +601,11 @@
|
|
|
452
601
|
React.createElement(core$1.Stack, { spacing: "xl" },
|
|
453
602
|
React.createElement(core$1.TextInput, { name: "projectName", label: "Project Name", placeholder: "My Project", required: true, autoFocus: true, error: getErrorsForInput(outcome, 'firstName') }),
|
|
454
603
|
React.createElement(core$1.Text, { color: "dimmed", size: "xs" },
|
|
455
|
-
"By clicking submit you agree to the Medplum
|
|
456
|
-
|
|
604
|
+
"By clicking submit you agree to the Medplum",
|
|
605
|
+
' ',
|
|
606
|
+
React.createElement(core$1.Anchor, { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
|
|
457
607
|
' and ',
|
|
458
|
-
React.createElement(
|
|
608
|
+
React.createElement(core$1.Anchor, { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
459
609
|
".")),
|
|
460
610
|
React.createElement(core$1.Group, { position: "right", mt: "xl", noWrap: true },
|
|
461
611
|
React.createElement(core$1.Button, { type: "submit" }, "Create project"))));
|
|
@@ -596,17 +746,18 @@
|
|
|
596
746
|
React.createElement(core$1.TextInput, { name: "email", type: "email", label: "Email", placeholder: "name@domain.com", required: true, error: getErrorsForInput(outcome, 'email') }),
|
|
597
747
|
React.createElement(core$1.PasswordInput, { name: "password", label: "Password", autoComplete: "off", required: true, error: getErrorsForInput(outcome, 'password') }),
|
|
598
748
|
React.createElement(core$1.Text, { color: "dimmed", size: "xs" },
|
|
599
|
-
"By clicking submit you agree to the Medplum
|
|
600
|
-
|
|
749
|
+
"By clicking submit you agree to the Medplum",
|
|
750
|
+
' ',
|
|
751
|
+
React.createElement(core$1.Anchor, { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
|
|
601
752
|
' and ',
|
|
602
|
-
React.createElement(
|
|
753
|
+
React.createElement(core$1.Anchor, { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
603
754
|
"."),
|
|
604
755
|
React.createElement(core$1.Text, { color: "dimmed", size: "xs" },
|
|
605
756
|
"This site is protected by reCAPTCHA and the Google",
|
|
606
757
|
' ',
|
|
607
|
-
React.createElement(
|
|
758
|
+
React.createElement(core$1.Anchor, { href: "https://policies.google.com/privacy" }, "Privacy\u00A0Policy"),
|
|
608
759
|
' and ',
|
|
609
|
-
React.createElement(
|
|
760
|
+
React.createElement(core$1.Anchor, { href: "https://policies.google.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
610
761
|
" apply.")),
|
|
611
762
|
React.createElement(core$1.Group, { position: "apart", mt: "xl", noWrap: true },
|
|
612
763
|
React.createElement(core$1.Checkbox, { name: "remember", label: "Remember me", size: "xs" }),
|
|
@@ -680,10 +831,10 @@
|
|
|
680
831
|
React.createElement(core$1.Stack, { spacing: "xl" },
|
|
681
832
|
React.createElement(core$1.TextInput, { name: "email", type: "email", label: "Email", placeholder: "name@domain.com", required: true, autoFocus: true, error: getErrorsForInput(outcome, 'email') }),
|
|
682
833
|
React.createElement(core$1.PasswordInput, { name: "password", type: "password", label: "Password", autoComplete: "off", required: true, error: getErrorsForInput(outcome, 'password') })),
|
|
683
|
-
React.createElement(core$1.Group, { position: "apart", mt: "xl", noWrap: true },
|
|
834
|
+
React.createElement(core$1.Group, { position: "apart", mt: "xl", spacing: 0, noWrap: true },
|
|
684
835
|
onForgotPassword && (React.createElement(core$1.Anchor, { component: "button", type: "button", color: "dimmed", onClick: onForgotPassword, size: "xs" }, "Forgot password")),
|
|
685
836
|
onRegister && (React.createElement(core$1.Anchor, { component: "button", type: "button", color: "dimmed", onClick: onRegister, size: "xs" }, "Register")),
|
|
686
|
-
React.createElement(core$1.Checkbox, { id: "remember", name: "remember", label: "Remember me", size: "xs" }),
|
|
837
|
+
React.createElement(core$1.Checkbox, { id: "remember", name: "remember", label: "Remember me", size: "xs", sx: { lineHeight: 1 } }),
|
|
687
838
|
React.createElement(core$1.Button, { type: "submit" }, "Sign in"))));
|
|
688
839
|
}
|
|
689
840
|
|
|
@@ -732,12 +883,48 @@
|
|
|
732
883
|
React.createElement(core$1.Button, { type: "submit" }, "Set scope")))));
|
|
733
884
|
}
|
|
734
885
|
|
|
886
|
+
function MfaForm(props) {
|
|
887
|
+
const medplum = useMedplum();
|
|
888
|
+
const [errorMessage, setErrorMessage] = React.useState(undefined);
|
|
889
|
+
return (React.createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => {
|
|
890
|
+
setErrorMessage(undefined);
|
|
891
|
+
medplum
|
|
892
|
+
.post('auth/mfa/verify', {
|
|
893
|
+
login: props.login,
|
|
894
|
+
token: formData.token,
|
|
895
|
+
})
|
|
896
|
+
.then(props.handleAuthResponse)
|
|
897
|
+
.catch((err) => setErrorMessage(core.normalizeErrorString(err)));
|
|
898
|
+
} },
|
|
899
|
+
React.createElement(core$1.Stack, null,
|
|
900
|
+
React.createElement(core$1.Center, { sx: { flexDirection: 'column' } },
|
|
901
|
+
React.createElement(Logo, { size: 32 }),
|
|
902
|
+
React.createElement(core$1.Title, null, "Enter MFA code")),
|
|
903
|
+
errorMessage && (React.createElement(core$1.Alert, { icon: React.createElement(icons.IconAlertCircle, { size: 16 }), title: "Error", color: "red" }, errorMessage)),
|
|
904
|
+
React.createElement(core$1.Stack, null,
|
|
905
|
+
React.createElement(core$1.TextInput, { name: "token", label: "MFA code", required: true })),
|
|
906
|
+
React.createElement(core$1.Group, { position: "right", mt: "xl" },
|
|
907
|
+
React.createElement(core$1.Button, { type: "submit" }, "Submit code")))));
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* The SignInForm component allows users to sign in to Medplum.
|
|
912
|
+
*
|
|
913
|
+
* "Signing in" is a multi-step process:
|
|
914
|
+
* 1) Authentication - identify the user
|
|
915
|
+
* 2) MFA - If MFA is enabled, prompt for MFA code
|
|
916
|
+
* 3) Choose profile - If the user has multiple profiles, prompt to choose one
|
|
917
|
+
* 4) Choose scope - If the user has multiple scopes, prompt to choose one
|
|
918
|
+
* 5) Success - Return to the caller with either a code or a redirect
|
|
919
|
+
*/
|
|
735
920
|
function SignInForm(props) {
|
|
736
921
|
const { chooseScopes, onSuccess, onForgotPassword, onRegister, onCode } = props, baseLoginRequest = __rest(props, ["chooseScopes", "onSuccess", "onForgotPassword", "onRegister", "onCode"]);
|
|
737
922
|
const medplum = useMedplum();
|
|
738
923
|
const [login, setLogin] = React.useState(undefined);
|
|
924
|
+
const [mfaRequired, setAuthenticatorRequired] = React.useState(false);
|
|
739
925
|
const [memberships, setMemberships] = React.useState(undefined);
|
|
740
926
|
function handleAuthResponse(response) {
|
|
927
|
+
setAuthenticatorRequired(!!response.mfaRequired);
|
|
741
928
|
if (response.login) {
|
|
742
929
|
setLogin(response.login);
|
|
743
930
|
}
|
|
@@ -775,6 +962,9 @@
|
|
|
775
962
|
if (!login) {
|
|
776
963
|
return (React.createElement(AuthenticationForm, Object.assign({ generatePkce: !onCode, onForgotPassword: onForgotPassword, onRegister: onRegister, handleAuthResponse: handleAuthResponse }, baseLoginRequest), props.children));
|
|
777
964
|
}
|
|
965
|
+
else if (mfaRequired) {
|
|
966
|
+
return React.createElement(MfaForm, { login: login, handleAuthResponse: handleAuthResponse });
|
|
967
|
+
}
|
|
778
968
|
else if (memberships) {
|
|
779
969
|
return React.createElement(ChooseProfileForm, { login: login, memberships: memberships, handleAuthResponse: handleAuthResponse });
|
|
780
970
|
}
|
|
@@ -1028,6 +1218,7 @@
|
|
|
1028
1218
|
case core.PropertyType.Period:
|
|
1029
1219
|
return React.createElement(React.Fragment, null, core.formatPeriod(value));
|
|
1030
1220
|
case core.PropertyType.Quantity:
|
|
1221
|
+
case core.PropertyType.Duration:
|
|
1031
1222
|
return React.createElement(QuantityDisplay, { value: value });
|
|
1032
1223
|
case core.PropertyType.Range:
|
|
1033
1224
|
return React.createElement(RangeDisplay, { value: value });
|
|
@@ -1037,6 +1228,9 @@
|
|
|
1037
1228
|
return React.createElement(ReferenceDisplay, { value: value, link: props.link });
|
|
1038
1229
|
case core.PropertyType.Timing:
|
|
1039
1230
|
return React.createElement(React.Fragment, null, core.formatTiming(value));
|
|
1231
|
+
case core.PropertyType.Dosage:
|
|
1232
|
+
case core.PropertyType.UsageContext:
|
|
1233
|
+
return (React.createElement(BackboneElementDisplay, { value: { type: propertyType, value }, compact: true, ignoreMissingValues: props.ignoreMissingValues }));
|
|
1040
1234
|
default:
|
|
1041
1235
|
if (!(property === null || property === void 0 ? void 0 : property.path)) {
|
|
1042
1236
|
throw Error(`Displaying property of type ${props.propertyType} requires element definition path`);
|
|
@@ -1093,6 +1287,9 @@
|
|
|
1093
1287
|
return null;
|
|
1094
1288
|
}
|
|
1095
1289
|
const property = entry[1];
|
|
1290
|
+
if (!property.path) {
|
|
1291
|
+
property.path = typeName + '.' + key;
|
|
1292
|
+
}
|
|
1096
1293
|
const [propertyValue, propertyType] = getValueAndType(typedValue, key);
|
|
1097
1294
|
if (props.ignoreMissingValues &&
|
|
1098
1295
|
(!propertyValue || (Array.isArray(propertyValue) && propertyValue.length === 0))) {
|
|
@@ -1220,59 +1417,39 @@
|
|
|
1220
1417
|
return obj;
|
|
1221
1418
|
}
|
|
1222
1419
|
|
|
1223
|
-
function
|
|
1420
|
+
function toKey(element) {
|
|
1421
|
+
return element.code;
|
|
1422
|
+
}
|
|
1423
|
+
function toOption(element) {
|
|
1224
1424
|
return {
|
|
1225
1425
|
value: element.code,
|
|
1226
1426
|
label: getDisplay(element),
|
|
1227
|
-
element,
|
|
1427
|
+
resource: element,
|
|
1428
|
+
};
|
|
1429
|
+
}
|
|
1430
|
+
function createValue(input) {
|
|
1431
|
+
return {
|
|
1432
|
+
code: input,
|
|
1433
|
+
display: input,
|
|
1228
1434
|
};
|
|
1229
1435
|
}
|
|
1230
1436
|
function ValueSetAutocomplete(props) {
|
|
1231
1437
|
const medplum = useMedplum();
|
|
1232
|
-
const {
|
|
1233
|
-
const
|
|
1234
|
-
const [data, setData] = React.useState((defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.code) ? [valueSetElementToAutocompleteItem(defaultValue)] : []);
|
|
1235
|
-
const dataRef = React.useRef();
|
|
1236
|
-
dataRef.current = data;
|
|
1237
|
-
const loadValues = React.useCallback((input) => __awaiter(this, void 0, void 0, function* () {
|
|
1438
|
+
const { elementDefinition } = props, rest = __rest(props, ["elementDefinition"]);
|
|
1439
|
+
const loadValues = React.useCallback((input, signal) => __awaiter(this, void 0, void 0, function* () {
|
|
1238
1440
|
var _a, _b;
|
|
1239
|
-
const system = (_a =
|
|
1240
|
-
const valueSet = yield medplum.searchValueSet(system, input);
|
|
1441
|
+
const system = (_a = elementDefinition.binding) === null || _a === void 0 ? void 0 : _a.valueSet;
|
|
1442
|
+
const valueSet = yield medplum.searchValueSet(system, input, { signal });
|
|
1241
1443
|
const valueSetElements = (_b = valueSet.expansion) === null || _b === void 0 ? void 0 : _b.contains;
|
|
1242
|
-
const newData = [
|
|
1444
|
+
const newData = [];
|
|
1243
1445
|
for (const valueSetElement of valueSetElements) {
|
|
1244
|
-
if (valueSetElement.code && !newData.some((item) => item.
|
|
1245
|
-
newData.push(
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
setData(newData);
|
|
1249
|
-
}), [medplum, property, dataRef]);
|
|
1250
|
-
function handleChange(values) {
|
|
1251
|
-
setTextValues(values);
|
|
1252
|
-
const textValue = values[0];
|
|
1253
|
-
let currentItem = undefined;
|
|
1254
|
-
if (textValue) {
|
|
1255
|
-
currentItem = dataRef.current.find((item) => item.value === values[0]);
|
|
1256
|
-
if (!currentItem) {
|
|
1257
|
-
const newElement = { code: textValue, display: textValue };
|
|
1258
|
-
currentItem = valueSetElementToAutocompleteItem(newElement);
|
|
1259
|
-
setData([...dataRef.current, currentItem]);
|
|
1446
|
+
if (valueSetElement.code && !newData.some((item) => item.code === valueSetElement.code)) {
|
|
1447
|
+
newData.push(valueSetElement);
|
|
1260
1448
|
}
|
|
1261
1449
|
}
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
}
|
|
1266
|
-
React.useEffect(() => {
|
|
1267
|
-
loadValues('').catch(console.log);
|
|
1268
|
-
}, [loadValues]);
|
|
1269
|
-
return (React.createElement(core$1.MultiSelect, { data: data, placeholder: props.placeholder, searchable: true, creatable: true, clearable: true, value: textValues, filter: (value, selected, item) => {
|
|
1270
|
-
var _a, _b;
|
|
1271
|
-
return !!(textValues.length === 0 &&
|
|
1272
|
-
!selected &&
|
|
1273
|
-
(((_a = item.element.display) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(value.toLowerCase().trim())) ||
|
|
1274
|
-
((_b = item.element.code) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes(value.toLowerCase().trim()))));
|
|
1275
|
-
}, onChange: handleChange, getCreateLabel: (query) => `+ Create ${query}`, onCreate: (query) => valueSetElementToAutocompleteItem({ code: query, display: query }) }));
|
|
1450
|
+
return newData;
|
|
1451
|
+
}), [medplum, elementDefinition]);
|
|
1452
|
+
return (React.createElement(AsyncAutocomplete, Object.assign({}, rest, { creatable: true, clearable: true, toKey: toKey, toOption: toOption, loadOptions: loadValues, getCreateLabel: (query) => `+ Create ${query}`, onCreate: createValue })));
|
|
1276
1453
|
}
|
|
1277
1454
|
function getDisplay(item) {
|
|
1278
1455
|
return item.display || item.code || '';
|
|
@@ -1280,46 +1457,47 @@
|
|
|
1280
1457
|
|
|
1281
1458
|
function CodeableConceptInput(props) {
|
|
1282
1459
|
const [value, setValue] = React.useState(props.defaultValue);
|
|
1283
|
-
function handleChange(
|
|
1284
|
-
const newConcept =
|
|
1460
|
+
function handleChange(newValues) {
|
|
1461
|
+
const newConcept = valueSetElementToCodeableConcept(newValues);
|
|
1285
1462
|
setValue(newConcept);
|
|
1286
1463
|
if (props.onChange) {
|
|
1287
1464
|
props.onChange(newConcept);
|
|
1288
1465
|
}
|
|
1289
1466
|
}
|
|
1290
|
-
return (React.createElement(ValueSetAutocomplete, {
|
|
1467
|
+
return (React.createElement(ValueSetAutocomplete, { elementDefinition: props.property, name: props.name, placeholder: props.placeholder, defaultValue: value && codeableConceptToValueSetElement(value), onChange: handleChange }));
|
|
1291
1468
|
}
|
|
1292
1469
|
function codeableConceptToValueSetElement(concept) {
|
|
1293
|
-
var _a
|
|
1294
|
-
return {
|
|
1295
|
-
system:
|
|
1296
|
-
code:
|
|
1297
|
-
display:
|
|
1298
|
-
};
|
|
1470
|
+
var _a;
|
|
1471
|
+
return (_a = concept.coding) === null || _a === void 0 ? void 0 : _a.map((c) => ({
|
|
1472
|
+
system: c.system,
|
|
1473
|
+
code: c.code,
|
|
1474
|
+
display: c.display,
|
|
1475
|
+
}));
|
|
1299
1476
|
}
|
|
1300
|
-
function valueSetElementToCodeableConcept(
|
|
1477
|
+
function valueSetElementToCodeableConcept(elements) {
|
|
1478
|
+
if (elements.length === 0) {
|
|
1479
|
+
return undefined;
|
|
1480
|
+
}
|
|
1301
1481
|
return {
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
display: element.display,
|
|
1308
|
-
},
|
|
1309
|
-
],
|
|
1482
|
+
coding: elements.map((e) => ({
|
|
1483
|
+
system: e.system,
|
|
1484
|
+
code: e.code,
|
|
1485
|
+
display: e.display,
|
|
1486
|
+
})),
|
|
1310
1487
|
};
|
|
1311
1488
|
}
|
|
1312
1489
|
|
|
1313
1490
|
function CodeInput(props) {
|
|
1314
1491
|
const [value, setValue] = React.useState(props.defaultValue);
|
|
1315
|
-
function handleChange(
|
|
1492
|
+
function handleChange(newValues) {
|
|
1493
|
+
const newValue = newValues[0];
|
|
1316
1494
|
const newCode = valueSetElementToCode(newValue);
|
|
1317
1495
|
setValue(newCode);
|
|
1318
1496
|
if (props.onChange) {
|
|
1319
1497
|
props.onChange(newCode);
|
|
1320
1498
|
}
|
|
1321
1499
|
}
|
|
1322
|
-
return (React.createElement(ValueSetAutocomplete, {
|
|
1500
|
+
return (React.createElement(ValueSetAutocomplete, { elementDefinition: props.property, name: props.name, placeholder: props.placeholder, defaultValue: codeToValueSetElement(value), onChange: handleChange }));
|
|
1323
1501
|
}
|
|
1324
1502
|
function codeToValueSetElement(code) {
|
|
1325
1503
|
return code ? { code } : undefined;
|
|
@@ -1330,14 +1508,15 @@
|
|
|
1330
1508
|
|
|
1331
1509
|
function CodingInput(props) {
|
|
1332
1510
|
const [value, setValue] = React.useState(props.defaultValue);
|
|
1333
|
-
function handleChange(
|
|
1511
|
+
function handleChange(newValues) {
|
|
1512
|
+
const newValue = newValues[0];
|
|
1334
1513
|
const newConcept = newValue && valueSetElementToCoding(newValue);
|
|
1335
1514
|
setValue(newConcept);
|
|
1336
1515
|
if (props.onChange) {
|
|
1337
1516
|
props.onChange(newConcept);
|
|
1338
1517
|
}
|
|
1339
1518
|
}
|
|
1340
|
-
return (React.createElement(ValueSetAutocomplete, {
|
|
1519
|
+
return (React.createElement(ValueSetAutocomplete, { elementDefinition: props.property, name: props.name, placeholder: props.placeholder, defaultValue: value && codingToValueSetElement(value), onChange: handleChange }));
|
|
1341
1520
|
}
|
|
1342
1521
|
function codingToValueSetElement(coding) {
|
|
1343
1522
|
return {
|
|
@@ -1645,6 +1824,7 @@
|
|
|
1645
1824
|
Observation: 'code',
|
|
1646
1825
|
RequestGroup: '_id',
|
|
1647
1826
|
ActivityDefinition: 'name',
|
|
1827
|
+
User: 'email:contains',
|
|
1648
1828
|
};
|
|
1649
1829
|
function ResourceInput(props) {
|
|
1650
1830
|
const medplum = useMedplum();
|
|
@@ -1662,7 +1842,7 @@
|
|
|
1662
1842
|
setLoading(true);
|
|
1663
1843
|
const searchCode = SEARCH_CODES[props.resourceType] || 'name';
|
|
1664
1844
|
const searchParams = new URLSearchParams({
|
|
1665
|
-
[searchCode]:
|
|
1845
|
+
[searchCode]: input,
|
|
1666
1846
|
_count: '10',
|
|
1667
1847
|
});
|
|
1668
1848
|
const resources = yield medplum.searchResources(props.resourceType, searchParams);
|
|
@@ -1968,6 +2148,7 @@
|
|
|
1968
2148
|
return React.createElement(IdentifierInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
1969
2149
|
case core.PropertyType.Period:
|
|
1970
2150
|
return React.createElement(PeriodInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2151
|
+
case core.PropertyType.Duration:
|
|
1971
2152
|
case core.PropertyType.Quantity:
|
|
1972
2153
|
return React.createElement(QuantityInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
1973
2154
|
case core.PropertyType.Range:
|
|
@@ -1978,6 +2159,9 @@
|
|
|
1978
2159
|
return (React.createElement(ReferenceInput, { name: name, defaultValue: value, targetTypes: getTargetTypes(property), onChange: props.onChange }));
|
|
1979
2160
|
case core.PropertyType.Timing:
|
|
1980
2161
|
return React.createElement(TimingInput, { name: name, defaultValue: value, onChange: props.onChange });
|
|
2162
|
+
case core.PropertyType.Dosage:
|
|
2163
|
+
case core.PropertyType.UsageContext:
|
|
2164
|
+
return (React.createElement(BackboneElementInput, { typeName: propertyType, defaultValue: value, onChange: props.onChange, outcome: props.outcome }));
|
|
1981
2165
|
default:
|
|
1982
2166
|
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 }));
|
|
1983
2167
|
}
|
|
@@ -2171,6 +2355,64 @@
|
|
|
2171
2355
|
React.createElement(ResourceName, { value: props.value, link: props.link })));
|
|
2172
2356
|
}
|
|
2173
2357
|
|
|
2358
|
+
/*
|
|
2359
|
+
* Request status: https://hl7.org/fhir/valueset-request-status.html
|
|
2360
|
+
* draft, active, on-hold, revoked, completed, entered-in-error, unknown
|
|
2361
|
+
*
|
|
2362
|
+
* Publication status: https://hl7.org/fhir/valueset-publication-status.html
|
|
2363
|
+
* draft, active, retired, unknown
|
|
2364
|
+
*
|
|
2365
|
+
* Observation status: https://www.hl7.org/fhir/valueset-observation-status.html
|
|
2366
|
+
* registered, preliminary, final, amended, corrected, cancelled, entered-in-error, unknown
|
|
2367
|
+
*
|
|
2368
|
+
* DiagnosticReport status: https://hl7.org/fhir/valueset-diagnostic-report-status.html
|
|
2369
|
+
* registered, preliminary, final, amended, corrected, appended, cancelled, entered-in-error, unknown
|
|
2370
|
+
*
|
|
2371
|
+
* Task status: https://hl7.org/fhir/valueset-task-status.html
|
|
2372
|
+
* draft, requested, received, accepted, rejected, ready, cancelled, in-progress, on-hold, failed, completed, entered-in-error
|
|
2373
|
+
*
|
|
2374
|
+
* Appointment status: https://www.hl7.org/fhir/valueset-appointmentstatus.html
|
|
2375
|
+
* proposed, pending, booked, arrived, fulfilled, cancelled, noshow, entered-in-error, chcked-in, waitlist
|
|
2376
|
+
*/
|
|
2377
|
+
const statusToColor = {
|
|
2378
|
+
draft: 'blue',
|
|
2379
|
+
active: 'blue',
|
|
2380
|
+
'on-hold': 'yellow',
|
|
2381
|
+
revoked: 'red',
|
|
2382
|
+
completed: 'green',
|
|
2383
|
+
'entered-in-error': 'red',
|
|
2384
|
+
unknown: 'gray',
|
|
2385
|
+
retired: 'gray',
|
|
2386
|
+
registered: 'blue',
|
|
2387
|
+
preliminary: 'blue',
|
|
2388
|
+
final: 'green',
|
|
2389
|
+
amended: 'yellow',
|
|
2390
|
+
corrected: 'yellow',
|
|
2391
|
+
cancelled: 'red',
|
|
2392
|
+
requested: 'blue',
|
|
2393
|
+
received: 'blue',
|
|
2394
|
+
accepted: 'blue',
|
|
2395
|
+
rejected: 'red',
|
|
2396
|
+
ready: 'blue',
|
|
2397
|
+
'in-progress': 'blue',
|
|
2398
|
+
failed: 'red',
|
|
2399
|
+
proposed: 'blue',
|
|
2400
|
+
pending: 'blue',
|
|
2401
|
+
booked: 'blue',
|
|
2402
|
+
arrived: 'blue',
|
|
2403
|
+
fulfilled: 'green',
|
|
2404
|
+
noshow: 'red',
|
|
2405
|
+
'checked-in': 'blue',
|
|
2406
|
+
waitlist: 'gray',
|
|
2407
|
+
routine: 'gray',
|
|
2408
|
+
urgent: 'red',
|
|
2409
|
+
asap: 'red',
|
|
2410
|
+
stat: 'red',
|
|
2411
|
+
};
|
|
2412
|
+
function StatusBadge(props) {
|
|
2413
|
+
return React.createElement(core$1.Badge, { color: statusToColor[props.status] }, props.status);
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2174
2416
|
const useStyles$9 = core$1.createStyles((theme) => ({
|
|
2175
2417
|
table: {
|
|
2176
2418
|
border: `0.1px solid ${theme.colors.gray[5]}`,
|
|
@@ -2239,7 +2481,9 @@
|
|
|
2239
2481
|
React.createElement("th", null, "Test"),
|
|
2240
2482
|
React.createElement("th", null, "Value"),
|
|
2241
2483
|
React.createElement("th", null, "Reference Range"),
|
|
2242
|
-
React.createElement("th", null, "Interpretation")
|
|
2484
|
+
React.createElement("th", null, "Interpretation"),
|
|
2485
|
+
React.createElement("th", null, "Category"),
|
|
2486
|
+
React.createElement("th", null, "Status"))),
|
|
2243
2487
|
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 }))))));
|
|
2244
2488
|
}
|
|
2245
2489
|
function ObservationRow(props) {
|
|
@@ -2257,7 +2501,10 @@
|
|
|
2257
2501
|
React.createElement(ObservationValueDisplay, { value: observation })),
|
|
2258
2502
|
React.createElement("td", null,
|
|
2259
2503
|
React.createElement(ReferenceRangeDisplay, { value: observation.referenceRange })),
|
|
2260
|
-
React.createElement("td", null, observation.interpretation && observation.interpretation.length > 0 && (React.createElement(CodeableConceptDisplay, { value: observation.interpretation[0] })))
|
|
2504
|
+
React.createElement("td", null, observation.interpretation && observation.interpretation.length > 0 && (React.createElement(CodeableConceptDisplay, { value: observation.interpretation[0] }))),
|
|
2505
|
+
React.createElement("td", null, observation.category && observation.category.length > 0 && (React.createElement("ul", null, observation.category.map((concept) => (React.createElement("li", null,
|
|
2506
|
+
React.createElement(CodeableConceptDisplay, { value: concept }))))))),
|
|
2507
|
+
React.createElement("td", null, observation.status && React.createElement(StatusBadge, { status: observation.status }))));
|
|
2261
2508
|
}
|
|
2262
2509
|
function ObservationValueDisplay(props) {
|
|
2263
2510
|
const obs = props.value;
|
|
@@ -2396,29 +2643,30 @@
|
|
|
2396
2643
|
}
|
|
2397
2644
|
|
|
2398
2645
|
function Timeline(props) {
|
|
2399
|
-
return React.createElement(
|
|
2646
|
+
return React.createElement(Container, null, props.children);
|
|
2400
2647
|
}
|
|
2401
2648
|
function TimelineItem(props) {
|
|
2402
|
-
var _a, _b
|
|
2403
|
-
const
|
|
2404
|
-
|
|
2405
|
-
|
|
2649
|
+
var _a, _b;
|
|
2650
|
+
const { resource, profile, padding, popupMenuItems } = props, others = __rest(props, ["resource", "profile", "padding", "popupMenuItems"]);
|
|
2651
|
+
const author = profile !== null && profile !== void 0 ? profile : (_a = resource.meta) === null || _a === void 0 ? void 0 : _a.author;
|
|
2652
|
+
return (React.createElement(Panel, Object.assign({ "data-testid": "timeline-item", fill: true }, others),
|
|
2653
|
+
React.createElement(core$1.Group, { position: "apart", spacing: 8, mx: "xs", my: "sm" },
|
|
2406
2654
|
React.createElement(ResourceAvatar, { value: author, link: true, size: "md" }),
|
|
2407
2655
|
React.createElement("div", { style: { flex: 1 } },
|
|
2408
2656
|
React.createElement(core$1.Text, { size: "sm" },
|
|
2409
2657
|
React.createElement(ResourceName, { color: "dark", weight: 500, value: author, link: true })),
|
|
2410
2658
|
React.createElement(core$1.Text, { size: "xs" },
|
|
2411
|
-
React.createElement(MedplumLink, { color: "dimmed", to: props.resource }, core.formatDateTime((
|
|
2659
|
+
React.createElement(MedplumLink, { color: "dimmed", to: props.resource }, core.formatDateTime((_b = props.resource.meta) === null || _b === void 0 ? void 0 : _b.lastUpdated)),
|
|
2412
2660
|
React.createElement(core$1.Text, { component: "span", color: "dimmed", mx: 8 }, "\u00B7"),
|
|
2413
2661
|
React.createElement(MedplumLink, { color: "dimmed", to: props.resource }, props.resource.resourceType))),
|
|
2414
|
-
|
|
2662
|
+
popupMenuItems && (React.createElement(core$1.Menu, { position: "bottom-end", shadow: "md", width: 200 },
|
|
2415
2663
|
React.createElement(core$1.Menu.Target, null,
|
|
2416
2664
|
React.createElement(core$1.ActionIcon, { radius: "xl", "aria-label": `Actions for ${core.getReferenceString(props.resource)}` },
|
|
2417
2665
|
React.createElement(icons.IconDots, null))),
|
|
2418
|
-
|
|
2666
|
+
popupMenuItems))),
|
|
2419
2667
|
React.createElement(ErrorBoundary, null,
|
|
2420
|
-
|
|
2421
|
-
!
|
|
2668
|
+
padding && React.createElement("div", { style: { padding: '0 16px 16px 16px' } }, props.children),
|
|
2669
|
+
!padding && React.createElement(React.Fragment, null, props.children))));
|
|
2422
2670
|
}
|
|
2423
2671
|
|
|
2424
2672
|
/**
|
|
@@ -2625,7 +2873,7 @@
|
|
|
2625
2873
|
React.createElement(core$1.Loader, null)));
|
|
2626
2874
|
}
|
|
2627
2875
|
return (React.createElement(Timeline, null,
|
|
2628
|
-
props.createCommunication && (React.createElement(
|
|
2876
|
+
props.createCommunication && (React.createElement(Panel, null,
|
|
2629
2877
|
React.createElement(Form, { testid: "timeline-form", onSubmit: (formData) => {
|
|
2630
2878
|
createComment(formData.text);
|
|
2631
2879
|
const input = inputRef.current;
|
|
@@ -4049,7 +4297,7 @@
|
|
|
4049
4297
|
checkboxColumn && (React.createElement("td", null,
|
|
4050
4298
|
React.createElement("input", { type: "checkbox", value: "checked", "data-testid": "row-checkbox", "aria-label": `Checkbox for ${resource.id}`, checked: !!state.selected[resource.id], onChange: (e) => handleSingleCheckboxClick(e, resource.id) }))),
|
|
4051
4299
|
fields.map((field) => (React.createElement("td", { key: field.name }, renderValue(resource, field))))))))),
|
|
4052
|
-
(resources === null || resources === void 0 ? void 0 : resources.length) === 0 && (React.createElement(
|
|
4300
|
+
(resources === null || resources === void 0 ? void 0 : resources.length) === 0 && (React.createElement(Container, null,
|
|
4053
4301
|
React.createElement(core$1.Center, null,
|
|
4054
4302
|
React.createElement(core$1.Text, { size: "xl", color: "dimmed" }, "No results")))),
|
|
4055
4303
|
(lastResult === null || lastResult === void 0 ? void 0 : lastResult.total) !== undefined && lastResult.total > 0 && (React.createElement(core$1.Center, { m: "md", p: "md" },
|
|
@@ -4341,7 +4589,7 @@
|
|
|
4341
4589
|
props.actions.map((action) => (React.createElement("div", { key: action.id },
|
|
4342
4590
|
React.createElement(ActionBuilder, { action: action, selectedKey: props.selectedKey, setSelectedKey: props.setSelectedKey, hoverKey: props.hoverKey, setHoverKey: props.setHoverKey, onChange: changeAction, onRemove: () => removeAction(action) })))),
|
|
4343
4591
|
React.createElement("div", { className: classes.bottomActions },
|
|
4344
|
-
React.createElement(
|
|
4592
|
+
React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
4345
4593
|
killEvent(e);
|
|
4346
4594
|
addAction({ id: generateId$1() });
|
|
4347
4595
|
} }, "Add action"))));
|
|
@@ -4367,7 +4615,7 @@
|
|
|
4367
4615
|
return (React.createElement("div", { "data-testid": action.id, className: className, onClick: onClick, onMouseOver: onHover },
|
|
4368
4616
|
editing ? (React.createElement(ActionEditor, { action: action, actionType: actionType, onChange: props.onChange, selectedKey: props.selectedKey, setSelectedKey: props.setSelectedKey, hoverKey: props.hoverKey, setHoverKey: props.setHoverKey, onRemove: props.onRemove })) : (React.createElement(ActionDisplay, { action: action, actionType: actionType })),
|
|
4369
4617
|
React.createElement("div", { className: classes.bottomActions },
|
|
4370
|
-
React.createElement(
|
|
4618
|
+
React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
4371
4619
|
e.preventDefault();
|
|
4372
4620
|
props.onRemove();
|
|
4373
4621
|
} }, "Remove"))));
|
|
@@ -4531,6 +4779,7 @@
|
|
|
4531
4779
|
function setItems(newResponseItems) {
|
|
4532
4780
|
const newResponse = {
|
|
4533
4781
|
resourceType: 'QuestionnaireResponse',
|
|
4782
|
+
status: 'completed',
|
|
4534
4783
|
item: newResponseItems,
|
|
4535
4784
|
};
|
|
4536
4785
|
setResponse(newResponse);
|
|
@@ -4917,7 +5166,7 @@
|
|
|
4917
5166
|
] })))) : (React.createElement("div", null, linkId)))),
|
|
4918
5167
|
React.createElement("div", { className: classes.bottomActions },
|
|
4919
5168
|
isContainer && (React.createElement(React.Fragment, null,
|
|
4920
|
-
React.createElement(
|
|
5169
|
+
React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
4921
5170
|
e.preventDefault();
|
|
4922
5171
|
addItem({
|
|
4923
5172
|
id: generateId(),
|
|
@@ -4926,7 +5175,7 @@
|
|
|
4926
5175
|
text: 'Question',
|
|
4927
5176
|
});
|
|
4928
5177
|
} }, "Add item"),
|
|
4929
|
-
React.createElement(
|
|
5178
|
+
React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
4930
5179
|
e.preventDefault();
|
|
4931
5180
|
addItem({
|
|
4932
5181
|
id: generateId(),
|
|
@@ -4935,7 +5184,7 @@
|
|
|
4935
5184
|
text: 'Group',
|
|
4936
5185
|
});
|
|
4937
5186
|
} }, "Add group"))),
|
|
4938
|
-
editing && !isResource && (React.createElement(
|
|
5187
|
+
editing && !isResource && (React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
4939
5188
|
e.preventDefault();
|
|
4940
5189
|
if (props.onRemove) {
|
|
4941
5190
|
props.onRemove();
|
|
@@ -4964,12 +5213,12 @@
|
|
|
4964
5213
|
props.onChange(newOptions);
|
|
4965
5214
|
} })),
|
|
4966
5215
|
React.createElement("div", null,
|
|
4967
|
-
React.createElement(
|
|
5216
|
+
React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
4968
5217
|
killEvent(e);
|
|
4969
5218
|
props.onChange(options.filter((o) => o.id !== option.id));
|
|
4970
5219
|
} }, "Remove"))));
|
|
4971
5220
|
}),
|
|
4972
|
-
React.createElement(
|
|
5221
|
+
React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
|
|
4973
5222
|
killEvent(e);
|
|
4974
5223
|
props.onChange([
|
|
4975
5224
|
...options,
|
|
@@ -5129,7 +5378,7 @@
|
|
|
5129
5378
|
function ReferenceRangeGroupEditor(props) {
|
|
5130
5379
|
const { intervalGroup, unit } = props;
|
|
5131
5380
|
const { classes } = useStyles$3();
|
|
5132
|
-
return (React.createElement(
|
|
5381
|
+
return (React.createElement(Container, { "data-testid": intervalGroup.id, className: classes.section },
|
|
5133
5382
|
React.createElement(core$1.Stack, { spacing: 'lg' },
|
|
5134
5383
|
React.createElement(core$1.Group, { position: "right" },
|
|
5135
5384
|
React.createElement(core$1.ActionIcon, { title: "Remove Group", "data-testid": `remove-group-button-${intervalGroup.id}`, key: `remove-group-button-${intervalGroup.id}`, size: "sm", onClick: (e) => {
|
|
@@ -5284,63 +5533,6 @@
|
|
|
5284
5533
|
return ((_b = (_a = interval.range) === null || _a === void 0 ? void 0 : _a.low) === null || _b === void 0 ? void 0 : _b.value) === undefined && ((_d = (_c = interval.range) === null || _c === void 0 ? void 0 : _c.high) === null || _d === void 0 ? void 0 : _d.value) === undefined;
|
|
5285
5534
|
}
|
|
5286
5535
|
|
|
5287
|
-
/*
|
|
5288
|
-
* Request status: https://hl7.org/fhir/valueset-request-status.html
|
|
5289
|
-
* draft, active, on-hold, revoked, completed, entered-in-error, unknown
|
|
5290
|
-
*
|
|
5291
|
-
* Publication status: https://hl7.org/fhir/valueset-publication-status.html
|
|
5292
|
-
* draft, active, retired, unknown
|
|
5293
|
-
*
|
|
5294
|
-
* Observation status: https://www.hl7.org/fhir/valueset-observation-status.html
|
|
5295
|
-
* registered, preliminary, final, amended, cancelled, entered-in-error, unknown
|
|
5296
|
-
*
|
|
5297
|
-
* DiagnosticReport status: https://hl7.org/fhir/valueset-diagnostic-report-status.html
|
|
5298
|
-
* registered, preliminary, final, amended, corrected, appended, cancelled, entered-in-error, unknown
|
|
5299
|
-
*
|
|
5300
|
-
* Task status: https://hl7.org/fhir/valueset-task-status.html
|
|
5301
|
-
* draft, requested, received, accepted, rejected, ready, cancelled, in-progress, on-hold, failed, completed, entered-in-error
|
|
5302
|
-
*
|
|
5303
|
-
* Appointment status: https://www.hl7.org/fhir/valueset-appointmentstatus.html
|
|
5304
|
-
* proposed, pending, booked, arrived, fulfilled, cancelled, noshow, entered-in-error, chcked-in, waitlist
|
|
5305
|
-
*/
|
|
5306
|
-
const statusToColor = {
|
|
5307
|
-
draft: 'blue',
|
|
5308
|
-
active: 'blue',
|
|
5309
|
-
'on-hold': 'yellow',
|
|
5310
|
-
revoked: 'red',
|
|
5311
|
-
completed: 'green',
|
|
5312
|
-
'entered-in-error': 'red',
|
|
5313
|
-
unknown: 'gray',
|
|
5314
|
-
retired: 'gray',
|
|
5315
|
-
registered: 'blue',
|
|
5316
|
-
preliminary: 'blue',
|
|
5317
|
-
final: 'green',
|
|
5318
|
-
amended: 'yellow',
|
|
5319
|
-
cancelled: 'red',
|
|
5320
|
-
requested: 'blue',
|
|
5321
|
-
received: 'blue',
|
|
5322
|
-
accepted: 'blue',
|
|
5323
|
-
rejected: 'red',
|
|
5324
|
-
ready: 'blue',
|
|
5325
|
-
'in-progress': 'blue',
|
|
5326
|
-
failed: 'red',
|
|
5327
|
-
proposed: 'blue',
|
|
5328
|
-
pending: 'blue',
|
|
5329
|
-
booked: 'blue',
|
|
5330
|
-
arrived: 'blue',
|
|
5331
|
-
fulfilled: 'green',
|
|
5332
|
-
noshow: 'red',
|
|
5333
|
-
'checked-in': 'blue',
|
|
5334
|
-
waitlist: 'gray',
|
|
5335
|
-
routine: 'gray',
|
|
5336
|
-
urgent: 'red',
|
|
5337
|
-
asap: 'red',
|
|
5338
|
-
stat: 'red',
|
|
5339
|
-
};
|
|
5340
|
-
function StatusBadge(props) {
|
|
5341
|
-
return React.createElement(core$1.Badge, { color: statusToColor[props.status] }, props.status);
|
|
5342
|
-
}
|
|
5343
|
-
|
|
5344
5536
|
function RequestGroupDisplay(props) {
|
|
5345
5537
|
var _a;
|
|
5346
5538
|
const medplum = useMedplum();
|
|
@@ -5910,6 +6102,7 @@
|
|
|
5910
6102
|
exports.AddressDisplay = AddressDisplay;
|
|
5911
6103
|
exports.AddressInput = AddressInput;
|
|
5912
6104
|
exports.AnnotationInput = AnnotationInput;
|
|
6105
|
+
exports.AsyncAutocomplete = AsyncAutocomplete;
|
|
5913
6106
|
exports.AttachmentArrayDisplay = AttachmentArrayDisplay;
|
|
5914
6107
|
exports.AttachmentArrayInput = AttachmentArrayInput;
|
|
5915
6108
|
exports.AttachmentButton = AttachmentButton;
|
|
@@ -5928,6 +6121,7 @@
|
|
|
5928
6121
|
exports.ContactDetailInput = ContactDetailInput;
|
|
5929
6122
|
exports.ContactPointDisplay = ContactPointDisplay;
|
|
5930
6123
|
exports.ContactPointInput = ContactPointInput;
|
|
6124
|
+
exports.Container = Container;
|
|
5931
6125
|
exports.DateTimeInput = DateTimeInput;
|
|
5932
6126
|
exports.DefaultResourceTimeline = DefaultResourceTimeline;
|
|
5933
6127
|
exports.DescriptionList = DescriptionList;
|
|
@@ -5951,6 +6145,7 @@
|
|
|
5951
6145
|
exports.MemoizedFhirPathTable = MemoizedFhirPathTable;
|
|
5952
6146
|
exports.MemoizedSearchControl = MemoizedSearchControl;
|
|
5953
6147
|
exports.ObservationTable = ObservationTable;
|
|
6148
|
+
exports.Panel = Panel;
|
|
5954
6149
|
exports.PatientTimeline = PatientTimeline;
|
|
5955
6150
|
exports.PlanDefinitionBuilder = PlanDefinitionBuilder;
|
|
5956
6151
|
exports.QuantityDisplay = QuantityDisplay;
|