@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/styles.css
CHANGED
|
@@ -172,6 +172,203 @@ select.medplum-select:disabled {
|
|
|
172
172
|
box-shadow: 0 0 0 2px var(--medplum-blue-200);
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
.medplum-document {
|
|
176
|
+
margin: 20px auto 6px auto;
|
|
177
|
+
padding: 10px;
|
|
178
|
+
clear: both;
|
|
179
|
+
text-align: center;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.medplum-document article {
|
|
183
|
+
background-color: var(--medplum-surface);
|
|
184
|
+
max-width: 900px;
|
|
185
|
+
margin: 8px auto 16px auto;
|
|
186
|
+
padding: 15px 25px;
|
|
187
|
+
text-align: left;
|
|
188
|
+
border: 0.1px solid var(--medplum-gray-300);
|
|
189
|
+
border-radius: 8px;
|
|
190
|
+
box-shadow: 0 1px 3px 0 var(--medplum-shadow);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.medplum-document h1,
|
|
194
|
+
.medplum-document h2,
|
|
195
|
+
.medplum-document h3 {
|
|
196
|
+
margin: 12px 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.medplum-document p,
|
|
200
|
+
.medplum-document li {
|
|
201
|
+
line-height: 175%;
|
|
202
|
+
margin: 8px 0;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@media (max-width: 700px) {
|
|
206
|
+
.medplum-document {
|
|
207
|
+
margin: 10px auto 6px auto;
|
|
208
|
+
padding: 6px;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.medplum-document article {
|
|
212
|
+
padding: 6px 12px;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.medplum-document img,
|
|
217
|
+
.medplum-document video {
|
|
218
|
+
width: 100%;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.medplum-document textarea {
|
|
222
|
+
margin: 0;
|
|
223
|
+
min-height: 100px;
|
|
224
|
+
width: 100%;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
fieldset.medplum-form-section {
|
|
228
|
+
border: 0;
|
|
229
|
+
margin: 6px 0 12px 0;
|
|
230
|
+
padding: 2px 0 8px 0;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
fieldset.medplum-form-section > label,
|
|
234
|
+
fieldset.medplum-form-section > legend {
|
|
235
|
+
display: block;
|
|
236
|
+
margin: 1px 0 3px 0;
|
|
237
|
+
line-height: 1.75;
|
|
238
|
+
font-weight: 500;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
fieldset.medplum-form-section > p {
|
|
242
|
+
margin: 1px 0 4px 0;
|
|
243
|
+
padding: 1px 0 4px 0;
|
|
244
|
+
line-height: 1.75;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.medplum-signin-buttons {
|
|
248
|
+
display: flex;
|
|
249
|
+
justify-content: space-between;
|
|
250
|
+
line-height: 32px;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.medplum-signin-buttons > div {
|
|
254
|
+
display: flex;
|
|
255
|
+
align-items: center;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.medplum-signin-buttons a {
|
|
259
|
+
font-size: 12px;
|
|
260
|
+
margin-right: 16px;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.medplum-signin-buttons label {
|
|
264
|
+
font-size: 12px;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.medplum-signin-google-container {
|
|
268
|
+
padding: 20px 0 10px 0;
|
|
269
|
+
margin: 20px 0 10px 0;
|
|
270
|
+
height: 70px;
|
|
271
|
+
text-align: center;
|
|
272
|
+
display: flex;
|
|
273
|
+
align-items: center;
|
|
274
|
+
justify-content: center;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.medplum-signin-separator {
|
|
278
|
+
padding: 12px 0;
|
|
279
|
+
margin: 12px 0;
|
|
280
|
+
overflow: hidden;
|
|
281
|
+
text-align: center;
|
|
282
|
+
font-size: var(--medplum-font-small);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.medplum-signin-separator::before,
|
|
286
|
+
.medplum-signin-separator::after {
|
|
287
|
+
background-color: var(--medplum-gray-400);
|
|
288
|
+
content: '';
|
|
289
|
+
display: inline-block;
|
|
290
|
+
height: 0.1px;
|
|
291
|
+
position: relative;
|
|
292
|
+
vertical-align: middle;
|
|
293
|
+
width: 50%;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.medplum-signin-separator::before {
|
|
297
|
+
right: 0.5em;
|
|
298
|
+
margin-left: -50%;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.medplum-signin-separator::after {
|
|
302
|
+
left: 0.5em;
|
|
303
|
+
margin-right: -50%;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.medplum-left {
|
|
307
|
+
text-align: left;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.medplum-center {
|
|
311
|
+
text-align: center;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.medplum-right {
|
|
315
|
+
text-align: right;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.medplum-avatar {
|
|
319
|
+
padding: 0;
|
|
320
|
+
width: 32px;
|
|
321
|
+
height: 32px;
|
|
322
|
+
min-width: 32px;
|
|
323
|
+
min-height: 32px;
|
|
324
|
+
line-height: 32px;
|
|
325
|
+
user-select: none;
|
|
326
|
+
border-radius: 50%;
|
|
327
|
+
overflow: hidden;
|
|
328
|
+
text-align: center;
|
|
329
|
+
color: var(--medplum-surface);
|
|
330
|
+
background-color: var(--medplum-gray-500);
|
|
331
|
+
font-size: 18px;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.medplum-avatar img {
|
|
335
|
+
width: 100%;
|
|
336
|
+
height: 100%;
|
|
337
|
+
object-fit: cover;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.medplum-avatar.xsmall {
|
|
341
|
+
width: 20px;
|
|
342
|
+
height: 20px;
|
|
343
|
+
min-width: 20px;
|
|
344
|
+
min-height: 20px;
|
|
345
|
+
line-height: 20px;
|
|
346
|
+
font-size: 10px;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.medplum-avatar.small {
|
|
350
|
+
width: 24px;
|
|
351
|
+
height: 24px;
|
|
352
|
+
min-width: 24px;
|
|
353
|
+
min-height: 24px;
|
|
354
|
+
line-height: 24px;
|
|
355
|
+
font-size: 11px;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.medplum-avatar.large {
|
|
359
|
+
width: 56px;
|
|
360
|
+
height: 56px;
|
|
361
|
+
min-width: 56px;
|
|
362
|
+
min-height: 56px;
|
|
363
|
+
line-height: 56px;
|
|
364
|
+
font-size: 28px;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.medplum-avatar > a {
|
|
368
|
+
color: var(--medplum-surface);
|
|
369
|
+
text-decoration: none;
|
|
370
|
+
}
|
|
371
|
+
|
|
175
372
|
.medplum-autocomplete-container {
|
|
176
373
|
border: 0.1px solid var(--medplum-gray-300);
|
|
177
374
|
border-radius: 3px;
|
|
@@ -306,60 +503,6 @@ select.medplum-select:disabled {
|
|
|
306
503
|
color: var(--medplum-gray-500);
|
|
307
504
|
}
|
|
308
505
|
|
|
309
|
-
.medplum-avatar {
|
|
310
|
-
padding: 0;
|
|
311
|
-
width: 32px;
|
|
312
|
-
height: 32px;
|
|
313
|
-
min-width: 32px;
|
|
314
|
-
min-height: 32px;
|
|
315
|
-
line-height: 32px;
|
|
316
|
-
user-select: none;
|
|
317
|
-
border-radius: 50%;
|
|
318
|
-
overflow: hidden;
|
|
319
|
-
text-align: center;
|
|
320
|
-
color: var(--medplum-surface);
|
|
321
|
-
background-color: var(--medplum-gray-500);
|
|
322
|
-
font-size: 18px;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
.medplum-avatar img {
|
|
326
|
-
width: 100%;
|
|
327
|
-
height: 100%;
|
|
328
|
-
object-fit: cover;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
.medplum-avatar.xsmall {
|
|
332
|
-
width: 20px;
|
|
333
|
-
height: 20px;
|
|
334
|
-
min-width: 20px;
|
|
335
|
-
min-height: 20px;
|
|
336
|
-
line-height: 20px;
|
|
337
|
-
font-size: 10px;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
.medplum-avatar.small {
|
|
341
|
-
width: 24px;
|
|
342
|
-
height: 24px;
|
|
343
|
-
min-width: 24px;
|
|
344
|
-
min-height: 24px;
|
|
345
|
-
line-height: 24px;
|
|
346
|
-
font-size: 11px;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
.medplum-avatar.large {
|
|
350
|
-
width: 56px;
|
|
351
|
-
height: 56px;
|
|
352
|
-
min-width: 56px;
|
|
353
|
-
min-height: 56px;
|
|
354
|
-
line-height: 56px;
|
|
355
|
-
font-size: 28px;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
.medplum-avatar > a {
|
|
359
|
-
color: var(--medplum-surface);
|
|
360
|
-
text-decoration: none;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
506
|
.medplum-checkbox-form-section {
|
|
364
507
|
display: flex;
|
|
365
508
|
justify-content: space-between;
|
|
@@ -378,26 +521,6 @@ select.medplum-select:disabled {
|
|
|
378
521
|
font-weight: 500;
|
|
379
522
|
}
|
|
380
523
|
|
|
381
|
-
fieldset.medplum-form-section {
|
|
382
|
-
border: 0;
|
|
383
|
-
margin: 6px 0 12px 0;
|
|
384
|
-
padding: 2px 0 8px 0;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
fieldset.medplum-form-section > label,
|
|
388
|
-
fieldset.medplum-form-section > legend {
|
|
389
|
-
display: block;
|
|
390
|
-
margin: 1px 0 3px 0;
|
|
391
|
-
line-height: 1.75;
|
|
392
|
-
font-weight: 500;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
fieldset.medplum-form-section > p {
|
|
396
|
-
margin: 1px 0 4px 0;
|
|
397
|
-
padding: 1px 0 4px 0;
|
|
398
|
-
line-height: 1.75;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
524
|
dl.medplum-description-list {
|
|
402
525
|
display: grid;
|
|
403
526
|
grid-template-columns: 30% 70%;
|
|
@@ -816,58 +939,6 @@ table.medplum-diff-table td {
|
|
|
816
939
|
margin-right: 4px;
|
|
817
940
|
}
|
|
818
941
|
|
|
819
|
-
.medplum-document {
|
|
820
|
-
margin: 20px auto 6px auto;
|
|
821
|
-
padding: 10px;
|
|
822
|
-
clear: both;
|
|
823
|
-
text-align: center;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
.medplum-document article {
|
|
827
|
-
background-color: var(--medplum-surface);
|
|
828
|
-
max-width: 900px;
|
|
829
|
-
margin: 8px auto 16px auto;
|
|
830
|
-
padding: 15px 25px;
|
|
831
|
-
text-align: left;
|
|
832
|
-
border: 0.1px solid var(--medplum-gray-300);
|
|
833
|
-
border-radius: 8px;
|
|
834
|
-
box-shadow: 0 1px 3px 0 var(--medplum-shadow);
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
.medplum-document h1,
|
|
838
|
-
.medplum-document h2,
|
|
839
|
-
.medplum-document h3 {
|
|
840
|
-
margin: 12px 0;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
.medplum-document p,
|
|
844
|
-
.medplum-document li {
|
|
845
|
-
line-height: 175%;
|
|
846
|
-
margin: 8px 0 16px 0;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
@media (max-width: 700px) {
|
|
850
|
-
.medplum-document {
|
|
851
|
-
margin: 10px auto 6px auto;
|
|
852
|
-
padding: 6px;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
.medplum-document article {
|
|
856
|
-
padding: 6px 12px;
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
.medplum-document img,
|
|
861
|
-
.medplum-document video {
|
|
862
|
-
width: 100%;
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
.medplum-document textarea {
|
|
866
|
-
margin: 0;
|
|
867
|
-
min-height: 100px;
|
|
868
|
-
width: 100%;
|
|
869
|
-
}
|
|
870
|
-
|
|
871
942
|
.medplum-search-control {
|
|
872
943
|
max-width: 100%;
|
|
873
944
|
overflow: auto;
|
|
@@ -1374,77 +1445,6 @@ div.medplum-nav-menu-container {
|
|
|
1374
1445
|
color: var(--medplum-blue-500);
|
|
1375
1446
|
}
|
|
1376
1447
|
|
|
1377
|
-
.medplum-signin-buttons {
|
|
1378
|
-
display: flex;
|
|
1379
|
-
justify-content: space-between;
|
|
1380
|
-
line-height: 32px;
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
|
-
.medplum-signin-buttons > div {
|
|
1384
|
-
display: flex;
|
|
1385
|
-
align-items: center;
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
.medplum-signin-buttons a {
|
|
1389
|
-
font-size: 12px;
|
|
1390
|
-
margin-right: 16px;
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
|
-
.medplum-signin-buttons label {
|
|
1394
|
-
font-size: 12px;
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
.medplum-signin-google-container {
|
|
1398
|
-
padding: 20px 0 10px 0;
|
|
1399
|
-
margin: 20px 0 10px 0;
|
|
1400
|
-
height: 70px;
|
|
1401
|
-
text-align: center;
|
|
1402
|
-
display: flex;
|
|
1403
|
-
align-items: center;
|
|
1404
|
-
justify-content: center;
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
.medplum-signin-separator {
|
|
1408
|
-
padding: 12px 0;
|
|
1409
|
-
margin: 12px 0;
|
|
1410
|
-
overflow: hidden;
|
|
1411
|
-
text-align: center;
|
|
1412
|
-
font-size: var(--medplum-font-small);
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
.medplum-signin-separator::before,
|
|
1416
|
-
.medplum-signin-separator::after {
|
|
1417
|
-
background-color: var(--medplum-gray-400);
|
|
1418
|
-
content: '';
|
|
1419
|
-
display: inline-block;
|
|
1420
|
-
height: 0.1px;
|
|
1421
|
-
position: relative;
|
|
1422
|
-
vertical-align: middle;
|
|
1423
|
-
width: 50%;
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1426
|
-
.medplum-signin-separator::before {
|
|
1427
|
-
right: 0.5em;
|
|
1428
|
-
margin-left: -50%;
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
|
-
.medplum-signin-separator::after {
|
|
1432
|
-
left: 0.5em;
|
|
1433
|
-
margin-right: -50%;
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
.medplum-left {
|
|
1437
|
-
text-align: left;
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
.medplum-center {
|
|
1441
|
-
text-align: center;
|
|
1442
|
-
}
|
|
1443
|
-
|
|
1444
|
-
.medplum-right {
|
|
1445
|
-
text-align: right;
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
1448
|
.medplum-status {
|
|
1449
1449
|
padding: 1px 6px;
|
|
1450
1450
|
font-size: 80%;
|
package/dist/esm/Autocomplete.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Autocomplete.js","sources":["../../src/Autocomplete.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport './Autocomplete.css';\nimport { killEvent } from './utils/dom';\n\nexport interface AutocompleteProps<T> {\n name: string;\n multiple?: boolean;\n autofocus?: boolean;\n defaultValue?: T[];\n className?: string;\n placeholder?: string;\n loadOnFocus?: boolean;\n loadOptions: (input: string, signal: AbortSignal) => Promise<T[]>;\n buildUnstructured?: (input: string) => T;\n getId: (item: T) => string;\n getIcon?: (item: T) => JSX.Element;\n getDisplay: (item: T) => JSX.Element;\n getHelpText?: (item: T) => string | undefined;\n onChange?: (values: T[]) => void;\n onCreateNew?: () => void;\n}\n\nexport function Autocomplete<T>(props: AutocompleteProps<T>): JSX.Element {\n const inputRef = useRef<HTMLInputElement>(null);\n const [focused, setFocused] = useState(false);\n const [lastValue, setLastValue] = useState<string | undefined>(undefined);\n const [timer, setTimer] = useState<number>();\n const [dropDownVisible, setDropDownVisible] = useState(false);\n const [values, setValues] = useState(props.defaultValue ?? []);\n const [options, setOptions] = useState<T[]>([]);\n const [selectedIndex, setSelectedIndex] = useState(-1);\n const [abortController, setAbortController] = useState<AbortController>();\n const [autoSubmit, setAutoSubmit] = useState<boolean>();\n\n const lastValueRef = useRef<string>();\n lastValueRef.current = lastValue;\n\n const timerRef = useRef<number>();\n timerRef.current = timer;\n\n const abortControllerRef = useRef<AbortController>();\n abortControllerRef.current = abortController;\n\n const autoSubmitRef = useRef<boolean>();\n autoSubmitRef.current = autoSubmit;\n\n useEffect(() => {\n return () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n useEffect(() => {\n setValues(props.defaultValue ?? []);\n }, [props.defaultValue]);\n\n function setValuesWrapper(newValues: T[]): void {\n setValues(newValues);\n if (props.onChange) {\n props.onChange(newValues);\n }\n }\n\n /**\n * Adds an option to the list of selected options.\n * @param option The option.\n */\n function addOption(option: T): void {\n const inputElement = inputRef.current as HTMLInputElement;\n inputElement.value = '';\n\n const newValues = props.multiple ? [...values, option] : [option];\n setFocused(true);\n setDropDownVisible(false);\n setLastValue('');\n setOptions([]);\n setSelectedIndex(-1);\n setValuesWrapper(newValues);\n }\n\n function handleClick(): void {\n inputRef.current?.focus();\n }\n\n function handleFocus(): void {\n setFocused(true);\n if (props.loadOnFocus) {\n handleInput();\n }\n }\n\n function handleBlur(): void {\n setFocused(false);\n dismissOnDelay();\n }\n\n /**\n * Handles an input event.\n * Clears existing timers.\n * Schedules a timer to execute the search after a short delay.\n */\n function handleInput(): void {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n setAbortController(undefined);\n }\n\n if (timerRef.current !== undefined) {\n window.clearTimeout(timerRef.current);\n }\n\n const newTimer = window.setTimeout(() => handleTimer(), 100);\n setTimer(newTimer);\n }\n\n function handleKeyDown(e: React.KeyboardEvent): void {\n switch (e.key) {\n case 'Enter':\n case 'Tab':\n handleSelectKey(e);\n break;\n\n case 'ArrowUp':\n moveSelection(-1);\n killEvent(e);\n break;\n\n case 'ArrowDown':\n moveSelection(1);\n killEvent(e);\n break;\n\n case 'Backspace':\n handleBackspaceKey(e);\n break;\n\n case ',':\n case ';':\n handleSeparatorKey(e);\n }\n }\n\n /**\n * Handles the \"enter\" or \"tab\" keys. The enter key logic is:\n * Try to add an option with tryAddOption. On success, cancel event.\n * Otherwise, let the browser handle the enter key normally.\n *\n * @param e The key down event.\n */\n function handleSelectKey(e: React.KeyboardEvent): void {\n if (!timerRef.current && !abortControllerRef.current && tryAddOption()) {\n killEvent(e);\n inputRef.current?.focus();\n } else {\n // The user pressed enter, but we don't have results yet.\n // We need to wait for the results to come in.\n setAutoSubmit(true);\n }\n }\n\n /**\n * Handles the \"backspace\" key. The backspace key logic is:\n * If the input is empty and there is at least one item, delete the last item.\n * Otherwise, let the browser handle the backspace key normally.\n *\n * @param e The key down event.\n */\n function handleBackspaceKey(e: React.KeyboardEvent): void {\n if (inputRef.current?.value) {\n // If there is still text in the input,\n // then handle backspace as normal.\n return;\n }\n\n if (values.length > 0) {\n // If there are selected items,\n // then delete the last item.\n killEvent(e);\n setValuesWrapper(values.slice(0, values.length - 1));\n }\n }\n\n /**\n * Handles a \"separator\" key (comma, semicolon, others?).\n *\n * The separator key logic is:\n * If the drop down is visible and something is selected, choose that.\n * If the drop down is visible but nothing is selected, choose the first.\n * If there is content in the input, use that as a \"gray\" option.\n * Otherwise, ignore.\n *\n * @param e The key down event.\n */\n function handleSeparatorKey(e: React.KeyboardEvent): void {\n tryAddOption();\n killEvent(e);\n inputRef.current?.focus();\n }\n\n /**\n * Tries to capture the existing input as an option.\n *\n * @return True if captured an option; false otherwise.\n */\n function tryAddOption(): boolean {\n let option: T | undefined;\n\n if (selectedIndex >= 0 && selectedIndex < options.length) {\n // Currently highlighted row\n option = options[selectedIndex];\n } else if (selectedIndex === -1 && options.length > 0) {\n // Default to first row\n option = options[0];\n } else if (props.buildUnstructured && inputRef.current?.value) {\n // Build semi-structured item\n option = props.buildUnstructured(inputRef.current.value);\n }\n\n if (!option) {\n return false;\n }\n\n addOption(option);\n return true;\n }\n\n /**\n * Handles a timer tick event.\n * If the contents of the input have changed, sends xhr to the server\n * for updated contents.\n */\n function handleTimer(): void {\n setTimer(undefined);\n\n const value = inputRef.current?.value?.trim() || '';\n if (value === lastValueRef.current) {\n // Nothing has changed, move on\n return;\n }\n\n setLastValue(value);\n\n const newAbortController = new AbortController();\n setAbortController(newAbortController);\n\n props\n .loadOptions(value, newAbortController.signal)\n .then((newOptions: T[]) => {\n if (!newAbortController.signal.aborted) {\n setDropDownVisible(newOptions.length > 0);\n setOptions(newOptions);\n setAbortController(undefined);\n if (autoSubmitRef.current) {\n addOption(newOptions[0]);\n setAutoSubmit(false);\n }\n }\n })\n .catch(console.log);\n }\n\n /**\n * Moves the selected row.\n * @param delta The amount to move the selection, up is negative.\n */\n function moveSelection(delta: number): void {\n let index = selectedIndex + delta;\n\n if (index < 0) {\n index = 0;\n } else if (index >= options.length) {\n index = options.length - 1;\n }\n\n setSelectedIndex(index);\n }\n\n /**\n * Handles a hover event.\n * @param _e The mouse event.\n * @param index The drop down option index.\n */\n function handleDropDownHover(_e: React.MouseEvent, index: number): void {\n setSelectedIndex(index);\n }\n\n /**\n * Handles a click event.\n * @param e The mouse event.\n * @param option The drop down option.\n */\n function handleDropDownClick(e: React.MouseEvent, option: T): void {\n killEvent(e);\n addOption(option);\n }\n\n /**\n * Dismisses the drop down menu after a slight delay.\n */\n function dismissOnDelay(): void {\n window.setTimeout(() => {\n setDropDownVisible(false);\n }, 200);\n }\n\n const baseClassName = props.className ?? 'medplum-autocomplete-container';\n\n return (\n <div\n data-testid=\"autocomplete\"\n className={baseClassName + (focused ? ' focused' : '')}\n onClick={() => handleClick()}\n >\n <ul onClick={() => handleClick()}>\n {values.map((value) => (\n <li key={props.getId(value)} data-testid=\"selected\" className=\"medplum-autocomplete-item choice\">\n {props.getDisplay(value)}\n </li>\n ))}\n <li className=\"medplum-autocomplete-item\">\n <input\n type=\"text\"\n autoFocus={props.autofocus}\n placeholder={values.length === 0 ? props.placeholder : undefined}\n autoComplete=\"off\"\n autoCapitalize=\"off\"\n spellCheck=\"true\"\n onFocus={() => handleFocus()}\n onBlur={() => handleBlur()}\n onChange={() => handleInput()}\n onInput={() => handleInput()}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e)}\n ref={inputRef}\n data-testid=\"input-element\"\n />\n </li>\n </ul>\n {dropDownVisible && (\n <div className=\"medplum-autocomplete\" data-testid=\"dropdown\">\n {options.map((option, index) => (\n <div\n key={props.getId(option)}\n className={\n index === selectedIndex\n ? 'medplum-autocomplete-row medplum-autocomplete-active'\n : 'medplum-autocomplete-row'\n }\n onMouseOver={(e) => handleDropDownHover(e, index)}\n onClick={(e) => handleDropDownClick(e, option)}\n >\n {props.getIcon && <div className=\"medplum-autocomplete-icon\">{props.getIcon(option)}</div>}\n <div className=\"medplum-autocomplete-label\">\n {props.getDisplay(option)}\n {props.getHelpText && <div className=\"medplum-autocomplete-help-text\">{props.getHelpText(option)}</div>}\n </div>\n </div>\n ))}\n {props.onCreateNew && (\n <div className=\"medplum-autocomplete-row\" onClick={props.onCreateNew}>\n <div className=\"medplum-autocomplete-label\">Create new...</div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Autocomplete.js","sources":["../../src/Autocomplete.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport { killEvent } from './utils/dom';\nimport './Autocomplete.css';\n\nexport interface AutocompleteProps<T> {\n name: string;\n multiple?: boolean;\n autofocus?: boolean;\n defaultValue?: T[];\n className?: string;\n placeholder?: string;\n loadOnFocus?: boolean;\n loadOptions: (input: string, signal: AbortSignal) => Promise<T[]>;\n buildUnstructured?: (input: string) => T;\n getId: (item: T) => string;\n getIcon?: (item: T) => JSX.Element;\n getDisplay: (item: T) => JSX.Element;\n getHelpText?: (item: T) => string | undefined;\n onChange?: (values: T[]) => void;\n onCreateNew?: () => void;\n}\n\nexport function Autocomplete<T>(props: AutocompleteProps<T>): JSX.Element {\n const inputRef = useRef<HTMLInputElement>(null);\n const [focused, setFocused] = useState(false);\n const [lastValue, setLastValue] = useState<string | undefined>(undefined);\n const [timer, setTimer] = useState<number>();\n const [dropDownVisible, setDropDownVisible] = useState(false);\n const [values, setValues] = useState(props.defaultValue ?? []);\n const [options, setOptions] = useState<T[]>([]);\n const [selectedIndex, setSelectedIndex] = useState(-1);\n const [abortController, setAbortController] = useState<AbortController>();\n const [autoSubmit, setAutoSubmit] = useState<boolean>();\n\n const lastValueRef = useRef<string>();\n lastValueRef.current = lastValue;\n\n const timerRef = useRef<number>();\n timerRef.current = timer;\n\n const abortControllerRef = useRef<AbortController>();\n abortControllerRef.current = abortController;\n\n const autoSubmitRef = useRef<boolean>();\n autoSubmitRef.current = autoSubmit;\n\n useEffect(() => {\n return () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n useEffect(() => {\n setValues(props.defaultValue ?? []);\n }, [props.defaultValue]);\n\n function setValuesWrapper(newValues: T[]): void {\n setValues(newValues);\n if (props.onChange) {\n props.onChange(newValues);\n }\n }\n\n /**\n * Adds an option to the list of selected options.\n * @param option The option.\n */\n function addOption(option: T): void {\n const inputElement = inputRef.current as HTMLInputElement;\n inputElement.value = '';\n\n const newValues = props.multiple ? [...values, option] : [option];\n setFocused(true);\n setDropDownVisible(false);\n setLastValue('');\n setOptions([]);\n setSelectedIndex(-1);\n setValuesWrapper(newValues);\n }\n\n function handleClick(): void {\n inputRef.current?.focus();\n }\n\n function handleFocus(): void {\n setFocused(true);\n if (props.loadOnFocus) {\n handleInput();\n }\n }\n\n function handleBlur(): void {\n tryAddOption();\n setFocused(false);\n dismissOnDelay();\n }\n\n /**\n * Handles an input event.\n * Clears existing timers.\n * Schedules a timer to execute the search after a short delay.\n */\n function handleInput(): void {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n setAbortController(undefined);\n }\n\n if (timerRef.current !== undefined) {\n window.clearTimeout(timerRef.current);\n }\n\n const newTimer = window.setTimeout(() => handleTimer(), 100);\n setTimer(newTimer);\n }\n\n function handleKeyDown(e: React.KeyboardEvent): void {\n switch (e.key) {\n case 'Enter':\n case 'Tab':\n handleSelectKey(e);\n break;\n\n case 'ArrowUp':\n moveSelection(-1);\n killEvent(e);\n break;\n\n case 'ArrowDown':\n moveSelection(1);\n killEvent(e);\n break;\n\n case 'Backspace':\n handleBackspaceKey(e);\n break;\n\n case ',':\n case ';':\n handleSeparatorKey(e);\n }\n }\n\n /**\n * Handles the \"enter\" or \"tab\" keys. The enter key logic is:\n * Try to add an option with tryAddOption. On success, cancel event.\n * Otherwise, let the browser handle the enter key normally.\n *\n * @param e The key down event.\n */\n function handleSelectKey(e: React.KeyboardEvent): void {\n if (!timerRef.current && !abortControllerRef.current && tryAddOption()) {\n killEvent(e);\n inputRef.current?.focus();\n } else {\n // The user pressed enter, but we don't have results yet.\n // We need to wait for the results to come in.\n setAutoSubmit(true);\n }\n }\n\n /**\n * Handles the \"backspace\" key. The backspace key logic is:\n * If the input is empty and there is at least one item, delete the last item.\n * Otherwise, let the browser handle the backspace key normally.\n *\n * @param e The key down event.\n */\n function handleBackspaceKey(e: React.KeyboardEvent): void {\n if (inputRef.current?.value) {\n // If there is still text in the input,\n // then handle backspace as normal.\n return;\n }\n\n if (values.length > 0) {\n // If there are selected items,\n // then delete the last item.\n killEvent(e);\n setValuesWrapper(values.slice(0, values.length - 1));\n }\n }\n\n /**\n * Handles a \"separator\" key (comma, semicolon, others?).\n *\n * The separator key logic is:\n * If the drop down is visible and something is selected, choose that.\n * If the drop down is visible but nothing is selected, choose the first.\n * If there is content in the input, use that as a \"gray\" option.\n * Otherwise, ignore.\n *\n * @param e The key down event.\n */\n function handleSeparatorKey(e: React.KeyboardEvent): void {\n tryAddOption();\n killEvent(e);\n inputRef.current?.focus();\n }\n\n /**\n * Tries to capture the existing input as an option.\n *\n * @return True if captured an option; false otherwise.\n */\n function tryAddOption(): boolean {\n let option: T | undefined;\n\n if (selectedIndex >= 0 && selectedIndex < options.length) {\n // Currently highlighted row\n option = options[selectedIndex];\n } else if (selectedIndex === -1 && options.length > 0) {\n // Default to first row\n option = options[0];\n } else if (props.buildUnstructured && inputRef.current?.value) {\n // Build semi-structured item\n option = props.buildUnstructured(inputRef.current.value);\n }\n\n if (!option) {\n return false;\n }\n\n addOption(option);\n return true;\n }\n\n /**\n * Handles a timer tick event.\n * If the contents of the input have changed, sends xhr to the server\n * for updated contents.\n */\n function handleTimer(): void {\n setTimer(undefined);\n\n const value = inputRef.current?.value?.trim() || '';\n if (value === lastValueRef.current) {\n // Nothing has changed, move on\n return;\n }\n\n setLastValue(value);\n\n const newAbortController = new AbortController();\n setAbortController(newAbortController);\n\n props\n .loadOptions(value, newAbortController.signal)\n .then((newOptions: T[]) => {\n if (!newAbortController.signal.aborted) {\n setDropDownVisible(newOptions.length > 0);\n setOptions(newOptions);\n setAbortController(undefined);\n if (autoSubmitRef.current) {\n addOption(newOptions[0]);\n setAutoSubmit(false);\n }\n }\n })\n .catch(console.log);\n }\n\n /**\n * Moves the selected row.\n * @param delta The amount to move the selection, up is negative.\n */\n function moveSelection(delta: number): void {\n let index = selectedIndex + delta;\n\n if (index < 0) {\n index = 0;\n } else if (index >= options.length) {\n index = options.length - 1;\n }\n\n setSelectedIndex(index);\n }\n\n /**\n * Handles a hover event.\n * @param _e The mouse event.\n * @param index The drop down option index.\n */\n function handleDropDownHover(_e: React.MouseEvent, index: number): void {\n setSelectedIndex(index);\n }\n\n /**\n * Handles a click event.\n * @param e The mouse event.\n * @param option The drop down option.\n */\n function handleDropDownClick(e: React.MouseEvent, option: T): void {\n killEvent(e);\n addOption(option);\n }\n\n /**\n * Dismisses the drop down menu after a slight delay.\n */\n function dismissOnDelay(): void {\n window.setTimeout(() => {\n setDropDownVisible(false);\n }, 200);\n }\n\n const baseClassName = props.className ?? 'medplum-autocomplete-container';\n\n return (\n <div\n data-testid=\"autocomplete\"\n className={baseClassName + (focused ? ' focused' : '')}\n onClick={() => handleClick()}\n >\n <ul onClick={() => handleClick()}>\n {values.map((value) => (\n <li key={props.getId(value)} data-testid=\"selected\" className=\"medplum-autocomplete-item choice\">\n {props.getDisplay(value)}\n </li>\n ))}\n <li className=\"medplum-autocomplete-item\">\n <input\n type=\"text\"\n autoFocus={props.autofocus}\n placeholder={values.length === 0 ? props.placeholder : undefined}\n autoComplete=\"off\"\n autoCapitalize=\"off\"\n spellCheck=\"true\"\n onFocus={() => handleFocus()}\n onBlur={() => handleBlur()}\n onChange={() => handleInput()}\n onInput={() => handleInput()}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e)}\n ref={inputRef}\n data-testid=\"input-element\"\n />\n </li>\n </ul>\n {dropDownVisible && (\n <div className=\"medplum-autocomplete\" data-testid=\"dropdown\">\n {options.map((option, index) => (\n <div\n key={props.getId(option)}\n className={\n index === selectedIndex\n ? 'medplum-autocomplete-row medplum-autocomplete-active'\n : 'medplum-autocomplete-row'\n }\n onMouseOver={(e) => handleDropDownHover(e, index)}\n onClick={(e) => handleDropDownClick(e, option)}\n >\n {props.getIcon && <div className=\"medplum-autocomplete-icon\">{props.getIcon(option)}</div>}\n <div className=\"medplum-autocomplete-label\">\n {props.getDisplay(option)}\n {props.getHelpText && <div className=\"medplum-autocomplete-help-text\">{props.getHelpText(option)}</div>}\n </div>\n </div>\n ))}\n {props.onCreateNew && (\n <div className=\"medplum-autocomplete-row\" onClick={props.onCreateNew}>\n <div className=\"medplum-autocomplete-label\">Create new...</div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
package/dist/esm/CodeInput.js
CHANGED
|
@@ -17,7 +17,7 @@ function CodeInput(props) {
|
|
|
17
17
|
contains.forEach((e) => (cachedDisplayValues[e.code] = e.display));
|
|
18
18
|
return contains.map((e) => e.code);
|
|
19
19
|
});
|
|
20
|
-
}, buildUnstructured: (str) => str, getId: (item) => item, getDisplay: (item) => React.createElement(React.Fragment, null, cachedDisplayValues[item] || item), name: props.name, defaultValue: defaultValue, onChange: (values) => {
|
|
20
|
+
}, buildUnstructured: (str) => str, getId: (item) => item, getDisplay: (item) => React.createElement(React.Fragment, null, cachedDisplayValues[item] || item), name: props.name, defaultValue: defaultValue, loadOnFocus: true, onChange: (values) => {
|
|
21
21
|
if (props.onChange) {
|
|
22
22
|
props.onChange(values[0]);
|
|
23
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeInput.js","sources":["../../src/CodeInput.tsx"],"sourcesContent":["import { ElementDefinition, ValueSet, ValueSetExpansion, ValueSetExpansionContains } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Autocomplete } from './Autocomplete';\nimport { useMedplum } from './MedplumProvider';\n\nexport interface CodeInputProps {\n property: ElementDefinition;\n name: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n}\n\nconst cachedDisplayValues: Record<string, string> = {};\n\nexport function CodeInput(props: CodeInputProps): JSX.Element {\n const medplum = useMedplum();\n\n let defaultValue = undefined;\n if (props.defaultValue) {\n defaultValue = [props.defaultValue];\n }\n\n return (\n <Autocomplete\n loadOptions={(input: string): Promise<string[]> => {\n const system = props.property.binding?.valueSet as string;\n return medplum.searchValueSet(system, input).then((valueSet: ValueSet) => {\n const contains = (valueSet.expansion as ValueSetExpansion).contains as ValueSetExpansionContains[];\n contains.forEach((e) => (cachedDisplayValues[e.code as string] = e.display as string));\n return contains.map((e) => e.code as string);\n });\n }}\n buildUnstructured={(str: string) => str}\n getId={(item: string) => item}\n getDisplay={(item: string) => <>{cachedDisplayValues[item] || item}</>}\n name={props.name}\n defaultValue={defaultValue}\n onChange={(values: string[]) => {\n if (props.onChange) {\n props.onChange(values[0]);\n }\n }}\n />\n );\n}\n"],"names":[],"mappings":";;;;AAYA,MAAM,mBAAmB,GAA2B,EAAE,CAAC;AAEjD,SAAU,SAAS,CAAC,KAAqB,EAAA;AAC7C,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,YAAY,GAAG,SAAS,CAAC;IAC7B,IAAI,KAAK,CAAC,YAAY,EAAE;AACtB,QAAA,YAAY,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACrC,KAAA;IAED,QACE,oBAAC,YAAY,EAAA,EACX,WAAW,EAAE,CAAC,KAAa,KAAuB;;YAChD,MAAM,MAAM,GAAG,CAAA,EAAA,GAAA,KAAK,CAAC,QAAQ,CAAC,OAAO,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,QAAkB,CAAC;AAC1D,YAAA,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,QAAkB,KAAI;AACvE,gBAAA,MAAM,QAAQ,GAAI,QAAQ,CAAC,SAA+B,CAAC,QAAuC,CAAC;gBACnG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,mBAAmB,CAAC,CAAC,CAAC,IAAc,CAAC,GAAG,CAAC,CAAC,OAAiB,CAAC,CAAC,CAAC;AACvF,gBAAA,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAc,CAAC,CAAC;AAC/C,aAAC,CAAC,CAAC;SACJ,EACD,iBAAiB,EAAE,CAAC,GAAW,KAAK,GAAG,EACvC,KAAK,EAAE,CAAC,IAAY,KAAK,IAAI,EAC7B,UAAU,EAAE,CAAC,IAAY,KAAK,
|
|
1
|
+
{"version":3,"file":"CodeInput.js","sources":["../../src/CodeInput.tsx"],"sourcesContent":["import { ElementDefinition, ValueSet, ValueSetExpansion, ValueSetExpansionContains } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Autocomplete } from './Autocomplete';\nimport { useMedplum } from './MedplumProvider';\n\nexport interface CodeInputProps {\n property: ElementDefinition;\n name: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n}\n\nconst cachedDisplayValues: Record<string, string> = {};\n\nexport function CodeInput(props: CodeInputProps): JSX.Element {\n const medplum = useMedplum();\n\n let defaultValue = undefined;\n if (props.defaultValue) {\n defaultValue = [props.defaultValue];\n }\n\n return (\n <Autocomplete\n loadOptions={(input: string): Promise<string[]> => {\n const system = props.property.binding?.valueSet as string;\n return medplum.searchValueSet(system, input).then((valueSet: ValueSet) => {\n const contains = (valueSet.expansion as ValueSetExpansion).contains as ValueSetExpansionContains[];\n contains.forEach((e) => (cachedDisplayValues[e.code as string] = e.display as string));\n return contains.map((e) => e.code as string);\n });\n }}\n buildUnstructured={(str: string) => str}\n getId={(item: string) => item}\n getDisplay={(item: string) => <>{cachedDisplayValues[item] || item}</>}\n name={props.name}\n defaultValue={defaultValue}\n loadOnFocus={true}\n onChange={(values: string[]) => {\n if (props.onChange) {\n props.onChange(values[0]);\n }\n }}\n />\n );\n}\n"],"names":[],"mappings":";;;;AAYA,MAAM,mBAAmB,GAA2B,EAAE,CAAC;AAEjD,SAAU,SAAS,CAAC,KAAqB,EAAA;AAC7C,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,YAAY,GAAG,SAAS,CAAC;IAC7B,IAAI,KAAK,CAAC,YAAY,EAAE;AACtB,QAAA,YAAY,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACrC,KAAA;IAED,QACE,oBAAC,YAAY,EAAA,EACX,WAAW,EAAE,CAAC,KAAa,KAAuB;;YAChD,MAAM,MAAM,GAAG,CAAA,EAAA,GAAA,KAAK,CAAC,QAAQ,CAAC,OAAO,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,QAAkB,CAAC;AAC1D,YAAA,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,QAAkB,KAAI;AACvE,gBAAA,MAAM,QAAQ,GAAI,QAAQ,CAAC,SAA+B,CAAC,QAAuC,CAAC;gBACnG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,mBAAmB,CAAC,CAAC,CAAC,IAAc,CAAC,GAAG,CAAC,CAAC,OAAiB,CAAC,CAAC,CAAC;AACvF,gBAAA,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAc,CAAC,CAAC;AAC/C,aAAC,CAAC,CAAC;SACJ,EACD,iBAAiB,EAAE,CAAC,GAAW,KAAK,GAAG,EACvC,KAAK,EAAE,CAAC,IAAY,KAAK,IAAI,EAC7B,UAAU,EAAE,CAAC,IAAY,KAAK,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAI,EACtE,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,IAAI,EACjB,QAAQ,EAAE,CAAC,MAAgB,KAAI;YAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE;gBAClB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3B,aAAA;SACF,EAAA,CACD,EACF;AACJ;;;;"}
|
|
@@ -15,7 +15,7 @@ function CodeableConceptInput(props) {
|
|
|
15
15
|
return medplum.searchValueSet(system, input).then((valueSet) => {
|
|
16
16
|
return valueSet.expansion.contains.map(valueSetElementToCodeableConcept);
|
|
17
17
|
});
|
|
18
|
-
}, buildUnstructured: buildUnstructured, getId: getId, getDisplay: getDisplay, name: props.name, defaultValue: defaultValue, onChange: (values) => {
|
|
18
|
+
}, buildUnstructured: buildUnstructured, getId: getId, getDisplay: getDisplay, name: props.name, defaultValue: defaultValue, loadOnFocus: true, onChange: (values) => {
|
|
19
19
|
if (props.onChange) {
|
|
20
20
|
props.onChange(values[0]);
|
|
21
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeableConceptInput.js","sources":["../../src/CodeableConceptInput.tsx"],"sourcesContent":["import { stringify } from '@medplum/core';\nimport {\n CodeableConcept,\n ElementDefinition,\n ValueSet,\n ValueSetExpansion,\n ValueSetExpansionContains,\n} from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Autocomplete } from './Autocomplete';\nimport { useMedplum } from './MedplumProvider';\n\nexport interface CodeableConceptInputProps {\n property: ElementDefinition;\n name: string;\n defaultValue?: CodeableConcept;\n onChange?: (value: CodeableConcept) => void;\n}\n\nexport function CodeableConceptInput(props: CodeableConceptInputProps): JSX.Element {\n const medplum = useMedplum();\n\n let defaultValue = undefined;\n if (props.defaultValue) {\n defaultValue = [props.defaultValue];\n }\n\n return (\n <Autocomplete\n loadOptions={(input: string): Promise<CodeableConcept[]> => {\n const system = props.property.binding?.valueSet as string;\n return medplum.searchValueSet(system, input).then((valueSet: ValueSet) => {\n return ((valueSet.expansion as ValueSetExpansion).contains as ValueSetExpansionContains[]).map(\n valueSetElementToCodeableConcept\n );\n });\n }}\n buildUnstructured={buildUnstructured}\n getId={getId}\n getDisplay={getDisplay}\n name={props.name}\n defaultValue={defaultValue}\n onChange={(values: CodeableConcept[]) => {\n if (props.onChange) {\n props.onChange(values[0]);\n }\n }}\n />\n );\n}\n\nfunction valueSetElementToCodeableConcept(element: ValueSetExpansionContains): CodeableConcept {\n return {\n text: element.display,\n coding: [\n {\n system: element.system,\n code: element.code,\n display: element.display,\n },\n ],\n };\n}\n\nfunction buildUnstructured(str: string): CodeableConcept {\n return { text: str };\n}\n\nfunction getId(concept: CodeableConcept): string {\n if (concept.coding && concept.coding.length > 0) {\n return concept.coding[0].code as string;\n }\n return stringify(concept);\n}\n\nfunction getDisplay(concept: CodeableConcept): JSX.Element {\n const text = concept.coding?.[0]?.display ?? concept.coding?.[0]?.code ?? concept.text;\n return <>{text}</>;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeableConceptInput.js","sources":["../../src/CodeableConceptInput.tsx"],"sourcesContent":["import { stringify } from '@medplum/core';\nimport {\n CodeableConcept,\n ElementDefinition,\n ValueSet,\n ValueSetExpansion,\n ValueSetExpansionContains,\n} from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Autocomplete } from './Autocomplete';\nimport { useMedplum } from './MedplumProvider';\n\nexport interface CodeableConceptInputProps {\n property: ElementDefinition;\n name: string;\n defaultValue?: CodeableConcept;\n onChange?: (value: CodeableConcept) => void;\n}\n\nexport function CodeableConceptInput(props: CodeableConceptInputProps): JSX.Element {\n const medplum = useMedplum();\n\n let defaultValue = undefined;\n if (props.defaultValue) {\n defaultValue = [props.defaultValue];\n }\n\n return (\n <Autocomplete\n loadOptions={(input: string): Promise<CodeableConcept[]> => {\n const system = props.property.binding?.valueSet as string;\n return medplum.searchValueSet(system, input).then((valueSet: ValueSet) => {\n return ((valueSet.expansion as ValueSetExpansion).contains as ValueSetExpansionContains[]).map(\n valueSetElementToCodeableConcept\n );\n });\n }}\n buildUnstructured={buildUnstructured}\n getId={getId}\n getDisplay={getDisplay}\n name={props.name}\n defaultValue={defaultValue}\n loadOnFocus={true}\n onChange={(values: CodeableConcept[]) => {\n if (props.onChange) {\n props.onChange(values[0]);\n }\n }}\n />\n );\n}\n\nfunction valueSetElementToCodeableConcept(element: ValueSetExpansionContains): CodeableConcept {\n return {\n text: element.display,\n coding: [\n {\n system: element.system,\n code: element.code,\n display: element.display,\n },\n ],\n };\n}\n\nfunction buildUnstructured(str: string): CodeableConcept {\n return { text: str };\n}\n\nfunction getId(concept: CodeableConcept): string {\n if (concept.coding && concept.coding.length > 0) {\n return concept.coding[0].code as string;\n }\n return stringify(concept);\n}\n\nfunction getDisplay(concept: CodeableConcept): JSX.Element {\n const text = concept.coding?.[0]?.display ?? concept.coding?.[0]?.code ?? concept.text;\n return <>{text}</>;\n}\n"],"names":[],"mappings":"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"}
|
package/dist/esm/CodingInput.js
CHANGED
|
@@ -19,7 +19,7 @@ function CodingInput(props) {
|
|
|
19
19
|
display: e.display,
|
|
20
20
|
}));
|
|
21
21
|
});
|
|
22
|
-
}, buildUnstructured: (str) => ({ code: str }), getId: (item) => item.code, getDisplay: (item) => React.createElement(CodingDisplay, { value: item }), name: props.name, defaultValue: defaultValue, onChange: (values) => {
|
|
22
|
+
}, buildUnstructured: (str) => ({ code: str }), getId: (item) => item.code, getDisplay: (item) => React.createElement(CodingDisplay, { value: item }), name: props.name, defaultValue: defaultValue, loadOnFocus: true, onChange: (values) => {
|
|
23
23
|
if (props.onChange) {
|
|
24
24
|
props.onChange(values[0]);
|
|
25
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodingInput.js","sources":["../../src/CodingInput.tsx"],"sourcesContent":["import { Coding, ElementDefinition, ValueSet, ValueSetExpansion, ValueSetExpansionContains } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Autocomplete } from './Autocomplete';\nimport { CodingDisplay } from './CodingDisplay';\nimport { useMedplum } from './MedplumProvider';\n\nexport interface CodingInputProps {\n property: ElementDefinition;\n name: string;\n defaultValue?: Coding;\n onChange?: (value: Coding) => void;\n}\n\nexport function CodingInput(props: CodingInputProps): JSX.Element {\n const medplum = useMedplum();\n\n let defaultValue = undefined;\n if (props.defaultValue) {\n defaultValue = [props.defaultValue];\n }\n\n return (\n <Autocomplete\n loadOptions={(input: string): Promise<Coding[]> => {\n const system = props.property.binding?.valueSet as string;\n return medplum.searchValueSet(system, input).then((valueSet: ValueSet) => {\n return ((valueSet.expansion as ValueSetExpansion).contains as ValueSetExpansionContains[]).map(\n (e) =>\n ({\n system: e.system,\n code: e.code,\n display: e.display,\n } as Coding)\n );\n });\n }}\n buildUnstructured={(str: string) => ({ code: str })}\n getId={(item: Coding) => item.code as string}\n getDisplay={(item: Coding) => <CodingDisplay value={item} />}\n name={props.name}\n defaultValue={defaultValue}\n onChange={(values: Coding[]) => {\n if (props.onChange) {\n props.onChange(values[0]);\n }\n }}\n />\n );\n}\n"],"names":[],"mappings":";;;;;AAaM,SAAU,WAAW,CAAC,KAAuB,EAAA;AACjD,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,YAAY,GAAG,SAAS,CAAC;IAC7B,IAAI,KAAK,CAAC,YAAY,EAAE;AACtB,QAAA,YAAY,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACrC,KAAA;IAED,QACE,oBAAC,YAAY,EAAA,EACX,WAAW,EAAE,CAAC,KAAa,KAAuB;;YAChD,MAAM,MAAM,GAAG,CAAA,EAAA,GAAA,KAAK,CAAC,QAAQ,CAAC,OAAO,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,QAAkB,CAAC;AAC1D,YAAA,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,QAAkB,KAAI;AACvE,gBAAA,OAAS,QAAQ,CAAC,SAA+B,CAAC,QAAwC,CAAC,GAAG,CAC5F,CAAC,CAAC,MACC;oBACC,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;AACR,iBAAA,CAAA,CACf,CAAC;AACJ,aAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"CodingInput.js","sources":["../../src/CodingInput.tsx"],"sourcesContent":["import { Coding, ElementDefinition, ValueSet, ValueSetExpansion, ValueSetExpansionContains } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Autocomplete } from './Autocomplete';\nimport { CodingDisplay } from './CodingDisplay';\nimport { useMedplum } from './MedplumProvider';\n\nexport interface CodingInputProps {\n property: ElementDefinition;\n name: string;\n defaultValue?: Coding;\n onChange?: (value: Coding) => void;\n}\n\nexport function CodingInput(props: CodingInputProps): JSX.Element {\n const medplum = useMedplum();\n\n let defaultValue = undefined;\n if (props.defaultValue) {\n defaultValue = [props.defaultValue];\n }\n\n return (\n <Autocomplete\n loadOptions={(input: string): Promise<Coding[]> => {\n const system = props.property.binding?.valueSet as string;\n return medplum.searchValueSet(system, input).then((valueSet: ValueSet) => {\n return ((valueSet.expansion as ValueSetExpansion).contains as ValueSetExpansionContains[]).map(\n (e) =>\n ({\n system: e.system,\n code: e.code,\n display: e.display,\n } as Coding)\n );\n });\n }}\n buildUnstructured={(str: string) => ({ code: str })}\n getId={(item: Coding) => item.code as string}\n getDisplay={(item: Coding) => <CodingDisplay value={item} />}\n name={props.name}\n defaultValue={defaultValue}\n loadOnFocus={true}\n onChange={(values: Coding[]) => {\n if (props.onChange) {\n props.onChange(values[0]);\n }\n }}\n />\n );\n}\n"],"names":[],"mappings":";;;;;AAaM,SAAU,WAAW,CAAC,KAAuB,EAAA;AACjD,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,YAAY,GAAG,SAAS,CAAC;IAC7B,IAAI,KAAK,CAAC,YAAY,EAAE;AACtB,QAAA,YAAY,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACrC,KAAA;IAED,QACE,oBAAC,YAAY,EAAA,EACX,WAAW,EAAE,CAAC,KAAa,KAAuB;;YAChD,MAAM,MAAM,GAAG,CAAA,EAAA,GAAA,KAAK,CAAC,QAAQ,CAAC,OAAO,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,QAAkB,CAAC;AAC1D,YAAA,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,QAAkB,KAAI;AACvE,gBAAA,OAAS,QAAQ,CAAC,SAA+B,CAAC,QAAwC,CAAC,GAAG,CAC5F,CAAC,CAAC,MACC;oBACC,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;AACR,iBAAA,CAAA,CACf,CAAC;AACJ,aAAC,CAAC,CAAC;AACL,SAAC,EACD,iBAAiB,EAAE,CAAC,GAAW,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EACnD,KAAK,EAAE,CAAC,IAAY,KAAK,IAAI,CAAC,IAAc,EAC5C,UAAU,EAAE,CAAC,IAAY,KAAK,KAAC,CAAA,aAAA,CAAA,aAAa,EAAC,EAAA,KAAK,EAAE,IAAI,EAAI,CAAA,EAC5D,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,IAAI,EACjB,QAAQ,EAAE,CAAC,MAAgB,KAAI;YAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE;gBAClB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3B,aAAA;SACF,EAAA,CACD,EACF;AACJ;;;;"}
|
package/dist/esm/GoogleButton.js
CHANGED
|
@@ -37,9 +37,9 @@ function getGoogleClientId(clientId) {
|
|
|
37
37
|
return clientId;
|
|
38
38
|
}
|
|
39
39
|
const origin = window.location.protocol + '//' + window.location.host;
|
|
40
|
-
const authorizedOrigins = (_b = (_a = "
|
|
40
|
+
const authorizedOrigins = (_b = (_a = "undefined") === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
|
|
41
41
|
if (authorizedOrigins.includes(origin)) {
|
|
42
|
-
return "
|
|
42
|
+
return "undefined";
|
|
43
43
|
}
|
|
44
44
|
return undefined;
|
|
45
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoogleButton.js","sources":["../../src/GoogleButton.tsx"],"sourcesContent":["import { GoogleCredentialResponse } from '@medplum/core';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { useMedplum } from './MedplumProvider';\nimport { createScriptTag } from './utils';\n\ninterface GoogleApi {\n accounts: {\n id: {\n initialize: (args: any) => void;\n renderButton: (parent: HTMLElement, args: any) => void;\n };\n };\n}\n\ndeclare const google: GoogleApi;\n\nexport interface GoogleButtonProps {\n readonly googleClientId?: string;\n readonly handleGoogleCredential: (response: GoogleCredentialResponse) => void;\n}\n\nexport function GoogleButton(props: GoogleButtonProps): JSX.Element | null {\n const medplum = useMedplum();\n const { googleClientId, handleGoogleCredential } = props;\n const parentRef = useRef<HTMLDivElement>(null);\n const [scriptLoaded, setScriptLoaded] = useState<boolean>(typeof google !== 'undefined');\n const [initialized, setInitialized] = useState<boolean>(false);\n const [buttonRendered, setButtonRendered] = useState<boolean>(false);\n\n useEffect(() => {\n if (typeof google === 'undefined') {\n createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));\n return;\n }\n\n if (!initialized) {\n google.accounts.id.initialize({\n client_id: googleClientId,\n callback: handleGoogleCredential,\n });\n setInitialized(true);\n }\n\n if (parentRef.current && !buttonRendered) {\n google.accounts.id.renderButton(parentRef.current, {});\n setButtonRendered(true);\n }\n }, [medplum, googleClientId, initialized, scriptLoaded, parentRef, buttonRendered, handleGoogleCredential]);\n\n if (!googleClientId) {\n return null;\n }\n\n return <div ref={parentRef} />;\n}\n\nexport function getGoogleClientId(clientId: string | undefined): string | undefined {\n if (clientId) {\n return clientId;\n }\n\n const origin = window.location.protocol + '//' + window.location.host;\n const authorizedOrigins = process.env.GOOGLE_AUTH_ORIGINS?.split(',') ?? [];\n if (authorizedOrigins.includes(origin)) {\n return process.env.GOOGLE_CLIENT_ID;\n }\n\n return undefined;\n}\n"],"names":[],"mappings":";;;;AAqBM,SAAU,YAAY,CAAC,KAAwB,EAAA;AACnD,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,EAAE,cAAc,EAAE,sBAAsB,EAAE,GAAG,KAAK,CAAC;AACzD,IAAA,MAAM,SAAS,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;AAC/C,IAAA,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC;IACzF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC/D,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAErE,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,eAAe,CAAC,wCAAwC,EAAE,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YACvF,OAAO;AACR,SAAA;QAED,IAAI,CAAC,WAAW,EAAE;AAChB,YAAA,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC;AAC5B,gBAAA,SAAS,EAAE,cAAc;AACzB,gBAAA,QAAQ,EAAE,sBAAsB;AACjC,aAAA,CAAC,CAAC;YACH,cAAc,CAAC,IAAI,CAAC,CAAC;AACtB,SAAA;AAED,QAAA,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,cAAc,EAAE;AACxC,YAAA,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACvD,iBAAiB,CAAC,IAAI,CAAC,CAAC;AACzB,SAAA;AACH,KAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAE5G,IAAI,CAAC,cAAc,EAAE;AACnB,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;AAED,IAAA,OAAO,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAG,EAAE,SAAS,GAAI,CAAC;AACjC,CAAC;AAEK,SAAU,iBAAiB,CAAC,QAA4B,EAAA;;AAC5D,IAAA,IAAI,QAAQ,EAAE;AACZ,QAAA,OAAO,QAAQ,CAAC;AACjB,KAAA;AAED,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACtE,IAAA,MAAM,iBAAiB,GAAG,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"GoogleButton.js","sources":["../../src/GoogleButton.tsx"],"sourcesContent":["import { GoogleCredentialResponse } from '@medplum/core';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { useMedplum } from './MedplumProvider';\nimport { createScriptTag } from './utils';\n\ninterface GoogleApi {\n accounts: {\n id: {\n initialize: (args: any) => void;\n renderButton: (parent: HTMLElement, args: any) => void;\n };\n };\n}\n\ndeclare const google: GoogleApi;\n\nexport interface GoogleButtonProps {\n readonly googleClientId?: string;\n readonly handleGoogleCredential: (response: GoogleCredentialResponse) => void;\n}\n\nexport function GoogleButton(props: GoogleButtonProps): JSX.Element | null {\n const medplum = useMedplum();\n const { googleClientId, handleGoogleCredential } = props;\n const parentRef = useRef<HTMLDivElement>(null);\n const [scriptLoaded, setScriptLoaded] = useState<boolean>(typeof google !== 'undefined');\n const [initialized, setInitialized] = useState<boolean>(false);\n const [buttonRendered, setButtonRendered] = useState<boolean>(false);\n\n useEffect(() => {\n if (typeof google === 'undefined') {\n createScriptTag('https://accounts.google.com/gsi/client', () => setScriptLoaded(true));\n return;\n }\n\n if (!initialized) {\n google.accounts.id.initialize({\n client_id: googleClientId,\n callback: handleGoogleCredential,\n });\n setInitialized(true);\n }\n\n if (parentRef.current && !buttonRendered) {\n google.accounts.id.renderButton(parentRef.current, {});\n setButtonRendered(true);\n }\n }, [medplum, googleClientId, initialized, scriptLoaded, parentRef, buttonRendered, handleGoogleCredential]);\n\n if (!googleClientId) {\n return null;\n }\n\n return <div ref={parentRef} />;\n}\n\nexport function getGoogleClientId(clientId: string | undefined): string | undefined {\n if (clientId) {\n return clientId;\n }\n\n const origin = window.location.protocol + '//' + window.location.host;\n const authorizedOrigins = process.env.GOOGLE_AUTH_ORIGINS?.split(',') ?? [];\n if (authorizedOrigins.includes(origin)) {\n return process.env.GOOGLE_CLIENT_ID;\n }\n\n return undefined;\n}\n"],"names":[],"mappings":";;;;AAqBM,SAAU,YAAY,CAAC,KAAwB,EAAA;AACnD,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,EAAE,cAAc,EAAE,sBAAsB,EAAE,GAAG,KAAK,CAAC;AACzD,IAAA,MAAM,SAAS,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;AAC/C,IAAA,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC;IACzF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC/D,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAErE,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,eAAe,CAAC,wCAAwC,EAAE,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YACvF,OAAO;AACR,SAAA;QAED,IAAI,CAAC,WAAW,EAAE;AAChB,YAAA,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC;AAC5B,gBAAA,SAAS,EAAE,cAAc;AACzB,gBAAA,QAAQ,EAAE,sBAAsB;AACjC,aAAA,CAAC,CAAC;YACH,cAAc,CAAC,IAAI,CAAC,CAAC;AACtB,SAAA;AAED,QAAA,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,cAAc,EAAE;AACxC,YAAA,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACvD,iBAAiB,CAAC,IAAI,CAAC,CAAC;AACzB,SAAA;AACH,KAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAE5G,IAAI,CAAC,cAAc,EAAE;AACnB,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;AAED,IAAA,OAAO,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAG,EAAE,SAAS,GAAI,CAAC;AACjC,CAAC;AAEK,SAAU,iBAAiB,CAAC,QAA4B,EAAA;;AAC5D,IAAA,IAAI,QAAQ,EAAE;AACZ,QAAA,OAAO,QAAQ,CAAC;AACjB,KAAA;AAED,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACtE,IAAA,MAAM,iBAAiB,GAAG,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,WAA+B,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,KAAK,CAAC,GAAG,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,EAAE,CAAC;AAC5E,IAAA,IAAI,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AACtC,QAAA,OAAO,WAA4B,CAAC;AACrC,KAAA;AAED,IAAA,OAAO,SAAS,CAAC;AACnB;;;;"}
|