@medplum/react 0.9.21 → 0.9.22
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 +160 -0
- 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 +58 -0
- package/dist/esm/index.js +161 -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 +58 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +12 -12
package/dist/cjs/index.js
CHANGED
|
@@ -5271,6 +5271,165 @@
|
|
|
5271
5271
|
return `/${resource.resourceType}/${resource.id}/_history/${(_a = resource.meta) === null || _a === void 0 ? void 0 : _a.versionId}`;
|
|
5272
5272
|
}
|
|
5273
5273
|
|
|
5274
|
+
/**
|
|
5275
|
+
* Returns a month display string (e.g. "January 2020").
|
|
5276
|
+
* @param date Any date within the month.
|
|
5277
|
+
* @returns The month display string (e.g. "January 2020")
|
|
5278
|
+
*/
|
|
5279
|
+
function getMonthString(date) {
|
|
5280
|
+
return date.toLocaleString('default', { month: 'long' }) + ' ' + date.getFullYear();
|
|
5281
|
+
}
|
|
5282
|
+
function CalendarInput(props) {
|
|
5283
|
+
const [month, setMonth] = React.useState(getStartMonth);
|
|
5284
|
+
function moveMonth(delta) {
|
|
5285
|
+
setMonth((currMonth) => {
|
|
5286
|
+
const prevMonth = new Date(currMonth.getTime());
|
|
5287
|
+
prevMonth.setMonth(currMonth.getMonth() + delta);
|
|
5288
|
+
return prevMonth;
|
|
5289
|
+
});
|
|
5290
|
+
}
|
|
5291
|
+
const grid = React.useMemo(() => buildGrid(month, props.slots), [month, props.slots]);
|
|
5292
|
+
return (React__default["default"].createElement("div", null,
|
|
5293
|
+
React__default["default"].createElement(InputRow, null,
|
|
5294
|
+
React__default["default"].createElement("p", { style: { flex: 1 } }, getMonthString(month)),
|
|
5295
|
+
React__default["default"].createElement("p", null,
|
|
5296
|
+
React__default["default"].createElement(Button, { label: "Previous month", onClick: () => moveMonth(-1) }, "<"),
|
|
5297
|
+
React__default["default"].createElement(Button, { label: "Next month", onClick: () => moveMonth(1) }, ">"))),
|
|
5298
|
+
React__default["default"].createElement("table", { className: "medplum-calendar-table" },
|
|
5299
|
+
React__default["default"].createElement("thead", null,
|
|
5300
|
+
React__default["default"].createElement("tr", null,
|
|
5301
|
+
React__default["default"].createElement("th", null, "SUN"),
|
|
5302
|
+
React__default["default"].createElement("th", null, "MON"),
|
|
5303
|
+
React__default["default"].createElement("th", null, "TUE"),
|
|
5304
|
+
React__default["default"].createElement("th", null, "WED"),
|
|
5305
|
+
React__default["default"].createElement("th", null, "THU"),
|
|
5306
|
+
React__default["default"].createElement("th", null, "FRI"),
|
|
5307
|
+
React__default["default"].createElement("th", null, "SAT"))),
|
|
5308
|
+
React__default["default"].createElement("tbody", null, grid.map((week, weekIndex) => (React__default["default"].createElement("tr", { key: 'week-' + weekIndex }, week.map((day, dayIndex) => (React__default["default"].createElement("td", { key: 'day-' + dayIndex }, day && (React__default["default"].createElement("button", { disabled: !day.available, onClick: () => props.onClick(day.date) }, day.date.getDate()))))))))))));
|
|
5309
|
+
}
|
|
5310
|
+
function getStartMonth() {
|
|
5311
|
+
const result = new Date();
|
|
5312
|
+
result.setDate(1);
|
|
5313
|
+
result.setHours(0, 0, 0, 0);
|
|
5314
|
+
return result;
|
|
5315
|
+
}
|
|
5316
|
+
function buildGrid(startDate, slots) {
|
|
5317
|
+
const d = new Date(startDate.getFullYear(), startDate.getMonth());
|
|
5318
|
+
const grid = [];
|
|
5319
|
+
let row = [];
|
|
5320
|
+
// Fill leading empty days
|
|
5321
|
+
for (let i = 0; i < d.getDay(); i++) {
|
|
5322
|
+
row.push(undefined);
|
|
5323
|
+
}
|
|
5324
|
+
while (d.getMonth() === startDate.getMonth()) {
|
|
5325
|
+
row.push({
|
|
5326
|
+
date: new Date(d.getTime()),
|
|
5327
|
+
// available: isAvailable(d),
|
|
5328
|
+
available: isDayAvailable(d, slots),
|
|
5329
|
+
});
|
|
5330
|
+
if (d.getDay() === 6) {
|
|
5331
|
+
grid.push(row);
|
|
5332
|
+
row = [];
|
|
5333
|
+
}
|
|
5334
|
+
d.setDate(d.getDate() + 1);
|
|
5335
|
+
}
|
|
5336
|
+
// Fill trailing empty days
|
|
5337
|
+
if (d.getDay() !== 0) {
|
|
5338
|
+
for (let i = d.getDay(); i < 7; i++) {
|
|
5339
|
+
row.push(undefined);
|
|
5340
|
+
}
|
|
5341
|
+
grid.push(row);
|
|
5342
|
+
}
|
|
5343
|
+
return grid;
|
|
5344
|
+
}
|
|
5345
|
+
/**
|
|
5346
|
+
* Returns true if the given date is available for booking.
|
|
5347
|
+
* @param day The day to check.
|
|
5348
|
+
* @param slots The list of available slots.
|
|
5349
|
+
* @returns True if there are any available slots for the day.
|
|
5350
|
+
*/
|
|
5351
|
+
function isDayAvailable(day, slots) {
|
|
5352
|
+
// Note that slot start and end time may or may not be in UTC.
|
|
5353
|
+
for (const slot of slots) {
|
|
5354
|
+
const slotStart = new Date(slot.start);
|
|
5355
|
+
if (slotStart.getFullYear() === day.getFullYear() &&
|
|
5356
|
+
slotStart.getMonth() === day.getMonth() &&
|
|
5357
|
+
slotStart.getDate() === day.getDate()) {
|
|
5358
|
+
return true;
|
|
5359
|
+
}
|
|
5360
|
+
}
|
|
5361
|
+
return false;
|
|
5362
|
+
}
|
|
5363
|
+
|
|
5364
|
+
function Scheduler(props) {
|
|
5365
|
+
var _a;
|
|
5366
|
+
const medplum = useMedplum();
|
|
5367
|
+
const schedule = useResource(props.schedule);
|
|
5368
|
+
const [slots, setSlots] = React.useState();
|
|
5369
|
+
const slotsRef = React.useRef();
|
|
5370
|
+
slotsRef.current = slots;
|
|
5371
|
+
const [date, setDate] = React.useState();
|
|
5372
|
+
const [slot, setSlot] = React.useState();
|
|
5373
|
+
const [info, setInfo] = React.useState();
|
|
5374
|
+
const [form, setForm] = React.useState();
|
|
5375
|
+
React.useEffect(() => {
|
|
5376
|
+
if (schedule) {
|
|
5377
|
+
medplum.search('Slot', 'schedule=' + core.getReferenceString(schedule)).then((bundle) => {
|
|
5378
|
+
setSlots(bundle.entry.map((entry) => entry.resource));
|
|
5379
|
+
});
|
|
5380
|
+
}
|
|
5381
|
+
else {
|
|
5382
|
+
setSlots(undefined);
|
|
5383
|
+
}
|
|
5384
|
+
}, [medplum, schedule]);
|
|
5385
|
+
if (!schedule || !slots) {
|
|
5386
|
+
return null;
|
|
5387
|
+
}
|
|
5388
|
+
const actor = (_a = schedule.actor) === null || _a === void 0 ? void 0 : _a[0];
|
|
5389
|
+
return (React__default["default"].createElement("div", { className: "medplum-calendar-container", "data-testid": "scheduler" },
|
|
5390
|
+
React__default["default"].createElement("div", { className: "medplum-calendar-info-pane" },
|
|
5391
|
+
actor && React__default["default"].createElement(Avatar, { value: actor, size: "large" }),
|
|
5392
|
+
actor && (React__default["default"].createElement("h1", null,
|
|
5393
|
+
React__default["default"].createElement(ResourceName, { value: actor }))),
|
|
5394
|
+
React__default["default"].createElement("p", null, "1 hour"),
|
|
5395
|
+
date && React__default["default"].createElement("p", null, date.toLocaleDateString()),
|
|
5396
|
+
slot && React__default["default"].createElement("p", null, formatTime(new Date(slot.start)))),
|
|
5397
|
+
React__default["default"].createElement("div", { className: "medplum-calendar-selection-pane" },
|
|
5398
|
+
!date && (React__default["default"].createElement("div", null,
|
|
5399
|
+
React__default["default"].createElement("h3", null, "Select date"),
|
|
5400
|
+
React__default["default"].createElement(CalendarInput, { slots: slots, onClick: setDate }))),
|
|
5401
|
+
date && !slot && (React__default["default"].createElement("div", null,
|
|
5402
|
+
React__default["default"].createElement("h3", null, "Select time"),
|
|
5403
|
+
slots.map((s) => {
|
|
5404
|
+
const slotStart = new Date(s.start);
|
|
5405
|
+
return (slotStart.getTime() > date.getTime() &&
|
|
5406
|
+
slotStart.getTime() < date.getTime() + 24 * 3600 * 1000 && (React__default["default"].createElement("div", { key: s.id },
|
|
5407
|
+
React__default["default"].createElement(Button, { style: { width: 150 }, onClick: () => setSlot(s) }, formatTime(slotStart)))));
|
|
5408
|
+
}))),
|
|
5409
|
+
date && slot && !info && (React__default["default"].createElement("div", null,
|
|
5410
|
+
React__default["default"].createElement("h3", null, "Enter your info"),
|
|
5411
|
+
React__default["default"].createElement(FormSection, { title: "Name", htmlFor: "name" },
|
|
5412
|
+
React__default["default"].createElement(Input, { name: "name" })),
|
|
5413
|
+
React__default["default"].createElement(FormSection, { title: "Email", htmlFor: "email" },
|
|
5414
|
+
React__default["default"].createElement(Input, { name: "email" })),
|
|
5415
|
+
React__default["default"].createElement(Button, { primary: true, onClick: () => setInfo('info') }, "Next"))),
|
|
5416
|
+
date && slot && info && !form && (React__default["default"].createElement("div", null,
|
|
5417
|
+
React__default["default"].createElement("h3", null, "Custom questions"),
|
|
5418
|
+
React__default["default"].createElement(FormSection, { title: "Question 1", htmlFor: "q1" },
|
|
5419
|
+
React__default["default"].createElement(Input, { name: "q1" })),
|
|
5420
|
+
React__default["default"].createElement(FormSection, { title: "Question 2", htmlFor: "q2" },
|
|
5421
|
+
React__default["default"].createElement(Input, { name: "email" })),
|
|
5422
|
+
React__default["default"].createElement(FormSection, { title: "Question 3", htmlFor: "q3" },
|
|
5423
|
+
React__default["default"].createElement(Input, { name: "email" })),
|
|
5424
|
+
React__default["default"].createElement(Button, { primary: true, onClick: () => setForm('form') }, "Next"))),
|
|
5425
|
+
date && slot && info && form && (React__default["default"].createElement("div", null,
|
|
5426
|
+
React__default["default"].createElement("h3", null, "You're all set!"),
|
|
5427
|
+
React__default["default"].createElement("p", null, "Check your email for a calendar invite."))))));
|
|
5428
|
+
}
|
|
5429
|
+
function formatTime(date) {
|
|
5430
|
+
return date.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
|
|
5431
|
+
}
|
|
5432
|
+
|
|
5274
5433
|
function ServiceRequestTimeline(props) {
|
|
5275
5434
|
return (React__default["default"].createElement(ResourceTimeline, { value: props.serviceRequest, buildSearchRequests: (resource) => ({
|
|
5276
5435
|
resourceType: 'Bundle',
|
|
@@ -5599,6 +5758,7 @@
|
|
|
5599
5758
|
exports.ResourcePropertyInput = ResourcePropertyInput;
|
|
5600
5759
|
exports.ResourceTable = ResourceTable;
|
|
5601
5760
|
exports.ResourceTimeline = ResourceTimeline;
|
|
5761
|
+
exports.Scheduler = Scheduler;
|
|
5602
5762
|
exports.Scrollable = Scrollable;
|
|
5603
5763
|
exports.SearchChangeEvent = SearchChangeEvent;
|
|
5604
5764
|
exports.SearchClickEvent = SearchClickEvent;
|