@medplum/react 0.9.22 → 0.9.23
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/index.js +188 -75
- 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 +70 -55
- package/dist/esm/index.js +187 -77
- 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 +70 -55
- package/dist/types/RegisterForm.d.ts +17 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/stories/RegisterForm.stories.d.ts +7 -0
- package/dist/types/utils/recaptcha.d.ts +10 -0
- package/package.json +5 -5
package/dist/cjs/index.js
CHANGED
|
@@ -1776,18 +1776,24 @@
|
|
|
1776
1776
|
}
|
|
1777
1777
|
|
|
1778
1778
|
function DiagnosticReportDisplay(props) {
|
|
1779
|
-
var _a;
|
|
1779
|
+
var _a, _b;
|
|
1780
1780
|
const diagnosticReport = useResource(props.value);
|
|
1781
|
+
const specimen = useResource((_a = diagnosticReport === null || diagnosticReport === void 0 ? void 0 : diagnosticReport.specimen) === null || _a === void 0 ? void 0 : _a[0]);
|
|
1781
1782
|
if (!diagnosticReport) {
|
|
1782
1783
|
return null;
|
|
1783
1784
|
}
|
|
1784
|
-
let textContent =
|
|
1785
|
+
let textContent = '';
|
|
1785
1786
|
if (diagnosticReport.presentedForm && diagnosticReport.presentedForm.length > 0) {
|
|
1786
1787
|
const pf = diagnosticReport.presentedForm[0];
|
|
1787
|
-
if (((
|
|
1788
|
+
if (((_b = pf.contentType) === null || _b === void 0 ? void 0 : _b.startsWith('text/plain')) && pf.data) {
|
|
1788
1789
|
textContent = window.atob(pf.data);
|
|
1789
1790
|
}
|
|
1790
1791
|
}
|
|
1792
|
+
if (specimen === null || specimen === void 0 ? void 0 : specimen.note) {
|
|
1793
|
+
for (const note of specimen.note) {
|
|
1794
|
+
textContent += note.text + '\n\n';
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1791
1797
|
return (React__default["default"].createElement("div", { className: "medplum-diagnostic-report" },
|
|
1792
1798
|
React__default["default"].createElement("h1", null, "Diagnostic Report"),
|
|
1793
1799
|
React__default["default"].createElement("div", { className: "medplum-diagnostic-report-header" },
|
|
@@ -1807,8 +1813,8 @@
|
|
|
1807
1813
|
diagnosticReport.status && (React__default["default"].createElement("dl", null,
|
|
1808
1814
|
React__default["default"].createElement("dt", null, "Status"),
|
|
1809
1815
|
React__default["default"].createElement("dd", null, core.capitalize(diagnosticReport.status))))),
|
|
1810
|
-
|
|
1811
|
-
|
|
1816
|
+
diagnosticReport.result && React__default["default"].createElement(ObservationTable, { value: diagnosticReport.result }),
|
|
1817
|
+
textContent && React__default["default"].createElement("pre", null, textContent.trim())));
|
|
1812
1818
|
}
|
|
1813
1819
|
function ObservationTable(props) {
|
|
1814
1820
|
var _a;
|
|
@@ -4904,6 +4910,163 @@
|
|
|
4904
4910
|
return options.map((option) => (Object.assign(Object.assign({}, option), { id: option.id || generateId() })));
|
|
4905
4911
|
}
|
|
4906
4912
|
|
|
4913
|
+
/**
|
|
4914
|
+
* Dynamically creates a script tag for the specified JavaScript file.
|
|
4915
|
+
* @param src The JavaScript file URL.
|
|
4916
|
+
*/
|
|
4917
|
+
function createScriptTag(src, onload) {
|
|
4918
|
+
const head = document.getElementsByTagName('head')[0];
|
|
4919
|
+
const script = document.createElement('script');
|
|
4920
|
+
script.async = true;
|
|
4921
|
+
script.src = src;
|
|
4922
|
+
script.onload = onload || null;
|
|
4923
|
+
head.appendChild(script);
|
|
4924
|
+
}
|
|
4925
|
+
|
|
4926
|
+
function GoogleButton(props) {
|
|
4927
|
+
const medplum = useMedplum();
|
|
4928
|
+
const { googleClientId, handleGoogleCredential } = props;
|
|
4929
|
+
const parentRef = React.useRef(null);
|
|
4930
|
+
const [scriptLoaded, setScriptLoaded] = React.useState(typeof google !== 'undefined');
|
|
4931
|
+
const [initialized, setInitialized] = React.useState(false);
|
|
4932
|
+
const [buttonRendered, setButtonRendered] = React.useState(false);
|
|
4933
|
+
React.useEffect(() => {
|
|
4934
|
+
if (typeof google === 'undefined') {
|
|
4935
|
+
createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));
|
|
4936
|
+
return;
|
|
4937
|
+
}
|
|
4938
|
+
if (!initialized) {
|
|
4939
|
+
google.accounts.id.initialize({
|
|
4940
|
+
client_id: googleClientId,
|
|
4941
|
+
callback: handleGoogleCredential,
|
|
4942
|
+
});
|
|
4943
|
+
setInitialized(true);
|
|
4944
|
+
}
|
|
4945
|
+
if (parentRef.current && !buttonRendered) {
|
|
4946
|
+
google.accounts.id.renderButton(parentRef.current, {});
|
|
4947
|
+
setButtonRendered(true);
|
|
4948
|
+
}
|
|
4949
|
+
}, [medplum, googleClientId, initialized, scriptLoaded, parentRef, buttonRendered, handleGoogleCredential]);
|
|
4950
|
+
if (!googleClientId) {
|
|
4951
|
+
return null;
|
|
4952
|
+
}
|
|
4953
|
+
return React__default["default"].createElement("div", { ref: parentRef });
|
|
4954
|
+
}
|
|
4955
|
+
function getGoogleClientId(clientId) {
|
|
4956
|
+
var _a, _b;
|
|
4957
|
+
if (clientId) {
|
|
4958
|
+
return clientId;
|
|
4959
|
+
}
|
|
4960
|
+
const origin = window.location.protocol + '//' + window.location.host;
|
|
4961
|
+
const authorizedOrigins = (_b = (_a = "http://localhost:3000,http://localhost:6006,https://app.medplum.com,https://docs.medplum.com") === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
|
|
4962
|
+
if (authorizedOrigins.includes(origin)) {
|
|
4963
|
+
return "921088377005-3j1sa10vr6hj86jgmdfh2l53v3mp7lfi.apps.googleusercontent.com";
|
|
4964
|
+
}
|
|
4965
|
+
return undefined;
|
|
4966
|
+
}
|
|
4967
|
+
|
|
4968
|
+
/**
|
|
4969
|
+
* Dynamically loads the recaptcha script.
|
|
4970
|
+
* We do not want to load the script on page load unless the user needs it.
|
|
4971
|
+
*/
|
|
4972
|
+
function initRecaptcha() {
|
|
4973
|
+
if (typeof grecaptcha === 'undefined') {
|
|
4974
|
+
createScriptTag('https://www.google.com/recaptcha/api.js?render=' + process.env.RECAPTCHA_SITE_KEY);
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
/**
|
|
4978
|
+
* Starts a request to generate a recapcha token.
|
|
4979
|
+
* @returns Promise to a recaptcha token for the current user.
|
|
4980
|
+
*/
|
|
4981
|
+
function getRecaptcha() {
|
|
4982
|
+
return new Promise((resolve) => {
|
|
4983
|
+
grecaptcha.ready(() => {
|
|
4984
|
+
grecaptcha.execute(process.env.RECAPTCHA_SITE_KEY, { action: 'submit' }).then(resolve);
|
|
4985
|
+
});
|
|
4986
|
+
});
|
|
4987
|
+
}
|
|
4988
|
+
|
|
4989
|
+
function RegisterForm(props) {
|
|
4990
|
+
const medplum = useMedplum();
|
|
4991
|
+
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
4992
|
+
const [outcome, setOutcome] = React.useState();
|
|
4993
|
+
const issues = getIssuesForExpression(outcome, undefined);
|
|
4994
|
+
React.useEffect(initRecaptcha, []);
|
|
4995
|
+
function handleAuthResponse(registerRequest, partialLogin) {
|
|
4996
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4997
|
+
try {
|
|
4998
|
+
let login;
|
|
4999
|
+
if (props.type === 'patient') {
|
|
5000
|
+
login = yield medplum.startNewPatient(registerRequest, partialLogin);
|
|
5001
|
+
}
|
|
5002
|
+
else {
|
|
5003
|
+
login = yield medplum.startNewProject(registerRequest, partialLogin);
|
|
5004
|
+
}
|
|
5005
|
+
yield medplum.processCode(login.code);
|
|
5006
|
+
props.onSuccess();
|
|
5007
|
+
}
|
|
5008
|
+
catch (err) {
|
|
5009
|
+
setOutcome(err);
|
|
5010
|
+
}
|
|
5011
|
+
});
|
|
5012
|
+
}
|
|
5013
|
+
return (React__default["default"].createElement(Document, { width: 450 },
|
|
5014
|
+
React__default["default"].createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => __awaiter(this, void 0, void 0, function* () {
|
|
5015
|
+
try {
|
|
5016
|
+
const recaptchaToken = yield getRecaptcha();
|
|
5017
|
+
const registerRequest = Object.assign(Object.assign({}, formData), { recaptchaToken });
|
|
5018
|
+
const userLogin = yield medplum.startNewUser(registerRequest);
|
|
5019
|
+
handleAuthResponse(registerRequest, userLogin);
|
|
5020
|
+
}
|
|
5021
|
+
catch (err) {
|
|
5022
|
+
setOutcome(err);
|
|
5023
|
+
}
|
|
5024
|
+
}) },
|
|
5025
|
+
React__default["default"].createElement("div", { className: "medplum-center" }, props.children),
|
|
5026
|
+
issues && (React__default["default"].createElement("div", { className: "medplum-input-error" }, issues.map((issue) => {
|
|
5027
|
+
var _a, _b;
|
|
5028
|
+
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));
|
|
5029
|
+
}))),
|
|
5030
|
+
googleClientId && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5031
|
+
React__default["default"].createElement("div", { className: "medplum-signin-google-container" },
|
|
5032
|
+
React__default["default"].createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) => __awaiter(this, void 0, void 0, function* () {
|
|
5033
|
+
try {
|
|
5034
|
+
const loginRequest = {
|
|
5035
|
+
googleClientId: response.clientId,
|
|
5036
|
+
googleCredential: response.credential,
|
|
5037
|
+
};
|
|
5038
|
+
const userLogin = yield medplum.startGoogleLogin(loginRequest);
|
|
5039
|
+
const googleClaims = core.parseJWTPayload(loginRequest.googleCredential);
|
|
5040
|
+
const registerRequest = {
|
|
5041
|
+
firstName: googleClaims.given_name,
|
|
5042
|
+
lastName: googleClaims.family_name,
|
|
5043
|
+
email: googleClaims.email,
|
|
5044
|
+
};
|
|
5045
|
+
handleAuthResponse(registerRequest, userLogin);
|
|
5046
|
+
}
|
|
5047
|
+
catch (err) {
|
|
5048
|
+
setOutcome(err);
|
|
5049
|
+
}
|
|
5050
|
+
}) })),
|
|
5051
|
+
React__default["default"].createElement("div", { className: "medplum-signin-separator" }, "or"))),
|
|
5052
|
+
React__default["default"].createElement(FormSection, { title: "First Name", htmlFor: "firstName", outcome: outcome },
|
|
5053
|
+
React__default["default"].createElement(Input, { name: "firstName", type: "text", testid: "firstName", placeholder: "First name", required: true, autoFocus: true, outcome: outcome })),
|
|
5054
|
+
React__default["default"].createElement(FormSection, { title: "Last Name", htmlFor: "lastName", outcome: outcome },
|
|
5055
|
+
React__default["default"].createElement(Input, { name: "lastName", type: "text", testid: "lastName", placeholder: "Last name", required: true, outcome: outcome })),
|
|
5056
|
+
props.type === 'project' && (React__default["default"].createElement(FormSection, { title: "Project Name", htmlFor: "projectName", outcome: outcome },
|
|
5057
|
+
React__default["default"].createElement(Input, { name: "projectName", type: "text", testid: "projectName", placeholder: "My Project", required: true, outcome: outcome }))),
|
|
5058
|
+
React__default["default"].createElement(FormSection, { title: "Email", htmlFor: "email", outcome: outcome },
|
|
5059
|
+
React__default["default"].createElement(Input, { name: "email", type: "email", testid: "email", placeholder: "name@domain.com", required: true, outcome: outcome })),
|
|
5060
|
+
React__default["default"].createElement(FormSection, { title: "Password", htmlFor: "password", outcome: outcome },
|
|
5061
|
+
React__default["default"].createElement(Input, { name: "password", type: "password", testid: "password", autoComplete: "off", required: true, outcome: outcome })),
|
|
5062
|
+
React__default["default"].createElement("div", { className: "medplum-signin-buttons" },
|
|
5063
|
+
React__default["default"].createElement("div", null,
|
|
5064
|
+
React__default["default"].createElement("input", { type: "checkbox", id: "remember", name: "remember", value: "true" }),
|
|
5065
|
+
React__default["default"].createElement("label", { htmlFor: "remember" }, "Remember me")),
|
|
5066
|
+
React__default["default"].createElement("div", null,
|
|
5067
|
+
React__default["default"].createElement(Button, { type: "submit", testid: "submit" }, "Create account"))))));
|
|
5068
|
+
}
|
|
5069
|
+
|
|
4907
5070
|
function StatusBadge(props) {
|
|
4908
5071
|
return React__default["default"].createElement("span", { className: `medplum-status medplum-status-${props.status}` }, props.status);
|
|
4909
5072
|
}
|
|
@@ -5477,62 +5640,6 @@
|
|
|
5477
5640
|
}) }));
|
|
5478
5641
|
}
|
|
5479
5642
|
|
|
5480
|
-
/**
|
|
5481
|
-
* Dynamically creates a script tag for the specified JavaScript file.
|
|
5482
|
-
* @param src The JavaScript file URL.
|
|
5483
|
-
*/
|
|
5484
|
-
function createScriptTag(src, onload) {
|
|
5485
|
-
const head = document.getElementsByTagName('head')[0];
|
|
5486
|
-
const script = document.createElement('script');
|
|
5487
|
-
script.async = true;
|
|
5488
|
-
script.src = src;
|
|
5489
|
-
script.onload = onload || null;
|
|
5490
|
-
head.appendChild(script);
|
|
5491
|
-
}
|
|
5492
|
-
|
|
5493
|
-
function GoogleButton(props) {
|
|
5494
|
-
const medplum = useMedplum();
|
|
5495
|
-
const { handleGoogleCredential } = props;
|
|
5496
|
-
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
5497
|
-
const parentRef = React.useRef(null);
|
|
5498
|
-
const [scriptLoaded, setScriptLoaded] = React.useState(typeof google !== 'undefined');
|
|
5499
|
-
const [initialized, setInitialized] = React.useState(false);
|
|
5500
|
-
const [buttonRendered, setButtonRendered] = React.useState(false);
|
|
5501
|
-
React.useEffect(() => {
|
|
5502
|
-
if (typeof google === 'undefined') {
|
|
5503
|
-
createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));
|
|
5504
|
-
return;
|
|
5505
|
-
}
|
|
5506
|
-
if (!initialized) {
|
|
5507
|
-
google.accounts.id.initialize({
|
|
5508
|
-
client_id: googleClientId,
|
|
5509
|
-
callback: handleGoogleCredential,
|
|
5510
|
-
});
|
|
5511
|
-
setInitialized(true);
|
|
5512
|
-
}
|
|
5513
|
-
if (parentRef.current && !buttonRendered) {
|
|
5514
|
-
google.accounts.id.renderButton(parentRef.current, {});
|
|
5515
|
-
setButtonRendered(true);
|
|
5516
|
-
}
|
|
5517
|
-
}, [medplum, googleClientId, initialized, scriptLoaded, parentRef, buttonRendered, handleGoogleCredential]);
|
|
5518
|
-
if (!googleClientId) {
|
|
5519
|
-
return null;
|
|
5520
|
-
}
|
|
5521
|
-
return React__default["default"].createElement("div", { ref: parentRef });
|
|
5522
|
-
}
|
|
5523
|
-
function getGoogleClientId(clientId) {
|
|
5524
|
-
var _a, _b;
|
|
5525
|
-
if (clientId) {
|
|
5526
|
-
return clientId;
|
|
5527
|
-
}
|
|
5528
|
-
const origin = window.location.protocol + '//' + window.location.host;
|
|
5529
|
-
const authorizedOrigins = (_b = (_a = "http://localhost:3000,http://localhost:6006,https://app.medplum.com,https://docs.medplum.com") === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
|
|
5530
|
-
if (authorizedOrigins.includes(origin)) {
|
|
5531
|
-
return "921088377005-3j1sa10vr6hj86jgmdfh2l53v3mp7lfi.apps.googleusercontent.com";
|
|
5532
|
-
}
|
|
5533
|
-
return undefined;
|
|
5534
|
-
}
|
|
5535
|
-
|
|
5536
5643
|
function SignInForm(props) {
|
|
5537
5644
|
const medplum = useMedplum();
|
|
5538
5645
|
const [login, setLogin] = React.useState(undefined);
|
|
@@ -5574,6 +5681,7 @@
|
|
|
5574
5681
|
}
|
|
5575
5682
|
function AuthenticationForm(props) {
|
|
5576
5683
|
const medplum = useMedplum();
|
|
5684
|
+
const googleClientId = getGoogleClientId(props.googleClientId);
|
|
5577
5685
|
const [outcome, setOutcome] = React.useState();
|
|
5578
5686
|
const issues = getIssuesForExpression(outcome, undefined);
|
|
5579
5687
|
return (React__default["default"].createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => {
|
|
@@ -5594,6 +5702,21 @@
|
|
|
5594
5702
|
var _a, _b;
|
|
5595
5703
|
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));
|
|
5596
5704
|
}))),
|
|
5705
|
+
googleClientId && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5706
|
+
React__default["default"].createElement("div", { className: "medplum-signin-google-container" },
|
|
5707
|
+
React__default["default"].createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) => {
|
|
5708
|
+
medplum
|
|
5709
|
+
.startGoogleLogin({
|
|
5710
|
+
clientId: props.clientId,
|
|
5711
|
+
scope: props.scope,
|
|
5712
|
+
nonce: props.nonce,
|
|
5713
|
+
googleClientId: response.clientId,
|
|
5714
|
+
googleCredential: response.credential,
|
|
5715
|
+
})
|
|
5716
|
+
.then(props.handleAuthResponse)
|
|
5717
|
+
.catch(setOutcome);
|
|
5718
|
+
} })),
|
|
5719
|
+
React__default["default"].createElement("div", { className: "medplum-signin-separator" }, "or"))),
|
|
5597
5720
|
React__default["default"].createElement(FormSection, { title: "Email", htmlFor: "email", outcome: outcome },
|
|
5598
5721
|
React__default["default"].createElement(Input, { name: "email", type: "email", testid: "email", required: true, autoFocus: true, outcome: outcome })),
|
|
5599
5722
|
React__default["default"].createElement(FormSection, { title: "Password", htmlFor: "password", outcome: outcome },
|
|
@@ -5606,20 +5729,7 @@
|
|
|
5606
5729
|
React__default["default"].createElement("input", { type: "checkbox", id: "remember", name: "remember", value: "true" }),
|
|
5607
5730
|
React__default["default"].createElement("label", { htmlFor: "remember" }, "Remember me")),
|
|
5608
5731
|
React__default["default"].createElement("div", null,
|
|
5609
|
-
React__default["default"].createElement(Button, { type: "submit", testid: "submit" }, "Sign in")))
|
|
5610
|
-
React__default["default"].createElement("div", { className: "medplum-signin-google-container" },
|
|
5611
|
-
React__default["default"].createElement(GoogleButton, { googleClientId: props.googleClientId, handleGoogleCredential: (response) => {
|
|
5612
|
-
medplum
|
|
5613
|
-
.startGoogleLogin({
|
|
5614
|
-
clientId: props.clientId,
|
|
5615
|
-
scope: props.scope,
|
|
5616
|
-
nonce: props.nonce,
|
|
5617
|
-
googleClientId: response.clientId,
|
|
5618
|
-
googleCredential: response.credential,
|
|
5619
|
-
})
|
|
5620
|
-
.then(props.handleAuthResponse)
|
|
5621
|
-
.catch(setOutcome);
|
|
5622
|
-
} }))));
|
|
5732
|
+
React__default["default"].createElement(Button, { type: "submit", testid: "submit" }, "Sign in")))));
|
|
5623
5733
|
}
|
|
5624
5734
|
function ProfileForm(props) {
|
|
5625
5735
|
const medplum = useMedplum();
|
|
@@ -5744,6 +5854,7 @@
|
|
|
5744
5854
|
exports.RangeDisplay = RangeDisplay;
|
|
5745
5855
|
exports.RangeInput = RangeInput;
|
|
5746
5856
|
exports.ReferenceInput = ReferenceInput;
|
|
5857
|
+
exports.RegisterForm = RegisterForm;
|
|
5747
5858
|
exports.RequestGroupDisplay = RequestGroupDisplay;
|
|
5748
5859
|
exports.ResourceArrayDisplay = ResourceArrayDisplay;
|
|
5749
5860
|
exports.ResourceArrayInput = ResourceArrayInput;
|
|
@@ -5802,11 +5913,13 @@
|
|
|
5802
5913
|
exports.deleteFilter = deleteFilter;
|
|
5803
5914
|
exports.formatRangeString = formatRangeString;
|
|
5804
5915
|
exports.getOpString = getOpString;
|
|
5916
|
+
exports.getRecaptcha = getRecaptcha;
|
|
5805
5917
|
exports.getSearchOperators = getSearchOperators;
|
|
5806
5918
|
exports.getSortField = getSortField;
|
|
5807
5919
|
exports.getTimeString = getTimeString;
|
|
5808
5920
|
exports.getValueAndType = getValueAndType;
|
|
5809
5921
|
exports.hasFilterOnField = hasFilterOnField;
|
|
5922
|
+
exports.initRecaptcha = initRecaptcha;
|
|
5810
5923
|
exports.isChoiceQuestion = isChoiceQuestion;
|
|
5811
5924
|
exports.isSortDescending = isSortDescending;
|
|
5812
5925
|
exports.movePage = movePage;
|