@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.
Files changed (303) hide show
  1. package/dist/src/allocation/adapters.d.ts +159 -0
  2. package/dist/src/allocation/adapters.d.ts.map +1 -0
  3. package/dist/src/allocation/adapters.js +241 -0
  4. package/dist/src/allocation/adapters.js.map +1 -0
  5. package/dist/src/allocation/functions.d.ts +664 -0
  6. package/dist/src/allocation/functions.d.ts.map +1 -0
  7. package/dist/src/allocation/functions.js +782 -0
  8. package/dist/src/allocation/functions.js.map +1 -0
  9. package/dist/src/allocation/index.d.ts +2985 -0
  10. package/dist/src/allocation/index.d.ts.map +1 -0
  11. package/dist/src/allocation/index.js +499 -0
  12. package/dist/src/allocation/index.js.map +1 -0
  13. package/dist/src/allocation/types.d.ts +832 -0
  14. package/dist/src/allocation/types.d.ts.map +1 -0
  15. package/dist/src/allocation/types.js +360 -0
  16. package/dist/src/allocation/types.js.map +1 -0
  17. package/dist/src/bind/func.d.ts +14 -0
  18. package/dist/src/bind/func.d.ts.map +1 -1
  19. package/dist/src/bind/func.js +22 -1
  20. package/dist/src/bind/func.js.map +1 -1
  21. package/dist/src/calendar/index.d.ts +510 -1639
  22. package/dist/src/calendar/index.d.ts.map +1 -1
  23. package/dist/src/calendar/index.js +56 -29
  24. package/dist/src/calendar/index.js.map +1 -1
  25. package/dist/src/flowchart/canvas.d.ts +9 -21
  26. package/dist/src/flowchart/canvas.d.ts.map +1 -1
  27. package/dist/src/flowchart/canvas.js +10 -22
  28. package/dist/src/flowchart/canvas.js.map +1 -1
  29. package/dist/src/flowchart/flowchart.d.ts +19 -13
  30. package/dist/src/flowchart/flowchart.d.ts.map +1 -1
  31. package/dist/src/flowchart/flowchart.js.map +1 -1
  32. package/dist/src/flowchart/index.d.ts +44 -21
  33. package/dist/src/flowchart/index.d.ts.map +1 -1
  34. package/dist/src/flowchart/index.js +43 -20
  35. package/dist/src/flowchart/index.js.map +1 -1
  36. package/dist/src/flowchart/library.d.ts +166 -81
  37. package/dist/src/flowchart/library.d.ts.map +1 -1
  38. package/dist/src/flowchart/library.js +232 -105
  39. package/dist/src/flowchart/library.js.map +1 -1
  40. package/dist/src/flowchart/over.d.ts +9 -16
  41. package/dist/src/flowchart/over.d.ts.map +1 -1
  42. package/dist/src/flowchart/over.js +9 -16
  43. package/dist/src/flowchart/over.js.map +1 -1
  44. package/dist/src/flowchart/payload.d.ts +710 -508
  45. package/dist/src/flowchart/payload.d.ts.map +1 -1
  46. package/dist/src/flowchart/payload.js +128 -74
  47. package/dist/src/flowchart/payload.js.map +1 -1
  48. package/dist/src/flowchart/window.d.ts +132 -347
  49. package/dist/src/flowchart/window.d.ts.map +1 -1
  50. package/dist/src/flowchart/window.js +48 -55
  51. package/dist/src/flowchart/window.js.map +1 -1
  52. package/dist/src/index.d.ts +11 -7
  53. package/dist/src/index.d.ts.map +1 -1
  54. package/dist/src/index.js +14 -6
  55. package/dist/src/index.js.map +1 -1
  56. package/dist/src/internal.d.ts +18 -7
  57. package/dist/src/internal.d.ts.map +1 -1
  58. package/dist/src/internal.js +28 -9
  59. package/dist/src/internal.js.map +1 -1
  60. package/dist/src/plan/event-rows.d.ts +26 -10
  61. package/dist/src/plan/event-rows.d.ts.map +1 -1
  62. package/dist/src/plan/event-rows.js +39 -13
  63. package/dist/src/plan/event-rows.js.map +1 -1
  64. package/dist/src/plan/ir.d.ts +244 -815
  65. package/dist/src/plan/ir.d.ts.map +1 -1
  66. package/dist/src/plan/ir.js +8 -6
  67. package/dist/src/plan/ir.js.map +1 -1
  68. package/dist/src/plan/library.d.ts +3 -0
  69. package/dist/src/plan/library.d.ts.map +1 -1
  70. package/dist/src/plan/library.js +1 -1
  71. package/dist/src/plan/library.js.map +1 -1
  72. package/dist/src/plan/ordered-source.d.ts +1 -0
  73. package/dist/src/plan/ordered-source.d.ts.map +1 -1
  74. package/dist/src/plan/plan.d.ts +559 -1667
  75. package/dist/src/plan/plan.d.ts.map +1 -1
  76. package/dist/src/plan/plan.js +123 -45
  77. package/dist/src/plan/plan.js.map +1 -1
  78. package/dist/src/plan/root.d.ts +16 -20
  79. package/dist/src/plan/root.d.ts.map +1 -1
  80. package/dist/src/plan/root.js +23 -33
  81. package/dist/src/plan/root.js.map +1 -1
  82. package/dist/src/roster/coverage.d.ts +17 -231
  83. package/dist/src/roster/coverage.d.ts.map +1 -1
  84. package/dist/src/roster/coverage.js +94 -90
  85. package/dist/src/roster/coverage.js.map +1 -1
  86. package/dist/src/roster/fit.d.ts +59 -0
  87. package/dist/src/roster/fit.d.ts.map +1 -0
  88. package/dist/src/roster/fit.js +155 -0
  89. package/dist/src/roster/fit.js.map +1 -0
  90. package/dist/src/roster/index.d.ts +2862 -3662
  91. package/dist/src/roster/index.d.ts.map +1 -1
  92. package/dist/src/roster/index.js +383 -81
  93. package/dist/src/roster/index.js.map +1 -1
  94. package/dist/src/roster/library.d.ts +37 -92
  95. package/dist/src/roster/library.d.ts.map +1 -1
  96. package/dist/src/roster/library.js +25 -64
  97. package/dist/src/roster/library.js.map +1 -1
  98. package/dist/src/roster/lists.d.ts +195 -0
  99. package/dist/src/roster/lists.d.ts.map +1 -0
  100. package/dist/src/roster/lists.js +233 -0
  101. package/dist/src/roster/lists.js.map +1 -0
  102. package/dist/src/roster/rules.d.ts +17 -260
  103. package/dist/src/roster/rules.d.ts.map +1 -1
  104. package/dist/src/roster/rules.js +135 -132
  105. package/dist/src/roster/rules.js.map +1 -1
  106. package/dist/src/roster/targets.d.ts +115 -0
  107. package/dist/src/roster/targets.d.ts.map +1 -0
  108. package/dist/src/roster/targets.js +213 -0
  109. package/dist/src/roster/targets.js.map +1 -0
  110. package/dist/src/roster/times.d.ts +251 -0
  111. package/dist/src/roster/times.d.ts.map +1 -0
  112. package/dist/src/roster/times.js +174 -0
  113. package/dist/src/roster/times.js.map +1 -0
  114. package/dist/src/roster/types.d.ts +828 -183
  115. package/dist/src/roster/types.d.ts.map +1 -1
  116. package/dist/src/roster/types.js +224 -97
  117. package/dist/src/roster/types.js.map +1 -1
  118. package/dist/src/schedule/accessor.d.ts +28 -0
  119. package/dist/src/schedule/accessor.d.ts.map +1 -0
  120. package/dist/src/schedule/accessor.js +39 -0
  121. package/dist/src/schedule/accessor.js.map +1 -0
  122. package/dist/src/schedule/events.d.ts +170 -42
  123. package/dist/src/schedule/events.d.ts.map +1 -1
  124. package/dist/src/schedule/events.js +431 -171
  125. package/dist/src/schedule/events.js.map +1 -1
  126. package/dist/src/schedule/index.d.ts +41 -4
  127. package/dist/src/schedule/index.d.ts.map +1 -1
  128. package/dist/src/schedule/index.js +35 -3
  129. package/dist/src/schedule/index.js.map +1 -1
  130. package/dist/src/schedule/library.d.ts +13 -3
  131. package/dist/src/schedule/library.d.ts.map +1 -1
  132. package/dist/src/schedule/library.js +11 -4
  133. package/dist/src/schedule/library.js.map +1 -1
  134. package/dist/src/schedule/periods.d.ts +115 -0
  135. package/dist/src/schedule/periods.d.ts.map +1 -0
  136. package/dist/src/schedule/periods.js +215 -0
  137. package/dist/src/schedule/periods.js.map +1 -0
  138. package/dist/src/schedule/record-window.d.ts +25 -3
  139. package/dist/src/schedule/record-window.d.ts.map +1 -1
  140. package/dist/src/schedule/record-window.js +31 -18
  141. package/dist/src/schedule/record-window.js.map +1 -1
  142. package/dist/src/schedule/resources.d.ts +82 -4
  143. package/dist/src/schedule/resources.d.ts.map +1 -1
  144. package/dist/src/schedule/resources.js +44 -14
  145. package/dist/src/schedule/resources.js.map +1 -1
  146. package/dist/src/schedule/session.d.ts +69 -0
  147. package/dist/src/schedule/session.d.ts.map +1 -0
  148. package/dist/src/schedule/session.js +121 -0
  149. package/dist/src/schedule/session.js.map +1 -0
  150. package/dist/src/schedule/templates.d.ts +14 -2
  151. package/dist/src/schedule/templates.d.ts.map +1 -1
  152. package/dist/src/schedule/templates.js +5 -3
  153. package/dist/src/schedule/templates.js.map +1 -1
  154. package/dist/src/schedule/types.d.ts +1671 -37
  155. package/dist/src/schedule/types.d.ts.map +1 -1
  156. package/dist/src/schedule/types.js +196 -5
  157. package/dist/src/schedule/types.js.map +1 -1
  158. package/dist/src/schedule/window.d.ts +14 -0
  159. package/dist/src/schedule/window.d.ts.map +1 -1
  160. package/dist/src/schedule/window.js +14 -4
  161. package/dist/src/schedule/window.js.map +1 -1
  162. package/dist/src/schedule/words.d.ts +22 -0
  163. package/dist/src/schedule/words.d.ts.map +1 -0
  164. package/dist/src/schedule/words.js +25 -0
  165. package/dist/src/schedule/words.js.map +1 -0
  166. package/dist/src/sheet/index.d.ts +61 -27
  167. package/dist/src/sheet/index.d.ts.map +1 -1
  168. package/dist/src/sheet/index.js +59 -25
  169. package/dist/src/sheet/index.js.map +1 -1
  170. package/dist/src/sheet/library.d.ts +21 -3
  171. package/dist/src/sheet/library.d.ts.map +1 -1
  172. package/dist/src/sheet/library.js +23 -6
  173. package/dist/src/sheet/library.js.map +1 -1
  174. package/dist/src/sheet/registers.d.ts +100 -85
  175. package/dist/src/sheet/registers.d.ts.map +1 -1
  176. package/dist/src/sheet/registers.js +100 -85
  177. package/dist/src/sheet/registers.js.map +1 -1
  178. package/dist/src/sheet/root.d.ts +8 -12
  179. package/dist/src/sheet/root.d.ts.map +1 -1
  180. package/dist/src/sheet/root.js +6 -40
  181. package/dist/src/sheet/root.js.map +1 -1
  182. package/dist/src/sheet/sheet.d.ts +598 -2349
  183. package/dist/src/sheet/sheet.d.ts.map +1 -1
  184. package/dist/src/sheet/sheet.js +124 -37
  185. package/dist/src/sheet/sheet.js.map +1 -1
  186. package/dist/src/sheet/sub-rows.d.ts +74 -28
  187. package/dist/src/sheet/sub-rows.d.ts.map +1 -1
  188. package/dist/src/sheet/sub-rows.js +74 -28
  189. package/dist/src/sheet/sub-rows.js.map +1 -1
  190. package/dist/src/sheet/templates.d.ts +98 -34
  191. package/dist/src/sheet/templates.d.ts.map +1 -1
  192. package/dist/src/sheet/templates.js +102 -58
  193. package/dist/src/sheet/templates.js.map +1 -1
  194. package/dist/src/sheet/types.d.ts +289 -1359
  195. package/dist/src/sheet/types.d.ts.map +1 -1
  196. package/dist/src/sheet/types.js +20 -26
  197. package/dist/src/sheet/types.js.map +1 -1
  198. package/dist/src/sheet/views.d.ts +10 -11
  199. package/dist/src/sheet/views.d.ts.map +1 -1
  200. package/dist/src/sheet/views.js +15 -20
  201. package/dist/src/sheet/views.js.map +1 -1
  202. package/dist/src/{roster/visibility.d.ts → utils/key-visibility.d.ts} +42 -7
  203. package/dist/src/utils/key-visibility.d.ts.map +1 -0
  204. package/dist/src/utils/key-visibility.js +36 -0
  205. package/dist/src/utils/key-visibility.js.map +1 -0
  206. package/dist/src/utils/ordered-source.d.ts +1 -0
  207. package/dist/src/utils/ordered-source.d.ts.map +1 -1
  208. package/dist/src/utils/ordered-source.js +8 -3
  209. package/dist/src/utils/ordered-source.js.map +1 -1
  210. package/dist/src/utils/record-sources.d.ts +107 -0
  211. package/dist/src/utils/record-sources.d.ts.map +1 -0
  212. package/dist/src/utils/record-sources.js +132 -0
  213. package/dist/src/utils/record-sources.js.map +1 -0
  214. package/dist/test/allocation/allocation.examples.d.ts +2902 -0
  215. package/dist/test/allocation/allocation.examples.d.ts.map +1 -0
  216. package/dist/test/allocation/allocation.examples.js +643 -0
  217. package/dist/test/allocation/allocation.examples.js.map +1 -0
  218. package/dist/test/allocation/fit.examples.d.ts +546 -0
  219. package/dist/test/allocation/fit.examples.d.ts.map +1 -0
  220. package/dist/test/allocation/fit.examples.js +171 -0
  221. package/dist/test/allocation/fit.examples.js.map +1 -0
  222. package/dist/test/allocation/kiln-yard.d.ts +181 -0
  223. package/dist/test/allocation/kiln-yard.d.ts.map +1 -0
  224. package/dist/test/allocation/kiln-yard.js +228 -0
  225. package/dist/test/allocation/kiln-yard.js.map +1 -0
  226. package/dist/test/bind/data/data.examples.d.ts +651 -1
  227. package/dist/test/bind/data/data.examples.d.ts.map +1 -1
  228. package/dist/test/bind/data/data.examples.js +140 -2
  229. package/dist/test/bind/data/data.examples.js.map +1 -1
  230. package/dist/test/bind/func/func.examples.d.ts +10 -1
  231. package/dist/test/bind/func/func.examples.d.ts.map +1 -1
  232. package/dist/test/bind/func/func.examples.js +8 -1
  233. package/dist/test/bind/func/func.examples.js.map +1 -1
  234. package/dist/test/bind/record/record.examples.d.ts +633 -1
  235. package/dist/test/bind/record/record.examples.d.ts.map +1 -1
  236. package/dist/test/bind/record/record.examples.js +26 -2
  237. package/dist/test/bind/record/record.examples.js.map +1 -1
  238. package/dist/test/calendar/calendar-records.examples.d.ts.map +1 -1
  239. package/dist/test/calendar/calendar-records.examples.js +18 -14
  240. package/dist/test/calendar/calendar-records.examples.js.map +1 -1
  241. package/dist/test/calendar/calendar.examples.d.ts +521 -16
  242. package/dist/test/calendar/calendar.examples.d.ts.map +1 -1
  243. package/dist/test/calendar/calendar.examples.js +182 -135
  244. package/dist/test/calendar/calendar.examples.js.map +1 -1
  245. package/dist/test/examples-package.d.ts +75 -0
  246. package/dist/test/examples-package.d.ts.map +1 -0
  247. package/dist/test/examples-package.js +263 -0
  248. package/dist/test/examples-package.js.map +1 -0
  249. package/dist/test/flowchart/flowchart.examples.d.ts +211 -19
  250. package/dist/test/flowchart/flowchart.examples.d.ts.map +1 -1
  251. package/dist/test/flowchart/flowchart.examples.js +102 -75
  252. package/dist/test/flowchart/flowchart.examples.js.map +1 -1
  253. package/dist/test/plan/plan-events.examples.d.ts +1439 -209
  254. package/dist/test/plan/plan-events.examples.d.ts.map +1 -1
  255. package/dist/test/plan/plan-events.examples.js +199 -59
  256. package/dist/test/plan/plan-events.examples.js.map +1 -1
  257. package/dist/test/plan/plan-records.examples.d.ts +420 -0
  258. package/dist/test/plan/plan-records.examples.d.ts.map +1 -1
  259. package/dist/test/plan/plan-records.examples.js +70 -19
  260. package/dist/test/plan/plan-records.examples.js.map +1 -1
  261. package/dist/test/plan/plan-windows.examples.d.ts +636 -55
  262. package/dist/test/plan/plan-windows.examples.d.ts.map +1 -1
  263. package/dist/test/plan/plan-windows.examples.js +69 -33
  264. package/dist/test/plan/plan-windows.examples.js.map +1 -1
  265. package/dist/test/plan/plan.examples.d.ts +153 -31
  266. package/dist/test/plan/plan.examples.d.ts.map +1 -1
  267. package/dist/test/plan/plan.examples.js +178 -101
  268. package/dist/test/plan/plan.examples.js.map +1 -1
  269. package/dist/test/roster/domain.examples.d.ts +467 -250
  270. package/dist/test/roster/domain.examples.d.ts.map +1 -1
  271. package/dist/test/roster/domain.examples.js +92 -29
  272. package/dist/test/roster/domain.examples.js.map +1 -1
  273. package/dist/test/roster/roster-records.examples.d.ts +430 -586
  274. package/dist/test/roster/roster-records.examples.d.ts.map +1 -1
  275. package/dist/test/roster/roster-records.examples.js +102 -43
  276. package/dist/test/roster/roster-records.examples.js.map +1 -1
  277. package/dist/test/roster/roster.examples.d.ts +2319 -606
  278. package/dist/test/roster/roster.examples.d.ts.map +1 -1
  279. package/dist/test/roster/roster.examples.js +456 -148
  280. package/dist/test/roster/roster.examples.js.map +1 -1
  281. package/dist/test/roster/warehouse.d.ts +172 -63
  282. package/dist/test/roster/warehouse.d.ts.map +1 -1
  283. package/dist/test/roster/warehouse.js +172 -39
  284. package/dist/test/roster/warehouse.js.map +1 -1
  285. package/dist/test/schedule/schedule.examples.d.ts +3499 -0
  286. package/dist/test/schedule/schedule.examples.d.ts.map +1 -0
  287. package/dist/test/schedule/schedule.examples.js +192 -0
  288. package/dist/test/schedule/schedule.examples.js.map +1 -0
  289. package/dist/test/sheet/sheet-records.examples.d.ts.map +1 -1
  290. package/dist/test/sheet/sheet-records.examples.js +22 -18
  291. package/dist/test/sheet/sheet-records.examples.js.map +1 -1
  292. package/dist/test/sheet/sheet.examples.d.ts +715 -26
  293. package/dist/test/sheet/sheet.examples.d.ts.map +1 -1
  294. package/dist/test/sheet/sheet.examples.js +204 -130
  295. package/dist/test/sheet/sheet.examples.js.map +1 -1
  296. package/package.json +17 -10
  297. package/dist/src/roster/people.d.ts +0 -50
  298. package/dist/src/roster/people.d.ts.map +0 -1
  299. package/dist/src/roster/people.js +0 -32
  300. package/dist/src/roster/people.js.map +0 -1
  301. package/dist/src/roster/visibility.d.ts.map +0 -1
  302. package/dist/src/roster/visibility.js +0 -25
  303. package/dist/src/roster/visibility.js.map +0 -1
@@ -4,7 +4,7 @@ import { jsx as _jsx } from "@elaraai/e3-ui/jsx-runtime";
4
4
  * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
5
5
  */
6
6
  /** @jsxImportSource @elaraai/e3-ui */
7
- import { DateTimeType, DictType, East, FloatType, FunctionType, NullType, OptionType, SetType, StringType, StructType, VariantType, example, none, some, variant } from "@elaraai/east";
7
+ import { DateTimeType, DictType, East, FloatType, FunctionType, IntegerType, NullType, OptionType, SetType, StringType, StructType, VariantType, example, none, some, variant } from "@elaraai/east";
8
8
  import { Box, Input, Reactive, Slice, UIComponentType } from "@elaraai/east-ui";
9
9
  import { Calendar, Data, Record } from "@elaraai/e3-ui";
10
10
  import e3 from "@elaraai/e3";
@@ -23,12 +23,12 @@ export const CalendarJobValues = StructType({ title: StringType, status: Calenda
23
23
  export const CalendarService = StructType({ title: StringType, start: DateTimeType, end: DateTimeType, machine: StringType, technician: StringType, notes: StringType });
24
24
  /** A person's shift is its own event kind. */
25
25
  export const CalendarShift = StructType({ title: StringType, start: DateTimeType, end: DateTimeType, person: StringType, notes: StringType });
26
- /** Job templates are live record data, including their duration and initial values. */
26
+ /** Job templates are live record data, including their duration and initial values; each has a group, which the rail narrows them by. */
27
27
  export const CalendarJobTemplate = StructType({ name: StringType, group: StringType, hours: FloatType, values: CalendarJobValues });
28
- /** Maintenance templates are also bound data. */
29
- export const CalendarServiceTemplate = StructType({ name: StringType, hours: FloatType, values: StructType({ title: StringType, technician: StringType, notes: StringType }) });
30
- /** Shift templates start at a particular time when dropped on a day. */
31
- export const CalendarShiftTemplate = StructType({ name: StringType, values: StructType({ title: StringType, notes: StringType }) });
28
+ /** Maintenance templates are also bound data, grouped as the job templates are. */
29
+ export const CalendarServiceTemplate = StructType({ name: StringType, group: StringType, hours: FloatType, values: StructType({ title: StringType, technician: StringType, notes: StringType }) });
30
+ /** Shift templates start at their hour when dropped on a day. */
31
+ export const CalendarShiftTemplate = StructType({ name: StringType, group: StringType, hour: IntegerType, values: StructType({ title: StringType, notes: StringType }) });
32
32
  export const calendarMachines = e3.record("calendar_machines", DictType(StringType, CalendarMachine), new Map([
33
33
  ["press1", { name: "Press 1", area: "Press shop" }], ["press2", { name: "Press 2", area: "Press shop" }],
34
34
  ["lathe1", { name: "Lathe 1", area: "Machine shop" }], ["lathe2", { name: "Lathe 2", area: "Machine shop" }],
@@ -60,76 +60,104 @@ export const calendarShifts = e3.record("calendar_shifts", DictType(StringType,
60
60
  ]));
61
61
  export const calendarShiftsPatch = e3.mutation.patch(calendarShifts);
62
62
  export const calendarJobTemplates = e3.record("calendar_job_templates", DictType(StringType, CalendarJobTemplate), new Map([
63
- ["brackets", { name: "Bracket batch", group: "Production", hours: 4.0, values: { title: "Bracket batch", status: variant("planned", null), hours: 4.0, customer: "", due: none } }],
64
- ["housings", { name: "Housing batch", group: "Production", hours: 2.0, values: { title: "Housing batch", status: variant("planned", null), hours: 2.0, customer: "", due: none } }],
63
+ ["brackets", { name: "Bracket batch", group: "Fabrication", hours: 4.0, values: { title: "Bracket batch", status: variant("planned", null), hours: 4.0, customer: "", due: none } }],
64
+ ["housings", { name: "Housing batch", group: "Machining", hours: 2.0, values: { title: "Housing batch", status: variant("planned", null), hours: 2.0, customer: "", due: none } }],
65
65
  ]));
66
66
  export const calendarServiceTemplates = e3.record("calendar_service_templates", DictType(StringType, CalendarServiceTemplate), new Map([
67
- ["service", { name: "Preventive maintenance", hours: 2.0, values: { title: "Preventive maintenance", technician: "ash", notes: "" } }],
67
+ ["calibration", { name: "Calibration", group: "Calibration", hours: 1.0, values: { title: "Calibration", technician: "cedar", notes: "Check against the reference gauge." } }],
68
+ ["service", { name: "Preventive maintenance", group: "Preventive", hours: 2.0, values: { title: "Preventive maintenance", technician: "ash", notes: "" } }],
68
69
  ]));
69
70
  export const calendarShiftTemplates = e3.record("calendar_shift_templates", DictType(StringType, CalendarShiftTemplate), new Map([
70
- ["day", { name: "Day shift", values: { title: "Day shift", notes: "" } }],
71
+ ["day", { name: "Day shift", group: "Day", hour: 6n, values: { title: "Day shift", notes: "" } }],
72
+ ["late", { name: "Late shift", group: "Late", hour: 14n, values: { title: "Late shift", notes: "" } }],
71
73
  ]));
72
- /** The application's cross-record filtering schema; original event rows remain in their records. */
73
- export const CalendarFilter = StructType({ title: StringType, kind: StringType, resourceKind: StringType, resourceKey: StringType, resource: StringType, status: StringType });
74
- /** A day key for the indexed calendar's author-bound Slice. */
75
- export const CalendarDay = StructType({ day: DateTimeType });
74
+ // The shop edits its machines and job templates elsewhere, each through its patch door; the Calendar reads them live.
75
+ export const calendarMachinesPatch = e3.mutation.patch(calendarMachines);
76
+ export const calendarJobTemplatesPatch = e3.mutation.patch(calendarJobTemplates);
77
+ // The rail narrows each record through its own indexes (#1343): each event kind over its interval index — on its own,
78
+ // and after its status, its machine or its person — so a narrowing keeps every event overlapping the window once.
79
+ export const calendarJobsByTime = e3.recordIndex("calendar_jobs_by_time", calendarJobs, { interval: { from: "start", to: "end" } });
80
+ export const calendarJobsByStatusTime = e3.recordIndex("calendar_jobs_by_status_time", calendarJobs, { on: ["status"], interval: { from: "start", to: "end" } });
81
+ export const calendarJobsByMachineTime = e3.recordIndex("calendar_jobs_by_machine_time", calendarJobs, { on: ["machine"], interval: { from: "start", to: "end" } });
82
+ export const calendarServicesByTime = e3.recordIndex("calendar_services_by_time", calendarServices, { interval: { from: "start", to: "end" } });
83
+ export const calendarServicesByMachineTime = e3.recordIndex("calendar_services_by_machine_time", calendarServices, { on: ["machine"], interval: { from: "start", to: "end" } });
84
+ export const calendarShiftsByTime = e3.recordIndex("calendar_shifts_by_time", calendarShifts, { interval: { from: "start", to: "end" } });
85
+ export const calendarShiftsByPersonTime = e3.recordIndex("calendar_shifts_by_person_time", calendarShifts, { on: ["person"], interval: { from: "start", to: "end" } });
86
+ export const calendarMachinesByArea = e3.recordIndex("calendar_machines_by_area", calendarMachines, { on: ["area"] });
87
+ export const calendarPeopleByTeam = e3.recordIndex("calendar_people_by_team", calendarPeople, { on: ["team"] });
88
+ export const calendarJobTemplatesByGroup = e3.recordIndex("calendar_job_templates_by_group", calendarJobTemplates, { on: ["group"] });
89
+ export const calendarServiceTemplatesByGroup = e3.recordIndex("calendar_service_templates_by_group", calendarServiceTemplates, { on: ["group"] });
90
+ export const calendarShiftTemplatesByGroup = e3.recordIndex("calendar_shift_templates_by_group", calendarShiftTemplates, { on: ["group"] });
76
91
  export const calendarOperations = example({
77
92
  inputs: [],
78
- description: "A metal fabrication calendar over three event records and bound machines, people and templates: Calendar, Resources and Timeline share one frame, Slice filters and Save history. Its library schedules the event record's backlog and assigns technicians; overlapping production and maintenance warn without blocking Save.",
79
- keywords: ["Calendar", "Record.bind", "Calendar.templates", "Schedule", "Slice", "Slice.bind", "Slice.rows", "Slice.apply.matches", "filter", "BuilderFrame", "library", "backlog", "inspector", "overlaps", "Save"],
93
+ description: "A metal fabrication calendar over three event records and bound machines, people and templates: Calendar, Resources and Timeline share one frame, one Slice.bindRecords rail — a source per event kind, resource kind and template record — and Save history. Its library schedules the event record's backlog and assigns technicians; overlapping production and maintenance warn without blocking Save.",
94
+ keywords: ["Calendar", "Record.bind", "Data.bind", "Calendar.templates", "Schedule", "Slice", "Slice.bindRecords", "Data.bindPaged", "recordIndex", "interval", "BuilderFrame", "library", "backlog", "inspector", "overlaps", "Save"],
80
95
  fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
81
- const machines = $.let(Record.bind(calendarMachines, []));
82
- const people = $.let(Record.bind(calendarPeople, []));
96
+ // What the Calendar reads whole binds with Data.bind, which keeps it loaded beside its pages; the event records
97
+ // it writes bind with Record.bind, and it reads their events through their pages alone.
98
+ const machines = $.let(Data.bind(calendarMachines));
99
+ const people = $.let(Data.bind(calendarPeople));
83
100
  const jobs = $.let(Record.bind(calendarJobs, [calendarJobsPatch]));
84
101
  const services = $.let(Record.bind(calendarServices, [calendarServicesPatch]));
85
102
  const shifts = $.let(Record.bind(calendarShifts, [calendarShiftsPatch]));
86
- const jobTemplates = $.let(Record.bind(calendarJobTemplates, []));
87
- const serviceTemplates = $.let(Record.bind(calendarServiceTemplates, []));
88
- const shiftTemplates = $.let(Record.bind(calendarShiftTemplates, []));
89
- const fields = { title: { label: "Title" }, kind: { label: "Kind" }, resourceKind: { label: "Resource kind" }, resource: { label: "Resource" }, status: { label: "Status" } };
90
- // The pure matcher applies this local Slice to each event kind.
91
- const cfg = Slice.config(CalendarFilter, { fields, searchFieldIds: ["title", "kind", "resource"] });
92
- const jobScope = $.const(East.function([CalendarJob], CalendarFilter, (_$2, row) => ({
93
- title: row.title, kind: "Production", resourceKind: "Machines", resourceKey: row.machine.match({ some: (_$3, key) => key, none: () => "" }), resource: row.machine.match({ some: (_$3, key) => machines.read().get(key).name, none: () => "Unassigned" }),
94
- status: row.status.match({ planned: () => "Planned", active: () => "Active", done: () => "Done" }),
95
- })));
96
- const serviceScope = $.const(East.function([CalendarService], CalendarFilter, (_$2, row) => ({
97
- title: row.title, kind: "Maintenance", resourceKind: "Machines", resourceKey: row.machine, resource: machines.read().get(row.machine).name, status: "",
98
- })));
99
- const shiftScope = $.const(East.function([CalendarShift], CalendarFilter, (_$2, row) => ({
100
- title: row.title, kind: "Shift", resourceKind: "People", resourceKey: row.person, resource: people.read().get(row.person).name, status: "",
101
- })));
102
- const scope = $.let(jobs.read().toArray((_$2, row) => jobScope(row))
103
- .concat(services.read().toArray((_$2, row) => serviceScope(row)))
104
- .concat(shifts.read().toArray((_$2, row) => shiftScope(row))));
105
- const slice = $.let(Slice.bind("ex.calendarOperations.scope", scope, { fields, search: ["title", "kind", "resource"] }));
106
- const visible = $.let(Slice.rows(slice));
107
- // Preserve record keys while the same Slice scopes resource rows upstream.
108
- const visibleMachines = $.let(machines.read().filter((_$2, _row, key) => slice.isActive().not().or(() => visible.some((_$3, row) => row.resourceKind.equal("Machines").and(() => row.resourceKey.equal(key))))));
109
- const visiblePeople = $.let(people.read().filter((_$2, _row, key) => slice.isActive().not().or(() => visible.some((_$3, row) => row.resourceKind.equal("People").and(() => row.resourceKey.equal(key))))));
110
- return _jsx(Box, { height: "760px", children: _jsx(Calendar, { id: "operations", inspector: true, view: { date: new Date("2026-10-01T00:00:00Z") }, now: new Date("2026-10-01T10:15:00Z"), slice: { slice, affordances: ["filter", "search"] }, resources: {
111
- machines: Calendar.resources(visibleMachines, { name: "Machines", icon: "gears", label: row => row.name, meta: row => some(row.area) }),
112
- people: Calendar.resources(visiblePeople, { name: "People", icon: "users", label: row => row.name, meta: row => some(row.team) }),
103
+ const jobTemplates = $.let(Data.bind(calendarJobTemplates));
104
+ const serviceTemplates = $.let(Data.bind(calendarServiceTemplates));
105
+ const shiftTemplates = $.let(Data.bind(calendarShiftTemplates));
106
+ // Every record paged: each event kind's interval indexes and its own entries, the others' fields' indexes.
107
+ const jobIndex = $.let(Data.bindPaged(calendarJobs, { indexes: [calendarJobsByTime, calendarJobsByStatusTime, calendarJobsByMachineTime] }));
108
+ const serviceIndex = $.let(Data.bindPaged(calendarServices, { indexes: [calendarServicesByTime, calendarServicesByMachineTime] }));
109
+ const shiftIndex = $.let(Data.bindPaged(calendarShifts, { indexes: [calendarShiftsByTime, calendarShiftsByPersonTime] }));
110
+ const machineIndex = $.let(Data.bindPaged(calendarMachines, { indexes: [calendarMachinesByArea] }));
111
+ const peopleIndex = $.let(Data.bindPaged(calendarPeople, { indexes: [calendarPeopleByTeam] }));
112
+ const jobTemplateIndex = $.let(Data.bindPaged(calendarJobTemplates, { indexes: [calendarJobTemplatesByGroup] }));
113
+ const serviceTemplateIndex = $.let(Data.bindPaged(calendarServiceTemplates, { indexes: [calendarServiceTemplatesByGroup] }));
114
+ const shiftTemplateIndex = $.let(Data.bindPaged(calendarShiftTemplates, { indexes: [calendarShiftTemplatesByGroup] }));
115
+ const jobEntries = $.let(Data.bindPaged(calendarJobs));
116
+ const serviceEntries = $.let(Data.bindPaged(calendarServices));
117
+ const shiftEntries = $.let(Data.bindPaged(calendarShifts));
118
+ // One rail over every record, a source each (#1343): each event kind through its interval indexes, its range the
119
+ // window the navigation writes in every kind at once; the machines, the people and each templates record by its fields.
120
+ const slice = $.let(Slice.bindRecords("ex.calendarOperations", {
121
+ job: { source: jobIndex, icon: { prefix: "fas", name: "industry" },
122
+ fields: { status: { label: "Status" }, machine: { label: "Machine", hints: ["press1", "press2", "lathe1", "lathe2", null] }, start: { label: "Dates" } }, range: "start" },
123
+ service: { source: serviceIndex, icon: { prefix: "fas", name: "screwdriver-wrench" },
124
+ fields: { machine: { label: "Machine", hints: ["press1", "press2", "lathe1", "lathe2"] }, start: { label: "Dates" } }, range: "start" },
125
+ shift: { source: shiftIndex, icon: { prefix: "fas", name: "user-clock" },
126
+ fields: { person: { label: "Person", hints: ["ash", "birch", "cedar"] }, start: { label: "Dates" } }, range: "start" },
127
+ machines: { source: machineIndex, icon: { prefix: "fas", name: "gears" },
128
+ fields: { area: { label: "Area", hints: ["Press shop", "Machine shop"] } } },
129
+ people: { source: peopleIndex, icon: { prefix: "fas", name: "users" },
130
+ fields: { team: { label: "Team", hints: ["Maintenance", "Production"] } } },
131
+ jobTemplates: { source: jobTemplateIndex, icon: { prefix: "fas", name: "layer-group" },
132
+ fields: { group: { label: "Job template", hints: ["Fabrication", "Machining"] } } },
133
+ serviceTemplates: { source: serviceTemplateIndex, icon: { prefix: "fas", name: "layer-group" },
134
+ fields: { group: { label: "Service template", hints: ["Preventive", "Calibration"] } } },
135
+ shiftTemplates: { source: shiftTemplateIndex, icon: { prefix: "fas", name: "layer-group" },
136
+ fields: { group: { label: "Shift template", hints: ["Day", "Late"] } } },
137
+ }));
138
+ return _jsx(Box, { height: "760px", children: _jsx(Calendar, { id: "operations", inspector: true, view: { date: new Date("2026-10-01T00:00:00Z") }, now: new Date("2026-10-01T10:15:00Z"), slice: { slice }, resources: {
139
+ machines: Calendar.resources(machines.read(), { name: "Machines", icon: "gears", label: row => row.name, meta: row => some(row.area) }),
140
+ people: Calendar.resources(people.read(), { name: "People", icon: "users", label: row => row.name, meta: row => some(row.team) }),
113
141
  }, events: {
114
142
  job: Calendar.events(jobs, { name: "Production", icon: "industry", title: "title", start: "start", end: "end", resource: { field: "machine", of: "machines" },
115
- filter: row => Slice.apply.matches([CalendarFilter], slice.read(), cfg, jobScope(row)),
143
+ entries: jobEntries,
116
144
  status: { field: "status", cases: { planned: { label: "Planned", tone: variant("neutral", null), ring: true }, active: { label: "Active", tone: variant("info", null), ring: false }, done: { label: "Done", tone: variant("success", null), ring: false } } },
117
145
  backlog: { duration: row => variant("hours", row.hours), due: row => row.due },
118
146
  ready: row => row.hours.lessEqual(0).ifElse(() => variant("incomplete", [{ field: "hours", message: "Duration must be positive" }]), () => variant("ready", null)),
119
- templates: Calendar.templates(jobTemplates.read(), { name: row => row.name, group: row => some(row.group), duration: row => variant("hours", row.hours), values: row => row.values }),
147
+ templates: Calendar.templates(jobTemplates.read(), { name: row => row.name, group: row => some(row.group), duration: row => variant("hours", row.hours), values: row => row.values, source: "jobTemplates" }),
120
148
  }),
121
149
  service: Calendar.events(services, { name: "Maintenance", icon: "screwdriver-wrench", title: "title", start: "start", end: "end", resource: { field: "machine", of: "machines" },
122
- filter: row => Slice.apply.matches([CalendarFilter], slice.read(), cfg, serviceScope(row)),
150
+ entries: serviceEntries,
123
151
  fields: { technician: Calendar.field.reference({ of: "people" }) },
124
- templates: Calendar.templates(serviceTemplates.read(), { name: row => row.name, duration: row => variant("hours", row.hours), values: row => row.values }),
152
+ templates: Calendar.templates(serviceTemplates.read(), { name: row => row.name, group: row => some(row.group), duration: row => variant("hours", row.hours), values: row => row.values, source: "serviceTemplates" }),
125
153
  }),
126
154
  shift: Calendar.events(shifts, { name: "Shift", icon: "user-clock", title: "title", start: "start", end: "end", resource: { field: "person", of: "people" }, overlaps: "allow",
127
- filter: row => Slice.apply.matches([CalendarFilter], slice.read(), cfg, shiftScope(row)),
128
- templates: Calendar.templates(shiftTemplates.read(), { name: row => row.name, at: () => some({ hour: 6n, minute: 0n }), duration: () => variant("hours", 8.0), values: row => row.values }),
155
+ entries: shiftEntries,
156
+ templates: Calendar.templates(shiftTemplates.read(), { name: row => row.name, group: row => some(row.group), at: row => some({ hour: row.hour, minute: 0n }), duration: () => variant("hours", 8.0), values: row => row.values, source: "shiftTemplates" }),
129
157
  }),
130
158
  }, library: [Calendar.library.templates(), Calendar.library.backlog(), Calendar.library.tab(people.read(), {
131
159
  name: "Technicians", icon: "user-gear", label: row => row.name, meta: row => some(row.team), group: row => row.team,
132
- drop: (_row, key) => Calendar.patch(CalendarService, { technician: key }),
160
+ drop: (_row, key) => Calendar.patch(CalendarService, { technician: key }), source: "people",
133
161
  })] }) });
134
162
  } })),
135
163
  });
@@ -138,58 +166,71 @@ export const calendarMobile = example({
138
166
  description: "The same bound calendar in a phone-width container: chronological agenda cards with explicit Move, Resize, Duplicate, Delete and Return to backlog actions, Create and Schedule in the library, shared forms and Save history. Resizing preserves the view, selection and drafts; no dragging on the agenda.",
139
167
  keywords: ["Calendar", "mobile", "responsive", "agenda", "cards", "no dragging", "explicit actions", "Record.bind", "templates"],
140
168
  fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
141
- const machines = $.let(Record.bind(calendarMachines, []));
142
- const people = $.let(Record.bind(calendarPeople, []));
169
+ // What the Calendar reads whole binds with Data.bind, which keeps it loaded beside its pages; the event records
170
+ // it writes bind with Record.bind, and it reads their events through their pages alone.
171
+ const machines = $.let(Data.bind(calendarMachines));
172
+ const people = $.let(Data.bind(calendarPeople));
143
173
  const jobs = $.let(Record.bind(calendarJobs, [calendarJobsPatch]));
144
174
  const services = $.let(Record.bind(calendarServices, [calendarServicesPatch]));
145
175
  const shifts = $.let(Record.bind(calendarShifts, [calendarShiftsPatch]));
146
- const jobTemplates = $.let(Record.bind(calendarJobTemplates, []));
147
- const serviceTemplates = $.let(Record.bind(calendarServiceTemplates, []));
148
- const shiftTemplates = $.let(Record.bind(calendarShiftTemplates, []));
149
- const fields = { title: { label: "Title" }, kind: { label: "Kind" }, resourceKind: { label: "Resource kind" }, resource: { label: "Resource" }, status: { label: "Status" } };
150
- // The pure matcher applies this local Slice to each event kind.
151
- const cfg = Slice.config(CalendarFilter, { fields, searchFieldIds: ["title", "kind", "resource"] });
152
- const jobScope = $.const(East.function([CalendarJob], CalendarFilter, (_$2, row) => ({
153
- title: row.title, kind: "Production", resourceKind: "Machines", resourceKey: row.machine.match({ some: (_$3, key) => key, none: () => "" }), resource: row.machine.match({ some: (_$3, key) => machines.read().get(key).name, none: () => "Unassigned" }),
154
- status: row.status.match({ planned: () => "Planned", active: () => "Active", done: () => "Done" }),
155
- })));
156
- const serviceScope = $.const(East.function([CalendarService], CalendarFilter, (_$2, row) => ({
157
- title: row.title, kind: "Maintenance", resourceKind: "Machines", resourceKey: row.machine, resource: machines.read().get(row.machine).name, status: "",
158
- })));
159
- const shiftScope = $.const(East.function([CalendarShift], CalendarFilter, (_$2, row) => ({
160
- title: row.title, kind: "Shift", resourceKind: "People", resourceKey: row.person, resource: people.read().get(row.person).name, status: "",
161
- })));
162
- const scope = $.let(jobs.read().toArray((_$2, row) => jobScope(row))
163
- .concat(services.read().toArray((_$2, row) => serviceScope(row)))
164
- .concat(shifts.read().toArray((_$2, row) => shiftScope(row))));
165
- const slice = $.let(Slice.bind("ex.calendarMobile.scope", scope, { fields, search: ["title", "kind", "resource"] }));
166
- const visible = $.let(Slice.rows(slice));
167
- // Preserve record keys while the same Slice scopes resource rows upstream.
168
- const visibleMachines = $.let(machines.read().filter((_$2, _row, key) => slice.isActive().not().or(() => visible.some((_$3, row) => row.resourceKind.equal("Machines").and(() => row.resourceKey.equal(key))))));
169
- const visiblePeople = $.let(people.read().filter((_$2, _row, key) => slice.isActive().not().or(() => visible.some((_$3, row) => row.resourceKind.equal("People").and(() => row.resourceKey.equal(key))))));
170
- return _jsx(Box, { width: "100%", maxWidth: "390px", height: "760px", children: _jsx(Calendar, { id: "operations", inspector: true, view: { date: new Date("2026-10-01T00:00:00Z") }, now: new Date("2026-10-01T10:15:00Z"), slice: { slice, affordances: ["filter", "search"] }, resources: {
171
- machines: Calendar.resources(visibleMachines, { name: "Machines", icon: "gears", label: row => row.name, meta: row => some(row.area) }),
172
- people: Calendar.resources(visiblePeople, { name: "People", icon: "users", label: row => row.name, meta: row => some(row.team) }),
176
+ const jobTemplates = $.let(Data.bind(calendarJobTemplates));
177
+ const serviceTemplates = $.let(Data.bind(calendarServiceTemplates));
178
+ const shiftTemplates = $.let(Data.bind(calendarShiftTemplates));
179
+ // Every record paged: each event kind's interval indexes and its own entries, the others' fields' indexes.
180
+ const jobIndex = $.let(Data.bindPaged(calendarJobs, { indexes: [calendarJobsByTime, calendarJobsByStatusTime, calendarJobsByMachineTime] }));
181
+ const serviceIndex = $.let(Data.bindPaged(calendarServices, { indexes: [calendarServicesByTime, calendarServicesByMachineTime] }));
182
+ const shiftIndex = $.let(Data.bindPaged(calendarShifts, { indexes: [calendarShiftsByTime, calendarShiftsByPersonTime] }));
183
+ const machineIndex = $.let(Data.bindPaged(calendarMachines, { indexes: [calendarMachinesByArea] }));
184
+ const peopleIndex = $.let(Data.bindPaged(calendarPeople, { indexes: [calendarPeopleByTeam] }));
185
+ const jobTemplateIndex = $.let(Data.bindPaged(calendarJobTemplates, { indexes: [calendarJobTemplatesByGroup] }));
186
+ const serviceTemplateIndex = $.let(Data.bindPaged(calendarServiceTemplates, { indexes: [calendarServiceTemplatesByGroup] }));
187
+ const shiftTemplateIndex = $.let(Data.bindPaged(calendarShiftTemplates, { indexes: [calendarShiftTemplatesByGroup] }));
188
+ const jobEntries = $.let(Data.bindPaged(calendarJobs));
189
+ const serviceEntries = $.let(Data.bindPaged(calendarServices));
190
+ const shiftEntries = $.let(Data.bindPaged(calendarShifts));
191
+ // One rail over every record, a source each (#1343): each event kind through its interval indexes, its range the
192
+ // window the navigation writes in every kind at once; the machines, the people and each templates record by its fields.
193
+ const slice = $.let(Slice.bindRecords("ex.calendarMobile", {
194
+ job: { source: jobIndex, icon: { prefix: "fas", name: "industry" },
195
+ fields: { status: { label: "Status" }, machine: { label: "Machine", hints: ["press1", "press2", "lathe1", "lathe2", null] }, start: { label: "Dates" } }, range: "start" },
196
+ service: { source: serviceIndex, icon: { prefix: "fas", name: "screwdriver-wrench" },
197
+ fields: { machine: { label: "Machine", hints: ["press1", "press2", "lathe1", "lathe2"] }, start: { label: "Dates" } }, range: "start" },
198
+ shift: { source: shiftIndex, icon: { prefix: "fas", name: "user-clock" },
199
+ fields: { person: { label: "Person", hints: ["ash", "birch", "cedar"] }, start: { label: "Dates" } }, range: "start" },
200
+ machines: { source: machineIndex, icon: { prefix: "fas", name: "gears" },
201
+ fields: { area: { label: "Area", hints: ["Press shop", "Machine shop"] } } },
202
+ people: { source: peopleIndex, icon: { prefix: "fas", name: "users" },
203
+ fields: { team: { label: "Team", hints: ["Maintenance", "Production"] } } },
204
+ jobTemplates: { source: jobTemplateIndex, icon: { prefix: "fas", name: "layer-group" },
205
+ fields: { group: { label: "Job template", hints: ["Fabrication", "Machining"] } } },
206
+ serviceTemplates: { source: serviceTemplateIndex, icon: { prefix: "fas", name: "layer-group" },
207
+ fields: { group: { label: "Service template", hints: ["Preventive", "Calibration"] } } },
208
+ shiftTemplates: { source: shiftTemplateIndex, icon: { prefix: "fas", name: "layer-group" },
209
+ fields: { group: { label: "Shift template", hints: ["Day", "Late"] } } },
210
+ }));
211
+ return _jsx(Box, { width: "100%", maxWidth: "390px", height: "760px", children: _jsx(Calendar, { id: "operations", inspector: true, view: { date: new Date("2026-10-01T00:00:00Z") }, now: new Date("2026-10-01T10:15:00Z"), slice: { slice }, resources: {
212
+ machines: Calendar.resources(machines.read(), { name: "Machines", icon: "gears", label: row => row.name, meta: row => some(row.area) }),
213
+ people: Calendar.resources(people.read(), { name: "People", icon: "users", label: row => row.name, meta: row => some(row.team) }),
173
214
  }, events: {
174
215
  job: Calendar.events(jobs, { name: "Production", icon: "industry", title: "title", start: "start", end: "end", resource: { field: "machine", of: "machines" },
175
- filter: row => Slice.apply.matches([CalendarFilter], slice.read(), cfg, jobScope(row)),
216
+ entries: jobEntries,
176
217
  status: { field: "status", cases: { planned: { label: "Planned", tone: variant("neutral", null), ring: true }, active: { label: "Active", tone: variant("info", null), ring: false }, done: { label: "Done", tone: variant("success", null), ring: false } } },
177
218
  backlog: { duration: row => variant("hours", row.hours), due: row => row.due },
178
219
  ready: row => row.hours.lessEqual(0).ifElse(() => variant("incomplete", [{ field: "hours", message: "Duration must be positive" }]), () => variant("ready", null)),
179
- templates: Calendar.templates(jobTemplates.read(), { name: row => row.name, group: row => some(row.group), duration: row => variant("hours", row.hours), values: row => row.values }),
220
+ templates: Calendar.templates(jobTemplates.read(), { name: row => row.name, group: row => some(row.group), duration: row => variant("hours", row.hours), values: row => row.values, source: "jobTemplates" }),
180
221
  }),
181
222
  service: Calendar.events(services, { name: "Maintenance", icon: "screwdriver-wrench", title: "title", start: "start", end: "end", resource: { field: "machine", of: "machines" },
182
- filter: row => Slice.apply.matches([CalendarFilter], slice.read(), cfg, serviceScope(row)),
223
+ entries: serviceEntries,
183
224
  fields: { technician: Calendar.field.reference({ of: "people" }) },
184
- templates: Calendar.templates(serviceTemplates.read(), { name: row => row.name, duration: row => variant("hours", row.hours), values: row => row.values }),
225
+ templates: Calendar.templates(serviceTemplates.read(), { name: row => row.name, group: row => some(row.group), duration: row => variant("hours", row.hours), values: row => row.values, source: "serviceTemplates" }),
185
226
  }),
186
227
  shift: Calendar.events(shifts, { name: "Shift", icon: "user-clock", title: "title", start: "start", end: "end", resource: { field: "person", of: "people" }, overlaps: "allow",
187
- filter: row => Slice.apply.matches([CalendarFilter], slice.read(), cfg, shiftScope(row)),
188
- templates: Calendar.templates(shiftTemplates.read(), { name: row => row.name, at: () => some({ hour: 6n, minute: 0n }), duration: () => variant("hours", 8.0), values: row => row.values }),
228
+ entries: shiftEntries,
229
+ templates: Calendar.templates(shiftTemplates.read(), { name: row => row.name, group: row => some(row.group), at: row => some({ hour: row.hour, minute: 0n }), duration: () => variant("hours", 8.0), values: row => row.values, source: "shiftTemplates" }),
189
230
  }),
190
231
  }, library: [Calendar.library.templates(), Calendar.library.backlog(), Calendar.library.tab(people.read(), {
191
232
  name: "Technicians", icon: "user-gear", label: row => row.name, meta: row => some(row.team), group: row => row.team,
192
- drop: (_row, key) => Calendar.patch(CalendarService, { technician: key }),
233
+ drop: (_row, key) => Calendar.patch(CalendarService, { technician: key }), source: "people",
193
234
  })] }) });
194
235
  } })),
195
236
  });
@@ -198,58 +239,71 @@ export const calendarReadOnly = example({
198
239
  description: "The same record calendar given readOnly: navigation, filtering, selection and overlaps, with a read-only inspector and no mutation session or editing actions.",
199
240
  keywords: ["Calendar", "readOnly", "records", "selection", "overlaps"],
200
241
  fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
201
- const machines = $.let(Record.bind(calendarMachines, []));
202
- const people = $.let(Record.bind(calendarPeople, []));
242
+ // What the Calendar reads whole binds with Data.bind, which keeps it loaded beside its pages; the event records
243
+ // it writes bind with Record.bind, and it reads their events through their pages alone.
244
+ const machines = $.let(Data.bind(calendarMachines));
245
+ const people = $.let(Data.bind(calendarPeople));
203
246
  const jobs = $.let(Record.bind(calendarJobs, [calendarJobsPatch]));
204
247
  const services = $.let(Record.bind(calendarServices, [calendarServicesPatch]));
205
248
  const shifts = $.let(Record.bind(calendarShifts, [calendarShiftsPatch]));
206
- const jobTemplates = $.let(Record.bind(calendarJobTemplates, []));
207
- const serviceTemplates = $.let(Record.bind(calendarServiceTemplates, []));
208
- const shiftTemplates = $.let(Record.bind(calendarShiftTemplates, []));
209
- const fields = { title: { label: "Title" }, kind: { label: "Kind" }, resourceKind: { label: "Resource kind" }, resource: { label: "Resource" }, status: { label: "Status" } };
210
- // The pure matcher applies this local Slice to each event kind.
211
- const cfg = Slice.config(CalendarFilter, { fields, searchFieldIds: ["title", "kind", "resource"] });
212
- const jobScope = $.const(East.function([CalendarJob], CalendarFilter, (_$2, row) => ({
213
- title: row.title, kind: "Production", resourceKind: "Machines", resourceKey: row.machine.match({ some: (_$3, key) => key, none: () => "" }), resource: row.machine.match({ some: (_$3, key) => machines.read().get(key).name, none: () => "Unassigned" }),
214
- status: row.status.match({ planned: () => "Planned", active: () => "Active", done: () => "Done" }),
215
- })));
216
- const serviceScope = $.const(East.function([CalendarService], CalendarFilter, (_$2, row) => ({
217
- title: row.title, kind: "Maintenance", resourceKind: "Machines", resourceKey: row.machine, resource: machines.read().get(row.machine).name, status: "",
218
- })));
219
- const shiftScope = $.const(East.function([CalendarShift], CalendarFilter, (_$2, row) => ({
220
- title: row.title, kind: "Shift", resourceKind: "People", resourceKey: row.person, resource: people.read().get(row.person).name, status: "",
221
- })));
222
- const scope = $.let(jobs.read().toArray((_$2, row) => jobScope(row))
223
- .concat(services.read().toArray((_$2, row) => serviceScope(row)))
224
- .concat(shifts.read().toArray((_$2, row) => shiftScope(row))));
225
- const slice = $.let(Slice.bind("ex.calendarReadOnly.scope", scope, { fields, search: ["title", "kind", "resource"] }));
226
- const visible = $.let(Slice.rows(slice));
227
- // Preserve record keys while the same Slice scopes resource rows upstream.
228
- const visibleMachines = $.let(machines.read().filter((_$2, _row, key) => slice.isActive().not().or(() => visible.some((_$3, row) => row.resourceKind.equal("Machines").and(() => row.resourceKey.equal(key))))));
229
- const visiblePeople = $.let(people.read().filter((_$2, _row, key) => slice.isActive().not().or(() => visible.some((_$3, row) => row.resourceKind.equal("People").and(() => row.resourceKey.equal(key))))));
230
- return _jsx(Box, { height: "760px", children: _jsx(Calendar, { id: "operations", inspector: true, readOnly: true, view: { date: new Date("2026-10-01T00:00:00Z") }, now: new Date("2026-10-01T10:15:00Z"), slice: { slice, affordances: ["filter", "search"] }, resources: {
231
- machines: Calendar.resources(visibleMachines, { name: "Machines", icon: "gears", label: row => row.name, meta: row => some(row.area) }),
232
- people: Calendar.resources(visiblePeople, { name: "People", icon: "users", label: row => row.name, meta: row => some(row.team) }),
249
+ const jobTemplates = $.let(Data.bind(calendarJobTemplates));
250
+ const serviceTemplates = $.let(Data.bind(calendarServiceTemplates));
251
+ const shiftTemplates = $.let(Data.bind(calendarShiftTemplates));
252
+ // Every record paged: each event kind's interval indexes and its own entries, the others' fields' indexes.
253
+ const jobIndex = $.let(Data.bindPaged(calendarJobs, { indexes: [calendarJobsByTime, calendarJobsByStatusTime, calendarJobsByMachineTime] }));
254
+ const serviceIndex = $.let(Data.bindPaged(calendarServices, { indexes: [calendarServicesByTime, calendarServicesByMachineTime] }));
255
+ const shiftIndex = $.let(Data.bindPaged(calendarShifts, { indexes: [calendarShiftsByTime, calendarShiftsByPersonTime] }));
256
+ const machineIndex = $.let(Data.bindPaged(calendarMachines, { indexes: [calendarMachinesByArea] }));
257
+ const peopleIndex = $.let(Data.bindPaged(calendarPeople, { indexes: [calendarPeopleByTeam] }));
258
+ const jobTemplateIndex = $.let(Data.bindPaged(calendarJobTemplates, { indexes: [calendarJobTemplatesByGroup] }));
259
+ const serviceTemplateIndex = $.let(Data.bindPaged(calendarServiceTemplates, { indexes: [calendarServiceTemplatesByGroup] }));
260
+ const shiftTemplateIndex = $.let(Data.bindPaged(calendarShiftTemplates, { indexes: [calendarShiftTemplatesByGroup] }));
261
+ const jobEntries = $.let(Data.bindPaged(calendarJobs));
262
+ const serviceEntries = $.let(Data.bindPaged(calendarServices));
263
+ const shiftEntries = $.let(Data.bindPaged(calendarShifts));
264
+ // One rail over every record, a source each (#1343): each event kind through its interval indexes, its range the
265
+ // window the navigation writes in every kind at once; the machines, the people and each templates record by its fields.
266
+ const slice = $.let(Slice.bindRecords("ex.calendarReadOnly", {
267
+ job: { source: jobIndex, icon: { prefix: "fas", name: "industry" },
268
+ fields: { status: { label: "Status" }, machine: { label: "Machine", hints: ["press1", "press2", "lathe1", "lathe2", null] }, start: { label: "Dates" } }, range: "start" },
269
+ service: { source: serviceIndex, icon: { prefix: "fas", name: "screwdriver-wrench" },
270
+ fields: { machine: { label: "Machine", hints: ["press1", "press2", "lathe1", "lathe2"] }, start: { label: "Dates" } }, range: "start" },
271
+ shift: { source: shiftIndex, icon: { prefix: "fas", name: "user-clock" },
272
+ fields: { person: { label: "Person", hints: ["ash", "birch", "cedar"] }, start: { label: "Dates" } }, range: "start" },
273
+ machines: { source: machineIndex, icon: { prefix: "fas", name: "gears" },
274
+ fields: { area: { label: "Area", hints: ["Press shop", "Machine shop"] } } },
275
+ people: { source: peopleIndex, icon: { prefix: "fas", name: "users" },
276
+ fields: { team: { label: "Team", hints: ["Maintenance", "Production"] } } },
277
+ jobTemplates: { source: jobTemplateIndex, icon: { prefix: "fas", name: "layer-group" },
278
+ fields: { group: { label: "Job template", hints: ["Fabrication", "Machining"] } } },
279
+ serviceTemplates: { source: serviceTemplateIndex, icon: { prefix: "fas", name: "layer-group" },
280
+ fields: { group: { label: "Service template", hints: ["Preventive", "Calibration"] } } },
281
+ shiftTemplates: { source: shiftTemplateIndex, icon: { prefix: "fas", name: "layer-group" },
282
+ fields: { group: { label: "Shift template", hints: ["Day", "Late"] } } },
283
+ }));
284
+ return _jsx(Box, { height: "760px", children: _jsx(Calendar, { id: "operations", inspector: true, readOnly: true, view: { date: new Date("2026-10-01T00:00:00Z") }, now: new Date("2026-10-01T10:15:00Z"), slice: { slice }, resources: {
285
+ machines: Calendar.resources(machines.read(), { name: "Machines", icon: "gears", label: row => row.name, meta: row => some(row.area) }),
286
+ people: Calendar.resources(people.read(), { name: "People", icon: "users", label: row => row.name, meta: row => some(row.team) }),
233
287
  }, events: {
234
288
  job: Calendar.events(jobs, { name: "Production", icon: "industry", title: "title", start: "start", end: "end", resource: { field: "machine", of: "machines" },
235
- filter: row => Slice.apply.matches([CalendarFilter], slice.read(), cfg, jobScope(row)),
289
+ entries: jobEntries,
236
290
  status: { field: "status", cases: { planned: { label: "Planned", tone: variant("neutral", null), ring: true }, active: { label: "Active", tone: variant("info", null), ring: false }, done: { label: "Done", tone: variant("success", null), ring: false } } },
237
291
  backlog: { duration: row => variant("hours", row.hours), due: row => row.due },
238
292
  ready: row => row.hours.lessEqual(0).ifElse(() => variant("incomplete", [{ field: "hours", message: "Duration must be positive" }]), () => variant("ready", null)),
239
- templates: Calendar.templates(jobTemplates.read(), { name: row => row.name, group: row => some(row.group), duration: row => variant("hours", row.hours), values: row => row.values }),
293
+ templates: Calendar.templates(jobTemplates.read(), { name: row => row.name, group: row => some(row.group), duration: row => variant("hours", row.hours), values: row => row.values, source: "jobTemplates" }),
240
294
  }),
241
295
  service: Calendar.events(services, { name: "Maintenance", icon: "screwdriver-wrench", title: "title", start: "start", end: "end", resource: { field: "machine", of: "machines" },
242
- filter: row => Slice.apply.matches([CalendarFilter], slice.read(), cfg, serviceScope(row)),
296
+ entries: serviceEntries,
243
297
  fields: { technician: Calendar.field.reference({ of: "people" }) },
244
- templates: Calendar.templates(serviceTemplates.read(), { name: row => row.name, duration: row => variant("hours", row.hours), values: row => row.values }),
298
+ templates: Calendar.templates(serviceTemplates.read(), { name: row => row.name, group: row => some(row.group), duration: row => variant("hours", row.hours), values: row => row.values, source: "serviceTemplates" }),
245
299
  }),
246
300
  shift: Calendar.events(shifts, { name: "Shift", icon: "user-clock", title: "title", start: "start", end: "end", resource: { field: "person", of: "people" }, overlaps: "allow",
247
- filter: row => Slice.apply.matches([CalendarFilter], slice.read(), cfg, shiftScope(row)),
248
- templates: Calendar.templates(shiftTemplates.read(), { name: row => row.name, at: () => some({ hour: 6n, minute: 0n }), duration: () => variant("hours", 8.0), values: row => row.values }),
301
+ entries: shiftEntries,
302
+ templates: Calendar.templates(shiftTemplates.read(), { name: row => row.name, group: row => some(row.group), at: row => some({ hour: row.hour, minute: 0n }), duration: () => variant("hours", 8.0), values: row => row.values, source: "shiftTemplates" }),
249
303
  }),
250
304
  }, library: [Calendar.library.templates(), Calendar.library.backlog(), Calendar.library.tab(people.read(), {
251
305
  name: "Technicians", icon: "user-gear", label: row => row.name, meta: row => some(row.team), group: row => row.team,
252
- drop: (_row, key) => Calendar.patch(CalendarService, { technician: key }),
306
+ drop: (_row, key) => Calendar.patch(CalendarService, { technician: key }), source: "people",
253
307
  })] }) });
254
308
  } })),
255
309
  });
@@ -282,23 +336,16 @@ export const calendarJobsUnscheduled = e3.recordIndex("calendar_jobs_unscheduled
282
336
  });
283
337
  export const calendarWindowed = example({
284
338
  inputs: [],
285
- description: "The jobs calendar read by its day and backlog indexes, with by-key reads for the inspector and checked saves. An author-bound Slice selects the day-index keys read; navigation and the shared range control write that same Slice. Counts describe the loaded window. The same mobile agenda and explicit actions work over the paged record.",
286
- keywords: ["Calendar", "Data.bindPaged", "recordIndex", "window", "backlogWindow", "entries", "Slice", "Slice.bind", "range", "day keys", "mobile", "Save"],
339
+ description: "The jobs calendar read by its day and backlog indexes, with by-key reads for the inspector and checked saves. The calendar's own navigation picks the days read. Counts describe the loaded window. The same mobile agenda and explicit actions work over the paged record.",
340
+ keywords: ["Calendar", "Data.bindPaged", "recordIndex", "window", "backlogWindow", "entries", "day keys", "mobile", "Save"],
287
341
  fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
288
342
  const machines = $.let(Record.bind(calendarMachines, []));
289
343
  const jobs = $.let(Record.bind(calendarJobs, [calendarJobsPatch]));
290
344
  const days = $.let(Data.bindPaged(calendarJobs, { index: calendarJobsByDay, join: true }));
291
345
  const backlog = $.let(Data.bindPaged(calendarJobs, { index: calendarJobsUnscheduled, join: true }));
292
346
  const entries = $.let(Data.bindPaged(calendarJobs));
293
- const first = $.const(new Date("2026-10-01T00:00:00Z"), DateTimeType);
294
- // A bounded horizon of day keys, not a download of the event record.
295
- const horizon = $.let(East.Array.generate(31n, CalendarDay, (_$2, i) => ({ day: first.addDays(i) })));
296
- const slice = $.let(Slice.bind("ex.calendarWindowed.days", horizon, {
297
- fields: { day: { label: "Day", format: { date: "MMM D" } } },
298
- range: "day",
299
- initial: { day: { from: first, to: first.addDays(1n).addMilliseconds(-1n) } },
300
- }));
301
- return _jsx(Box, { height: "760px", children: _jsx(Calendar, { id: "windowed", inspector: true, view: { period: "day", date: new Date("2026-10-01T00:00:00Z") }, now: new Date("2026-10-01T10:15:00Z"), slice: { slice, affordances: ["range"] }, resources: { machines: Calendar.resources(machines.read(), { name: "Machines", icon: "gears", label: row => row.name }) }, events: { job: Calendar.events(jobs, { name: "Production", icon: "industry", title: "title", start: "start", end: "end", resource: { field: "machine", of: "machines" },
347
+ // The days in view are the calendar's own navigation's: it reads them through the day index, never the record whole.
348
+ return _jsx(Box, { height: "760px", children: _jsx(Calendar, { id: "windowed", inspector: true, view: { period: "day", date: new Date("2026-10-01T00:00:00Z") }, now: new Date("2026-10-01T10:15:00Z"), resources: { machines: Calendar.resources(machines.read(), { name: "Machines", icon: "gears", label: row => row.name }) }, events: { job: Calendar.events(jobs, { name: "Production", icon: "industry", title: "title", start: "start", end: "end", resource: { field: "machine", of: "machines" },
302
349
  window: days, backlogWindow: backlog, entries, backlog: { duration: row => variant("hours", row.hours), due: row => row.due },
303
350
  }) }, library: [Calendar.library.backlog()] }) });
304
351
  } })),