@medplum/react-scheduling 5.1.38 → 5.1.39
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.cjs +4 -2
- package/dist/cjs/index.cjs.map +4 -4
- package/dist/cjs/index.d.ts +182 -35
- package/dist/esm/index.d.ts +182 -35
- package/dist/esm/index.mjs +4 -2
- package/dist/esm/index.mjs.map +4 -4
- package/package.json +11 -11
package/dist/esm/index.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ import type { MantineThemeColors } from '@mantine/core';
|
|
|
9
9
|
import type { MedplumClient } from '@medplum/core';
|
|
10
10
|
import type { OperationOutcome } from '@medplum/fhirtypes';
|
|
11
11
|
import type { Patient } from '@medplum/fhirtypes';
|
|
12
|
+
import type { ReactNode } from 'react';
|
|
12
13
|
import type { Reference } from '@medplum/fhirtypes';
|
|
13
|
-
import type { Resource } from '@medplum/fhirtypes';
|
|
14
14
|
import type { Schedule } from '@medplum/fhirtypes';
|
|
15
15
|
import type { SchedulingRequirement } from '@medplum/core';
|
|
16
16
|
import type { Slot } from '@medplum/fhirtypes';
|
|
@@ -19,8 +19,8 @@ import type { WithId } from '@medplum/core';
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* One way of holding an appointment: a set of actors whose schedules `$find`
|
|
22
|
-
* intersects in a single request.
|
|
23
|
-
*
|
|
22
|
+
* intersects in a single request. Each requirement contributes exactly one
|
|
23
|
+
* actor, since a row is satisfied by any one of its alternatives.
|
|
24
24
|
*/
|
|
25
25
|
export declare interface ActorCombination {
|
|
26
26
|
/** Matches `getActorGroupKey` of the appointments offered for these actors. */
|
|
@@ -31,26 +31,70 @@ export declare interface ActorCombination {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* One thing an appointment needs, of a single actor type.
|
|
35
|
+
*
|
|
36
|
+
* The candidates in it are alternatives: a row naming two
|
|
37
|
+
* providers asks for *either* of them rather than both.
|
|
36
38
|
*/
|
|
37
|
-
export declare
|
|
39
|
+
export declare interface ActorRequirement {
|
|
40
|
+
readonly id: string;
|
|
41
|
+
readonly candidates: readonly ScheduleCandidate[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* What an appointment is being asked for, per actor type.
|
|
46
|
+
*
|
|
47
|
+
* Each actor type holds a list of requirements, and the two directions read
|
|
48
|
+
* differently: requirements are ANDed, so two provider rows ask for two
|
|
49
|
+
* providers, while the candidates within one row are ORed.
|
|
50
|
+
*/
|
|
51
|
+
export declare type ActorSelections = Partial<Record<SchedulingActorType, readonly ActorRequirement[]>>;
|
|
38
52
|
|
|
39
53
|
export declare function addDays(date: Date, days: number): Date;
|
|
40
54
|
|
|
41
55
|
/**
|
|
42
|
-
* Chooses
|
|
56
|
+
* Chooses which actors of one type can hold an appointment.
|
|
43
57
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
58
|
+
* The names in one of these fields are **alternatives** to each other.
|
|
59
|
+
* Several actors that all have to attend go in a field each - see {@link AppointmentActorSelections},
|
|
60
|
+
* which arranges these into rows.
|
|
46
61
|
*
|
|
47
|
-
*
|
|
62
|
+
* The results are `Schedule` resources, bound to the actors that can hold the appointment.
|
|
48
63
|
*
|
|
49
64
|
* @param props - The React props.
|
|
50
65
|
* @returns The field for one actor type.
|
|
51
66
|
*/
|
|
52
67
|
export declare function AppointmentActorSelect(props: AppointmentActorSelectProps): JSX.Element;
|
|
53
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Asks what an appointment needs by actor type (e.g., provider, room, device).
|
|
71
|
+
*
|
|
72
|
+
* Each actor type gets a stack of rows. **The rows are ANDed and the names
|
|
73
|
+
* within a row are ORed**: two provider rows ask for two providers, while two
|
|
74
|
+
* names in one row ask for either of them.
|
|
75
|
+
*
|
|
76
|
+
* A row is one alternative set, so it is also one dimension of the search:
|
|
77
|
+
* `getActorCombinations` takes one name from each row, and every way of doing
|
|
78
|
+
* that is one `$find` request.
|
|
79
|
+
*
|
|
80
|
+
* @param props - The React props.
|
|
81
|
+
* @returns One group of rows per bookable actor type.
|
|
82
|
+
*/
|
|
83
|
+
export declare function AppointmentActorSelections(props: AppointmentActorSelectionsProps): JSX.Element;
|
|
84
|
+
|
|
85
|
+
export declare interface AppointmentActorSelectionsProps {
|
|
86
|
+
/** What the appointment is being asked for so far, per actor type. */
|
|
87
|
+
readonly value: ActorSelections;
|
|
88
|
+
/** The service being booked. Nothing is offered until it resolves. */
|
|
89
|
+
readonly service: Reference<HealthcareService> | WithId<HealthcareService> | undefined;
|
|
90
|
+
/** The site being booked at. Actors sited elsewhere are left out. */
|
|
91
|
+
readonly location?: Reference<Location_2> | WithId<Location_2>;
|
|
92
|
+
readonly disabled?: boolean;
|
|
93
|
+
/** What is wrong with a type's rows, shown under them. None by default. */
|
|
94
|
+
readonly errors?: Partial<Record<BookableActorType, string>>;
|
|
95
|
+
readonly onChange: (selections: ActorSelections) => void;
|
|
96
|
+
}
|
|
97
|
+
|
|
54
98
|
export declare interface AppointmentActorSelectProps {
|
|
55
99
|
readonly actorType: BookableActorType;
|
|
56
100
|
/** The service being booked. Nothing is offered until it resolves. */
|
|
@@ -65,6 +109,16 @@ export declare interface AppointmentActorSelectProps {
|
|
|
65
109
|
readonly onChange: (candidates: readonly ScheduleCandidate[]) => void;
|
|
66
110
|
readonly error?: string;
|
|
67
111
|
readonly disabled?: boolean;
|
|
112
|
+
/** Names the field. Defaults to the actor type's own label. */
|
|
113
|
+
readonly label?: ReactNode;
|
|
114
|
+
/** The line under the field. None by default. */
|
|
115
|
+
readonly description?: ReactNode;
|
|
116
|
+
/** What the empty field invites. Defaults to searching the actor type by name. */
|
|
117
|
+
readonly placeholder?: string;
|
|
118
|
+
/** Whether the field must be answered. Defaults to whether its actor type is required. */
|
|
119
|
+
readonly required?: boolean;
|
|
120
|
+
/** Whether to mark the field with an asterisk. Defaults to `required`. */
|
|
121
|
+
readonly withAsterisk?: boolean;
|
|
68
122
|
}
|
|
69
123
|
|
|
70
124
|
/** What a booking wrote, as `Appointment/$book` returned it. */
|
|
@@ -149,13 +203,6 @@ export declare interface AppointmentOptionRowProps {
|
|
|
149
203
|
* Gathers what a visit is held on, finds a time every one of them is free, and
|
|
150
204
|
* hands the proposal out to be booked.
|
|
151
205
|
*
|
|
152
|
-
* One field per scheduling role, each searching the schedules bookable for the
|
|
153
|
-
* chosen visit type. Everything named attends, because `$find` intersects their
|
|
154
|
-
* schedules — so naming a second room narrows the times rather than widening them.
|
|
155
|
-
*
|
|
156
|
-
* Only a time the search offered can be chosen: the field holding it accepts no
|
|
157
|
-
* input, so nothing can be booked onto time nobody checked availability for.
|
|
158
|
-
*
|
|
159
206
|
* Writes nothing and announces nothing: `onBook` owns that. Mount this to do
|
|
160
207
|
* something other than `$book` with the proposal — hold it through `$hold`, or
|
|
161
208
|
* write it inside a transaction of your own. {@link AppointmentBookingForm} is the
|
|
@@ -246,7 +293,7 @@ export declare interface AppointmentServiceSelectProps {
|
|
|
246
293
|
export declare interface AppointmentSlotGroup {
|
|
247
294
|
/** Stable key derived from the actors, so React keys survive a refetch. */
|
|
248
295
|
readonly key: string;
|
|
249
|
-
readonly actors: readonly
|
|
296
|
+
readonly actors: readonly SchedulingActorValue[];
|
|
250
297
|
readonly durationMinutes: number;
|
|
251
298
|
/** Sorted by start time. */
|
|
252
299
|
readonly appointments: readonly Appointment[];
|
|
@@ -274,9 +321,11 @@ export declare interface AppointmentSlotGroupCardProps {
|
|
|
274
321
|
* Actor types whose schedules may be offered for booking, in the order they are
|
|
275
322
|
* asked about.
|
|
276
323
|
*
|
|
277
|
-
* Each type becomes
|
|
278
|
-
* given: a time is offered only when the practitioner *and* the location *and*
|
|
279
|
-
* the device are all free for it.
|
|
324
|
+
* Each type becomes its own question, because `$find` intersects the schedules it
|
|
325
|
+
* is given: a time is offered only when the practitioner *and* the location *and*
|
|
326
|
+
* the device are all free for it. Asking for *either* of two practitioners is a
|
|
327
|
+
* second request rather than a second schedule on the same one — see
|
|
328
|
+
* `getActorCombinations`.
|
|
280
329
|
*
|
|
281
330
|
* Does not include `PractitionerRole` to prevent double-booking a `Practitioner`
|
|
282
331
|
* who holds multiple roles. A practitioner is booked on their `Practitioner`,
|
|
@@ -325,6 +374,26 @@ declare interface CommonProps {
|
|
|
325
374
|
readonly onCancel?: () => void;
|
|
326
375
|
}
|
|
327
376
|
|
|
377
|
+
/**
|
|
378
|
+
* Counts the combinations the selections expand into, without building them.
|
|
379
|
+
*
|
|
380
|
+
* An upper bound rather than an exact count: the ones that would name the same
|
|
381
|
+
* actor twice are only recognised while building. Enough to decide whether the
|
|
382
|
+
* product is worth expanding at all.
|
|
383
|
+
*
|
|
384
|
+
* @param selections - What has been chosen.
|
|
385
|
+
* @returns How many ways there are of satisfying every row, or 0 when nothing
|
|
386
|
+
* has been chosen.
|
|
387
|
+
*/
|
|
388
|
+
export declare function countActorCombinations(selections: ActorSelections): number;
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Opens a new requirement row.
|
|
392
|
+
* @param candidates - What it starts out asking for. Empty by default.
|
|
393
|
+
* @returns The row.
|
|
394
|
+
*/
|
|
395
|
+
export declare function createActorRequirement(candidates?: readonly ScheduleCandidate[]): ActorRequirement;
|
|
396
|
+
|
|
328
397
|
/** The days a search covers. Either end may be open. */
|
|
329
398
|
export declare interface DateRange {
|
|
330
399
|
readonly start?: Date;
|
|
@@ -426,11 +495,17 @@ export declare interface FormatZonedTimeOptions {
|
|
|
426
495
|
* Builds the sets of actors an appointment could be held on.
|
|
427
496
|
*
|
|
428
497
|
* One combination is one `$find` request: the schedules within it are
|
|
429
|
-
* intersected, so its times are the times all of those actors are free.
|
|
498
|
+
* intersected, so its times are the times all of those actors are free. Rows are
|
|
499
|
+
* ANDed and the alternatives within a row are ORed, so the combinations are the
|
|
500
|
+
* product of the rows — one alternative taken from each.
|
|
501
|
+
*
|
|
502
|
+
* Ordered as an odometer with the last row turning fastest, so the first
|
|
503
|
+
* combination is every row's first pick and the rounds the search runs stay
|
|
504
|
+
* predictable.
|
|
430
505
|
*
|
|
431
506
|
* @param selections - What has been chosen.
|
|
432
|
-
* @returns One combination
|
|
433
|
-
*
|
|
507
|
+
* @returns One combination per way of satisfying every row, or an empty list
|
|
508
|
+
* when nothing is chosen.
|
|
434
509
|
*/
|
|
435
510
|
export declare function getActorCombinations(selections: ActorSelections): ActorCombination[];
|
|
436
511
|
|
|
@@ -449,16 +524,16 @@ export declare function getActorGroupKey(appointment: Appointment): string;
|
|
|
449
524
|
export declare function getActorsKey(actors: readonly Reference[]): string;
|
|
450
525
|
|
|
451
526
|
/**
|
|
452
|
-
* Extracts the resource type
|
|
527
|
+
* Extracts the resource type of an actor, given as itself or as a reference.
|
|
453
528
|
*
|
|
454
529
|
* Only supports references that may be used for Scheduling operations, which are
|
|
455
530
|
* those that have a qualified `reference` attribute. The attribute must be present,
|
|
456
531
|
* and may not be a reference to a "contained" resource (eg. `{ reference: "#cid" }`)
|
|
457
532
|
*
|
|
458
|
-
* @param
|
|
459
|
-
* @returns The type
|
|
533
|
+
* @param actor - A schedulable resource, or a Reference to one
|
|
534
|
+
* @returns The type of the actor.
|
|
460
535
|
*/
|
|
461
|
-
export declare function getActorType(
|
|
536
|
+
export declare function getActorType(actor: SchedulingActorValue): SchedulingActorType;
|
|
462
537
|
|
|
463
538
|
/**
|
|
464
539
|
* Provides the label we use for scheduling resource types in this UI
|
|
@@ -468,6 +543,14 @@ export declare function getActorType(reference: SchedulingActor): SchedulingActo
|
|
|
468
543
|
*/
|
|
469
544
|
export declare function getActorTypeLabel(resourceType: SchedulingActorType): string;
|
|
470
545
|
|
|
546
|
+
/**
|
|
547
|
+
* Get the actor(s) of an appointment.
|
|
548
|
+
* @param appointment - The proposed appointment.
|
|
549
|
+
* @param actorResources - Map of actor resources that have already been previously loaded.
|
|
550
|
+
* @returns List of actors. Resource if it's already loaded, reference otherwise.
|
|
551
|
+
*/
|
|
552
|
+
export declare function getAppointmentActors(appointment: Appointment | undefined, actorResources?: ReadonlyMap<string, SchedulingActorResource>): SchedulingActorValue[];
|
|
553
|
+
|
|
471
554
|
/**
|
|
472
555
|
* Returns a key uniquely identifying a proposed appointment.
|
|
473
556
|
*
|
|
@@ -557,18 +640,41 @@ export declare function getFindWindowError(range: DateRange): string | undefined
|
|
|
557
640
|
export declare function getNativeInputType(type: 'date' | 'time'): string;
|
|
558
641
|
|
|
559
642
|
/**
|
|
560
|
-
* Returns
|
|
643
|
+
* Returns every row across every actor type, in the order they are asked about.
|
|
561
644
|
* @param selections - What has been chosen.
|
|
562
|
-
* @returns The
|
|
645
|
+
* @returns The rows, empty ones included.
|
|
646
|
+
*/
|
|
647
|
+
export declare function getRequirements(selections: ActorSelections): ActorRequirement[];
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Flattens the loaded actor resources into a map, keyed by their reference.
|
|
651
|
+
* @param selections - What has been chosen.
|
|
652
|
+
* @returns The resource behind each chosen actor the search was able to include.
|
|
653
|
+
*/
|
|
654
|
+
export declare function getSelectedActorResources(selections: ActorSelections): Map<string, SchedulingActorResource>;
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Returns everything chosen, across rows and actor types.
|
|
658
|
+
* @param selections - What has been chosen.
|
|
659
|
+
* @returns The chosen candidates in `BOOKABLE_ACTOR_TYPES` order, then row order.
|
|
563
660
|
*/
|
|
564
661
|
export declare function getSelectedCandidates(selections: ActorSelections): ScheduleCandidate[];
|
|
565
662
|
|
|
566
663
|
/**
|
|
567
664
|
* Reports why the current selections cannot be searched, if they cannot.
|
|
568
665
|
* @param selections - What has been chosen.
|
|
569
|
-
* @returns
|
|
666
|
+
* @returns The blocker to show the user, or undefined when the search can run.
|
|
667
|
+
*/
|
|
668
|
+
export declare function getSelectionError(selections: ActorSelections): SelectionBlocker | undefined;
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Finds the rows that cannot all be filled at once, when there are any. Specifically happens
|
|
672
|
+
* when two rows offer the same resource, so one resource cannot fill both halves of a visit.
|
|
673
|
+
* @param selections - What has been chosen.
|
|
674
|
+
* @returns The first type whose rows have no answer between them, or undefined when
|
|
675
|
+
* every type can be satisfied.
|
|
570
676
|
*/
|
|
571
|
-
export declare function
|
|
677
|
+
export declare function getUnsatisfiableRows(selections: ActorSelections): UnsatisfiableRows | undefined;
|
|
572
678
|
|
|
573
679
|
/**
|
|
574
680
|
* Search window for a calendar day in the given timezone, starting from now if that day is already underway.
|
|
@@ -587,9 +693,11 @@ export declare function getZonedDayRange(day: Date, timezone?: string): Required
|
|
|
587
693
|
* @param searched - Days to list whether or not they offer anything, so a searched day
|
|
588
694
|
* that came back empty still shows up rather than going missing. Read on the local
|
|
589
695
|
* calendar, matching how a day is picked.
|
|
696
|
+
* @param actorResources - The actors' own resources, keyed by reference, for
|
|
697
|
+
* whichever of them the caller has already read. See {@link getAppointmentActors}.
|
|
590
698
|
* @returns Days in ascending order, each holding its groups.
|
|
591
699
|
*/
|
|
592
|
-
export declare function groupAppointmentsByDay(appointments: readonly Appointment[], timezone?: string, searched?: DateRange): AppointmentDay[];
|
|
700
|
+
export declare function groupAppointmentsByDay(appointments: readonly Appointment[], timezone?: string, searched?: DateRange, actorResources?: ReadonlyMap<string, SchedulingActorResource>): AppointmentDay[];
|
|
593
701
|
|
|
594
702
|
/**
|
|
595
703
|
* Whether every requirement a visit type names has been answered.
|
|
@@ -624,6 +732,15 @@ export declare function isRequirementAnswered(requirement: SchedulingRequirement
|
|
|
624
732
|
*/
|
|
625
733
|
export declare function isViewerTimezone(timezone: string | undefined, viewer?: string): boolean;
|
|
626
734
|
|
|
735
|
+
/**
|
|
736
|
+
* The most alternatives worth expanding into requests at all.
|
|
737
|
+
*
|
|
738
|
+
* The search runs a few combinations at a time, so this is not the size of a
|
|
739
|
+
* round: it is the point past which the whole product is more than anyone is
|
|
740
|
+
* going to sit through, whatever order it is asked in.
|
|
741
|
+
*/
|
|
742
|
+
export declare const MAX_ACTOR_COMBINATIONS = 100;
|
|
743
|
+
|
|
627
744
|
/**
|
|
628
745
|
* The longest window `Appointment/$find` accepts. Requests wider than this are
|
|
629
746
|
* rejected outright, so callers have to keep their own date range inside it.
|
|
@@ -713,7 +830,7 @@ export declare type ScheduleAvailabilityEditorProps = ScheduleOverrideEditorProp
|
|
|
713
830
|
export declare interface ScheduleCandidate {
|
|
714
831
|
readonly schedule: WithId<Schedule>;
|
|
715
832
|
/** The actor itself, when the search was able to include it. */
|
|
716
|
-
readonly actorResource:
|
|
833
|
+
readonly actorResource: SchedulingActorResource | undefined;
|
|
717
834
|
}
|
|
718
835
|
|
|
719
836
|
/**
|
|
@@ -734,7 +851,15 @@ export declare interface ScheduleOverrideEditorProps extends CommonProps {
|
|
|
734
851
|
*/
|
|
735
852
|
export declare type SchedulingActor = Schedule['actor'][number];
|
|
736
853
|
|
|
737
|
-
|
|
854
|
+
/** A loaded actor resource. */
|
|
855
|
+
export declare type SchedulingActorResource = WithId<Dereference<SchedulingActor>>;
|
|
856
|
+
|
|
857
|
+
export declare type SchedulingActorType = SchedulingActorResource['resourceType'];
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* An actor as a reference, or as the resource when it has already been read.
|
|
861
|
+
*/
|
|
862
|
+
export declare type SchedulingActorValue = SchedulingActor | SchedulingActorResource;
|
|
738
863
|
|
|
739
864
|
/**
|
|
740
865
|
* A data-coordination component pairing {@link CalendarsPanel} with {@link MultiCalendar}.
|
|
@@ -801,6 +926,20 @@ export declare interface SearchScheduleCandidatesOptions {
|
|
|
801
926
|
readonly count?: number;
|
|
802
927
|
}
|
|
803
928
|
|
|
929
|
+
/** Why the current selections cannot be searched. */
|
|
930
|
+
export declare interface SelectionBlocker {
|
|
931
|
+
/** A whole sentence to show the user. */
|
|
932
|
+
readonly message: string;
|
|
933
|
+
readonly severity: SelectionBlockerSeverity;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* Whether a blocker is a form that is not finished yet, or answers that cannot work.
|
|
938
|
+
*
|
|
939
|
+
* Only `invalid` is the user's to undo, so only it is worth showing as an error.
|
|
940
|
+
*/
|
|
941
|
+
export declare type SelectionBlockerSeverity = 'incomplete' | 'invalid';
|
|
942
|
+
|
|
804
943
|
/**
|
|
805
944
|
* Props for editing a service's own default hours, in place of any one calendar's override.
|
|
806
945
|
* @param schedule - Omitted, which is what selects this mode.
|
|
@@ -852,6 +991,14 @@ export declare type TimeOfDay = 'any' | 'morning' | 'afternoon';
|
|
|
852
991
|
*/
|
|
853
992
|
export declare function toCodings(elements: readonly ValueSetExpansionContains[]): Coding[];
|
|
854
993
|
|
|
994
|
+
/** Rows that cannot all be filled at once, and where to say so. */
|
|
995
|
+
export declare interface UnsatisfiableRows {
|
|
996
|
+
/** The actor type whose rows have no answer between them. */
|
|
997
|
+
readonly actorType: BookableActorType;
|
|
998
|
+
/** What to do about it, to show against those rows. */
|
|
999
|
+
readonly message: string;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
855
1002
|
/**
|
|
856
1003
|
* Searches for the times an appointment could be held at.
|
|
857
1004
|
*
|