@medplum/react 0.9.29 → 0.9.32
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/auth/AuthenticationForm.d.ts +14 -0
- package/dist/cjs/auth/ChooseProfileForm.d.ts +8 -0
- package/dist/cjs/auth/NewProjectForm.d.ts +7 -0
- package/dist/cjs/auth/NewUserForm.d.ts +10 -0
- package/dist/cjs/auth/RegisterForm.d.ts +12 -0
- package/dist/cjs/{SignInForm.d.ts → auth/SignInForm.d.ts} +1 -1
- package/dist/cjs/index.d.ts +3 -2
- package/dist/cjs/index.js +609 -548
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +1 -1
- package/dist/cjs/index.min.js.map +1 -1
- package/dist/cjs/styles.css +197 -197
- package/dist/esm/Autocomplete.js +1 -0
- package/dist/esm/Autocomplete.js.map +1 -1
- package/dist/esm/CodeInput.js +1 -1
- package/dist/esm/CodeInput.js.map +1 -1
- package/dist/esm/CodeableConceptInput.js +1 -1
- package/dist/esm/CodeableConceptInput.js.map +1 -1
- package/dist/esm/CodingInput.js +1 -1
- package/dist/esm/CodingInput.js.map +1 -1
- package/dist/esm/GoogleButton.js +2 -2
- package/dist/esm/GoogleButton.js.map +1 -1
- package/dist/esm/MedplumLink.js +29 -14
- package/dist/esm/MedplumLink.js.map +1 -1
- package/dist/esm/ResourceHistoryTable.js +15 -11
- package/dist/esm/ResourceHistoryTable.js.map +1 -1
- package/dist/esm/ResourceTimeline.js +3 -1
- package/dist/esm/ResourceTimeline.js.map +1 -1
- package/dist/esm/auth/AuthenticationForm.d.ts +14 -0
- package/dist/esm/{SignInForm.js → auth/AuthenticationForm.js} +12 -76
- package/dist/esm/auth/AuthenticationForm.js.map +1 -0
- package/dist/esm/auth/ChooseProfileForm.d.ts +8 -0
- package/dist/esm/auth/ChooseProfileForm.js +32 -0
- package/dist/esm/auth/ChooseProfileForm.js.map +1 -0
- package/dist/esm/auth/NewProjectForm.d.ts +7 -0
- package/dist/esm/auth/NewProjectForm.js +42 -0
- package/dist/esm/auth/NewProjectForm.js.map +1 -0
- package/dist/esm/auth/NewUserForm.d.ts +10 -0
- package/dist/esm/auth/NewUserForm.js +87 -0
- package/dist/esm/auth/NewUserForm.js.map +1 -0
- package/dist/esm/auth/RegisterForm.d.ts +12 -0
- package/dist/esm/auth/RegisterForm.js +39 -0
- package/dist/esm/auth/RegisterForm.js.map +1 -0
- package/dist/esm/{SignInForm.d.ts → auth/SignInForm.d.ts} +1 -1
- package/dist/esm/auth/SignInForm.js +52 -0
- package/dist/esm/auth/SignInForm.js.map +1 -0
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.js +3 -2
- 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/styles.css +197 -197
- package/package.json +16 -18
- package/dist/cjs/RegisterForm.d.ts +0 -18
- package/dist/esm/RegisterForm.d.ts +0 -18
- package/dist/esm/RegisterForm.js +0 -121
- package/dist/esm/RegisterForm.js.map +0 -1
- package/dist/esm/SignInForm.js.map +0 -1
- package/stats.html +0 -4034
package/dist/cjs/index.js
CHANGED
|
@@ -329,6 +329,578 @@
|
|
|
329
329
|
return React__default["default"].createElement(UploadButton, { onUpload: setValueWrapper });
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
+
function Document(props) {
|
|
333
|
+
return (React__default["default"].createElement("main", { className: "medplum-document" },
|
|
334
|
+
React__default["default"].createElement("article", { style: { maxWidth: props.width } }, props.children)));
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/******************************************************************************
|
|
338
|
+
Copyright (c) Microsoft Corporation.
|
|
339
|
+
|
|
340
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
341
|
+
purpose with or without fee is hereby granted.
|
|
342
|
+
|
|
343
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
344
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
345
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
346
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
347
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
348
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
349
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
350
|
+
***************************************************************************** */
|
|
351
|
+
|
|
352
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
353
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
354
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
355
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
356
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
357
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
358
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Parses an HTML form and returns the result as a JavaScript object.
|
|
364
|
+
* @param form The HTML form element.
|
|
365
|
+
*/
|
|
366
|
+
function parseForm(form) {
|
|
367
|
+
const result = {};
|
|
368
|
+
for (const element of Array.from(form.elements)) {
|
|
369
|
+
if (element instanceof HTMLInputElement) {
|
|
370
|
+
parseInputElement(result, element);
|
|
371
|
+
}
|
|
372
|
+
else if (element instanceof HTMLTextAreaElement) {
|
|
373
|
+
result[element.name] = element.value;
|
|
374
|
+
}
|
|
375
|
+
else if (element instanceof HTMLSelectElement) {
|
|
376
|
+
parseSelectElement(result, element);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return result;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Parses an HTML input element.
|
|
383
|
+
* Sets the name/value pair in the result,
|
|
384
|
+
* but only if the element is enabled and checked.
|
|
385
|
+
* @param el The input element.
|
|
386
|
+
* @param result The result builder.
|
|
387
|
+
*/
|
|
388
|
+
function parseInputElement(result, el) {
|
|
389
|
+
if (el.disabled) {
|
|
390
|
+
// Ignore disabled elements
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
if ((el.type === 'checkbox' || el.type === 'radio') && !el.checked) {
|
|
394
|
+
// Ignore unchecked radio or checkbox elements
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
result[el.name] = el.value;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Parses an HTML select element.
|
|
401
|
+
* Sets the name/value pair if one is selected.
|
|
402
|
+
* @param result The result builder.
|
|
403
|
+
* @param el The select element.
|
|
404
|
+
*/
|
|
405
|
+
function parseSelectElement(result, el) {
|
|
406
|
+
result[el.name] = el.value;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function Form(props) {
|
|
410
|
+
return (React__default["default"].createElement("form", { style: props.style, "data-testid": props.testid, onSubmit: (e) => {
|
|
411
|
+
e.preventDefault();
|
|
412
|
+
const formData = parseForm(e.target);
|
|
413
|
+
if (props.onSubmit) {
|
|
414
|
+
props.onSubmit(formData);
|
|
415
|
+
}
|
|
416
|
+
} }, props.children));
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function FormSection(props) {
|
|
420
|
+
const issues = getIssuesForExpression(props.outcome, props.htmlFor);
|
|
421
|
+
const invalid = issues && issues.length > 0;
|
|
422
|
+
return (React__default["default"].createElement("fieldset", { className: "medplum-form-section" },
|
|
423
|
+
props.title && React__default["default"].createElement("label", { htmlFor: props.htmlFor }, props.title),
|
|
424
|
+
props.description && React__default["default"].createElement("p", null, props.description),
|
|
425
|
+
props.children,
|
|
426
|
+
invalid && (React__default["default"].createElement("div", { id: props.htmlFor + '-errors', className: "medplum-input-error" }, issues === null || issues === void 0 ? void 0 : issues.map((issue) => {
|
|
427
|
+
var _a, _b;
|
|
428
|
+
return (React__default["default"].createElement("div", { "data-testid": "text-field-error", key: (_a = issue.details) === null || _a === void 0 ? void 0 : _a.text }, (_b = issue.details) === null || _b === void 0 ? void 0 : _b.text));
|
|
429
|
+
})))));
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
function Logo(props) {
|
|
433
|
+
return (React__default["default"].createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 491 491", style: { width: props.size, height: props.size } },
|
|
434
|
+
React__default["default"].createElement("title", null, "Medplum Logo"),
|
|
435
|
+
React__default["default"].createElement("path", { fill: props.fill || '#ad7136', d: "M282 67c6-16 16-29 29-40L289 0c-22 17-37 41-43 68l17 23 19-24z" }),
|
|
436
|
+
React__default["default"].createElement("path", { fill: props.fill || '#654b87', d: "M311 63c-17 0-33 4-48 11-16-7-32-11-49-11-87 0-158 96-158 214s71 214 158 214c17 0 33-4 49-11 15 7 31 11 48 11 87 0 158-96 158-214S398 63 311 63z" }),
|
|
437
|
+
React__default["default"].createElement("path", { fill: props.fill || '#463068', d: "M231 489l-17 2c-87 0-158-96-158-214S127 63 214 63l17 1c-39 12-70 102-70 213s31 201 70 212z" }),
|
|
438
|
+
React__default["default"].createElement("path", { fill: props.fill || '#70d65b', d: "M207 220a176 176 0 01-177 43A176 176 0 01251 43l1 5c17 59 2 125-45 172z" }),
|
|
439
|
+
React__default["default"].createElement("path", { fill: props.fill || '#58b741', d: "M252 48A421 421 0 0057 270l-27-7A176 176 0 01251 43l1 5z" })));
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function NewProjectForm(props) {
|
|
443
|
+
const medplum = useMedplum();
|
|
444
|
+
const [outcome, setOutcome] = React.useState();
|
|
445
|
+
return (React__default["default"].createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => __awaiter(this, void 0, void 0, function* () {
|
|
446
|
+
try {
|
|
447
|
+
props.handleAuthResponse(yield medplum.startNewProject({
|
|
448
|
+
login: props.login,
|
|
449
|
+
projectName: formData.projectName,
|
|
450
|
+
}));
|
|
451
|
+
}
|
|
452
|
+
catch (err) {
|
|
453
|
+
setOutcome(err);
|
|
454
|
+
}
|
|
455
|
+
}) },
|
|
456
|
+
React__default["default"].createElement("div", { className: "medplum-center" },
|
|
457
|
+
React__default["default"].createElement(Logo, { size: 32 }),
|
|
458
|
+
React__default["default"].createElement("h1", null, "Create project")),
|
|
459
|
+
React__default["default"].createElement(FormSection, { title: "Project Name", htmlFor: "projectName", outcome: outcome },
|
|
460
|
+
React__default["default"].createElement(Input, { name: "projectName", type: "text", testid: "projectName", placeholder: "My Project", required: true, outcome: outcome })),
|
|
461
|
+
React__default["default"].createElement("p", { style: { fontSize: '12px', color: '#888' } },
|
|
462
|
+
"By clicking submit you agree to the Medplum ",
|
|
463
|
+
React__default["default"].createElement("a", { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
|
|
464
|
+
' and ',
|
|
465
|
+
React__default["default"].createElement("a", { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
466
|
+
"."),
|
|
467
|
+
React__default["default"].createElement("div", { className: "medplum-signin-buttons" },
|
|
468
|
+
React__default["default"].createElement("div", null),
|
|
469
|
+
React__default["default"].createElement("div", null,
|
|
470
|
+
React__default["default"].createElement(Button, { type: "submit", testid: "submit" }, "Create project")))));
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Dynamically creates a script tag for the specified JavaScript file.
|
|
475
|
+
* @param src The JavaScript file URL.
|
|
476
|
+
*/
|
|
477
|
+
function createScriptTag(src, onload) {
|
|
478
|
+
const head = document.getElementsByTagName('head')[0];
|
|
479
|
+
const script = document.createElement('script');
|
|
480
|
+
script.async = true;
|
|
481
|
+
script.src = src;
|
|
482
|
+
script.onload = onload || null;
|
|
483
|
+
head.appendChild(script);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function GoogleButton(props) {
|
|
487
|
+
const medplum = useMedplum();
|
|
488
|
+
const { googleClientId, handleGoogleCredential } = props;
|
|
489
|
+
const parentRef = React.useRef(null);
|
|
490
|
+
const [scriptLoaded, setScriptLoaded] = React.useState(typeof google !== 'undefined');
|
|
491
|
+
const [initialized, setInitialized] = React.useState(false);
|
|
492
|
+
const [buttonRendered, setButtonRendered] = React.useState(false);
|
|
493
|
+
React.useEffect(() => {
|
|
494
|
+
if (typeof google === 'undefined') {
|
|
495
|
+
createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
if (!initialized) {
|
|
499
|
+
google.accounts.id.initialize({
|
|
500
|
+
client_id: googleClientId,
|
|
501
|
+
callback: handleGoogleCredential,
|
|
502
|
+
});
|
|
503
|
+
setInitialized(true);
|
|
504
|
+
}
|
|
505
|
+
if (parentRef.current && !buttonRendered) {
|
|
506
|
+
google.accounts.id.renderButton(parentRef.current, {});
|
|
507
|
+
setButtonRendered(true);
|
|
508
|
+
}
|
|
509
|
+
}, [medplum, googleClientId, initialized, scriptLoaded, parentRef, buttonRendered, handleGoogleCredential]);
|
|
510
|
+
if (!googleClientId) {
|
|
511
|
+
return null;
|
|
512
|
+
}
|
|
513
|
+
return React__default["default"].createElement("div", { ref: parentRef });
|
|
514
|
+
}
|
|
515
|
+
function getGoogleClientId(clientId) {
|
|
516
|
+
var _a, _b;
|
|
517
|
+
if (clientId) {
|
|
518
|
+
return clientId;
|
|
519
|
+
}
|
|
520
|
+
const origin = window.location.protocol + '//' + window.location.host;
|
|
521
|
+
const authorizedOrigins = (_b = (_a = "undefined") === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
|
|
522
|
+
if (authorizedOrigins.includes(origin)) {
|
|
523
|
+
return "undefined";
|
|
524
|
+
}
|
|
525
|
+
return undefined;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Dynamically loads the recaptcha script.
|
|
530
|
+
* We do not want to load the script on page load unless the user needs it.
|
|
531
|
+
* @param siteKey The reCAPTCHA site key, available from the reCAPTCHA admin page.
|
|
532
|
+
*/
|
|
533
|
+
function initRecaptcha(siteKey) {
|
|
534
|
+
if (typeof grecaptcha === 'undefined') {
|
|
535
|
+
createScriptTag('https://www.google.com/recaptcha/api.js?render=' + siteKey);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Starts a request to generate a recapcha token.
|
|
540
|
+
* @param siteKey The reCAPTCHA site key, available from the reCAPTCHA admin page.
|
|
541
|
+
* @returns Promise to a recaptcha token for the current user.
|
|
542
|
+
*/
|
|
543
|
+
function getRecaptcha(siteKey) {
|
|
544
|
+
return new Promise((resolve, reject) => {
|
|
545
|
+
grecaptcha.ready(() => __awaiter(this, void 0, void 0, function* () {
|
|
546
|
+
try {
|
|
547
|
+
resolve(yield grecaptcha.execute(siteKey, { action: 'submit' }));
|
|
548
|
+
}
|
|
549
|
+
catch (err) {
|
|
550
|
+
reject(err);
|
|
551
|
+
}
|
|
552
|
+
}));
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
function NewUserForm(props) {
|
|
557
|
+
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
558
|
+
const recaptchaSiteKey = props.recaptchaSiteKey;
|
|
559
|
+
const medplum = useMedplum();
|
|
560
|
+
const [outcome, setOutcome] = React.useState();
|
|
561
|
+
const issues = getIssuesForExpression(outcome, undefined);
|
|
562
|
+
React.useEffect(() => initRecaptcha(recaptchaSiteKey), [recaptchaSiteKey]);
|
|
563
|
+
return (React__default["default"].createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => __awaiter(this, void 0, void 0, function* () {
|
|
564
|
+
try {
|
|
565
|
+
const recaptchaToken = yield getRecaptcha(recaptchaSiteKey);
|
|
566
|
+
props.handleAuthResponse(yield medplum.startNewUser({
|
|
567
|
+
projectId: props.projectId,
|
|
568
|
+
firstName: formData.firstName,
|
|
569
|
+
lastName: formData.lastName,
|
|
570
|
+
email: formData.email,
|
|
571
|
+
password: formData.password,
|
|
572
|
+
remember: formData.remember === 'true',
|
|
573
|
+
recaptchaSiteKey,
|
|
574
|
+
recaptchaToken,
|
|
575
|
+
}));
|
|
576
|
+
}
|
|
577
|
+
catch (err) {
|
|
578
|
+
setOutcome(err);
|
|
579
|
+
}
|
|
580
|
+
}) },
|
|
581
|
+
React__default["default"].createElement("div", { className: "medplum-center" }, props.children),
|
|
582
|
+
issues && (React__default["default"].createElement("div", { className: "medplum-input-error" }, issues.map((issue) => {
|
|
583
|
+
var _a, _b;
|
|
584
|
+
return (React__default["default"].createElement("div", { "data-testid": "text-field-error", key: (_a = issue.details) === null || _a === void 0 ? void 0 : _a.text }, (_b = issue.details) === null || _b === void 0 ? void 0 : _b.text));
|
|
585
|
+
}))),
|
|
586
|
+
googleClientId && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
587
|
+
React__default["default"].createElement("div", { className: "medplum-signin-google-container" },
|
|
588
|
+
React__default["default"].createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) => __awaiter(this, void 0, void 0, function* () {
|
|
589
|
+
try {
|
|
590
|
+
props.handleAuthResponse(yield medplum.startGoogleLogin({
|
|
591
|
+
googleClientId: response.clientId,
|
|
592
|
+
googleCredential: response.credential,
|
|
593
|
+
createUser: true,
|
|
594
|
+
}));
|
|
595
|
+
}
|
|
596
|
+
catch (err) {
|
|
597
|
+
setOutcome(err);
|
|
598
|
+
}
|
|
599
|
+
}) })),
|
|
600
|
+
React__default["default"].createElement("div", { className: "medplum-signin-separator" }, "or"))),
|
|
601
|
+
React__default["default"].createElement(FormSection, { title: "First Name", htmlFor: "firstName", outcome: outcome },
|
|
602
|
+
React__default["default"].createElement(Input, { name: "firstName", type: "text", testid: "firstName", placeholder: "First name", required: true, autoFocus: true, outcome: outcome })),
|
|
603
|
+
React__default["default"].createElement(FormSection, { title: "Last Name", htmlFor: "lastName", outcome: outcome },
|
|
604
|
+
React__default["default"].createElement(Input, { name: "lastName", type: "text", testid: "lastName", placeholder: "Last name", required: true, outcome: outcome })),
|
|
605
|
+
React__default["default"].createElement(FormSection, { title: "Email", htmlFor: "email", outcome: outcome },
|
|
606
|
+
React__default["default"].createElement(Input, { name: "email", type: "email", testid: "email", placeholder: "name@domain.com", required: true, outcome: outcome })),
|
|
607
|
+
React__default["default"].createElement(FormSection, { title: "Password", htmlFor: "password", outcome: outcome },
|
|
608
|
+
React__default["default"].createElement(Input, { name: "password", type: "password", testid: "password", autoComplete: "off", required: true, outcome: outcome })),
|
|
609
|
+
React__default["default"].createElement("p", { style: { fontSize: '12px', color: '#888' } },
|
|
610
|
+
"By clicking submit you agree to the Medplum ",
|
|
611
|
+
React__default["default"].createElement("a", { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
|
|
612
|
+
' and ',
|
|
613
|
+
React__default["default"].createElement("a", { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
614
|
+
"."),
|
|
615
|
+
React__default["default"].createElement("p", { style: { fontSize: '12px', color: '#888' } },
|
|
616
|
+
"This site is protected by reCAPTCHA and the Google",
|
|
617
|
+
' ',
|
|
618
|
+
React__default["default"].createElement("a", { href: "https://policies.google.com/privacy" }, "Privacy\u00A0Policy"),
|
|
619
|
+
' and ',
|
|
620
|
+
React__default["default"].createElement("a", { href: "https://policies.google.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
621
|
+
" apply."),
|
|
622
|
+
React__default["default"].createElement("div", { className: "medplum-signin-buttons" },
|
|
623
|
+
React__default["default"].createElement("div", null,
|
|
624
|
+
React__default["default"].createElement("input", { type: "checkbox", id: "remember", name: "remember", value: "true" }),
|
|
625
|
+
React__default["default"].createElement("label", { htmlFor: "remember" }, "Remember me")),
|
|
626
|
+
React__default["default"].createElement("div", null,
|
|
627
|
+
React__default["default"].createElement(Button, { type: "submit", testid: "submit" }, "Create account")))));
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
function RegisterForm(props) {
|
|
631
|
+
const { type, projectId, googleClientId, recaptchaSiteKey, onSuccess } = props;
|
|
632
|
+
const medplum = useMedplum();
|
|
633
|
+
const [login, setLogin] = React.useState(undefined);
|
|
634
|
+
const [outcome, setOutcome] = React.useState();
|
|
635
|
+
React.useEffect(() => {
|
|
636
|
+
if (type === 'patient' && login) {
|
|
637
|
+
medplum
|
|
638
|
+
.startNewPatient({ login, projectId: projectId })
|
|
639
|
+
.then((response) => medplum.processCode(response.code))
|
|
640
|
+
.then(() => onSuccess())
|
|
641
|
+
.catch((err) => setOutcome(err));
|
|
642
|
+
}
|
|
643
|
+
}, [medplum, type, projectId, login, onSuccess]);
|
|
644
|
+
function handleAuthResponse(response) {
|
|
645
|
+
if (response.code) {
|
|
646
|
+
medplum
|
|
647
|
+
.processCode(response.code)
|
|
648
|
+
.then(() => onSuccess())
|
|
649
|
+
.catch(console.log);
|
|
650
|
+
}
|
|
651
|
+
else if (response.login) {
|
|
652
|
+
setLogin(response.login);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return (React__default["default"].createElement(Document, { width: 450 },
|
|
656
|
+
outcome && React__default["default"].createElement("pre", null, JSON.stringify(outcome, null, 2)),
|
|
657
|
+
!login && (React__default["default"].createElement(NewUserForm, { projectId: projectId, googleClientId: googleClientId, recaptchaSiteKey: recaptchaSiteKey, handleAuthResponse: handleAuthResponse }, props.children)),
|
|
658
|
+
login && type === 'project' && React__default["default"].createElement(NewProjectForm, { login: login, handleAuthResponse: handleAuthResponse })));
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function MedplumLink(props) {
|
|
662
|
+
const navigate = reactRouterDom.useNavigate();
|
|
663
|
+
let href = getHref(props.to);
|
|
664
|
+
if (props.suffix) {
|
|
665
|
+
href += '/' + props.suffix;
|
|
666
|
+
}
|
|
667
|
+
return (React__default["default"].createElement("a", { href: href, id: props.id, "aria-label": props.label, "data-testid": props.testid || 'link', className: props.className, onClick: (e) => {
|
|
668
|
+
killEvent(e);
|
|
669
|
+
if (props.onClick) {
|
|
670
|
+
props.onClick();
|
|
671
|
+
}
|
|
672
|
+
else if (props.to) {
|
|
673
|
+
navigate(href);
|
|
674
|
+
}
|
|
675
|
+
} }, props.children));
|
|
676
|
+
}
|
|
677
|
+
function getHref(to) {
|
|
678
|
+
if (to) {
|
|
679
|
+
if (typeof to === 'string') {
|
|
680
|
+
return getStringHref(to);
|
|
681
|
+
}
|
|
682
|
+
else if ('resourceType' in to) {
|
|
683
|
+
return getResourceHref(to);
|
|
684
|
+
}
|
|
685
|
+
else if ('reference' in to) {
|
|
686
|
+
return getReferenceHref(to);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return '#';
|
|
690
|
+
}
|
|
691
|
+
function getStringHref(to) {
|
|
692
|
+
if (to.startsWith('http://') || to.startsWith('https://') || to.startsWith('/')) {
|
|
693
|
+
return to;
|
|
694
|
+
}
|
|
695
|
+
return '/' + to;
|
|
696
|
+
}
|
|
697
|
+
function getResourceHref(to) {
|
|
698
|
+
return `/${to.resourceType}/${to.id}`;
|
|
699
|
+
}
|
|
700
|
+
function getReferenceHref(to) {
|
|
701
|
+
return `/${to.reference}`;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
function AuthenticationForm(props) {
|
|
705
|
+
const medplum = useMedplum();
|
|
706
|
+
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
707
|
+
const [outcome, setOutcome] = React.useState();
|
|
708
|
+
const issues = getIssuesForExpression(outcome, undefined);
|
|
709
|
+
return (React__default["default"].createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => {
|
|
710
|
+
medplum
|
|
711
|
+
.startLogin({
|
|
712
|
+
projectId: props.projectId,
|
|
713
|
+
clientId: props.clientId,
|
|
714
|
+
scope: props.scope,
|
|
715
|
+
nonce: props.nonce,
|
|
716
|
+
email: formData.email,
|
|
717
|
+
password: formData.password,
|
|
718
|
+
remember: formData.remember === 'true',
|
|
719
|
+
})
|
|
720
|
+
.then(props.handleAuthResponse)
|
|
721
|
+
.catch(setOutcome);
|
|
722
|
+
} },
|
|
723
|
+
React__default["default"].createElement("div", { className: "medplum-center" }, props.children),
|
|
724
|
+
issues && (React__default["default"].createElement("div", { className: "medplum-input-error" }, issues.map((issue) => {
|
|
725
|
+
var _a, _b;
|
|
726
|
+
return (React__default["default"].createElement("div", { "data-testid": "text-field-error", key: (_a = issue.details) === null || _a === void 0 ? void 0 : _a.text }, (_b = issue.details) === null || _b === void 0 ? void 0 : _b.text));
|
|
727
|
+
}))),
|
|
728
|
+
googleClientId && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
729
|
+
React__default["default"].createElement("div", { className: "medplum-signin-google-container" },
|
|
730
|
+
React__default["default"].createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) => {
|
|
731
|
+
medplum
|
|
732
|
+
.startGoogleLogin({
|
|
733
|
+
projectId: props.projectId,
|
|
734
|
+
clientId: props.clientId,
|
|
735
|
+
scope: props.scope,
|
|
736
|
+
nonce: props.nonce,
|
|
737
|
+
googleClientId: response.clientId,
|
|
738
|
+
googleCredential: response.credential,
|
|
739
|
+
})
|
|
740
|
+
.then(props.handleAuthResponse)
|
|
741
|
+
.catch(setOutcome);
|
|
742
|
+
} })),
|
|
743
|
+
React__default["default"].createElement("div", { className: "medplum-signin-separator" }, "or"))),
|
|
744
|
+
React__default["default"].createElement(FormSection, { title: "Email", htmlFor: "email", outcome: outcome },
|
|
745
|
+
React__default["default"].createElement(Input, { name: "email", type: "email", testid: "email", required: true, autoFocus: true, outcome: outcome })),
|
|
746
|
+
React__default["default"].createElement(FormSection, { title: "Password", htmlFor: "password", outcome: outcome },
|
|
747
|
+
React__default["default"].createElement(Input, { name: "password", type: "password", testid: "password", autoComplete: "off", required: true, outcome: outcome })),
|
|
748
|
+
React__default["default"].createElement("div", { className: "medplum-signin-buttons" },
|
|
749
|
+
(props.onForgotPassword || props.onRegister) && (React__default["default"].createElement("div", null,
|
|
750
|
+
props.onForgotPassword && (React__default["default"].createElement(MedplumLink, { testid: "forgotpassword", onClick: props.onForgotPassword }, "Forgot password")),
|
|
751
|
+
props.onRegister && (React__default["default"].createElement(MedplumLink, { testid: "register", onClick: props.onRegister }, "Register")))),
|
|
752
|
+
React__default["default"].createElement("div", null,
|
|
753
|
+
React__default["default"].createElement("input", { type: "checkbox", id: "remember", name: "remember", value: "true" }),
|
|
754
|
+
React__default["default"].createElement("label", { htmlFor: "remember" }, "Remember me")),
|
|
755
|
+
React__default["default"].createElement("div", null,
|
|
756
|
+
React__default["default"].createElement(Button, { type: "submit", testid: "submit" }, "Sign in")))));
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
const system = {
|
|
760
|
+
resourceType: 'Device',
|
|
761
|
+
id: 'system',
|
|
762
|
+
deviceName: [
|
|
763
|
+
{
|
|
764
|
+
name: 'System',
|
|
765
|
+
},
|
|
766
|
+
],
|
|
767
|
+
};
|
|
768
|
+
/**
|
|
769
|
+
* React Hook to use a FHIR reference.
|
|
770
|
+
* Handles the complexity of resolving references and caching resources.
|
|
771
|
+
* @param value The resource or reference to resource.
|
|
772
|
+
* @returns The resolved resource.
|
|
773
|
+
*/
|
|
774
|
+
function useResource(value) {
|
|
775
|
+
const medplum = useMedplum();
|
|
776
|
+
const [resource, setResource] = React.useState(getInitialResource(medplum, value));
|
|
777
|
+
React.useEffect(() => {
|
|
778
|
+
let subscribed = true;
|
|
779
|
+
if (!resource && value && 'reference' in value && value.reference) {
|
|
780
|
+
medplum
|
|
781
|
+
.readReference(value)
|
|
782
|
+
.then((r) => {
|
|
783
|
+
if (subscribed) {
|
|
784
|
+
setResource(r);
|
|
785
|
+
}
|
|
786
|
+
})
|
|
787
|
+
.catch(() => setResource(undefined));
|
|
788
|
+
}
|
|
789
|
+
return (() => (subscribed = false));
|
|
790
|
+
}, [medplum, resource, value]);
|
|
791
|
+
return resource;
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Returns the initial resource value based on the input value.
|
|
795
|
+
* If the input value is a resource, returns the resource.
|
|
796
|
+
* If the input value is a reference to system, returns the system resource.
|
|
797
|
+
* If the input value is a reference to a resource available in the cache, returns the resource.
|
|
798
|
+
* Otherwise, returns undefined.
|
|
799
|
+
* @param medplum The medplum client.
|
|
800
|
+
* @param value The resource or reference to resource.
|
|
801
|
+
* @returns An initial resource if available; undefined otherwise.
|
|
802
|
+
*/
|
|
803
|
+
function getInitialResource(medplum, value) {
|
|
804
|
+
if (!value) {
|
|
805
|
+
return undefined;
|
|
806
|
+
}
|
|
807
|
+
if ('resourceType' in value) {
|
|
808
|
+
return value;
|
|
809
|
+
}
|
|
810
|
+
if ('reference' in value) {
|
|
811
|
+
if (value.reference === 'system') {
|
|
812
|
+
return system;
|
|
813
|
+
}
|
|
814
|
+
return medplum.getCachedReference(value);
|
|
815
|
+
}
|
|
816
|
+
return undefined;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
function Avatar(props) {
|
|
820
|
+
var _a, _b;
|
|
821
|
+
const resource = useResource(props.value);
|
|
822
|
+
const className = props.size ? 'medplum-avatar ' + props.size : 'medplum-avatar';
|
|
823
|
+
const text = resource ? core.getDisplayString(resource) : (_a = props.alt) !== null && _a !== void 0 ? _a : '';
|
|
824
|
+
const initials = text && getInitials(text);
|
|
825
|
+
const imageUrl = (_b = (resource && core.getImageSrc(resource))) !== null && _b !== void 0 ? _b : props.src;
|
|
826
|
+
const innerContent = imageUrl ? React__default["default"].createElement("img", { src: imageUrl, alt: text }) : initials;
|
|
827
|
+
return (React__default["default"].createElement("div", { className: className, style: { backgroundColor: props.color }, "data-testid": "avatar" }, props.link && resource ? React__default["default"].createElement(MedplumLink, { to: resource }, innerContent) : innerContent));
|
|
828
|
+
}
|
|
829
|
+
function getInitials(text) {
|
|
830
|
+
return text
|
|
831
|
+
.split(' ')
|
|
832
|
+
.map((n) => n[0])
|
|
833
|
+
.join('');
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
function ChooseProfileForm(props) {
|
|
837
|
+
const medplum = useMedplum();
|
|
838
|
+
return (React__default["default"].createElement("div", null,
|
|
839
|
+
React__default["default"].createElement("div", { className: "medplum-center" },
|
|
840
|
+
React__default["default"].createElement(Logo, { size: 32 }),
|
|
841
|
+
React__default["default"].createElement("h1", null, "Choose profile")),
|
|
842
|
+
props.memberships.map((membership) => {
|
|
843
|
+
var _a, _b, _c;
|
|
844
|
+
return (React__default["default"].createElement("div", { className: "medplum-nav-menu-profile", key: membership.id, onClick: () => {
|
|
845
|
+
medplum
|
|
846
|
+
.post('auth/profile', {
|
|
847
|
+
login: props.login,
|
|
848
|
+
profile: membership.id,
|
|
849
|
+
})
|
|
850
|
+
.then(props.handleAuthResponse)
|
|
851
|
+
.catch(console.log);
|
|
852
|
+
} },
|
|
853
|
+
React__default["default"].createElement("div", { className: "medplum-nav-menu-profile-icon" },
|
|
854
|
+
React__default["default"].createElement(Avatar, { alt: (_a = membership.profile) === null || _a === void 0 ? void 0 : _a.display })),
|
|
855
|
+
React__default["default"].createElement("div", { className: "medplum-nav-menu-profile-label" }, (_b = membership.profile) === null || _b === void 0 ? void 0 :
|
|
856
|
+
_b.display,
|
|
857
|
+
React__default["default"].createElement("div", { className: "medplum-nav-menu-profile-help-text" }, (_c = membership.project) === null || _c === void 0 ? void 0 : _c.display))));
|
|
858
|
+
})));
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
function SignInForm(props) {
|
|
862
|
+
const medplum = useMedplum();
|
|
863
|
+
const [login, setLogin] = React.useState(undefined);
|
|
864
|
+
const [memberships, setMemberships] = React.useState(undefined);
|
|
865
|
+
function handleAuthResponse(response) {
|
|
866
|
+
if (response.login) {
|
|
867
|
+
setLogin(response.login);
|
|
868
|
+
}
|
|
869
|
+
if (response.memberships) {
|
|
870
|
+
setMemberships(response.memberships);
|
|
871
|
+
}
|
|
872
|
+
if (response.code) {
|
|
873
|
+
if (props.onCode) {
|
|
874
|
+
props.onCode(response.code);
|
|
875
|
+
}
|
|
876
|
+
else {
|
|
877
|
+
medplum
|
|
878
|
+
.processCode(response.code)
|
|
879
|
+
.then(() => {
|
|
880
|
+
if (props.onSuccess) {
|
|
881
|
+
props.onSuccess();
|
|
882
|
+
}
|
|
883
|
+
})
|
|
884
|
+
.catch(console.log);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
return (React__default["default"].createElement(Document, { width: 450 }, (() => {
|
|
889
|
+
if (!login) {
|
|
890
|
+
return (React__default["default"].createElement(AuthenticationForm, { projectId: props.projectId, clientId: props.clientId, scope: props.scope, nonce: props.nonce, googleClientId: props.googleClientId, onForgotPassword: props.onForgotPassword, onRegister: props.onRegister, handleAuthResponse: handleAuthResponse }, props.children));
|
|
891
|
+
}
|
|
892
|
+
else if (memberships) {
|
|
893
|
+
return React__default["default"].createElement(ChooseProfileForm, { login: login, memberships: memberships, handleAuthResponse: handleAuthResponse });
|
|
894
|
+
}
|
|
895
|
+
else if (props.projectId === 'new') {
|
|
896
|
+
return React__default["default"].createElement(NewProjectForm, { login: login, handleAuthResponse: handleAuthResponse });
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
return React__default["default"].createElement("div", null, "Success");
|
|
900
|
+
}
|
|
901
|
+
})()));
|
|
902
|
+
}
|
|
903
|
+
|
|
332
904
|
function Autocomplete(props) {
|
|
333
905
|
var _a, _b;
|
|
334
906
|
const inputRef = React.useRef(null);
|
|
@@ -392,6 +964,7 @@
|
|
|
392
964
|
}
|
|
393
965
|
}
|
|
394
966
|
function handleBlur() {
|
|
967
|
+
tryAddOption();
|
|
395
968
|
setFocused(false);
|
|
396
969
|
dismissOnDelay();
|
|
397
970
|
}
|
|
@@ -604,111 +1177,6 @@
|
|
|
604
1177
|
React__default["default"].createElement("div", { className: "medplum-autocomplete-label" }, "Create new...")))))));
|
|
605
1178
|
}
|
|
606
1179
|
|
|
607
|
-
function MedplumLink(props) {
|
|
608
|
-
const navigate = reactRouterDom.useNavigate();
|
|
609
|
-
let href = '#';
|
|
610
|
-
if (props.to) {
|
|
611
|
-
if (typeof props.to === 'string') {
|
|
612
|
-
href = props.to;
|
|
613
|
-
}
|
|
614
|
-
else if ('resourceType' in props.to) {
|
|
615
|
-
href = `/${props.to.resourceType}/${props.to.id}`;
|
|
616
|
-
}
|
|
617
|
-
else if ('reference' in props.to) {
|
|
618
|
-
href = `/${props.to.reference}`;
|
|
619
|
-
}
|
|
620
|
-
if (props.suffix) {
|
|
621
|
-
href += '/' + props.suffix;
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
return (React__default["default"].createElement("a", { href: href, id: props.id, "aria-label": props.label, "data-testid": props.testid || 'link', className: props.className, onClick: (e) => {
|
|
625
|
-
killEvent(e);
|
|
626
|
-
if (props.onClick) {
|
|
627
|
-
props.onClick();
|
|
628
|
-
}
|
|
629
|
-
else if (props.to) {
|
|
630
|
-
navigate(href);
|
|
631
|
-
}
|
|
632
|
-
} }, props.children));
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
const system = {
|
|
636
|
-
resourceType: 'Device',
|
|
637
|
-
id: 'system',
|
|
638
|
-
deviceName: [
|
|
639
|
-
{
|
|
640
|
-
name: 'System',
|
|
641
|
-
},
|
|
642
|
-
],
|
|
643
|
-
};
|
|
644
|
-
/**
|
|
645
|
-
* React Hook to use a FHIR reference.
|
|
646
|
-
* Handles the complexity of resolving references and caching resources.
|
|
647
|
-
* @param value The resource or reference to resource.
|
|
648
|
-
* @returns The resolved resource.
|
|
649
|
-
*/
|
|
650
|
-
function useResource(value) {
|
|
651
|
-
const medplum = useMedplum();
|
|
652
|
-
const [resource, setResource] = React.useState(getInitialResource(medplum, value));
|
|
653
|
-
React.useEffect(() => {
|
|
654
|
-
let subscribed = true;
|
|
655
|
-
if (!resource && value && 'reference' in value && value.reference) {
|
|
656
|
-
medplum
|
|
657
|
-
.readReference(value)
|
|
658
|
-
.then((r) => {
|
|
659
|
-
if (subscribed) {
|
|
660
|
-
setResource(r);
|
|
661
|
-
}
|
|
662
|
-
})
|
|
663
|
-
.catch(() => setResource(undefined));
|
|
664
|
-
}
|
|
665
|
-
return (() => (subscribed = false));
|
|
666
|
-
}, [medplum, resource, value]);
|
|
667
|
-
return resource;
|
|
668
|
-
}
|
|
669
|
-
/**
|
|
670
|
-
* Returns the initial resource value based on the input value.
|
|
671
|
-
* If the input value is a resource, returns the resource.
|
|
672
|
-
* If the input value is a reference to system, returns the system resource.
|
|
673
|
-
* If the input value is a reference to a resource available in the cache, returns the resource.
|
|
674
|
-
* Otherwise, returns undefined.
|
|
675
|
-
* @param medplum The medplum client.
|
|
676
|
-
* @param value The resource or reference to resource.
|
|
677
|
-
* @returns An initial resource if available; undefined otherwise.
|
|
678
|
-
*/
|
|
679
|
-
function getInitialResource(medplum, value) {
|
|
680
|
-
if (!value) {
|
|
681
|
-
return undefined;
|
|
682
|
-
}
|
|
683
|
-
if ('resourceType' in value) {
|
|
684
|
-
return value;
|
|
685
|
-
}
|
|
686
|
-
if ('reference' in value) {
|
|
687
|
-
if (value.reference === 'system') {
|
|
688
|
-
return system;
|
|
689
|
-
}
|
|
690
|
-
return medplum.getCachedReference(value);
|
|
691
|
-
}
|
|
692
|
-
return undefined;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
function Avatar(props) {
|
|
696
|
-
var _a, _b;
|
|
697
|
-
const resource = useResource(props.value);
|
|
698
|
-
const className = props.size ? 'medplum-avatar ' + props.size : 'medplum-avatar';
|
|
699
|
-
const text = resource ? core.getDisplayString(resource) : (_a = props.alt) !== null && _a !== void 0 ? _a : '';
|
|
700
|
-
const initials = text && getInitials(text);
|
|
701
|
-
const imageUrl = (_b = (resource && core.getImageSrc(resource))) !== null && _b !== void 0 ? _b : props.src;
|
|
702
|
-
const innerContent = imageUrl ? React__default["default"].createElement("img", { src: imageUrl, alt: text }) : initials;
|
|
703
|
-
return (React__default["default"].createElement("div", { className: className, style: { backgroundColor: props.color }, "data-testid": "avatar" }, props.link && resource ? React__default["default"].createElement(MedplumLink, { to: resource }, innerContent) : innerContent));
|
|
704
|
-
}
|
|
705
|
-
function getInitials(text) {
|
|
706
|
-
return text
|
|
707
|
-
.split(' ')
|
|
708
|
-
.map((n) => n[0])
|
|
709
|
-
.join('');
|
|
710
|
-
}
|
|
711
|
-
|
|
712
1180
|
function CheckboxFormSection(props) {
|
|
713
1181
|
return (React__default["default"].createElement("div", { className: "medplum-checkbox-form-section" },
|
|
714
1182
|
React__default["default"].createElement("div", { className: "medplum-checkbox-form-section-checkbox-container" }, props.children),
|
|
@@ -727,19 +1195,6 @@
|
|
|
727
1195
|
'modifierExtension',
|
|
728
1196
|
];
|
|
729
1197
|
|
|
730
|
-
function FormSection(props) {
|
|
731
|
-
const issues = getIssuesForExpression(props.outcome, props.htmlFor);
|
|
732
|
-
const invalid = issues && issues.length > 0;
|
|
733
|
-
return (React__default["default"].createElement("fieldset", { className: "medplum-form-section" },
|
|
734
|
-
props.title && React__default["default"].createElement("label", { htmlFor: props.htmlFor }, props.title),
|
|
735
|
-
props.description && React__default["default"].createElement("p", null, props.description),
|
|
736
|
-
props.children,
|
|
737
|
-
invalid && (React__default["default"].createElement("div", { id: props.htmlFor + '-errors', className: "medplum-input-error" }, issues === null || issues === void 0 ? void 0 : issues.map((issue) => {
|
|
738
|
-
var _a, _b;
|
|
739
|
-
return (React__default["default"].createElement("div", { "data-testid": "text-field-error", key: (_a = issue.details) === null || _a === void 0 ? void 0 : _a.text }, (_b = issue.details) === null || _b === void 0 ? void 0 : _b.text));
|
|
740
|
-
})))));
|
|
741
|
-
}
|
|
742
|
-
|
|
743
1198
|
function ResourceForm(props) {
|
|
744
1199
|
const medplum = useMedplum();
|
|
745
1200
|
const defaultValue = useResource(props.defaultValue);
|
|
@@ -1106,7 +1561,7 @@
|
|
|
1106
1561
|
return medplum.searchValueSet(system, input).then((valueSet) => {
|
|
1107
1562
|
return valueSet.expansion.contains.map(valueSetElementToCodeableConcept);
|
|
1108
1563
|
});
|
|
1109
|
-
}, buildUnstructured: buildUnstructured, getId: getId, getDisplay: getDisplay, name: props.name, defaultValue: defaultValue, onChange: (values) => {
|
|
1564
|
+
}, buildUnstructured: buildUnstructured, getId: getId, getDisplay: getDisplay, name: props.name, defaultValue: defaultValue, loadOnFocus: true, onChange: (values) => {
|
|
1110
1565
|
if (props.onChange) {
|
|
1111
1566
|
props.onChange(values[0]);
|
|
1112
1567
|
}
|
|
@@ -1154,7 +1609,7 @@
|
|
|
1154
1609
|
contains.forEach((e) => (cachedDisplayValues[e.code] = e.display));
|
|
1155
1610
|
return contains.map((e) => e.code);
|
|
1156
1611
|
});
|
|
1157
|
-
}, buildUnstructured: (str) => str, getId: (item) => item, getDisplay: (item) => React__default["default"].createElement(React__default["default"].Fragment, null, cachedDisplayValues[item] || item), name: props.name, defaultValue: defaultValue, onChange: (values) => {
|
|
1612
|
+
}, buildUnstructured: (str) => str, getId: (item) => item, getDisplay: (item) => React__default["default"].createElement(React__default["default"].Fragment, null, cachedDisplayValues[item] || item), name: props.name, defaultValue: defaultValue, loadOnFocus: true, onChange: (values) => {
|
|
1158
1613
|
if (props.onChange) {
|
|
1159
1614
|
props.onChange(values[0]);
|
|
1160
1615
|
}
|
|
@@ -1177,7 +1632,7 @@
|
|
|
1177
1632
|
display: e.display,
|
|
1178
1633
|
}));
|
|
1179
1634
|
});
|
|
1180
|
-
}, buildUnstructured: (str) => ({ code: str }), getId: (item) => item.code, getDisplay: (item) => React__default["default"].createElement(CodingDisplay, { value: item }), name: props.name, defaultValue: defaultValue, onChange: (values) => {
|
|
1635
|
+
}, buildUnstructured: (str) => ({ code: str }), getId: (item) => item.code, getDisplay: (item) => React__default["default"].createElement(CodingDisplay, { value: item }), name: props.name, defaultValue: defaultValue, loadOnFocus: true, onChange: (values) => {
|
|
1181
1636
|
if (props.onChange) {
|
|
1182
1637
|
props.onChange(values[0]);
|
|
1183
1638
|
}
|
|
@@ -1472,31 +1927,6 @@
|
|
|
1472
1927
|
React__default["default"].createElement(QuantityInput, { name: props.name + '-denominator', defaultValue: value === null || value === void 0 ? void 0 : value.denominator, onChange: (v) => setValueWrapper(Object.assign(Object.assign({}, value), { denominator: v })) })));
|
|
1473
1928
|
}
|
|
1474
1929
|
|
|
1475
|
-
/******************************************************************************
|
|
1476
|
-
Copyright (c) Microsoft Corporation.
|
|
1477
|
-
|
|
1478
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
1479
|
-
purpose with or without fee is hereby granted.
|
|
1480
|
-
|
|
1481
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1482
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1483
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1484
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1485
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1486
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1487
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
1488
|
-
***************************************************************************** */
|
|
1489
|
-
|
|
1490
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1491
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1492
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1493
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1494
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1495
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1496
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1497
|
-
});
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
1930
|
function ResourceName(props) {
|
|
1501
1931
|
const resource = useResource(props.value);
|
|
1502
1932
|
if (!resource) {
|
|
@@ -1968,77 +2398,20 @@
|
|
|
1968
2398
|
}
|
|
1969
2399
|
if (obs === null || obs === void 0 ? void 0 : obs.valueString) {
|
|
1970
2400
|
return React__default["default"].createElement(React__default["default"].Fragment, null, obs.valueString);
|
|
1971
|
-
}
|
|
1972
|
-
if (obs && 'component' in obs && (obs === null || obs === void 0 ? void 0 : obs.component)) {
|
|
1973
|
-
return (React__default["default"].createElement(React__default["default"].Fragment, null, obs.component
|
|
1974
|
-
.map((component, index) => (React__default["default"].createElement(ObservationValueDisplay, { key: `obs-${index}`, value: component })))
|
|
1975
|
-
.reduce((prev, curr) => [prev, ' / ', curr])));
|
|
1976
|
-
}
|
|
1977
|
-
return null;
|
|
1978
|
-
}
|
|
1979
|
-
function ReferenceRangeDisplay(props) {
|
|
1980
|
-
const range = props.value && props.value.length > 0 && props.value[0];
|
|
1981
|
-
if (!range) {
|
|
1982
|
-
return null;
|
|
1983
|
-
}
|
|
1984
|
-
return React__default["default"].createElement(RangeDisplay, { value: range });
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
/**
|
|
1988
|
-
* Parses an HTML form and returns the result as a JavaScript object.
|
|
1989
|
-
* @param form The HTML form element.
|
|
1990
|
-
*/
|
|
1991
|
-
function parseForm(form) {
|
|
1992
|
-
const result = {};
|
|
1993
|
-
for (const element of Array.from(form.elements)) {
|
|
1994
|
-
if (element instanceof HTMLInputElement) {
|
|
1995
|
-
parseInputElement(result, element);
|
|
1996
|
-
}
|
|
1997
|
-
else if (element instanceof HTMLTextAreaElement) {
|
|
1998
|
-
result[element.name] = element.value;
|
|
1999
|
-
}
|
|
2000
|
-
else if (element instanceof HTMLSelectElement) {
|
|
2001
|
-
parseSelectElement(result, element);
|
|
2002
|
-
}
|
|
2003
|
-
}
|
|
2004
|
-
return result;
|
|
2005
|
-
}
|
|
2006
|
-
/**
|
|
2007
|
-
* Parses an HTML input element.
|
|
2008
|
-
* Sets the name/value pair in the result,
|
|
2009
|
-
* but only if the element is enabled and checked.
|
|
2010
|
-
* @param el The input element.
|
|
2011
|
-
* @param result The result builder.
|
|
2012
|
-
*/
|
|
2013
|
-
function parseInputElement(result, el) {
|
|
2014
|
-
if (el.disabled) {
|
|
2015
|
-
// Ignore disabled elements
|
|
2016
|
-
return;
|
|
2017
|
-
}
|
|
2018
|
-
if ((el.type === 'checkbox' || el.type === 'radio') && !el.checked) {
|
|
2019
|
-
// Ignore unchecked radio or checkbox elements
|
|
2020
|
-
return;
|
|
2021
|
-
}
|
|
2022
|
-
result[el.name] = el.value;
|
|
2023
|
-
}
|
|
2024
|
-
/**
|
|
2025
|
-
* Parses an HTML select element.
|
|
2026
|
-
* Sets the name/value pair if one is selected.
|
|
2027
|
-
* @param result The result builder.
|
|
2028
|
-
* @param el The select element.
|
|
2029
|
-
*/
|
|
2030
|
-
function parseSelectElement(result, el) {
|
|
2031
|
-
result[el.name] = el.value;
|
|
2032
|
-
}
|
|
2033
|
-
|
|
2034
|
-
function Form(props) {
|
|
2035
|
-
return (React__default["default"].createElement("form", { style: props.style, "data-testid": props.testid, onSubmit: (e) => {
|
|
2036
|
-
e.preventDefault();
|
|
2037
|
-
const formData = parseForm(e.target);
|
|
2038
|
-
if (props.onSubmit) {
|
|
2039
|
-
props.onSubmit(formData);
|
|
2040
|
-
}
|
|
2041
|
-
} }, props.children));
|
|
2401
|
+
}
|
|
2402
|
+
if (obs && 'component' in obs && (obs === null || obs === void 0 ? void 0 : obs.component)) {
|
|
2403
|
+
return (React__default["default"].createElement(React__default["default"].Fragment, null, obs.component
|
|
2404
|
+
.map((component, index) => (React__default["default"].createElement(ObservationValueDisplay, { key: `obs-${index}`, value: component })))
|
|
2405
|
+
.reduce((prev, curr) => [prev, ' / ', curr])));
|
|
2406
|
+
}
|
|
2407
|
+
return null;
|
|
2408
|
+
}
|
|
2409
|
+
function ReferenceRangeDisplay(props) {
|
|
2410
|
+
const range = props.value && props.value.length > 0 && props.value[0];
|
|
2411
|
+
if (!range) {
|
|
2412
|
+
return null;
|
|
2413
|
+
}
|
|
2414
|
+
return React__default["default"].createElement(RangeDisplay, { value: range });
|
|
2042
2415
|
}
|
|
2043
2416
|
|
|
2044
2417
|
function Loading() {
|
|
@@ -2330,7 +2703,9 @@
|
|
|
2330
2703
|
}
|
|
2331
2704
|
if (bundle.entry) {
|
|
2332
2705
|
for (const entry of bundle.entry) {
|
|
2333
|
-
|
|
2706
|
+
if (entry.resource) {
|
|
2707
|
+
newItems.push(entry.resource);
|
|
2708
|
+
}
|
|
2334
2709
|
}
|
|
2335
2710
|
}
|
|
2336
2711
|
}
|
|
@@ -2517,11 +2892,6 @@
|
|
|
2517
2892
|
}) }));
|
|
2518
2893
|
}
|
|
2519
2894
|
|
|
2520
|
-
function Document(props) {
|
|
2521
|
-
return (React__default["default"].createElement("main", { className: "medplum-document" },
|
|
2522
|
-
React__default["default"].createElement("article", { style: { maxWidth: props.width } }, props.children)));
|
|
2523
|
-
}
|
|
2524
|
-
|
|
2525
2895
|
function EncounterTimeline(props) {
|
|
2526
2896
|
return (React__default["default"].createElement(ResourceTimeline, { value: props.encounter, buildSearchRequests: (resource) => ({
|
|
2527
2897
|
resourceType: 'Bundle',
|
|
@@ -4300,16 +4670,6 @@
|
|
|
4300
4670
|
React__default["default"].createElement(MedplumLink, { to: "/changepassword" }, "Change password"))))));
|
|
4301
4671
|
}
|
|
4302
4672
|
|
|
4303
|
-
function Logo(props) {
|
|
4304
|
-
return (React__default["default"].createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 491 491", style: { width: props.size, height: props.size } },
|
|
4305
|
-
React__default["default"].createElement("title", null, "Medplum Logo"),
|
|
4306
|
-
React__default["default"].createElement("path", { fill: props.fill || '#ad7136', d: "M282 67c6-16 16-29 29-40L289 0c-22 17-37 41-43 68l17 23 19-24z" }),
|
|
4307
|
-
React__default["default"].createElement("path", { fill: props.fill || '#654b87', d: "M311 63c-17 0-33 4-48 11-16-7-32-11-49-11-87 0-158 96-158 214s71 214 158 214c17 0 33-4 49-11 15 7 31 11 48 11 87 0 158-96 158-214S398 63 311 63z" }),
|
|
4308
|
-
React__default["default"].createElement("path", { fill: props.fill || '#463068', d: "M231 489l-17 2c-87 0-158-96-158-214S127 63 214 63l17 1c-39 12-70 102-70 213s31 201 70 212z" }),
|
|
4309
|
-
React__default["default"].createElement("path", { fill: props.fill || '#70d65b', d: "M207 220a176 176 0 01-177 43A176 176 0 01251 43l1 5c17 59 2 125-45 172z" }),
|
|
4310
|
-
React__default["default"].createElement("path", { fill: props.fill || '#58b741', d: "M252 48A421 421 0 0057 270l-27-7A176 176 0 01251 43l1 5z" })));
|
|
4311
|
-
}
|
|
4312
|
-
|
|
4313
4673
|
const searches = [
|
|
4314
4674
|
'$/_history',
|
|
4315
4675
|
'Communication?subject=$',
|
|
@@ -5048,195 +5408,6 @@
|
|
|
5048
5408
|
return options.map((option) => (Object.assign(Object.assign({}, option), { id: option.id || generateId() })));
|
|
5049
5409
|
}
|
|
5050
5410
|
|
|
5051
|
-
/**
|
|
5052
|
-
* Dynamically creates a script tag for the specified JavaScript file.
|
|
5053
|
-
* @param src The JavaScript file URL.
|
|
5054
|
-
*/
|
|
5055
|
-
function createScriptTag(src, onload) {
|
|
5056
|
-
const head = document.getElementsByTagName('head')[0];
|
|
5057
|
-
const script = document.createElement('script');
|
|
5058
|
-
script.async = true;
|
|
5059
|
-
script.src = src;
|
|
5060
|
-
script.onload = onload || null;
|
|
5061
|
-
head.appendChild(script);
|
|
5062
|
-
}
|
|
5063
|
-
|
|
5064
|
-
function GoogleButton(props) {
|
|
5065
|
-
const medplum = useMedplum();
|
|
5066
|
-
const { googleClientId, handleGoogleCredential } = props;
|
|
5067
|
-
const parentRef = React.useRef(null);
|
|
5068
|
-
const [scriptLoaded, setScriptLoaded] = React.useState(typeof google !== 'undefined');
|
|
5069
|
-
const [initialized, setInitialized] = React.useState(false);
|
|
5070
|
-
const [buttonRendered, setButtonRendered] = React.useState(false);
|
|
5071
|
-
React.useEffect(() => {
|
|
5072
|
-
if (typeof google === 'undefined') {
|
|
5073
|
-
createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));
|
|
5074
|
-
return;
|
|
5075
|
-
}
|
|
5076
|
-
if (!initialized) {
|
|
5077
|
-
google.accounts.id.initialize({
|
|
5078
|
-
client_id: googleClientId,
|
|
5079
|
-
callback: handleGoogleCredential,
|
|
5080
|
-
});
|
|
5081
|
-
setInitialized(true);
|
|
5082
|
-
}
|
|
5083
|
-
if (parentRef.current && !buttonRendered) {
|
|
5084
|
-
google.accounts.id.renderButton(parentRef.current, {});
|
|
5085
|
-
setButtonRendered(true);
|
|
5086
|
-
}
|
|
5087
|
-
}, [medplum, googleClientId, initialized, scriptLoaded, parentRef, buttonRendered, handleGoogleCredential]);
|
|
5088
|
-
if (!googleClientId) {
|
|
5089
|
-
return null;
|
|
5090
|
-
}
|
|
5091
|
-
return React__default["default"].createElement("div", { ref: parentRef });
|
|
5092
|
-
}
|
|
5093
|
-
function getGoogleClientId(clientId) {
|
|
5094
|
-
var _a, _b;
|
|
5095
|
-
if (clientId) {
|
|
5096
|
-
return clientId;
|
|
5097
|
-
}
|
|
5098
|
-
const origin = window.location.protocol + '//' + window.location.host;
|
|
5099
|
-
const authorizedOrigins = (_b = (_a = "http://localhost:3000,http://127.0.0.1:3000,http://localhost:6006,http://127.0.0.1:6006,https://app.medplum.com,https://docs.medplum.com") === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
|
|
5100
|
-
if (authorizedOrigins.includes(origin)) {
|
|
5101
|
-
return "921088377005-3j1sa10vr6hj86jgmdfh2l53v3mp7lfi.apps.googleusercontent.com";
|
|
5102
|
-
}
|
|
5103
|
-
return undefined;
|
|
5104
|
-
}
|
|
5105
|
-
|
|
5106
|
-
/**
|
|
5107
|
-
* Dynamically loads the recaptcha script.
|
|
5108
|
-
* We do not want to load the script on page load unless the user needs it.
|
|
5109
|
-
* @param siteKey The reCAPTCHA site key, available from the reCAPTCHA admin page.
|
|
5110
|
-
*/
|
|
5111
|
-
function initRecaptcha(siteKey) {
|
|
5112
|
-
if (typeof grecaptcha === 'undefined') {
|
|
5113
|
-
createScriptTag('https://www.google.com/recaptcha/api.js?render=' + siteKey);
|
|
5114
|
-
}
|
|
5115
|
-
}
|
|
5116
|
-
/**
|
|
5117
|
-
* Starts a request to generate a recapcha token.
|
|
5118
|
-
* @param siteKey The reCAPTCHA site key, available from the reCAPTCHA admin page.
|
|
5119
|
-
* @returns Promise to a recaptcha token for the current user.
|
|
5120
|
-
*/
|
|
5121
|
-
function getRecaptcha(siteKey) {
|
|
5122
|
-
return new Promise((resolve, reject) => {
|
|
5123
|
-
grecaptcha.ready(() => __awaiter(this, void 0, void 0, function* () {
|
|
5124
|
-
try {
|
|
5125
|
-
resolve(yield grecaptcha.execute(siteKey, { action: 'submit' }));
|
|
5126
|
-
}
|
|
5127
|
-
catch (err) {
|
|
5128
|
-
reject(err);
|
|
5129
|
-
}
|
|
5130
|
-
}));
|
|
5131
|
-
});
|
|
5132
|
-
}
|
|
5133
|
-
|
|
5134
|
-
function RegisterForm(props) {
|
|
5135
|
-
const medplum = useMedplum();
|
|
5136
|
-
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
5137
|
-
const recaptchaSiteKey = props.recaptchaSiteKey;
|
|
5138
|
-
const [outcome, setOutcome] = React.useState();
|
|
5139
|
-
const issues = getIssuesForExpression(outcome, undefined);
|
|
5140
|
-
React.useEffect(() => initRecaptcha(recaptchaSiteKey), [recaptchaSiteKey]);
|
|
5141
|
-
function handleAuthResponse(registerRequest, partialLogin) {
|
|
5142
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
5143
|
-
try {
|
|
5144
|
-
let login;
|
|
5145
|
-
if (props.type === 'patient') {
|
|
5146
|
-
login = yield medplum.startNewPatient(registerRequest, partialLogin);
|
|
5147
|
-
}
|
|
5148
|
-
else {
|
|
5149
|
-
login = yield medplum.startNewProject(registerRequest, partialLogin);
|
|
5150
|
-
}
|
|
5151
|
-
yield medplum.processCode(login.code);
|
|
5152
|
-
props.onSuccess();
|
|
5153
|
-
}
|
|
5154
|
-
catch (err) {
|
|
5155
|
-
setOutcome(err);
|
|
5156
|
-
}
|
|
5157
|
-
});
|
|
5158
|
-
}
|
|
5159
|
-
return (React__default["default"].createElement(Document, { width: 450 },
|
|
5160
|
-
React__default["default"].createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => __awaiter(this, void 0, void 0, function* () {
|
|
5161
|
-
try {
|
|
5162
|
-
const recaptchaToken = yield getRecaptcha(recaptchaSiteKey);
|
|
5163
|
-
const registerRequest = {
|
|
5164
|
-
projectId: props.projectId,
|
|
5165
|
-
projectName: formData.projectName,
|
|
5166
|
-
firstName: formData.firstName,
|
|
5167
|
-
lastName: formData.lastName,
|
|
5168
|
-
email: formData.email,
|
|
5169
|
-
password: formData.password,
|
|
5170
|
-
remember: formData.remember === 'true',
|
|
5171
|
-
recaptchaSiteKey,
|
|
5172
|
-
recaptchaToken,
|
|
5173
|
-
};
|
|
5174
|
-
const userLogin = yield medplum.startNewUser(registerRequest);
|
|
5175
|
-
yield handleAuthResponse(registerRequest, userLogin);
|
|
5176
|
-
}
|
|
5177
|
-
catch (err) {
|
|
5178
|
-
setOutcome(err);
|
|
5179
|
-
}
|
|
5180
|
-
}) },
|
|
5181
|
-
React__default["default"].createElement("div", { className: "medplum-center" }, props.children),
|
|
5182
|
-
issues && (React__default["default"].createElement("div", { className: "medplum-input-error" }, issues.map((issue) => {
|
|
5183
|
-
var _a, _b;
|
|
5184
|
-
return (React__default["default"].createElement("div", { "data-testid": "text-field-error", key: (_a = issue.details) === null || _a === void 0 ? void 0 : _a.text }, (_b = issue.details) === null || _b === void 0 ? void 0 : _b.text));
|
|
5185
|
-
}))),
|
|
5186
|
-
googleClientId && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5187
|
-
React__default["default"].createElement("div", { className: "medplum-signin-google-container" },
|
|
5188
|
-
React__default["default"].createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) => __awaiter(this, void 0, void 0, function* () {
|
|
5189
|
-
try {
|
|
5190
|
-
const loginRequest = {
|
|
5191
|
-
googleClientId: response.clientId,
|
|
5192
|
-
googleCredential: response.credential,
|
|
5193
|
-
};
|
|
5194
|
-
const userLogin = yield medplum.startGoogleLogin(loginRequest);
|
|
5195
|
-
const googleClaims = core.parseJWTPayload(loginRequest.googleCredential);
|
|
5196
|
-
const registerRequest = {
|
|
5197
|
-
projectId: props.projectId,
|
|
5198
|
-
firstName: googleClaims.given_name,
|
|
5199
|
-
lastName: googleClaims.family_name,
|
|
5200
|
-
email: googleClaims.email,
|
|
5201
|
-
};
|
|
5202
|
-
yield handleAuthResponse(registerRequest, userLogin);
|
|
5203
|
-
}
|
|
5204
|
-
catch (err) {
|
|
5205
|
-
setOutcome(err);
|
|
5206
|
-
}
|
|
5207
|
-
}) })),
|
|
5208
|
-
React__default["default"].createElement("div", { className: "medplum-signin-separator" }, "or"))),
|
|
5209
|
-
React__default["default"].createElement(FormSection, { title: "First Name", htmlFor: "firstName", outcome: outcome },
|
|
5210
|
-
React__default["default"].createElement(Input, { name: "firstName", type: "text", testid: "firstName", placeholder: "First name", required: true, autoFocus: true, outcome: outcome })),
|
|
5211
|
-
React__default["default"].createElement(FormSection, { title: "Last Name", htmlFor: "lastName", outcome: outcome },
|
|
5212
|
-
React__default["default"].createElement(Input, { name: "lastName", type: "text", testid: "lastName", placeholder: "Last name", required: true, outcome: outcome })),
|
|
5213
|
-
props.type === 'project' && (React__default["default"].createElement(FormSection, { title: "Project Name", htmlFor: "projectName", outcome: outcome },
|
|
5214
|
-
React__default["default"].createElement(Input, { name: "projectName", type: "text", testid: "projectName", placeholder: "My Project", required: true, outcome: outcome }))),
|
|
5215
|
-
React__default["default"].createElement(FormSection, { title: "Email", htmlFor: "email", outcome: outcome },
|
|
5216
|
-
React__default["default"].createElement(Input, { name: "email", type: "email", testid: "email", placeholder: "name@domain.com", required: true, outcome: outcome })),
|
|
5217
|
-
React__default["default"].createElement(FormSection, { title: "Password", htmlFor: "password", outcome: outcome },
|
|
5218
|
-
React__default["default"].createElement(Input, { name: "password", type: "password", testid: "password", autoComplete: "off", required: true, outcome: outcome })),
|
|
5219
|
-
React__default["default"].createElement("p", { style: { fontSize: '12px', color: '#888' } },
|
|
5220
|
-
"By clicking submit you agree to the Medplum ",
|
|
5221
|
-
React__default["default"].createElement("a", { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
|
|
5222
|
-
' and ',
|
|
5223
|
-
React__default["default"].createElement("a", { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
5224
|
-
"."),
|
|
5225
|
-
React__default["default"].createElement("p", { style: { fontSize: '12px', color: '#888' } },
|
|
5226
|
-
"This site is protected by reCAPTCHA and the Google",
|
|
5227
|
-
' ',
|
|
5228
|
-
React__default["default"].createElement("a", { href: "https://policies.google.com/privacy" }, "Privacy\u00A0Policy"),
|
|
5229
|
-
' and ',
|
|
5230
|
-
React__default["default"].createElement("a", { href: "https://policies.google.com/terms" }, "Terms\u00A0of\u00A0Service"),
|
|
5231
|
-
" apply."),
|
|
5232
|
-
React__default["default"].createElement("div", { className: "medplum-signin-buttons" },
|
|
5233
|
-
React__default["default"].createElement("div", null,
|
|
5234
|
-
React__default["default"].createElement("input", { type: "checkbox", id: "remember", name: "remember", value: "true" }),
|
|
5235
|
-
React__default["default"].createElement("label", { htmlFor: "remember" }, "Remember me")),
|
|
5236
|
-
React__default["default"].createElement("div", null,
|
|
5237
|
-
React__default["default"].createElement(Button, { type: "submit", testid: "submit" }, "Create account"))))));
|
|
5238
|
-
}
|
|
5239
|
-
|
|
5240
5411
|
function StatusBadge(props) {
|
|
5241
5412
|
return React__default["default"].createElement("span", { className: `medplum-status medplum-status-${props.status}` }, props.status);
|
|
5242
5413
|
}
|
|
@@ -5587,19 +5758,23 @@
|
|
|
5587
5758
|
React__default["default"].createElement("th", null, "Author"),
|
|
5588
5759
|
React__default["default"].createElement("th", null, "Date"),
|
|
5589
5760
|
React__default["default"].createElement("th", null, "Version"))),
|
|
5590
|
-
React__default["default"].createElement("tbody", null, (_a = value.entry) === null || _a === void 0 ? void 0 : _a.map((entry) => {
|
|
5591
|
-
var _a, _b;
|
|
5592
|
-
return (React__default["default"].createElement(HistoryRow, { key: (_b = (_a = entry.resource) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.versionId, version: entry.resource }));
|
|
5593
|
-
}))));
|
|
5761
|
+
React__default["default"].createElement("tbody", null, (_a = value.entry) === null || _a === void 0 ? void 0 : _a.map((entry, index) => (React__default["default"].createElement(HistoryRow, { key: 'entry-' + index, entry: entry }))))));
|
|
5594
5762
|
}
|
|
5595
5763
|
function HistoryRow(props) {
|
|
5596
5764
|
var _a, _b, _c;
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
React__default["default"].createElement(
|
|
5765
|
+
const { response, resource } = props.entry;
|
|
5766
|
+
if (resource) {
|
|
5767
|
+
return (React__default["default"].createElement("tr", null,
|
|
5768
|
+
React__default["default"].createElement("td", null,
|
|
5769
|
+
React__default["default"].createElement(ResourceBadge, { value: (_a = resource.meta) === null || _a === void 0 ? void 0 : _a.author, link: true })),
|
|
5770
|
+
React__default["default"].createElement("td", null, core.formatDateTime((_b = resource.meta) === null || _b === void 0 ? void 0 : _b.lastUpdated)),
|
|
5771
|
+
React__default["default"].createElement("td", null,
|
|
5772
|
+
React__default["default"].createElement(MedplumLink, { to: getVersionUrl(resource) }, (_c = resource.meta) === null || _c === void 0 ? void 0 : _c.versionId))));
|
|
5773
|
+
}
|
|
5774
|
+
else {
|
|
5775
|
+
return (React__default["default"].createElement("tr", null,
|
|
5776
|
+
React__default["default"].createElement("td", { colSpan: 3 }, core.normalizeErrorString(response === null || response === void 0 ? void 0 : response.outcome))));
|
|
5777
|
+
}
|
|
5603
5778
|
}
|
|
5604
5779
|
function getVersionUrl(resource) {
|
|
5605
5780
|
var _a;
|
|
@@ -5820,122 +5995,6 @@
|
|
|
5820
5995
|
}) }));
|
|
5821
5996
|
}
|
|
5822
5997
|
|
|
5823
|
-
function SignInForm(props) {
|
|
5824
|
-
const medplum = useMedplum();
|
|
5825
|
-
const [login, setLogin] = React.useState(undefined);
|
|
5826
|
-
const [memberships, setMemberships] = React.useState(undefined);
|
|
5827
|
-
function handleAuthResponse(response) {
|
|
5828
|
-
if (response.login) {
|
|
5829
|
-
setLogin(response.login);
|
|
5830
|
-
}
|
|
5831
|
-
if (response.memberships) {
|
|
5832
|
-
setMemberships(response.memberships);
|
|
5833
|
-
}
|
|
5834
|
-
if (response.code) {
|
|
5835
|
-
if (props.onCode) {
|
|
5836
|
-
props.onCode(response.code);
|
|
5837
|
-
}
|
|
5838
|
-
else {
|
|
5839
|
-
medplum
|
|
5840
|
-
.processCode(response.code)
|
|
5841
|
-
.then(() => {
|
|
5842
|
-
if (props.onSuccess) {
|
|
5843
|
-
props.onSuccess();
|
|
5844
|
-
}
|
|
5845
|
-
})
|
|
5846
|
-
.catch(console.log);
|
|
5847
|
-
}
|
|
5848
|
-
}
|
|
5849
|
-
}
|
|
5850
|
-
return (React__default["default"].createElement(Document, { width: 450 }, (() => {
|
|
5851
|
-
if (!login) {
|
|
5852
|
-
return (React__default["default"].createElement(AuthenticationForm, { clientId: props.clientId, scope: props.scope, nonce: props.nonce, googleClientId: props.googleClientId, onForgotPassword: props.onForgotPassword, onRegister: props.onRegister, handleAuthResponse: handleAuthResponse }, props.children));
|
|
5853
|
-
}
|
|
5854
|
-
else if (memberships) {
|
|
5855
|
-
return React__default["default"].createElement(ProfileForm, { login: login, memberships: memberships, handleAuthResponse: handleAuthResponse });
|
|
5856
|
-
}
|
|
5857
|
-
else {
|
|
5858
|
-
return React__default["default"].createElement("div", null, "Success");
|
|
5859
|
-
}
|
|
5860
|
-
})()));
|
|
5861
|
-
}
|
|
5862
|
-
function AuthenticationForm(props) {
|
|
5863
|
-
const medplum = useMedplum();
|
|
5864
|
-
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
5865
|
-
const [outcome, setOutcome] = React.useState();
|
|
5866
|
-
const issues = getIssuesForExpression(outcome, undefined);
|
|
5867
|
-
return (React__default["default"].createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => {
|
|
5868
|
-
medplum
|
|
5869
|
-
.startLogin({
|
|
5870
|
-
clientId: props.clientId,
|
|
5871
|
-
scope: props.scope,
|
|
5872
|
-
nonce: props.nonce,
|
|
5873
|
-
email: formData.email,
|
|
5874
|
-
password: formData.password,
|
|
5875
|
-
remember: formData.remember === 'true',
|
|
5876
|
-
})
|
|
5877
|
-
.then(props.handleAuthResponse)
|
|
5878
|
-
.catch(setOutcome);
|
|
5879
|
-
} },
|
|
5880
|
-
React__default["default"].createElement("div", { className: "medplum-center" }, props.children),
|
|
5881
|
-
issues && (React__default["default"].createElement("div", { className: "medplum-input-error" }, issues.map((issue) => {
|
|
5882
|
-
var _a, _b;
|
|
5883
|
-
return (React__default["default"].createElement("div", { "data-testid": "text-field-error", key: (_a = issue.details) === null || _a === void 0 ? void 0 : _a.text }, (_b = issue.details) === null || _b === void 0 ? void 0 : _b.text));
|
|
5884
|
-
}))),
|
|
5885
|
-
googleClientId && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5886
|
-
React__default["default"].createElement("div", { className: "medplum-signin-google-container" },
|
|
5887
|
-
React__default["default"].createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) => {
|
|
5888
|
-
medplum
|
|
5889
|
-
.startGoogleLogin({
|
|
5890
|
-
clientId: props.clientId,
|
|
5891
|
-
scope: props.scope,
|
|
5892
|
-
nonce: props.nonce,
|
|
5893
|
-
googleClientId: response.clientId,
|
|
5894
|
-
googleCredential: response.credential,
|
|
5895
|
-
})
|
|
5896
|
-
.then(props.handleAuthResponse)
|
|
5897
|
-
.catch(setOutcome);
|
|
5898
|
-
} })),
|
|
5899
|
-
React__default["default"].createElement("div", { className: "medplum-signin-separator" }, "or"))),
|
|
5900
|
-
React__default["default"].createElement(FormSection, { title: "Email", htmlFor: "email", outcome: outcome },
|
|
5901
|
-
React__default["default"].createElement(Input, { name: "email", type: "email", testid: "email", required: true, autoFocus: true, outcome: outcome })),
|
|
5902
|
-
React__default["default"].createElement(FormSection, { title: "Password", htmlFor: "password", outcome: outcome },
|
|
5903
|
-
React__default["default"].createElement(Input, { name: "password", type: "password", testid: "password", autoComplete: "off", required: true, outcome: outcome })),
|
|
5904
|
-
React__default["default"].createElement("div", { className: "medplum-signin-buttons" },
|
|
5905
|
-
(props.onForgotPassword || props.onRegister) && (React__default["default"].createElement("div", null,
|
|
5906
|
-
props.onForgotPassword && (React__default["default"].createElement(MedplumLink, { testid: "forgotpassword", onClick: props.onForgotPassword }, "Forgot password")),
|
|
5907
|
-
props.onRegister && (React__default["default"].createElement(MedplumLink, { testid: "register", onClick: props.onRegister }, "Register")))),
|
|
5908
|
-
React__default["default"].createElement("div", null,
|
|
5909
|
-
React__default["default"].createElement("input", { type: "checkbox", id: "remember", name: "remember", value: "true" }),
|
|
5910
|
-
React__default["default"].createElement("label", { htmlFor: "remember" }, "Remember me")),
|
|
5911
|
-
React__default["default"].createElement("div", null,
|
|
5912
|
-
React__default["default"].createElement(Button, { type: "submit", testid: "submit" }, "Sign in")))));
|
|
5913
|
-
}
|
|
5914
|
-
function ProfileForm(props) {
|
|
5915
|
-
const medplum = useMedplum();
|
|
5916
|
-
return (React__default["default"].createElement("div", null,
|
|
5917
|
-
React__default["default"].createElement("div", { className: "medplum-center" },
|
|
5918
|
-
React__default["default"].createElement(Logo, { size: 32 }),
|
|
5919
|
-
React__default["default"].createElement("h1", null, "Choose profile")),
|
|
5920
|
-
props.memberships.map((membership) => {
|
|
5921
|
-
var _a, _b, _c;
|
|
5922
|
-
return (React__default["default"].createElement("div", { className: "medplum-nav-menu-profile", key: membership.id, onClick: () => {
|
|
5923
|
-
medplum
|
|
5924
|
-
.post('auth/profile', {
|
|
5925
|
-
login: props.login,
|
|
5926
|
-
profile: membership.id,
|
|
5927
|
-
})
|
|
5928
|
-
.then(props.handleAuthResponse)
|
|
5929
|
-
.catch(console.log);
|
|
5930
|
-
} },
|
|
5931
|
-
React__default["default"].createElement("div", { className: "medplum-nav-menu-profile-icon" },
|
|
5932
|
-
React__default["default"].createElement(Avatar, { alt: (_a = membership.profile) === null || _a === void 0 ? void 0 : _a.display })),
|
|
5933
|
-
React__default["default"].createElement("div", { className: "medplum-nav-menu-profile-label" }, (_b = membership.profile) === null || _b === void 0 ? void 0 :
|
|
5934
|
-
_b.display,
|
|
5935
|
-
React__default["default"].createElement("div", { className: "medplum-nav-menu-profile-help-text" }, (_c = membership.project) === null || _c === void 0 ? void 0 : _c.display))));
|
|
5936
|
-
})));
|
|
5937
|
-
}
|
|
5938
|
-
|
|
5939
5998
|
function Tab(props) {
|
|
5940
5999
|
let className = 'medplum-tab';
|
|
5941
6000
|
if (props.selected) {
|
|
@@ -6002,6 +6061,8 @@
|
|
|
6002
6061
|
exports.ContactPointInput = ContactPointInput;
|
|
6003
6062
|
exports.DateTimeInput = DateTimeInput;
|
|
6004
6063
|
exports.DefaultResourceTimeline = DefaultResourceTimeline;
|
|
6064
|
+
exports.DescriptionList = DescriptionList;
|
|
6065
|
+
exports.DescriptionListEntry = DescriptionListEntry;
|
|
6005
6066
|
exports.DiagnosticReportDisplay = DiagnosticReportDisplay;
|
|
6006
6067
|
exports.Document = Document;
|
|
6007
6068
|
exports.ElementDefinitionInputSelector = ElementDefinitionInputSelector;
|