@elaraai/e3-ui 1.0.94 → 1.0.95
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/src/allocation/adapters.d.ts +159 -0
- package/dist/src/allocation/adapters.d.ts.map +1 -0
- package/dist/src/allocation/adapters.js +241 -0
- package/dist/src/allocation/adapters.js.map +1 -0
- package/dist/src/allocation/functions.d.ts +664 -0
- package/dist/src/allocation/functions.d.ts.map +1 -0
- package/dist/src/allocation/functions.js +782 -0
- package/dist/src/allocation/functions.js.map +1 -0
- package/dist/src/allocation/index.d.ts +2985 -0
- package/dist/src/allocation/index.d.ts.map +1 -0
- package/dist/src/allocation/index.js +499 -0
- package/dist/src/allocation/index.js.map +1 -0
- package/dist/src/allocation/types.d.ts +832 -0
- package/dist/src/allocation/types.d.ts.map +1 -0
- package/dist/src/allocation/types.js +360 -0
- package/dist/src/allocation/types.js.map +1 -0
- package/dist/src/bind/func.d.ts +14 -0
- package/dist/src/bind/func.d.ts.map +1 -1
- package/dist/src/bind/func.js +22 -1
- package/dist/src/bind/func.js.map +1 -1
- package/dist/src/calendar/index.d.ts +510 -1639
- package/dist/src/calendar/index.d.ts.map +1 -1
- package/dist/src/calendar/index.js +56 -29
- package/dist/src/calendar/index.js.map +1 -1
- package/dist/src/flowchart/canvas.d.ts +9 -21
- package/dist/src/flowchart/canvas.d.ts.map +1 -1
- package/dist/src/flowchart/canvas.js +10 -22
- package/dist/src/flowchart/canvas.js.map +1 -1
- package/dist/src/flowchart/flowchart.d.ts +19 -13
- package/dist/src/flowchart/flowchart.d.ts.map +1 -1
- package/dist/src/flowchart/flowchart.js.map +1 -1
- package/dist/src/flowchart/index.d.ts +44 -21
- package/dist/src/flowchart/index.d.ts.map +1 -1
- package/dist/src/flowchart/index.js +43 -20
- package/dist/src/flowchart/index.js.map +1 -1
- package/dist/src/flowchart/library.d.ts +166 -81
- package/dist/src/flowchart/library.d.ts.map +1 -1
- package/dist/src/flowchart/library.js +232 -105
- package/dist/src/flowchart/library.js.map +1 -1
- package/dist/src/flowchart/over.d.ts +9 -16
- package/dist/src/flowchart/over.d.ts.map +1 -1
- package/dist/src/flowchart/over.js +9 -16
- package/dist/src/flowchart/over.js.map +1 -1
- package/dist/src/flowchart/payload.d.ts +710 -508
- package/dist/src/flowchart/payload.d.ts.map +1 -1
- package/dist/src/flowchart/payload.js +128 -74
- package/dist/src/flowchart/payload.js.map +1 -1
- package/dist/src/flowchart/window.d.ts +132 -347
- package/dist/src/flowchart/window.d.ts.map +1 -1
- package/dist/src/flowchart/window.js +48 -55
- package/dist/src/flowchart/window.js.map +1 -1
- package/dist/src/index.d.ts +11 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +14 -6
- package/dist/src/index.js.map +1 -1
- package/dist/src/internal.d.ts +18 -7
- package/dist/src/internal.d.ts.map +1 -1
- package/dist/src/internal.js +28 -9
- package/dist/src/internal.js.map +1 -1
- package/dist/src/plan/event-rows.d.ts +26 -10
- package/dist/src/plan/event-rows.d.ts.map +1 -1
- package/dist/src/plan/event-rows.js +39 -13
- package/dist/src/plan/event-rows.js.map +1 -1
- package/dist/src/plan/ir.d.ts +244 -815
- package/dist/src/plan/ir.d.ts.map +1 -1
- package/dist/src/plan/ir.js +8 -6
- package/dist/src/plan/ir.js.map +1 -1
- package/dist/src/plan/library.d.ts +3 -0
- package/dist/src/plan/library.d.ts.map +1 -1
- package/dist/src/plan/library.js +1 -1
- package/dist/src/plan/library.js.map +1 -1
- package/dist/src/plan/ordered-source.d.ts +1 -0
- package/dist/src/plan/ordered-source.d.ts.map +1 -1
- package/dist/src/plan/plan.d.ts +559 -1667
- package/dist/src/plan/plan.d.ts.map +1 -1
- package/dist/src/plan/plan.js +123 -45
- package/dist/src/plan/plan.js.map +1 -1
- package/dist/src/plan/root.d.ts +16 -20
- package/dist/src/plan/root.d.ts.map +1 -1
- package/dist/src/plan/root.js +23 -33
- package/dist/src/plan/root.js.map +1 -1
- package/dist/src/roster/coverage.d.ts +17 -231
- package/dist/src/roster/coverage.d.ts.map +1 -1
- package/dist/src/roster/coverage.js +94 -90
- package/dist/src/roster/coverage.js.map +1 -1
- package/dist/src/roster/fit.d.ts +59 -0
- package/dist/src/roster/fit.d.ts.map +1 -0
- package/dist/src/roster/fit.js +155 -0
- package/dist/src/roster/fit.js.map +1 -0
- package/dist/src/roster/index.d.ts +2862 -3662
- package/dist/src/roster/index.d.ts.map +1 -1
- package/dist/src/roster/index.js +383 -81
- package/dist/src/roster/index.js.map +1 -1
- package/dist/src/roster/library.d.ts +37 -92
- package/dist/src/roster/library.d.ts.map +1 -1
- package/dist/src/roster/library.js +25 -64
- package/dist/src/roster/library.js.map +1 -1
- package/dist/src/roster/lists.d.ts +195 -0
- package/dist/src/roster/lists.d.ts.map +1 -0
- package/dist/src/roster/lists.js +233 -0
- package/dist/src/roster/lists.js.map +1 -0
- package/dist/src/roster/rules.d.ts +17 -260
- package/dist/src/roster/rules.d.ts.map +1 -1
- package/dist/src/roster/rules.js +135 -132
- package/dist/src/roster/rules.js.map +1 -1
- package/dist/src/roster/targets.d.ts +115 -0
- package/dist/src/roster/targets.d.ts.map +1 -0
- package/dist/src/roster/targets.js +213 -0
- package/dist/src/roster/targets.js.map +1 -0
- package/dist/src/roster/times.d.ts +251 -0
- package/dist/src/roster/times.d.ts.map +1 -0
- package/dist/src/roster/times.js +174 -0
- package/dist/src/roster/times.js.map +1 -0
- package/dist/src/roster/types.d.ts +828 -183
- package/dist/src/roster/types.d.ts.map +1 -1
- package/dist/src/roster/types.js +224 -97
- package/dist/src/roster/types.js.map +1 -1
- package/dist/src/schedule/accessor.d.ts +28 -0
- package/dist/src/schedule/accessor.d.ts.map +1 -0
- package/dist/src/schedule/accessor.js +39 -0
- package/dist/src/schedule/accessor.js.map +1 -0
- package/dist/src/schedule/events.d.ts +170 -42
- package/dist/src/schedule/events.d.ts.map +1 -1
- package/dist/src/schedule/events.js +431 -171
- package/dist/src/schedule/events.js.map +1 -1
- package/dist/src/schedule/index.d.ts +41 -4
- package/dist/src/schedule/index.d.ts.map +1 -1
- package/dist/src/schedule/index.js +35 -3
- package/dist/src/schedule/index.js.map +1 -1
- package/dist/src/schedule/library.d.ts +13 -3
- package/dist/src/schedule/library.d.ts.map +1 -1
- package/dist/src/schedule/library.js +11 -4
- package/dist/src/schedule/library.js.map +1 -1
- package/dist/src/schedule/periods.d.ts +115 -0
- package/dist/src/schedule/periods.d.ts.map +1 -0
- package/dist/src/schedule/periods.js +215 -0
- package/dist/src/schedule/periods.js.map +1 -0
- package/dist/src/schedule/record-window.d.ts +25 -3
- package/dist/src/schedule/record-window.d.ts.map +1 -1
- package/dist/src/schedule/record-window.js +31 -18
- package/dist/src/schedule/record-window.js.map +1 -1
- package/dist/src/schedule/resources.d.ts +82 -4
- package/dist/src/schedule/resources.d.ts.map +1 -1
- package/dist/src/schedule/resources.js +44 -14
- package/dist/src/schedule/resources.js.map +1 -1
- package/dist/src/schedule/session.d.ts +69 -0
- package/dist/src/schedule/session.d.ts.map +1 -0
- package/dist/src/schedule/session.js +121 -0
- package/dist/src/schedule/session.js.map +1 -0
- package/dist/src/schedule/templates.d.ts +14 -2
- package/dist/src/schedule/templates.d.ts.map +1 -1
- package/dist/src/schedule/templates.js +5 -3
- package/dist/src/schedule/templates.js.map +1 -1
- package/dist/src/schedule/types.d.ts +1671 -37
- package/dist/src/schedule/types.d.ts.map +1 -1
- package/dist/src/schedule/types.js +196 -5
- package/dist/src/schedule/types.js.map +1 -1
- package/dist/src/schedule/window.d.ts +14 -0
- package/dist/src/schedule/window.d.ts.map +1 -1
- package/dist/src/schedule/window.js +14 -4
- package/dist/src/schedule/window.js.map +1 -1
- package/dist/src/schedule/words.d.ts +22 -0
- package/dist/src/schedule/words.d.ts.map +1 -0
- package/dist/src/schedule/words.js +25 -0
- package/dist/src/schedule/words.js.map +1 -0
- package/dist/src/sheet/index.d.ts +61 -27
- package/dist/src/sheet/index.d.ts.map +1 -1
- package/dist/src/sheet/index.js +59 -25
- package/dist/src/sheet/index.js.map +1 -1
- package/dist/src/sheet/library.d.ts +21 -3
- package/dist/src/sheet/library.d.ts.map +1 -1
- package/dist/src/sheet/library.js +23 -6
- package/dist/src/sheet/library.js.map +1 -1
- package/dist/src/sheet/registers.d.ts +100 -85
- package/dist/src/sheet/registers.d.ts.map +1 -1
- package/dist/src/sheet/registers.js +100 -85
- package/dist/src/sheet/registers.js.map +1 -1
- package/dist/src/sheet/root.d.ts +8 -12
- package/dist/src/sheet/root.d.ts.map +1 -1
- package/dist/src/sheet/root.js +6 -40
- package/dist/src/sheet/root.js.map +1 -1
- package/dist/src/sheet/sheet.d.ts +598 -2349
- package/dist/src/sheet/sheet.d.ts.map +1 -1
- package/dist/src/sheet/sheet.js +124 -37
- package/dist/src/sheet/sheet.js.map +1 -1
- package/dist/src/sheet/sub-rows.d.ts +74 -28
- package/dist/src/sheet/sub-rows.d.ts.map +1 -1
- package/dist/src/sheet/sub-rows.js +74 -28
- package/dist/src/sheet/sub-rows.js.map +1 -1
- package/dist/src/sheet/templates.d.ts +98 -34
- package/dist/src/sheet/templates.d.ts.map +1 -1
- package/dist/src/sheet/templates.js +102 -58
- package/dist/src/sheet/templates.js.map +1 -1
- package/dist/src/sheet/types.d.ts +289 -1359
- package/dist/src/sheet/types.d.ts.map +1 -1
- package/dist/src/sheet/types.js +20 -26
- package/dist/src/sheet/types.js.map +1 -1
- package/dist/src/sheet/views.d.ts +10 -11
- package/dist/src/sheet/views.d.ts.map +1 -1
- package/dist/src/sheet/views.js +15 -20
- package/dist/src/sheet/views.js.map +1 -1
- package/dist/src/{roster/visibility.d.ts → utils/key-visibility.d.ts} +42 -7
- package/dist/src/utils/key-visibility.d.ts.map +1 -0
- package/dist/src/utils/key-visibility.js +36 -0
- package/dist/src/utils/key-visibility.js.map +1 -0
- package/dist/src/utils/ordered-source.d.ts +1 -0
- package/dist/src/utils/ordered-source.d.ts.map +1 -1
- package/dist/src/utils/ordered-source.js +8 -3
- package/dist/src/utils/ordered-source.js.map +1 -1
- package/dist/src/utils/record-sources.d.ts +107 -0
- package/dist/src/utils/record-sources.d.ts.map +1 -0
- package/dist/src/utils/record-sources.js +132 -0
- package/dist/src/utils/record-sources.js.map +1 -0
- package/dist/test/allocation/allocation.examples.d.ts +2902 -0
- package/dist/test/allocation/allocation.examples.d.ts.map +1 -0
- package/dist/test/allocation/allocation.examples.js +643 -0
- package/dist/test/allocation/allocation.examples.js.map +1 -0
- package/dist/test/allocation/fit.examples.d.ts +546 -0
- package/dist/test/allocation/fit.examples.d.ts.map +1 -0
- package/dist/test/allocation/fit.examples.js +171 -0
- package/dist/test/allocation/fit.examples.js.map +1 -0
- package/dist/test/allocation/kiln-yard.d.ts +181 -0
- package/dist/test/allocation/kiln-yard.d.ts.map +1 -0
- package/dist/test/allocation/kiln-yard.js +228 -0
- package/dist/test/allocation/kiln-yard.js.map +1 -0
- package/dist/test/bind/data/data.examples.d.ts +651 -1
- package/dist/test/bind/data/data.examples.d.ts.map +1 -1
- package/dist/test/bind/data/data.examples.js +140 -2
- package/dist/test/bind/data/data.examples.js.map +1 -1
- package/dist/test/bind/func/func.examples.d.ts +10 -1
- package/dist/test/bind/func/func.examples.d.ts.map +1 -1
- package/dist/test/bind/func/func.examples.js +8 -1
- package/dist/test/bind/func/func.examples.js.map +1 -1
- package/dist/test/bind/record/record.examples.d.ts +633 -1
- package/dist/test/bind/record/record.examples.d.ts.map +1 -1
- package/dist/test/bind/record/record.examples.js +26 -2
- package/dist/test/bind/record/record.examples.js.map +1 -1
- package/dist/test/calendar/calendar-records.examples.d.ts.map +1 -1
- package/dist/test/calendar/calendar-records.examples.js +18 -14
- package/dist/test/calendar/calendar-records.examples.js.map +1 -1
- package/dist/test/calendar/calendar.examples.d.ts +521 -16
- package/dist/test/calendar/calendar.examples.d.ts.map +1 -1
- package/dist/test/calendar/calendar.examples.js +182 -135
- package/dist/test/calendar/calendar.examples.js.map +1 -1
- package/dist/test/examples-package.d.ts +75 -0
- package/dist/test/examples-package.d.ts.map +1 -0
- package/dist/test/examples-package.js +263 -0
- package/dist/test/examples-package.js.map +1 -0
- package/dist/test/flowchart/flowchart.examples.d.ts +211 -19
- package/dist/test/flowchart/flowchart.examples.d.ts.map +1 -1
- package/dist/test/flowchart/flowchart.examples.js +102 -75
- package/dist/test/flowchart/flowchart.examples.js.map +1 -1
- package/dist/test/plan/plan-events.examples.d.ts +1439 -209
- package/dist/test/plan/plan-events.examples.d.ts.map +1 -1
- package/dist/test/plan/plan-events.examples.js +199 -59
- package/dist/test/plan/plan-events.examples.js.map +1 -1
- package/dist/test/plan/plan-records.examples.d.ts +420 -0
- package/dist/test/plan/plan-records.examples.d.ts.map +1 -1
- package/dist/test/plan/plan-records.examples.js +70 -19
- package/dist/test/plan/plan-records.examples.js.map +1 -1
- package/dist/test/plan/plan-windows.examples.d.ts +636 -55
- package/dist/test/plan/plan-windows.examples.d.ts.map +1 -1
- package/dist/test/plan/plan-windows.examples.js +69 -33
- package/dist/test/plan/plan-windows.examples.js.map +1 -1
- package/dist/test/plan/plan.examples.d.ts +153 -31
- package/dist/test/plan/plan.examples.d.ts.map +1 -1
- package/dist/test/plan/plan.examples.js +178 -101
- package/dist/test/plan/plan.examples.js.map +1 -1
- package/dist/test/roster/domain.examples.d.ts +467 -250
- package/dist/test/roster/domain.examples.d.ts.map +1 -1
- package/dist/test/roster/domain.examples.js +92 -29
- package/dist/test/roster/domain.examples.js.map +1 -1
- package/dist/test/roster/roster-records.examples.d.ts +430 -586
- package/dist/test/roster/roster-records.examples.d.ts.map +1 -1
- package/dist/test/roster/roster-records.examples.js +102 -43
- package/dist/test/roster/roster-records.examples.js.map +1 -1
- package/dist/test/roster/roster.examples.d.ts +2319 -606
- package/dist/test/roster/roster.examples.d.ts.map +1 -1
- package/dist/test/roster/roster.examples.js +456 -148
- package/dist/test/roster/roster.examples.js.map +1 -1
- package/dist/test/roster/warehouse.d.ts +172 -63
- package/dist/test/roster/warehouse.d.ts.map +1 -1
- package/dist/test/roster/warehouse.js +172 -39
- package/dist/test/roster/warehouse.js.map +1 -1
- package/dist/test/schedule/schedule.examples.d.ts +3499 -0
- package/dist/test/schedule/schedule.examples.d.ts.map +1 -0
- package/dist/test/schedule/schedule.examples.js +192 -0
- package/dist/test/schedule/schedule.examples.js.map +1 -0
- package/dist/test/sheet/sheet-records.examples.d.ts.map +1 -1
- package/dist/test/sheet/sheet-records.examples.js +22 -18
- package/dist/test/sheet/sheet-records.examples.js.map +1 -1
- package/dist/test/sheet/sheet.examples.d.ts +715 -26
- package/dist/test/sheet/sheet.examples.d.ts.map +1 -1
- package/dist/test/sheet/sheet.examples.js +204 -130
- package/dist/test/sheet/sheet.examples.js.map +1 -1
- package/package.json +17 -10
- package/dist/src/roster/people.d.ts +0 -50
- package/dist/src/roster/people.d.ts.map +0 -1
- package/dist/src/roster/people.js +0 -32
- package/dist/src/roster/people.js.map +0 -1
- package/dist/src/roster/visibility.d.ts.map +0 -1
- package/dist/src/roster/visibility.js +0 -25
- package/dist/src/roster/visibility.js.map +0 -1
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* `Roster.targets(record, config)` (#1368, `Builder Interfaces Spec.md`
|
|
7
|
+
* §5.2): the staffing targets the Roster writes, the app's own record — a row
|
|
8
|
+
* per slot, its fields mapped to the Roster's roles: the slot's day, group and
|
|
9
|
+
* shift, the positions to fill, and the hours each activity needs. The app's
|
|
10
|
+
* forecast fills it; the planner edits it.
|
|
11
|
+
*
|
|
12
|
+
* - **Roles.** Each names a field of the row: `day` a DateTime (a UTC
|
|
13
|
+
* midnight), `group` and `shift` Strings, `positions` an Integer, `hours` a
|
|
14
|
+
* `Dict<String, Float>`. An edit writes only those fields; every other field
|
|
15
|
+
* of the row reads back as it was.
|
|
16
|
+
* - **New rows.** A slot with no row has no target. A target edit on such a
|
|
17
|
+
* slot inserts one, keyed by a key the Roster mints, its unmapped fields
|
|
18
|
+
* their type's default.
|
|
19
|
+
* - **Reads.** Through the Roster's slice, by its `targets` source — an
|
|
20
|
+
* interval index from the day to the day, its `range` the day field — and
|
|
21
|
+
* then `entries` reads one target by its key; or the record whole.
|
|
22
|
+
* - **The inspector.** The app's own form for one target, `(row, update) =>
|
|
23
|
+
* UIComponentType`, in place of the Roster's.
|
|
24
|
+
*
|
|
25
|
+
* The targets are one session of the Roster's history (`session.ts`), as its
|
|
26
|
+
* duties and its periods are: Save sends their changes through the record's
|
|
27
|
+
* patch door as a request of their own.
|
|
28
|
+
*
|
|
29
|
+
* @packageDocumentation
|
|
30
|
+
*/
|
|
31
|
+
import { BlobType, DateTimeType, DictType, East, Expr, FloatType, IntegerType, NullType, OptionType, StringType, defaultValue, isTypeEqual, none, some, toEastTypeValue, } from "@elaraai/east";
|
|
32
|
+
import { scheduleRecordWindow } from "../schedule/record-window.js";
|
|
33
|
+
import { scheduleRecordSession } from "../schedule/session.js";
|
|
34
|
+
import { checkEntries, typeText } from "../schedule/window.js";
|
|
35
|
+
import { RowInspectorType, rowInspector } from "../utils/row-inspector.js";
|
|
36
|
+
import { RosterTargetEntryType, RosterTargetRolesType, RosterTargetsKindType } from "./types.js";
|
|
37
|
+
/** The key the targets' declaration carries what it is under. */
|
|
38
|
+
export const ROSTER_TARGETS = Symbol("Roster.targets");
|
|
39
|
+
/** A field of a struct as an East expression, by name. */
|
|
40
|
+
function fieldOf(row, name) {
|
|
41
|
+
return row[name];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Declares the app's targets (see the module docs).
|
|
45
|
+
*
|
|
46
|
+
* @typeParam R - The app's target row type
|
|
47
|
+
* @param record - The app's record of targets, `Record.bind(record, [e3.mutation.patch(record)])`: a `Dict` keyed by String
|
|
48
|
+
* @param config - The fields its roles name, the app's own form, and its read by key
|
|
49
|
+
* @returns The targets, for the Roster's `targets`
|
|
50
|
+
* @throws {Error} Naming the option: a record not bound with its patch mutation, not keyed by String, or whose rows are no
|
|
51
|
+
* structs; a role naming a field the row lacks, or a field of another type; two roles naming one field; `entries`
|
|
52
|
+
* that is not a paged read of the record's own entries; and an `inspector` that is no East function `(row, update) =>
|
|
53
|
+
* UIComponentType` over the row
|
|
54
|
+
* @example
|
|
55
|
+
* ```tsx
|
|
56
|
+
* import { DateTimeType, DictType, FloatType, IntegerType, StringType, StructType } from "@elaraai/east";
|
|
57
|
+
* import { Record, Roster } from "@elaraai/e3-ui";
|
|
58
|
+
* import e3 from "@elaraai/e3";
|
|
59
|
+
*
|
|
60
|
+
* const Cover = StructType({ day: DateTimeType, team: StringType, shift: StringType, heads: IntegerType, hours: DictType(StringType, FloatType) });
|
|
61
|
+
* const cover = e3.record("cover", DictType(StringType, Cover), new Map());
|
|
62
|
+
* const coverPatch = e3.mutation.patch(cover);
|
|
63
|
+
*
|
|
64
|
+
* // Inside the Roster's Reactive body: a target per slot, over the app's own rows.
|
|
65
|
+
* const targets = Roster.targets(Record.bind(cover, [coverPatch]), { day: "day", group: "team", shift: "shift", positions: "heads", hours: "hours" });
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function rosterTargets(record, config) {
|
|
69
|
+
const where = "Roster.targets";
|
|
70
|
+
const c = config;
|
|
71
|
+
const handleType = Expr.type(record);
|
|
72
|
+
const read = handleType.type === "Struct" ? handleType.fields["read"] : undefined;
|
|
73
|
+
if (handleType.type !== "Struct" || read === undefined || read.type !== "Function"
|
|
74
|
+
|| handleType.fields["binding"] === undefined) {
|
|
75
|
+
throw new Error(`${where}: \`record\` is the app's record of targets, bound with its patch mutation — Record.bind(record, [e3.mutation.patch(record)])`);
|
|
76
|
+
}
|
|
77
|
+
const recordType = read.output;
|
|
78
|
+
if (recordType.type !== "Dict" || !isTypeEqual(recordType.key, StringType)) {
|
|
79
|
+
throw new Error(`${where}: a target is keyed by a String — the Roster mints a new target's key — and this record holds ${typeText(recordType)}`);
|
|
80
|
+
}
|
|
81
|
+
const rowType = recordType.value;
|
|
82
|
+
if (rowType.type !== "Struct") {
|
|
83
|
+
throw new Error(`${where}: a target's row is a struct of the app's fields, its roles among them — and this record's rows are ${typeText(rowType)}`);
|
|
84
|
+
}
|
|
85
|
+
const fields = rowType.fields;
|
|
86
|
+
// Each role a field of the row, of the role's type.
|
|
87
|
+
const role = (prop, name, type, what) => {
|
|
88
|
+
if (typeof name !== "string")
|
|
89
|
+
throw new Error(`${where}: \`${prop}\` names ${what} of the row`);
|
|
90
|
+
const held = fields[name];
|
|
91
|
+
if (held === undefined)
|
|
92
|
+
throw new Error(`${where}: \`${prop}\` names "${name}", a field the row does not have (${Object.keys(fields).join(", ")})`);
|
|
93
|
+
if (!isTypeEqual(held, type))
|
|
94
|
+
throw new Error(`${where}: \`${prop}\` names ${what} — "${name}" holds ${typeText(held)}`);
|
|
95
|
+
return name;
|
|
96
|
+
};
|
|
97
|
+
const day = role("day", c.day, DateTimeType, "a DateTime field, the slot's day");
|
|
98
|
+
const group = role("group", c.group, StringType, "a String field, the slot's group");
|
|
99
|
+
const shift = role("shift", c.shift, StringType, "a String field, the slot's shift");
|
|
100
|
+
const positions = role("positions", c.positions, IntegerType, "an Integer field, the positions to fill");
|
|
101
|
+
const hours = role("hours", c.hours, DictType(StringType, FloatType), "a Dict of String to Float field, the hours each activity needs");
|
|
102
|
+
// The Roster writes each role into a field of its own.
|
|
103
|
+
const named = new Map();
|
|
104
|
+
for (const [prop, name] of [["day", day], ["group", group], ["shift", shift], ["positions", positions], ["hours", hours]]) {
|
|
105
|
+
const prior = named.get(name);
|
|
106
|
+
if (prior !== undefined)
|
|
107
|
+
throw new Error(`${where}: \`${prior}\` and \`${prop}\` both name "${name}" — the Roster writes each of its roles into a field of its own`);
|
|
108
|
+
named.set(name, prop);
|
|
109
|
+
}
|
|
110
|
+
const inspector = c.inspector === undefined ? undefined : rowInspector(c.inspector, rowType, `${where}: \`inspector\` is the app's own form for one target — an East.function over the target's row and its writer: ` +
|
|
111
|
+
"East.function([RowType, FunctionType([RowType], NullType)], UIComponentType, ($, row, update) => …), RowType the record's row");
|
|
112
|
+
// The targets read by key, or whole; and their session, declared now, so a record bound without its patch door is refused here.
|
|
113
|
+
const entries = c.entries === undefined ? undefined : checkEntries(c.entries, StringType, rowType, `${where}: \`entries\``);
|
|
114
|
+
const session = scheduleRecordSession(record, StringType, rowType, entries);
|
|
115
|
+
return {
|
|
116
|
+
[ROSTER_TARGETS]: true,
|
|
117
|
+
rowType,
|
|
118
|
+
build(part) {
|
|
119
|
+
if (part === undefined && entries !== undefined) {
|
|
120
|
+
throw new Error(`${where}: \`entries\` reads one target by its key beside the Roster's slice's \`targets\` source, which reads the week's — ` +
|
|
121
|
+
"give that source with it, or leave `entries` out to read the record whole");
|
|
122
|
+
}
|
|
123
|
+
if (part !== undefined && entries === undefined) {
|
|
124
|
+
throw new Error(`${where}: the Roster's slice's \`targets\` source reads only the week's targets — and one target, its editing's, ` +
|
|
125
|
+
"is read by its key: give `entries` beside it, Data.bindPaged(record), the record's own entries");
|
|
126
|
+
}
|
|
127
|
+
// The week's targets through the slice's source — its interval index from the day to the day — or the record whole.
|
|
128
|
+
const window = part === undefined ? undefined
|
|
129
|
+
: scheduleRecordWindow(part, "targets", StringType, rowType, day, day, false, false, where);
|
|
130
|
+
const { editing, entries: seam } = session.build();
|
|
131
|
+
const Roles = RosterTargetRolesType;
|
|
132
|
+
// A row's roles: the slot's day, group and shift, its positions and its hours.
|
|
133
|
+
const rolesOf = East.function([rowType], Roles, (_$, row) => ({
|
|
134
|
+
day: fieldOf(row, day), group: fieldOf(row, group),
|
|
135
|
+
shift: fieldOf(row, shift), positions: fieldOf(row, positions),
|
|
136
|
+
hours: fieldOf(row, hours),
|
|
137
|
+
}));
|
|
138
|
+
// The row with its roles written from `roles`, and every other field from `source`.
|
|
139
|
+
const rowWith = (source, roles) => East.value(Object.fromEntries(Object.keys(fields).map((f) => [f,
|
|
140
|
+
f === day ? roles.day
|
|
141
|
+
: f === group ? roles.group
|
|
142
|
+
: f === shift ? roles.shift
|
|
143
|
+
: f === positions ? roles.positions
|
|
144
|
+
: f === hours ? roles.hours
|
|
145
|
+
: fieldOf(source, f)])), rowType);
|
|
146
|
+
const RowsType = OptionType(DictType(StringType, RosterTargetEntryType));
|
|
147
|
+
// Erased as the record's own read is, so the record whole and a window of it are one type.
|
|
148
|
+
const HeldType = DictType(StringType, rowType);
|
|
149
|
+
const rows = East.function([DateTimeType, DateTimeType], RowsType, ($, from, to) => {
|
|
150
|
+
const roles = $.const(rolesOf);
|
|
151
|
+
const result = $.let(East.value(none, RowsType), RowsType);
|
|
152
|
+
let held;
|
|
153
|
+
if (window === undefined) {
|
|
154
|
+
held = $.let(East.value(some(session.readAll()), OptionType(HeldType)));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const read = $.const(window);
|
|
158
|
+
held = $.let(read(from, to));
|
|
159
|
+
}
|
|
160
|
+
$.match(held, {
|
|
161
|
+
some: ($2, all) => {
|
|
162
|
+
const out = $2.let(new Map(), DictType(StringType, RosterTargetEntryType));
|
|
163
|
+
$2.for(all, ($3, row, key) => {
|
|
164
|
+
const at = $3.const(fieldOf(row, day));
|
|
165
|
+
$3.if(East.greaterEqual(at, from).and(() => East.less(at, to)), ($4) => {
|
|
166
|
+
$4(out.insert(key, { roles: roles(row), row: East.Blob.encodeBeast(row, "v2") }));
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
$2.assign(result, East.value(some(out), RowsType));
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
return result;
|
|
173
|
+
});
|
|
174
|
+
const readRoles = East.function([BlobType], Roles, ($, bytes) => {
|
|
175
|
+
const of = $.const(rolesOf);
|
|
176
|
+
return of(bytes.decodeBeast(rowType, "v2"));
|
|
177
|
+
});
|
|
178
|
+
const write = East.function([BlobType, Roles], BlobType, ($, bytes, roles) => {
|
|
179
|
+
const row = $.const(bytes.decodeBeast(rowType, "v2"));
|
|
180
|
+
return East.Blob.encodeBeast(rowWith(row, roles), "v2");
|
|
181
|
+
});
|
|
182
|
+
// A new target: its roles written, and every other field its type's default.
|
|
183
|
+
const blank = East.value(defaultValue(rowType), rowType);
|
|
184
|
+
const create = East.function([Roles], BlobType, ($, roles) => {
|
|
185
|
+
const row = $.const(blank);
|
|
186
|
+
return East.Blob.encodeBeast(rowWith(row, roles), "v2");
|
|
187
|
+
});
|
|
188
|
+
return East.value({
|
|
189
|
+
editing,
|
|
190
|
+
entries: seam,
|
|
191
|
+
rows,
|
|
192
|
+
read: readRoles,
|
|
193
|
+
write,
|
|
194
|
+
create,
|
|
195
|
+
history: session.history,
|
|
196
|
+
inspector: inspector === undefined ? East.value(none, OptionType(RowInspectorType)) : East.value(some(inspector), OptionType(RowInspectorType)),
|
|
197
|
+
rowType: toEastTypeValue(rowType),
|
|
198
|
+
}, RosterTargetsKindType);
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Whether a value is the app's targets, declared (`Roster.targets`): what the
|
|
204
|
+
* Roster's `targets` checks before it takes one.
|
|
205
|
+
*
|
|
206
|
+
* @param value - What the app passed
|
|
207
|
+
* @returns Whether it is the targets, declared
|
|
208
|
+
* @internal
|
|
209
|
+
*/
|
|
210
|
+
export function isRosterTargets(value) {
|
|
211
|
+
return typeof value === "object" && value !== null && value[ROSTER_TARGETS] === true;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=targets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.js","sourceRoot":"","sources":["../../../src/roster/targets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* What the Roster reads from a duty's times (#1368, `Builder Interfaces
|
|
7
|
+
* Spec.md` §5.5): pure East functions, compiled once by the renderer, so a
|
|
8
|
+
* task and the screen use the same arithmetic.
|
|
9
|
+
*
|
|
10
|
+
* - **Day.** A duty's day is the UTC day whose shift start is nearest the
|
|
11
|
+
* duty's start ({@link rosterDayOf}); its week is the week holding that day.
|
|
12
|
+
* - **A duty**, as the Roster reads it, is its kind's roles and its row
|
|
13
|
+
* ({@link rosterPlacement}): its slot, from its day, its group and its
|
|
14
|
+
* shift; who it is, from its resource; its position, its activity, its own
|
|
15
|
+
* times and its hours. A duty whose shift or group isn't configured, or that
|
|
16
|
+
* names no one, is placed nowhere: the Roster lists it in Issues and keeps
|
|
17
|
+
* it as stored.
|
|
18
|
+
* - **A move** to another slot ({@link rosterMove}) moves the duty's start
|
|
19
|
+
* and end with it, kept where they stood against its shift's start, and
|
|
20
|
+
* writes its shift and group: a move and back leaves its times as they were.
|
|
21
|
+
* - **A new duty** ({@link rosterNewDuty}) runs its slot's shift: from the
|
|
22
|
+
* shift's start on its day ({@link rosterShiftStart}), for the shift's
|
|
23
|
+
* hours. Copying the week before copies each duty so, its other fields as
|
|
24
|
+
* they were.
|
|
25
|
+
*
|
|
26
|
+
* @packageDocumentation
|
|
27
|
+
*/
|
|
28
|
+
import { DateTimeType, IntegerType, OptionType, StringType, type EastType, type ExprType, type FunctionType } from "@elaraai/east";
|
|
29
|
+
import { ScheduleRosterRolesType } from "../schedule/types.js";
|
|
30
|
+
import { RosterContextType, RosterPlacementTypeFor } from "./types.js";
|
|
31
|
+
/**
|
|
32
|
+
* A duty's day (§5.5, rule 1): the UTC midnight of the day whose shift start is
|
|
33
|
+
* nearest the duty's start.
|
|
34
|
+
*
|
|
35
|
+
* @param start - The duty's start
|
|
36
|
+
* @param clock - Its shift's start, a time of day
|
|
37
|
+
* @returns Its day, a UTC midnight
|
|
38
|
+
* @remarks The shift starts on the duty's day within 12 hours of the duty's start, so the day is the one `start` falls in once moved back by the shift's start and on by 12 hours: an early start (`05:00` on the `06:00` shift) is the shift's day, and a night shift's duty past midnight (`00:30` on the `22:00` shift) the night before's.
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export declare const rosterDayOf: import("@elaraai/east").CallableFunctionExpr<[DateTimeType, import("@elaraai/east").StructType<{
|
|
42
|
+
readonly hour: IntegerType;
|
|
43
|
+
readonly minute: IntegerType;
|
|
44
|
+
}>], DateTimeType>;
|
|
45
|
+
/**
|
|
46
|
+
* A shift's start on a day (§5.5, rule 5): where a new duty of the shift
|
|
47
|
+
* starts, and what a duty's own times are drawn against.
|
|
48
|
+
*
|
|
49
|
+
* @param day - The day, a UTC midnight
|
|
50
|
+
* @param shift - The shift
|
|
51
|
+
* @returns Its start on that day
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export declare const rosterShiftStart: import("@elaraai/east").CallableFunctionExpr<[DateTimeType, import("@elaraai/east").StructType<{
|
|
55
|
+
readonly key: StringType;
|
|
56
|
+
readonly label: StringType;
|
|
57
|
+
readonly code: StringType;
|
|
58
|
+
readonly start: import("@elaraai/east").StructType<{
|
|
59
|
+
readonly hour: IntegerType;
|
|
60
|
+
readonly minute: IntegerType;
|
|
61
|
+
}>;
|
|
62
|
+
readonly hours: import("@elaraai/east").FloatType;
|
|
63
|
+
}>], DateTimeType>;
|
|
64
|
+
/**
|
|
65
|
+
* Reads one duty as the Roster does: its kind's roles and its row, in the week
|
|
66
|
+
* of `start`.
|
|
67
|
+
*
|
|
68
|
+
* @typeParam R - The app's duty row type
|
|
69
|
+
* @param row - The app's duty row type
|
|
70
|
+
* @returns An East function `(roles, row, key, start, context) → Placement(R)`: the duty placed in the week of
|
|
71
|
+
* `start`; `elsewhere` for a duty whose day falls in another week; `unplaced`, with the issue that lists it, for a
|
|
72
|
+
* duty of this week whose shift or group isn't configured, or that names no person and no agency
|
|
73
|
+
* @remarks The duty kind's resource names the `people` slot for a person and the `agencies` slot for an agency's request; a kind with no `position` role holds none, `""`. A duty of a shift not configured has no shift start to be nearest: its day is the UTC day it starts.
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
76
|
+
export declare function rosterPlacement<R extends EastType>(row: R): ExprType<FunctionType<[ScheduleRosterRolesType, R, StringType, DateTimeType, RosterContextType], RosterPlacementTypeFor<R>>>;
|
|
77
|
+
/**
|
|
78
|
+
* A duty moved to a slot (§5.5, rule 3): its start and end moved with it,
|
|
79
|
+
* kept where they stood against its shift's start, and its shift and group
|
|
80
|
+
* written.
|
|
81
|
+
*
|
|
82
|
+
* @param roles - The duty's roles
|
|
83
|
+
* @param start - The week's first day, a UTC midnight
|
|
84
|
+
* @param slot - The slot it moves to
|
|
85
|
+
* @param context - The configuration
|
|
86
|
+
* @returns Its roles, moved; `none` for a slot whose shift or group isn't configured
|
|
87
|
+
* @remarks Its length is kept, and its start stands as far from the slot's shift's start as it stood from its own: a move and back leaves its times as they were. A duty of a shift not configured has no start to stand against, and starts the slot's shift.
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
export declare const rosterMove: import("@elaraai/east").CallableFunctionExpr<[import("@elaraai/east").StructType<{
|
|
91
|
+
readonly start: DateTimeType;
|
|
92
|
+
readonly end: DateTimeType;
|
|
93
|
+
readonly resource: OptionType<import("@elaraai/east").StructType<{
|
|
94
|
+
readonly kind: StringType;
|
|
95
|
+
readonly key: StringType;
|
|
96
|
+
}>>;
|
|
97
|
+
readonly shift: StringType;
|
|
98
|
+
readonly group: StringType;
|
|
99
|
+
readonly position: OptionType<StringType>;
|
|
100
|
+
readonly activity: OptionType<StringType>;
|
|
101
|
+
readonly hours: import("@elaraai/east").FloatType;
|
|
102
|
+
}>, DateTimeType, import("@elaraai/east").StructType<{
|
|
103
|
+
readonly day: IntegerType;
|
|
104
|
+
readonly group: StringType;
|
|
105
|
+
readonly shift: StringType;
|
|
106
|
+
}>, import("@elaraai/east").StructType<{
|
|
107
|
+
readonly people: import("@elaraai/east").DictType<StringType, import("@elaraai/east").StructType<{
|
|
108
|
+
readonly key: StringType;
|
|
109
|
+
readonly name: StringType;
|
|
110
|
+
readonly group: StringType;
|
|
111
|
+
readonly position: StringType;
|
|
112
|
+
readonly skills: import("@elaraai/east").SetType<StringType>;
|
|
113
|
+
readonly contract: import("@elaraai/east").FloatType;
|
|
114
|
+
readonly agency: import("@elaraai/east").BooleanType;
|
|
115
|
+
readonly trainer: import("@elaraai/east").BooleanType;
|
|
116
|
+
readonly trainee: import("@elaraai/east").BooleanType;
|
|
117
|
+
readonly usual: OptionType<StringType>;
|
|
118
|
+
}>>;
|
|
119
|
+
readonly groups: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
120
|
+
readonly key: StringType;
|
|
121
|
+
readonly label: StringType;
|
|
122
|
+
}>>;
|
|
123
|
+
readonly activities: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
124
|
+
readonly key: StringType;
|
|
125
|
+
readonly label: StringType;
|
|
126
|
+
readonly code: StringType;
|
|
127
|
+
readonly group: OptionType<StringType>;
|
|
128
|
+
}>>;
|
|
129
|
+
readonly shifts: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
130
|
+
readonly key: StringType;
|
|
131
|
+
readonly label: StringType;
|
|
132
|
+
readonly code: StringType;
|
|
133
|
+
readonly start: import("@elaraai/east").StructType<{
|
|
134
|
+
readonly hour: IntegerType;
|
|
135
|
+
readonly minute: IntegerType;
|
|
136
|
+
}>;
|
|
137
|
+
readonly hours: import("@elaraai/east").FloatType;
|
|
138
|
+
}>>;
|
|
139
|
+
readonly positions: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
140
|
+
readonly key: StringType;
|
|
141
|
+
readonly label: StringType;
|
|
142
|
+
readonly code: StringType;
|
|
143
|
+
readonly lead: import("@elaraai/east").BooleanType;
|
|
144
|
+
}>>;
|
|
145
|
+
readonly agencies: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
146
|
+
readonly key: StringType;
|
|
147
|
+
readonly name: StringType;
|
|
148
|
+
}>>;
|
|
149
|
+
readonly rules: import("@elaraai/east").StructType<{
|
|
150
|
+
readonly rest: import("@elaraai/east").FloatType;
|
|
151
|
+
readonly lead: import("@elaraai/east").BooleanType;
|
|
152
|
+
readonly trainer: import("@elaraai/east").BooleanType;
|
|
153
|
+
readonly skill: import("@elaraai/east").BooleanType;
|
|
154
|
+
}>;
|
|
155
|
+
}>], OptionType<import("@elaraai/east").StructType<{
|
|
156
|
+
readonly start: DateTimeType;
|
|
157
|
+
readonly end: DateTimeType;
|
|
158
|
+
readonly resource: OptionType<import("@elaraai/east").StructType<{
|
|
159
|
+
readonly kind: StringType;
|
|
160
|
+
readonly key: StringType;
|
|
161
|
+
}>>;
|
|
162
|
+
readonly shift: StringType;
|
|
163
|
+
readonly group: StringType;
|
|
164
|
+
readonly position: OptionType<StringType>;
|
|
165
|
+
readonly activity: OptionType<StringType>;
|
|
166
|
+
readonly hours: import("@elaraai/east").FloatType;
|
|
167
|
+
}>>>;
|
|
168
|
+
/**
|
|
169
|
+
* A new duty (§5.5, rule 5): it runs its slot's shift, from the shift's start
|
|
170
|
+
* on its day, for the shift's hours.
|
|
171
|
+
*
|
|
172
|
+
* @param who - Who it is: a person, or an agency asked to send someone
|
|
173
|
+
* @param slot - Its slot
|
|
174
|
+
* @param start - The week's first day, a UTC midnight
|
|
175
|
+
* @param position - The position it holds; `none` for a kind with no `position` role
|
|
176
|
+
* @param activity - Its activity, if any
|
|
177
|
+
* @param context - The configuration
|
|
178
|
+
* @returns Its roles; `none` for a slot whose shift or group isn't configured
|
|
179
|
+
* @remarks A person is a key of the `people` resource kind, an agency of the `agencies` one. Its hours are the shift's, until its row says otherwise. Copying the week before runs each of its duties so, written over its own row.
|
|
180
|
+
* @internal
|
|
181
|
+
*/
|
|
182
|
+
export declare const rosterNewDuty: import("@elaraai/east").CallableFunctionExpr<[import("@elaraai/east").VariantType<{
|
|
183
|
+
readonly person: StringType;
|
|
184
|
+
readonly request: StringType;
|
|
185
|
+
}>, import("@elaraai/east").StructType<{
|
|
186
|
+
readonly day: IntegerType;
|
|
187
|
+
readonly group: StringType;
|
|
188
|
+
readonly shift: StringType;
|
|
189
|
+
}>, DateTimeType, OptionType<StringType>, OptionType<StringType>, import("@elaraai/east").StructType<{
|
|
190
|
+
readonly people: import("@elaraai/east").DictType<StringType, import("@elaraai/east").StructType<{
|
|
191
|
+
readonly key: StringType;
|
|
192
|
+
readonly name: StringType;
|
|
193
|
+
readonly group: StringType;
|
|
194
|
+
readonly position: StringType;
|
|
195
|
+
readonly skills: import("@elaraai/east").SetType<StringType>;
|
|
196
|
+
readonly contract: import("@elaraai/east").FloatType;
|
|
197
|
+
readonly agency: import("@elaraai/east").BooleanType;
|
|
198
|
+
readonly trainer: import("@elaraai/east").BooleanType;
|
|
199
|
+
readonly trainee: import("@elaraai/east").BooleanType;
|
|
200
|
+
readonly usual: OptionType<StringType>;
|
|
201
|
+
}>>;
|
|
202
|
+
readonly groups: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
203
|
+
readonly key: StringType;
|
|
204
|
+
readonly label: StringType;
|
|
205
|
+
}>>;
|
|
206
|
+
readonly activities: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
207
|
+
readonly key: StringType;
|
|
208
|
+
readonly label: StringType;
|
|
209
|
+
readonly code: StringType;
|
|
210
|
+
readonly group: OptionType<StringType>;
|
|
211
|
+
}>>;
|
|
212
|
+
readonly shifts: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
213
|
+
readonly key: StringType;
|
|
214
|
+
readonly label: StringType;
|
|
215
|
+
readonly code: StringType;
|
|
216
|
+
readonly start: import("@elaraai/east").StructType<{
|
|
217
|
+
readonly hour: IntegerType;
|
|
218
|
+
readonly minute: IntegerType;
|
|
219
|
+
}>;
|
|
220
|
+
readonly hours: import("@elaraai/east").FloatType;
|
|
221
|
+
}>>;
|
|
222
|
+
readonly positions: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
223
|
+
readonly key: StringType;
|
|
224
|
+
readonly label: StringType;
|
|
225
|
+
readonly code: StringType;
|
|
226
|
+
readonly lead: import("@elaraai/east").BooleanType;
|
|
227
|
+
}>>;
|
|
228
|
+
readonly agencies: import("@elaraai/east").ArrayType<import("@elaraai/east").StructType<{
|
|
229
|
+
readonly key: StringType;
|
|
230
|
+
readonly name: StringType;
|
|
231
|
+
}>>;
|
|
232
|
+
readonly rules: import("@elaraai/east").StructType<{
|
|
233
|
+
readonly rest: import("@elaraai/east").FloatType;
|
|
234
|
+
readonly lead: import("@elaraai/east").BooleanType;
|
|
235
|
+
readonly trainer: import("@elaraai/east").BooleanType;
|
|
236
|
+
readonly skill: import("@elaraai/east").BooleanType;
|
|
237
|
+
}>;
|
|
238
|
+
}>], OptionType<import("@elaraai/east").StructType<{
|
|
239
|
+
readonly start: DateTimeType;
|
|
240
|
+
readonly end: DateTimeType;
|
|
241
|
+
readonly resource: OptionType<import("@elaraai/east").StructType<{
|
|
242
|
+
readonly kind: StringType;
|
|
243
|
+
readonly key: StringType;
|
|
244
|
+
}>>;
|
|
245
|
+
readonly shift: StringType;
|
|
246
|
+
readonly group: StringType;
|
|
247
|
+
readonly position: OptionType<StringType>;
|
|
248
|
+
readonly activity: OptionType<StringType>;
|
|
249
|
+
readonly hours: import("@elaraai/east").FloatType;
|
|
250
|
+
}>>>;
|
|
251
|
+
//# sourceMappingURL=times.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"times.d.ts","sourceRoot":"","sources":["../../../src/roster/times.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EACH,YAAY,EAAQ,WAAW,EAAE,UAAU,EAAE,UAAU,EACvD,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAClD,MAAM,eAAe,CAAC;AACvB,OAAO,EAA8C,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC3G,OAAO,EAAE,iBAAiB,EAAmB,sBAAsB,EAAkD,MAAM,YAAY,CAAC;AAExI;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW;;;kBAGtB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;kBAC8C,CAAC;AAE5E;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,QAAQ,EAAE,GAAG,EAAE,CAAC,GA6CrC,QAAQ,CAAC,YAAY,CAAC,CAAC,uBAAuB,EAAE,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,iBAAiB,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAChJ;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoBjB,CAAC;AAEP;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiBpB,CAAC"}
|