@flamingo-stack/openframe-frontend-core 0.0.740 → 0.0.742

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 (206) hide show
  1. package/dist/build/export-map.json +1 -1
  2. package/dist/{chunk-BV5WZVOP.cjs → chunk-32Q7K5OP.cjs} +254 -254
  3. package/dist/{chunk-ZLTCQKTD.cjs → chunk-3LW43GIJ.cjs} +6 -6
  4. package/dist/{chunk-VA7OMDZO.cjs → chunk-4FWURR3W.cjs} +50 -50
  5. package/dist/{chunk-EKGL5K5K.cjs → chunk-4LDU32OB.cjs} +17 -17
  6. package/dist/{chunk-VC4IV3AY.cjs → chunk-4PKORVOX.cjs} +2804 -954
  7. package/dist/{chunk-3ZIQOYNX.cjs → chunk-54EA4RLX.cjs} +8 -8
  8. package/dist/{chunk-YXKB5WRE.cjs → chunk-5MH6BRPY.cjs} +36 -36
  9. package/dist/{chunk-PQ2M7P2U.cjs → chunk-5TCIRWHL.cjs} +9 -9
  10. package/dist/{chunk-WFPCCBOM.cjs → chunk-7AM3AFM4.cjs} +10 -10
  11. package/dist/{chunk-7ZFCR7UY.cjs → chunk-ABLUMGCI.cjs} +3 -3
  12. package/dist/{chunk-PX7FY655.cjs → chunk-ASMNNSUQ.cjs} +3 -3
  13. package/dist/{chunk-HF7Z2E4W.cjs → chunk-BI3XBCQX.cjs} +2 -2
  14. package/dist/{chunk-SA7LDEVJ.cjs → chunk-CSJO7ZGN.cjs} +3 -3
  15. package/dist/{chunk-VOX4E6AX.cjs → chunk-DGFDBPO7.cjs} +7 -5
  16. package/dist/{chunk-KHXZFLIN.cjs → chunk-DKOLQPE7.cjs} +8 -2
  17. package/dist/{chunk-BDA5F6RM.cjs → chunk-DNFSMVXJ.cjs} +16 -16
  18. package/dist/{chunk-B3XBJCOD.cjs → chunk-H3UA7UY5.cjs} +7 -7
  19. package/dist/{chunk-2Y5Y4FLM.cjs → chunk-HDBY2URA.cjs} +64 -64
  20. package/dist/{chunk-UW3YXDC4.cjs → chunk-HIRVNBX5.cjs} +20 -20
  21. package/dist/{chunk-LLAC2UZ3.cjs → chunk-ISJXKKYW.cjs} +28 -28
  22. package/dist/{chunk-FICJS5OA.cjs → chunk-KTPR66EE.cjs} +4 -4
  23. package/dist/{chunk-7UIQPMBJ.cjs → chunk-L34TKFTS.cjs} +21 -164
  24. package/dist/{chunk-AAFW4STC.cjs → chunk-LU7TD6QS.cjs} +5 -5
  25. package/dist/{chunk-3HPB4H4C.cjs → chunk-NTGIQP7O.cjs} +7 -7
  26. package/dist/{chunk-WBANGORJ.cjs → chunk-OBODY7F3.cjs} +3 -3
  27. package/dist/{chunk-GABDE3FM.cjs → chunk-OWGLRE74.cjs} +19 -19
  28. package/dist/{chunk-CWRVTQUO.cjs → chunk-PS6T65KA.cjs} +101 -101
  29. package/dist/{chunk-IFS4AH77.cjs → chunk-QYLIHZKZ.cjs} +10 -10
  30. package/dist/{chunk-GVTDVS5U.cjs → chunk-R34JD6NP.cjs} +3 -3
  31. package/dist/{chunk-VU4CKUJW.cjs → chunk-R6SCSV2I.cjs} +103 -103
  32. package/dist/{chunk-II4QMH26.cjs → chunk-STEJZPIO.cjs} +3 -3
  33. package/dist/{chunk-4RLGLB45.cjs → chunk-T433HSL6.cjs} +47 -47
  34. package/dist/{chunk-DSVNFRY5.cjs → chunk-U2O5YQRP.cjs} +38 -38
  35. package/dist/{chunk-O67V3HJR.cjs → chunk-URVIPSAJ.cjs} +24 -24
  36. package/dist/{chunk-HYBMADYO.cjs → chunk-UWHCRIQQ.cjs} +22 -22
  37. package/dist/{chunk-GSWQZX23.cjs → chunk-UY6A6TEY.cjs} +2 -2
  38. package/dist/{chunk-D5KEWWLW.cjs → chunk-UZLRSFGG.cjs} +32 -32
  39. package/dist/{chunk-DUVOQHQI.cjs → chunk-W2RM764D.cjs} +7 -7
  40. package/dist/{chunk-NTJE6SM6.cjs → chunk-WI2OTGKC.cjs} +2 -2
  41. package/dist/{chunk-SFY4UYPY.cjs → chunk-WIHHA54J.cjs} +44 -44
  42. package/dist/{chunk-YRE3O65E.cjs → chunk-XAA5EZ5T.cjs} +12 -12
  43. package/dist/{chunk-KLI4OSRA.cjs → chunk-YQGDXH3M.cjs} +2 -2
  44. package/dist/{chunk-SWR22DOZ.cjs → chunk-Z2DQYKZA.cjs} +89 -89
  45. package/dist/{chunk-5SVOGLNK.cjs → chunk-ZIFYSLIM.cjs} +6 -6
  46. package/dist/{cloud-tenants-PVXDI5MU.cjs → cloud-tenants-6ICAL3HO.cjs} +34 -34
  47. package/dist/components/case-studies/index.cjs +37 -37
  48. package/dist/components/chat/index.cjs +17 -17
  49. package/dist/components/contact/index.cjs +25 -25
  50. package/dist/components/docs/index.cjs +28 -28
  51. package/dist/components/embeds/index.cjs +25 -25
  52. package/dist/components/faq/index.cjs +26 -26
  53. package/dist/components/features/capability-explorer.d.ts +9 -2
  54. package/dist/components/features/capability-explorer.d.ts.map +1 -1
  55. package/dist/components/features/capability-explorer.js +113 -6
  56. package/dist/components/features/index.cjs +162 -24
  57. package/dist/components/features/index.d.ts +1 -0
  58. package/dist/components/features/index.d.ts.map +1 -1
  59. package/dist/components/features/index.js +1 -0
  60. package/dist/components/features/scripts/execution-cells.d.ts +65 -0
  61. package/dist/components/features/scripts/execution-cells.d.ts.map +1 -0
  62. package/dist/components/features/scripts/execution-cells.js +75 -0
  63. package/dist/components/features/scripts/execution-status.d.ts +48 -0
  64. package/dist/components/features/scripts/execution-status.d.ts.map +1 -0
  65. package/dist/components/features/scripts/execution-status.js +15 -0
  66. package/dist/components/features/scripts/index.d.ts +20 -0
  67. package/dist/components/features/scripts/index.d.ts.map +1 -0
  68. package/dist/components/features/scripts/index.js +59 -0
  69. package/dist/components/features/scripts/schedule-form/index.d.ts +18 -0
  70. package/dist/components/features/scripts/schedule-form/index.d.ts.map +1 -0
  71. package/dist/components/features/scripts/schedule-form/index.js +84 -0
  72. package/dist/components/features/scripts/schedule-form/schedule-enums.d.ts +24 -0
  73. package/dist/components/features/scripts/schedule-form/schedule-enums.d.ts.map +1 -0
  74. package/dist/components/features/scripts/schedule-form/schedule-enums.js +18 -0
  75. package/dist/components/features/scripts/schedule-form/schedule-form-fields.d.ts +57 -0
  76. package/dist/components/features/scripts/schedule-form/schedule-form-fields.d.ts.map +1 -0
  77. package/dist/components/features/scripts/schedule-form/schedule-form-fields.js +169 -0
  78. package/dist/components/features/scripts/schedule-form/schedule-form-types.d.ts +138 -0
  79. package/dist/components/features/scripts/schedule-form/schedule-form-types.d.ts.map +1 -0
  80. package/dist/components/features/scripts/schedule-form/schedule-form-types.js +72 -0
  81. package/dist/components/features/scripts/schedule-form/schedule-interval-input.d.ts +54 -0
  82. package/dist/components/features/scripts/schedule-form/schedule-interval-input.d.ts.map +1 -0
  83. package/dist/components/features/scripts/schedule-form/schedule-interval-input.js +60 -0
  84. package/dist/components/features/scripts/schedule-form/schedule-offline-fields.d.ts +29 -0
  85. package/dist/components/features/scripts/schedule-form/schedule-offline-fields.d.ts.map +1 -0
  86. package/dist/components/features/scripts/schedule-form/schedule-offline-fields.js +124 -0
  87. package/dist/components/features/scripts/schedule-form/schedule-script-picker-card.d.ts +52 -0
  88. package/dist/components/features/scripts/schedule-form/schedule-script-picker-card.d.ts.map +1 -0
  89. package/dist/components/features/scripts/schedule-form/schedule-script-picker-card.js +244 -0
  90. package/dist/components/features/scripts/schedule-form/schedule-script-search-field.d.ts +35 -0
  91. package/dist/components/features/scripts/schedule-form/schedule-script-search-field.d.ts.map +1 -0
  92. package/dist/components/features/scripts/schedule-form/schedule-script-search-field.js +58 -0
  93. package/dist/components/features/scripts/schedule-form/schedule-scripts-field.d.ts +25 -0
  94. package/dist/components/features/scripts/schedule-form/schedule-scripts-field.d.ts.map +1 -0
  95. package/dist/components/features/scripts/schedule-form/schedule-scripts-field.js +66 -0
  96. package/dist/components/features/scripts/schedule-form/schedule-timing-fields.d.ts +77 -0
  97. package/dist/components/features/scripts/schedule-form/schedule-timing-fields.d.ts.map +1 -0
  98. package/dist/components/features/scripts/schedule-form/schedule-timing-fields.js +262 -0
  99. package/dist/components/features/scripts/schedule-form/schedule-timing.d.ts +288 -0
  100. package/dist/components/features/scripts/schedule-form/schedule-timing.d.ts.map +1 -0
  101. package/dist/components/features/scripts/schedule-form/schedule-timing.js +165 -0
  102. package/dist/components/features/scripts/script-cells.d.ts +11 -0
  103. package/dist/components/features/scripts/script-cells.d.ts.map +1 -0
  104. package/dist/components/features/scripts/script-cells.js +19 -0
  105. package/dist/components/features/scripts/script-executions-table.d.ts +58 -0
  106. package/dist/components/features/scripts/script-executions-table.d.ts.map +1 -0
  107. package/dist/components/features/scripts/script-executions-table.js +88 -0
  108. package/dist/components/features/scripts/script-schedules-table.d.ts +38 -0
  109. package/dist/components/features/scripts/script-schedules-table.d.ts.map +1 -0
  110. package/dist/components/features/scripts/script-schedules-table.js +71 -0
  111. package/dist/components/features/scripts/script-shell-badge.d.ts +9 -0
  112. package/dist/components/features/scripts/script-shell-badge.d.ts.map +1 -0
  113. package/dist/components/features/scripts/script-shell-badge.js +15 -0
  114. package/dist/components/features/scripts/scripts-table-columns.d.ts +162 -0
  115. package/dist/components/features/scripts/scripts-table-columns.d.ts.map +1 -0
  116. package/dist/components/features/scripts/scripts-table-columns.js +69 -0
  117. package/dist/components/features/scripts/scripts-table-shared.d.ts +19 -0
  118. package/dist/components/features/scripts/scripts-table-shared.d.ts.map +1 -0
  119. package/dist/components/features/scripts/scripts-table-shared.js +35 -0
  120. package/dist/components/features/scripts/scripts-table.d.ts +40 -0
  121. package/dist/components/features/scripts/scripts-table.d.ts.map +1 -0
  122. package/dist/components/features/scripts/scripts-table.js +84 -0
  123. package/dist/components/features/scripts/scripts-tabs.d.ts +5 -0
  124. package/dist/components/features/scripts/scripts-tabs.d.ts.map +1 -0
  125. package/dist/components/features/scripts/scripts-tabs.js +10 -0
  126. package/dist/components/features/scripts/shell-types.d.ts +13 -0
  127. package/dist/components/features/scripts/shell-types.d.ts.map +1 -0
  128. package/dist/components/features/scripts/shell-types.js +21 -0
  129. package/dist/components/help-center-pages/index.cjs +144 -144
  130. package/dist/components/index.cjs +224 -86
  131. package/dist/components/meeting-scheduler/index.cjs +74 -74
  132. package/dist/components/navigation/index.cjs +27 -27
  133. package/dist/components/onboarding-guides/index.cjs +27 -27
  134. package/dist/components/product-demo/fixtures/scripts.d.ts +34 -0
  135. package/dist/components/product-demo/fixtures/scripts.d.ts.map +1 -0
  136. package/dist/components/product-demo/fixtures/scripts.js +123 -0
  137. package/dist/components/product-demo/fixtures/shared.d.ts +8 -0
  138. package/dist/components/product-demo/fixtures/shared.d.ts.map +1 -1
  139. package/dist/components/product-demo/fixtures/shared.js +7 -1
  140. package/dist/components/product-demo/fixtures/software-update.d.ts.map +1 -1
  141. package/dist/components/product-demo/fixtures/software-update.js +1 -5
  142. package/dist/components/product-demo/index.cjs +16 -13
  143. package/dist/components/product-demo/product-screen.d.ts.map +1 -1
  144. package/dist/components/product-demo/product-screen.js +2 -1
  145. package/dist/components/product-demo/registry.d.ts.map +1 -1
  146. package/dist/components/product-demo/registry.js +2 -1
  147. package/dist/components/product-demo/screen-keys.cjs +2 -1
  148. package/dist/components/product-demo/screen-keys.d.ts +1 -0
  149. package/dist/components/product-demo/screen-keys.d.ts.map +1 -1
  150. package/dist/components/product-demo/screen-keys.js +2 -1
  151. package/dist/components/product-demo/screens/scripts.d.ts +11 -0
  152. package/dist/components/product-demo/screens/scripts.d.ts.map +1 -0
  153. package/dist/components/product-demo/screens/scripts.js +130 -0
  154. package/dist/components/related-content/index.cjs +12 -12
  155. package/dist/components/tickets/index.cjs +30 -30
  156. package/dist/components/ui/index.cjs +24 -24
  157. package/dist/{devices-TWEA7XOR.cjs → devices-OFP2IBKN.cjs} +30 -30
  158. package/dist/{embeddable-chat-6JKKFQEB.cjs → embeddable-chat-4C22MGNC.cjs} +92 -92
  159. package/dist/hooks/index.cjs +10 -10
  160. package/dist/index.cjs +169 -31
  161. package/dist/{knowledge-4GQDBNQB.cjs → knowledge-KKBCSNUA.cjs} +29 -29
  162. package/dist/{logs-EVU6GJHZ.cjs → logs-X2GRNO57.cjs} +46 -46
  163. package/dist/{policies-OZUEA5YS.cjs → policies-35BXKB6P.cjs} +31 -31
  164. package/dist/{remote-session-DNFZ5OLY.cjs → remote-session-N4PJB5FW.cjs} +15 -15
  165. package/dist/scripts-KQYVQOLU.cjs +2112 -0
  166. package/dist/{software-update-BLIVYOY2.cjs → software-update-ED33WSKT.cjs} +36 -40
  167. package/dist/{tickets-board-CKZRB6YV.cjs → tickets-board-O753S4ZB.cjs} +31 -31
  168. package/dist/utils/embed-authed-fetch.d.ts +33 -0
  169. package/dist/utils/embed-authed-fetch.d.ts.map +1 -1
  170. package/dist/utils/embed-authed-fetch.js +3 -1
  171. package/dist/utils/index.cjs +3 -1
  172. package/dist/{video-file-player-ZH2ILAPO.cjs → video-file-player-QZ3YOLHO.cjs} +2 -2
  173. package/package.json +1 -1
  174. package/src/components/features/capability-explorer.tsx +134 -7
  175. package/src/components/features/index.ts +1 -0
  176. package/src/components/features/scripts/execution-cells.tsx +149 -0
  177. package/src/components/features/scripts/execution-status.ts +42 -0
  178. package/src/components/features/scripts/index.ts +42 -0
  179. package/src/components/features/scripts/schedule-form/index.ts +59 -0
  180. package/src/components/features/scripts/schedule-form/schedule-enums.ts +26 -0
  181. package/src/components/features/scripts/schedule-form/schedule-form-fields.tsx +249 -0
  182. package/src/components/features/scripts/schedule-form/schedule-form-types.ts +189 -0
  183. package/src/components/features/scripts/schedule-form/schedule-interval-input.tsx +121 -0
  184. package/src/components/features/scripts/schedule-form/schedule-offline-fields.tsx +218 -0
  185. package/src/components/features/scripts/schedule-form/schedule-script-picker-card.tsx +321 -0
  186. package/src/components/features/scripts/schedule-form/schedule-script-search-field.tsx +115 -0
  187. package/src/components/features/scripts/schedule-form/schedule-scripts-field.tsx +97 -0
  188. package/src/components/features/scripts/schedule-form/schedule-timing-fields.tsx +482 -0
  189. package/src/components/features/scripts/schedule-form/schedule-timing.ts +484 -0
  190. package/src/components/features/scripts/script-cells.tsx +29 -0
  191. package/src/components/features/scripts/script-executions-table.tsx +145 -0
  192. package/src/components/features/scripts/script-schedules-table.tsx +113 -0
  193. package/src/components/features/scripts/script-shell-badge.tsx +25 -0
  194. package/src/components/features/scripts/scripts-table-columns.ts +95 -0
  195. package/src/components/features/scripts/scripts-table-shared.tsx +43 -0
  196. package/src/components/features/scripts/scripts-table.tsx +124 -0
  197. package/src/components/features/scripts/scripts-tabs.ts +11 -0
  198. package/src/components/features/scripts/shell-types.ts +26 -0
  199. package/src/components/product-demo/fixtures/scripts.ts +186 -0
  200. package/src/components/product-demo/fixtures/shared.ts +7 -0
  201. package/src/components/product-demo/fixtures/software-update.ts +1 -7
  202. package/src/components/product-demo/product-screen.tsx +3 -1
  203. package/src/components/product-demo/registry.ts +1 -0
  204. package/src/components/product-demo/screen-keys.ts +1 -0
  205. package/src/components/product-demo/screens/scripts.tsx +192 -0
  206. package/src/utils/embed-authed-fetch.ts +42 -1
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { OS_PLATFORMS } from "../../../../utils/os-platforms.js";
4
+ import { Autocomplete } from "../../../ui/autocomplete.js";
5
+ import { Label } from "../../../ui/label.js";
6
+ import { TruncateText } from "../../../ui/truncate-text.js";
7
+ function ScriptPlatformIcons({ platforms }) {
8
+ return /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center gap-0.5", children: OS_PLATFORMS.filter((p) => platforms.includes(p.id)).map((p) => /* @__PURE__ */ jsx(p.icon, { className: "h-3.5 w-3.5 text-ods-text-secondary opacity-60" }, p.id)) });
9
+ }
10
+ function ScheduleScriptSearchField({
11
+ scriptId,
12
+ name,
13
+ scripts,
14
+ isLoading = false,
15
+ inputValue = "",
16
+ onInputChange,
17
+ onOpen,
18
+ onClose,
19
+ onChange,
20
+ disabled = false,
21
+ error,
22
+ invalid = false
23
+ }) {
24
+ const handleBlur = (e) => {
25
+ if (!e.currentTarget.contains(e.relatedTarget)) onClose?.();
26
+ };
27
+ const options = scripts.map((s) => ({ label: s.name, value: s.id }));
28
+ if (scriptId && !options.some((o) => o.value === scriptId)) {
29
+ options.unshift({ label: name, value: scriptId });
30
+ }
31
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-[var(--spacing-system-xxs)]", onFocus: onOpen, onBlur: handleBlur, children: [
32
+ /* @__PURE__ */ jsx(Label, { className: "text-h4", children: "Select Script" }),
33
+ /* @__PURE__ */ jsx(
34
+ Autocomplete,
35
+ {
36
+ options,
37
+ value: scriptId || null,
38
+ onChange,
39
+ placeholder: "Select a script...",
40
+ disableClientFilter: true,
41
+ onInputChange,
42
+ loading: isLoading,
43
+ loadingText: "Searching scripts...",
44
+ noOptionsText: inputValue ? "No scripts match your search" : "No scripts available",
45
+ disabled,
46
+ error,
47
+ invalid,
48
+ renderOption: (option, isSelected) => /* @__PURE__ */ jsxs("span", { className: "flex w-full min-w-0 items-center gap-[var(--spacing-system-xsf)]", children: [
49
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(TruncateText, { className: isSelected ? "text-ods-accent" : void 0, children: option.label }) }),
50
+ /* @__PURE__ */ jsx(ScriptPlatformIcons, { platforms: scripts.find((s) => s.id === option.value)?.supportedPlatforms ?? [] })
51
+ ] })
52
+ }
53
+ )
54
+ ] });
55
+ }
56
+ export {
57
+ ScheduleScriptSearchField
58
+ };
@@ -0,0 +1,25 @@
1
+ import { type RenderScheduleScriptSearch } from './schedule-form-types';
2
+ export interface ScheduleScriptsFieldProps {
3
+ showErrors: boolean;
4
+ disabled?: boolean;
5
+ /** The "Select Script" field of each card. */
6
+ renderScriptSearch: RenderScheduleScriptSearch;
7
+ /** The "Scheduled Scripts" heading over the cards. Default true. */
8
+ showHeading?: boolean;
9
+ /** Each card's arguments and environment variables. Default true; false is one row per card. */
10
+ showScriptParams?: boolean;
11
+ /** Offer "Add Script" (several scripts in one schedule). Default true. */
12
+ addScripts?: boolean;
13
+ }
14
+ /**
15
+ * "Scheduled Scripts" — the ordered list of script cards. Card order IS the run
16
+ * order: it is submitted as `scriptIds` verbatim, so a reorder is a real,
17
+ * persisted change.
18
+ *
19
+ * Reordering runs on the core library's `SortableList` (Pragmatic drag and
20
+ * drop): drag on desktop, an up/down button pair per card on touch/narrow
21
+ * viewports, where no DnD is initialized at all. The list owns the live-region
22
+ * announcements (`getItemLabel`) and the keyboard path on the handle.
23
+ */
24
+ export declare function ScheduleScriptsField({ showErrors, disabled, renderScriptSearch, showHeading, showScriptParams, addScripts, }: ScheduleScriptsFieldProps): import("react").JSX.Element;
25
+ //# sourceMappingURL=schedule-scripts-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-scripts-field.d.ts","sourceRoot":"","sources":["../../../../../src/components/features/scripts/schedule-form/schedule-scripts-field.tsx"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,0BAA0B,EAEhC,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,kBAAkB,EAAE,0BAA0B,CAAC;IAC/C,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,UAAU,EACV,QAAgB,EAChB,kBAAkB,EAClB,WAAkB,EAClB,gBAAuB,EACvB,UAAiB,GAClB,EAAE,yBAAyB,+BAoD3B"}
@@ -0,0 +1,66 @@
1
+ "use client";
2
+ "use no memo";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { useFieldArray, useFormContext, useWatch } from "react-hook-form";
5
+ import { PlusCircleIcon } from "../../../icons-v2-generated/signs-and-symbols/plus-circle-icon.js";
6
+ import { Button } from "../../../ui/button/index.js";
7
+ import { SortableList } from "../../sortable-list/sortable-list.js";
8
+ import {
9
+ EMPTY_SCHEDULE_SCRIPT_ROW
10
+ } from "./schedule-form-types.js";
11
+ import { ScheduleScriptPickerCard } from "./schedule-script-picker-card.js";
12
+ function ScheduleScriptsField({
13
+ showErrors,
14
+ disabled = false,
15
+ renderScriptSearch,
16
+ showHeading = true,
17
+ showScriptParams = true,
18
+ addScripts = true
19
+ }) {
20
+ const { control, getValues } = useFormContext();
21
+ const { fields, append, remove, move } = useFieldArray({ control, name: "scripts" });
22
+ const supportedPlatforms = useWatch({ control, name: "supportedPlatforms" });
23
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-[var(--spacing-system-lf)]", children: [
24
+ showHeading && /* @__PURE__ */ jsx("div", { className: "flex min-h-[72px] items-end pt-[var(--spacing-system-l)]", children: /* @__PURE__ */ jsx("h2", { className: "text-ods-text-primary text-h2", children: "Scheduled Scripts" }) }),
25
+ /* @__PURE__ */ jsx(
26
+ SortableList,
27
+ {
28
+ onReorder: move,
29
+ disabled,
30
+ getItemLabel: (index) => getValues(`scripts.${index}.name`) || `script ${index + 1}`,
31
+ className: "flex flex-col gap-[var(--spacing-system-lf)]",
32
+ children: fields.map((field, index) => /* @__PURE__ */ jsx(
33
+ ScheduleScriptPickerCard,
34
+ {
35
+ index,
36
+ count: fields.length,
37
+ supportedPlatforms,
38
+ renderScriptSearch,
39
+ onRemove: () => remove(index),
40
+ canRemove: fields.length > 1,
41
+ disabled,
42
+ showErrors,
43
+ showParams: showScriptParams
44
+ },
45
+ field.id
46
+ ))
47
+ }
48
+ ),
49
+ addScripts && /* @__PURE__ */ jsx(
50
+ Button,
51
+ {
52
+ type: "button",
53
+ variant: "outline",
54
+ size: "small",
55
+ onClick: () => append(EMPTY_SCHEDULE_SCRIPT_ROW),
56
+ disabled,
57
+ className: "self-start",
58
+ leftIcon: /* @__PURE__ */ jsx(PlusCircleIcon, { className: "text-ods-text-secondary" }),
59
+ children: "Add Script"
60
+ }
61
+ )
62
+ ] });
63
+ }
64
+ export {
65
+ ScheduleScriptsField
66
+ };
@@ -0,0 +1,77 @@
1
+ import type { ScheduleTimeReference } from './schedule-enums';
2
+ import { type ScheduleFormGate, type ScheduleTimeSlot } from './schedule-form-types';
3
+ export interface ScheduleTimingFieldsProps {
4
+ showErrors: boolean;
5
+ disabled?: boolean;
6
+ /**
7
+ * Whether the Timezone picker is offered. It is a layout switch (it turns one
8
+ * row into two), so a host that reads it from a flag passes the flag's GATE.
9
+ * Default `off`.
10
+ */
11
+ timeReferenceGate?: ScheduleFormGate;
12
+ /**
13
+ * The Time dropdown's options for a picked day and reading. Default
14
+ * `getTimeSlotOptions`: the viewer's own clock and locale. A picture of the
15
+ * form passes fixed readings, so a server and a browser draw the same one.
16
+ */
17
+ getTimeSlots?: (date: Date | null, timeReference: ScheduleTimeReference) => ScheduleTimeSlot[];
18
+ }
19
+ /**
20
+ * Date | Time | Timezone | Repeat | Repeat in — the timing a DATE_TIME schedule
21
+ * fires on.
22
+ *
23
+ * `scheduledDate` + `scheduledTime` combine into the backend's `startAt` (30-min
24
+ * boundary, enforced by the Time slots) and are both required; the repeat toggle
25
+ * + interval + unit become `repeat` seconds.
26
+ *
27
+ * **Timezone** (`timeReference`, design node 793:61340) says what that pair
28
+ * MEANS — the account's clock (SERVER, one instant worldwide) or each device's
29
+ * (DEVICE_LOCAL, one reading re-based per device). It is behind the
30
+ * host's `timeReferenceGate` (the product's `script-schedule-device-time`
31
+ * flag), and it is the field that makes this a
32
+ * five-control row: with the picker on, the design wraps Repeat onto a second
33
+ * line, which is why the row is a 4-column GRID rather than the flex row it
34
+ * used to be — the wrap is then a `col-start-1` on one cell instead of a second
35
+ * layout.
36
+ *
37
+ * Recurrence stays OFFERED for DEVICE_LOCAL — "every day at 9 AM on each
38
+ * device's own clock" is the reason the reading exists — even though the API
39
+ * refuses it today ("A DEVICE_LOCAL schedule does not support repeat **yet**",
40
+ * `ScheduleScriptService.validateTiming`). Saving one is answered by that
41
+ * message in the error toast until the backend drops the check; nothing here
42
+ * has to change when it does. Its offline setting is refused the same way and
43
+ * IS hidden, because that one is not merely unimplemented: the device-local
44
+ * runner already retries on reconnect within its catch-up window, so the
45
+ * setting would have nothing to add — see `ScheduleOfflineFields`.
46
+ *
47
+ * What it does NOT constrain is the clock. The picked pair is a wall clock every
48
+ * device reads on its own timezone, so the viewer's "already gone by" says
49
+ * nothing about the fleet's: all 48 slots stay offered, the past-start rule is
50
+ * off, and the only bound left is the day one (`earliestScheduleDay` — today as
51
+ * read in UTC−12). The API validates no start against the past either, for
52
+ * either reading.
53
+ *
54
+ * Only DATE_TIME schedules have timing, so the row collapses when the event
55
+ * trigger is picked. It stays MOUNTED (a toggle back restores what was typed)
56
+ * and animates with the `0fr → 1fr` grid-rows technique — the portable way to
57
+ * transition to an intrinsic height, since `interpolate-size` / `calc-size()`
58
+ * still aren't cross-browser. `inert` drops the collapsed fields out of the tab
59
+ * order and the accessibility tree.
60
+ *
61
+ * The `overflow-hidden` the technique requires also clips anything hanging below
62
+ * the fields — and field errors are absolutely positioned there (out of flow, so
63
+ * showing one never reflows the form). The bottom padding is the room they render
64
+ * into; the constant negative margin cancels it again, so the spacing below the
65
+ * row is unchanged and a COLLAPSED row leaves no 24px hole.
66
+ *
67
+ * That padding sits on the field row INSIDE the clipping box, not on the box
68
+ * itself, and the difference is load-bearing: a box is never shorter than its own
69
+ * padding — `border-box` does not change that, it only decides what a specified
70
+ * height includes — so padding on the grid item survives the 0fr track as 24px of
71
+ * residue. The negative margin then spends itself cancelling that instead of
72
+ * closing the section gap, and the collapsed row leaves the hole this was written
73
+ * to avoid. Nested one level down it is clipped like everything else, and the row
74
+ * measures 0.
75
+ */
76
+ export declare function ScheduleTimingFields({ showErrors, disabled, timeReferenceGate, getTimeSlots, }: ScheduleTimingFieldsProps): import("react").JSX.Element;
77
+ //# sourceMappingURL=schedule-timing-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-timing-fields.d.ts","sourceRoot":"","sources":["../../../../../src/components/features/scripts/schedule-form/schedule-timing-fields.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAkB/B,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,gBAAgB,CAAC;IACrC;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,aAAa,EAAE,qBAAqB,KAAK,gBAAgB,EAAE,CAAC;CAChG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,UAAU,EACV,QAAgB,EAChB,iBAAyB,EACzB,YAAiC,GAClC,EAAE,yBAAyB,+BA+W3B"}
@@ -0,0 +1,262 @@
1
+ "use client";
2
+ "use no memo";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { useCallback, useMemo } from "react";
5
+ import { Controller, useFormContext, useWatch } from "react-hook-form";
6
+ import { cn } from "../../../../utils/cn.js";
7
+ import { XmarkCircleIcon } from "../../../icons-v2-generated/signs-and-symbols/xmark-circle-icon.js";
8
+ import { CheckboxBlock } from "../../../ui/checkbox-block.js";
9
+ import { DatePickerInputSimple } from "../../../ui/date-picker.js";
10
+ import { Label } from "../../../ui/label.js";
11
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../../ui/select.js";
12
+ import {
13
+ SCHEDULE_TIME_REFERENCE_OPTIONS
14
+ } from "./schedule-form-types.js";
15
+ import { ScheduleIntervalInput } from "./schedule-interval-input.js";
16
+ import {
17
+ DURATION_UNIT_OPTIONS,
18
+ earliestScheduleDay,
19
+ getTimeSlotOptions,
20
+ isEventTrigger,
21
+ isScheduleStartInPast,
22
+ isSlotOnGrid,
23
+ isStartInPastAndChanged,
24
+ MIN_REPEAT_MINUTES,
25
+ NO_SLOTS_TODAY_MESSAGE,
26
+ PAST_START_MESSAGE,
27
+ slotToLabel,
28
+ snapRepeatInterval
29
+ } from "./schedule-timing.js";
30
+ function ScheduleTimingFields({
31
+ showErrors,
32
+ disabled = false,
33
+ timeReferenceGate = "off",
34
+ getTimeSlots = getTimeSlotOptions
35
+ }) {
36
+ const { control, getValues, setValue, trigger: triggerValidation } = useFormContext();
37
+ const showTimeReference = timeReferenceGate === "on";
38
+ const fieldsDisabled = disabled || timeReferenceGate === "loading";
39
+ const recheckReconnectWindow = useCallback(() => {
40
+ if (showErrors) void triggerValidation("reconnectInterval");
41
+ }, [showErrors, triggerValidation]);
42
+ const trigger = useWatch({ control, name: "trigger" });
43
+ const repeatEnabled = useWatch({ control, name: "repeatEnabled" });
44
+ const repeatUnit = useWatch({ control, name: "repeatUnit" });
45
+ const scheduledDate = useWatch({ control, name: "scheduledDate" });
46
+ const scheduledTime = useWatch({ control, name: "scheduledTime" });
47
+ const timeReference = useWatch({ control, name: "timeReference" });
48
+ const eventDriven = isEventTrigger(trigger);
49
+ const intervalStep = repeatUnit === "minute" ? MIN_REPEAT_MINUTES : 1;
50
+ const timeSlots = useMemo(() => {
51
+ const slots = getTimeSlots(scheduledDate, timeReference);
52
+ if (!scheduledTime || slots.some((slot) => slot.value === scheduledTime)) return slots;
53
+ return [{ value: scheduledTime, label: slotToLabel(scheduledTime) }, ...slots];
54
+ }, [getTimeSlots, scheduledDate, scheduledTime, timeReference]);
55
+ const minDate = useMemo(() => earliestScheduleDay(timeReference), [timeReference]);
56
+ const handleDateChange = useCallback(
57
+ (onChange, date) => {
58
+ onChange(date);
59
+ const time = getValues("scheduledTime");
60
+ if (date && time && date >= minDate && isScheduleStartInPast(date, time, getValues("timeReference")))
61
+ setValue("scheduledTime", "");
62
+ },
63
+ [getValues, setValue, minDate]
64
+ );
65
+ const handleTimeReferenceChange = useCallback(
66
+ (onChange, next) => {
67
+ onChange(next);
68
+ const time = getValues("scheduledTime");
69
+ if (time && !isSlotOnGrid(time, next)) setValue("scheduledTime", "");
70
+ },
71
+ [getValues, setValue]
72
+ );
73
+ const startAtStored = useWatch({ control, name: "startAtStored" });
74
+ const startsInPast = !eventDriven && isStartInPastAndChanged(scheduledDate, scheduledTime, startAtStored, timeReference);
75
+ const pastDateError = startsInPast && scheduledDate && scheduledDate < minDate ? PAST_START_MESSAGE : void 0;
76
+ const pastTimeError = startsInPast && !pastDateError ? PAST_START_MESSAGE : void 0;
77
+ const noSlotsLeftToday = !eventDriven && timeSlots.length === 0;
78
+ const dateError = pastDateError ?? (noSlotsLeftToday ? NO_SLOTS_TODAY_MESSAGE : void 0);
79
+ return /* @__PURE__ */ jsx(
80
+ "div",
81
+ {
82
+ inert: eventDriven,
83
+ style: {
84
+ gridTemplateRows: eventDriven ? "0fr" : "1fr",
85
+ opacity: eventDriven ? 0 : 1
86
+ },
87
+ className: "mb-[calc(-1*var(--spacing-system-lf))] grid transition-[grid-template-rows,opacity] duration-200 ease-out motion-reduce:transition-none",
88
+ children: /* @__PURE__ */ jsx("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-[var(--spacing-system-lf)] pb-[var(--spacing-system-lf)] content-md:grid-cols-4 content-md:items-end", children: [
89
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-[var(--spacing-system-xxs)]", children: [
90
+ /* @__PURE__ */ jsx(Label, { className: "text-h4", children: "Date" }),
91
+ /* @__PURE__ */ jsx(
92
+ Controller,
93
+ {
94
+ name: "scheduledDate",
95
+ control,
96
+ render: ({ field, fieldState }) => (
97
+ // The core picker has no clear affordance, so the design's xmark
98
+ // rides on top of the trigger's free right edge.
99
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
100
+ /* @__PURE__ */ jsx(
101
+ DatePickerInputSimple,
102
+ {
103
+ placeholder: "Select date",
104
+ value: field.value ?? void 0,
105
+ onChange: (date) => handleDateChange(field.onChange, date ?? null),
106
+ fromDate: minDate,
107
+ disabled: fieldsDisabled,
108
+ className: "w-full",
109
+ error: dateError ?? (showErrors ? fieldState.error?.message : void 0),
110
+ invalid: !!dateError || showErrors && !!fieldState.error
111
+ }
112
+ ),
113
+ field.value && !fieldsDisabled && /* @__PURE__ */ jsx(
114
+ "button",
115
+ {
116
+ type: "button",
117
+ onClick: () => field.onChange(null),
118
+ "aria-label": "Clear date",
119
+ className: "absolute right-3 top-6 -translate-y-1/2 text-ods-text-secondary hover:text-ods-text-primary",
120
+ children: /* @__PURE__ */ jsx(XmarkCircleIcon, { size: 24 })
121
+ }
122
+ )
123
+ ] })
124
+ )
125
+ }
126
+ )
127
+ ] }),
128
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-[var(--spacing-system-xxs)]", children: [
129
+ /* @__PURE__ */ jsx(Label, { className: "text-h4", children: "Time" }),
130
+ /* @__PURE__ */ jsx(
131
+ Controller,
132
+ {
133
+ name: "scheduledTime",
134
+ control,
135
+ render: ({ field, fieldState }) => (
136
+ // `''` reads as "no selection" to Radix, so the placeholder shows
137
+ // until a slot is picked — a date at midnight no longer
138
+ // masquerades as a chosen 12:00 AM.
139
+ /* @__PURE__ */ jsxs(Select, { value: field.value, onValueChange: field.onChange, disabled: fieldsDisabled, children: [
140
+ /* @__PURE__ */ jsx(
141
+ SelectTrigger,
142
+ {
143
+ className: "w-full",
144
+ error: pastTimeError ?? (showErrors ? fieldState.error?.message : void 0),
145
+ invalid: !!pastTimeError || showErrors && !!fieldState.error,
146
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select time" })
147
+ }
148
+ ),
149
+ /* @__PURE__ */ jsx(SelectContent, { children: timeSlots.length === 0 ? (
150
+ // Deliberately NOT a `SelectItem` — there is nothing here
151
+ // to select, and a selectable row would put a bogus value
152
+ // in the form. It replaces a popup that opened blank; the
153
+ // Date field carries the same sentence for whoever never
154
+ // opens this one.
155
+ /* @__PURE__ */ jsx("p", { className: "px-4 py-[var(--spacing-system-sf)] text-ods-text-secondary text-h6", children: NO_SLOTS_TODAY_MESSAGE })
156
+ ) : timeSlots.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
157
+ ] })
158
+ )
159
+ }
160
+ )
161
+ ] }),
162
+ showTimeReference && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-[var(--spacing-system-xxs)]", children: [
163
+ /* @__PURE__ */ jsx(Label, { className: "text-h4", children: "Timezone" }),
164
+ /* @__PURE__ */ jsx(
165
+ Controller,
166
+ {
167
+ name: "timeReference",
168
+ control,
169
+ render: ({ field }) => /* @__PURE__ */ jsxs(
170
+ Select,
171
+ {
172
+ value: field.value,
173
+ onValueChange: (next) => handleTimeReferenceChange(field.onChange, next),
174
+ disabled: fieldsDisabled,
175
+ children: [
176
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-full", "aria-label": "Timezone", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
177
+ /* @__PURE__ */ jsx(SelectContent, { children: SCHEDULE_TIME_REFERENCE_OPTIONS.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
178
+ ]
179
+ }
180
+ )
181
+ }
182
+ )
183
+ ] }),
184
+ /* @__PURE__ */ jsx("div", { className: cn("min-w-0", showTimeReference && "content-md:col-start-1"), children: /* @__PURE__ */ jsx(
185
+ Controller,
186
+ {
187
+ name: "repeatEnabled",
188
+ control,
189
+ render: ({ field }) => /* @__PURE__ */ jsx(
190
+ CheckboxBlock,
191
+ {
192
+ label: "Repeat Script Run",
193
+ checked: field.value,
194
+ onCheckedChange: (next) => {
195
+ field.onChange(next);
196
+ recheckReconnectWindow();
197
+ },
198
+ disabled: fieldsDisabled,
199
+ className: "w-full"
200
+ }
201
+ )
202
+ }
203
+ ) }),
204
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-end gap-[var(--spacing-system-xs)]", children: [
205
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-[var(--spacing-system-xxs)]", children: [
206
+ /* @__PURE__ */ jsx(Label, { className: "text-h4", children: "Repeat in" }),
207
+ /* @__PURE__ */ jsx(
208
+ Controller,
209
+ {
210
+ name: "repeatInterval",
211
+ control,
212
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsx(
213
+ ScheduleIntervalInput,
214
+ {
215
+ min: intervalStep,
216
+ className: "w-full",
217
+ value: field.value,
218
+ onChange: field.onChange,
219
+ onBlur: () => {
220
+ field.onBlur();
221
+ recheckReconnectWindow();
222
+ },
223
+ disabled: fieldsDisabled || !repeatEnabled,
224
+ error: showErrors ? fieldState.error?.message : void 0,
225
+ invalid: showErrors && !!fieldState.error
226
+ }
227
+ )
228
+ }
229
+ )
230
+ ] }),
231
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(
232
+ Controller,
233
+ {
234
+ name: "repeatUnit",
235
+ control,
236
+ render: ({ field }) => /* @__PURE__ */ jsxs(
237
+ Select,
238
+ {
239
+ value: field.value,
240
+ onValueChange: (next) => {
241
+ field.onChange(next);
242
+ const snapped = snapRepeatInterval(getValues("repeatInterval"), next);
243
+ if (snapped !== getValues("repeatInterval")) setValue("repeatInterval", snapped);
244
+ recheckReconnectWindow();
245
+ },
246
+ disabled: fieldsDisabled || !repeatEnabled,
247
+ children: [
248
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
249
+ /* @__PURE__ */ jsx(SelectContent, { children: DURATION_UNIT_OPTIONS.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
250
+ ]
251
+ }
252
+ )
253
+ }
254
+ ) })
255
+ ] })
256
+ ] }) })
257
+ }
258
+ );
259
+ }
260
+ export {
261
+ ScheduleTimingFields
262
+ };