@djangocfg/ui-tools 2.1.390 → 2.1.394

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 (184) hide show
  1. package/README.md +7 -10
  2. package/dist/chunk-PAWJFY3S.mjs +6 -0
  3. package/dist/{chunk-N2XQF2OL.mjs.map → chunk-PAWJFY3S.mjs.map} +1 -1
  4. package/dist/chunk-PK6SKIKE.cjs +8 -0
  5. package/dist/{chunk-OLISEQHS.cjs.map → chunk-PK6SKIKE.cjs.map} +1 -1
  6. package/dist/file-icon/index.cjs +6 -6
  7. package/dist/file-icon/index.d.cts +1 -1
  8. package/dist/file-icon/index.d.ts +1 -1
  9. package/dist/file-icon/index.mjs +1 -1
  10. package/dist/tree/index.cjs +1372 -143
  11. package/dist/tree/index.cjs.map +1 -1
  12. package/dist/tree/index.d.cts +2 -2
  13. package/dist/tree/index.d.ts +2 -2
  14. package/dist/tree/index.mjs +1322 -3
  15. package/dist/tree/index.mjs.map +1 -1
  16. package/dist/{types-CevSbyfD.d.cts → types-B_zhyAqR.d.cts} +1 -1
  17. package/dist/{types-CevSbyfD.d.ts → types-B_zhyAqR.d.ts} +1 -1
  18. package/package.json +6 -14
  19. package/src/tools/AudioPlayer/README.md +4 -4
  20. package/src/tools/Chat/README.md +6 -6
  21. package/src/tools/CronScheduler/index.tsx +1 -1
  22. package/src/tools/CronScheduler/lazy.tsx +1 -1
  23. package/src/tools/ImageViewer/README.md +1 -1
  24. package/src/tools/JsonForm/README.md +2 -2
  25. package/src/tools/MarkdownEditor/README.md +3 -3
  26. package/src/tools/MarkdownMessage/README.md +2 -2
  27. package/src/tools/OpenapiViewer/components/DocsLayout/grouping.ts +5 -1
  28. package/src/tools/PrettyCode/lazy.tsx +6 -0
  29. package/src/tools/SpeechRecognition/README.md +1 -1
  30. package/dist/ChatRoot-EFNXQXXN.cjs +0 -15
  31. package/dist/ChatRoot-EFNXQXXN.cjs.map +0 -1
  32. package/dist/ChatRoot-FITF5RVP.mjs +0 -6
  33. package/dist/ChatRoot-FITF5RVP.mjs.map +0 -1
  34. package/dist/ChatRoot-PNNGQCYF.css +0 -7
  35. package/dist/ChatRoot-PNNGQCYF.css.map +0 -1
  36. package/dist/CronScheduler.client-DLMXCPAJ.mjs +0 -67
  37. package/dist/CronScheduler.client-DLMXCPAJ.mjs.map +0 -1
  38. package/dist/CronScheduler.client-WEJF4PWQ.cjs +0 -72
  39. package/dist/CronScheduler.client-WEJF4PWQ.cjs.map +0 -1
  40. package/dist/DictationField-AS2F33WI.cjs +0 -13
  41. package/dist/DictationField-AS2F33WI.cjs.map +0 -1
  42. package/dist/DictationField-WPONUCYE.mjs +0 -4
  43. package/dist/DictationField-WPONUCYE.mjs.map +0 -1
  44. package/dist/DocsLayout-EKASBSP7.mjs +0 -3448
  45. package/dist/DocsLayout-EKASBSP7.mjs.map +0 -1
  46. package/dist/DocsLayout-MBFIB4NO.css +0 -7
  47. package/dist/DocsLayout-MBFIB4NO.css.map +0 -1
  48. package/dist/DocsLayout-OURFYWQE.cjs +0 -3455
  49. package/dist/DocsLayout-OURFYWQE.cjs.map +0 -1
  50. package/dist/JsonSchemaForm-DD7CLRIG.cjs +0 -13
  51. package/dist/JsonSchemaForm-DD7CLRIG.cjs.map +0 -1
  52. package/dist/JsonSchemaForm-XKUIVELK.mjs +0 -4
  53. package/dist/JsonSchemaForm-XKUIVELK.mjs.map +0 -1
  54. package/dist/JsonTree-43PQAJKY.mjs +0 -5
  55. package/dist/JsonTree-43PQAJKY.mjs.map +0 -1
  56. package/dist/JsonTree-MLET23ZA.css +0 -7
  57. package/dist/JsonTree-MLET23ZA.css.map +0 -1
  58. package/dist/JsonTree-X6W5YEVY.cjs +0 -11
  59. package/dist/JsonTree-X6W5YEVY.cjs.map +0 -1
  60. package/dist/LottiePlayer.client-2S7ISJ2S.cjs +0 -168
  61. package/dist/LottiePlayer.client-2S7ISJ2S.cjs.map +0 -1
  62. package/dist/LottiePlayer.client-5LDSSJWS.mjs +0 -161
  63. package/dist/LottiePlayer.client-5LDSSJWS.mjs.map +0 -1
  64. package/dist/MapContainer-AKIPABJK.mjs +0 -4
  65. package/dist/MapContainer-AKIPABJK.mjs.map +0 -1
  66. package/dist/MapContainer-STVDMC36.cjs +0 -17
  67. package/dist/MapContainer-STVDMC36.cjs.map +0 -1
  68. package/dist/Mermaid.client-DDXWXZXY.css +0 -7
  69. package/dist/Mermaid.client-DDXWXZXY.css.map +0 -1
  70. package/dist/Mermaid.client-NL4SVR7F.mjs +0 -481
  71. package/dist/Mermaid.client-NL4SVR7F.mjs.map +0 -1
  72. package/dist/Mermaid.client-NNTI6DFX.cjs +0 -487
  73. package/dist/Mermaid.client-NNTI6DFX.cjs.map +0 -1
  74. package/dist/Player-BRV7XTWR.mjs +0 -4
  75. package/dist/Player-BRV7XTWR.mjs.map +0 -1
  76. package/dist/Player-PM7F7DD7.cjs +0 -13
  77. package/dist/Player-PM7F7DD7.cjs.map +0 -1
  78. package/dist/Player-ZGQKKOWI.css +0 -66
  79. package/dist/Player-ZGQKKOWI.css.map +0 -1
  80. package/dist/PrettyCode.client-GWFAIVFN.css +0 -7
  81. package/dist/PrettyCode.client-GWFAIVFN.css.map +0 -1
  82. package/dist/PrettyCode.client-KOHDVPPN.cjs +0 -285
  83. package/dist/PrettyCode.client-KOHDVPPN.cjs.map +0 -1
  84. package/dist/PrettyCode.client-ZGYGKE7G.mjs +0 -283
  85. package/dist/PrettyCode.client-ZGYGKE7G.mjs.map +0 -1
  86. package/dist/TreeRoot-5COOOSWG.mjs +0 -4
  87. package/dist/TreeRoot-5COOOSWG.mjs.map +0 -1
  88. package/dist/TreeRoot-AABP2J6Y.cjs +0 -19
  89. package/dist/TreeRoot-AABP2J6Y.cjs.map +0 -1
  90. package/dist/chunk-2NG4SXEP.mjs +0 -743
  91. package/dist/chunk-2NG4SXEP.mjs.map +0 -1
  92. package/dist/chunk-4LFB7I5K.cjs +0 -1387
  93. package/dist/chunk-4LFB7I5K.cjs.map +0 -1
  94. package/dist/chunk-5D2OCOPQ.cjs +0 -222
  95. package/dist/chunk-5D2OCOPQ.cjs.map +0 -1
  96. package/dist/chunk-5I5QNGUG.cjs +0 -611
  97. package/dist/chunk-5I5QNGUG.cjs.map +0 -1
  98. package/dist/chunk-6ZX2G25W.mjs +0 -1361
  99. package/dist/chunk-6ZX2G25W.mjs.map +0 -1
  100. package/dist/chunk-76NNDZH6.cjs +0 -1061
  101. package/dist/chunk-76NNDZH6.cjs.map +0 -1
  102. package/dist/chunk-7CWGZPO3.mjs +0 -214
  103. package/dist/chunk-7CWGZPO3.mjs.map +0 -1
  104. package/dist/chunk-7EYHNP3E.cjs +0 -965
  105. package/dist/chunk-7EYHNP3E.cjs.map +0 -1
  106. package/dist/chunk-7IYXZUJO.cjs +0 -769
  107. package/dist/chunk-7IYXZUJO.cjs.map +0 -1
  108. package/dist/chunk-ADEN3UA4.cjs +0 -892
  109. package/dist/chunk-ADEN3UA4.cjs.map +0 -1
  110. package/dist/chunk-B6IR5KSC.mjs +0 -59
  111. package/dist/chunk-B6IR5KSC.mjs.map +0 -1
  112. package/dist/chunk-C6GXVH5J.mjs +0 -338
  113. package/dist/chunk-C6GXVH5J.mjs.map +0 -1
  114. package/dist/chunk-DMX7W4XZ.mjs +0 -1113
  115. package/dist/chunk-DMX7W4XZ.mjs.map +0 -1
  116. package/dist/chunk-ECONRHIG.mjs +0 -212
  117. package/dist/chunk-ECONRHIG.mjs.map +0 -1
  118. package/dist/chunk-FEN5S772.cjs +0 -1227
  119. package/dist/chunk-FEN5S772.cjs.map +0 -1
  120. package/dist/chunk-FP2RLYQZ.cjs +0 -187
  121. package/dist/chunk-FP2RLYQZ.cjs.map +0 -1
  122. package/dist/chunk-FVVF7VCD.cjs +0 -1325
  123. package/dist/chunk-FVVF7VCD.cjs.map +0 -1
  124. package/dist/chunk-GYIO7W7M.mjs +0 -1197
  125. package/dist/chunk-GYIO7W7M.mjs.map +0 -1
  126. package/dist/chunk-KNDLV4PI.cjs +0 -1356
  127. package/dist/chunk-KNDLV4PI.cjs.map +0 -1
  128. package/dist/chunk-KNEQRUBA.mjs +0 -181
  129. package/dist/chunk-KNEQRUBA.mjs.map +0 -1
  130. package/dist/chunk-N2XQF2OL.mjs +0 -14
  131. package/dist/chunk-N4MZYNR4.mjs +0 -1342
  132. package/dist/chunk-N4MZYNR4.mjs.map +0 -1
  133. package/dist/chunk-NTVBIIUD.mjs +0 -1439
  134. package/dist/chunk-NTVBIIUD.mjs.map +0 -1
  135. package/dist/chunk-OBRSGM64.mjs +0 -607
  136. package/dist/chunk-OBRSGM64.mjs.map +0 -1
  137. package/dist/chunk-ODO4GMW7.mjs +0 -79
  138. package/dist/chunk-ODO4GMW7.mjs.map +0 -1
  139. package/dist/chunk-OLISEQHS.cjs +0 -18
  140. package/dist/chunk-PVAX67JG.mjs +0 -1041
  141. package/dist/chunk-PVAX67JG.mjs.map +0 -1
  142. package/dist/chunk-QJ6GTUCO.cjs +0 -81
  143. package/dist/chunk-QJ6GTUCO.cjs.map +0 -1
  144. package/dist/chunk-T3MWM23F.cjs +0 -214
  145. package/dist/chunk-T3MWM23F.cjs.map +0 -1
  146. package/dist/chunk-TBSHZO5R.cjs +0 -1134
  147. package/dist/chunk-TBSHZO5R.cjs.map +0 -1
  148. package/dist/chunk-UNCS5V5F.mjs +0 -887
  149. package/dist/chunk-UNCS5V5F.mjs.map +0 -1
  150. package/dist/chunk-VWQ5WOIL.mjs +0 -2059
  151. package/dist/chunk-VWQ5WOIL.mjs.map +0 -1
  152. package/dist/chunk-W75B7Y6C.cjs +0 -1478
  153. package/dist/chunk-W75B7Y6C.cjs.map +0 -1
  154. package/dist/chunk-Y6UTOBF6.mjs +0 -938
  155. package/dist/chunk-Y6UTOBF6.mjs.map +0 -1
  156. package/dist/chunk-YDPDTOSP.cjs +0 -2061
  157. package/dist/chunk-YDPDTOSP.cjs.map +0 -1
  158. package/dist/chunk-YW5IVWHQ.cjs +0 -346
  159. package/dist/chunk-YW5IVWHQ.cjs.map +0 -1
  160. package/dist/chunk-YXZ6GU7H.cjs +0 -63
  161. package/dist/chunk-YXZ6GU7H.cjs.map +0 -1
  162. package/dist/chunk-ZL7FH4NW.mjs +0 -1274
  163. package/dist/chunk-ZL7FH4NW.mjs.map +0 -1
  164. package/dist/components-EHOGXATG.cjs +0 -22
  165. package/dist/components-EHOGXATG.cjs.map +0 -1
  166. package/dist/components-MQ6DR7TX.cjs +0 -26
  167. package/dist/components-MQ6DR7TX.cjs.map +0 -1
  168. package/dist/components-XRX7QGLB.mjs +0 -5
  169. package/dist/components-XRX7QGLB.mjs.map +0 -1
  170. package/dist/components-YATKRWLH.mjs +0 -5
  171. package/dist/components-YATKRWLH.mjs.map +0 -1
  172. package/dist/index.cjs +0 -3674
  173. package/dist/index.cjs.map +0 -1
  174. package/dist/index.css +0 -234
  175. package/dist/index.css.map +0 -1
  176. package/dist/index.d.cts +0 -4929
  177. package/dist/index.d.ts +0 -4929
  178. package/dist/index.mjs +0 -2912
  179. package/dist/index.mjs.map +0 -1
  180. package/dist/launcher-5Y42OBSN.mjs +0 -6
  181. package/dist/launcher-5Y42OBSN.mjs.map +0 -1
  182. package/dist/launcher-PMW2YB24.cjs +0 -59
  183. package/dist/launcher-PMW2YB24.cjs.map +0 -1
  184. package/src/index.ts +0 -157
@@ -1,1041 +0,0 @@
1
- import { __name } from './chunk-N2XQF2OL.mjs';
2
- import { createContext, useRef, useState, useEffect, useMemo, useCallback, useContext } from 'react';
3
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { Tabs, TabsList, TabsTrigger, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Input, Popover, PopoverTrigger, PopoverContent } from '@djangocfg/ui-core/components';
5
- import { cn } from '@djangocfg/ui-core/lib';
6
- import { Clock, CheckCircle2, AlertCircle, HelpCircle, Calendar, Check, Copy, ArrowRight } from 'lucide-react';
7
-
8
- // src/tools/CronScheduler/utils/cron-builder.ts
9
- function buildCron(state) {
10
- if (!state || typeof state !== "object") {
11
- return "0 0 * * *";
12
- }
13
- const { type, hour = 0, minute = 0, weekDays = [], monthDays = [], customCron = "" } = state;
14
- const h = Math.max(0, Math.min(23, Number(hour) || 0));
15
- const m = Math.max(0, Math.min(59, Number(minute) || 0));
16
- const safeWeekDays = Array.isArray(weekDays) ? weekDays : [];
17
- const safeMonthDays = Array.isArray(monthDays) ? monthDays : [];
18
- switch (type) {
19
- case "daily":
20
- return `${m} ${h} * * *`;
21
- case "weekly": {
22
- const sortedDays = [...safeWeekDays].sort((a, b) => a - b);
23
- const daysStr = sortedDays.length > 0 ? formatNumberList(sortedDays) : "*";
24
- return `${m} ${h} * * ${daysStr}`;
25
- }
26
- case "monthly": {
27
- const sortedDays = [...safeMonthDays].sort((a, b) => a - b);
28
- const daysStr = sortedDays.length > 0 ? formatNumberList(sortedDays) : "1";
29
- return `${m} ${h} ${daysStr} * *`;
30
- }
31
- case "custom":
32
- return (customCron || "").trim() || "* * * * *";
33
- default:
34
- return "0 0 * * *";
35
- }
36
- }
37
- __name(buildCron, "buildCron");
38
- function formatNumberList(nums) {
39
- if (nums.length === 0) return "";
40
- if (nums.length === 1) return nums[0].toString();
41
- const sorted = [...nums].sort((a, b) => a - b);
42
- const ranges = [];
43
- let start = sorted[0];
44
- let end = sorted[0];
45
- for (let i = 1; i < sorted.length; i++) {
46
- if (sorted[i] === end + 1) {
47
- end = sorted[i];
48
- } else {
49
- ranges.push(start === end ? `${start}` : `${start}-${end}`);
50
- start = sorted[i];
51
- end = sorted[i];
52
- }
53
- }
54
- ranges.push(start === end ? `${start}` : `${start}-${end}`);
55
- return ranges.join(",");
56
- }
57
- __name(formatNumberList, "formatNumberList");
58
-
59
- // src/tools/CronScheduler/utils/cron-parser.ts
60
- function parseCron(cron) {
61
- if (!cron || typeof cron !== "string") return null;
62
- const parts = cron.trim().split(/\s+/);
63
- if (parts.length !== 5) return null;
64
- const [minutePart, hourPart, dayOfMonthPart, monthPart, dayOfWeekPart] = parts;
65
- if (!isValidCronField(minutePart, 0, 59)) return null;
66
- if (!isValidCronField(hourPart, 0, 23)) return null;
67
- if (!isValidCronField(dayOfMonthPart, 1, 31)) return null;
68
- if (!isValidCronField(monthPart, 1, 12)) return null;
69
- if (!isValidCronField(dayOfWeekPart, 0, 6)) return null;
70
- const minute = parseField(minutePart);
71
- const hour = parseField(hourPart);
72
- const result = detectScheduleType(
73
- minutePart,
74
- hourPart,
75
- dayOfMonthPart,
76
- monthPart,
77
- dayOfWeekPart
78
- );
79
- return {
80
- type: result.type,
81
- hour: hour ?? 0,
82
- minute: minute ?? 0,
83
- weekDays: result.weekDays,
84
- monthDays: result.monthDays,
85
- customCron: cron,
86
- isValid: true
87
- };
88
- }
89
- __name(parseCron, "parseCron");
90
- function isSimpleField(part) {
91
- return part === "*" || /^\d+$/.test(part);
92
- }
93
- __name(isSimpleField, "isSimpleField");
94
- function detectScheduleType(minutePart, hourPart, dayOfMonthPart, monthPart, dayOfWeekPart) {
95
- let type = "custom";
96
- let weekDays = [1, 2, 3, 4, 5];
97
- let monthDays = [1];
98
- if (!isSimpleField(minutePart) || !isSimpleField(hourPart)) {
99
- return { type: "custom", weekDays, monthDays };
100
- }
101
- if (dayOfMonthPart === "*" && monthPart === "*" && dayOfWeekPart === "*") {
102
- type = "daily";
103
- } else if (dayOfMonthPart === "*" && monthPart === "*" && dayOfWeekPart !== "*") {
104
- type = "weekly";
105
- weekDays = parseWeekDays(dayOfWeekPart);
106
- } else if (dayOfMonthPart !== "*" && monthPart === "*" && dayOfWeekPart === "*") {
107
- type = "monthly";
108
- monthDays = parseMonthDays(dayOfMonthPart);
109
- }
110
- return { type, weekDays, monthDays };
111
- }
112
- __name(detectScheduleType, "detectScheduleType");
113
- function isValidCronField(part, min, max) {
114
- if (part === "*") return true;
115
- if (part.includes("/")) {
116
- const [base, step] = part.split("/");
117
- if (!step || !/^\d+$/.test(step)) return false;
118
- if (base === "*") return true;
119
- return isValidCronField(base, min, max);
120
- }
121
- if (part.includes("-") && !part.includes(",")) {
122
- const [start, end] = part.split("-").map((s) => parseInt(s, 10));
123
- return !isNaN(start) && !isNaN(end) && start >= min && end <= max && start <= end;
124
- }
125
- if (part.includes(",")) {
126
- return part.split(",").every((p) => isValidCronField(p.trim(), min, max));
127
- }
128
- if (/^\d+$/.test(part)) {
129
- const num = parseInt(part, 10);
130
- return num >= min && num <= max;
131
- }
132
- return false;
133
- }
134
- __name(isValidCronField, "isValidCronField");
135
- function parseField(part, _min, _max) {
136
- if (/^\d+$/.test(part)) {
137
- return parseInt(part, 10);
138
- }
139
- return null;
140
- }
141
- __name(parseField, "parseField");
142
- function parseWeekDays(part) {
143
- const result = [];
144
- if (part.includes("-")) {
145
- const [start, end] = part.split("-").map((s) => parseInt(s, 10));
146
- if (!isNaN(start) && !isNaN(end)) {
147
- for (let i = start; i <= end && i <= 6; i++) {
148
- if (i >= 0) result.push(i);
149
- }
150
- }
151
- return result.length > 0 ? result : [1, 2, 3, 4, 5];
152
- }
153
- for (const segment of part.split(",")) {
154
- const num = parseInt(segment.trim(), 10);
155
- if (!isNaN(num) && num >= 0 && num <= 6) {
156
- result.push(num);
157
- }
158
- }
159
- return result.length > 0 ? result : [1, 2, 3, 4, 5];
160
- }
161
- __name(parseWeekDays, "parseWeekDays");
162
- function parseMonthDays(part) {
163
- const result = [];
164
- if (part.includes("-")) {
165
- const [start, end] = part.split("-").map((s) => parseInt(s, 10));
166
- if (!isNaN(start) && !isNaN(end)) {
167
- for (let i = start; i <= end && i <= 31; i++) {
168
- if (i >= 1) result.push(i);
169
- }
170
- }
171
- return result.length > 0 ? result : [1];
172
- }
173
- for (const segment of part.split(",")) {
174
- const num = parseInt(segment.trim(), 10);
175
- if (!isNaN(num) && num >= 1 && num <= 31) {
176
- result.push(num);
177
- }
178
- }
179
- return result.length > 0 ? result : [1];
180
- }
181
- __name(parseMonthDays, "parseMonthDays");
182
- function isValidCron(cron) {
183
- if (!cron || typeof cron !== "string") return false;
184
- const parts = cron.trim().split(/\s+/);
185
- if (parts.length !== 5) return false;
186
- const [minutePart, hourPart, dayOfMonthPart, monthPart, dayOfWeekPart] = parts;
187
- return isValidCronField(minutePart, 0, 59) && isValidCronField(hourPart, 0, 23) && isValidCronField(dayOfMonthPart, 1, 31) && isValidCronField(monthPart, 1, 12) && isValidCronField(dayOfWeekPart, 0, 6);
188
- }
189
- __name(isValidCron, "isValidCron");
190
-
191
- // src/tools/CronScheduler/utils/cron-humanize.ts
192
- var WEEKDAY_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
193
- function humanizeCron(cron) {
194
- if (!cron || typeof cron !== "string") return "Invalid schedule";
195
- const parts = cron.trim().split(/\s+/);
196
- if (parts.length !== 5) return "Invalid schedule";
197
- const [minutePart, hourPart, dayOfMonthPart, monthPart, dayOfWeekPart] = parts;
198
- const minute = parseInt(minutePart, 10);
199
- const hour = parseInt(hourPart, 10);
200
- const timeStr = formatTime(hour, minute);
201
- if (minutePart === "*" && hourPart === "*" && dayOfMonthPart === "*" && monthPart === "*" && dayOfWeekPart === "*") {
202
- return "Every minute";
203
- }
204
- if (minutePart.startsWith("*/")) {
205
- const interval = parseInt(minutePart.slice(2), 10);
206
- if (hourPart === "*") {
207
- return `Every ${interval} minute${interval > 1 ? "s" : ""}`;
208
- }
209
- return `Every ${interval} minute${interval > 1 ? "s" : ""} at hour ${hour}`;
210
- }
211
- if (!isNaN(minute) && hourPart === "*" && dayOfMonthPart === "*" && monthPart === "*" && dayOfWeekPart === "*") {
212
- return `Every hour at minute ${minute}`;
213
- }
214
- if (dayOfMonthPart === "*" && monthPart === "*" && dayOfWeekPart === "*") {
215
- return `Every day at ${timeStr}`;
216
- }
217
- if (dayOfMonthPart === "*" && monthPart === "*" && dayOfWeekPart !== "*") {
218
- const days = parseWeekDays2(dayOfWeekPart);
219
- if (days.length === 7) {
220
- return `Every day at ${timeStr}`;
221
- }
222
- if (days.length === 5 && isWeekdays(days)) {
223
- return `Weekdays at ${timeStr}`;
224
- }
225
- if (days.length === 2 && isWeekend(days)) {
226
- return `Weekends at ${timeStr}`;
227
- }
228
- const dayNames = days.map((d) => WEEKDAY_SHORT[d]).join(", ");
229
- return `${dayNames} at ${timeStr}`;
230
- }
231
- if (dayOfMonthPart !== "*" && monthPart === "*" && dayOfWeekPart === "*") {
232
- const days = parseMonthDays2(dayOfMonthPart);
233
- if (days.length === 1) {
234
- return `${ordinal(days[0])} of every month at ${timeStr}`;
235
- }
236
- if (days.length <= 3) {
237
- const dayStr = days.map((d) => ordinal(d)).join(", ");
238
- return `${dayStr} of every month at ${timeStr}`;
239
- }
240
- return `${days.length} days per month at ${timeStr}`;
241
- }
242
- return `Custom schedule`;
243
- }
244
- __name(humanizeCron, "humanizeCron");
245
- function formatTime(hour, minute) {
246
- const h = isNaN(hour) ? 0 : Math.max(0, Math.min(23, hour));
247
- const m = isNaN(minute) ? 0 : Math.max(0, Math.min(59, minute));
248
- return `${h.toString().padStart(2, "0")}:${m.toString().padStart(2, "0")}`;
249
- }
250
- __name(formatTime, "formatTime");
251
- function parseWeekDays2(part) {
252
- const result = [];
253
- if (part.includes("-") && !part.includes(",")) {
254
- const [start, end] = part.split("-").map((s) => parseInt(s, 10));
255
- if (!isNaN(start) && !isNaN(end)) {
256
- for (let i = start; i <= end && i <= 6; i++) {
257
- if (i >= 0) result.push(i);
258
- }
259
- }
260
- return result;
261
- }
262
- for (const segment of part.split(",")) {
263
- if (segment.includes("-")) {
264
- const [start, end] = segment.split("-").map((s) => parseInt(s, 10));
265
- if (!isNaN(start) && !isNaN(end)) {
266
- for (let i = start; i <= end && i <= 6; i++) {
267
- if (i >= 0) result.push(i);
268
- }
269
- }
270
- } else {
271
- const num = parseInt(segment.trim(), 10);
272
- if (!isNaN(num) && num >= 0 && num <= 6) {
273
- result.push(num);
274
- }
275
- }
276
- }
277
- return result.sort((a, b) => a - b);
278
- }
279
- __name(parseWeekDays2, "parseWeekDays");
280
- function parseMonthDays2(part) {
281
- const result = [];
282
- if (part.includes("-") && !part.includes(",")) {
283
- const [start, end] = part.split("-").map((s) => parseInt(s, 10));
284
- if (!isNaN(start) && !isNaN(end)) {
285
- for (let i = start; i <= end && i <= 31; i++) {
286
- if (i >= 1) result.push(i);
287
- }
288
- }
289
- return result;
290
- }
291
- for (const segment of part.split(",")) {
292
- const num = parseInt(segment.trim(), 10);
293
- if (!isNaN(num) && num >= 1 && num <= 31) {
294
- result.push(num);
295
- }
296
- }
297
- return result.sort((a, b) => a - b);
298
- }
299
- __name(parseMonthDays2, "parseMonthDays");
300
- function isWeekdays(days) {
301
- const sorted = [...days].sort((a, b) => a - b);
302
- return sorted.join(",") === "1,2,3,4,5";
303
- }
304
- __name(isWeekdays, "isWeekdays");
305
- function isWeekend(days) {
306
- const sorted = [...days].sort((a, b) => a - b);
307
- return sorted.join(",") === "0,6";
308
- }
309
- __name(isWeekend, "isWeekend");
310
- function ordinal(n) {
311
- const s = ["th", "st", "nd", "rd"];
312
- const v = n % 100;
313
- return n + (s[(v - 20) % 10] || s[v] || s[0]);
314
- }
315
- __name(ordinal, "ordinal");
316
- var CronSchedulerContext = createContext(null);
317
- var DEFAULT_STATE = {
318
- type: "daily",
319
- hour: 9,
320
- minute: 0,
321
- weekDays: [1, 2, 3, 4, 5],
322
- // Mon-Fri
323
- monthDays: [1],
324
- customCron: "* * * * *",
325
- isValid: true
326
- };
327
- function CronSchedulerProvider({
328
- children,
329
- value,
330
- onChange,
331
- defaultType = "daily"
332
- }) {
333
- const isInitialMount = useRef(true);
334
- const onChangeRef = useRef(onChange);
335
- onChangeRef.current = onChange;
336
- const [initialValue] = useState(() => value || null);
337
- const [state, setState] = useState(() => {
338
- try {
339
- if (value) {
340
- const parsed = parseCron(value);
341
- if (parsed) return parsed;
342
- }
343
- } catch {
344
- }
345
- return { ...DEFAULT_STATE, type: defaultType };
346
- });
347
- useEffect(() => {
348
- try {
349
- if (value) {
350
- const parsed = parseCron(value);
351
- if (parsed) {
352
- const currentCron = buildCron(state);
353
- if (value !== currentCron) {
354
- setState(parsed);
355
- }
356
- }
357
- }
358
- } catch {
359
- }
360
- }, [value]);
361
- const cronExpression = useMemo(() => buildCron(state), [state]);
362
- const humanDescription = useMemo(() => humanizeCron(cronExpression), [cronExpression]);
363
- useEffect(() => {
364
- if (isInitialMount.current) {
365
- isInitialMount.current = false;
366
- return;
367
- }
368
- onChangeRef.current?.(cronExpression);
369
- }, [cronExpression]);
370
- const setType = useCallback((type) => {
371
- setState((s) => ({ ...s, type }));
372
- }, []);
373
- const setTime = useCallback((hour, minute) => {
374
- setState((s) => ({
375
- ...s,
376
- hour: Math.max(0, Math.min(23, hour)),
377
- minute: Math.max(0, Math.min(59, minute))
378
- }));
379
- }, []);
380
- const toggleWeekDay = useCallback((day) => {
381
- setState((s) => {
382
- const hasDay = s.weekDays.includes(day);
383
- if (hasDay && s.weekDays.length === 1) return s;
384
- const newDays = hasDay ? s.weekDays.filter((d) => d !== day) : [...s.weekDays, day];
385
- return {
386
- ...s,
387
- weekDays: newDays.sort((a, b) => a - b)
388
- };
389
- });
390
- }, []);
391
- const setWeekDays = useCallback((days) => {
392
- setState((s) => ({
393
- ...s,
394
- weekDays: days.length > 0 ? [...days].sort((a, b) => a - b) : [1]
395
- // Default to Monday if empty
396
- }));
397
- }, []);
398
- const toggleMonthDay = useCallback((day) => {
399
- setState((s) => {
400
- const hasDay = s.monthDays.includes(day);
401
- if (hasDay && s.monthDays.length === 1) return s;
402
- const newDays = hasDay ? s.monthDays.filter((d) => d !== day) : [...s.monthDays, day];
403
- return {
404
- ...s,
405
- monthDays: newDays.sort((a, b) => a - b)
406
- };
407
- });
408
- }, []);
409
- const setMonthDays = useCallback((days) => {
410
- setState((s) => ({
411
- ...s,
412
- monthDays: days.length > 0 ? [...days].sort((a, b) => a - b) : [1]
413
- // Default to 1st if empty
414
- }));
415
- }, []);
416
- const setCustomCron = useCallback((customCron) => {
417
- const parsed = parseCron(customCron);
418
- setState((s) => ({
419
- ...s,
420
- customCron,
421
- isValid: parsed !== null
422
- }));
423
- }, []);
424
- const reset = useCallback(() => {
425
- setState({ ...DEFAULT_STATE, type: defaultType });
426
- }, [defaultType]);
427
- const contextValue = useMemo(
428
- () => ({
429
- // State
430
- ...state,
431
- // Computed
432
- cronExpression,
433
- humanDescription,
434
- initialValue,
435
- // Actions
436
- setType,
437
- setTime,
438
- toggleWeekDay,
439
- setWeekDays,
440
- toggleMonthDay,
441
- setMonthDays,
442
- setCustomCron,
443
- reset
444
- }),
445
- [
446
- state,
447
- cronExpression,
448
- humanDescription,
449
- initialValue,
450
- setType,
451
- setTime,
452
- toggleWeekDay,
453
- setWeekDays,
454
- toggleMonthDay,
455
- setMonthDays,
456
- setCustomCron,
457
- reset
458
- ]
459
- );
460
- return /* @__PURE__ */ jsx(CronSchedulerContext.Provider, { value: contextValue, children });
461
- }
462
- __name(CronSchedulerProvider, "CronSchedulerProvider");
463
- function useCronSchedulerContext() {
464
- const context = useContext(CronSchedulerContext);
465
- if (!context) {
466
- throw new Error(
467
- "useCronSchedulerContext must be used within CronSchedulerProvider"
468
- );
469
- }
470
- return context;
471
- }
472
- __name(useCronSchedulerContext, "useCronSchedulerContext");
473
- function useCronType() {
474
- const { type, setType } = useCronSchedulerContext();
475
- return useMemo(() => ({ type, setType }), [type, setType]);
476
- }
477
- __name(useCronType, "useCronType");
478
- function useCronTime() {
479
- const { hour, minute, setTime } = useCronSchedulerContext();
480
- return useMemo(() => ({ hour, minute, setTime }), [hour, minute, setTime]);
481
- }
482
- __name(useCronTime, "useCronTime");
483
- function useCronWeekDays() {
484
- const { weekDays, toggleWeekDay, setWeekDays } = useCronSchedulerContext();
485
- return useMemo(
486
- () => ({ weekDays, toggleWeekDay, setWeekDays }),
487
- [weekDays, toggleWeekDay, setWeekDays]
488
- );
489
- }
490
- __name(useCronWeekDays, "useCronWeekDays");
491
- function useCronMonthDays() {
492
- const { monthDays, toggleMonthDay, setMonthDays } = useCronSchedulerContext();
493
- return useMemo(
494
- () => ({ monthDays, toggleMonthDay, setMonthDays }),
495
- [monthDays, toggleMonthDay, setMonthDays]
496
- );
497
- }
498
- __name(useCronMonthDays, "useCronMonthDays");
499
- function useCronCustom() {
500
- const { customCron, isValid, setCustomCron } = useCronSchedulerContext();
501
- return useMemo(
502
- () => ({ customCron, isValid, setCustomCron }),
503
- [customCron, isValid, setCustomCron]
504
- );
505
- }
506
- __name(useCronCustom, "useCronCustom");
507
- function useCronPreview() {
508
- const { cronExpression, humanDescription, isValid, initialValue } = useCronSchedulerContext();
509
- return useMemo(
510
- () => ({ cronExpression, humanDescription, isValid, initialValue }),
511
- [cronExpression, humanDescription, isValid, initialValue]
512
- );
513
- }
514
- __name(useCronPreview, "useCronPreview");
515
- function useCronScheduler() {
516
- return useCronSchedulerContext();
517
- }
518
- __name(useCronScheduler, "useCronScheduler");
519
- var SCHEDULE_TYPES = [
520
- { value: "daily", label: "Daily" },
521
- { value: "weekly", label: "Weekly" },
522
- { value: "monthly", label: "Monthly" },
523
- { value: "custom", label: "Custom" }
524
- ];
525
- function ScheduleTypeSelector({
526
- disabled,
527
- className
528
- }) {
529
- const { type, setType } = useCronType();
530
- const triggerClassName = cn(
531
- "text-xs font-medium px-2 py-1.5",
532
- "data-[state=active]:shadow-sm",
533
- "transition-all duration-150"
534
- );
535
- const triggers = SCHEDULE_TYPES.map(({ value, label }) => ({
536
- value,
537
- label,
538
- disabled,
539
- className: triggerClassName
540
- }));
541
- return /* @__PURE__ */ jsx(
542
- Tabs,
543
- {
544
- value: type,
545
- onValueChange: (v) => setType(v),
546
- className: cn("w-full", className),
547
- children: /* @__PURE__ */ jsx(TabsList, { className: "grid w-full grid-cols-4 h-9 p-0.5", children: triggers.map((trigger) => /* @__PURE__ */ jsx(
548
- TabsTrigger,
549
- {
550
- value: trigger.value,
551
- disabled: trigger.disabled,
552
- className: trigger.className,
553
- children: trigger.label
554
- },
555
- trigger.value
556
- )) })
557
- }
558
- );
559
- }
560
- __name(ScheduleTypeSelector, "ScheduleTypeSelector");
561
- var HOURS = Array.from({ length: 24 }, (_, i) => i);
562
- var MINUTES = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55];
563
- function TimeSelector({
564
- format = "24h",
565
- disabled,
566
- className
567
- }) {
568
- const { hour, minute, setTime } = useCronTime();
569
- const is24h = format === "24h";
570
- const displayHour = is24h ? hour : hour % 12 || 12;
571
- const isPM = hour >= 12;
572
- const handleHourChange = /* @__PURE__ */ __name((value) => {
573
- let newHour = parseInt(value, 10);
574
- if (!is24h) {
575
- if (isPM && newHour !== 12) newHour += 12;
576
- else if (!isPM && newHour === 12) newHour = 0;
577
- }
578
- setTime(newHour, minute);
579
- }, "handleHourChange");
580
- const handleMinuteChange = /* @__PURE__ */ __name((value) => {
581
- setTime(hour, parseInt(value, 10));
582
- }, "handleMinuteChange");
583
- const handlePeriodChange = /* @__PURE__ */ __name((value) => {
584
- const newIsPM = value === "PM";
585
- let newHour = hour;
586
- if (newIsPM && hour < 12) newHour = hour + 12;
587
- else if (!newIsPM && hour >= 12) newHour = hour - 12;
588
- setTime(newHour, minute);
589
- }, "handlePeriodChange");
590
- const hours = is24h ? HOURS : Array.from({ length: 12 }, (_, i) => i + 1);
591
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3", className), children: [
592
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
593
- /* @__PURE__ */ jsx(Clock, { className: "h-4 w-4" }),
594
- /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Run at" })
595
- ] }),
596
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 flex-1", children: [
597
- /* @__PURE__ */ jsxs(
598
- Select,
599
- {
600
- value: displayHour.toString(),
601
- onValueChange: handleHourChange,
602
- disabled,
603
- children: [
604
- /* @__PURE__ */ jsx(SelectTrigger, { className: "w-[70px] h-9", children: /* @__PURE__ */ jsx(SelectValue, { children: displayHour.toString().padStart(2, "0") }) }),
605
- /* @__PURE__ */ jsx(SelectContent, { className: "max-h-48", children: hours.map((h) => /* @__PURE__ */ jsx(SelectItem, { value: h.toString(), children: h.toString().padStart(2, "0") }, h)) })
606
- ]
607
- }
608
- ),
609
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-medium", children: ":" }),
610
- /* @__PURE__ */ jsxs(
611
- Select,
612
- {
613
- value: minute.toString(),
614
- onValueChange: handleMinuteChange,
615
- disabled,
616
- children: [
617
- /* @__PURE__ */ jsx(SelectTrigger, { className: "w-[70px] h-9", children: /* @__PURE__ */ jsx(SelectValue, { children: minute.toString().padStart(2, "0") }) }),
618
- /* @__PURE__ */ jsx(SelectContent, { className: "max-h-48", children: MINUTES.map((m) => /* @__PURE__ */ jsx(SelectItem, { value: m.toString(), children: m.toString().padStart(2, "0") }, m)) })
619
- ]
620
- }
621
- ),
622
- !is24h && /* @__PURE__ */ jsxs(
623
- Select,
624
- {
625
- value: isPM ? "PM" : "AM",
626
- onValueChange: handlePeriodChange,
627
- disabled,
628
- children: [
629
- /* @__PURE__ */ jsx(SelectTrigger, { className: "w-[70px] h-9", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
630
- /* @__PURE__ */ jsxs(SelectContent, { children: [
631
- /* @__PURE__ */ jsx(SelectItem, { value: "AM", children: "AM" }),
632
- /* @__PURE__ */ jsx(SelectItem, { value: "PM", children: "PM" })
633
- ] })
634
- ]
635
- }
636
- )
637
- ] })
638
- ] });
639
- }
640
- __name(TimeSelector, "TimeSelector");
641
- var DAYS = [
642
- { value: 1, label: "Mon" },
643
- { value: 2, label: "Tue" },
644
- { value: 3, label: "Wed" },
645
- { value: 4, label: "Thu" },
646
- { value: 5, label: "Fri" },
647
- { value: 6, label: "Sat" },
648
- { value: 0, label: "Sun" }
649
- ];
650
- function DayChips({
651
- disabled,
652
- showPresets = true,
653
- className
654
- }) {
655
- const { weekDays, toggleWeekDay, setWeekDays } = useCronWeekDays();
656
- const safeWeekDays = Array.isArray(weekDays) ? weekDays : [];
657
- const isWeekdays2 = safeWeekDays.length === 5 && [1, 2, 3, 4, 5].every((d) => safeWeekDays.includes(d));
658
- const isWeekendPreset = safeWeekDays.length === 2 && [0, 6].every((d) => safeWeekDays.includes(d));
659
- const isEveryday = safeWeekDays.length === 7;
660
- const dayButtons = DAYS.map(({ value, label }) => {
661
- const isSelected = safeWeekDays.includes(value);
662
- const isWeekendDay = value === 0 || value === 6;
663
- return {
664
- value,
665
- label,
666
- isSelected,
667
- isWeekendDay,
668
- className: cn(
669
- "flex flex-col items-center justify-center",
670
- "py-2.5 rounded-lg text-xs font-medium",
671
- "transition-all duration-150",
672
- "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
673
- "active:scale-[0.97]",
674
- isSelected ? "bg-primary text-primary-foreground shadow-sm" : cn(
675
- "bg-muted/50 hover:bg-muted",
676
- isWeekendDay ? "text-muted-foreground/70" : "text-muted-foreground"
677
- ),
678
- disabled && "opacity-50 cursor-not-allowed pointer-events-none"
679
- )
680
- };
681
- });
682
- const presets = [
683
- { label: "Weekdays", isActive: isWeekdays2, days: [1, 2, 3, 4, 5] },
684
- { label: "Weekends", isActive: isWeekendPreset, days: [0, 6] },
685
- { label: "Every day", isActive: isEveryday, days: [0, 1, 2, 3, 4, 5, 6] }
686
- ];
687
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-3", className), children: [
688
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-1", children: dayButtons.map((day) => /* @__PURE__ */ jsx(
689
- "button",
690
- {
691
- type: "button",
692
- disabled,
693
- onClick: () => toggleWeekDay(day.value),
694
- "aria-pressed": day.isSelected,
695
- className: day.className,
696
- children: /* @__PURE__ */ jsx("span", { children: day.label })
697
- },
698
- day.value
699
- )) }),
700
- showPresets && /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: presets.map((preset) => /* @__PURE__ */ jsx(
701
- PresetButton,
702
- {
703
- label: preset.label,
704
- isActive: preset.isActive,
705
- onClick: () => setWeekDays(preset.days),
706
- disabled
707
- },
708
- preset.label
709
- )) })
710
- ] });
711
- }
712
- __name(DayChips, "DayChips");
713
- function PresetButton({ label, isActive, onClick, disabled }) {
714
- return /* @__PURE__ */ jsx(
715
- "button",
716
- {
717
- type: "button",
718
- disabled,
719
- onClick,
720
- className: cn(
721
- "flex-1 px-3 py-1.5 rounded-md text-xs font-medium",
722
- "transition-colors duration-150",
723
- "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
724
- isActive ? "bg-primary/15 text-primary border border-primary/30" : "bg-muted/30 text-muted-foreground hover:bg-muted/50 border border-transparent",
725
- disabled && "opacity-50 cursor-not-allowed"
726
- ),
727
- children: label
728
- }
729
- );
730
- }
731
- __name(PresetButton, "PresetButton");
732
- Array.from({ length: 31 }, (_, i) => i + 1);
733
- var GRID_SIZE = 35;
734
- function MonthDayGrid({
735
- disabled,
736
- showPresets = true,
737
- className
738
- }) {
739
- const { monthDays, toggleMonthDay, setMonthDays } = useCronMonthDays();
740
- const safeMonthDays = Array.isArray(monthDays) ? monthDays : [];
741
- const is1st = safeMonthDays.length === 1 && safeMonthDays[0] === 1;
742
- const is15th = safeMonthDays.length === 1 && safeMonthDays[0] === 15;
743
- const is1stAnd15th = safeMonthDays.length === 2 && safeMonthDays.includes(1) && safeMonthDays.includes(15);
744
- const presets = [
745
- { label: "1st", isActive: is1st, days: [1] },
746
- { label: "15th", isActive: is15th, days: [15] },
747
- { label: "1st & 15th", isActive: is1stAnd15th, days: [1, 15] }
748
- ];
749
- const gridCells = Array.from({ length: GRID_SIZE }, (_, i) => {
750
- const day = i + 1;
751
- const isValidDay = day <= 31;
752
- const isSelected = isValidDay && safeMonthDays.includes(day);
753
- const isPartialMonth = day > 28;
754
- if (!isValidDay) {
755
- return { type: "empty", key: i };
756
- }
757
- return {
758
- type: "day",
759
- key: day,
760
- day,
761
- isSelected,
762
- className: cn(
763
- "aspect-square flex items-center justify-center",
764
- "rounded-lg text-sm font-medium",
765
- "transition-all duration-150",
766
- "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
767
- "active:scale-[0.95]",
768
- isSelected ? "bg-primary text-primary-foreground shadow-sm" : cn(
769
- "bg-muted/30 hover:bg-muted/60",
770
- isPartialMonth ? "text-muted-foreground/50" : "text-muted-foreground"
771
- ),
772
- disabled && "opacity-50 cursor-not-allowed pointer-events-none"
773
- )
774
- };
775
- });
776
- const selectionCount = safeMonthDays.length;
777
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-3", className), children: [
778
- showPresets && /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: presets.map((preset) => /* @__PURE__ */ jsx(
779
- PresetButton2,
780
- {
781
- label: preset.label,
782
- isActive: preset.isActive,
783
- onClick: () => setMonthDays(preset.days),
784
- disabled
785
- },
786
- preset.label
787
- )) }),
788
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-1", children: gridCells.map((cell) => {
789
- if (cell.type === "empty") {
790
- return /* @__PURE__ */ jsx("div", { className: "aspect-square" }, cell.key);
791
- }
792
- return /* @__PURE__ */ jsx(
793
- "button",
794
- {
795
- type: "button",
796
- disabled,
797
- onClick: () => toggleMonthDay(cell.day),
798
- "aria-pressed": cell.isSelected,
799
- "aria-label": `Day ${cell.day}`,
800
- className: cell.className,
801
- children: cell.day
802
- },
803
- cell.key
804
- );
805
- }) }),
806
- selectionCount > 1 && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground text-center", children: [
807
- selectionCount,
808
- " days selected"
809
- ] })
810
- ] });
811
- }
812
- __name(MonthDayGrid, "MonthDayGrid");
813
- function PresetButton2({ label, isActive, onClick, disabled }) {
814
- return /* @__PURE__ */ jsx(
815
- "button",
816
- {
817
- type: "button",
818
- disabled,
819
- onClick,
820
- className: cn(
821
- "flex-1 px-3 py-1.5 rounded-md text-xs font-medium",
822
- "transition-colors duration-150",
823
- "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
824
- isActive ? "bg-primary/15 text-primary border border-primary/30" : "bg-muted/30 text-muted-foreground hover:bg-muted/50 border border-transparent",
825
- disabled && "opacity-50 cursor-not-allowed"
826
- ),
827
- children: label
828
- }
829
- );
830
- }
831
- __name(PresetButton2, "PresetButton");
832
- function CustomInput({ disabled, className }) {
833
- const { customCron, isValid, setCustomCron } = useCronCustom();
834
- const [localValue, setLocalValue] = useState(customCron);
835
- const [localValid, setLocalValid] = useState(isValid);
836
- useEffect(() => {
837
- setLocalValue(customCron);
838
- setLocalValid(isValid);
839
- }, [customCron, isValid]);
840
- const handleChange = /* @__PURE__ */ __name((e) => {
841
- const value = e.target.value;
842
- setLocalValue(value);
843
- const valid = isValidCron(value);
844
- setLocalValid(valid);
845
- setCustomCron(value);
846
- }, "handleChange");
847
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
848
- /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Cron expression" }),
849
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
850
- /* @__PURE__ */ jsx(
851
- Input,
852
- {
853
- type: "text",
854
- value: localValue,
855
- onChange: handleChange,
856
- disabled,
857
- placeholder: "* * * * *",
858
- className: cn(
859
- "font-mono text-base pr-10 h-11",
860
- !localValid && localValue.trim() && "border-destructive focus-visible:ring-destructive/50"
861
- )
862
- }
863
- ),
864
- /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2", children: localValue.trim() && (localValid ? /* @__PURE__ */ jsx(CheckCircle2, { className: "h-5 w-5 text-green-500" }) : /* @__PURE__ */ jsx(AlertCircle, { className: "h-5 w-5 text-destructive" })) })
865
- ] })
866
- ] });
867
- }
868
- __name(CustomInput, "CustomInput");
869
- function CronCheatsheet({ className }) {
870
- return /* @__PURE__ */ jsxs(Popover, { children: [
871
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
872
- "button",
873
- {
874
- type: "button",
875
- className: cn(
876
- "p-1 rounded hover:bg-muted/50 transition-colors",
877
- className
878
- ),
879
- "aria-label": "Cron syntax help",
880
- children: /* @__PURE__ */ jsx(HelpCircle, { className: "h-4 w-4 text-muted-foreground" })
881
- }
882
- ) }),
883
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-72 p-3", align: "end", children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
884
- /* @__PURE__ */ jsx("p", { className: "font-medium text-sm", children: "Cron Format" }),
885
- /* @__PURE__ */ jsx("code", { className: "block text-xs bg-muted px-2 py-1.5 rounded font-mono text-center", children: "min hour day month weekday" }),
886
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-4 gap-y-1 text-xs", children: [
887
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
888
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "minute" }),
889
- /* @__PURE__ */ jsx("span", { children: "0-59" })
890
- ] }),
891
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
892
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "hour" }),
893
- /* @__PURE__ */ jsx("span", { children: "0-23" })
894
- ] }),
895
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
896
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "day" }),
897
- /* @__PURE__ */ jsx("span", { children: "1-31" })
898
- ] }),
899
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
900
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "month" }),
901
- /* @__PURE__ */ jsx("span", { children: "1-12" })
902
- ] }),
903
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between col-span-2", children: [
904
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "weekday" }),
905
- /* @__PURE__ */ jsx("span", { children: "0-6 (Sun-Sat)" })
906
- ] })
907
- ] }),
908
- /* @__PURE__ */ jsxs("div", { className: "pt-2 border-t border-border space-y-1.5", children: [
909
- /* @__PURE__ */ jsx("p", { className: "text-xs font-medium", children: "Special characters" }),
910
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-1.5 text-xs", children: [
911
- /* @__PURE__ */ jsxs("span", { children: [
912
- /* @__PURE__ */ jsx("code", { className: "bg-muted px-1 rounded", children: "*" }),
913
- " any value"
914
- ] }),
915
- /* @__PURE__ */ jsxs("span", { children: [
916
- /* @__PURE__ */ jsx("code", { className: "bg-muted px-1 rounded", children: "," }),
917
- " list (1,3,5)"
918
- ] }),
919
- /* @__PURE__ */ jsxs("span", { children: [
920
- /* @__PURE__ */ jsx("code", { className: "bg-muted px-1 rounded", children: "-" }),
921
- " range (1-5)"
922
- ] }),
923
- /* @__PURE__ */ jsxs("span", { children: [
924
- /* @__PURE__ */ jsx("code", { className: "bg-muted px-1 rounded", children: "/" }),
925
- " step (*/15)"
926
- ] })
927
- ] })
928
- ] }),
929
- /* @__PURE__ */ jsxs("div", { className: "pt-2 border-t border-border space-y-1.5", children: [
930
- /* @__PURE__ */ jsx("p", { className: "text-xs font-medium", children: "Examples" }),
931
- /* @__PURE__ */ jsxs("div", { className: "space-y-1 text-xs", children: [
932
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between font-mono", children: [
933
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "0 9 * * *" }),
934
- /* @__PURE__ */ jsx("span", { children: "daily at 9am" })
935
- ] }),
936
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between font-mono", children: [
937
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "0 9 * * 1-5" }),
938
- /* @__PURE__ */ jsx("span", { children: "weekdays 9am" })
939
- ] }),
940
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between font-mono", children: [
941
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "*/15 * * * *" }),
942
- /* @__PURE__ */ jsx("span", { children: "every 15 min" })
943
- ] }),
944
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between font-mono", children: [
945
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "0 0 1 * *" }),
946
- /* @__PURE__ */ jsx("span", { children: "1st of month" })
947
- ] })
948
- ] })
949
- ] })
950
- ] }) })
951
- ] });
952
- }
953
- __name(CronCheatsheet, "CronCheatsheet");
954
- function SchedulePreview({
955
- showCronExpression = true,
956
- allowCopy = false,
957
- showInitialValue = true,
958
- className
959
- }) {
960
- const { cronExpression, humanDescription, isValid, initialValue } = useCronPreview();
961
- const hasChanged = useMemo(
962
- () => showInitialValue && initialValue && initialValue !== cronExpression,
963
- [showInitialValue, initialValue, cronExpression]
964
- );
965
- const [copied, setCopied] = useState(false);
966
- const handleCopy = useCallback(async () => {
967
- try {
968
- await navigator.clipboard.writeText(cronExpression);
969
- setCopied(true);
970
- setTimeout(() => setCopied(false), 2e3);
971
- } catch (err) {
972
- console.error("Failed to copy:", err);
973
- }
974
- }, [cronExpression]);
975
- return /* @__PURE__ */ jsxs(
976
- "div",
977
- {
978
- className: cn(
979
- "px-3 py-2.5 rounded-lg border",
980
- "bg-muted/30 border-border/50",
981
- !isValid && "border-destructive/30 bg-destructive/5",
982
- className
983
- ),
984
- children: [
985
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
986
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
987
- /* @__PURE__ */ jsx(
988
- Calendar,
989
- {
990
- className: cn(
991
- "h-4 w-4 shrink-0",
992
- isValid ? "text-primary" : "text-destructive"
993
- )
994
- }
995
- ),
996
- /* @__PURE__ */ jsx(
997
- "span",
998
- {
999
- className: cn(
1000
- "text-sm",
1001
- isValid ? "text-foreground" : "text-destructive"
1002
- ),
1003
- children: humanDescription
1004
- }
1005
- )
1006
- ] }),
1007
- allowCopy && /* @__PURE__ */ jsx(
1008
- "button",
1009
- {
1010
- type: "button",
1011
- onClick: handleCopy,
1012
- disabled: !isValid,
1013
- className: cn(
1014
- "p-1 rounded transition-colors duration-150",
1015
- "hover:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
1016
- "disabled:opacity-50 disabled:cursor-not-allowed"
1017
- ),
1018
- title: copied ? "Copied!" : "Copy cron expression",
1019
- children: copied ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-green-500" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5 text-muted-foreground" })
1020
- }
1021
- )
1022
- ] }),
1023
- showCronExpression && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 pt-1.5 border-t border-border/30 flex items-center justify-between", children: [
1024
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 min-w-0", children: [
1025
- hasChanged && /* @__PURE__ */ jsxs(Fragment, { children: [
1026
- /* @__PURE__ */ jsx("code", { className: "text-xs font-mono text-muted-foreground/60 line-through", children: initialValue }),
1027
- /* @__PURE__ */ jsx(ArrowRight, { className: "h-3 w-3 text-muted-foreground/40 shrink-0" })
1028
- ] }),
1029
- /* @__PURE__ */ jsx("code", { className: "text-xs font-mono text-muted-foreground", children: cronExpression })
1030
- ] }),
1031
- /* @__PURE__ */ jsx(CronCheatsheet, {})
1032
- ] })
1033
- ]
1034
- }
1035
- );
1036
- }
1037
- __name(SchedulePreview, "SchedulePreview");
1038
-
1039
- export { CronSchedulerProvider, CustomInput, DayChips, MonthDayGrid, SchedulePreview, ScheduleTypeSelector, TimeSelector, buildCron, humanizeCron, isValidCron, parseCron, useCronCustom, useCronMonthDays, useCronPreview, useCronScheduler, useCronSchedulerContext, useCronTime, useCronType, useCronWeekDays };
1040
- //# sourceMappingURL=chunk-PVAX67JG.mjs.map
1041
- //# sourceMappingURL=chunk-PVAX67JG.mjs.map